@palbase/backend 30.0.1 → 32.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 (67) hide show
  1. package/dist/bin/palbase-backend.cjs +136 -3
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +7 -7
  4. package/dist/{chunk-TWX6JTGJ.js → chunk-26GH54D2.js} +3 -5
  5. package/dist/{chunk-TWX6JTGJ.js.map → chunk-26GH54D2.js.map} +1 -1
  6. package/dist/{chunk-YRVIWHJC.js → chunk-5C5UCILO.js} +23 -323
  7. package/dist/chunk-5C5UCILO.js.map +1 -0
  8. package/dist/{chunk-RADVOY7Y.js → chunk-AZJIKCOR.js} +113 -15
  9. package/dist/chunk-AZJIKCOR.js.map +1 -0
  10. package/dist/{chunk-VVMJEVQP.js → chunk-BRLJOXWS.js} +2 -2
  11. package/dist/{chunk-3TUJWHC2.js → chunk-IXAX5CON.js} +378 -19
  12. package/dist/chunk-IXAX5CON.js.map +1 -0
  13. package/dist/{chunk-CGNN2PUH.js → chunk-KATPXCJ5.js} +37 -4
  14. package/dist/{chunk-CGNN2PUH.js.map → chunk-KATPXCJ5.js.map} +1 -1
  15. package/dist/chunk-KGP6ALIU.js +361 -0
  16. package/dist/chunk-KGP6ALIU.js.map +1 -0
  17. package/dist/chunk-XEGZ3S2Q.js +346 -0
  18. package/dist/chunk-XEGZ3S2Q.js.map +1 -0
  19. package/dist/{chunk-ENZ2RFFJ.js → chunk-Z4CZRMNF.js} +3 -310
  20. package/dist/chunk-Z4CZRMNF.js.map +1 -0
  21. package/dist/db/index.cjs +29 -0
  22. package/dist/db/index.cjs.map +1 -1
  23. package/dist/db/index.d.cts +1 -1
  24. package/dist/db/index.d.ts +1 -1
  25. package/dist/db/index.js +12 -13
  26. package/dist/engine/index.cjs +136 -3
  27. package/dist/engine/index.cjs.map +1 -1
  28. package/dist/engine/index.d.cts +3 -3
  29. package/dist/engine/index.d.ts +3 -3
  30. package/dist/engine/index.js +7 -7
  31. package/dist/{index-b-Q3l7W5.d.ts → index-BILC9WwS.d.ts} +9 -2
  32. package/dist/{index-8qy3kIuA.d.ts → index-BgWnP07a.d.ts} +119 -17
  33. package/dist/{index-Zi7MptvP.d.cts → index-CWGiJ2Up.d.cts} +9 -2
  34. package/dist/{index-DtCgaZAg.d.cts → index-DgYkdNT9.d.cts} +119 -17
  35. package/dist/index.cjs +83 -3
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +6 -23
  38. package/dist/index.d.ts +6 -23
  39. package/dist/index.js +48 -48
  40. package/dist/index.js.map +1 -1
  41. package/dist/openapi/index.d.cts +2 -2
  42. package/dist/openapi/index.d.ts +2 -2
  43. package/dist/openapi/index.js +3 -4
  44. package/dist/openapi/index.js.map +1 -1
  45. package/dist/{registry-CEYLH-Iz.d.cts → registry-BcRYIQ-R.d.cts} +1 -1
  46. package/dist/{registry-BGJ-Al6F.d.ts → registry-ClzjxIWy.d.ts} +1 -1
  47. package/dist/test/index.cjs +703 -14
  48. package/dist/test/index.cjs.map +1 -1
  49. package/dist/test/index.d.cts +59 -4
  50. package/dist/test/index.d.ts +59 -4
  51. package/dist/test/index.js +51 -13
  52. package/dist/test/index.js.map +1 -1
  53. package/docs/README.md +1 -1
  54. package/docs/database.md +54 -0
  55. package/docs/llms-full.txt +87 -1
  56. package/docs/schema.md +32 -0
  57. package/package.json +1 -1
  58. package/template/package.json +1 -1
  59. package/dist/chunk-3TUJWHC2.js.map +0 -1
  60. package/dist/chunk-ENZ2RFFJ.js.map +0 -1
  61. package/dist/chunk-RADVOY7Y.js.map +0 -1
  62. package/dist/chunk-SG4UTNOP.js +0 -374
  63. package/dist/chunk-SG4UTNOP.js.map +0 -1
  64. package/dist/chunk-VXPNPVAG.js +0 -40
  65. package/dist/chunk-VXPNPVAG.js.map +0 -1
  66. package/dist/chunk-YRVIWHJC.js.map +0 -1
  67. /package/dist/{chunk-VVMJEVQP.js.map → chunk-BRLJOXWS.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -1270,7 +1270,11 @@ function toSchemaJSON(schemas) {
1270
1270
  __name(toSchemaJSON, "toSchemaJSON");
1271
1271
 
1272
1272
  // src/runtime.ts
1273
- var __requestALS = new import_node_async_hooks.AsyncLocalStorage();
1273
+ var REQUEST_ALS = /* @__PURE__ */ Symbol.for("palbase.backend.requestALS");
1274
+ var __requestALS = (() => {
1275
+ const g = globalThis;
1276
+ return g[REQUEST_ALS] ??= new import_node_async_hooks.AsyncLocalStorage();
1277
+ })();
1274
1278
  var runtime = null;
1275
1279
  function __setRuntime(services) {
1276
1280
  runtime = services;
@@ -1559,8 +1563,21 @@ var Flags = Object.assign({
1559
1563
  * the runtime proxy, so caching would leak one request's sibling into
1560
1564
  * another concurrent request. Mirrors `Database.asService()`.
1561
1565
  */
1562
- asService() {
1566
+ $asService() {
1563
1567
  return rawFlags.asService();
1568
+ },
1569
+ /**
1570
+ * The name this member carried before 31.0.0.
1571
+ *
1572
+ * It does NOT work silently. A retired member that quietly keeps returning
1573
+ * is how a rename becomes a mystery: the old call site goes on compiling,
1574
+ * the new name never spreads, and the two live side by side until somebody
1575
+ * greps for one and misses half the codebase. `Database` made this split
1576
+ * first (`$asService`), and this JSDoc promised "exactly like
1577
+ * Database.$asService()" while the promise went unkept.
1578
+ */
1579
+ asService() {
1580
+ throw new Error("Flags.asService() was renamed to Flags.$asService() in 31.0.0 \u2014 system members carry the `$` prefix, like Database.$asService().");
1564
1581
  }
1565
1582
  });
1566
1583
  var Realtime = makeServiceProxy("Realtime");
@@ -2103,7 +2120,7 @@ function buildFlagsClient(http, cfg) {
2103
2120
  return {
2104
2121
  data: null,
2105
2122
  error: {
2106
- message: "setOverride requires a signed-in user; use Flags.asService().setOverrideForUser(userId, key, value) for cross-user writes"
2123
+ message: "setOverride requires a signed-in user; use Flags.$asService().setOverrideForUser(userId, key, value) for cross-user writes"
2107
2124
  },
2108
2125
  status: 400
2109
2126
  };
@@ -3295,6 +3312,23 @@ function isPalbaseExtension(name) {
3295
3312
  __name(isPalbaseExtension, "isPalbaseExtension");
3296
3313
 
3297
3314
  // src/db/columns.ts
3315
+ var CODECS = {
3316
+ // Exact-precision column → JS number. Safe below 2^53; a value above it is
3317
+ // not representable and the author wants `asDecimal()` instead.
3318
+ number: {
3319
+ fromDb: /* @__PURE__ */ __name((v) => Number(v), "fromDb"),
3320
+ toDb: /* @__PURE__ */ __name((v) => String(v), "toDb"),
3321
+ tsType: "number"
3322
+ },
3323
+ // Exact-precision column → the string Postgres sent. It exists so the
3324
+ // DECLARATION is explicit: "this column is a decimal I handle as text",
3325
+ // rather than the ABSENCE of a declaration meaning the same thing by default.
3326
+ decimal: {
3327
+ fromDb: /* @__PURE__ */ __name((v) => String(v), "fromDb"),
3328
+ toDb: /* @__PURE__ */ __name((v) => String(v), "toDb"),
3329
+ tsType: "string"
3330
+ }
3331
+ };
3298
3332
  function refuseOnVector(def, modifier) {
3299
3333
  if (def.type === "vector") {
3300
3334
  throw new Error(`vector column: .${modifier}() is not supported (FR-002 \u2014 allowed: nullable()/notNull())`);
@@ -3498,6 +3532,35 @@ var ColumnBuilder = class _ColumnBuilder {
3498
3532
  * A transform is a PROJECTION, never a constraint: it lives only in this
3499
3533
  * process, so it can neither validate nor migrate what is stored.
3500
3534
  */
3535
+ /**
3536
+ * Surface this exact-precision column as a JS `number` (FR-001).
3537
+ *
3538
+ * `numeric`/`bigint` arrive as strings because a JS number cannot hold their
3539
+ * full range — correct, and exactly why this exists: application code that
3540
+ * does arithmetic on the column otherwise rewrites the same `Number(row.x)` /
3541
+ * `String(v)` pair in every caller, and each rewrite is a place the two
3542
+ * directions can drift apart.
3543
+ */
3544
+ asNumber() {
3545
+ return this.withCodec("number", "asNumber");
3546
+ }
3547
+ /**
3548
+ * Surface this exact-precision column as a `string` — the value Postgres
3549
+ * sent, DECLARED rather than defaulted (FR-001).
3550
+ */
3551
+ asDecimal() {
3552
+ return this.withCodec("decimal", "asDecimal");
3553
+ }
3554
+ withCodec(codec, method) {
3555
+ if (this._def.type !== "bigint" && this._def.type !== "numeric") {
3556
+ throw new Error(`${this._def.type} column: .${method}() is only available on bigint()/numeric() \u2014 those are the exact-precision types that surface as string.`);
3557
+ }
3558
+ if (this._def.transform !== void 0) {
3559
+ throw new Error(`.${method}() and .transform() are two ways to say the same thing on one column \u2014 keep .${method}().`);
3560
+ }
3561
+ this._def.codec = codec;
3562
+ return new _ColumnBuilder(this._def.type, this._def);
3563
+ }
3501
3564
  transform(fns) {
3502
3565
  this._def.transform = fns;
3503
3566
  return new _ColumnBuilder(this._def.type, this._def);
@@ -3643,6 +3706,9 @@ __name(isDeclarationRefused, "isDeclarationRefused");
3643
3706
 
3644
3707
  // src/db/env-gen.ts
3645
3708
  function baseTsType(def) {
3709
+ if (def.codec !== void 0 && def.codec in CODECS) {
3710
+ return CODECS[def.codec].tsType;
3711
+ }
3646
3712
  switch (def.type) {
3647
3713
  case "uuid":
3648
3714
  case "text":
@@ -3820,7 +3886,21 @@ function tableBlock(table, relations, indent) {
3820
3886
  ].join("\n");
3821
3887
  }
3822
3888
  __name(tableBlock, "tableBlock");
3889
+ function refuseFreeFormTransforms(schemas) {
3890
+ for (const schema of schemas) {
3891
+ for (const table of Object.values(schema.tables)) {
3892
+ for (const [col2, builder] of Object.entries(table.columns)) {
3893
+ const def = builder._def;
3894
+ if (def.transform === void 0 || def.codec !== void 0) continue;
3895
+ const where = qualifiedTableKey(schema.name, table.name);
3896
+ throw new DeclarationRefused(`table "${where}" column "${col2}" declares .transform<T>(): its target type does not exist at runtime, so the generated types would say something the engine contradicts. Declare a named codec instead \u2014 .asNumber() for a JS number, .asDecimal() for the exact string.`);
3897
+ }
3898
+ }
3899
+ }
3900
+ }
3901
+ __name(refuseFreeFormTransforms, "refuseFreeFormTransforms");
3823
3902
  function makeEnvDts(schemas) {
3903
+ refuseFreeFormTransforms(schemas);
3824
3904
  const relations = buildRelations(schemas);
3825
3905
  const publicSchema = schemas.find((s) => s.name === "public");
3826
3906
  const others = schemas.filter((s) => s.name !== "public");