@palbase/backend 24.3.0 → 25.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 +101 -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-43A3KGWL.js} +80 -49
- package/dist/chunk-43A3KGWL.js.map +1 -0
- package/dist/{chunk-ERDL5VAE.js → chunk-5CMLOAEF.js} +2 -2
- package/dist/chunk-OEQBHE2Z.js +825 -0
- package/dist/chunk-OEQBHE2Z.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-UWSYTUGM.js → chunk-ZQRWW37O.js} +44 -1
- package/dist/chunk-ZQRWW37O.js.map +1 -0
- package/dist/db/env.cjs.map +1 -1
- package/dist/db/env.d.cts +29 -13
- package/dist/db/env.d.ts +29 -13
- package/dist/db/index.cjs +212 -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 +87 -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-DEneI8Mn.d.ts → index-BF1f0DfA.d.ts} +5 -2
- package/dist/{index-C-ALG22n.d.cts → index-CoaDN9dL.d.cts} +5 -2
- package/dist/{index-BTMYod_l.d.ts → index-Ct1iiB4N.d.ts} +203 -61
- package/dist/{index-BLAbr9ZH.d.cts → index-CwaWRhyc.d.cts} +203 -61
- package/dist/index.cjs +550 -297
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -20
- package/dist/index.d.ts +122 -20
- package/dist/index.js +164 -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 +399 -153
- package/docs/schema.md +272 -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-5CMLOAEF.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -2,27 +2,33 @@ 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,
|
|
16
20
|
raw,
|
|
17
21
|
text,
|
|
18
22
|
timestamp,
|
|
23
|
+
toSchemaJSON,
|
|
24
|
+
userRef,
|
|
19
25
|
uuid,
|
|
20
26
|
vector
|
|
21
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-OEQBHE2Z.js";
|
|
22
28
|
import {
|
|
23
29
|
defineError,
|
|
24
30
|
getErrorRegistry
|
|
25
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-5CMLOAEF.js";
|
|
26
32
|
import {
|
|
27
33
|
Cache,
|
|
28
34
|
Database,
|
|
@@ -41,7 +47,7 @@ import {
|
|
|
41
47
|
__setRuntime,
|
|
42
48
|
onShutdown,
|
|
43
49
|
onStart
|
|
44
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-XJ2RSHEU.js";
|
|
45
51
|
import {
|
|
46
52
|
TxPlanError,
|
|
47
53
|
TxRefError,
|
|
@@ -67,10 +73,13 @@ import {
|
|
|
67
73
|
getRegisteredControllers,
|
|
68
74
|
getRoutes,
|
|
69
75
|
recordParam,
|
|
76
|
+
recordRoom,
|
|
77
|
+
recordRoomHook,
|
|
78
|
+
recordRoomMessage,
|
|
70
79
|
recordRoute,
|
|
71
80
|
recordThrows,
|
|
72
81
|
resolveEffectiveAuth
|
|
73
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-ZQRWW37O.js";
|
|
74
83
|
import "./chunk-7D4SUZUM.js";
|
|
75
84
|
|
|
76
85
|
// src/clients/http.ts
|
|
@@ -948,168 +957,6 @@ function buildModuleClients(cfg) {
|
|
|
948
957
|
};
|
|
949
958
|
}
|
|
950
959
|
|
|
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
960
|
// src/channels.ts
|
|
1114
961
|
var CHANNELS = /* @__PURE__ */ Symbol.for("palbase.backend.channels");
|
|
1115
962
|
function ownerOnly() {
|
|
@@ -1209,50 +1056,73 @@ function rowType(def) {
|
|
|
1209
1056
|
function optionalOnInsert(def) {
|
|
1210
1057
|
return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
|
|
1211
1058
|
}
|
|
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;
|
|
1059
|
+
function forwardName(column) {
|
|
1060
|
+
return column.endsWith("_id") ? column.slice(0, -3) : column;
|
|
1218
1061
|
}
|
|
1219
|
-
function
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
if (bucket === void 0) continue;
|
|
1231
|
-
if (bucket.some((e) => e.child === childName)) continue;
|
|
1232
|
-
bucket.push({ child: childName, column: col });
|
|
1062
|
+
function qualify(schemaName, tableName) {
|
|
1063
|
+
return schemaName === "public" ? tableName : `${schemaName}.${tableName}`;
|
|
1064
|
+
}
|
|
1065
|
+
function buildRelations(schemas) {
|
|
1066
|
+
const out = /* @__PURE__ */ new Map();
|
|
1067
|
+
const keyOf = /* @__PURE__ */ new Map();
|
|
1068
|
+
for (const schema of schemas) {
|
|
1069
|
+
for (const t of Object.values(schema.tables)) {
|
|
1070
|
+
const key = qualify(schema.name, t.name);
|
|
1071
|
+
out.set(key, []);
|
|
1072
|
+
keyOf.set(t.name, key);
|
|
1233
1073
|
}
|
|
1234
1074
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1075
|
+
for (const schema of schemas) {
|
|
1076
|
+
for (const table of Object.values(schema.tables)) {
|
|
1077
|
+
const childKey = qualify(schema.name, table.name);
|
|
1078
|
+
const bucket = out.get(childKey);
|
|
1079
|
+
if (bucket === void 0) continue;
|
|
1080
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
1081
|
+
for (const [col, builder] of Object.entries(table.columns)) {
|
|
1082
|
+
const ref = builder._def.references;
|
|
1083
|
+
if (ref === void 0) continue;
|
|
1084
|
+
const list = byTarget.get(ref.table) ?? [];
|
|
1085
|
+
list.push(col);
|
|
1086
|
+
byTarget.set(ref.table, list);
|
|
1087
|
+
}
|
|
1088
|
+
for (const [target, cols] of byTarget) {
|
|
1089
|
+
if (cols.length < 2) continue;
|
|
1090
|
+
const unnamed = cols.filter((c) => {
|
|
1091
|
+
const d = table.columns[c]?._def;
|
|
1092
|
+
return d?.refAs === void 0 && d?.owns !== true;
|
|
1093
|
+
});
|
|
1094
|
+
if (unnamed.length > 0) {
|
|
1095
|
+
throw new Error(
|
|
1096
|
+
`table "${table.name}" declares ${cols.length} foreign keys onto "${target}" (${cols.join(", ")}) \u2014 name each one: references(() => \u2026, { as: "\u2026" })`
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
for (const [col, builder] of Object.entries(table.columns)) {
|
|
1101
|
+
const def = builder._def;
|
|
1102
|
+
if (def.references === void 0) continue;
|
|
1103
|
+
const name = def.owns === true ? "owner" : def.refAs ?? forwardName(col);
|
|
1104
|
+
if (bucket.some((r) => r.name === name)) {
|
|
1105
|
+
throw new Error(
|
|
1106
|
+
name === "owner" ? `table "${table.name}": two columns claim ownership of the row \u2014 a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: \u2026 }) instead.` : `table "${table.name}": two relations resolve to the name "${name}" \u2014 give one an explicit { as: "\u2026" }`
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
const targetKey = keyOf.get(def.references.table) ?? def.references.table;
|
|
1110
|
+
bucket.push({ name, to: targetKey, kind: "one", via: col });
|
|
1111
|
+
const parent = out.get(targetKey);
|
|
1112
|
+
if (parent === void 0 || targetKey === childKey) continue;
|
|
1113
|
+
const reverse = def.refAs ?? table.name;
|
|
1114
|
+
if (parent.some((r) => r.name === reverse)) {
|
|
1115
|
+
throw new Error(
|
|
1116
|
+
`table "${def.references.table}": two reverse relations resolve to the name "${reverse}" \u2014 give one an explicit { as: "\u2026" }`
|
|
1117
|
+
);
|
|
1118
|
+
}
|
|
1119
|
+
parent.push({ name: reverse, to: childKey, kind: "many", via: col });
|
|
1120
|
+
}
|
|
1247
1121
|
}
|
|
1248
|
-
state.set(table, "done");
|
|
1249
1122
|
}
|
|
1250
|
-
|
|
1251
|
-
if (state.get(table) === void 0) visit(table);
|
|
1252
|
-
}
|
|
1253
|
-
return pruned;
|
|
1123
|
+
return out;
|
|
1254
1124
|
}
|
|
1255
|
-
function tableBlock(table,
|
|
1125
|
+
function tableBlock(table, relations, indent) {
|
|
1256
1126
|
const cols = Object.entries(table.columns);
|
|
1257
1127
|
const rowLines = cols.map(([col, builder]) => {
|
|
1258
1128
|
return `${indent} ${col}: ${rowType(builder._def)};`;
|
|
@@ -1262,8 +1132,9 @@ function tableBlock(table, children, indent) {
|
|
|
1262
1132
|
const opt = optionalOnInsert(def) ? "?" : "";
|
|
1263
1133
|
return `${indent} ${col}${opt}: ${rowType(def)};`;
|
|
1264
1134
|
});
|
|
1265
|
-
const
|
|
1266
|
-
|
|
1135
|
+
const relEntries = relations.map(
|
|
1136
|
+
(r) => `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`
|
|
1137
|
+
).join("; ");
|
|
1267
1138
|
return [
|
|
1268
1139
|
`${indent}${table.name}: {`,
|
|
1269
1140
|
`${indent} row: {`,
|
|
@@ -1272,8 +1143,7 @@ function tableBlock(table, children, indent) {
|
|
|
1272
1143
|
`${indent} insert: {`,
|
|
1273
1144
|
...insertLines,
|
|
1274
1145
|
`${indent} };`,
|
|
1275
|
-
`${indent}
|
|
1276
|
-
`${indent} children: {${childEntries === "" ? "" : ` ${childEntries} `}};`,
|
|
1146
|
+
`${indent} relations: {${relEntries === "" ? "" : ` ${relEntries} `}};`,
|
|
1277
1147
|
// searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
|
|
1278
1148
|
// üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
|
|
1279
1149
|
// mevcut şemaların d.ts'i bayt-aynı kalsın.
|
|
@@ -1281,22 +1151,37 @@ function tableBlock(table, children, indent) {
|
|
|
1281
1151
|
`${indent}};`
|
|
1282
1152
|
].join("\n");
|
|
1283
1153
|
}
|
|
1284
|
-
function makeEnvDts(
|
|
1285
|
-
const
|
|
1286
|
-
const
|
|
1287
|
-
const
|
|
1288
|
-
|
|
1154
|
+
function makeEnvDts(schemas) {
|
|
1155
|
+
const relations = buildRelations(schemas);
|
|
1156
|
+
const qualify2 = (schemaName, table) => schemaName === "public" ? table : `${schemaName}.${table}`;
|
|
1157
|
+
const publicSchema = schemas.find((s) => s.name === "public");
|
|
1158
|
+
const others = schemas.filter((s) => s.name !== "public");
|
|
1159
|
+
const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map(
|
|
1160
|
+
(name) => tableBlock(publicSchema.tables[name], relations.get(name) ?? [], " ")
|
|
1289
1161
|
);
|
|
1290
|
-
const body =
|
|
1291
|
-
${
|
|
1162
|
+
const body = publicBlocks.length > 0 ? `
|
|
1163
|
+
${publicBlocks.join("\n")}
|
|
1164
|
+
` : "";
|
|
1165
|
+
const schemaBlocks = others.map((schema) => {
|
|
1166
|
+
const inner = Object.keys(schema.tables).map(
|
|
1167
|
+
(name) => tableBlock(schema.tables[name], relations.get(qualify2(schema.name, name)) ?? [], " ")
|
|
1168
|
+
);
|
|
1169
|
+
return ` ${schema.name}: {
|
|
1170
|
+
${inner.join("\n")}
|
|
1171
|
+
};`;
|
|
1172
|
+
});
|
|
1173
|
+
const schemasBody = schemaBlocks.length > 0 ? `
|
|
1174
|
+
${schemaBlocks.join("\n")}
|
|
1292
1175
|
` : "";
|
|
1293
1176
|
return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
|
|
1294
|
-
// Regenerated from db
|
|
1177
|
+
// Regenerated from db/*.ts by \`palbase build\` and by every deploy.
|
|
1295
1178
|
// Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
|
|
1296
|
-
// is typed with no import and no generic.
|
|
1179
|
+
// is typed with no import and no generic. Schemas other than \`public\` land
|
|
1180
|
+
// under \`Schemas\`, reached with \`Database.schema("<name>").tables.*\`.
|
|
1297
1181
|
|
|
1298
1182
|
declare module "@palbase/backend/env" {
|
|
1299
1183
|
interface Tables {${body}}
|
|
1184
|
+
interface Schemas {${schemasBody}}
|
|
1300
1185
|
}
|
|
1301
1186
|
|
|
1302
1187
|
export {};
|
|
@@ -1577,6 +1462,56 @@ function Signal() {
|
|
|
1577
1462
|
};
|
|
1578
1463
|
}
|
|
1579
1464
|
|
|
1465
|
+
// src/decorators/room.ts
|
|
1466
|
+
var DEFAULT_GRACE_MS = 6e4;
|
|
1467
|
+
function assertPattern(pattern) {
|
|
1468
|
+
if (pattern.includes("/")) {
|
|
1469
|
+
throw new Error(
|
|
1470
|
+
`@Room("${pattern}"): channel patterns are colon-separated, not slash-separated. Write "${pattern.replace(/\//g, ":")}" \u2014 a slash matches no live topic.`
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
const segments = pattern.split(":");
|
|
1474
|
+
if (segments.some((s) => s === "")) {
|
|
1475
|
+
throw new Error(`@Room("${pattern}"): empty segment \u2014 every segment must be non-empty.`);
|
|
1476
|
+
}
|
|
1477
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1478
|
+
for (const s of segments) {
|
|
1479
|
+
if (!s.startsWith("{") || !s.endsWith("}")) continue;
|
|
1480
|
+
const name = s.slice(1, -1);
|
|
1481
|
+
if (name === "") throw new Error(`@Room("${pattern}"): "{}" names no parameter.`);
|
|
1482
|
+
if (seen.has(name)) {
|
|
1483
|
+
throw new Error(`@Room("${pattern}"): parameter "{${name}}" appears twice.`);
|
|
1484
|
+
}
|
|
1485
|
+
seen.add(name);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
function Room(pattern, options) {
|
|
1489
|
+
return function(ctor) {
|
|
1490
|
+
assertPattern(pattern);
|
|
1491
|
+
recordRoom(ctor, {
|
|
1492
|
+
pattern,
|
|
1493
|
+
events: options.events,
|
|
1494
|
+
graceMs: options.graceMs ?? DEFAULT_GRACE_MS
|
|
1495
|
+
});
|
|
1496
|
+
return ctor;
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function hookDecorator(hook) {
|
|
1500
|
+
return () => function(target, propertyKey) {
|
|
1501
|
+
recordRoomHook(target, hook, String(propertyKey));
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
var OnAuthorize = hookDecorator("authorize");
|
|
1505
|
+
var OnFirst = hookDecorator("first");
|
|
1506
|
+
var OnJoin = hookDecorator("join");
|
|
1507
|
+
var OnLeave = hookDecorator("leave");
|
|
1508
|
+
var OnEmpty = hookDecorator("empty");
|
|
1509
|
+
function OnMessage(name, schema) {
|
|
1510
|
+
return function(target, propertyKey) {
|
|
1511
|
+
recordRoomMessage(target, name, String(propertyKey), schema);
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1580
1515
|
// src/decorators/params.ts
|
|
1581
1516
|
function makeParamDecorator(kind, extra) {
|
|
1582
1517
|
return function(target, propertyKey, parameterIndex) {
|
|
@@ -1777,6 +1712,12 @@ export {
|
|
|
1777
1712
|
NotFound,
|
|
1778
1713
|
Notifications,
|
|
1779
1714
|
On,
|
|
1715
|
+
OnAuthorize,
|
|
1716
|
+
OnEmpty,
|
|
1717
|
+
OnFirst,
|
|
1718
|
+
OnJoin,
|
|
1719
|
+
OnLeave,
|
|
1720
|
+
OnMessage,
|
|
1780
1721
|
OptionalUser,
|
|
1781
1722
|
PALBASE_EXTENSIONS,
|
|
1782
1723
|
PalError,
|
|
@@ -1791,11 +1732,13 @@ export {
|
|
|
1791
1732
|
Realtime,
|
|
1792
1733
|
Req,
|
|
1793
1734
|
RequestId,
|
|
1735
|
+
Room,
|
|
1794
1736
|
Secrets,
|
|
1795
1737
|
Signal,
|
|
1796
1738
|
Sse,
|
|
1797
1739
|
SseOut,
|
|
1798
1740
|
Storage,
|
|
1741
|
+
TABLE_META,
|
|
1799
1742
|
TooManyRequests,
|
|
1800
1743
|
TraceId,
|
|
1801
1744
|
TxPlanError,
|
|
@@ -1824,6 +1767,7 @@ export {
|
|
|
1824
1767
|
defineError,
|
|
1825
1768
|
defineMiddleware,
|
|
1826
1769
|
defineSchema,
|
|
1770
|
+
defineTable,
|
|
1827
1771
|
enumType,
|
|
1828
1772
|
getErrorRegistry,
|
|
1829
1773
|
getHookConfig,
|
|
@@ -1832,6 +1776,7 @@ export {
|
|
|
1832
1776
|
getRoutes,
|
|
1833
1777
|
getWebhookConfig,
|
|
1834
1778
|
inc,
|
|
1779
|
+
installationRef,
|
|
1835
1780
|
integer,
|
|
1836
1781
|
isPalbaseExtension,
|
|
1837
1782
|
jsonb,
|
|
@@ -1844,6 +1789,7 @@ export {
|
|
|
1844
1789
|
onShutdown,
|
|
1845
1790
|
onStart,
|
|
1846
1791
|
openai,
|
|
1792
|
+
ownedByUser,
|
|
1847
1793
|
ownerOnly,
|
|
1848
1794
|
policy,
|
|
1849
1795
|
publicChannel,
|
|
@@ -1853,6 +1799,7 @@ export {
|
|
|
1853
1799
|
text,
|
|
1854
1800
|
timestamp,
|
|
1855
1801
|
toSchemaJSON,
|
|
1802
|
+
userRef,
|
|
1856
1803
|
uuid,
|
|
1857
1804
|
vector,
|
|
1858
1805
|
z
|