@palbase/backend 18.0.1 → 21.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/bin/palbase-backend.cjs +36 -17
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +1 -1
- package/dist/{chunk-VYH4U7ZQ.js → chunk-PFQJYW6C.js} +37 -18
- package/dist/chunk-PFQJYW6C.js.map +1 -0
- package/dist/engine/index.cjs +36 -17
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +1 -1
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/{index-DZDUMth5.d.ts → index-BeHLq2i-.d.ts} +5 -0
- package/dist/{index-B46CGNvx.d.cts → index-Br9P7yRu.d.cts} +5 -0
- package/dist/index.cjs +173 -147
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +149 -121
- package/dist/index.d.ts +149 -121
- package/dist/index.js +155 -129
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/template/package.json +2 -2
- package/dist/chunk-VYH4U7ZQ.js.map +0 -1
package/dist/engine/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as App, l as AuthVerifier, B as BootRefused, m as CreateAppOptions, E as EgressPolicy, n as EngineConfig, M as ModuleClients, o as RateLimiter, p as RequestDatabase, q as RouteEntry, r as RuntimeHooks, s as ScrubResult, t as SqlDriver, u as SqlTx, v as buildRouteTable, w as createApp, x as createLazyTransaction, y as createOps, z as createRequestDatabase, G as effectiveAuth, H as hostAllowed, I as installEgressFence, J as loadConfig, K as makeMemoryCache, O as matchRoute, Q as quoteIdent, T as scrubSecrets, U as withTables } from '../index-
|
|
1
|
+
export { A as App, l as AuthVerifier, B as BootRefused, m as CreateAppOptions, E as EgressPolicy, n as EngineConfig, M as ModuleClients, o as RateLimiter, p as RequestDatabase, q as RouteEntry, r as RuntimeHooks, s as ScrubResult, t as SqlDriver, u as SqlTx, v as buildRouteTable, w as createApp, x as createLazyTransaction, y as createOps, z as createRequestDatabase, G as effectiveAuth, H as hostAllowed, I as installEgressFence, J as loadConfig, K as makeMemoryCache, O as matchRoute, Q as quoteIdent, T as scrubSecrets, U as withTables } from '../index-Br9P7yRu.cjs';
|
|
2
2
|
import '../endpoint-B0LpZixz.cjs';
|
|
3
3
|
import '../db/env.cjs';
|
|
4
4
|
import 'node:async_hooks';
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as App, l as AuthVerifier, B as BootRefused, m as CreateAppOptions, E as EgressPolicy, n as EngineConfig, M as ModuleClients, o as RateLimiter, p as RequestDatabase, q as RouteEntry, r as RuntimeHooks, s as ScrubResult, t as SqlDriver, u as SqlTx, v as buildRouteTable, w as createApp, x as createLazyTransaction, y as createOps, z as createRequestDatabase, G as effectiveAuth, H as hostAllowed, I as installEgressFence, J as loadConfig, K as makeMemoryCache, O as matchRoute, Q as quoteIdent, T as scrubSecrets, U as withTables } from '../index-
|
|
1
|
+
export { A as App, l as AuthVerifier, B as BootRefused, m as CreateAppOptions, E as EgressPolicy, n as EngineConfig, M as ModuleClients, o as RateLimiter, p as RequestDatabase, q as RouteEntry, r as RuntimeHooks, s as ScrubResult, t as SqlDriver, u as SqlTx, v as buildRouteTable, w as createApp, x as createLazyTransaction, y as createOps, z as createRequestDatabase, G as effectiveAuth, H as hostAllowed, I as installEgressFence, J as loadConfig, K as makeMemoryCache, O as matchRoute, Q as quoteIdent, T as scrubSecrets, U as withTables } from '../index-BeHLq2i-.js';
|
|
2
2
|
import '../endpoint-B0LpZixz.js';
|
|
3
3
|
import '../db/env.js';
|
|
4
4
|
import 'node:async_hooks';
|
package/dist/engine/index.js
CHANGED
|
@@ -827,6 +827,11 @@ interface App {
|
|
|
827
827
|
handle: (req: Request) => Promise<Response>;
|
|
828
828
|
routes: readonly RouteEntry[];
|
|
829
829
|
config: EngineConfig;
|
|
830
|
+
/**
|
|
831
|
+
* Run work that has no request behind it — a scheduled job — inside the same
|
|
832
|
+
* request scope a handler gets, with its own transaction.
|
|
833
|
+
*/
|
|
834
|
+
runInServiceScope: <T>(fn: () => T | Promise<T>) => Promise<T>;
|
|
830
835
|
/** Close the pool and release resources. */
|
|
831
836
|
shutdown: () => Promise<void>;
|
|
832
837
|
}
|
|
@@ -827,6 +827,11 @@ interface App {
|
|
|
827
827
|
handle: (req: Request) => Promise<Response>;
|
|
828
828
|
routes: readonly RouteEntry[];
|
|
829
829
|
config: EngineConfig;
|
|
830
|
+
/**
|
|
831
|
+
* Run work that has no request behind it — a scheduled job — inside the same
|
|
832
|
+
* request scope a handler gets, with its own transaction.
|
|
833
|
+
*/
|
|
834
|
+
runInServiceScope: <T>(fn: () => T | Promise<T>) => Promise<T>;
|
|
830
835
|
/** Close the pool and release resources. */
|
|
831
836
|
shutdown: () => Promise<void>;
|
|
832
837
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ __export(src_exports, {
|
|
|
29
29
|
DEFAULT_TEMPLATE_LOCALE: () => DEFAULT_TEMPLATE_LOCALE,
|
|
30
30
|
Database: () => Database,
|
|
31
31
|
Delete: () => Delete,
|
|
32
|
+
Deny: () => Deny,
|
|
32
33
|
Documents: () => Documents,
|
|
33
34
|
EGRESS_CONFIG_KIND: () => EGRESS_CONFIG_KIND,
|
|
34
35
|
EGRESS_TIMEOUT_DEFAULT_MS: () => EGRESS_TIMEOUT_DEFAULT_MS,
|
|
@@ -40,6 +41,7 @@ __export(src_exports, {
|
|
|
40
41
|
Forbidden: () => Forbidden,
|
|
41
42
|
Get: () => Get,
|
|
42
43
|
Headers: () => Headers,
|
|
44
|
+
Hook: () => Hook,
|
|
43
45
|
HttpError: () => HttpError,
|
|
44
46
|
Job: () => Job,
|
|
45
47
|
Log: () => Log,
|
|
@@ -89,7 +91,6 @@ __export(src_exports, {
|
|
|
89
91
|
__runWithRuntime: () => __runWithRuntime,
|
|
90
92
|
__setRuntime: () => __setRuntime,
|
|
91
93
|
__shutdownResources: () => __shutdownResources,
|
|
92
|
-
auth: () => auth,
|
|
93
94
|
bigint: () => bigint,
|
|
94
95
|
boolean: () => boolean,
|
|
95
96
|
bucket: () => bucket,
|
|
@@ -105,12 +106,12 @@ __export(src_exports, {
|
|
|
105
106
|
defineSecrets: () => defineSecrets,
|
|
106
107
|
defineStorage: () => defineStorage,
|
|
107
108
|
defineTestUsers: () => defineTestUsers,
|
|
108
|
-
documents: () => documents,
|
|
109
109
|
entitlementFor: () => entitlementFor,
|
|
110
110
|
enumType: () => enumType,
|
|
111
111
|
extractVariables: () => extractVariables,
|
|
112
112
|
flag: () => flag,
|
|
113
113
|
getErrorRegistry: () => getErrorRegistry,
|
|
114
|
+
getHookConfig: () => getHookConfig,
|
|
114
115
|
getJobConfig: () => getJobConfig,
|
|
115
116
|
getRegisteredControllers: () => getRegisteredControllers,
|
|
116
117
|
getRoutes: () => getRoutes,
|
|
@@ -132,7 +133,6 @@ __export(src_exports, {
|
|
|
132
133
|
reservedSecretKey: () => reservedSecretKey,
|
|
133
134
|
secret: () => secret,
|
|
134
135
|
spendFor: () => spendFor,
|
|
135
|
-
storage: () => storage,
|
|
136
136
|
testUser: () => testUser,
|
|
137
137
|
text: () => text,
|
|
138
138
|
timestamp: () => timestamp,
|
|
@@ -645,13 +645,13 @@ var Database = Object.assign(makeTypedSurface(rawDatabase), {
|
|
|
645
645
|
}
|
|
646
646
|
});
|
|
647
647
|
var Documents = makeServiceProxy("Documents");
|
|
648
|
-
function makeBucketsAccessor(
|
|
648
|
+
function makeBucketsAccessor(storage) {
|
|
649
649
|
return new Proxy(
|
|
650
650
|
{},
|
|
651
651
|
{
|
|
652
652
|
get(_t, prop) {
|
|
653
653
|
if (typeof prop !== "string") return void 0;
|
|
654
|
-
return
|
|
654
|
+
return storage().bucket(prop);
|
|
655
655
|
}
|
|
656
656
|
}
|
|
657
657
|
);
|
|
@@ -2297,7 +2297,7 @@ function makeEnvDts(schema) {
|
|
|
2297
2297
|
${blocks.join("\n")}
|
|
2298
2298
|
` : "";
|
|
2299
2299
|
return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
|
|
2300
|
-
// Regenerated from db/schema.ts
|
|
2300
|
+
// Regenerated from db/schema.ts by \`palbase build\` and by every deploy.
|
|
2301
2301
|
// Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
|
|
2302
2302
|
// is typed with no import and no generic.
|
|
2303
2303
|
|
|
@@ -3114,13 +3114,162 @@ var Patch = makeMethodDecorator("PATCH");
|
|
|
3114
3114
|
var Delete = makeMethodDecorator("DELETE");
|
|
3115
3115
|
var Query = makeMethodDecorator("QUERY");
|
|
3116
3116
|
|
|
3117
|
+
// src/decorators/webhook.ts
|
|
3118
|
+
var WEBHOOK_META = /* @__PURE__ */ Symbol.for("palbase.backend.webhookMeta");
|
|
3119
|
+
var WEBHOOK_EVENTS = /* @__PURE__ */ Symbol.for("palbase.backend.webhookEvents");
|
|
3120
|
+
function carrierOf3(ctor) {
|
|
3121
|
+
return ctor;
|
|
3122
|
+
}
|
|
3123
|
+
function Webhook(options) {
|
|
3124
|
+
return function(ctor) {
|
|
3125
|
+
const carrier = carrierOf3(ctor);
|
|
3126
|
+
Object.defineProperty(carrier, WEBHOOK_META, {
|
|
3127
|
+
value: options,
|
|
3128
|
+
enumerable: false,
|
|
3129
|
+
configurable: true,
|
|
3130
|
+
writable: false
|
|
3131
|
+
});
|
|
3132
|
+
Object.defineProperty(carrier, "__palbase", {
|
|
3133
|
+
value: "webhook",
|
|
3134
|
+
enumerable: false,
|
|
3135
|
+
configurable: true,
|
|
3136
|
+
writable: false
|
|
3137
|
+
});
|
|
3138
|
+
return ctor;
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3141
|
+
function On(event) {
|
|
3142
|
+
return function(target, fnName) {
|
|
3143
|
+
const carrier = carrierOf3(target.constructor);
|
|
3144
|
+
const existing = carrier[WEBHOOK_EVENTS];
|
|
3145
|
+
const entries = existing ? [...existing] : [];
|
|
3146
|
+
entries.push({ event, fnName: String(fnName) });
|
|
3147
|
+
Object.defineProperty(carrier, WEBHOOK_EVENTS, {
|
|
3148
|
+
value: entries,
|
|
3149
|
+
enumerable: false,
|
|
3150
|
+
configurable: true,
|
|
3151
|
+
writable: false
|
|
3152
|
+
});
|
|
3153
|
+
};
|
|
3154
|
+
}
|
|
3155
|
+
function getWebhookConfig(ctor) {
|
|
3156
|
+
const carrier = carrierOf3(ctor);
|
|
3157
|
+
const meta = carrier[WEBHOOK_META];
|
|
3158
|
+
const entries = carrier[WEBHOOK_EVENTS] ?? [];
|
|
3159
|
+
if (!meta) {
|
|
3160
|
+
throw new Error(
|
|
3161
|
+
`@On used on a class that is not decorated with @Webhook (${ctor.name ?? "anonymous"})`
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
if (!meta.provider && !meta.signature) {
|
|
3165
|
+
throw new Error(
|
|
3166
|
+
"@Webhook requires either a `provider` preset or an explicit `signature` \u2014 an endpoint with no verification would accept forged deliveries"
|
|
3167
|
+
);
|
|
3168
|
+
}
|
|
3169
|
+
if (meta.provider && meta.signature) {
|
|
3170
|
+
throw new Error(
|
|
3171
|
+
"@Webhook declares BOTH a `provider` preset and an explicit `signature` \u2014 these are alternatives; keep the one that describes the sender, because only `provider` would be used"
|
|
3172
|
+
);
|
|
3173
|
+
}
|
|
3174
|
+
if (meta.signature) {
|
|
3175
|
+
const sig = meta.signature;
|
|
3176
|
+
if (!sig.header) {
|
|
3177
|
+
throw new Error("@Webhook signature requires `header` \u2014 the header the signature arrives in");
|
|
3178
|
+
}
|
|
3179
|
+
if (sig.algo !== "hmac-sha256" && sig.algo !== "hmac-sha1") {
|
|
3180
|
+
throw new Error(`@Webhook signature has an unsupported algo "${sig.algo}"`);
|
|
3181
|
+
}
|
|
3182
|
+
if (sig.encoding !== "hex" && sig.encoding !== "base64") {
|
|
3183
|
+
throw new Error(`@Webhook signature has an unsupported encoding "${sig.encoding}"`);
|
|
3184
|
+
}
|
|
3185
|
+
if (!sig.signs?.includes("{body}")) {
|
|
3186
|
+
throw new Error("@Webhook signature `signs` must contain {body} \u2014 signing a constant is not a signature");
|
|
3187
|
+
}
|
|
3188
|
+
if (sig.signs.includes("{ts}") && !sig.timestampHeader) {
|
|
3189
|
+
throw new Error("@Webhook signature uses {ts} but declares no `timestampHeader` to read it from");
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
if (!meta.secret?.env) {
|
|
3193
|
+
throw new Error('@Webhook requires `secret: { env: "VAR_NAME" }`');
|
|
3194
|
+
}
|
|
3195
|
+
if (entries.length === 0) {
|
|
3196
|
+
throw new Error("@Webhook requires at least one @On handler");
|
|
3197
|
+
}
|
|
3198
|
+
const instance = new ctor();
|
|
3199
|
+
const events = /* @__PURE__ */ Object.create(null);
|
|
3200
|
+
for (const entry of entries) {
|
|
3201
|
+
if (Object.prototype.hasOwnProperty.call(events, entry.event)) {
|
|
3202
|
+
throw new Error(`@On("${entry.event}") declared twice on the same webhook`);
|
|
3203
|
+
}
|
|
3204
|
+
events[entry.event] = (event, metaArg) => instance[entry.fnName].call(instance, event, metaArg);
|
|
3205
|
+
}
|
|
3206
|
+
return {
|
|
3207
|
+
...meta.provider ? { provider: meta.provider } : {},
|
|
3208
|
+
...meta.signature ? { signature: meta.signature } : {},
|
|
3209
|
+
secret: meta.secret,
|
|
3210
|
+
events
|
|
3211
|
+
};
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
// src/decorators/hook.ts
|
|
3215
|
+
var Deny = class extends Error {
|
|
3216
|
+
constructor(reason) {
|
|
3217
|
+
super(reason);
|
|
3218
|
+
this.name = "Deny";
|
|
3219
|
+
}
|
|
3220
|
+
};
|
|
3221
|
+
var HOOK_BLOCKING = /* @__PURE__ */ Symbol.for("palbase.backend.hookBlocking");
|
|
3222
|
+
function Hook(event) {
|
|
3223
|
+
return function(target, fnName) {
|
|
3224
|
+
const carrier = target.constructor;
|
|
3225
|
+
const existing = carrier[HOOK_BLOCKING];
|
|
3226
|
+
const entries = existing ? [...existing] : [];
|
|
3227
|
+
entries.push({ event, fnName: String(fnName) });
|
|
3228
|
+
Object.defineProperty(carrier, HOOK_BLOCKING, {
|
|
3229
|
+
value: entries,
|
|
3230
|
+
enumerable: false,
|
|
3231
|
+
configurable: true,
|
|
3232
|
+
writable: false
|
|
3233
|
+
});
|
|
3234
|
+
};
|
|
3235
|
+
}
|
|
3236
|
+
function bind(instance, entries, kind) {
|
|
3237
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3238
|
+
for (const entry of entries) {
|
|
3239
|
+
if (Object.prototype.hasOwnProperty.call(out, entry.event)) {
|
|
3240
|
+
throw new Error(`${kind}("${entry.event}") declared twice on the same hook class`);
|
|
3241
|
+
}
|
|
3242
|
+
const fn = instance[entry.fnName];
|
|
3243
|
+
if (typeof fn !== "function") {
|
|
3244
|
+
throw new Error(`${kind}("${entry.event}") names no method "${entry.fnName}" on the class`);
|
|
3245
|
+
}
|
|
3246
|
+
out[entry.event] = (event, meta) => fn.call(instance, event, meta);
|
|
3247
|
+
}
|
|
3248
|
+
return out;
|
|
3249
|
+
}
|
|
3250
|
+
function getHookConfig(ctor) {
|
|
3251
|
+
const carrier = ctor;
|
|
3252
|
+
const blockingEntries = carrier[HOOK_BLOCKING] ?? [];
|
|
3253
|
+
const listenerEntries = carrier[WEBHOOK_EVENTS] ?? [];
|
|
3254
|
+
if (blockingEntries.length === 0 && listenerEntries.length === 0) {
|
|
3255
|
+
throw new Error(
|
|
3256
|
+
`${ctor.name ?? "a hook class"} carries no handler \u2014 a hook file must declare at least one @Hook (blocking) or @On (listener) method`
|
|
3257
|
+
);
|
|
3258
|
+
}
|
|
3259
|
+
const instance = new ctor();
|
|
3260
|
+
return {
|
|
3261
|
+
blocking: bind(instance, blockingEntries, "@Hook"),
|
|
3262
|
+
listeners: bind(instance, listenerEntries, "@On")
|
|
3263
|
+
};
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3117
3266
|
// src/decorators/upload.ts
|
|
3118
3267
|
function Upload(subpath, config) {
|
|
3119
|
-
const { auth
|
|
3268
|
+
const { auth, rateLimit, ...uploadConfig } = config;
|
|
3120
3269
|
validateUploadConfigShape(uploadConfig);
|
|
3121
3270
|
const options = {
|
|
3122
3271
|
uploadConfig,
|
|
3123
|
-
...
|
|
3272
|
+
...auth !== void 0 ? { auth } : {},
|
|
3124
3273
|
...rateLimit !== void 0 ? { rateLimit } : {}
|
|
3125
3274
|
};
|
|
3126
3275
|
return function(target, propertyKey) {
|
|
@@ -3146,10 +3295,10 @@ function validateUploadConfigShape(c) {
|
|
|
3146
3295
|
throw new Error("@Upload config.pathTemplate must be a non-empty key template");
|
|
3147
3296
|
}
|
|
3148
3297
|
}
|
|
3149
|
-
function validateUploadAgainstStorage(uploadConfig,
|
|
3150
|
-
const def =
|
|
3298
|
+
function validateUploadAgainstStorage(uploadConfig, storage, routeLabel) {
|
|
3299
|
+
const def = storage.buckets[uploadConfig.bucket];
|
|
3151
3300
|
if (def === void 0) {
|
|
3152
|
-
const known = Object.keys(
|
|
3301
|
+
const known = Object.keys(storage.buckets);
|
|
3153
3302
|
throw new Error(
|
|
3154
3303
|
`@Upload route ${routeLabel} targets bucket "${uploadConfig.bucket}" which is not declared in defineStorage(...). ` + (known.length ? `Known buckets: ${known.join(", ")}.` : "No buckets are declared.")
|
|
3155
3304
|
);
|
|
@@ -3333,103 +3482,6 @@ function humanize(code) {
|
|
|
3333
3482
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
3334
3483
|
}
|
|
3335
3484
|
|
|
3336
|
-
// src/decorators/webhook.ts
|
|
3337
|
-
var WEBHOOK_META = /* @__PURE__ */ Symbol.for("palbase.backend.webhookMeta");
|
|
3338
|
-
var WEBHOOK_EVENTS = /* @__PURE__ */ Symbol.for("palbase.backend.webhookEvents");
|
|
3339
|
-
function carrierOf3(ctor) {
|
|
3340
|
-
return ctor;
|
|
3341
|
-
}
|
|
3342
|
-
function Webhook(options) {
|
|
3343
|
-
return function(ctor) {
|
|
3344
|
-
const carrier = carrierOf3(ctor);
|
|
3345
|
-
Object.defineProperty(carrier, WEBHOOK_META, {
|
|
3346
|
-
value: options,
|
|
3347
|
-
enumerable: false,
|
|
3348
|
-
configurable: true,
|
|
3349
|
-
writable: false
|
|
3350
|
-
});
|
|
3351
|
-
Object.defineProperty(carrier, "__palbase", {
|
|
3352
|
-
value: "webhook",
|
|
3353
|
-
enumerable: false,
|
|
3354
|
-
configurable: true,
|
|
3355
|
-
writable: false
|
|
3356
|
-
});
|
|
3357
|
-
return ctor;
|
|
3358
|
-
};
|
|
3359
|
-
}
|
|
3360
|
-
function On(event) {
|
|
3361
|
-
return function(target, fnName) {
|
|
3362
|
-
const carrier = carrierOf3(target.constructor);
|
|
3363
|
-
const existing = carrier[WEBHOOK_EVENTS];
|
|
3364
|
-
const entries = existing ? [...existing] : [];
|
|
3365
|
-
entries.push({ event, fnName: String(fnName) });
|
|
3366
|
-
Object.defineProperty(carrier, WEBHOOK_EVENTS, {
|
|
3367
|
-
value: entries,
|
|
3368
|
-
enumerable: false,
|
|
3369
|
-
configurable: true,
|
|
3370
|
-
writable: false
|
|
3371
|
-
});
|
|
3372
|
-
};
|
|
3373
|
-
}
|
|
3374
|
-
function getWebhookConfig(ctor) {
|
|
3375
|
-
const carrier = carrierOf3(ctor);
|
|
3376
|
-
const meta = carrier[WEBHOOK_META];
|
|
3377
|
-
const entries = carrier[WEBHOOK_EVENTS] ?? [];
|
|
3378
|
-
if (!meta) {
|
|
3379
|
-
throw new Error(
|
|
3380
|
-
`@On used on a class that is not decorated with @Webhook (${ctor.name ?? "anonymous"})`
|
|
3381
|
-
);
|
|
3382
|
-
}
|
|
3383
|
-
if (!meta.provider && !meta.signature) {
|
|
3384
|
-
throw new Error(
|
|
3385
|
-
"@Webhook requires either a `provider` preset or an explicit `signature` \u2014 an endpoint with no verification would accept forged deliveries"
|
|
3386
|
-
);
|
|
3387
|
-
}
|
|
3388
|
-
if (meta.provider && meta.signature) {
|
|
3389
|
-
throw new Error(
|
|
3390
|
-
"@Webhook declares BOTH a `provider` preset and an explicit `signature` \u2014 these are alternatives; keep the one that describes the sender, because only `provider` would be used"
|
|
3391
|
-
);
|
|
3392
|
-
}
|
|
3393
|
-
if (meta.signature) {
|
|
3394
|
-
const sig = meta.signature;
|
|
3395
|
-
if (!sig.header) {
|
|
3396
|
-
throw new Error("@Webhook signature requires `header` \u2014 the header the signature arrives in");
|
|
3397
|
-
}
|
|
3398
|
-
if (sig.algo !== "hmac-sha256" && sig.algo !== "hmac-sha1") {
|
|
3399
|
-
throw new Error(`@Webhook signature has an unsupported algo "${sig.algo}"`);
|
|
3400
|
-
}
|
|
3401
|
-
if (sig.encoding !== "hex" && sig.encoding !== "base64") {
|
|
3402
|
-
throw new Error(`@Webhook signature has an unsupported encoding "${sig.encoding}"`);
|
|
3403
|
-
}
|
|
3404
|
-
if (!sig.signs?.includes("{body}")) {
|
|
3405
|
-
throw new Error("@Webhook signature `signs` must contain {body} \u2014 signing a constant is not a signature");
|
|
3406
|
-
}
|
|
3407
|
-
if (sig.signs.includes("{ts}") && !sig.timestampHeader) {
|
|
3408
|
-
throw new Error("@Webhook signature uses {ts} but declares no `timestampHeader` to read it from");
|
|
3409
|
-
}
|
|
3410
|
-
}
|
|
3411
|
-
if (!meta.secret?.env) {
|
|
3412
|
-
throw new Error('@Webhook requires `secret: { env: "VAR_NAME" }`');
|
|
3413
|
-
}
|
|
3414
|
-
if (entries.length === 0) {
|
|
3415
|
-
throw new Error("@Webhook requires at least one @On handler");
|
|
3416
|
-
}
|
|
3417
|
-
const instance = new ctor();
|
|
3418
|
-
const events = /* @__PURE__ */ Object.create(null);
|
|
3419
|
-
for (const entry of entries) {
|
|
3420
|
-
if (Object.prototype.hasOwnProperty.call(events, entry.event)) {
|
|
3421
|
-
throw new Error(`@On("${entry.event}") declared twice on the same webhook`);
|
|
3422
|
-
}
|
|
3423
|
-
events[entry.event] = (event, metaArg) => instance[entry.fnName].call(instance, event, metaArg);
|
|
3424
|
-
}
|
|
3425
|
-
return {
|
|
3426
|
-
...meta.provider ? { provider: meta.provider } : {},
|
|
3427
|
-
...meta.signature ? { signature: meta.signature } : {},
|
|
3428
|
-
secret: meta.secret,
|
|
3429
|
-
events
|
|
3430
|
-
};
|
|
3431
|
-
}
|
|
3432
|
-
|
|
3433
3485
|
// src/job.ts
|
|
3434
3486
|
function validateCronExpression(expression) {
|
|
3435
3487
|
const trimmed = expression.trim();
|
|
@@ -3500,6 +3552,8 @@ function validateCronField(field, name, min, max) {
|
|
|
3500
3552
|
// src/decorators/job.ts
|
|
3501
3553
|
var DEFAULT_TIMEOUT_SECONDS = 30;
|
|
3502
3554
|
var MAX_TIMEOUT_SECONDS = 300;
|
|
3555
|
+
var DEFAULT_RETRY = 5;
|
|
3556
|
+
var MAX_RETRY = 10;
|
|
3503
3557
|
var JOB_META = /* @__PURE__ */ Symbol.for("palbase.backend.jobMeta");
|
|
3504
3558
|
function Job(options) {
|
|
3505
3559
|
return function(ctor) {
|
|
@@ -3540,12 +3594,19 @@ function getJobConfig(ctor) {
|
|
|
3540
3594
|
if (timeout > MAX_TIMEOUT_SECONDS) {
|
|
3541
3595
|
throw new Error(`@Job \`timeout\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);
|
|
3542
3596
|
}
|
|
3597
|
+
const retry = meta.retry ?? DEFAULT_RETRY;
|
|
3598
|
+
if (!Number.isInteger(retry) || retry < 0) {
|
|
3599
|
+
throw new Error("@Job `retry` must be a whole number of attempts, zero or more");
|
|
3600
|
+
}
|
|
3601
|
+
if (retry > MAX_RETRY) {
|
|
3602
|
+
throw new Error(`@Job \`retry\` exceeds the ceiling of ${MAX_RETRY}`);
|
|
3603
|
+
}
|
|
3543
3604
|
const instance = new ctor();
|
|
3544
3605
|
if (typeof instance.run !== "function") {
|
|
3545
3606
|
throw new Error("@Job class must declare an async run() method");
|
|
3546
3607
|
}
|
|
3547
3608
|
const run = instance.run.bind(instance);
|
|
3548
|
-
return { schedule: meta.schedule, timeout, handler: run };
|
|
3609
|
+
return { schedule: meta.schedule, timeout, retry, handler: run };
|
|
3549
3610
|
}
|
|
3550
3611
|
|
|
3551
3612
|
// src/resource.ts
|
|
@@ -3594,41 +3655,6 @@ async function __shutdownResources() {
|
|
|
3594
3655
|
registry2.length = 0;
|
|
3595
3656
|
}
|
|
3596
3657
|
|
|
3597
|
-
// src/hooks.ts
|
|
3598
|
-
var auth = {
|
|
3599
|
-
onUserCreated(handler) {
|
|
3600
|
-
return { module: "auth", event: "user.created", handler };
|
|
3601
|
-
},
|
|
3602
|
-
onSignIn(handler) {
|
|
3603
|
-
return { module: "auth", event: "user.sign_in", handler };
|
|
3604
|
-
},
|
|
3605
|
-
onSignOut(handler) {
|
|
3606
|
-
return { module: "auth", event: "user.sign_out", handler };
|
|
3607
|
-
},
|
|
3608
|
-
onPasswordReset(handler) {
|
|
3609
|
-
return { module: "auth", event: "user.password_reset", handler };
|
|
3610
|
-
}
|
|
3611
|
-
};
|
|
3612
|
-
var storage = {
|
|
3613
|
-
onFileUploaded(handler) {
|
|
3614
|
-
return { module: "storage", event: "file.uploaded", handler };
|
|
3615
|
-
},
|
|
3616
|
-
onFileDeleted(handler) {
|
|
3617
|
-
return { module: "storage", event: "file.deleted", handler };
|
|
3618
|
-
}
|
|
3619
|
-
};
|
|
3620
|
-
var documents = {
|
|
3621
|
-
onDocumentCreated(handler) {
|
|
3622
|
-
return { module: "documents", event: "document.created", handler };
|
|
3623
|
-
},
|
|
3624
|
-
onDocumentUpdated(handler) {
|
|
3625
|
-
return { module: "documents", event: "document.updated", handler };
|
|
3626
|
-
},
|
|
3627
|
-
onDocumentDeleted(handler) {
|
|
3628
|
-
return { module: "documents", event: "document.deleted", handler };
|
|
3629
|
-
}
|
|
3630
|
-
};
|
|
3631
|
-
|
|
3632
3658
|
// src/index.ts
|
|
3633
3659
|
var import_zod2 = require("zod");
|
|
3634
3660
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -3642,6 +3668,7 @@ var import_zod2 = require("zod");
|
|
|
3642
3668
|
DEFAULT_TEMPLATE_LOCALE,
|
|
3643
3669
|
Database,
|
|
3644
3670
|
Delete,
|
|
3671
|
+
Deny,
|
|
3645
3672
|
Documents,
|
|
3646
3673
|
EGRESS_CONFIG_KIND,
|
|
3647
3674
|
EGRESS_TIMEOUT_DEFAULT_MS,
|
|
@@ -3653,6 +3680,7 @@ var import_zod2 = require("zod");
|
|
|
3653
3680
|
Forbidden,
|
|
3654
3681
|
Get,
|
|
3655
3682
|
Headers,
|
|
3683
|
+
Hook,
|
|
3656
3684
|
HttpError,
|
|
3657
3685
|
Job,
|
|
3658
3686
|
Log,
|
|
@@ -3702,7 +3730,6 @@ var import_zod2 = require("zod");
|
|
|
3702
3730
|
__runWithRuntime,
|
|
3703
3731
|
__setRuntime,
|
|
3704
3732
|
__shutdownResources,
|
|
3705
|
-
auth,
|
|
3706
3733
|
bigint,
|
|
3707
3734
|
boolean,
|
|
3708
3735
|
bucket,
|
|
@@ -3718,12 +3745,12 @@ var import_zod2 = require("zod");
|
|
|
3718
3745
|
defineSecrets,
|
|
3719
3746
|
defineStorage,
|
|
3720
3747
|
defineTestUsers,
|
|
3721
|
-
documents,
|
|
3722
3748
|
entitlementFor,
|
|
3723
3749
|
enumType,
|
|
3724
3750
|
extractVariables,
|
|
3725
3751
|
flag,
|
|
3726
3752
|
getErrorRegistry,
|
|
3753
|
+
getHookConfig,
|
|
3727
3754
|
getJobConfig,
|
|
3728
3755
|
getRegisteredControllers,
|
|
3729
3756
|
getRoutes,
|
|
@@ -3745,7 +3772,6 @@ var import_zod2 = require("zod");
|
|
|
3745
3772
|
reservedSecretKey,
|
|
3746
3773
|
secret,
|
|
3747
3774
|
spendFor,
|
|
3748
|
-
storage,
|
|
3749
3775
|
testUser,
|
|
3750
3776
|
text,
|
|
3751
3777
|
timestamp,
|