@palbase/backend 30.0.0 → 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-5J5W75A6.js → chunk-5C5UCILO.js} +27 -325
  7. package/dist/chunk-5C5UCILO.js.map +1 -0
  8. package/dist/{chunk-VN7NMDUH.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 +87 -5
  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-5J5W75A6.js.map +0 -1
  61. package/dist/chunk-ENZ2RFFJ.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-VN7NMDUH.js.map +0 -1
  65. package/dist/chunk-VXPNPVAG.js +0 -40
  66. package/dist/chunk-VXPNPVAG.js.map +0 -1
  67. /package/dist/{chunk-VVMJEVQP.js.map → chunk-BRLJOXWS.js.map} +0 -0
@@ -827,7 +827,11 @@ function qualifiedTableKey(schemaName, tableName) {
827
827
  __name(qualifiedTableKey, "qualifiedTableKey");
828
828
 
829
829
  // src/runtime.ts
830
- var __requestALS = new import_node_async_hooks.AsyncLocalStorage();
830
+ var REQUEST_ALS = /* @__PURE__ */ Symbol.for("palbase.backend.requestALS");
831
+ var __requestALS = (() => {
832
+ const g = globalThis;
833
+ return g[REQUEST_ALS] ??= new import_node_async_hooks.AsyncLocalStorage();
834
+ })();
831
835
  var runtime = null;
832
836
  function __runWithRuntime(services, fn) {
833
837
  return __requestALS.run({
@@ -1093,8 +1097,21 @@ var Flags = Object.assign({
1093
1097
  * the runtime proxy, so caching would leak one request's sibling into
1094
1098
  * another concurrent request. Mirrors `Database.asService()`.
1095
1099
  */
1096
- asService() {
1100
+ $asService() {
1097
1101
  return rawFlags.asService();
1102
+ },
1103
+ /**
1104
+ * The name this member carried before 31.0.0.
1105
+ *
1106
+ * It does NOT work silently. A retired member that quietly keeps returning
1107
+ * is how a rename becomes a mystery: the old call site goes on compiling,
1108
+ * the new name never spreads, and the two live side by side until somebody
1109
+ * greps for one and misses half the codebase. `Database` made this split
1110
+ * first (`$asService`), and this JSDoc promised "exactly like
1111
+ * Database.$asService()" while the promise went unkept.
1112
+ */
1113
+ asService() {
1114
+ throw new Error("Flags.asService() was renamed to Flags.$asService() in 31.0.0 \u2014 system members carry the `$` prefix, like Database.$asService().");
1098
1115
  }
1099
1116
  });
1100
1117
  var Realtime = makeServiceProxy("Realtime");
@@ -1463,6 +1480,25 @@ function makeMemoryCache(opts = {}) {
1463
1480
  }
1464
1481
  __name(makeMemoryCache, "makeMemoryCache");
1465
1482
 
1483
+ // src/db/columns.ts
1484
+ var CODECS = {
1485
+ // Exact-precision column → JS number. Safe below 2^53; a value above it is
1486
+ // not representable and the author wants `asDecimal()` instead.
1487
+ number: {
1488
+ fromDb: /* @__PURE__ */ __name((v) => Number(v), "fromDb"),
1489
+ toDb: /* @__PURE__ */ __name((v) => String(v), "toDb"),
1490
+ tsType: "number"
1491
+ },
1492
+ // Exact-precision column → the string Postgres sent. It exists so the
1493
+ // DECLARATION is explicit: "this column is a decimal I handle as text",
1494
+ // rather than the ABSENCE of a declaration meaning the same thing by default.
1495
+ decimal: {
1496
+ fromDb: /* @__PURE__ */ __name((v) => String(v), "fromDb"),
1497
+ toDb: /* @__PURE__ */ __name((v) => String(v), "toDb"),
1498
+ tsType: "string"
1499
+ }
1500
+ };
1501
+
1466
1502
  // src/db/env-gen.ts
1467
1503
  function forwardName(column) {
1468
1504
  return column.endsWith("_id") ? column.slice(0, -3) : column;
@@ -1676,6 +1712,15 @@ function transformsOf(schema, table) {
1676
1712
  if (def) {
1677
1713
  for (const [col, c] of Object.entries(def.columns ?? {})) {
1678
1714
  const d = c !== null && typeof c === "object" && "_def" in c ? c._def : c;
1715
+ const codec = d?.codec;
1716
+ if (typeof codec === "string" && codec in CODECS) {
1717
+ const c2 = CODECS[codec];
1718
+ out.set(col, {
1719
+ fromDb: c2.fromDb,
1720
+ toDb: c2.toDb
1721
+ });
1722
+ continue;
1723
+ }
1679
1724
  const t = d?.transform;
1680
1725
  if (t !== null && typeof t === "object") {
1681
1726
  out.set(col, t);
@@ -2011,6 +2056,29 @@ function selectClause(table, known, select) {
2011
2056
  }).join(", ");
2012
2057
  }
2013
2058
  __name(selectClause, "selectClause");
2059
+ function quoteLiteral(v) {
2060
+ return `'${v.replace(/'/g, "''")}'`;
2061
+ }
2062
+ __name(quoteLiteral, "quoteLiteral");
2063
+ function orderClauseFor(table, known, orderBy, alias) {
2064
+ if (orderBy === void 0 || orderBy === null) return "";
2065
+ const items = Array.isArray(orderBy) ? orderBy : [
2066
+ orderBy
2067
+ ];
2068
+ if (items.length === 0) return "";
2069
+ const rendered = items.map((o) => {
2070
+ const col = o.column;
2071
+ const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);
2072
+ if (known !== null ? !known.has(col) : !shapeOK) {
2073
+ throw new Error(`with(${table}): orderBy kolonu "${col}" tabloda yok`);
2074
+ }
2075
+ const dir = o.direction === "desc" ? "DESC" : "ASC";
2076
+ const nulls = o.nulls === "first" ? " NULLS FIRST" : o.nulls === "last" ? " NULLS LAST" : "";
2077
+ return `${alias}.${quoteIdent(col)} ${dir}${nulls}`;
2078
+ });
2079
+ return ` ORDER BY ${rendered.join(", ")}`;
2080
+ }
2081
+ __name(orderClauseFor, "orderClauseFor");
2014
2082
  function orderClause(table, known, orderBy) {
2015
2083
  if (!orderBy) return "";
2016
2084
  const items = Array.isArray(orderBy) ? orderBy : [
@@ -2314,6 +2382,65 @@ function aggregateExpr(table, fn, col, alias) {
2314
2382
  return t !== null && NUMERIC_PG_TYPES.has(t) && t !== "integer" ? `${fn}(${q})::text AS ${quoteIdent(alias)}` : `${fn}(${q}) AS ${quoteIdent(alias)}`;
2315
2383
  }
2316
2384
  __name(aggregateExpr, "aggregateExpr");
2385
+ function jsonObjectFor(table, cols, alias) {
2386
+ const pairs = cols.map((c) => {
2387
+ const t = columnTypeOf(table, c);
2388
+ const expr = t !== null && (t === "numeric" || t === "bigint") ? `${alias}.${quoteIdent(c)}::text` : `${alias}.${quoteIdent(c)}`;
2389
+ return `${quoteLiteral(c)}, ${expr}`;
2390
+ });
2391
+ return `json_build_object(${pairs.join(", ")})`;
2392
+ }
2393
+ __name(jsonObjectFor, "jsonObjectFor");
2394
+ function withClauses(table, spec, add, caller) {
2395
+ const rels = currentRelations.get(table) ?? [];
2396
+ const select = [];
2397
+ const joins = [];
2398
+ let i = 0;
2399
+ for (const [name, opt] of Object.entries(spec)) {
2400
+ if (opt === false || opt === void 0) continue;
2401
+ const rel = rels.find((r) => r.name === name);
2402
+ if (rel === void 0) {
2403
+ const known = rels.map((r) => r.name).sort();
2404
+ throw new Error(`${caller}(${table}): with.${name} diye bir ili\u015Fki yok` + (known.length > 0 ? ` (bilinenler: ${known.join(", ")})` : `. Bu tablo hi\xE7 yabanc\u0131 anahtar bildirmiyor ve ili\u015Fkiler onlardan T\xDCRET\u0130L\u0130R`) + `. \u0130li\u015Fkiler references(() => <tablo>.<kolon>) ile bildirilir.`);
2405
+ }
2406
+ const ourCol = rel.kind === "many" ? primaryKeyOf(table) : rel.via;
2407
+ const theirCol = rel.kind === "many" ? rel.via : primaryKeyOf(rel.to);
2408
+ if (ourCol === null || theirCol === null) {
2409
+ throw new Error(`${caller}(${table}): with.${name} birincil anahtar bilmeden kurulamaz \u2014 ili\u015Fkinin bir ucu tablonun PK's\u0131 ve bu tablo tek kolonlu bir PK bildirmiyor.`);
2410
+ }
2411
+ const o = typeof opt === "object" && opt !== null ? opt : {};
2412
+ const childAlias = `w${++i}`;
2413
+ const childKnown = schemaColumns(rel.to);
2414
+ const childCols = Array.isArray(o["select"]) && o["select"].length > 0 ? o["select"] : childKnown !== null ? [
2415
+ ...childKnown
2416
+ ] : [];
2417
+ if (childCols.length === 0) {
2418
+ throw new Error(`${caller}(${table}): with.${name} i\xE7in "${rel.to}" tablosunun kolonlar\u0131 bilinmiyor \u2014 select ile hangi kolonlar\u0131 istedi\u011Finizi yaz\u0131n.`);
2419
+ }
2420
+ for (const c of childCols) {
2421
+ if (childKnown !== null && !childKnown.has(c)) {
2422
+ throw new Error(`${caller}(${table}): with.${name}.select kolonu "${c}" "${rel.to}" tablosunda yok`);
2423
+ }
2424
+ }
2425
+ const obj = jsonObjectFor(rel.to, childCols, childAlias);
2426
+ const innerWhere = o["where"] !== void 0 && o["where"] !== null ? compileWhereBare(rel.to, childKnown, o["where"], add, caller, childAlias, i) : "";
2427
+ const link = `${childAlias}.${quoteIdent(theirCol)} = t.${quoteIdent(ourCol)}`;
2428
+ const cond = innerWhere === "" ? link : `${link} AND ${innerWhere}`;
2429
+ const inner = orderClauseFor(rel.to, childKnown, o["orderBy"], childAlias) + limitClause(o["limit"]);
2430
+ const outAlias = `wj${i}`;
2431
+ if (rel.kind === "many") {
2432
+ joins.push(`LEFT JOIN LATERAL (SELECT coalesce(json_agg(x.o), '[]'::json) AS d FROM (SELECT ${obj} AS o FROM ${quoteTable(rel.to)} ${childAlias} WHERE ${cond}${inner}) x) ${quoteIdent(outAlias)} ON true`);
2433
+ } else {
2434
+ joins.push(`LEFT JOIN LATERAL (SELECT ${obj} AS d FROM ${quoteTable(rel.to)} ${childAlias} WHERE ${cond}${inner} LIMIT 1) ${quoteIdent(outAlias)} ON true`);
2435
+ }
2436
+ select.push(`${quoteIdent(outAlias)}."d" AS ${quoteIdent(name)}`);
2437
+ }
2438
+ return {
2439
+ select,
2440
+ joins
2441
+ };
2442
+ }
2443
+ __name(withClauses, "withClauses");
2317
2444
  function createOps(tx) {
2318
2445
  const at = /* @__PURE__ */ __name(() => resolveTx(tx), "at");
2319
2446
  const ops = {
@@ -2757,7 +2884,13 @@ function createOps(tx) {
2757
2884
  const limit = limitClause(opts.limit);
2758
2885
  const offset = offsetClause(opts.offset, opts.limit);
2759
2886
  const cols = selectClause(table, known, opts.select);
2760
- const sql = `SELECT ${cols} FROM ${quoteTable(table)} t WHERE true${whereSql}${order}${limit}${offset}`;
2887
+ const w = opts.with !== void 0 && Object.keys(opts.with).length > 0 ? withClauses(table, opts.with, add, "findMany") : {
2888
+ select: [],
2889
+ joins: []
2890
+ };
2891
+ const selectList = w.select.length > 0 ? `${cols === "*" ? "t.*" : cols}, ${w.select.join(", ")}` : cols;
2892
+ const joinSql = w.joins.length > 0 ? ` ${w.joins.join(" ")}` : "";
2893
+ const sql = `SELECT ${selectList} FROM ${quoteTable(table)} t${joinSql} WHERE true${whereSql}${order}${limit}${offset}`;
2761
2894
  return asTableRows(table, await (await at()).unsafe(sql, params));
2762
2895
  },
2763
2896
  /**