@palbase/backend 25.1.0 → 27.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/bin/palbase-backend.cjs +2432 -1039
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +87 -51
  4. package/dist/bin/palbase-backend.js.map +1 -1
  5. package/dist/chunk-BQN723PL.js +930 -0
  6. package/dist/chunk-BQN723PL.js.map +1 -0
  7. package/dist/chunk-CGNN2PUH.js +213 -0
  8. package/dist/chunk-CGNN2PUH.js.map +1 -0
  9. package/dist/{chunk-VDF2T4AS.js → chunk-EB3TUX5J.js} +1228 -591
  10. package/dist/chunk-EB3TUX5J.js.map +1 -0
  11. package/dist/chunk-JVZQCC77.js +728 -0
  12. package/dist/chunk-JVZQCC77.js.map +1 -0
  13. package/dist/chunk-OZKSM3JW.js +370 -0
  14. package/dist/chunk-OZKSM3JW.js.map +1 -0
  15. package/dist/{chunk-YOY5DFQS.js → chunk-TWX6JTGJ.js} +76 -34
  16. package/dist/{chunk-YOY5DFQS.js.map → chunk-TWX6JTGJ.js.map} +1 -1
  17. package/dist/{chunk-35PNTIRN.js → chunk-VVMJEVQP.js} +63 -162
  18. package/dist/chunk-VVMJEVQP.js.map +1 -0
  19. package/dist/{chunk-7D4SUZUM.js → chunk-VXPNPVAG.js} +3 -1
  20. package/dist/chunk-XABHGMUT.js +885 -0
  21. package/dist/chunk-XABHGMUT.js.map +1 -0
  22. package/dist/db/env.cjs.map +1 -1
  23. package/dist/db/env.d.cts +2 -2
  24. package/dist/db/env.d.ts +2 -2
  25. package/dist/db/index.cjs +780 -344
  26. package/dist/db/index.cjs.map +1 -1
  27. package/dist/db/index.d.cts +2 -2
  28. package/dist/db/index.d.ts +2 -2
  29. package/dist/db/index.js +7 -4
  30. package/dist/engine/index.cjs +2366 -1002
  31. package/dist/engine/index.cjs.map +1 -1
  32. package/dist/engine/index.d.cts +6 -6
  33. package/dist/engine/index.d.ts +6 -6
  34. package/dist/engine/index.js +7 -6
  35. package/dist/{index-CUomTA3e.d.ts → index-CAKOgAlP.d.ts} +171 -296
  36. package/dist/index-CgE4sVhg.d.cts +4864 -0
  37. package/dist/{index-ClpDeSos.d.cts → index-H-0qv5d4.d.cts} +171 -296
  38. package/dist/index-V7QRh1wg.d.ts +4864 -0
  39. package/dist/index.cjs +2720 -1169
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +165 -19
  42. package/dist/index.d.ts +165 -19
  43. package/dist/index.js +738 -477
  44. package/dist/index.js.map +1 -1
  45. package/dist/module-Dl1KFVtc.d.cts +54 -0
  46. package/dist/module-Dl1KFVtc.d.ts +54 -0
  47. package/dist/openapi/index.cjs +1330 -484
  48. package/dist/openapi/index.cjs.map +1 -1
  49. package/dist/openapi/index.d.cts +4 -2
  50. package/dist/openapi/index.d.ts +4 -2
  51. package/dist/openapi/index.js +1264 -474
  52. package/dist/openapi/index.js.map +1 -1
  53. package/dist/{registry-dZZ5JKYg.d.ts → registry-4EI8aaFs.d.ts} +1 -1
  54. package/dist/{registry-CC0WBQq6.d.cts → registry-DHsPDY0_.d.cts} +1 -1
  55. package/dist/stack.cjs.map +1 -1
  56. package/dist/test/index.cjs +732 -141
  57. package/dist/test/index.cjs.map +1 -1
  58. package/dist/test/index.d.cts +30 -4
  59. package/dist/test/index.d.ts +30 -4
  60. package/dist/test/index.js +490 -124
  61. package/dist/test/index.js.map +1 -1
  62. package/docs/README.md +33 -18
  63. package/docs/auth.md +1 -1
  64. package/docs/background.md +2 -2
  65. package/docs/database.md +255 -50
  66. package/docs/endpoints.md +3 -4
  67. package/docs/events.md +3 -3
  68. package/docs/getting-started.md +1 -1
  69. package/docs/llms-full.txt +435 -117
  70. package/docs/migrations.md +2 -2
  71. package/docs/schema.md +19 -10
  72. package/docs/services.md +116 -26
  73. package/package.json +8 -4
  74. package/stager/generics.js +205 -0
  75. package/stager/stage.js +39 -3
  76. package/template/AGENTS.md +110 -72
  77. package/template/db/public.ts +1 -1
  78. package/template/{controllers → modules/health}/health.controller.ts +1 -1
  79. package/template/modules/health/health.module.ts +24 -0
  80. package/template/modules/notes/note.service.test.ts +49 -0
  81. package/template/modules/notes/note.service.ts +108 -0
  82. package/template/{controllers → modules/notes}/notes.controller.ts +17 -11
  83. package/template/modules/notes/notes.module.ts +37 -0
  84. package/template/package.json +5 -3
  85. package/template/scripts/test.sh +33 -0
  86. package/template/tsconfig.json +29 -30
  87. package/dist/chunk-35PNTIRN.js.map +0 -1
  88. package/dist/chunk-CJSKYY76.js +0 -627
  89. package/dist/chunk-CJSKYY76.js.map +0 -1
  90. package/dist/chunk-CRQKCRGF.js +0 -276
  91. package/dist/chunk-CRQKCRGF.js.map +0 -1
  92. package/dist/chunk-G4R6BTLV.js +0 -662
  93. package/dist/chunk-G4R6BTLV.js.map +0 -1
  94. package/dist/chunk-VDF2T4AS.js.map +0 -1
  95. package/dist/chunk-XABBC7JP.js +0 -55
  96. package/dist/chunk-XABBC7JP.js.map +0 -1
  97. package/dist/endpoint-CTEHhb7A.d.ts +0 -2386
  98. package/dist/endpoint-DYHMo6cC.d.cts +0 -2386
  99. package/dist/index-CW21M9Z3.d.ts +0 -1222
  100. package/dist/index-CmBK76nx.d.cts +0 -1222
  101. package/template/services/note.service.test.ts +0 -45
  102. package/template/services/note.service.ts +0 -76
  103. /package/dist/{chunk-7D4SUZUM.js.map → chunk-VXPNPVAG.js.map} +0 -0
  104. /package/template/{models/notes → modules/notes/dto}/create.ts +0 -0
@@ -0,0 +1,930 @@
1
+ import {
2
+ qualifiedTableKey,
3
+ withRetry
4
+ } from "./chunk-OZKSM3JW.js";
5
+ import {
6
+ TxPlanBuilder,
7
+ runTxPlan
8
+ } from "./chunk-JVZQCC77.js";
9
+ import {
10
+ __name
11
+ } from "./chunk-VXPNPVAG.js";
12
+
13
+ // src/runtime.ts
14
+ import { AsyncLocalStorage } from "async_hooks";
15
+ var __requestALS = new AsyncLocalStorage();
16
+ var runtime = null;
17
+ function __setRuntime(services) {
18
+ runtime = services;
19
+ }
20
+ __name(__setRuntime, "__setRuntime");
21
+ function __runWithRuntime(services, fn) {
22
+ return __requestALS.run({
23
+ runtime: services
24
+ }, fn);
25
+ }
26
+ __name(__runWithRuntime, "__runWithRuntime");
27
+ function __getRuntime() {
28
+ const scoped = __requestALS.getStore();
29
+ if (scoped) return scoped.runtime;
30
+ if (runtime === null) {
31
+ throw new Error("Palbase services accessed outside a request scope. The Database/Documents/\u2026 singletons are only available inside an endpoint handler (or after the runtime has called __runWithRuntime / __setRuntime).");
32
+ }
33
+ return runtime;
34
+ }
35
+ __name(__getRuntime, "__getRuntime");
36
+ var LIFECYCLE = /* @__PURE__ */ Symbol.for("palbase.backend.lifecycleHooks");
37
+ function declaredLifecycle() {
38
+ const g = globalThis;
39
+ return g[LIFECYCLE] ??= {
40
+ start: [],
41
+ shutdown: []
42
+ };
43
+ }
44
+ __name(declaredLifecycle, "declaredLifecycle");
45
+ function onStart(name, hook) {
46
+ declaredLifecycle().start.push({
47
+ name,
48
+ run: hook
49
+ });
50
+ }
51
+ __name(onStart, "onStart");
52
+ function onShutdown(name, hook) {
53
+ declaredLifecycle().shutdown.push({
54
+ name,
55
+ run: hook
56
+ });
57
+ }
58
+ __name(onShutdown, "onShutdown");
59
+ function reason(err) {
60
+ return err instanceof Error ? err.message : String(err);
61
+ }
62
+ __name(reason, "reason");
63
+ async function drain(hooks) {
64
+ for (const h of [
65
+ ...hooks
66
+ ].reverse()) {
67
+ try {
68
+ await h.run();
69
+ } catch (err) {
70
+ console.error(`[palbase] shutdown hook "${h.name}" failed: ${reason(err)}`, err);
71
+ }
72
+ }
73
+ }
74
+ __name(drain, "drain");
75
+ async function __runStartHooks() {
76
+ const slot3 = declaredLifecycle();
77
+ const start = slot3.start.splice(0);
78
+ const shutdown = slot3.shutdown.splice(0);
79
+ for (const h of start) {
80
+ try {
81
+ await h.run();
82
+ } catch (err) {
83
+ await drain(shutdown);
84
+ throw new Error(`[palbase] start hook "${h.name}" failed: ${reason(err)}`, {
85
+ cause: err
86
+ });
87
+ }
88
+ }
89
+ let drained = false;
90
+ return async () => {
91
+ if (drained) return;
92
+ drained = true;
93
+ await drain(shutdown);
94
+ };
95
+ }
96
+ __name(__runStartHooks, "__runStartHooks");
97
+ function __resetLifecycleHooks() {
98
+ const g = globalThis;
99
+ delete g[LIFECYCLE];
100
+ }
101
+ __name(__resetLifecycleHooks, "__resetLifecycleHooks");
102
+ function makeServiceProxy(key) {
103
+ const handler = {
104
+ get(_target, prop, receiver) {
105
+ const client = __getRuntime()[key];
106
+ const value = Reflect.get(client, prop, receiver);
107
+ return typeof value === "function" ? value.bind(client) : value;
108
+ }
109
+ };
110
+ return new Proxy({}, handler);
111
+ }
112
+ __name(makeServiceProxy, "makeServiceProxy");
113
+ function makeTableProxy(ops, prefix) {
114
+ return new Proxy({}, {
115
+ get(_t, prop) {
116
+ if (typeof prop !== "string") return void 0;
117
+ const name = `${prefix}${prop}`;
118
+ return {
119
+ insert: /* @__PURE__ */ __name((data) => ops().insert(name, data), "insert"),
120
+ update: /* @__PURE__ */ __name((q) => ops().update(name, q.where.id, q.set), "update"),
121
+ delete: /* @__PURE__ */ __name((id) => ops().delete(name, id), "delete"),
122
+ findById: /* @__PURE__ */ __name((id) => ops().findById(name, id), "findById"),
123
+ findMany: /* @__PURE__ */ __name((q) => {
124
+ const { where, ...opts } = q ?? {};
125
+ return ops().findMany(name, where, opts);
126
+ }, "findMany"),
127
+ put: /* @__PURE__ */ __name((q) => ops().put(name, q.data, {
128
+ onConflict: q.onConflict
129
+ }), "put"),
130
+ // THREE VERBS THE TYPE PROMISED AND THIS PROXY DID NOT EMIT.
131
+ //
132
+ // `EnvTypedTableBase` declares `updateMany`, `deleteMany` and `count`
133
+ // (typed-db.ts) and the ops layer implements all three — only this
134
+ // proxy, which is what a handler actually touches, left them out. So
135
+ // the type said the verb exists, autocomplete offered it, and the call
136
+ // answered `undefined is not a function`.
137
+ //
138
+ // Older than this run, but the run rewrote this proxy for
139
+ // `Database.schema(name).tables.*` and would have carried the gap onto
140
+ // the new surface too.
141
+ updateMany: /* @__PURE__ */ __name((q) => ops().updateMany(name, q.where, q.set), "updateMany"),
142
+ deleteMany: /* @__PURE__ */ __name((q) => ops().deleteMany(name, q.where), "deleteMany"),
143
+ count: /* @__PURE__ */ __name((q) => ops().count(name, q?.where), "count"),
144
+ search: /* @__PURE__ */ __name((params) => ops().search(name, params), "search"),
145
+ similar: /* @__PURE__ */ __name((id, params) => ops().similar(name, id, params), "similar"),
146
+ recommend: /* @__PURE__ */ __name((params) => ops().recommend(name, params), "recommend"),
147
+ facets: /* @__PURE__ */ __name((params) => ops().facets(name, params), "facets"),
148
+ supersede: /* @__PURE__ */ __name((id, row) => ops().supersede(name, id, row), "supersede"),
149
+ claim: /* @__PURE__ */ __name((unique, extra) => ops().claim(name, unique, extra), "claim")
150
+ };
151
+ }
152
+ });
153
+ }
154
+ __name(makeTableProxy, "makeTableProxy");
155
+ var rawDatabase = makeServiceProxy("Database");
156
+ function makeTypedSurface(raw) {
157
+ const reco = raw;
158
+ const ops = {
159
+ $query: /* @__PURE__ */ __name((sql, params) => raw.query(sql, params), "$query"),
160
+ $insert: /* @__PURE__ */ __name((table, data) => raw.insert(table, data), "$insert"),
161
+ $update: /* @__PURE__ */ __name((table, id, data) => raw.update(table, id, data), "$update"),
162
+ $delete: /* @__PURE__ */ __name((table, id) => raw.delete(table, id), "$delete"),
163
+ $findById: /* @__PURE__ */ __name((table, id) => raw.findById(table, id), "$findById"),
164
+ $findMany: /* @__PURE__ */ __name((table, query, opts) => raw.findMany(table, query, opts), "$findMany"),
165
+ $put: /* @__PURE__ */ __name((table, data, opts) => raw.put(table, data, opts), "$put"),
166
+ $updateMany: /* @__PURE__ */ __name((table, where, set) => raw.updateMany(table, where, set), "$updateMany"),
167
+ $deleteMany: /* @__PURE__ */ __name((table, where) => raw.deleteMany(table, where), "$deleteMany"),
168
+ $count: /* @__PURE__ */ __name((table, where) => raw.count(table, where), "$count"),
169
+ $search: /* @__PURE__ */ __name((table, params) => raw.search(table, params), "$search"),
170
+ $similar: /* @__PURE__ */ __name((table, id, params) => reco.similar(table, id, params), "$similar"),
171
+ $recommend: /* @__PURE__ */ __name((table, params) => reco.recommend(table, params), "$recommend"),
172
+ $facets: /* @__PURE__ */ __name((table, params) => reco.facets(table, params), "$facets"),
173
+ $claim: /* @__PURE__ */ __name((table, unique, extra) => reco.claim(table, unique, extra), "$claim"),
174
+ $lockRows: /* @__PURE__ */ __name((table, ids) => reco.lockRows(table, ids), "$lockRows"),
175
+ $advisoryXactLock: /* @__PURE__ */ __name((key) => reco.advisoryXactLock(key), "$advisoryXactLock"),
176
+ $supersede: /* @__PURE__ */ __name((table, id, row) => raw.supersede(table, id, row), "$supersede")
177
+ };
178
+ const base = Object.assign(ops, {
179
+ // Both surfaces get it: a savepoint on the service transaction is as useful
180
+ // as one on the request's, and each is bound to its own connection.
181
+ $attempt: /* @__PURE__ */ __name((fn) => raw.attempt(fn), "$attempt"),
182
+ $transaction(fn, opts) {
183
+ return withRetry(() => {
184
+ const builder = new TxPlanBuilder();
185
+ return runTxPlan(raw, makeTxPlanHandle(builder), builder, fn);
186
+ }, opts ?? {});
187
+ }
188
+ });
189
+ return new Proxy(base, {
190
+ get(target, prop, receiver) {
191
+ if (prop === "tables") return makeTableProxy(() => reco, "");
192
+ if (typeof prop === "string" && !prop.startsWith("$") && !(prop in target)) {
193
+ return makeTableProxy(() => reco, qualifiedTableKey(prop, ""));
194
+ }
195
+ return Reflect.get(target, prop, receiver);
196
+ }
197
+ });
198
+ }
199
+ __name(makeTypedSurface, "makeTypedSurface");
200
+ function makeTxTablesAccessor(builder, prefix = "") {
201
+ const tablesProxy = new Proxy({}, {
202
+ get(_t, prop) {
203
+ if (typeof prop !== "string") return void 0;
204
+ return builder.table(prefix + prop);
205
+ }
206
+ });
207
+ return tablesProxy;
208
+ }
209
+ __name(makeTxTablesAccessor, "makeTxTablesAccessor");
210
+ function makeTxPlanHandle(builder) {
211
+ const publicTables = makeTxTablesAccessor(builder);
212
+ return new Proxy({}, {
213
+ get(_t, prop) {
214
+ if (typeof prop !== "string") return void 0;
215
+ if (prop === "tables") return publicTables;
216
+ return makeTxTablesAccessor(builder, qualifiedTableKey(prop, ""));
217
+ }
218
+ });
219
+ }
220
+ __name(makeTxPlanHandle, "makeTxPlanHandle");
221
+ var Database = Object.assign(makeTypedSurface(rawDatabase), {
222
+ /**
223
+ * Lazily resolve the runtime's service-role sibling on each call. We do NOT
224
+ * cache it: `rawDatabase.asService()` reads the CURRENT request scope through
225
+ * the runtime proxy, and the per-request runtime injects a service client
226
+ * bound to that request's identity headers — caching would leak one request's
227
+ * sibling into another concurrent request.
228
+ */
229
+ $asService() {
230
+ return makeTypedSurface(rawDatabase.asService());
231
+ }
232
+ });
233
+ var Documents = makeServiceProxy("Documents");
234
+ function makeBucketsAccessor(storage) {
235
+ return new Proxy({}, {
236
+ get(_t, prop) {
237
+ if (typeof prop !== "string") return void 0;
238
+ return storage().bucket(prop);
239
+ }
240
+ });
241
+ }
242
+ __name(makeBucketsAccessor, "makeBucketsAccessor");
243
+ var rawStorage = makeServiceProxy("Storage");
244
+ var Storage = Object.assign({
245
+ // FORWARDED explicitly, not assigned onto the service proxy.
246
+ //
247
+ // `Object.assign(rawStorage, {buckets})` writes onto the proxy's TARGET, and
248
+ // the proxy's only trap is `get`, which forwards every read to the module
249
+ // client — so the property landed somewhere nothing reads and
250
+ // `Storage.buckets.docs` was `undefined` in a deployed handler. It
251
+ // typechecked, every test passed, and the live call answered
252
+ // "TypeError: undefined is not an object". `Database` never had the bug
253
+ // because it builds a plain surface the same way this now does.
254
+ bucket: /* @__PURE__ */ __name((name) => rawStorage.bucket(name), "bucket")
255
+ }, {
256
+ buckets: makeBucketsAccessor(() => rawStorage)
257
+ });
258
+ var Cache = makeServiceProxy("Cache");
259
+ var Secrets = makeServiceProxy("Secrets");
260
+ var Log = makeServiceProxy("Log");
261
+ var Notifications = makeServiceProxy("Notifications");
262
+ var rawFlags = makeServiceProxy("Flags");
263
+ var Flags = Object.assign({
264
+ isEnabled(flagName, context) {
265
+ return rawFlags.isEnabled(flagName, context);
266
+ },
267
+ getVariant(flagName, context) {
268
+ return rawFlags.getVariant(flagName, context);
269
+ },
270
+ getAll(context) {
271
+ return rawFlags.getAll(context);
272
+ },
273
+ /**
274
+ * Resolve a flag's value, with an optional fallback.
275
+ *
276
+ * FORWARDED as of 2026-08-15. This surface is written out by hand, method
277
+ * by method, and `get` was missing from it — so the client implemented it,
278
+ * thirty assertions covered it, and `Flags.get("x")` was `undefined` in a
279
+ * deployed handler. Exactly the shape of the `Storage.buckets` defect found
280
+ * the same day: a hand-maintained forwarding list is a list somebody has to
281
+ * remember to update.
282
+ */
283
+ get(flagName, defaultOrContext, maybeContext) {
284
+ return rawFlags.get(flagName, defaultOrContext, maybeContext);
285
+ },
286
+ setOverride(key, value) {
287
+ return rawFlags.setOverride(key, value);
288
+ }
289
+ }, {
290
+ /**
291
+ * Lazily resolve the runtime's cross-user sibling on each call. We do NOT
292
+ * cache it: `rawFlags.asService()` reads the CURRENT request scope through
293
+ * the runtime proxy, so caching would leak one request's sibling into
294
+ * another concurrent request. Mirrors `Database.asService()`.
295
+ */
296
+ asService() {
297
+ return rawFlags.asService();
298
+ }
299
+ });
300
+ var Realtime = makeServiceProxy("Realtime");
301
+
302
+ // src/db/env-gen.ts
303
+ function baseTsType(def) {
304
+ switch (def.type) {
305
+ case "uuid":
306
+ case "text":
307
+ case "timestamp":
308
+ return "string";
309
+ case "integer":
310
+ return "number";
311
+ // Both are exact-precision in Postgres and lossy as a JSON number, so the
312
+ // database proxy serializes them as strings — measured: 9007199254740993
313
+ // used to arrive as ...992 and 41.00821234567890123 as 41.0082123456789.
314
+ // numeric had no case at all and fell through to `unknown`, which typed
315
+ // every numeric column out of existence.
316
+ case "bigint":
317
+ case "numeric":
318
+ return "string";
319
+ case "boolean":
320
+ return "boolean";
321
+ case "jsonb":
322
+ return "unknown";
323
+ // FR-008: the authoring type of a pgvector column. The default `unknown`
324
+ // branch below STAYS — an unknown wire type is refused on the Go side
325
+ // (FR-005), never papered over here.
326
+ case "vector":
327
+ return "number[]";
328
+ case "enum": {
329
+ const values = def.enumValues ?? [];
330
+ if (values.length === 0) return "string";
331
+ return values.map((v) => JSON.stringify(v)).join(" | ");
332
+ }
333
+ default:
334
+ return "unknown";
335
+ }
336
+ }
337
+ __name(baseTsType, "baseTsType");
338
+ function rowType(def) {
339
+ const base = baseTsType(def);
340
+ return def.nullable ? `${base} | null` : base;
341
+ }
342
+ __name(rowType, "rowType");
343
+ function optionalOnInsert(def) {
344
+ return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
345
+ }
346
+ __name(optionalOnInsert, "optionalOnInsert");
347
+ function forwardName(column) {
348
+ return column.endsWith("_id") ? column.slice(0, -3) : column;
349
+ }
350
+ __name(forwardName, "forwardName");
351
+ function describeOrigin(o) {
352
+ return o.direction === "forward" ? `the foreign key "${o.table}.${o.column}"` : `the reverse of "${o.table}.${o.column}"`;
353
+ }
354
+ __name(describeOrigin, "describeOrigin");
355
+ function renameCall(o) {
356
+ if (o.direction === "reverse") return `references(() => \u2026, { reverseAs: "\u2026" })`;
357
+ if (o.def.owns === true) {
358
+ return `ownedByUser() takes no { as } \u2014 if "${o.column}" only POINTS at a user, declare it userRef({ onDelete: \u2026 }) instead`;
359
+ }
360
+ const target = o.def.references?.table;
361
+ if (target === "auth.users") return `userRef({ onDelete: \u2026, as: "\u2026" })`;
362
+ if (target === "auth.installations") return `installationRef({ onDelete: \u2026, as: "\u2026" })`;
363
+ if (o.def.selfRefColumn !== void 0) return `selfReferences("\u2026", { as: "\u2026" })`;
364
+ return `references(() => \u2026, { as: "\u2026" })`;
365
+ }
366
+ __name(renameCall, "renameCall");
367
+ function buildRelations(schemas) {
368
+ const out = /* @__PURE__ */ new Map();
369
+ const taken = /* @__PURE__ */ new Map();
370
+ for (const schema of schemas) {
371
+ for (const t of Object.values(schema.tables)) {
372
+ const key = qualifiedTableKey(schema.name, t.name);
373
+ out.set(key, []);
374
+ taken.set(key, /* @__PURE__ */ new Map());
375
+ }
376
+ }
377
+ const claim = /* @__PURE__ */ __name((tableKey, name, origin, edge) => {
378
+ const names = taken.get(tableKey);
379
+ if (names === void 0) return;
380
+ const held = names.get(name);
381
+ if (held !== void 0) {
382
+ if (held.def.owns === true && origin.def.owns === true) {
383
+ throw new Error(`table "${tableKey}" declares TWO owner columns (${held.column}, ${origin.column}) \u2014 a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: \u2026 }) instead.`);
384
+ }
385
+ const heldFix = renameCall(held);
386
+ const originFix = renameCall(origin);
387
+ const remedy = heldFix === originFix ? `rename one of them: ${heldFix}` : `rename one of them \u2014 "${held.table}.${held.column}": ${heldFix}; "${origin.table}.${origin.column}": ${originFix}`;
388
+ throw new Error(`table "${tableKey}": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name "${name}" \u2014 ${remedy}.`);
389
+ }
390
+ names.set(name, origin);
391
+ out.get(tableKey)?.push(edge);
392
+ }, "claim");
393
+ for (const schema of schemas) {
394
+ for (const table of Object.values(schema.tables)) {
395
+ const childKey = qualifiedTableKey(schema.name, table.name);
396
+ if (!out.has(childKey)) continue;
397
+ for (const [col, builder] of Object.entries(table.columns)) {
398
+ const def = builder._def;
399
+ if (def.references === void 0) continue;
400
+ const targetKey = def.references.table;
401
+ const name = def.owns === true ? "owner" : def.refAs ?? forwardName(col);
402
+ claim(childKey, name, {
403
+ table: table.name,
404
+ column: col,
405
+ direction: "forward",
406
+ def
407
+ }, {
408
+ name,
409
+ to: targetKey,
410
+ kind: "one",
411
+ via: col
412
+ });
413
+ if (!out.has(targetKey) || targetKey === childKey) continue;
414
+ const reverse = def.reverseAs ?? table.name;
415
+ claim(targetKey, reverse, {
416
+ table: table.name,
417
+ column: col,
418
+ direction: "reverse",
419
+ def
420
+ }, {
421
+ name: reverse,
422
+ to: childKey,
423
+ kind: "many",
424
+ via: col
425
+ });
426
+ }
427
+ }
428
+ }
429
+ return out;
430
+ }
431
+ __name(buildRelations, "buildRelations");
432
+ function tableBlock(table, relations, indent) {
433
+ const cols = Object.entries(table.columns);
434
+ const rowLines = cols.map(([col, builder]) => {
435
+ return `${indent} ${col}: ${rowType(builder._def)};`;
436
+ });
437
+ const insertLines = cols.map(([col, builder]) => {
438
+ const def = builder._def;
439
+ const opt = optionalOnInsert(def) ? "?" : "";
440
+ return `${indent} ${col}${opt}: ${rowType(def)};`;
441
+ });
442
+ const relEntries = relations.map((r) => `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`).join("; ");
443
+ return [
444
+ `${indent}${table.name}: {`,
445
+ `${indent} row: {`,
446
+ ...rowLines,
447
+ `${indent} };`,
448
+ `${indent} insert: {`,
449
+ ...insertLines,
450
+ `${indent} };`,
451
+ `${indent} relations: {${relEntries === "" ? "" : ` ${relEntries} `}};`,
452
+ // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
453
+ // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
454
+ // mevcut şemaların d.ts'i bayt-aynı kalsın.
455
+ ...cols.some(([, b]) => b._def.type === "vector") || table.search !== void 0 ? [
456
+ `${indent} searchable: true;`
457
+ ] : [],
458
+ // appendOnly (FR-031): EnvTypedTable'ın altı yazma üyesini KALDIRAN yapısal
459
+ // bayrak. `searchable` ile aynı desen ve aynı OMIT disiplini — bayrak yokken
460
+ // satır hiç üretilmez ki mevcut şemaların d.ts'i bayt-aynı kalsın.
461
+ ...table.appendOnly === true ? [
462
+ `${indent} appendOnly: true;`
463
+ ] : [],
464
+ `${indent}};`
465
+ ].join("\n");
466
+ }
467
+ __name(tableBlock, "tableBlock");
468
+ function makeEnvDts(schemas) {
469
+ const relations = buildRelations(schemas);
470
+ const publicSchema = schemas.find((s) => s.name === "public");
471
+ const others = schemas.filter((s) => s.name !== "public");
472
+ const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map((name) => tableBlock(publicSchema.tables[name], relations.get(name) ?? [], " "));
473
+ const body = publicBlocks.length > 0 ? `
474
+ ${publicBlocks.join("\n")}
475
+ ` : "";
476
+ const schemaBlocks = others.map((schema) => {
477
+ const inner = Object.keys(schema.tables).map((name) => tableBlock(schema.tables[name], relations.get(qualifiedTableKey(schema.name, name)) ?? [], " "));
478
+ return ` ${schema.name}: {
479
+ ${inner.join("\n")}
480
+ };`;
481
+ });
482
+ const schemasBody = schemaBlocks.length > 0 ? `
483
+ ${schemaBlocks.join("\n")}
484
+ ` : "";
485
+ return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
486
+ // Regenerated from db/*.ts by \`palbase build\` and by every deploy.
487
+ // Augments the @palbase/backend/env \`Tables\` interface so \`Database.public.*\`
488
+ // is typed with no import and no generic. Schemas other than \`public\` land
489
+ // under \`Schemas\`, reached with \`Database.schema("<name>").tables.*\`.
490
+
491
+ declare module "@palbase/backend/env" {
492
+ interface Tables {${body}}
493
+ interface Schemas {${schemasBody}}
494
+ }
495
+
496
+ export {};
497
+ `;
498
+ }
499
+ __name(makeEnvDts, "makeEnvDts");
500
+
501
+ // src/decorators/injectable.ts
502
+ var DI_INJECTABLES = /* @__PURE__ */ Symbol.for("palbase.backend.diInjectables");
503
+ var INJECTABLE = /* @__PURE__ */ Symbol.for("palbase.backend.injectable");
504
+ var isInjectable = /* @__PURE__ */ __name((c) => c?.[INJECTABLE] === true, "isInjectable");
505
+ function slot() {
506
+ const g = globalThis;
507
+ return g[DI_INJECTABLES] ??= [];
508
+ }
509
+ __name(slot, "slot");
510
+ function Injectable() {
511
+ return (target) => {
512
+ target[INJECTABLE] = true;
513
+ slot().push(target);
514
+ };
515
+ }
516
+ __name(Injectable, "Injectable");
517
+ function __claimInjectables() {
518
+ return slot().splice(0);
519
+ }
520
+ __name(__claimInjectables, "__claimInjectables");
521
+
522
+ // src/decorators/kinds.ts
523
+ var JOB = /* @__PURE__ */ Symbol.for("palbase.backend.jobMeta");
524
+ var WEBHOOK = /* @__PURE__ */ Symbol.for("palbase.backend.webhookMeta");
525
+ var HOOK_BLOCKING = /* @__PURE__ */ Symbol.for("palbase.backend.hookBlocking");
526
+ var HOOK_LISTENERS = /* @__PURE__ */ Symbol.for("palbase.backend.webhookEvents");
527
+ var ROOM = /* @__PURE__ */ Symbol.for("palbase.backend.room");
528
+ var CONTROLLER = /* @__PURE__ */ Symbol.for("palbase.backend.controllerMeta");
529
+ var has = /* @__PURE__ */ __name((c, s) => c[s] !== void 0, "has");
530
+ var isEntryPointClass = /* @__PURE__ */ __name((c) => has(c, JOB) || has(c, WEBHOOK) || has(c, ROOM) || has(c, CONTROLLER) || has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS), "isEntryPointClass");
531
+ var owned = /* @__PURE__ */ __name((container) => [
532
+ ...container.owned
533
+ ], "owned");
534
+ var jobsOf = /* @__PURE__ */ __name((container) => owned(container).filter((c) => has(c, JOB)), "jobsOf");
535
+ var webhooksOf = /* @__PURE__ */ __name((container) => owned(container).filter((c) => has(c, WEBHOOK)), "webhooksOf");
536
+ var hooksOf = /* @__PURE__ */ __name((container) => owned(container).filter((c) => !has(c, WEBHOOK) && !has(c, CONTROLLER) && (has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS))), "hooksOf");
537
+ var roomsOf = /* @__PURE__ */ __name((container) => owned(container).filter((c) => has(c, ROOM)), "roomsOf");
538
+ var controllersOf = /* @__PURE__ */ __name((container) => owned(container).filter((c) => has(c, CONTROLLER)), "controllersOf");
539
+
540
+ // src/decorators/module.ts
541
+ var DI_MODULES = /* @__PURE__ */ Symbol.for("palbase.backend.diModules");
542
+ function slot2() {
543
+ const g = globalThis;
544
+ return g[DI_MODULES] ??= [];
545
+ }
546
+ __name(slot2, "slot");
547
+ function Module(def) {
548
+ return (target) => {
549
+ slot2().push({
550
+ mod: target,
551
+ def
552
+ });
553
+ };
554
+ }
555
+ __name(Module, "Module");
556
+ function __claimModules() {
557
+ return slot2().splice(0);
558
+ }
559
+ __name(__claimModules, "__claimModules");
560
+
561
+ // src/container.ts
562
+ import "reflect-metadata";
563
+ var DiError = class extends Error {
564
+ static {
565
+ __name(this, "DiError");
566
+ }
567
+ kind;
568
+ path;
569
+ at;
570
+ fixes;
571
+ constructor(kind, path, at, detail, fixes) {
572
+ super(`
573
+ Kind: ${kind}
574
+ Path: ${path.length > 0 ? path.join(" -> ") : "(none)"}
575
+ At: ${at}
576
+ ${detail}
577
+
578
+ Potential solutions:
579
+ ${fixes.map((f) => ` - ${f}`).join("\n")}
580
+ `), this.kind = kind, this.path = path, this.at = at, this.fixes = fixes;
581
+ this.name = "DiError";
582
+ }
583
+ };
584
+ var nameOf = /* @__PURE__ */ __name((c) => c?.name ?? String(c), "nameOf");
585
+ var UNRESOLVABLE = /* @__PURE__ */ new Set([
586
+ Object,
587
+ Function,
588
+ String,
589
+ Number,
590
+ Boolean,
591
+ Array,
592
+ Symbol,
593
+ Promise,
594
+ Date,
595
+ void 0,
596
+ null
597
+ ]);
598
+ var DATA = /* @__PURE__ */ new Set([
599
+ String,
600
+ Number,
601
+ Boolean,
602
+ Date,
603
+ Symbol
604
+ ]);
605
+ function declaresDependencies(ctor) {
606
+ const arity = ctor?.length ?? 0;
607
+ if (arity === 0) return true;
608
+ const meta = Reflect.getMetadata("design:paramtypes", ctor);
609
+ return meta !== void 0 && meta.length === arity;
610
+ }
611
+ __name(declaresDependencies, "declaresDependencies");
612
+ function buildContainer() {
613
+ const entries = __claimModules();
614
+ const declared = __claimInjectables();
615
+ if (entries.length === 0) {
616
+ throw new DiError("unowned class", [], "project", "no module was declared \u2014 every project declares at least one @Module.", [
617
+ "create `<domain>.module.ts` with @Module({ controllers: [...], providers: [...] })",
618
+ "`palbase init` scaffolds one for you"
619
+ ]);
620
+ }
621
+ const declaredModules = new Set(entries.map((e) => e.mod));
622
+ const owner = /* @__PURE__ */ new Map();
623
+ for (const { mod, def } of entries) {
624
+ const m = nameOf(mod);
625
+ for (const c of [
626
+ ...def.providers ?? [],
627
+ ...def.controllers ?? []
628
+ ]) {
629
+ const prev = owner.get(c);
630
+ if (prev !== void 0) {
631
+ throw new DiError("duplicate ownership", [
632
+ nameOf(c)
633
+ ], `${prev} & ${m}`, `${nameOf(c)} is listed by two modules, so which one owns it has two answers.`, [
634
+ `remove ${nameOf(c)} from ${prev}`,
635
+ `or remove it from ${m}`,
636
+ `if both modules need it, keep ONE owner and export it, then import that module`
637
+ ]);
638
+ }
639
+ owner.set(c, m);
640
+ }
641
+ }
642
+ {
643
+ for (const { mod, def } of entries) {
644
+ for (const p of def.providers ?? []) {
645
+ if (isInjectable(p) || isEntryPointClass(p)) continue;
646
+ if (!declaresDependencies(p)) continue;
647
+ throw new DiError("undeclared provider", [
648
+ nameOf(mod),
649
+ nameOf(p)
650
+ ], `${nameOf(mod)}.providers`, `${nameOf(p)} is listed in ${nameOf(mod)}.providers but carries no decorator, so the container cannot know it is constructible or what its constructor asks for.`, [
651
+ `mark ${nameOf(p)} \`@Injectable()\` if it is a concrete class`,
652
+ `if ${nameOf(p)} is an \`abstract class\`, list the class that \`extends\` it instead \u2014 name the abstraction as the DEPENDENCY and the container resolves it`
653
+ ]);
654
+ }
655
+ }
656
+ }
657
+ {
658
+ const orphans = declared.filter((c) => !owner.has(c));
659
+ if (orphans.length > 0) {
660
+ const names = orphans.map(nameOf);
661
+ throw new DiError("unowned class", names, "module declarations", `${names.join(", ")} ${orphans.length === 1 ? "is" : "are"} marked @Injectable() but listed in no module's providers, so nothing can reach ${orphans.length === 1 ? "it" : "them"}.`, [
662
+ `add ${names.length === 1 ? names[0] : "each of them"} to a module's \`providers\``,
663
+ "or delete the class \u2014 one no module lists is never built"
664
+ ]);
665
+ }
666
+ }
667
+ const exported = /* @__PURE__ */ new Map();
668
+ const importsOf = /* @__PURE__ */ new Map();
669
+ for (const { mod, def } of entries) {
670
+ const m = nameOf(mod);
671
+ for (const e of def.exports ?? []) {
672
+ if (owner.get(e) !== m) {
673
+ const holder = owner.get(e);
674
+ throw new DiError("unknown export", [
675
+ m
676
+ ], `${m}.exports`, holder === void 0 ? `${m} exports ${nameOf(e)}, but no module owns it.` : `${m} exports ${nameOf(e)}, but ${holder} owns it \u2014 a module cannot re-export another's class.`, holder === void 0 ? [
677
+ `add ${nameOf(e)} to ${m}.providers`,
678
+ `or remove it from ${m}.exports`
679
+ ] : [
680
+ `remove ${nameOf(e)} from ${m}.exports`,
681
+ `and have ${holder} export it instead, then add ${holder} to the importing module's imports`
682
+ ]);
683
+ }
684
+ }
685
+ for (const i of def.imports ?? []) {
686
+ if (i === mod) {
687
+ throw new DiError("unknown import", [
688
+ m
689
+ ], `${m}.imports`, `${m} imports itself, which grants nothing it does not already have.`, [
690
+ `remove ${m} from its own imports`,
691
+ "or name the module you meant instead"
692
+ ]);
693
+ }
694
+ if (!declaredModules.has(i)) {
695
+ throw new DiError("unknown import", [
696
+ m
697
+ ], `${m}.imports`, `${m} imports ${nameOf(i)}, which is not a module.`, [
698
+ `add @Module({ ... }) to ${nameOf(i)}`,
699
+ `or remove ${nameOf(i)} from ${m}.imports \u2014 to reach a class, import the module that OWNS it`
700
+ ]);
701
+ }
702
+ }
703
+ exported.set(m, new Set(def.exports ?? []));
704
+ importsOf.set(m, new Set((def.imports ?? []).map(nameOf)));
705
+ }
706
+ const deps = /* @__PURE__ */ new Map();
707
+ const implementorsOf = /* @__PURE__ */ __name((t) => [
708
+ ...owner.keys()
709
+ ].filter((c) => c !== t && Object.prototype.isPrototypeOf.call(t, c)), "implementorsOf");
710
+ const withArity = [
711
+ ...owner.keys()
712
+ ].filter((c) => c.length > 0);
713
+ const missingMeta = withArity.filter((c) => Reflect.getMetadata("design:paramtypes", c) === void 0);
714
+ if (withArity.length >= 2 && missingMeta.length === withArity.length) {
715
+ throw new DiError("metadata missing", withArity.map(nameOf), "the whole build", `no class carries constructor metadata \u2014 every one of the ${withArity.length} class(es) that asks for a dependency is missing it, so this is the build, not the classes.`, [
716
+ "set `emitDecoratorMetadata: true` in the project's tsconfig.json",
717
+ "and import `reflect-metadata` before any decorated class evaluates \u2014 without it the emitted helper is a silent no-op",
718
+ "if the build is fine, then none of these classes carries @Injectable()"
719
+ ]);
720
+ }
721
+ for (const [cls, m] of owner) {
722
+ const arity = cls.length;
723
+ if (arity === 0) {
724
+ deps.set(cls, []);
725
+ continue;
726
+ }
727
+ if (!declaresDependencies(cls)) {
728
+ const meta2 = Reflect.getMetadata("design:paramtypes", cls);
729
+ throw new DiError("metadata missing", [
730
+ nameOf(cls)
731
+ ], `${nameOf(cls)} constructor`, `${nameOf(cls)} declares ${arity} parameter(s) but carries ${meta2 === void 0 ? "no" : String(meta2.length)} metadata entries, so every parameter would arrive as undefined.`, [
732
+ `add @Injectable() to ${nameOf(cls)} \u2014 metadata is emitted for DECORATED classes only`,
733
+ "or the build ran without emitDecoratorMetadata: check tsconfig.json"
734
+ ]);
735
+ }
736
+ const meta = Reflect.getMetadata("design:paramtypes", cls);
737
+ const list = [];
738
+ meta.forEach((t, i) => {
739
+ const at = `${nameOf(cls)} constructor, parameter ${i}`;
740
+ if (typeof t !== "function" || UNRESOLVABLE.has(t)) {
741
+ throw new DiError("unresolvable dependency", [
742
+ nameOf(cls)
743
+ ], at, `parameter ${i} has no runtime class \u2014 an interface, a type alias, a union, or a data type. The container has nothing to construct.`, DATA.has(t) ? [
744
+ "an injectable's constructor takes dependencies, not data",
745
+ "move the value to a method argument instead",
746
+ "or make this a plain value class (no @Injectable, in no module) and `new` it yourself"
747
+ ] : [
748
+ "depend on a concrete class or an abstract class",
749
+ "a TypeScript interface does not exist at runtime \u2014 there is nothing to inject"
750
+ ]);
751
+ }
752
+ const dep = t;
753
+ {
754
+ let dm = owner.get(dep);
755
+ if (dm === void 0) {
756
+ const impls = implementorsOf(dep);
757
+ if (impls.length === 1) {
758
+ const impl = impls[0];
759
+ list.push(impl);
760
+ dm = owner.get(impl);
761
+ if (dm !== m) {
762
+ if (!importsOf.get(m)?.has(dm)) {
763
+ throw new DiError("missing import", [
764
+ nameOf(cls),
765
+ nameOf(impl)
766
+ ], at, `${nameOf(impl)} implements ${nameOf(dep)} and is owned by ${dm}, which ${m} does not import.`, [
767
+ `add ${dm} to ${m}.imports`
768
+ ]);
769
+ }
770
+ if (!exported.get(dm)?.has(impl)) {
771
+ throw new DiError("private dependency", [
772
+ nameOf(cls),
773
+ nameOf(impl)
774
+ ], at, `${nameOf(impl)} implements ${nameOf(dep)} but is internal to ${dm}.`, [
775
+ `add ${nameOf(impl)} to ${dm}.exports (and say why)`
776
+ ]);
777
+ }
778
+ }
779
+ return;
780
+ }
781
+ if (impls.length > 1) {
782
+ const names = impls.map(nameOf).sort();
783
+ throw new DiError("duplicate ownership", [
784
+ nameOf(cls),
785
+ nameOf(dep)
786
+ ], at, `${names.join(" and ")} both extend ${nameOf(dep)}, so which one ${nameOf(cls)} should receive has two answers.`, [
787
+ `keep ONE class extending ${nameOf(dep)} in this graph`,
788
+ `or depend on ${names[0]} or ${names[1]} directly, by name`
789
+ ]);
790
+ }
791
+ throw new DiError("unowned class", [
792
+ nameOf(cls),
793
+ nameOf(dep)
794
+ ], at, `${nameOf(dep)} belongs to no module, and nothing in this graph extends it \u2014 so there is nothing to construct. (An abstract class cannot be built: \`abstract\` is a type-level claim, and \`new\` on one returns an object missing every abstract member.)`, [
795
+ `add ${nameOf(dep)} to a module's providers if it is concrete`,
796
+ `or add a class that \`extends ${nameOf(dep)}\` to a module's providers`
797
+ ]);
798
+ }
799
+ if (dm !== m) {
800
+ if (!importsOf.get(m)?.has(dm)) {
801
+ throw new DiError("missing import", [
802
+ nameOf(cls),
803
+ nameOf(dep)
804
+ ], at, `${nameOf(dep)} is owned by ${dm}, which ${m} does not import.`, [
805
+ `add ${dm} to ${m}.imports`
806
+ ]);
807
+ }
808
+ if (!exported.get(dm)?.has(dep)) {
809
+ throw new DiError("private dependency", [
810
+ nameOf(cls),
811
+ nameOf(dep)
812
+ ], at, `${nameOf(dep)} is internal to ${dm} \u2014 it is not exported.`, [
813
+ `use one of ${dm}'s exported classes`,
814
+ `or add ${nameOf(dep)} to ${dm}.exports (and say why it should be public)`
815
+ ]);
816
+ }
817
+ }
818
+ }
819
+ list.push(dep);
820
+ });
821
+ deps.set(cls, list);
822
+ }
823
+ const state = /* @__PURE__ */ new Map();
824
+ const stack = [];
825
+ const walk = /* @__PURE__ */ __name((c) => {
826
+ if (state.get(c) === 1) {
827
+ const cyc = [
828
+ ...stack.slice(stack.indexOf(c)),
829
+ c
830
+ ].map(nameOf);
831
+ throw new DiError("dependency cycle", cyc, `${cyc[0]} constructor`, `the dependency graph contains a cycle: ${cyc.join(" -> ")}.`, [
832
+ "extract the shared part into a third class both can depend on",
833
+ "or invert one direction \u2014 have the callee raise an event the caller listens for"
834
+ ]);
835
+ }
836
+ if (state.get(c) === 2) return;
837
+ state.set(c, 1);
838
+ stack.push(c);
839
+ for (const d of deps.get(c) ?? []) walk(d);
840
+ stack.pop();
841
+ state.set(c, 2);
842
+ }, "walk");
843
+ for (const c of owner.keys()) walk(c);
844
+ const cache = /* @__PURE__ */ new Map();
845
+ const make = /* @__PURE__ */ __name((c) => {
846
+ if (!owner.has(c)) {
847
+ throw new DiError("unowned class", [
848
+ nameOf(c)
849
+ ], "container.get", `${nameOf(c)} belongs to no module, so this container never validated it and will not build it.`, [
850
+ `add ${nameOf(c)} to a module's providers`,
851
+ "or, if it is a plain value class, construct it yourself with `new`"
852
+ ]);
853
+ }
854
+ const hit = cache.get(c);
855
+ if (hit !== void 0) return hit;
856
+ const args = (deps.get(c) ?? []).map(make);
857
+ const inst = new c(...args);
858
+ cache.set(c, inst);
859
+ return inst;
860
+ }, "make");
861
+ return {
862
+ get: /* @__PURE__ */ __name((t) => make(t), "get"),
863
+ owned: new Set(owner.keys()),
864
+ pressure: computePressure(entries)
865
+ };
866
+ }
867
+ __name(buildContainer, "buildContainer");
868
+ function computePressure(entries) {
869
+ const total = entries.length;
870
+ const count = /* @__PURE__ */ new Map();
871
+ for (const { def } of entries) {
872
+ for (const i of def.imports ?? []) {
873
+ const n = nameOf(i);
874
+ count.set(n, (count.get(n) ?? 0) + 1);
875
+ }
876
+ }
877
+ return [
878
+ ...count
879
+ ].map(([module, c]) => ({
880
+ module,
881
+ pct: Math.round(c / (total - 1) * 100),
882
+ of: total - 1
883
+ })).sort((a, b) => b.pct - a.pct);
884
+ }
885
+ __name(computePressure, "computePressure");
886
+ function assertNoOrphanEntryPoints(registered, owned2) {
887
+ const orphans = registered.filter((c) => !owned2.has(c));
888
+ if (orphans.length === 0) return;
889
+ const names = orphans.map((c) => c.name ?? "<anonymous>");
890
+ throw new DiError("unowned class", names, "module declarations", `${names.join(", ")} ${orphans.length === 1 ? "is" : "are"} decorated as an entry point but listed in no module, so nothing decides whether it should be served.`, [
891
+ "add it to a module's `controllers` (for @Controller) or `providers` (for @Room/@Job/@Hook/@Webhook)",
892
+ "an entry point no module lists is never mounted and never reaches the OpenAPI document"
893
+ ]);
894
+ }
895
+ __name(assertNoOrphanEntryPoints, "assertNoOrphanEntryPoints");
896
+
897
+ export {
898
+ __requestALS,
899
+ __setRuntime,
900
+ __runWithRuntime,
901
+ __getRuntime,
902
+ onStart,
903
+ onShutdown,
904
+ __runStartHooks,
905
+ __resetLifecycleHooks,
906
+ Database,
907
+ Documents,
908
+ Storage,
909
+ Cache,
910
+ Secrets,
911
+ Log,
912
+ Notifications,
913
+ Flags,
914
+ Realtime,
915
+ buildRelations,
916
+ makeEnvDts,
917
+ Injectable,
918
+ __claimInjectables,
919
+ jobsOf,
920
+ webhooksOf,
921
+ hooksOf,
922
+ roomsOf,
923
+ controllersOf,
924
+ Module,
925
+ __claimModules,
926
+ DiError,
927
+ buildContainer,
928
+ assertNoOrphanEntryPoints
929
+ };
930
+ //# sourceMappingURL=chunk-BQN723PL.js.map