@palbase/backend 24.1.0 → 24.2.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.
@@ -1037,6 +1037,56 @@ function makeMemoryCache(opts = {}) {
1037
1037
  };
1038
1038
  }
1039
1039
 
1040
+ // src/db/input-guards.ts
1041
+ var KNOWN_OPS = /* @__PURE__ */ new Set(["gt", "gte", "lt", "lte", "neq", "eq", "in"]);
1042
+ function assertUsableFilter(caller, table, where) {
1043
+ if (!where) return;
1044
+ for (const [col, cond] of Object.entries(where)) {
1045
+ if (cond === void 0) {
1046
+ throw new Error(
1047
+ `${caller}(${table}): where.${col} de\u011Feri undefined \u2014 bu bir filtre de\u011Feri de\u011Fil. Ba\u011Flan\u0131nca NULL olur ve '= NULL' hi\xE7bir sat\u0131ra uymaz, yani sorgu sessizce bo\u015F sonu\xE7 d\xF6nerdi. De\u011Fer yoksa anahtar\u0131 filtreye hi\xE7 koymay\u0131n.`
1048
+ );
1049
+ }
1050
+ if (cond === null || typeof cond !== "object" || Array.isArray(cond)) continue;
1051
+ const entries = Object.entries(cond);
1052
+ if (entries.length === 0) {
1053
+ throw new Error(
1054
+ `${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).`
1055
+ );
1056
+ }
1057
+ for (const [op, v] of entries) {
1058
+ if (op === "in") {
1059
+ if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmal\u0131`);
1060
+ if (v.some((x) => x === void 0)) {
1061
+ throw new Error(
1062
+ `${caller}(${table}): where.${col}.in listesinde undefined var \u2014 sessizce NULL'a ba\u011Flan\u0131r ve o eleman hi\xE7bir sat\u0131rla e\u015Fle\u015Fmez. Listeyi kurarken eleyin.`
1063
+ );
1064
+ }
1065
+ continue;
1066
+ }
1067
+ if (!KNOWN_OPS.has(op)) {
1068
+ throw new Error(
1069
+ `${caller}(${table}): where.${col} bilinmeyen operat\xF6r "${op}" (gt/gte/lt/lte/neq/in)`
1070
+ );
1071
+ }
1072
+ if (v === void 0) {
1073
+ throw new Error(
1074
+ `${caller}(${table}): where.${col}.${op} de\u011Feri undefined \u2014 kar\u015F\u0131la\u015Ft\u0131rman\u0131n sa\u011F taraf\u0131 NULL olur ve sonu\xE7 hi\xE7bir sat\u0131ra uymaz. Ko\u015Fulu kurmay\u0131n.`
1075
+ );
1076
+ }
1077
+ }
1078
+ }
1079
+ }
1080
+ function assertUsableWriteValues(caller, table, cols, data) {
1081
+ for (const c of cols) {
1082
+ if (data[c] === void 0) {
1083
+ throw new Error(
1084
+ `${caller}(${table}): "${c}" de\u011Feri undefined \u2014 bu bir yazma de\u011Feri de\u011Fil. Kolonu bo\u015Faltmak istiyorsan null yaz; kolonu de\u011Fi\u015Ftirmek istemiyorsan nesneye hi\xE7 koyma (bir eksik istek alan\u0131 sessizce NULL yaz\u0131yordu \u2014 FR-016).`
1085
+ );
1086
+ }
1087
+ }
1088
+ }
1089
+
1040
1090
  // src/engine/db.ts
1041
1091
  function quoteIdent(name) {
1042
1092
  return `"${name.replace(/"/g, '""')}"`;
@@ -1165,13 +1215,7 @@ function asTableRows(table, rows) {
1165
1215
  return rows.map((row) => applyFromDb(reviveVectors(asWireRow(row), vectorCols), transforms));
1166
1216
  }
1167
1217
  function asBindParams(table, cols, data, caller) {
1168
- for (const c of cols) {
1169
- if (data[c] === void 0) {
1170
- throw new Error(
1171
- `${caller}(${table}): "${c}" de\u011Feri undefined \u2014 bu bir yazma de\u011Feri de\u011Fil. Kolonu bo\u015Faltmak istiyorsan null yaz; kolonu de\u011Fi\u015Ftirmek istemiyorsan nesneye hi\xE7 koyma (bir eksik istek alan\u0131 sessizce NULL yaz\u0131yordu \u2014 FR-016).`
1172
- );
1173
- }
1174
- }
1218
+ assertUsableWriteValues(caller, table, cols, data);
1175
1219
  const vectorCols = vectorColumnsOf(currentSchema, table);
1176
1220
  const transforms = transformsOf(currentSchema, table);
1177
1221
  return cols.map((c) => {
@@ -1394,42 +1438,23 @@ function compileWhere(table, colSet, where, add, caller = "search") {
1394
1438
  const t = transforms.get(col);
1395
1439
  return t?.toDb === void 0 ? add : (v) => add(v === null || v === void 0 ? v : t.toDb(v));
1396
1440
  };
1441
+ assertUsableFilter(caller, table, where);
1397
1442
  for (const [col, cond] of Object.entries(where)) {
1398
1443
  if (colSet !== null && !colSet.has(col)) {
1399
1444
  throw new Error(`${caller}(${table}): where kolonu "${col}" tabloda yok (FR-016)`);
1400
1445
  }
1401
- if (cond === void 0) {
1402
- throw new Error(
1403
- `${caller}(${table}): where.${col} de\u011Feri undefined \u2014 bu bir filtre de\u011Feri de\u011Fil. Ba\u011Flan\u0131nca NULL olur ve '= NULL' hi\xE7bir sat\u0131ra uymaz, yani sorgu sessizce bo\u015F sonu\xE7 d\xF6nerdi. De\u011Fer yoksa anahtar\u0131 filtreye hi\xE7 koymay\u0131n.`
1404
- );
1405
- }
1406
1446
  const q = `t.${quoteIdent(col)}`;
1407
1447
  const bind = bindFor(col);
1408
1448
  if (cond !== null && typeof cond === "object" && !Array.isArray(cond)) {
1409
- if (Object.keys(cond).length === 0) {
1410
- throw new Error(
1411
- `${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).`
1412
- );
1413
- }
1414
1449
  for (const [op, v] of Object.entries(cond)) {
1415
1450
  if (op === "in") {
1416
1451
  if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmal\u0131`);
1417
- if (v.some((x) => x === void 0)) {
1418
- throw new Error(
1419
- `${caller}(${table}): where.${col}.in listesinde undefined var \u2014 sessizce NULL'a ba\u011Flan\u0131r ve o eleman hi\xE7bir sat\u0131rla e\u015Fle\u015Fmez. Listeyi kurarken eleyin.`
1420
- );
1421
- }
1422
1452
  if (v.length === 0) {
1423
1453
  parts.push("false");
1424
1454
  continue;
1425
1455
  }
1426
1456
  parts.push(`${q} IN (${v.map((x) => bind(x)).join(", ")})`);
1427
1457
  } else if (op in WHERE_OPS) {
1428
- if (v === void 0) {
1429
- throw new Error(
1430
- `${caller}(${table}): where.${col}.${op} de\u011Feri undefined \u2014 kar\u015F\u0131la\u015Ft\u0131rman\u0131n sa\u011F taraf\u0131 NULL olur ve sonu\xE7 hi\xE7bir sat\u0131ra uymaz. Ko\u015Fulu kurmay\u0131n.`
1431
- );
1432
- }
1433
1458
  if (v === null && (op === "neq" || op === "eq")) {
1434
1459
  parts.push(`${q} IS ${op === "neq" ? "NOT " : ""}NULL`);
1435
1460
  continue;
@@ -2749,7 +2774,7 @@ async function createApp(opts) {
2749
2774
  const completions = new CompletionLedger();
2750
2775
  function buildServices(db) {
2751
2776
  return {
2752
- Database: db.client,
2777
+ Database: db?.client ?? stubModule("Database (a start hook runs before any request \u2014 open your own connection here)"),
2753
2778
  Cache: cache,
2754
2779
  Log: log,
2755
2780
  Documents: modules.Documents ?? stubModule("Documents"),
@@ -3128,9 +3153,10 @@ async function createApp(opts) {
3128
3153
  return envelope("internal_error", "The request could not be completed", 500, requestId);
3129
3154
  }
3130
3155
  }
3156
+ const bootServices = buildServices(null);
3131
3157
  let runShutdownHooks;
3132
3158
  try {
3133
- runShutdownHooks = await __runStartHooks();
3159
+ runShutdownHooks = await runWithRuntime(bootServices, () => __runStartHooks());
3134
3160
  } catch (err) {
3135
3161
  await closeDriver(sql);
3136
3162
  throw err;