@palbase/backend 32.0.0 → 33.0.1
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 +79 -26
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +5 -5
- package/dist/{chunk-AZJIKCOR.js → chunk-IKDONZ5D.js} +39 -23
- package/dist/{chunk-AZJIKCOR.js.map → chunk-IKDONZ5D.js.map} +1 -1
- package/dist/{chunk-IXAX5CON.js → chunk-SI4KGEM3.js} +1 -1
- package/dist/{chunk-IXAX5CON.js.map → chunk-SI4KGEM3.js.map} +1 -1
- package/dist/{chunk-XEGZ3S2Q.js → chunk-TVCCR6SO.js} +32 -7
- package/dist/chunk-TVCCR6SO.js.map +1 -0
- package/dist/{chunk-5C5UCILO.js → chunk-WWUG2QXF.js} +3 -3
- package/dist/{chunk-KGP6ALIU.js → chunk-XOX6RFPZ.js} +30 -8
- package/dist/chunk-XOX6RFPZ.js.map +1 -0
- package/dist/{chunk-Z4CZRMNF.js → chunk-YIQ4RS4F.js} +2 -2
- package/dist/db/index.cjs +14 -4
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +3 -3
- package/dist/engine/index.cjs +79 -26
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +3 -3
- package/dist/engine/index.d.ts +3 -3
- package/dist/engine/index.js +5 -5
- package/dist/{index-BILC9WwS.d.ts → index-D-3duy8Y.d.ts} +2 -2
- package/dist/{index-DgYkdNT9.d.cts → index-DB_nW-AV.d.cts} +87 -30
- package/dist/{index-CWGiJ2Up.d.cts → index-DLveQoOf.d.cts} +2 -2
- package/dist/{index-BgWnP07a.d.ts → index-DMZG3kpo.d.ts} +87 -30
- package/dist/index.cjs +59 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +5 -5
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{registry-BcRYIQ-R.d.cts → registry-DSTThhKf.d.cts} +1 -1
- package/dist/{registry-ClzjxIWy.d.ts → registry-JjF5lcj4.d.ts} +1 -1
- package/dist/test/index.cjs +1155 -12
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +1126 -8
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +124 -80
- package/docs/auth.md +112 -26
- package/docs/background.md +16 -7
- package/docs/database.md +22 -18
- package/docs/endpoints.md +26 -20
- package/docs/errors.md +2 -3
- package/docs/events.md +63 -29
- package/docs/getting-started.md +8 -7
- package/docs/llms-full.txt +519 -244
- package/docs/migrations.md +6 -5
- package/docs/routing.md +34 -11
- package/docs/schema.md +78 -27
- package/docs/services.md +30 -13
- package/package.json +2 -1
- package/stack-images.json +24 -0
- package/template/db/public.ts +23 -0
- package/template/package.json +1 -1
- package/dist/chunk-KGP6ALIU.js.map +0 -1
- package/dist/chunk-XEGZ3S2Q.js.map +0 -1
- /package/dist/{chunk-5C5UCILO.js.map → chunk-WWUG2QXF.js.map} +0 -0
- /package/dist/{chunk-Z4CZRMNF.js.map → chunk-YIQ4RS4F.js.map} +0 -0
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
BootRefused,
|
|
4
4
|
createApp,
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-IKDONZ5D.js";
|
|
7
|
+
import "../chunk-WWUG2QXF.js";
|
|
8
|
+
import "../chunk-TVCCR6SO.js";
|
|
9
|
+
import "../chunk-XOX6RFPZ.js";
|
|
10
|
+
import "../chunk-SI4KGEM3.js";
|
|
11
11
|
import {
|
|
12
12
|
getRegisteredControllers
|
|
13
13
|
} from "../chunk-BRLJOXWS.js";
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
assertNoOrphanEntryPoints,
|
|
4
4
|
buildContainer,
|
|
5
5
|
buildRelations
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WWUG2QXF.js";
|
|
7
7
|
import {
|
|
8
8
|
__requestALS,
|
|
9
9
|
__runStartHooks,
|
|
10
10
|
__runWithRuntime
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-TVCCR6SO.js";
|
|
12
12
|
import {
|
|
13
13
|
CODECS
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-XOX6RFPZ.js";
|
|
15
15
|
import {
|
|
16
16
|
assertNoExpressionHandles,
|
|
17
17
|
assertUsableFilter,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
looksLikeUnbrandedPlanRef,
|
|
26
26
|
looksLikeUnbrandedRef,
|
|
27
27
|
qualifiedTableKey
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-SI4KGEM3.js";
|
|
29
29
|
import {
|
|
30
30
|
getRoutes,
|
|
31
31
|
resolveEffectiveAuth
|
|
@@ -3187,23 +3187,21 @@ async function createApp(opts) {
|
|
|
3187
3187
|
if (spec.required && !callerClaims) {
|
|
3188
3188
|
return envelope("unauthorized", "A valid access token is required", 401, requestId);
|
|
3189
3189
|
}
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
if (refusal) {
|
|
3199
|
-
await uploadDb.commit();
|
|
3200
|
-
return refusal;
|
|
3201
|
-
}
|
|
3190
|
+
const uploadDb = createRequestDatabase(sql, {
|
|
3191
|
+
role: config.dbRole,
|
|
3192
|
+
serviceRole: config.dbServiceRole,
|
|
3193
|
+
claimsJson: JSON.stringify(callerClaims ?? {})
|
|
3194
|
+
});
|
|
3195
|
+
try {
|
|
3196
|
+
const refusal = await refuseUnlessAuthorized(uploadDb.client, spec, requestId, makeRoleResolver(uploadDb.client));
|
|
3197
|
+
if (refusal) {
|
|
3202
3198
|
await uploadDb.commit();
|
|
3203
|
-
|
|
3204
|
-
await uploadDb.rollback(err);
|
|
3205
|
-
throw err;
|
|
3199
|
+
return refusal;
|
|
3206
3200
|
}
|
|
3201
|
+
await uploadDb.commit();
|
|
3202
|
+
} catch (err) {
|
|
3203
|
+
await uploadDb.rollback(err);
|
|
3204
|
+
throw err;
|
|
3207
3205
|
}
|
|
3208
3206
|
const grant = grantFor(target?.entry, {
|
|
3209
3207
|
userId: typeof callerClaims?.sub === "string" ? callerClaims.sub : null,
|
|
@@ -3242,11 +3240,18 @@ async function createApp(opts) {
|
|
|
3242
3240
|
claimsJson: JSON.stringify(claims ?? {})
|
|
3243
3241
|
});
|
|
3244
3242
|
const rolesOfCaller = makeRoleResolver(db.client);
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
if (
|
|
3243
|
+
let dispatched = false;
|
|
3244
|
+
const settleBeforeRefusal = /* @__PURE__ */ __name(async () => {
|
|
3245
|
+
if (dispatched) return;
|
|
3246
|
+
await db.rollback(new Error("request refused before dispatch"));
|
|
3247
|
+
}, "settleBeforeRefusal");
|
|
3248
|
+
const refusal = await refuseUnlessAuthorized(db.client, spec, requestId, rolesOfCaller);
|
|
3249
|
+
if (refusal) {
|
|
3250
|
+
await settleBeforeRefusal();
|
|
3251
|
+
return refusal;
|
|
3248
3252
|
}
|
|
3249
3253
|
if (claims && spec.verifiedEmail && claims.email_verified !== true) {
|
|
3254
|
+
await settleBeforeRefusal();
|
|
3250
3255
|
return envelope("email_not_verified", "A verified email address is required", 403, requestId);
|
|
3251
3256
|
}
|
|
3252
3257
|
let parsedBody;
|
|
@@ -3255,6 +3260,7 @@ async function createApp(opts) {
|
|
|
3255
3260
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
3256
3261
|
const declared = Number(req.headers.get("content-length") ?? "");
|
|
3257
3262
|
if (Number.isFinite(declared) && declared > MAX_BODY_BYTES) {
|
|
3263
|
+
await settleBeforeRefusal();
|
|
3258
3264
|
return new Response(JSON.stringify({
|
|
3259
3265
|
error: "payload_too_large",
|
|
3260
3266
|
error_description: `Request body exceeds ${MAX_BODY_BYTES} bytes`,
|
|
@@ -3267,6 +3273,7 @@ async function createApp(opts) {
|
|
|
3267
3273
|
}
|
|
3268
3274
|
const buf = await req.arrayBuffer().catch(() => null);
|
|
3269
3275
|
if (buf && buf.byteLength > MAX_BODY_BYTES) {
|
|
3276
|
+
await settleBeforeRefusal();
|
|
3270
3277
|
return new Response(JSON.stringify({
|
|
3271
3278
|
error: "payload_too_large",
|
|
3272
3279
|
error_description: `Request body exceeds ${MAX_BODY_BYTES} bytes`,
|
|
@@ -3302,6 +3309,7 @@ async function createApp(opts) {
|
|
|
3302
3309
|
...JSON_HEADERS
|
|
3303
3310
|
};
|
|
3304
3311
|
if (attest.nextChallenge) headers["x-palbase-attest-challenge"] = attest.nextChallenge;
|
|
3312
|
+
await settleBeforeRefusal();
|
|
3305
3313
|
return new Response(JSON.stringify({
|
|
3306
3314
|
error: attest.reason,
|
|
3307
3315
|
error_description: "This endpoint requires a verified app instance",
|
|
@@ -3316,6 +3324,7 @@ async function createApp(opts) {
|
|
|
3316
3324
|
attestChallengeOut = attest.nextChallenge;
|
|
3317
3325
|
const retryAfter = limiter.check(meta.options?.rateLimit, RateLimiter.key(hit.entry.id, userId, req.headers), Date.now());
|
|
3318
3326
|
if (retryAfter !== null) {
|
|
3327
|
+
await settleBeforeRefusal();
|
|
3319
3328
|
return new Response(JSON.stringify({
|
|
3320
3329
|
error: "too_many_requests",
|
|
3321
3330
|
error_description: "Rate limit exceeded for this endpoint",
|
|
@@ -3347,6 +3356,7 @@ async function createApp(opts) {
|
|
|
3347
3356
|
readParsedBody();
|
|
3348
3357
|
const r = p.schema.safeParse(parsedBody);
|
|
3349
3358
|
if (!r.success) {
|
|
3359
|
+
await settleBeforeRefusal();
|
|
3350
3360
|
return envelope("bad_request", "Request body failed validation", 400, requestId, {
|
|
3351
3361
|
data: {
|
|
3352
3362
|
fields: fieldErrors(r.error)
|
|
@@ -3359,6 +3369,7 @@ async function createApp(opts) {
|
|
|
3359
3369
|
case "query": {
|
|
3360
3370
|
const r = p.schema.safeParse(Object.fromEntries(url.searchParams));
|
|
3361
3371
|
if (!r.success) {
|
|
3372
|
+
await settleBeforeRefusal();
|
|
3362
3373
|
return envelope("bad_request", "Query parameters failed validation", 400, requestId, {
|
|
3363
3374
|
data: {
|
|
3364
3375
|
fields: fieldErrors(r.error)
|
|
@@ -3379,6 +3390,7 @@ async function createApp(opts) {
|
|
|
3379
3390
|
}
|
|
3380
3391
|
const r = p.schema.safeParse(headersFor(raw, p.schema));
|
|
3381
3392
|
if (!r.success) {
|
|
3393
|
+
await settleBeforeRefusal();
|
|
3382
3394
|
return envelope("bad_request", "Request headers failed validation", 400, requestId, {
|
|
3383
3395
|
data: {
|
|
3384
3396
|
fields: fieldErrors(r.error)
|
|
@@ -3411,17 +3423,20 @@ async function createApp(opts) {
|
|
|
3411
3423
|
break;
|
|
3412
3424
|
case "uploadedObject": {
|
|
3413
3425
|
if (uploadSecret === "" || !verifySignature(req.headers.get(SIGNATURE_HEADER) ?? "", uploadSecret)) {
|
|
3426
|
+
await settleBeforeRefusal();
|
|
3414
3427
|
return envelope("unauthorized", "This endpoint accepts uploads through storage, not directly", 401, requestId);
|
|
3415
3428
|
}
|
|
3416
3429
|
readParsedBody();
|
|
3417
3430
|
const envelopeIn = parsedBody;
|
|
3418
3431
|
if (!envelopeIn?.uploadedObject) {
|
|
3432
|
+
await settleBeforeRefusal();
|
|
3419
3433
|
return envelope("bad_request", "the completion call carried no uploaded object", 400, requestId);
|
|
3420
3434
|
}
|
|
3421
3435
|
const uploadId = envelopeIn.uploadedObject.uploadId;
|
|
3422
3436
|
if (typeof uploadId === "string" && uploadId !== "") {
|
|
3423
3437
|
const already = completions.recall(uploadId);
|
|
3424
3438
|
if (already) {
|
|
3439
|
+
await settleBeforeRefusal();
|
|
3425
3440
|
return new Response(already.body, {
|
|
3426
3441
|
status: already.status,
|
|
3427
3442
|
headers: already.contentType ? {
|
|
@@ -3471,6 +3486,7 @@ async function createApp(opts) {
|
|
|
3471
3486
|
args[p.index] = void 0;
|
|
3472
3487
|
}
|
|
3473
3488
|
}
|
|
3489
|
+
dispatched = true;
|
|
3474
3490
|
try {
|
|
3475
3491
|
const services = buildServices(db);
|
|
3476
3492
|
if (meta.options?.sseConfig !== void 0) {
|
|
@@ -3663,4 +3679,4 @@ export {
|
|
|
3663
3679
|
installEgressFence,
|
|
3664
3680
|
createApp
|
|
3665
3681
|
};
|
|
3666
|
-
//# sourceMappingURL=chunk-
|
|
3682
|
+
//# sourceMappingURL=chunk-IKDONZ5D.js.map
|