@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.
- package/dist/chunk-EG7TTYHY.js +235 -0
- package/dist/chunk-EG7TTYHY.js.map +1 -0
- package/dist/chunk-WUQO76NW.js +101 -0
- package/dist/chunk-WUQO76NW.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 +143 -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 +13 -233
- package/dist/db/index.js.map +1 -1
- package/dist/{endpoint-Djk5L6G2.d.ts → endpoint-2d_DpASt.d.cts} +94 -96
- package/dist/{endpoint-BlcY2xNA.d.cts → endpoint-2d_DpASt.d.ts} +94 -96
- package/dist/index-DZW9CjiY.d.ts +463 -0
- package/dist/index-DzRFS3Tl.d.cts +463 -0
- package/dist/index.cjs +557 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +278 -161
- package/dist/index.d.ts +278 -161
- package/dist/index.js +343 -12
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +57 -2
- 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 +10 -2
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +33 -12
- package/docs/background.md +19 -13
- package/docs/database.md +70 -17
- package/docs/endpoints.md +103 -79
- package/docs/errors.md +37 -31
- package/docs/events.md +25 -17
- package/docs/getting-started.md +38 -18
- package/docs/llms-full.txt +758 -267
- package/docs/llms.txt +3 -1
- package/docs/migrations.md +98 -0
- package/docs/resources.md +94 -0
- package/docs/routing.md +54 -27
- package/docs/schema.md +163 -42
- package/docs/services.md +17 -14
- package/package.json +12 -2
- package/dist/chunk-4J3F32SH.js +0 -96
- package/dist/chunk-4J3F32SH.js.map +0 -1
- package/dist/chunk-L36JLUPO.js +0 -97
- 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
|
@@ -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
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
148
|
-
return
|
|
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
|
-
|
|
151
|
-
|
|
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(
|
|
196
|
-
this._def.references = { table
|
|
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
|
});
|