@palbase/backend 2.0.2 → 3.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/{chunk-4J3F32SH.js → chunk-B7EUJP5W.js} +38 -9
- package/dist/chunk-B7EUJP5W.js.map +1 -0
- package/dist/{chunk-L36JLUPO.js → chunk-PHAFZGHN.js} +43 -46
- package/dist/chunk-PHAFZGHN.js.map +1 -0
- package/dist/db/env.cjs +19 -0
- package/dist/db/env.cjs.map +1 -0
- package/dist/db/env.d.cts +45 -0
- package/dist/db/env.d.ts +45 -0
- package/dist/db/env.js +1 -0
- package/dist/db/env.js.map +1 -0
- package/dist/db/index.cjs +28 -231
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +4 -20
- package/dist/db/index.d.ts +4 -20
- package/dist/db/index.js +3 -233
- package/dist/db/index.js.map +1 -1
- package/dist/{endpoint-Djk5L6G2.d.ts → endpoint-DJ98tQd6.d.cts} +30 -68
- package/dist/{endpoint-BlcY2xNA.d.cts → endpoint-DJ98tQd6.d.ts} +30 -68
- package/dist/index-CXUs9iTQ.d.ts +294 -0
- package/dist/index-CZAwpQE1.d.cts +294 -0
- package/dist/index.cjs +229 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +398 -154
- package/dist/index.d.ts +398 -154
- package/dist/index.js +147 -12
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +41 -1
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -2
- package/dist/test/index.d.ts +1 -2
- package/dist/test/index.js +1 -1
- package/docs/README.md +31 -10
- package/docs/background.md +19 -13
- package/docs/database.md +30 -17
- package/docs/endpoints.md +42 -24
- package/docs/errors.md +3 -4
- package/docs/events.md +25 -17
- package/docs/getting-started.md +25 -9
- package/docs/llms-full.txt +489 -164
- package/docs/llms.txt +3 -1
- package/docs/migrations.md +98 -0
- package/docs/resources.md +94 -0
- package/docs/routing.md +59 -26
- package/docs/schema.md +48 -38
- package/docs/services.md +5 -6
- package/package.json +11 -1
- package/dist/chunk-4J3F32SH.js.map +0 -1
- package/dist/chunk-L36JLUPO.js.map +0 -1
- package/dist/schema-BqfEhIC0.d.cts +0 -133
- package/dist/schema-BqfEhIC0.d.ts +0 -133
package/dist/index.cjs
CHANGED
|
@@ -28,14 +28,19 @@ __export(src_exports, {
|
|
|
28
28
|
Log: () => Log,
|
|
29
29
|
Notifications: () => Notifications,
|
|
30
30
|
Queue: () => Queue,
|
|
31
|
+
Resource: () => Resource,
|
|
31
32
|
Storage: () => Storage,
|
|
32
33
|
__getRuntime: () => __getRuntime,
|
|
34
|
+
__registerResource: () => __registerResource,
|
|
33
35
|
__requestALS: () => __requestALS,
|
|
36
|
+
__runResourceBoot: () => __runResourceBoot,
|
|
34
37
|
__runWithRuntime: () => __runWithRuntime,
|
|
35
38
|
__setRuntime: () => __setRuntime,
|
|
39
|
+
__shutdownResources: () => __shutdownResources,
|
|
36
40
|
auth: () => auth,
|
|
37
41
|
boolean: () => boolean,
|
|
38
|
-
|
|
42
|
+
defineController: () => defineController,
|
|
43
|
+
defineHandler: () => defineHandler,
|
|
39
44
|
defineJob: () => defineJob,
|
|
40
45
|
defineMiddleware: () => defineMiddleware,
|
|
41
46
|
defineSchema: () => defineSchema,
|
|
@@ -45,54 +50,19 @@ __export(src_exports, {
|
|
|
45
50
|
enumType: () => enumType,
|
|
46
51
|
integer: () => integer,
|
|
47
52
|
jsonb: () => jsonb,
|
|
53
|
+
makeEnvDts: () => makeEnvDts,
|
|
48
54
|
makeTypedDB: () => makeTypedDB,
|
|
55
|
+
route: () => route,
|
|
49
56
|
storage: () => storage,
|
|
50
|
-
table: () => table,
|
|
51
57
|
text: () => text,
|
|
52
58
|
timestamp: () => timestamp,
|
|
53
|
-
typedDatabase: () => typedDatabase,
|
|
54
59
|
uuid: () => uuid,
|
|
55
60
|
z: () => import_zod.z
|
|
56
61
|
});
|
|
57
62
|
module.exports = __toCommonJS(src_exports);
|
|
58
63
|
|
|
59
|
-
// src/endpoint.ts
|
|
60
|
-
function defineEndpoint(config) {
|
|
61
|
-
return config;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
64
|
// src/runtime.ts
|
|
65
65
|
var import_node_async_hooks = require("async_hooks");
|
|
66
|
-
|
|
67
|
-
// src/db/typed-db.ts
|
|
68
|
-
function makeTypedTable(name, raw) {
|
|
69
|
-
return {
|
|
70
|
-
insert: (data) => raw.insert(name, data),
|
|
71
|
-
update: (id, data) => raw.update(name, id, data),
|
|
72
|
-
delete: (id) => raw.delete(name, id),
|
|
73
|
-
findById: (id) => raw.findById(name, id),
|
|
74
|
-
findMany: (query) => raw.findMany(name, query)
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
function makeTypedDB(schema, raw) {
|
|
78
|
-
function buildTables(client) {
|
|
79
|
-
const tables = {};
|
|
80
|
-
for (const key of Object.keys(schema.tables)) {
|
|
81
|
-
const tableDef = schema.tables[key];
|
|
82
|
-
if (tableDef !== void 0) {
|
|
83
|
-
tables[key] = makeTypedTable(tableDef.name, client);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return tables;
|
|
87
|
-
}
|
|
88
|
-
const result = {
|
|
89
|
-
tables: buildTables(raw),
|
|
90
|
-
transaction: (fn) => raw.transaction((rawTx) => fn({ tables: buildTables(rawTx) }))
|
|
91
|
-
};
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// src/runtime.ts
|
|
96
66
|
var __requestALS = new import_node_async_hooks.AsyncLocalStorage();
|
|
97
67
|
var runtime = null;
|
|
98
68
|
function __setRuntime(services) {
|
|
@@ -121,7 +91,47 @@ function makeServiceProxy(key) {
|
|
|
121
91
|
};
|
|
122
92
|
return new Proxy({}, handler);
|
|
123
93
|
}
|
|
124
|
-
|
|
94
|
+
function makeTablesAccessor(ops) {
|
|
95
|
+
const tablesProxy = new Proxy(
|
|
96
|
+
{},
|
|
97
|
+
{
|
|
98
|
+
get(_t, prop) {
|
|
99
|
+
if (typeof prop !== "string") return void 0;
|
|
100
|
+
const name = prop;
|
|
101
|
+
return {
|
|
102
|
+
insert: (data) => ops().insert(name, data),
|
|
103
|
+
update: (id, data) => ops().update(name, id, data),
|
|
104
|
+
delete: (id) => ops().delete(name, id),
|
|
105
|
+
findById: (id) => ops().findById(name, id),
|
|
106
|
+
findMany: (query) => ops().findMany(name, query)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
return tablesProxy;
|
|
112
|
+
}
|
|
113
|
+
var rawDatabase = makeServiceProxy("Database");
|
|
114
|
+
var Database = Object.assign(
|
|
115
|
+
// Spread the raw ops onto a fresh object so the added `tables`/typed
|
|
116
|
+
// `transaction` members live alongside them. Each op still forwards through
|
|
117
|
+
// the request-scoped runtime Proxy.
|
|
118
|
+
{
|
|
119
|
+
query: (sql, params) => rawDatabase.query(sql, params),
|
|
120
|
+
insert: (table, data) => rawDatabase.insert(table, data),
|
|
121
|
+
update: (table, id, data) => rawDatabase.update(table, id, data),
|
|
122
|
+
delete: (table, id) => rawDatabase.delete(table, id),
|
|
123
|
+
findById: (table, id) => rawDatabase.findById(table, id),
|
|
124
|
+
findMany: (table, query) => rawDatabase.findMany(table, query)
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
tables: makeTablesAccessor(() => rawDatabase),
|
|
128
|
+
transaction(fn) {
|
|
129
|
+
return rawDatabase.transaction(
|
|
130
|
+
(rawTx) => fn({ tables: makeTablesAccessor(() => rawTx) })
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
);
|
|
125
135
|
var Documents = makeServiceProxy("Documents");
|
|
126
136
|
var Storage = makeServiceProxy("Storage");
|
|
127
137
|
var Cache = makeServiceProxy("Cache");
|
|
@@ -129,25 +139,13 @@ var Queue = makeServiceProxy("Queue");
|
|
|
129
139
|
var Log = makeServiceProxy("Log");
|
|
130
140
|
var Notifications = makeServiceProxy("Notifications");
|
|
131
141
|
var Flags = makeServiceProxy("Flags");
|
|
132
|
-
function typedDatabase(schema) {
|
|
133
|
-
const typed = makeTypedDB(schema, Database);
|
|
134
|
-
const rawOps = {
|
|
135
|
-
query: (sql, params) => Database.query(sql, params),
|
|
136
|
-
insert: (table2, data) => Database.insert(table2, data),
|
|
137
|
-
update: (table2, id, data) => Database.update(table2, id, data),
|
|
138
|
-
delete: (table2, id) => Database.delete(table2, id),
|
|
139
|
-
findById: (table2, id) => Database.findById(table2, id),
|
|
140
|
-
findMany: (table2, q) => Database.findMany(table2, q),
|
|
141
|
-
transaction: (fn) => Database.transaction(fn)
|
|
142
|
-
};
|
|
143
|
-
return Object.assign(rawOps, typed);
|
|
144
|
-
}
|
|
145
142
|
|
|
146
143
|
// src/db/schema.ts
|
|
147
|
-
function
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
144
|
+
function defineSchema(input) {
|
|
145
|
+
const tables = {};
|
|
146
|
+
for (const name of Object.keys(input.tables)) {
|
|
147
|
+
tables[name] = { name, columns: input.tables[name] };
|
|
148
|
+
}
|
|
151
149
|
return { tables };
|
|
152
150
|
}
|
|
153
151
|
|
|
@@ -192,8 +190,8 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
192
190
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
193
191
|
}
|
|
194
192
|
/** Add a foreign key reference. */
|
|
195
|
-
references(
|
|
196
|
-
this._def.references = { table
|
|
193
|
+
references(table, column) {
|
|
194
|
+
this._def.references = { table, column };
|
|
197
195
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
198
196
|
}
|
|
199
197
|
/** Set the ON DELETE action for a foreign key reference. */
|
|
@@ -227,6 +225,125 @@ function enumType(name, values) {
|
|
|
227
225
|
return builder;
|
|
228
226
|
}
|
|
229
227
|
|
|
228
|
+
// src/db/typed-db.ts
|
|
229
|
+
function makeTypedTable(name, raw) {
|
|
230
|
+
return {
|
|
231
|
+
insert: (data) => raw.insert(name, data),
|
|
232
|
+
update: (id, data) => raw.update(name, id, data),
|
|
233
|
+
delete: (id) => raw.delete(name, id),
|
|
234
|
+
findById: (id) => raw.findById(name, id),
|
|
235
|
+
findMany: (query) => raw.findMany(name, query)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function makeTypedDB(schema, raw) {
|
|
239
|
+
function buildTables(client) {
|
|
240
|
+
const tables = {};
|
|
241
|
+
for (const key of Object.keys(schema.tables)) {
|
|
242
|
+
const tableDef = schema.tables[key];
|
|
243
|
+
if (tableDef !== void 0) {
|
|
244
|
+
tables[key] = makeTypedTable(tableDef.name, client);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return tables;
|
|
248
|
+
}
|
|
249
|
+
const result = {
|
|
250
|
+
tables: buildTables(raw),
|
|
251
|
+
transaction: (fn) => raw.transaction((rawTx) => fn({ tables: buildTables(rawTx) }))
|
|
252
|
+
};
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/db/env-gen.ts
|
|
257
|
+
function baseTsType(def) {
|
|
258
|
+
switch (def.type) {
|
|
259
|
+
case "uuid":
|
|
260
|
+
case "text":
|
|
261
|
+
case "timestamp":
|
|
262
|
+
return "string";
|
|
263
|
+
case "integer":
|
|
264
|
+
return "number";
|
|
265
|
+
case "boolean":
|
|
266
|
+
return "boolean";
|
|
267
|
+
case "jsonb":
|
|
268
|
+
return "unknown";
|
|
269
|
+
case "enum": {
|
|
270
|
+
const values = def.enumValues ?? [];
|
|
271
|
+
if (values.length === 0) return "string";
|
|
272
|
+
return values.map((v) => JSON.stringify(v)).join(" | ");
|
|
273
|
+
}
|
|
274
|
+
default:
|
|
275
|
+
return "unknown";
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function rowType(def) {
|
|
279
|
+
const base = baseTsType(def);
|
|
280
|
+
return def.nullable ? `${base} | null` : base;
|
|
281
|
+
}
|
|
282
|
+
function optionalOnInsert(def) {
|
|
283
|
+
return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
|
|
284
|
+
}
|
|
285
|
+
function tableBlock(table, indent) {
|
|
286
|
+
const cols = Object.entries(table.columns);
|
|
287
|
+
const rowLines = cols.map(([col, builder]) => {
|
|
288
|
+
return `${indent} ${col}: ${rowType(builder._def)};`;
|
|
289
|
+
});
|
|
290
|
+
const insertLines = cols.map(([col, builder]) => {
|
|
291
|
+
const def = builder._def;
|
|
292
|
+
const opt = optionalOnInsert(def) ? "?" : "";
|
|
293
|
+
return `${indent} ${col}${opt}: ${rowType(def)};`;
|
|
294
|
+
});
|
|
295
|
+
return [
|
|
296
|
+
`${indent}${table.name}: {`,
|
|
297
|
+
`${indent} row: {`,
|
|
298
|
+
...rowLines,
|
|
299
|
+
`${indent} };`,
|
|
300
|
+
`${indent} insert: {`,
|
|
301
|
+
...insertLines,
|
|
302
|
+
`${indent} };`,
|
|
303
|
+
`${indent}};`
|
|
304
|
+
].join("\n");
|
|
305
|
+
}
|
|
306
|
+
function makeEnvDts(schema) {
|
|
307
|
+
const tableNames = Object.keys(schema.tables);
|
|
308
|
+
const blocks = tableNames.map((name) => tableBlock(schema.tables[name], " "));
|
|
309
|
+
const body = blocks.length > 0 ? `
|
|
310
|
+
${blocks.join("\n")}
|
|
311
|
+
` : "";
|
|
312
|
+
return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
|
|
313
|
+
// Regenerated from db/schema.ts on every \`palbase serve\` / deploy.
|
|
314
|
+
// Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
|
|
315
|
+
// is typed with no import and no generic.
|
|
316
|
+
|
|
317
|
+
declare module "@palbase/backend/env" {
|
|
318
|
+
interface Tables {${body}}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export {};
|
|
322
|
+
`;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/handler.ts
|
|
326
|
+
function defineHandler(config) {
|
|
327
|
+
return { __palbase: "handler", ...config };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/controller.ts
|
|
331
|
+
function makeRoute(method) {
|
|
332
|
+
return function(path, handler) {
|
|
333
|
+
return { __palbase: "route", method, path, handler };
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
var route = {
|
|
337
|
+
get: makeRoute("GET"),
|
|
338
|
+
post: makeRoute("POST"),
|
|
339
|
+
put: makeRoute("PUT"),
|
|
340
|
+
patch: makeRoute("PATCH"),
|
|
341
|
+
delete: makeRoute("DELETE")
|
|
342
|
+
};
|
|
343
|
+
function defineController(basePath, routes) {
|
|
344
|
+
return { __palbase: "controller", basePath, routes };
|
|
345
|
+
}
|
|
346
|
+
|
|
230
347
|
// src/middleware.ts
|
|
231
348
|
function defineMiddleware(fn) {
|
|
232
349
|
return fn;
|
|
@@ -486,6 +603,52 @@ function validateCustomWebhook(config) {
|
|
|
486
603
|
};
|
|
487
604
|
}
|
|
488
605
|
|
|
606
|
+
// src/resource.ts
|
|
607
|
+
var Resource = class {
|
|
608
|
+
/** The env-var names this resource needs. Optional; omit for none. */
|
|
609
|
+
static secrets;
|
|
610
|
+
};
|
|
611
|
+
function hasSecrets(value) {
|
|
612
|
+
if (typeof value !== "object" && typeof value !== "function") return false;
|
|
613
|
+
const secrets = value.secrets;
|
|
614
|
+
return secrets === void 0 || Array.isArray(secrets);
|
|
615
|
+
}
|
|
616
|
+
var registry = [];
|
|
617
|
+
function __registerResource(resource) {
|
|
618
|
+
registry.push({ resource, booted: false });
|
|
619
|
+
}
|
|
620
|
+
function declaredSecrets(resource) {
|
|
621
|
+
const ctor = resource.constructor;
|
|
622
|
+
return hasSecrets(ctor) ? ctor.secrets ?? [] : [];
|
|
623
|
+
}
|
|
624
|
+
async function __runResourceBoot(envMap) {
|
|
625
|
+
for (const entry of registry) {
|
|
626
|
+
if (entry.booted) continue;
|
|
627
|
+
const secrets = declaredSecrets(entry.resource);
|
|
628
|
+
const env = {};
|
|
629
|
+
for (const name of secrets) {
|
|
630
|
+
const value = envMap[name];
|
|
631
|
+
if (value === void 0) {
|
|
632
|
+
throw new Error(
|
|
633
|
+
`Resource ${entry.resource.constructor.name} requires secret "${name}" but it is not set. Set it with \`palbase secret set ${name} ...\` (or in Studio) and redeploy.`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
env[name] = value;
|
|
637
|
+
}
|
|
638
|
+
await entry.resource.init(env);
|
|
639
|
+
entry.booted = true;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
async function __shutdownResources() {
|
|
643
|
+
for (let i = registry.length - 1; i >= 0; i -= 1) {
|
|
644
|
+
const entry = registry[i];
|
|
645
|
+
if (entry.booted && entry.resource.shutdown) {
|
|
646
|
+
await entry.resource.shutdown();
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
registry.length = 0;
|
|
650
|
+
}
|
|
651
|
+
|
|
489
652
|
// src/hooks.ts
|
|
490
653
|
var auth = {
|
|
491
654
|
onUserCreated(handler) {
|
|
@@ -533,14 +696,19 @@ var import_zod = require("zod");
|
|
|
533
696
|
Log,
|
|
534
697
|
Notifications,
|
|
535
698
|
Queue,
|
|
699
|
+
Resource,
|
|
536
700
|
Storage,
|
|
537
701
|
__getRuntime,
|
|
702
|
+
__registerResource,
|
|
538
703
|
__requestALS,
|
|
704
|
+
__runResourceBoot,
|
|
539
705
|
__runWithRuntime,
|
|
540
706
|
__setRuntime,
|
|
707
|
+
__shutdownResources,
|
|
541
708
|
auth,
|
|
542
709
|
boolean,
|
|
543
|
-
|
|
710
|
+
defineController,
|
|
711
|
+
defineHandler,
|
|
544
712
|
defineJob,
|
|
545
713
|
defineMiddleware,
|
|
546
714
|
defineSchema,
|
|
@@ -550,12 +718,12 @@ var import_zod = require("zod");
|
|
|
550
718
|
enumType,
|
|
551
719
|
integer,
|
|
552
720
|
jsonb,
|
|
721
|
+
makeEnvDts,
|
|
553
722
|
makeTypedDB,
|
|
723
|
+
route,
|
|
554
724
|
storage,
|
|
555
|
-
table,
|
|
556
725
|
text,
|
|
557
726
|
timestamp,
|
|
558
|
-
typedDatabase,
|
|
559
727
|
uuid,
|
|
560
728
|
z
|
|
561
729
|
});
|