@palbase/backend 27.1.0 → 28.0.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 (52) hide show
  1. package/dist/bin/palbase-backend.cjs +133 -38
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +4 -4
  4. package/dist/{chunk-JVZQCC77.js → chunk-3TUJWHC2.js} +8 -3
  5. package/dist/chunk-3TUJWHC2.js.map +1 -0
  6. package/dist/{chunk-EB3TUX5J.js → chunk-75YROPRZ.js} +102 -38
  7. package/dist/chunk-75YROPRZ.js.map +1 -0
  8. package/dist/{chunk-XABHGMUT.js → chunk-IVZERLTM.js} +2 -2
  9. package/dist/{chunk-BQN723PL.js → chunk-RVP6BTEZ.js} +63 -6
  10. package/dist/chunk-RVP6BTEZ.js.map +1 -0
  11. package/dist/{chunk-OZKSM3JW.js → chunk-SNDXY565.js} +3 -2
  12. package/dist/chunk-SNDXY565.js.map +1 -0
  13. package/dist/db/index.cjs +4 -1
  14. package/dist/db/index.cjs.map +1 -1
  15. package/dist/db/index.d.cts +1 -1
  16. package/dist/db/index.d.ts +1 -1
  17. package/dist/db/index.js +3 -3
  18. package/dist/engine/index.cjs +143 -38
  19. package/dist/engine/index.cjs.map +1 -1
  20. package/dist/engine/index.d.cts +3 -3
  21. package/dist/engine/index.d.ts +3 -3
  22. package/dist/engine/index.js +11 -4
  23. package/dist/{index-H-0qv5d4.d.cts → index-9C3JHxg-.d.cts} +112 -5
  24. package/dist/{index-CAKOgAlP.d.ts → index-BbvOoZFr.d.ts} +112 -5
  25. package/dist/{index-CgE4sVhg.d.cts → index-DtISj9QX.d.cts} +94 -11
  26. package/dist/{index-V7QRh1wg.d.ts → index-dTTLlHIn.d.ts} +94 -11
  27. package/dist/index.cjs +67 -4
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +6 -22
  30. package/dist/index.d.ts +6 -22
  31. package/dist/index.js +10 -4
  32. package/dist/index.js.map +1 -1
  33. package/dist/openapi/index.d.cts +2 -2
  34. package/dist/openapi/index.d.ts +2 -2
  35. package/dist/{registry-4EI8aaFs.d.ts → registry-JQNIX-eA.d.ts} +1 -1
  36. package/dist/{registry-DHsPDY0_.d.cts → registry-qIPM5BQe.d.cts} +1 -1
  37. package/dist/test/index.cjs +73 -6
  38. package/dist/test/index.cjs.map +1 -1
  39. package/dist/test/index.d.cts +1 -1
  40. package/dist/test/index.d.ts +1 -1
  41. package/dist/test/index.js +70 -6
  42. package/dist/test/index.js.map +1 -1
  43. package/docs/README.md +1 -1
  44. package/docs/database.md +69 -1
  45. package/docs/llms-full.txt +70 -2
  46. package/package.json +1 -1
  47. package/template/package.json +1 -1
  48. package/dist/chunk-BQN723PL.js.map +0 -1
  49. package/dist/chunk-EB3TUX5J.js.map +0 -1
  50. package/dist/chunk-JVZQCC77.js.map +0 -1
  51. package/dist/chunk-OZKSM3JW.js.map +0 -1
  52. /package/dist/{chunk-XABHGMUT.js.map → chunk-IVZERLTM.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- export { f as AnyColumn, k as ColumnBuilder, l as ColumnDef, m as ColumnMap, n as ColumnType, E as EXTENSION_DEPENDENCIES, s as EmbeddingModelRef, u as EnvServiceDatabase, w as EnvTypedDatabase, N as InsertShape, V as Materialized, a0 as OnDeleteAction, a1 as PALBASE_EXTENSIONS, aA as PalbaseExtension, bx as PolicyBuilder, by as PolicyCommand, bz as PolicyDef, bC as PolicyMode, bE as RawConstraintDef, bG as Ref, bI as RowShape, S as SchemaDef, bR as TABLE_META, bS as TableDef, bT as TableHandle, bU as TableInput, bW as TxColumnExpr, bX as TxInsertShape, bZ as TxNow, b_ as TxPlan, T as TxPlanBody, b$ as TxPlanError, c0 as TxPlanHandle, c1 as TxPlanOpResult, c2 as TxPlanRejection, b as TxPlanResponse, c3 as TxRefError, c4 as TxRow, c5 as TxRows, c6 as TxSelectOptions, c7 as TxSetShape, c9 as TxTable, ca as TxTables, cb as TxWhere, ch as TypedDB, ci as TypedTable, cj as TypedTx, cs as bigint, ct as boolean, cv as dec, cy as defineSchema, cz as defineTable, cA as enumType, cC as inc, cF as installationRef, cG as integer, cH as isPalbaseExtension, cJ as jsonb, cK as makeTypedDB, cL as now, cP as openai, cQ as ownedByUser, cR as policy, cS as raw, cU as text, cV as timestamp, cW as userRef, cX as uuid, cY as vector } from '../index-CgE4sVhg.cjs';
1
+ export { f as AnyColumn, k as ColumnBuilder, l as ColumnDef, m as ColumnMap, n as ColumnType, E as EXTENSION_DEPENDENCIES, s as EmbeddingModelRef, u as EnvServiceDatabase, w as EnvTypedDatabase, N as InsertShape, V as Materialized, a0 as OnDeleteAction, a1 as PALBASE_EXTENSIONS, aA as PalbaseExtension, bx as PolicyBuilder, by as PolicyCommand, bz as PolicyDef, bC as PolicyMode, bE as RawConstraintDef, bG as Ref, bI as RowShape, S as SchemaDef, bR as TABLE_META, bS as TableDef, bT as TableHandle, bU as TableInput, bW as TxColumnExpr, bX as TxInsertShape, bZ as TxNow, b_ as TxPlan, T as TxPlanBody, b$ as TxPlanError, c0 as TxPlanHandle, c1 as TxPlanOpResult, c2 as TxPlanRejection, b as TxPlanResponse, c3 as TxRefError, c4 as TxRow, c5 as TxRows, c6 as TxSelectOptions, c7 as TxSetShape, c9 as TxTable, ca as TxTables, cb as TxWhere, ch as TypedDB, ci as TypedTable, cj as TypedTx, cs as bigint, ct as boolean, cv as dec, cy as defineSchema, cz as defineTable, cA as enumType, cC as inc, cF as installationRef, cG as integer, cH as isPalbaseExtension, cJ as jsonb, cK as makeTypedDB, cL as now, cP as openai, cQ as ownedByUser, cR as policy, cS as raw, cU as text, cV as timestamp, cW as userRef, cX as uuid, cY as vector } from '../index-DtISj9QX.cjs';
2
2
  import './env.cjs';
3
3
  import '../stack.cjs';
4
4
  import 'zod';
@@ -1,4 +1,4 @@
1
- export { f as AnyColumn, k as ColumnBuilder, l as ColumnDef, m as ColumnMap, n as ColumnType, E as EXTENSION_DEPENDENCIES, s as EmbeddingModelRef, u as EnvServiceDatabase, w as EnvTypedDatabase, N as InsertShape, V as Materialized, a0 as OnDeleteAction, a1 as PALBASE_EXTENSIONS, aA as PalbaseExtension, bx as PolicyBuilder, by as PolicyCommand, bz as PolicyDef, bC as PolicyMode, bE as RawConstraintDef, bG as Ref, bI as RowShape, S as SchemaDef, bR as TABLE_META, bS as TableDef, bT as TableHandle, bU as TableInput, bW as TxColumnExpr, bX as TxInsertShape, bZ as TxNow, b_ as TxPlan, T as TxPlanBody, b$ as TxPlanError, c0 as TxPlanHandle, c1 as TxPlanOpResult, c2 as TxPlanRejection, b as TxPlanResponse, c3 as TxRefError, c4 as TxRow, c5 as TxRows, c6 as TxSelectOptions, c7 as TxSetShape, c9 as TxTable, ca as TxTables, cb as TxWhere, ch as TypedDB, ci as TypedTable, cj as TypedTx, cs as bigint, ct as boolean, cv as dec, cy as defineSchema, cz as defineTable, cA as enumType, cC as inc, cF as installationRef, cG as integer, cH as isPalbaseExtension, cJ as jsonb, cK as makeTypedDB, cL as now, cP as openai, cQ as ownedByUser, cR as policy, cS as raw, cU as text, cV as timestamp, cW as userRef, cX as uuid, cY as vector } from '../index-V7QRh1wg.js';
1
+ export { f as AnyColumn, k as ColumnBuilder, l as ColumnDef, m as ColumnMap, n as ColumnType, E as EXTENSION_DEPENDENCIES, s as EmbeddingModelRef, u as EnvServiceDatabase, w as EnvTypedDatabase, N as InsertShape, V as Materialized, a0 as OnDeleteAction, a1 as PALBASE_EXTENSIONS, aA as PalbaseExtension, bx as PolicyBuilder, by as PolicyCommand, bz as PolicyDef, bC as PolicyMode, bE as RawConstraintDef, bG as Ref, bI as RowShape, S as SchemaDef, bR as TABLE_META, bS as TableDef, bT as TableHandle, bU as TableInput, bW as TxColumnExpr, bX as TxInsertShape, bZ as TxNow, b_ as TxPlan, T as TxPlanBody, b$ as TxPlanError, c0 as TxPlanHandle, c1 as TxPlanOpResult, c2 as TxPlanRejection, b as TxPlanResponse, c3 as TxRefError, c4 as TxRow, c5 as TxRows, c6 as TxSelectOptions, c7 as TxSetShape, c9 as TxTable, ca as TxTables, cb as TxWhere, ch as TypedDB, ci as TypedTable, cj as TypedTx, cs as bigint, ct as boolean, cv as dec, cy as defineSchema, cz as defineTable, cA as enumType, cC as inc, cF as installationRef, cG as integer, cH as isPalbaseExtension, cJ as jsonb, cK as makeTypedDB, cL as now, cP as openai, cQ as ownedByUser, cR as policy, cS as raw, cU as text, cV as timestamp, cW as userRef, cX as uuid, cY as vector } from '../index-dTTLlHIn.js';
2
2
  import './env.js';
3
3
  import '../stack.js';
4
4
  import 'zod';
package/dist/db/index.js CHANGED
@@ -21,17 +21,17 @@ import {
21
21
  userRef,
22
22
  uuid,
23
23
  vector
24
- } from "../chunk-XABHGMUT.js";
24
+ } from "../chunk-IVZERLTM.js";
25
25
  import {
26
26
  makeTypedDB
27
- } from "../chunk-OZKSM3JW.js";
27
+ } from "../chunk-SNDXY565.js";
28
28
  import {
29
29
  TxPlanError,
30
30
  TxRefError,
31
31
  dec,
32
32
  inc,
33
33
  now
34
- } from "../chunk-JVZQCC77.js";
34
+ } from "../chunk-3TUJWHC2.js";
35
35
  import "../chunk-CGNN2PUH.js";
36
36
  import "../chunk-VXPNPVAG.js";
37
37
  export {
@@ -23,6 +23,8 @@ var engine_exports = {};
23
23
  __export(engine_exports, {
24
24
  AuthVerifier: () => AuthVerifier,
25
25
  BootRefused: () => BootRefused,
26
+ DECLARATION_REFUSAL: () => DECLARATION_REFUSAL,
27
+ DeclarationRefused: () => DeclarationRefused,
26
28
  RateLimiter: () => RateLimiter,
27
29
  buildRouteTable: () => buildRouteTable,
28
30
  createApp: () => createApp,
@@ -32,6 +34,7 @@ __export(engine_exports, {
32
34
  effectiveAuth: () => effectiveAuth,
33
35
  hostAllowed: () => hostAllowed,
34
36
  installEgressFence: () => installEgressFence,
37
+ isDeclarationRefused: () => isDeclarationRefused,
35
38
  loadConfig: () => loadConfig,
36
39
  makeMemoryCache: () => makeMemoryCache,
37
40
  matchRoute: () => matchRoute,
@@ -116,8 +119,11 @@ __name(isColumnExpr, "isColumnExpr");
116
119
  function assertNoExpressionHandles(caller, table, cols, data) {
117
120
  for (const c of cols) {
118
121
  const v = data[c];
122
+ if (isNowExpr(v)) {
123
+ throw new Error(`${caller}(${table}): "${c}" now() ald\u0131 \u2014 bu yolda de\u011Fer beklenir. Sat\u0131r EKLEN\u0130RKEN sunucu saatini yazman\u0131n yolu kolonu defaultNow() ile bildirmek (varsay\u0131lan kolonun yan\u0131nda durur, her \xE7a\u011Fr\u0131da tekrarlanmaz); var olan bir sat\u0131r\u0131 damgalamak i\xE7in updateMany({ where, set: { ${c}: now() } }) ya da $transaction i\xE7inde tx.public.${table}.updateWhere(where, { ${c}: now() }).`);
124
+ }
119
125
  if (isColumnExpr(v)) {
120
- throw new Error(`${caller}(${table}): "${c}" bir ifade tutama\u011F\u0131 ald\u0131 (increment()/decrement()/now()). Bu yolda de\u011Fer beklenir. Saya\xE7 art\u0131\u015F\u0131 i\xE7in updateMany(where, { ${c}: increment(n) }) ya da $transaction i\xE7inde tx.tables.${table}.updateWhere(where, { ${c}: increment(n) }) kullan\u0131n.`);
126
+ throw new Error(`${caller}(${table}): "${c}" bir ifade tutama\u011F\u0131 ald\u0131 (increment()/decrement()). Bu yolda de\u011Fer beklenir. Saya\xE7 art\u0131\u015F\u0131 i\xE7in updateMany({ where, set: { ${c}: increment(n) } }) ya da $transaction i\xE7inde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullan\u0131n.`);
121
127
  }
122
128
  if (isColRef(v)) {
123
129
  throw new Error(`${caller}(${table}): "${c}" bir col() ald\u0131. Kolon referans\u0131 yaln\u0131z F\u0130LTREDE durabilir; bir kolonun de\u011Ferini ba\u015Fka bir kolona yazmak i\xE7in $query kullan\u0131n.`);
@@ -409,7 +415,9 @@ function encodeMap(map, allowColumnExpr) {
409
415
  const out = {};
410
416
  for (const key of Object.keys(map).sort()) {
411
417
  const value = map[key];
412
- if (value === void 0) continue;
418
+ if (value === void 0) {
419
+ throw new TxPlanError(`${key} de\u011Feri undefined \u2014 bu bir yazma de\u011Feri de\u011Fil. Anahtar duruyor ama de\u011Feri yok, yani kolon sessizce YAZILMAZDI (istek g\xF6vdesinden gelen bir alan\u0131n eksik olmas\u0131 bu \u015Fekilde g\xF6r\xFCn\xFCr). Kolon varsay\u0131lan\u0131n\u0131 istiyorsan\u0131z anahtar\u0131 hi\xE7 koymay\u0131n; NULL yazmak istiyorsan\u0131z a\xE7\u0131k\xE7a null yaz\u0131n.`);
420
+ }
413
421
  out[key] = encodeValue(value, key, allowColumnExpr);
414
422
  }
415
423
  return out;
@@ -937,6 +945,10 @@ function makeTableProxy(ops, prefix) {
937
945
  const name = `${prefix}${prop}`;
938
946
  return {
939
947
  insert: /* @__PURE__ */ __name((data) => ops().insert(name, data), "insert"),
948
+ // DÖRDÜNCÜ FİİL, aynı gerekçeyle: tip söz veriyor, ops katmanı
949
+ // uyguluyor, ve bir handler'ın gerçekten dokunduğu yer BURASI.
950
+ // `runtime-table-verbs` kapısı bunu adıyla saydı.
951
+ insertMany: /* @__PURE__ */ __name((rows, opts) => ops().insertMany(name, rows, opts), "insertMany"),
940
952
  update: /* @__PURE__ */ __name((q) => ops().update(name, q.where.id, q.set), "update"),
941
953
  delete: /* @__PURE__ */ __name((id) => ops().delete(name, id), "delete"),
942
954
  findById: /* @__PURE__ */ __name((id) => ops().findById(name, id), "findById"),
@@ -993,6 +1005,7 @@ function makeTypedSurface(raw) {
993
1005
  $claim: /* @__PURE__ */ __name((table, unique, extra) => reco.claim(table, unique, extra), "$claim"),
994
1006
  $lockRows: /* @__PURE__ */ __name((table, ids) => reco.lockRows(table, ids), "$lockRows"),
995
1007
  $advisoryXactLock: /* @__PURE__ */ __name((key) => reco.advisoryXactLock(key), "$advisoryXactLock"),
1008
+ $insertMany: /* @__PURE__ */ __name((table, rows, opts) => raw.insertMany(table, rows, opts), "$insertMany"),
996
1009
  $supersede: /* @__PURE__ */ __name((table, id, row) => raw.supersede(table, id, row), "$supersede")
997
1010
  };
998
1011
  const base = Object.assign(ops, {
@@ -1182,6 +1195,24 @@ ${detail}`);
1182
1195
  }
1183
1196
  __name(loadConfig, "loadConfig");
1184
1197
 
1198
+ // src/refusals.ts
1199
+ var DECLARATION_REFUSAL = /* @__PURE__ */ Symbol.for("palbase.backend.declarationRefusal");
1200
+ var DeclarationRefused = class extends Error {
1201
+ static {
1202
+ __name(this, "DeclarationRefused");
1203
+ }
1204
+ /** @see DECLARATION_REFUSAL — realm-safe, unlike `instanceof`. */
1205
+ [DECLARATION_REFUSAL] = true;
1206
+ constructor(message) {
1207
+ super(message);
1208
+ this.name = "DeclarationRefused";
1209
+ }
1210
+ };
1211
+ function isDeclarationRefused(e) {
1212
+ return typeof e === "object" && e !== null && e[DECLARATION_REFUSAL] === true;
1213
+ }
1214
+ __name(isDeclarationRefused, "isDeclarationRefused");
1215
+
1185
1216
  // src/engine/auth.ts
1186
1217
  function b64urlToBytes(s) {
1187
1218
  const pad = s.replace(/-/g, "+").replace(/_/g, "/");
@@ -1504,12 +1535,12 @@ function buildRelations(schemas) {
1504
1535
  const held = names.get(name);
1505
1536
  if (held !== void 0) {
1506
1537
  if (held.def.owns === true && origin.def.owns === true) {
1507
- 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.`);
1538
+ throw new DeclarationRefused(`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.`);
1508
1539
  }
1509
1540
  const heldFix = renameCall(held);
1510
1541
  const originFix = renameCall(origin);
1511
1542
  const remedy = heldFix === originFix ? `rename one of them: ${heldFix}` : `rename one of them \u2014 "${held.table}.${held.column}": ${heldFix}; "${origin.table}.${origin.column}": ${originFix}`;
1512
- throw new Error(`table "${tableKey}": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name "${name}" \u2014 ${remedy}.`);
1543
+ throw new DeclarationRefused(`table "${tableKey}": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name "${name}" \u2014 ${remedy}.`);
1513
1544
  }
1514
1545
  names.set(name, origin);
1515
1546
  out.get(tableKey)?.push(edge);
@@ -2087,7 +2118,7 @@ function compileWhereBare(table, colSet, where, add, caller = "search", alias =
2087
2118
  const rel = rels.find((r) => r.name === relName);
2088
2119
  if (rel === void 0) {
2089
2120
  const known = rels.map((r) => r.name).sort();
2090
- throw new Error(`${caller}(${table}): has.${relName} diye bir ili\u015Fki yok${known.length > 0 ? ` (bilinenler: ${known.join(", ")})` : " \u2014 bu tablonun hi\xE7 ili\u015Fkisi yok"}. \u0130li\u015Fkiler yabanc\u0131 anahtarlardan T\xDCRET\u0130L\u0130R; ad\u0131n\u0131 de\u011Fi\u015Ftirmek i\xE7in references(..., { as, reverseAs }).`);
2121
+ throw new Error(`${caller}(${table}): has.${relName} diye bir ili\u015Fki yok` + (known.length > 0 ? ` (bilinenler: ${known.join(", ")}). \u0130li\u015Fkiler yabanc\u0131 anahtarlardan T\xDCRET\u0130L\u0130R; ad\u0131n\u0131 de\u011Fi\u015Ftirmek i\xE7in references(..., { as, reverseAs }).` : `. Bu tablo H\u0130\xC7 yabanc\u0131 anahtar bildirmiyor, ve ili\u015Fkiler onlardan T\xDCRET\u0130L\u0130R. Var olan bir veritaban\u0131ndan introspect edilmi\u015F \u015Femalarda bu s\u0131k olur: kolon \`text()\`/\`uuid()\` olarak durur, \`references(() => <tablo>.<kolon>)\` yoktur. Bildirdi\u011Finiz anda ili\u015Fki iki tarafta da adland\u0131r\u0131l\u0131r \u2014 ama bu CANLI veritaban\u0131na giden bir k\u0131s\u0131tt\u0131r ve mevcut yetim sat\u0131rlar onu d\xFC\u015F\xFCr\xFCr; \xF6nce onlar\u0131 say\u0131n.`));
2091
2122
  }
2092
2123
  const ourCol = rel.kind === "many" ? primaryKeyOf(table) : rel.via;
2093
2124
  const theirCol = rel.kind === "many" ? rel.via : primaryKeyOf(rel.to);
@@ -2267,6 +2298,37 @@ async function embedQuery(embed, text) {
2267
2298
  }
2268
2299
  }
2269
2300
  __name(embedQuery, "embedQuery");
2301
+ function buildSetAssignments(table, cols, set, add, caller) {
2302
+ return cols.map((c) => {
2303
+ const expr = columnExprOf(set[c]);
2304
+ if (expr !== null && expr.fn === "now") {
2305
+ return `${quoteIdent(c)} = now()`;
2306
+ }
2307
+ if (expr !== null) {
2308
+ const operator = expr.fn === "inc" ? "+" : "-";
2309
+ const t = transformsOf(currentSchema, table).get(c);
2310
+ const amount = t?.toDb === void 0 || expr.by === null || expr.by === void 0 ? expr.by : t.toDb(expr.by);
2311
+ return `${quoteIdent(c)} = ${quoteIdent(c)} ${operator} ${add(amount)}`;
2312
+ }
2313
+ return `${quoteIdent(c)} = ${add(asBindParams(table, [
2314
+ c
2315
+ ], set, caller)[0])}`;
2316
+ }).join(", ");
2317
+ }
2318
+ __name(buildSetAssignments, "buildSetAssignments");
2319
+ function buildValueTuple(table, cols, data, add, caller) {
2320
+ return cols.map((c) => {
2321
+ const expr = columnExprOf(data[c]);
2322
+ if (expr !== null && expr.fn === "now") return "now()";
2323
+ if (expr !== null) {
2324
+ throw new Error(`${caller}(${table}): "${c}" ${expr.fn === "inc" ? "increment()" : "decrement()"} ald\u0131 \u2014 sat\u0131r HEN\xDCZ YOK, yani "kolonun \u015Fu anki de\u011Feri" diye bir \u015Fey yok. Ba\u015Flang\u0131\xE7 de\u011Ferini yaz\u0131n; art\u0131rmak i\xE7in sat\u0131r olu\u015Ftuktan sonra updateMany({ where, set: { ${c}: ${expr.fn === "inc" ? "increment" : "decrement"}(n) } }).`);
2325
+ }
2326
+ return add(asBindParams(table, [
2327
+ c
2328
+ ], data, caller)[0]);
2329
+ }).join(", ");
2330
+ }
2331
+ __name(buildValueTuple, "buildValueTuple");
2270
2332
  function createOps(tx) {
2271
2333
  const at = /* @__PURE__ */ __name(() => resolveTx(tx), "at");
2272
2334
  const ops = {
@@ -2280,9 +2342,11 @@ function createOps(tx) {
2280
2342
  async insert(table, data) {
2281
2343
  const cols = Object.keys(data);
2282
2344
  if (cols.length === 0) throw new Error(`insert into ${table}: no columns given`);
2283
- const placeholders = cols.map((_, i) => `$${i + 1}`).join(", ");
2284
- const sql = `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${placeholders}) RETURNING *`;
2285
- const rows = await (await at()).unsafe(sql, asBindParams(table, cols, data, "insert"));
2345
+ const params = [];
2346
+ const add = /* @__PURE__ */ __name((v) => `$${params.push(v)}`, "add");
2347
+ const tuple = buildValueTuple(table, cols, data, add, "insert");
2348
+ const sql = `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${tuple}) RETURNING *`;
2349
+ const rows = await (await at()).unsafe(sql, params);
2286
2350
  const inserted = rows[0];
2287
2351
  if (!inserted) {
2288
2352
  throw new Error(`insert into ${table} returned no row \u2014 the write was rejected (an RLS policy, most likely).`);
@@ -2290,6 +2354,41 @@ function createOps(tx) {
2290
2354
  return asTableRow(table, inserted);
2291
2355
  },
2292
2356
  /**
2357
+ * Çok satırı TEK statement'la ekle.
2358
+ *
2359
+ * Motor bunu zaten yapıyordu ve yalnız PLAN yolundan erişilebiliyordu
2360
+ * (`tx.public.x.insertMany`). Dışarıda tek kapı `insert(row)` olduğu için
2361
+ * "şu 200 satırı yaz" ya 200 gidiş-dönüş ya da ham SQL oluyordu — ölçüldü:
2362
+ * bir müşteri projesinde bir seed rutini satırları tek tek siliyor
2363
+ * (`deleteMany` VARKEN) ve tek tek ekliyor.
2364
+ *
2365
+ * SATIRLARIN ANAHTAR KÜMESİ AYNI OLMAK ZORUNDA. Kolon listesi tek bir
2366
+ * statement'ta paylaşıldığı için ilk satırdan türer; farklı anahtar taşıyan
2367
+ * bir satırın fazla kolonu SESSİZCE YAZILMAZDI. Eksik kolon için `null`
2368
+ * yazın ya da varsayılanı istiyorsanız o satırları ayrı çağrıda ekleyin.
2369
+ */
2370
+ async insertMany(table, rows, opts) {
2371
+ if (rows.length === 0) return [];
2372
+ const first = rows[0];
2373
+ const cols = Object.keys(first);
2374
+ if (cols.length === 0) throw new Error(`insertMany into ${table}: no columns given`);
2375
+ for (let i = 1; i < rows.length; i++) {
2376
+ const keys = Object.keys(rows[i]);
2377
+ const missing = cols.filter((c) => !(c in rows[i]));
2378
+ const extra = keys.filter((k) => !cols.includes(k));
2379
+ if (missing.length > 0 || extra.length > 0) {
2380
+ throw new Error(`insertMany(${table}): ${i}. sat\u0131r\u0131n kolonlar\u0131 ilk sat\u0131rla ayn\u0131 de\u011Fil` + (missing.length > 0 ? ` (eksik: ${missing.join(", ")})` : "") + (extra.length > 0 ? ` (fazla: ${extra.join(", ")})` : "") + `. Tek statement kolon listesini PAYLA\u015EIR, yani fazla kolon sessizce yaz\u0131lmaz ve eksik kolon yanl\u0131\u015F s\xFCtuna kayar. Eksikler i\xE7in null yaz\u0131n, ya da farkl\u0131 \u015Fekilli sat\u0131rlar\u0131 ayr\u0131 \xE7a\u011Fr\u0131larda ekleyin.`);
2381
+ }
2382
+ }
2383
+ const params = [];
2384
+ const add = /* @__PURE__ */ __name((v) => `$${params.push(v)}`, "add");
2385
+ const tuples = rows.map((r) => `(${buildValueTuple(table, cols, r, add, "insertMany")})`);
2386
+ const tail = opts !== void 0 && opts.onConflict.length > 0 ? ` ${onConflictTail(cols, opts.onConflict, opts.action ?? "ignore")}` : "";
2387
+ const sql = `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES ${tuples.join(", ")}${tail} RETURNING *`;
2388
+ const out = await (await at()).unsafe(sql, params);
2389
+ return out.map((r) => asTableRow(table, r));
2390
+ },
2391
+ /**
2293
2392
  * Bir ADI kilitle — satırı değil (FR-054).
2294
2393
  *
2295
2394
  * "Aynı anda tek bir fatura kapanışı koşsun" gibi, kilitlenecek satırı
@@ -2375,8 +2474,10 @@ function createOps(tx) {
2375
2474
  const live = await at();
2376
2475
  try {
2377
2476
  return await live.savepoint(async (sp) => {
2378
- const placeholders = cols.map((_, i) => `$${i + 1}`).join(", ");
2379
- const rows = await sp.unsafe(`INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${placeholders}) RETURNING *`, asBindParams(table, cols, data, "claim"));
2477
+ const params = [];
2478
+ const add = /* @__PURE__ */ __name((v) => `$${params.push(v)}`, "add");
2479
+ const tuple = buildValueTuple(table, cols, data, add, "claim");
2480
+ const rows = await sp.unsafe(`INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${tuple}) RETURNING *`, params);
2380
2481
  if (!rows[0]) {
2381
2482
  throw new Error(`claim(${table}): INSERT sat\u0131r d\xF6nd\xFCrmedi \u2014 yazma reddedildi (b\xFCy\xFCk olas\u0131l\u0131kla bir RLS policy'si).`);
2382
2483
  }
@@ -2427,10 +2528,11 @@ function createOps(tx) {
2427
2528
  const cols = Object.keys(data);
2428
2529
  if (cols.length === 0) throw new Error(`upsert into ${table}: no columns given`);
2429
2530
  if (searchConfigFor(table)?.validity) {
2430
- const ph = cols.map((_, i) => `$${i + 1}`).join(", ");
2531
+ const bindData = [];
2532
+ const addPut = /* @__PURE__ */ __name((v) => `$${bindData.push(v)}`, "addPut");
2533
+ const ph = buildValueTuple(table, cols, data, addPut, "put");
2431
2534
  const insertSql = `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${ph}) ON CONFLICT (${conflict.map(quoteIdent).join(", ")}) WHERE "valid_to" IS NULL DO NOTHING RETURNING *`;
2432
2535
  const live = await at();
2433
- const bindData = asBindParams(table, cols, data, "put");
2434
2536
  const first = await live.unsafe(insertSql, bindData);
2435
2537
  if (first[0]) return asTableRow(table, first[0]);
2436
2538
  const condSql = conflict.map((c, i) => `${quoteIdent(c)} = $${i + 1}`).join(" AND ");
@@ -2455,12 +2557,14 @@ function createOps(tx) {
2455
2557
  ]);
2456
2558
  return asTableRow(table, second[0]);
2457
2559
  }
2458
- const placeholders = cols.map((_, i) => `$${i + 1}`).join(", ");
2560
+ const params = [];
2561
+ const add = /* @__PURE__ */ __name((v) => `$${params.push(v)}`, "add");
2562
+ const placeholders = buildValueTuple(table, cols, data, add, "put");
2459
2563
  const conflictSet = new Set(conflict);
2460
2564
  const assignments = cols.filter((c) => !conflictSet.has(c)).map((c) => `${quoteIdent(c)} = EXCLUDED.${quoteIdent(c)}`);
2461
2565
  const action = assignments.length ? `DO UPDATE SET ${assignments.join(", ")}` : `DO UPDATE SET ${quoteIdent(conflict[0])} = EXCLUDED.${quoteIdent(conflict[0])}`;
2462
2566
  const sql = `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${placeholders}) ON CONFLICT (${conflict.map(quoteIdent).join(", ")}) ${action} RETURNING *`;
2463
- const rows = await (await at()).unsafe(sql, asBindParams(table, cols, data, "put"));
2567
+ const rows = await (await at()).unsafe(sql, params);
2464
2568
  const row = rows[0];
2465
2569
  if (!row) {
2466
2570
  throw new Error(`upsert into ${table} returned no row \u2014 the write was rejected (an RLS policy, most likely).`);
@@ -2471,12 +2575,14 @@ function createOps(tx) {
2471
2575
  assertNotAppendOnly("update", table);
2472
2576
  const cols = Object.keys(data);
2473
2577
  if (cols.length === 0) return ops.findById(table, id);
2474
- const assignments = cols.map((c, i) => `${quoteIdent(c)} = $${i + 1}`).join(", ");
2475
- const sql = `UPDATE ${quoteTable(table)} SET ${assignments} WHERE id = $${cols.length + 1} RETURNING *`;
2476
- const rows = await (await at()).unsafe(sql, [
2477
- ...asBindParams(table, cols, data, "update"),
2478
- id
2479
- ]);
2578
+ const params = [];
2579
+ const add = /* @__PURE__ */ __name((v) => {
2580
+ params.push(v);
2581
+ return `$${params.length}`;
2582
+ }, "add");
2583
+ const assignments = buildSetAssignments(table, cols, data, add, "update");
2584
+ const sql = `UPDATE ${quoteTable(table)} SET ${assignments} WHERE id = ${add(id)} RETURNING *`;
2585
+ const rows = await (await at()).unsafe(sql, params);
2480
2586
  return rows[0] ? asTableRow(table, rows[0]) : null;
2481
2587
  },
2482
2588
  async delete(table, id) {
@@ -2522,21 +2628,7 @@ function createOps(tx) {
2522
2628
  params.push(v);
2523
2629
  return `$${params.length}`;
2524
2630
  }, "add");
2525
- const assignments = cols.map((c) => {
2526
- const expr = columnExprOf(set[c]);
2527
- if (expr !== null && expr.fn === "now") {
2528
- return `${quoteIdent(c)} = now()`;
2529
- }
2530
- if (expr !== null) {
2531
- const operator = expr.fn === "inc" ? "+" : "-";
2532
- const t = transformsOf(currentSchema, table).get(c);
2533
- const amount = t?.toDb === void 0 || expr.by === null || expr.by === void 0 ? expr.by : t.toDb(expr.by);
2534
- return `${quoteIdent(c)} = ${quoteIdent(c)} ${operator} ${add(amount)}`;
2535
- }
2536
- return `${quoteIdent(c)} = ${add(asBindParams(table, [
2537
- c
2538
- ], set, "updateMany")[0])}`;
2539
- }).join(", ");
2631
+ const assignments = buildSetAssignments(table, cols, set, add, "updateMany");
2540
2632
  const whereSql = compileWhere(table, known, where, add, "updateMany");
2541
2633
  assertHasPredicate(whereSql, "updateMany", table);
2542
2634
  const pk = primaryKeyOf(table);
@@ -2994,8 +3086,10 @@ function createOps(tx) {
2994
3086
  [cfg.pk]: newId
2995
3087
  };
2996
3088
  const cols = Object.keys(data);
2997
- const placeholders = cols.map((_, i) => `$${i + 1}`).join(", ");
2998
- const rows = await sp.unsafe(`INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${placeholders}) RETURNING *`, asBindParams(table, cols, data, "supersede"));
3089
+ const params = [];
3090
+ const add = /* @__PURE__ */ __name((v) => `$${params.push(v)}`, "add");
3091
+ const tuple = buildValueTuple(table, cols, data, add, "supersede");
3092
+ const rows = await sp.unsafe(`INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(", ")}) VALUES (${tuple}) RETURNING *`, params);
2999
3093
  if (!rows[0]) {
3000
3094
  throw new Error(`supersede(${table}): INSERT sat\u0131r d\xF6nd\xFCrmedi \u2014 yazma reddedildi (b\xFCy\xFCk olas\u0131l\u0131kla bir RLS policy'si)`);
3001
3095
  }
@@ -3937,6 +4031,14 @@ var DiError = class extends Error {
3937
4031
  path;
3938
4032
  at;
3939
4033
  fixes;
4034
+ /**
4035
+ * EVERY `DiKind` IS A FACT ABOUT THE AUTHOR'S DECLARATIONS — an unresolvable
4036
+ * dependency, a cycle, a class no module owns. Not one of them is something
4037
+ * the environment could change, so restarting re-reads the same bytes and
4038
+ * fails identically. The cure is a new artifact, and the tag is how the
4039
+ * runtime learns that without matching on wording.
4040
+ */
4041
+ [DECLARATION_REFUSAL] = true;
3940
4042
  constructor(kind, path, at, detail, fixes) {
3941
4043
  super(`
3942
4044
  Kind: ${kind}
@@ -4420,7 +4522,7 @@ async function createApp(opts) {
4420
4522
  assertNoOrphanEntryPoints(controllers, container.owned);
4421
4523
  const routes = buildRouteTable(controllers, liveContainer);
4422
4524
  if (routes.length === 0) {
4423
- throw new BootRefused([], "boot refused: zero endpoints collected \u2014 nothing would answer.");
4525
+ throw new DeclarationRefused("boot refused: zero endpoints collected \u2014 nothing would answer.");
4424
4526
  }
4425
4527
  const sql = opts.sql ?? await defaultSqlDriver(config);
4426
4528
  await sql.unsafe("select 1");
@@ -4931,6 +5033,8 @@ __name(closeDriver, "closeDriver");
4931
5033
  0 && (module.exports = {
4932
5034
  AuthVerifier,
4933
5035
  BootRefused,
5036
+ DECLARATION_REFUSAL,
5037
+ DeclarationRefused,
4934
5038
  RateLimiter,
4935
5039
  buildRouteTable,
4936
5040
  createApp,
@@ -4940,6 +5044,7 @@ __name(closeDriver, "closeDriver");
4940
5044
  effectiveAuth,
4941
5045
  hostAllowed,
4942
5046
  installEgressFence,
5047
+ isDeclarationRefused,
4943
5048
  loadConfig,
4944
5049
  makeMemoryCache,
4945
5050
  matchRoute,