@zthun/romulator-api 1.10.0 → 1.11.0

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.js CHANGED
@@ -3,18 +3,17 @@ import { ApiProperty, ApiParam, ApiBody, ApiQuery, ApiResponse, ApiTags, Documen
3
3
  import { InternalServerErrorException, NotFoundException, Injectable, Inject, Get, Query, Patch, UsePipes, ValidationPipe, Param, Body, Controller, Module, NotAcceptableException, StreamableFile, ForbiddenException, Req, Delete } from '@nestjs/common';
4
4
  import { ZFileSystemModule, ZFileSystemToken } from '@zthun/crumbtrail-nest';
5
5
  import { ZLoggerToken, ZLoggerModule } from '@zthun/lumberjacky-nest';
6
- import { ZDataSourceStaticOptionsBuilder, ZDataSearchFields, ZDataSourceStatic, ZPageBuilder, ZDataRequestBuilder, ZSortBuilder, ZFilterBinaryBuilder } from '@zthun/helpful-query';
6
+ import { ZDataSourceStaticOptionsBuilder, ZDataSearchFields, ZDataSourceStatic, ZPageBuilder, ZDataRequestBuilder, ZFilterBinaryBuilder, ZSortBuilder, ZFilterCollectionBuilder, ZFilterLogicBuilder } from '@zthun/helpful-query';
7
7
  import { IsDefined, IsObject, IsNotEmptyObject } from 'class-validator';
8
- import { firstDefined, createError, detokenize, firstTruthy, mib, html } from '@zthun/helpful-fn';
9
- import { ZLoggerContext, ZLogEntryBuilder } from '@zthun/lumberjacky-log';
10
- import { ZRomulatorConfigBuilder, ZRomulatorConfigId as ZRomulatorConfigId$1, ZRomulatorConfigGamesMetadata, ZRomulatorSystemBuilder, ZRomulatorSystemId, ZRomulatorConfigGamesBuilder, ZRomulatorGameBuilder, isSystemId, ZRomulatorMediaBuilder } from '@zthun/romulator-client';
11
- import { find, kebabCase, first, castArray, findIndex } from 'lodash-es';
8
+ import { firstDefined, createError, detokenize, mib, firstTruthy, html } from '@zthun/helpful-fn';
9
+ import { ZLogEntryBuilder, ZLoggerContext } from '@zthun/lumberjacky-log';
10
+ import { ZRomulatorConfigBuilder, ZRomulatorConfigId as ZRomulatorConfigId$1, ZRomulatorConfigGamesMetadata, ZRomulatorConfigGamesBuilder, ZRomulatorSystemId, isSystemId, ZRomulatorSystemBuilder, ZRomulatorGameBuilder, ZRomulatorMediaBuilder } from '@zthun/romulator-client';
11
+ import { find, trimStart, flatten, castArray, uniq, kebabCase, get, findIndex } from 'lodash-es';
12
12
  import { readFile, mkdir, writeFile, unlink } from 'node:fs/promises';
13
- import { resolve, dirname, basename, parse } from 'node:path';
13
+ import { resolve, dirname, basename } from 'node:path';
14
14
  import { homedir } from 'node:os';
15
- import { isTagged, ZTag } from '@zthun/helpful-reflection';
16
- import 'reflect-metadata';
17
- import { ZFileRepository, ZStreamFolder, ZStreamFile } from '@zthun/crumbtrail-fs';
15
+ import { ZFileRepository, ZStreamFolder, ZStreamFile, ZFileSystemNodeBuilder } from '@zthun/crumbtrail-fs';
16
+ import { resolve as resolve$1 } from 'path';
18
17
  import { env } from 'node:process';
19
18
  import { ZHttpCodeSuccess, ZHttpCodeClient } from '@zthun/webigail-http';
20
19
  import { ZMimeTypeImage } from '@zthun/webigail-url';
@@ -22,6 +21,19 @@ import { lookup } from 'mime-types';
22
21
  import { createReadStream } from 'node:fs';
23
22
  import { Readable } from 'node:stream';
24
23
 
24
+ function _define_property$c(obj, key, value) {
25
+ if (key in obj) {
26
+ Object.defineProperty(obj, key, {
27
+ value: value,
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true
31
+ });
32
+ } else {
33
+ obj[key] = value;
34
+ }
35
+ return obj;
36
+ }
25
37
  function _ts_decorate$i(decorators, target, key, desc) {
26
38
  var c = arguments.length, r = c < 3 ? target : desc, d;
27
39
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -32,7 +44,9 @@ function _ts_metadata$c(k, v) {
32
44
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
33
45
  }
34
46
  class ZRomulatorConfigUpdateDto {
35
- contents;
47
+ constructor(){
48
+ _define_property$c(this, "contents", void 0);
49
+ }
36
50
  }
37
51
  _ts_decorate$i([
38
52
  ApiProperty({
@@ -73,6 +87,19 @@ class ZRomulatorConfigKnown {
73
87
  }
74
88
  }
75
89
 
90
+ function _define_property$b(obj, key, value) {
91
+ if (key in obj) {
92
+ Object.defineProperty(obj, key, {
93
+ value: value,
94
+ enumerable: true,
95
+ configurable: true,
96
+ writable: true
97
+ });
98
+ } else {
99
+ obj[key] = value;
100
+ }
101
+ return obj;
102
+ }
76
103
  function _ts_decorate$h(decorators, target, key, desc) {
77
104
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
78
105
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -82,17 +109,13 @@ function _ts_decorate$h(decorators, target, key, desc) {
82
109
  function _ts_metadata$b(k, v) {
83
110
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
84
111
  }
85
- function _ts_param$a(paramIndex, decorator) {
112
+ function _ts_param$b(paramIndex, decorator) {
86
113
  return function(target, key) {
87
114
  decorator(target, key, paramIndex);
88
115
  };
89
116
  }
90
117
  const ZRomulatorConfigsToken = Symbol("configs");
91
118
  class ZRomulatorConfigsService {
92
- _logger;
93
- constructor(_logger){
94
- this._logger = new ZLoggerContext("ZRomulatorConfigsService", _logger);
95
- }
96
119
  async list(req) {
97
120
  const page = firstDefined(1, req.page);
98
121
  const size = firstDefined(Infinity, req.size);
@@ -163,16 +186,33 @@ class ZRomulatorConfigsService {
163
186
  this._logger.log(new ZLogEntryBuilder().info().message(msg).build());
164
187
  return config;
165
188
  }
189
+ constructor(_logger){
190
+ _define_property$b(this, "_logger", void 0);
191
+ this._logger = new ZLoggerContext("ZRomulatorConfigsService", _logger);
192
+ }
166
193
  }
167
194
  ZRomulatorConfigsService = _ts_decorate$h([
168
195
  Injectable(),
169
- _ts_param$a(0, Inject(ZLoggerToken)),
196
+ _ts_param$b(0, Inject(ZLoggerToken)),
170
197
  _ts_metadata$b("design:type", Function),
171
198
  _ts_metadata$b("design:paramtypes", [
172
199
  typeof IZLogger === "undefined" ? Object : IZLogger
173
200
  ])
174
201
  ], ZRomulatorConfigsService);
175
202
 
203
+ function _define_property$a(obj, key, value) {
204
+ if (key in obj) {
205
+ Object.defineProperty(obj, key, {
206
+ value: value,
207
+ enumerable: true,
208
+ configurable: true,
209
+ writable: true
210
+ });
211
+ } else {
212
+ obj[key] = value;
213
+ }
214
+ return obj;
215
+ }
176
216
  function _ts_decorate$g(decorators, target, key, desc) {
177
217
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
178
218
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -182,16 +222,12 @@ function _ts_decorate$g(decorators, target, key, desc) {
182
222
  function _ts_metadata$a(k, v) {
183
223
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
184
224
  }
185
- function _ts_param$9(paramIndex, decorator) {
225
+ function _ts_param$a(paramIndex, decorator) {
186
226
  return function(target, key) {
187
227
  decorator(target, key, paramIndex);
188
228
  };
189
229
  }
190
230
  class ZRomulatorConfigsController {
191
- _configs;
192
- constructor(_configs){
193
- this._configs = _configs;
194
- }
195
231
  async list(query) {
196
232
  const request = new ZDataRequestBuilder().query(query).build();
197
233
  return this._configs.list(request);
@@ -202,10 +238,14 @@ class ZRomulatorConfigsController {
202
238
  async get(identification) {
203
239
  return await this._configs.get(identification);
204
240
  }
241
+ constructor(_configs){
242
+ _define_property$a(this, "_configs", void 0);
243
+ this._configs = _configs;
244
+ }
205
245
  }
206
246
  _ts_decorate$g([
207
247
  Get(),
208
- _ts_param$9(0, Query()),
248
+ _ts_param$a(0, Query()),
209
249
  _ts_metadata$a("design:type", Function),
210
250
  _ts_metadata$a("design:paramtypes", [
211
251
  typeof IZDataRequestQuery === "undefined" ? Object : IZDataRequestQuery
@@ -229,8 +269,8 @@ _ts_decorate$g([
229
269
  skipNullProperties: false,
230
270
  skipUndefinedProperties: false
231
271
  })),
232
- _ts_param$9(0, Param("identification")),
233
- _ts_param$9(1, Body()),
272
+ _ts_param$a(0, Param("identification")),
273
+ _ts_param$a(1, Body()),
234
274
  _ts_metadata$a("design:type", Function),
235
275
  _ts_metadata$a("design:paramtypes", [
236
276
  typeof ZRomulatorConfigId === "undefined" ? Object : ZRomulatorConfigId,
@@ -245,7 +285,7 @@ _ts_decorate$g([
245
285
  description: "The id of the config"
246
286
  }),
247
287
  Get(":identification"),
248
- _ts_param$9(0, Param("identification")),
288
+ _ts_param$a(0, Param("identification")),
249
289
  _ts_metadata$a("design:type", Function),
250
290
  _ts_metadata$a("design:paramtypes", [
251
291
  typeof ZRomulatorConfigId === "undefined" ? Object : ZRomulatorConfigId
@@ -254,7 +294,7 @@ _ts_decorate$g([
254
294
  ], ZRomulatorConfigsController.prototype, "get", null);
255
295
  ZRomulatorConfigsController = _ts_decorate$g([
256
296
  Controller("configs"),
257
- _ts_param$9(0, Inject(ZRomulatorConfigsToken)),
297
+ _ts_param$a(0, Inject(ZRomulatorConfigsToken)),
258
298
  _ts_metadata$a("design:type", Function),
259
299
  _ts_metadata$a("design:paramtypes", [
260
300
  typeof IZRomulatorConfigsService === "undefined" ? Object : IZRomulatorConfigsService
@@ -290,358 +330,35 @@ ZRomulatorConfigsModule = _ts_decorate$f([
290
330
  })
291
331
  ], ZRomulatorConfigsModule);
292
332
 
293
- function _ts_decorate$e(decorators, target, key, desc) {
294
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
295
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
296
- 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;
297
- return c > 3 && r && Object.defineProperty(target, key, r), r;
298
- }
299
- function _ts_metadata$9(k, v) {
300
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
301
- }
302
- const KnownSystem = "@zthunworks/romulator/known-system";
303
- /**
304
- * A helper factory class for creating supported systems.
305
- */ class ZRomulatorSystemKnown {
306
- /**
307
- * Returns all known systems.
308
- *
309
- * @returns
310
- * All supported systems.
311
- */ static all() {
312
- const properties = Object.getOwnPropertyNames(ZRomulatorSystemKnown);
313
- const methods = properties.filter((p)=>isTagged(KnownSystem, ZRomulatorSystemKnown, p)).map((p)=>ZRomulatorSystemKnown[p]).map((f)=>f);
314
- return methods.map((m)=>m.call(null));
315
- }
316
- /**
317
- * Creates a system that represents the Nintendo
318
- * Entertainment System (NES).
319
- *
320
- * @returns
321
- * A {@link ZRomulatorSystemBuilder} instance that has
322
- * built the nes.
323
- */ static nes() {
324
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.Nintendo).name("Nintendo Entertainment System").build();
325
- }
326
- /**
327
- * Creates a system that represents the Super
328
- * Nintendo Entertainment System (SNES).
329
- *
330
- * @returns
331
- * This instance.
332
- */ static snes() {
333
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.SuperNintendo).name("Super Nintendo Entertainment System").build();
334
- }
335
- /**
336
- * Creates a system that represents the Nintendo
337
- * 64 (N64).
338
- *
339
- * @returns
340
- * This instance.
341
- */ static n64() {
342
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.Nintendo64).name("Nintendo 64").build();
343
- }
344
- /**
345
- * Creates a system that represents the Nintendo
346
- * GameCube (GC).
347
- *
348
- * @returns
349
- * This instance.
350
- */ static gc() {
351
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.GameCube).name("Nintendo GameCube").build();
352
- }
353
- /**
354
- * Creates a system that represents the Nintendo
355
- * Wii (Wii).
356
- *
357
- * @returns
358
- * This instance.
359
- */ static wii() {
360
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.Wii).name("Nintendo Wii").build();
361
- }
362
- /**
363
- * Creates a system that represents the Nintendo
364
- * Wii U (WiiU).
365
- *
366
- * @returns
367
- * This instance.
368
- */ static wiiu() {
369
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.WiiU).name("Nintendo Wii U").build();
370
- }
371
- /**
372
- * Creates a system that represents the Nintendo
373
- * Switch (Switch).
374
- *
375
- * @returns
376
- * This instance.
377
- */ static switch() {
378
- return new ZRomulatorSystemBuilder().id(ZRomulatorSystemId.Switch).name("Nintendo Switch").build();
379
- }
380
- /**
381
- * Creates a system from an id slug.
382
- *
383
- * @param id -
384
- * The id slug of the system to create.
385
- *
386
- * @return
387
- * The system, or null if the id is not known.
388
- */ static from(id) {
389
- if (isTagged(KnownSystem, ZRomulatorSystemKnown, id)) {
390
- return ZRomulatorSystemKnown[id]();
391
- }
392
- return null;
393
- }
394
- }
395
- _ts_decorate$e([
396
- ZTag(KnownSystem),
397
- _ts_metadata$9("design:type", Function),
398
- _ts_metadata$9("design:paramtypes", []),
399
- _ts_metadata$9("design:returntype", void 0)
400
- ], ZRomulatorSystemKnown, "nes", null);
401
- _ts_decorate$e([
402
- ZTag(KnownSystem),
403
- _ts_metadata$9("design:type", Function),
404
- _ts_metadata$9("design:paramtypes", []),
405
- _ts_metadata$9("design:returntype", void 0)
406
- ], ZRomulatorSystemKnown, "snes", null);
407
- _ts_decorate$e([
408
- ZTag(KnownSystem),
409
- _ts_metadata$9("design:type", Function),
410
- _ts_metadata$9("design:paramtypes", []),
411
- _ts_metadata$9("design:returntype", void 0)
412
- ], ZRomulatorSystemKnown, "n64", null);
413
- _ts_decorate$e([
414
- ZTag(KnownSystem),
415
- _ts_metadata$9("design:type", Function),
416
- _ts_metadata$9("design:paramtypes", []),
417
- _ts_metadata$9("design:returntype", void 0)
418
- ], ZRomulatorSystemKnown, "gc", null);
419
- _ts_decorate$e([
420
- ZTag(KnownSystem),
421
- _ts_metadata$9("design:type", Function),
422
- _ts_metadata$9("design:paramtypes", []),
423
- _ts_metadata$9("design:returntype", void 0)
424
- ], ZRomulatorSystemKnown, "wii", null);
425
- _ts_decorate$e([
426
- ZTag(KnownSystem),
427
- _ts_metadata$9("design:type", Function),
428
- _ts_metadata$9("design:paramtypes", []),
429
- _ts_metadata$9("design:returntype", void 0)
430
- ], ZRomulatorSystemKnown, "wiiu", null);
431
- _ts_decorate$e([
432
- ZTag(KnownSystem),
433
- _ts_metadata$9("design:type", Function),
434
- _ts_metadata$9("design:paramtypes", []),
435
- _ts_metadata$9("design:returntype", void 0)
436
- ], ZRomulatorSystemKnown, "switch", null);
437
-
438
- function _ts_decorate$d(decorators, target, key, desc) {
439
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
440
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
441
- 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;
442
- return c > 3 && r && Object.defineProperty(target, key, r), r;
443
- }
444
- function _ts_metadata$8(k, v) {
445
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
446
- }
447
- function _ts_param$8(paramIndex, decorator) {
448
- return function(target, key) {
449
- decorator(target, key, paramIndex);
450
- };
451
- }
452
- const ZRomulatorGamesToken = Symbol("romulator-games-service");
453
- class ZRomulatorGamesService {
454
- _file;
455
- _config;
456
- _logger;
457
- constructor(_file, _config, logger){
458
- this._file = _file;
459
- this._config = _config;
460
- this._logger = new ZLoggerContext("ZRomulatorGamesService", logger);
461
- }
462
- async list(req) {
463
- const config = ZRomulatorConfigKnown.games();
464
- const { contents } = await this._config.get(config.id);
465
- const { gamesFolder } = new ZRomulatorConfigGamesBuilder().copy(contents).build();
466
- const { fallback } = ZRomulatorConfigGamesMetadata.gamesFolder();
467
- const cwd = detokenize(firstDefined(fallback, gamesFolder), process.env);
468
- const time = new Date();
469
- let msg = `Searching for games in ${cwd}`;
470
- this._logger.log(new ZLogEntryBuilder().info().message(msg).build());
471
- const systems = ZRomulatorSystemKnown.all().map((system)=>system.id);
472
- const glob = `{${systems.join(",")}}/**/*.zip`;
473
- const nodes = await this._file.search(glob, {
474
- cwd,
475
- stat: false
476
- });
477
- const span = new Date().getTime() - time.getTime();
478
- msg = `Found ${nodes.length} games. Search took ${span} milliseconds.`;
479
- this._logger.log(new ZLogEntryBuilder().info().message(msg).build());
480
- const games = nodes.map(({ path })=>{
481
- const dir = basename(dirname(path));
482
- const { name: file } = parse(path);
483
- const id = `${dir}-${kebabCase(file)}`;
484
- return new ZRomulatorGameBuilder().id(id).system(dir).file(path).name(file).build();
333
+ function _define_property$9(obj, key, value) {
334
+ if (key in obj) {
335
+ Object.defineProperty(obj, key, {
336
+ value: value,
337
+ enumerable: true,
338
+ configurable: true,
339
+ writable: true
485
340
  });
486
- const options = new ZDataSourceStaticOptionsBuilder().search(this).build();
487
- const source = new ZDataSourceStatic(games, options);
488
- const $sort = new ZSortBuilder().sorts(firstDefined([], req.sort)).ascending("system").ascending("name").build();
489
- const $request = new ZDataRequestBuilder().copy(req).sort($sort).build();
490
- const data = await source.retrieve($request);
491
- const count = await source.count($request);
492
- return new ZPageBuilder().count(count).data(data).build();
493
- }
494
- async get(id) {
495
- const { data: games } = await this.list(new ZDataRequestBuilder().build());
496
- const match = games.find((game)=>game.id === id);
497
- if (!match) {
498
- throw new NotFoundException(`Unable to find game with id, ${id}.`);
499
- }
500
- return match;
501
- }
502
- match(data, filter) {
503
- const needle = filter?.trim().toLowerCase();
504
- const { name = "", system = "" } = data;
505
- const target = ZRomulatorSystemKnown.from(system);
506
- const systemName = firstTruthy("", target?.name);
507
- if (!needle?.length) {
508
- return true;
509
- }
510
- return [
511
- name,
512
- system,
513
- systemName
514
- ].filter((s)=>s.length).some((k)=>k.toLowerCase().includes(needle));
341
+ } else {
342
+ obj[key] = value;
515
343
  }
344
+ return obj;
516
345
  }
517
- ZRomulatorGamesService = _ts_decorate$d([
518
- Injectable(),
519
- _ts_param$8(0, Inject(ZFileSystemToken)),
520
- _ts_param$8(1, Inject(ZRomulatorConfigsToken)),
521
- _ts_param$8(2, Inject(ZLoggerToken)),
522
- _ts_metadata$8("design:type", Function),
523
- _ts_metadata$8("design:paramtypes", [
524
- typeof IZFileSystemService === "undefined" ? Object : IZFileSystemService,
525
- typeof IZRomulatorConfigsService === "undefined" ? Object : IZRomulatorConfigsService,
526
- typeof IZLogger === "undefined" ? Object : IZLogger
527
- ])
528
- ], ZRomulatorGamesService);
529
-
530
- function _ts_decorate$c(decorators, target, key, desc) {
531
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
532
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
533
- 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;
534
- return c > 3 && r && Object.defineProperty(target, key, r), r;
535
- }
536
- function _ts_metadata$7(k, v) {
537
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
538
- }
539
- function _ts_param$7(paramIndex, decorator) {
540
- return function(target, key) {
541
- decorator(target, key, paramIndex);
542
- };
543
- }
544
- class ZRomulatorGamesController {
545
- _games;
546
- constructor(_games){
547
- this._games = _games;
548
- }
549
- list(query) {
550
- return this._games.list(new ZDataRequestBuilder().query(query).build());
551
- }
552
- get(identification) {
553
- return this._games.get(identification);
554
- }
555
- }
556
- _ts_decorate$c([
557
- Get(),
558
- _ts_param$7(0, Query()),
559
- _ts_metadata$7("design:type", Function),
560
- _ts_metadata$7("design:paramtypes", [
561
- typeof IZDataRequestQuery === "undefined" ? Object : IZDataRequestQuery
562
- ]),
563
- _ts_metadata$7("design:returntype", typeof Promise === "undefined" ? Object : Promise)
564
- ], ZRomulatorGamesController.prototype, "list", null);
565
- _ts_decorate$c([
566
- Get(":identification"),
567
- _ts_param$7(0, Param("identification")),
568
- _ts_metadata$7("design:type", Function),
569
- _ts_metadata$7("design:paramtypes", [
570
- String
571
- ]),
572
- _ts_metadata$7("design:returntype", void 0)
573
- ], ZRomulatorGamesController.prototype, "get", null);
574
- ZRomulatorGamesController = _ts_decorate$c([
575
- Controller("games"),
576
- _ts_param$7(0, Inject(ZRomulatorGamesToken)),
577
- _ts_metadata$7("design:type", Function),
578
- _ts_metadata$7("design:paramtypes", [
579
- typeof IZRomulatorGamesService === "undefined" ? Object : IZRomulatorGamesService
580
- ])
581
- ], ZRomulatorGamesController);
582
-
583
- function _ts_decorate$b(decorators, target, key, desc) {
584
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
585
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
586
- 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;
587
- return c > 3 && r && Object.defineProperty(target, key, r), r;
588
- }
589
- class ZRomulatorGamesModule {
590
- }
591
- ZRomulatorGamesModule = _ts_decorate$b([
592
- Module({
593
- imports: [
594
- ZRomulatorConfigsModule,
595
- ZFileSystemModule,
596
- ZLoggerModule
597
- ],
598
- controllers: [
599
- ZRomulatorGamesController
600
- ],
601
- providers: [
602
- {
603
- provide: ZRomulatorGamesToken,
604
- useClass: ZRomulatorGamesService
605
- }
606
- ]
607
- })
608
- ], ZRomulatorGamesModule);
609
-
610
- function _ts_decorate$a(decorators, target, key, desc) {
346
+ function _ts_decorate$e(decorators, target, key, desc) {
611
347
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
612
348
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
613
349
  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;
614
350
  return c > 3 && r && Object.defineProperty(target, key, r), r;
615
351
  }
616
- function _ts_metadata$6(k, v) {
352
+ function _ts_metadata$9(k, v) {
617
353
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
618
354
  }
619
- function _ts_param$6(paramIndex, decorator) {
355
+ function _ts_param$9(paramIndex, decorator) {
620
356
  return function(target, key) {
621
357
  decorator(target, key, paramIndex);
622
358
  };
623
359
  }
624
- const ZRomulatorFilesToken = Symbol("files");
360
+ const ZRomulatorFilesRepositoryToken = Symbol("files-repository");
625
361
  class ZRomulatorFilesRepository {
626
- _configs;
627
- _fileSystem;
628
- static MediaFolderName = ".media";
629
- static InfoFolderName = ".info";
630
- _repository = new ZFileRepository();
631
- _folderStream = new ZStreamFolder();
632
- _globs;
633
- _systems;
634
- constructor(_configs, _fileSystem){
635
- this._configs = _configs;
636
- this._fileSystem = _fileSystem;
637
- const slugs = Object.values(ZRomulatorSystemId);
638
- this._globs = [
639
- ".media/**",
640
- ".info/**",
641
- ...slugs.map((s)=>`${s}/*.*`)
642
- ];
643
- this._systems = Object.values(ZRomulatorSystemId);
644
- }
645
362
  async gamesFolder() {
646
363
  const config = await this._configs.get(ZRomulatorConfigId$1.Games);
647
364
  const { gamesFolder } = new ZRomulatorConfigGamesBuilder().copy(config.contents).build();
@@ -682,7 +399,21 @@ class ZRomulatorFilesRepository {
682
399
  const path = resolve(folder, `${id}.json`);
683
400
  return this._repository.get(path);
684
401
  }
685
- async systems(id) {
402
+ async json(node) {
403
+ if (node == null) {
404
+ return null;
405
+ }
406
+ try {
407
+ const contents = await this._fileStream.read(node.path);
408
+ return JSON.parse(contents.toString());
409
+ } catch (e) {
410
+ const err = createError(e);
411
+ const msg = `Unable to read ${node.path}: ${err.message}`;
412
+ this._logger.log(new ZLogEntryBuilder().error().message(msg).build());
413
+ return null;
414
+ }
415
+ }
416
+ async systems() {
686
417
  // Systems use directories. There's a maximum limit of about 200 systems.
687
418
  // Since we don't actually need to read any metadata or scan through thousands
688
419
  // of unknown folders, we can use the supported system ids to just grab the
@@ -690,73 +421,106 @@ class ZRomulatorFilesRepository {
690
421
  // grab the systems from the file system and it should be fast enough. These are all
691
422
  // folders, so we don't even need the stats for them and we can assume folders.
692
423
  const games = await this.gamesFolder();
693
- const folders = id == null ? this._systems.map((s)=>`${s}/`) : resolve(games, id);
694
- const items = await this._fileSystem.search(folders, {
424
+ const folders = this._systems.map((s)=>`${s}/`);
425
+ return await this._fileSystem.search(folders, {
695
426
  cwd: games,
696
427
  stat: false
697
428
  });
698
- return id == null ? items : firstDefined(null, first(items));
429
+ }
430
+ async games(systems) {
431
+ const repository = await this.init();
432
+ const folder = await this.gamesFolder();
433
+ const queries = systems.map((s)=>{
434
+ const dir = `${folder}/${s.id}`;
435
+ const byExtension = new ZFilterCollectionBuilder().subject("extension").in().values(s.extensions.map((e)=>`.${trimStart(e, ".")}`)).build();
436
+ const inPath = new ZFilterBinaryBuilder().subject("parent").equal().value(dir).build();
437
+ const filter = new ZFilterLogicBuilder().and().clause(inPath).clause(byExtension).build();
438
+ const request = new ZDataRequestBuilder().filter(filter).build();
439
+ return repository.retrieve(request);
440
+ });
441
+ const results = await Promise.all(queries);
442
+ return flatten(results);
443
+ }
444
+ constructor(_configs, _fileSystem, logger){
445
+ _define_property$9(this, "_configs", void 0);
446
+ _define_property$9(this, "_fileSystem", void 0);
447
+ _define_property$9(this, "logger", void 0);
448
+ _define_property$9(this, "_logger", void 0);
449
+ _define_property$9(this, "_repository", void 0);
450
+ _define_property$9(this, "_folderStream", void 0);
451
+ _define_property$9(this, "_fileStream", void 0);
452
+ _define_property$9(this, "_globs", void 0);
453
+ _define_property$9(this, "_systems", void 0);
454
+ this._configs = _configs;
455
+ this._fileSystem = _fileSystem;
456
+ this.logger = logger;
457
+ this._repository = new ZFileRepository();
458
+ this._folderStream = new ZStreamFolder();
459
+ this._fileStream = new ZStreamFile({
460
+ cache: {
461
+ fileSize: BigInt(mib(1)),
462
+ maxFiles: 250
463
+ }
464
+ });
465
+ const slugs = Object.values(ZRomulatorSystemId);
466
+ this._globs = [
467
+ ".media/**",
468
+ ".info/**",
469
+ ...slugs.map((s)=>`${s}/*.*`)
470
+ ];
471
+ this._systems = Object.values(ZRomulatorSystemId);
472
+ this._logger = new ZLoggerContext("ZRomulatorFilesRepository", logger);
699
473
  }
700
474
  }
701
- ZRomulatorFilesRepository = _ts_decorate$a([
475
+ _define_property$9(ZRomulatorFilesRepository, "MediaFolderName", ".media");
476
+ _define_property$9(ZRomulatorFilesRepository, "InfoFolderName", ".info");
477
+ ZRomulatorFilesRepository = _ts_decorate$e([
702
478
  Injectable(),
703
- _ts_param$6(0, Inject(ZRomulatorConfigsToken)),
704
- _ts_param$6(1, Inject(ZFileSystemToken)),
705
- _ts_metadata$6("design:type", Function),
706
- _ts_metadata$6("design:paramtypes", [
479
+ _ts_param$9(0, Inject(ZRomulatorConfigsToken)),
480
+ _ts_param$9(1, Inject(ZFileSystemToken)),
481
+ _ts_param$9(2, Inject(ZLoggerToken)),
482
+ _ts_metadata$9("design:type", Function),
483
+ _ts_metadata$9("design:paramtypes", [
707
484
  typeof IZRomulatorConfigsService === "undefined" ? Object : IZRomulatorConfigsService,
708
- typeof IZFileSystemService === "undefined" ? Object : IZFileSystemService
485
+ typeof IZFileSystemService === "undefined" ? Object : IZFileSystemService,
486
+ typeof IZLogger === "undefined" ? Object : IZLogger
709
487
  ])
710
488
  ], ZRomulatorFilesRepository);
711
489
 
712
- function _ts_decorate$9(decorators, target, key, desc) {
490
+ function _define_property$8(obj, key, value) {
491
+ if (key in obj) {
492
+ Object.defineProperty(obj, key, {
493
+ value: value,
494
+ enumerable: true,
495
+ configurable: true,
496
+ writable: true
497
+ });
498
+ } else {
499
+ obj[key] = value;
500
+ }
501
+ return obj;
502
+ }
503
+ function _ts_decorate$d(decorators, target, key, desc) {
713
504
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
714
505
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
715
506
  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;
716
507
  return c > 3 && r && Object.defineProperty(target, key, r), r;
717
508
  }
718
- function _ts_metadata$5(k, v) {
509
+ function _ts_metadata$8(k, v) {
719
510
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
720
511
  }
721
- function _ts_param$5(paramIndex, decorator) {
512
+ function _ts_param$8(paramIndex, decorator) {
722
513
  return function(target, key) {
723
514
  decorator(target, key, paramIndex);
724
515
  };
725
516
  }
726
- const ZRomulatorFilesSystemsJsonRepositoryToken = Symbol("files-systems-json-repository");
727
- class ZRomulatorFilesSystemsJsonRepository {
728
- _files;
729
- _logger;
730
- _stream = new ZStreamFile({
731
- cache: {
732
- maxFiles: 1,
733
- fileSize: BigInt(mib(5))
734
- }
735
- });
736
- /**
737
- * Initializes a new instance of this object.
738
- */ constructor(_files, logger){
739
- this._files = _files;
740
- this._logger = new ZLoggerContext("ZRomulatorSystemsRepository", logger);
741
- }
742
- async _read() {
743
- const info = await this._files.info("systems");
744
- if (info == null) {
745
- return [];
746
- }
747
- try {
748
- const contents = await this._stream.read(info.path);
749
- const json = JSON.parse(contents.toString());
750
- return castArray(json);
751
- } catch (e) {
752
- const err = createError(e);
753
- const msg = `Unable to read ${info.path}: ${err.message}`;
754
- this._logger.log(new ZLogEntryBuilder().error().message(msg).build());
755
- return [];
756
- }
757
- }
517
+ const ZRomulatorFilesSystemsRepositoryToken = Symbol("files-systems-repository");
518
+ class ZRomulatorFilesSystemsRepository {
758
519
  async systems() {
759
- const candidates = await this._read();
520
+ const info = await this._filesRepository.info("systems");
521
+ const json = await this._filesRepository.json(info);
522
+ const candidates = castArray(firstDefined([], json));
523
+ const folders = await this._filesRepository.systems();
760
524
  function hasId(candidate) {
761
525
  return Object.prototype.hasOwnProperty.call(candidate, "id");
762
526
  }
@@ -764,47 +528,149 @@ class ZRomulatorFilesSystemsJsonRepository {
764
528
  c.id,
765
529
  c
766
530
  ]);
767
- return Promise.resolve(new Map(entries));
531
+ const lookup = new Map(entries);
532
+ const systems = folders.map((folder)=>folder.path).map((path)=>basename(path)).filter((slug)=>isSystemId(slug)).map((slug)=>new ZRomulatorSystemBuilder().parse(lookup.get(slug)).id(slug).build());
533
+ return new Map(systems.map((s)=>[
534
+ s.id,
535
+ s
536
+ ]));
537
+ }
538
+ /**
539
+ * Initializes a new instance of this object.
540
+ */ constructor(_filesRepository){
541
+ _define_property$8(this, "_filesRepository", void 0);
542
+ this._filesRepository = _filesRepository;
768
543
  }
769
544
  }
770
- ZRomulatorFilesSystemsJsonRepository = _ts_decorate$9([
545
+ ZRomulatorFilesSystemsRepository = _ts_decorate$d([
771
546
  Injectable(),
772
- _ts_param$5(0, Inject(ZRomulatorFilesToken)),
773
- _ts_param$5(1, Inject(ZLoggerToken)),
774
- _ts_metadata$5("design:type", Function),
775
- _ts_metadata$5("design:paramtypes", [
776
- typeof IZRomulatorFilesRepository === "undefined" ? Object : IZRomulatorFilesRepository,
777
- typeof IZLogger === "undefined" ? Object : IZLogger
547
+ _ts_param$8(0, Inject(ZRomulatorFilesRepositoryToken)),
548
+ _ts_metadata$8("design:type", Function),
549
+ _ts_metadata$8("design:paramtypes", [
550
+ typeof IZRomulatorFilesRepository === "undefined" ? Object : IZRomulatorFilesRepository
778
551
  ])
779
- ], ZRomulatorFilesSystemsJsonRepository);
552
+ ], ZRomulatorFilesSystemsRepository);
780
553
 
781
- function _ts_decorate$8(decorators, target, key, desc) {
554
+ function _define_property$7(obj, key, value) {
555
+ if (key in obj) {
556
+ Object.defineProperty(obj, key, {
557
+ value: value,
558
+ enumerable: true,
559
+ configurable: true,
560
+ writable: true
561
+ });
562
+ } else {
563
+ obj[key] = value;
564
+ }
565
+ return obj;
566
+ }
567
+ function _ts_decorate$c(decorators, target, key, desc) {
782
568
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
783
569
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
784
570
  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;
785
571
  return c > 3 && r && Object.defineProperty(target, key, r), r;
786
572
  }
787
- function _ts_metadata$4(k, v) {
573
+ function _ts_metadata$7(k, v) {
788
574
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
789
575
  }
790
- function _ts_param$4(paramIndex, decorator) {
576
+ function _ts_param$7(paramIndex, decorator) {
791
577
  return function(target, key) {
792
578
  decorator(target, key, paramIndex);
793
579
  };
794
580
  }
795
- class ZRomulatorFilesModule {
796
- _files;
797
- constructor(_files){
798
- this._files = _files;
581
+ const ZRomulatorFilesGamesRepositoryToken = Symbol("files-games-repository");
582
+ class ZRomulatorFilesGamesRepository {
583
+ async games() {
584
+ function hasPath(entry) {
585
+ return typeof get(entry, "path") === "string";
586
+ }
587
+ const gamesFolder = await this._filesRepository.gamesFolder();
588
+ const games = [];
589
+ const systemLookup = await this._systemsRepository.systems();
590
+ const systems = Array.from(systemLookup.values());
591
+ const gameFiles = await this._filesRepository.games(systems);
592
+ const systemsInUse = uniq(gameFiles.map((g)=>g.parent)).map((dir)=>new ZFileSystemNodeBuilder().path(dir).folder().build()).map((node)=>node.title).filter((title)=>isSystemId(title));
593
+ const gameInfo = new Map();
594
+ for await (const system of systemsInUse){
595
+ const info = await this._filesRepository.info(system);
596
+ const json = await this._filesRepository.json(info);
597
+ const gameList = castArray(json).filter((e)=>hasPath(e));
598
+ gameList.forEach((entry)=>{
599
+ gameInfo.set(resolve$1(gamesFolder, system, entry.path), entry);
600
+ });
601
+ }
602
+ // Variable, gameInfo, now has all of the information data that we need.
603
+ for (const file of gameFiles){
604
+ const { title, path } = file;
605
+ const { title: systemId } = new ZFileSystemNodeBuilder().path(file.parent).folder().build();
606
+ const id = `${kebabCase(systemId)}-${kebabCase(title)}`;
607
+ const info = gameInfo.get(path);
608
+ const game = new ZRomulatorGameBuilder().id(id).system(systemId).file(path).parse(info).build();
609
+ games.push(game);
610
+ }
611
+ return new Map(games.map((g)=>[
612
+ g.id,
613
+ g
614
+ ]));
615
+ }
616
+ constructor(_systemsRepository, _filesRepository){
617
+ _define_property$7(this, "_systemsRepository", void 0);
618
+ _define_property$7(this, "_filesRepository", void 0);
619
+ this._systemsRepository = _systemsRepository;
620
+ this._filesRepository = _filesRepository;
799
621
  }
622
+ }
623
+ ZRomulatorFilesGamesRepository = _ts_decorate$c([
624
+ Injectable(),
625
+ _ts_param$7(0, Inject(ZRomulatorFilesSystemsRepositoryToken)),
626
+ _ts_param$7(1, Inject(ZRomulatorFilesRepositoryToken)),
627
+ _ts_metadata$7("design:type", Function),
628
+ _ts_metadata$7("design:paramtypes", [
629
+ typeof IZRomulatorFilesSystemsRepository === "undefined" ? Object : IZRomulatorFilesSystemsRepository,
630
+ typeof IZRomulatorFilesRepository === "undefined" ? Object : IZRomulatorFilesRepository
631
+ ])
632
+ ], ZRomulatorFilesGamesRepository);
633
+
634
+ function _define_property$6(obj, key, value) {
635
+ if (key in obj) {
636
+ Object.defineProperty(obj, key, {
637
+ value: value,
638
+ enumerable: true,
639
+ configurable: true,
640
+ writable: true
641
+ });
642
+ } else {
643
+ obj[key] = value;
644
+ }
645
+ return obj;
646
+ }
647
+ function _ts_decorate$b(decorators, target, key, desc) {
648
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
649
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
650
+ 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;
651
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
652
+ }
653
+ function _ts_metadata$6(k, v) {
654
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
655
+ }
656
+ function _ts_param$6(paramIndex, decorator) {
657
+ return function(target, key) {
658
+ decorator(target, key, paramIndex);
659
+ };
660
+ }
661
+ class ZRomulatorFilesModule {
800
662
  async onModuleInit() {
801
663
  await this._files.init();
802
664
  }
803
665
  async onModuleDestroy() {
804
666
  await this._files.dispose();
805
667
  }
668
+ constructor(_files){
669
+ _define_property$6(this, "_files", void 0);
670
+ this._files = _files;
671
+ }
806
672
  }
807
- ZRomulatorFilesModule = _ts_decorate$8([
673
+ ZRomulatorFilesModule = _ts_decorate$b([
808
674
  Module({
809
675
  imports: [
810
676
  ZFileSystemModule,
@@ -813,26 +679,216 @@ ZRomulatorFilesModule = _ts_decorate$8([
813
679
  ],
814
680
  providers: [
815
681
  {
816
- provide: ZRomulatorFilesToken,
682
+ provide: ZRomulatorFilesRepositoryToken,
817
683
  useClass: ZRomulatorFilesRepository
818
684
  },
819
685
  {
820
- provide: ZRomulatorFilesSystemsJsonRepositoryToken,
821
- useClass: ZRomulatorFilesSystemsJsonRepository
686
+ provide: ZRomulatorFilesSystemsRepositoryToken,
687
+ useClass: ZRomulatorFilesSystemsRepository
688
+ },
689
+ {
690
+ provide: ZRomulatorFilesGamesRepositoryToken,
691
+ useClass: ZRomulatorFilesGamesRepository
822
692
  }
823
693
  ],
824
694
  exports: [
825
- ZRomulatorFilesToken,
826
- ZRomulatorFilesSystemsJsonRepositoryToken
695
+ ZRomulatorFilesRepositoryToken,
696
+ ZRomulatorFilesSystemsRepositoryToken,
697
+ ZRomulatorFilesGamesRepositoryToken
827
698
  ]
828
699
  }),
829
- _ts_param$4(0, Inject(ZRomulatorFilesToken)),
830
- _ts_metadata$4("design:type", Function),
831
- _ts_metadata$4("design:paramtypes", [
700
+ _ts_param$6(0, Inject(ZRomulatorFilesRepositoryToken)),
701
+ _ts_metadata$6("design:type", Function),
702
+ _ts_metadata$6("design:paramtypes", [
832
703
  typeof IZRomulatorFilesRepository === "undefined" ? Object : IZRomulatorFilesRepository
833
704
  ])
834
705
  ], ZRomulatorFilesModule);
835
706
 
707
+ function _define_property$5(obj, key, value) {
708
+ if (key in obj) {
709
+ Object.defineProperty(obj, key, {
710
+ value: value,
711
+ enumerable: true,
712
+ configurable: true,
713
+ writable: true
714
+ });
715
+ } else {
716
+ obj[key] = value;
717
+ }
718
+ return obj;
719
+ }
720
+ function _ts_decorate$a(decorators, target, key, desc) {
721
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
722
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
723
+ 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;
724
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
725
+ }
726
+ function _ts_metadata$5(k, v) {
727
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
728
+ }
729
+ function _ts_param$5(paramIndex, decorator) {
730
+ return function(target, key) {
731
+ decorator(target, key, paramIndex);
732
+ };
733
+ }
734
+ const ZRomulatorGamesToken = Symbol("romulator-games-service");
735
+ class ZRomulatorGamesService {
736
+ async list(req) {
737
+ const msg = `Searching for games`;
738
+ this._logger.log(new ZLogEntryBuilder().info().message(msg).build());
739
+ const systems = await this._systemsRepository.systems();
740
+ const games = await this._filesRepository.games();
741
+ const match = (data, filter)=>{
742
+ const needle = filter?.trim().toLowerCase();
743
+ const { name = "", system = "" } = data;
744
+ const systemId = system;
745
+ const systemName = firstTruthy("", systems.get(systemId)?.name);
746
+ if (!needle?.length) {
747
+ return true;
748
+ }
749
+ return [
750
+ name,
751
+ system,
752
+ systemName
753
+ ].filter((s)=>s.length).some((k)=>k.toLowerCase().includes(needle));
754
+ };
755
+ const options = new ZDataSourceStaticOptionsBuilder().search({
756
+ match
757
+ }).build();
758
+ const source = new ZDataSourceStatic(Array.from(games.values()), options);
759
+ const $sort = new ZSortBuilder().sorts(firstDefined([], req.sort)).ascending("system").ascending("name").build();
760
+ const $request = new ZDataRequestBuilder().copy(req).sort($sort).build();
761
+ const data = await source.retrieve($request);
762
+ const count = await source.count($request);
763
+ return new ZPageBuilder().count(count).data(data).build();
764
+ }
765
+ async get(id) {
766
+ const filter = new ZFilterBinaryBuilder().subject("id").equal().value(id).build();
767
+ const request = new ZDataRequestBuilder().filter(filter).size(1).build();
768
+ const { data: games } = await this.list(request);
769
+ const [game] = games;
770
+ if (game == null) {
771
+ const message = `Game, ${id}, was not found.`;
772
+ throw new NotFoundException(message);
773
+ }
774
+ return game;
775
+ }
776
+ constructor(_systemsRepository, _filesRepository, logger){
777
+ _define_property$5(this, "_systemsRepository", void 0);
778
+ _define_property$5(this, "_filesRepository", void 0);
779
+ _define_property$5(this, "logger", void 0);
780
+ _define_property$5(this, "_logger", void 0);
781
+ this._systemsRepository = _systemsRepository;
782
+ this._filesRepository = _filesRepository;
783
+ this.logger = logger;
784
+ this._logger = new ZLoggerContext("ZRomulatorGamesService", logger);
785
+ }
786
+ }
787
+ ZRomulatorGamesService = _ts_decorate$a([
788
+ Injectable(),
789
+ _ts_param$5(0, Inject(ZRomulatorFilesSystemsRepositoryToken)),
790
+ _ts_param$5(1, Inject(ZRomulatorFilesGamesRepositoryToken)),
791
+ _ts_param$5(2, Inject(ZLoggerToken)),
792
+ _ts_metadata$5("design:type", Function),
793
+ _ts_metadata$5("design:paramtypes", [
794
+ typeof IZRomulatorFilesSystemsRepository === "undefined" ? Object : IZRomulatorFilesSystemsRepository,
795
+ typeof IZRomulatorFilesGamesRepository === "undefined" ? Object : IZRomulatorFilesGamesRepository,
796
+ typeof IZLogger === "undefined" ? Object : IZLogger
797
+ ])
798
+ ], ZRomulatorGamesService);
799
+
800
+ function _define_property$4(obj, key, value) {
801
+ if (key in obj) {
802
+ Object.defineProperty(obj, key, {
803
+ value: value,
804
+ enumerable: true,
805
+ configurable: true,
806
+ writable: true
807
+ });
808
+ } else {
809
+ obj[key] = value;
810
+ }
811
+ return obj;
812
+ }
813
+ function _ts_decorate$9(decorators, target, key, desc) {
814
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
815
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
816
+ 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;
817
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
818
+ }
819
+ function _ts_metadata$4(k, v) {
820
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
821
+ }
822
+ function _ts_param$4(paramIndex, decorator) {
823
+ return function(target, key) {
824
+ decorator(target, key, paramIndex);
825
+ };
826
+ }
827
+ class ZRomulatorGamesController {
828
+ list(query) {
829
+ return this._games.list(new ZDataRequestBuilder().query(query).build());
830
+ }
831
+ get(identification) {
832
+ return this._games.get(identification);
833
+ }
834
+ constructor(_games){
835
+ _define_property$4(this, "_games", void 0);
836
+ this._games = _games;
837
+ }
838
+ }
839
+ _ts_decorate$9([
840
+ Get(),
841
+ _ts_param$4(0, Query()),
842
+ _ts_metadata$4("design:type", Function),
843
+ _ts_metadata$4("design:paramtypes", [
844
+ typeof IZDataRequestQuery === "undefined" ? Object : IZDataRequestQuery
845
+ ]),
846
+ _ts_metadata$4("design:returntype", typeof Promise === "undefined" ? Object : Promise)
847
+ ], ZRomulatorGamesController.prototype, "list", null);
848
+ _ts_decorate$9([
849
+ Get(":identification"),
850
+ _ts_param$4(0, Param("identification")),
851
+ _ts_metadata$4("design:type", Function),
852
+ _ts_metadata$4("design:paramtypes", [
853
+ String
854
+ ]),
855
+ _ts_metadata$4("design:returntype", void 0)
856
+ ], ZRomulatorGamesController.prototype, "get", null);
857
+ ZRomulatorGamesController = _ts_decorate$9([
858
+ Controller("games"),
859
+ _ts_param$4(0, Inject(ZRomulatorGamesToken)),
860
+ _ts_metadata$4("design:type", Function),
861
+ _ts_metadata$4("design:paramtypes", [
862
+ typeof IZRomulatorGamesService === "undefined" ? Object : IZRomulatorGamesService
863
+ ])
864
+ ], ZRomulatorGamesController);
865
+
866
+ function _ts_decorate$8(decorators, target, key, desc) {
867
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
868
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
869
+ 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;
870
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
871
+ }
872
+ class ZRomulatorGamesModule {
873
+ }
874
+ ZRomulatorGamesModule = _ts_decorate$8([
875
+ Module({
876
+ imports: [
877
+ ZRomulatorFilesModule,
878
+ ZLoggerModule
879
+ ],
880
+ controllers: [
881
+ ZRomulatorGamesController
882
+ ],
883
+ providers: [
884
+ {
885
+ provide: ZRomulatorGamesToken,
886
+ useClass: ZRomulatorGamesService
887
+ }
888
+ ]
889
+ })
890
+ ], ZRomulatorGamesModule);
891
+
836
892
  function _ts_decorate$7(decorators, target, key, desc) {
837
893
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
838
894
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -879,6 +935,19 @@ ZRomulatorMediaGenerator = _ts_decorate$7([
879
935
  Injectable()
880
936
  ], ZRomulatorMediaGenerator);
881
937
 
938
+ function _define_property$3(obj, key, value) {
939
+ if (key in obj) {
940
+ Object.defineProperty(obj, key, {
941
+ value: value,
942
+ enumerable: true,
943
+ configurable: true,
944
+ writable: true
945
+ });
946
+ } else {
947
+ obj[key] = value;
948
+ }
949
+ return obj;
950
+ }
882
951
  function _ts_decorate$6(decorators, target, key, desc) {
883
952
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
884
953
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -895,14 +964,6 @@ function _ts_param$3(paramIndex, decorator) {
895
964
  }
896
965
  const ZRomulatorMediaToken = Symbol("romulator-media-service");
897
966
  class ZRomulatorMediaService {
898
- _generator;
899
- _files;
900
- _logger;
901
- constructor(_generator, _files, logger){
902
- this._generator = _generator;
903
- this._files = _files;
904
- this._logger = new ZLoggerContext("ZRomulatorMediaService", logger);
905
- }
906
967
  async findAllMedia() {
907
968
  const files = await this._files.media();
908
969
  return files.map((f)=>new ZRomulatorMediaBuilder().from(f.path).build()).filter((media)=>!!media.id);
@@ -997,11 +1058,19 @@ class ZRomulatorMediaService {
997
1058
  log = `Deleted ${url}`;
998
1059
  this._logger.log(new ZLogEntryBuilder().info().message(log).build());
999
1060
  }
1061
+ constructor(_generator, _files, logger){
1062
+ _define_property$3(this, "_generator", void 0);
1063
+ _define_property$3(this, "_files", void 0);
1064
+ _define_property$3(this, "_logger", void 0);
1065
+ this._generator = _generator;
1066
+ this._files = _files;
1067
+ this._logger = new ZLoggerContext("ZRomulatorMediaService", logger);
1068
+ }
1000
1069
  }
1001
1070
  ZRomulatorMediaService = _ts_decorate$6([
1002
1071
  Injectable(),
1003
1072
  _ts_param$3(0, Inject(ZRomulatorMediaGeneratorToken)),
1004
- _ts_param$3(1, Inject(ZRomulatorFilesToken)),
1073
+ _ts_param$3(1, Inject(ZRomulatorFilesRepositoryToken)),
1005
1074
  _ts_param$3(2, Inject(ZLoggerToken)),
1006
1075
  _ts_metadata$3("design:type", Function),
1007
1076
  _ts_metadata$3("design:paramtypes", [
@@ -1011,6 +1080,19 @@ ZRomulatorMediaService = _ts_decorate$6([
1011
1080
  ])
1012
1081
  ], ZRomulatorMediaService);
1013
1082
 
1083
+ function _define_property$2(obj, key, value) {
1084
+ if (key in obj) {
1085
+ Object.defineProperty(obj, key, {
1086
+ value: value,
1087
+ enumerable: true,
1088
+ configurable: true,
1089
+ writable: true
1090
+ });
1091
+ } else {
1092
+ obj[key] = value;
1093
+ }
1094
+ return obj;
1095
+ }
1014
1096
  function _ts_decorate$5(decorators, target, key, desc) {
1015
1097
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1016
1098
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1026,10 +1108,6 @@ function _ts_param$2(paramIndex, decorator) {
1026
1108
  };
1027
1109
  }
1028
1110
  class ZRomulatorMediaController {
1029
- _media;
1030
- constructor(_media){
1031
- this._media = _media;
1032
- }
1033
1111
  list(params) {
1034
1112
  const request = new ZDataRequestBuilder().query(params).build();
1035
1113
  return this._media.list(request);
@@ -1041,6 +1119,10 @@ class ZRomulatorMediaController {
1041
1119
  async delete(identification) {
1042
1120
  await this._media.delete(identification);
1043
1121
  }
1122
+ constructor(_media){
1123
+ _define_property$2(this, "_media", void 0);
1124
+ this._media = _media;
1125
+ }
1044
1126
  }
1045
1127
  _ts_decorate$5([
1046
1128
  ApiQuery({
@@ -1177,6 +1259,19 @@ ZRomulatorMediaModule = _ts_decorate$4([
1177
1259
  })
1178
1260
  ], ZRomulatorMediaModule);
1179
1261
 
1262
+ function _define_property$1(obj, key, value) {
1263
+ if (key in obj) {
1264
+ Object.defineProperty(obj, key, {
1265
+ value: value,
1266
+ enumerable: true,
1267
+ configurable: true,
1268
+ writable: true
1269
+ });
1270
+ } else {
1271
+ obj[key] = value;
1272
+ }
1273
+ return obj;
1274
+ }
1180
1275
  function _ts_decorate$3(decorators, target, key, desc) {
1181
1276
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1182
1277
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1193,30 +1288,18 @@ function _ts_param$1(paramIndex, decorator) {
1193
1288
  }
1194
1289
  const ZRomulatorSystemsToken = Symbol("romulator-systems-service");
1195
1290
  class ZRomulatorSystemsService {
1196
- _filesRepository;
1197
- _systemsRepository;
1198
- logger;
1199
- _logger;
1200
- constructor(_filesRepository, _systemsRepository, logger){
1201
- this._filesRepository = _filesRepository;
1202
- this._systemsRepository = _systemsRepository;
1203
- this.logger = logger;
1204
- this._logger = new ZLoggerContext("ZRomulatorSystemsService", logger);
1205
- }
1206
1291
  async list(req) {
1207
1292
  const page = firstDefined(1, req.page);
1208
1293
  const size = firstDefined(Infinity, req.size);
1209
1294
  let msg = `Retrieving systems page, ${page}, with size, ${size}.`;
1210
1295
  this._logger.log(new ZLogEntryBuilder().info().message(msg).build());
1211
- const folders = await this._filesRepository.systems();
1212
- const lookup = await this._systemsRepository.systems();
1213
- const systems = await Promise.all(folders.map((folder)=>folder.path).map((path)=>basename(path)).filter((slug)=>isSystemId(slug)).map((slug)=>new ZRomulatorSystemBuilder().id(slug).parse(lookup.get(slug)).build()));
1296
+ const systemMap = await this._systemsRepository.systems();
1297
+ const systems = Array.from(systemMap.values());
1214
1298
  msg = `Found ${systems.length} systems`;
1215
1299
  this._logger.log(new ZLogEntryBuilder().info().message(msg).build());
1216
1300
  const sourceOptions = new ZDataSourceStaticOptionsBuilder().search(new ZDataSearchFields([
1217
1301
  "id",
1218
- "name",
1219
- "short"
1302
+ "name"
1220
1303
  ])).build();
1221
1304
  const source = new ZDataSourceStatic(systems, sourceOptions);
1222
1305
  const data = await source.retrieve(req);
@@ -1229,29 +1312,49 @@ class ZRomulatorSystemsService {
1229
1312
  const message = `The specified system slug, ${id}, is not supported.`;
1230
1313
  throw new NotFoundException(message);
1231
1314
  }
1232
- const system = await this._filesRepository.systems(id);
1315
+ const filter = new ZFilterBinaryBuilder().subject("id").equal().value(id).build();
1316
+ const request = new ZDataRequestBuilder().filter(filter).size(1).build();
1317
+ const { data: systems } = await this.list(request);
1318
+ const [system] = systems;
1233
1319
  if (system == null) {
1234
1320
  const message = `System with slug, ${id}, was not found.`;
1235
1321
  throw new NotFoundException(message);
1236
1322
  }
1237
- const lookup = await this._systemsRepository.systems();
1238
- const info = lookup.get(id);
1239
- return new ZRomulatorSystemBuilder().id(id).parse(info).build();
1323
+ return system;
1324
+ }
1325
+ constructor(_systemsRepository, logger){
1326
+ _define_property$1(this, "_systemsRepository", void 0);
1327
+ _define_property$1(this, "logger", void 0);
1328
+ _define_property$1(this, "_logger", void 0);
1329
+ this._systemsRepository = _systemsRepository;
1330
+ this.logger = logger;
1331
+ this._logger = new ZLoggerContext("ZRomulatorSystemsService", logger);
1240
1332
  }
1241
1333
  }
1242
1334
  ZRomulatorSystemsService = _ts_decorate$3([
1243
1335
  Injectable(),
1244
- _ts_param$1(0, Inject(ZRomulatorFilesToken)),
1245
- _ts_param$1(1, Inject(ZRomulatorFilesSystemsJsonRepositoryToken)),
1246
- _ts_param$1(2, Inject(ZLoggerToken)),
1336
+ _ts_param$1(0, Inject(ZRomulatorFilesSystemsRepositoryToken)),
1337
+ _ts_param$1(1, Inject(ZLoggerToken)),
1247
1338
  _ts_metadata$1("design:type", Function),
1248
1339
  _ts_metadata$1("design:paramtypes", [
1249
- typeof IZRomulatorFilesRepository === "undefined" ? Object : IZRomulatorFilesRepository,
1250
- typeof IZRomulatorFilesSystemsJsonRepository === "undefined" ? Object : IZRomulatorFilesSystemsJsonRepository,
1340
+ typeof IZRomulatorFilesSystemsRepository === "undefined" ? Object : IZRomulatorFilesSystemsRepository,
1251
1341
  typeof IZLogger === "undefined" ? Object : IZLogger
1252
1342
  ])
1253
1343
  ], ZRomulatorSystemsService);
1254
1344
 
1345
+ function _define_property(obj, key, value) {
1346
+ if (key in obj) {
1347
+ Object.defineProperty(obj, key, {
1348
+ value: value,
1349
+ enumerable: true,
1350
+ configurable: true,
1351
+ writable: true
1352
+ });
1353
+ } else {
1354
+ obj[key] = value;
1355
+ }
1356
+ return obj;
1357
+ }
1255
1358
  function _ts_decorate$2(decorators, target, key, desc) {
1256
1359
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1257
1360
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1267,16 +1370,16 @@ function _ts_param(paramIndex, decorator) {
1267
1370
  };
1268
1371
  }
1269
1372
  class ZRomulatorSystemsController {
1270
- _systems;
1271
- constructor(_systems){
1272
- this._systems = _systems;
1273
- }
1274
1373
  list(query) {
1275
1374
  return this._systems.list(new ZDataRequestBuilder().query(query).build());
1276
1375
  }
1277
1376
  get(identification) {
1278
1377
  return this._systems.get(identification);
1279
1378
  }
1379
+ constructor(_systems){
1380
+ _define_property(this, "_systems", void 0);
1381
+ this._systems = _systems;
1382
+ }
1280
1383
  }
1281
1384
  _ts_decorate$2([
1282
1385
  Get(),