equipped 5.3.0 → 5.3.2
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/CHANGELOG.md +9 -0
- package/dist/cjs/cache/adapters/in-memory/index.cjs +155 -155
- package/dist/cjs/cache/adapters/in-memory/index.cjs.map +1 -1
- package/dist/cjs/cache/adapters/in-memory/index.min.cjs +3 -3
- package/dist/cjs/cache/adapters/in-memory/index.min.cjs.map +1 -1
- package/dist/cjs/dbs/adapters/mongodb/index.cjs.map +1 -1
- package/dist/cjs/dbs/adapters/mongodb/index.min.cjs +2 -2
- package/dist/cjs/dbs/adapters/mongodb/index.min.cjs.map +1 -1
- package/dist/cjs/dbs/index.cjs +181 -179
- package/dist/cjs/dbs/index.cjs.map +1 -1
- package/dist/cjs/dbs/index.min.cjs +3 -3
- package/dist/cjs/dbs/index.min.cjs.map +1 -1
- package/dist/cjs/events/adapters/kafka/index.cjs.map +1 -1
- package/dist/cjs/events/adapters/kafka/index.min.cjs +2 -2
- package/dist/cjs/events/adapters/kafka/index.min.cjs.map +1 -1
- package/dist/cjs/events/adapters/rabbitmq/index.cjs +179 -179
- package/dist/cjs/events/adapters/rabbitmq/index.cjs.map +1 -1
- package/dist/cjs/events/adapters/rabbitmq/index.min.cjs +3 -3
- package/dist/cjs/events/adapters/rabbitmq/index.min.cjs.map +1 -1
- package/dist/cjs/orm/adapters/mongodb/index.cjs +144 -144
- package/dist/cjs/orm/adapters/mongodb/index.cjs.map +1 -1
- package/dist/cjs/orm/adapters/mongodb/index.min.cjs +1 -1
- package/dist/cjs/orm/adapters/mongodb/index.min.cjs.map +1 -1
- package/dist/cjs/orm/adapters/postgresql/index.cjs +144 -215
- package/dist/cjs/orm/adapters/postgresql/index.cjs.map +1 -1
- package/dist/cjs/orm/adapters/postgresql/index.min.cjs +11 -11
- package/dist/cjs/orm/adapters/postgresql/index.min.cjs.map +1 -1
- package/dist/cjs/server/adapters/express/index.cjs +338 -226
- package/dist/cjs/server/adapters/express/index.cjs.map +1 -1
- package/dist/cjs/server/adapters/express/index.min.cjs +7 -7
- package/dist/cjs/server/adapters/express/index.min.cjs.map +1 -1
- package/dist/cjs/server/adapters/fastify/index.cjs +323 -211
- package/dist/cjs/server/adapters/fastify/index.cjs.map +1 -1
- package/dist/cjs/server/adapters/fastify/index.min.cjs +7 -7
- package/dist/cjs/server/adapters/fastify/index.min.cjs.map +1 -1
- package/dist/cjs/server/index.cjs +128 -16
- package/dist/cjs/server/index.cjs.map +1 -1
- package/dist/cjs/server/index.min.cjs +6 -6
- package/dist/cjs/server/index.min.cjs.map +1 -1
- package/dist/cjs/utilities/index.cjs +0 -5
- package/dist/cjs/utilities/index.cjs.map +1 -1
- package/dist/cjs/utilities/index.min.cjs +2 -2
- package/dist/cjs/utilities/index.min.cjs.map +1 -1
- package/dist/esm/cache/adapters/in-memory/index.min.mjs +1 -1
- package/dist/esm/cache/adapters/in-memory/index.min.mjs.map +1 -1
- package/dist/esm/cache/adapters/in-memory/index.mjs +6 -3
- package/dist/esm/cache/adapters/in-memory/index.mjs.map +1 -1
- package/dist/esm/cache/adapters/redis/index.min.mjs +1 -1
- package/dist/esm/cache/adapters/redis/index.mjs +5 -3
- package/dist/esm/cache/index.min.mjs +1 -1
- package/dist/esm/cache/index.mjs +2 -2
- package/dist/esm/{chunk-PNZNNUMN.mjs → chunk-26BOI6IL.mjs} +7 -5
- package/dist/esm/{chunk-PNZNNUMN.mjs.map → chunk-26BOI6IL.mjs.map} +1 -1
- package/dist/esm/{chunk-4JLDXF7T.min.mjs → chunk-AODOD22O.min.mjs} +2 -2
- package/dist/esm/chunk-APSDCRY5.min.mjs +32 -0
- package/dist/esm/chunk-APSDCRY5.min.mjs.map +1 -0
- package/dist/esm/{chunk-MDQKODYQ.mjs → chunk-CEYT5YBA.mjs} +204 -348
- package/dist/esm/chunk-CEYT5YBA.mjs.map +1 -0
- package/dist/esm/chunk-CU2HU5UE.min.mjs +2 -0
- package/dist/esm/chunk-CU2HU5UE.min.mjs.map +1 -0
- package/dist/esm/chunk-DAK7OKSH.min.mjs +2 -0
- package/dist/esm/{chunk-SGZNOYC3.min.mjs.map → chunk-DAK7OKSH.min.mjs.map} +1 -1
- package/dist/esm/{chunk-PCAUXBAG.min.mjs → chunk-DAUQA32Q.min.mjs} +2 -2
- package/dist/esm/{chunk-JH6EBXY4.mjs → chunk-FQYRVHQT.mjs} +2 -2
- package/dist/esm/chunk-NEF3UYFA.mjs +144 -0
- package/dist/esm/chunk-NEF3UYFA.mjs.map +1 -0
- package/dist/esm/chunk-NNFUYHQ7.mjs +135 -0
- package/dist/esm/chunk-NNFUYHQ7.mjs.map +1 -0
- package/dist/esm/{chunk-4MXYZS5R.mjs → chunk-PCEHFZ6G.mjs} +9 -5
- package/dist/esm/{chunk-4MXYZS5R.mjs.map → chunk-PCEHFZ6G.mjs.map} +1 -1
- package/dist/esm/{chunk-B5QQ32YY.min.mjs → chunk-QCCDJLBH.min.mjs} +2 -2
- package/dist/esm/{chunk-PQCBVQL6.mjs → chunk-RIXTQQUU.mjs} +2 -2
- package/dist/esm/{chunk-Z2TZ3KR7.mjs → chunk-RPPYCWXW.mjs} +2 -2
- package/dist/esm/{chunk-AKQBDYUO.mjs → chunk-T2O72JBW.mjs} +3 -3
- package/dist/esm/{chunk-TVTYDU2D.mjs → chunk-VQO4MSEC.mjs} +5 -5
- package/dist/esm/{chunk-ZGMFFK6Y.min.mjs → chunk-X7VNAGLR.min.mjs} +2 -2
- package/dist/esm/chunk-XTXAEBXY.min.mjs +2 -0
- package/dist/esm/{chunk-5VW3JAFR.min.mjs.map → chunk-XTXAEBXY.min.mjs.map} +1 -1
- package/dist/esm/{chunk-QHLKB47N.min.mjs → chunk-YDQW6ETS.min.mjs} +2 -2
- package/dist/esm/chunk-ZDBDR3IB.min.mjs +2 -0
- package/dist/esm/chunk-ZDBDR3IB.min.mjs.map +1 -0
- package/dist/esm/dbs/adapters/mongodb/index.min.mjs +1 -1
- package/dist/esm/dbs/adapters/mongodb/index.min.mjs.map +1 -1
- package/dist/esm/dbs/adapters/mongodb/index.mjs +8 -5
- package/dist/esm/dbs/adapters/mongodb/index.mjs.map +1 -1
- package/dist/esm/dbs/index.min.mjs +1 -1
- package/dist/esm/dbs/index.mjs +5 -3
- package/dist/esm/errors/index.min.mjs +1 -1
- package/dist/esm/errors/index.mjs +1 -1
- package/dist/esm/events/adapters/kafka/index.min.mjs +1 -1
- package/dist/esm/events/adapters/kafka/index.mjs +4 -2
- package/dist/esm/events/adapters/rabbitmq/index.min.mjs +1 -1
- package/dist/esm/events/adapters/rabbitmq/index.min.mjs.map +1 -1
- package/dist/esm/events/adapters/rabbitmq/index.mjs +7 -3
- package/dist/esm/events/adapters/rabbitmq/index.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/instance/index.min.mjs +1 -1
- package/dist/esm/instance/index.mjs +1 -1
- package/dist/esm/{introspection-32BRYKYY.mjs → introspection-FGDVYTPP.mjs} +3 -3
- package/dist/esm/introspection-UDWDS6DV.min.mjs +2 -0
- package/dist/esm/jobs/adapters/redis/index.min.mjs +1 -1
- package/dist/esm/jobs/adapters/redis/index.min.mjs.map +1 -1
- package/dist/esm/jobs/adapters/redis/index.mjs +10 -6
- package/dist/esm/jobs/adapters/redis/index.mjs.map +1 -1
- package/dist/esm/orm/adapters/in-memory/index.min.mjs +1 -1
- package/dist/esm/orm/adapters/in-memory/index.mjs +4 -3
- package/dist/esm/orm/adapters/json/index.min.mjs +1 -1
- package/dist/esm/orm/adapters/json/index.min.mjs.map +1 -1
- package/dist/esm/orm/adapters/json/index.mjs +6 -5
- package/dist/esm/orm/adapters/json/index.mjs.map +1 -1
- package/dist/esm/orm/adapters/mongodb/index.min.mjs +1 -1
- package/dist/esm/orm/adapters/mongodb/index.min.mjs.map +1 -1
- package/dist/esm/orm/adapters/mongodb/index.mjs +6 -4
- package/dist/esm/orm/adapters/mongodb/index.mjs.map +1 -1
- package/dist/esm/orm/adapters/postgresql/index.min.mjs +2 -2
- package/dist/esm/orm/adapters/postgresql/index.min.mjs.map +1 -1
- package/dist/esm/orm/adapters/postgresql/index.mjs +8 -5
- package/dist/esm/orm/adapters/postgresql/index.mjs.map +1 -1
- package/dist/esm/orm/index.min.mjs +1 -1
- package/dist/esm/orm/index.mjs +3 -3
- package/dist/esm/server/adapters/express/index.min.mjs +1 -1
- package/dist/esm/server/adapters/express/index.min.mjs.map +1 -1
- package/dist/esm/server/adapters/express/index.mjs +7 -3
- package/dist/esm/server/adapters/express/index.mjs.map +1 -1
- package/dist/esm/server/adapters/fastify/index.min.mjs +1 -1
- package/dist/esm/server/adapters/fastify/index.min.mjs.map +1 -1
- package/dist/esm/server/adapters/fastify/index.mjs +7 -3
- package/dist/esm/server/adapters/fastify/index.mjs.map +1 -1
- package/dist/esm/server/index.min.mjs +1 -1
- package/dist/esm/server/index.mjs +1 -1
- package/dist/esm/utilities/index.min.mjs +1 -1
- package/dist/esm/utilities/index.mjs +5 -4
- package/dist/esm/validations/index.min.mjs +1 -1
- package/dist/esm/validations/index.mjs +1 -1
- package/dist/types/{base-DVr0fHil.d.ts → base-qDndMBf8.d.ts} +9 -3
- package/dist/types/cache/adapters/in-memory/index.js +7 -4
- package/dist/types/cache/adapters/redis/index.js +5 -3
- package/dist/types/cache/index.js +2 -2
- package/dist/types/{chunk-NJ2FHI3U.js → chunk-35CDCTLR.js} +4 -4
- package/dist/types/{chunk-XGGGAEET.js → chunk-4YQA5GPT.js} +8 -4
- package/dist/types/{chunk-65EHKCDZ.js → chunk-AQIV47BY.js} +6 -4
- package/dist/types/{chunk-YTY3EFNB.js → chunk-BKDWUJRG.js} +203 -347
- package/dist/types/{chunk-JQ2FWX4W.js → chunk-DA2VYP7D.js} +1 -1
- package/dist/types/{chunk-3TKJGSCZ.js → chunk-GDMGPX4C.js} +1 -1
- package/dist/types/chunk-H5V6ADFD.js +134 -0
- package/dist/types/{chunk-3M4PBZAQ.js → chunk-OOKJEMQI.js} +2 -2
- package/dist/types/chunk-PPD4WDG6.js +143 -0
- package/dist/types/{chunk-OHFTQGQG.js → chunk-T7K7PO6G.js} +1 -1
- package/dist/types/dbs/adapters/mongodb/index.js +8 -5
- package/dist/types/dbs/index.js +5 -3
- package/dist/types/errors/index.js +1 -1
- package/dist/types/events/adapters/kafka/index.js +4 -2
- package/dist/types/events/adapters/rabbitmq/index.js +7 -3
- package/dist/types/index.js +1 -1
- package/dist/types/instance/index.js +1 -1
- package/dist/types/{introspection-VOIU3XE6.js → introspection-FSNS33CQ.js} +2 -2
- package/dist/types/jobs/adapters/redis/index.js +10 -6
- package/dist/types/orm/adapters/in-memory/index.js +4 -3
- package/dist/types/orm/adapters/json/index.js +6 -5
- package/dist/types/orm/adapters/mongodb/index.js +6 -4
- package/dist/types/orm/adapters/postgresql/index.js +8 -5
- package/dist/types/orm/index.js +3 -3
- package/dist/types/server/adapters/express/index.d.ts +1 -1
- package/dist/types/server/adapters/express/index.js +7 -3
- package/dist/types/server/adapters/fastify/index.d.ts +1 -1
- package/dist/types/server/adapters/fastify/index.js +7 -3
- package/dist/types/server/index.d.ts +2 -2
- package/dist/types/server/index.js +1 -1
- package/dist/types/utilities/index.d.ts +1 -2
- package/dist/types/utilities/index.js +5 -4
- package/dist/types/validations/index.js +1 -1
- package/package.json +1 -1
- package/dist/esm/chunk-5VW3JAFR.min.mjs +0 -2
- package/dist/esm/chunk-FLAPYQUT.min.mjs +0 -32
- package/dist/esm/chunk-FLAPYQUT.min.mjs.map +0 -1
- package/dist/esm/chunk-MDQKODYQ.mjs.map +0 -1
- package/dist/esm/chunk-SGZNOYC3.min.mjs +0 -2
- package/dist/esm/introspection-A72WMWE3.min.mjs +0 -2
- /package/dist/esm/{chunk-4JLDXF7T.min.mjs.map → chunk-AODOD22O.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-PCAUXBAG.min.mjs.map → chunk-DAUQA32Q.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-JH6EBXY4.mjs.map → chunk-FQYRVHQT.mjs.map} +0 -0
- /package/dist/esm/{chunk-B5QQ32YY.min.mjs.map → chunk-QCCDJLBH.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-PQCBVQL6.mjs.map → chunk-RIXTQQUU.mjs.map} +0 -0
- /package/dist/esm/{chunk-Z2TZ3KR7.mjs.map → chunk-RPPYCWXW.mjs.map} +0 -0
- /package/dist/esm/{chunk-AKQBDYUO.mjs.map → chunk-T2O72JBW.mjs.map} +0 -0
- /package/dist/esm/{chunk-TVTYDU2D.mjs.map → chunk-VQO4MSEC.mjs.map} +0 -0
- /package/dist/esm/{chunk-ZGMFFK6Y.min.mjs.map → chunk-X7VNAGLR.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-QHLKB47N.min.mjs.map → chunk-YDQW6ETS.min.mjs.map} +0 -0
- /package/dist/esm/{introspection-32BRYKYY.mjs.map → introspection-FGDVYTPP.mjs.map} +0 -0
- /package/dist/esm/{introspection-A72WMWE3.min.mjs.map → introspection-UDWDS6DV.min.mjs.map} +0 -0
|
@@ -46,7 +46,7 @@ var import_pino_http = require("pino-http");
|
|
|
46
46
|
// src/instance/index.ts
|
|
47
47
|
var import_pino = __toESM(require("pino"), 1);
|
|
48
48
|
var import_ulid = require("ulid");
|
|
49
|
-
var
|
|
49
|
+
var import_valleyed8 = require("valleyed");
|
|
50
50
|
|
|
51
51
|
// src/errors/equippedError.ts
|
|
52
52
|
var EquippedError = class extends Error {
|
|
@@ -73,7 +73,7 @@ var import_cors = require("@fastify/cors");
|
|
|
73
73
|
var import_cors2 = require("cors");
|
|
74
74
|
var import_socket = require("socket.io");
|
|
75
75
|
var import_supertest = __toESM(require("supertest"), 1);
|
|
76
|
-
var
|
|
76
|
+
var import_valleyed5 = require("valleyed");
|
|
77
77
|
|
|
78
78
|
// src/events/adapters/base.ts
|
|
79
79
|
var EventBus = class {
|
|
@@ -426,170 +426,6 @@ var openapi = (config) => {
|
|
|
426
426
|
};
|
|
427
427
|
};
|
|
428
428
|
|
|
429
|
-
// src/utilities/configurable.ts
|
|
430
|
-
var import_valleyed5 = require("valleyed");
|
|
431
|
-
function configurable(pipeFn, base) {
|
|
432
|
-
const pipe = pipeFn();
|
|
433
|
-
import_valleyed5.v.compile(pipe);
|
|
434
|
-
class Configurable extends base {
|
|
435
|
-
constructor(config, ...baseArgs) {
|
|
436
|
-
super(...baseArgs);
|
|
437
|
-
this.config = config;
|
|
438
|
-
}
|
|
439
|
-
static create(input, ...args) {
|
|
440
|
-
const r = import_valleyed5.v.validate(pipe, input);
|
|
441
|
-
if (!r.valid) throw r.error;
|
|
442
|
-
return new this(r.value, ...args);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
return Configurable;
|
|
446
|
-
}
|
|
447
|
-
if (void 0) {
|
|
448
|
-
const { describe, test, expect, expectTypeOf } = void 0;
|
|
449
|
-
const { v: v8 } = null;
|
|
450
|
-
const testPipe = () => v8.object({
|
|
451
|
-
host: v8.string(),
|
|
452
|
-
port: v8.number()
|
|
453
|
-
});
|
|
454
|
-
class TestBase {
|
|
455
|
-
baseValue;
|
|
456
|
-
constructor() {
|
|
457
|
-
this.baseValue = "base";
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
class TestBaseWithArgs {
|
|
461
|
-
label;
|
|
462
|
-
constructor(label) {
|
|
463
|
-
this.label = label;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
describe("configurable", () => {
|
|
467
|
-
test("validation runs in static create before constructor body executes", () => {
|
|
468
|
-
let constructorRan = false;
|
|
469
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
470
|
-
class MyClass extends Wrapped {
|
|
471
|
-
constructor(config) {
|
|
472
|
-
super(config);
|
|
473
|
-
constructorRan = true;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
expect(() => MyClass.create({ host: 123, port: "bad" })).toThrow();
|
|
477
|
-
expect(constructorRan).toBe(false);
|
|
478
|
-
MyClass.create({ host: "localhost", port: 3e3 });
|
|
479
|
-
expect(constructorRan).toBe(true);
|
|
480
|
-
});
|
|
481
|
-
test("constructor receives validated value", () => {
|
|
482
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
483
|
-
let receivedConfig;
|
|
484
|
-
class MyClass extends Wrapped {
|
|
485
|
-
constructor(config) {
|
|
486
|
-
super(config);
|
|
487
|
-
receivedConfig = this.config;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
MyClass.create({ host: "localhost", port: 3e3 });
|
|
491
|
-
expect(receivedConfig).toEqual({ host: "localhost", port: 3e3 });
|
|
492
|
-
});
|
|
493
|
-
test("external new is a compile error", () => {
|
|
494
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
495
|
-
class MyClass extends Wrapped {
|
|
496
|
-
constructor(config) {
|
|
497
|
-
super(config);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
void (() => new MyClass({ host: "localhost", port: 3e3 }));
|
|
501
|
-
});
|
|
502
|
-
test("static Config resolves to PipeOutput<P> at the type level", () => {
|
|
503
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
504
|
-
class MyClass extends Wrapped {
|
|
505
|
-
constructor(config) {
|
|
506
|
-
super(config);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
expectTypeOf().toEqualTypeOf();
|
|
510
|
-
expect(MyClass.create).toBeTypeOf("function");
|
|
511
|
-
});
|
|
512
|
-
test("ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures", () => {
|
|
513
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
514
|
-
class MyClass extends Wrapped {
|
|
515
|
-
extra;
|
|
516
|
-
constructor(config, extra) {
|
|
517
|
-
super(config);
|
|
518
|
-
this.extra = extra;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 }, 42);
|
|
522
|
-
expect(instance.extra).toBe(42);
|
|
523
|
-
expectTypeOf(instance).toHaveProperty("extra");
|
|
524
|
-
expectTypeOf(instance.extra).toEqualTypeOf();
|
|
525
|
-
void (() => MyClass.create({ host: "localhost", port: 3e3 }, "not-a-number"));
|
|
526
|
-
});
|
|
527
|
-
test("base-args forwarding works for non-zero-arg bases", () => {
|
|
528
|
-
const Wrapped = configurable(testPipe, TestBaseWithArgs);
|
|
529
|
-
class MyClass extends Wrapped {
|
|
530
|
-
constructor(config, label) {
|
|
531
|
-
super(config, label);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 }, "test-label");
|
|
535
|
-
expect(instance.label).toBe("test-label");
|
|
536
|
-
});
|
|
537
|
-
test("config is accessible as protected readonly on instances", () => {
|
|
538
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
539
|
-
class MyClass extends Wrapped {
|
|
540
|
-
constructor(config) {
|
|
541
|
-
super(config);
|
|
542
|
-
}
|
|
543
|
-
getHost() {
|
|
544
|
-
return this.config.host;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 });
|
|
548
|
-
expect(instance.getHost()).toBe("localhost");
|
|
549
|
-
});
|
|
550
|
-
test("accepts an abstract base class", () => {
|
|
551
|
-
class AbstractBase {
|
|
552
|
-
}
|
|
553
|
-
const Wrapped = configurable(testPipe, AbstractBase);
|
|
554
|
-
class Concrete extends Wrapped {
|
|
555
|
-
constructor(config) {
|
|
556
|
-
super(config);
|
|
557
|
-
}
|
|
558
|
-
greet() {
|
|
559
|
-
return `hello from ${this.config.host}`;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
const instance = Concrete.create({ host: "localhost", port: 3e3 });
|
|
563
|
-
expect(instance.greet()).toBe("hello from localhost");
|
|
564
|
-
expectTypeOf(instance).toHaveProperty("config");
|
|
565
|
-
});
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// src/utilities/json.ts
|
|
570
|
-
var parseJSONValue = (data) => {
|
|
571
|
-
try {
|
|
572
|
-
if (data?.constructor?.name !== "String") return data;
|
|
573
|
-
return JSON.parse(data);
|
|
574
|
-
} catch {
|
|
575
|
-
return data;
|
|
576
|
-
}
|
|
577
|
-
};
|
|
578
|
-
function parseJSONObject(data) {
|
|
579
|
-
return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, parseJSONValue(value)]));
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// src/utilities/media.ts
|
|
583
|
-
var import_music_metadata = require("music-metadata");
|
|
584
|
-
var getMediaDuration = async (buffer) => {
|
|
585
|
-
try {
|
|
586
|
-
const meta = await (0, import_music_metadata.parseBuffer)(buffer);
|
|
587
|
-
return meta.format.duration ?? 0;
|
|
588
|
-
} catch {
|
|
589
|
-
return 0;
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
|
|
593
429
|
// src/server/requests.ts
|
|
594
430
|
var Request = class {
|
|
595
431
|
ip;
|
|
@@ -618,8 +454,10 @@ var Request = class {
|
|
|
618
454
|
this.params = params;
|
|
619
455
|
this.cookies = cookies;
|
|
620
456
|
this.headers = headers;
|
|
621
|
-
|
|
622
|
-
|
|
457
|
+
const hasFiles = Object.keys(files).length > 0;
|
|
458
|
+
const bodyFields = body && typeof body === "object" && !Array.isArray(body) ? body : {};
|
|
459
|
+
this.query = query;
|
|
460
|
+
this.body = hasFiles ? Object.assign({}, bodyFields, files) : body;
|
|
623
461
|
}
|
|
624
462
|
pipe(stream, opts = {}) {
|
|
625
463
|
return new Response({ ...opts, piped: true, body: stream });
|
|
@@ -665,6 +503,83 @@ var Response = class {
|
|
|
665
503
|
});
|
|
666
504
|
}
|
|
667
505
|
};
|
|
506
|
+
if (void 0) {
|
|
507
|
+
const { describe, expect, test } = void 0;
|
|
508
|
+
describe("Request", () => {
|
|
509
|
+
test("preserves adapter-provided query and body values without JSON normalization", () => {
|
|
510
|
+
const query = {
|
|
511
|
+
count: "10",
|
|
512
|
+
active: "true",
|
|
513
|
+
filter: '{"name":"test"}',
|
|
514
|
+
quoted: '"value"'
|
|
515
|
+
};
|
|
516
|
+
const body = {
|
|
517
|
+
count: "10",
|
|
518
|
+
active: "false",
|
|
519
|
+
payload: '{"nested":true}',
|
|
520
|
+
quoted: '"value"'
|
|
521
|
+
};
|
|
522
|
+
const request = new Request({
|
|
523
|
+
ip: void 0,
|
|
524
|
+
body,
|
|
525
|
+
cookies: {},
|
|
526
|
+
params: {},
|
|
527
|
+
query,
|
|
528
|
+
method: "post",
|
|
529
|
+
path: "/items",
|
|
530
|
+
headers: {},
|
|
531
|
+
files: {}
|
|
532
|
+
});
|
|
533
|
+
expect(request.query).toEqual(query);
|
|
534
|
+
expect(request.body).toEqual(body);
|
|
535
|
+
});
|
|
536
|
+
test("continues merging uploaded files into body fields without parsing string fields", () => {
|
|
537
|
+
const file = {
|
|
538
|
+
name: "avatar.png",
|
|
539
|
+
type: "image/png",
|
|
540
|
+
size: 4,
|
|
541
|
+
isTruncated: false,
|
|
542
|
+
data: Buffer.from("file"),
|
|
543
|
+
duration: 0
|
|
544
|
+
};
|
|
545
|
+
const body = { metadata: '{"alt":"avatar"}' };
|
|
546
|
+
const request = new Request({
|
|
547
|
+
ip: void 0,
|
|
548
|
+
body,
|
|
549
|
+
cookies: {},
|
|
550
|
+
params: {},
|
|
551
|
+
query: {},
|
|
552
|
+
method: "post",
|
|
553
|
+
path: "/upload",
|
|
554
|
+
headers: {},
|
|
555
|
+
files: { avatar: [file] }
|
|
556
|
+
});
|
|
557
|
+
expect(request.body).toEqual({ metadata: '{"alt":"avatar"}', avatar: [file] });
|
|
558
|
+
});
|
|
559
|
+
test("does not spread non-object body values when uploaded files are present", () => {
|
|
560
|
+
const file = {
|
|
561
|
+
name: "avatar.png",
|
|
562
|
+
type: "image/png",
|
|
563
|
+
size: 4,
|
|
564
|
+
isTruncated: false,
|
|
565
|
+
data: Buffer.from("file"),
|
|
566
|
+
duration: 0
|
|
567
|
+
};
|
|
568
|
+
const request = new Request({
|
|
569
|
+
ip: void 0,
|
|
570
|
+
body: "raw text body",
|
|
571
|
+
cookies: {},
|
|
572
|
+
params: {},
|
|
573
|
+
query: {},
|
|
574
|
+
method: "post",
|
|
575
|
+
path: "/upload",
|
|
576
|
+
headers: {},
|
|
577
|
+
files: { avatar: [file] }
|
|
578
|
+
});
|
|
579
|
+
expect(request.body).toEqual({ avatar: [file] });
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
}
|
|
668
583
|
|
|
669
584
|
// src/server/requests-auth-methods/base.ts
|
|
670
585
|
var import_node_http2 = require("http2");
|
|
@@ -795,50 +710,50 @@ var SocketEmitter = class {
|
|
|
795
710
|
};
|
|
796
711
|
|
|
797
712
|
// src/server/adapters/base.ts
|
|
798
|
-
var serverConfigPipe = () =>
|
|
799
|
-
port:
|
|
800
|
-
cors:
|
|
801
|
-
|
|
802
|
-
origin:
|
|
803
|
-
methods:
|
|
804
|
-
credentials:
|
|
713
|
+
var serverConfigPipe = () => import_valleyed5.v.object({
|
|
714
|
+
port: import_valleyed5.v.number(),
|
|
715
|
+
cors: import_valleyed5.v.optional(
|
|
716
|
+
import_valleyed5.v.object({
|
|
717
|
+
origin: import_valleyed5.v.optional(import_valleyed5.v.or([import_valleyed5.v.array(import_valleyed5.v.string()), import_valleyed5.v.is(true)])),
|
|
718
|
+
methods: import_valleyed5.v.optional(import_valleyed5.v.array(import_valleyed5.v.in(Object.values(Methods)))),
|
|
719
|
+
credentials: import_valleyed5.v.optional(import_valleyed5.v.boolean())
|
|
805
720
|
})
|
|
806
721
|
),
|
|
807
|
-
eventBus:
|
|
808
|
-
publicPath:
|
|
809
|
-
healthPath:
|
|
810
|
-
openapi:
|
|
811
|
-
|
|
812
|
-
docsVersion:
|
|
813
|
-
docsBaseUrl:
|
|
814
|
-
docsPath:
|
|
722
|
+
eventBus: import_valleyed5.v.optional(import_valleyed5.v.instanceOf(EventBus)),
|
|
723
|
+
publicPath: import_valleyed5.v.optional(import_valleyed5.v.string()),
|
|
724
|
+
healthPath: import_valleyed5.v.optional(import_valleyed5.v.string()),
|
|
725
|
+
openapi: import_valleyed5.v.defaults(
|
|
726
|
+
import_valleyed5.v.object({
|
|
727
|
+
docsVersion: import_valleyed5.v.defaults(import_valleyed5.v.string(), "1.0.0"),
|
|
728
|
+
docsBaseUrl: import_valleyed5.v.defaults(import_valleyed5.v.array(import_valleyed5.v.string()), ["/"]),
|
|
729
|
+
docsPath: import_valleyed5.v.defaults(import_valleyed5.v.string(), "/__docs")
|
|
815
730
|
}),
|
|
816
731
|
{}
|
|
817
732
|
),
|
|
818
|
-
requests:
|
|
819
|
-
|
|
820
|
-
log:
|
|
821
|
-
rateLimit:
|
|
822
|
-
|
|
823
|
-
enabled:
|
|
824
|
-
periodInMs:
|
|
825
|
-
limit:
|
|
733
|
+
requests: import_valleyed5.v.defaults(
|
|
734
|
+
import_valleyed5.v.object({
|
|
735
|
+
log: import_valleyed5.v.defaults(import_valleyed5.v.boolean(), true),
|
|
736
|
+
rateLimit: import_valleyed5.v.defaults(
|
|
737
|
+
import_valleyed5.v.object({
|
|
738
|
+
enabled: import_valleyed5.v.defaults(import_valleyed5.v.boolean(), false),
|
|
739
|
+
periodInMs: import_valleyed5.v.defaults(import_valleyed5.v.number(), 60 * 60 * 1e3),
|
|
740
|
+
limit: import_valleyed5.v.defaults(import_valleyed5.v.number(), 5e3)
|
|
826
741
|
}),
|
|
827
742
|
{}
|
|
828
743
|
),
|
|
829
|
-
slowdown:
|
|
830
|
-
|
|
831
|
-
enabled:
|
|
832
|
-
periodInMs:
|
|
833
|
-
delayAfter:
|
|
834
|
-
delayInMs:
|
|
744
|
+
slowdown: import_valleyed5.v.defaults(
|
|
745
|
+
import_valleyed5.v.object({
|
|
746
|
+
enabled: import_valleyed5.v.defaults(import_valleyed5.v.boolean(), false),
|
|
747
|
+
periodInMs: import_valleyed5.v.defaults(import_valleyed5.v.number(), 10 * 60 * 1e3),
|
|
748
|
+
delayAfter: import_valleyed5.v.defaults(import_valleyed5.v.number(), 2e3),
|
|
749
|
+
delayInMs: import_valleyed5.v.defaults(import_valleyed5.v.number(), 500)
|
|
835
750
|
}),
|
|
836
751
|
{}
|
|
837
752
|
)
|
|
838
753
|
}),
|
|
839
754
|
{}
|
|
840
755
|
),
|
|
841
|
-
socketsAuthMethods:
|
|
756
|
+
socketsAuthMethods: import_valleyed5.v.defaults(import_valleyed5.v.array(import_valleyed5.v.instanceOf(BaseRequestAuthMethod)), [])
|
|
842
757
|
});
|
|
843
758
|
var rawResponseHandledSymbol = /* @__PURE__ */ Symbol("rawResponseHandled");
|
|
844
759
|
var rawResponseHandled = Object.freeze({ [rawResponseHandledSymbol]: true });
|
|
@@ -859,7 +774,7 @@ function writeRawHandlerError(response, error) {
|
|
|
859
774
|
var errorsSchemas = Object.entries(StatusCodes).filter(([, value]) => value > 399).map(([key, value]) => ({
|
|
860
775
|
status: value,
|
|
861
776
|
contentType: "application/json",
|
|
862
|
-
pipe:
|
|
777
|
+
pipe: import_valleyed5.v.meta(import_valleyed5.v.array(import_valleyed5.v.object({ message: import_valleyed5.v.string(), field: import_valleyed5.v.optional(import_valleyed5.v.string()) })), {
|
|
863
778
|
$refId: `Errors.${key}Response`,
|
|
864
779
|
description: `${key} Response`
|
|
865
780
|
})
|
|
@@ -873,6 +788,7 @@ var Server = class {
|
|
|
873
788
|
#queue = [];
|
|
874
789
|
#routesByKey = /* @__PURE__ */ new Set();
|
|
875
790
|
#started = false;
|
|
791
|
+
#beforeListenHandlers = [];
|
|
876
792
|
#notFoundHandler = null;
|
|
877
793
|
setup(httpServer, config) {
|
|
878
794
|
this.#httpServer = httpServer;
|
|
@@ -928,6 +844,11 @@ var Server = class {
|
|
|
928
844
|
this.#notFoundHandler = handler;
|
|
929
845
|
return this;
|
|
930
846
|
}
|
|
847
|
+
onBeforeListen(handler) {
|
|
848
|
+
if (this.#started) throw new EquippedError("Cannot add before-listen handler after server has started", {});
|
|
849
|
+
this.#beforeListenHandlers.push(handler);
|
|
850
|
+
return this;
|
|
851
|
+
}
|
|
931
852
|
test() {
|
|
932
853
|
return (0, import_supertest.default)(this.#httpServer);
|
|
933
854
|
}
|
|
@@ -961,6 +882,7 @@ var Server = class {
|
|
|
961
882
|
});
|
|
962
883
|
return await this.handleResponse(res, response);
|
|
963
884
|
});
|
|
885
|
+
for (const handler of this.#beforeListenHandlers) await handler({ httpServer: this.#httpServer, port: config.port });
|
|
964
886
|
const started = await this.startServer(config.port);
|
|
965
887
|
if (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${config.port}`);
|
|
966
888
|
return started;
|
|
@@ -1009,37 +931,37 @@ var Server = class {
|
|
|
1009
931
|
{ key: "responseCookies", type: "response" }
|
|
1010
932
|
];
|
|
1011
933
|
defs.forEach((def) => {
|
|
1012
|
-
const pipe = schema[def.key] ??
|
|
934
|
+
const pipe = schema[def.key] ?? import_valleyed5.v.any();
|
|
1013
935
|
if (def.skip) return;
|
|
1014
936
|
if (def.type === "request") {
|
|
1015
937
|
requestPipeDefs[def.key] = pipe;
|
|
1016
|
-
jsonSchema.request[def.key] =
|
|
938
|
+
jsonSchema.request[def.key] = import_valleyed5.v.schema(pipe);
|
|
1017
939
|
}
|
|
1018
940
|
if (def.type === "response") {
|
|
1019
941
|
const pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe });
|
|
1020
|
-
responsePipeDefs[def.key] =
|
|
942
|
+
responsePipeDefs[def.key] = import_valleyed5.v.any().pipe((input) => {
|
|
1021
943
|
const p = pipeRecords.find((rec) => rec.status === status)?.pipe;
|
|
1022
|
-
if (!p) throw
|
|
1023
|
-
const r =
|
|
944
|
+
if (!p) throw import_valleyed5.PipeError.root(`schema not defined for status code: ${status}`, input);
|
|
945
|
+
const r = import_valleyed5.v.validate(p, input);
|
|
1024
946
|
if (!r.valid) throw r.error;
|
|
1025
947
|
return r.value;
|
|
1026
948
|
});
|
|
1027
949
|
jsonSchema.response[def.key] = pipeRecords.map((record) => ({
|
|
1028
950
|
status: record.status,
|
|
1029
951
|
contentType: record.contentType,
|
|
1030
|
-
schema:
|
|
952
|
+
schema: import_valleyed5.v.schema(record.pipe)
|
|
1031
953
|
}));
|
|
1032
954
|
}
|
|
1033
955
|
});
|
|
1034
|
-
const requestPipe =
|
|
1035
|
-
|
|
1036
|
-
const responsePipe =
|
|
1037
|
-
|
|
956
|
+
const requestPipe = import_valleyed5.v.object(requestPipeDefs);
|
|
957
|
+
import_valleyed5.v.compile(requestPipe, { allErrors: true });
|
|
958
|
+
const responsePipe = import_valleyed5.v.object(responsePipeDefs);
|
|
959
|
+
import_valleyed5.v.compile(responsePipe, { allErrors: true });
|
|
1038
960
|
const validateRequest = async (request) => {
|
|
1039
961
|
if (!Object.keys(requestPipeDefs)) return request;
|
|
1040
962
|
const validity = requestLocalStorage.run(
|
|
1041
963
|
request,
|
|
1042
|
-
() =>
|
|
964
|
+
() => import_valleyed5.v.validate(requestPipe, {
|
|
1043
965
|
params: request.params,
|
|
1044
966
|
headers: request.headers,
|
|
1045
967
|
query: request.query,
|
|
@@ -1061,7 +983,7 @@ var Server = class {
|
|
|
1061
983
|
contentType = response.contentType;
|
|
1062
984
|
const validity = responseLocalStorage.run(
|
|
1063
985
|
response,
|
|
1064
|
-
() =>
|
|
986
|
+
() => import_valleyed5.v.validate(responsePipe, {
|
|
1065
987
|
responseHeaders: response.headers,
|
|
1066
988
|
responseCookies: Object.fromEntries(Object.entries(response.cookies).map(([key, val]) => [key, val.value])),
|
|
1067
989
|
response: response.body
|
|
@@ -1112,6 +1034,7 @@ if (void 0) {
|
|
|
1112
1034
|
const testInstanceState = globalThis;
|
|
1113
1035
|
class TestServer extends Server {
|
|
1114
1036
|
handledResponse = null;
|
|
1037
|
+
startedPorts = [];
|
|
1115
1038
|
notFoundHandler = null;
|
|
1116
1039
|
constructor() {
|
|
1117
1040
|
super();
|
|
@@ -1156,7 +1079,8 @@ if (void 0) {
|
|
|
1156
1079
|
registerNotFoundHandler(cb) {
|
|
1157
1080
|
this.notFoundHandler = cb;
|
|
1158
1081
|
}
|
|
1159
|
-
async startServer() {
|
|
1082
|
+
async startServer(port) {
|
|
1083
|
+
this.startedPorts.push(port);
|
|
1160
1084
|
return true;
|
|
1161
1085
|
}
|
|
1162
1086
|
async dispatchNotFound(path) {
|
|
@@ -1167,6 +1091,43 @@ if (void 0) {
|
|
|
1167
1091
|
return { handledResponse: this.handledResponse, rawResponse };
|
|
1168
1092
|
}
|
|
1169
1093
|
}
|
|
1094
|
+
describe("Server before-listen handlers", () => {
|
|
1095
|
+
test("runs before-listen handlers before adapter listen in registration order", async () => {
|
|
1096
|
+
ensureTestInstance();
|
|
1097
|
+
const server = new TestServer();
|
|
1098
|
+
const calls = [];
|
|
1099
|
+
let receivedServer = null;
|
|
1100
|
+
server.onBeforeListen(({ httpServer, port }) => {
|
|
1101
|
+
calls.push(`first:${port}`);
|
|
1102
|
+
receivedServer = httpServer;
|
|
1103
|
+
expect(server.startedPorts).toEqual([]);
|
|
1104
|
+
}).onBeforeListen(({ httpServer, port }) => {
|
|
1105
|
+
calls.push(`second:${port}`);
|
|
1106
|
+
expect(httpServer).toBe(receivedServer);
|
|
1107
|
+
expect(server.startedPorts).toEqual([]);
|
|
1108
|
+
});
|
|
1109
|
+
await server.start();
|
|
1110
|
+
expect(calls).toEqual(["first:0", "second:0"]);
|
|
1111
|
+
expect(receivedServer).toBeInstanceOf(http.Server);
|
|
1112
|
+
expect(server.startedPorts).toEqual([0]);
|
|
1113
|
+
});
|
|
1114
|
+
test("rejects startup when a before-listen handler fails before adapter listen", async () => {
|
|
1115
|
+
ensureTestInstance();
|
|
1116
|
+
const server = new TestServer();
|
|
1117
|
+
server.onBeforeListen(async () => {
|
|
1118
|
+
throw new Error("before-listen failed");
|
|
1119
|
+
});
|
|
1120
|
+
await expect(server.start()).rejects.toThrow("before-listen failed");
|
|
1121
|
+
expect(server.startedPorts).toEqual([]);
|
|
1122
|
+
});
|
|
1123
|
+
test("rejects adding before-listen handlers after server startup", async () => {
|
|
1124
|
+
ensureTestInstance();
|
|
1125
|
+
const server = new TestServer();
|
|
1126
|
+
await server.start();
|
|
1127
|
+
expect(() => server.onBeforeListen(() => {
|
|
1128
|
+
})).toThrow("Cannot add before-listen handler after server has started");
|
|
1129
|
+
});
|
|
1130
|
+
});
|
|
1170
1131
|
describe("Server not-found handler", () => {
|
|
1171
1132
|
test("throws the default Equipped not-found error when no custom handler is set", async () => {
|
|
1172
1133
|
ensureTestInstance();
|
|
@@ -1675,22 +1636,22 @@ if (void 0) {
|
|
|
1675
1636
|
}
|
|
1676
1637
|
|
|
1677
1638
|
// src/instance/settings.ts
|
|
1678
|
-
var
|
|
1679
|
-
var instanceSettingsPipe = () =>
|
|
1680
|
-
app:
|
|
1681
|
-
name:
|
|
1639
|
+
var import_valleyed7 = require("valleyed");
|
|
1640
|
+
var instanceSettingsPipe = () => import_valleyed7.v.object({
|
|
1641
|
+
app: import_valleyed7.v.object({
|
|
1642
|
+
name: import_valleyed7.v.string()
|
|
1682
1643
|
}),
|
|
1683
|
-
log:
|
|
1684
|
-
|
|
1685
|
-
level:
|
|
1644
|
+
log: import_valleyed7.v.defaults(
|
|
1645
|
+
import_valleyed7.v.object({
|
|
1646
|
+
level: import_valleyed7.v.defaults(import_valleyed7.v.in(["fatal", "error", "warn", "info", "debug", "trace", "silent"]), "info")
|
|
1686
1647
|
}),
|
|
1687
1648
|
{}
|
|
1688
1649
|
),
|
|
1689
|
-
utils:
|
|
1690
|
-
|
|
1691
|
-
hashSaltRounds:
|
|
1692
|
-
paginationDefaultLimit:
|
|
1693
|
-
maxFileUploadSizeInMb:
|
|
1650
|
+
utils: import_valleyed7.v.defaults(
|
|
1651
|
+
import_valleyed7.v.object({
|
|
1652
|
+
hashSaltRounds: import_valleyed7.v.defaults(import_valleyed7.v.number(), 10),
|
|
1653
|
+
paginationDefaultLimit: import_valleyed7.v.defaults(import_valleyed7.v.number(), 100),
|
|
1654
|
+
maxFileUploadSizeInMb: import_valleyed7.v.defaults(import_valleyed7.v.number(), 500)
|
|
1694
1655
|
}),
|
|
1695
1656
|
{}
|
|
1696
1657
|
)
|
|
@@ -1740,7 +1701,7 @@ var Instance = class _Instance {
|
|
|
1740
1701
|
}
|
|
1741
1702
|
}
|
|
1742
1703
|
static envs(envsPipe) {
|
|
1743
|
-
const envValidity =
|
|
1704
|
+
const envValidity = import_valleyed8.v.validate(envsPipe, process.env);
|
|
1744
1705
|
if (!envValidity.valid) {
|
|
1745
1706
|
_Instance.crash(
|
|
1746
1707
|
new EquippedError(`Environment variables are not valid
|
|
@@ -1753,7 +1714,7 @@ ${envValidity.error.toString()}`, {
|
|
|
1753
1714
|
}
|
|
1754
1715
|
static create(settings) {
|
|
1755
1716
|
if (_Instance.#instance) return _Instance.crash(new EquippedError("Instance has been initialized already", {}));
|
|
1756
|
-
const settingsValidity =
|
|
1717
|
+
const settingsValidity = import_valleyed8.v.validate(instanceSettingsPipe(), settings);
|
|
1757
1718
|
if (!settingsValidity.valid) {
|
|
1758
1719
|
_Instance.crash(
|
|
1759
1720
|
new EquippedError(`Settings are not valid
|
|
@@ -1807,6 +1768,157 @@ ${settingsValidity.error.toString()}`, {
|
|
|
1807
1768
|
}
|
|
1808
1769
|
};
|
|
1809
1770
|
|
|
1771
|
+
// src/utilities/configurable.ts
|
|
1772
|
+
var import_valleyed9 = require("valleyed");
|
|
1773
|
+
function configurable(pipeFn, base) {
|
|
1774
|
+
const pipe = pipeFn();
|
|
1775
|
+
import_valleyed9.v.compile(pipe);
|
|
1776
|
+
class Configurable extends base {
|
|
1777
|
+
constructor(config, ...baseArgs) {
|
|
1778
|
+
super(...baseArgs);
|
|
1779
|
+
this.config = config;
|
|
1780
|
+
}
|
|
1781
|
+
static create(input, ...args) {
|
|
1782
|
+
const r = import_valleyed9.v.validate(pipe, input);
|
|
1783
|
+
if (!r.valid) throw r.error;
|
|
1784
|
+
return new this(r.value, ...args);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
return Configurable;
|
|
1788
|
+
}
|
|
1789
|
+
if (void 0) {
|
|
1790
|
+
const { describe, test, expect, expectTypeOf } = void 0;
|
|
1791
|
+
const { v: v8 } = null;
|
|
1792
|
+
const testPipe = () => v8.object({
|
|
1793
|
+
host: v8.string(),
|
|
1794
|
+
port: v8.number()
|
|
1795
|
+
});
|
|
1796
|
+
class TestBase {
|
|
1797
|
+
baseValue;
|
|
1798
|
+
constructor() {
|
|
1799
|
+
this.baseValue = "base";
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
class TestBaseWithArgs {
|
|
1803
|
+
label;
|
|
1804
|
+
constructor(label) {
|
|
1805
|
+
this.label = label;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
describe("configurable", () => {
|
|
1809
|
+
test("validation runs in static create before constructor body executes", () => {
|
|
1810
|
+
let constructorRan = false;
|
|
1811
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
1812
|
+
class MyClass extends Wrapped {
|
|
1813
|
+
constructor(config) {
|
|
1814
|
+
super(config);
|
|
1815
|
+
constructorRan = true;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
expect(() => MyClass.create({ host: 123, port: "bad" })).toThrow();
|
|
1819
|
+
expect(constructorRan).toBe(false);
|
|
1820
|
+
MyClass.create({ host: "localhost", port: 3e3 });
|
|
1821
|
+
expect(constructorRan).toBe(true);
|
|
1822
|
+
});
|
|
1823
|
+
test("constructor receives validated value", () => {
|
|
1824
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
1825
|
+
let receivedConfig;
|
|
1826
|
+
class MyClass extends Wrapped {
|
|
1827
|
+
constructor(config) {
|
|
1828
|
+
super(config);
|
|
1829
|
+
receivedConfig = this.config;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
MyClass.create({ host: "localhost", port: 3e3 });
|
|
1833
|
+
expect(receivedConfig).toEqual({ host: "localhost", port: 3e3 });
|
|
1834
|
+
});
|
|
1835
|
+
test("external new is a compile error", () => {
|
|
1836
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
1837
|
+
class MyClass extends Wrapped {
|
|
1838
|
+
constructor(config) {
|
|
1839
|
+
super(config);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
void (() => new MyClass({ host: "localhost", port: 3e3 }));
|
|
1843
|
+
});
|
|
1844
|
+
test("static Config resolves to PipeOutput<P> at the type level", () => {
|
|
1845
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
1846
|
+
class MyClass extends Wrapped {
|
|
1847
|
+
constructor(config) {
|
|
1848
|
+
super(config);
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
expectTypeOf().toEqualTypeOf();
|
|
1852
|
+
expect(MyClass.create).toBeTypeOf("function");
|
|
1853
|
+
});
|
|
1854
|
+
test("ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures", () => {
|
|
1855
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
1856
|
+
class MyClass extends Wrapped {
|
|
1857
|
+
extra;
|
|
1858
|
+
constructor(config, extra) {
|
|
1859
|
+
super(config);
|
|
1860
|
+
this.extra = extra;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
const instance = MyClass.create({ host: "localhost", port: 3e3 }, 42);
|
|
1864
|
+
expect(instance.extra).toBe(42);
|
|
1865
|
+
expectTypeOf(instance).toHaveProperty("extra");
|
|
1866
|
+
expectTypeOf(instance.extra).toEqualTypeOf();
|
|
1867
|
+
void (() => MyClass.create({ host: "localhost", port: 3e3 }, "not-a-number"));
|
|
1868
|
+
});
|
|
1869
|
+
test("base-args forwarding works for non-zero-arg bases", () => {
|
|
1870
|
+
const Wrapped = configurable(testPipe, TestBaseWithArgs);
|
|
1871
|
+
class MyClass extends Wrapped {
|
|
1872
|
+
constructor(config, label) {
|
|
1873
|
+
super(config, label);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
const instance = MyClass.create({ host: "localhost", port: 3e3 }, "test-label");
|
|
1877
|
+
expect(instance.label).toBe("test-label");
|
|
1878
|
+
});
|
|
1879
|
+
test("config is accessible as protected readonly on instances", () => {
|
|
1880
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
1881
|
+
class MyClass extends Wrapped {
|
|
1882
|
+
constructor(config) {
|
|
1883
|
+
super(config);
|
|
1884
|
+
}
|
|
1885
|
+
getHost() {
|
|
1886
|
+
return this.config.host;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
const instance = MyClass.create({ host: "localhost", port: 3e3 });
|
|
1890
|
+
expect(instance.getHost()).toBe("localhost");
|
|
1891
|
+
});
|
|
1892
|
+
test("accepts an abstract base class", () => {
|
|
1893
|
+
class AbstractBase {
|
|
1894
|
+
}
|
|
1895
|
+
const Wrapped = configurable(testPipe, AbstractBase);
|
|
1896
|
+
class Concrete extends Wrapped {
|
|
1897
|
+
constructor(config) {
|
|
1898
|
+
super(config);
|
|
1899
|
+
}
|
|
1900
|
+
greet() {
|
|
1901
|
+
return `hello from ${this.config.host}`;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
const instance = Concrete.create({ host: "localhost", port: 3e3 });
|
|
1905
|
+
expect(instance.greet()).toBe("hello from localhost");
|
|
1906
|
+
expectTypeOf(instance).toHaveProperty("config");
|
|
1907
|
+
});
|
|
1908
|
+
});
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
// src/utilities/media.ts
|
|
1912
|
+
var import_music_metadata = require("music-metadata");
|
|
1913
|
+
var getMediaDuration = async (buffer) => {
|
|
1914
|
+
try {
|
|
1915
|
+
const meta = await (0, import_music_metadata.parseBuffer)(buffer);
|
|
1916
|
+
return meta.format.duration ?? 0;
|
|
1917
|
+
} catch {
|
|
1918
|
+
return 0;
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1921
|
+
|
|
1810
1922
|
// src/server/adapters/express/index.ts
|
|
1811
1923
|
var ExpressServer = class extends configurable(serverConfigPipe, Server) {
|
|
1812
1924
|
#app;
|