diff --git a/src/v2/controller/addon.controller.ts b/src/v2/controller/addon.controller.ts index 4b865f5..9de85f7 100644 --- a/src/v2/controller/addon.controller.ts +++ b/src/v2/controller/addon.controller.ts @@ -36,40 +36,40 @@ export class AddonController extends Controller { private async getAddonProperty(id: number, property: AddonProperty): Promise { switch (property) { - case "files": - return (await this.service.getFiles(id)).map((f) => { + case "files": + return (await this.service.getFiles(id)).map((f) => { + if ((f.use === "header" || f.use === "screenshot") && f.source.startsWith("/")) + f.source = process.env.DB_IMAGE_ROOT + f.source; + + if ( + f.use === "download" && + !f.source.startsWith("https://") && + !f.source.startsWith("http://") + ) + f.source = `http://${f.source}`; + + return f; + }); + + case "all": + default: + return this.service.getAll(id).then((addon: AddonAll) => { + addon.files = addon.files.map((f) => { if ((f.use === "header" || f.use === "screenshot") && f.source.startsWith("/")) f.source = process.env.DB_IMAGE_ROOT + f.source; if ( f.use === "download" && - !f.source.startsWith("https://") && - !f.source.startsWith("http://") + !f.source.startsWith("https://") && + !f.source.startsWith("http://") ) f.source = `http://${f.source}`; return f; }); - case "all": - default: - return this.service.getAll(id).then((addon: AddonAll) => { - addon.files = addon.files.map((f) => { - if ((f.use === "header" || f.use === "screenshot") && f.source.startsWith("/")) - f.source = process.env.DB_IMAGE_ROOT + f.source; - - if ( - f.use === "download" && - !f.source.startsWith("https://") && - !f.source.startsWith("http://") - ) - f.source = `http://${f.source}`; - - return f; - }); - - return addon; - }); + return addon; + }); } } @@ -175,7 +175,7 @@ export class AddonController extends Controller { @Get("{id_or_slug}/{property}") public async getAddonPropertyById( @Path() id_or_slug: string, - property: AddonProperty, + property: AddonProperty, ): Promise { return this.service .getAddonFromSlugOrId(id_or_slug) diff --git a/src/v2/interfaces/paths.ts b/src/v2/interfaces/paths.ts index ba2f3d6..a98087c 100644 --- a/src/v2/interfaces/paths.ts +++ b/src/v2/interfaces/paths.ts @@ -24,6 +24,7 @@ export interface PathRepository { getPathUseById(use_id: string): Promise; getPathsByUseIdsAndVersion(use_ids: string[], version: string): Promise; createPath(path: InputPath): Promise; + createPathBulk(paths: InputPath[]): Promise; updatePath(path_id: string, path: Path): Promise; modifyVersion(old_version: string, new_version: string): void | PromiseLike; removePathById(path_id: string): Promise; diff --git a/src/v2/interfaces/uses.ts b/src/v2/interfaces/uses.ts index f8b061e..61cddf6 100644 --- a/src/v2/interfaces/uses.ts +++ b/src/v2/interfaces/uses.ts @@ -30,6 +30,7 @@ export interface UseRepository { getUseByIdOrName(id_or_name: string): Promise; deleteUse(id: string): Promise; set(use: Use): Promise; + setMultiple(uses: Use[]): Promise; removeUseById(use_id: string): Promise; removeUsesByBulk(use_ids: string[]): Promise; } diff --git a/src/v2/repository/firestorm/path.repository.ts b/src/v2/repository/firestorm/path.repository.ts index 54b9923..d315f10 100644 --- a/src/v2/repository/firestorm/path.repository.ts +++ b/src/v2/repository/firestorm/path.repository.ts @@ -29,7 +29,11 @@ export default class PathFirestormRepository implements PathRepository { createPath(path: InputPath): Promise { // breaks without structuredClone, not sure why - return paths.add(structuredClone(path)).then((id) => paths.get(id)); + return paths.add(structuredClone(path)).then((id) => ({ ...structuredClone(path), id }) ); + } + + createPathBulk(pathArray: InputPath[]): Promise { + return paths.addBulk(pathArray).then((ids) => paths.searchKeys(ids)) } removePathById(path_id: string): Promise { diff --git a/src/v2/repository/firestorm/use.repository.ts b/src/v2/repository/firestorm/use.repository.ts index a8fc376..4c93388 100644 --- a/src/v2/repository/firestorm/use.repository.ts +++ b/src/v2/repository/firestorm/use.repository.ts @@ -55,7 +55,12 @@ export default class UseFirestormRepository implements UseRepository { set(use: Use): Promise { // breaks without structuredClone, not sure why - return uses.set(use.id, structuredClone(use)).then((id) => uses.get(id)); + return uses.set(use.id, structuredClone(use)).then(() => uses.get(use.id)); + } + + setMultiple(useArray: Use[]): Promise { + const use_ids = useArray.map(u => u.id); + return uses.setBulk(use_ids, useArray).then(() => uses.searchKeys(use_ids)); } removeUseById(use_id: string): Promise { diff --git a/src/v2/service/path.service.ts b/src/v2/service/path.service.ts index 7644c74..b8b524c 100644 --- a/src/v2/service/path.service.ts +++ b/src/v2/service/path.service.ts @@ -1,6 +1,6 @@ import { BadRequestError } from "../tools/ApiError"; import UseService from "./use.service"; -import { InputPath, Path, PathNewVersionParam, Paths } from "../interfaces"; +import { InputPath, Path, PathNewVersionParam, PathRepository, Paths } from "../interfaces"; import PathFirestormRepository from "../repository/firestorm/path.repository"; import TextureService from "./texture.service"; import { settings } from "../firestorm"; @@ -18,7 +18,7 @@ export default class PathService { else this.useService = new UseService(this); } - private readonly repository = new PathFirestormRepository(); + private readonly repository: PathRepository = new PathFirestormRepository(); getRaw(): Promise> { return this.repository.getRaw(); @@ -35,6 +35,10 @@ export default class PathService { .then(() => this.repository.createPath(path)); } + async createMultiplePaths(paths: InputPath[]): Promise { + return this.repository.createPathBulk(paths); + } + getPathById(id: string): Promise { return this.repository.getPathById(id); } diff --git a/src/v2/service/texture.service.ts b/src/v2/service/texture.service.ts index 46d718a..aadb3b0 100644 --- a/src/v2/service/texture.service.ts +++ b/src/v2/service/texture.service.ts @@ -1,4 +1,4 @@ -import { Contributions, Paths, Texture, Textures, Uses } from "../interfaces"; +import { Contributions, InputPath, Paths, Texture, Textures, Use, Uses } from "../interfaces"; import { Edition, EntireTextureToCreate, @@ -97,32 +97,29 @@ export default class TextureService { const texture_id = created_texture.id; // create uses - const uses_created = await Promise.all( - input.uses.map(async (u, ui) => { - const use_id = String(texture_id) + String.fromCharCode("a".charCodeAt(0) + ui); - return this.useService.createUse({ - name: u.name, - edition: u.edition, - texture: Number.parseInt(texture_id, 10), - id: use_id, - }); - }), - ); + const [use_ids, full_uses_to_create]: [string[], Use[]] = input.uses.reduce((acc,u,ui) => { + const use_id = String(texture_id) + String.fromCharCode("a".charCodeAt(0) + ui); + const use = { + name: u.name, + edition: u.edition, + texture: Number.parseInt(texture_id, 10), + id: use_id, + } + acc[0].push(use_id) + acc[1].push(use) + return acc + }, [[],[]]); + await this.useService.createMultipleUses(full_uses_to_create); // create paths - await Promise.all( - uses_created.map((u, ui) => { - const use_id_created = u.id; - return Promise.all( - input.uses[ui].paths.map((p) => - this.pathService.createPath({ - ...p, - use: use_id_created, - }), - ), - ); - }), - ); + const paths_to_add = input.uses.reduce((acc, u, ui) => { + const paths: InputPath[] = u.paths.map(p => ({ + ...p, + use: use_ids[ui] + })) + return [ ...acc, ...paths ] + }, [] as InputPath[]) + await this.pathService.createMultiplePaths(paths_to_add); return created_texture; } diff --git a/src/v2/service/use.service.ts b/src/v2/service/use.service.ts index 272970f..1ac85c1 100644 --- a/src/v2/service/use.service.ts +++ b/src/v2/service/use.service.ts @@ -81,4 +81,13 @@ export default class UseService { }); }); } + + createMultipleUses(uses: Use[]): Promise { + return Promise.all(uses.map(u => new Promise((resolve, reject) => { + this.getUseByIdOrNameAndCatch(u.id) + .then(() => reject()) + .catch(() => resolve(undefined)) + }))) + .then(() => this.useRepo.setMultiple(uses)) + } }