@palbase/backend 24.3.0 → 25.0.1
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 +103 -60
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +17 -13
- package/dist/bin/palbase-backend.js.map +1 -1
- package/dist/{chunk-EIXCY4SS.js → chunk-34I4GB7D.js} +82 -49
- package/dist/chunk-34I4GB7D.js.map +1 -0
- package/dist/{chunk-UWSYTUGM.js → chunk-35PNTIRN.js} +48 -1
- package/dist/chunk-35PNTIRN.js.map +1 -0
- package/dist/chunk-HBOJLP2Z.js +840 -0
- package/dist/chunk-HBOJLP2Z.js.map +1 -0
- package/dist/{chunk-7Z6MGMXQ.js → chunk-XJ2RSHEU.js} +11 -5
- package/dist/chunk-XJ2RSHEU.js.map +1 -0
- package/dist/{chunk-ERDL5VAE.js → chunk-YOY5DFQS.js} +2 -2
- package/dist/db/env.cjs.map +1 -1
- package/dist/db/env.d.cts +31 -14
- package/dist/db/env.d.ts +31 -14
- package/dist/db/index.cjs +226 -111
- 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 +11 -1
- package/dist/engine/index.cjs +89 -50
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +2 -2
- package/dist/engine/index.d.ts +2 -2
- package/dist/engine/index.js +3 -3
- package/dist/{index-BTMYod_l.d.ts → index-B4CcpqLb.d.ts} +224 -75
- package/dist/{index-DEneI8Mn.d.ts → index-B8v6hVyU.d.ts} +5 -2
- package/dist/{index-BLAbr9ZH.d.cts → index-DmVyY6N7.d.cts} +224 -75
- package/dist/{index-C-ALG22n.d.cts → index-VsjBQ4Kw.d.cts} +5 -2
- package/dist/index.cjs +580 -301
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +125 -22
- package/dist/index.d.ts +125 -22
- package/dist/index.js +173 -217
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs +100 -36
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.js +59 -2
- package/dist/openapi/index.js.map +1 -1
- package/docs/README.md +64 -31
- package/docs/endpoints.md +25 -28
- package/docs/llms-full.txt +430 -153
- package/docs/schema.md +303 -91
- package/docs/services.md +39 -4
- package/package.json +1 -1
- package/template/AGENTS.md +119 -314
- package/template/CLAUDE.md +13 -0
- package/template/controllers/notes.controller.ts +6 -13
- package/template/db/public.ts +38 -0
- package/template/models/notes/create.ts +38 -0
- package/template/package.json +6 -3
- package/template/services/note.service.test.ts +45 -0
- package/template/services/note.service.ts +2 -2
- package/dist/chunk-7Z6MGMXQ.js.map +0 -1
- package/dist/chunk-D5CQES25.js +0 -556
- package/dist/chunk-D5CQES25.js.map +0 -1
- package/dist/chunk-EIXCY4SS.js.map +0 -1
- package/dist/chunk-UWSYTUGM.js.map +0 -1
- package/template/db/schema.ts +0 -35
- /package/dist/{chunk-ERDL5VAE.js.map → chunk-YOY5DFQS.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -2,27 +2,34 @@ import {
|
|
|
2
2
|
EXTENSION_DEPENDENCIES,
|
|
3
3
|
PALBASE_EXTENSIONS,
|
|
4
4
|
PolicyBuilder,
|
|
5
|
+
TABLE_META,
|
|
5
6
|
bigint,
|
|
6
7
|
boolean,
|
|
7
8
|
defineSchema,
|
|
9
|
+
defineTable,
|
|
8
10
|
enumType,
|
|
11
|
+
installationRef,
|
|
9
12
|
integer,
|
|
10
13
|
isPalbaseExtension,
|
|
11
14
|
jsonb,
|
|
12
15
|
makeTypedDB,
|
|
13
16
|
numeric,
|
|
14
17
|
openai,
|
|
18
|
+
ownedByUser,
|
|
15
19
|
policy,
|
|
20
|
+
qualifiedTableKey,
|
|
16
21
|
raw,
|
|
17
22
|
text,
|
|
18
23
|
timestamp,
|
|
24
|
+
toSchemaJSON,
|
|
25
|
+
userRef,
|
|
19
26
|
uuid,
|
|
20
27
|
vector
|
|
21
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-HBOJLP2Z.js";
|
|
22
29
|
import {
|
|
23
30
|
defineError,
|
|
24
31
|
getErrorRegistry
|
|
25
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-YOY5DFQS.js";
|
|
26
33
|
import {
|
|
27
34
|
Cache,
|
|
28
35
|
Database,
|
|
@@ -41,7 +48,7 @@ import {
|
|
|
41
48
|
__setRuntime,
|
|
42
49
|
onShutdown,
|
|
43
50
|
onStart
|
|
44
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-XJ2RSHEU.js";
|
|
45
52
|
import {
|
|
46
53
|
TxPlanError,
|
|
47
54
|
TxRefError,
|
|
@@ -67,10 +74,13 @@ import {
|
|
|
67
74
|
getRegisteredControllers,
|
|
68
75
|
getRoutes,
|
|
69
76
|
recordParam,
|
|
77
|
+
recordRoom,
|
|
78
|
+
recordRoomHook,
|
|
79
|
+
recordRoomMessage,
|
|
70
80
|
recordRoute,
|
|
71
81
|
recordThrows,
|
|
72
82
|
resolveEffectiveAuth
|
|
73
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-35PNTIRN.js";
|
|
74
84
|
import "./chunk-7D4SUZUM.js";
|
|
75
85
|
|
|
76
86
|
// src/clients/http.ts
|
|
@@ -948,168 +958,6 @@ function buildModuleClients(cfg) {
|
|
|
948
958
|
};
|
|
949
959
|
}
|
|
950
960
|
|
|
951
|
-
// src/db/schema-json.ts
|
|
952
|
-
function defOf(column) {
|
|
953
|
-
return "_def" in column ? column._def : column;
|
|
954
|
-
}
|
|
955
|
-
function columnToJSON(column) {
|
|
956
|
-
const def = defOf(column);
|
|
957
|
-
const out = {
|
|
958
|
-
type: def.type,
|
|
959
|
-
nullable: def.nullable,
|
|
960
|
-
primaryKey: def.primaryKey
|
|
961
|
-
};
|
|
962
|
-
if (def.defaultValue !== void 0) out.defaultValue = def.defaultValue;
|
|
963
|
-
if (def.defaultRandom === true) out.defaultRandom = true;
|
|
964
|
-
if (def.defaultNow === true) out.defaultNow = true;
|
|
965
|
-
if (def.renamedFrom !== void 0) out.renamedFrom = def.renamedFrom;
|
|
966
|
-
if (def.ignored === true) out.ignored = true;
|
|
967
|
-
if (def.references !== void 0) {
|
|
968
|
-
out.references = { table: def.references.table, column: def.references.column };
|
|
969
|
-
}
|
|
970
|
-
if (def.onDeleteAction !== void 0) out.onDeleteAction = def.onDeleteAction;
|
|
971
|
-
if (def.enumName !== void 0) out.enumName = def.enumName;
|
|
972
|
-
if (def.enumValues !== void 0) out.enumValues = [...def.enumValues];
|
|
973
|
-
if (def.unique === true) out.unique = true;
|
|
974
|
-
if (def.dimensions !== void 0) out.dimensions = def.dimensions;
|
|
975
|
-
return out;
|
|
976
|
-
}
|
|
977
|
-
function policyToJSON(policy2) {
|
|
978
|
-
return {
|
|
979
|
-
name: policy2.name,
|
|
980
|
-
command: policy2.command ?? "all",
|
|
981
|
-
roles: policy2.roles ? [...policy2.roles] : [],
|
|
982
|
-
// null rather than omitted: a policy with no USING clause is a different
|
|
983
|
-
// thing from one whose clause the emitter forgot, and Go reads the
|
|
984
|
-
// difference.
|
|
985
|
-
using: policy2.using ?? null,
|
|
986
|
-
withCheck: policy2.withCheck ?? null,
|
|
987
|
-
permissive: policy2.permissive !== false
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
function commonSearchFields(search, out) {
|
|
991
|
-
if (search.synonyms !== void 0 && Object.keys(search.synonyms).length > 0) {
|
|
992
|
-
out.synonyms = Object.fromEntries(
|
|
993
|
-
Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]])
|
|
994
|
-
);
|
|
995
|
-
}
|
|
996
|
-
if (search.validity === true) out.validity = true;
|
|
997
|
-
}
|
|
998
|
-
function searchToJSON(search, vectorColumn) {
|
|
999
|
-
if (search.from !== void 0 && search.model !== void 0) {
|
|
1000
|
-
const out2 = {};
|
|
1001
|
-
const textCols = search.text === false ? void 0 : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;
|
|
1002
|
-
if (textCols !== void 0) out2.text = { columns: [...textCols] };
|
|
1003
|
-
const v = { metric: search.metric ?? "cosine" };
|
|
1004
|
-
if (vectorColumn !== void 0) v.column = vectorColumn;
|
|
1005
|
-
v.embed = {
|
|
1006
|
-
provider: search.model.provider,
|
|
1007
|
-
model: search.model.model,
|
|
1008
|
-
from: [...search.from],
|
|
1009
|
-
...search.model.apiKeyName !== void 0 ? { apiKeyName: search.model.apiKeyName } : {},
|
|
1010
|
-
...search.model.dimensions !== void 0 ? { dimensions: search.model.dimensions } : {},
|
|
1011
|
-
...search.model.baseURL !== void 0 ? { baseURL: search.model.baseURL } : {}
|
|
1012
|
-
};
|
|
1013
|
-
if (search.staleness !== void 0) v.staleness = search.staleness;
|
|
1014
|
-
if (vectorColumn === void 0) {
|
|
1015
|
-
v.mode = "chunks";
|
|
1016
|
-
if (search.chunks !== void 0) {
|
|
1017
|
-
const c = {};
|
|
1018
|
-
if (search.chunks.size !== void 0 && search.chunks.size > 0) c.sizeChars = search.chunks.size;
|
|
1019
|
-
if (search.chunks.overlap !== void 0 && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;
|
|
1020
|
-
if (Object.keys(c).length > 0) v.chunks = c;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
out2.vector = [v];
|
|
1024
|
-
commonSearchFields(search, out2);
|
|
1025
|
-
return out2;
|
|
1026
|
-
}
|
|
1027
|
-
const out = {};
|
|
1028
|
-
if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };
|
|
1029
|
-
const legs = search.vector === void 0 ? [] : Array.isArray(search.vector) ? search.vector : [search.vector];
|
|
1030
|
-
if (legs.length > 0) {
|
|
1031
|
-
out.vector = legs.map((leg) => {
|
|
1032
|
-
const v = { metric: leg.metric ?? "cosine" };
|
|
1033
|
-
if (leg.column !== void 0) v.column = leg.column;
|
|
1034
|
-
if (leg.staleness !== void 0) v.staleness = leg.staleness;
|
|
1035
|
-
if (leg.model !== void 0) {
|
|
1036
|
-
v.embed = {
|
|
1037
|
-
provider: leg.model.provider,
|
|
1038
|
-
model: leg.model.model,
|
|
1039
|
-
from: [...leg.from ?? []],
|
|
1040
|
-
...leg.model.apiKeyName !== void 0 ? { apiKeyName: leg.model.apiKeyName } : {},
|
|
1041
|
-
...leg.model.dimensions !== void 0 ? { dimensions: leg.model.dimensions } : {},
|
|
1042
|
-
...leg.model.baseURL !== void 0 ? { baseURL: leg.model.baseURL } : {}
|
|
1043
|
-
};
|
|
1044
|
-
}
|
|
1045
|
-
return v;
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
commonSearchFields(search, out);
|
|
1049
|
-
return out;
|
|
1050
|
-
}
|
|
1051
|
-
function memoryToJSON(m) {
|
|
1052
|
-
return {
|
|
1053
|
-
from: [...m.from],
|
|
1054
|
-
into: m.into,
|
|
1055
|
-
...m.subject !== void 0 ? { subject: m.subject } : {},
|
|
1056
|
-
extract: { provider: m.extract.provider, model: m.extract.model }
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
function tableToJSON(table) {
|
|
1060
|
-
const columns = {};
|
|
1061
|
-
for (const [name, column] of Object.entries(table.columns)) {
|
|
1062
|
-
columns[name] = columnToJSON(column);
|
|
1063
|
-
}
|
|
1064
|
-
const out = {
|
|
1065
|
-
name: table.name,
|
|
1066
|
-
columns,
|
|
1067
|
-
// Read, not re-derived. `defineSchema` already resolves the fail-closed
|
|
1068
|
-
// default (RLS on unless the author wrote `rls: false`, and forced on by any
|
|
1069
|
-
// policy), and a second copy of a SECURITY default is exactly the thing that
|
|
1070
|
-
// drifts — the direction it drifted last time was "expose everything", and
|
|
1071
|
-
// the live proof was one user reading another's rows.
|
|
1072
|
-
rls: table.rls,
|
|
1073
|
-
policies: (table.policies ?? []).map(policyToJSON)
|
|
1074
|
-
};
|
|
1075
|
-
if (table.primaryKey !== void 0 && table.primaryKey.length > 0) {
|
|
1076
|
-
out.primaryKey = [...table.primaryKey];
|
|
1077
|
-
}
|
|
1078
|
-
if (table.unique !== void 0 && table.unique.length > 0) {
|
|
1079
|
-
out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));
|
|
1080
|
-
}
|
|
1081
|
-
if (table.raw !== void 0 && table.raw.length > 0) {
|
|
1082
|
-
out.rawConstraints = table.raw.map((r) => ({
|
|
1083
|
-
name: r.name,
|
|
1084
|
-
up: r.up,
|
|
1085
|
-
down: r.down ?? null
|
|
1086
|
-
}));
|
|
1087
|
-
}
|
|
1088
|
-
if (table.checks !== void 0 && table.checks.length > 0) {
|
|
1089
|
-
out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));
|
|
1090
|
-
}
|
|
1091
|
-
if (table.indexes !== void 0 && table.indexes.length > 0) {
|
|
1092
|
-
out.indexes = table.indexes.map((i) => ({ name: i.name, columns: [...i.columns] }));
|
|
1093
|
-
}
|
|
1094
|
-
if (table.search !== void 0) {
|
|
1095
|
-
const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== void 0)?.[0];
|
|
1096
|
-
const sj = searchToJSON(table.search, vectorColumn);
|
|
1097
|
-
if (sj.text !== void 0 || sj.vector !== void 0) out.search = sj;
|
|
1098
|
-
}
|
|
1099
|
-
if (table.memory !== void 0) {
|
|
1100
|
-
out.memory = memoryToJSON(table.memory);
|
|
1101
|
-
}
|
|
1102
|
-
return out;
|
|
1103
|
-
}
|
|
1104
|
-
function toSchemaJSON(schema) {
|
|
1105
|
-
const tables = {};
|
|
1106
|
-
for (const table of Object.values(schema.tables)) {
|
|
1107
|
-
const json = tableToJSON(table);
|
|
1108
|
-
tables[json.name] = json;
|
|
1109
|
-
}
|
|
1110
|
-
return { tables, extensions: [...new Set(schema.extensions ?? [])] };
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
961
|
// src/channels.ts
|
|
1114
962
|
var CHANNELS = /* @__PURE__ */ Symbol.for("palbase.backend.channels");
|
|
1115
963
|
function ownerOnly() {
|
|
@@ -1209,50 +1057,82 @@ function rowType(def) {
|
|
|
1209
1057
|
function optionalOnInsert(def) {
|
|
1210
1058
|
return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
|
|
1211
1059
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
for (const [col, builder] of Object.entries(table.columns)) {
|
|
1215
|
-
if (builder._def.references?.table === AUTH_USERS_TABLE) return col;
|
|
1216
|
-
}
|
|
1217
|
-
return null;
|
|
1060
|
+
function forwardName(column) {
|
|
1061
|
+
return column.endsWith("_id") ? column.slice(0, -3) : column;
|
|
1218
1062
|
}
|
|
1219
|
-
function
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
const ref = builder._def.references;
|
|
1227
|
-
if (ref === void 0) continue;
|
|
1228
|
-
if (ref.table === childName) continue;
|
|
1229
|
-
const bucket = edges.get(ref.table);
|
|
1230
|
-
if (bucket === void 0) continue;
|
|
1231
|
-
if (bucket.some((e) => e.child === childName)) continue;
|
|
1232
|
-
bucket.push({ child: childName, column: col });
|
|
1233
|
-
}
|
|
1063
|
+
function describeOrigin(o) {
|
|
1064
|
+
return o.direction === "forward" ? `the foreign key "${o.table}.${o.column}"` : `the reverse of "${o.table}.${o.column}"`;
|
|
1065
|
+
}
|
|
1066
|
+
function renameCall(o) {
|
|
1067
|
+
if (o.direction === "reverse") return `references(() => \u2026, { reverseAs: "\u2026" })`;
|
|
1068
|
+
if (o.def.owns === true) {
|
|
1069
|
+
return `ownedByUser() takes no { as } \u2014 if "${o.column}" only POINTS at a user, declare it userRef({ onDelete: \u2026 }) instead`;
|
|
1234
1070
|
}
|
|
1235
|
-
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1071
|
+
const target = o.def.references?.table;
|
|
1072
|
+
if (target === "auth.users") return `userRef({ onDelete: \u2026, as: "\u2026" })`;
|
|
1073
|
+
if (target === "auth.installations") return `installationRef({ onDelete: \u2026, as: "\u2026" })`;
|
|
1074
|
+
if (o.def.selfRefColumn !== void 0) return `selfReferences("\u2026", { as: "\u2026" })`;
|
|
1075
|
+
return `references(() => \u2026, { as: "\u2026" })`;
|
|
1076
|
+
}
|
|
1077
|
+
function buildRelations(schemas) {
|
|
1078
|
+
const out = /* @__PURE__ */ new Map();
|
|
1079
|
+
const taken = /* @__PURE__ */ new Map();
|
|
1080
|
+
for (const schema of schemas) {
|
|
1081
|
+
for (const t of Object.values(schema.tables)) {
|
|
1082
|
+
const key = qualifiedTableKey(schema.name, t.name);
|
|
1083
|
+
out.set(key, []);
|
|
1084
|
+
taken.set(key, /* @__PURE__ */ new Map());
|
|
1247
1085
|
}
|
|
1248
|
-
state.set(table, "done");
|
|
1249
1086
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1087
|
+
const claim = (tableKey, name, origin, edge) => {
|
|
1088
|
+
const names = taken.get(tableKey);
|
|
1089
|
+
if (names === void 0) return;
|
|
1090
|
+
const held = names.get(name);
|
|
1091
|
+
if (held !== void 0) {
|
|
1092
|
+
if (held.def.owns === true && origin.def.owns === true) {
|
|
1093
|
+
throw new Error(
|
|
1094
|
+
`table "${tableKey}" declares TWO owner columns (${held.column}, ${origin.column}) \u2014 a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: \u2026 }) instead.`
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
const heldFix = renameCall(held);
|
|
1098
|
+
const originFix = renameCall(origin);
|
|
1099
|
+
const remedy = heldFix === originFix ? `rename one of them: ${heldFix}` : `rename one of them \u2014 "${held.table}.${held.column}": ${heldFix}; "${origin.table}.${origin.column}": ${originFix}`;
|
|
1100
|
+
throw new Error(
|
|
1101
|
+
`table "${tableKey}": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name "${name}" \u2014 ${remedy}.`
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
names.set(name, origin);
|
|
1105
|
+
out.get(tableKey)?.push(edge);
|
|
1106
|
+
};
|
|
1107
|
+
for (const schema of schemas) {
|
|
1108
|
+
for (const table of Object.values(schema.tables)) {
|
|
1109
|
+
const childKey = qualifiedTableKey(schema.name, table.name);
|
|
1110
|
+
if (!out.has(childKey)) continue;
|
|
1111
|
+
for (const [col, builder] of Object.entries(table.columns)) {
|
|
1112
|
+
const def = builder._def;
|
|
1113
|
+
if (def.references === void 0) continue;
|
|
1114
|
+
const targetKey = def.references.table;
|
|
1115
|
+
const name = def.owns === true ? "owner" : def.refAs ?? forwardName(col);
|
|
1116
|
+
claim(
|
|
1117
|
+
childKey,
|
|
1118
|
+
name,
|
|
1119
|
+
{ table: table.name, column: col, direction: "forward", def },
|
|
1120
|
+
{ name, to: targetKey, kind: "one", via: col }
|
|
1121
|
+
);
|
|
1122
|
+
if (!out.has(targetKey) || targetKey === childKey) continue;
|
|
1123
|
+
const reverse = def.reverseAs ?? table.name;
|
|
1124
|
+
claim(
|
|
1125
|
+
targetKey,
|
|
1126
|
+
reverse,
|
|
1127
|
+
{ table: table.name, column: col, direction: "reverse", def },
|
|
1128
|
+
{ name: reverse, to: childKey, kind: "many", via: col }
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1252
1132
|
}
|
|
1253
|
-
return
|
|
1133
|
+
return out;
|
|
1254
1134
|
}
|
|
1255
|
-
function tableBlock(table,
|
|
1135
|
+
function tableBlock(table, relations, indent) {
|
|
1256
1136
|
const cols = Object.entries(table.columns);
|
|
1257
1137
|
const rowLines = cols.map(([col, builder]) => {
|
|
1258
1138
|
return `${indent} ${col}: ${rowType(builder._def)};`;
|
|
@@ -1262,8 +1142,9 @@ function tableBlock(table, children, indent) {
|
|
|
1262
1142
|
const opt = optionalOnInsert(def) ? "?" : "";
|
|
1263
1143
|
return `${indent} ${col}${opt}: ${rowType(def)};`;
|
|
1264
1144
|
});
|
|
1265
|
-
const
|
|
1266
|
-
|
|
1145
|
+
const relEntries = relations.map(
|
|
1146
|
+
(r) => `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`
|
|
1147
|
+
).join("; ");
|
|
1267
1148
|
return [
|
|
1268
1149
|
`${indent}${table.name}: {`,
|
|
1269
1150
|
`${indent} row: {`,
|
|
@@ -1272,8 +1153,7 @@ function tableBlock(table, children, indent) {
|
|
|
1272
1153
|
`${indent} insert: {`,
|
|
1273
1154
|
...insertLines,
|
|
1274
1155
|
`${indent} };`,
|
|
1275
|
-
`${indent}
|
|
1276
|
-
`${indent} children: {${childEntries === "" ? "" : ` ${childEntries} `}};`,
|
|
1156
|
+
`${indent} relations: {${relEntries === "" ? "" : ` ${relEntries} `}};`,
|
|
1277
1157
|
// searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
|
|
1278
1158
|
// üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
|
|
1279
1159
|
// mevcut şemaların d.ts'i bayt-aynı kalsın.
|
|
@@ -1281,22 +1161,36 @@ function tableBlock(table, children, indent) {
|
|
|
1281
1161
|
`${indent}};`
|
|
1282
1162
|
].join("\n");
|
|
1283
1163
|
}
|
|
1284
|
-
function makeEnvDts(
|
|
1285
|
-
const
|
|
1286
|
-
const
|
|
1287
|
-
const
|
|
1288
|
-
|
|
1164
|
+
function makeEnvDts(schemas) {
|
|
1165
|
+
const relations = buildRelations(schemas);
|
|
1166
|
+
const publicSchema = schemas.find((s) => s.name === "public");
|
|
1167
|
+
const others = schemas.filter((s) => s.name !== "public");
|
|
1168
|
+
const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map(
|
|
1169
|
+
(name) => tableBlock(publicSchema.tables[name], relations.get(name) ?? [], " ")
|
|
1289
1170
|
);
|
|
1290
|
-
const body =
|
|
1291
|
-
${
|
|
1171
|
+
const body = publicBlocks.length > 0 ? `
|
|
1172
|
+
${publicBlocks.join("\n")}
|
|
1173
|
+
` : "";
|
|
1174
|
+
const schemaBlocks = others.map((schema) => {
|
|
1175
|
+
const inner = Object.keys(schema.tables).map(
|
|
1176
|
+
(name) => tableBlock(schema.tables[name], relations.get(qualifiedTableKey(schema.name, name)) ?? [], " ")
|
|
1177
|
+
);
|
|
1178
|
+
return ` ${schema.name}: {
|
|
1179
|
+
${inner.join("\n")}
|
|
1180
|
+
};`;
|
|
1181
|
+
});
|
|
1182
|
+
const schemasBody = schemaBlocks.length > 0 ? `
|
|
1183
|
+
${schemaBlocks.join("\n")}
|
|
1292
1184
|
` : "";
|
|
1293
1185
|
return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
|
|
1294
|
-
// Regenerated from db
|
|
1186
|
+
// Regenerated from db/*.ts by \`palbase build\` and by every deploy.
|
|
1295
1187
|
// Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
|
|
1296
|
-
// is typed with no import and no generic.
|
|
1188
|
+
// is typed with no import and no generic. Schemas other than \`public\` land
|
|
1189
|
+
// under \`Schemas\`, reached with \`Database.schema("<name>").tables.*\`.
|
|
1297
1190
|
|
|
1298
1191
|
declare module "@palbase/backend/env" {
|
|
1299
1192
|
interface Tables {${body}}
|
|
1193
|
+
interface Schemas {${schemasBody}}
|
|
1300
1194
|
}
|
|
1301
1195
|
|
|
1302
1196
|
export {};
|
|
@@ -1577,6 +1471,56 @@ function Signal() {
|
|
|
1577
1471
|
};
|
|
1578
1472
|
}
|
|
1579
1473
|
|
|
1474
|
+
// src/decorators/room.ts
|
|
1475
|
+
var DEFAULT_GRACE_MS = 6e4;
|
|
1476
|
+
function assertPattern(pattern) {
|
|
1477
|
+
if (pattern.includes("/")) {
|
|
1478
|
+
throw new Error(
|
|
1479
|
+
`@Room("${pattern}"): channel patterns are colon-separated, not slash-separated. Write "${pattern.replace(/\//g, ":")}" \u2014 a slash matches no live topic.`
|
|
1480
|
+
);
|
|
1481
|
+
}
|
|
1482
|
+
const segments = pattern.split(":");
|
|
1483
|
+
if (segments.some((s) => s === "")) {
|
|
1484
|
+
throw new Error(`@Room("${pattern}"): empty segment \u2014 every segment must be non-empty.`);
|
|
1485
|
+
}
|
|
1486
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1487
|
+
for (const s of segments) {
|
|
1488
|
+
if (!s.startsWith("{") || !s.endsWith("}")) continue;
|
|
1489
|
+
const name = s.slice(1, -1);
|
|
1490
|
+
if (name === "") throw new Error(`@Room("${pattern}"): "{}" names no parameter.`);
|
|
1491
|
+
if (seen.has(name)) {
|
|
1492
|
+
throw new Error(`@Room("${pattern}"): parameter "{${name}}" appears twice.`);
|
|
1493
|
+
}
|
|
1494
|
+
seen.add(name);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
function Room(pattern, options) {
|
|
1498
|
+
return function(ctor) {
|
|
1499
|
+
assertPattern(pattern);
|
|
1500
|
+
recordRoom(ctor, {
|
|
1501
|
+
pattern,
|
|
1502
|
+
events: options.events,
|
|
1503
|
+
graceMs: options.graceMs ?? DEFAULT_GRACE_MS
|
|
1504
|
+
});
|
|
1505
|
+
return ctor;
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
function hookDecorator(hook) {
|
|
1509
|
+
return () => function(target, propertyKey) {
|
|
1510
|
+
recordRoomHook(target, hook, String(propertyKey));
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
var OnAuthorize = hookDecorator("authorize");
|
|
1514
|
+
var OnFirst = hookDecorator("first");
|
|
1515
|
+
var OnJoin = hookDecorator("join");
|
|
1516
|
+
var OnLeave = hookDecorator("leave");
|
|
1517
|
+
var OnEmpty = hookDecorator("empty");
|
|
1518
|
+
function OnMessage(name, schema) {
|
|
1519
|
+
return function(target, propertyKey) {
|
|
1520
|
+
recordRoomMessage(target, name, String(propertyKey), schema);
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1580
1524
|
// src/decorators/params.ts
|
|
1581
1525
|
function makeParamDecorator(kind, extra) {
|
|
1582
1526
|
return function(target, propertyKey, parameterIndex) {
|
|
@@ -1777,6 +1721,12 @@ export {
|
|
|
1777
1721
|
NotFound,
|
|
1778
1722
|
Notifications,
|
|
1779
1723
|
On,
|
|
1724
|
+
OnAuthorize,
|
|
1725
|
+
OnEmpty,
|
|
1726
|
+
OnFirst,
|
|
1727
|
+
OnJoin,
|
|
1728
|
+
OnLeave,
|
|
1729
|
+
OnMessage,
|
|
1780
1730
|
OptionalUser,
|
|
1781
1731
|
PALBASE_EXTENSIONS,
|
|
1782
1732
|
PalError,
|
|
@@ -1791,11 +1741,13 @@ export {
|
|
|
1791
1741
|
Realtime,
|
|
1792
1742
|
Req,
|
|
1793
1743
|
RequestId,
|
|
1744
|
+
Room,
|
|
1794
1745
|
Secrets,
|
|
1795
1746
|
Signal,
|
|
1796
1747
|
Sse,
|
|
1797
1748
|
SseOut,
|
|
1798
1749
|
Storage,
|
|
1750
|
+
TABLE_META,
|
|
1799
1751
|
TooManyRequests,
|
|
1800
1752
|
TraceId,
|
|
1801
1753
|
TxPlanError,
|
|
@@ -1824,6 +1776,7 @@ export {
|
|
|
1824
1776
|
defineError,
|
|
1825
1777
|
defineMiddleware,
|
|
1826
1778
|
defineSchema,
|
|
1779
|
+
defineTable,
|
|
1827
1780
|
enumType,
|
|
1828
1781
|
getErrorRegistry,
|
|
1829
1782
|
getHookConfig,
|
|
@@ -1832,6 +1785,7 @@ export {
|
|
|
1832
1785
|
getRoutes,
|
|
1833
1786
|
getWebhookConfig,
|
|
1834
1787
|
inc,
|
|
1788
|
+
installationRef,
|
|
1835
1789
|
integer,
|
|
1836
1790
|
isPalbaseExtension,
|
|
1837
1791
|
jsonb,
|
|
@@ -1844,6 +1798,7 @@ export {
|
|
|
1844
1798
|
onShutdown,
|
|
1845
1799
|
onStart,
|
|
1846
1800
|
openai,
|
|
1801
|
+
ownedByUser,
|
|
1847
1802
|
ownerOnly,
|
|
1848
1803
|
policy,
|
|
1849
1804
|
publicChannel,
|
|
@@ -1853,6 +1808,7 @@ export {
|
|
|
1853
1808
|
text,
|
|
1854
1809
|
timestamp,
|
|
1855
1810
|
toSchemaJSON,
|
|
1811
|
+
userRef,
|
|
1856
1812
|
uuid,
|
|
1857
1813
|
vector,
|
|
1858
1814
|
z
|