@palbase/backend 27.0.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 +165 -39
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +4 -4
  4. package/dist/{chunk-GYK6QYS4.js → chunk-3TUJWHC2.js} +28 -3
  5. package/dist/chunk-3TUJWHC2.js.map +1 -0
  6. package/dist/{chunk-OO7R25AI.js → chunk-75YROPRZ.js} +118 -39
  7. package/dist/chunk-75YROPRZ.js.map +1 -0
  8. package/dist/{chunk-TS4U7NBD.js → chunk-IVZERLTM.js} +2 -2
  9. package/dist/{chunk-I3C4PFIW.js → chunk-RVP6BTEZ.js} +63 -6
  10. package/dist/chunk-RVP6BTEZ.js.map +1 -0
  11. package/dist/{chunk-DRZFQRJI.js → chunk-SNDXY565.js} +3 -2
  12. package/dist/chunk-SNDXY565.js.map +1 -0
  13. package/dist/db/index.cjs +30 -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 +175 -39
  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-VtToZmUm.d.cts → index-9C3JHxg-.d.cts} +112 -5
  24. package/dist/{index-NuzRCuxe.d.ts → index-BbvOoZFr.d.ts} +112 -5
  25. package/dist/{index-Bve7BBTL.d.cts → index-DtISj9QX.d.cts} +125 -22
  26. package/dist/{index-BrvvxSpn.d.ts → index-dTTLlHIn.d.ts} +125 -22
  27. package/dist/index.cjs +93 -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-B0eyOF9x.d.ts → registry-JQNIX-eA.d.ts} +1 -1
  36. package/dist/{registry-Bk9_rbNd.d.cts → registry-qIPM5BQe.d.cts} +1 -1
  37. package/dist/test/index.cjs +100 -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 +88 -6
  42. package/dist/test/index.js.map +1 -1
  43. package/docs/README.md +1 -1
  44. package/docs/database.md +103 -1
  45. package/docs/llms-full.txt +104 -2
  46. package/package.json +1 -1
  47. package/template/package.json +1 -1
  48. package/dist/chunk-DRZFQRJI.js.map +0 -1
  49. package/dist/chunk-GYK6QYS4.js.map +0 -1
  50. package/dist/chunk-I3C4PFIW.js.map +0 -1
  51. package/dist/chunk-OO7R25AI.js.map +0 -1
  52. /package/dist/{chunk-TS4U7NBD.js.map → chunk-IVZERLTM.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { OpenApiGeneratorV31 } from '@asteasolutions/zod-to-openapi';
2
2
  import { ZodTypeAny } from 'zod';
3
- import { A as AuthSpec, R as RateLimitConfig } from '../index-Bve7BBTL.cjs';
4
- import { P as ParamMeta, T as ThrowDescriptor, U as UploadConfig, S as SseConfig } from '../registry-Bk9_rbNd.cjs';
3
+ import { A as AuthSpec, R as RateLimitConfig } from '../index-DtISj9QX.cjs';
4
+ import { P as ParamMeta, T as ThrowDescriptor, U as UploadConfig, S as SseConfig } from '../registry-qIPM5BQe.cjs';
5
5
  import '../db/env.cjs';
6
6
  import '../stack.cjs';
7
7
  import 'node:async_hooks';
@@ -1,7 +1,7 @@
1
1
  import { OpenApiGeneratorV31 } from '@asteasolutions/zod-to-openapi';
2
2
  import { ZodTypeAny } from 'zod';
3
- import { A as AuthSpec, R as RateLimitConfig } from '../index-BrvvxSpn.js';
4
- import { P as ParamMeta, T as ThrowDescriptor, U as UploadConfig, S as SseConfig } from '../registry-B0eyOF9x.js';
3
+ import { A as AuthSpec, R as RateLimitConfig } from '../index-dTTLlHIn.js';
4
+ import { P as ParamMeta, T as ThrowDescriptor, U as UploadConfig, S as SseConfig } from '../registry-JQNIX-eA.js';
5
5
  import '../db/env.js';
6
6
  import '../stack.js';
7
7
  import 'node:async_hooks';
@@ -1,4 +1,4 @@
1
- import { A as AuthSpec, R as RateLimitConfig } from './index-BrvvxSpn.js';
1
+ import { A as AuthSpec, R as RateLimitConfig } from './index-dTTLlHIn.js';
2
2
  import { ZodTypeAny } from 'zod';
3
3
  import { PalbaseBucketName } from './stack.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { A as AuthSpec, R as RateLimitConfig } from './index-Bve7BBTL.cjs';
1
+ import { A as AuthSpec, R as RateLimitConfig } from './index-DtISj9QX.cjs';
2
2
  import { ZodTypeAny } from 'zod';
3
3
  import { PalbaseBucketName } from './stack.cjs';
4
4
 
@@ -366,6 +366,16 @@ function isSqlFragment(v) {
366
366
  }
367
367
  __name(isSqlFragment, "isSqlFragment");
368
368
  var TX_EXPR = /* @__PURE__ */ Symbol.for("palbase.tx.expr");
369
+ function isNowExpr(v) {
370
+ if (!isColumnExpr(v)) return false;
371
+ try {
372
+ const e = v[TX_EXPR];
373
+ return typeof e === "object" && e !== null && e.fn === "now";
374
+ } catch {
375
+ return false;
376
+ }
377
+ }
378
+ __name(isNowExpr, "isNowExpr");
369
379
  function isColumnExpr(v) {
370
380
  if (typeof v !== "object" && typeof v !== "function") return false;
371
381
  if (v === null) return false;
@@ -379,8 +389,11 @@ __name(isColumnExpr, "isColumnExpr");
379
389
  function assertNoExpressionHandles(caller, table, cols, data) {
380
390
  for (const c of cols) {
381
391
  const v = data[c];
392
+ if (isNowExpr(v)) {
393
+ 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() }).`);
394
+ }
382
395
  if (isColumnExpr(v)) {
383
- 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.`);
396
+ 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.`);
384
397
  }
385
398
  if (isColRef(v)) {
386
399
  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.`);
@@ -448,6 +461,7 @@ function assertUsableFilter(caller, table, where) {
448
461
  }
449
462
  if (cond === null || typeof cond !== "object" || Array.isArray(cond)) continue;
450
463
  if (isColRef(cond)) continue;
464
+ if (isNowExpr(cond)) continue;
451
465
  const entries = Object.entries(cond);
452
466
  if (entries.length === 0) {
453
467
  throw new Error(`${caller}(${table}): where.${col} bo\u015F bir operat\xF6r nesnesi ({}) \u2014 hi\xE7bir ko\u015Ful \xFCretmez, yani bu alan filtreden sessizce D\xDC\u015EERD\u0130. Ko\u015Ful kurulmayacaksa anahtar\u0131 filtreye hi\xE7 koymay\u0131n (D-21).`);
@@ -699,9 +713,25 @@ function cmp(a, b, op) {
699
713
  __name(cmp, "cmp");
700
714
  function matchesCell(caller, table, row, key, cond) {
701
715
  if (isColRef(cond)) return cmp(row[key], row[cond.$col], "eq");
716
+ if (isNowExpr(cond)) return cmp(row[key], (/* @__PURE__ */ new Date()).toISOString(), "eq");
702
717
  if (cond !== null && typeof cond === "object" && !Array.isArray(cond)) {
703
718
  return Object.entries(cond).every(([op, v]) => {
704
719
  const cell = row[key];
720
+ if (isNowExpr(v)) {
721
+ if (![
722
+ "neq",
723
+ "gt",
724
+ "gte",
725
+ "lt",
726
+ "lte"
727
+ ].includes(op)) {
728
+ throw new Error(`${caller}(${table}): where.${key}.${op} now() ile kullan\u0131lamaz`);
729
+ }
730
+ return cmp(cell, (/* @__PURE__ */ new Date()).toISOString(), op);
731
+ }
732
+ if (isColumnExpr(v)) {
733
+ throw new Error(`${caller}(${table}): where.${key}.${op} bir YAZMA ifadesi ald\u0131 (increment/decrement) \u2014 kar\u015F\u0131la\u015Ft\u0131rma de\u011Feri de\u011Fil. Sunucu saati i\xE7in now() kullan\u0131n.`);
734
+ }
705
735
  if (isColRef(v)) {
706
736
  if (![
707
737
  "neq",
@@ -777,6 +807,22 @@ function createMockDB() {
777
807
  ]);
778
808
  }
779
809
  __name(track, "track");
810
+ function resolveInsertValues(caller, table, data) {
811
+ const out = {};
812
+ for (const [k, v] of Object.entries(data)) {
813
+ const expr = columnExprOf(v);
814
+ if (expr !== null && expr.fn === "now") {
815
+ out[k] = (/* @__PURE__ */ new Date()).toISOString();
816
+ continue;
817
+ }
818
+ if (expr !== null) {
819
+ throw new Error(`${caller}(${table}): "${k}" ${expr.fn === "inc" ? "increment()" : "decrement()"} ald\u0131 \u2014 sat\u0131r HEN\xDCZ YOK, yani "kolonun \u015Fu anki de\u011Feri" diye bir \u015Fey yok.`);
820
+ }
821
+ out[k] = v;
822
+ }
823
+ return out;
824
+ }
825
+ __name(resolveInsertValues, "resolveInsertValues");
780
826
  const ops = {
781
827
  // The bulk ops and count run against the SAME in-memory store the direct
782
828
  // ops write to, so a test that writes three rows and counts them gets 3 —
@@ -839,7 +885,8 @@ function createMockDB() {
839
885
  async query(_sql, _params) {
840
886
  return [];
841
887
  },
842
- async insert(table, data) {
888
+ async insert(table, raw) {
889
+ const data = resolveInsertValues("insert", table, raw);
843
890
  assertUsableWriteValues("insert", table, Object.keys(data), data);
844
891
  assertNoExpressionHandles("insert", table, Object.keys(data), data);
845
892
  const record = {
@@ -851,6 +898,38 @@ function createMockDB() {
851
898
  return record;
852
899
  },
853
900
  /**
901
+ * `insertMany` — motorla PARİTE, ANAHTAR KÜMESİ kuralı dahil.
902
+ *
903
+ * Fake bu kuralı bilmeseydi farklı şekilli satırları kabul eder, test yeşil
904
+ * kalır, üretimde motor adıyla reddederdi — yani fake, sürüm atlamayı
905
+ * kolaylaştırmak yerine gizlerdi.
906
+ */
907
+ async insertMany(table, rows) {
908
+ if (rows.length === 0) return [];
909
+ const cols = Object.keys(rows[0]);
910
+ for (let i = 1; i < rows.length; i++) {
911
+ const missing = cols.filter((c) => !(c in rows[i]));
912
+ const extra = Object.keys(rows[i]).filter((k) => !cols.includes(k));
913
+ if (missing.length > 0 || extra.length > 0) {
914
+ 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(", ")})` : "") + `. Eksikler i\xE7in null yaz\u0131n, ya da farkl\u0131 \u015Fekilli sat\u0131rlar\u0131 ayr\u0131 \xE7a\u011Fr\u0131larda ekleyin.`);
915
+ }
916
+ }
917
+ const out = [];
918
+ for (const rawRow of rows) {
919
+ const data = resolveInsertValues("insertMany", table, rawRow);
920
+ assertUsableWriteValues("insertMany", table, cols, data);
921
+ assertNoExpressionHandles("insertMany", table, cols, data);
922
+ const record = {
923
+ id: crypto.randomUUID(),
924
+ ...data
925
+ };
926
+ rowsOf(table).push(record);
927
+ track(tracked.inserted, table, record);
928
+ out.push(record);
929
+ }
930
+ return out;
931
+ },
932
+ /**
854
933
  * `claim` — motorla PARİTE (FR-033).
855
934
  *
856
935
  * Fake bunu sunmasaydı `claim` ile yazılmış bir servis, iskelenin yazarlara
@@ -909,10 +988,11 @@ function createMockDB() {
909
988
  },
910
989
  // Same semantics the engine's SQL has: match on the conflict columns, update
911
990
  // everything else, and return the resulting row either way.
912
- async put(table, data, opts) {
991
+ async put(table, rawData, opts) {
913
992
  if (opts.onConflict.length === 0) {
914
993
  throw new Error(`put into ${table}: onConflict en az bir kolon ad\u0131 ister`);
915
994
  }
995
+ const data = resolveInsertValues("put", table, rawData);
916
996
  assertUsableWriteValues("upsert", table, Object.keys(data), data);
917
997
  assertNoExpressionHandles("upsert", table, Object.keys(data), data);
918
998
  const rows = rowsOf(table);
@@ -933,15 +1013,29 @@ function createMockDB() {
933
1013
  },
934
1014
  async update(table, id, data) {
935
1015
  assertUsableWriteValues("update", table, Object.keys(data), data);
936
- assertNoExpressionHandles("update", table, Object.keys(data), data);
937
1016
  const rows = store.get(table) ?? [];
938
1017
  const idx = rows.findIndex((r) => r["id"] === id);
1018
+ const current = idx >= 0 ? rows[idx] : {};
1019
+ const applied = {};
1020
+ for (const [k, v] of Object.entries(data)) {
1021
+ const expr = columnExprOf(v);
1022
+ if (expr !== null && expr.fn === "now") {
1023
+ applied[k] = /* @__PURE__ */ new Date();
1024
+ continue;
1025
+ }
1026
+ if (expr !== null) {
1027
+ applied[k] = addDecimal(current[k], expr.by, expr.fn === "inc" ? 1 : -1);
1028
+ continue;
1029
+ }
1030
+ applied[k] = v;
1031
+ }
1032
+ assertNoExpressionHandles("update", table, Object.keys(applied), applied);
939
1033
  const updated = idx >= 0 ? {
940
1034
  ...rows[idx],
941
- ...data
1035
+ ...applied
942
1036
  } : {
943
1037
  id,
944
- ...data
1038
+ ...applied
945
1039
  };
946
1040
  if (idx >= 0) {
947
1041
  rows[idx] = updated;