@palbase/backend 2.0.2 → 4.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 (53) hide show
  1. package/dist/chunk-EG7TTYHY.js +235 -0
  2. package/dist/chunk-EG7TTYHY.js.map +1 -0
  3. package/dist/chunk-WUQO76NW.js +101 -0
  4. package/dist/chunk-WUQO76NW.js.map +1 -0
  5. package/dist/db/env.cjs +19 -0
  6. package/dist/db/env.cjs.map +1 -0
  7. package/dist/db/env.d.cts +45 -0
  8. package/dist/db/env.d.ts +45 -0
  9. package/dist/db/env.js +1 -0
  10. package/dist/db/env.js.map +1 -0
  11. package/dist/db/index.cjs +143 -231
  12. package/dist/db/index.cjs.map +1 -1
  13. package/dist/db/index.d.cts +4 -20
  14. package/dist/db/index.d.ts +4 -20
  15. package/dist/db/index.js +13 -233
  16. package/dist/db/index.js.map +1 -1
  17. package/dist/{endpoint-Djk5L6G2.d.ts → endpoint-2d_DpASt.d.cts} +94 -96
  18. package/dist/{endpoint-BlcY2xNA.d.cts → endpoint-2d_DpASt.d.ts} +94 -96
  19. package/dist/index-DZW9CjiY.d.ts +463 -0
  20. package/dist/index-DzRFS3Tl.d.cts +463 -0
  21. package/dist/index.cjs +557 -60
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +278 -161
  24. package/dist/index.d.ts +278 -161
  25. package/dist/index.js +343 -12
  26. package/dist/index.js.map +1 -1
  27. package/dist/test/index.cjs +57 -2
  28. package/dist/test/index.cjs.map +1 -1
  29. package/dist/test/index.d.cts +1 -2
  30. package/dist/test/index.d.ts +1 -2
  31. package/dist/test/index.js +10 -2
  32. package/dist/test/index.js.map +1 -1
  33. package/docs/README.md +33 -12
  34. package/docs/background.md +19 -13
  35. package/docs/database.md +70 -17
  36. package/docs/endpoints.md +103 -79
  37. package/docs/errors.md +37 -31
  38. package/docs/events.md +25 -17
  39. package/docs/getting-started.md +38 -18
  40. package/docs/llms-full.txt +758 -267
  41. package/docs/llms.txt +3 -1
  42. package/docs/migrations.md +98 -0
  43. package/docs/resources.md +94 -0
  44. package/docs/routing.md +54 -27
  45. package/docs/schema.md +163 -42
  46. package/docs/services.md +17 -14
  47. package/package.json +12 -2
  48. package/dist/chunk-4J3F32SH.js +0 -96
  49. package/dist/chunk-4J3F32SH.js.map +0 -1
  50. package/dist/chunk-L36JLUPO.js +0 -97
  51. package/dist/chunk-L36JLUPO.js.map +0 -1
  52. package/dist/schema-BqfEhIC0.d.cts +0 -133
  53. package/dist/schema-BqfEhIC0.d.ts +0 -133
package/dist/index.cjs CHANGED
@@ -20,22 +20,52 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ BadRequest: () => BadRequest,
24
+ Body: () => Body,
23
25
  Cache: () => Cache,
26
+ Client: () => Client,
27
+ Conflict: () => Conflict,
28
+ Controller: () => Controller,
24
29
  Database: () => Database,
30
+ Delete: () => Delete,
25
31
  Documents: () => Documents,
32
+ EXTENSION_DEPENDENCIES: () => EXTENSION_DEPENDENCIES,
26
33
  Flags: () => Flags,
34
+ Forbidden: () => Forbidden,
35
+ Get: () => Get,
36
+ Headers: () => Headers,
27
37
  HttpError: () => HttpError,
28
38
  Log: () => Log,
39
+ NotFound: () => NotFound,
29
40
  Notifications: () => Notifications,
41
+ OptionalUser: () => OptionalUser,
42
+ PALBASE_EXTENSIONS: () => PALBASE_EXTENSIONS,
43
+ PalError: () => PalError,
44
+ Param: () => Param,
45
+ Patch: () => Patch,
46
+ PolicyBuilder: () => PolicyBuilder,
47
+ Post: () => Post,
48
+ Put: () => Put,
49
+ Query: () => Query,
30
50
  Queue: () => Queue,
51
+ Req: () => Req,
52
+ RequestId: () => RequestId,
53
+ Resource: () => Resource,
54
+ Returns: () => Returns,
31
55
  Storage: () => Storage,
56
+ TooManyRequests: () => TooManyRequests,
57
+ TraceId: () => TraceId,
58
+ Unauthorized: () => Unauthorized,
59
+ User: () => User,
32
60
  __getRuntime: () => __getRuntime,
61
+ __registerResource: () => __registerResource,
33
62
  __requestALS: () => __requestALS,
63
+ __runResourceBoot: () => __runResourceBoot,
34
64
  __runWithRuntime: () => __runWithRuntime,
35
65
  __setRuntime: () => __setRuntime,
66
+ __shutdownResources: () => __shutdownResources,
36
67
  auth: () => auth,
37
68
  boolean: () => boolean,
38
- defineEndpoint: () => defineEndpoint,
39
69
  defineJob: () => defineJob,
40
70
  defineMiddleware: () => defineMiddleware,
41
71
  defineSchema: () => defineSchema,
@@ -44,55 +74,21 @@ __export(src_exports, {
44
74
  documents: () => documents,
45
75
  enumType: () => enumType,
46
76
  integer: () => integer,
77
+ isPalbaseExtension: () => isPalbaseExtension,
47
78
  jsonb: () => jsonb,
79
+ makeEnvDts: () => makeEnvDts,
48
80
  makeTypedDB: () => makeTypedDB,
81
+ policy: () => policy,
49
82
  storage: () => storage,
50
- table: () => table,
51
83
  text: () => text,
52
84
  timestamp: () => timestamp,
53
- typedDatabase: () => typedDatabase,
54
85
  uuid: () => uuid,
55
86
  z: () => import_zod.z
56
87
  });
57
88
  module.exports = __toCommonJS(src_exports);
58
89
 
59
- // src/endpoint.ts
60
- function defineEndpoint(config) {
61
- return config;
62
- }
63
-
64
90
  // src/runtime.ts
65
91
  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
92
  var __requestALS = new import_node_async_hooks.AsyncLocalStorage();
97
93
  var runtime = null;
98
94
  function __setRuntime(services) {
@@ -121,7 +117,54 @@ function makeServiceProxy(key) {
121
117
  };
122
118
  return new Proxy({}, handler);
123
119
  }
124
- var Database = makeServiceProxy("Database");
120
+ function makeTablesAccessor(ops) {
121
+ const tablesProxy = new Proxy(
122
+ {},
123
+ {
124
+ get(_t, prop) {
125
+ if (typeof prop !== "string") return void 0;
126
+ const name = prop;
127
+ return {
128
+ insert: (data) => ops().insert(name, data),
129
+ update: (id, data) => ops().update(name, id, data),
130
+ delete: (id) => ops().delete(name, id),
131
+ findById: (id) => ops().findById(name, id),
132
+ findMany: (query) => ops().findMany(name, query)
133
+ };
134
+ }
135
+ }
136
+ );
137
+ return tablesProxy;
138
+ }
139
+ var rawDatabase = makeServiceProxy("Database");
140
+ function makeTypedSurface(raw) {
141
+ const ops = {
142
+ query: (sql, params) => raw.query(sql, params),
143
+ insert: (table, data) => raw.insert(table, data),
144
+ update: (table, id, data) => raw.update(table, id, data),
145
+ delete: (table, id) => raw.delete(table, id),
146
+ findById: (table, id) => raw.findById(table, id),
147
+ findMany: (table, query) => raw.findMany(table, query)
148
+ };
149
+ return Object.assign(ops, {
150
+ tables: makeTablesAccessor(() => raw),
151
+ transaction(fn) {
152
+ return raw.transaction((rawTx) => fn({ tables: makeTablesAccessor(() => rawTx) }));
153
+ }
154
+ });
155
+ }
156
+ var Database = Object.assign(makeTypedSurface(rawDatabase), {
157
+ /**
158
+ * Lazily resolve the runtime's service-role sibling on each call. We do NOT
159
+ * cache it: `rawDatabase.asService()` reads the CURRENT request scope through
160
+ * the runtime proxy, and the per-request runtime injects a service client
161
+ * bound to that request's identity headers — caching would leak one request's
162
+ * sibling into another concurrent request.
163
+ */
164
+ asService() {
165
+ return makeTypedSurface(rawDatabase.asService());
166
+ }
167
+ });
125
168
  var Documents = makeServiceProxy("Documents");
126
169
  var Storage = makeServiceProxy("Storage");
127
170
  var Cache = makeServiceProxy("Cache");
@@ -129,26 +172,119 @@ var Queue = makeServiceProxy("Queue");
129
172
  var Log = makeServiceProxy("Log");
130
173
  var Notifications = makeServiceProxy("Notifications");
131
174
  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);
175
+
176
+ // src/db/policy.ts
177
+ var PolicyBuilder = class {
178
+ _def;
179
+ constructor(name) {
180
+ this._def = {
181
+ name,
182
+ command: "all",
183
+ roles: ["authenticated"],
184
+ using: null,
185
+ withCheck: null,
186
+ permissive: true
187
+ };
188
+ }
189
+ /** Restrict the policy to a single SQL command (default `"all"`). */
190
+ for(command) {
191
+ this._def.command = command;
192
+ return this;
193
+ }
194
+ /**
195
+ * Set the DB roles the policy applies to (the `TO` clause), replacing any
196
+ * previously-set roles. Call with no arguments to target PUBLIC (all roles).
197
+ *
198
+ * @example
199
+ * policy("p").to("authenticated")
200
+ * policy("p").to("authenticated", "service_role")
201
+ * policy("p").to() // PUBLIC
202
+ */
203
+ to(...roles) {
204
+ this._def.roles = roles;
205
+ return this;
206
+ }
207
+ /** Set the `USING (...)` row-visibility expression (raw SQL). */
208
+ using(sqlExpr) {
209
+ this._def.using = sqlExpr;
210
+ return this;
211
+ }
212
+ /** Set the `WITH CHECK (...)` write-validation expression (raw SQL). */
213
+ withCheck(sqlExpr) {
214
+ this._def.withCheck = sqlExpr;
215
+ return this;
216
+ }
217
+ /** Set the policy mode: `"permissive"` (default, OR-combined) or
218
+ * `"restrictive"` (AND-combined). */
219
+ as(mode) {
220
+ this._def.permissive = mode === "permissive";
221
+ return this;
222
+ }
223
+ };
224
+ function policy(name) {
225
+ return new PolicyBuilder(name);
144
226
  }
145
227
 
146
228
  // src/db/schema.ts
147
- function table(name, columns) {
148
- return { name, columns };
229
+ function toPolicyDef(p) {
230
+ return p instanceof PolicyBuilder ? p._def : p;
231
+ }
232
+ function defineSchema(input) {
233
+ const tables = {};
234
+ for (const name of Object.keys(input.tables)) {
235
+ const table = input.tables[name];
236
+ if (table === void 0) continue;
237
+ const policies = (table.policies ?? []).map(toPolicyDef);
238
+ const rls = table.rls === true || policies.length > 0;
239
+ tables[name] = {
240
+ name,
241
+ columns: table.columns,
242
+ rls,
243
+ policies
244
+ };
245
+ }
246
+ const extensions = [...new Set(input.extensions ?? [])];
247
+ return { tables, extensions };
149
248
  }
150
- function defineSchema(tables) {
151
- return { tables };
249
+
250
+ // src/db/extensions.ts
251
+ var PALBASE_EXTENSIONS = [
252
+ // Search & text
253
+ "vector",
254
+ // pgvector: AI embeddings + vector similarity search (semantic search / RAG).
255
+ // NB: the Postgres extension is named "vector", not "pgvector" — declare "vector".
256
+ "pg_trgm",
257
+ // trigram fuzzy / typo-tolerant text search
258
+ "unaccent",
259
+ // accent-insensitive text search
260
+ "citext",
261
+ // case-insensitive text type
262
+ // Geospatial / location
263
+ "postgis",
264
+ // geospatial types + queries (maps, "near me")
265
+ "cube",
266
+ // multi-dimensional cubes (dependency of earthdistance)
267
+ "earthdistance",
268
+ // great-circle distance (needs cube)
269
+ // Data types & structures
270
+ "hstore",
271
+ // key/value pairs in a single column
272
+ "ltree",
273
+ // hierarchical tree-structured labels
274
+ // Scheduling
275
+ "pg_cron",
276
+ // schedule jobs inside the database
277
+ // Crypto / ids (also installed by default; listable for explicitness)
278
+ "pgcrypto",
279
+ // cryptographic functions (hashing, encryption)
280
+ "uuid-ossp"
281
+ // UUID generation functions
282
+ ];
283
+ var EXTENSION_DEPENDENCIES = {
284
+ earthdistance: ["cube"]
285
+ };
286
+ function isPalbaseExtension(name) {
287
+ return PALBASE_EXTENSIONS.includes(name);
152
288
  }
153
289
 
154
290
  // src/db/columns.ts
@@ -192,8 +328,8 @@ var ColumnBuilder = class _ColumnBuilder {
192
328
  return new _ColumnBuilder(this._def.type, this._def);
193
329
  }
194
330
  /** Add a foreign key reference. */
195
- references(table2, column) {
196
- this._def.references = { table: table2, column };
331
+ references(table, column) {
332
+ this._def.references = { table, column };
197
333
  return new _ColumnBuilder(this._def.type, this._def);
198
334
  }
199
335
  /** Set the ON DELETE action for a foreign key reference. */
@@ -227,6 +363,244 @@ function enumType(name, values) {
227
363
  return builder;
228
364
  }
229
365
 
366
+ // src/db/typed-db.ts
367
+ function makeTypedTable(name, raw) {
368
+ return {
369
+ insert: (data) => raw.insert(name, data),
370
+ update: (id, data) => raw.update(name, id, data),
371
+ delete: (id) => raw.delete(name, id),
372
+ findById: (id) => raw.findById(name, id),
373
+ findMany: (query) => raw.findMany(name, query)
374
+ };
375
+ }
376
+ function makeTypedDB(schema, raw) {
377
+ function buildTables(client) {
378
+ const tables = {};
379
+ for (const key of Object.keys(schema.tables)) {
380
+ const tableDef = schema.tables[key];
381
+ if (tableDef !== void 0) {
382
+ tables[key] = makeTypedTable(tableDef.name, client);
383
+ }
384
+ }
385
+ return tables;
386
+ }
387
+ const result = {
388
+ tables: buildTables(raw),
389
+ transaction: (fn) => raw.transaction((rawTx) => fn({ tables: buildTables(rawTx) }))
390
+ };
391
+ return result;
392
+ }
393
+
394
+ // src/db/env-gen.ts
395
+ function baseTsType(def) {
396
+ switch (def.type) {
397
+ case "uuid":
398
+ case "text":
399
+ case "timestamp":
400
+ return "string";
401
+ case "integer":
402
+ return "number";
403
+ case "boolean":
404
+ return "boolean";
405
+ case "jsonb":
406
+ return "unknown";
407
+ case "enum": {
408
+ const values = def.enumValues ?? [];
409
+ if (values.length === 0) return "string";
410
+ return values.map((v) => JSON.stringify(v)).join(" | ");
411
+ }
412
+ default:
413
+ return "unknown";
414
+ }
415
+ }
416
+ function rowType(def) {
417
+ const base = baseTsType(def);
418
+ return def.nullable ? `${base} | null` : base;
419
+ }
420
+ function optionalOnInsert(def) {
421
+ return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
422
+ }
423
+ function tableBlock(table, indent) {
424
+ const cols = Object.entries(table.columns);
425
+ const rowLines = cols.map(([col, builder]) => {
426
+ return `${indent} ${col}: ${rowType(builder._def)};`;
427
+ });
428
+ const insertLines = cols.map(([col, builder]) => {
429
+ const def = builder._def;
430
+ const opt = optionalOnInsert(def) ? "?" : "";
431
+ return `${indent} ${col}${opt}: ${rowType(def)};`;
432
+ });
433
+ return [
434
+ `${indent}${table.name}: {`,
435
+ `${indent} row: {`,
436
+ ...rowLines,
437
+ `${indent} };`,
438
+ `${indent} insert: {`,
439
+ ...insertLines,
440
+ `${indent} };`,
441
+ `${indent}};`
442
+ ].join("\n");
443
+ }
444
+ function makeEnvDts(schema) {
445
+ const tableNames = Object.keys(schema.tables);
446
+ const blocks = tableNames.map((name) => tableBlock(schema.tables[name], " "));
447
+ const body = blocks.length > 0 ? `
448
+ ${blocks.join("\n")}
449
+ ` : "";
450
+ return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
451
+ // Regenerated from db/schema.ts on every \`palbase serve\` / deploy.
452
+ // Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
453
+ // is typed with no import and no generic.
454
+
455
+ declare module "@palbase/backend/env" {
456
+ interface Tables {${body}}
457
+ }
458
+
459
+ export {};
460
+ `;
461
+ }
462
+
463
+ // src/decorators/controller.ts
464
+ var CONTROLLER_META = /* @__PURE__ */ Symbol.for("palbase.backend.controllerMeta");
465
+ function Controller(basePath, options = {}) {
466
+ return function(ctor) {
467
+ const carrier = ctor;
468
+ const meta = {
469
+ __palbase: "controller",
470
+ basePath,
471
+ ...options.auth !== void 0 ? { defaultAuth: options.auth } : {}
472
+ };
473
+ Object.defineProperty(carrier, CONTROLLER_META, {
474
+ value: meta,
475
+ enumerable: false,
476
+ configurable: true,
477
+ writable: false
478
+ });
479
+ Object.defineProperty(carrier, "__palbase", {
480
+ value: "controller",
481
+ enumerable: false,
482
+ configurable: true,
483
+ writable: false
484
+ });
485
+ return ctor;
486
+ };
487
+ }
488
+
489
+ // src/decorators/registry.ts
490
+ var ROUTES = /* @__PURE__ */ Symbol.for("palbase.backend.routes");
491
+ var PARAM_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.paramBuffer");
492
+ function carrierOf(target) {
493
+ const ctor = typeof target === "function" ? target : target.constructor ?? target;
494
+ return ctor;
495
+ }
496
+ function ownRoutes(carrier) {
497
+ if (!Object.prototype.hasOwnProperty.call(carrier, ROUTES)) {
498
+ carrier[ROUTES] = [];
499
+ }
500
+ return carrier[ROUTES];
501
+ }
502
+ function ownParamBuffer(carrier) {
503
+ if (!Object.prototype.hasOwnProperty.call(carrier, PARAM_BUFFER)) {
504
+ carrier[PARAM_BUFFER] = {};
505
+ }
506
+ return carrier[PARAM_BUFFER];
507
+ }
508
+ function recordRoute(target, fnName, method, subpath, options) {
509
+ const carrier = carrierOf(target);
510
+ const routes = ownRoutes(carrier);
511
+ const buffer = ownParamBuffer(carrier);
512
+ const params = (buffer[fnName] ?? []).slice().sort((a, b) => a.index - b.index);
513
+ routes.push({ method, subpath, fnName, options, params });
514
+ }
515
+ function recordParam(target, fnName, meta) {
516
+ const carrier = carrierOf(target);
517
+ const buffer = ownParamBuffer(carrier);
518
+ (buffer[fnName] ??= []).push(meta);
519
+ const routes = carrier[ROUTES];
520
+ if (routes) {
521
+ const route = routes.find((r) => r.fnName === fnName);
522
+ if (route) {
523
+ route.params.push(meta);
524
+ route.params.sort((a, b) => a.index - b.index);
525
+ }
526
+ }
527
+ }
528
+ var RETURN_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.returnBuffer");
529
+ function recordReturn(target, fnName, schema) {
530
+ const carrier = carrierOf(target);
531
+ const routes = carrier[ROUTES];
532
+ const route = routes?.find((r) => r.fnName === fnName);
533
+ if (route) {
534
+ route.returnSchema = schema;
535
+ return;
536
+ }
537
+ if (!Object.prototype.hasOwnProperty.call(carrier, RETURN_BUFFER)) {
538
+ carrier[RETURN_BUFFER] = {};
539
+ }
540
+ carrier[RETURN_BUFFER][fnName] = schema;
541
+ }
542
+
543
+ // src/decorators/methods.ts
544
+ function makeMethodDecorator(method) {
545
+ return function(subpath, options = {}) {
546
+ return function(target, propertyKey) {
547
+ recordRoute(target, String(propertyKey), method, subpath, options);
548
+ };
549
+ };
550
+ }
551
+ var Get = makeMethodDecorator("GET");
552
+ var Post = makeMethodDecorator("POST");
553
+ var Put = makeMethodDecorator("PUT");
554
+ var Patch = makeMethodDecorator("PATCH");
555
+ var Delete = makeMethodDecorator("DELETE");
556
+ function Returns(schema) {
557
+ return function(target, propertyKey) {
558
+ recordReturn(target, String(propertyKey), schema);
559
+ };
560
+ }
561
+
562
+ // src/decorators/params.ts
563
+ function makeParamDecorator(kind, extra) {
564
+ return function(target, propertyKey, parameterIndex) {
565
+ recordParam(target, String(propertyKey), {
566
+ index: parameterIndex,
567
+ kind,
568
+ ...extra?.schema !== void 0 ? { schema: extra.schema } : {},
569
+ ...extra?.name !== void 0 ? { name: extra.name } : {}
570
+ });
571
+ };
572
+ }
573
+ function Body(schema) {
574
+ return makeParamDecorator("body", { schema });
575
+ }
576
+ function Query(schema) {
577
+ return makeParamDecorator("query", { schema });
578
+ }
579
+ function Headers(schema) {
580
+ return makeParamDecorator("headers", schema !== void 0 ? { schema } : void 0);
581
+ }
582
+ function Param(name) {
583
+ return makeParamDecorator("param", { name });
584
+ }
585
+ function User() {
586
+ return makeParamDecorator("user");
587
+ }
588
+ function OptionalUser() {
589
+ return makeParamDecorator("optionalUser");
590
+ }
591
+ function Client() {
592
+ return makeParamDecorator("client");
593
+ }
594
+ function RequestId() {
595
+ return makeParamDecorator("requestId");
596
+ }
597
+ function TraceId() {
598
+ return makeParamDecorator("traceId");
599
+ }
600
+ function Req() {
601
+ return makeParamDecorator("req");
602
+ }
603
+
230
604
  // src/middleware.ts
231
605
  function defineMiddleware(fn) {
232
606
  return fn;
@@ -269,6 +643,52 @@ var HttpError = class extends Error {
269
643
  return result;
270
644
  }
271
645
  };
646
+ var PalError = class extends HttpError {
647
+ constructor(status, code, description, data) {
648
+ super(status, code, description, data);
649
+ this.name = "PalError";
650
+ }
651
+ };
652
+ var NamedHttpError = class extends HttpError {
653
+ constructor(status, defaultCode, name, message, code, data) {
654
+ super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
655
+ this.name = name;
656
+ }
657
+ };
658
+ function defaultMessage(name) {
659
+ const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
660
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
661
+ }
662
+ var BadRequest = class extends NamedHttpError {
663
+ constructor(message, code, data) {
664
+ super(400, "bad_request", "BadRequest", message, code, data);
665
+ }
666
+ };
667
+ var Unauthorized = class extends NamedHttpError {
668
+ constructor(message, code, data) {
669
+ super(401, "unauthorized", "Unauthorized", message, code, data);
670
+ }
671
+ };
672
+ var Forbidden = class extends NamedHttpError {
673
+ constructor(message, code, data) {
674
+ super(403, "forbidden", "Forbidden", message, code, data);
675
+ }
676
+ };
677
+ var NotFound = class extends NamedHttpError {
678
+ constructor(message, code, data) {
679
+ super(404, "not_found", "NotFound", message, code, data);
680
+ }
681
+ };
682
+ var Conflict = class extends NamedHttpError {
683
+ constructor(message, code, data) {
684
+ super(409, "conflict", "Conflict", message, code, data);
685
+ }
686
+ };
687
+ var TooManyRequests = class extends NamedHttpError {
688
+ constructor(message, code, data) {
689
+ super(429, "too_many_requests", "TooManyRequests", message, code, data);
690
+ }
691
+ };
272
692
 
273
693
  // src/worker.ts
274
694
  var VALID_WORKER_NAME = /^[a-zA-Z0-9_-]+$/;
@@ -486,6 +906,52 @@ function validateCustomWebhook(config) {
486
906
  };
487
907
  }
488
908
 
909
+ // src/resource.ts
910
+ var Resource = class {
911
+ /** The env-var names this resource needs. Optional; omit for none. */
912
+ static secrets;
913
+ };
914
+ function hasSecrets(value) {
915
+ if (typeof value !== "object" && typeof value !== "function") return false;
916
+ const secrets = value.secrets;
917
+ return secrets === void 0 || Array.isArray(secrets);
918
+ }
919
+ var registry = [];
920
+ function __registerResource(resource) {
921
+ registry.push({ resource, booted: false });
922
+ }
923
+ function declaredSecrets(resource) {
924
+ const ctor = resource.constructor;
925
+ return hasSecrets(ctor) ? ctor.secrets ?? [] : [];
926
+ }
927
+ async function __runResourceBoot(envMap) {
928
+ for (const entry of registry) {
929
+ if (entry.booted) continue;
930
+ const secrets = declaredSecrets(entry.resource);
931
+ const env = {};
932
+ for (const name of secrets) {
933
+ const value = envMap[name];
934
+ if (value === void 0) {
935
+ throw new Error(
936
+ `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.`
937
+ );
938
+ }
939
+ env[name] = value;
940
+ }
941
+ await entry.resource.init(env);
942
+ entry.booted = true;
943
+ }
944
+ }
945
+ async function __shutdownResources() {
946
+ for (let i = registry.length - 1; i >= 0; i -= 1) {
947
+ const entry = registry[i];
948
+ if (entry.booted && entry.resource.shutdown) {
949
+ await entry.resource.shutdown();
950
+ }
951
+ }
952
+ registry.length = 0;
953
+ }
954
+
489
955
  // src/hooks.ts
490
956
  var auth = {
491
957
  onUserCreated(handler) {
@@ -525,22 +991,52 @@ var documents = {
525
991
  var import_zod = require("zod");
526
992
  // Annotate the CommonJS export names for ESM import in node:
527
993
  0 && (module.exports = {
994
+ BadRequest,
995
+ Body,
528
996
  Cache,
997
+ Client,
998
+ Conflict,
999
+ Controller,
529
1000
  Database,
1001
+ Delete,
530
1002
  Documents,
1003
+ EXTENSION_DEPENDENCIES,
531
1004
  Flags,
1005
+ Forbidden,
1006
+ Get,
1007
+ Headers,
532
1008
  HttpError,
533
1009
  Log,
1010
+ NotFound,
534
1011
  Notifications,
1012
+ OptionalUser,
1013
+ PALBASE_EXTENSIONS,
1014
+ PalError,
1015
+ Param,
1016
+ Patch,
1017
+ PolicyBuilder,
1018
+ Post,
1019
+ Put,
1020
+ Query,
535
1021
  Queue,
1022
+ Req,
1023
+ RequestId,
1024
+ Resource,
1025
+ Returns,
536
1026
  Storage,
1027
+ TooManyRequests,
1028
+ TraceId,
1029
+ Unauthorized,
1030
+ User,
537
1031
  __getRuntime,
1032
+ __registerResource,
538
1033
  __requestALS,
1034
+ __runResourceBoot,
539
1035
  __runWithRuntime,
540
1036
  __setRuntime,
1037
+ __shutdownResources,
541
1038
  auth,
542
1039
  boolean,
543
- defineEndpoint,
544
1040
  defineJob,
545
1041
  defineMiddleware,
546
1042
  defineSchema,
@@ -549,13 +1045,14 @@ var import_zod = require("zod");
549
1045
  documents,
550
1046
  enumType,
551
1047
  integer,
1048
+ isPalbaseExtension,
552
1049
  jsonb,
1050
+ makeEnvDts,
553
1051
  makeTypedDB,
1052
+ policy,
554
1053
  storage,
555
- table,
556
1054
  text,
557
1055
  timestamp,
558
- typedDatabase,
559
1056
  uuid,
560
1057
  z
561
1058
  });