@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.js
CHANGED
|
@@ -10,25 +10,233 @@ import {
|
|
|
10
10
|
__getRuntime,
|
|
11
11
|
__requestALS,
|
|
12
12
|
__runWithRuntime,
|
|
13
|
-
__setRuntime
|
|
14
|
-
|
|
15
|
-
typedDatabase
|
|
16
|
-
} from "./chunk-L36JLUPO.js";
|
|
13
|
+
__setRuntime
|
|
14
|
+
} from "./chunk-WUQO76NW.js";
|
|
17
15
|
import {
|
|
16
|
+
EXTENSION_DEPENDENCIES,
|
|
17
|
+
PALBASE_EXTENSIONS,
|
|
18
|
+
PolicyBuilder,
|
|
18
19
|
boolean,
|
|
19
20
|
defineSchema,
|
|
20
21
|
enumType,
|
|
21
22
|
integer,
|
|
23
|
+
isPalbaseExtension,
|
|
22
24
|
jsonb,
|
|
23
|
-
|
|
25
|
+
makeTypedDB,
|
|
26
|
+
policy,
|
|
24
27
|
text,
|
|
25
28
|
timestamp,
|
|
26
29
|
uuid
|
|
27
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-EG7TTYHY.js";
|
|
31
|
+
|
|
32
|
+
// src/db/env-gen.ts
|
|
33
|
+
function baseTsType(def) {
|
|
34
|
+
switch (def.type) {
|
|
35
|
+
case "uuid":
|
|
36
|
+
case "text":
|
|
37
|
+
case "timestamp":
|
|
38
|
+
return "string";
|
|
39
|
+
case "integer":
|
|
40
|
+
return "number";
|
|
41
|
+
case "boolean":
|
|
42
|
+
return "boolean";
|
|
43
|
+
case "jsonb":
|
|
44
|
+
return "unknown";
|
|
45
|
+
case "enum": {
|
|
46
|
+
const values = def.enumValues ?? [];
|
|
47
|
+
if (values.length === 0) return "string";
|
|
48
|
+
return values.map((v) => JSON.stringify(v)).join(" | ");
|
|
49
|
+
}
|
|
50
|
+
default:
|
|
51
|
+
return "unknown";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function rowType(def) {
|
|
55
|
+
const base = baseTsType(def);
|
|
56
|
+
return def.nullable ? `${base} | null` : base;
|
|
57
|
+
}
|
|
58
|
+
function optionalOnInsert(def) {
|
|
59
|
+
return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
|
|
60
|
+
}
|
|
61
|
+
function tableBlock(table, indent) {
|
|
62
|
+
const cols = Object.entries(table.columns);
|
|
63
|
+
const rowLines = cols.map(([col, builder]) => {
|
|
64
|
+
return `${indent} ${col}: ${rowType(builder._def)};`;
|
|
65
|
+
});
|
|
66
|
+
const insertLines = cols.map(([col, builder]) => {
|
|
67
|
+
const def = builder._def;
|
|
68
|
+
const opt = optionalOnInsert(def) ? "?" : "";
|
|
69
|
+
return `${indent} ${col}${opt}: ${rowType(def)};`;
|
|
70
|
+
});
|
|
71
|
+
return [
|
|
72
|
+
`${indent}${table.name}: {`,
|
|
73
|
+
`${indent} row: {`,
|
|
74
|
+
...rowLines,
|
|
75
|
+
`${indent} };`,
|
|
76
|
+
`${indent} insert: {`,
|
|
77
|
+
...insertLines,
|
|
78
|
+
`${indent} };`,
|
|
79
|
+
`${indent}};`
|
|
80
|
+
].join("\n");
|
|
81
|
+
}
|
|
82
|
+
function makeEnvDts(schema) {
|
|
83
|
+
const tableNames = Object.keys(schema.tables);
|
|
84
|
+
const blocks = tableNames.map((name) => tableBlock(schema.tables[name], " "));
|
|
85
|
+
const body = blocks.length > 0 ? `
|
|
86
|
+
${blocks.join("\n")}
|
|
87
|
+
` : "";
|
|
88
|
+
return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
|
|
89
|
+
// Regenerated from db/schema.ts on every \`palbase serve\` / deploy.
|
|
90
|
+
// Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
|
|
91
|
+
// is typed with no import and no generic.
|
|
92
|
+
|
|
93
|
+
declare module "@palbase/backend/env" {
|
|
94
|
+
interface Tables {${body}}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export {};
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/decorators/controller.ts
|
|
102
|
+
var CONTROLLER_META = /* @__PURE__ */ Symbol.for("palbase.backend.controllerMeta");
|
|
103
|
+
function Controller(basePath, options = {}) {
|
|
104
|
+
return function(ctor) {
|
|
105
|
+
const carrier = ctor;
|
|
106
|
+
const meta = {
|
|
107
|
+
__palbase: "controller",
|
|
108
|
+
basePath,
|
|
109
|
+
...options.auth !== void 0 ? { defaultAuth: options.auth } : {}
|
|
110
|
+
};
|
|
111
|
+
Object.defineProperty(carrier, CONTROLLER_META, {
|
|
112
|
+
value: meta,
|
|
113
|
+
enumerable: false,
|
|
114
|
+
configurable: true,
|
|
115
|
+
writable: false
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(carrier, "__palbase", {
|
|
118
|
+
value: "controller",
|
|
119
|
+
enumerable: false,
|
|
120
|
+
configurable: true,
|
|
121
|
+
writable: false
|
|
122
|
+
});
|
|
123
|
+
return ctor;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/decorators/registry.ts
|
|
128
|
+
var ROUTES = /* @__PURE__ */ Symbol.for("palbase.backend.routes");
|
|
129
|
+
var PARAM_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.paramBuffer");
|
|
130
|
+
function carrierOf(target) {
|
|
131
|
+
const ctor = typeof target === "function" ? target : target.constructor ?? target;
|
|
132
|
+
return ctor;
|
|
133
|
+
}
|
|
134
|
+
function ownRoutes(carrier) {
|
|
135
|
+
if (!Object.prototype.hasOwnProperty.call(carrier, ROUTES)) {
|
|
136
|
+
carrier[ROUTES] = [];
|
|
137
|
+
}
|
|
138
|
+
return carrier[ROUTES];
|
|
139
|
+
}
|
|
140
|
+
function ownParamBuffer(carrier) {
|
|
141
|
+
if (!Object.prototype.hasOwnProperty.call(carrier, PARAM_BUFFER)) {
|
|
142
|
+
carrier[PARAM_BUFFER] = {};
|
|
143
|
+
}
|
|
144
|
+
return carrier[PARAM_BUFFER];
|
|
145
|
+
}
|
|
146
|
+
function recordRoute(target, fnName, method, subpath, options) {
|
|
147
|
+
const carrier = carrierOf(target);
|
|
148
|
+
const routes = ownRoutes(carrier);
|
|
149
|
+
const buffer = ownParamBuffer(carrier);
|
|
150
|
+
const params = (buffer[fnName] ?? []).slice().sort((a, b) => a.index - b.index);
|
|
151
|
+
routes.push({ method, subpath, fnName, options, params });
|
|
152
|
+
}
|
|
153
|
+
function recordParam(target, fnName, meta) {
|
|
154
|
+
const carrier = carrierOf(target);
|
|
155
|
+
const buffer = ownParamBuffer(carrier);
|
|
156
|
+
(buffer[fnName] ??= []).push(meta);
|
|
157
|
+
const routes = carrier[ROUTES];
|
|
158
|
+
if (routes) {
|
|
159
|
+
const route = routes.find((r) => r.fnName === fnName);
|
|
160
|
+
if (route) {
|
|
161
|
+
route.params.push(meta);
|
|
162
|
+
route.params.sort((a, b) => a.index - b.index);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
var RETURN_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.returnBuffer");
|
|
167
|
+
function recordReturn(target, fnName, schema) {
|
|
168
|
+
const carrier = carrierOf(target);
|
|
169
|
+
const routes = carrier[ROUTES];
|
|
170
|
+
const route = routes?.find((r) => r.fnName === fnName);
|
|
171
|
+
if (route) {
|
|
172
|
+
route.returnSchema = schema;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (!Object.prototype.hasOwnProperty.call(carrier, RETURN_BUFFER)) {
|
|
176
|
+
carrier[RETURN_BUFFER] = {};
|
|
177
|
+
}
|
|
178
|
+
carrier[RETURN_BUFFER][fnName] = schema;
|
|
179
|
+
}
|
|
28
180
|
|
|
29
|
-
// src/
|
|
30
|
-
function
|
|
31
|
-
return
|
|
181
|
+
// src/decorators/methods.ts
|
|
182
|
+
function makeMethodDecorator(method) {
|
|
183
|
+
return function(subpath, options = {}) {
|
|
184
|
+
return function(target, propertyKey) {
|
|
185
|
+
recordRoute(target, String(propertyKey), method, subpath, options);
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
var Get = makeMethodDecorator("GET");
|
|
190
|
+
var Post = makeMethodDecorator("POST");
|
|
191
|
+
var Put = makeMethodDecorator("PUT");
|
|
192
|
+
var Patch = makeMethodDecorator("PATCH");
|
|
193
|
+
var Delete = makeMethodDecorator("DELETE");
|
|
194
|
+
function Returns(schema) {
|
|
195
|
+
return function(target, propertyKey) {
|
|
196
|
+
recordReturn(target, String(propertyKey), schema);
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/decorators/params.ts
|
|
201
|
+
function makeParamDecorator(kind, extra) {
|
|
202
|
+
return function(target, propertyKey, parameterIndex) {
|
|
203
|
+
recordParam(target, String(propertyKey), {
|
|
204
|
+
index: parameterIndex,
|
|
205
|
+
kind,
|
|
206
|
+
...extra?.schema !== void 0 ? { schema: extra.schema } : {},
|
|
207
|
+
...extra?.name !== void 0 ? { name: extra.name } : {}
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function Body(schema) {
|
|
212
|
+
return makeParamDecorator("body", { schema });
|
|
213
|
+
}
|
|
214
|
+
function Query(schema) {
|
|
215
|
+
return makeParamDecorator("query", { schema });
|
|
216
|
+
}
|
|
217
|
+
function Headers(schema) {
|
|
218
|
+
return makeParamDecorator("headers", schema !== void 0 ? { schema } : void 0);
|
|
219
|
+
}
|
|
220
|
+
function Param(name) {
|
|
221
|
+
return makeParamDecorator("param", { name });
|
|
222
|
+
}
|
|
223
|
+
function User() {
|
|
224
|
+
return makeParamDecorator("user");
|
|
225
|
+
}
|
|
226
|
+
function OptionalUser() {
|
|
227
|
+
return makeParamDecorator("optionalUser");
|
|
228
|
+
}
|
|
229
|
+
function Client() {
|
|
230
|
+
return makeParamDecorator("client");
|
|
231
|
+
}
|
|
232
|
+
function RequestId() {
|
|
233
|
+
return makeParamDecorator("requestId");
|
|
234
|
+
}
|
|
235
|
+
function TraceId() {
|
|
236
|
+
return makeParamDecorator("traceId");
|
|
237
|
+
}
|
|
238
|
+
function Req() {
|
|
239
|
+
return makeParamDecorator("req");
|
|
32
240
|
}
|
|
33
241
|
|
|
34
242
|
// src/middleware.ts
|
|
@@ -73,6 +281,52 @@ var HttpError = class extends Error {
|
|
|
73
281
|
return result;
|
|
74
282
|
}
|
|
75
283
|
};
|
|
284
|
+
var PalError = class extends HttpError {
|
|
285
|
+
constructor(status, code, description, data) {
|
|
286
|
+
super(status, code, description, data);
|
|
287
|
+
this.name = "PalError";
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
var NamedHttpError = class extends HttpError {
|
|
291
|
+
constructor(status, defaultCode, name, message, code, data) {
|
|
292
|
+
super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
|
|
293
|
+
this.name = name;
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
function defaultMessage(name) {
|
|
297
|
+
const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
298
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
|
|
299
|
+
}
|
|
300
|
+
var BadRequest = class extends NamedHttpError {
|
|
301
|
+
constructor(message, code, data) {
|
|
302
|
+
super(400, "bad_request", "BadRequest", message, code, data);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
var Unauthorized = class extends NamedHttpError {
|
|
306
|
+
constructor(message, code, data) {
|
|
307
|
+
super(401, "unauthorized", "Unauthorized", message, code, data);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
var Forbidden = class extends NamedHttpError {
|
|
311
|
+
constructor(message, code, data) {
|
|
312
|
+
super(403, "forbidden", "Forbidden", message, code, data);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
var NotFound = class extends NamedHttpError {
|
|
316
|
+
constructor(message, code, data) {
|
|
317
|
+
super(404, "not_found", "NotFound", message, code, data);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
var Conflict = class extends NamedHttpError {
|
|
321
|
+
constructor(message, code, data) {
|
|
322
|
+
super(409, "conflict", "Conflict", message, code, data);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
var TooManyRequests = class extends NamedHttpError {
|
|
326
|
+
constructor(message, code, data) {
|
|
327
|
+
super(429, "too_many_requests", "TooManyRequests", message, code, data);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
76
330
|
|
|
77
331
|
// src/worker.ts
|
|
78
332
|
var VALID_WORKER_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
@@ -290,6 +544,52 @@ function validateCustomWebhook(config) {
|
|
|
290
544
|
};
|
|
291
545
|
}
|
|
292
546
|
|
|
547
|
+
// src/resource.ts
|
|
548
|
+
var Resource = class {
|
|
549
|
+
/** The env-var names this resource needs. Optional; omit for none. */
|
|
550
|
+
static secrets;
|
|
551
|
+
};
|
|
552
|
+
function hasSecrets(value) {
|
|
553
|
+
if (typeof value !== "object" && typeof value !== "function") return false;
|
|
554
|
+
const secrets = value.secrets;
|
|
555
|
+
return secrets === void 0 || Array.isArray(secrets);
|
|
556
|
+
}
|
|
557
|
+
var registry = [];
|
|
558
|
+
function __registerResource(resource) {
|
|
559
|
+
registry.push({ resource, booted: false });
|
|
560
|
+
}
|
|
561
|
+
function declaredSecrets(resource) {
|
|
562
|
+
const ctor = resource.constructor;
|
|
563
|
+
return hasSecrets(ctor) ? ctor.secrets ?? [] : [];
|
|
564
|
+
}
|
|
565
|
+
async function __runResourceBoot(envMap) {
|
|
566
|
+
for (const entry of registry) {
|
|
567
|
+
if (entry.booted) continue;
|
|
568
|
+
const secrets = declaredSecrets(entry.resource);
|
|
569
|
+
const env = {};
|
|
570
|
+
for (const name of secrets) {
|
|
571
|
+
const value = envMap[name];
|
|
572
|
+
if (value === void 0) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
`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.`
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
env[name] = value;
|
|
578
|
+
}
|
|
579
|
+
await entry.resource.init(env);
|
|
580
|
+
entry.booted = true;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
async function __shutdownResources() {
|
|
584
|
+
for (let i = registry.length - 1; i >= 0; i -= 1) {
|
|
585
|
+
const entry = registry[i];
|
|
586
|
+
if (entry.booted && entry.resource.shutdown) {
|
|
587
|
+
await entry.resource.shutdown();
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
registry.length = 0;
|
|
591
|
+
}
|
|
592
|
+
|
|
293
593
|
// src/hooks.ts
|
|
294
594
|
var auth = {
|
|
295
595
|
onUserCreated(handler) {
|
|
@@ -328,22 +628,52 @@ var documents = {
|
|
|
328
628
|
// src/index.ts
|
|
329
629
|
import { z } from "zod";
|
|
330
630
|
export {
|
|
631
|
+
BadRequest,
|
|
632
|
+
Body,
|
|
331
633
|
Cache,
|
|
634
|
+
Client,
|
|
635
|
+
Conflict,
|
|
636
|
+
Controller,
|
|
332
637
|
Database,
|
|
638
|
+
Delete,
|
|
333
639
|
Documents,
|
|
640
|
+
EXTENSION_DEPENDENCIES,
|
|
334
641
|
Flags,
|
|
642
|
+
Forbidden,
|
|
643
|
+
Get,
|
|
644
|
+
Headers,
|
|
335
645
|
HttpError,
|
|
336
646
|
Log,
|
|
647
|
+
NotFound,
|
|
337
648
|
Notifications,
|
|
649
|
+
OptionalUser,
|
|
650
|
+
PALBASE_EXTENSIONS,
|
|
651
|
+
PalError,
|
|
652
|
+
Param,
|
|
653
|
+
Patch,
|
|
654
|
+
PolicyBuilder,
|
|
655
|
+
Post,
|
|
656
|
+
Put,
|
|
657
|
+
Query,
|
|
338
658
|
Queue,
|
|
659
|
+
Req,
|
|
660
|
+
RequestId,
|
|
661
|
+
Resource,
|
|
662
|
+
Returns,
|
|
339
663
|
Storage,
|
|
664
|
+
TooManyRequests,
|
|
665
|
+
TraceId,
|
|
666
|
+
Unauthorized,
|
|
667
|
+
User,
|
|
340
668
|
__getRuntime,
|
|
669
|
+
__registerResource,
|
|
341
670
|
__requestALS,
|
|
671
|
+
__runResourceBoot,
|
|
342
672
|
__runWithRuntime,
|
|
343
673
|
__setRuntime,
|
|
674
|
+
__shutdownResources,
|
|
344
675
|
auth,
|
|
345
676
|
boolean,
|
|
346
|
-
defineEndpoint,
|
|
347
677
|
defineJob,
|
|
348
678
|
defineMiddleware,
|
|
349
679
|
defineSchema,
|
|
@@ -352,13 +682,14 @@ export {
|
|
|
352
682
|
documents,
|
|
353
683
|
enumType,
|
|
354
684
|
integer,
|
|
685
|
+
isPalbaseExtension,
|
|
355
686
|
jsonb,
|
|
687
|
+
makeEnvDts,
|
|
356
688
|
makeTypedDB,
|
|
689
|
+
policy,
|
|
357
690
|
storage,
|
|
358
|
-
table,
|
|
359
691
|
text,
|
|
360
692
|
timestamp,
|
|
361
|
-
typedDatabase,
|
|
362
693
|
uuid,
|
|
363
694
|
z
|
|
364
695
|
};
|