@palbase/backend 33.0.2 → 34.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 (81) hide show
  1. package/dist/bin/palbase-backend.cjs +2020 -350
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +9 -7
  4. package/dist/bin/palbase-backend.js.map +1 -1
  5. package/dist/{chunk-SI4KGEM3.js → chunk-FOWA7PF4.js} +97 -96
  6. package/dist/chunk-FOWA7PF4.js.map +1 -0
  7. package/dist/chunk-GHNC2UHS.js +20 -0
  8. package/dist/chunk-GHNC2UHS.js.map +1 -0
  9. package/dist/{chunk-AAT5G7KY.js → chunk-JJW3L62T.js} +2 -2
  10. package/dist/chunk-JJW3L62T.js.map +1 -0
  11. package/dist/{chunk-TVCCR6SO.js → chunk-LOGL2ZHD.js} +58 -9
  12. package/dist/chunk-LOGL2ZHD.js.map +1 -0
  13. package/dist/{chunk-C6COAB3E.js → chunk-MNGZE2MM.js} +1651 -186
  14. package/dist/chunk-MNGZE2MM.js.map +1 -0
  15. package/dist/{chunk-XOX6RFPZ.js → chunk-PRH45NZU.js} +46 -3
  16. package/dist/chunk-PRH45NZU.js.map +1 -0
  17. package/dist/{chunk-26GH54D2.js → chunk-RZLY4BOY.js} +5 -3
  18. package/dist/{chunk-26GH54D2.js.map → chunk-RZLY4BOY.js.map} +1 -1
  19. package/dist/{chunk-YIQ4RS4F.js → chunk-SEM36BWY.js} +283 -5
  20. package/dist/chunk-SEM36BWY.js.map +1 -0
  21. package/dist/{chunk-KATPXCJ5.js → chunk-UMESJJRS.js} +19 -40
  22. package/dist/chunk-UMESJJRS.js.map +1 -0
  23. package/dist/chunk-VXPNPVAG.js +40 -0
  24. package/dist/chunk-VXPNPVAG.js.map +1 -0
  25. package/dist/{chunk-WWUG2QXF.js → chunk-YX7UA7VC.js} +53 -4
  26. package/dist/chunk-YX7UA7VC.js.map +1 -0
  27. package/dist/db/env.cjs.map +1 -1
  28. package/dist/db/env.d.cts +2 -0
  29. package/dist/db/env.d.ts +2 -0
  30. package/dist/db/index.cjs +261 -2
  31. package/dist/db/index.cjs.map +1 -1
  32. package/dist/db/index.d.cts +46 -3
  33. package/dist/db/index.d.ts +46 -3
  34. package/dist/db/index.js +14 -5
  35. package/dist/{index-DMZG3kpo.d.ts → endpoint-DpNUx-ON.d.ts} +315 -57
  36. package/dist/{index-DB_nW-AV.d.cts → endpoint-kYgEHrrV.d.cts} +315 -57
  37. package/dist/engine/index.cjs +2026 -348
  38. package/dist/engine/index.cjs.map +1 -1
  39. package/dist/engine/index.d.cts +5 -5
  40. package/dist/engine/index.d.ts +5 -5
  41. package/dist/engine/index.js +17 -7
  42. package/dist/{index-D-3duy8Y.d.ts → index-JrHqNsjQ.d.ts} +108 -50
  43. package/dist/{index-DLveQoOf.d.cts → index-pnDsEfxJ.d.cts} +108 -50
  44. package/dist/index.cjs +616 -254
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +7 -6
  47. package/dist/index.d.ts +7 -6
  48. package/dist/index.js +25 -15
  49. package/dist/index.js.map +1 -1
  50. package/dist/openapi/index.cjs +7 -0
  51. package/dist/openapi/index.cjs.map +1 -1
  52. package/dist/openapi/index.d.cts +3 -3
  53. package/dist/openapi/index.d.ts +3 -3
  54. package/dist/openapi/index.js +4 -3
  55. package/dist/openapi/index.js.map +1 -1
  56. package/dist/{registry-DSTThhKf.d.cts → registry-BcOd8Zhf.d.cts} +3 -1
  57. package/dist/{registry-JjF5lcj4.d.ts → registry-BoX5iNyY.d.ts} +3 -1
  58. package/dist/test/index.cjs +103 -66
  59. package/dist/test/index.cjs.map +1 -1
  60. package/dist/test/index.d.cts +3 -3
  61. package/dist/test/index.d.ts +3 -3
  62. package/dist/test/index.js +33 -7
  63. package/dist/test/index.js.map +1 -1
  64. package/docs/README.md +1 -1
  65. package/docs/database.md +308 -0
  66. package/docs/examples/check-query-contracts.ts +5 -0
  67. package/docs/examples/database-dx.contract.json +65 -0
  68. package/docs/examples/database-dx.ts +63 -0
  69. package/docs/examples/money-transfer.ts +73 -0
  70. package/docs/llms-full.txt +309 -1
  71. package/package.json +1 -2
  72. package/template/package.json +1 -1
  73. package/dist/chunk-AAT5G7KY.js.map +0 -1
  74. package/dist/chunk-C6COAB3E.js.map +0 -1
  75. package/dist/chunk-KATPXCJ5.js.map +0 -1
  76. package/dist/chunk-SI4KGEM3.js.map +0 -1
  77. package/dist/chunk-TVCCR6SO.js.map +0 -1
  78. package/dist/chunk-WWUG2QXF.js.map +0 -1
  79. package/dist/chunk-XOX6RFPZ.js.map +0 -1
  80. package/dist/chunk-YIQ4RS4F.js.map +0 -1
  81. package/stack-images.json +0 -24
package/dist/index.cjs CHANGED
@@ -102,6 +102,7 @@ __export(src_exports, {
102
102
  __runWithRuntime: () => __runWithRuntime,
103
103
  __setRuntime: () => __setRuntime,
104
104
  assertNoOrphanEntryPoints: () => assertNoOrphanEntryPoints,
105
+ assertQueryManifest: () => assertQueryManifest,
105
106
  assertZeroArgConstructor: () => assertZeroArgConstructor,
106
107
  bigint: () => bigint,
107
108
  boolean: () => boolean,
@@ -115,8 +116,10 @@ __export(src_exports, {
115
116
  defineDefaultAuth: () => defineDefaultAuth,
116
117
  defineError: () => defineError,
117
118
  defineMiddleware: () => defineMiddleware,
119
+ defineQuery: () => defineQuery,
118
120
  defineSchema: () => defineSchema,
119
121
  defineTable: () => defineTable,
122
+ defineWorkload: () => defineWorkload,
120
123
  enumType: () => enumType,
121
124
  exprCtx: () => exprCtx,
122
125
  getErrorRegistry: () => getErrorRegistry,
@@ -152,6 +155,7 @@ __export(src_exports, {
152
155
  ownerOnly: () => ownerOnly,
153
156
  policy: () => policy,
154
157
  publicChannel: () => publicChannel,
158
+ queryManifest: () => queryManifest,
155
159
  raw: () => raw,
156
160
  recordThrows: () => recordThrows,
157
161
  resolveEffectiveAuth: () => resolveEffectiveAuth,
@@ -165,7 +169,7 @@ __export(src_exports, {
165
169
  vector: () => vector,
166
170
  webhooksOf: () => webhooksOf,
167
171
  withRetry: () => withRetry,
168
- z: () => import_zod2.z
172
+ z: () => import_zod3.z
169
173
  });
170
174
  module.exports = __toCommonJS(src_exports);
171
175
 
@@ -741,260 +745,54 @@ function translateRejection(err, builder) {
741
745
  }
742
746
  __name(translateRejection, "translateRejection");
743
747
 
744
- // src/errors.ts
745
- var HTTP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("palbase.backend.httpError");
746
- var HttpError = class extends Error {
747
- static {
748
- __name(this, "HttpError");
749
- }
750
- status;
751
- error;
752
- errorDescription;
753
- data;
754
- /** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */
755
- [HTTP_ERROR_BRAND] = true;
756
- constructor(status, error, errorDescription, data) {
757
- super(errorDescription);
758
- this.name = "HttpError";
759
- this.status = status;
760
- this.error = error;
761
- this.errorDescription = errorDescription;
762
- if (data !== void 0) {
763
- this.data = data;
764
- }
765
- }
766
- /**
767
- * Serialize to the standard Palbase error response format.
768
- * The `requestId` is injected by the runtime layer from the request context.
769
- * When called without arguments (e.g. JSON.stringify), request_id is omitted.
770
- * When `data` is set, it is appended as a strict-superset field.
771
- */
772
- toJSON(requestId) {
773
- const result = {
774
- error: this.error,
775
- error_description: this.errorDescription,
776
- status: this.status
777
- };
778
- if (requestId) {
779
- result.request_id = requestId;
780
- }
781
- if (this.data !== void 0) {
782
- result.data = this.data;
783
- }
784
- return result;
785
- }
786
- };
787
- var PalError = class extends HttpError {
788
- static {
789
- __name(this, "PalError");
790
- }
791
- constructor(status, code, description, data) {
792
- super(status, code, description, data);
793
- this.name = "PalError";
794
- }
795
- };
796
- var NamedHttpError = class NamedHttpError2 extends HttpError {
797
- static {
798
- __name(this, "NamedHttpError");
799
- }
800
- constructor(status, defaultCode, name, message, code, data) {
801
- super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
802
- this.name = name;
803
- }
804
- };
805
- function defaultMessage(name) {
806
- const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
807
- return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
808
- }
809
- __name(defaultMessage, "defaultMessage");
810
- var BadRequest = class extends NamedHttpError {
811
- static {
812
- __name(this, "BadRequest");
813
- }
814
- constructor(data, message) {
815
- super(400, "bad_request", "BadRequest", message, void 0, data);
816
- }
817
- };
818
- var Unauthorized = class extends NamedHttpError {
819
- static {
820
- __name(this, "Unauthorized");
821
- }
822
- constructor(message, code, data) {
823
- super(401, "unauthorized", "Unauthorized", message, code, data);
824
- }
825
- };
826
- var Forbidden = class extends NamedHttpError {
827
- static {
828
- __name(this, "Forbidden");
829
- }
830
- constructor(message, code, data) {
831
- super(403, "forbidden", "Forbidden", message, code, data);
832
- }
833
- };
834
- var NotFound = class extends NamedHttpError {
835
- static {
836
- __name(this, "NotFound");
837
- }
838
- constructor(message, code, data) {
839
- super(404, "not_found", "NotFound", message, code, data);
840
- }
841
- };
842
- var Conflict = class extends NamedHttpError {
843
- static {
844
- __name(this, "Conflict");
845
- }
846
- constructor(message, code, data) {
847
- super(409, "conflict", "Conflict", message, code, data);
848
- }
849
- };
850
- var UniqueViolation = class extends Conflict {
851
- static {
852
- __name(this, "UniqueViolation");
853
- }
854
- /**
855
- * Whether `e` is a unique violation — REGARDLESS of which copy of this SDK
856
- * constructed it.
857
- *
858
- * Use this instead of `instanceof`. Measured on a live stack: a controller
859
- * bundle INLINES its own copy of `@palbase/backend`, and the engine that
860
- * raises this error is the runtime's copy. Two copies, two class identities,
861
- * and `e instanceof UniqueViolation` is false in the one place a caller
862
- * writes it — a check that reads as correct and silently never matches.
863
- */
864
- static is(e) {
865
- return typeof e === "object" && e !== null && e.name === "UniqueViolation" && typeof e.constraint === "string";
866
- }
867
- /** The unique constraint the statement violated, as Postgres named it.
868
- * `""` when the driver did not say which — see `engine/db.ts`. */
869
- constraint;
870
- constructor(constraint, message, code, data) {
871
- super(message ?? "Unique constraint violated", code ?? "unique_violation", data);
872
- this.name = "UniqueViolation";
873
- this.constraint = constraint;
874
- }
875
- };
876
- function isRetryable(e) {
877
- return typeof e === "object" && e !== null && e.retryable === true && typeof e.sqlstate === "string";
878
- }
879
- __name(isRetryable, "isRetryable");
880
- var SerializationFailure = class extends Conflict {
881
- static {
882
- __name(this, "SerializationFailure");
883
- }
884
- retryable = true;
885
- sqlstate;
886
- static is(e) {
887
- return typeof e === "object" && e !== null && e.name === "SerializationFailure";
888
- }
889
- constructor(sqlstate = "40001", message, data) {
890
- super(message ?? "i\u015Flem e\u015Fzamanl\u0131 bir i\u015Flemle serile\u015Ftirilemedi \u2014 ayn\u0131 i\u015Flemi ba\u015Ftan \xE7al\u0131\u015Ft\u0131r\u0131n ($transaction'a { retry: n } verebilirsiniz)", "serialization_failure", data);
891
- this.name = "SerializationFailure";
892
- this.sqlstate = sqlstate;
893
- }
894
- };
895
- var DeadlockDetected = class extends Conflict {
896
- static {
897
- __name(this, "DeadlockDetected");
898
- }
899
- retryable = true;
900
- sqlstate;
901
- static is(e) {
902
- return typeof e === "object" && e !== null && e.name === "DeadlockDetected";
903
- }
904
- constructor(sqlstate = "40P01", message, data) {
905
- super(message ?? "deadlock: iki i\u015Flem birbirinin kilidini bekledi ve bu i\u015Flem iptal edildi \u2014 kilit s\u0131ras\u0131n\u0131 sabitlemek i\xE7in Database.$lockRows(tablo, id'ler) kullan\u0131n", "deadlock_detected", data);
906
- this.name = "DeadlockDetected";
907
- this.sqlstate = sqlstate;
908
- }
909
- };
910
- var TooManyRequests = class extends NamedHttpError {
911
- static {
912
- __name(this, "TooManyRequests");
913
- }
914
- constructor(data, message) {
915
- super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
916
- }
917
- };
918
-
919
- // src/db/typed-db.ts
920
- function makeTypedTable(name, raw2) {
921
- return {
922
- insert: /* @__PURE__ */ __name((data) => raw2.insert(name, data), "insert"),
923
- aggregate: /* @__PURE__ */ __name((q) => raw2.aggregate(name, q), "aggregate"),
924
- insertMany: /* @__PURE__ */ __name((rows, opts) => raw2.insertMany(name, rows, opts), "insertMany"),
925
- put: /* @__PURE__ */ __name((q) => raw2.put(name, q.data, {
926
- onConflict: q.onConflict
927
- }), "put"),
928
- update: /* @__PURE__ */ __name((q) => raw2.update(name, q.where.id, q.set), "update"),
929
- delete: /* @__PURE__ */ __name((id) => raw2.delete(name, id), "delete"),
930
- findById: /* @__PURE__ */ __name((id) => raw2.findById(name, id), "findById"),
931
- findMany: /* @__PURE__ */ __name((q) => {
932
- const { where, ...opts } = q ?? {};
933
- return raw2.findMany(name, where, opts);
934
- }, "findMany"),
935
- updateMany: /* @__PURE__ */ __name((q) => raw2.updateMany(name, q.where, q.set, q.returning === void 0 ? void 0 : {
936
- returning: q.returning
937
- }), "updateMany"),
938
- deleteMany: /* @__PURE__ */ __name((q) => raw2.deleteMany(name, q.where), "deleteMany"),
939
- count: /* @__PURE__ */ __name((q) => raw2.count(name, q?.where), "count")
940
- };
941
- }
942
- __name(makeTypedTable, "makeTypedTable");
943
- function makeTypedDB(schema, raw2) {
944
- const tables = {};
945
- for (const key of Object.keys(schema.tables)) {
946
- const tableDef = schema.tables[key];
947
- if (tableDef !== void 0) {
948
- tables[key] = makeTypedTable(tableDef.name, raw2);
949
- }
950
- }
748
+ // src/db/workload.ts
749
+ function defineWorkload(name, options) {
951
750
  const result = {
952
- tables,
953
- transaction(fn) {
954
- const builder = new TxPlanBuilder();
955
- const planTables = {};
956
- for (const key of Object.keys(schema.tables)) {
957
- const tableDef = schema.tables[key];
958
- if (tableDef !== void 0) planTables[key] = builder.table(tableDef.name);
959
- }
960
- return runTxPlan(raw2, {
961
- tables: planTables
962
- }, builder, fn);
963
- }
751
+ name,
752
+ concurrency: options.concurrency,
753
+ queueLimit: options.queueLimit,
754
+ tenantConcurrency: options.tenantConcurrency ?? options.concurrency,
755
+ tenantQueueLimit: options.tenantQueueLimit ?? options.queueLimit,
756
+ queueTimeoutMs: options.queueTimeoutMs ?? 1e3,
757
+ tenantClaim: options.tenantClaim ?? "tenant_id"
964
758
  };
965
- return result;
966
- }
967
- __name(makeTypedDB, "makeTypedDB");
968
- function col(name) {
969
- return brandRef({
970
- $col: name
971
- }, "col");
972
- }
973
- __name(col, "col");
974
- async function withRetry(fn, opts = {}) {
975
- const budget = opts.retry ?? 0;
976
- let attempt = 0;
977
- for (; ; ) {
978
- try {
979
- return await fn();
980
- } catch (e) {
981
- if (attempt >= budget || !isRetryable(e)) throw e;
982
- attempt += 1;
983
- }
759
+ validateWorkload(result);
760
+ return Object.freeze(result);
761
+ }
762
+ __name(defineWorkload, "defineWorkload");
763
+ function validateWorkload(value) {
764
+ if (typeof value.name !== "string" || !/^[a-zA-Z][a-zA-Z0-9_.-]{0,63}$/.test(value.name)) throw new Error("workload name must be 1\u201364 letters/digits/dots/dashes");
765
+ for (const name of [
766
+ "concurrency",
767
+ "tenantConcurrency",
768
+ "queueLimit",
769
+ "tenantQueueLimit",
770
+ "queueTimeoutMs"
771
+ ]) {
772
+ const n = value[name], min = name.endsWith("Limit") ? 0 : 1;
773
+ const max = name === "queueTimeoutMs" ? 6e4 : name.endsWith("Limit") ? 1e4 : 1e3;
774
+ if (!Number.isInteger(n) || n < min || n > max) throw new Error(`workload ${name} must be an integer between ${min} and ${max}`);
775
+ }
776
+ if (value.tenantConcurrency > value.concurrency || value.tenantQueueLimit > value.queueLimit) throw new Error("workload tenant limits cannot exceed global limits");
777
+ if (typeof value.tenantClaim !== "string" || !/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(value.tenantClaim)) throw new Error("workload tenantClaim must be a top-level claim name");
778
+ }
779
+ __name(validateWorkload, "validateWorkload");
780
+
781
+ // src/db/transaction-options.ts
782
+ function retryBudget(value) {
783
+ const n = value ?? 0;
784
+ if (!Number.isInteger(n) || n < 0 || n > 10) {
785
+ throw new Error("transaction retry must be an integer between 0 and 10");
984
786
  }
787
+ return n;
985
788
  }
986
- __name(withRetry, "withRetry");
987
- function sqlFragment(strings, ...values) {
988
- return brandRef({
989
- $sql: {
990
- text: [
991
- ...strings
992
- ],
993
- values
994
- }
995
- }, "sql");
789
+ __name(retryBudget, "retryBudget");
790
+ function assertPlanRetry(options) {
791
+ if (retryBudget(options?.retry) !== 0) {
792
+ throw new Error("Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.");
793
+ }
996
794
  }
997
- __name(sqlFragment, "sqlFragment");
795
+ __name(assertPlanRetry, "assertPlanRetry");
998
796
 
999
797
  // src/db/schema-json.ts
1000
798
  function defOf(column) {
@@ -1407,6 +1205,14 @@ function makeTableProxy(ops, prefix) {
1407
1205
  update: /* @__PURE__ */ __name((q) => ops().update(name, q.where.id, q.set), "update"),
1408
1206
  delete: /* @__PURE__ */ __name((id) => ops().delete(name, id), "delete"),
1409
1207
  findById: /* @__PURE__ */ __name((id) => ops().findById(name, id), "findById"),
1208
+ findUnique: /* @__PURE__ */ __name((q) => ops().findUnique(name, q.where, {
1209
+ select: q.select,
1210
+ with: q.with
1211
+ }), "findUnique"),
1212
+ page: /* @__PURE__ */ __name((q) => {
1213
+ const { where, ...opts } = q ?? {};
1214
+ return ops().page(name, where, opts);
1215
+ }, "page"),
1410
1216
  findMany: /* @__PURE__ */ __name((q) => {
1411
1217
  const { where, ...opts } = q ?? {};
1412
1218
  return ops().findMany(name, where, opts);
@@ -1444,10 +1250,16 @@ function makeTypedSurface(raw2) {
1444
1250
  const reco = raw2;
1445
1251
  const ops = {
1446
1252
  $query: /* @__PURE__ */ __name((sql, params) => raw2.query(sql, params), "$query"),
1253
+ $diagnostics: /* @__PURE__ */ __name(() => raw2.diagnostics(), "$diagnostics"),
1254
+ $readQuery: /* @__PURE__ */ __name((query) => raw2.readQuery(query), "$readQuery"),
1255
+ $compileQuery: /* @__PURE__ */ __name((query) => raw2.compileQuery(query), "$compileQuery"),
1256
+ $explainQuery: /* @__PURE__ */ __name((query) => raw2.explainQuery(query), "$explainQuery"),
1447
1257
  $insert: /* @__PURE__ */ __name((table, data) => raw2.insert(table, data), "$insert"),
1448
1258
  $update: /* @__PURE__ */ __name((table, id, data) => raw2.update(table, id, data), "$update"),
1449
1259
  $delete: /* @__PURE__ */ __name((table, id) => raw2.delete(table, id), "$delete"),
1450
1260
  $findById: /* @__PURE__ */ __name((table, id) => raw2.findById(table, id), "$findById"),
1261
+ $findUnique: /* @__PURE__ */ __name((table, where, opts) => raw2.findUnique(table, where, opts), "$findUnique"),
1262
+ $page: /* @__PURE__ */ __name((table, query, opts) => raw2.page(table, query, opts), "$page"),
1451
1263
  $findMany: /* @__PURE__ */ __name((table, query, opts) => raw2.findMany(table, query, opts), "$findMany"),
1452
1264
  $put: /* @__PURE__ */ __name((table, data, opts) => raw2.put(table, data, opts), "$put"),
1453
1265
  // `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,
@@ -1470,14 +1282,49 @@ function makeTypedSurface(raw2) {
1470
1282
  $supersede: /* @__PURE__ */ __name((table, id, row) => raw2.supersede(table, id, row), "$supersede")
1471
1283
  };
1472
1284
  const base = Object.assign(ops, {
1285
+ $atomic(fn, options) {
1286
+ if (typeof raw2.atomic !== "function") {
1287
+ throw new Error("This Database handle cannot open a root transaction; nested $atomic is not supported");
1288
+ }
1289
+ const parent = __requestALS.getStore();
1290
+ let runtime2;
1291
+ try {
1292
+ runtime2 = __getRuntime();
1293
+ } catch {
1294
+ }
1295
+ return raw2.atomic(async (tx) => {
1296
+ const typed = makeTypedSurface(tx);
1297
+ const invoke = /* @__PURE__ */ __name(() => fn(typed), "invoke");
1298
+ if (!runtime2) return invoke();
1299
+ const refuse2 = /* @__PURE__ */ __name(() => {
1300
+ throw new Error("Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed");
1301
+ }, "refuse");
1302
+ const ambient = Object.assign({}, tx, {
1303
+ atomic: refuse2,
1304
+ asService: refuse2
1305
+ });
1306
+ return __requestALS.run({
1307
+ ...parent,
1308
+ runtime: {
1309
+ ...runtime2,
1310
+ Database: ambient
1311
+ }
1312
+ }, invoke);
1313
+ }, options);
1314
+ },
1473
1315
  // Both surfaces get it: a savepoint on the service transaction is as useful
1474
1316
  // as one on the request's, and each is bound to its own connection.
1475
1317
  $attempt: /* @__PURE__ */ __name((fn) => raw2.attempt(fn), "$attempt"),
1476
1318
  $transaction(fn, opts) {
1477
- return withRetry(() => {
1478
- const builder = new TxPlanBuilder();
1479
- return runTxPlan(raw2, makeTxPlanHandle(builder), builder, fn);
1480
- }, opts ?? {});
1319
+ assertPlanRetry(opts);
1320
+ const builder = new TxPlanBuilder();
1321
+ return runTxPlan(raw2, makeTxPlanHandle(builder), builder, fn);
1322
+ },
1323
+ $command(fn, options) {
1324
+ const builder = new TxPlanBuilder();
1325
+ return runTxPlan({
1326
+ txPlan: /* @__PURE__ */ __name((plan) => raw2.command(plan, options), "txPlan")
1327
+ }, makeTxPlanHandle(builder), builder, fn);
1481
1328
  }
1482
1329
  });
1483
1330
  return new Proxy(base, {
@@ -3134,6 +2981,13 @@ function defineTable(name, input) {
3134
2981
  }
3135
2982
  __name(defineTable, "defineTable");
3136
2983
  var declaringSchemaOf = /* @__PURE__ */ new WeakMap();
2984
+ function declaredTableKey(table) {
2985
+ const metadata = table[TABLE_META];
2986
+ const schema = declaringSchemaOf.get(metadata);
2987
+ if (schema === void 0) throw new Error(`defineQuery: table ${metadata.name} must belong to defineSchema before defining its query`);
2988
+ return qualifiedTableKey(schema, metadata.name);
2989
+ }
2990
+ __name(declaredTableKey, "declaredTableKey");
3137
2991
  function resolveReferences(tables, schemaName) {
3138
2992
  for (const table of Object.values(tables)) {
3139
2993
  for (const [colName, builder] of Object.entries(table.columns)) {
@@ -3733,6 +3587,295 @@ var openai = {
3733
3587
  }
3734
3588
  };
3735
3589
 
3590
+ // src/db/sqlstate.ts
3591
+ var SQLSTATE = Object.freeze({
3592
+ serializationFailure: "40001",
3593
+ deadlockDetected: "40P01",
3594
+ commandGuardFailed: "PBC01"
3595
+ });
3596
+ function isTransactionRollbackState(state) {
3597
+ return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;
3598
+ }
3599
+ __name(isTransactionRollbackState, "isTransactionRollbackState");
3600
+
3601
+ // src/errors.ts
3602
+ var HTTP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("palbase.backend.httpError");
3603
+ var HttpError = class extends Error {
3604
+ static {
3605
+ __name(this, "HttpError");
3606
+ }
3607
+ status;
3608
+ error;
3609
+ errorDescription;
3610
+ data;
3611
+ /** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */
3612
+ [HTTP_ERROR_BRAND] = true;
3613
+ constructor(status, error, errorDescription, data) {
3614
+ super(errorDescription);
3615
+ this.name = "HttpError";
3616
+ this.status = status;
3617
+ this.error = error;
3618
+ this.errorDescription = errorDescription;
3619
+ if (data !== void 0) {
3620
+ this.data = data;
3621
+ }
3622
+ }
3623
+ /**
3624
+ * Serialize to the standard Palbase error response format.
3625
+ * The `requestId` is injected by the runtime layer from the request context.
3626
+ * When called without arguments (e.g. JSON.stringify), request_id is omitted.
3627
+ * When `data` is set, it is appended as a strict-superset field.
3628
+ */
3629
+ toJSON(requestId) {
3630
+ const result = {
3631
+ error: this.error,
3632
+ error_description: this.errorDescription,
3633
+ status: this.status
3634
+ };
3635
+ if (requestId) {
3636
+ result.request_id = requestId;
3637
+ }
3638
+ if (this.data !== void 0) {
3639
+ result.data = this.data;
3640
+ }
3641
+ return result;
3642
+ }
3643
+ };
3644
+ var PalError = class extends HttpError {
3645
+ static {
3646
+ __name(this, "PalError");
3647
+ }
3648
+ constructor(status, code, description, data) {
3649
+ super(status, code, description, data);
3650
+ this.name = "PalError";
3651
+ }
3652
+ };
3653
+ var NamedHttpError = class NamedHttpError2 extends HttpError {
3654
+ static {
3655
+ __name(this, "NamedHttpError");
3656
+ }
3657
+ constructor(status, defaultCode, name, message, code, data) {
3658
+ super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
3659
+ this.name = name;
3660
+ }
3661
+ };
3662
+ function defaultMessage(name) {
3663
+ const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
3664
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
3665
+ }
3666
+ __name(defaultMessage, "defaultMessage");
3667
+ var BadRequest = class extends NamedHttpError {
3668
+ static {
3669
+ __name(this, "BadRequest");
3670
+ }
3671
+ constructor(data, message) {
3672
+ super(400, "bad_request", "BadRequest", message, void 0, data);
3673
+ }
3674
+ };
3675
+ var Unauthorized = class extends NamedHttpError {
3676
+ static {
3677
+ __name(this, "Unauthorized");
3678
+ }
3679
+ constructor(message, code, data) {
3680
+ super(401, "unauthorized", "Unauthorized", message, code, data);
3681
+ }
3682
+ };
3683
+ var Forbidden = class extends NamedHttpError {
3684
+ static {
3685
+ __name(this, "Forbidden");
3686
+ }
3687
+ constructor(message, code, data) {
3688
+ super(403, "forbidden", "Forbidden", message, code, data);
3689
+ }
3690
+ };
3691
+ var NotFound = class extends NamedHttpError {
3692
+ static {
3693
+ __name(this, "NotFound");
3694
+ }
3695
+ constructor(message, code, data) {
3696
+ super(404, "not_found", "NotFound", message, code, data);
3697
+ }
3698
+ };
3699
+ var Conflict = class extends NamedHttpError {
3700
+ static {
3701
+ __name(this, "Conflict");
3702
+ }
3703
+ constructor(message, code, data) {
3704
+ super(409, "conflict", "Conflict", message, code, data);
3705
+ }
3706
+ };
3707
+ var UniqueViolation = class extends Conflict {
3708
+ static {
3709
+ __name(this, "UniqueViolation");
3710
+ }
3711
+ /**
3712
+ * Whether `e` is a unique violation — REGARDLESS of which copy of this SDK
3713
+ * constructed it.
3714
+ *
3715
+ * Use this instead of `instanceof`. Measured on a live stack: a controller
3716
+ * bundle INLINES its own copy of `@palbase/backend`, and the engine that
3717
+ * raises this error is the runtime's copy. Two copies, two class identities,
3718
+ * and `e instanceof UniqueViolation` is false in the one place a caller
3719
+ * writes it — a check that reads as correct and silently never matches.
3720
+ */
3721
+ static is(e) {
3722
+ return typeof e === "object" && e !== null && e.name === "UniqueViolation" && typeof e.constraint === "string";
3723
+ }
3724
+ /** The unique constraint the statement violated, as Postgres named it.
3725
+ * `""` when the driver did not say which — see `engine/db.ts`. */
3726
+ constraint;
3727
+ constructor(constraint, message, code, data) {
3728
+ super(message ?? "Unique constraint violated", code ?? "unique_violation", data);
3729
+ this.name = "UniqueViolation";
3730
+ this.constraint = constraint;
3731
+ }
3732
+ };
3733
+ function isRetryable(e) {
3734
+ return typeof e === "object" && e !== null && e.retryable === true && isTransactionRollbackState(e.sqlstate);
3735
+ }
3736
+ __name(isRetryable, "isRetryable");
3737
+ var SerializationFailure = class extends Conflict {
3738
+ static {
3739
+ __name(this, "SerializationFailure");
3740
+ }
3741
+ retryable = true;
3742
+ sqlstate;
3743
+ static is(e) {
3744
+ return typeof e === "object" && e !== null && e.name === "SerializationFailure";
3745
+ }
3746
+ constructor(sqlstate = SQLSTATE.serializationFailure, message, data) {
3747
+ super(message ?? "i\u015Flem e\u015Fzamanl\u0131 bir i\u015Flemle serile\u015Ftirilemedi \u2014 ayn\u0131 i\u015Flemi ba\u015Ftan \xE7al\u0131\u015Ft\u0131r\u0131n (karar okumalar\u0131 ve yazmalar\u0131 $atomic i\xE7ine al\u0131p { retry: n } verin)", "serialization_failure", data);
3748
+ this.name = "SerializationFailure";
3749
+ this.sqlstate = sqlstate;
3750
+ }
3751
+ };
3752
+ var DeadlockDetected = class extends Conflict {
3753
+ static {
3754
+ __name(this, "DeadlockDetected");
3755
+ }
3756
+ retryable = true;
3757
+ sqlstate;
3758
+ static is(e) {
3759
+ return typeof e === "object" && e !== null && e.name === "DeadlockDetected";
3760
+ }
3761
+ constructor(sqlstate = SQLSTATE.deadlockDetected, message, data) {
3762
+ super(message ?? "deadlock: iki i\u015Flem birbirinin kilidini bekledi ve bu i\u015Flem iptal edildi \u2014 kilit s\u0131ras\u0131n\u0131 sabitlemek i\xE7in Database.$lockRows(tablo, id'ler) kullan\u0131n", "deadlock_detected", data);
3763
+ this.name = "DeadlockDetected";
3764
+ this.sqlstate = sqlstate;
3765
+ }
3766
+ };
3767
+ var TooManyRequests = class extends NamedHttpError {
3768
+ static {
3769
+ __name(this, "TooManyRequests");
3770
+ }
3771
+ constructor(data, message) {
3772
+ super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
3773
+ }
3774
+ };
3775
+
3776
+ // src/db/typed-db.ts
3777
+ function makeTypedTable(name, raw2) {
3778
+ return {
3779
+ insert: /* @__PURE__ */ __name((data) => raw2.insert(name, data), "insert"),
3780
+ aggregate: /* @__PURE__ */ __name((q) => raw2.aggregate(name, q), "aggregate"),
3781
+ insertMany: /* @__PURE__ */ __name((rows, opts) => raw2.insertMany(name, rows, opts), "insertMany"),
3782
+ put: /* @__PURE__ */ __name((q) => raw2.put(name, q.data, {
3783
+ onConflict: q.onConflict
3784
+ }), "put"),
3785
+ update: /* @__PURE__ */ __name((q) => raw2.update(name, q.where.id, q.set), "update"),
3786
+ delete: /* @__PURE__ */ __name((id) => raw2.delete(name, id), "delete"),
3787
+ findUnique: /* @__PURE__ */ __name((q) => raw2.findUnique(name, q.where, {
3788
+ select: q.select
3789
+ }), "findUnique"),
3790
+ findById: /* @__PURE__ */ __name((id) => raw2.findById(name, id), "findById"),
3791
+ page: /* @__PURE__ */ __name((q) => {
3792
+ const { where, ...opts } = q ?? {};
3793
+ return raw2.page(name, where, opts);
3794
+ }, "page"),
3795
+ findMany: /* @__PURE__ */ __name((q) => {
3796
+ const { where, ...opts } = q ?? {};
3797
+ return raw2.findMany(name, where, opts);
3798
+ }, "findMany"),
3799
+ updateMany: /* @__PURE__ */ __name((q) => raw2.updateMany(name, q.where, q.set, q.returning === void 0 ? void 0 : {
3800
+ returning: q.returning
3801
+ }), "updateMany"),
3802
+ deleteMany: /* @__PURE__ */ __name((q) => raw2.deleteMany(name, q.where), "deleteMany"),
3803
+ count: /* @__PURE__ */ __name((q) => raw2.count(name, q?.where), "count")
3804
+ };
3805
+ }
3806
+ __name(makeTypedTable, "makeTypedTable");
3807
+ function makeTypedDB(schema, raw2) {
3808
+ const tables = {};
3809
+ for (const key of Object.keys(schema.tables)) {
3810
+ const tableDef = schema.tables[key];
3811
+ if (tableDef !== void 0) {
3812
+ tables[key] = makeTypedTable(qualifiedTableKey(schema.name, tableDef.name), raw2);
3813
+ }
3814
+ }
3815
+ const result = {
3816
+ tables,
3817
+ diagnostics: /* @__PURE__ */ __name(() => raw2.diagnostics(), "diagnostics"),
3818
+ readQuery: /* @__PURE__ */ __name((query) => raw2.readQuery(query), "readQuery"),
3819
+ compileQuery: /* @__PURE__ */ __name((query) => raw2.compileQuery(query), "compileQuery"),
3820
+ explainQuery: /* @__PURE__ */ __name((query) => raw2.explainQuery(query), "explainQuery"),
3821
+ command(fn, options) {
3822
+ const builder = new TxPlanBuilder();
3823
+ const planTables = Object.fromEntries(Object.entries(schema.tables).map(([key, table]) => [
3824
+ key,
3825
+ builder.table(qualifiedTableKey(schema.name, table.name))
3826
+ ]));
3827
+ return runTxPlan({
3828
+ txPlan: /* @__PURE__ */ __name((plan) => raw2.command(plan, options), "txPlan")
3829
+ }, {
3830
+ tables: planTables
3831
+ }, builder, fn);
3832
+ },
3833
+ transaction(fn) {
3834
+ const builder = new TxPlanBuilder();
3835
+ const planTables = {};
3836
+ for (const key of Object.keys(schema.tables)) {
3837
+ const tableDef = schema.tables[key];
3838
+ if (tableDef !== void 0) planTables[key] = builder.table(qualifiedTableKey(schema.name, tableDef.name));
3839
+ }
3840
+ return runTxPlan(raw2, {
3841
+ tables: planTables
3842
+ }, builder, fn);
3843
+ }
3844
+ };
3845
+ return result;
3846
+ }
3847
+ __name(makeTypedDB, "makeTypedDB");
3848
+ function col(name) {
3849
+ return brandRef({
3850
+ $col: name
3851
+ }, "col");
3852
+ }
3853
+ __name(col, "col");
3854
+ async function withRetry(fn, opts = {}) {
3855
+ const budget = retryBudget(opts.retry);
3856
+ let attempt = 0;
3857
+ for (; ; ) {
3858
+ try {
3859
+ return await fn();
3860
+ } catch (e) {
3861
+ if (attempt >= budget || !isRetryable(e)) throw e;
3862
+ attempt += 1;
3863
+ }
3864
+ }
3865
+ }
3866
+ __name(withRetry, "withRetry");
3867
+ function sqlFragment(strings, ...values) {
3868
+ return brandRef({
3869
+ $sql: {
3870
+ text: [
3871
+ ...strings
3872
+ ],
3873
+ values
3874
+ }
3875
+ }, "sql");
3876
+ }
3877
+ __name(sqlFragment, "sqlFragment");
3878
+
3736
3879
  // src/refusals.ts
3737
3880
  var DECLARATION_REFUSAL = /* @__PURE__ */ Symbol.for("palbase.backend.declarationRefusal");
3738
3881
  var DeclarationRefused = class extends Error {
@@ -3751,6 +3894,39 @@ function isDeclarationRefused(e) {
3751
3894
  }
3752
3895
  __name(isDeclarationRefused, "isDeclarationRefused");
3753
3896
 
3897
+ // src/db/unique.ts
3898
+ function uniqueKeysOf(table) {
3899
+ const columns = table.columns ?? {};
3900
+ const inlinePrimary = [], keys = [];
3901
+ for (const [name, value] of Object.entries(columns)) {
3902
+ const col2 = value && typeof value === "object" && "_def" in value ? value._def : value;
3903
+ if (col2?.primaryKey) inlinePrimary.push(name);
3904
+ if (col2?.unique) keys.push([
3905
+ name
3906
+ ]);
3907
+ }
3908
+ const primary = table.primaryKey ?? inlinePrimary;
3909
+ if (primary.length) keys.unshift([
3910
+ ...primary
3911
+ ]);
3912
+ for (const key of table.unique ?? []) keys.push([
3913
+ ...key.columns
3914
+ ]);
3915
+ const seen = /* @__PURE__ */ new Set();
3916
+ return keys.filter((key) => {
3917
+ if (!key.length || new Set(key).size !== key.length || key.some((col2) => !Object.hasOwn(columns, col2))) {
3918
+ throw new Error("Unique lookup requires a nonempty declared key of distinct, known columns");
3919
+ }
3920
+ const identity = JSON.stringify([
3921
+ ...key
3922
+ ].sort());
3923
+ if (seen.has(identity)) return false;
3924
+ seen.add(identity);
3925
+ return true;
3926
+ });
3927
+ }
3928
+ __name(uniqueKeysOf, "uniqueKeysOf");
3929
+
3754
3930
  // src/db/env-gen.ts
3755
3931
  function baseTsType(def) {
3756
3932
  if (def.codec !== void 0 && def.codec in CODECS) {
@@ -3917,6 +4093,7 @@ function tableBlock(table, relations, indent) {
3917
4093
  ...insertLines,
3918
4094
  `${indent} };`,
3919
4095
  `${indent} relations: {${relEntries === "" ? "" : ` ${relEntries} `}};`,
4096
+ `${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,
3920
4097
  // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
3921
4098
  // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
3922
4099
  // mevcut şemaların d.ts'i bayt-aynı kalsın.
@@ -5455,7 +5632,188 @@ function getJobConfig(ctor, container) {
5455
5632
  __name(getJobConfig, "getJobConfig");
5456
5633
 
5457
5634
  // src/index.ts
5635
+ var import_zod3 = require("zod");
5636
+
5637
+ // src/db/query.ts
5458
5638
  var import_zod2 = require("zod");
5639
+ var import_zod_to_openapi2 = require("@asteasolutions/zod-to-openapi");
5640
+
5641
+ // src/db/query-contract.ts
5642
+ function queryColumnContract(column) {
5643
+ const def = column && typeof column === "object" && "_def" in column ? column._def : column;
5644
+ if (!def?.type) throw new Error("Query contract requires declared column types");
5645
+ if (def.transform !== void 0 && def.codec === void 0) throw new Error("Query contracts require a named codec instead of a free-form column transform");
5646
+ return {
5647
+ type: def.type,
5648
+ nullable: def.nullable === true,
5649
+ ...def.codec === void 0 ? {} : {
5650
+ codec: def.codec
5651
+ },
5652
+ ...def.enumValues === void 0 ? {} : {
5653
+ enumValues: [
5654
+ ...def.enumValues
5655
+ ]
5656
+ },
5657
+ ...def.dimensions === void 0 ? {} : {
5658
+ dimensions: def.dimensions
5659
+ }
5660
+ };
5661
+ }
5662
+ __name(queryColumnContract, "queryColumnContract");
5663
+ function stableContract(value) {
5664
+ if (Array.isArray(value)) return `[${value.map(stableContract).join(",")}]`;
5665
+ if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableContract(value[key])}`).join(",")}}`;
5666
+ return JSON.stringify(value) ?? "null";
5667
+ }
5668
+ __name(stableContract, "stableContract");
5669
+
5670
+ // src/db/query.ts
5671
+ (0, import_zod_to_openapi2.extendZodWithOpenApi)(import_zod2.z);
5672
+ function responseColumn(column, validator) {
5673
+ const contract = queryColumnContract(column);
5674
+ let schema;
5675
+ if (validator) return validator;
5676
+ if (contract.codec === "number") schema = import_zod2.z.number().finite();
5677
+ else if (contract.codec === "decimal") schema = import_zod2.z.string();
5678
+ else switch (contract.type) {
5679
+ case "integer":
5680
+ schema = import_zod2.z.number().int().min(-2147483648).max(2147483647);
5681
+ break;
5682
+ case "boolean":
5683
+ schema = import_zod2.z.boolean();
5684
+ break;
5685
+ case "vector":
5686
+ schema = import_zod2.z.array(import_zod2.z.number().finite());
5687
+ break;
5688
+ case "enum": {
5689
+ const values = contract.enumValues;
5690
+ if (!values?.length) throw new Error("Query response requires declared enum values");
5691
+ schema = import_zod2.z.enum(values);
5692
+ break;
5693
+ }
5694
+ case "uuid":
5695
+ case "text":
5696
+ case "timestamp":
5697
+ case "numeric":
5698
+ case "bigint":
5699
+ schema = import_zod2.z.string();
5700
+ break;
5701
+ case "jsonb":
5702
+ throw new Error("Query response requires a fields validator for a selected jsonb column: its TypeScript payload is erased at runtime");
5703
+ default:
5704
+ throw new Error(`Query response does not support column type ${contract.type}`);
5705
+ }
5706
+ return contract.nullable ? schema.nullable() : schema;
5707
+ }
5708
+ __name(responseColumn, "responseColumn");
5709
+ function defineQuery(name, options) {
5710
+ if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_]{0,127}$/.test(name)) throw new Error("defineQuery requires a stable name of 1\u2013128 letters, digits or underscores");
5711
+ const table = declaredTableKey(options.table);
5712
+ const select = [
5713
+ ...options.select
5714
+ ];
5715
+ if (!select.length || new Set(select).size !== select.length) throw new Error(`Query ${name}: select must be explicit, nonempty and distinct`);
5716
+ const shape = {}, columns = {};
5717
+ for (const key of select) {
5718
+ if (!Object.hasOwn(options.table[TABLE_META].columns, key)) throw new Error(`Query ${name}: unknown column ${key}`);
5719
+ columns[key] = queryColumnContract(options.table[key]);
5720
+ shape[key] = responseColumn(options.table[key], options.fields?.[key]);
5721
+ }
5722
+ const response = import_zod2.z.array(import_zod2.z.object(shape).strict());
5723
+ const queryInput = options.input, where = options.where, limit = options.limit;
5724
+ const orderBy = options.orderBy === void 0 ? void 0 : JSON.parse(JSON.stringify(options.orderBy));
5725
+ const prepare = /* @__PURE__ */ __name((input) => {
5726
+ const parsed = queryInput.parse(input);
5727
+ const filter = where === void 0 ? {} : where(parsed);
5728
+ if (!filter || typeof filter !== "object" || Array.isArray(filter) || typeof filter.then === "function") {
5729
+ throw new Error(`Query ${name}: where must return a synchronous filter object`);
5730
+ }
5731
+ const size = typeof limit === "function" ? limit(parsed) : limit;
5732
+ if (limit !== void 0 && (typeof size !== "number" || !Number.isSafeInteger(size) || size < 0)) throw new Error(`Query ${name}: limit must produce a nonnegative safe integer`);
5733
+ return {
5734
+ name,
5735
+ table,
5736
+ columns: JSON.parse(JSON.stringify(columns)),
5737
+ where: filter,
5738
+ options: {
5739
+ select: [
5740
+ ...select
5741
+ ],
5742
+ ...orderBy === void 0 ? {} : {
5743
+ orderBy: structuredClone(orderBy)
5744
+ },
5745
+ ...limit === void 0 ? {} : {
5746
+ limit: size
5747
+ }
5748
+ }
5749
+ };
5750
+ }, "prepare");
5751
+ const attach = /* @__PURE__ */ __name((schema) => {
5752
+ const api = {
5753
+ queryName: name,
5754
+ input: queryInput,
5755
+ prepare,
5756
+ async run(database, input) {
5757
+ const request = prepare(input);
5758
+ const rows = await ("$readQuery" in database ? database.$readQuery(request) : database.readQuery(request));
5759
+ return schema.parse(rows);
5760
+ },
5761
+ sql(database, input) {
5762
+ const request = prepare(input);
5763
+ return "$compileQuery" in database ? database.$compileQuery(request) : database.compileQuery(request);
5764
+ },
5765
+ explain(database, input) {
5766
+ const request = prepare(input);
5767
+ return "$explainQuery" in database ? database.$explainQuery(request) : database.explainQuery(request);
5768
+ },
5769
+ contract() {
5770
+ const registry2 = new import_zod_to_openapi2.OpenAPIRegistry();
5771
+ registry2.register(`${name}Input`, queryInput);
5772
+ registry2.register(`${name}Response`, schema);
5773
+ return JSON.parse(JSON.stringify({
5774
+ name,
5775
+ table,
5776
+ select,
5777
+ columns,
5778
+ components: new import_zod_to_openapi2.OpenApiGeneratorV31(registry2.definitions).generateComponents().components
5779
+ }));
5780
+ }
5781
+ };
5782
+ for (const key of [
5783
+ "min",
5784
+ "max",
5785
+ "length",
5786
+ "describe",
5787
+ "openapi"
5788
+ ]) {
5789
+ const modify = schema[key].bind(schema);
5790
+ Object.defineProperty(schema, key, {
5791
+ value: /* @__PURE__ */ __name((...args) => attach(modify(...args)), "value"),
5792
+ configurable: true
5793
+ });
5794
+ }
5795
+ return Object.assign(schema, api);
5796
+ }, "attach");
5797
+ return attach(response);
5798
+ }
5799
+ __name(defineQuery, "defineQuery");
5800
+ function queryManifest(queries) {
5801
+ const sorted = [
5802
+ ...queries
5803
+ ].sort((a, b) => a.queryName.localeCompare(b.queryName));
5804
+ if (new Set(sorted.map((query) => query.queryName)).size !== sorted.length) throw new Error("Query manifest contains duplicate names");
5805
+ return JSON.parse(stableContract({
5806
+ version: 1,
5807
+ queries: sorted.map((query) => query.contract())
5808
+ }));
5809
+ }
5810
+ __name(queryManifest, "queryManifest");
5811
+ function assertQueryManifest(queries, baseline) {
5812
+ if (stableContract(queryManifest(queries)) !== stableContract(baseline)) {
5813
+ throw new Error("Query contract drift: compare queryManifest() with the committed manifest and review the API/client changes before updating it");
5814
+ }
5815
+ }
5816
+ __name(assertQueryManifest, "assertQueryManifest");
5459
5817
  // Annotate the CommonJS export names for ESM import in node:
5460
5818
  0 && (module.exports = {
5461
5819
  Auth,
@@ -5539,6 +5897,7 @@ var import_zod2 = require("zod");
5539
5897
  __runWithRuntime,
5540
5898
  __setRuntime,
5541
5899
  assertNoOrphanEntryPoints,
5900
+ assertQueryManifest,
5542
5901
  assertZeroArgConstructor,
5543
5902
  bigint,
5544
5903
  boolean,
@@ -5552,8 +5911,10 @@ var import_zod2 = require("zod");
5552
5911
  defineDefaultAuth,
5553
5912
  defineError,
5554
5913
  defineMiddleware,
5914
+ defineQuery,
5555
5915
  defineSchema,
5556
5916
  defineTable,
5917
+ defineWorkload,
5557
5918
  enumType,
5558
5919
  exprCtx,
5559
5920
  getErrorRegistry,
@@ -5589,6 +5950,7 @@ var import_zod2 = require("zod");
5589
5950
  ownerOnly,
5590
5951
  policy,
5591
5952
  publicChannel,
5953
+ queryManifest,
5592
5954
  raw,
5593
5955
  recordThrows,
5594
5956
  resolveEffectiveAuth,