@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
@@ -1,8 +1,16 @@
1
1
  import {
2
+ assertNoExpressionHandles,
2
3
  assertUsableFilter,
3
- assertUsableWriteValues
4
- } from "../chunk-XABBC7JP.js";
5
- import "../chunk-7D4SUZUM.js";
4
+ assertUsableWriteValues,
5
+ columnExprOf,
6
+ isColRef,
7
+ isColumnExpr,
8
+ isNowExpr,
9
+ isSqlFragment
10
+ } from "../chunk-JVZQCC77.js";
11
+ import {
12
+ __name
13
+ } from "../chunk-VXPNPVAG.js";
6
14
 
7
15
  // ../core/dist/index.js
8
16
  var CACHE_TTL_MS = 5 * 60 * 1e3;
@@ -17,8 +25,13 @@ function asPowChallenge(details) {
17
25
  const { id, prefix, difficulty } = c;
18
26
  if (typeof id !== "string" || typeof prefix !== "string") return null;
19
27
  if (typeof difficulty !== "number" || !Number.isInteger(difficulty) || difficulty < 0) return null;
20
- return { id, prefix, difficulty };
28
+ return {
29
+ id,
30
+ prefix,
31
+ difficulty
32
+ };
21
33
  }
34
+ __name(asPowChallenge, "asPowChallenge");
22
35
  var encoder = new TextEncoder();
23
36
  var hasher = null;
24
37
  async function digester() {
@@ -33,16 +46,17 @@ async function digester() {
33
46
  );
34
47
  if (typeof mod.createHash === "function") {
35
48
  const createHash = mod.createHash;
36
- hasher = (input) => new Uint8Array(createHash("sha256").update(input).digest());
49
+ hasher = /* @__PURE__ */ __name((input) => new Uint8Array(createHash("sha256").update(input).digest()), "hasher");
37
50
  return hasher;
38
51
  }
39
52
  } catch {
40
53
  }
41
54
  }
42
- hasher = async (input) => new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(input)));
55
+ hasher = /* @__PURE__ */ __name(async (input) => new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(input))), "hasher");
43
56
  return hasher;
44
57
  }
45
- var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
58
+ __name(digester, "digester");
59
+ var now = /* @__PURE__ */ __name(() => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now(), "now");
46
60
  function leadingZeroBits(hash) {
47
61
  let bits = 0;
48
62
  for (const byte of hash) {
@@ -54,18 +68,18 @@ function leadingZeroBits(hash) {
54
68
  }
55
69
  return bits;
56
70
  }
71
+ __name(leadingZeroBits, "leadingZeroBits");
57
72
  var MAX_POW_DIFFICULTY = 24;
58
73
  function powBudget(difficulty) {
59
74
  return 8 * 2 ** difficulty;
60
75
  }
76
+ __name(powBudget, "powBudget");
61
77
  var POW_TIME_BUDGET_MS = 12e4;
62
78
  var CALIBRATION_WARMUP = 1024;
63
79
  var CALIBRATION_END = 9216;
64
80
  async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.difficulty), signal) {
65
81
  if (challenge.difficulty > MAX_POW_DIFFICULTY) {
66
- throw new Error(
67
- `proof-of-work: refusing difficulty ${challenge.difficulty}; this client attempts at most ${MAX_POW_DIFFICULTY}, which is the highest a Palbase stack issues`
68
- );
82
+ throw new Error(`proof-of-work: refusing difficulty ${challenge.difficulty}; this client attempts at most ${MAX_POW_DIFFICULTY}, which is the highest a Palbase stack issues`);
69
83
  }
70
84
  const digest = await digester();
71
85
  let warmedAt = 0;
@@ -77,9 +91,7 @@ async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.
77
91
  throw new DOMException("proof-of-work solve aborted", "AbortError");
78
92
  }
79
93
  if (now() > deadline) {
80
- throw new Error(
81
- `proof-of-work: gave up on difficulty ${challenge.difficulty} after ${POW_TIME_BUDGET_MS / 1e3}s and ${nonce.toLocaleString()} attempts \u2014 the tail this run drew is longer than the allowance`
82
- );
94
+ throw new Error(`proof-of-work: gave up on difficulty ${challenge.difficulty} after ${POW_TIME_BUDGET_MS / 1e3}s and ${nonce.toLocaleString()} attempts \u2014 the tail this run drew is longer than the allowance`);
83
95
  }
84
96
  }
85
97
  if (nonce === CALIBRATION_WARMUP) {
@@ -91,9 +103,7 @@ async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.
91
103
  const rate = (CALIBRATION_END - CALIBRATION_WARMUP) / (elapsed / 1e3);
92
104
  const expectedMs = 2 ** challenge.difficulty / rate * 1e3;
93
105
  if (expectedMs > POW_TIME_BUDGET_MS) {
94
- throw new Error(
95
- `proof-of-work: difficulty ${challenge.difficulty} needs about ${Math.round(expectedMs / 1e3)}s here (${Math.round(rate).toLocaleString()} digests/s) and this client allows ${POW_TIME_BUDGET_MS / 1e3}s; refusing before spending the time rather than after`
96
- );
106
+ throw new Error(`proof-of-work: difficulty ${challenge.difficulty} needs about ${Math.round(expectedMs / 1e3)}s here (${Math.round(rate).toLocaleString()} digests/s) and this client allows ${POW_TIME_BUDGET_MS / 1e3}s; refusing before spending the time rather than after`);
97
107
  }
98
108
  deadline = now() + (POW_TIME_BUDGET_MS - (now() - warmedAt));
99
109
  }
@@ -105,13 +115,15 @@ async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.
105
115
  };
106
116
  }
107
117
  }
108
- throw new Error(
109
- `proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`
110
- );
118
+ throw new Error(`proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`);
111
119
  }
120
+ __name(solvePowChallenge, "solvePowChallenge");
112
121
 
113
122
  // src/test/api.ts
114
123
  var TestApiError = class extends Error {
124
+ static {
125
+ __name(this, "TestApiError");
126
+ }
115
127
  status;
116
128
  error;
117
129
  /** Payload of an error your code threw — `new BadRequest({ fields })` arrives here. */
@@ -131,12 +143,11 @@ var TestApiError = class extends Error {
131
143
  };
132
144
  function required(value, envName) {
133
145
  if (!value) {
134
- throw new Error(
135
- `${envName} is not set \u2014 the test client has nowhere to send requests. This is set by the deploy that runs your tests; if you are running them by hand, set it yourself.`
136
- );
146
+ throw new Error(`${envName} is not set \u2014 the test client has nowhere to send requests. This is set by the deploy that runs your tests; if you are running them by hand, set it yourself.`);
137
147
  }
138
148
  return value;
139
149
  }
150
+ __name(required, "required");
140
151
  function isLocalTarget(baseUrl) {
141
152
  try {
142
153
  const { hostname } = new URL(baseUrl);
@@ -145,6 +156,7 @@ function isLocalTarget(baseUrl) {
145
156
  return false;
146
157
  }
147
158
  }
159
+ __name(isLocalTarget, "isLocalTarget");
148
160
  function secondsUntilExpiry(token) {
149
161
  const body = token.split(".")[1];
150
162
  if (!body) return null;
@@ -155,6 +167,7 @@ function secondsUntilExpiry(token) {
155
167
  return null;
156
168
  }
157
169
  }
170
+ __name(secondsUntilExpiry, "secondsUntilExpiry");
158
171
  function createTestApi(config) {
159
172
  const baseUrl = required(config.baseUrl, "PALBASE_TEST_BASE_URL").replace(/\/$/, "");
160
173
  const apiKey = required(config.apiKey, "PALBASE_TEST_API_KEY");
@@ -169,7 +182,9 @@ function createTestApi(config) {
169
182
  // Selects the release under test. Omit it and the gateway serves the LIVE
170
183
  // one, which would make the whole suite grade the wrong code. Absent only
171
184
  // against a local stack, which has a single version.
172
- ...candidateToken ? { "x-palbase-candidate": candidateToken } : {},
185
+ ...candidateToken ? {
186
+ "x-palbase-candidate": candidateToken
187
+ } : {},
173
188
  ...opts.headers
174
189
  };
175
190
  if (bearer) headers.authorization = `Bearer ${bearer}`;
@@ -182,7 +197,12 @@ function createTestApi(config) {
182
197
  });
183
198
  const text = await res.text();
184
199
  const parsed = text ? safeParse(text) : void 0;
185
- requests.push({ method, path, status: res.status, ms: Date.now() - startedAt });
200
+ requests.push({
201
+ method,
202
+ path,
203
+ status: res.status,
204
+ ms: Date.now() - startedAt
205
+ });
186
206
  if (!res.ok) {
187
207
  if (res.status === 401 && bearer) {
188
208
  const left = secondsUntilExpiry(bearer);
@@ -197,41 +217,39 @@ function createTestApi(config) {
197
217
  }
198
218
  return parsed;
199
219
  }
220
+ __name(call, "call");
200
221
  return {
201
222
  requests,
202
- get: (path, opts) => call("GET", path, void 0, opts),
203
- post: (path, body, opts) => call("POST", path, body, opts),
204
- patch: (path, body, opts) => call("PATCH", path, body, opts),
205
- put: (path, body, opts) => call("PUT", path, body, opts),
206
- delete: (path, opts) => call("DELETE", path, void 0, opts),
207
- query: (path, body, opts) => call("QUERY", path, body, opts),
223
+ get: /* @__PURE__ */ __name((path, opts) => call("GET", path, void 0, opts), "get"),
224
+ post: /* @__PURE__ */ __name((path, body, opts) => call("POST", path, body, opts), "post"),
225
+ patch: /* @__PURE__ */ __name((path, body, opts) => call("PATCH", path, body, opts), "patch"),
226
+ put: /* @__PURE__ */ __name((path, body, opts) => call("PUT", path, body, opts), "put"),
227
+ delete: /* @__PURE__ */ __name((path, opts) => call("DELETE", path, void 0, opts), "delete"),
228
+ query: /* @__PURE__ */ __name((path, body, opts) => call("QUERY", path, body, opts), "query"),
208
229
  async signInAs(name) {
209
230
  const identity = (config.identities ?? {})[name];
210
231
  if (!identity) {
211
232
  const declared = Object.keys(config.identities ?? {});
212
- throw new Error(
213
- `no test identity named ${JSON.stringify(name)} \u2014 the deploy mints one per user declared in config/test-users.ts` + (declared.length ? `; this run has: ${declared.join(", ")}` : (
214
- // Not "you declared none": from here the two causes are
215
- // indistinguishable, and blaming the customer's config for a
216
- // platform failure sends them to look in the wrong file. The
217
- // deploy log names which one it was.
218
- ", and this run has none \u2014 either your config declares no users or the deploy could not mint them; the deploy log says which"
219
- ))
220
- );
233
+ throw new Error(`no test identity named ${JSON.stringify(name)} \u2014 the deploy mints one per user declared in config/test-users.ts` + (declared.length ? `; this run has: ${declared.join(", ")}` : (
234
+ // indistinguishable, and blaming the customer's config for a
235
+ // platform failure sends them to look in the wrong file. The
236
+ // deploy log names which one it was.
237
+ ", and this run has none \u2014 either your config declares no users or the deploy could not mint them; the deploy log says which"
238
+ )));
221
239
  }
222
240
  if (identity.accessToken) {
223
241
  bearer = identity.accessToken;
224
- return { id: identity.id ?? "", email: identity.email };
242
+ return {
243
+ id: identity.id ?? "",
244
+ email: identity.email
245
+ };
225
246
  }
226
247
  return this.signIn(identity);
227
248
  },
228
249
  async signIn(credentials) {
229
- const attempt = async (extra) => call(
230
- "POST",
231
- "/auth/login",
232
- credentials,
233
- extra ? { headers: extra } : {}
234
- );
250
+ const attempt = /* @__PURE__ */ __name(async (extra) => call("POST", "/auth/login", credentials, extra ? {
251
+ headers: extra
252
+ } : {}), "attempt");
235
253
  let result;
236
254
  try {
237
255
  result = await attempt();
@@ -242,7 +260,9 @@ function createTestApi(config) {
242
260
  result = await attempt(await solvePowChallenge(challenge));
243
261
  }
244
262
  bearer = result.access_token;
245
- return result.user ?? { id: "" };
263
+ return result.user ?? {
264
+ id: ""
265
+ };
246
266
  },
247
267
  async signOut() {
248
268
  await call("POST", "/auth/logout", void 0);
@@ -253,6 +273,7 @@ function createTestApi(config) {
253
273
  }
254
274
  };
255
275
  }
276
+ __name(createTestApi, "createTestApi");
256
277
  function parseIdentities(raw) {
257
278
  if (!raw) return {};
258
279
  try {
@@ -261,6 +282,7 @@ function parseIdentities(raw) {
261
282
  return {};
262
283
  }
263
284
  }
285
+ __name(parseIdentities, "parseIdentities");
264
286
  function safeParse(text) {
265
287
  try {
266
288
  return JSON.parse(text);
@@ -268,6 +290,7 @@ function safeParse(text) {
268
290
  return text;
269
291
  }
270
292
  }
293
+ __name(safeParse, "safeParse");
271
294
  var configured = null;
272
295
  var api = new Proxy({}, {
273
296
  get(_target, prop) {
@@ -281,7 +304,184 @@ var api = new Proxy({}, {
281
304
  }
282
305
  });
283
306
 
307
+ // src/test/container.ts
308
+ import "reflect-metadata";
309
+ function isolated() {
310
+ const over = /* @__PURE__ */ new Map();
311
+ const local = /* @__PURE__ */ new Map();
312
+ const make = /* @__PURE__ */ __name((c) => {
313
+ if (over.has(c)) return over.get(c);
314
+ const hit = local.get(c);
315
+ if (hit !== void 0) return hit;
316
+ const meta = Reflect.getMetadata("design:paramtypes", c) ?? [];
317
+ const inst = new c(...meta.map((d) => make(d)));
318
+ local.set(c, inst);
319
+ return inst;
320
+ }, "make");
321
+ const api2 = {
322
+ with(t, v) {
323
+ over.set(t, v);
324
+ return api2;
325
+ },
326
+ get(t) {
327
+ return make(t);
328
+ }
329
+ };
330
+ return api2;
331
+ }
332
+ __name(isolated, "isolated");
333
+
284
334
  // src/__tests__/helpers/mock-db.ts
335
+ function refuseFragment(caller, table, where) {
336
+ if (isSqlFragment(where)) {
337
+ throw new Error(`${caller}(${table}): fakeDatabase bir sqlFragment'i de\u011Ferlendiremez \u2014 sahte depo SQL \xE7al\u0131\u015Ft\u0131rmaz. Filtreyi tipli filtre diliyle kurun (gt/gte/lt/lte/neq/in/contains/isNull, OR/AND/NOT), ya da bu testi ger\xE7ek bir Postgres'e kar\u015F\u0131 yaz\u0131n.`);
338
+ }
339
+ if (where === null || typeof where !== "object") return;
340
+ for (const [k, v] of Object.entries(where)) {
341
+ if (k === "OR" || k === "AND") {
342
+ for (const branch of Array.isArray(v) ? v : []) refuseFragment(caller, table, branch);
343
+ } else if (k === "NOT") {
344
+ refuseFragment(caller, table, v);
345
+ }
346
+ }
347
+ }
348
+ __name(refuseFragment, "refuseFragment");
349
+ function addDecimal(cell, by, sign) {
350
+ if (cell === null || cell === void 0) return null;
351
+ if (typeof cell === "number" && typeof by === "number") return cell + sign * by;
352
+ const a = String(cell);
353
+ const b = String(by);
354
+ const parse = /* @__PURE__ */ __name((x) => {
355
+ const m = /^([+-]?)(\d*)(?:\.(\d*))?$/.exec(x.trim());
356
+ if (m === null || m[2] === "" && (m[3] ?? "") === "") return null;
357
+ const frac = m[3] ?? "";
358
+ const unit = BigInt(`${m[1] === "-" ? "-" : ""}${m[2] === "" ? "0" : m[2]}${frac}`);
359
+ return {
360
+ unit,
361
+ scale: frac.length
362
+ };
363
+ }, "parse");
364
+ const pa = parse(a);
365
+ const pb = parse(b);
366
+ if (pa === null || pb === null) {
367
+ throw new Error(`fakeDatabase: increment()/decrement() say\u0131sal olmayan bir de\u011Fere uyguland\u0131 ("${a}") \u2014 Postgres bunu "operator does not exist" ile reddeder.`);
368
+ }
369
+ const scale = Math.max(pa.scale, pb.scale);
370
+ const lift = /* @__PURE__ */ __name((v) => v.unit * 10n ** BigInt(scale - v.scale), "lift");
371
+ const total = lift(pa) + BigInt(sign) * lift(pb);
372
+ if (scale === 0) return typeof cell === "number" ? Number(total) : total.toString();
373
+ const neg = total < 0n;
374
+ const digits = (neg ? -total : total).toString().padStart(scale + 1, "0");
375
+ const out = `${neg ? "-" : ""}${digits.slice(0, -scale)}.${digits.slice(-scale)}`;
376
+ return typeof cell === "number" ? Number(out) : out;
377
+ }
378
+ __name(addDecimal, "addDecimal");
379
+ function rowMatchesFilter(caller, table, row, f) {
380
+ return Object.entries(f).every(([k, c]) => {
381
+ if (k === "OR") return c.some((b) => rowMatchesFilter(caller, table, row, b));
382
+ if (k === "AND") return c.every((b) => rowMatchesFilter(caller, table, row, b));
383
+ if (k === "NOT") return !rowMatchesFilter(caller, table, row, c);
384
+ if (k === "has") {
385
+ throw new Error(`${caller}(${table}): fakeDatabase bir \`has\` filtresini \xE7\xF6zemez \u2014 ili\u015Fki grafi\u011Fi bildirimden t\xFCretiliyor ve sahte deponun bildirimi yok. Bu testi ger\xE7ek bir Postgres'e kar\u015F\u0131 yaz\u0131n, ya da ili\u015Fkiyi filtrede A\xC7IK\xC7A kurun (\xF6nce ili\u015Fki tablosunu okuyup { id: { in: [...] } } ile s\xFCz\xFCn).`);
386
+ }
387
+ return matchesCell(caller, table, row, k, c);
388
+ });
389
+ }
390
+ __name(rowMatchesFilter, "rowMatchesFilter");
391
+ function cmp(a, b, op) {
392
+ if (a === null || a === void 0 || b === null || b === void 0) return false;
393
+ const l = a instanceof Date ? a.getTime() : a;
394
+ const r = b instanceof Date ? b.getTime() : b;
395
+ switch (op) {
396
+ case "eq":
397
+ return l === r;
398
+ case "neq":
399
+ return l !== r;
400
+ case "gt":
401
+ return l > r;
402
+ case "gte":
403
+ return l >= r;
404
+ case "lt":
405
+ return l < r;
406
+ case "lte":
407
+ return l <= r;
408
+ default:
409
+ return false;
410
+ }
411
+ }
412
+ __name(cmp, "cmp");
413
+ function matchesCell(caller, table, row, key, cond) {
414
+ if (isColRef(cond)) return cmp(row[key], row[cond.$col], "eq");
415
+ if (isNowExpr(cond)) return cmp(row[key], (/* @__PURE__ */ new Date()).toISOString(), "eq");
416
+ if (cond !== null && typeof cond === "object" && !Array.isArray(cond)) {
417
+ return Object.entries(cond).every(([op, v]) => {
418
+ const cell = row[key];
419
+ if (isNowExpr(v)) {
420
+ if (![
421
+ "neq",
422
+ "gt",
423
+ "gte",
424
+ "lt",
425
+ "lte"
426
+ ].includes(op)) {
427
+ throw new Error(`${caller}(${table}): where.${key}.${op} now() ile kullan\u0131lamaz`);
428
+ }
429
+ return cmp(cell, (/* @__PURE__ */ new Date()).toISOString(), op);
430
+ }
431
+ if (isColumnExpr(v)) {
432
+ throw new Error(`${caller}(${table}): where.${key}.${op} bir YAZMA ifadesi ald\u0131 (increment/decrement) \u2014 kar\u015F\u0131la\u015Ft\u0131rma de\u011Feri de\u011Fil. Sunucu saati i\xE7in now() kullan\u0131n.`);
433
+ }
434
+ if (isColRef(v)) {
435
+ if (![
436
+ "neq",
437
+ "gt",
438
+ "gte",
439
+ "lt",
440
+ "lte"
441
+ ].includes(op)) {
442
+ throw new Error(`${caller}(${table}): where.${key}.${op} col() ile kullan\u0131lamaz`);
443
+ }
444
+ return cmp(cell, row[v.$col], op);
445
+ }
446
+ switch (op) {
447
+ case "in":
448
+ if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${key}.in bir dizi olmal\u0131`);
449
+ if (v.some(isColRef)) {
450
+ throw new Error(`${caller}(${table}): where.${key}.in col() ile kullan\u0131lamaz \u2014 kolon kar\u015F\u0131la\u015Ft\u0131rmas\u0131 i\xE7in gt/gte/lt/lte/neq kullan\u0131n`);
451
+ }
452
+ return v.includes(cell);
453
+ case "neq":
454
+ case "gt":
455
+ case "gte":
456
+ case "lt":
457
+ case "lte":
458
+ return cmp(cell, v, op);
459
+ // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bunlar BURADA
460
+ // da olmak zorunda: guard onları KABUL ettiği anda fake sessizce yanlış
461
+ // cevap verir ve yazarın testi, üretimde farklı davranan koda karşı
462
+ // yeşil verirdi (input-guards.ts'in uyardığı tam sınıf).
463
+ case "isNull":
464
+ if (typeof v !== "boolean") throw new Error(`${caller}(${table}): where.${key}.isNull bir boolean olmal\u0131`);
465
+ return v ? cell == null : cell != null;
466
+ case "contains":
467
+ case "icontains":
468
+ case "startsWith":
469
+ case "endsWith": {
470
+ if (typeof v !== "string") throw new Error(`${caller}(${table}): where.${key}.${op} bir string olmal\u0131`);
471
+ if (typeof cell !== "string") return false;
472
+ if (op === "contains") return cell.includes(v);
473
+ if (op === "icontains") return cell.toLowerCase().includes(v.toLowerCase());
474
+ if (op === "startsWith") return cell.startsWith(v);
475
+ return cell.endsWith(v);
476
+ }
477
+ default:
478
+ throw new Error(`${caller}(${table}): where.${key} bilinmeyen operat\xF6r "${op}"`);
479
+ }
480
+ });
481
+ }
482
+ return row[key] === cond;
483
+ }
484
+ __name(matchesCell, "matchesCell");
285
485
  function createMockDB() {
286
486
  const store = /* @__PURE__ */ new Map();
287
487
  const tracked = {
@@ -297,11 +497,15 @@ function createMockDB() {
297
497
  }
298
498
  return rows;
299
499
  }
500
+ __name(rowsOf, "rowsOf");
300
501
  function track(map, table, row) {
301
502
  const list = map.get(table);
302
503
  if (list) list.push(row);
303
- else map.set(table, [row]);
504
+ else map.set(table, [
505
+ row
506
+ ]);
304
507
  }
508
+ __name(track, "track");
305
509
  const ops = {
306
510
  // The bulk ops and count run against the SAME in-memory store the direct
307
511
  // ops write to, so a test that writes three rows and counts them gets 3 —
@@ -310,26 +514,38 @@ function createMockDB() {
310
514
  async updateMany(table, where, set) {
311
515
  if (Object.keys(where).length === 0) throw new Error(`updateMany(${table}): bo\u015F filtre`);
312
516
  assertUsableFilter("updateMany", table, where);
517
+ refuseFragment("updateMany", table, where);
313
518
  assertUsableWriteValues("updateMany", table, Object.keys(set), set);
314
- const hit = (store.get(table) ?? []).filter(
315
- (r) => Object.entries(where).every(([k, v]) => r[k] === v)
316
- );
317
- for (const row of hit) Object.assign(row, set);
519
+ const hit = (store.get(table) ?? []).filter((r) => rowMatchesFilter("updateMany", table, r, where));
520
+ for (const row of hit) {
521
+ for (const [k, v] of Object.entries(set)) {
522
+ const expr = columnExprOf(v);
523
+ if (expr !== null && expr.fn === "now") {
524
+ row[k] = /* @__PURE__ */ new Date();
525
+ continue;
526
+ }
527
+ if (expr !== null) {
528
+ row[k] = addDecimal(row[k], expr.by, expr.fn === "inc" ? 1 : -1);
529
+ continue;
530
+ }
531
+ row[k] = v;
532
+ }
533
+ }
318
534
  return hit;
319
535
  },
320
536
  async deleteMany(table, where) {
321
537
  if (Object.keys(where).length === 0) throw new Error(`deleteMany(${table}): bo\u015F filtre`);
322
538
  assertUsableFilter("deleteMany", table, where);
539
+ refuseFragment("deleteMany", table, where);
323
540
  const list = store.get(table) ?? [];
324
- const keep = list.filter((r) => !Object.entries(where).every(([k, v]) => r[k] === v));
541
+ const keep = list.filter((r) => !rowMatchesFilter("deleteMany", table, r, where));
325
542
  store.set(table, keep);
326
543
  return list.length - keep.length;
327
544
  },
328
545
  async count(table, where = {}) {
329
546
  assertUsableFilter("count", table, where);
330
- return (store.get(table) ?? []).filter(
331
- (r) => Object.entries(where).every(([k, v]) => r[k] === v)
332
- ).length;
547
+ refuseFragment("count", table, where);
548
+ return (store.get(table) ?? []).filter((r) => rowMatchesFilter("count", table, r, where)).length;
333
549
  },
334
550
  async search(_table, _params) {
335
551
  return [];
@@ -344,25 +560,90 @@ function createMockDB() {
344
560
  return [];
345
561
  },
346
562
  async supersede(_table, _id, row) {
347
- return { id: crypto.randomUUID(), ...row };
563
+ return {
564
+ id: crypto.randomUUID(),
565
+ ...row
566
+ };
348
567
  },
349
568
  async query(_sql, _params) {
350
569
  return [];
351
570
  },
352
571
  async insert(table, data) {
353
572
  assertUsableWriteValues("insert", table, Object.keys(data), data);
354
- const record = { id: crypto.randomUUID(), ...data };
573
+ assertNoExpressionHandles("insert", table, Object.keys(data), data);
574
+ const record = {
575
+ id: crypto.randomUUID(),
576
+ ...data
577
+ };
355
578
  rowsOf(table).push(record);
356
579
  track(tracked.inserted, table, record);
357
580
  return record;
358
581
  },
582
+ /**
583
+ * `claim` — motorla PARİTE (FR-033).
584
+ *
585
+ * Fake bunu sunmasaydı `claim` ile yazılmış bir servis, iskelenin yazarlara
586
+ * önerdiği test yolunda `undefined is not a function` verirdi; sunup da
587
+ * FARKLI davransaydı (ör. hep `inserted: true`) idempotency testi üretimde
588
+ * çalışmayan koda karşı yeşil olurdu.
589
+ *
590
+ * Anahtar ZATEN VARSA var olan satır dönüyor ve hiçbir şey yazılmıyor —
591
+ * motorun 23505 dalının aynısı.
592
+ */
593
+ /**
594
+ * `lockRows` — sahte depoda kilit YOKTUR, ama çağrı da patlamamalı.
595
+ *
596
+ * Motorla parite burada "aynı SQL" değil, "aynı SÖZLEŞME": boş liste
597
+ * no-op, tekrar edenler tekilleşir, ve PK'sı olmayan tablo adıyla
598
+ * reddedilir. Kilidin kendisi tek işlemli bir sahte depoda anlamsız —
599
+ * ama sözleşmeyi bozan bir çağrı burada da hata almalı.
600
+ */
601
+ async lockRows(table, ids) {
602
+ if (ids.length === 0) return;
603
+ const rows = store.get(table) ?? [];
604
+ const unique = [
605
+ ...new Set(ids)
606
+ ].sort();
607
+ const missing = unique.filter((id) => !rows.some((r) => r["id"] === id));
608
+ if (missing.length > 0 && rows.length > 0) {
609
+ throw new Error(`lockRows(${table}): \u015Fu id'ler yok: ${missing.join(", ")} \u2014 kilitlenecek sat\u0131r bulunamad\u0131.`);
610
+ }
611
+ },
612
+ /** Sahte depoda kilit yok; sözleşme (çağrı patlamaz) korunuyor. */
613
+ async advisoryXactLock(_key) {
614
+ return void 0;
615
+ },
616
+ async claim(table, unique, extra = {}) {
617
+ const keyCols = Object.keys(unique);
618
+ if (keyCols.length === 0) {
619
+ throw new Error(`claim(${table}): benzersiz alan verilmedi. claim, bir anahtar\u0131 sahiplenmektir; anahtar yoksa sahiplenecek bir \u015Fey de yok \u2014 insert(${table}, \u2026) kullan\u0131n.`);
620
+ }
621
+ assertUsableWriteValues("claim", table, keyCols, unique);
622
+ const existing = (store.get(table) ?? []).find((r) => keyCols.every((c) => r[c] === unique[c]));
623
+ if (existing) return {
624
+ inserted: false,
625
+ row: existing
626
+ };
627
+ const record = {
628
+ id: crypto.randomUUID(),
629
+ ...unique,
630
+ ...extra
631
+ };
632
+ rowsOf(table).push(record);
633
+ track(tracked.inserted, table, record);
634
+ return {
635
+ inserted: true,
636
+ row: record
637
+ };
638
+ },
359
639
  // Same semantics the engine's SQL has: match on the conflict columns, update
360
640
  // everything else, and return the resulting row either way.
361
- async upsert(table, data, opts) {
641
+ async put(table, data, opts) {
362
642
  if (opts.onConflict.length === 0) {
363
- throw new Error(`upsert into ${table}: onConflict en az bir kolon ad\u0131 ister`);
643
+ throw new Error(`put into ${table}: onConflict en az bir kolon ad\u0131 ister`);
364
644
  }
365
645
  assertUsableWriteValues("upsert", table, Object.keys(data), data);
646
+ assertNoExpressionHandles("upsert", table, Object.keys(data), data);
366
647
  const rows = rowsOf(table);
367
648
  const existing = rows.find((r) => opts.onConflict.every((c) => r[c] === data[c]));
368
649
  if (existing) {
@@ -371,16 +652,26 @@ function createMockDB() {
371
652
  }
372
653
  return existing;
373
654
  }
374
- const record = { id: crypto.randomUUID(), ...data };
655
+ const record = {
656
+ id: crypto.randomUUID(),
657
+ ...data
658
+ };
375
659
  rows.push(record);
376
660
  track(tracked.inserted, table, record);
377
661
  return record;
378
662
  },
379
663
  async update(table, id, data) {
380
664
  assertUsableWriteValues("update", table, Object.keys(data), data);
665
+ assertNoExpressionHandles("update", table, Object.keys(data), data);
381
666
  const rows = store.get(table) ?? [];
382
667
  const idx = rows.findIndex((r) => r["id"] === id);
383
- const updated = idx >= 0 ? { ...rows[idx], ...data } : { id, ...data };
668
+ const updated = idx >= 0 ? {
669
+ ...rows[idx],
670
+ ...data
671
+ } : {
672
+ id,
673
+ ...data
674
+ };
384
675
  if (idx >= 0) {
385
676
  rows[idx] = updated;
386
677
  }
@@ -393,7 +684,9 @@ function createMockDB() {
393
684
  if (idx >= 0) rows.splice(idx, 1);
394
685
  const list = tracked.deleted.get(table);
395
686
  if (list) list.push(id);
396
- else tracked.deleted.set(table, [id]);
687
+ else tracked.deleted.set(table, [
688
+ id
689
+ ]);
397
690
  },
398
691
  async findById(table, id) {
399
692
  const rows = store.get(table) ?? [];
@@ -405,51 +698,60 @@ function createMockDB() {
405
698
  // thing a stand-in must never do.
406
699
  async findMany(table, query, opts) {
407
700
  assertUsableFilter("findMany", table, query);
701
+ refuseFragment("findMany", table, query);
408
702
  const rows = store.get(table) ?? [];
409
- const matches2 = (row, key, cond) => {
410
- if (cond !== null && typeof cond === "object" && !Array.isArray(cond)) {
411
- return Object.entries(cond).every(([op, v]) => {
412
- const cell = row[key];
413
- switch (op) {
414
- case "in":
415
- return Array.isArray(v) && v.includes(cell);
416
- case "neq":
417
- return cell !== v;
418
- case "gt":
419
- return cell > v;
420
- case "gte":
421
- return cell >= v;
422
- case "lt":
423
- return cell < v;
424
- case "lte":
425
- return cell <= v;
426
- default:
427
- throw new Error(`findMany(${table}): where.${key} bilinmeyen operat\xF6r "${op}"`);
703
+ let out = query ? rows.filter((row) => rowMatchesFilter("findMany", table, row, query)) : [
704
+ ...rows
705
+ ];
706
+ const orderSpecs = opts?.orderBy === void 0 ? [] : Array.isArray(opts.orderBy) ? opts.orderBy : [
707
+ opts.orderBy
708
+ ];
709
+ if (orderSpecs.length > 0) {
710
+ out = [
711
+ ...out
712
+ ].sort((a, b) => {
713
+ for (const o of orderSpecs) {
714
+ const dir = o.direction === "desc" ? -1 : 1;
715
+ const x = a[o.column];
716
+ const y = b[o.column];
717
+ const xNull = x === null || x === void 0;
718
+ const yNull = y === null || y === void 0;
719
+ if (xNull || yNull) {
720
+ if (xNull && yNull) continue;
721
+ const nullsFirst = o.nulls === void 0 ? dir === -1 : o.nulls === "first";
722
+ return (xNull ? 1 : -1) * (nullsFirst ? -1 : 1);
428
723
  }
429
- });
430
- }
431
- return row[key] === cond;
432
- };
433
- let out = query ? rows.filter((row) => Object.entries(query).every(([k, c]) => matches2(row, k, c))) : [...rows];
434
- const order = opts?.orderBy;
435
- if (order) {
436
- const dir = order.direction === "desc" ? -1 : 1;
437
- out = [...out].sort((a, b) => {
438
- const x = a[order.column];
439
- const y = b[order.column];
440
- return x === y ? 0 : (x < y ? -1 : 1) * dir;
724
+ if (x === y) continue;
725
+ return (x < y ? -1 : 1) * dir;
726
+ }
727
+ return 0;
441
728
  });
442
729
  }
443
- return opts?.limit === void 0 ? out : out.slice(0, opts.limit);
730
+ const page = opts?.limit === void 0 ? out : out.slice(0, opts.limit);
731
+ const cols = opts?.select;
732
+ if (cols === void 0 || cols.length === 0) return page;
733
+ return page.map((row) => Object.fromEntries(cols.map((c) => [
734
+ c,
735
+ row[c]
736
+ ])));
444
737
  }
445
738
  };
446
739
  async function txPlan(plan) {
447
740
  const snapshot = /* @__PURE__ */ new Map();
448
- for (const [table, rows] of store) snapshot.set(table, [...rows]);
741
+ for (const [table, rows] of store) snapshot.set(table, [
742
+ ...rows
743
+ ]);
449
744
  const trackedSnapshot = {
450
745
  inserted: cloneTracked(tracked.inserted),
451
746
  updated: cloneTracked(tracked.updated),
452
- deleted: new Map([...tracked.deleted].map(([k, v]) => [k, [...v]]))
747
+ deleted: new Map([
748
+ ...tracked.deleted
749
+ ].map(([k, v]) => [
750
+ k,
751
+ [
752
+ ...v
753
+ ]
754
+ ]))
453
755
  };
454
756
  const results = [];
455
757
  try {
@@ -467,8 +769,11 @@ function createMockDB() {
467
769
  tracked.deleted = trackedSnapshot.deleted;
468
770
  throw err;
469
771
  }
470
- return { results };
772
+ return {
773
+ results
774
+ };
471
775
  }
776
+ __name(txPlan, "txPlan");
472
777
  function applyOp(op, results) {
473
778
  switch (op.op) {
474
779
  case "upsert": {
@@ -480,27 +785,54 @@ function createMockDB() {
480
785
  for (const [key, value] of Object.entries(values)) {
481
786
  if (!conflict.includes(key)) hit[key] = value;
482
787
  }
483
- return { rows: [hit], rows_affected: 1 };
788
+ return {
789
+ rows: [
790
+ hit
791
+ ],
792
+ rows_affected: 1
793
+ };
484
794
  }
485
- const created = { id: crypto.randomUUID(), ...values };
795
+ const created = {
796
+ id: crypto.randomUUID(),
797
+ ...values
798
+ };
486
799
  rows.push(created);
487
800
  track(tracked.inserted, op.table, created);
488
- return { rows: [created], rows_affected: 1 };
801
+ return {
802
+ rows: [
803
+ created
804
+ ],
805
+ rows_affected: 1
806
+ };
489
807
  }
490
808
  case "insert": {
491
- const record = { id: crypto.randomUUID(), ...resolveMap(op.values ?? {}, results, null) };
809
+ const record = {
810
+ id: crypto.randomUUID(),
811
+ ...resolveMap(op.values ?? {}, results, null)
812
+ };
492
813
  rowsOf(op.table).push(record);
493
814
  track(tracked.inserted, op.table, record);
494
- return { rows: [record], rows_affected: 1 };
815
+ return {
816
+ rows: [
817
+ record
818
+ ],
819
+ rows_affected: 1
820
+ };
495
821
  }
496
822
  case "insertMany": {
497
823
  const written = (op.rows ?? []).map((row) => {
498
- const record = { id: crypto.randomUUID(), ...resolveMap(row, results, null) };
824
+ const record = {
825
+ id: crypto.randomUUID(),
826
+ ...resolveMap(row, results, null)
827
+ };
499
828
  rowsOf(op.table).push(record);
500
829
  track(tracked.inserted, op.table, record);
501
830
  return record;
502
831
  });
503
- return { rows: written, rows_affected: written.length };
832
+ return {
833
+ rows: written,
834
+ rows_affected: written.length
835
+ };
504
836
  }
505
837
  case "update": {
506
838
  const rows = rowsOf(op.table);
@@ -509,12 +841,18 @@ function createMockDB() {
509
841
  for (let i = 0; i < rows.length; i++) {
510
842
  const row = rows[i];
511
843
  if (!row || !matches(row, where)) continue;
512
- const next = { ...row, ...resolveMap(op.set ?? {}, results, row) };
844
+ const next = {
845
+ ...row,
846
+ ...resolveMap(op.set ?? {}, results, row)
847
+ };
513
848
  rows[i] = next;
514
849
  track(tracked.updated, op.table, next);
515
850
  written.push(next);
516
851
  }
517
- return { rows: written, rows_affected: written.length };
852
+ return {
853
+ rows: written,
854
+ rows_affected: written.length
855
+ };
518
856
  }
519
857
  case "delete": {
520
858
  const rows = rowsOf(op.table);
@@ -526,23 +864,32 @@ function createMockDB() {
526
864
  const list = tracked.deleted.get(op.table);
527
865
  const key = typeof id === "string" ? id : String(id);
528
866
  if (list) list.push(key);
529
- else tracked.deleted.set(op.table, [key]);
867
+ else tracked.deleted.set(op.table, [
868
+ key
869
+ ]);
530
870
  }
531
- return { rows: removed, rows_affected: removed.length };
871
+ return {
872
+ rows: removed,
873
+ rows_affected: removed.length
874
+ };
532
875
  }
533
876
  case "select": {
534
877
  const where = resolveMap(op.where ?? {}, results, null);
535
878
  let found = rowsOf(op.table).filter((row) => matches(row, where));
536
879
  if (op.limit !== void 0) found = found.slice(0, op.limit);
537
- return { rows: found, rows_affected: found.length };
880
+ return {
881
+ rows: found,
882
+ rows_affected: found.length
883
+ };
538
884
  }
539
885
  }
540
886
  }
887
+ __name(applyOp, "applyOp");
541
888
  const client = {
542
889
  ...ops,
543
890
  // No real savepoint in memory: the fake runs the callback against the SAME
544
891
  // store. An assertion about rollback here would be asserting the fake.
545
- attempt: (fn) => fn(ops),
892
+ attempt: /* @__PURE__ */ __name((fn) => fn(ops), "attempt"),
546
893
  txPlan,
547
894
  // In tests there is no real DB role; `asService()` returns the same
548
895
  // in-memory client so RLS-bypass code paths still hit the same store and
@@ -561,14 +908,25 @@ function createMockDB() {
561
908
  return tracked.deleted.get(table) ?? [];
562
909
  },
563
910
  seed(table, data) {
564
- store.set(table, [...data]);
911
+ store.set(table, [
912
+ ...data
913
+ ]);
565
914
  }
566
915
  };
567
916
  return client;
568
917
  }
918
+ __name(createMockDB, "createMockDB");
569
919
  function cloneTracked(map) {
570
- return new Map([...map].map(([k, v]) => [k, [...v]]));
920
+ return new Map([
921
+ ...map
922
+ ].map(([k, v]) => [
923
+ k,
924
+ [
925
+ ...v
926
+ ]
927
+ ]));
571
928
  }
929
+ __name(cloneTracked, "cloneTracked");
572
930
  function resolveValue(value, results, current, column) {
573
931
  if (typeof value !== "object" || value === null) return value;
574
932
  const tagged = value;
@@ -590,6 +948,7 @@ function resolveValue(value, results, current, column) {
590
948
  }
591
949
  return value;
592
950
  }
951
+ __name(resolveValue, "resolveValue");
593
952
  function resolveMap(map, results, current) {
594
953
  const out = {};
595
954
  for (const [key, value] of Object.entries(map)) {
@@ -597,11 +956,11 @@ function resolveMap(map, results, current) {
597
956
  }
598
957
  return out;
599
958
  }
959
+ __name(resolveMap, "resolveMap");
600
960
  function matches(row, where) {
601
- return Object.entries(where).every(
602
- ([key, value]) => value === null ? row[key] === null || row[key] === void 0 : row[key] === value
603
- );
961
+ return Object.entries(where).every(([key, value]) => value === null ? row[key] === null || row[key] === void 0 : row[key] === value);
604
962
  }
963
+ __name(matches, "matches");
605
964
  function guardFailure(guard, count) {
606
965
  if (!guard) return null;
607
966
  const ok = guard.kind === "one" ? count === 1 : guard.kind === "none" ? count === 0 : guard.kind === "atLeast" ? count >= guard.n : count <= guard.n;
@@ -611,6 +970,7 @@ function guardFailure(guard, count) {
611
970
  message: `expected ${guard.kind} ${guard.n} row(s), got ${count}`
612
971
  });
613
972
  }
973
+ __name(guardFailure, "guardFailure");
614
974
  function txRejection(status, code, extra) {
615
975
  const err = new Error(extra.message);
616
976
  err.status = status;
@@ -618,30 +978,36 @@ function txRejection(status, code, extra) {
618
978
  if (extra.slot !== void 0) err.slot = extra.slot;
619
979
  return err;
620
980
  }
981
+ __name(txRejection, "txRejection");
621
982
 
622
983
  // src/test/fake-db.ts
623
984
  function fakeDatabase() {
624
985
  const mock = createMockDB();
625
986
  const queries = [];
626
987
  const db = Object.assign(Object.create(Object.getPrototypeOf(mock)), mock, {
627
- query: async (sql, params = []) => {
628
- queries.push({ sql, params });
988
+ query: /* @__PURE__ */ __name(async (sql, params = []) => {
989
+ queries.push({
990
+ sql,
991
+ params
992
+ });
629
993
  return mock.query(sql, params);
630
- }
994
+ }, "query")
631
995
  });
632
996
  return {
633
997
  db,
634
998
  queries,
635
- seed: (table, rows) => mock.seed(table, rows),
636
- inserted: (table) => mock.inserted(table),
637
- updated: (table) => mock.updated(table),
638
- deleted: (table) => mock.deleted(table)
999
+ seed: /* @__PURE__ */ __name((table, rows) => mock.seed(table, rows), "seed"),
1000
+ inserted: /* @__PURE__ */ __name((table) => mock.inserted(table), "inserted"),
1001
+ updated: /* @__PURE__ */ __name((table) => mock.updated(table), "updated"),
1002
+ deleted: /* @__PURE__ */ __name((table) => mock.deleted(table), "deleted")
639
1003
  };
640
1004
  }
1005
+ __name(fakeDatabase, "fakeDatabase");
641
1006
  export {
642
1007
  TestApiError,
643
1008
  api,
644
1009
  createTestApi,
645
- fakeDatabase
1010
+ fakeDatabase,
1011
+ isolated
646
1012
  };
647
1013
  //# sourceMappingURL=index.js.map