@zthun/romulator-api 1.18.2 → 1.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.cjs CHANGED
@@ -1444,7 +1444,7 @@ ZRomulatorSystemsModule = _ts_decorate$1([
1444
1444
  })
1445
1445
  ], ZRomulatorSystemsModule);
1446
1446
 
1447
- /* istanbul ignore file -- @preserve */ function _ts_decorate(decorators, target, key, desc) {
1447
+ function _ts_decorate(decorators, target, key, desc) {
1448
1448
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1449
1449
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1450
1450
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
package/dist/main.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.cjs","sources":["../src/config/config-update.mts","../src/dir/dir.ts","../src/config/config-known.mts","../src/config/configs-service.mts","../src/config/configs-controller.mts","../src/config/configs-module.mts","../src/files/files-repository.mts","../src/files/files-systems-repository.mts","../src/files/files-games-repository.mts","../src/files/files-module.mts","../src/games/games-service.mts","../src/games/games-controller.mts","../src/games/games-module.mts","../src/media/media-generator.mts","../src/media/media-service.mts","../src/media/media-controller.mts","../src/media/media-module.mts","../src/systems/systems-service.mts","../src/systems/systems-controller.mts","../src/systems/systems-module.mts","../src/app/app-module.mts","../src/main.mts"],"sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsDefined, IsNotEmptyObject, IsObject } from \"class-validator\";\n\nexport class ZRomulatorConfigUpdateDto<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n @ApiProperty({ type: \"object\", properties: {} })\n @IsDefined({ message: \"The contents of the config is required\" })\n @IsObject({ message: \"The contents of the config must be an object \" })\n @IsNotEmptyObject()\n contents: T;\n}\n","import { homedir } from \"node:os\";\nimport { resolve } from \"node:path\";\n\nexport abstract class ZDir {\n public static application() {\n return resolve(homedir(), \".zthunworks\", \"romulator\");\n }\n\n public static configs() {\n return resolve(ZDir.application(), \"configs\");\n }\n}\n","import {\n ZRomulatorConfigBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { resolve } from \"node:path\";\nimport { ZDir } from \"../dir/dir.js\";\n\nexport abstract class ZRomulatorConfigKnown {\n public static all() {\n return [ZRomulatorConfigKnown.games()];\n }\n\n private static create(id: ZRomulatorConfigId) {\n const file = resolve(ZDir.configs(), `${id}.json`);\n return new ZRomulatorConfigBuilder().id(id).file(file);\n }\n\n public static games() {\n return ZRomulatorConfigKnown.create(ZRomulatorConfigId.Games)\n .name(\"Game Settings\")\n .description(\"Modify where your games are stored and related settings\")\n .avatar(\"gamepad\")\n .metadata(ZRomulatorConfigGamesMetadata.all())\n .build();\n }\n}\n","import {\n Inject,\n Injectable,\n InternalServerErrorException,\n NotFoundException,\n} from \"@nestjs/common\";\nimport { createError, firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigBuilder } from \"@zthun/romulator-client\";\nimport type { IZRestfulGet, IZRestfulUpdate } from \"@zthun/webigail-rest\";\nimport { find } from \"lodash-es\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { ZRomulatorConfigKnown } from \"./config-known.mjs\";\n\nexport const ZRomulatorConfigsToken = Symbol(\"configs\");\n\nexport interface IZRomulatorConfigsService\n extends IZRestfulUpdate<IZRomulatorConfig>,\n IZRestfulGet<IZRomulatorConfig> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>>;\n}\n\n@Injectable()\nexport class ZRomulatorConfigsService implements IZRomulatorConfigsService {\n private _logger: IZLogger;\n\n public constructor(@Inject(ZLoggerToken) _logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZRomulatorConfigsService\", _logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving configs page, ${page}, with size, ${size}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const configs = ZRomulatorConfigKnown.all();\n const options = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic<IZRomulatorConfig>(configs, options);\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n msg = `Responding with ${data.length} configs out of ${count} total`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return new ZPageBuilder<IZRomulatorConfig>()\n .data(data)\n .count(count)\n .build();\n }\n\n public async get<T>(\n id: ZRomulatorConfigId,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this._find(id);\n let msg = `Attempting to read the file contents for config, ${id}.`;\n let contents: any = {};\n\n try {\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const buffer = await readFile(config.file);\n const json = buffer.toString(\"utf-8\");\n contents = JSON.parse(json);\n msg = `Finished reading config contents (${buffer.byteLength} bytes)`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n } catch (e) {\n msg = createError(e).message;\n this._logger.log(new ZLogEntryBuilder().warning().message(msg).build());\n }\n\n const result = new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(contents)\n .build();\n\n return Promise.resolve(result as Required<IZRomulatorConfig<T>>);\n }\n\n public async update<T>(\n id: ZRomulatorConfigId,\n record: Pick<IZRomulatorConfig, \"contents\">,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this.get<T>(id);\n\n let msg = `Updating config file, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const next = { ...config.contents, ...record.contents };\n const json = JSON.stringify(next);\n\n try {\n await mkdir(dirname(config.file), { recursive: true });\n await writeFile(config.file, json);\n return new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(next)\n .build() as Required<IZRomulatorConfig<T>>;\n } catch (e) {\n const error = createError(e);\n msg = `Unable to write to, ${config.file}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n msg = error.message;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new InternalServerErrorException(error));\n }\n }\n\n private async _find(id: ZRomulatorConfigId): Promise<IZRomulatorConfig> {\n let msg = `Attempting to retrieve config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const configs = ZRomulatorConfigKnown.all();\n const config = find(configs, (c) => c.id === id);\n\n if (config == null) {\n msg = `Could not find config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new NotFoundException(msg));\n }\n\n msg = `Config, ${id}, found`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return config;\n }\n}\n","import {\n Body,\n Controller,\n Get,\n Inject,\n Param,\n Patch,\n Query,\n UsePipes,\n ValidationPipe,\n} from \"@nestjs/common\";\nimport { ApiBody, ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigUpdateDto } from \"./config-update.mjs\";\nimport type { IZRomulatorConfigsService } from \"./configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"./configs-service.mjs\";\n\n@Controller(\"configs\")\nexport class ZRomulatorConfigsController {\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n ) {}\n\n @Get()\n public async list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorConfig>> {\n const request = new ZDataRequestBuilder().query(query).build();\n return this._configs.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @ApiBody({\n type: ZRomulatorConfigUpdateDto,\n })\n @Patch(\":identification\")\n @UsePipes(\n new ValidationPipe({\n transform: true,\n whitelist: true,\n skipMissingProperties: false,\n skipNullProperties: false,\n skipUndefinedProperties: false,\n }),\n )\n public async update(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n @Body() payload: ZRomulatorConfigUpdateDto,\n ): Promise<IZRomulatorConfig> {\n return this._configs.update(identification, payload);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n ): Promise<IZRomulatorConfig> {\n return await this._configs.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsController } from \"./configs-controller.mjs\";\nimport {\n ZRomulatorConfigsService,\n ZRomulatorConfigsToken,\n} from \"./configs-service.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZLoggerModule],\n controllers: [ZRomulatorConfigsController],\n providers: [\n { provide: ZRomulatorConfigsToken, useClass: ZRomulatorConfigsService },\n ],\n exports: [ZRomulatorConfigsToken],\n})\nexport class ZRomulatorConfigsModule {}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport type {\n IZFileRepository,\n IZFileSystemNode,\n IZFileSystemService,\n} from \"@zthun/crumbtrail-fs\";\nimport {\n ZFileRepository,\n ZStreamFile,\n ZStreamFolder,\n} from \"@zthun/crumbtrail-fs\";\nimport { ZFileSystemToken } from \"@zthun/crumbtrail-nest\";\nimport type { ZOptional } from \"@zthun/helpful-fn\";\nimport { createError, detokenize, firstDefined, mib } from \"@zthun/helpful-fn\";\nimport {\n ZDataRequestBuilder,\n ZFilterBinaryBuilder,\n ZFilterCollectionBuilder,\n ZFilterLogicBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport {\n ZRomulatorConfigGamesBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { flatten } from \"lodash-es\";\nimport { resolve } from \"node:path\";\nimport { env } from \"node:process\";\nimport type { IZRomulatorConfigsService } from \"../config/configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"../config/configs-service.mjs\";\n\nexport const ZRomulatorFilesRepositoryToken = Symbol(\"files-repository\");\n\n/**\n * Represents the repository that you can use to\n * scan the games folder for media, info, games, and systems.\n */\nexport interface IZRomulatorFilesRepository {\n /**\n * The absolute path to the configured games\n * folder.\n *\n * @returns\n * The absolute path to the games folder.\n */\n gamesFolder(): Promise<string>;\n\n /**\n * The path to the media folder.\n *\n * @returns\n * The path to the .media folder inside the\n * games folder.\n */\n mediaFolder(): Promise<string>;\n\n /**\n * The path to the info folder.\n *\n * @returns\n * The path to the .info folder inside the\n * games folder.\n */\n infoFolder(): Promise<string>;\n\n /**\n * Retrieves all media found in the games .media folder.\n *\n * @returns\n * A list of all media found in the game media folder.\n */\n media(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all systems found in the games folder.\n *\n * A system is a root folder that is a slug of a supported\n * system.\n *\n * @returns\n * A list of all system folders found in the games folder.\n */\n systems(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all games for the given systems list.\n *\n * @param systems -\n * The list of systems to query games by.\n *\n * @returns\n * A list of file system nodes that represent a game\n * in the system directory.\n */\n games(systems: IZRomulatorSystem[]): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves the file that represents the systems info or games info\n * for a given system.\n *\n * @param id -\n * Which info item you want to receive - the root system information\n * or the information for a given game list for an individual system.\n *\n * @returns\n * The node that represents the info json, or null if no such file\n * exists.\n */\n info(id: \"systems\" | ZRomulatorSystemId): Promise<IZFileSystemNode | null>;\n\n /**\n * Reads a file and returns the json representation.\n *\n * @param node -\n * The node to read. If this is falsy, then null is returned.\n *\n * @returns\n * The file contents as json, or null if the contents cannot be read.\n */\n json(node: ZOptional<IZFileSystemNode>): Promise<unknown>;\n\n /**\n * Initializes the file repository.\n */\n init(): Promise<any>;\n\n /**\n * Cleans up internal resources.\n */\n dispose(): Promise<void>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesRepository implements IZRomulatorFilesRepository {\n private static readonly MediaFolderName = \".media\";\n private static readonly InfoFolderName = \".info\";\n\n private _logger: IZLogger;\n private _repository: ZFileRepository = new ZFileRepository();\n private _folderStream = new ZStreamFolder();\n private _fileStream = new ZStreamFile({\n cache: {\n fileSize: BigInt(mib(1)),\n maxFiles: 250,\n },\n });\n\n private _globs: string[];\n private _systems: string[];\n\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n @Inject(ZFileSystemToken)\n private readonly _fileSystem: IZFileSystemService,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n const slugs = Object.values(ZRomulatorSystemId);\n this._globs = [\".media/**\", \".info/**\", ...slugs.map((s) => `${s}/*.*`)];\n this._systems = Object.values(ZRomulatorSystemId);\n this._logger = new ZLoggerContext(\"ZRomulatorFilesRepository\", logger);\n }\n\n public async gamesFolder() {\n const config = await this._configs.get(ZRomulatorConfigId.Games);\n const { gamesFolder } = new ZRomulatorConfigGamesBuilder()\n .copy(config.contents)\n .build();\n const { fallback } = ZRomulatorConfigGamesMetadata.gamesFolder();\n const _gamesFolder = firstDefined(fallback.gamesFolder, gamesFolder);\n return detokenize(_gamesFolder, env);\n }\n\n public async mediaFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.MediaFolderName);\n }\n\n public async infoFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.InfoFolderName);\n }\n\n public async dispose() {\n await this._repository.reset();\n }\n\n public async init(): Promise<IZFileRepository> {\n const path = await this.gamesFolder();\n\n if (this._repository.path !== path) {\n await this._folderStream.write(await this.mediaFolder());\n await this._folderStream.write(await this.infoFolder());\n await this._repository.initialize(path, this._globs);\n }\n\n return this._repository;\n }\n\n public async media() {\n const repository = await this.init();\n const folder = `${await this.mediaFolder()}/`;\n const request = new ZDataRequestBuilder()\n .filter(\n new ZFilterBinaryBuilder()\n .subject(\"path\")\n .startsWith()\n .value(folder)\n .build(),\n )\n .sort(new ZSortBuilder().ascending(\"path\").build())\n .build();\n\n return repository.retrieve(request);\n }\n\n public async info(id?: \"systems\" | ZRomulatorSystemId) {\n // The info json files are json files that contain arrays of games grouped by systems,\n // or systems.json which describes system information.\n const folder = await this.infoFolder();\n const path = resolve(folder, `${id}.json`);\n\n return this._repository.get(path);\n }\n\n public async json(node: IZFileSystemNode): Promise<unknown> {\n if (node == null) {\n return null;\n }\n\n try {\n const contents = await this._fileStream.read(node.path);\n return JSON.parse(contents.toString());\n } catch (e) {\n const err = createError(e);\n const msg = `Unable to read ${node.path}: ${err.message}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return null;\n }\n }\n\n public async systems() {\n // Systems use directories. There's a maximum limit of about 200 systems.\n // Since we don't actually need to read any metadata or scan through thousands\n // of unknown folders, we can use the supported system ids to just grab the\n // systems that we need. Since the file repository does a stat anyway, we can just\n // grab the systems from the file system and it should be fast enough. These are all\n // folders, so we don't even need the stats for them and we can assume folders.\n const games = await this.gamesFolder();\n const folders = this._systems.map((s) => `${s}/`);\n return await this._fileSystem.search(folders, {\n cwd: games,\n stat: false,\n });\n }\n\n public async games(systems: IZRomulatorSystem[]) {\n const repository = await this.init();\n const folder = await this.gamesFolder();\n\n const queries = systems.map((s) => {\n const dir = `${folder}/${s.id}`;\n\n const byExtension = new ZFilterCollectionBuilder()\n .subject(\"extension\")\n .in()\n .values(s.extensions)\n .build();\n const inPath = new ZFilterBinaryBuilder()\n .subject(\"parent\")\n .equal()\n .value(dir)\n .build();\n const filter = new ZFilterLogicBuilder()\n .and()\n .clause(inPath)\n .clause(byExtension)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).build();\n return repository.retrieve(request);\n });\n\n const results = await Promise.all(queries);\n\n return flatten(results);\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type {\n IZRomulatorSystem,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorSystemBuilder } from \"@zthun/romulator-client\";\nimport { castArray } from \"lodash-es\";\nimport { basename } from \"node:path\";\nimport {\n ZRomulatorFilesRepositoryToken,\n type IZRomulatorFilesRepository,\n} from \"./files-repository.mjs\";\n\nexport const ZRomulatorFilesSystemsRepositoryToken = Symbol(\n \"files-systems-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of system.json.\n */\nexport interface IZRomulatorFilesSystemsRepository {\n /**\n * Reads all system entries in the systems.json file and combines\n * them with the existing system list in the games directory\n *\n * @returns\n * A list of all the systems that are in the games\n * directory decorated with the content data in systems.json\n * in the .info directory.\n */\n systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesSystemsRepository\n implements IZRomulatorFilesSystemsRepository\n{\n /**\n * Initializes a new instance of this object.\n */\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>> {\n const info = await this._filesRepository.info(\"systems\");\n const json = await this._filesRepository.json(info);\n const candidates = castArray(firstDefined([], json));\n const folders = await this._filesRepository.systems();\n\n function hasId(candidate: any): candidate is { id: string } {\n return Object.prototype.hasOwnProperty.call(candidate, \"id\");\n }\n\n const entries: [ZRomulatorSystemId, unknown][] = candidates\n .filter((c) => hasId(c))\n .filter((c) => isSystemId(c.id))\n .map((c) => [c.id as ZRomulatorSystemId, c as unknown]);\n\n const lookup = new Map(entries);\n\n const systems = folders\n .map((folder) => folder.path)\n .map((path) => basename(path))\n .filter((slug) => isSystemId(slug))\n .map((slug) =>\n new ZRomulatorSystemBuilder().parse(lookup.get(slug)).id(slug).build(),\n );\n\n return new Map(systems.map((s) => [s.id, s]));\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { ZFileSystemNodeBuilder } from \"@zthun/crumbtrail-fs\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorGameBuilder } from \"@zthun/romulator-client\";\nimport { castArray, get, kebabCase, uniq } from \"lodash-es\";\nimport { resolve } from \"path\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"./files-repository.mjs\";\nimport type { IZRomulatorFilesSystemsRepository } from \"./files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"./files-systems-repository.mjs\";\n\nexport const ZRomulatorFilesGamesRepositoryToken = Symbol(\n \"files-games-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of a game list json file.\n */\nexport interface IZRomulatorFilesGamesRepository {\n /**\n * Reads all of the games in the games directory.\n *\n * Game targets are determined by the extensions in system.json.\n *\n * @returns\n * A list of all the games that are in the games\n * directory decorated with the content data in the matching\n * system json file in the .info directory.\n */\n games(): Promise<Map<string, IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesGamesRepository\n implements IZRomulatorFilesGamesRepository\n{\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async games(): Promise<Map<string, IZRomulatorGame>> {\n function hasPath(entry: unknown): entry is { path: string } {\n return typeof get(entry, \"path\") === \"string\";\n }\n\n const gamesFolder = await this._filesRepository.gamesFolder();\n const games: IZRomulatorGame[] = [];\n const systemLookup = await this._systemsRepository.systems();\n const systems = Array.from(systemLookup.values());\n const gameFiles = await this._filesRepository.games(systems);\n const systemsInUse = uniq(gameFiles.map((g) => g.parent))\n .map((dir) => new ZFileSystemNodeBuilder().path(dir).folder().build())\n .map((node) => node.title)\n .filter((title) => isSystemId(title));\n\n const gameInfo = new Map<string, unknown>();\n\n for await (const system of systemsInUse) {\n const info = await this._filesRepository.info(system);\n const json = await this._filesRepository.json(info);\n const gameList = castArray(json).filter((e) => hasPath(e));\n gameList.forEach((entry) => {\n gameInfo.set(resolve(gamesFolder, system, entry.path), entry);\n });\n }\n\n // Variable, gameInfo, now has all of the information data that we need.\n for (const file of gameFiles) {\n const { title, path } = file;\n const { title: systemId } = new ZFileSystemNodeBuilder()\n .path(file.parent)\n .folder()\n .build();\n const id = `${kebabCase(systemId)}-${kebabCase(title)}`;\n const info = gameInfo.get(path);\n\n const game = new ZRomulatorGameBuilder()\n .id(id)\n .system(systemId as ZRomulatorSystemId)\n .file(path)\n .parse(info)\n .build();\n\n games.push(game);\n }\n\n return new Map(games.map((g) => [g.id, g]));\n }\n}\n","import { Inject, Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport {\n ZRomulatorFilesGamesRepository,\n ZRomulatorFilesGamesRepositoryToken,\n} from \"./files-games-repository.mjs\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesRepository,\n ZRomulatorFilesRepositoryToken,\n} from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepository,\n ZRomulatorFilesSystemsRepositoryToken,\n} from \"./files-systems-repository.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZRomulatorConfigsModule, ZLoggerModule],\n providers: [\n {\n provide: ZRomulatorFilesRepositoryToken,\n useClass: ZRomulatorFilesRepository,\n },\n {\n provide: ZRomulatorFilesSystemsRepositoryToken,\n useClass: ZRomulatorFilesSystemsRepository,\n },\n {\n provide: ZRomulatorFilesGamesRepositoryToken,\n useClass: ZRomulatorFilesGamesRepository,\n },\n ],\n exports: [\n ZRomulatorFilesRepositoryToken,\n ZRomulatorFilesSystemsRepositoryToken,\n ZRomulatorFilesGamesRepositoryToken,\n ],\n})\nexport class ZRomulatorFilesModule {\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _files: IZRomulatorFilesRepository,\n ) {}\n\n public async onModuleInit() {\n await this._files.init();\n }\n\n public async onModuleDestroy() {\n await this._files.dispose();\n }\n}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulGet } from \"@zthun/webigail-rest\";\nimport {\n ZRomulatorFilesGamesRepositoryToken,\n type IZRomulatorFilesGamesRepository,\n} from \"../files/files-games-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepositoryToken,\n type IZRomulatorFilesSystemsRepository,\n} from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorGamesToken = Symbol(\"romulator-games-service\");\n\nexport interface IZRomulatorGamesService extends IZRestfulGet<IZRomulatorGame> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorGamesService implements IZRomulatorGamesService {\n private readonly _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesGamesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesGamesRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorGamesService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>> {\n const msg = `Searching for games`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systems = await this._systemsRepository.systems();\n const games = await this._filesRepository.games();\n\n const match = (data: IZRomulatorGame, filter: string): boolean => {\n const needle = filter?.trim().toLowerCase();\n const { name = \"\", system = \"\" } = data;\n const systemId = system as ZRomulatorSystemId;\n const systemName = firstTruthy(\"\", systems.get(systemId)?.name);\n\n if (!needle?.length) {\n return true;\n }\n\n return [name, system, systemName]\n .filter((s) => s.length)\n .some((k) => k.toLowerCase().includes(needle));\n };\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorGame>()\n .search({ match })\n .build();\n const source = new ZDataSourceStatic(Array.from(games.values()), options);\n\n const $sort = new ZSortBuilder()\n .sorts(firstDefined([], req.sort))\n .ascending(\"system\")\n .ascending(\"name\")\n .build();\n const $request = new ZDataRequestBuilder().copy(req).sort($sort).build();\n\n const data = await source.retrieve($request);\n const count = await source.count($request);\n\n return new ZPageBuilder().count(count).data(data).build();\n }\n\n public async get(id: string): Promise<IZRomulatorGame> {\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: games } = await this.list(request);\n const [game] = games;\n\n if (game == null) {\n const message = `Game, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return game;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorGame } from \"@zthun/romulator-client\";\nimport type { IZRomulatorGamesService } from \"./games-service.mjs\";\nimport { ZRomulatorGamesToken } from \"./games-service.mjs\";\n\n@Controller(\"games\")\nexport class ZRomulatorGamesController {\n public constructor(\n @Inject(ZRomulatorGamesToken)\n private readonly _games: IZRomulatorGamesService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorGame>> {\n return this._games.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._games.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorGamesController } from \"./games-controller.mjs\";\nimport {\n ZRomulatorGamesService,\n ZRomulatorGamesToken,\n} from \"./games-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorGamesController],\n providers: [\n {\n provide: ZRomulatorGamesToken,\n useClass: ZRomulatorGamesService,\n },\n ],\n})\nexport class ZRomulatorGamesModule {}\n","import { Injectable } from \"@nestjs/common\";\nimport { html } from \"@zthun/helpful-fn\";\n\n/**\n * The injection token for the media generator.\n */\nexport const ZRomulatorMediaGeneratorToken = Symbol(\"media-generator\");\n\n/**\n * A generator that generates in memory media for systems and\n * games that have their media missing.\n */\nexport interface IZRomulatorMediaGenerator {\n /**\n * Generates a wheel image with a given name.\n *\n * A wheel is 373x187 pixels. It'll have a transparent background\n * with the name in uppercase It will display the name\n * in the middle of the wheel image. It assumes it will live on a\n * dark background so the name will be white.\n *\n * @param name -\n * The name to place in the middle of the wheel image.\n *\n * @returns\n * A buffer with the generated wheel.\n */\n generate(name: string): Promise<Buffer>;\n}\n\n/**\n * An implementation of the ZRomulatorMediaGenerator.\n */\n@Injectable()\nexport class ZRomulatorMediaGenerator implements IZRomulatorMediaGenerator {\n public generate(name: string): Promise<Buffer> {\n const width = 373;\n const height = 187;\n const fallbackName = name?.trim().length ? name.trim() : \"?\";\n const uppercaseName = fallbackName.toUpperCase();\n const escapedName = this.escapeSvgText(uppercaseName);\n\n const svg = html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"${width}\"\n height=\"${height}\"\n viewBox=\"0 0 ${width} ${height}\"\n >\n <text\n x=\"50%\"\n y=\"50%\"\n fill=\"#fff\"\n font-size=\"48\"\n text-anchor=\"middle\"\n textLength=\"${width}\"\n lengthAdjust=\"spacingAndGlyphs\"\n >\n ${escapedName}\n </text>\n </svg>\n `;\n\n return Promise.resolve(Buffer.from(svg));\n }\n\n private escapeSvgText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n }\n}\n","import {\n ForbiddenException,\n Inject,\n Injectable,\n NotAcceptableException,\n NotFoundException,\n StreamableFile,\n} from \"@nestjs/common\";\nimport { createError, firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n type IZDataRequest,\n type IZPage,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport {\n ZRomulatorMediaBuilder,\n type IZRomulatorMedia,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulDelete, IZRestfulGet } from \"@zthun/webigail-rest\";\nimport { ZMimeTypeImage } from \"@zthun/webigail-url\";\nimport { findIndex } from \"lodash-es\";\nimport { lookup } from \"mime-types\";\nimport { createReadStream } from \"node:fs\";\nimport { unlink } from \"node:fs/promises\";\nimport { Readable } from \"node:stream\";\nimport type { IZRomulatorFilesRepository } from \"../files/files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"../files/files-repository.mjs\";\nimport type { IZRomulatorMediaGenerator } from \"./media-generator.mjs\";\nimport { ZRomulatorMediaGeneratorToken } from \"./media-generator.mjs\";\n\nexport const ZRomulatorMediaToken = Symbol(\"romulator-media-service\");\n\nexport interface IZRomulatorMediaService\n extends IZRestfulGet<IZRomulatorMedia>,\n IZRestfulDelete {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>>;\n download(id: string, accept: string): Promise<StreamableFile>;\n}\n\n@Injectable()\nexport class ZRomulatorMediaService implements IZRomulatorMediaService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorMediaGeneratorToken)\n private _generator: IZRomulatorMediaGenerator,\n @Inject(ZRomulatorFilesRepositoryToken)\n private _files: IZRomulatorFilesRepository,\n @Inject(ZLoggerToken)\n logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorMediaService\", logger);\n }\n\n private async findAllMedia(): Promise<IZRomulatorMedia[]> {\n const files = await this._files.media();\n\n return files\n .map((f) => new ZRomulatorMediaBuilder().from(f.path).build())\n .filter((media) => !!media.id);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>> {\n let msg = `Querying media`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const time = new Date();\n const mediaList = await this.findAllMedia();\n const span = new Date().getTime() - time.getTime();\n msg = `Found ${mediaList.length} media files. Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorMedia>()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic(mediaList, options);\n const page = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder<IZRomulatorMedia>().data(page).count(count).build();\n }\n\n private async query(id: string): Promise<IZRomulatorMedia | null> {\n const mediaList = await this.findAllMedia();\n const index = findIndex(mediaList, (m) => m.id === id);\n\n return firstDefined(null, mediaList[index]);\n }\n\n public async get(id: string): Promise<IZRomulatorMedia> {\n const time = new Date();\n let log = `Searching for media with id ${id}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n\n const span = new Date().getTime() - time.getTime();\n\n if (media == null) {\n const msg = `Could not find any media with id, ${id}.`;\n log = `${msg} Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n throw new NotFoundException(msg);\n }\n\n log = `Found media, ${media.url} after ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n return media;\n }\n\n public async download(id: string, accept: string): Promise<StreamableFile> {\n const log = `Download request received for ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n const url = firstDefined(\"\", media?.url);\n const fileName = firstDefined(\"\", media?.fileName);\n const mime: string = firstTruthy(\n ZMimeTypeImage.SVG,\n lookup(fileName),\n ) as string;\n\n const accepts = accept.split(\",\").map((h) => h.split(\";\")[0].trim());\n\n const acceptable = accepts.some((a) => {\n if (a === \"*/*\") {\n return true;\n }\n if (a.endsWith(\"/*\")) {\n return mime.startsWith(a.slice(0, -1));\n }\n return a === mime;\n });\n\n if (!acceptable) {\n const msg =\n `The media requested is of type ${mime}. ` +\n `The request only accepts ${accept}.`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n throw new NotAcceptableException(msg);\n }\n\n const generate = async () => {\n // Note that this isn't perfect and is just a fallback to a wheel + marquee for now.\n // When we get to retrieving other media besides wheels, we will generate\n // everything, but for now, this will be fine enough.\n const log = `Media, ${id}, does not exist. Generating one`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n\n const parts = id.split(\"-\");\n parts.pop();\n const name = parts.join(\" \");\n const buffer = await this._generator.generate(name);\n\n return Readable.from(buffer);\n };\n\n const stream = media == null ? await generate() : createReadStream(url);\n\n return new StreamableFile(stream, {\n type: mime,\n disposition: `inline; filename=${fileName}`,\n });\n }\n\n public async delete(id: string): Promise<void> {\n const { url } = await this.get(id);\n const _url = firstDefined(\"\", url);\n\n let log = `Attempting to delete file ${_url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n try {\n await unlink(_url);\n } catch (err) {\n const { message } = createError(err);\n this._logger.log(new ZLogEntryBuilder().error().message(message).build());\n throw new ForbiddenException(message);\n }\n\n log = `Deleted ${url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n }\n}\n","import {\n Controller,\n Delete,\n Get,\n Inject,\n Param,\n Query,\n Req,\n} from \"@nestjs/common\";\nimport { ApiParam, ApiQuery, ApiResponse, ApiTags } from \"@nestjs/swagger\";\nimport {\n ZDataRequestBuilder,\n type IZDataRequestQuery,\n} from \"@zthun/helpful-query\";\nimport { ZHttpCodeClient, ZHttpCodeSuccess } from \"@zthun/webigail-http\";\nimport type { Request } from \"express\";\nimport type { IZRomulatorMediaService } from \"./media-service.mjs\";\nimport { ZRomulatorMediaToken } from \"./media-service.mjs\";\n\n@ApiTags(\"Media\")\n@Controller(\"media\")\nexport class ZRomulatorMediaController {\n public constructor(\n @Inject(ZRomulatorMediaToken)\n private _media: IZRomulatorMediaService,\n ) {}\n\n @ApiQuery({\n name: \"page\",\n required: false,\n type: Number,\n example: 1,\n description: \"Page number (1-based)\",\n })\n @ApiQuery({\n name: \"size\",\n required: false,\n type: Number,\n example: 20,\n description: \"Items per page. Defaults to Infinity\",\n })\n @ApiQuery({\n name: \"search\",\n required: false,\n type: String,\n description: \"Search query\",\n })\n @ApiQuery({\n name: \"sort\",\n required: false,\n type: String,\n description: \"Sort criterion\",\n })\n @ApiQuery({\n name: \"filter\",\n required: false,\n type: String,\n description: \"Filter criterion\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the requested page of media and the total count\",\n })\n @Get()\n public list(@Query() params: IZDataRequestQuery) {\n const request = new ZDataRequestBuilder().query(params).build();\n return this._media.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the media\",\n content: {\n \"*/*\": {},\n \"image/*\": {},\n \"image/png\": {},\n \"image/jpeg\": {},\n \"application/mp4\": {},\n \"application/json\": {},\n },\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotFound,\n description: \"Media not found\",\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotAcceptable,\n description: \"Unsupported Accept header\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: string,\n @Req() req: Request,\n ) {\n const { accept = \"*/*\" } = req.headers;\n\n return accept.includes(\"application/json\")\n ? this._media.get(identification)\n : this._media.download(identification, accept);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @Delete(\":identification\")\n public async delete(@Param(\"identification\") identification: string) {\n await this._media.delete(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorMediaController } from \"./media-controller.mjs\";\nimport {\n ZRomulatorMediaGenerator,\n ZRomulatorMediaGeneratorToken,\n} from \"./media-generator.mjs\";\nimport {\n ZRomulatorMediaService,\n ZRomulatorMediaToken,\n} from \"./media-service.mjs\";\n\n@Module({\n imports: [ZLoggerModule, ZRomulatorFilesModule],\n controllers: [ZRomulatorMediaController],\n providers: [\n {\n provide: ZRomulatorMediaGeneratorToken,\n useClass: ZRomulatorMediaGenerator,\n },\n {\n provide: ZRomulatorMediaToken,\n useClass: ZRomulatorMediaService,\n },\n ],\n})\nexport class ZRomulatorMediaModule {}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport { isSystemId } from \"@zthun/romulator-client\";\nimport type { IZRomulatorFilesSystemsRepository } from \"../files/files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorSystemsToken = Symbol(\"romulator-systems-service\");\n\nexport interface IZRomulatorSystemsService {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>>;\n get(id: string): Promise<IZRomulatorSystem>;\n}\n\n@Injectable()\nexport class ZRomulatorSystemsService implements IZRomulatorSystemsService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorSystemsService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving systems page, ${page}, with size, ${size}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systemMap = await this._systemsRepository.systems();\n const systems = Array.from(systemMap.values());\n\n msg = `Found ${systems.length} systems`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const sourceOptions = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields([\"id\", \"name\"]))\n .build();\n\n const source = new ZDataSourceStatic<IZRomulatorSystem>(\n systems,\n sourceOptions,\n );\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder().data(data).count(count).build();\n }\n\n public async get(id: string): Promise<IZRomulatorSystem> {\n // The system path should be the slug itself.\n if (!isSystemId(id)) {\n const message = `The specified system slug, ${id}, is not supported.`;\n throw new NotFoundException(message);\n }\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: systems } = await this.list(request);\n const [system] = systems;\n\n if (system == null) {\n const message = `System with slug, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return system;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport { ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport type { IZRomulatorSystemsService } from \"./systems-service.mjs\";\nimport { ZRomulatorSystemsToken } from \"./systems-service.mjs\";\n\n@Controller(\"systems\")\nexport class ZRomulatorSystemsController {\n public constructor(\n @Inject(ZRomulatorSystemsToken)\n private readonly _systems: IZRomulatorSystemsService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorSystem>> {\n return this._systems.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the system\",\n })\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._systems.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorSystemsController } from \"./systems-controller.mjs\";\nimport {\n ZRomulatorSystemsService,\n ZRomulatorSystemsToken,\n} from \"./systems-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorSystemsController],\n providers: [\n {\n provide: ZRomulatorSystemsToken,\n useClass: ZRomulatorSystemsService,\n },\n ],\n exports: [ZRomulatorSystemsToken],\n})\nexport class ZRomulatorSystemsModule {}\n","/* istanbul ignore file -- @preserve */\nimport { Module } from \"@nestjs/common\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport { ZRomulatorGamesModule } from \"../games/games-module.mjs\";\nimport { ZRomulatorMediaModule } from \"../media/media-module.mjs\";\nimport { ZRomulatorSystemsModule } from \"../systems/systems-module.mjs\";\n\n@Module({\n imports: [\n ZRomulatorSystemsModule,\n ZRomulatorConfigsModule,\n ZRomulatorMediaModule,\n ZRomulatorGamesModule,\n ],\n})\nexport class ZRomulatorModule {}\n","import { NestFactory } from \"@nestjs/core\";\nimport { DocumentBuilder, SwaggerModule } from \"@nestjs/swagger\";\nimport { ZRomulatorModule } from \"./app/app-module.mjs\";\n\nconst PORT = 3000;\n\n(async function () {\n const app = await NestFactory.create(ZRomulatorModule);\n app.setGlobalPrefix(\"api\");\n app.enableCors();\n\n const config = new DocumentBuilder()\n .setTitle(\"Romulator API\")\n .setDescription(\"The Romulator API\")\n .setVersion(\"1\")\n .build();\n\n const document = () => SwaggerModule.createDocument(app, config);\n SwaggerModule.setup(\"api/docs\", app, document);\n\n await app.listen(PORT);\n})();\n"],"names":["ZRomulatorConfigUpdateDto","_define_property","contents","type","properties","message","ZDir","application","resolve","homedir","configs","ZRomulatorConfigKnown","all","games","create","id","file","ZRomulatorConfigBuilder","ZRomulatorConfigId","Games","name","description","avatar","metadata","ZRomulatorConfigGamesMetadata","build","ZRomulatorConfigsToken","Symbol","ZRomulatorConfigsService","list","req","page","firstDefined","size","Infinity","msg","_logger","log","ZLogEntryBuilder","info","options","ZDataSourceStaticOptionsBuilder","search","ZDataSearchFields","source","ZDataSourceStatic","data","retrieve","count","length","ZPageBuilder","get","config","_find","buffer","readFile","json","toString","JSON","parse","byteLength","e","createError","warning","result","copy","Promise","update","record","next","stringify","mkdir","dirname","recursive","writeFile","error","reject","InternalServerErrorException","find","c","NotFoundException","ZLoggerContext","ZRomulatorConfigsController","request","ZDataRequestBuilder","query","_configs","payload","identification","ValidationPipe","transform","whitelist","skipMissingProperties","skipNullProperties","skipUndefinedProperties","ZRomulatorConfigsModule","imports","ZFileSystemModule","ZLoggerModule","controllers","providers","provide","useClass","exports","ZRomulatorFilesRepositoryToken","ZRomulatorFilesRepository","gamesFolder","ZRomulatorConfigGamesBuilder","fallback","_gamesFolder","detokenize","env","mediaFolder","MediaFolderName","infoFolder","InfoFolderName","dispose","_repository","reset","init","path","_folderStream","write","initialize","_globs","media","repository","folder","filter","ZFilterBinaryBuilder","subject","startsWith","value","sort","ZSortBuilder","ascending","node","_fileStream","read","err","systems","folders","_systems","map","s","_fileSystem","cwd","stat","queries","dir","byExtension","ZFilterCollectionBuilder","in","values","extensions","inPath","equal","ZFilterLogicBuilder","and","clause","results","flatten","logger","ZFileRepository","ZStreamFolder","ZStreamFile","cache","fileSize","BigInt","mib","maxFiles","slugs","Object","ZRomulatorSystemId","ZRomulatorFilesSystemsRepositoryToken","ZRomulatorFilesSystemsRepository","_filesRepository","candidates","castArray","hasId","candidate","prototype","hasOwnProperty","call","entries","isSystemId","lookup","Map","basename","slug","ZRomulatorSystemBuilder","ZRomulatorFilesGamesRepositoryToken","ZRomulatorFilesGamesRepository","hasPath","entry","systemLookup","_systemsRepository","Array","from","gameFiles","systemsInUse","uniq","g","parent","ZFileSystemNodeBuilder","title","gameInfo","system","gameList","forEach","set","systemId","kebabCase","game","ZRomulatorGameBuilder","push","ZRomulatorFilesModule","onModuleInit","_files","onModuleDestroy","ZRomulatorGamesToken","ZRomulatorGamesService","match","needle","trim","toLowerCase","systemName","firstTruthy","some","k","includes","$sort","sorts","$request","ZRomulatorGamesController","_games","ZRomulatorGamesModule","ZRomulatorMediaGeneratorToken","ZRomulatorMediaGenerator","generate","width","height","fallbackName","uppercaseName","toUpperCase","escapedName","escapeSvgText","svg","html","Buffer","replace","ZRomulatorMediaToken","ZRomulatorMediaService","findAllMedia","files","f","ZRomulatorMediaBuilder","time","Date","mediaList","span","getTime","index","findIndex","m","url","download","accept","fileName","mime","ZMimeTypeImage","SVG","accepts","split","h","acceptable","a","endsWith","slice","NotAcceptableException","parts","pop","join","_generator","Readable","stream","createReadStream","StreamableFile","disposition","delete","_url","unlink","ForbiddenException","ZRomulatorMediaController","params","_media","headers","required","Number","example","String","status","ZHttpCodeSuccess","OK","content","ZHttpCodeClient","NotFound","NotAcceptable","ZRomulatorMediaModule","ZRomulatorSystemsToken","ZRomulatorSystemsService","systemMap","sourceOptions","ZRomulatorSystemsController","ZRomulatorSystemsModule","ZRomulatorModule","PORT","app","NestFactory","setGlobalPrefix","enableCors","DocumentBuilder","setTitle","setDescription","setVersion","document","SwaggerModule","createDocument","setup","listen"],"mappings":"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"}
1
+ {"version":3,"file":"main.cjs","sources":["../src/config/config-update.mts","../src/dir/dir.ts","../src/config/config-known.mts","../src/config/configs-service.mts","../src/config/configs-controller.mts","../src/config/configs-module.mts","../src/files/files-repository.mts","../src/files/files-systems-repository.mts","../src/files/files-games-repository.mts","../src/files/files-module.mts","../src/games/games-service.mts","../src/games/games-controller.mts","../src/games/games-module.mts","../src/media/media-generator.mts","../src/media/media-service.mts","../src/media/media-controller.mts","../src/media/media-module.mts","../src/systems/systems-service.mts","../src/systems/systems-controller.mts","../src/systems/systems-module.mts","../src/app/app-module.mts","../src/main.mts"],"sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsDefined, IsNotEmptyObject, IsObject } from \"class-validator\";\n\nexport class ZRomulatorConfigUpdateDto<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n @ApiProperty({ type: \"object\", properties: {} })\n @IsDefined({ message: \"The contents of the config is required\" })\n @IsObject({ message: \"The contents of the config must be an object \" })\n @IsNotEmptyObject()\n contents: T;\n}\n","import { homedir } from \"node:os\";\nimport { resolve } from \"node:path\";\n\nexport abstract class ZDir {\n public static application() {\n return resolve(homedir(), \".zthunworks\", \"romulator\");\n }\n\n public static configs() {\n return resolve(ZDir.application(), \"configs\");\n }\n}\n","import {\n ZRomulatorConfigBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { resolve } from \"node:path\";\nimport { ZDir } from \"../dir/dir.js\";\n\nexport abstract class ZRomulatorConfigKnown {\n public static all() {\n return [ZRomulatorConfigKnown.games()];\n }\n\n private static create(id: ZRomulatorConfigId) {\n const file = resolve(ZDir.configs(), `${id}.json`);\n return new ZRomulatorConfigBuilder().id(id).file(file);\n }\n\n public static games() {\n return ZRomulatorConfigKnown.create(ZRomulatorConfigId.Games)\n .name(\"Game Settings\")\n .description(\"Modify where your games are stored and related settings\")\n .avatar(\"gamepad\")\n .metadata(ZRomulatorConfigGamesMetadata.all())\n .build();\n }\n}\n","import {\n Inject,\n Injectable,\n InternalServerErrorException,\n NotFoundException,\n} from \"@nestjs/common\";\nimport { createError, firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigBuilder } from \"@zthun/romulator-client\";\nimport type { IZRestfulGet, IZRestfulUpdate } from \"@zthun/webigail-rest\";\nimport { find } from \"lodash-es\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { ZRomulatorConfigKnown } from \"./config-known.mjs\";\n\nexport const ZRomulatorConfigsToken = Symbol(\"configs\");\n\nexport interface IZRomulatorConfigsService\n extends IZRestfulUpdate<IZRomulatorConfig>, IZRestfulGet<IZRomulatorConfig> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>>;\n}\n\n@Injectable()\nexport class ZRomulatorConfigsService implements IZRomulatorConfigsService {\n private _logger: IZLogger;\n\n public constructor(@Inject(ZLoggerToken) _logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZRomulatorConfigsService\", _logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving configs page, ${page}, with size, ${size}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const configs = ZRomulatorConfigKnown.all();\n const options = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic<IZRomulatorConfig>(configs, options);\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n msg = `Responding with ${data.length} configs out of ${count} total`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return new ZPageBuilder<IZRomulatorConfig>()\n .data(data)\n .count(count)\n .build();\n }\n\n public async get<T>(\n id: ZRomulatorConfigId,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this._find(id);\n let msg = `Attempting to read the file contents for config, ${id}.`;\n let contents: any = {};\n\n try {\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const buffer = await readFile(config.file);\n const json = buffer.toString(\"utf-8\");\n contents = JSON.parse(json);\n msg = `Finished reading config contents (${buffer.byteLength} bytes)`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n } catch (e) {\n msg = createError(e).message;\n this._logger.log(new ZLogEntryBuilder().warning().message(msg).build());\n }\n\n const result = new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(contents)\n .build();\n\n return Promise.resolve(result as Required<IZRomulatorConfig<T>>);\n }\n\n public async update<T>(\n id: ZRomulatorConfigId,\n record: Pick<IZRomulatorConfig, \"contents\">,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this.get<T>(id);\n\n let msg = `Updating config file, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const next = { ...config.contents, ...record.contents };\n const json = JSON.stringify(next);\n\n try {\n await mkdir(dirname(config.file), { recursive: true });\n await writeFile(config.file, json);\n return new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(next)\n .build() as Required<IZRomulatorConfig<T>>;\n } catch (e) {\n const error = createError(e);\n msg = `Unable to write to, ${config.file}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n msg = error.message;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new InternalServerErrorException(error));\n }\n }\n\n private async _find(id: ZRomulatorConfigId): Promise<IZRomulatorConfig> {\n let msg = `Attempting to retrieve config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const configs = ZRomulatorConfigKnown.all();\n const config = find(configs, (c) => c.id === id);\n\n if (config == null) {\n msg = `Could not find config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new NotFoundException(msg));\n }\n\n msg = `Config, ${id}, found`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return config;\n }\n}\n","import {\n Body,\n Controller,\n Get,\n Inject,\n Param,\n Patch,\n Query,\n UsePipes,\n ValidationPipe,\n} from \"@nestjs/common\";\nimport { ApiBody, ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigUpdateDto } from \"./config-update.mjs\";\nimport type { IZRomulatorConfigsService } from \"./configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"./configs-service.mjs\";\n\n@Controller(\"configs\")\nexport class ZRomulatorConfigsController {\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n ) {}\n\n @Get()\n public async list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorConfig>> {\n const request = new ZDataRequestBuilder().query(query).build();\n return this._configs.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @ApiBody({\n type: ZRomulatorConfigUpdateDto,\n })\n @Patch(\":identification\")\n @UsePipes(\n new ValidationPipe({\n transform: true,\n whitelist: true,\n skipMissingProperties: false,\n skipNullProperties: false,\n skipUndefinedProperties: false,\n }),\n )\n public async update(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n @Body() payload: ZRomulatorConfigUpdateDto,\n ): Promise<IZRomulatorConfig> {\n return this._configs.update(identification, payload);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n ): Promise<IZRomulatorConfig> {\n return await this._configs.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsController } from \"./configs-controller.mjs\";\nimport {\n ZRomulatorConfigsService,\n ZRomulatorConfigsToken,\n} from \"./configs-service.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZLoggerModule],\n controllers: [ZRomulatorConfigsController],\n providers: [\n { provide: ZRomulatorConfigsToken, useClass: ZRomulatorConfigsService },\n ],\n exports: [ZRomulatorConfigsToken],\n})\nexport class ZRomulatorConfigsModule {}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport type {\n IZFileRepository,\n IZFileSystemNode,\n IZFileSystemService,\n} from \"@zthun/crumbtrail-fs\";\nimport {\n ZFileRepository,\n ZStreamFile,\n ZStreamFolder,\n} from \"@zthun/crumbtrail-fs\";\nimport { ZFileSystemToken } from \"@zthun/crumbtrail-nest\";\nimport type { ZOptional } from \"@zthun/helpful-fn\";\nimport { createError, detokenize, firstDefined, mib } from \"@zthun/helpful-fn\";\nimport {\n ZDataRequestBuilder,\n ZFilterBinaryBuilder,\n ZFilterCollectionBuilder,\n ZFilterLogicBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport {\n ZRomulatorConfigGamesBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { flatten } from \"lodash-es\";\nimport { resolve } from \"node:path\";\nimport { env } from \"node:process\";\nimport type { IZRomulatorConfigsService } from \"../config/configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"../config/configs-service.mjs\";\n\nexport const ZRomulatorFilesRepositoryToken = Symbol(\"files-repository\");\n\n/**\n * Represents the repository that you can use to\n * scan the games folder for media, info, games, and systems.\n */\nexport interface IZRomulatorFilesRepository {\n /**\n * The absolute path to the configured games\n * folder.\n *\n * @returns\n * The absolute path to the games folder.\n */\n gamesFolder(): Promise<string>;\n\n /**\n * The path to the media folder.\n *\n * @returns\n * The path to the .media folder inside the\n * games folder.\n */\n mediaFolder(): Promise<string>;\n\n /**\n * The path to the info folder.\n *\n * @returns\n * The path to the .info folder inside the\n * games folder.\n */\n infoFolder(): Promise<string>;\n\n /**\n * Retrieves all media found in the games .media folder.\n *\n * @returns\n * A list of all media found in the game media folder.\n */\n media(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all systems found in the games folder.\n *\n * A system is a root folder that is a slug of a supported\n * system.\n *\n * @returns\n * A list of all system folders found in the games folder.\n */\n systems(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all games for the given systems list.\n *\n * @param systems -\n * The list of systems to query games by.\n *\n * @returns\n * A list of file system nodes that represent a game\n * in the system directory.\n */\n games(systems: IZRomulatorSystem[]): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves the file that represents the systems info or games info\n * for a given system.\n *\n * @param id -\n * Which info item you want to receive - the root system information\n * or the information for a given game list for an individual system.\n *\n * @returns\n * The node that represents the info json, or null if no such file\n * exists.\n */\n info(id: \"systems\" | ZRomulatorSystemId): Promise<IZFileSystemNode | null>;\n\n /**\n * Reads a file and returns the json representation.\n *\n * @param node -\n * The node to read. If this is falsy, then null is returned.\n *\n * @returns\n * The file contents as json, or null if the contents cannot be read.\n */\n json(node: ZOptional<IZFileSystemNode>): Promise<unknown>;\n\n /**\n * Initializes the file repository.\n */\n init(): Promise<any>;\n\n /**\n * Cleans up internal resources.\n */\n dispose(): Promise<void>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesRepository implements IZRomulatorFilesRepository {\n private static readonly MediaFolderName = \".media\";\n private static readonly InfoFolderName = \".info\";\n\n private _logger: IZLogger;\n private _repository: ZFileRepository = new ZFileRepository();\n private _folderStream = new ZStreamFolder();\n private _fileStream = new ZStreamFile({\n cache: {\n fileSize: BigInt(mib(1)),\n maxFiles: 250,\n },\n });\n\n private _globs: string[];\n private _systems: string[];\n\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n @Inject(ZFileSystemToken)\n private readonly _fileSystem: IZFileSystemService,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n const slugs = Object.values(ZRomulatorSystemId);\n this._globs = [\".media/**\", \".info/**\", ...slugs.map((s) => `${s}/*.*`)];\n this._systems = Object.values(ZRomulatorSystemId);\n this._logger = new ZLoggerContext(\"ZRomulatorFilesRepository\", logger);\n }\n\n public async gamesFolder() {\n const config = await this._configs.get(ZRomulatorConfigId.Games);\n const { gamesFolder } = new ZRomulatorConfigGamesBuilder()\n .copy(config.contents)\n .build();\n const { fallback } = ZRomulatorConfigGamesMetadata.gamesFolder();\n const _gamesFolder = firstDefined(fallback.gamesFolder, gamesFolder);\n return detokenize(_gamesFolder, env);\n }\n\n public async mediaFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.MediaFolderName);\n }\n\n public async infoFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.InfoFolderName);\n }\n\n public async dispose() {\n await this._repository.reset();\n }\n\n public async init(): Promise<IZFileRepository> {\n const path = await this.gamesFolder();\n\n if (this._repository.path !== path) {\n await this._folderStream.write(await this.mediaFolder());\n await this._folderStream.write(await this.infoFolder());\n await this._repository.initialize(path, this._globs);\n }\n\n return this._repository;\n }\n\n public async media() {\n const repository = await this.init();\n const folder = `${await this.mediaFolder()}/`;\n const request = new ZDataRequestBuilder()\n .filter(\n new ZFilterBinaryBuilder()\n .subject(\"path\")\n .startsWith()\n .value(folder)\n .build(),\n )\n .sort(new ZSortBuilder().ascending(\"path\").build())\n .build();\n\n return repository.retrieve(request);\n }\n\n public async info(id?: \"systems\" | ZRomulatorSystemId) {\n // The info json files are json files that contain arrays of games grouped by systems,\n // or systems.json which describes system information.\n const folder = await this.infoFolder();\n const path = resolve(folder, `${id}.json`);\n\n return this._repository.get(path);\n }\n\n public async json(node: IZFileSystemNode): Promise<unknown> {\n if (node == null) {\n return null;\n }\n\n try {\n const contents = await this._fileStream.read(node.path);\n return JSON.parse(contents.toString());\n } catch (e) {\n const err = createError(e);\n const msg = `Unable to read ${node.path}: ${err.message}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return null;\n }\n }\n\n public async systems() {\n // Systems use directories. There's a maximum limit of about 200 systems.\n // Since we don't actually need to read any metadata or scan through thousands\n // of unknown folders, we can use the supported system ids to just grab the\n // systems that we need. Since the file repository does a stat anyway, we can just\n // grab the systems from the file system and it should be fast enough. These are all\n // folders, so we don't even need the stats for them and we can assume folders.\n const games = await this.gamesFolder();\n const folders = this._systems.map((s) => `${s}/`);\n return await this._fileSystem.search(folders, {\n cwd: games,\n stat: false,\n });\n }\n\n public async games(systems: IZRomulatorSystem[]) {\n const repository = await this.init();\n const folder = await this.gamesFolder();\n\n const queries = systems.map((s) => {\n const dir = `${folder}/${s.id}`;\n\n const byExtension = new ZFilterCollectionBuilder()\n .subject(\"extension\")\n .in()\n .values(s.extensions)\n .build();\n const inPath = new ZFilterBinaryBuilder()\n .subject(\"parent\")\n .equal()\n .value(dir)\n .build();\n const filter = new ZFilterLogicBuilder()\n .and()\n .clause(inPath)\n .clause(byExtension)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).build();\n return repository.retrieve(request);\n });\n\n const results = await Promise.all(queries);\n\n return flatten(results);\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type {\n IZRomulatorSystem,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorSystemBuilder } from \"@zthun/romulator-client\";\nimport { castArray } from \"lodash-es\";\nimport { basename } from \"node:path\";\nimport {\n ZRomulatorFilesRepositoryToken,\n type IZRomulatorFilesRepository,\n} from \"./files-repository.mjs\";\n\nexport const ZRomulatorFilesSystemsRepositoryToken = Symbol(\n \"files-systems-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of system.json.\n */\nexport interface IZRomulatorFilesSystemsRepository {\n /**\n * Reads all system entries in the systems.json file and combines\n * them with the existing system list in the games directory\n *\n * @returns\n * A list of all the systems that are in the games\n * directory decorated with the content data in systems.json\n * in the .info directory.\n */\n systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesSystemsRepository implements IZRomulatorFilesSystemsRepository {\n /**\n * Initializes a new instance of this object.\n */\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>> {\n const info = await this._filesRepository.info(\"systems\");\n const json = await this._filesRepository.json(info);\n const candidates = castArray(firstDefined([], json));\n const folders = await this._filesRepository.systems();\n\n function hasId(candidate: any): candidate is { id: string } {\n return Object.prototype.hasOwnProperty.call(candidate, \"id\");\n }\n\n const entries: [ZRomulatorSystemId, unknown][] = candidates\n .filter((c) => hasId(c))\n .filter((c) => isSystemId(c.id))\n .map((c) => [c.id as ZRomulatorSystemId, c as unknown]);\n\n const lookup = new Map(entries);\n\n const systems = folders\n .map((folder) => folder.path)\n .map((path) => basename(path))\n .filter((slug) => isSystemId(slug))\n .map((slug) =>\n new ZRomulatorSystemBuilder().parse(lookup.get(slug)).id(slug).build(),\n );\n\n return new Map(systems.map((s) => [s.id, s]));\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { ZFileSystemNodeBuilder } from \"@zthun/crumbtrail-fs\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorGameBuilder } from \"@zthun/romulator-client\";\nimport { castArray, get, kebabCase, uniq } from \"lodash-es\";\nimport { resolve } from \"path\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"./files-repository.mjs\";\nimport type { IZRomulatorFilesSystemsRepository } from \"./files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"./files-systems-repository.mjs\";\n\nexport const ZRomulatorFilesGamesRepositoryToken = Symbol(\n \"files-games-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of a game list json file.\n */\nexport interface IZRomulatorFilesGamesRepository {\n /**\n * Reads all of the games in the games directory.\n *\n * Game targets are determined by the extensions in system.json.\n *\n * @returns\n * A list of all the games that are in the games\n * directory decorated with the content data in the matching\n * system json file in the .info directory.\n */\n games(): Promise<Map<string, IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesGamesRepository implements IZRomulatorFilesGamesRepository {\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async games(): Promise<Map<string, IZRomulatorGame>> {\n function hasPath(entry: unknown): entry is { path: string } {\n return typeof get(entry, \"path\") === \"string\";\n }\n\n const gamesFolder = await this._filesRepository.gamesFolder();\n const games: IZRomulatorGame[] = [];\n const systemLookup = await this._systemsRepository.systems();\n const systems = Array.from(systemLookup.values());\n const gameFiles = await this._filesRepository.games(systems);\n const systemsInUse = uniq(gameFiles.map((g) => g.parent))\n .map((dir) => new ZFileSystemNodeBuilder().path(dir).folder().build())\n .map((node) => node.title)\n .filter((title) => isSystemId(title));\n\n const gameInfo = new Map<string, unknown>();\n\n for await (const system of systemsInUse) {\n const info = await this._filesRepository.info(system);\n const json = await this._filesRepository.json(info);\n const gameList = castArray(json).filter((e) => hasPath(e));\n gameList.forEach((entry) => {\n gameInfo.set(resolve(gamesFolder, system, entry.path), entry);\n });\n }\n\n // Variable, gameInfo, now has all of the information data that we need.\n for (const file of gameFiles) {\n const { title, path } = file;\n const { title: systemId } = new ZFileSystemNodeBuilder()\n .path(file.parent)\n .folder()\n .build();\n const id = `${kebabCase(systemId)}-${kebabCase(title)}`;\n const info = gameInfo.get(path);\n\n const game = new ZRomulatorGameBuilder()\n .id(id)\n .system(systemId as ZRomulatorSystemId)\n .file(path)\n .parse(info)\n .build();\n\n games.push(game);\n }\n\n return new Map(games.map((g) => [g.id, g]));\n }\n}\n","import { Inject, Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport {\n ZRomulatorFilesGamesRepository,\n ZRomulatorFilesGamesRepositoryToken,\n} from \"./files-games-repository.mjs\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesRepository,\n ZRomulatorFilesRepositoryToken,\n} from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepository,\n ZRomulatorFilesSystemsRepositoryToken,\n} from \"./files-systems-repository.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZRomulatorConfigsModule, ZLoggerModule],\n providers: [\n {\n provide: ZRomulatorFilesRepositoryToken,\n useClass: ZRomulatorFilesRepository,\n },\n {\n provide: ZRomulatorFilesSystemsRepositoryToken,\n useClass: ZRomulatorFilesSystemsRepository,\n },\n {\n provide: ZRomulatorFilesGamesRepositoryToken,\n useClass: ZRomulatorFilesGamesRepository,\n },\n ],\n exports: [\n ZRomulatorFilesRepositoryToken,\n ZRomulatorFilesSystemsRepositoryToken,\n ZRomulatorFilesGamesRepositoryToken,\n ],\n})\nexport class ZRomulatorFilesModule {\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _files: IZRomulatorFilesRepository,\n ) {}\n\n public async onModuleInit() {\n await this._files.init();\n }\n\n public async onModuleDestroy() {\n await this._files.dispose();\n }\n}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulGet } from \"@zthun/webigail-rest\";\nimport {\n ZRomulatorFilesGamesRepositoryToken,\n type IZRomulatorFilesGamesRepository,\n} from \"../files/files-games-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepositoryToken,\n type IZRomulatorFilesSystemsRepository,\n} from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorGamesToken = Symbol(\"romulator-games-service\");\n\nexport interface IZRomulatorGamesService extends IZRestfulGet<IZRomulatorGame> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorGamesService implements IZRomulatorGamesService {\n private readonly _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesGamesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesGamesRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorGamesService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>> {\n const msg = `Searching for games`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systems = await this._systemsRepository.systems();\n const games = await this._filesRepository.games();\n\n const match = (data: IZRomulatorGame, filter: string): boolean => {\n const needle = filter?.trim().toLowerCase();\n const { name = \"\", system = \"\" } = data;\n const systemId = system as ZRomulatorSystemId;\n const systemName = firstTruthy(\"\", systems.get(systemId)?.name);\n\n if (!needle?.length) {\n return true;\n }\n\n return [name, system, systemName]\n .filter((s) => s.length)\n .some((k) => k.toLowerCase().includes(needle));\n };\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorGame>()\n .search({ match })\n .build();\n const source = new ZDataSourceStatic(Array.from(games.values()), options);\n\n const $sort = new ZSortBuilder()\n .sorts(firstDefined([], req.sort))\n .ascending(\"system\")\n .ascending(\"name\")\n .build();\n const $request = new ZDataRequestBuilder().copy(req).sort($sort).build();\n\n const data = await source.retrieve($request);\n const count = await source.count($request);\n\n return new ZPageBuilder().count(count).data(data).build();\n }\n\n public async get(id: string): Promise<IZRomulatorGame> {\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: games } = await this.list(request);\n const [game] = games;\n\n if (game == null) {\n const message = `Game, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return game;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorGame } from \"@zthun/romulator-client\";\nimport type { IZRomulatorGamesService } from \"./games-service.mjs\";\nimport { ZRomulatorGamesToken } from \"./games-service.mjs\";\n\n@Controller(\"games\")\nexport class ZRomulatorGamesController {\n public constructor(\n @Inject(ZRomulatorGamesToken)\n private readonly _games: IZRomulatorGamesService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorGame>> {\n return this._games.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._games.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorGamesController } from \"./games-controller.mjs\";\nimport {\n ZRomulatorGamesService,\n ZRomulatorGamesToken,\n} from \"./games-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorGamesController],\n providers: [\n {\n provide: ZRomulatorGamesToken,\n useClass: ZRomulatorGamesService,\n },\n ],\n})\nexport class ZRomulatorGamesModule {}\n","import { Injectable } from \"@nestjs/common\";\nimport { html } from \"@zthun/helpful-fn\";\n\n/**\n * The injection token for the media generator.\n */\nexport const ZRomulatorMediaGeneratorToken = Symbol(\"media-generator\");\n\n/**\n * A generator that generates in memory media for systems and\n * games that have their media missing.\n */\nexport interface IZRomulatorMediaGenerator {\n /**\n * Generates a wheel image with a given name.\n *\n * A wheel is 373x187 pixels. It'll have a transparent background\n * with the name in uppercase It will display the name\n * in the middle of the wheel image. It assumes it will live on a\n * dark background so the name will be white.\n *\n * @param name -\n * The name to place in the middle of the wheel image.\n *\n * @returns\n * A buffer with the generated wheel.\n */\n generate(name: string): Promise<Buffer>;\n}\n\n/**\n * An implementation of the ZRomulatorMediaGenerator.\n */\n@Injectable()\nexport class ZRomulatorMediaGenerator implements IZRomulatorMediaGenerator {\n public generate(name: string): Promise<Buffer> {\n const width = 373;\n const height = 187;\n const fallbackName = name?.trim().length ? name.trim() : \"?\";\n const uppercaseName = fallbackName.toUpperCase();\n const escapedName = this.escapeSvgText(uppercaseName);\n\n const svg = html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"${width}\"\n height=\"${height}\"\n viewBox=\"0 0 ${width} ${height}\"\n >\n <text\n x=\"50%\"\n y=\"50%\"\n fill=\"#fff\"\n font-size=\"48\"\n text-anchor=\"middle\"\n textLength=\"${width}\"\n lengthAdjust=\"spacingAndGlyphs\"\n >\n ${escapedName}\n </text>\n </svg>\n `;\n\n return Promise.resolve(Buffer.from(svg));\n }\n\n private escapeSvgText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n }\n}\n","import {\n ForbiddenException,\n Inject,\n Injectable,\n NotAcceptableException,\n NotFoundException,\n StreamableFile,\n} from \"@nestjs/common\";\nimport { createError, firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n type IZDataRequest,\n type IZPage,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport {\n ZRomulatorMediaBuilder,\n type IZRomulatorMedia,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulDelete, IZRestfulGet } from \"@zthun/webigail-rest\";\nimport { ZMimeTypeImage } from \"@zthun/webigail-url\";\nimport { findIndex } from \"lodash-es\";\nimport { lookup } from \"mime-types\";\nimport { createReadStream } from \"node:fs\";\nimport { unlink } from \"node:fs/promises\";\nimport { Readable } from \"node:stream\";\nimport type { IZRomulatorFilesRepository } from \"../files/files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"../files/files-repository.mjs\";\nimport type { IZRomulatorMediaGenerator } from \"./media-generator.mjs\";\nimport { ZRomulatorMediaGeneratorToken } from \"./media-generator.mjs\";\n\nexport const ZRomulatorMediaToken = Symbol(\"romulator-media-service\");\n\nexport interface IZRomulatorMediaService\n extends IZRestfulGet<IZRomulatorMedia>, IZRestfulDelete {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>>;\n download(id: string, accept: string): Promise<StreamableFile>;\n}\n\n@Injectable()\nexport class ZRomulatorMediaService implements IZRomulatorMediaService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorMediaGeneratorToken)\n private _generator: IZRomulatorMediaGenerator,\n @Inject(ZRomulatorFilesRepositoryToken)\n private _files: IZRomulatorFilesRepository,\n @Inject(ZLoggerToken)\n logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorMediaService\", logger);\n }\n\n private async findAllMedia(): Promise<IZRomulatorMedia[]> {\n const files = await this._files.media();\n\n return files\n .map((f) => new ZRomulatorMediaBuilder().from(f.path).build())\n .filter((media) => !!media.id);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>> {\n let msg = `Querying media`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const time = new Date();\n const mediaList = await this.findAllMedia();\n const span = new Date().getTime() - time.getTime();\n msg = `Found ${mediaList.length} media files. Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorMedia>()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic(mediaList, options);\n const page = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder<IZRomulatorMedia>().data(page).count(count).build();\n }\n\n private async query(id: string): Promise<IZRomulatorMedia | null> {\n const mediaList = await this.findAllMedia();\n const index = findIndex(mediaList, (m) => m.id === id);\n\n return firstDefined(null, mediaList[index]);\n }\n\n public async get(id: string): Promise<IZRomulatorMedia> {\n const time = new Date();\n let log = `Searching for media with id ${id}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n\n const span = new Date().getTime() - time.getTime();\n\n if (media == null) {\n const msg = `Could not find any media with id, ${id}.`;\n log = `${msg} Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n throw new NotFoundException(msg);\n }\n\n log = `Found media, ${media.url} after ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n return media;\n }\n\n public async download(id: string, accept: string): Promise<StreamableFile> {\n const log = `Download request received for ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n const url = firstDefined(\"\", media?.url);\n const fileName = firstDefined(\"\", media?.fileName);\n const mime: string = firstTruthy(\n ZMimeTypeImage.SVG,\n lookup(fileName),\n ) as string;\n\n const accepts = accept.split(\",\").map((h) => h.split(\";\")[0].trim());\n\n const acceptable = accepts.some((a) => {\n if (a === \"*/*\") {\n return true;\n }\n if (a.endsWith(\"/*\")) {\n return mime.startsWith(a.slice(0, -1));\n }\n return a === mime;\n });\n\n if (!acceptable) {\n const msg =\n `The media requested is of type ${mime}. ` +\n `The request only accepts ${accept}.`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n throw new NotAcceptableException(msg);\n }\n\n const generate = async () => {\n // Note that this isn't perfect and is just a fallback to a wheel + marquee for now.\n // When we get to retrieving other media besides wheels, we will generate\n // everything, but for now, this will be fine enough.\n const log = `Media, ${id}, does not exist. Generating one`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n\n const parts = id.split(\"-\");\n parts.pop();\n const name = parts.join(\" \");\n const buffer = await this._generator.generate(name);\n\n return Readable.from(buffer);\n };\n\n const stream = media == null ? await generate() : createReadStream(url);\n\n return new StreamableFile(stream, {\n type: mime,\n disposition: `inline; filename=${fileName}`,\n });\n }\n\n public async delete(id: string): Promise<void> {\n const { url } = await this.get(id);\n const _url = firstDefined(\"\", url);\n\n let log = `Attempting to delete file ${_url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n try {\n await unlink(_url);\n } catch (err) {\n const { message } = createError(err);\n this._logger.log(new ZLogEntryBuilder().error().message(message).build());\n throw new ForbiddenException(message);\n }\n\n log = `Deleted ${url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n }\n}\n","import {\n Controller,\n Delete,\n Get,\n Inject,\n Param,\n Query,\n Req,\n} from \"@nestjs/common\";\nimport { ApiParam, ApiQuery, ApiResponse, ApiTags } from \"@nestjs/swagger\";\nimport {\n ZDataRequestBuilder,\n type IZDataRequestQuery,\n} from \"@zthun/helpful-query\";\nimport { ZHttpCodeClient, ZHttpCodeSuccess } from \"@zthun/webigail-http\";\nimport type { Request } from \"express\";\nimport type { IZRomulatorMediaService } from \"./media-service.mjs\";\nimport { ZRomulatorMediaToken } from \"./media-service.mjs\";\n\n@ApiTags(\"Media\")\n@Controller(\"media\")\nexport class ZRomulatorMediaController {\n public constructor(\n @Inject(ZRomulatorMediaToken)\n private _media: IZRomulatorMediaService,\n ) {}\n\n @ApiQuery({\n name: \"page\",\n required: false,\n type: Number,\n example: 1,\n description: \"Page number (1-based)\",\n })\n @ApiQuery({\n name: \"size\",\n required: false,\n type: Number,\n example: 20,\n description: \"Items per page. Defaults to Infinity\",\n })\n @ApiQuery({\n name: \"search\",\n required: false,\n type: String,\n description: \"Search query\",\n })\n @ApiQuery({\n name: \"sort\",\n required: false,\n type: String,\n description: \"Sort criterion\",\n })\n @ApiQuery({\n name: \"filter\",\n required: false,\n type: String,\n description: \"Filter criterion\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the requested page of media and the total count\",\n })\n @Get()\n public list(@Query() params: IZDataRequestQuery) {\n const request = new ZDataRequestBuilder().query(params).build();\n return this._media.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the media\",\n content: {\n \"*/*\": {},\n \"image/*\": {},\n \"image/png\": {},\n \"image/jpeg\": {},\n \"application/mp4\": {},\n \"application/json\": {},\n },\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotFound,\n description: \"Media not found\",\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotAcceptable,\n description: \"Unsupported Accept header\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: string,\n @Req() req: Request,\n ) {\n const { accept = \"*/*\" } = req.headers;\n\n return accept.includes(\"application/json\")\n ? this._media.get(identification)\n : this._media.download(identification, accept);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @Delete(\":identification\")\n public async delete(@Param(\"identification\") identification: string) {\n await this._media.delete(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorMediaController } from \"./media-controller.mjs\";\nimport {\n ZRomulatorMediaGenerator,\n ZRomulatorMediaGeneratorToken,\n} from \"./media-generator.mjs\";\nimport {\n ZRomulatorMediaService,\n ZRomulatorMediaToken,\n} from \"./media-service.mjs\";\n\n@Module({\n imports: [ZLoggerModule, ZRomulatorFilesModule],\n controllers: [ZRomulatorMediaController],\n providers: [\n {\n provide: ZRomulatorMediaGeneratorToken,\n useClass: ZRomulatorMediaGenerator,\n },\n {\n provide: ZRomulatorMediaToken,\n useClass: ZRomulatorMediaService,\n },\n ],\n})\nexport class ZRomulatorMediaModule {}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport { isSystemId } from \"@zthun/romulator-client\";\nimport type { IZRomulatorFilesSystemsRepository } from \"../files/files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorSystemsToken = Symbol(\"romulator-systems-service\");\n\nexport interface IZRomulatorSystemsService {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>>;\n get(id: string): Promise<IZRomulatorSystem>;\n}\n\n@Injectable()\nexport class ZRomulatorSystemsService implements IZRomulatorSystemsService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorSystemsService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving systems page, ${page}, with size, ${size}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systemMap = await this._systemsRepository.systems();\n const systems = Array.from(systemMap.values());\n\n msg = `Found ${systems.length} systems`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const sourceOptions = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields([\"id\", \"name\"]))\n .build();\n\n const source = new ZDataSourceStatic<IZRomulatorSystem>(\n systems,\n sourceOptions,\n );\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder().data(data).count(count).build();\n }\n\n public async get(id: string): Promise<IZRomulatorSystem> {\n // The system path should be the slug itself.\n if (!isSystemId(id)) {\n const message = `The specified system slug, ${id}, is not supported.`;\n throw new NotFoundException(message);\n }\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: systems } = await this.list(request);\n const [system] = systems;\n\n if (system == null) {\n const message = `System with slug, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return system;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport { ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport type { IZRomulatorSystemsService } from \"./systems-service.mjs\";\nimport { ZRomulatorSystemsToken } from \"./systems-service.mjs\";\n\n@Controller(\"systems\")\nexport class ZRomulatorSystemsController {\n public constructor(\n @Inject(ZRomulatorSystemsToken)\n private readonly _systems: IZRomulatorSystemsService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorSystem>> {\n return this._systems.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the system\",\n })\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._systems.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorSystemsController } from \"./systems-controller.mjs\";\nimport {\n ZRomulatorSystemsService,\n ZRomulatorSystemsToken,\n} from \"./systems-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorSystemsController],\n providers: [\n {\n provide: ZRomulatorSystemsToken,\n useClass: ZRomulatorSystemsService,\n },\n ],\n exports: [ZRomulatorSystemsToken],\n})\nexport class ZRomulatorSystemsModule {}\n","/* istanbul ignore file -- @preserve */\nimport { Module } from \"@nestjs/common\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport { ZRomulatorGamesModule } from \"../games/games-module.mjs\";\nimport { ZRomulatorMediaModule } from \"../media/media-module.mjs\";\nimport { ZRomulatorSystemsModule } from \"../systems/systems-module.mjs\";\n\n@Module({\n imports: [\n ZRomulatorSystemsModule,\n ZRomulatorConfigsModule,\n ZRomulatorMediaModule,\n ZRomulatorGamesModule,\n ],\n})\nexport class ZRomulatorModule {}\n","import { NestFactory } from \"@nestjs/core\";\nimport { DocumentBuilder, SwaggerModule } from \"@nestjs/swagger\";\nimport { ZRomulatorModule } from \"./app/app-module.mjs\";\n\nconst PORT = 3000;\n\n(async function () {\n const app = await NestFactory.create(ZRomulatorModule);\n app.setGlobalPrefix(\"api\");\n app.enableCors();\n\n const config = new DocumentBuilder()\n .setTitle(\"Romulator API\")\n .setDescription(\"The Romulator API\")\n .setVersion(\"1\")\n .build();\n\n const document = () => SwaggerModule.createDocument(app, config);\n SwaggerModule.setup(\"api/docs\", app, document);\n\n await app.listen(PORT);\n})();\n"],"names":["ZRomulatorConfigUpdateDto","_define_property","contents","type","properties","message","ZDir","application","resolve","homedir","configs","ZRomulatorConfigKnown","all","games","create","id","file","ZRomulatorConfigBuilder","ZRomulatorConfigId","Games","name","description","avatar","metadata","ZRomulatorConfigGamesMetadata","build","ZRomulatorConfigsToken","Symbol","ZRomulatorConfigsService","list","req","page","firstDefined","size","Infinity","msg","_logger","log","ZLogEntryBuilder","info","options","ZDataSourceStaticOptionsBuilder","search","ZDataSearchFields","source","ZDataSourceStatic","data","retrieve","count","length","ZPageBuilder","get","config","_find","buffer","readFile","json","toString","JSON","parse","byteLength","e","createError","warning","result","copy","Promise","update","record","next","stringify","mkdir","dirname","recursive","writeFile","error","reject","InternalServerErrorException","find","c","NotFoundException","ZLoggerContext","ZRomulatorConfigsController","request","ZDataRequestBuilder","query","_configs","payload","identification","ValidationPipe","transform","whitelist","skipMissingProperties","skipNullProperties","skipUndefinedProperties","ZRomulatorConfigsModule","imports","ZFileSystemModule","ZLoggerModule","controllers","providers","provide","useClass","exports","ZRomulatorFilesRepositoryToken","ZRomulatorFilesRepository","gamesFolder","ZRomulatorConfigGamesBuilder","fallback","_gamesFolder","detokenize","env","mediaFolder","MediaFolderName","infoFolder","InfoFolderName","dispose","_repository","reset","init","path","_folderStream","write","initialize","_globs","media","repository","folder","filter","ZFilterBinaryBuilder","subject","startsWith","value","sort","ZSortBuilder","ascending","node","_fileStream","read","err","systems","folders","_systems","map","s","_fileSystem","cwd","stat","queries","dir","byExtension","ZFilterCollectionBuilder","in","values","extensions","inPath","equal","ZFilterLogicBuilder","and","clause","results","flatten","logger","ZFileRepository","ZStreamFolder","ZStreamFile","cache","fileSize","BigInt","mib","maxFiles","slugs","Object","ZRomulatorSystemId","ZRomulatorFilesSystemsRepositoryToken","ZRomulatorFilesSystemsRepository","_filesRepository","candidates","castArray","hasId","candidate","prototype","hasOwnProperty","call","entries","isSystemId","lookup","Map","basename","slug","ZRomulatorSystemBuilder","ZRomulatorFilesGamesRepositoryToken","ZRomulatorFilesGamesRepository","hasPath","entry","systemLookup","_systemsRepository","Array","from","gameFiles","systemsInUse","uniq","g","parent","ZFileSystemNodeBuilder","title","gameInfo","system","gameList","forEach","set","systemId","kebabCase","game","ZRomulatorGameBuilder","push","ZRomulatorFilesModule","onModuleInit","_files","onModuleDestroy","ZRomulatorGamesToken","ZRomulatorGamesService","match","needle","trim","toLowerCase","systemName","firstTruthy","some","k","includes","$sort","sorts","$request","ZRomulatorGamesController","_games","ZRomulatorGamesModule","ZRomulatorMediaGeneratorToken","ZRomulatorMediaGenerator","generate","width","height","fallbackName","uppercaseName","toUpperCase","escapedName","escapeSvgText","svg","html","Buffer","replace","ZRomulatorMediaToken","ZRomulatorMediaService","findAllMedia","files","f","ZRomulatorMediaBuilder","time","Date","mediaList","span","getTime","index","findIndex","m","url","download","accept","fileName","mime","ZMimeTypeImage","SVG","accepts","split","h","acceptable","a","endsWith","slice","NotAcceptableException","parts","pop","join","_generator","Readable","stream","createReadStream","StreamableFile","disposition","delete","_url","unlink","ForbiddenException","ZRomulatorMediaController","params","_media","headers","required","Number","example","String","status","ZHttpCodeSuccess","OK","content","ZHttpCodeClient","NotFound","NotAcceptable","ZRomulatorMediaModule","ZRomulatorSystemsToken","ZRomulatorSystemsService","systemMap","sourceOptions","ZRomulatorSystemsController","ZRomulatorSystemsModule","ZRomulatorModule","PORT","app","NestFactory","setGlobalPrefix","enableCors","DocumentBuilder","setTitle","setDescription","setVersion","document","SwaggerModule","createDocument","setup","listen"],"mappings":"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"}
package/dist/main.js CHANGED
@@ -1442,7 +1442,7 @@ ZRomulatorSystemsModule = _ts_decorate$1([
1442
1442
  })
1443
1443
  ], ZRomulatorSystemsModule);
1444
1444
 
1445
- /* istanbul ignore file -- @preserve */ function _ts_decorate(decorators, target, key, desc) {
1445
+ function _ts_decorate(decorators, target, key, desc) {
1446
1446
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1447
1447
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1448
1448
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../src/config/config-update.mts","../src/dir/dir.ts","../src/config/config-known.mts","../src/config/configs-service.mts","../src/config/configs-controller.mts","../src/config/configs-module.mts","../src/files/files-repository.mts","../src/files/files-systems-repository.mts","../src/files/files-games-repository.mts","../src/files/files-module.mts","../src/games/games-service.mts","../src/games/games-controller.mts","../src/games/games-module.mts","../src/media/media-generator.mts","../src/media/media-service.mts","../src/media/media-controller.mts","../src/media/media-module.mts","../src/systems/systems-service.mts","../src/systems/systems-controller.mts","../src/systems/systems-module.mts","../src/app/app-module.mts","../src/main.mts"],"sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsDefined, IsNotEmptyObject, IsObject } from \"class-validator\";\n\nexport class ZRomulatorConfigUpdateDto<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n @ApiProperty({ type: \"object\", properties: {} })\n @IsDefined({ message: \"The contents of the config is required\" })\n @IsObject({ message: \"The contents of the config must be an object \" })\n @IsNotEmptyObject()\n contents: T;\n}\n","import { homedir } from \"node:os\";\nimport { resolve } from \"node:path\";\n\nexport abstract class ZDir {\n public static application() {\n return resolve(homedir(), \".zthunworks\", \"romulator\");\n }\n\n public static configs() {\n return resolve(ZDir.application(), \"configs\");\n }\n}\n","import {\n ZRomulatorConfigBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { resolve } from \"node:path\";\nimport { ZDir } from \"../dir/dir.js\";\n\nexport abstract class ZRomulatorConfigKnown {\n public static all() {\n return [ZRomulatorConfigKnown.games()];\n }\n\n private static create(id: ZRomulatorConfigId) {\n const file = resolve(ZDir.configs(), `${id}.json`);\n return new ZRomulatorConfigBuilder().id(id).file(file);\n }\n\n public static games() {\n return ZRomulatorConfigKnown.create(ZRomulatorConfigId.Games)\n .name(\"Game Settings\")\n .description(\"Modify where your games are stored and related settings\")\n .avatar(\"gamepad\")\n .metadata(ZRomulatorConfigGamesMetadata.all())\n .build();\n }\n}\n","import {\n Inject,\n Injectable,\n InternalServerErrorException,\n NotFoundException,\n} from \"@nestjs/common\";\nimport { createError, firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigBuilder } from \"@zthun/romulator-client\";\nimport type { IZRestfulGet, IZRestfulUpdate } from \"@zthun/webigail-rest\";\nimport { find } from \"lodash-es\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { ZRomulatorConfigKnown } from \"./config-known.mjs\";\n\nexport const ZRomulatorConfigsToken = Symbol(\"configs\");\n\nexport interface IZRomulatorConfigsService\n extends IZRestfulUpdate<IZRomulatorConfig>,\n IZRestfulGet<IZRomulatorConfig> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>>;\n}\n\n@Injectable()\nexport class ZRomulatorConfigsService implements IZRomulatorConfigsService {\n private _logger: IZLogger;\n\n public constructor(@Inject(ZLoggerToken) _logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZRomulatorConfigsService\", _logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving configs page, ${page}, with size, ${size}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const configs = ZRomulatorConfigKnown.all();\n const options = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic<IZRomulatorConfig>(configs, options);\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n msg = `Responding with ${data.length} configs out of ${count} total`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return new ZPageBuilder<IZRomulatorConfig>()\n .data(data)\n .count(count)\n .build();\n }\n\n public async get<T>(\n id: ZRomulatorConfigId,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this._find(id);\n let msg = `Attempting to read the file contents for config, ${id}.`;\n let contents: any = {};\n\n try {\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const buffer = await readFile(config.file);\n const json = buffer.toString(\"utf-8\");\n contents = JSON.parse(json);\n msg = `Finished reading config contents (${buffer.byteLength} bytes)`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n } catch (e) {\n msg = createError(e).message;\n this._logger.log(new ZLogEntryBuilder().warning().message(msg).build());\n }\n\n const result = new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(contents)\n .build();\n\n return Promise.resolve(result as Required<IZRomulatorConfig<T>>);\n }\n\n public async update<T>(\n id: ZRomulatorConfigId,\n record: Pick<IZRomulatorConfig, \"contents\">,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this.get<T>(id);\n\n let msg = `Updating config file, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const next = { ...config.contents, ...record.contents };\n const json = JSON.stringify(next);\n\n try {\n await mkdir(dirname(config.file), { recursive: true });\n await writeFile(config.file, json);\n return new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(next)\n .build() as Required<IZRomulatorConfig<T>>;\n } catch (e) {\n const error = createError(e);\n msg = `Unable to write to, ${config.file}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n msg = error.message;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new InternalServerErrorException(error));\n }\n }\n\n private async _find(id: ZRomulatorConfigId): Promise<IZRomulatorConfig> {\n let msg = `Attempting to retrieve config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const configs = ZRomulatorConfigKnown.all();\n const config = find(configs, (c) => c.id === id);\n\n if (config == null) {\n msg = `Could not find config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new NotFoundException(msg));\n }\n\n msg = `Config, ${id}, found`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return config;\n }\n}\n","import {\n Body,\n Controller,\n Get,\n Inject,\n Param,\n Patch,\n Query,\n UsePipes,\n ValidationPipe,\n} from \"@nestjs/common\";\nimport { ApiBody, ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigUpdateDto } from \"./config-update.mjs\";\nimport type { IZRomulatorConfigsService } from \"./configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"./configs-service.mjs\";\n\n@Controller(\"configs\")\nexport class ZRomulatorConfigsController {\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n ) {}\n\n @Get()\n public async list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorConfig>> {\n const request = new ZDataRequestBuilder().query(query).build();\n return this._configs.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @ApiBody({\n type: ZRomulatorConfigUpdateDto,\n })\n @Patch(\":identification\")\n @UsePipes(\n new ValidationPipe({\n transform: true,\n whitelist: true,\n skipMissingProperties: false,\n skipNullProperties: false,\n skipUndefinedProperties: false,\n }),\n )\n public async update(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n @Body() payload: ZRomulatorConfigUpdateDto,\n ): Promise<IZRomulatorConfig> {\n return this._configs.update(identification, payload);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n ): Promise<IZRomulatorConfig> {\n return await this._configs.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsController } from \"./configs-controller.mjs\";\nimport {\n ZRomulatorConfigsService,\n ZRomulatorConfigsToken,\n} from \"./configs-service.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZLoggerModule],\n controllers: [ZRomulatorConfigsController],\n providers: [\n { provide: ZRomulatorConfigsToken, useClass: ZRomulatorConfigsService },\n ],\n exports: [ZRomulatorConfigsToken],\n})\nexport class ZRomulatorConfigsModule {}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport type {\n IZFileRepository,\n IZFileSystemNode,\n IZFileSystemService,\n} from \"@zthun/crumbtrail-fs\";\nimport {\n ZFileRepository,\n ZStreamFile,\n ZStreamFolder,\n} from \"@zthun/crumbtrail-fs\";\nimport { ZFileSystemToken } from \"@zthun/crumbtrail-nest\";\nimport type { ZOptional } from \"@zthun/helpful-fn\";\nimport { createError, detokenize, firstDefined, mib } from \"@zthun/helpful-fn\";\nimport {\n ZDataRequestBuilder,\n ZFilterBinaryBuilder,\n ZFilterCollectionBuilder,\n ZFilterLogicBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport {\n ZRomulatorConfigGamesBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { flatten } from \"lodash-es\";\nimport { resolve } from \"node:path\";\nimport { env } from \"node:process\";\nimport type { IZRomulatorConfigsService } from \"../config/configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"../config/configs-service.mjs\";\n\nexport const ZRomulatorFilesRepositoryToken = Symbol(\"files-repository\");\n\n/**\n * Represents the repository that you can use to\n * scan the games folder for media, info, games, and systems.\n */\nexport interface IZRomulatorFilesRepository {\n /**\n * The absolute path to the configured games\n * folder.\n *\n * @returns\n * The absolute path to the games folder.\n */\n gamesFolder(): Promise<string>;\n\n /**\n * The path to the media folder.\n *\n * @returns\n * The path to the .media folder inside the\n * games folder.\n */\n mediaFolder(): Promise<string>;\n\n /**\n * The path to the info folder.\n *\n * @returns\n * The path to the .info folder inside the\n * games folder.\n */\n infoFolder(): Promise<string>;\n\n /**\n * Retrieves all media found in the games .media folder.\n *\n * @returns\n * A list of all media found in the game media folder.\n */\n media(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all systems found in the games folder.\n *\n * A system is a root folder that is a slug of a supported\n * system.\n *\n * @returns\n * A list of all system folders found in the games folder.\n */\n systems(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all games for the given systems list.\n *\n * @param systems -\n * The list of systems to query games by.\n *\n * @returns\n * A list of file system nodes that represent a game\n * in the system directory.\n */\n games(systems: IZRomulatorSystem[]): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves the file that represents the systems info or games info\n * for a given system.\n *\n * @param id -\n * Which info item you want to receive - the root system information\n * or the information for a given game list for an individual system.\n *\n * @returns\n * The node that represents the info json, or null if no such file\n * exists.\n */\n info(id: \"systems\" | ZRomulatorSystemId): Promise<IZFileSystemNode | null>;\n\n /**\n * Reads a file and returns the json representation.\n *\n * @param node -\n * The node to read. If this is falsy, then null is returned.\n *\n * @returns\n * The file contents as json, or null if the contents cannot be read.\n */\n json(node: ZOptional<IZFileSystemNode>): Promise<unknown>;\n\n /**\n * Initializes the file repository.\n */\n init(): Promise<any>;\n\n /**\n * Cleans up internal resources.\n */\n dispose(): Promise<void>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesRepository implements IZRomulatorFilesRepository {\n private static readonly MediaFolderName = \".media\";\n private static readonly InfoFolderName = \".info\";\n\n private _logger: IZLogger;\n private _repository: ZFileRepository = new ZFileRepository();\n private _folderStream = new ZStreamFolder();\n private _fileStream = new ZStreamFile({\n cache: {\n fileSize: BigInt(mib(1)),\n maxFiles: 250,\n },\n });\n\n private _globs: string[];\n private _systems: string[];\n\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n @Inject(ZFileSystemToken)\n private readonly _fileSystem: IZFileSystemService,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n const slugs = Object.values(ZRomulatorSystemId);\n this._globs = [\".media/**\", \".info/**\", ...slugs.map((s) => `${s}/*.*`)];\n this._systems = Object.values(ZRomulatorSystemId);\n this._logger = new ZLoggerContext(\"ZRomulatorFilesRepository\", logger);\n }\n\n public async gamesFolder() {\n const config = await this._configs.get(ZRomulatorConfigId.Games);\n const { gamesFolder } = new ZRomulatorConfigGamesBuilder()\n .copy(config.contents)\n .build();\n const { fallback } = ZRomulatorConfigGamesMetadata.gamesFolder();\n const _gamesFolder = firstDefined(fallback.gamesFolder, gamesFolder);\n return detokenize(_gamesFolder, env);\n }\n\n public async mediaFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.MediaFolderName);\n }\n\n public async infoFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.InfoFolderName);\n }\n\n public async dispose() {\n await this._repository.reset();\n }\n\n public async init(): Promise<IZFileRepository> {\n const path = await this.gamesFolder();\n\n if (this._repository.path !== path) {\n await this._folderStream.write(await this.mediaFolder());\n await this._folderStream.write(await this.infoFolder());\n await this._repository.initialize(path, this._globs);\n }\n\n return this._repository;\n }\n\n public async media() {\n const repository = await this.init();\n const folder = `${await this.mediaFolder()}/`;\n const request = new ZDataRequestBuilder()\n .filter(\n new ZFilterBinaryBuilder()\n .subject(\"path\")\n .startsWith()\n .value(folder)\n .build(),\n )\n .sort(new ZSortBuilder().ascending(\"path\").build())\n .build();\n\n return repository.retrieve(request);\n }\n\n public async info(id?: \"systems\" | ZRomulatorSystemId) {\n // The info json files are json files that contain arrays of games grouped by systems,\n // or systems.json which describes system information.\n const folder = await this.infoFolder();\n const path = resolve(folder, `${id}.json`);\n\n return this._repository.get(path);\n }\n\n public async json(node: IZFileSystemNode): Promise<unknown> {\n if (node == null) {\n return null;\n }\n\n try {\n const contents = await this._fileStream.read(node.path);\n return JSON.parse(contents.toString());\n } catch (e) {\n const err = createError(e);\n const msg = `Unable to read ${node.path}: ${err.message}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return null;\n }\n }\n\n public async systems() {\n // Systems use directories. There's a maximum limit of about 200 systems.\n // Since we don't actually need to read any metadata or scan through thousands\n // of unknown folders, we can use the supported system ids to just grab the\n // systems that we need. Since the file repository does a stat anyway, we can just\n // grab the systems from the file system and it should be fast enough. These are all\n // folders, so we don't even need the stats for them and we can assume folders.\n const games = await this.gamesFolder();\n const folders = this._systems.map((s) => `${s}/`);\n return await this._fileSystem.search(folders, {\n cwd: games,\n stat: false,\n });\n }\n\n public async games(systems: IZRomulatorSystem[]) {\n const repository = await this.init();\n const folder = await this.gamesFolder();\n\n const queries = systems.map((s) => {\n const dir = `${folder}/${s.id}`;\n\n const byExtension = new ZFilterCollectionBuilder()\n .subject(\"extension\")\n .in()\n .values(s.extensions)\n .build();\n const inPath = new ZFilterBinaryBuilder()\n .subject(\"parent\")\n .equal()\n .value(dir)\n .build();\n const filter = new ZFilterLogicBuilder()\n .and()\n .clause(inPath)\n .clause(byExtension)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).build();\n return repository.retrieve(request);\n });\n\n const results = await Promise.all(queries);\n\n return flatten(results);\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type {\n IZRomulatorSystem,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorSystemBuilder } from \"@zthun/romulator-client\";\nimport { castArray } from \"lodash-es\";\nimport { basename } from \"node:path\";\nimport {\n ZRomulatorFilesRepositoryToken,\n type IZRomulatorFilesRepository,\n} from \"./files-repository.mjs\";\n\nexport const ZRomulatorFilesSystemsRepositoryToken = Symbol(\n \"files-systems-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of system.json.\n */\nexport interface IZRomulatorFilesSystemsRepository {\n /**\n * Reads all system entries in the systems.json file and combines\n * them with the existing system list in the games directory\n *\n * @returns\n * A list of all the systems that are in the games\n * directory decorated with the content data in systems.json\n * in the .info directory.\n */\n systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesSystemsRepository\n implements IZRomulatorFilesSystemsRepository\n{\n /**\n * Initializes a new instance of this object.\n */\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>> {\n const info = await this._filesRepository.info(\"systems\");\n const json = await this._filesRepository.json(info);\n const candidates = castArray(firstDefined([], json));\n const folders = await this._filesRepository.systems();\n\n function hasId(candidate: any): candidate is { id: string } {\n return Object.prototype.hasOwnProperty.call(candidate, \"id\");\n }\n\n const entries: [ZRomulatorSystemId, unknown][] = candidates\n .filter((c) => hasId(c))\n .filter((c) => isSystemId(c.id))\n .map((c) => [c.id as ZRomulatorSystemId, c as unknown]);\n\n const lookup = new Map(entries);\n\n const systems = folders\n .map((folder) => folder.path)\n .map((path) => basename(path))\n .filter((slug) => isSystemId(slug))\n .map((slug) =>\n new ZRomulatorSystemBuilder().parse(lookup.get(slug)).id(slug).build(),\n );\n\n return new Map(systems.map((s) => [s.id, s]));\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { ZFileSystemNodeBuilder } from \"@zthun/crumbtrail-fs\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorGameBuilder } from \"@zthun/romulator-client\";\nimport { castArray, get, kebabCase, uniq } from \"lodash-es\";\nimport { resolve } from \"path\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"./files-repository.mjs\";\nimport type { IZRomulatorFilesSystemsRepository } from \"./files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"./files-systems-repository.mjs\";\n\nexport const ZRomulatorFilesGamesRepositoryToken = Symbol(\n \"files-games-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of a game list json file.\n */\nexport interface IZRomulatorFilesGamesRepository {\n /**\n * Reads all of the games in the games directory.\n *\n * Game targets are determined by the extensions in system.json.\n *\n * @returns\n * A list of all the games that are in the games\n * directory decorated with the content data in the matching\n * system json file in the .info directory.\n */\n games(): Promise<Map<string, IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesGamesRepository\n implements IZRomulatorFilesGamesRepository\n{\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async games(): Promise<Map<string, IZRomulatorGame>> {\n function hasPath(entry: unknown): entry is { path: string } {\n return typeof get(entry, \"path\") === \"string\";\n }\n\n const gamesFolder = await this._filesRepository.gamesFolder();\n const games: IZRomulatorGame[] = [];\n const systemLookup = await this._systemsRepository.systems();\n const systems = Array.from(systemLookup.values());\n const gameFiles = await this._filesRepository.games(systems);\n const systemsInUse = uniq(gameFiles.map((g) => g.parent))\n .map((dir) => new ZFileSystemNodeBuilder().path(dir).folder().build())\n .map((node) => node.title)\n .filter((title) => isSystemId(title));\n\n const gameInfo = new Map<string, unknown>();\n\n for await (const system of systemsInUse) {\n const info = await this._filesRepository.info(system);\n const json = await this._filesRepository.json(info);\n const gameList = castArray(json).filter((e) => hasPath(e));\n gameList.forEach((entry) => {\n gameInfo.set(resolve(gamesFolder, system, entry.path), entry);\n });\n }\n\n // Variable, gameInfo, now has all of the information data that we need.\n for (const file of gameFiles) {\n const { title, path } = file;\n const { title: systemId } = new ZFileSystemNodeBuilder()\n .path(file.parent)\n .folder()\n .build();\n const id = `${kebabCase(systemId)}-${kebabCase(title)}`;\n const info = gameInfo.get(path);\n\n const game = new ZRomulatorGameBuilder()\n .id(id)\n .system(systemId as ZRomulatorSystemId)\n .file(path)\n .parse(info)\n .build();\n\n games.push(game);\n }\n\n return new Map(games.map((g) => [g.id, g]));\n }\n}\n","import { Inject, Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport {\n ZRomulatorFilesGamesRepository,\n ZRomulatorFilesGamesRepositoryToken,\n} from \"./files-games-repository.mjs\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesRepository,\n ZRomulatorFilesRepositoryToken,\n} from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepository,\n ZRomulatorFilesSystemsRepositoryToken,\n} from \"./files-systems-repository.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZRomulatorConfigsModule, ZLoggerModule],\n providers: [\n {\n provide: ZRomulatorFilesRepositoryToken,\n useClass: ZRomulatorFilesRepository,\n },\n {\n provide: ZRomulatorFilesSystemsRepositoryToken,\n useClass: ZRomulatorFilesSystemsRepository,\n },\n {\n provide: ZRomulatorFilesGamesRepositoryToken,\n useClass: ZRomulatorFilesGamesRepository,\n },\n ],\n exports: [\n ZRomulatorFilesRepositoryToken,\n ZRomulatorFilesSystemsRepositoryToken,\n ZRomulatorFilesGamesRepositoryToken,\n ],\n})\nexport class ZRomulatorFilesModule {\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _files: IZRomulatorFilesRepository,\n ) {}\n\n public async onModuleInit() {\n await this._files.init();\n }\n\n public async onModuleDestroy() {\n await this._files.dispose();\n }\n}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulGet } from \"@zthun/webigail-rest\";\nimport {\n ZRomulatorFilesGamesRepositoryToken,\n type IZRomulatorFilesGamesRepository,\n} from \"../files/files-games-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepositoryToken,\n type IZRomulatorFilesSystemsRepository,\n} from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorGamesToken = Symbol(\"romulator-games-service\");\n\nexport interface IZRomulatorGamesService extends IZRestfulGet<IZRomulatorGame> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorGamesService implements IZRomulatorGamesService {\n private readonly _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesGamesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesGamesRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorGamesService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>> {\n const msg = `Searching for games`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systems = await this._systemsRepository.systems();\n const games = await this._filesRepository.games();\n\n const match = (data: IZRomulatorGame, filter: string): boolean => {\n const needle = filter?.trim().toLowerCase();\n const { name = \"\", system = \"\" } = data;\n const systemId = system as ZRomulatorSystemId;\n const systemName = firstTruthy(\"\", systems.get(systemId)?.name);\n\n if (!needle?.length) {\n return true;\n }\n\n return [name, system, systemName]\n .filter((s) => s.length)\n .some((k) => k.toLowerCase().includes(needle));\n };\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorGame>()\n .search({ match })\n .build();\n const source = new ZDataSourceStatic(Array.from(games.values()), options);\n\n const $sort = new ZSortBuilder()\n .sorts(firstDefined([], req.sort))\n .ascending(\"system\")\n .ascending(\"name\")\n .build();\n const $request = new ZDataRequestBuilder().copy(req).sort($sort).build();\n\n const data = await source.retrieve($request);\n const count = await source.count($request);\n\n return new ZPageBuilder().count(count).data(data).build();\n }\n\n public async get(id: string): Promise<IZRomulatorGame> {\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: games } = await this.list(request);\n const [game] = games;\n\n if (game == null) {\n const message = `Game, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return game;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorGame } from \"@zthun/romulator-client\";\nimport type { IZRomulatorGamesService } from \"./games-service.mjs\";\nimport { ZRomulatorGamesToken } from \"./games-service.mjs\";\n\n@Controller(\"games\")\nexport class ZRomulatorGamesController {\n public constructor(\n @Inject(ZRomulatorGamesToken)\n private readonly _games: IZRomulatorGamesService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorGame>> {\n return this._games.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._games.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorGamesController } from \"./games-controller.mjs\";\nimport {\n ZRomulatorGamesService,\n ZRomulatorGamesToken,\n} from \"./games-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorGamesController],\n providers: [\n {\n provide: ZRomulatorGamesToken,\n useClass: ZRomulatorGamesService,\n },\n ],\n})\nexport class ZRomulatorGamesModule {}\n","import { Injectable } from \"@nestjs/common\";\nimport { html } from \"@zthun/helpful-fn\";\n\n/**\n * The injection token for the media generator.\n */\nexport const ZRomulatorMediaGeneratorToken = Symbol(\"media-generator\");\n\n/**\n * A generator that generates in memory media for systems and\n * games that have their media missing.\n */\nexport interface IZRomulatorMediaGenerator {\n /**\n * Generates a wheel image with a given name.\n *\n * A wheel is 373x187 pixels. It'll have a transparent background\n * with the name in uppercase It will display the name\n * in the middle of the wheel image. It assumes it will live on a\n * dark background so the name will be white.\n *\n * @param name -\n * The name to place in the middle of the wheel image.\n *\n * @returns\n * A buffer with the generated wheel.\n */\n generate(name: string): Promise<Buffer>;\n}\n\n/**\n * An implementation of the ZRomulatorMediaGenerator.\n */\n@Injectable()\nexport class ZRomulatorMediaGenerator implements IZRomulatorMediaGenerator {\n public generate(name: string): Promise<Buffer> {\n const width = 373;\n const height = 187;\n const fallbackName = name?.trim().length ? name.trim() : \"?\";\n const uppercaseName = fallbackName.toUpperCase();\n const escapedName = this.escapeSvgText(uppercaseName);\n\n const svg = html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"${width}\"\n height=\"${height}\"\n viewBox=\"0 0 ${width} ${height}\"\n >\n <text\n x=\"50%\"\n y=\"50%\"\n fill=\"#fff\"\n font-size=\"48\"\n text-anchor=\"middle\"\n textLength=\"${width}\"\n lengthAdjust=\"spacingAndGlyphs\"\n >\n ${escapedName}\n </text>\n </svg>\n `;\n\n return Promise.resolve(Buffer.from(svg));\n }\n\n private escapeSvgText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n }\n}\n","import {\n ForbiddenException,\n Inject,\n Injectable,\n NotAcceptableException,\n NotFoundException,\n StreamableFile,\n} from \"@nestjs/common\";\nimport { createError, firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n type IZDataRequest,\n type IZPage,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport {\n ZRomulatorMediaBuilder,\n type IZRomulatorMedia,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulDelete, IZRestfulGet } from \"@zthun/webigail-rest\";\nimport { ZMimeTypeImage } from \"@zthun/webigail-url\";\nimport { findIndex } from \"lodash-es\";\nimport { lookup } from \"mime-types\";\nimport { createReadStream } from \"node:fs\";\nimport { unlink } from \"node:fs/promises\";\nimport { Readable } from \"node:stream\";\nimport type { IZRomulatorFilesRepository } from \"../files/files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"../files/files-repository.mjs\";\nimport type { IZRomulatorMediaGenerator } from \"./media-generator.mjs\";\nimport { ZRomulatorMediaGeneratorToken } from \"./media-generator.mjs\";\n\nexport const ZRomulatorMediaToken = Symbol(\"romulator-media-service\");\n\nexport interface IZRomulatorMediaService\n extends IZRestfulGet<IZRomulatorMedia>,\n IZRestfulDelete {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>>;\n download(id: string, accept: string): Promise<StreamableFile>;\n}\n\n@Injectable()\nexport class ZRomulatorMediaService implements IZRomulatorMediaService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorMediaGeneratorToken)\n private _generator: IZRomulatorMediaGenerator,\n @Inject(ZRomulatorFilesRepositoryToken)\n private _files: IZRomulatorFilesRepository,\n @Inject(ZLoggerToken)\n logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorMediaService\", logger);\n }\n\n private async findAllMedia(): Promise<IZRomulatorMedia[]> {\n const files = await this._files.media();\n\n return files\n .map((f) => new ZRomulatorMediaBuilder().from(f.path).build())\n .filter((media) => !!media.id);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>> {\n let msg = `Querying media`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const time = new Date();\n const mediaList = await this.findAllMedia();\n const span = new Date().getTime() - time.getTime();\n msg = `Found ${mediaList.length} media files. Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorMedia>()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic(mediaList, options);\n const page = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder<IZRomulatorMedia>().data(page).count(count).build();\n }\n\n private async query(id: string): Promise<IZRomulatorMedia | null> {\n const mediaList = await this.findAllMedia();\n const index = findIndex(mediaList, (m) => m.id === id);\n\n return firstDefined(null, mediaList[index]);\n }\n\n public async get(id: string): Promise<IZRomulatorMedia> {\n const time = new Date();\n let log = `Searching for media with id ${id}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n\n const span = new Date().getTime() - time.getTime();\n\n if (media == null) {\n const msg = `Could not find any media with id, ${id}.`;\n log = `${msg} Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n throw new NotFoundException(msg);\n }\n\n log = `Found media, ${media.url} after ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n return media;\n }\n\n public async download(id: string, accept: string): Promise<StreamableFile> {\n const log = `Download request received for ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n const url = firstDefined(\"\", media?.url);\n const fileName = firstDefined(\"\", media?.fileName);\n const mime: string = firstTruthy(\n ZMimeTypeImage.SVG,\n lookup(fileName),\n ) as string;\n\n const accepts = accept.split(\",\").map((h) => h.split(\";\")[0].trim());\n\n const acceptable = accepts.some((a) => {\n if (a === \"*/*\") {\n return true;\n }\n if (a.endsWith(\"/*\")) {\n return mime.startsWith(a.slice(0, -1));\n }\n return a === mime;\n });\n\n if (!acceptable) {\n const msg =\n `The media requested is of type ${mime}. ` +\n `The request only accepts ${accept}.`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n throw new NotAcceptableException(msg);\n }\n\n const generate = async () => {\n // Note that this isn't perfect and is just a fallback to a wheel + marquee for now.\n // When we get to retrieving other media besides wheels, we will generate\n // everything, but for now, this will be fine enough.\n const log = `Media, ${id}, does not exist. Generating one`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n\n const parts = id.split(\"-\");\n parts.pop();\n const name = parts.join(\" \");\n const buffer = await this._generator.generate(name);\n\n return Readable.from(buffer);\n };\n\n const stream = media == null ? await generate() : createReadStream(url);\n\n return new StreamableFile(stream, {\n type: mime,\n disposition: `inline; filename=${fileName}`,\n });\n }\n\n public async delete(id: string): Promise<void> {\n const { url } = await this.get(id);\n const _url = firstDefined(\"\", url);\n\n let log = `Attempting to delete file ${_url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n try {\n await unlink(_url);\n } catch (err) {\n const { message } = createError(err);\n this._logger.log(new ZLogEntryBuilder().error().message(message).build());\n throw new ForbiddenException(message);\n }\n\n log = `Deleted ${url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n }\n}\n","import {\n Controller,\n Delete,\n Get,\n Inject,\n Param,\n Query,\n Req,\n} from \"@nestjs/common\";\nimport { ApiParam, ApiQuery, ApiResponse, ApiTags } from \"@nestjs/swagger\";\nimport {\n ZDataRequestBuilder,\n type IZDataRequestQuery,\n} from \"@zthun/helpful-query\";\nimport { ZHttpCodeClient, ZHttpCodeSuccess } from \"@zthun/webigail-http\";\nimport type { Request } from \"express\";\nimport type { IZRomulatorMediaService } from \"./media-service.mjs\";\nimport { ZRomulatorMediaToken } from \"./media-service.mjs\";\n\n@ApiTags(\"Media\")\n@Controller(\"media\")\nexport class ZRomulatorMediaController {\n public constructor(\n @Inject(ZRomulatorMediaToken)\n private _media: IZRomulatorMediaService,\n ) {}\n\n @ApiQuery({\n name: \"page\",\n required: false,\n type: Number,\n example: 1,\n description: \"Page number (1-based)\",\n })\n @ApiQuery({\n name: \"size\",\n required: false,\n type: Number,\n example: 20,\n description: \"Items per page. Defaults to Infinity\",\n })\n @ApiQuery({\n name: \"search\",\n required: false,\n type: String,\n description: \"Search query\",\n })\n @ApiQuery({\n name: \"sort\",\n required: false,\n type: String,\n description: \"Sort criterion\",\n })\n @ApiQuery({\n name: \"filter\",\n required: false,\n type: String,\n description: \"Filter criterion\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the requested page of media and the total count\",\n })\n @Get()\n public list(@Query() params: IZDataRequestQuery) {\n const request = new ZDataRequestBuilder().query(params).build();\n return this._media.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the media\",\n content: {\n \"*/*\": {},\n \"image/*\": {},\n \"image/png\": {},\n \"image/jpeg\": {},\n \"application/mp4\": {},\n \"application/json\": {},\n },\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotFound,\n description: \"Media not found\",\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotAcceptable,\n description: \"Unsupported Accept header\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: string,\n @Req() req: Request,\n ) {\n const { accept = \"*/*\" } = req.headers;\n\n return accept.includes(\"application/json\")\n ? this._media.get(identification)\n : this._media.download(identification, accept);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @Delete(\":identification\")\n public async delete(@Param(\"identification\") identification: string) {\n await this._media.delete(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorMediaController } from \"./media-controller.mjs\";\nimport {\n ZRomulatorMediaGenerator,\n ZRomulatorMediaGeneratorToken,\n} from \"./media-generator.mjs\";\nimport {\n ZRomulatorMediaService,\n ZRomulatorMediaToken,\n} from \"./media-service.mjs\";\n\n@Module({\n imports: [ZLoggerModule, ZRomulatorFilesModule],\n controllers: [ZRomulatorMediaController],\n providers: [\n {\n provide: ZRomulatorMediaGeneratorToken,\n useClass: ZRomulatorMediaGenerator,\n },\n {\n provide: ZRomulatorMediaToken,\n useClass: ZRomulatorMediaService,\n },\n ],\n})\nexport class ZRomulatorMediaModule {}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport { isSystemId } from \"@zthun/romulator-client\";\nimport type { IZRomulatorFilesSystemsRepository } from \"../files/files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorSystemsToken = Symbol(\"romulator-systems-service\");\n\nexport interface IZRomulatorSystemsService {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>>;\n get(id: string): Promise<IZRomulatorSystem>;\n}\n\n@Injectable()\nexport class ZRomulatorSystemsService implements IZRomulatorSystemsService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorSystemsService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving systems page, ${page}, with size, ${size}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systemMap = await this._systemsRepository.systems();\n const systems = Array.from(systemMap.values());\n\n msg = `Found ${systems.length} systems`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const sourceOptions = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields([\"id\", \"name\"]))\n .build();\n\n const source = new ZDataSourceStatic<IZRomulatorSystem>(\n systems,\n sourceOptions,\n );\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder().data(data).count(count).build();\n }\n\n public async get(id: string): Promise<IZRomulatorSystem> {\n // The system path should be the slug itself.\n if (!isSystemId(id)) {\n const message = `The specified system slug, ${id}, is not supported.`;\n throw new NotFoundException(message);\n }\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: systems } = await this.list(request);\n const [system] = systems;\n\n if (system == null) {\n const message = `System with slug, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return system;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport { ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport type { IZRomulatorSystemsService } from \"./systems-service.mjs\";\nimport { ZRomulatorSystemsToken } from \"./systems-service.mjs\";\n\n@Controller(\"systems\")\nexport class ZRomulatorSystemsController {\n public constructor(\n @Inject(ZRomulatorSystemsToken)\n private readonly _systems: IZRomulatorSystemsService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorSystem>> {\n return this._systems.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the system\",\n })\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._systems.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorSystemsController } from \"./systems-controller.mjs\";\nimport {\n ZRomulatorSystemsService,\n ZRomulatorSystemsToken,\n} from \"./systems-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorSystemsController],\n providers: [\n {\n provide: ZRomulatorSystemsToken,\n useClass: ZRomulatorSystemsService,\n },\n ],\n exports: [ZRomulatorSystemsToken],\n})\nexport class ZRomulatorSystemsModule {}\n","/* istanbul ignore file -- @preserve */\nimport { Module } from \"@nestjs/common\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport { ZRomulatorGamesModule } from \"../games/games-module.mjs\";\nimport { ZRomulatorMediaModule } from \"../media/media-module.mjs\";\nimport { ZRomulatorSystemsModule } from \"../systems/systems-module.mjs\";\n\n@Module({\n imports: [\n ZRomulatorSystemsModule,\n ZRomulatorConfigsModule,\n ZRomulatorMediaModule,\n ZRomulatorGamesModule,\n ],\n})\nexport class ZRomulatorModule {}\n","import { NestFactory } from \"@nestjs/core\";\nimport { DocumentBuilder, SwaggerModule } from \"@nestjs/swagger\";\nimport { ZRomulatorModule } from \"./app/app-module.mjs\";\n\nconst PORT = 3000;\n\n(async function () {\n const app = await NestFactory.create(ZRomulatorModule);\n app.setGlobalPrefix(\"api\");\n app.enableCors();\n\n const config = new DocumentBuilder()\n .setTitle(\"Romulator API\")\n .setDescription(\"The Romulator API\")\n .setVersion(\"1\")\n .build();\n\n const document = () => SwaggerModule.createDocument(app, config);\n SwaggerModule.setup(\"api/docs\", app, document);\n\n await app.listen(PORT);\n})();\n"],"names":["ZRomulatorConfigUpdateDto","_define_property","contents","type","properties","message","ZDir","application","resolve","homedir","configs","ZRomulatorConfigKnown","all","games","create","id","file","ZRomulatorConfigBuilder","ZRomulatorConfigId","Games","name","description","avatar","metadata","ZRomulatorConfigGamesMetadata","build","ZRomulatorConfigsToken","Symbol","ZRomulatorConfigsService","list","req","page","firstDefined","size","Infinity","msg","_logger","log","ZLogEntryBuilder","info","options","ZDataSourceStaticOptionsBuilder","search","ZDataSearchFields","source","ZDataSourceStatic","data","retrieve","count","length","ZPageBuilder","get","config","_find","buffer","readFile","json","toString","JSON","parse","byteLength","e","createError","warning","result","copy","Promise","update","record","next","stringify","mkdir","dirname","recursive","writeFile","error","reject","InternalServerErrorException","find","c","NotFoundException","ZLoggerContext","ZRomulatorConfigsController","request","ZDataRequestBuilder","query","_configs","payload","identification","ValidationPipe","transform","whitelist","skipMissingProperties","skipNullProperties","skipUndefinedProperties","ZRomulatorConfigsModule","imports","ZFileSystemModule","ZLoggerModule","controllers","providers","provide","useClass","exports","ZRomulatorFilesRepositoryToken","ZRomulatorFilesRepository","gamesFolder","ZRomulatorConfigGamesBuilder","fallback","_gamesFolder","detokenize","env","mediaFolder","MediaFolderName","infoFolder","InfoFolderName","dispose","_repository","reset","init","path","_folderStream","write","initialize","_globs","media","repository","folder","filter","ZFilterBinaryBuilder","subject","startsWith","value","sort","ZSortBuilder","ascending","node","_fileStream","read","err","systems","folders","_systems","map","s","_fileSystem","cwd","stat","queries","dir","byExtension","ZFilterCollectionBuilder","in","values","extensions","inPath","equal","ZFilterLogicBuilder","and","clause","results","flatten","logger","ZFileRepository","ZStreamFolder","ZStreamFile","cache","fileSize","BigInt","mib","maxFiles","slugs","Object","ZRomulatorSystemId","ZRomulatorFilesSystemsRepositoryToken","ZRomulatorFilesSystemsRepository","_filesRepository","candidates","castArray","hasId","candidate","prototype","hasOwnProperty","call","entries","isSystemId","lookup","Map","basename","slug","ZRomulatorSystemBuilder","ZRomulatorFilesGamesRepositoryToken","ZRomulatorFilesGamesRepository","hasPath","entry","systemLookup","_systemsRepository","Array","from","gameFiles","systemsInUse","uniq","g","parent","ZFileSystemNodeBuilder","title","gameInfo","system","gameList","forEach","set","systemId","kebabCase","game","ZRomulatorGameBuilder","push","ZRomulatorFilesModule","onModuleInit","_files","onModuleDestroy","ZRomulatorGamesToken","ZRomulatorGamesService","match","needle","trim","toLowerCase","systemName","firstTruthy","some","k","includes","$sort","sorts","$request","ZRomulatorGamesController","_games","ZRomulatorGamesModule","ZRomulatorMediaGeneratorToken","ZRomulatorMediaGenerator","generate","width","height","fallbackName","uppercaseName","toUpperCase","escapedName","escapeSvgText","svg","html","Buffer","replace","ZRomulatorMediaToken","ZRomulatorMediaService","findAllMedia","files","f","ZRomulatorMediaBuilder","time","Date","mediaList","span","getTime","index","findIndex","m","url","download","accept","fileName","mime","ZMimeTypeImage","SVG","accepts","split","h","acceptable","a","endsWith","slice","NotAcceptableException","parts","pop","join","_generator","Readable","stream","createReadStream","StreamableFile","disposition","delete","_url","unlink","ForbiddenException","ZRomulatorMediaController","params","_media","headers","required","Number","example","String","status","ZHttpCodeSuccess","OK","content","ZHttpCodeClient","NotFound","NotAcceptable","ZRomulatorMediaModule","ZRomulatorSystemsToken","ZRomulatorSystemsService","systemMap","sourceOptions","ZRomulatorSystemsController","ZRomulatorSystemsModule","ZRomulatorModule","PORT","app","NestFactory","setGlobalPrefix","enableCors","DocumentBuilder","setTitle","setDescription","setVersion","document","SwaggerModule","createDocument","setup","listen"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,MAAMA,yBAAAA,CAAAA;;AAGX,QAAAC,kBAAA,CAAA,IAAA,EAIAC,YAJA,MAAA,CAAA;;AAKF;;;QALiBC,IAAM,EAAA,QAAA;AAAUC,QAAAA,UAAAA,EAAY;;;QAC9BC,OAAS,EAAA;;;QACVA,OAAS,EAAA;;;;;;ACLhB,MAAeC,IAAAA,CAAAA;AACpB,IAAA,OAAcC,WAAc,GAAA;QAC1B,OAAOC,OAAAA,CAAQC,WAAW,aAAe,EAAA,WAAA,CAAA;AAC3C;AAEA,IAAA,OAAcC,OAAU,GAAA;QACtB,OAAOF,OAAAA,CAAQF,IAAKC,CAAAA,WAAW,EAAI,EAAA,SAAA,CAAA;AACrC;AACF;;ACHO,MAAeI,qBAAAA,CAAAA;AACpB,IAAA,OAAcC,GAAM,GAAA;QAClB,OAAO;AAACD,YAAAA,qBAAAA,CAAsBE,KAAK;AAAG,SAAA;AACxC;IAEA,OAAeC,MAAAA,CAAOC,EAAsB,EAAE;QAC5C,MAAMC,IAAAA,GAAOR,QAAQF,IAAKI,CAAAA,OAAO,IAAI,CAAGK,EAAAA,EAAAA,CAAG,KAAK,CAAC,CAAA;AACjD,QAAA,OAAO,IAAIE,uBAA0BF,EAAAA,CAAAA,EAAE,CAACA,EAAAA,CAAAA,CAAIC,IAAI,CAACA,IAAAA,CAAAA;AACnD;AAEA,IAAA,OAAcH,KAAQ,GAAA;QACpB,OAAOF,qBAAAA,CAAsBG,MAAM,CAACI,oBAAAA,CAAmBC,KAAK,CACzDC,CAAAA,IAAI,CAAC,eACLC,CAAAA,CAAAA,WAAW,CAAC,yDACZC,CAAAA,CAAAA,MAAM,CAAC,SACPC,CAAAA,CAAAA,QAAQ,CAACC,6BAA8BZ,CAAAA,GAAG,IAC1Ca,KAAK,EAAA;AACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACEO,MAAMC,sBAAyBC,GAAAA,MAAAA,CAAO,SAAW,CAAA;AASjD,MAAMC,wBAAAA,CAAAA;IAOX,MAAaC,IAAAA,CAAKC,GAAkB,EAAsC;AACxE,QAAA,MAAMC,IAAOC,GAAAA,YAAAA,CAAa,CAAGF,EAAAA,GAAAA,CAAIC,IAAI,CAAA;AACrC,QAAA,MAAME,IAAOD,GAAAA,YAAAA,CAAaE,QAAUJ,EAAAA,GAAAA,CAAIG,IAAI,CAAA;AAC5C,QAAA,IAAIE,MAAM,CAAC,yBAAyB,EAAEJ,IAAK,CAAA,aAAa,EAAEE,IAAM,CAAA,CAAA;AAChE,QAAA,IAAI,CAACG,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;QAEjE,MAAMf,OAAAA,GAAUC,sBAAsBC,GAAG,EAAA;AACzC,QAAA,MAAM4B,UAAU,IAAIC,+BAAAA,EAAAA,CACjBC,MAAM,CAAC,IAAIC,qBACXlB,KAAK,EAAA;QACR,MAAMmB,MAAAA,GAAS,IAAIC,iBAAAA,CAAqCnC,OAAS8B,EAAAA,OAAAA,CAAAA;AAEjE,QAAA,MAAMM,IAAO,GAAA,MAAMF,MAAOG,CAAAA,QAAQ,CAACjB,GAAAA,CAAAA;AACnC,QAAA,MAAMkB,KAAQ,GAAA,MAAMJ,MAAOI,CAAAA,KAAK,CAAClB,GAAAA,CAAAA;QAEjCK,GAAM,GAAA,CAAC,gBAAgB,EAAEW,IAAKG,CAAAA,MAAM,CAAC,gBAAgB,EAAED,KAAM,CAAA,MAAM,CAAC;AACpE,QAAA,IAAI,CAACZ,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;QAEjE,OAAO,IAAIyB,eACRJ,IAAI,CAACA,MACLE,KAAK,CAACA,OACNvB,KAAK,EAAA;AACV;IAEA,MAAa0B,GAAAA,CACXpC,EAAsB,EACmB;AACzC,QAAA,MAAMqC,MAAS,GAAA,MAAM,IAAI,CAACC,KAAK,CAACtC,EAAAA,CAAAA;AAChC,QAAA,IAAIoB,MAAM,CAAC,iDAAiD,EAAEpB,EAAAA,CAAG,CAAC,CAAC;AACnE,QAAA,IAAIb,WAAgB,EAAC;QAErB,IAAI;AACF,YAAA,IAAI,CAACkC,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AACjE,YAAA,MAAM6B,MAAS,GAAA,MAAMC,QAASH,CAAAA,MAAAA,CAAOpC,IAAI,CAAA;YACzC,MAAMwC,IAAAA,GAAOF,MAAOG,CAAAA,QAAQ,CAAC,OAAA,CAAA;YAC7BvD,QAAWwD,GAAAA,IAAAA,CAAKC,KAAK,CAACH,IAAAA,CAAAA;AACtBrB,YAAAA,GAAAA,GAAM,CAAC,kCAAkC,EAAEmB,OAAOM,UAAU,CAAC,OAAO,CAAC;AACrE,YAAA,IAAI,CAACxB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AACnE,SAAA,CAAE,OAAOoC,CAAG,EAAA;YACV1B,GAAM2B,GAAAA,WAAAA,CAAYD,GAAGxD,OAAO;AAC5B,YAAA,IAAI,CAAC+B,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmByB,EAAAA,CAAAA,OAAO,EAAG1D,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AACtE;QAEA,MAAMuC,MAAAA,GAAS,IAAI/C,uBAChBgD,EAAAA,CAAAA,IAAI,CAACb,MACLlD,CAAAA,CAAAA,QAAQ,CAACA,QAAAA,CAAAA,CACTuB,KAAK,EAAA;QAER,OAAOyC,OAAAA,CAAQ1D,OAAO,CAACwD,MAAAA,CAAAA;AACzB;AAEA,IAAA,MAAaG,MACXpD,CAAAA,EAAsB,EACtBqD,MAA2C,EACF;AACzC,QAAA,MAAMhB,MAAS,GAAA,MAAM,IAAI,CAACD,GAAG,CAAIpC,EAAAA,CAAAA;AAEjC,QAAA,IAAIoB,GAAM,GAAA,CAAC,sBAAsB,EAAEpB,EAAI,CAAA,CAAA;AACvC,QAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAEjE,QAAA,MAAM4C,IAAO,GAAA;AAAE,YAAA,GAAGjB,OAAOlD,QAAQ;AAAE,YAAA,GAAGkE,OAAOlE;AAAS,SAAA;QACtD,MAAMsD,IAAAA,GAAOE,IAAKY,CAAAA,SAAS,CAACD,IAAAA,CAAAA;QAE5B,IAAI;AACF,YAAA,MAAME,KAAMC,CAAAA,OAAAA,CAAQpB,MAAOpC,CAAAA,IAAI,CAAG,EAAA;gBAAEyD,SAAW,EAAA;AAAK,aAAA,CAAA;YACpD,MAAMC,SAAAA,CAAUtB,MAAOpC,CAAAA,IAAI,EAAEwC,IAAAA,CAAAA;YAC7B,OAAO,IAAIvC,0BACRgD,IAAI,CAACb,QACLlD,QAAQ,CAACmE,MACT5C,KAAK,EAAA;AACV,SAAA,CAAE,OAAOoC,CAAG,EAAA;AACV,YAAA,MAAMc,QAAQb,WAAYD,CAAAA,CAAAA,CAAAA;AAC1B1B,YAAAA,GAAAA,GAAM,CAAC,oBAAoB,EAAEiB,MAAAA,CAAOpC,IAAI,CAAE,CAAA;AAC1C,YAAA,IAAI,CAACoB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBqC,EAAAA,CAAAA,KAAK,EAAGtE,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAClEU,YAAAA,GAAAA,GAAMwC,MAAMtE,OAAO;AACnB,YAAA,IAAI,CAAC+B,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBqC,EAAAA,CAAAA,KAAK,EAAGtE,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAClE,YAAA,OAAOyC,OAAQU,CAAAA,MAAM,CAAC,IAAIC,4BAA6BF,CAAAA,KAAAA,CAAAA,CAAAA;AACzD;AACF;IAEA,MAActB,KAAAA,CAAMtC,EAAsB,EAA8B;AACtE,QAAA,IAAIoB,GAAM,GAAA,CAAC,+BAA+B,EAAEpB,EAAI,CAAA,CAAA;AAChD,QAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;QACjE,MAAMf,OAAAA,GAAUC,sBAAsBC,GAAG,EAAA;AACzC,QAAA,MAAMwC,SAAS0B,IAAKpE,CAAAA,OAAAA,EAAS,CAACqE,CAAMA,GAAAA,CAAAA,CAAEhE,EAAE,KAAKA,EAAAA,CAAAA;AAE7C,QAAA,IAAIqC,UAAU,IAAM,EAAA;YAClBjB,GAAM,GAAA,CAAC,uBAAuB,EAAEpB,EAAI,CAAA,CAAA;AACpC,YAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBqC,EAAAA,CAAAA,KAAK,EAAGtE,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAClE,YAAA,OAAOyC,OAAQU,CAAAA,MAAM,CAAC,IAAII,iBAAkB7C,CAAAA,GAAAA,CAAAA,CAAAA;AAC9C;AAEAA,QAAAA,GAAAA,GAAM,CAAC,QAAQ,EAAEpB,EAAAA,CAAG,OAAO,CAAC;AAC5B,QAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;QAEjE,OAAO2B,MAAAA;AACT;IApGA,WAAmB,CAAsBhB,OAAiB,CAAE;AAF5D,QAAAnC,kBAAA,CAAA,IAAA,EAAQmC,WAAR,MAAA,CAAA;AAGE,QAAA,IAAI,CAACA,OAAO,GAAG,IAAI6C,eAAe,0BAA4B7C,EAAAA,OAAAA,CAAAA;AAChE;AAmGF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtHO,MAAM8C,2BAAAA,CAAAA;IAMX,MACarD,IAAAA,CACX,KAAkC,EACE;AACpC,QAAA,MAAMsD,UAAU,IAAIC,mBAAAA,EAAAA,CAAsBC,KAAK,CAACA,OAAO5D,KAAK,EAAA;AAC5D,QAAA,OAAO,IAAI,CAAC6D,QAAQ,CAACzD,IAAI,CAACsD,OAAAA,CAAAA;AAC5B;AAEA,IAAA,MAkBahB,OACX,cAA2D,EACnDoB,OAAkC,EACd;AAC5B,QAAA,OAAO,IAAI,CAACD,QAAQ,CAACnB,MAAM,CAACqB,cAAgBD,EAAAA,OAAAA,CAAAA;AAC9C;IAEA,MAMapC,GAAAA,CACX,cAA2D,EAC/B;AAC5B,QAAA,OAAO,MAAM,IAAI,CAACmC,QAAQ,CAACnC,GAAG,CAACqC,cAAAA,CAAAA;AACjC;IAhDA,WACE,CACiBF,QAAmC,CACpD;;aADiBA,QAAAA,GAAAA,QAAAA;AAChB;AA8CL;;;;;;;;;;;;QAnCInF,IAAM,EAAA,QAAA;QACNiB,IAAM,EAAA,gBAAA;QACNC,WAAa,EAAA;;;QAGblB,IAAMH,EAAAA;;;iBAIFyF,cAAe,CAAA;QACjBC,SAAW,EAAA,IAAA;QACXC,SAAW,EAAA,IAAA;QACXC,qBAAuB,EAAA,KAAA;QACvBC,kBAAoB,EAAA,KAAA;QACpBC,uBAAyB,EAAA;AAC3B,KAAA,CAAA,CAAA;;;;;;;;;;;;QAUA3F,IAAM,EAAA,QAAA;QACNiB,IAAM,EAAA,gBAAA;QACNC,WAAa,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;AChDV,MAAM0E,uBAAAA,CAAAA;AAAyB;;;QAPpCC,OAAS,EAAA;AAACC,YAAAA,iBAAAA;AAAmBC,YAAAA;AAAc,SAAA;QAC3CC,WAAa,EAAA;AAACjB,YAAAA;AAA4B,SAAA;QAC1CkB,SAAW,EAAA;AACT,YAAA;gBAAEC,OAAS3E,EAAAA,sBAAAA;gBAAwB4E,QAAU1E,EAAAA;AAAyB;AACvE,SAAA;QACD2E,OAAS,EAAA;AAAC7E,YAAAA;AAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACyB5B,MAAM8E,8BAAiC7E,GAAAA,MAAAA,CAAO,kBAAoB,CAAA;AAsGlE,MAAM8E,yBAAAA,CAAAA;AA+BX,IAAA,MAAaC,WAAc,GAAA;QACzB,MAAMtD,MAAAA,GAAS,MAAM,IAAI,CAACkC,QAAQ,CAACnC,GAAG,CAACjC,oBAAAA,CAAmBC,KAAK,CAAA;QAC/D,MAAM,EAAEuF,WAAW,EAAE,GAAG,IAAIC,4BACzB1C,EAAAA,CAAAA,IAAI,CAACb,MAAAA,CAAOlD,QAAQ,CAAA,CACpBuB,KAAK,EAAA;AACR,QAAA,MAAM,EAAEmF,QAAQ,EAAE,GAAGpF,8BAA8BkF,WAAW,EAAA;AAC9D,QAAA,MAAMG,YAAe7E,GAAAA,YAAAA,CAAa4E,QAASF,CAAAA,WAAW,EAAEA,WAAAA,CAAAA;AACxD,QAAA,OAAOI,WAAWD,YAAcE,EAAAA,GAAAA,CAAAA;AAClC;AAEA,IAAA,MAAaC,WAAc,GAAA;AACzB,QAAA,MAAMN,WAAc,GAAA,MAAM,IAAI,CAACA,WAAW,EAAA;QAC1C,OAAOlG,OAAAA,CAAQkG,WAAaD,EAAAA,yBAAAA,CAA0BQ,eAAe,CAAA;AACvE;AAEA,IAAA,MAAaC,UAAa,GAAA;AACxB,QAAA,MAAMR,WAAc,GAAA,MAAM,IAAI,CAACA,WAAW,EAAA;QAC1C,OAAOlG,OAAAA,CAAQkG,WAAaD,EAAAA,yBAAAA,CAA0BU,cAAc,CAAA;AACtE;AAEA,IAAA,MAAaC,OAAU,GAAA;AACrB,QAAA,MAAM,IAAI,CAACC,WAAW,CAACC,KAAK,EAAA;AAC9B;AAEA,IAAA,MAAaC,IAAkC,GAAA;AAC7C,QAAA,MAAMC,IAAO,GAAA,MAAM,IAAI,CAACd,WAAW,EAAA;AAEnC,QAAA,IAAI,IAAI,CAACW,WAAW,CAACG,IAAI,KAAKA,IAAM,EAAA;YAClC,MAAM,IAAI,CAACC,aAAa,CAACC,KAAK,CAAC,MAAM,IAAI,CAACV,WAAW,EAAA,CAAA;YACrD,MAAM,IAAI,CAACS,aAAa,CAACC,KAAK,CAAC,MAAM,IAAI,CAACR,UAAU,EAAA,CAAA;YACpD,MAAM,IAAI,CAACG,WAAW,CAACM,UAAU,CAACH,IAAAA,EAAM,IAAI,CAACI,MAAM,CAAA;AACrD;QAEA,OAAO,IAAI,CAACP,WAAW;AACzB;AAEA,IAAA,MAAaQ,KAAQ,GAAA;AACnB,QAAA,MAAMC,UAAa,GAAA,MAAM,IAAI,CAACP,IAAI,EAAA;QAClC,MAAMQ,MAAAA,GAAS,GAAG,MAAM,IAAI,CAACf,WAAW,EAAA,CAAG,CAAC,CAAC;QAC7C,MAAM7B,OAAAA,GAAU,IAAIC,mBAAAA,EAAAA,CACjB4C,MAAM,CACL,IAAIC,oBAAAA,EAAAA,CACDC,OAAO,CAAC,MACRC,CAAAA,CAAAA,UAAU,EACVC,CAAAA,KAAK,CAACL,MACNtG,CAAAA,CAAAA,KAAK,EAET4G,CAAAA,CAAAA,IAAI,CAAC,IAAIC,YAAeC,EAAAA,CAAAA,SAAS,CAAC,MAAA,CAAA,CAAQ9G,KAAK,EAAA,CAAA,CAC/CA,KAAK,EAAA;QAER,OAAOqG,UAAAA,CAAW/E,QAAQ,CAACoC,OAAAA,CAAAA;AAC7B;IAEA,MAAa5C,IAAAA,CAAKxB,EAAmC,EAAE;;;AAGrD,QAAA,MAAMgH,MAAS,GAAA,MAAM,IAAI,CAACb,UAAU,EAAA;AACpC,QAAA,MAAMM,OAAOhH,OAAQuH,CAAAA,MAAAA,EAAQ,CAAGhH,EAAAA,EAAAA,CAAG,KAAK,CAAC,CAAA;AAEzC,QAAA,OAAO,IAAI,CAACsG,WAAW,CAAClE,GAAG,CAACqE,IAAAA,CAAAA;AAC9B;IAEA,MAAahE,IAAAA,CAAKgF,IAAsB,EAAoB;AAC1D,QAAA,IAAIA,QAAQ,IAAM,EAAA;YAChB,OAAO,IAAA;AACT;QAEA,IAAI;YACF,MAAMtI,QAAAA,GAAW,MAAM,IAAI,CAACuI,WAAW,CAACC,IAAI,CAACF,IAAAA,CAAKhB,IAAI,CAAA;AACtD,YAAA,OAAO9D,IAAKC,CAAAA,KAAK,CAACzD,QAAAA,CAASuD,QAAQ,EAAA,CAAA;AACrC,SAAA,CAAE,OAAOI,CAAG,EAAA;AACV,YAAA,MAAM8E,MAAM7E,WAAYD,CAAAA,CAAAA,CAAAA;YACxB,MAAM1B,GAAAA,GAAM,CAAC,eAAe,EAAEqG,IAAAA,CAAKhB,IAAI,CAAC,EAAE,EAAEmB,GAAItI,CAAAA,OAAO,CAAE,CAAA;AACzD,YAAA,IAAI,CAAC+B,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBqC,EAAAA,CAAAA,KAAK,EAAGtE,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;YAClE,OAAO,IAAA;AACT;AACF;AAEA,IAAA,MAAamH,OAAU,GAAA;;;;;;;AAOrB,QAAA,MAAM/H,KAAQ,GAAA,MAAM,IAAI,CAAC6F,WAAW,EAAA;AACpC,QAAA,MAAMmC,OAAU,GAAA,IAAI,CAACC,QAAQ,CAACC,GAAG,CAAC,CAACC,CAAM,GAAA,CAAA,EAAGA,CAAE,CAAA,CAAC,CAAC,CAAA;AAChD,QAAA,OAAO,MAAM,IAAI,CAACC,WAAW,CAACvG,MAAM,CAACmG,OAAS,EAAA;YAC5CK,GAAKrI,EAAAA,KAAAA;YACLsI,IAAM,EAAA;AACR,SAAA,CAAA;AACF;IAEA,MAAatI,KAAAA,CAAM+H,OAA4B,EAAE;AAC/C,QAAA,MAAMd,UAAa,GAAA,MAAM,IAAI,CAACP,IAAI,EAAA;AAClC,QAAA,MAAMQ,MAAS,GAAA,MAAM,IAAI,CAACrB,WAAW,EAAA;AAErC,QAAA,MAAM0C,OAAUR,GAAAA,OAAAA,CAAQG,GAAG,CAAC,CAACC,CAAAA,GAAAA;AAC3B,YAAA,MAAMK,MAAM,CAAGtB,EAAAA,MAAAA,CAAO,CAAC,EAAEiB,CAAAA,CAAEjI,EAAE,CAAE,CAAA;AAE/B,YAAA,MAAMuI,WAAc,GAAA,IAAIC,wBACrBrB,EAAAA,CAAAA,OAAO,CAAC,WAAA,CAAA,CACRsB,EAAE,EAAA,CACFC,MAAM,CAACT,CAAEU,CAAAA,UAAU,EACnBjI,KAAK,EAAA;YACR,MAAMkI,MAAAA,GAAS,IAAI1B,oBAAAA,EAAAA,CAChBC,OAAO,CAAC,QACR0B,CAAAA,CAAAA,KAAK,EACLxB,CAAAA,KAAK,CAACiB,GAAAA,CAAAA,CACN5H,KAAK,EAAA;YACR,MAAMuG,MAAAA,GAAS,IAAI6B,mBAAAA,EAAAA,CAChBC,GAAG,EAAA,CACHC,MAAM,CAACJ,MACPI,CAAAA,CAAAA,MAAM,CAACT,WAAAA,CAAAA,CACP7H,KAAK,EAAA;AACR,YAAA,MAAM0D,UAAU,IAAIC,mBAAAA,EAAAA,CAAsB4C,MAAM,CAACA,QAAQvG,KAAK,EAAA;YAC9D,OAAOqG,UAAAA,CAAW/E,QAAQ,CAACoC,OAAAA,CAAAA;AAC7B,SAAA,CAAA;AAEA,QAAA,MAAM6E,OAAU,GAAA,MAAM9F,OAAQtD,CAAAA,GAAG,CAACwI,OAAAA,CAAAA;AAElC,QAAA,OAAOa,OAAQD,CAAAA,OAAAA,CAAAA;AACjB;IAxIA,WACE,CACiB1E,QAAmC,EAEnC2D,WAAgC,EAExCiB,MAAgB,CACzB;;;;AApBF,QAAAjK,kBAAA,CAAA,IAAA,EAAQmC,WAAR,MAAA,CAAA;AACA,QAAAnC,kBAAA,CAAA,IAAA,EAAQoH,eAAR,MAAA,CAAA;AACA,QAAApH,kBAAA,CAAA,IAAA,EAAQwH,iBAAR,MAAA,CAAA;AACA,QAAAxH,kBAAA,CAAA,IAAA,EAAQwI,eAAR,MAAA,CAAA;AAOA,QAAAxI,kBAAA,CAAA,IAAA,EAAQ2H,UAAR,MAAA,CAAA;AACA,QAAA3H,kBAAA,CAAA,IAAA,EAAQ6I,YAAR,MAAA,CAAA;aAImBxD,QAAAA,GAAAA,QAAAA;aAEA2D,WAAAA,GAAAA,WAAAA;aAERiB,MAAAA,GAAAA,MAAAA;AAlBH7C,QAAAA,IAAAA,CAAAA,WAAAA,GAA+B,IAAI8C,eAAAA,EAAAA;AACnC1C,QAAAA,IAAAA,CAAAA,aAAAA,GAAgB,IAAI2C,aAAAA,EAAAA;AACpB3B,QAAAA,IAAAA,CAAAA,WAAAA,GAAc,IAAI4B,WAAY,CAAA;YACpCC,KAAO,EAAA;AACLC,gBAAAA,QAAAA,EAAUC,OAAOC,GAAI,CAAA,CAAA,CAAA,CAAA;gBACrBC,QAAU,EAAA;AACZ;AACF,SAAA,CAAA;QAaE,MAAMC,KAAAA,GAAQC,MAAOnB,CAAAA,MAAM,CAACoB,kBAAAA,CAAAA;QAC5B,IAAI,CAACjD,MAAM,GAAG;AAAC,YAAA,WAAA;AAAa,YAAA,UAAA;AAAe+C,YAAAA,GAAAA,KAAAA,CAAM5B,GAAG,CAAC,CAACC,IAAM,CAAGA,EAAAA,CAAAA,CAAE,IAAI,CAAC;AAAE,SAAA;AACxE,QAAA,IAAI,CAACF,QAAQ,GAAG8B,MAAAA,CAAOnB,MAAM,CAACoB,kBAAAA,CAAAA;AAC9B,QAAA,IAAI,CAACzI,OAAO,GAAG,IAAI6C,eAAe,2BAA6BiF,EAAAA,MAAAA,CAAAA;AACjE;AA6HF;AAzJEjK,kBAAA,CADWwG,2BACaQ,iBAAkB,EAAA,QAAA,CAAA;AAC1ChH,kBAAA,CAFWwG,2BAEaU,gBAAiB,EAAA,OAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClIpC,MAAM2D,qCAAwCnJ,GAAAA,MAAAA,CACnD,0BACA,CAAA;AAoBK,MAAMoJ,gCAAAA,CAAAA;AAWX,IAAA,MAAanC,OAA+D,GAAA;AAC1E,QAAA,MAAMrG,OAAO,MAAM,IAAI,CAACyI,gBAAgB,CAACzI,IAAI,CAAC,SAAA,CAAA;AAC9C,QAAA,MAAMiB,OAAO,MAAM,IAAI,CAACwH,gBAAgB,CAACxH,IAAI,CAACjB,IAAAA,CAAAA;AAC9C,QAAA,MAAM0I,UAAaC,GAAAA,SAAAA,CAAUlJ,YAAa,CAAA,EAAE,EAAEwB,IAAAA,CAAAA,CAAAA;AAC9C,QAAA,MAAMqF,UAAU,MAAM,IAAI,CAACmC,gBAAgB,CAACpC,OAAO,EAAA;AAEnD,QAAA,SAASuC,MAAMC,SAAc,EAAA;AAC3B,YAAA,OAAOR,OAAOS,SAAS,CAACC,cAAc,CAACC,IAAI,CAACH,SAAW,EAAA,IAAA,CAAA;AACzD;AAEA,QAAA,MAAMI,UAA2CP,UAC9CjD,CAAAA,MAAM,CAAC,CAACjD,CAAAA,GAAMoG,MAAMpG,CACpBiD,CAAAA,CAAAA,CAAAA,MAAM,CAAC,CAACjD,CAAAA,GAAM0G,WAAW1G,CAAEhE,CAAAA,EAAE,GAC7BgI,GAAG,CAAC,CAAChE,CAAM,GAAA;AAACA,gBAAAA,CAAAA,CAAEhE,EAAE;AAAwBgE,gBAAAA;AAAa,aAAA,CAAA;QAExD,MAAM2G,MAAAA,GAAS,IAAIC,GAAIH,CAAAA,OAAAA,CAAAA;AAEvB,QAAA,MAAM5C,UAAUC,OACbE,CAAAA,GAAG,CAAC,CAAChB,SAAWA,MAAOP,CAAAA,IAAI,CAC3BuB,CAAAA,GAAG,CAAC,CAACvB,IAAAA,GAASoE,QAASpE,CAAAA,IAAAA,CAAAA,CAAAA,CACvBQ,MAAM,CAAC,CAAC6D,IAASJ,GAAAA,UAAAA,CAAWI,OAC5B9C,GAAG,CAAC,CAAC8C,IAAAA,GACJ,IAAIC,uBAA0BnI,EAAAA,CAAAA,KAAK,CAAC+H,MAAAA,CAAOvI,GAAG,CAAC0I,IAAAA,CAAAA,CAAAA,CAAO9K,EAAE,CAAC8K,MAAMpK,KAAK,EAAA,CAAA;AAGxE,QAAA,OAAO,IAAIkK,GAAI/C,CAAAA,OAAAA,CAAQG,GAAG,CAAC,CAACC,CAAM,GAAA;AAACA,gBAAAA,CAAAA,CAAEjI,EAAE;AAAEiI,gBAAAA;AAAE,aAAA,CAAA,CAAA;AAC7C;AAlCA;;MAGA,WAAA,CACE,gBACoD,CACpD;;aADQgC,gBAAAA,GAAAA,gBAAAA;AACP;AA6BL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DO,MAAMe,mCAAsCpK,GAAAA,MAAAA,CACjD,wBACA,CAAA;AAqBK,MAAMqK,8BAAAA,CAAAA;AAUX,IAAA,MAAanL,KAA+C,GAAA;AAC1D,QAAA,SAASoL,QAAQC,KAAc,EAAA;YAC7B,OAAO,OAAO/I,GAAI+I,CAAAA,KAAAA,EAAO,MAAY,CAAA,KAAA,QAAA;AACvC;AAEA,QAAA,MAAMxF,cAAc,MAAM,IAAI,CAACsE,gBAAgB,CAACtE,WAAW,EAAA;AAC3D,QAAA,MAAM7F,QAA2B,EAAE;AACnC,QAAA,MAAMsL,eAAe,MAAM,IAAI,CAACC,kBAAkB,CAACxD,OAAO,EAAA;AAC1D,QAAA,MAAMA,OAAUyD,GAAAA,KAAAA,CAAMC,IAAI,CAACH,aAAa1C,MAAM,EAAA,CAAA;AAC9C,QAAA,MAAM8C,YAAY,MAAM,IAAI,CAACvB,gBAAgB,CAACnK,KAAK,CAAC+H,OAAAA,CAAAA;AACpD,QAAA,MAAM4D,YAAeC,GAAAA,IAAAA,CAAKF,SAAUxD,CAAAA,GAAG,CAAC,CAAC2D,CAAAA,GAAMA,CAAEC,CAAAA,MAAM,GACpD5D,GAAG,CAAC,CAACM,GAAAA,GAAQ,IAAIuD,sBAAyBpF,EAAAA,CAAAA,IAAI,CAAC6B,GAAAA,CAAAA,CAAKtB,MAAM,EAAA,CAAGtG,KAAK,EAAA,CAAA,CAClEsH,GAAG,CAAC,CAACP,IAASA,GAAAA,IAAAA,CAAKqE,KAAK,CACxB7E,CAAAA,MAAM,CAAC,CAAC6E,QAAUpB,UAAWoB,CAAAA,KAAAA,CAAAA,CAAAA;AAEhC,QAAA,MAAMC,WAAW,IAAInB,GAAAA,EAAAA;QAErB,WAAW,MAAMoB,UAAUP,YAAc,CAAA;AACvC,YAAA,MAAMjK,OAAO,MAAM,IAAI,CAACyI,gBAAgB,CAACzI,IAAI,CAACwK,MAAAA,CAAAA;AAC9C,YAAA,MAAMvJ,OAAO,MAAM,IAAI,CAACwH,gBAAgB,CAACxH,IAAI,CAACjB,IAAAA,CAAAA;AAC9C,YAAA,MAAMyK,WAAW9B,SAAU1H,CAAAA,IAAAA,CAAAA,CAAMwE,MAAM,CAAC,CAACnE,IAAMoI,OAAQpI,CAAAA,CAAAA,CAAAA,CAAAA;YACvDmJ,QAASC,CAAAA,OAAO,CAAC,CAACf,KAAAA,GAAAA;AAChBY,gBAAAA,QAAAA,CAASI,GAAG,CAAC1M,SAAAA,CAAQkG,aAAaqG,MAAQb,EAAAA,KAAAA,CAAM1E,IAAI,CAAG0E,EAAAA,KAAAA,CAAAA;AACzD,aAAA,CAAA;AACF;;QAGA,KAAK,MAAMlL,QAAQuL,SAAW,CAAA;AAC5B,YAAA,MAAM,EAAEM,KAAK,EAAErF,IAAI,EAAE,GAAGxG,IAAAA;AACxB,YAAA,MAAM,EAAE6L,KAAAA,EAAOM,QAAQ,EAAE,GAAG,IAAIP,sBAAAA,EAAAA,CAC7BpF,IAAI,CAACxG,IAAK2L,CAAAA,MAAM,CAChB5E,CAAAA,MAAM,GACNtG,KAAK,EAAA;AACR,YAAA,MAAMV,KAAK,CAAGqM,EAAAA,SAAAA,CAAUD,UAAU,CAAC,EAAEC,UAAUP,KAAQ,CAAA,CAAA,CAAA;YACvD,MAAMtK,IAAAA,GAAOuK,QAAS3J,CAAAA,GAAG,CAACqE,IAAAA,CAAAA;AAE1B,YAAA,MAAM6F,IAAO,GAAA,IAAIC,qBACdvM,EAAAA,CAAAA,EAAE,CAACA,EACHgM,CAAAA,CAAAA,MAAM,CAACI,QAAAA,CAAAA,CACPnM,IAAI,CAACwG,IAAAA,CAAAA,CACL7D,KAAK,CAACpB,MACNd,KAAK,EAAA;AAERZ,YAAAA,KAAAA,CAAM0M,IAAI,CAACF,IAAAA,CAAAA;AACb;AAEA,QAAA,OAAO,IAAI1B,GAAI9K,CAAAA,KAAAA,CAAMkI,GAAG,CAAC,CAAC2D,CAAM,GAAA;AAACA,gBAAAA,CAAAA,CAAE3L,EAAE;AAAE2L,gBAAAA;AAAE,aAAA,CAAA,CAAA;AAC3C;AAtDA,IAAA,WAAA,CACE,kBACsE,EAErD1B,gBAA4C,CAC7D;;;aAHiBoB,kBAAAA,GAAAA,kBAAAA;aAEApB,gBAAAA,GAAAA,gBAAAA;AAChB;AAkDL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvDO,MAAMwC,qBAAAA,CAAAA;AAMX,IAAA,MAAaC,YAAe,GAAA;AAC1B,QAAA,MAAM,IAAI,CAACC,MAAM,CAACnG,IAAI,EAAA;AACxB;AAEA,IAAA,MAAaoG,eAAkB,GAAA;AAC7B,QAAA,MAAM,IAAI,CAACD,MAAM,CAACtG,OAAO,EAAA;AAC3B;IAXA,WACE,CACiBsG,MAAkC,CACnD;;aADiBA,MAAAA,GAAAA,MAAAA;AAChB;AASL;;;QAlCE1H,OAAS,EAAA;AAACC,YAAAA,iBAAAA;AAAmBF,YAAAA,uBAAAA;AAAyBG,YAAAA;AAAc,SAAA;QACpEE,SAAW,EAAA;AACT,YAAA;gBACEC,OAASG,EAAAA,8BAAAA;gBACTF,QAAUG,EAAAA;AACZ,aAAA;AACA,YAAA;gBACEJ,OAASyE,EAAAA,qCAAAA;gBACTxE,QAAUyE,EAAAA;AACZ,aAAA;AACA,YAAA;gBACE1E,OAAS0F,EAAAA,mCAAAA;gBACTzF,QAAU0F,EAAAA;AACZ;AACD,SAAA;QACDzF,OAAS,EAAA;AACPC,YAAAA,8BAAAA;AACAsE,YAAAA,qCAAAA;AACAiB,YAAAA;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACPI,MAAM6B,oBAAuBjM,GAAAA,MAAAA,CAAO,yBAA2B,CAAA;AAO/D,MAAMkM,sBAAAA,CAAAA;IAcX,MAAahM,IAAAA,CAAKC,GAAkB,EAAoC;QACtE,MAAMK,GAAAA,GAAM,CAAC,mBAAmB,CAAC;AACjC,QAAA,IAAI,CAACC,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAEjE,QAAA,MAAMmH,UAAU,MAAM,IAAI,CAACwD,kBAAkB,CAACxD,OAAO,EAAA;AACrD,QAAA,MAAM/H,QAAQ,MAAM,IAAI,CAACmK,gBAAgB,CAACnK,KAAK,EAAA;QAE/C,MAAMiN,KAAAA,GAAQ,CAAChL,IAAuBkF,EAAAA,MAAAA,GAAAA;YACpC,MAAM+F,MAAAA,GAAS/F,QAAQgG,IAAOC,EAAAA,CAAAA,WAAAA,EAAAA;AAC9B,YAAA,MAAM,EAAE7M,IAAO,GAAA,EAAE,EAAE2L,MAAS,GAAA,EAAE,EAAE,GAAGjK,IAAAA;AACnC,YAAA,MAAMqK,QAAWJ,GAAAA,MAAAA;AACjB,YAAA,MAAMmB,aAAaC,WAAY,CAAA,EAAA,EAAIvF,OAAQzF,CAAAA,GAAG,CAACgK,QAAW/L,CAAAA,EAAAA,IAAAA,CAAAA;YAE1D,IAAI,CAAC2M,QAAQ9K,MAAQ,EAAA;gBACnB,OAAO,IAAA;AACT;YAEA,OAAO;AAAC7B,gBAAAA,IAAAA;AAAM2L,gBAAAA,MAAAA;AAAQmB,gBAAAA;AAAW,aAAA,CAC9BlG,MAAM,CAAC,CAACgB,CAAAA,GAAMA,EAAE/F,MAAM,CAAA,CACtBmL,IAAI,CAAC,CAACC,CAAMA,GAAAA,CAAAA,CAAEJ,WAAW,EAAA,CAAGK,QAAQ,CAACP,MAAAA,CAAAA,CAAAA;AAC1C,SAAA;AAEA,QAAA,MAAMvL,OAAU,GAAA,IAAIC,+BACjBC,EAAAA,CAAAA,MAAM,CAAC;AAAEoL,YAAAA;AAAM,SAAA,CAAA,CACfrM,KAAK,EAAA;QACR,MAAMmB,MAAAA,GAAS,IAAIC,iBAAkBwJ,CAAAA,KAAAA,CAAMC,IAAI,CAACzL,KAAAA,CAAM4I,MAAM,EAAKjH,CAAAA,EAAAA,OAAAA,CAAAA;AAEjE,QAAA,MAAM+L,QAAQ,IAAIjG,YAAAA,EAAAA,CACfkG,KAAK,CAACxM,aAAa,EAAE,EAAEF,GAAIuG,CAAAA,IAAI,GAC/BE,SAAS,CAAC,UACVA,SAAS,CAAC,QACV9G,KAAK,EAAA;QACR,MAAMgN,QAAAA,GAAW,IAAIrJ,mBAAsBnB,EAAAA,CAAAA,IAAI,CAACnC,GAAKuG,CAAAA,CAAAA,IAAI,CAACkG,KAAAA,CAAAA,CAAO9M,KAAK,EAAA;AAEtE,QAAA,MAAMqB,IAAO,GAAA,MAAMF,MAAOG,CAAAA,QAAQ,CAAC0L,QAAAA,CAAAA;AACnC,QAAA,MAAMzL,KAAQ,GAAA,MAAMJ,MAAOI,CAAAA,KAAK,CAACyL,QAAAA,CAAAA;QAEjC,OAAO,IAAIvL,eAAeF,KAAK,CAACA,OAAOF,IAAI,CAACA,MAAMrB,KAAK,EAAA;AACzD;IAEA,MAAa0B,GAAAA,CAAIpC,EAAU,EAA4B;QACrD,MAAMiH,MAAAA,GAAS,IAAIC,oBAAAA,EAAAA,CAChBC,OAAO,CAAC,IACR0B,CAAAA,CAAAA,KAAK,EACLxB,CAAAA,KAAK,CAACrH,EAAAA,CAAAA,CACNU,KAAK,EAAA;QACR,MAAM0D,OAAAA,GAAU,IAAIC,mBAAsB4C,EAAAA,CAAAA,MAAM,CAACA,MAAQ/F,CAAAA,CAAAA,IAAI,CAAC,CAAA,CAAA,CAAGR,KAAK,EAAA;QAEtE,MAAM,EAAEqB,MAAMjC,KAAK,EAAE,GAAG,MAAM,IAAI,CAACgB,IAAI,CAACsD,OAAAA,CAAAA;QACxC,MAAM,CAACkI,KAAK,GAAGxM,KAAAA;AAEf,QAAA,IAAIwM,QAAQ,IAAM,EAAA;AAChB,YAAA,MAAMhN,UAAU,CAAC,MAAM,EAAEU,EAAAA,CAAG,gBAAgB,CAAC;AAC7C,YAAA,MAAM,IAAIiE,iBAAkB3E,CAAAA,OAAAA,CAAAA;AAC9B;QAEA,OAAOgN,IAAAA;AACT;IApEA,WACE,CACiBjB,kBAAqD,EAErDpB,gBAAiD,EAEzDd,MAAgB,CACzB;;;;AATF,QAAAjK,kBAAA,CAAA,IAAA,EAAiBmC,WAAjB,MAAA,CAAA;aAImBgK,kBAAAA,GAAAA,kBAAAA;aAEApB,gBAAAA,GAAAA,gBAAAA;aAERd,MAAAA,GAAAA,MAAAA;AAET,QAAA,IAAI,CAAC9H,OAAO,GAAG,IAAI6C,eAAe,wBAA0BiF,EAAAA,MAAAA,CAAAA;AAC9D;AA4DF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtGO,MAAMwE,yBAAAA,CAAAA;IAOJ7M,IACL,CAASwD,KAAyB,EACA;QAClC,OAAO,IAAI,CAACsJ,MAAM,CAAC9M,IAAI,CAAC,IAAIuD,mBAAsBC,EAAAA,CAAAA,KAAK,CAACA,KAAAA,CAAAA,CAAO5D,KAAK,EAAA,CAAA;AACtE;IAGO0B,GAAI,CAAyBqC,cAAsB,EAAE;AAC1D,QAAA,OAAO,IAAI,CAACmJ,MAAM,CAACxL,GAAG,CAACqC,cAAAA,CAAAA;AACzB;IAfA,WACE,CACiBmJ,MAA+B,CAChD;;aADiBA,MAAAA,GAAAA,MAAAA;AAChB;AAaL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNO,MAAMC,qBAAAA,CAAAA;AAAuB;;;QATlC5I,OAAS,EAAA;AAACwH,YAAAA,qBAAAA;AAAuBtH,YAAAA;AAAc,SAAA;QAC/CC,WAAa,EAAA;AAACuI,YAAAA;AAA0B,SAAA;QACxCtI,SAAW,EAAA;AACT,YAAA;gBACEC,OAASuH,EAAAA,oBAAAA;gBACTtH,QAAUuH,EAAAA;AACZ;AACD;;;;;;;;;;ACdH;;AAEC,IACM,MAAMgB,6BAAgClN,GAAAA,MAAAA,CAAO,iBAAmB,CAAA;AA4BhE,MAAMmN,wBAAAA,CAAAA;AACJC,IAAAA,QAAAA,CAAS3N,IAAY,EAAmB;AAC7C,QAAA,MAAM4N,KAAQ,GAAA,GAAA;AACd,QAAA,MAAMC,MAAS,GAAA,GAAA;AACf,QAAA,MAAMC,eAAe9N,IAAM4M,EAAAA,IAAAA,EAAAA,CAAO/K,MAAS7B,GAAAA,IAAAA,CAAK4M,IAAI,EAAK,GAAA,GAAA;QACzD,MAAMmB,aAAAA,GAAgBD,aAAaE,WAAW,EAAA;AAC9C,QAAA,MAAMC,WAAc,GAAA,IAAI,CAACC,aAAa,CAACH,aAAAA,CAAAA;QAEvC,MAAMI,GAAAA,GAAMC,IAAI;;;AAGL,eAAA,EAAER,KAAM,CAAA;AACP,gBAAA,EAAEC,MAAO,CAAA;qBACJ,EAAED,KAAAA,CAAM,CAAC,EAAEC,MAAO,CAAA;;;;;;;;AAQjB,sBAAA,EAAED,KAAM,CAAA;;;AAGpB,UAAA,EAAEK,WAAY;;;IAGpB,CAAC;AAED,QAAA,OAAOnL,OAAQ1D,CAAAA,OAAO,CAACiP,MAAAA,CAAOnD,IAAI,CAACiD,GAAAA,CAAAA,CAAAA;AACrC;AAEQD,IAAAA,aAAAA,CAAclH,KAAa,EAAU;AAC3C,QAAA,OAAOA,MACJsH,OAAO,CAAC,MAAM,OACdA,CAAAA,CAAAA,OAAO,CAAC,IAAM,EAAA,MAAA,CAAA,CACdA,OAAO,CAAC,IAAA,EAAM,QACdA,OAAO,CAAC,MAAM,QACdA,CAAAA,CAAAA,OAAO,CAAC,IAAM,EAAA,QAAA,CAAA;AACnB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCO,MAAMC,oBAAuBhO,GAAAA,MAAAA,CAAO,yBAA2B,CAAA;AAU/D,MAAMiO,sBAAAA,CAAAA;AAcX,IAAA,MAAcC,YAA4C,GAAA;AACxD,QAAA,MAAMC,QAAQ,MAAM,IAAI,CAACpC,MAAM,CAAC7F,KAAK,EAAA;QAErC,OAAOiI,KAAAA,CACJ/G,GAAG,CAAC,CAACgH,IAAM,IAAIC,sBAAAA,EAAAA,CAAyB1D,IAAI,CAACyD,CAAAA,CAAEvI,IAAI,CAAE/F,CAAAA,KAAK,IAC1DuG,MAAM,CAAC,CAACH,KAAU,GAAA,CAAC,CAACA,KAAAA,CAAM9G,EAAE,CAAA;AACjC;IAEA,MAAac,IAAAA,CAAKC,GAAkB,EAAqC;QACvE,IAAIK,GAAAA,GAAM,CAAC,cAAc,CAAC;AAC1B,QAAA,IAAI,CAACC,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AACjE,QAAA,MAAMwO,OAAO,IAAIC,IAAAA,EAAAA;AACjB,QAAA,MAAMC,SAAY,GAAA,MAAM,IAAI,CAACN,YAAY,EAAA;AACzC,QAAA,MAAMO,OAAO,IAAIF,IAAAA,EAAAA,CAAOG,OAAO,EAAA,GAAKJ,KAAKI,OAAO,EAAA;QAChDlO,GAAM,GAAA,CAAC,MAAM,EAAEgO,SAAUlN,CAAAA,MAAM,CAAC,0BAA0B,EAAEmN,IAAK,CAAA,aAAa,CAAC;AAC/E,QAAA,IAAI,CAAChO,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAEjE,QAAA,MAAMe,UAAU,IAAIC,+BAAAA,EAAAA,CACjBC,MAAM,CAAC,IAAIC,qBACXlB,KAAK,EAAA;QACR,MAAMmB,MAAAA,GAAS,IAAIC,iBAAAA,CAAkBsN,SAAW3N,EAAAA,OAAAA,CAAAA;AAChD,QAAA,MAAMT,IAAO,GAAA,MAAMa,MAAOG,CAAAA,QAAQ,CAACjB,GAAAA,CAAAA;AACnC,QAAA,MAAMkB,KAAQ,GAAA,MAAMJ,MAAOI,CAAAA,KAAK,CAAClB,GAAAA,CAAAA;QAEjC,OAAO,IAAIoB,eAAiCJ,IAAI,CAACf,MAAMiB,KAAK,CAACA,OAAOvB,KAAK,EAAA;AAC3E;IAEA,MAAc4D,KAAAA,CAAMtE,EAAU,EAAoC;AAChE,QAAA,MAAMoP,SAAY,GAAA,MAAM,IAAI,CAACN,YAAY,EAAA;AACzC,QAAA,MAAMS,QAAQC,SAAUJ,CAAAA,SAAAA,EAAW,CAACK,CAAMA,GAAAA,CAAAA,CAAEzP,EAAE,KAAKA,EAAAA,CAAAA;AAEnD,QAAA,OAAOiB,YAAa,CAAA,IAAA,EAAMmO,SAAS,CAACG,KAAM,CAAA,CAAA;AAC5C;IAEA,MAAanN,GAAAA,CAAIpC,EAAU,EAA6B;AACtD,QAAA,MAAMkP,OAAO,IAAIC,IAAAA,EAAAA;AACjB,QAAA,IAAI7N,MAAM,CAAC,4BAA4B,EAAEtB,EAAAA,CAAG,CAAC,CAAC;AAC9C,QAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;AACjE,QAAA,MAAMoG,KAAQ,GAAA,MAAM,IAAI,CAACxC,KAAK,CAACtE,EAAAA,CAAAA;AAE/B,QAAA,MAAMqP,OAAO,IAAIF,IAAAA,EAAAA,CAAOG,OAAO,EAAA,GAAKJ,KAAKI,OAAO,EAAA;AAEhD,QAAA,IAAIxI,SAAS,IAAM,EAAA;AACjB,YAAA,MAAM1F,MAAM,CAAC,kCAAkC,EAAEpB,EAAAA,CAAG,CAAC,CAAC;AACtDsB,YAAAA,GAAAA,GAAM,GAAGF,GAAI,CAAA,aAAa,EAAEiO,IAAAA,CAAK,aAAa,CAAC;AAC/C,YAAA,IAAI,CAAChO,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmByB,EAAAA,CAAAA,OAAO,EAAG1D,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;AACpE,YAAA,MAAM,IAAIuD,iBAAkB7C,CAAAA,GAAAA,CAAAA;AAC9B;QAEAE,GAAM,GAAA,CAAC,aAAa,EAAEwF,KAAM4I,CAAAA,GAAG,CAAC,OAAO,EAAEL,IAAK,CAAA,aAAa,CAAC;AAC5D,QAAA,IAAI,CAAChO,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;QAEjE,OAAOoG,KAAAA;AACT;AAEA,IAAA,MAAa6I,QAAS3P,CAAAA,EAAU,EAAE4P,MAAc,EAA2B;AACzE,QAAA,MAAMtO,GAAM,GAAA,CAAC,8BAA8B,EAAEtB,EAAI,CAAA,CAAA;AACjD,QAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;AACjE,QAAA,MAAMoG,KAAQ,GAAA,MAAM,IAAI,CAACxC,KAAK,CAACtE,EAAAA,CAAAA;QAC/B,MAAM0P,GAAAA,GAAMzO,YAAa,CAAA,EAAA,EAAI6F,KAAO4I,EAAAA,GAAAA,CAAAA;QACpC,MAAMG,QAAAA,GAAW5O,YAAa,CAAA,EAAA,EAAI6F,KAAO+I,EAAAA,QAAAA,CAAAA;AACzC,QAAA,MAAMC,IAAe1C,GAAAA,WAAAA,CACnB2C,cAAeC,CAAAA,GAAG,EAClBrF,MAAOkF,CAAAA,QAAAA,CAAAA,CAAAA;AAGT,QAAA,MAAMI,UAAUL,MAAOM,CAAAA,KAAK,CAAC,GAAA,CAAA,CAAKlI,GAAG,CAAC,CAACmI,CAAMA,GAAAA,CAAAA,CAAED,KAAK,CAAC,GAAA,CAAI,CAAC,CAAA,CAAE,CAACjD,IAAI,EAAA,CAAA;AAEjE,QAAA,MAAMmD,UAAaH,GAAAA,OAAAA,CAAQ5C,IAAI,CAAC,CAACgD,CAAAA,GAAAA;AAC/B,YAAA,IAAIA,MAAM,KAAO,EAAA;gBACf,OAAO,IAAA;AACT;YACA,IAAIA,CAAAA,CAAEC,QAAQ,CAAC,IAAO,CAAA,EAAA;AACpB,gBAAA,OAAOR,KAAK1I,UAAU,CAACiJ,EAAEE,KAAK,CAAC,GAAG,EAAC,CAAA,CAAA;AACrC;AACA,YAAA,OAAOF,CAAMP,KAAAA,IAAAA;AACf,SAAA,CAAA;AAEA,QAAA,IAAI,CAACM,UAAY,EAAA;AACf,YAAA,MAAMhP,GACJ,GAAA,CAAC,+BAA+B,EAAE0O,IAAK,CAAA,EAAE,CAAC,GAC1C,CAAC,yBAAyB,EAAEF,MAAAA,CAAO,CAAC,CAAC;AACvC,YAAA,IAAI,CAACvO,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBqC,EAAAA,CAAAA,KAAK,EAAGtE,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAClE,YAAA,MAAM,IAAI8P,sBAAuBpP,CAAAA,GAAAA,CAAAA;AACnC;AAEA,QAAA,MAAM4M,QAAW,GAAA,UAAA;;;;AAIf,YAAA,MAAM1M,MAAM,CAAC,OAAO,EAAEtB,EAAAA,CAAG,iCAAiC,CAAC;AAC3D,YAAA,IAAI,CAACqB,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmByB,EAAAA,CAAAA,OAAO,EAAG1D,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;YAEpE,MAAM+P,KAAAA,GAAQzQ,EAAGkQ,CAAAA,KAAK,CAAC,GAAA,CAAA;AACvBO,YAAAA,KAAAA,CAAMC,GAAG,EAAA;YACT,MAAMrQ,IAAAA,GAAOoQ,KAAME,CAAAA,IAAI,CAAC,GAAA,CAAA;AACxB,YAAA,MAAMpO,SAAS,MAAM,IAAI,CAACqO,UAAU,CAAC5C,QAAQ,CAAC3N,IAAAA,CAAAA;YAE9C,OAAOwQ,QAAAA,CAAStF,IAAI,CAAChJ,MAAAA,CAAAA;AACvB,SAAA;AAEA,QAAA,MAAMuO,MAAShK,GAAAA,KAAAA,IAAS,IAAO,GAAA,MAAMkH,aAAa+C,gBAAiBrB,CAAAA,GAAAA,CAAAA;QAEnE,OAAO,IAAIsB,eAAeF,MAAQ,EAAA;YAChC1R,IAAM0Q,EAAAA,IAAAA;YACNmB,WAAa,EAAA,CAAC,iBAAiB,EAAEpB,QAAU,CAAA;AAC7C,SAAA,CAAA;AACF;IAEA,MAAaqB,MAAAA,CAAOlR,EAAU,EAAiB;QAC7C,MAAM,EAAE0P,GAAG,EAAE,GAAG,MAAM,IAAI,CAACtN,GAAG,CAACpC,EAAAA,CAAAA;QAC/B,MAAMmR,IAAAA,GAAOlQ,aAAa,EAAIyO,EAAAA,GAAAA,CAAAA;AAE9B,QAAA,IAAIpO,GAAM,GAAA,CAAC,0BAA0B,EAAE6P,IAAM,CAAA,CAAA;AAC7C,QAAA,IAAI,CAAC9P,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;QAEjE,IAAI;AACF,YAAA,MAAM0Q,MAAOD,CAAAA,IAAAA,CAAAA;AACf,SAAA,CAAE,OAAOvJ,GAAK,EAAA;AACZ,YAAA,MAAM,EAAEtI,OAAO,EAAE,GAAGyD,WAAY6E,CAAAA,GAAAA,CAAAA;AAChC,YAAA,IAAI,CAACvG,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBqC,EAAAA,CAAAA,KAAK,EAAGtE,CAAAA,OAAO,CAACA,OAAAA,CAAAA,CAASoB,KAAK,EAAA,CAAA;AACtE,YAAA,MAAM,IAAI2Q,kBAAmB/R,CAAAA,OAAAA,CAAAA;AAC/B;QAEAgC,GAAM,GAAA,CAAC,QAAQ,EAAEoO,GAAK,CAAA,CAAA;AACtB,QAAA,IAAI,CAACrO,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAACgC,GAAAA,CAAAA,CAAKZ,KAAK,EAAA,CAAA;AACnE;IAzIA,WACE,CACQkQ,UAAqC,EAErCjE,MAAkC,EAE1CxD,MAAgB,CAChB;;;AATF,QAAAjK,kBAAA,CAAA,IAAA,EAAQmC,WAAR,MAAA,CAAA;aAIUuP,UAAAA,GAAAA,UAAAA;aAEAjE,MAAAA,GAAAA,MAAAA;AAIR,QAAA,IAAI,CAACtL,OAAO,GAAG,IAAI6C,eAAe,wBAA0BiF,EAAAA,MAAAA,CAAAA;AAC9D;AAiIF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzKO,MAAMmI,yBAAAA,CAAAA;IA2CJxQ,IAAK,CAASyQ,MAA0B,EAAE;AAC/C,QAAA,MAAMnN,UAAU,IAAIC,mBAAAA,EAAAA,CAAsBC,KAAK,CAACiN,QAAQ7Q,KAAK,EAAA;AAC7D,QAAA,OAAO,IAAI,CAAC8Q,MAAM,CAAC1Q,IAAI,CAACsD,OAAAA,CAAAA;AAC1B;AAEA,IAAA,MA0BahC,IACX,cAA+C,EACxCrB,GAAY,EACnB;AACA,QAAA,MAAM,EAAE6O,MAAS,GAAA,KAAK,EAAE,GAAG7O,IAAI0Q,OAAO;AAEtC,QAAA,OAAO7B,OAAOrC,QAAQ,CAAC,kBACnB,CAAA,GAAA,IAAI,CAACiE,MAAM,CAACpP,GAAG,CAACqC,kBAChB,IAAI,CAAC+M,MAAM,CAAC7B,QAAQ,CAAClL,cAAgBmL,EAAAA,MAAAA,CAAAA;AAC3C;IAEA,MAMasB,MAAAA,CAAO,cAA+C,EAAE;AACnE,QAAA,MAAM,IAAI,CAACM,MAAM,CAACN,MAAM,CAACzM,cAAAA,CAAAA;AAC3B;IA5FA,WACE,CACQ+M,MAA+B,CACvC;;aADQA,MAAAA,GAAAA,MAAAA;AACP;AA0FL;;;QAvFInR,IAAM,EAAA,MAAA;QACNqR,QAAU,EAAA,KAAA;QACVtS,IAAMuS,EAAAA,MAAAA;QACNC,OAAS,EAAA,CAAA;QACTtR,WAAa,EAAA;;;QAGbD,IAAM,EAAA,MAAA;QACNqR,QAAU,EAAA,KAAA;QACVtS,IAAMuS,EAAAA,MAAAA;QACNC,OAAS,EAAA,EAAA;QACTtR,WAAa,EAAA;;;QAGbD,IAAM,EAAA,QAAA;QACNqR,QAAU,EAAA,KAAA;QACVtS,IAAMyS,EAAAA,MAAAA;QACNvR,WAAa,EAAA;;;QAGbD,IAAM,EAAA,MAAA;QACNqR,QAAU,EAAA,KAAA;QACVtS,IAAMyS,EAAAA,MAAAA;QACNvR,WAAa,EAAA;;;QAGbD,IAAM,EAAA,QAAA;QACNqR,QAAU,EAAA,KAAA;QACVtS,IAAMyS,EAAAA,MAAAA;QACNvR,WAAa,EAAA;;;AAGbwR,QAAAA,MAAAA,EAAQC,iBAAiBC,EAAE;QAC3B1R,WAAa,EAAA;;;;;;;;;;;;QASblB,IAAM,EAAA,QAAA;QACNiB,IAAM,EAAA,gBAAA;QACNC,WAAa,EAAA;;;AAGbwR,QAAAA,MAAAA,EAAQC,iBAAiBC,EAAE;QAC3B1R,WAAa,EAAA,mBAAA;QACb2R,OAAS,EAAA;AACP,YAAA,KAAA,EAAO,EAAC;AACR,YAAA,SAAA,EAAW,EAAC;AACZ,YAAA,WAAA,EAAa,EAAC;AACd,YAAA,YAAA,EAAc,EAAC;AACf,YAAA,iBAAA,EAAmB,EAAC;AACpB,YAAA,kBAAA,EAAoB;AACtB;;;AAGAH,QAAAA,MAAAA,EAAQI,gBAAgBC,QAAQ;QAChC7R,WAAa,EAAA;;;AAGbwR,QAAAA,MAAAA,EAAQI,gBAAgBE,aAAa;QACrC9R,WAAa,EAAA;;;;;;;;;;;;;;QAeblB,IAAM,EAAA,QAAA;QACNiB,IAAM,EAAA,gBAAA;QACNC,WAAa,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AClFV,MAAM+R,qBAAAA,CAAAA;AAAuB;;;QAblCpN,OAAS,EAAA;AAACE,YAAAA,aAAAA;AAAesH,YAAAA;AAAsB,SAAA;QAC/CrH,WAAa,EAAA;AAACkM,YAAAA;AAA0B,SAAA;QACxCjM,SAAW,EAAA;AACT,YAAA;gBACEC,OAASwI,EAAAA,6BAAAA;gBACTvI,QAAUwI,EAAAA;AACZ,aAAA;AACA,YAAA;gBACEzI,OAASsJ,EAAAA,oBAAAA;gBACTrJ,QAAUsJ,EAAAA;AACZ;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACHI,MAAMyD,sBAAyB1R,GAAAA,MAAAA,CAAO,2BAA6B,CAAA;AAQnE,MAAM2R,wBAAAA,CAAAA;IAYX,MAAazR,IAAAA,CAAKC,GAAkB,EAAsC;AACxE,QAAA,MAAMC,IAAOC,GAAAA,YAAAA,CAAa,CAAGF,EAAAA,GAAAA,CAAIC,IAAI,CAAA;AACrC,QAAA,MAAME,IAAOD,GAAAA,YAAAA,CAAaE,QAAUJ,EAAAA,GAAAA,CAAIG,IAAI,CAAA;QAC5C,IAAIE,GAAAA,GAAM,CAAC,yBAAyB,EAAEJ,KAAK,aAAa,EAAEE,IAAK,CAAA,CAAC,CAAC;AACjE,QAAA,IAAI,CAACG,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAEjE,QAAA,MAAM8R,YAAY,MAAM,IAAI,CAACnH,kBAAkB,CAACxD,OAAO,EAAA;AACvD,QAAA,MAAMA,OAAUyD,GAAAA,KAAAA,CAAMC,IAAI,CAACiH,UAAU9J,MAAM,EAAA,CAAA;AAE3CtH,QAAAA,GAAAA,GAAM,CAAC,MAAM,EAAEyG,QAAQ3F,MAAM,CAAC,QAAQ,CAAC;AACvC,QAAA,IAAI,CAACb,OAAO,CAACC,GAAG,CAAC,IAAIC,gBAAmBC,EAAAA,CAAAA,IAAI,EAAGlC,CAAAA,OAAO,CAAC8B,GAAAA,CAAAA,CAAKV,KAAK,EAAA,CAAA;AAEjE,QAAA,MAAM+R,gBAAgB,IAAI/Q,+BAAAA,EAAAA,CACvBC,MAAM,CAAC,IAAIC,iBAAkB,CAAA;AAAC,YAAA,IAAA;AAAM,YAAA;AAAO,SAAA,CAAA,CAAA,CAC3ClB,KAAK,EAAA;QAER,MAAMmB,MAAAA,GAAS,IAAIC,iBAAAA,CACjB+F,OACA4K,EAAAA,aAAAA,CAAAA;AAGF,QAAA,MAAM1Q,IAAO,GAAA,MAAMF,MAAOG,CAAAA,QAAQ,CAACjB,GAAAA,CAAAA;AACnC,QAAA,MAAMkB,KAAQ,GAAA,MAAMJ,MAAOI,CAAAA,KAAK,CAAClB,GAAAA,CAAAA;QAEjC,OAAO,IAAIoB,eAAeJ,IAAI,CAACA,MAAME,KAAK,CAACA,OAAOvB,KAAK,EAAA;AACzD;IAEA,MAAa0B,GAAAA,CAAIpC,EAAU,EAA8B;;QAEvD,IAAI,CAAC0K,WAAW1K,EAAK,CAAA,EAAA;AACnB,YAAA,MAAMV,UAAU,CAAC,2BAA2B,EAAEU,EAAAA,CAAG,mBAAmB,CAAC;AACrE,YAAA,MAAM,IAAIiE,iBAAkB3E,CAAAA,OAAAA,CAAAA;AAC9B;QACA,MAAM2H,MAAAA,GAAS,IAAIC,oBAAAA,EAAAA,CAChBC,OAAO,CAAC,IACR0B,CAAAA,CAAAA,KAAK,EACLxB,CAAAA,KAAK,CAACrH,EAAAA,CAAAA,CACNU,KAAK,EAAA;QACR,MAAM0D,OAAAA,GAAU,IAAIC,mBAAsB4C,EAAAA,CAAAA,MAAM,CAACA,MAAQ/F,CAAAA,CAAAA,IAAI,CAAC,CAAA,CAAA,CAAGR,KAAK,EAAA;QAEtE,MAAM,EAAEqB,MAAM8F,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC/G,IAAI,CAACsD,OAAAA,CAAAA;QAC1C,MAAM,CAAC4H,OAAO,GAAGnE,OAAAA;AAEjB,QAAA,IAAImE,UAAU,IAAM,EAAA;AAClB,YAAA,MAAM1M,UAAU,CAAC,kBAAkB,EAAEU,EAAAA,CAAG,gBAAgB,CAAC;AACzD,YAAA,MAAM,IAAIiE,iBAAkB3E,CAAAA,OAAAA,CAAAA;AAC9B;QAEA,OAAO0M,MAAAA;AACT;AA1DA,IAAA,WAAA,CACE,kBACsE,EAE7D7C,MAAgB,CACzB;;;AAPF,QAAAjK,kBAAA,CAAA,IAAA,EAAQmC,WAAR,MAAA,CAAA;aAImBgK,kBAAAA,GAAAA,kBAAAA;aAERlC,MAAAA,GAAAA,MAAAA;AAET,QAAA,IAAI,CAAC9H,OAAO,GAAG,IAAI6C,eAAe,0BAA4BiF,EAAAA,MAAAA,CAAAA;AAChE;AAoDF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnFO,MAAMuJ,2BAAAA,CAAAA;IAOJ5R,IACL,CAASwD,KAAyB,EACE;QACpC,OAAO,IAAI,CAACyD,QAAQ,CAACjH,IAAI,CAAC,IAAIuD,mBAAsBC,EAAAA,CAAAA,KAAK,CAACA,KAAAA,CAAAA,CAAO5D,KAAK,EAAA,CAAA;AACxE;IAQO0B,GAAI,CAAyBqC,cAAsB,EAAE;AAC1D,QAAA,OAAO,IAAI,CAACsD,QAAQ,CAAC3F,GAAG,CAACqC,cAAAA,CAAAA;AAC3B;IApBA,WACE,CACiBsD,QAAmC,CACpD;;aADiBA,QAAAA,GAAAA,QAAAA;AAChB;AAkBL;;;;;;;;;;;;QARI3I,IAAM,EAAA,QAAA;QACNiB,IAAM,EAAA,gBAAA;QACNC,WAAa,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;ACLV,MAAMqS,uBAAAA,CAAAA;AAAyB;;;QAVpC1N,OAAS,EAAA;AAACwH,YAAAA,qBAAAA;AAAuBtH,YAAAA;AAAc,SAAA;QAC/CC,WAAa,EAAA;AAACsN,YAAAA;AAA4B,SAAA;QAC1CrN,SAAW,EAAA;AACT,YAAA;gBACEC,OAASgN,EAAAA,sBAAAA;gBACT/M,QAAUgN,EAAAA;AACZ;AACD,SAAA;QACD/M,OAAS,EAAA;AAAC8M,YAAAA;AAAuB;;;;AClBnC,wCAAqC,SAAA,YAAA,CAAA,UAAA,EAAA,MAAA,EAAA,GAAA,EAAA,IAAA,EAAA;;;;;;AAe9B,MAAMM,gBAAAA,CAAAA;AAAkB;;;QAP7B3N,OAAS,EAAA;AACP0N,YAAAA,uBAAAA;AACA3N,YAAAA,uBAAAA;AACAqN,YAAAA,qBAAAA;AACAxE,YAAAA;AACD;;;;ACTH,MAAMgF,IAAO,GAAA,IAAA;AAEZ,CAAA,iBAAA;AACC,IAAA,MAAMC,GAAM,GAAA,MAAMC,WAAYhT,CAAAA,MAAM,CAAC6S,gBAAAA,CAAAA;AACrCE,IAAAA,GAAAA,CAAIE,eAAe,CAAC,KAAA,CAAA;AACpBF,IAAAA,GAAAA,CAAIG,UAAU,EAAA;AAEd,IAAA,MAAM5Q,MAAS,GAAA,IAAI6Q,eAChBC,EAAAA,CAAAA,QAAQ,CAAC,eAAA,CAAA,CACTC,cAAc,CAAC,mBACfC,CAAAA,CAAAA,UAAU,CAAC,GAAA,CAAA,CACX3S,KAAK,EAAA;AAER,IAAA,MAAM4S,QAAW,GAAA,IAAMC,aAAcC,CAAAA,cAAc,CAACV,GAAKzQ,EAAAA,MAAAA,CAAAA;IACzDkR,aAAcE,CAAAA,KAAK,CAAC,UAAA,EAAYX,GAAKQ,EAAAA,QAAAA,CAAAA;IAErC,MAAMR,GAAAA,CAAIY,MAAM,CAACb,IAAAA,CAAAA;AACnB,CAAA,GAAA"}
1
+ {"version":3,"file":"main.js","sources":["../src/config/config-update.mts","../src/dir/dir.ts","../src/config/config-known.mts","../src/config/configs-service.mts","../src/config/configs-controller.mts","../src/config/configs-module.mts","../src/files/files-repository.mts","../src/files/files-systems-repository.mts","../src/files/files-games-repository.mts","../src/files/files-module.mts","../src/games/games-service.mts","../src/games/games-controller.mts","../src/games/games-module.mts","../src/media/media-generator.mts","../src/media/media-service.mts","../src/media/media-controller.mts","../src/media/media-module.mts","../src/systems/systems-service.mts","../src/systems/systems-controller.mts","../src/systems/systems-module.mts","../src/app/app-module.mts","../src/main.mts"],"sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsDefined, IsNotEmptyObject, IsObject } from \"class-validator\";\n\nexport class ZRomulatorConfigUpdateDto<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n @ApiProperty({ type: \"object\", properties: {} })\n @IsDefined({ message: \"The contents of the config is required\" })\n @IsObject({ message: \"The contents of the config must be an object \" })\n @IsNotEmptyObject()\n contents: T;\n}\n","import { homedir } from \"node:os\";\nimport { resolve } from \"node:path\";\n\nexport abstract class ZDir {\n public static application() {\n return resolve(homedir(), \".zthunworks\", \"romulator\");\n }\n\n public static configs() {\n return resolve(ZDir.application(), \"configs\");\n }\n}\n","import {\n ZRomulatorConfigBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { resolve } from \"node:path\";\nimport { ZDir } from \"../dir/dir.js\";\n\nexport abstract class ZRomulatorConfigKnown {\n public static all() {\n return [ZRomulatorConfigKnown.games()];\n }\n\n private static create(id: ZRomulatorConfigId) {\n const file = resolve(ZDir.configs(), `${id}.json`);\n return new ZRomulatorConfigBuilder().id(id).file(file);\n }\n\n public static games() {\n return ZRomulatorConfigKnown.create(ZRomulatorConfigId.Games)\n .name(\"Game Settings\")\n .description(\"Modify where your games are stored and related settings\")\n .avatar(\"gamepad\")\n .metadata(ZRomulatorConfigGamesMetadata.all())\n .build();\n }\n}\n","import {\n Inject,\n Injectable,\n InternalServerErrorException,\n NotFoundException,\n} from \"@nestjs/common\";\nimport { createError, firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigBuilder } from \"@zthun/romulator-client\";\nimport type { IZRestfulGet, IZRestfulUpdate } from \"@zthun/webigail-rest\";\nimport { find } from \"lodash-es\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { ZRomulatorConfigKnown } from \"./config-known.mjs\";\n\nexport const ZRomulatorConfigsToken = Symbol(\"configs\");\n\nexport interface IZRomulatorConfigsService\n extends IZRestfulUpdate<IZRomulatorConfig>, IZRestfulGet<IZRomulatorConfig> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>>;\n}\n\n@Injectable()\nexport class ZRomulatorConfigsService implements IZRomulatorConfigsService {\n private _logger: IZLogger;\n\n public constructor(@Inject(ZLoggerToken) _logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZRomulatorConfigsService\", _logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorConfig>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving configs page, ${page}, with size, ${size}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const configs = ZRomulatorConfigKnown.all();\n const options = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic<IZRomulatorConfig>(configs, options);\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n msg = `Responding with ${data.length} configs out of ${count} total`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return new ZPageBuilder<IZRomulatorConfig>()\n .data(data)\n .count(count)\n .build();\n }\n\n public async get<T>(\n id: ZRomulatorConfigId,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this._find(id);\n let msg = `Attempting to read the file contents for config, ${id}.`;\n let contents: any = {};\n\n try {\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const buffer = await readFile(config.file);\n const json = buffer.toString(\"utf-8\");\n contents = JSON.parse(json);\n msg = `Finished reading config contents (${buffer.byteLength} bytes)`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n } catch (e) {\n msg = createError(e).message;\n this._logger.log(new ZLogEntryBuilder().warning().message(msg).build());\n }\n\n const result = new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(contents)\n .build();\n\n return Promise.resolve(result as Required<IZRomulatorConfig<T>>);\n }\n\n public async update<T>(\n id: ZRomulatorConfigId,\n record: Pick<IZRomulatorConfig, \"contents\">,\n ): Promise<Required<IZRomulatorConfig<T>>> {\n const config = await this.get<T>(id);\n\n let msg = `Updating config file, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const next = { ...config.contents, ...record.contents };\n const json = JSON.stringify(next);\n\n try {\n await mkdir(dirname(config.file), { recursive: true });\n await writeFile(config.file, json);\n return new ZRomulatorConfigBuilder()\n .copy(config)\n .contents(next)\n .build() as Required<IZRomulatorConfig<T>>;\n } catch (e) {\n const error = createError(e);\n msg = `Unable to write to, ${config.file}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n msg = error.message;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new InternalServerErrorException(error));\n }\n }\n\n private async _find(id: ZRomulatorConfigId): Promise<IZRomulatorConfig> {\n let msg = `Attempting to retrieve config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const configs = ZRomulatorConfigKnown.all();\n const config = find(configs, (c) => c.id === id);\n\n if (config == null) {\n msg = `Could not find config, ${id}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return Promise.reject(new NotFoundException(msg));\n }\n\n msg = `Config, ${id}, found`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n return config;\n }\n}\n","import {\n Body,\n Controller,\n Get,\n Inject,\n Param,\n Patch,\n Query,\n UsePipes,\n ValidationPipe,\n} from \"@nestjs/common\";\nimport { ApiBody, ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type {\n IZRomulatorConfig,\n ZRomulatorConfigId,\n} from \"@zthun/romulator-client\";\nimport { ZRomulatorConfigUpdateDto } from \"./config-update.mjs\";\nimport type { IZRomulatorConfigsService } from \"./configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"./configs-service.mjs\";\n\n@Controller(\"configs\")\nexport class ZRomulatorConfigsController {\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n ) {}\n\n @Get()\n public async list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorConfig>> {\n const request = new ZDataRequestBuilder().query(query).build();\n return this._configs.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @ApiBody({\n type: ZRomulatorConfigUpdateDto,\n })\n @Patch(\":identification\")\n @UsePipes(\n new ValidationPipe({\n transform: true,\n whitelist: true,\n skipMissingProperties: false,\n skipNullProperties: false,\n skipUndefinedProperties: false,\n }),\n )\n public async update(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n @Body() payload: ZRomulatorConfigUpdateDto,\n ): Promise<IZRomulatorConfig> {\n return this._configs.update(identification, payload);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the config\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: ZRomulatorConfigId,\n ): Promise<IZRomulatorConfig> {\n return await this._configs.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsController } from \"./configs-controller.mjs\";\nimport {\n ZRomulatorConfigsService,\n ZRomulatorConfigsToken,\n} from \"./configs-service.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZLoggerModule],\n controllers: [ZRomulatorConfigsController],\n providers: [\n { provide: ZRomulatorConfigsToken, useClass: ZRomulatorConfigsService },\n ],\n exports: [ZRomulatorConfigsToken],\n})\nexport class ZRomulatorConfigsModule {}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport type {\n IZFileRepository,\n IZFileSystemNode,\n IZFileSystemService,\n} from \"@zthun/crumbtrail-fs\";\nimport {\n ZFileRepository,\n ZStreamFile,\n ZStreamFolder,\n} from \"@zthun/crumbtrail-fs\";\nimport { ZFileSystemToken } from \"@zthun/crumbtrail-nest\";\nimport type { ZOptional } from \"@zthun/helpful-fn\";\nimport { createError, detokenize, firstDefined, mib } from \"@zthun/helpful-fn\";\nimport {\n ZDataRequestBuilder,\n ZFilterBinaryBuilder,\n ZFilterCollectionBuilder,\n ZFilterLogicBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport {\n ZRomulatorConfigGamesBuilder,\n ZRomulatorConfigGamesMetadata,\n ZRomulatorConfigId,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { flatten } from \"lodash-es\";\nimport { resolve } from \"node:path\";\nimport { env } from \"node:process\";\nimport type { IZRomulatorConfigsService } from \"../config/configs-service.mjs\";\nimport { ZRomulatorConfigsToken } from \"../config/configs-service.mjs\";\n\nexport const ZRomulatorFilesRepositoryToken = Symbol(\"files-repository\");\n\n/**\n * Represents the repository that you can use to\n * scan the games folder for media, info, games, and systems.\n */\nexport interface IZRomulatorFilesRepository {\n /**\n * The absolute path to the configured games\n * folder.\n *\n * @returns\n * The absolute path to the games folder.\n */\n gamesFolder(): Promise<string>;\n\n /**\n * The path to the media folder.\n *\n * @returns\n * The path to the .media folder inside the\n * games folder.\n */\n mediaFolder(): Promise<string>;\n\n /**\n * The path to the info folder.\n *\n * @returns\n * The path to the .info folder inside the\n * games folder.\n */\n infoFolder(): Promise<string>;\n\n /**\n * Retrieves all media found in the games .media folder.\n *\n * @returns\n * A list of all media found in the game media folder.\n */\n media(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all systems found in the games folder.\n *\n * A system is a root folder that is a slug of a supported\n * system.\n *\n * @returns\n * A list of all system folders found in the games folder.\n */\n systems(): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves all games for the given systems list.\n *\n * @param systems -\n * The list of systems to query games by.\n *\n * @returns\n * A list of file system nodes that represent a game\n * in the system directory.\n */\n games(systems: IZRomulatorSystem[]): Promise<IZFileSystemNode[]>;\n\n /**\n * Retrieves the file that represents the systems info or games info\n * for a given system.\n *\n * @param id -\n * Which info item you want to receive - the root system information\n * or the information for a given game list for an individual system.\n *\n * @returns\n * The node that represents the info json, or null if no such file\n * exists.\n */\n info(id: \"systems\" | ZRomulatorSystemId): Promise<IZFileSystemNode | null>;\n\n /**\n * Reads a file and returns the json representation.\n *\n * @param node -\n * The node to read. If this is falsy, then null is returned.\n *\n * @returns\n * The file contents as json, or null if the contents cannot be read.\n */\n json(node: ZOptional<IZFileSystemNode>): Promise<unknown>;\n\n /**\n * Initializes the file repository.\n */\n init(): Promise<any>;\n\n /**\n * Cleans up internal resources.\n */\n dispose(): Promise<void>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesRepository implements IZRomulatorFilesRepository {\n private static readonly MediaFolderName = \".media\";\n private static readonly InfoFolderName = \".info\";\n\n private _logger: IZLogger;\n private _repository: ZFileRepository = new ZFileRepository();\n private _folderStream = new ZStreamFolder();\n private _fileStream = new ZStreamFile({\n cache: {\n fileSize: BigInt(mib(1)),\n maxFiles: 250,\n },\n });\n\n private _globs: string[];\n private _systems: string[];\n\n public constructor(\n @Inject(ZRomulatorConfigsToken)\n private readonly _configs: IZRomulatorConfigsService,\n @Inject(ZFileSystemToken)\n private readonly _fileSystem: IZFileSystemService,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n const slugs = Object.values(ZRomulatorSystemId);\n this._globs = [\".media/**\", \".info/**\", ...slugs.map((s) => `${s}/*.*`)];\n this._systems = Object.values(ZRomulatorSystemId);\n this._logger = new ZLoggerContext(\"ZRomulatorFilesRepository\", logger);\n }\n\n public async gamesFolder() {\n const config = await this._configs.get(ZRomulatorConfigId.Games);\n const { gamesFolder } = new ZRomulatorConfigGamesBuilder()\n .copy(config.contents)\n .build();\n const { fallback } = ZRomulatorConfigGamesMetadata.gamesFolder();\n const _gamesFolder = firstDefined(fallback.gamesFolder, gamesFolder);\n return detokenize(_gamesFolder, env);\n }\n\n public async mediaFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.MediaFolderName);\n }\n\n public async infoFolder() {\n const gamesFolder = await this.gamesFolder();\n return resolve(gamesFolder, ZRomulatorFilesRepository.InfoFolderName);\n }\n\n public async dispose() {\n await this._repository.reset();\n }\n\n public async init(): Promise<IZFileRepository> {\n const path = await this.gamesFolder();\n\n if (this._repository.path !== path) {\n await this._folderStream.write(await this.mediaFolder());\n await this._folderStream.write(await this.infoFolder());\n await this._repository.initialize(path, this._globs);\n }\n\n return this._repository;\n }\n\n public async media() {\n const repository = await this.init();\n const folder = `${await this.mediaFolder()}/`;\n const request = new ZDataRequestBuilder()\n .filter(\n new ZFilterBinaryBuilder()\n .subject(\"path\")\n .startsWith()\n .value(folder)\n .build(),\n )\n .sort(new ZSortBuilder().ascending(\"path\").build())\n .build();\n\n return repository.retrieve(request);\n }\n\n public async info(id?: \"systems\" | ZRomulatorSystemId) {\n // The info json files are json files that contain arrays of games grouped by systems,\n // or systems.json which describes system information.\n const folder = await this.infoFolder();\n const path = resolve(folder, `${id}.json`);\n\n return this._repository.get(path);\n }\n\n public async json(node: IZFileSystemNode): Promise<unknown> {\n if (node == null) {\n return null;\n }\n\n try {\n const contents = await this._fileStream.read(node.path);\n return JSON.parse(contents.toString());\n } catch (e) {\n const err = createError(e);\n const msg = `Unable to read ${node.path}: ${err.message}`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n return null;\n }\n }\n\n public async systems() {\n // Systems use directories. There's a maximum limit of about 200 systems.\n // Since we don't actually need to read any metadata or scan through thousands\n // of unknown folders, we can use the supported system ids to just grab the\n // systems that we need. Since the file repository does a stat anyway, we can just\n // grab the systems from the file system and it should be fast enough. These are all\n // folders, so we don't even need the stats for them and we can assume folders.\n const games = await this.gamesFolder();\n const folders = this._systems.map((s) => `${s}/`);\n return await this._fileSystem.search(folders, {\n cwd: games,\n stat: false,\n });\n }\n\n public async games(systems: IZRomulatorSystem[]) {\n const repository = await this.init();\n const folder = await this.gamesFolder();\n\n const queries = systems.map((s) => {\n const dir = `${folder}/${s.id}`;\n\n const byExtension = new ZFilterCollectionBuilder()\n .subject(\"extension\")\n .in()\n .values(s.extensions)\n .build();\n const inPath = new ZFilterBinaryBuilder()\n .subject(\"parent\")\n .equal()\n .value(dir)\n .build();\n const filter = new ZFilterLogicBuilder()\n .and()\n .clause(inPath)\n .clause(byExtension)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).build();\n return repository.retrieve(request);\n });\n\n const results = await Promise.all(queries);\n\n return flatten(results);\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type {\n IZRomulatorSystem,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorSystemBuilder } from \"@zthun/romulator-client\";\nimport { castArray } from \"lodash-es\";\nimport { basename } from \"node:path\";\nimport {\n ZRomulatorFilesRepositoryToken,\n type IZRomulatorFilesRepository,\n} from \"./files-repository.mjs\";\n\nexport const ZRomulatorFilesSystemsRepositoryToken = Symbol(\n \"files-systems-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of system.json.\n */\nexport interface IZRomulatorFilesSystemsRepository {\n /**\n * Reads all system entries in the systems.json file and combines\n * them with the existing system list in the games directory\n *\n * @returns\n * A list of all the systems that are in the games\n * directory decorated with the content data in systems.json\n * in the .info directory.\n */\n systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesSystemsRepository implements IZRomulatorFilesSystemsRepository {\n /**\n * Initializes a new instance of this object.\n */\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async systems(): Promise<Map<ZRomulatorSystemId, IZRomulatorSystem>> {\n const info = await this._filesRepository.info(\"systems\");\n const json = await this._filesRepository.json(info);\n const candidates = castArray(firstDefined([], json));\n const folders = await this._filesRepository.systems();\n\n function hasId(candidate: any): candidate is { id: string } {\n return Object.prototype.hasOwnProperty.call(candidate, \"id\");\n }\n\n const entries: [ZRomulatorSystemId, unknown][] = candidates\n .filter((c) => hasId(c))\n .filter((c) => isSystemId(c.id))\n .map((c) => [c.id as ZRomulatorSystemId, c as unknown]);\n\n const lookup = new Map(entries);\n\n const systems = folders\n .map((folder) => folder.path)\n .map((path) => basename(path))\n .filter((slug) => isSystemId(slug))\n .map((slug) =>\n new ZRomulatorSystemBuilder().parse(lookup.get(slug)).id(slug).build(),\n );\n\n return new Map(systems.map((s) => [s.id, s]));\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { ZFileSystemNodeBuilder } from \"@zthun/crumbtrail-fs\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport { isSystemId, ZRomulatorGameBuilder } from \"@zthun/romulator-client\";\nimport { castArray, get, kebabCase, uniq } from \"lodash-es\";\nimport { resolve } from \"path\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"./files-repository.mjs\";\nimport type { IZRomulatorFilesSystemsRepository } from \"./files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"./files-systems-repository.mjs\";\n\nexport const ZRomulatorFilesGamesRepositoryToken = Symbol(\n \"files-games-repository\",\n);\n\n/**\n * A repository responsible for joining IZFileSystemNode objects\n * with the contents of a game list json file.\n */\nexport interface IZRomulatorFilesGamesRepository {\n /**\n * Reads all of the games in the games directory.\n *\n * Game targets are determined by the extensions in system.json.\n *\n * @returns\n * A list of all the games that are in the games\n * directory decorated with the content data in the matching\n * system json file in the .info directory.\n */\n games(): Promise<Map<string, IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorFilesGamesRepository implements IZRomulatorFilesGamesRepository {\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesRepository,\n ) {}\n\n public async games(): Promise<Map<string, IZRomulatorGame>> {\n function hasPath(entry: unknown): entry is { path: string } {\n return typeof get(entry, \"path\") === \"string\";\n }\n\n const gamesFolder = await this._filesRepository.gamesFolder();\n const games: IZRomulatorGame[] = [];\n const systemLookup = await this._systemsRepository.systems();\n const systems = Array.from(systemLookup.values());\n const gameFiles = await this._filesRepository.games(systems);\n const systemsInUse = uniq(gameFiles.map((g) => g.parent))\n .map((dir) => new ZFileSystemNodeBuilder().path(dir).folder().build())\n .map((node) => node.title)\n .filter((title) => isSystemId(title));\n\n const gameInfo = new Map<string, unknown>();\n\n for await (const system of systemsInUse) {\n const info = await this._filesRepository.info(system);\n const json = await this._filesRepository.json(info);\n const gameList = castArray(json).filter((e) => hasPath(e));\n gameList.forEach((entry) => {\n gameInfo.set(resolve(gamesFolder, system, entry.path), entry);\n });\n }\n\n // Variable, gameInfo, now has all of the information data that we need.\n for (const file of gameFiles) {\n const { title, path } = file;\n const { title: systemId } = new ZFileSystemNodeBuilder()\n .path(file.parent)\n .folder()\n .build();\n const id = `${kebabCase(systemId)}-${kebabCase(title)}`;\n const info = gameInfo.get(path);\n\n const game = new ZRomulatorGameBuilder()\n .id(id)\n .system(systemId as ZRomulatorSystemId)\n .file(path)\n .parse(info)\n .build();\n\n games.push(game);\n }\n\n return new Map(games.map((g) => [g.id, g]));\n }\n}\n","import { Inject, Module } from \"@nestjs/common\";\nimport { ZFileSystemModule } from \"@zthun/crumbtrail-nest\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport {\n ZRomulatorFilesGamesRepository,\n ZRomulatorFilesGamesRepositoryToken,\n} from \"./files-games-repository.mjs\";\nimport type { IZRomulatorFilesRepository } from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesRepository,\n ZRomulatorFilesRepositoryToken,\n} from \"./files-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepository,\n ZRomulatorFilesSystemsRepositoryToken,\n} from \"./files-systems-repository.mjs\";\n\n@Module({\n imports: [ZFileSystemModule, ZRomulatorConfigsModule, ZLoggerModule],\n providers: [\n {\n provide: ZRomulatorFilesRepositoryToken,\n useClass: ZRomulatorFilesRepository,\n },\n {\n provide: ZRomulatorFilesSystemsRepositoryToken,\n useClass: ZRomulatorFilesSystemsRepository,\n },\n {\n provide: ZRomulatorFilesGamesRepositoryToken,\n useClass: ZRomulatorFilesGamesRepository,\n },\n ],\n exports: [\n ZRomulatorFilesRepositoryToken,\n ZRomulatorFilesSystemsRepositoryToken,\n ZRomulatorFilesGamesRepositoryToken,\n ],\n})\nexport class ZRomulatorFilesModule {\n public constructor(\n @Inject(ZRomulatorFilesRepositoryToken)\n private readonly _files: IZRomulatorFilesRepository,\n ) {}\n\n public async onModuleInit() {\n await this._files.init();\n }\n\n public async onModuleDestroy() {\n await this._files.dispose();\n }\n}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n ZSortBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type {\n IZRomulatorGame,\n ZRomulatorSystemId,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulGet } from \"@zthun/webigail-rest\";\nimport {\n ZRomulatorFilesGamesRepositoryToken,\n type IZRomulatorFilesGamesRepository,\n} from \"../files/files-games-repository.mjs\";\nimport {\n ZRomulatorFilesSystemsRepositoryToken,\n type IZRomulatorFilesSystemsRepository,\n} from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorGamesToken = Symbol(\"romulator-games-service\");\n\nexport interface IZRomulatorGamesService extends IZRestfulGet<IZRomulatorGame> {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>>;\n}\n\n@Injectable()\nexport class ZRomulatorGamesService implements IZRomulatorGamesService {\n private readonly _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZRomulatorFilesGamesRepositoryToken)\n private readonly _filesRepository: IZRomulatorFilesGamesRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorGamesService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorGame>> {\n const msg = `Searching for games`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systems = await this._systemsRepository.systems();\n const games = await this._filesRepository.games();\n\n const match = (data: IZRomulatorGame, filter: string): boolean => {\n const needle = filter?.trim().toLowerCase();\n const { name = \"\", system = \"\" } = data;\n const systemId = system as ZRomulatorSystemId;\n const systemName = firstTruthy(\"\", systems.get(systemId)?.name);\n\n if (!needle?.length) {\n return true;\n }\n\n return [name, system, systemName]\n .filter((s) => s.length)\n .some((k) => k.toLowerCase().includes(needle));\n };\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorGame>()\n .search({ match })\n .build();\n const source = new ZDataSourceStatic(Array.from(games.values()), options);\n\n const $sort = new ZSortBuilder()\n .sorts(firstDefined([], req.sort))\n .ascending(\"system\")\n .ascending(\"name\")\n .build();\n const $request = new ZDataRequestBuilder().copy(req).sort($sort).build();\n\n const data = await source.retrieve($request);\n const count = await source.count($request);\n\n return new ZPageBuilder().count(count).data(data).build();\n }\n\n public async get(id: string): Promise<IZRomulatorGame> {\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: games } = await this.list(request);\n const [game] = games;\n\n if (game == null) {\n const message = `Game, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return game;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorGame } from \"@zthun/romulator-client\";\nimport type { IZRomulatorGamesService } from \"./games-service.mjs\";\nimport { ZRomulatorGamesToken } from \"./games-service.mjs\";\n\n@Controller(\"games\")\nexport class ZRomulatorGamesController {\n public constructor(\n @Inject(ZRomulatorGamesToken)\n private readonly _games: IZRomulatorGamesService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorGame>> {\n return this._games.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._games.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorGamesController } from \"./games-controller.mjs\";\nimport {\n ZRomulatorGamesService,\n ZRomulatorGamesToken,\n} from \"./games-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorGamesController],\n providers: [\n {\n provide: ZRomulatorGamesToken,\n useClass: ZRomulatorGamesService,\n },\n ],\n})\nexport class ZRomulatorGamesModule {}\n","import { Injectable } from \"@nestjs/common\";\nimport { html } from \"@zthun/helpful-fn\";\n\n/**\n * The injection token for the media generator.\n */\nexport const ZRomulatorMediaGeneratorToken = Symbol(\"media-generator\");\n\n/**\n * A generator that generates in memory media for systems and\n * games that have their media missing.\n */\nexport interface IZRomulatorMediaGenerator {\n /**\n * Generates a wheel image with a given name.\n *\n * A wheel is 373x187 pixels. It'll have a transparent background\n * with the name in uppercase It will display the name\n * in the middle of the wheel image. It assumes it will live on a\n * dark background so the name will be white.\n *\n * @param name -\n * The name to place in the middle of the wheel image.\n *\n * @returns\n * A buffer with the generated wheel.\n */\n generate(name: string): Promise<Buffer>;\n}\n\n/**\n * An implementation of the ZRomulatorMediaGenerator.\n */\n@Injectable()\nexport class ZRomulatorMediaGenerator implements IZRomulatorMediaGenerator {\n public generate(name: string): Promise<Buffer> {\n const width = 373;\n const height = 187;\n const fallbackName = name?.trim().length ? name.trim() : \"?\";\n const uppercaseName = fallbackName.toUpperCase();\n const escapedName = this.escapeSvgText(uppercaseName);\n\n const svg = html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"${width}\"\n height=\"${height}\"\n viewBox=\"0 0 ${width} ${height}\"\n >\n <text\n x=\"50%\"\n y=\"50%\"\n fill=\"#fff\"\n font-size=\"48\"\n text-anchor=\"middle\"\n textLength=\"${width}\"\n lengthAdjust=\"spacingAndGlyphs\"\n >\n ${escapedName}\n </text>\n </svg>\n `;\n\n return Promise.resolve(Buffer.from(svg));\n }\n\n private escapeSvgText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n }\n}\n","import {\n ForbiddenException,\n Inject,\n Injectable,\n NotAcceptableException,\n NotFoundException,\n StreamableFile,\n} from \"@nestjs/common\";\nimport { createError, firstDefined, firstTruthy } from \"@zthun/helpful-fn\";\nimport {\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZPageBuilder,\n type IZDataRequest,\n type IZPage,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport {\n ZRomulatorMediaBuilder,\n type IZRomulatorMedia,\n} from \"@zthun/romulator-client\";\nimport type { IZRestfulDelete, IZRestfulGet } from \"@zthun/webigail-rest\";\nimport { ZMimeTypeImage } from \"@zthun/webigail-url\";\nimport { findIndex } from \"lodash-es\";\nimport { lookup } from \"mime-types\";\nimport { createReadStream } from \"node:fs\";\nimport { unlink } from \"node:fs/promises\";\nimport { Readable } from \"node:stream\";\nimport type { IZRomulatorFilesRepository } from \"../files/files-repository.mjs\";\nimport { ZRomulatorFilesRepositoryToken } from \"../files/files-repository.mjs\";\nimport type { IZRomulatorMediaGenerator } from \"./media-generator.mjs\";\nimport { ZRomulatorMediaGeneratorToken } from \"./media-generator.mjs\";\n\nexport const ZRomulatorMediaToken = Symbol(\"romulator-media-service\");\n\nexport interface IZRomulatorMediaService\n extends IZRestfulGet<IZRomulatorMedia>, IZRestfulDelete {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>>;\n download(id: string, accept: string): Promise<StreamableFile>;\n}\n\n@Injectable()\nexport class ZRomulatorMediaService implements IZRomulatorMediaService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorMediaGeneratorToken)\n private _generator: IZRomulatorMediaGenerator,\n @Inject(ZRomulatorFilesRepositoryToken)\n private _files: IZRomulatorFilesRepository,\n @Inject(ZLoggerToken)\n logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorMediaService\", logger);\n }\n\n private async findAllMedia(): Promise<IZRomulatorMedia[]> {\n const files = await this._files.media();\n\n return files\n .map((f) => new ZRomulatorMediaBuilder().from(f.path).build())\n .filter((media) => !!media.id);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorMedia>> {\n let msg = `Querying media`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n const time = new Date();\n const mediaList = await this.findAllMedia();\n const span = new Date().getTime() - time.getTime();\n msg = `Found ${mediaList.length} media files. Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const options = new ZDataSourceStaticOptionsBuilder<IZRomulatorMedia>()\n .search(new ZDataSearchFields())\n .build();\n const source = new ZDataSourceStatic(mediaList, options);\n const page = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder<IZRomulatorMedia>().data(page).count(count).build();\n }\n\n private async query(id: string): Promise<IZRomulatorMedia | null> {\n const mediaList = await this.findAllMedia();\n const index = findIndex(mediaList, (m) => m.id === id);\n\n return firstDefined(null, mediaList[index]);\n }\n\n public async get(id: string): Promise<IZRomulatorMedia> {\n const time = new Date();\n let log = `Searching for media with id ${id}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n\n const span = new Date().getTime() - time.getTime();\n\n if (media == null) {\n const msg = `Could not find any media with id, ${id}.`;\n log = `${msg} Search took ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n throw new NotFoundException(msg);\n }\n\n log = `Found media, ${media.url} after ${span} milliseconds`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n return media;\n }\n\n public async download(id: string, accept: string): Promise<StreamableFile> {\n const log = `Download request received for ${id}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n const media = await this.query(id);\n const url = firstDefined(\"\", media?.url);\n const fileName = firstDefined(\"\", media?.fileName);\n const mime: string = firstTruthy(\n ZMimeTypeImage.SVG,\n lookup(fileName),\n ) as string;\n\n const accepts = accept.split(\",\").map((h) => h.split(\";\")[0].trim());\n\n const acceptable = accepts.some((a) => {\n if (a === \"*/*\") {\n return true;\n }\n if (a.endsWith(\"/*\")) {\n return mime.startsWith(a.slice(0, -1));\n }\n return a === mime;\n });\n\n if (!acceptable) {\n const msg =\n `The media requested is of type ${mime}. ` +\n `The request only accepts ${accept}.`;\n this._logger.log(new ZLogEntryBuilder().error().message(msg).build());\n throw new NotAcceptableException(msg);\n }\n\n const generate = async () => {\n // Note that this isn't perfect and is just a fallback to a wheel + marquee for now.\n // When we get to retrieving other media besides wheels, we will generate\n // everything, but for now, this will be fine enough.\n const log = `Media, ${id}, does not exist. Generating one`;\n this._logger.log(new ZLogEntryBuilder().warning().message(log).build());\n\n const parts = id.split(\"-\");\n parts.pop();\n const name = parts.join(\" \");\n const buffer = await this._generator.generate(name);\n\n return Readable.from(buffer);\n };\n\n const stream = media == null ? await generate() : createReadStream(url);\n\n return new StreamableFile(stream, {\n type: mime,\n disposition: `inline; filename=${fileName}`,\n });\n }\n\n public async delete(id: string): Promise<void> {\n const { url } = await this.get(id);\n const _url = firstDefined(\"\", url);\n\n let log = `Attempting to delete file ${_url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n\n try {\n await unlink(_url);\n } catch (err) {\n const { message } = createError(err);\n this._logger.log(new ZLogEntryBuilder().error().message(message).build());\n throw new ForbiddenException(message);\n }\n\n log = `Deleted ${url}`;\n this._logger.log(new ZLogEntryBuilder().info().message(log).build());\n }\n}\n","import {\n Controller,\n Delete,\n Get,\n Inject,\n Param,\n Query,\n Req,\n} from \"@nestjs/common\";\nimport { ApiParam, ApiQuery, ApiResponse, ApiTags } from \"@nestjs/swagger\";\nimport {\n ZDataRequestBuilder,\n type IZDataRequestQuery,\n} from \"@zthun/helpful-query\";\nimport { ZHttpCodeClient, ZHttpCodeSuccess } from \"@zthun/webigail-http\";\nimport type { Request } from \"express\";\nimport type { IZRomulatorMediaService } from \"./media-service.mjs\";\nimport { ZRomulatorMediaToken } from \"./media-service.mjs\";\n\n@ApiTags(\"Media\")\n@Controller(\"media\")\nexport class ZRomulatorMediaController {\n public constructor(\n @Inject(ZRomulatorMediaToken)\n private _media: IZRomulatorMediaService,\n ) {}\n\n @ApiQuery({\n name: \"page\",\n required: false,\n type: Number,\n example: 1,\n description: \"Page number (1-based)\",\n })\n @ApiQuery({\n name: \"size\",\n required: false,\n type: Number,\n example: 20,\n description: \"Items per page. Defaults to Infinity\",\n })\n @ApiQuery({\n name: \"search\",\n required: false,\n type: String,\n description: \"Search query\",\n })\n @ApiQuery({\n name: \"sort\",\n required: false,\n type: String,\n description: \"Sort criterion\",\n })\n @ApiQuery({\n name: \"filter\",\n required: false,\n type: String,\n description: \"Filter criterion\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the requested page of media and the total count\",\n })\n @Get()\n public list(@Query() params: IZDataRequestQuery) {\n const request = new ZDataRequestBuilder().query(params).build();\n return this._media.list(request);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @ApiResponse({\n status: ZHttpCodeSuccess.OK,\n description: \"Returns the media\",\n content: {\n \"*/*\": {},\n \"image/*\": {},\n \"image/png\": {},\n \"image/jpeg\": {},\n \"application/mp4\": {},\n \"application/json\": {},\n },\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotFound,\n description: \"Media not found\",\n })\n @ApiResponse({\n status: ZHttpCodeClient.NotAcceptable,\n description: \"Unsupported Accept header\",\n })\n @Get(\":identification\")\n public async get(\n @Param(\"identification\") identification: string,\n @Req() req: Request,\n ) {\n const { accept = \"*/*\" } = req.headers;\n\n return accept.includes(\"application/json\")\n ? this._media.get(identification)\n : this._media.download(identification, accept);\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the media\",\n })\n @Delete(\":identification\")\n public async delete(@Param(\"identification\") identification: string) {\n await this._media.delete(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorMediaController } from \"./media-controller.mjs\";\nimport {\n ZRomulatorMediaGenerator,\n ZRomulatorMediaGeneratorToken,\n} from \"./media-generator.mjs\";\nimport {\n ZRomulatorMediaService,\n ZRomulatorMediaToken,\n} from \"./media-service.mjs\";\n\n@Module({\n imports: [ZLoggerModule, ZRomulatorFilesModule],\n controllers: [ZRomulatorMediaController],\n providers: [\n {\n provide: ZRomulatorMediaGeneratorToken,\n useClass: ZRomulatorMediaGenerator,\n },\n {\n provide: ZRomulatorMediaToken,\n useClass: ZRomulatorMediaService,\n },\n ],\n})\nexport class ZRomulatorMediaModule {}\n","import { Inject, Injectable, NotFoundException } from \"@nestjs/common\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZPage } from \"@zthun/helpful-query\";\nimport {\n ZDataRequestBuilder,\n ZDataSearchFields,\n ZDataSourceStatic,\n ZDataSourceStaticOptionsBuilder,\n ZFilterBinaryBuilder,\n ZPageBuilder,\n} from \"@zthun/helpful-query\";\nimport {\n ZLogEntryBuilder,\n ZLoggerContext,\n type IZLogger,\n} from \"@zthun/lumberjacky-log\";\nimport { ZLoggerToken } from \"@zthun/lumberjacky-nest\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport { isSystemId } from \"@zthun/romulator-client\";\nimport type { IZRomulatorFilesSystemsRepository } from \"../files/files-systems-repository.mjs\";\nimport { ZRomulatorFilesSystemsRepositoryToken } from \"../files/files-systems-repository.mjs\";\n\nexport const ZRomulatorSystemsToken = Symbol(\"romulator-systems-service\");\n\nexport interface IZRomulatorSystemsService {\n list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>>;\n get(id: string): Promise<IZRomulatorSystem>;\n}\n\n@Injectable()\nexport class ZRomulatorSystemsService implements IZRomulatorSystemsService {\n private _logger: IZLogger;\n\n public constructor(\n @Inject(ZRomulatorFilesSystemsRepositoryToken)\n private readonly _systemsRepository: IZRomulatorFilesSystemsRepository,\n @Inject(ZLoggerToken)\n readonly logger: IZLogger,\n ) {\n this._logger = new ZLoggerContext(\"ZRomulatorSystemsService\", logger);\n }\n\n public async list(req: IZDataRequest): Promise<IZPage<IZRomulatorSystem>> {\n const page = firstDefined(1, req.page);\n const size = firstDefined(Infinity, req.size);\n let msg = `Retrieving systems page, ${page}, with size, ${size}.`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const systemMap = await this._systemsRepository.systems();\n const systems = Array.from(systemMap.values());\n\n msg = `Found ${systems.length} systems`;\n this._logger.log(new ZLogEntryBuilder().info().message(msg).build());\n\n const sourceOptions = new ZDataSourceStaticOptionsBuilder()\n .search(new ZDataSearchFields([\"id\", \"name\"]))\n .build();\n\n const source = new ZDataSourceStatic<IZRomulatorSystem>(\n systems,\n sourceOptions,\n );\n\n const data = await source.retrieve(req);\n const count = await source.count(req);\n\n return new ZPageBuilder().data(data).count(count).build();\n }\n\n public async get(id: string): Promise<IZRomulatorSystem> {\n // The system path should be the slug itself.\n if (!isSystemId(id)) {\n const message = `The specified system slug, ${id}, is not supported.`;\n throw new NotFoundException(message);\n }\n const filter = new ZFilterBinaryBuilder()\n .subject(\"id\")\n .equal()\n .value(id)\n .build();\n const request = new ZDataRequestBuilder().filter(filter).size(1).build();\n\n const { data: systems } = await this.list(request);\n const [system] = systems;\n\n if (system == null) {\n const message = `System with slug, ${id}, was not found.`;\n throw new NotFoundException(message);\n }\n\n return system;\n }\n}\n","import { Controller, Get, Inject, Param, Query } from \"@nestjs/common\";\nimport { ApiParam } from \"@nestjs/swagger\";\nimport type { IZDataRequestQuery, IZPage } from \"@zthun/helpful-query\";\nimport { ZDataRequestBuilder } from \"@zthun/helpful-query\";\nimport type { IZRomulatorSystem } from \"@zthun/romulator-client\";\nimport type { IZRomulatorSystemsService } from \"./systems-service.mjs\";\nimport { ZRomulatorSystemsToken } from \"./systems-service.mjs\";\n\n@Controller(\"systems\")\nexport class ZRomulatorSystemsController {\n public constructor(\n @Inject(ZRomulatorSystemsToken)\n private readonly _systems: IZRomulatorSystemsService,\n ) {}\n\n @Get()\n public list(\n @Query() query: IZDataRequestQuery,\n ): Promise<IZPage<IZRomulatorSystem>> {\n return this._systems.list(new ZDataRequestBuilder().query(query).build());\n }\n\n @ApiParam({\n type: \"string\",\n name: \"identification\",\n description: \"The id of the system\",\n })\n @Get(\":identification\")\n public get(@Param(\"identification\") identification: string) {\n return this._systems.get(identification);\n }\n}\n","import { Module } from \"@nestjs/common\";\nimport { ZLoggerModule } from \"@zthun/lumberjacky-nest\";\nimport { ZRomulatorFilesModule } from \"../files/files-module.mjs\";\nimport { ZRomulatorSystemsController } from \"./systems-controller.mjs\";\nimport {\n ZRomulatorSystemsService,\n ZRomulatorSystemsToken,\n} from \"./systems-service.mjs\";\n\n@Module({\n imports: [ZRomulatorFilesModule, ZLoggerModule],\n controllers: [ZRomulatorSystemsController],\n providers: [\n {\n provide: ZRomulatorSystemsToken,\n useClass: ZRomulatorSystemsService,\n },\n ],\n exports: [ZRomulatorSystemsToken],\n})\nexport class ZRomulatorSystemsModule {}\n","/* istanbul ignore file -- @preserve */\nimport { Module } from \"@nestjs/common\";\nimport { ZRomulatorConfigsModule } from \"../config/configs-module.mjs\";\nimport { ZRomulatorGamesModule } from \"../games/games-module.mjs\";\nimport { ZRomulatorMediaModule } from \"../media/media-module.mjs\";\nimport { ZRomulatorSystemsModule } from \"../systems/systems-module.mjs\";\n\n@Module({\n imports: [\n ZRomulatorSystemsModule,\n ZRomulatorConfigsModule,\n ZRomulatorMediaModule,\n ZRomulatorGamesModule,\n ],\n})\nexport class ZRomulatorModule {}\n","import { NestFactory } from \"@nestjs/core\";\nimport { DocumentBuilder, SwaggerModule } from \"@nestjs/swagger\";\nimport { ZRomulatorModule } from \"./app/app-module.mjs\";\n\nconst PORT = 3000;\n\n(async function () {\n const app = await NestFactory.create(ZRomulatorModule);\n app.setGlobalPrefix(\"api\");\n app.enableCors();\n\n const config = new DocumentBuilder()\n .setTitle(\"Romulator API\")\n .setDescription(\"The Romulator API\")\n .setVersion(\"1\")\n .build();\n\n const document = () => SwaggerModule.createDocument(app, config);\n SwaggerModule.setup(\"api/docs\", app, document);\n\n await app.listen(PORT);\n})();\n"],"names":["ZRomulatorConfigUpdateDto","_define_property","contents","type","properties","message","ZDir","application","resolve","homedir","configs","ZRomulatorConfigKnown","all","games","create","id","file","ZRomulatorConfigBuilder","ZRomulatorConfigId","Games","name","description","avatar","metadata","ZRomulatorConfigGamesMetadata","build","ZRomulatorConfigsToken","Symbol","ZRomulatorConfigsService","list","req","page","firstDefined","size","Infinity","msg","_logger","log","ZLogEntryBuilder","info","options","ZDataSourceStaticOptionsBuilder","search","ZDataSearchFields","source","ZDataSourceStatic","data","retrieve","count","length","ZPageBuilder","get","config","_find","buffer","readFile","json","toString","JSON","parse","byteLength","e","createError","warning","result","copy","Promise","update","record","next","stringify","mkdir","dirname","recursive","writeFile","error","reject","InternalServerErrorException","find","c","NotFoundException","ZLoggerContext","ZRomulatorConfigsController","request","ZDataRequestBuilder","query","_configs","payload","identification","ValidationPipe","transform","whitelist","skipMissingProperties","skipNullProperties","skipUndefinedProperties","ZRomulatorConfigsModule","imports","ZFileSystemModule","ZLoggerModule","controllers","providers","provide","useClass","exports","ZRomulatorFilesRepositoryToken","ZRomulatorFilesRepository","gamesFolder","ZRomulatorConfigGamesBuilder","fallback","_gamesFolder","detokenize","env","mediaFolder","MediaFolderName","infoFolder","InfoFolderName","dispose","_repository","reset","init","path","_folderStream","write","initialize","_globs","media","repository","folder","filter","ZFilterBinaryBuilder","subject","startsWith","value","sort","ZSortBuilder","ascending","node","_fileStream","read","err","systems","folders","_systems","map","s","_fileSystem","cwd","stat","queries","dir","byExtension","ZFilterCollectionBuilder","in","values","extensions","inPath","equal","ZFilterLogicBuilder","and","clause","results","flatten","logger","ZFileRepository","ZStreamFolder","ZStreamFile","cache","fileSize","BigInt","mib","maxFiles","slugs","Object","ZRomulatorSystemId","ZRomulatorFilesSystemsRepositoryToken","ZRomulatorFilesSystemsRepository","_filesRepository","candidates","castArray","hasId","candidate","prototype","hasOwnProperty","call","entries","isSystemId","lookup","Map","basename","slug","ZRomulatorSystemBuilder","ZRomulatorFilesGamesRepositoryToken","ZRomulatorFilesGamesRepository","hasPath","entry","systemLookup","_systemsRepository","Array","from","gameFiles","systemsInUse","uniq","g","parent","ZFileSystemNodeBuilder","title","gameInfo","system","gameList","forEach","set","systemId","kebabCase","game","ZRomulatorGameBuilder","push","ZRomulatorFilesModule","onModuleInit","_files","onModuleDestroy","ZRomulatorGamesToken","ZRomulatorGamesService","match","needle","trim","toLowerCase","systemName","firstTruthy","some","k","includes","$sort","sorts","$request","ZRomulatorGamesController","_games","ZRomulatorGamesModule","ZRomulatorMediaGeneratorToken","ZRomulatorMediaGenerator","generate","width","height","fallbackName","uppercaseName","toUpperCase","escapedName","escapeSvgText","svg","html","Buffer","replace","ZRomulatorMediaToken","ZRomulatorMediaService","findAllMedia","files","f","ZRomulatorMediaBuilder","time","Date","mediaList","span","getTime","index","findIndex","m","url","download","accept","fileName","mime","ZMimeTypeImage","SVG","accepts","split","h","acceptable","a","endsWith","slice","NotAcceptableException","parts","pop","join","_generator","Readable","stream","createReadStream","StreamableFile","disposition","delete","_url","unlink","ForbiddenException","ZRomulatorMediaController","params","_media","headers","required","Number","example","String","status","ZHttpCodeSuccess","OK","content","ZHttpCodeClient","NotFound","NotAcceptable","ZRomulatorMediaModule","ZRomulatorSystemsToken","ZRomulatorSystemsService","systemMap","sourceOptions","ZRomulatorSystemsController","ZRomulatorSystemsModule","ZRomulatorModule","PORT","app","NestFactory","setGlobalPrefix","enableCors","DocumentBuilder","setTitle","setDescription","setVersion","document","SwaggerModule","createDocument","setup","listen"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zthun/romulator-api",
3
- "version": "1.18.2",
3
+ "version": "1.18.3",
4
4
  "description": "A service for your rom directory for managing media and the directory structure.",
5
5
  "author": "Anthony Bonta",
6
6
  "license": "MIT",
@@ -21,41 +21,42 @@
21
21
  "access": "public"
22
22
  },
23
23
  "dependencies": {
24
- "@nestjs/common": "^11.1.8",
25
- "@nestjs/core": "^11.1.8",
26
- "@nestjs/platform-express": "^11.1.8",
27
- "@nestjs/swagger": "^11.2.1",
28
- "@zthun/crumbtrail-fs": "^2.4.1",
29
- "@zthun/crumbtrail-nest": "^2.4.1",
30
- "@zthun/helpful-fn": "^9.11.0",
31
- "@zthun/helpful-query": "^9.11.0",
32
- "@zthun/helpful-reflection": "^9.11.0",
33
- "@zthun/lumberjacky-log": "^4.0.1",
34
- "@zthun/lumberjacky-nest": "^4.0.1",
35
- "@zthun/romulator-client": "^1.18.2",
36
- "@zthun/webigail-http": "^5.0.1",
37
- "@zthun/webigail-rest": "^5.0.1",
38
- "@zthun/webigail-url": "^5.0.1",
24
+ "@nestjs/common": "^11.1.11",
25
+ "@nestjs/core": "^11.1.11",
26
+ "@nestjs/platform-express": "^11.1.11",
27
+ "@nestjs/swagger": "^11.2.3",
28
+ "@zthun/crumbtrail-fs": "^2.4.4",
29
+ "@zthun/crumbtrail-nest": "^2.4.4",
30
+ "@zthun/helpful-fn": "^9.11.2",
31
+ "@zthun/helpful-query": "^9.11.3",
32
+ "@zthun/helpful-reflection": "^9.11.2",
33
+ "@zthun/lumberjacky-log": "^4.0.3",
34
+ "@zthun/lumberjacky-nest": "^4.0.3",
35
+ "@zthun/romulator-client": "^1.18.3",
36
+ "@zthun/webigail-http": "^5.0.3",
37
+ "@zthun/webigail-rest": "^5.0.4",
38
+ "@zthun/webigail-url": "^5.0.3",
39
39
  "class-transformer": "^0.5.1",
40
- "class-validator": "^0.14.2",
41
- "express": "^5.1.0",
40
+ "class-validator": "^0.14.3",
41
+ "express": "^5.2.1",
42
42
  "helmet": "^8.1.0",
43
- "lodash-es": "^4.17.21",
44
- "mime-types": "^3.0.1",
43
+ "lodash-es": "^4.17.22",
44
+ "mime-types": "^3.0.2",
45
45
  "reflect-metadata": "^0.2.2",
46
46
  "rxjs": "^7.8.2"
47
47
  },
48
48
  "devDependencies": {
49
- "@nestjs/cli": "^11.0.10",
50
- "@nestjs/testing": "^11.1.8",
51
- "@types/express": "^5.0.5",
49
+ "@nestjs/cli": "^11.0.14",
50
+ "@nestjs/testing": "^11.1.11",
51
+ "@types/express": "^5.0.6",
52
52
  "@types/mime-types": "^3.0.1",
53
- "@zthun/janitor-build-config": "^19.4.2",
53
+ "@zthun/janitor-build-config": "^19.5.4",
54
+ "@zthun/janitor-ts-config": "^19.5.3",
54
55
  "supertest": "^7.1.4",
55
- "tsx": "^4.20.6",
56
+ "tsx": "^4.21.0",
56
57
  "typescript": "^5.9.3",
57
- "vite": "^7.2.1",
58
- "vitest": "^4.0.7",
58
+ "vite": "^7.3.0",
59
+ "vitest": "^4.0.16",
59
60
  "vitest-mock-extended": "^3.1.0"
60
61
  },
61
62
  "files": [
@@ -63,5 +64,5 @@
63
64
  "assets"
64
65
  ],
65
66
  "sideEffects": false,
66
- "gitHead": "84056c393e5de707ef0e0f14b26c3bc34fd238d9"
67
+ "gitHead": "71edc74d72d566881b161224dfe5e7f1271cca0b"
67
68
  }