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
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [5.3.2](https://github.com/kevinand11/equipped/compare/v5.3.1...v5.3.2) (2026-06-20)
|
|
6
|
+
|
|
7
|
+
### [5.3.1](https://github.com/kevinand11/equipped/compare/v5.3.0...v5.3.1) (2026-06-19)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **server:** add before listen hook ([f72134c](https://github.com/kevinand11/equipped/commit/f72134c67273023a3e98351dd079fa6600b6a43d))
|
|
13
|
+
|
|
5
14
|
## [5.3.0](https://github.com/kevinand11/equipped/compare/v5.3.0-alpha.0...v5.3.0) (2026-06-19)
|
|
6
15
|
|
|
7
16
|
|
|
@@ -39,7 +39,7 @@ var import_valleyed4 = require("valleyed");
|
|
|
39
39
|
// src/instance/index.ts
|
|
40
40
|
var import_pino = __toESM(require("pino"), 1);
|
|
41
41
|
var import_ulid = require("ulid");
|
|
42
|
-
var
|
|
42
|
+
var import_valleyed2 = require("valleyed");
|
|
43
43
|
|
|
44
44
|
// src/errors/equippedError.ts
|
|
45
45
|
var EquippedError = class extends Error {
|
|
@@ -51,146 +51,6 @@ var EquippedError = class extends Error {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
// src/utilities/configurable.ts
|
|
55
|
-
var import_valleyed = require("valleyed");
|
|
56
|
-
function configurable(pipeFn, base) {
|
|
57
|
-
const pipe = pipeFn();
|
|
58
|
-
import_valleyed.v.compile(pipe);
|
|
59
|
-
class Configurable extends base {
|
|
60
|
-
constructor(config, ...baseArgs) {
|
|
61
|
-
super(...baseArgs);
|
|
62
|
-
this.config = config;
|
|
63
|
-
}
|
|
64
|
-
static create(input, ...args) {
|
|
65
|
-
const r = import_valleyed.v.validate(pipe, input);
|
|
66
|
-
if (!r.valid) throw r.error;
|
|
67
|
-
return new this(r.value, ...args);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return Configurable;
|
|
71
|
-
}
|
|
72
|
-
if (void 0) {
|
|
73
|
-
const { describe, test, expect, expectTypeOf } = void 0;
|
|
74
|
-
const { v: v5 } = null;
|
|
75
|
-
const testPipe = () => v5.object({
|
|
76
|
-
host: v5.string(),
|
|
77
|
-
port: v5.number()
|
|
78
|
-
});
|
|
79
|
-
class TestBase {
|
|
80
|
-
baseValue;
|
|
81
|
-
constructor() {
|
|
82
|
-
this.baseValue = "base";
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
class TestBaseWithArgs {
|
|
86
|
-
label;
|
|
87
|
-
constructor(label) {
|
|
88
|
-
this.label = label;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
describe("configurable", () => {
|
|
92
|
-
test("validation runs in static create before constructor body executes", () => {
|
|
93
|
-
let constructorRan = false;
|
|
94
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
95
|
-
class MyClass extends Wrapped {
|
|
96
|
-
constructor(config) {
|
|
97
|
-
super(config);
|
|
98
|
-
constructorRan = true;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
expect(() => MyClass.create({ host: 123, port: "bad" })).toThrow();
|
|
102
|
-
expect(constructorRan).toBe(false);
|
|
103
|
-
MyClass.create({ host: "localhost", port: 3e3 });
|
|
104
|
-
expect(constructorRan).toBe(true);
|
|
105
|
-
});
|
|
106
|
-
test("constructor receives validated value", () => {
|
|
107
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
108
|
-
let receivedConfig;
|
|
109
|
-
class MyClass extends Wrapped {
|
|
110
|
-
constructor(config) {
|
|
111
|
-
super(config);
|
|
112
|
-
receivedConfig = this.config;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
MyClass.create({ host: "localhost", port: 3e3 });
|
|
116
|
-
expect(receivedConfig).toEqual({ host: "localhost", port: 3e3 });
|
|
117
|
-
});
|
|
118
|
-
test("external new is a compile error", () => {
|
|
119
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
120
|
-
class MyClass extends Wrapped {
|
|
121
|
-
constructor(config) {
|
|
122
|
-
super(config);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
void (() => new MyClass({ host: "localhost", port: 3e3 }));
|
|
126
|
-
});
|
|
127
|
-
test("static Config resolves to PipeOutput<P> at the type level", () => {
|
|
128
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
129
|
-
class MyClass extends Wrapped {
|
|
130
|
-
constructor(config) {
|
|
131
|
-
super(config);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
expectTypeOf().toEqualTypeOf();
|
|
135
|
-
expect(MyClass.create).toBeTypeOf("function");
|
|
136
|
-
});
|
|
137
|
-
test("ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures", () => {
|
|
138
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
139
|
-
class MyClass extends Wrapped {
|
|
140
|
-
extra;
|
|
141
|
-
constructor(config, extra) {
|
|
142
|
-
super(config);
|
|
143
|
-
this.extra = extra;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 }, 42);
|
|
147
|
-
expect(instance.extra).toBe(42);
|
|
148
|
-
expectTypeOf(instance).toHaveProperty("extra");
|
|
149
|
-
expectTypeOf(instance.extra).toEqualTypeOf();
|
|
150
|
-
void (() => MyClass.create({ host: "localhost", port: 3e3 }, "not-a-number"));
|
|
151
|
-
});
|
|
152
|
-
test("base-args forwarding works for non-zero-arg bases", () => {
|
|
153
|
-
const Wrapped = configurable(testPipe, TestBaseWithArgs);
|
|
154
|
-
class MyClass extends Wrapped {
|
|
155
|
-
constructor(config, label) {
|
|
156
|
-
super(config, label);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 }, "test-label");
|
|
160
|
-
expect(instance.label).toBe("test-label");
|
|
161
|
-
});
|
|
162
|
-
test("config is accessible as protected readonly on instances", () => {
|
|
163
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
164
|
-
class MyClass extends Wrapped {
|
|
165
|
-
constructor(config) {
|
|
166
|
-
super(config);
|
|
167
|
-
}
|
|
168
|
-
getHost() {
|
|
169
|
-
return this.config.host;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 });
|
|
173
|
-
expect(instance.getHost()).toBe("localhost");
|
|
174
|
-
});
|
|
175
|
-
test("accepts an abstract base class", () => {
|
|
176
|
-
class AbstractBase {
|
|
177
|
-
}
|
|
178
|
-
const Wrapped = configurable(testPipe, AbstractBase);
|
|
179
|
-
class Concrete extends Wrapped {
|
|
180
|
-
constructor(config) {
|
|
181
|
-
super(config);
|
|
182
|
-
}
|
|
183
|
-
greet() {
|
|
184
|
-
return `hello from ${this.config.host}`;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
const instance = Concrete.create({ host: "localhost", port: 3e3 });
|
|
188
|
-
expect(instance.greet()).toBe("hello from localhost");
|
|
189
|
-
expectTypeOf(instance).toHaveProperty("config");
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
54
|
// src/instance/hooks.ts
|
|
195
55
|
function registerHook(hooks, record) {
|
|
196
56
|
for (const dep of record.after) {
|
|
@@ -593,22 +453,22 @@ if (void 0) {
|
|
|
593
453
|
}
|
|
594
454
|
|
|
595
455
|
// src/instance/settings.ts
|
|
596
|
-
var
|
|
597
|
-
var instanceSettingsPipe = () =>
|
|
598
|
-
app:
|
|
599
|
-
name:
|
|
456
|
+
var import_valleyed = require("valleyed");
|
|
457
|
+
var instanceSettingsPipe = () => import_valleyed.v.object({
|
|
458
|
+
app: import_valleyed.v.object({
|
|
459
|
+
name: import_valleyed.v.string()
|
|
600
460
|
}),
|
|
601
|
-
log:
|
|
602
|
-
|
|
603
|
-
level:
|
|
461
|
+
log: import_valleyed.v.defaults(
|
|
462
|
+
import_valleyed.v.object({
|
|
463
|
+
level: import_valleyed.v.defaults(import_valleyed.v.in(["fatal", "error", "warn", "info", "debug", "trace", "silent"]), "info")
|
|
604
464
|
}),
|
|
605
465
|
{}
|
|
606
466
|
),
|
|
607
|
-
utils:
|
|
608
|
-
|
|
609
|
-
hashSaltRounds:
|
|
610
|
-
paginationDefaultLimit:
|
|
611
|
-
maxFileUploadSizeInMb:
|
|
467
|
+
utils: import_valleyed.v.defaults(
|
|
468
|
+
import_valleyed.v.object({
|
|
469
|
+
hashSaltRounds: import_valleyed.v.defaults(import_valleyed.v.number(), 10),
|
|
470
|
+
paginationDefaultLimit: import_valleyed.v.defaults(import_valleyed.v.number(), 100),
|
|
471
|
+
maxFileUploadSizeInMb: import_valleyed.v.defaults(import_valleyed.v.number(), 500)
|
|
612
472
|
}),
|
|
613
473
|
{}
|
|
614
474
|
)
|
|
@@ -658,7 +518,7 @@ var Instance = class _Instance {
|
|
|
658
518
|
}
|
|
659
519
|
}
|
|
660
520
|
static envs(envsPipe) {
|
|
661
|
-
const envValidity =
|
|
521
|
+
const envValidity = import_valleyed2.v.validate(envsPipe, process.env);
|
|
662
522
|
if (!envValidity.valid) {
|
|
663
523
|
_Instance.crash(
|
|
664
524
|
new EquippedError(`Environment variables are not valid
|
|
@@ -671,7 +531,7 @@ ${envValidity.error.toString()}`, {
|
|
|
671
531
|
}
|
|
672
532
|
static create(settings) {
|
|
673
533
|
if (_Instance.#instance) return _Instance.crash(new EquippedError("Instance has been initialized already", {}));
|
|
674
|
-
const settingsValidity =
|
|
534
|
+
const settingsValidity = import_valleyed2.v.validate(instanceSettingsPipe(), settings);
|
|
675
535
|
if (!settingsValidity.valid) {
|
|
676
536
|
_Instance.crash(
|
|
677
537
|
new EquippedError(`Settings are not valid
|
|
@@ -725,6 +585,146 @@ ${settingsValidity.error.toString()}`, {
|
|
|
725
585
|
}
|
|
726
586
|
};
|
|
727
587
|
|
|
588
|
+
// src/utilities/configurable.ts
|
|
589
|
+
var import_valleyed3 = require("valleyed");
|
|
590
|
+
function configurable(pipeFn, base) {
|
|
591
|
+
const pipe = pipeFn();
|
|
592
|
+
import_valleyed3.v.compile(pipe);
|
|
593
|
+
class Configurable extends base {
|
|
594
|
+
constructor(config, ...baseArgs) {
|
|
595
|
+
super(...baseArgs);
|
|
596
|
+
this.config = config;
|
|
597
|
+
}
|
|
598
|
+
static create(input, ...args) {
|
|
599
|
+
const r = import_valleyed3.v.validate(pipe, input);
|
|
600
|
+
if (!r.valid) throw r.error;
|
|
601
|
+
return new this(r.value, ...args);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return Configurable;
|
|
605
|
+
}
|
|
606
|
+
if (void 0) {
|
|
607
|
+
const { describe, test, expect, expectTypeOf } = void 0;
|
|
608
|
+
const { v: v5 } = null;
|
|
609
|
+
const testPipe = () => v5.object({
|
|
610
|
+
host: v5.string(),
|
|
611
|
+
port: v5.number()
|
|
612
|
+
});
|
|
613
|
+
class TestBase {
|
|
614
|
+
baseValue;
|
|
615
|
+
constructor() {
|
|
616
|
+
this.baseValue = "base";
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
class TestBaseWithArgs {
|
|
620
|
+
label;
|
|
621
|
+
constructor(label) {
|
|
622
|
+
this.label = label;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
describe("configurable", () => {
|
|
626
|
+
test("validation runs in static create before constructor body executes", () => {
|
|
627
|
+
let constructorRan = false;
|
|
628
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
629
|
+
class MyClass extends Wrapped {
|
|
630
|
+
constructor(config) {
|
|
631
|
+
super(config);
|
|
632
|
+
constructorRan = true;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
expect(() => MyClass.create({ host: 123, port: "bad" })).toThrow();
|
|
636
|
+
expect(constructorRan).toBe(false);
|
|
637
|
+
MyClass.create({ host: "localhost", port: 3e3 });
|
|
638
|
+
expect(constructorRan).toBe(true);
|
|
639
|
+
});
|
|
640
|
+
test("constructor receives validated value", () => {
|
|
641
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
642
|
+
let receivedConfig;
|
|
643
|
+
class MyClass extends Wrapped {
|
|
644
|
+
constructor(config) {
|
|
645
|
+
super(config);
|
|
646
|
+
receivedConfig = this.config;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
MyClass.create({ host: "localhost", port: 3e3 });
|
|
650
|
+
expect(receivedConfig).toEqual({ host: "localhost", port: 3e3 });
|
|
651
|
+
});
|
|
652
|
+
test("external new is a compile error", () => {
|
|
653
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
654
|
+
class MyClass extends Wrapped {
|
|
655
|
+
constructor(config) {
|
|
656
|
+
super(config);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
void (() => new MyClass({ host: "localhost", port: 3e3 }));
|
|
660
|
+
});
|
|
661
|
+
test("static Config resolves to PipeOutput<P> at the type level", () => {
|
|
662
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
663
|
+
class MyClass extends Wrapped {
|
|
664
|
+
constructor(config) {
|
|
665
|
+
super(config);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
expectTypeOf().toEqualTypeOf();
|
|
669
|
+
expect(MyClass.create).toBeTypeOf("function");
|
|
670
|
+
});
|
|
671
|
+
test("ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures", () => {
|
|
672
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
673
|
+
class MyClass extends Wrapped {
|
|
674
|
+
extra;
|
|
675
|
+
constructor(config, extra) {
|
|
676
|
+
super(config);
|
|
677
|
+
this.extra = extra;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
const instance = MyClass.create({ host: "localhost", port: 3e3 }, 42);
|
|
681
|
+
expect(instance.extra).toBe(42);
|
|
682
|
+
expectTypeOf(instance).toHaveProperty("extra");
|
|
683
|
+
expectTypeOf(instance.extra).toEqualTypeOf();
|
|
684
|
+
void (() => MyClass.create({ host: "localhost", port: 3e3 }, "not-a-number"));
|
|
685
|
+
});
|
|
686
|
+
test("base-args forwarding works for non-zero-arg bases", () => {
|
|
687
|
+
const Wrapped = configurable(testPipe, TestBaseWithArgs);
|
|
688
|
+
class MyClass extends Wrapped {
|
|
689
|
+
constructor(config, label) {
|
|
690
|
+
super(config, label);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
const instance = MyClass.create({ host: "localhost", port: 3e3 }, "test-label");
|
|
694
|
+
expect(instance.label).toBe("test-label");
|
|
695
|
+
});
|
|
696
|
+
test("config is accessible as protected readonly on instances", () => {
|
|
697
|
+
const Wrapped = configurable(testPipe, TestBase);
|
|
698
|
+
class MyClass extends Wrapped {
|
|
699
|
+
constructor(config) {
|
|
700
|
+
super(config);
|
|
701
|
+
}
|
|
702
|
+
getHost() {
|
|
703
|
+
return this.config.host;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
const instance = MyClass.create({ host: "localhost", port: 3e3 });
|
|
707
|
+
expect(instance.getHost()).toBe("localhost");
|
|
708
|
+
});
|
|
709
|
+
test("accepts an abstract base class", () => {
|
|
710
|
+
class AbstractBase {
|
|
711
|
+
}
|
|
712
|
+
const Wrapped = configurable(testPipe, AbstractBase);
|
|
713
|
+
class Concrete extends Wrapped {
|
|
714
|
+
constructor(config) {
|
|
715
|
+
super(config);
|
|
716
|
+
}
|
|
717
|
+
greet() {
|
|
718
|
+
return `hello from ${this.config.host}`;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
const instance = Concrete.create({ host: "localhost", port: 3e3 });
|
|
722
|
+
expect(instance.greet()).toBe("hello from localhost");
|
|
723
|
+
expectTypeOf(instance).toHaveProperty("config");
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
|
|
728
728
|
// src/cache/adapters/base.ts
|
|
729
729
|
var Cache = class {
|
|
730
730
|
getScopedKey(key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/cache/adapters/in-memory/index.ts","../../../../../src/instance/index.ts","../../../../../src/errors/equippedError.ts","../../../../../src/utilities/configurable.ts","../../../../../src/instance/hooks.ts","../../../../../src/instance/settings.ts","../../../../../src/cache/adapters/base.ts"],"sourcesContent":["import { v } from 'valleyed'\n\nimport { Instance } from '../../../instance'\nimport { configurable } from '../../../utilities'\nimport { Cache } from '../base'\n\ntype CacheEntry = {\n\tdata: string\n\texpiredAt?: number\n}\n\nexport const inMemoryCacheConfigPipe = () => v.object({})\n\nexport class InMemoryCache extends configurable(inMemoryCacheConfigPipe, Cache) {\n\t#caches = new Map<string, CacheEntry>()\n\t#interval?: ReturnType<typeof setInterval>\n\n\tprotected constructor(config: typeof InMemoryCache.Config) {\n\t\tsuper(config)\n\t\tInstance.on('start', async () => {\n\t\t\tthis.#interval = setInterval(() => {\n\t\t\t\tconst now = Date.now()\n\t\t\t\tfor (const [key, record] of this.#caches.entries()) {\n\t\t\t\t\tif (record.expiredAt && record.expiredAt <= now) this.#caches.delete(key)\n\t\t\t\t}\n\t\t\t}, 5000)\n\t\t}, { class: InMemoryCache })\n\t\tInstance.on('close', async () => clearInterval(this.#interval), { class: InMemoryCache })\n\t}\n\n\tasync delete(key: string) {\n\t\tthis.#caches.delete(this.getScopedKey(key))\n\t}\n\tasync get(key: string) {\n\t\tconst record = this.#caches.get(this.getScopedKey(key))\n\t\tif (record && (record.expiredAt === undefined || record.expiredAt > Date.now())) return record.data\n\t\treturn null\n\t}\n\tasync set(key: string, data: string, ttlInSecs?: number) {\n\t\tthis.#caches.set(this.getScopedKey(key), { data, expiredAt: ttlInSecs ? Date.now() + ttlInSecs * 1000 : undefined })\n\t}\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect, expectTypeOf, vi, beforeEach, afterEach } = import.meta.vitest\n\n\tlet hookCalls: Array<{ event: string; options?: any }>\n\n\tbeforeEach(() => {\n\t\thookCalls = []\n\t\tvi.spyOn(Instance, 'on').mockImplementation((event, _cb, options) => {\n\t\t\thookCalls.push({ event, options })\n\t\t})\n\t\tvi.spyOn(Instance, 'get').mockReturnValue({ getScopedName: (_name: string, _sep: string) => `test:${_name}` } as any)\n\t})\n\n\tafterEach(() => {\n\t\tvi.restoreAllMocks()\n\t})\n\n\tdescribe('InMemoryCache', () => {\n\t\ttest('create() produces a working instance', () => {\n\t\t\tconst cache = InMemoryCache.create({})\n\t\t\texpect(cache).toBeInstanceOf(InMemoryCache)\n\t\t})\n\n\t\ttest('new InMemoryCache() is a compile error', () => {\n\t\t\t// @ts-expect-error — external `new` on a class with protected constructor is a compile error\n\t\t\tvoid (() => new InMemoryCache({}))\n\t\t})\n\n\t\ttest('Instance.on calls use { class: InMemoryCache }', () => {\n\t\t\tInMemoryCache.create({})\n\t\t\tconst startHook = hookCalls.find((h) => h.event === 'start')\n\t\t\tconst closeHook = hookCalls.find((h) => h.event === 'close')\n\t\t\texpect(startHook?.options).toEqual({ class: InMemoryCache })\n\t\t\texpect(closeHook?.options).toEqual({ class: InMemoryCache })\n\t\t})\n\n\t\ttest('set/get/delete work correctly', async () => {\n\t\t\tconst cache = InMemoryCache.create({})\n\t\t\tawait cache.set('key1', 'value1')\n\t\t\texpect(await cache.get('key1')).toBe('value1')\n\t\t\tawait cache.delete('key1')\n\t\t\texpect(await cache.get('key1')).toBeNull()\n\t\t})\n\n\t\ttest('get returns null after ttl expires', async () => {\n\t\t\tconst now = Date.now()\n\t\t\tvi.spyOn(Date, 'now').mockReturnValue(now)\n\t\t\tconst cache = InMemoryCache.create({})\n\t\t\tawait cache.set('key1', 'value1', 1)\n\t\t\tvi.spyOn(Date, 'now').mockReturnValue(now + 1001)\n\t\t\texpect(await cache.get('key1')).toBeNull()\n\t\t})\n\n\t\ttest('Config type is accessible', () => {\n\t\t\ttype PipeOutput<T> = import('valleyed').PipeOutput<T>\n\t\t\ttype Expected = PipeOutput<ReturnType<typeof inMemoryCacheConfigPipe>>\n\t\t\texpectTypeOf<typeof InMemoryCache.Config>().toEqualTypeOf<Expected>()\n\t\t})\n\t})\n}\n","import pino, { type Logger } from 'pino'\nimport { ulid } from 'ulid'\nimport { type Pipe, v } from 'valleyed'\n\nimport { EquippedError } from '../errors'\nimport { type ClassRef, type HookCb, type HookEvent, type HookOptions, type HookRecord, registerHook, runHooks } from './hooks'\nimport { instanceSettingsPipe, type Settings, type SettingsInput } from './settings'\n\nexport type { ClassRef, HookCb, HookEvent, HookOptions }\n\nexport class Instance {\n\tstatic #id: string | undefined\n\tstatic #instance: Instance | undefined\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly settings: Readonly<Settings>\n\treadonly log: Logger<never>\n\n\tprivate constructor(settings: Settings) {\n\t\tInstance.#instance = this\n\t\tthis.settings = Object.freeze(settings)\n\t\tthis.log = pino<never>({\n\t\t\tlevel: this.settings.log.level,\n\t\t\tserializers: {\n\t\t\t\terr: pino.stdSerializers.err,\n\t\t\t\terror: pino.stdSerializers.err,\n\t\t\t\treq: pino.stdSerializers.req,\n\t\t\t\tres: pino.stdSerializers.res,\n\t\t\t},\n\t\t\tmixin: () => ({\n\t\t\t\tinstanceId: Instance.#id,\n\t\t\t}),\n\t\t})\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\talias(id: string) {\n\t\tif (Instance.#id !== undefined) return Instance.crash(new EquippedError('Instance already has an alias', {}))\n\t\tInstance.#id = id\n\t}\n\n\tget id() {\n\t\tif (Instance.#id === undefined) return Instance.crash(new EquippedError('Instance doesnt have an alias yet', {}))\n\t\treturn Instance.#id\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic envs<E extends object>(envsPipe: Pipe<unknown, E>): E {\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn envValidity.value\n\t}\n\n\tstatic create(settings: SettingsInput) {\n\t\tif (Instance.#instance) return Instance.crash(new EquippedError('Instance has been initialized already', {}))\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings)\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance(settingsValidity.value)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic maybeGet() {\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, options?: HookOptions) {\n\t\tInstance.#hooks[event] ??= []\n\t\tconst record: HookRecord = { cb, class: options?.class, after: options?.after ?? [] }\n\t\tregisterHook(Instance.#hooks[event], record)\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {}, true)\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n\n\tstatic createId(opts?: { prefix?: string; time?: Date }) {\n\t\treturn `${opts?.prefix ?? ''}${ulid(opts?.time?.getTime())}`\n\t}\n}\n","export class EquippedError extends Error {\n\tconstructor(\n\t\tpublic readonly message: string,\n\t\tpublic readonly context: Record<string, unknown>,\n\t\tpublic readonly cause?: unknown,\n\t) {\n\t\tsuper(message, { cause })\n\t}\n}\n","import { v, type ConditionalObjectKeys, type Pipe, type PipeInput, type PipeOutput } from 'valleyed'\n\ntype CtorParams<T> = ConstructorParameters<T & (abstract new (...args: any[]) => any)>\ntype BaseCtorParams<T> = T extends abstract new (...args: infer A) => any ? A : never\n\nexport function configurable<P extends Pipe<any, any>, Base extends abstract new (...args: any[]) => any>(pipeFn: () => P, base: Base) {\n\tconst pipe = pipeFn()\n\tv.compile(pipe)\n\n\tabstract class Configurable extends (base as unknown as new (...args: any[]) => any) {\n\t\tdeclare static readonly Config: PipeOutput<P>\n\n\t\tprotected constructor (protected readonly config: PipeOutput<P>, ...baseArgs: BaseCtorParams<Base>) {\n\t\t\t// eslint-disable-next-line constructor-super\n\t\t\tsuper(...baseArgs)\n\t\t}\n\n\t\tstatic create<This extends Function & { prototype: any }>(\n\t\t\tthis: This,\n\t\t\tinput: ConditionalObjectKeys<PipeInput<P>>,\n\t\t\t...args: CtorParams<This> extends [PipeOutput<P>, ...infer R] ? R : never\n\t\t): This['prototype'] {\n\t\t\tconst r = v.validate(pipe, input)\n\t\t\tif (!r.valid) throw r.error\n\t\t\treturn new (this as any)(r.value, ...args) as This['prototype']\n\t\t}\n\t}\n\n\treturn Configurable as unknown as (abstract new (validated: PipeOutput<P>, ...baseArgs: BaseCtorParams<Base>) => InstanceType<Base> & { readonly config: PipeOutput<P> }) & {\n\t\treadonly Config: PipeOutput<P>\n\t\tcreate<This extends Function & { prototype: any }>(\n\t\t\tthis: This,\n\t\t\tinput: ConditionalObjectKeys<PipeInput<P>>,\n\t\t\t...args: CtorParams<This> extends [PipeOutput<P>, ...infer R] ? R : never\n\t\t): This['prototype']\n\t}\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect, expectTypeOf } = import.meta.vitest\n\tconst { v } = await import('valleyed')\n\n\tconst testPipe = () =>\n\t\tv.object({\n\t\t\thost: v.string(),\n\t\t\tport: v.number(),\n\t\t})\n\n\ttype TestConfig = PipeOutput<ReturnType<typeof testPipe>>\n\n\tclass TestBase {\n\t\tbaseValue: string\n\t\tconstructor() {\n\t\t\tthis.baseValue = 'base'\n\t\t}\n\t}\n\n\tclass TestBaseWithArgs {\n\t\tlabel: string\n\t\tconstructor(label: string) {\n\t\t\tthis.label = label\n\t\t}\n\t}\n\n\tdescribe('configurable', () => {\n\t\ttest('validation runs in static create before constructor body executes', () => {\n\t\t\tlet constructorRan = false\n\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t\tconstructorRan = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(() => MyClass.create({ host: 123, port: 'bad' } as any)).toThrow()\n\t\t\texpect(constructorRan).toBe(false)\n\n\t\t\tMyClass.create({ host: 'localhost', port: 3000 })\n\t\t\texpect(constructorRan).toBe(true)\n\t\t})\n\n\t\ttest('constructor receives validated value', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tlet receivedConfig: unknown\n\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t\treceivedConfig = this.config\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tMyClass.create({ host: 'localhost', port: 3000 })\n\n\t\t\texpect(receivedConfig).toEqual({ host: 'localhost', port: 3000 })\n\t\t})\n\n\t\ttest('external new is a compile error', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// @ts-expect-error — external `new` on a class with protected constructor is a compile error\n\t\t\tvoid (() => new MyClass({ host: 'localhost', port: 3000 }))\n\t\t})\n\n\t\ttest('static Config resolves to PipeOutput<P> at the type level', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpectTypeOf<typeof MyClass.Config>().toEqualTypeOf<TestConfig>()\n\t\t\texpect(MyClass.create).toBeTypeOf('function')\n\t\t})\n\n\t\ttest('ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\textra: number\n\t\t\t\tprotected constructor(config: typeof MyClass.Config, extra: number) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t\tthis.extra = extra\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = MyClass.create({ host: 'localhost', port: 3000 }, 42)\n\n\t\t\texpect(instance.extra).toBe(42)\n\t\t\texpectTypeOf(instance).toHaveProperty('extra')\n\t\t\texpectTypeOf(instance.extra).toEqualTypeOf<number>()\n\n\t\t\t// @ts-expect-error — wrong extra type\n\t\t\tvoid (() => MyClass.create({ host: 'localhost', port: 3000 }, 'not-a-number'))\n\t\t})\n\n\t\ttest('base-args forwarding works for non-zero-arg bases', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBaseWithArgs)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config, label: string) {\n\t\t\t\t\tsuper(config, label)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = MyClass.create({ host: 'localhost', port: 3000 }, 'test-label')\n\n\t\t\texpect(instance.label).toBe('test-label')\n\t\t})\n\n\t\ttest('config is accessible as protected readonly on instances', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\n\t\t\t\tgetHost() {\n\t\t\t\t\treturn this.config.host\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = MyClass.create({ host: 'localhost', port: 3000 })\n\t\t\texpect(instance.getHost()).toBe('localhost')\n\t\t})\n\n\t\ttest('accepts an abstract base class', () => {\n\t\t\tabstract class AbstractBase {\n\t\t\t\tabstract greet(): string\n\t\t\t}\n\n\t\t\tconst Wrapped = configurable(testPipe, AbstractBase)\n\t\t\tclass Concrete extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof Concrete.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\t\t\t\tgreet() {\n\t\t\t\t\treturn `hello from ${this.config.host}`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = Concrete.create({ host: 'localhost', port: 3000 })\n\t\t\texpect(instance.greet()).toBe('hello from localhost')\n\t\t\texpectTypeOf(instance).toHaveProperty('config')\n\t\t})\n\t})\n}\n","export type HookEvent = 'setup' | 'start' | 'close'\nexport type HookCb = Promise<unknown | void> | (() => void | unknown | Promise<void | unknown>)\n\nexport type ClassRef = Function & { prototype: unknown; name: string }\nexport type HookOptions = {\n\tclass?: ClassRef\n\tafter?: ClassRef[]\n}\nexport type HookRecord = { cb: HookCb; class?: ClassRef; after: ClassRef[] }\n\nexport function registerHook(hooks: HookRecord[], record: HookRecord): void {\n\tfor (const dep of record.after) {\n\t\tif (!hooks.some((h) => h.class === dep)) {\n\t\t\tconst depName = dep.name || 'unknown'\n\t\t\tconst ownerName = record.class?.name || 'anonymous'\n\t\t\tthrow new Error(`Missing dependency: ${ownerName} declares after: [${depName}], but ${depName} is not registered`)\n\t\t}\n\t}\n\n\tif (record.class) {\n\t\tconst tentative = [...hooks, record]\n\t\tdetectCycle(tentative)\n\t}\n\n\thooks.push(record)\n}\n\nfunction detectCycle(hooks: HookRecord[]): void {\n\tconst classToAfter = new Map<ClassRef, ClassRef[]>()\n\tfor (const h of hooks) {\n\t\tif (!h.class) continue\n\t\tconst existing = classToAfter.get(h.class)\n\t\tif (existing) {\n\t\t\tfor (const dep of h.after) {\n\t\t\t\tif (!existing.includes(dep)) existing.push(dep)\n\t\t\t}\n\t\t} else {\n\t\t\tclassToAfter.set(h.class, [...h.after])\n\t\t}\n\t}\n\n\tconst visited = new Set<ClassRef>()\n\tconst stack = new Set<ClassRef>()\n\n\tfunction visit(cls: ClassRef, path: ClassRef[]): void {\n\t\tif (stack.has(cls)) {\n\t\t\tconst cycleStart = path.indexOf(cls)\n\t\t\tconst cycle = [...path.slice(cycleStart), cls]\n\t\t\tconst names = cycle.map((c) => c.name || 'unknown')\n\t\t\tthrow new Error(`Cycle detected: ${names.join(' → ')}`)\n\t\t}\n\t\tif (visited.has(cls)) return\n\t\tstack.add(cls)\n\t\tpath.push(cls)\n\t\tfor (const dep of classToAfter.get(cls) ?? []) {\n\t\t\tvisit(dep, path)\n\t\t}\n\t\tpath.pop()\n\t\tstack.delete(cls)\n\t\tvisited.add(cls)\n\t}\n\n\tfor (const cls of classToAfter.keys()) {\n\t\tvisit(cls, [])\n\t}\n}\n\nexport type HookLayer = HookRecord[]\n\nexport function resolveHookDAG(hooks: HookRecord[], invert: boolean = false): HookLayer[] {\n\tif (hooks.length === 0) return []\n\n\tconst classToHooks = new Map<ClassRef, HookRecord[]>()\n\tconst anonymous: HookRecord[] = []\n\n\tfor (const h of hooks) {\n\t\tif (h.class) {\n\t\t\tconst list = classToHooks.get(h.class)\n\t\t\tif (list) list.push(h)\n\t\t\telse classToHooks.set(h.class, [h])\n\t\t} else {\n\t\t\tanonymous.push(h)\n\t\t}\n\t}\n\n\tconst classes = [...classToHooks.keys()]\n\n\tconst inDegree = new Map<ClassRef, number>()\n\tconst graph = new Map<ClassRef, ClassRef[]>()\n\n\tfor (const cls of classes) {\n\t\tinDegree.set(cls, 0)\n\t\tgraph.set(cls, [])\n\t}\n\n\tfor (const h of hooks) {\n\t\tif (!h.class) continue\n\t\tfor (const dep of h.after) {\n\t\t\tconst [from, to] = invert ? [h.class, dep] : [dep, h.class]\n\t\t\tconst edges = graph.get(from)!\n\t\t\tif (!edges.includes(to)) {\n\t\t\t\tedges.push(to)\n\t\t\t\tinDegree.set(to, inDegree.get(to)! + 1)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst layers: HookLayer[] = []\n\tlet queue = classes.filter((c) => inDegree.get(c) === 0)\n\n\twhile (queue.length > 0) {\n\t\tconst layer: HookRecord[] = []\n\t\tconst next: ClassRef[] = []\n\n\t\tfor (const cls of queue) {\n\t\t\tlayer.push(...(classToHooks.get(cls) ?? []))\n\t\t}\n\t\tlayers.push(layer)\n\n\t\tfor (const cls of queue) {\n\t\t\tfor (const neighbor of graph.get(cls) ?? []) {\n\t\t\t\tconst d = inDegree.get(neighbor)! - 1\n\t\t\t\tinDegree.set(neighbor, d)\n\t\t\t\tif (d === 0) next.push(neighbor)\n\t\t\t}\n\t\t}\n\n\t\tqueue = next\n\t}\n\n\tif (anonymous.length > 0) {\n\t\tconst anonWithDeps = anonymous.filter((h) => h.after.length > 0)\n\t\tconst anonWithoutDeps = anonymous.filter((h) => h.after.length === 0)\n\n\t\tif (anonWithDeps.length > 0) {\n\t\t\tlet maxLayer = -1\n\t\t\tfor (const h of anonWithDeps) {\n\t\t\t\tfor (const dep of h.after) {\n\t\t\t\t\tconst depLayer = layers.findIndex((l) => l.some((r) => r.class === dep))\n\t\t\t\t\tif (depLayer > maxLayer) maxLayer = depLayer\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst insertAt = maxLayer + 1\n\t\t\tif (insertAt < layers.length) {\n\t\t\t\tlayers[insertAt].push(...anonWithDeps)\n\t\t\t} else {\n\t\t\t\tlayers.push(anonWithDeps)\n\t\t\t}\n\t\t}\n\n\t\tif (anonWithoutDeps.length > 0) {\n\t\t\tif (layers.length > 0) {\n\t\t\t\tlayers[layers.length - 1].push(...anonWithoutDeps)\n\t\t\t} else {\n\t\t\t\tlayers.push(anonWithoutDeps)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn layers\n}\n\nexport async function runHooks(\n\thooks: HookRecord[],\n\tonError: (error: Error) => void = (error) => {\n\t\tthrow error\n\t},\n\tinvert: boolean = false,\n) {\n\tconst layers = resolveHookDAG(hooks, invert)\n\tfor (const layer of layers)\n\t\tawait Promise.all(\n\t\t\tlayer.map(async (h) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof h.cb === 'function') return await h.cb()\n\t\t\t\t\treturn await h.cb\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn onError(error instanceof Error ? error : new Error(`${error}`))\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect } = import.meta.vitest\n\n\tclass A {}\n\tclass B {}\n\tclass C {}\n\tclass D {}\n\n\tconst noop = () => {}\n\n\tdescribe('registerHook', () => {\n\t\ttest('registers a hook with no dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\texpect(hooks).toHaveLength(1)\n\t\t})\n\n\t\ttest('throws on missing dependency', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: B, after: [A] })).toThrow(/Missing dependency.*B.*A/)\n\t\t})\n\n\t\ttest('throws on cycle: A→B→A', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, class: B, after: [A] })\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: A, after: [B] })).toThrow(/Cycle detected/)\n\t\t})\n\n\t\ttest('throws on transitive cycle: A→B→C→A', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, class: B, after: [A] })\n\t\t\tregisterHook(hooks, { cb: noop, class: C, after: [B] })\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: A, after: [C] })).toThrow(/Cycle detected/)\n\t\t})\n\n\t\ttest('allows anonymous hooks with dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, after: [A] })\n\t\t\texpect(hooks).toHaveLength(2)\n\t\t})\n\n\t\ttest('anonymous hook throws on missing dependency', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\texpect(() => registerHook(hooks, { cb: noop, after: [A] })).toThrow(/Missing dependency.*anonymous.*A/)\n\t\t})\n\t})\n\n\tdescribe('resolveHookDAG', () => {\n\t\ttest('linear chain: A → B → C', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t\texpect(layers[1].every((h) => h.class === B)).toBe(true)\n\t\t\texpect(layers[2].every((h) => h.class === C)).toBe(true)\n\t\t})\n\n\t\ttest('fan-out: A → B, A → C (B and C are parallel)', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t\tconst secondClasses = layers[1].map((h) => h.class)\n\t\t\texpect(secondClasses).toContain(B)\n\t\t\texpect(secondClasses).toContain(C)\n\t\t})\n\n\t\ttest('fan-in: B → D, C → D', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: B, after: [] },\n\t\t\t\t{ cb: noop, class: C, after: [] },\n\t\t\t\t{ cb: noop, class: D, after: [B, C] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst firstClasses = layers[0].map((h) => h.class)\n\t\t\texpect(firstClasses).toContain(B)\n\t\t\texpect(firstClasses).toContain(C)\n\t\t\texpect(layers[1].every((h) => h.class === D)).toBe(true)\n\t\t})\n\n\t\ttest('diamond: A → B, A → C, B → D, C → D', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t\t{ cb: noop, class: D, after: [B, C] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0][0].class).toBe(A)\n\t\t\tconst midClasses = layers[1].map((h) => h.class)\n\t\t\texpect(midClasses).toContain(B)\n\t\t\texpect(midClasses).toContain(C)\n\t\t\texpect(layers[2][0].class).toBe(D)\n\t\t})\n\n\t\ttest('close-event inversion reverses the graph', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks, true)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0].every((h) => h.class === C)).toBe(true)\n\t\t\texpect(layers[1].every((h) => h.class === B)).toBe(true)\n\t\t\texpect(layers[2].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('close inversion: fan-out becomes fan-in', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks, true)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst firstClasses = layers[0].map((h) => h.class)\n\t\t\texpect(firstClasses).toContain(B)\n\t\t\texpect(firstClasses).toContain(C)\n\t\t\texpect(layers[1].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('multiple hooks per class are all in the same layer', () => {\n\t\t\tconst cb1 = () => {}\n\t\t\tconst cb2 = () => {}\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: cb1, class: A, after: [] },\n\t\t\t\t{ cb: cb2, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\texpect(layers[0]).toHaveLength(2)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('anonymous hooks without deps run at deepest level', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, after: [] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst lastLayer = layers[layers.length - 1]\n\t\t\texpect(lastLayer.some((h) => h.class === undefined)).toBe(true)\n\t\t})\n\n\t\ttest('anonymous hooks with deps run after their dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t\t{ cb: noop, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\tconst anonLayer = layers.findIndex((l) => l.some((h) => h.class === undefined))\n\t\t\tconst aLayer = layers.findIndex((l) => l.some((h) => h.class === A))\n\t\t\texpect(anonLayer).toBeGreaterThan(aLayer)\n\t\t})\n\n\t\ttest('empty hooks returns empty layers', () => {\n\t\t\texpect(resolveHookDAG([])).toEqual([])\n\t\t})\n\t})\n\n\tdescribe('runHooks', () => {\n\t\ttest('same-depth siblings observably overlap', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('B-start')\n\t\t\t\t\t\tawait new Promise((r) => setTimeout(r, 20))\n\t\t\t\t\t\tlog.push('B-end')\n\t\t\t\t\t},\n\t\t\t\t\tclass: B,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('C-start')\n\t\t\t\t\t\tawait new Promise((r) => setTimeout(r, 20))\n\t\t\t\t\t\tlog.push('C-end')\n\t\t\t\t\t},\n\t\t\t\t\tclass: C,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log[0]).toBe('B-start')\n\t\t\texpect(log[1]).toBe('C-start')\n\t\t})\n\n\t\ttest('different depths run sequentially', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('A')\n\t\t\t\t\t},\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('B')\n\t\t\t\t\t},\n\t\t\t\t\tclass: B,\n\t\t\t\t\tafter: [A],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log).toEqual(['A', 'B'])\n\t\t})\n\n\t\ttest('close inversion runs hooks in reverse dependency order', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: async () => log.push('A'), class: A, after: [] },\n\t\t\t\t{ cb: async () => log.push('B'), class: B, after: [A] },\n\t\t\t\t{ cb: async () => log.push('C'), class: C, after: [B] },\n\t\t\t]\n\t\t\tawait runHooks(hooks, undefined, true)\n\t\t\texpect(log).toEqual(['C', 'B', 'A'])\n\t\t})\n\n\t\ttest('errors are routed to onError handler', async () => {\n\t\t\tconst errors: Error[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: () => {\n\t\t\t\t\t\tthrow new Error('boom')\n\t\t\t\t\t},\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks, (e) => {\n\t\t\t\terrors.push(e)\n\t\t\t})\n\t\t\texpect(errors).toHaveLength(1)\n\t\t\texpect(errors[0].message).toBe('boom')\n\t\t})\n\n\t\ttest('raw promise callbacks are awaited', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: Promise.resolve().then(() => log.push('resolved')),\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log).toContain('resolved')\n\t\t})\n\t})\n}\n","import { type ConditionalObjectKeys, type PipeInput, type PipeOutput, v } from 'valleyed'\n\nexport const instanceSettingsPipe = () =>\n\tv.object({\n\t\tapp: v.object({\n\t\t\tname: v.string(),\n\t\t}),\n\t\tlog: v.defaults(\n\t\t\tv.object({\n\t\t\t\tlevel: v.defaults(v.in(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent'] as const), 'info'),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t\tutils: v.defaults(\n\t\t\tv.object({\n\t\t\t\thashSaltRounds: v.defaults(v.number(), 10),\n\t\t\t\tpaginationDefaultLimit: v.defaults(v.number(), 100),\n\t\t\t\tmaxFileUploadSizeInMb: v.defaults(v.number(), 500),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t})\n\nexport type Settings = PipeOutput<ReturnType<typeof instanceSettingsPipe>>\nexport type SettingsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof instanceSettingsPipe>>>\n","import { Instance } from '../../instance'\n\nexport abstract class Cache {\n\tabstract set(key: string, data: string, ttlInSecs?: number): Promise<void>\n\tabstract get(key: string): Promise<string | null>\n\tabstract delete(key: string): Promise<void>\n\n\tgetScopedKey(key: string) {\n\t\treturn Instance.get().getScopedName(key, ':')\n\t}\n\n\tasync getOrSet<T>(key: string, fn: () => Promise<T>, ttlInSecs?: number): Promise<T> {\n\t\tconst cached = await this.get(key)\n\t\tif (cached) return JSON.parse(cached) as T\n\n\t\tconst result = await fn()\n\t\tawait this.set(key, JSON.stringify(result), ttlInSecs)\n\t\treturn result\n\t}\n}\n"],"mappings":"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","names":["import_valleyed","import_valleyed","v","import_valleyed","pino"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/cache/adapters/in-memory/index.ts","../../../../../src/instance/index.ts","../../../../../src/errors/equippedError.ts","../../../../../src/instance/hooks.ts","../../../../../src/instance/settings.ts","../../../../../src/utilities/configurable.ts","../../../../../src/cache/adapters/base.ts"],"sourcesContent":["import { v } from 'valleyed'\n\nimport { Instance } from '../../../instance'\nimport { configurable } from '../../../utilities'\nimport { Cache } from '../base'\n\ntype CacheEntry = {\n\tdata: string\n\texpiredAt?: number\n}\n\nexport const inMemoryCacheConfigPipe = () => v.object({})\n\nexport class InMemoryCache extends configurable(inMemoryCacheConfigPipe, Cache) {\n\t#caches = new Map<string, CacheEntry>()\n\t#interval?: ReturnType<typeof setInterval>\n\n\tprotected constructor(config: typeof InMemoryCache.Config) {\n\t\tsuper(config)\n\t\tInstance.on('start', async () => {\n\t\t\tthis.#interval = setInterval(() => {\n\t\t\t\tconst now = Date.now()\n\t\t\t\tfor (const [key, record] of this.#caches.entries()) {\n\t\t\t\t\tif (record.expiredAt && record.expiredAt <= now) this.#caches.delete(key)\n\t\t\t\t}\n\t\t\t}, 5000)\n\t\t}, { class: InMemoryCache })\n\t\tInstance.on('close', async () => clearInterval(this.#interval), { class: InMemoryCache })\n\t}\n\n\tasync delete(key: string) {\n\t\tthis.#caches.delete(this.getScopedKey(key))\n\t}\n\tasync get(key: string) {\n\t\tconst record = this.#caches.get(this.getScopedKey(key))\n\t\tif (record && (record.expiredAt === undefined || record.expiredAt > Date.now())) return record.data\n\t\treturn null\n\t}\n\tasync set(key: string, data: string, ttlInSecs?: number) {\n\t\tthis.#caches.set(this.getScopedKey(key), { data, expiredAt: ttlInSecs ? Date.now() + ttlInSecs * 1000 : undefined })\n\t}\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect, expectTypeOf, vi, beforeEach, afterEach } = import.meta.vitest\n\n\tlet hookCalls: Array<{ event: string; options?: any }>\n\n\tbeforeEach(() => {\n\t\thookCalls = []\n\t\tvi.spyOn(Instance, 'on').mockImplementation((event, _cb, options) => {\n\t\t\thookCalls.push({ event, options })\n\t\t})\n\t\tvi.spyOn(Instance, 'get').mockReturnValue({ getScopedName: (_name: string, _sep: string) => `test:${_name}` } as any)\n\t})\n\n\tafterEach(() => {\n\t\tvi.restoreAllMocks()\n\t})\n\n\tdescribe('InMemoryCache', () => {\n\t\ttest('create() produces a working instance', () => {\n\t\t\tconst cache = InMemoryCache.create({})\n\t\t\texpect(cache).toBeInstanceOf(InMemoryCache)\n\t\t})\n\n\t\ttest('new InMemoryCache() is a compile error', () => {\n\t\t\t// @ts-expect-error — external `new` on a class with protected constructor is a compile error\n\t\t\tvoid (() => new InMemoryCache({}))\n\t\t})\n\n\t\ttest('Instance.on calls use { class: InMemoryCache }', () => {\n\t\t\tInMemoryCache.create({})\n\t\t\tconst startHook = hookCalls.find((h) => h.event === 'start')\n\t\t\tconst closeHook = hookCalls.find((h) => h.event === 'close')\n\t\t\texpect(startHook?.options).toEqual({ class: InMemoryCache })\n\t\t\texpect(closeHook?.options).toEqual({ class: InMemoryCache })\n\t\t})\n\n\t\ttest('set/get/delete work correctly', async () => {\n\t\t\tconst cache = InMemoryCache.create({})\n\t\t\tawait cache.set('key1', 'value1')\n\t\t\texpect(await cache.get('key1')).toBe('value1')\n\t\t\tawait cache.delete('key1')\n\t\t\texpect(await cache.get('key1')).toBeNull()\n\t\t})\n\n\t\ttest('get returns null after ttl expires', async () => {\n\t\t\tconst now = Date.now()\n\t\t\tvi.spyOn(Date, 'now').mockReturnValue(now)\n\t\t\tconst cache = InMemoryCache.create({})\n\t\t\tawait cache.set('key1', 'value1', 1)\n\t\t\tvi.spyOn(Date, 'now').mockReturnValue(now + 1001)\n\t\t\texpect(await cache.get('key1')).toBeNull()\n\t\t})\n\n\t\ttest('Config type is accessible', () => {\n\t\t\ttype PipeOutput<T> = import('valleyed').PipeOutput<T>\n\t\t\ttype Expected = PipeOutput<ReturnType<typeof inMemoryCacheConfigPipe>>\n\t\t\texpectTypeOf<typeof InMemoryCache.Config>().toEqualTypeOf<Expected>()\n\t\t})\n\t})\n}\n","import pino, { type Logger } from 'pino'\nimport { ulid } from 'ulid'\nimport { type Pipe, v } from 'valleyed'\n\nimport { EquippedError } from '../errors'\nimport { type ClassRef, type HookCb, type HookEvent, type HookOptions, type HookRecord, registerHook, runHooks } from './hooks'\nimport { instanceSettingsPipe, type Settings, type SettingsInput } from './settings'\n\nexport type { ClassRef, HookCb, HookEvent, HookOptions }\n\nexport class Instance {\n\tstatic #id: string | undefined\n\tstatic #instance: Instance | undefined\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly settings: Readonly<Settings>\n\treadonly log: Logger<never>\n\n\tprivate constructor(settings: Settings) {\n\t\tInstance.#instance = this\n\t\tthis.settings = Object.freeze(settings)\n\t\tthis.log = pino<never>({\n\t\t\tlevel: this.settings.log.level,\n\t\t\tserializers: {\n\t\t\t\terr: pino.stdSerializers.err,\n\t\t\t\terror: pino.stdSerializers.err,\n\t\t\t\treq: pino.stdSerializers.req,\n\t\t\t\tres: pino.stdSerializers.res,\n\t\t\t},\n\t\t\tmixin: () => ({\n\t\t\t\tinstanceId: Instance.#id,\n\t\t\t}),\n\t\t})\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\talias(id: string) {\n\t\tif (Instance.#id !== undefined) return Instance.crash(new EquippedError('Instance already has an alias', {}))\n\t\tInstance.#id = id\n\t}\n\n\tget id() {\n\t\tif (Instance.#id === undefined) return Instance.crash(new EquippedError('Instance doesnt have an alias yet', {}))\n\t\treturn Instance.#id\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic envs<E extends object>(envsPipe: Pipe<unknown, E>): E {\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn envValidity.value\n\t}\n\n\tstatic create(settings: SettingsInput) {\n\t\tif (Instance.#instance) return Instance.crash(new EquippedError('Instance has been initialized already', {}))\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings)\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance(settingsValidity.value)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic maybeGet() {\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, options?: HookOptions) {\n\t\tInstance.#hooks[event] ??= []\n\t\tconst record: HookRecord = { cb, class: options?.class, after: options?.after ?? [] }\n\t\tregisterHook(Instance.#hooks[event], record)\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {}, true)\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n\n\tstatic createId(opts?: { prefix?: string; time?: Date }) {\n\t\treturn `${opts?.prefix ?? ''}${ulid(opts?.time?.getTime())}`\n\t}\n}\n","export class EquippedError extends Error {\n\tconstructor(\n\t\tpublic readonly message: string,\n\t\tpublic readonly context: Record<string, unknown>,\n\t\tpublic readonly cause?: unknown,\n\t) {\n\t\tsuper(message, { cause })\n\t}\n}\n","export type HookEvent = 'setup' | 'start' | 'close'\nexport type HookCb = Promise<unknown | void> | (() => void | unknown | Promise<void | unknown>)\n\nexport type ClassRef = Function & { prototype: unknown; name: string }\nexport type HookOptions = {\n\tclass?: ClassRef\n\tafter?: ClassRef[]\n}\nexport type HookRecord = { cb: HookCb; class?: ClassRef; after: ClassRef[] }\n\nexport function registerHook(hooks: HookRecord[], record: HookRecord): void {\n\tfor (const dep of record.after) {\n\t\tif (!hooks.some((h) => h.class === dep)) {\n\t\t\tconst depName = dep.name || 'unknown'\n\t\t\tconst ownerName = record.class?.name || 'anonymous'\n\t\t\tthrow new Error(`Missing dependency: ${ownerName} declares after: [${depName}], but ${depName} is not registered`)\n\t\t}\n\t}\n\n\tif (record.class) {\n\t\tconst tentative = [...hooks, record]\n\t\tdetectCycle(tentative)\n\t}\n\n\thooks.push(record)\n}\n\nfunction detectCycle(hooks: HookRecord[]): void {\n\tconst classToAfter = new Map<ClassRef, ClassRef[]>()\n\tfor (const h of hooks) {\n\t\tif (!h.class) continue\n\t\tconst existing = classToAfter.get(h.class)\n\t\tif (existing) {\n\t\t\tfor (const dep of h.after) {\n\t\t\t\tif (!existing.includes(dep)) existing.push(dep)\n\t\t\t}\n\t\t} else {\n\t\t\tclassToAfter.set(h.class, [...h.after])\n\t\t}\n\t}\n\n\tconst visited = new Set<ClassRef>()\n\tconst stack = new Set<ClassRef>()\n\n\tfunction visit(cls: ClassRef, path: ClassRef[]): void {\n\t\tif (stack.has(cls)) {\n\t\t\tconst cycleStart = path.indexOf(cls)\n\t\t\tconst cycle = [...path.slice(cycleStart), cls]\n\t\t\tconst names = cycle.map((c) => c.name || 'unknown')\n\t\t\tthrow new Error(`Cycle detected: ${names.join(' → ')}`)\n\t\t}\n\t\tif (visited.has(cls)) return\n\t\tstack.add(cls)\n\t\tpath.push(cls)\n\t\tfor (const dep of classToAfter.get(cls) ?? []) {\n\t\t\tvisit(dep, path)\n\t\t}\n\t\tpath.pop()\n\t\tstack.delete(cls)\n\t\tvisited.add(cls)\n\t}\n\n\tfor (const cls of classToAfter.keys()) {\n\t\tvisit(cls, [])\n\t}\n}\n\nexport type HookLayer = HookRecord[]\n\nexport function resolveHookDAG(hooks: HookRecord[], invert: boolean = false): HookLayer[] {\n\tif (hooks.length === 0) return []\n\n\tconst classToHooks = new Map<ClassRef, HookRecord[]>()\n\tconst anonymous: HookRecord[] = []\n\n\tfor (const h of hooks) {\n\t\tif (h.class) {\n\t\t\tconst list = classToHooks.get(h.class)\n\t\t\tif (list) list.push(h)\n\t\t\telse classToHooks.set(h.class, [h])\n\t\t} else {\n\t\t\tanonymous.push(h)\n\t\t}\n\t}\n\n\tconst classes = [...classToHooks.keys()]\n\n\tconst inDegree = new Map<ClassRef, number>()\n\tconst graph = new Map<ClassRef, ClassRef[]>()\n\n\tfor (const cls of classes) {\n\t\tinDegree.set(cls, 0)\n\t\tgraph.set(cls, [])\n\t}\n\n\tfor (const h of hooks) {\n\t\tif (!h.class) continue\n\t\tfor (const dep of h.after) {\n\t\t\tconst [from, to] = invert ? [h.class, dep] : [dep, h.class]\n\t\t\tconst edges = graph.get(from)!\n\t\t\tif (!edges.includes(to)) {\n\t\t\t\tedges.push(to)\n\t\t\t\tinDegree.set(to, inDegree.get(to)! + 1)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst layers: HookLayer[] = []\n\tlet queue = classes.filter((c) => inDegree.get(c) === 0)\n\n\twhile (queue.length > 0) {\n\t\tconst layer: HookRecord[] = []\n\t\tconst next: ClassRef[] = []\n\n\t\tfor (const cls of queue) {\n\t\t\tlayer.push(...(classToHooks.get(cls) ?? []))\n\t\t}\n\t\tlayers.push(layer)\n\n\t\tfor (const cls of queue) {\n\t\t\tfor (const neighbor of graph.get(cls) ?? []) {\n\t\t\t\tconst d = inDegree.get(neighbor)! - 1\n\t\t\t\tinDegree.set(neighbor, d)\n\t\t\t\tif (d === 0) next.push(neighbor)\n\t\t\t}\n\t\t}\n\n\t\tqueue = next\n\t}\n\n\tif (anonymous.length > 0) {\n\t\tconst anonWithDeps = anonymous.filter((h) => h.after.length > 0)\n\t\tconst anonWithoutDeps = anonymous.filter((h) => h.after.length === 0)\n\n\t\tif (anonWithDeps.length > 0) {\n\t\t\tlet maxLayer = -1\n\t\t\tfor (const h of anonWithDeps) {\n\t\t\t\tfor (const dep of h.after) {\n\t\t\t\t\tconst depLayer = layers.findIndex((l) => l.some((r) => r.class === dep))\n\t\t\t\t\tif (depLayer > maxLayer) maxLayer = depLayer\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst insertAt = maxLayer + 1\n\t\t\tif (insertAt < layers.length) {\n\t\t\t\tlayers[insertAt].push(...anonWithDeps)\n\t\t\t} else {\n\t\t\t\tlayers.push(anonWithDeps)\n\t\t\t}\n\t\t}\n\n\t\tif (anonWithoutDeps.length > 0) {\n\t\t\tif (layers.length > 0) {\n\t\t\t\tlayers[layers.length - 1].push(...anonWithoutDeps)\n\t\t\t} else {\n\t\t\t\tlayers.push(anonWithoutDeps)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn layers\n}\n\nexport async function runHooks(\n\thooks: HookRecord[],\n\tonError: (error: Error) => void = (error) => {\n\t\tthrow error\n\t},\n\tinvert: boolean = false,\n) {\n\tconst layers = resolveHookDAG(hooks, invert)\n\tfor (const layer of layers)\n\t\tawait Promise.all(\n\t\t\tlayer.map(async (h) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof h.cb === 'function') return await h.cb()\n\t\t\t\t\treturn await h.cb\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn onError(error instanceof Error ? error : new Error(`${error}`))\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect } = import.meta.vitest\n\n\tclass A {}\n\tclass B {}\n\tclass C {}\n\tclass D {}\n\n\tconst noop = () => {}\n\n\tdescribe('registerHook', () => {\n\t\ttest('registers a hook with no dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\texpect(hooks).toHaveLength(1)\n\t\t})\n\n\t\ttest('throws on missing dependency', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: B, after: [A] })).toThrow(/Missing dependency.*B.*A/)\n\t\t})\n\n\t\ttest('throws on cycle: A→B→A', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, class: B, after: [A] })\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: A, after: [B] })).toThrow(/Cycle detected/)\n\t\t})\n\n\t\ttest('throws on transitive cycle: A→B→C→A', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, class: B, after: [A] })\n\t\t\tregisterHook(hooks, { cb: noop, class: C, after: [B] })\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: A, after: [C] })).toThrow(/Cycle detected/)\n\t\t})\n\n\t\ttest('allows anonymous hooks with dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, after: [A] })\n\t\t\texpect(hooks).toHaveLength(2)\n\t\t})\n\n\t\ttest('anonymous hook throws on missing dependency', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\texpect(() => registerHook(hooks, { cb: noop, after: [A] })).toThrow(/Missing dependency.*anonymous.*A/)\n\t\t})\n\t})\n\n\tdescribe('resolveHookDAG', () => {\n\t\ttest('linear chain: A → B → C', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t\texpect(layers[1].every((h) => h.class === B)).toBe(true)\n\t\t\texpect(layers[2].every((h) => h.class === C)).toBe(true)\n\t\t})\n\n\t\ttest('fan-out: A → B, A → C (B and C are parallel)', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t\tconst secondClasses = layers[1].map((h) => h.class)\n\t\t\texpect(secondClasses).toContain(B)\n\t\t\texpect(secondClasses).toContain(C)\n\t\t})\n\n\t\ttest('fan-in: B → D, C → D', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: B, after: [] },\n\t\t\t\t{ cb: noop, class: C, after: [] },\n\t\t\t\t{ cb: noop, class: D, after: [B, C] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst firstClasses = layers[0].map((h) => h.class)\n\t\t\texpect(firstClasses).toContain(B)\n\t\t\texpect(firstClasses).toContain(C)\n\t\t\texpect(layers[1].every((h) => h.class === D)).toBe(true)\n\t\t})\n\n\t\ttest('diamond: A → B, A → C, B → D, C → D', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t\t{ cb: noop, class: D, after: [B, C] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0][0].class).toBe(A)\n\t\t\tconst midClasses = layers[1].map((h) => h.class)\n\t\t\texpect(midClasses).toContain(B)\n\t\t\texpect(midClasses).toContain(C)\n\t\t\texpect(layers[2][0].class).toBe(D)\n\t\t})\n\n\t\ttest('close-event inversion reverses the graph', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks, true)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0].every((h) => h.class === C)).toBe(true)\n\t\t\texpect(layers[1].every((h) => h.class === B)).toBe(true)\n\t\t\texpect(layers[2].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('close inversion: fan-out becomes fan-in', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks, true)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst firstClasses = layers[0].map((h) => h.class)\n\t\t\texpect(firstClasses).toContain(B)\n\t\t\texpect(firstClasses).toContain(C)\n\t\t\texpect(layers[1].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('multiple hooks per class are all in the same layer', () => {\n\t\t\tconst cb1 = () => {}\n\t\t\tconst cb2 = () => {}\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: cb1, class: A, after: [] },\n\t\t\t\t{ cb: cb2, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\texpect(layers[0]).toHaveLength(2)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('anonymous hooks without deps run at deepest level', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, after: [] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst lastLayer = layers[layers.length - 1]\n\t\t\texpect(lastLayer.some((h) => h.class === undefined)).toBe(true)\n\t\t})\n\n\t\ttest('anonymous hooks with deps run after their dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t\t{ cb: noop, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\tconst anonLayer = layers.findIndex((l) => l.some((h) => h.class === undefined))\n\t\t\tconst aLayer = layers.findIndex((l) => l.some((h) => h.class === A))\n\t\t\texpect(anonLayer).toBeGreaterThan(aLayer)\n\t\t})\n\n\t\ttest('empty hooks returns empty layers', () => {\n\t\t\texpect(resolveHookDAG([])).toEqual([])\n\t\t})\n\t})\n\n\tdescribe('runHooks', () => {\n\t\ttest('same-depth siblings observably overlap', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('B-start')\n\t\t\t\t\t\tawait new Promise((r) => setTimeout(r, 20))\n\t\t\t\t\t\tlog.push('B-end')\n\t\t\t\t\t},\n\t\t\t\t\tclass: B,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('C-start')\n\t\t\t\t\t\tawait new Promise((r) => setTimeout(r, 20))\n\t\t\t\t\t\tlog.push('C-end')\n\t\t\t\t\t},\n\t\t\t\t\tclass: C,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log[0]).toBe('B-start')\n\t\t\texpect(log[1]).toBe('C-start')\n\t\t})\n\n\t\ttest('different depths run sequentially', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('A')\n\t\t\t\t\t},\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('B')\n\t\t\t\t\t},\n\t\t\t\t\tclass: B,\n\t\t\t\t\tafter: [A],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log).toEqual(['A', 'B'])\n\t\t})\n\n\t\ttest('close inversion runs hooks in reverse dependency order', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: async () => log.push('A'), class: A, after: [] },\n\t\t\t\t{ cb: async () => log.push('B'), class: B, after: [A] },\n\t\t\t\t{ cb: async () => log.push('C'), class: C, after: [B] },\n\t\t\t]\n\t\t\tawait runHooks(hooks, undefined, true)\n\t\t\texpect(log).toEqual(['C', 'B', 'A'])\n\t\t})\n\n\t\ttest('errors are routed to onError handler', async () => {\n\t\t\tconst errors: Error[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: () => {\n\t\t\t\t\t\tthrow new Error('boom')\n\t\t\t\t\t},\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks, (e) => {\n\t\t\t\terrors.push(e)\n\t\t\t})\n\t\t\texpect(errors).toHaveLength(1)\n\t\t\texpect(errors[0].message).toBe('boom')\n\t\t})\n\n\t\ttest('raw promise callbacks are awaited', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: Promise.resolve().then(() => log.push('resolved')),\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log).toContain('resolved')\n\t\t})\n\t})\n}\n","import { type ConditionalObjectKeys, type PipeInput, type PipeOutput, v } from 'valleyed'\n\nexport const instanceSettingsPipe = () =>\n\tv.object({\n\t\tapp: v.object({\n\t\t\tname: v.string(),\n\t\t}),\n\t\tlog: v.defaults(\n\t\t\tv.object({\n\t\t\t\tlevel: v.defaults(v.in(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent'] as const), 'info'),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t\tutils: v.defaults(\n\t\t\tv.object({\n\t\t\t\thashSaltRounds: v.defaults(v.number(), 10),\n\t\t\t\tpaginationDefaultLimit: v.defaults(v.number(), 100),\n\t\t\t\tmaxFileUploadSizeInMb: v.defaults(v.number(), 500),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t})\n\nexport type Settings = PipeOutput<ReturnType<typeof instanceSettingsPipe>>\nexport type SettingsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof instanceSettingsPipe>>>\n","import { v, type ConditionalObjectKeys, type Pipe, type PipeInput, type PipeOutput } from 'valleyed'\n\ntype CtorParams<T> = ConstructorParameters<T & (abstract new (...args: any[]) => any)>\ntype BaseCtorParams<T> = T extends abstract new (...args: infer A) => any ? A : never\n\nexport function configurable<P extends Pipe<any, any>, Base extends abstract new (...args: any[]) => any>(pipeFn: () => P, base: Base) {\n\tconst pipe = pipeFn()\n\tv.compile(pipe)\n\n\tabstract class Configurable extends (base as unknown as new (...args: any[]) => any) {\n\t\tdeclare static readonly Config: PipeOutput<P>\n\n\t\tprotected constructor (protected readonly config: PipeOutput<P>, ...baseArgs: BaseCtorParams<Base>) {\n\t\t\t// eslint-disable-next-line constructor-super\n\t\t\tsuper(...baseArgs)\n\t\t}\n\n\t\tstatic create<This extends Function & { prototype: any }>(\n\t\t\tthis: This,\n\t\t\tinput: ConditionalObjectKeys<PipeInput<P>>,\n\t\t\t...args: CtorParams<This> extends [PipeOutput<P>, ...infer R] ? R : never\n\t\t): This['prototype'] {\n\t\t\tconst r = v.validate(pipe, input)\n\t\t\tif (!r.valid) throw r.error\n\t\t\treturn new (this as any)(r.value, ...args) as This['prototype']\n\t\t}\n\t}\n\n\treturn Configurable as unknown as (abstract new (validated: PipeOutput<P>, ...baseArgs: BaseCtorParams<Base>) => InstanceType<Base> & { readonly config: PipeOutput<P> }) & {\n\t\treadonly Config: PipeOutput<P>\n\t\tcreate<This extends Function & { prototype: any }>(\n\t\t\tthis: This,\n\t\t\tinput: ConditionalObjectKeys<PipeInput<P>>,\n\t\t\t...args: CtorParams<This> extends [PipeOutput<P>, ...infer R] ? R : never\n\t\t): This['prototype']\n\t}\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect, expectTypeOf } = import.meta.vitest\n\tconst { v } = await import('valleyed')\n\n\tconst testPipe = () =>\n\t\tv.object({\n\t\t\thost: v.string(),\n\t\t\tport: v.number(),\n\t\t})\n\n\ttype TestConfig = PipeOutput<ReturnType<typeof testPipe>>\n\n\tclass TestBase {\n\t\tbaseValue: string\n\t\tconstructor() {\n\t\t\tthis.baseValue = 'base'\n\t\t}\n\t}\n\n\tclass TestBaseWithArgs {\n\t\tlabel: string\n\t\tconstructor(label: string) {\n\t\t\tthis.label = label\n\t\t}\n\t}\n\n\tdescribe('configurable', () => {\n\t\ttest('validation runs in static create before constructor body executes', () => {\n\t\t\tlet constructorRan = false\n\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t\tconstructorRan = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(() => MyClass.create({ host: 123, port: 'bad' } as any)).toThrow()\n\t\t\texpect(constructorRan).toBe(false)\n\n\t\t\tMyClass.create({ host: 'localhost', port: 3000 })\n\t\t\texpect(constructorRan).toBe(true)\n\t\t})\n\n\t\ttest('constructor receives validated value', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tlet receivedConfig: unknown\n\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t\treceivedConfig = this.config\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tMyClass.create({ host: 'localhost', port: 3000 })\n\n\t\t\texpect(receivedConfig).toEqual({ host: 'localhost', port: 3000 })\n\t\t})\n\n\t\ttest('external new is a compile error', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// @ts-expect-error — external `new` on a class with protected constructor is a compile error\n\t\t\tvoid (() => new MyClass({ host: 'localhost', port: 3000 }))\n\t\t})\n\n\t\ttest('static Config resolves to PipeOutput<P> at the type level', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpectTypeOf<typeof MyClass.Config>().toEqualTypeOf<TestConfig>()\n\t\t\texpect(MyClass.create).toBeTypeOf('function')\n\t\t})\n\n\t\ttest('ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\textra: number\n\t\t\t\tprotected constructor(config: typeof MyClass.Config, extra: number) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t\tthis.extra = extra\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = MyClass.create({ host: 'localhost', port: 3000 }, 42)\n\n\t\t\texpect(instance.extra).toBe(42)\n\t\t\texpectTypeOf(instance).toHaveProperty('extra')\n\t\t\texpectTypeOf(instance.extra).toEqualTypeOf<number>()\n\n\t\t\t// @ts-expect-error — wrong extra type\n\t\t\tvoid (() => MyClass.create({ host: 'localhost', port: 3000 }, 'not-a-number'))\n\t\t})\n\n\t\ttest('base-args forwarding works for non-zero-arg bases', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBaseWithArgs)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config, label: string) {\n\t\t\t\t\tsuper(config, label)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = MyClass.create({ host: 'localhost', port: 3000 }, 'test-label')\n\n\t\t\texpect(instance.label).toBe('test-label')\n\t\t})\n\n\t\ttest('config is accessible as protected readonly on instances', () => {\n\t\t\tconst Wrapped = configurable(testPipe, TestBase)\n\t\t\tclass MyClass extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof MyClass.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\n\t\t\t\tgetHost() {\n\t\t\t\t\treturn this.config.host\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = MyClass.create({ host: 'localhost', port: 3000 })\n\t\t\texpect(instance.getHost()).toBe('localhost')\n\t\t})\n\n\t\ttest('accepts an abstract base class', () => {\n\t\t\tabstract class AbstractBase {\n\t\t\t\tabstract greet(): string\n\t\t\t}\n\n\t\t\tconst Wrapped = configurable(testPipe, AbstractBase)\n\t\t\tclass Concrete extends Wrapped {\n\t\t\t\tprotected constructor(config: typeof Concrete.Config) {\n\t\t\t\t\tsuper(config)\n\t\t\t\t}\n\t\t\t\tgreet() {\n\t\t\t\t\treturn `hello from ${this.config.host}`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst instance = Concrete.create({ host: 'localhost', port: 3000 })\n\t\t\texpect(instance.greet()).toBe('hello from localhost')\n\t\t\texpectTypeOf(instance).toHaveProperty('config')\n\t\t})\n\t})\n}\n","import { Instance } from '../../instance'\n\nexport abstract class Cache {\n\tabstract set(key: string, data: string, ttlInSecs?: number): Promise<void>\n\tabstract get(key: string): Promise<string | null>\n\tabstract delete(key: string): Promise<void>\n\n\tgetScopedKey(key: string) {\n\t\treturn Instance.get().getScopedName(key, ':')\n\t}\n\n\tasync getOrSet<T>(key: string, fn: () => Promise<T>, ttlInSecs?: number): Promise<T> {\n\t\tconst cached = await this.get(key)\n\t\tif (cached) return JSON.parse(cached) as T\n\n\t\tconst result = await fn()\n\t\tawait this.set(key, JSON.stringify(result), ttlInSecs)\n\t\treturn result\n\t}\n}\n"],"mappings":"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","names":["import_valleyed","import_valleyed","pino","import_valleyed","v"]}
|