@palbase/backend 18.0.0 → 20.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 +189 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +190 -121
- package/dist/index.d.ts +190 -121
- package/dist/index.js +178 -121
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/template/package.json +1 -1
- 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,
|
|
@@ -111,6 +113,7 @@ __export(src_exports, {
|
|
|
111
113
|
extractVariables: () => extractVariables,
|
|
112
114
|
flag: () => flag,
|
|
113
115
|
getErrorRegistry: () => getErrorRegistry,
|
|
116
|
+
getHookConfig: () => getHookConfig,
|
|
114
117
|
getJobConfig: () => getJobConfig,
|
|
115
118
|
getRegisteredControllers: () => getRegisteredControllers,
|
|
116
119
|
getRoutes: () => getRoutes,
|
|
@@ -1703,13 +1706,13 @@ function buildBucketClient(http, bucketName) {
|
|
|
1703
1706
|
},
|
|
1704
1707
|
async remove(paths) {
|
|
1705
1708
|
for (const p of paths) validateStoragePath(p);
|
|
1706
|
-
const
|
|
1709
|
+
const removed2 = [];
|
|
1707
1710
|
for (const p of paths) {
|
|
1708
1711
|
const res = await http.request("DELETE", objectPath(p));
|
|
1709
1712
|
if (res.error) return { data: null, error: res.error, status: res.status };
|
|
1710
|
-
|
|
1713
|
+
removed2.push(toFileObject(bucketName, { path: p }));
|
|
1711
1714
|
}
|
|
1712
|
-
return { data:
|
|
1715
|
+
return { data: removed2, error: null, status: 200 };
|
|
1713
1716
|
},
|
|
1714
1717
|
async move(from, to) {
|
|
1715
1718
|
validateStoragePath(from);
|
|
@@ -2297,7 +2300,7 @@ function makeEnvDts(schema) {
|
|
|
2297
2300
|
${blocks.join("\n")}
|
|
2298
2301
|
` : "";
|
|
2299
2302
|
return `// AUTO-GENERATED by @palbase/backend \u2014 DO NOT EDIT.
|
|
2300
|
-
// Regenerated from db/schema.ts
|
|
2303
|
+
// Regenerated from db/schema.ts by \`palbase build\` and by every deploy.
|
|
2301
2304
|
// Augments the @palbase/backend/env \`Tables\` interface so \`Database.tables.*\`
|
|
2302
2305
|
// is typed with no import and no generic.
|
|
2303
2306
|
|
|
@@ -3114,6 +3117,155 @@ var Patch = makeMethodDecorator("PATCH");
|
|
|
3114
3117
|
var Delete = makeMethodDecorator("DELETE");
|
|
3115
3118
|
var Query = makeMethodDecorator("QUERY");
|
|
3116
3119
|
|
|
3120
|
+
// src/decorators/webhook.ts
|
|
3121
|
+
var WEBHOOK_META = /* @__PURE__ */ Symbol.for("palbase.backend.webhookMeta");
|
|
3122
|
+
var WEBHOOK_EVENTS = /* @__PURE__ */ Symbol.for("palbase.backend.webhookEvents");
|
|
3123
|
+
function carrierOf3(ctor) {
|
|
3124
|
+
return ctor;
|
|
3125
|
+
}
|
|
3126
|
+
function Webhook(options) {
|
|
3127
|
+
return function(ctor) {
|
|
3128
|
+
const carrier = carrierOf3(ctor);
|
|
3129
|
+
Object.defineProperty(carrier, WEBHOOK_META, {
|
|
3130
|
+
value: options,
|
|
3131
|
+
enumerable: false,
|
|
3132
|
+
configurable: true,
|
|
3133
|
+
writable: false
|
|
3134
|
+
});
|
|
3135
|
+
Object.defineProperty(carrier, "__palbase", {
|
|
3136
|
+
value: "webhook",
|
|
3137
|
+
enumerable: false,
|
|
3138
|
+
configurable: true,
|
|
3139
|
+
writable: false
|
|
3140
|
+
});
|
|
3141
|
+
return ctor;
|
|
3142
|
+
};
|
|
3143
|
+
}
|
|
3144
|
+
function On(event) {
|
|
3145
|
+
return function(target, fnName) {
|
|
3146
|
+
const carrier = carrierOf3(target.constructor);
|
|
3147
|
+
const existing = carrier[WEBHOOK_EVENTS];
|
|
3148
|
+
const entries = existing ? [...existing] : [];
|
|
3149
|
+
entries.push({ event, fnName: String(fnName) });
|
|
3150
|
+
Object.defineProperty(carrier, WEBHOOK_EVENTS, {
|
|
3151
|
+
value: entries,
|
|
3152
|
+
enumerable: false,
|
|
3153
|
+
configurable: true,
|
|
3154
|
+
writable: false
|
|
3155
|
+
});
|
|
3156
|
+
};
|
|
3157
|
+
}
|
|
3158
|
+
function getWebhookConfig(ctor) {
|
|
3159
|
+
const carrier = carrierOf3(ctor);
|
|
3160
|
+
const meta = carrier[WEBHOOK_META];
|
|
3161
|
+
const entries = carrier[WEBHOOK_EVENTS] ?? [];
|
|
3162
|
+
if (!meta) {
|
|
3163
|
+
throw new Error(
|
|
3164
|
+
`@On used on a class that is not decorated with @Webhook (${ctor.name ?? "anonymous"})`
|
|
3165
|
+
);
|
|
3166
|
+
}
|
|
3167
|
+
if (!meta.provider && !meta.signature) {
|
|
3168
|
+
throw new Error(
|
|
3169
|
+
"@Webhook requires either a `provider` preset or an explicit `signature` \u2014 an endpoint with no verification would accept forged deliveries"
|
|
3170
|
+
);
|
|
3171
|
+
}
|
|
3172
|
+
if (meta.provider && meta.signature) {
|
|
3173
|
+
throw new Error(
|
|
3174
|
+
"@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"
|
|
3175
|
+
);
|
|
3176
|
+
}
|
|
3177
|
+
if (meta.signature) {
|
|
3178
|
+
const sig = meta.signature;
|
|
3179
|
+
if (!sig.header) {
|
|
3180
|
+
throw new Error("@Webhook signature requires `header` \u2014 the header the signature arrives in");
|
|
3181
|
+
}
|
|
3182
|
+
if (sig.algo !== "hmac-sha256" && sig.algo !== "hmac-sha1") {
|
|
3183
|
+
throw new Error(`@Webhook signature has an unsupported algo "${sig.algo}"`);
|
|
3184
|
+
}
|
|
3185
|
+
if (sig.encoding !== "hex" && sig.encoding !== "base64") {
|
|
3186
|
+
throw new Error(`@Webhook signature has an unsupported encoding "${sig.encoding}"`);
|
|
3187
|
+
}
|
|
3188
|
+
if (!sig.signs?.includes("{body}")) {
|
|
3189
|
+
throw new Error("@Webhook signature `signs` must contain {body} \u2014 signing a constant is not a signature");
|
|
3190
|
+
}
|
|
3191
|
+
if (sig.signs.includes("{ts}") && !sig.timestampHeader) {
|
|
3192
|
+
throw new Error("@Webhook signature uses {ts} but declares no `timestampHeader` to read it from");
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
if (!meta.secret?.env) {
|
|
3196
|
+
throw new Error('@Webhook requires `secret: { env: "VAR_NAME" }`');
|
|
3197
|
+
}
|
|
3198
|
+
if (entries.length === 0) {
|
|
3199
|
+
throw new Error("@Webhook requires at least one @On handler");
|
|
3200
|
+
}
|
|
3201
|
+
const instance = new ctor();
|
|
3202
|
+
const events = /* @__PURE__ */ Object.create(null);
|
|
3203
|
+
for (const entry of entries) {
|
|
3204
|
+
if (Object.prototype.hasOwnProperty.call(events, entry.event)) {
|
|
3205
|
+
throw new Error(`@On("${entry.event}") declared twice on the same webhook`);
|
|
3206
|
+
}
|
|
3207
|
+
events[entry.event] = (event, metaArg) => instance[entry.fnName].call(instance, event, metaArg);
|
|
3208
|
+
}
|
|
3209
|
+
return {
|
|
3210
|
+
...meta.provider ? { provider: meta.provider } : {},
|
|
3211
|
+
...meta.signature ? { signature: meta.signature } : {},
|
|
3212
|
+
secret: meta.secret,
|
|
3213
|
+
events
|
|
3214
|
+
};
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
// src/decorators/hook.ts
|
|
3218
|
+
var Deny = class extends Error {
|
|
3219
|
+
constructor(reason) {
|
|
3220
|
+
super(reason);
|
|
3221
|
+
this.name = "Deny";
|
|
3222
|
+
}
|
|
3223
|
+
};
|
|
3224
|
+
var HOOK_BLOCKING = /* @__PURE__ */ Symbol.for("palbase.backend.hookBlocking");
|
|
3225
|
+
function Hook(event) {
|
|
3226
|
+
return function(target, fnName) {
|
|
3227
|
+
const carrier = target.constructor;
|
|
3228
|
+
const existing = carrier[HOOK_BLOCKING];
|
|
3229
|
+
const entries = existing ? [...existing] : [];
|
|
3230
|
+
entries.push({ event, fnName: String(fnName) });
|
|
3231
|
+
Object.defineProperty(carrier, HOOK_BLOCKING, {
|
|
3232
|
+
value: entries,
|
|
3233
|
+
enumerable: false,
|
|
3234
|
+
configurable: true,
|
|
3235
|
+
writable: false
|
|
3236
|
+
});
|
|
3237
|
+
};
|
|
3238
|
+
}
|
|
3239
|
+
function bind(instance, entries, kind) {
|
|
3240
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3241
|
+
for (const entry of entries) {
|
|
3242
|
+
if (Object.prototype.hasOwnProperty.call(out, entry.event)) {
|
|
3243
|
+
throw new Error(`${kind}("${entry.event}") declared twice on the same hook class`);
|
|
3244
|
+
}
|
|
3245
|
+
const fn = instance[entry.fnName];
|
|
3246
|
+
if (typeof fn !== "function") {
|
|
3247
|
+
throw new Error(`${kind}("${entry.event}") names no method "${entry.fnName}" on the class`);
|
|
3248
|
+
}
|
|
3249
|
+
out[entry.event] = (event, meta) => fn.call(instance, event, meta);
|
|
3250
|
+
}
|
|
3251
|
+
return out;
|
|
3252
|
+
}
|
|
3253
|
+
function getHookConfig(ctor) {
|
|
3254
|
+
const carrier = ctor;
|
|
3255
|
+
const blockingEntries = carrier[HOOK_BLOCKING] ?? [];
|
|
3256
|
+
const listenerEntries = carrier[WEBHOOK_EVENTS] ?? [];
|
|
3257
|
+
if (blockingEntries.length === 0 && listenerEntries.length === 0) {
|
|
3258
|
+
throw new Error(
|
|
3259
|
+
`${ctor.name ?? "a hook class"} carries no handler \u2014 a hook file must declare at least one @Hook (blocking) or @On (listener) method`
|
|
3260
|
+
);
|
|
3261
|
+
}
|
|
3262
|
+
const instance = new ctor();
|
|
3263
|
+
return {
|
|
3264
|
+
blocking: bind(instance, blockingEntries, "@Hook"),
|
|
3265
|
+
listeners: bind(instance, listenerEntries, "@On")
|
|
3266
|
+
};
|
|
3267
|
+
}
|
|
3268
|
+
|
|
3117
3269
|
// src/decorators/upload.ts
|
|
3118
3270
|
function Upload(subpath, config) {
|
|
3119
3271
|
const { auth: auth2, rateLimit, ...uploadConfig } = config;
|
|
@@ -3333,103 +3485,6 @@ function humanize(code) {
|
|
|
3333
3485
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
3334
3486
|
}
|
|
3335
3487
|
|
|
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
3488
|
// src/job.ts
|
|
3434
3489
|
function validateCronExpression(expression) {
|
|
3435
3490
|
const trimmed = expression.trim();
|
|
@@ -3500,6 +3555,8 @@ function validateCronField(field, name, min, max) {
|
|
|
3500
3555
|
// src/decorators/job.ts
|
|
3501
3556
|
var DEFAULT_TIMEOUT_SECONDS = 30;
|
|
3502
3557
|
var MAX_TIMEOUT_SECONDS = 300;
|
|
3558
|
+
var DEFAULT_RETRY = 5;
|
|
3559
|
+
var MAX_RETRY = 10;
|
|
3503
3560
|
var JOB_META = /* @__PURE__ */ Symbol.for("palbase.backend.jobMeta");
|
|
3504
3561
|
function Job(options) {
|
|
3505
3562
|
return function(ctor) {
|
|
@@ -3540,12 +3597,19 @@ function getJobConfig(ctor) {
|
|
|
3540
3597
|
if (timeout > MAX_TIMEOUT_SECONDS) {
|
|
3541
3598
|
throw new Error(`@Job \`timeout\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);
|
|
3542
3599
|
}
|
|
3600
|
+
const retry = meta.retry ?? DEFAULT_RETRY;
|
|
3601
|
+
if (!Number.isInteger(retry) || retry < 0) {
|
|
3602
|
+
throw new Error("@Job `retry` must be a whole number of attempts, zero or more");
|
|
3603
|
+
}
|
|
3604
|
+
if (retry > MAX_RETRY) {
|
|
3605
|
+
throw new Error(`@Job \`retry\` exceeds the ceiling of ${MAX_RETRY}`);
|
|
3606
|
+
}
|
|
3543
3607
|
const instance = new ctor();
|
|
3544
3608
|
if (typeof instance.run !== "function") {
|
|
3545
3609
|
throw new Error("@Job class must declare an async run() method");
|
|
3546
3610
|
}
|
|
3547
3611
|
const run = instance.run.bind(instance);
|
|
3548
|
-
return { schedule: meta.schedule, timeout, handler: run };
|
|
3612
|
+
return { schedule: meta.schedule, timeout, retry, handler: run };
|
|
3549
3613
|
}
|
|
3550
3614
|
|
|
3551
3615
|
// src/resource.ts
|
|
@@ -3595,38 +3659,31 @@ async function __shutdownResources() {
|
|
|
3595
3659
|
}
|
|
3596
3660
|
|
|
3597
3661
|
// src/hooks.ts
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
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 };
|
|
3662
|
+
function removed(helper, decorator, event) {
|
|
3663
|
+
throw new Error(
|
|
3664
|
+
`${helper}() does not register anything and never did \u2014 nothing in the runtime or the bundler reads what it returns, so the handler you passed would never run. Declare it instead in hooks/<name>.ts:
|
|
3665
|
+
|
|
3666
|
+
export default class MyHooks {
|
|
3667
|
+
${decorator}("${event}")
|
|
3668
|
+
async handle(event, meta) { /* \u2026 */ }
|
|
3610
3669
|
}
|
|
3670
|
+
`
|
|
3671
|
+
);
|
|
3672
|
+
}
|
|
3673
|
+
var auth = {
|
|
3674
|
+
onUserCreated: (_h) => removed("auth.onUserCreated", "@Hook", "before.user.create"),
|
|
3675
|
+
onSignIn: (_h) => removed("auth.onSignIn", "@Hook", "before.login"),
|
|
3676
|
+
onSignOut: (_h) => removed("auth.onSignOut", "@On", "after.session.revoke"),
|
|
3677
|
+
onPasswordReset: (_h) => removed("auth.onPasswordReset", "@Hook", "before.password.reset")
|
|
3611
3678
|
};
|
|
3612
3679
|
var storage = {
|
|
3613
|
-
onFileUploaded(
|
|
3614
|
-
|
|
3615
|
-
},
|
|
3616
|
-
onFileDeleted(handler) {
|
|
3617
|
-
return { module: "storage", event: "file.deleted", handler };
|
|
3618
|
-
}
|
|
3680
|
+
onFileUploaded: (_h) => removed("storage.onFileUploaded", "@On", "file.uploaded"),
|
|
3681
|
+
onFileDeleted: (_h) => removed("storage.onFileDeleted", "@On", "file.deleted")
|
|
3619
3682
|
};
|
|
3620
3683
|
var documents = {
|
|
3621
|
-
onDocumentCreated(
|
|
3622
|
-
|
|
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
|
-
}
|
|
3684
|
+
onDocumentCreated: (_h) => removed("documents.onDocumentCreated", "@On", "document.created"),
|
|
3685
|
+
onDocumentUpdated: (_h) => removed("documents.onDocumentUpdated", "@On", "document.updated"),
|
|
3686
|
+
onDocumentDeleted: (_h) => removed("documents.onDocumentDeleted", "@On", "document.deleted")
|
|
3630
3687
|
};
|
|
3631
3688
|
|
|
3632
3689
|
// src/index.ts
|
|
@@ -3642,6 +3699,7 @@ var import_zod2 = require("zod");
|
|
|
3642
3699
|
DEFAULT_TEMPLATE_LOCALE,
|
|
3643
3700
|
Database,
|
|
3644
3701
|
Delete,
|
|
3702
|
+
Deny,
|
|
3645
3703
|
Documents,
|
|
3646
3704
|
EGRESS_CONFIG_KIND,
|
|
3647
3705
|
EGRESS_TIMEOUT_DEFAULT_MS,
|
|
@@ -3653,6 +3711,7 @@ var import_zod2 = require("zod");
|
|
|
3653
3711
|
Forbidden,
|
|
3654
3712
|
Get,
|
|
3655
3713
|
Headers,
|
|
3714
|
+
Hook,
|
|
3656
3715
|
HttpError,
|
|
3657
3716
|
Job,
|
|
3658
3717
|
Log,
|
|
@@ -3724,6 +3783,7 @@ var import_zod2 = require("zod");
|
|
|
3724
3783
|
extractVariables,
|
|
3725
3784
|
flag,
|
|
3726
3785
|
getErrorRegistry,
|
|
3786
|
+
getHookConfig,
|
|
3727
3787
|
getJobConfig,
|
|
3728
3788
|
getRegisteredControllers,
|
|
3729
3789
|
getRoutes,
|