@palbase/backend 2.0.0 → 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.
Files changed (51) hide show
  1. package/README.md +24 -0
  2. package/dist/{chunk-4J3F32SH.js → chunk-B7EUJP5W.js} +38 -9
  3. package/dist/chunk-B7EUJP5W.js.map +1 -0
  4. package/dist/{chunk-L36JLUPO.js → chunk-PHAFZGHN.js} +43 -46
  5. package/dist/chunk-PHAFZGHN.js.map +1 -0
  6. package/dist/db/env.cjs +19 -0
  7. package/dist/db/env.cjs.map +1 -0
  8. package/dist/db/env.d.cts +45 -0
  9. package/dist/db/env.d.ts +45 -0
  10. package/dist/db/env.js +1 -0
  11. package/dist/db/env.js.map +1 -0
  12. package/dist/db/index.cjs +28 -231
  13. package/dist/db/index.cjs.map +1 -1
  14. package/dist/db/index.d.cts +4 -20
  15. package/dist/db/index.d.ts +4 -20
  16. package/dist/db/index.js +3 -233
  17. package/dist/db/index.js.map +1 -1
  18. package/dist/{endpoint-Djk5L6G2.d.ts → endpoint-DJ98tQd6.d.cts} +30 -68
  19. package/dist/{endpoint-BlcY2xNA.d.cts → endpoint-DJ98tQd6.d.ts} +30 -68
  20. package/dist/index-CXUs9iTQ.d.ts +294 -0
  21. package/dist/index-CZAwpQE1.d.cts +294 -0
  22. package/dist/index.cjs +229 -61
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +398 -154
  25. package/dist/index.d.ts +398 -154
  26. package/dist/index.js +147 -12
  27. package/dist/index.js.map +1 -1
  28. package/dist/test/index.cjs +41 -1
  29. package/dist/test/index.cjs.map +1 -1
  30. package/dist/test/index.d.cts +1 -2
  31. package/dist/test/index.d.ts +1 -2
  32. package/dist/test/index.js +1 -1
  33. package/docs/README.md +72 -0
  34. package/docs/background.md +62 -0
  35. package/docs/database.md +73 -0
  36. package/docs/endpoints.md +134 -0
  37. package/docs/errors.md +47 -0
  38. package/docs/events.md +67 -0
  39. package/docs/getting-started.md +65 -0
  40. package/docs/llms-full.txt +1038 -0
  41. package/docs/llms.txt +18 -0
  42. package/docs/migrations.md +98 -0
  43. package/docs/resources.md +94 -0
  44. package/docs/routing.md +67 -0
  45. package/docs/schema.md +92 -0
  46. package/docs/services.md +104 -0
  47. package/package.json +15 -3
  48. package/dist/chunk-4J3F32SH.js.map +0 -1
  49. package/dist/chunk-L36JLUPO.js.map +0 -1
  50. package/dist/schema-BqfEhIC0.d.cts +0 -133
  51. 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
- defineEndpoint: () => defineEndpoint,
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
- var Database = makeServiceProxy("Database");
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 table(name, columns) {
148
- return { name, columns };
149
- }
150
- function defineSchema(tables) {
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(table2, column) {
196
- this._def.references = { table: table2, column };
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
- defineEndpoint,
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
  });