@palbase/backend 38.0.16 → 39.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.
- package/dist/bin/palbase-backend.cjs +46 -1
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +5 -5
- package/dist/{chunk-LFUNRWUE.js → chunk-4J6I4KVQ.js} +67 -3
- package/dist/{chunk-LFUNRWUE.js.map → chunk-4J6I4KVQ.js.map} +1 -1
- package/dist/{chunk-7WAGQ3VR.js → chunk-AR2I4M7I.js} +497 -17
- package/dist/chunk-AR2I4M7I.js.map +1 -0
- package/dist/{chunk-YANGWAIM.js → chunk-H7EKL6HC.js} +2 -2
- package/dist/{chunk-EHKEMHB4.js → chunk-JJSR4BUX.js} +49 -5
- package/dist/chunk-JJSR4BUX.js.map +1 -0
- package/dist/{chunk-CS6NQ6PO.js → chunk-JPTFYHP3.js} +2 -2
- package/dist/{chunk-CS6NQ6PO.js.map → chunk-JPTFYHP3.js.map} +1 -1
- package/dist/{chunk-X7UR3VXA.js → chunk-XZWOMPD3.js} +3 -2
- package/dist/chunk-XZWOMPD3.js.map +1 -0
- package/dist/{chunk-PDD55QWN.js → chunk-ZNQDL466.js} +2 -2
- package/dist/db/index.cjs +378 -14
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +3 -3
- package/dist/engine/index.cjs +46 -1
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +3 -3
- package/dist/engine/index.d.ts +3 -3
- package/dist/engine/index.js +5 -5
- package/dist/{index-CI7S0Wqv.d.cts → index-B0mjUnxy.d.cts} +25 -2
- package/dist/{index-CUy50OLU.d.ts → index-eN4KzGa5.d.ts} +555 -29
- package/dist/{index-DRx880KY.d.cts → index-pK2At5Yc.d.cts} +555 -29
- package/dist/{index-Ogi30dbt.d.ts → index-yDno9Ju9.d.ts} +25 -2
- package/dist/index.cjs +628 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +183 -8
- package/dist/index.d.ts +183 -8
- package/dist/index.js +74 -6
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/openapi/index.js +2 -2
- package/dist/{registry-C7UCkQf0.d.cts → registry-9dNeVN5d.d.cts} +1 -1
- package/dist/{registry-DJcvbomD.d.ts → registry-B8ddZiMY.d.ts} +1 -1
- package/dist/test/index.cjs +19 -0
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +20 -2
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/database.md +79 -0
- package/docs/llms-full.txt +462 -33
- package/docs/schema.md +382 -32
- package/package.json +1 -1
- package/template/package.json +1 -1
- package/dist/chunk-7WAGQ3VR.js.map +0 -1
- package/dist/chunk-EHKEMHB4.js.map +0 -1
- package/dist/chunk-X7UR3VXA.js.map +0 -1
- /package/dist/{chunk-YANGWAIM.js.map → chunk-H7EKL6HC.js.map} +0 -0
- /package/dist/{chunk-PDD55QWN.js.map → chunk-ZNQDL466.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -80,7 +80,7 @@ __export(src_exports, {
|
|
|
80
80
|
Sse: () => Sse,
|
|
81
81
|
SseOut: () => SseOut,
|
|
82
82
|
Storage: () => Storage,
|
|
83
|
-
TABLE_META: () =>
|
|
83
|
+
TABLE_META: () => TABLE_META2,
|
|
84
84
|
TooManyRequests: () => TooManyRequests,
|
|
85
85
|
TraceId: () => TraceId,
|
|
86
86
|
TxPlanError: () => TxPlanError,
|
|
@@ -103,11 +103,13 @@ __export(src_exports, {
|
|
|
103
103
|
__setRuntime: () => __setRuntime,
|
|
104
104
|
assertNoOrphanEntryPoints: () => assertNoOrphanEntryPoints,
|
|
105
105
|
assertZeroArgConstructor: () => assertZeroArgConstructor,
|
|
106
|
+
backfill: () => backfill,
|
|
106
107
|
bigint: () => bigint,
|
|
107
108
|
boolean: () => boolean,
|
|
108
109
|
buildContainer: () => buildContainer,
|
|
109
110
|
buildModuleClients: () => buildModuleClients,
|
|
110
111
|
can: () => can,
|
|
112
|
+
check: () => check,
|
|
111
113
|
col: () => col,
|
|
112
114
|
controllersOf: () => controllersOf,
|
|
113
115
|
dec: () => dec,
|
|
@@ -116,10 +118,13 @@ __export(src_exports, {
|
|
|
116
118
|
defineDefaultAuth: () => defineDefaultAuth,
|
|
117
119
|
defineError: () => defineError,
|
|
118
120
|
defineMiddleware: () => defineMiddleware,
|
|
121
|
+
defineRepository: () => defineRepository,
|
|
119
122
|
defineSchema: () => defineSchema,
|
|
120
123
|
defineTable: () => defineTable,
|
|
121
124
|
enumType: () => enumType,
|
|
122
125
|
exprCtx: () => exprCtx,
|
|
126
|
+
foreignKey: () => foreignKey,
|
|
127
|
+
freeze: () => freeze,
|
|
123
128
|
getErrorRegistry: () => getErrorRegistry,
|
|
124
129
|
getHookConfig: () => getHookConfig,
|
|
125
130
|
getHookManifest: () => getHookManifest,
|
|
@@ -129,6 +134,7 @@ __export(src_exports, {
|
|
|
129
134
|
getRoutes: () => getRoutes,
|
|
130
135
|
getWebhookConfig: () => getWebhookConfig,
|
|
131
136
|
getWebhookManifest: () => getWebhookManifest,
|
|
137
|
+
guard: () => guard,
|
|
132
138
|
hooksOf: () => hooksOf,
|
|
133
139
|
inc: () => inc,
|
|
134
140
|
increment: () => increment,
|
|
@@ -962,8 +968,7 @@ function tableToJSON(table, schemaName) {
|
|
|
962
968
|
if (table.raw !== void 0 && table.raw.length > 0) {
|
|
963
969
|
out.rawConstraints = table.raw.map((r) => ({
|
|
964
970
|
name: r.name,
|
|
965
|
-
up: r.up
|
|
966
|
-
down: r.down ?? null
|
|
971
|
+
up: r.up
|
|
967
972
|
}));
|
|
968
973
|
}
|
|
969
974
|
if (table.checks !== void 0 && table.checks.length > 0) {
|
|
@@ -980,6 +985,7 @@ function tableToJSON(table, schemaName) {
|
|
|
980
985
|
...i.columns
|
|
981
986
|
] : []
|
|
982
987
|
};
|
|
988
|
+
if (i.unique === true) ix.unique = true;
|
|
983
989
|
if (i.where !== void 0) ix.where = i.where;
|
|
984
990
|
if (i.expression !== void 0) ix.expression = i.expression;
|
|
985
991
|
if (i.sort !== void 0) ix.sort = i.sort;
|
|
@@ -990,6 +996,70 @@ function tableToJSON(table, schemaName) {
|
|
|
990
996
|
return ix;
|
|
991
997
|
});
|
|
992
998
|
}
|
|
999
|
+
if (table.dropConstraints !== void 0 && table.dropConstraints.length > 0) {
|
|
1000
|
+
out.dropConstraints = [
|
|
1001
|
+
...table.dropConstraints
|
|
1002
|
+
];
|
|
1003
|
+
}
|
|
1004
|
+
if (table.foreignKeys !== void 0 && table.foreignKeys.length > 0) {
|
|
1005
|
+
out.foreignKeys = table.foreignKeys.map((fk) => {
|
|
1006
|
+
const j = {
|
|
1007
|
+
name: fk.name,
|
|
1008
|
+
columns: [
|
|
1009
|
+
...fk.columns
|
|
1010
|
+
],
|
|
1011
|
+
refTable: fk.refTable,
|
|
1012
|
+
refColumns: [
|
|
1013
|
+
...fk.refColumns
|
|
1014
|
+
]
|
|
1015
|
+
};
|
|
1016
|
+
if (fk.onUpdate !== void 0) j.onUpdate = fk.onUpdate;
|
|
1017
|
+
if (fk.onDelete !== void 0) j.onDelete = fk.onDelete;
|
|
1018
|
+
if (fk.match !== void 0) j.match = fk.match;
|
|
1019
|
+
return j;
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
if (table.freeze !== void 0 && table.freeze.length > 0) {
|
|
1023
|
+
out.freeze = table.freeze.map((f) => ({
|
|
1024
|
+
name: f.name,
|
|
1025
|
+
when: f.when,
|
|
1026
|
+
columns: [
|
|
1027
|
+
...f.columns
|
|
1028
|
+
],
|
|
1029
|
+
refTable: f.refTable,
|
|
1030
|
+
refColumns: [
|
|
1031
|
+
...f.refColumns
|
|
1032
|
+
]
|
|
1033
|
+
}));
|
|
1034
|
+
}
|
|
1035
|
+
if (table.guards !== void 0 && table.guards.length > 0) {
|
|
1036
|
+
out.guards = table.guards.map((g) => ({
|
|
1037
|
+
name: g.name,
|
|
1038
|
+
event: g.event,
|
|
1039
|
+
...g.when !== void 0 ? {
|
|
1040
|
+
when: g.when
|
|
1041
|
+
} : {},
|
|
1042
|
+
...g.exists !== void 0 ? {
|
|
1043
|
+
exists: g.exists
|
|
1044
|
+
} : {},
|
|
1045
|
+
message: g.message,
|
|
1046
|
+
...g.detail !== void 0 ? {
|
|
1047
|
+
detail: g.detail
|
|
1048
|
+
} : {},
|
|
1049
|
+
...g.hint !== void 0 ? {
|
|
1050
|
+
hint: g.hint
|
|
1051
|
+
} : {},
|
|
1052
|
+
...g.column !== void 0 ? {
|
|
1053
|
+
column: g.column
|
|
1054
|
+
} : {}
|
|
1055
|
+
}));
|
|
1056
|
+
}
|
|
1057
|
+
if (table.backfills !== void 0 && table.backfills.length > 0) {
|
|
1058
|
+
out.backfills = table.backfills.map((b) => ({
|
|
1059
|
+
name: b.name,
|
|
1060
|
+
sql: b.sql
|
|
1061
|
+
}));
|
|
1062
|
+
}
|
|
993
1063
|
if (table.appendOnly === true) out.appendOnly = true;
|
|
994
1064
|
if (table.search !== void 0) {
|
|
995
1065
|
const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== void 0)?.[0];
|
|
@@ -1244,6 +1314,7 @@ function makeTypedSurface(raw2) {
|
|
|
1244
1314
|
$facets: /* @__PURE__ */ __name((table, params) => reco.facets(table, params), "$facets"),
|
|
1245
1315
|
$claim: /* @__PURE__ */ __name((table, unique, extra) => reco.claim(table, unique, extra), "$claim"),
|
|
1246
1316
|
$lockRows: /* @__PURE__ */ __name((table, ids) => reco.lockRows(table, ids), "$lockRows"),
|
|
1317
|
+
$lockRowsWhere: /* @__PURE__ */ __name((table, where, opts) => reco.lockRowsWhere(table, where, opts), "$lockRowsWhere"),
|
|
1247
1318
|
$advisoryXactLock: /* @__PURE__ */ __name((key) => reco.advisoryXactLock(key), "$advisoryXactLock"),
|
|
1248
1319
|
$aggregate: /* @__PURE__ */ __name((table, q) => raw2.aggregate(table, q), "$aggregate"),
|
|
1249
1320
|
$insertMany: /* @__PURE__ */ __name((table, rows, opts) => raw2.insertMany(table, rows, opts), "$insertMany"),
|
|
@@ -2576,6 +2647,192 @@ __name(buildModuleClients, "buildModuleClients");
|
|
|
2576
2647
|
|
|
2577
2648
|
// src/db/policy.ts
|
|
2578
2649
|
var import_zod = require("zod");
|
|
2650
|
+
|
|
2651
|
+
// src/db/foreign-key.ts
|
|
2652
|
+
var TABLE_META = /* @__PURE__ */ Symbol.for("palbase.table.meta");
|
|
2653
|
+
var REF_TARGET = /* @__PURE__ */ Symbol.for("palbase.ref.target");
|
|
2654
|
+
var ForeignKeyBuilder = class {
|
|
2655
|
+
static {
|
|
2656
|
+
__name(this, "ForeignKeyBuilder");
|
|
2657
|
+
}
|
|
2658
|
+
_def;
|
|
2659
|
+
constructor(name) {
|
|
2660
|
+
if (name.trim() === "") {
|
|
2661
|
+
throw new Error("foreignKey(ad): foreign key'in ad\u0131 bo\u015F olamaz \u2014 Palbase k\u0131s\u0131tlar\u0131 ADA g\xF6re uzla\u015Ft\u0131r\u0131r.");
|
|
2662
|
+
}
|
|
2663
|
+
this._def = {
|
|
2664
|
+
name,
|
|
2665
|
+
columns: [],
|
|
2666
|
+
refTable: "",
|
|
2667
|
+
refColumns: []
|
|
2668
|
+
};
|
|
2669
|
+
}
|
|
2670
|
+
/** Yerel sütunlar. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */
|
|
2671
|
+
on(...cols) {
|
|
2672
|
+
this._def.columns = cols.map((c) => {
|
|
2673
|
+
const e = c.expr;
|
|
2674
|
+
if (e.kind !== "col") {
|
|
2675
|
+
throw new Error(`foreignKey(${this._def.name}).on(): yaln\u0131z kolon referans\u0131 al\u0131r \u2014 ifade bir FK'n\u0131n par\xE7as\u0131 olamaz.`);
|
|
2676
|
+
}
|
|
2677
|
+
return e.name;
|
|
2678
|
+
});
|
|
2679
|
+
return this;
|
|
2680
|
+
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Hedef tablo ve sütunları. Sütun sayısı `.on()`'unkiyle eşit OLMALI ve bu
|
|
2683
|
+
* burada, bildirim yazılırken kontrol edilir — bozuk bir FK wire'a hiç çıkmaz.
|
|
2684
|
+
*/
|
|
2685
|
+
references(table, ...cols) {
|
|
2686
|
+
if (cols.length === 0) {
|
|
2687
|
+
throw new Error(`foreignKey(${this._def.name}).references(): en az bir hedef s\xFCtun gerekir.`);
|
|
2688
|
+
}
|
|
2689
|
+
this._def.refTable = table[TABLE_META].name;
|
|
2690
|
+
this._def.refColumns = [
|
|
2691
|
+
...cols
|
|
2692
|
+
];
|
|
2693
|
+
Object.defineProperty(this._def, REF_TARGET, {
|
|
2694
|
+
value: table[TABLE_META],
|
|
2695
|
+
enumerable: false,
|
|
2696
|
+
configurable: true
|
|
2697
|
+
});
|
|
2698
|
+
return this;
|
|
2699
|
+
}
|
|
2700
|
+
onUpdate(action) {
|
|
2701
|
+
this._def.onUpdate = action;
|
|
2702
|
+
return this;
|
|
2703
|
+
}
|
|
2704
|
+
onDelete(action) {
|
|
2705
|
+
this._def.onDelete = action;
|
|
2706
|
+
return this;
|
|
2707
|
+
}
|
|
2708
|
+
/**
|
|
2709
|
+
* `MATCH FULL`: referans veren sütunların HEPSİ NULL olmadıkça kısıt
|
|
2710
|
+
* değerlendirilir. Varsayılan `MATCH SIMPLE`'da tek bir NULL kısıtı atlatır —
|
|
2711
|
+
* `freeze` bunu bilerek kullanır, sıradan bir FK'da genelde istenmez.
|
|
2712
|
+
*/
|
|
2713
|
+
match(m) {
|
|
2714
|
+
this._def.match = m;
|
|
2715
|
+
return this;
|
|
2716
|
+
}
|
|
2717
|
+
};
|
|
2718
|
+
function foreignKey(name) {
|
|
2719
|
+
return new ForeignKeyBuilder(name);
|
|
2720
|
+
}
|
|
2721
|
+
__name(foreignKey, "foreignKey");
|
|
2722
|
+
function toForeignKeyDef(b) {
|
|
2723
|
+
const def = b instanceof ForeignKeyBuilder ? b._def : b;
|
|
2724
|
+
if (def.columns.length === 0) {
|
|
2725
|
+
throw new Error(`foreignKey(${def.name}): en az bir yerel s\xFCtun gerekir \u2014 .on(...) \xE7a\u011F\u0131r\u0131n.`);
|
|
2726
|
+
}
|
|
2727
|
+
if (def.refColumns.length === 0 || def.refTable === "") {
|
|
2728
|
+
throw new Error(`foreignKey(${def.name}): hedef tablo ve s\xFCtunlar gerekir \u2014 .references(...) \xE7a\u011F\u0131r\u0131n.`);
|
|
2729
|
+
}
|
|
2730
|
+
if (def.columns.length !== def.refColumns.length) {
|
|
2731
|
+
throw new Error(`foreignKey(${def.name}): ${def.columns.length} yerel s\xFCtun (${def.columns.join(", ")}) ama ${def.refColumns.length} hedef s\xFCtun (${def.refColumns.join(", ")}) \u2014 iki liste e\u015Fit uzunlukta olmal\u0131.`);
|
|
2732
|
+
}
|
|
2733
|
+
return def;
|
|
2734
|
+
}
|
|
2735
|
+
__name(toForeignKeyDef, "toForeignKeyDef");
|
|
2736
|
+
var FreezeBuilder = class {
|
|
2737
|
+
static {
|
|
2738
|
+
__name(this, "FreezeBuilder");
|
|
2739
|
+
}
|
|
2740
|
+
_def;
|
|
2741
|
+
constructor(name) {
|
|
2742
|
+
if (name.trim() === "") {
|
|
2743
|
+
throw new Error("freeze(ad): freeze k\u0131s\u0131t\u0131n\u0131n ad\u0131 bo\u015F olamaz \u2014 Palbase k\u0131s\u0131tlar\u0131 ADA g\xF6re uzla\u015Ft\u0131r\u0131r.");
|
|
2744
|
+
}
|
|
2745
|
+
this._def = {
|
|
2746
|
+
name,
|
|
2747
|
+
columns: [],
|
|
2748
|
+
refTable: "",
|
|
2749
|
+
refColumns: []
|
|
2750
|
+
};
|
|
2751
|
+
}
|
|
2752
|
+
/**
|
|
2753
|
+
* DONMA KOŞULU — çocuk satırının kendi kolonları üzerinde bir yüklem.
|
|
2754
|
+
*
|
|
2755
|
+
* Generated sütunlara `CASE WHEN <koşul> THEN <sütun> END` olarak iner; yani
|
|
2756
|
+
* koşul yanlışken sütunlar NULL olur ve FK o satır için hiç değerlendirilmez.
|
|
2757
|
+
*/
|
|
2758
|
+
when(pred) {
|
|
2759
|
+
this._def.when = pred.expr;
|
|
2760
|
+
return this;
|
|
2761
|
+
}
|
|
2762
|
+
/** Çocuğun DONAN sütunları. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */
|
|
2763
|
+
columns(...cols) {
|
|
2764
|
+
if (cols.length === 0) {
|
|
2765
|
+
throw new Error(`freeze(${this._def.name}).columns(): en az bir donan s\xFCtun gerekir \u2014 hi\xE7birini vermeyen bir freeze hi\xE7bir \u015Feyi dondurmaz.`);
|
|
2766
|
+
}
|
|
2767
|
+
this._def.columns = [
|
|
2768
|
+
...cols
|
|
2769
|
+
];
|
|
2770
|
+
return this;
|
|
2771
|
+
}
|
|
2772
|
+
/**
|
|
2773
|
+
* Ebeveyn tablo ve donan demetin ORADAKİ karşılığı. Zincirin SON halkası:
|
|
2774
|
+
* bildirim burada tamamlanır ve tutarlılığı burada doğrulanır, yani
|
|
2775
|
+
* `.references()`'ı unutmuş bir freeze `FreezeDef` üretmediği için tabloya
|
|
2776
|
+
* hiç giremez.
|
|
2777
|
+
*/
|
|
2778
|
+
references(table, ...cols) {
|
|
2779
|
+
if (cols.length === 0) {
|
|
2780
|
+
throw new Error(`freeze(${this._def.name}).references(): en az bir hedef s\xFCtun gerekir.`);
|
|
2781
|
+
}
|
|
2782
|
+
this._def.refTable = table[TABLE_META].name;
|
|
2783
|
+
this._def.refColumns = [
|
|
2784
|
+
...cols
|
|
2785
|
+
];
|
|
2786
|
+
Object.defineProperty(this._def, REF_TARGET, {
|
|
2787
|
+
value: table[TABLE_META],
|
|
2788
|
+
enumerable: false,
|
|
2789
|
+
configurable: true
|
|
2790
|
+
});
|
|
2791
|
+
return toFreezeDef(this);
|
|
2792
|
+
}
|
|
2793
|
+
};
|
|
2794
|
+
function freeze(name) {
|
|
2795
|
+
return new FreezeBuilder(name);
|
|
2796
|
+
}
|
|
2797
|
+
__name(freeze, "freeze");
|
|
2798
|
+
function toFreezeDef(b) {
|
|
2799
|
+
const def = b instanceof FreezeBuilder ? b._def : b;
|
|
2800
|
+
if (def.columns.length === 0) {
|
|
2801
|
+
throw new Error(`freeze(${def.name}): en az bir donan s\xFCtun gerekir \u2014 .columns(...) \xE7a\u011F\u0131r\u0131n.`);
|
|
2802
|
+
}
|
|
2803
|
+
if (def.refColumns.length === 0 || def.refTable === "") {
|
|
2804
|
+
throw new Error(`freeze(${def.name}): hedef tablo ve s\xFCtunlar gerekir \u2014 .references(...) \xE7a\u011F\u0131r\u0131n.`);
|
|
2805
|
+
}
|
|
2806
|
+
if (def.columns.length !== def.refColumns.length) {
|
|
2807
|
+
throw new Error(`freeze(${def.name}): ${def.columns.length} donan s\xFCtun (${def.columns.join(", ")}) ama ${def.refColumns.length} hedef s\xFCtun (${def.refColumns.join(", ")}) \u2014 iki liste e\u015Fit uzunlukta olmal\u0131.`);
|
|
2808
|
+
}
|
|
2809
|
+
if (def.when === void 0) {
|
|
2810
|
+
throw new Error(`freeze(${def.name}): donma ko\u015Fulu gerekir \u2014 .when(...) \xE7a\u011F\u0131r\u0131n. Ko\u015Fulsuz bir freeze s\u0131radan bir FK'd\u0131r; onun i\xE7in foreignKey(...) var.`);
|
|
2811
|
+
}
|
|
2812
|
+
const out = {
|
|
2813
|
+
name: def.name,
|
|
2814
|
+
when: def.when,
|
|
2815
|
+
columns: [
|
|
2816
|
+
...def.columns
|
|
2817
|
+
],
|
|
2818
|
+
refTable: def.refTable,
|
|
2819
|
+
refColumns: [
|
|
2820
|
+
...def.refColumns
|
|
2821
|
+
]
|
|
2822
|
+
};
|
|
2823
|
+
const target = def[REF_TARGET];
|
|
2824
|
+
if (target !== void 0) {
|
|
2825
|
+
Object.defineProperty(out, REF_TARGET, {
|
|
2826
|
+
value: target,
|
|
2827
|
+
enumerable: false,
|
|
2828
|
+
configurable: true
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
return out;
|
|
2832
|
+
}
|
|
2833
|
+
__name(toFreezeDef, "toFreezeDef");
|
|
2834
|
+
|
|
2835
|
+
// src/db/policy.ts
|
|
2579
2836
|
var PolicyExprRef = class _PolicyExprRef {
|
|
2580
2837
|
static {
|
|
2581
2838
|
__name(this, "PolicyExprRef");
|
|
@@ -2687,15 +2944,21 @@ function exprCtx(_columns, depth = 0, ownTable = "") {
|
|
|
2687
2944
|
expr: part.expr
|
|
2688
2945
|
}), "not"),
|
|
2689
2946
|
existsIn: /* @__PURE__ */ __name((table, predicate) => {
|
|
2690
|
-
const meta = table[
|
|
2947
|
+
const meta = table[TABLE_META2];
|
|
2691
2948
|
const inner = exprCtx(Object.keys(meta.columns), depth + 1, ownTable);
|
|
2692
|
-
|
|
2949
|
+
const node = {
|
|
2693
2950
|
kind: "exists",
|
|
2694
2951
|
table: meta.name,
|
|
2695
2952
|
alias: `pb_e${depth + 1}`,
|
|
2696
2953
|
outer: ownTable,
|
|
2697
2954
|
predicate: predicate(inner).expr
|
|
2955
|
+
};
|
|
2956
|
+
Object.defineProperty(node, REF_TARGET, {
|
|
2957
|
+
value: meta,
|
|
2958
|
+
enumerable: false,
|
|
2959
|
+
configurable: true
|
|
2698
2960
|
});
|
|
2961
|
+
return new PolicyExprRef(node);
|
|
2699
2962
|
}, "existsIn")
|
|
2700
2963
|
};
|
|
2701
2964
|
}
|
|
@@ -2783,13 +3046,13 @@ var PolicyBuilder = class {
|
|
|
2783
3046
|
* // → id IN (SELECT "channel_id" FROM "channel_members"
|
|
2784
3047
|
* // WHERE "user_id" = (select auth.uid()))
|
|
2785
3048
|
*/
|
|
2786
|
-
memberOf(membershipTable,
|
|
3049
|
+
memberOf(membershipTable, foreignKey2, options = {}) {
|
|
2787
3050
|
if (this._def.using !== null) {
|
|
2788
3051
|
throw new Error(`policy(${this._def.name}).memberOf(): this policy already has a using() expression. Write one or the other \u2014 memberOf IS the using expression.`);
|
|
2789
3052
|
}
|
|
2790
3053
|
const column = options.column ?? "id";
|
|
2791
3054
|
const userColumn = options.userColumn ?? "user_id";
|
|
2792
|
-
this._def.using = `${quote(column)} IN (SELECT ${quote(
|
|
3055
|
+
this._def.using = `${quote(column)} IN (SELECT ${quote(foreignKey2)} FROM ${quote(membershipTable)} WHERE ${quote(userColumn)} = (select auth.uid()))`;
|
|
2793
3056
|
return this;
|
|
2794
3057
|
}
|
|
2795
3058
|
/** `WITH CHECK (...)` yazma doğrulaması — `using` ile aynı iki biçim. */
|
|
@@ -2808,6 +3071,92 @@ function policy(name) {
|
|
|
2808
3071
|
return new PolicyBuilder(name);
|
|
2809
3072
|
}
|
|
2810
3073
|
__name(policy, "policy");
|
|
3074
|
+
function assertCheckNode(node, name) {
|
|
3075
|
+
switch (node.kind) {
|
|
3076
|
+
case "exists":
|
|
3077
|
+
throw new Error(`check(${name}): \`existsIn(...)\` is a subquery and PostgreSQL forbids subqueries in a CHECK constraint \u2014 express a cross-table rule as a composite FOREIGN KEY (foreignKeys), or as a guard.`);
|
|
3078
|
+
case "authUid":
|
|
3079
|
+
throw new Error(`check(${name}): \`auth.uid()\` renders as a subquery \`(SELECT auth.uid())\` and PostgreSQL forbids subqueries in a CHECK constraint \u2014 a caller-dependent rule belongs in an RLS policy, not a CHECK.`);
|
|
3080
|
+
case "binop":
|
|
3081
|
+
assertCheckNode(node.left, name);
|
|
3082
|
+
assertCheckNode(node.right, name);
|
|
3083
|
+
return;
|
|
3084
|
+
case "and":
|
|
3085
|
+
case "or":
|
|
3086
|
+
for (const part of node.parts) assertCheckNode(part, name);
|
|
3087
|
+
return;
|
|
3088
|
+
case "not":
|
|
3089
|
+
case "isNull":
|
|
3090
|
+
assertCheckNode(node.expr, name);
|
|
3091
|
+
return;
|
|
3092
|
+
default:
|
|
3093
|
+
return;
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
__name(assertCheckNode, "assertCheckNode");
|
|
3097
|
+
var CHECK_BIN_OPS = {
|
|
3098
|
+
eq: "=",
|
|
3099
|
+
neq: "<>",
|
|
3100
|
+
gt: ">",
|
|
3101
|
+
gte: ">=",
|
|
3102
|
+
lt: "<",
|
|
3103
|
+
lte: "<="
|
|
3104
|
+
};
|
|
3105
|
+
function literalSQL(v) {
|
|
3106
|
+
if (v === null) return "NULL";
|
|
3107
|
+
if (typeof v === "boolean") return v ? "true" : "false";
|
|
3108
|
+
if (typeof v === "number") {
|
|
3109
|
+
if (!Number.isFinite(v)) {
|
|
3110
|
+
throw new Error(`check(): ${v} bir SQL say\u0131 literali de\u011Fil.`);
|
|
3111
|
+
}
|
|
3112
|
+
return String(v);
|
|
3113
|
+
}
|
|
3114
|
+
return `'${v.replace(/'/g, "''")}'`;
|
|
3115
|
+
}
|
|
3116
|
+
__name(literalSQL, "literalSQL");
|
|
3117
|
+
function checkNodeSQL(node, name) {
|
|
3118
|
+
switch (node.kind) {
|
|
3119
|
+
case "col":
|
|
3120
|
+
return quote(node.name);
|
|
3121
|
+
case "lit":
|
|
3122
|
+
return literalSQL(node.value);
|
|
3123
|
+
case "binop": {
|
|
3124
|
+
const op = CHECK_BIN_OPS[node.op];
|
|
3125
|
+
if (op === void 0) {
|
|
3126
|
+
throw new Error(`check(${name}): \`${node.op}\` bir CHECK ifadesinde desteklenmiyor.`);
|
|
3127
|
+
}
|
|
3128
|
+
return `(${checkNodeSQL(node.left, name)} ${op} ${checkNodeSQL(node.right, name)})`;
|
|
3129
|
+
}
|
|
3130
|
+
case "and":
|
|
3131
|
+
case "or": {
|
|
3132
|
+
if (node.parts.length === 0) {
|
|
3133
|
+
return node.kind === "and" ? "(true)" : "(false)";
|
|
3134
|
+
}
|
|
3135
|
+
const joiner = node.kind === "and" ? " AND " : " OR ";
|
|
3136
|
+
return `(${node.parts.map((p) => checkNodeSQL(p, name)).join(joiner)})`;
|
|
3137
|
+
}
|
|
3138
|
+
case "not":
|
|
3139
|
+
return `(NOT ${checkNodeSQL(node.expr, name)})`;
|
|
3140
|
+
case "isNull":
|
|
3141
|
+
return `(${checkNodeSQL(node.expr, name)} IS ${node.negated ? "NOT NULL" : "NULL"})`;
|
|
3142
|
+
default: {
|
|
3143
|
+
const kind = node.kind;
|
|
3144
|
+
throw new Error(`check(${name}): \`${kind}\` d\xFC\u011F\xFCm\xFC bir CHECK ifadesinde tan\u0131nm\u0131yor.`);
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
__name(checkNodeSQL, "checkNodeSQL");
|
|
3149
|
+
function check(name, expr) {
|
|
3150
|
+
if (name.trim() === "") {
|
|
3151
|
+
throw new Error("check(): k\u0131s\u0131t\u0131n ad\u0131 bo\u015F olamaz \u2014 CHECK'ler ADA g\xF6re uzla\u015Ft\u0131r\u0131l\u0131yor.");
|
|
3152
|
+
}
|
|
3153
|
+
assertCheckNode(expr.expr, name);
|
|
3154
|
+
return {
|
|
3155
|
+
name,
|
|
3156
|
+
expr: checkNodeSQL(expr.expr, name)
|
|
3157
|
+
};
|
|
3158
|
+
}
|
|
3159
|
+
__name(check, "check");
|
|
2811
3160
|
function can(table) {
|
|
2812
3161
|
if (table === void 0 || table === null) {
|
|
2813
3162
|
throw new Error("can(<table>): received " + String(table) + " \u2014 the schema declares no such table (check the name against db/*.ts; can(publicSchema.tables.<name>))");
|
|
@@ -2851,6 +3200,117 @@ function reservedCanRelation(tableName, columns) {
|
|
|
2851
3200
|
}
|
|
2852
3201
|
__name(reservedCanRelation, "reservedCanRelation");
|
|
2853
3202
|
|
|
3203
|
+
// src/db/guard.ts
|
|
3204
|
+
var GuardBuilder = class {
|
|
3205
|
+
static {
|
|
3206
|
+
__name(this, "GuardBuilder");
|
|
3207
|
+
}
|
|
3208
|
+
_def;
|
|
3209
|
+
constructor(name) {
|
|
3210
|
+
if (name.trim() === "") {
|
|
3211
|
+
throw new Error("guard(ad): guard'\u0131n ad\u0131 bo\u015F olamaz \u2014 Postgres ayn\u0131 olaydaki trigger'lar\u0131 ADA G\xD6RE alfabetik ko\u015Fuyor ve ba\u015Fka s\u0131ra tutamac\u0131 yok.");
|
|
3212
|
+
}
|
|
3213
|
+
this._def = {
|
|
3214
|
+
name
|
|
3215
|
+
};
|
|
3216
|
+
}
|
|
3217
|
+
/** Hangi yazma fiilinde bakılacak. */
|
|
3218
|
+
on(event) {
|
|
3219
|
+
this._def.event = event;
|
|
3220
|
+
return this;
|
|
3221
|
+
}
|
|
3222
|
+
/**
|
|
3223
|
+
* Satırın KENDİ kolonları üzerinde koşul — trigger'ın `WHEN` yan tümcesi.
|
|
3224
|
+
*
|
|
3225
|
+
* Emitter karşılaştırmaları `IS DISTINCT FROM` ile yazar (`<>` NULL'da yanlış
|
|
3226
|
+
* cevap verir) ve geçen sütunlardan bir `UPDATE OF (…)` listesi türetir
|
|
3227
|
+
* (FR-018).
|
|
3228
|
+
*/
|
|
3229
|
+
when(pred) {
|
|
3230
|
+
this._def.when = pred.expr;
|
|
3231
|
+
return this;
|
|
3232
|
+
}
|
|
3233
|
+
/**
|
|
3234
|
+
* ÇAPRAZ SATIR koşulu — gövdedeki `EXISTS` bloğuna iner, `WHEN`'e DEĞİL:
|
|
3235
|
+
* Postgres trigger `WHEN`'inde alt sorgu kabul etmiyor (FR-019).
|
|
3236
|
+
*
|
|
3237
|
+
* Yüklem içinde takma adsız kalan kolon guard'ın KENDİ satırıdır (`NEW`/`OLD`);
|
|
3238
|
+
* `r.col(...)` hedef tablonun kolonlarını verir ve ayrı nitelenir. Bu yüzden
|
|
3239
|
+
* düğümün `outer` alanı BOŞ kalır: bir guard'ın "dış satır"ı bir tablo takma
|
|
3240
|
+
* adı değildir.
|
|
3241
|
+
*/
|
|
3242
|
+
exists(table, predicate) {
|
|
3243
|
+
this._def.exists = exprCtx().existsIn(table, predicate).expr;
|
|
3244
|
+
return this;
|
|
3245
|
+
}
|
|
3246
|
+
/**
|
|
3247
|
+
* REDDİN KENDİSİ ve zincirin son halkası: mesaj olmadan bir guard tamamlanmaz.
|
|
3248
|
+
*
|
|
3249
|
+
* `detail`/`hint` Postgres'in aynı adlı alanlarına, `column` ise `COLUMN`
|
|
3250
|
+
* alanına gider — istemci hangi alanın reddedildiğini mesajı parse etmeden
|
|
3251
|
+
* okur.
|
|
3252
|
+
*/
|
|
3253
|
+
refuse(message, opts) {
|
|
3254
|
+
this._def.message = message;
|
|
3255
|
+
if (opts?.detail !== void 0) this._def.detail = opts.detail;
|
|
3256
|
+
if (opts?.hint !== void 0) this._def.hint = opts.hint;
|
|
3257
|
+
if (opts?.column !== void 0) this._def.column = opts.column;
|
|
3258
|
+
return toGuardDef(this);
|
|
3259
|
+
}
|
|
3260
|
+
};
|
|
3261
|
+
function guard(name) {
|
|
3262
|
+
return new GuardBuilder(name);
|
|
3263
|
+
}
|
|
3264
|
+
__name(guard, "guard");
|
|
3265
|
+
function toGuardDef(b) {
|
|
3266
|
+
const def = b instanceof GuardBuilder ? b._def : b;
|
|
3267
|
+
if (def.event === void 0) {
|
|
3268
|
+
throw new Error(`guard(${def.name}): hangi olayda bakaca\u011F\u0131 gerekir \u2014 .on("insert"|"update"|"delete") \xE7a\u011F\u0131r\u0131n.`);
|
|
3269
|
+
}
|
|
3270
|
+
if (def.when === void 0 && def.exists === void 0) {
|
|
3271
|
+
throw new Error(`guard(${def.name}): bir ko\u015Ful gerekir \u2014 .when(...) ya da .exists(...) \xE7a\u011F\u0131r\u0131n. Ko\u015Fulsuz bir guard o olaydaki HER yazmay\u0131 reddeder.`);
|
|
3272
|
+
}
|
|
3273
|
+
if (def.message === void 0 || def.message.trim() === "") {
|
|
3274
|
+
throw new Error(`guard(${def.name}): bo\u015F mesaj kabul edilmez \u2014 reddin mesaj\u0131 guard'\u0131n kullan\u0131c\u0131ya ula\u015Fan TEK \xE7\u0131kt\u0131s\u0131.`);
|
|
3275
|
+
}
|
|
3276
|
+
return {
|
|
3277
|
+
name: def.name,
|
|
3278
|
+
event: def.event,
|
|
3279
|
+
...def.when !== void 0 ? {
|
|
3280
|
+
when: def.when
|
|
3281
|
+
} : {},
|
|
3282
|
+
...def.exists !== void 0 ? {
|
|
3283
|
+
exists: def.exists
|
|
3284
|
+
} : {},
|
|
3285
|
+
message: def.message,
|
|
3286
|
+
...def.detail !== void 0 ? {
|
|
3287
|
+
detail: def.detail
|
|
3288
|
+
} : {},
|
|
3289
|
+
...def.hint !== void 0 ? {
|
|
3290
|
+
hint: def.hint
|
|
3291
|
+
} : {},
|
|
3292
|
+
...def.column !== void 0 ? {
|
|
3293
|
+
column: def.column
|
|
3294
|
+
} : {}
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3297
|
+
__name(toGuardDef, "toGuardDef");
|
|
3298
|
+
|
|
3299
|
+
// src/db/backfill.ts
|
|
3300
|
+
function backfill(name, sql) {
|
|
3301
|
+
if (name.trim() === "") {
|
|
3302
|
+
throw new Error("backfill(ad, sql): backfill'in ad\u0131 bo\u015F olamaz \u2014 'bir kez ko\u015Ftu' kayd\u0131 ADA g\xF6re tutuluyor.");
|
|
3303
|
+
}
|
|
3304
|
+
if (sql.trim() === "") {
|
|
3305
|
+
throw new Error(`backfill(${name}): SQL bo\u015F olamaz \u2014 bo\u015F bir g\xF6vde ad\u0131 kayda ge\xE7irip KALICI olarak yakar; sonradan yaz\u0131lan ger\xE7ek SQL "zaten ko\u015Ftu" diye hi\xE7 \xE7al\u0131\u015Fmaz.`);
|
|
3306
|
+
}
|
|
3307
|
+
return {
|
|
3308
|
+
name,
|
|
3309
|
+
sql
|
|
3310
|
+
};
|
|
3311
|
+
}
|
|
3312
|
+
__name(backfill, "backfill");
|
|
3313
|
+
|
|
2854
3314
|
// src/db/schema.ts
|
|
2855
3315
|
var IndexBuilder = class {
|
|
2856
3316
|
static {
|
|
@@ -2865,6 +3325,15 @@ var IndexBuilder = class {
|
|
|
2865
3325
|
name
|
|
2866
3326
|
};
|
|
2867
3327
|
}
|
|
3328
|
+
/**
|
|
3329
|
+
* `CREATE UNIQUE INDEX` (FR-007). `.where()` ile birlikte PARTIAL UNIQUE
|
|
3330
|
+
* index verir (FR-007b) — "NULL'lar serbest, non-NULL'lar tekil" kalıbının
|
|
3331
|
+
* tek bildirimsel yolu.
|
|
3332
|
+
*/
|
|
3333
|
+
unique() {
|
|
3334
|
+
this._def.unique = true;
|
|
3335
|
+
return this;
|
|
3336
|
+
}
|
|
2868
3337
|
/** Index'in kolonları. SIRA KORUNUR — çok kolonlu bir index'in anlamı sırasıdır. */
|
|
2869
3338
|
on(...cols) {
|
|
2870
3339
|
this._def.columns = cols.map((c) => {
|
|
@@ -2922,7 +3391,7 @@ function toPolicyDef(p) {
|
|
|
2922
3391
|
return p instanceof PolicyBuilder ? p._def : p;
|
|
2923
3392
|
}
|
|
2924
3393
|
__name(toPolicyDef, "toPolicyDef");
|
|
2925
|
-
var
|
|
3394
|
+
var TABLE_META2 = /* @__PURE__ */ Symbol.for("palbase.table.meta");
|
|
2926
3395
|
function defineTable(name, input) {
|
|
2927
3396
|
if (name.trim() === "") {
|
|
2928
3397
|
throw new Error("defineTable(name, \u2026): name must not be empty");
|
|
@@ -2955,9 +3424,46 @@ function defineTable(name, input) {
|
|
|
2955
3424
|
if (input.primaryKey !== void 0) def.primaryKey = input.primaryKey;
|
|
2956
3425
|
if (input.unique !== void 0) def.unique = input.unique;
|
|
2957
3426
|
if (input.raw !== void 0 && input.raw.length > 0) def.raw = input.raw.slice();
|
|
2958
|
-
|
|
3427
|
+
const declaredChecks = typeof input.checks === "function" ? input.checks(exprCtx(Object.keys(input.columns), 0, name)) : input.checks?.slice() ?? [];
|
|
3428
|
+
if (declaredChecks.length > 0) def.checks = declaredChecks;
|
|
2959
3429
|
const declaredIndexes = (input.indexes?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map((i) => i instanceof IndexBuilder ? i._def : i);
|
|
2960
3430
|
if (declaredIndexes.length > 0) def.indexes = declaredIndexes;
|
|
3431
|
+
const declaredFKs = (input.foreignKeys?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toForeignKeyDef);
|
|
3432
|
+
if (declaredFKs.length > 0) def.foreignKeys = declaredFKs;
|
|
3433
|
+
const declaredFreezes = (input.freeze?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toFreezeDef);
|
|
3434
|
+
if (declaredFreezes.length > 0) def.freeze = declaredFreezes;
|
|
3435
|
+
for (const fz of declaredFreezes) {
|
|
3436
|
+
for (const c of fz.columns) {
|
|
3437
|
+
if (!(c in input.columns)) {
|
|
3438
|
+
throw new Error(`table "${name}": freeze("${fz.name}").columns("${c}") \u2014 no such column on this table. Declared columns: ${Object.keys(input.columns).join(", ")}`);
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
const declaredGuards = (input.guards?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toGuardDef);
|
|
3443
|
+
if (declaredGuards.length > 0) def.guards = declaredGuards;
|
|
3444
|
+
for (const g of declaredGuards) {
|
|
3445
|
+
if (g.column !== void 0 && !(g.column in input.columns)) {
|
|
3446
|
+
throw new Error(`table "${name}": guard("${g.name}").refuse(\u2026, { column: "${g.column}" }) \u2014 no such column on this table. Declared columns: ${Object.keys(input.columns).join(", ")}`);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
if (input.backfills !== void 0 && input.backfills.length > 0) {
|
|
3450
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3451
|
+
for (const b of input.backfills) {
|
|
3452
|
+
if (seen.has(b.name)) {
|
|
3453
|
+
throw new Error(`table ${name}: backfill ad\u0131 iki kez bildirildi: ${b.name} \u2014 kay\u0131t ADA g\xF6re tutuluyor, ikincisi hi\xE7 ko\u015Fmazd\u0131.`);
|
|
3454
|
+
}
|
|
3455
|
+
seen.add(b.name);
|
|
3456
|
+
}
|
|
3457
|
+
def.backfills = input.backfills.map((b) => ({
|
|
3458
|
+
name: b.name,
|
|
3459
|
+
sql: b.sql
|
|
3460
|
+
}));
|
|
3461
|
+
}
|
|
3462
|
+
if (input.dropConstraints !== void 0 && input.dropConstraints.length > 0) {
|
|
3463
|
+
def.dropConstraints = [
|
|
3464
|
+
...input.dropConstraints
|
|
3465
|
+
];
|
|
3466
|
+
}
|
|
2961
3467
|
if (input.appendOnly === true) def.appendOnly = true;
|
|
2962
3468
|
if (input.ignored === true) def.ignored = true;
|
|
2963
3469
|
if (input.search !== void 0) {
|
|
@@ -3011,7 +3517,7 @@ function defineTable(name, input) {
|
|
|
3011
3517
|
const handle = {
|
|
3012
3518
|
...owned2
|
|
3013
3519
|
};
|
|
3014
|
-
Object.defineProperty(handle,
|
|
3520
|
+
Object.defineProperty(handle, TABLE_META2, {
|
|
3015
3521
|
value: def,
|
|
3016
3522
|
enumerable: false
|
|
3017
3523
|
});
|
|
@@ -3020,6 +3526,9 @@ function defineTable(name, input) {
|
|
|
3020
3526
|
__name(defineTable, "defineTable");
|
|
3021
3527
|
var declaringSchemaOf = /* @__PURE__ */ new WeakMap();
|
|
3022
3528
|
function resolveReferences(tables, schemaName) {
|
|
3529
|
+
for (const table of Object.values(tables)) {
|
|
3530
|
+
qualifyRefTargets(table, `table "${table.name}"`);
|
|
3531
|
+
}
|
|
3023
3532
|
for (const table of Object.values(tables)) {
|
|
3024
3533
|
for (const [colName, builder] of Object.entries(table.columns)) {
|
|
3025
3534
|
const def = builder._def;
|
|
@@ -3064,7 +3573,7 @@ function defineSchema(name, input) {
|
|
|
3064
3573
|
}
|
|
3065
3574
|
const tables = {};
|
|
3066
3575
|
for (const handle of input.tables) {
|
|
3067
|
-
const table = handle[
|
|
3576
|
+
const table = handle[TABLE_META2];
|
|
3068
3577
|
if (tables[table.name] !== void 0) {
|
|
3069
3578
|
throw new Error(`defineSchema("${name}"): two tables declare the name "${table.name}" \u2014 table names must be unique within a schema`);
|
|
3070
3579
|
}
|
|
@@ -3108,6 +3617,48 @@ function defineSchema(name, input) {
|
|
|
3108
3617
|
};
|
|
3109
3618
|
}
|
|
3110
3619
|
__name(defineSchema, "defineSchema");
|
|
3620
|
+
function qualifyRefTargets(table, where) {
|
|
3621
|
+
const qualify = /* @__PURE__ */ __name((holder, what) => {
|
|
3622
|
+
const target = holder[REF_TARGET];
|
|
3623
|
+
if (target === void 0) return;
|
|
3624
|
+
const targetSchema = declaringSchemaOf.get(target);
|
|
3625
|
+
if (targetSchema === void 0) {
|
|
3626
|
+
throw new Error(`${where}: ${what} points at table "${target.name}", which no defineSchema(...) has claimed yet \u2014 a cross-table reference cannot be written without its target's schema. Declare that table's schema first (one file per schema: db/public.ts, db/billing.ts \u2026, imported by this one).`);
|
|
3627
|
+
}
|
|
3628
|
+
const qualified = qualifiedTableKey(targetSchema, target.name);
|
|
3629
|
+
if (holder.refTable !== void 0) holder.refTable = qualified;
|
|
3630
|
+
if (holder.table !== void 0) holder.table = qualified;
|
|
3631
|
+
}, "qualify");
|
|
3632
|
+
for (const fk of table.foreignKeys ?? []) qualify(fk, `foreignKey("${fk.name}")`);
|
|
3633
|
+
for (const fz of table.freeze ?? []) qualify(fz, `freeze("${fz.name}")`);
|
|
3634
|
+
for (const g of table.guards ?? []) {
|
|
3635
|
+
if (g.exists !== void 0) {
|
|
3636
|
+
qualifyExistsNodes(g.exists, `guard("${g.name}").exists(...)`, where);
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
__name(qualifyRefTargets, "qualifyRefTargets");
|
|
3641
|
+
function qualifyExistsNodes(node, what, where) {
|
|
3642
|
+
if (node === null || typeof node !== "object") return;
|
|
3643
|
+
if (node.kind === "exists") {
|
|
3644
|
+
const target = node[REF_TARGET];
|
|
3645
|
+
if (target !== void 0) {
|
|
3646
|
+
const targetSchema = declaringSchemaOf.get(target);
|
|
3647
|
+
if (targetSchema === void 0) {
|
|
3648
|
+
throw new Error(`${where}: ${what} points at table "${target.name}", which no defineSchema(...) has claimed yet \u2014 a guard body is parsed at RUN TIME under a pinned search_path, so an unqualified name never resolves.`);
|
|
3649
|
+
}
|
|
3650
|
+
node.table = qualifiedTableKey(targetSchema, target.name);
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
for (const v of Object.values(node)) {
|
|
3654
|
+
if (Array.isArray(v)) {
|
|
3655
|
+
for (const e of v) qualifyExistsNodes(e, what, where);
|
|
3656
|
+
} else if (v !== null && typeof v === "object") {
|
|
3657
|
+
qualifyExistsNodes(v, what, where);
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
__name(qualifyExistsNodes, "qualifyExistsNodes");
|
|
3111
3662
|
|
|
3112
3663
|
// src/channels.ts
|
|
3113
3664
|
var CHANNELS = /* @__PURE__ */ Symbol.for("palbase.backend.channels");
|
|
@@ -3584,13 +4135,10 @@ function installationRef(opts) {
|
|
|
3584
4135
|
__name(installationRef, "installationRef");
|
|
3585
4136
|
|
|
3586
4137
|
// src/db/raw.ts
|
|
3587
|
-
function raw(name, up
|
|
4138
|
+
function raw(name, up) {
|
|
3588
4139
|
return {
|
|
3589
4140
|
name,
|
|
3590
|
-
up
|
|
3591
|
-
...opts?.down != null ? {
|
|
3592
|
-
down: opts.down
|
|
3593
|
-
} : {}
|
|
4141
|
+
up
|
|
3594
4142
|
};
|
|
3595
4143
|
}
|
|
3596
4144
|
__name(raw, "raw");
|
|
@@ -3791,7 +4339,7 @@ var DeadlockDetected = class extends Conflict {
|
|
|
3791
4339
|
return typeof e === "object" && e !== null && e.name === "DeadlockDetected";
|
|
3792
4340
|
}
|
|
3793
4341
|
constructor(sqlstate = SQLSTATE.deadlockDetected, message, data) {
|
|
3794
|
-
super(message ?? "deadlock: iki i\u015Flem birbirinin kilidini bekledi ve bu i\u015Flem iptal edildi \u2014 kilit s\u0131ras\u0131n\u0131
|
|
4342
|
+
super(message ?? "deadlock: iki i\u015Flem birbirinin kilidini bekledi ve bu i\u015Flem iptal edildi \u2014 kilit s\u0131ras\u0131n\u0131 sabitleyin: id'ler elinizdeyse Database.$lockRows(tablo, id'ler), elinizde bir filtre varsa Database.$lockRowsWhere(tablo, filtre) kullan\u0131n", "deadlock_detected", data);
|
|
3795
4343
|
this.name = "DeadlockDetected";
|
|
3796
4344
|
this.sqlstate = sqlstate;
|
|
3797
4345
|
}
|
|
@@ -3905,6 +4453,63 @@ function sqlFragment(strings, ...values) {
|
|
|
3905
4453
|
}
|
|
3906
4454
|
__name(sqlFragment, "sqlFragment");
|
|
3907
4455
|
|
|
4456
|
+
// src/db/repository.ts
|
|
4457
|
+
function defineRepository(table, opts) {
|
|
4458
|
+
const tenantColumn = opts.tenant;
|
|
4459
|
+
const scope = /* @__PURE__ */ __name((tenant) => ({
|
|
4460
|
+
[tenantColumn]: tenant
|
|
4461
|
+
}), "scope");
|
|
4462
|
+
const scopeRow = /* @__PURE__ */ __name((tenant, id) => ({
|
|
4463
|
+
[tenantColumn]: tenant,
|
|
4464
|
+
id
|
|
4465
|
+
}), "scopeRow");
|
|
4466
|
+
const scopedPayload = /* @__PURE__ */ __name((values, tenant) => ({
|
|
4467
|
+
...values,
|
|
4468
|
+
[tenantColumn]: tenant
|
|
4469
|
+
}), "scopedPayload");
|
|
4470
|
+
let Repository = class Repository {
|
|
4471
|
+
static {
|
|
4472
|
+
__name(this, "Repository");
|
|
4473
|
+
}
|
|
4474
|
+
list(tenant) {
|
|
4475
|
+
return table.findMany({
|
|
4476
|
+
where: scope(tenant)
|
|
4477
|
+
});
|
|
4478
|
+
}
|
|
4479
|
+
async find(tenant, id) {
|
|
4480
|
+
const rows = await table.findMany({
|
|
4481
|
+
where: scopeRow(tenant, id),
|
|
4482
|
+
limit: 1
|
|
4483
|
+
});
|
|
4484
|
+
return rows[0] ?? null;
|
|
4485
|
+
}
|
|
4486
|
+
insert(tenant, values) {
|
|
4487
|
+
return table.insert(scopedPayload(values, tenant));
|
|
4488
|
+
}
|
|
4489
|
+
async update(tenant, id, patch) {
|
|
4490
|
+
const row = await this.updateScoped(tenant, id, patch);
|
|
4491
|
+
if (row === null) {
|
|
4492
|
+
throw new NotFound(`${String(tenantColumn)}=${String(tenant)} kapsam\u0131nda ${id} bulunamad\u0131`);
|
|
4493
|
+
}
|
|
4494
|
+
return row;
|
|
4495
|
+
}
|
|
4496
|
+
async updateScoped(tenant, id, patch) {
|
|
4497
|
+
const rows = await table.updateMany({
|
|
4498
|
+
where: scopeRow(tenant, id),
|
|
4499
|
+
set: patch
|
|
4500
|
+
});
|
|
4501
|
+
return rows[0] ?? null;
|
|
4502
|
+
}
|
|
4503
|
+
async delete(tenant, id) {
|
|
4504
|
+
await table.deleteMany({
|
|
4505
|
+
where: scopeRow(tenant, id)
|
|
4506
|
+
});
|
|
4507
|
+
}
|
|
4508
|
+
};
|
|
4509
|
+
return Repository;
|
|
4510
|
+
}
|
|
4511
|
+
__name(defineRepository, "defineRepository");
|
|
4512
|
+
|
|
3908
4513
|
// src/refusals.ts
|
|
3909
4514
|
var DECLARATION_REFUSAL = /* @__PURE__ */ Symbol.for("palbase.backend.declarationRefusal");
|
|
3910
4515
|
var DeclarationRefused = class extends Error {
|
|
@@ -5761,11 +6366,13 @@ var import_zod3 = require("zod");
|
|
|
5761
6366
|
__setRuntime,
|
|
5762
6367
|
assertNoOrphanEntryPoints,
|
|
5763
6368
|
assertZeroArgConstructor,
|
|
6369
|
+
backfill,
|
|
5764
6370
|
bigint,
|
|
5765
6371
|
boolean,
|
|
5766
6372
|
buildContainer,
|
|
5767
6373
|
buildModuleClients,
|
|
5768
6374
|
can,
|
|
6375
|
+
check,
|
|
5769
6376
|
col,
|
|
5770
6377
|
controllersOf,
|
|
5771
6378
|
dec,
|
|
@@ -5774,10 +6381,13 @@ var import_zod3 = require("zod");
|
|
|
5774
6381
|
defineDefaultAuth,
|
|
5775
6382
|
defineError,
|
|
5776
6383
|
defineMiddleware,
|
|
6384
|
+
defineRepository,
|
|
5777
6385
|
defineSchema,
|
|
5778
6386
|
defineTable,
|
|
5779
6387
|
enumType,
|
|
5780
6388
|
exprCtx,
|
|
6389
|
+
foreignKey,
|
|
6390
|
+
freeze,
|
|
5781
6391
|
getErrorRegistry,
|
|
5782
6392
|
getHookConfig,
|
|
5783
6393
|
getHookManifest,
|
|
@@ -5787,6 +6397,7 @@ var import_zod3 = require("zod");
|
|
|
5787
6397
|
getRoutes,
|
|
5788
6398
|
getWebhookConfig,
|
|
5789
6399
|
getWebhookManifest,
|
|
6400
|
+
guard,
|
|
5790
6401
|
hooksOf,
|
|
5791
6402
|
inc,
|
|
5792
6403
|
increment,
|