@void/platform 0.21.1 → 0.21.3
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/runtime/api/README.md +1 -1
- package/dist/runtime/api/assets/admin/client.js +4 -4
- package/dist/runtime/api/assets/admin/style.css +1 -1
- package/dist/runtime/api/index.js +890 -443
- package/dist/runtime/api/index.js.map +4 -4
- package/dist/runtime/dispatch/README.md +1 -1
- package/dist/runtime/drizzle/0051_icy_psylocke.sql +12 -0
- package/dist/runtime/drizzle/compatibility.json +4 -0
- package/dist/runtime/drizzle/meta/_journal.json +7 -0
- package/dist/runtime/emailGateway/README.md +1 -1
- package/dist/runtime/manifest.json +22 -12
- package/dist/runtime/proxy/README.md +1 -1
- package/dist/runtime/proxy/index.js +110 -71
- package/dist/runtime/proxy/index.js.map +4 -4
- package/dist/runtime/tail/README.md +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
This folder contains the built output assets for the worker "void-runtime-build-dispatch" generated at 2026-09-
|
|
1
|
+
This folder contains the built output assets for the worker "void-runtime-build-dispatch" generated at 2026-09-30T07:33:18.333Z.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
CREATE TABLE "project_cleanup_jobs" (
|
|
2
|
+
"target" text PRIMARY KEY NOT NULL,
|
|
3
|
+
"project_id" text NOT NULL,
|
|
4
|
+
"kind" text NOT NULL,
|
|
5
|
+
"payload" jsonb NOT NULL,
|
|
6
|
+
"attempts" integer DEFAULT 0 NOT NULL,
|
|
7
|
+
"last_error" text,
|
|
8
|
+
"next_attempt_at" timestamp DEFAULT now() NOT NULL,
|
|
9
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
CREATE INDEX "project_cleanup_jobs_due" ON "project_cleanup_jobs" USING btree ("next_attempt_at","created_at");
|
|
@@ -37,6 +37,10 @@
|
|
|
37
37
|
{
|
|
38
38
|
"platformVersion": "0.20.3",
|
|
39
39
|
"schemaDigest": "408364e61c4b7d83def4030a1c11e8b9b07fc21dd3bffe6529e1b7d3759979b6"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"platformVersion": "0.21.2",
|
|
43
|
+
"schemaDigest": "9a9ae6677b795debd4ffaa20a05f533727063c7a21366310a2fe4b17bd918edd"
|
|
40
44
|
}
|
|
41
45
|
]
|
|
42
46
|
}
|
|
@@ -309,6 +309,13 @@
|
|
|
309
309
|
"when": 1790587573932,
|
|
310
310
|
"tag": "0050_project_member_direct_grants",
|
|
311
311
|
"breakpoints": true
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"idx": 51,
|
|
315
|
+
"version": "7",
|
|
316
|
+
"when": 1790721898182,
|
|
317
|
+
"tag": "0051_icy_psylocke",
|
|
318
|
+
"breakpoints": true
|
|
312
319
|
}
|
|
313
320
|
]
|
|
314
321
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
This folder contains the built output assets for the worker "void-runtime-build-email-gateway" generated at 2026-09-
|
|
1
|
+
This folder contains the built output assets for the worker "void-runtime-build-email-gateway" generated at 2026-09-30T07:33:16.373Z.
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"artifacts": {
|
|
3
3
|
"api": {
|
|
4
4
|
"path": "api/index.js",
|
|
5
|
-
"sha256": "
|
|
6
|
-
"size":
|
|
5
|
+
"sha256": "4508bbe56a40fae5369cf3d040d4944f5c89af18ba36c199e22e00e51f19147a",
|
|
6
|
+
"size": 7018886
|
|
7
7
|
},
|
|
8
8
|
"dispatch": {
|
|
9
9
|
"path": "dispatch/index.js",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"proxy": {
|
|
14
14
|
"path": "proxy/index.js",
|
|
15
|
-
"sha256": "
|
|
16
|
-
"size":
|
|
15
|
+
"sha256": "8a54ad376927b76113dca48613ba918ffd7f207947aa5a56186043b25e6473aa",
|
|
16
|
+
"size": 179041
|
|
17
17
|
},
|
|
18
18
|
"tail": {
|
|
19
19
|
"path": "tail/index.js",
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
"assets": {
|
|
30
30
|
"adminClient": {
|
|
31
31
|
"path": "api/assets/admin/client.js",
|
|
32
|
-
"sha256": "
|
|
33
|
-
"size":
|
|
32
|
+
"sha256": "47ec65f6cb7d8580d876fd6d15957fedf56fee60d4c7629bc84d29d4449d0fb3",
|
|
33
|
+
"size": 964281
|
|
34
34
|
},
|
|
35
35
|
"adminStyle": {
|
|
36
36
|
"path": "api/assets/admin/style.css",
|
|
37
|
-
"sha256": "
|
|
38
|
-
"size":
|
|
37
|
+
"sha256": "0916057e76d56161c961fd43460e362ca035737d4231fcc3280568bfceb48334",
|
|
38
|
+
"size": 206131
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"authenticationProtocolVersion": 1,
|
|
42
42
|
"emailProtocolVersion": 1,
|
|
43
43
|
"applicationRoutingVersion": 1,
|
|
44
44
|
"database": {
|
|
45
|
-
"journalSha256": "
|
|
45
|
+
"journalSha256": "652a62b5568aec5e66bb77cdcf0fd15a67b54671e94870aae36bd69cf2174ef6",
|
|
46
46
|
"lineage": "void-platform-postgresql-v1",
|
|
47
47
|
"migrations": [
|
|
48
48
|
{
|
|
@@ -308,6 +308,12 @@
|
|
|
308
308
|
"sha256": "4ad14938169de2b5c397a3087393b963300a006cbb7394e1f8e083b1896c6e77",
|
|
309
309
|
"tag": "0050_project_member_direct_grants",
|
|
310
310
|
"timestampMillis": 1790587573932
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"index": 51,
|
|
314
|
+
"sha256": "7f360e8e02a2e2ebdd10f7e5e68b35c8aa380e3c68b174ca969f627622641c6c",
|
|
315
|
+
"tag": "0051_icy_psylocke",
|
|
316
|
+
"timestampMillis": 1790721898182
|
|
311
317
|
}
|
|
312
318
|
],
|
|
313
319
|
"protocolVersion": 1,
|
|
@@ -347,15 +353,19 @@
|
|
|
347
353
|
{
|
|
348
354
|
"platformVersion": "0.20.3",
|
|
349
355
|
"schemaDigest": "408364e61c4b7d83def4030a1c11e8b9b07fc21dd3bffe6529e1b7d3759979b6"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"platformVersion": "0.21.2",
|
|
359
|
+
"schemaDigest": "9a9ae6677b795debd4ffaa20a05f533727063c7a21366310a2fe4b17bd918edd"
|
|
350
360
|
}
|
|
351
361
|
],
|
|
352
|
-
"schemaDigest": "
|
|
362
|
+
"schemaDigest": "ac70deb5847c71ece9938edd27e5dbc50ce41e16771926c78e757850baf15bfa"
|
|
353
363
|
},
|
|
354
|
-
"platformVersion": "0.21.
|
|
364
|
+
"platformVersion": "0.21.3",
|
|
355
365
|
"safetyProtocols": {
|
|
356
366
|
"sandboxDrain": 3
|
|
357
367
|
},
|
|
358
368
|
"schemaVersion": 2,
|
|
359
|
-
"sourceRevision": "
|
|
369
|
+
"sourceRevision": "c6543fc657eb855160eff82009acb7e105d0335e",
|
|
360
370
|
"usageProtocolVersion": 2
|
|
361
371
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
This folder contains the built output assets for the worker "void-runtime-build-proxy" generated at 2026-09-
|
|
1
|
+
This folder contains the built output assets for the worker "void-runtime-build-proxy" generated at 2026-09-30T07:33:15.568Z.
|
|
@@ -3153,75 +3153,12 @@ d1.post("/batch", async (context) => {
|
|
|
3153
3153
|
return context.json({ error: "atomic D1 batch unavailable for active deployment" }, 503);
|
|
3154
3154
|
});
|
|
3155
3155
|
|
|
3156
|
-
// ../../home/runner/work/void/void/platform/packages/proxy/src/email-request-body.ts
|
|
3157
|
-
var EMAIL_REQUEST_DEADLINE_MS = 5e3;
|
|
3158
|
-
var decoder2 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: false });
|
|
3159
|
-
async function beforeDeadline(deadline, run) {
|
|
3160
|
-
const remaining = deadline - Date.now();
|
|
3161
|
-
if (remaining <= 0) {
|
|
3162
|
-
throw new Error("email request timeout");
|
|
3163
|
-
}
|
|
3164
|
-
let timer;
|
|
3165
|
-
return Promise.race([
|
|
3166
|
-
run(),
|
|
3167
|
-
new Promise((_, reject) => {
|
|
3168
|
-
timer = setTimeout(() => reject(new Error("email request timeout")), remaining);
|
|
3169
|
-
})
|
|
3170
|
-
]).finally(() => {
|
|
3171
|
-
if (timer !== void 0) {
|
|
3172
|
-
clearTimeout(timer);
|
|
3173
|
-
}
|
|
3174
|
-
});
|
|
3175
|
-
}
|
|
3176
|
-
__name(beforeDeadline, "beforeDeadline");
|
|
3177
|
-
async function readEmailRequestJson(request, maxBytes = 2 * 1024) {
|
|
3178
|
-
const declaredLength = request.headers.get("content-length");
|
|
3179
|
-
if (request.headers.has("content-encoding") || !request.body || declaredLength !== null && (!/^\d+$/.test(declaredLength) || Number(declaredLength) > maxBytes)) {
|
|
3180
|
-
void request.body?.cancel().catch(() => {
|
|
3181
|
-
});
|
|
3182
|
-
throw new Error("invalid email request body");
|
|
3183
|
-
}
|
|
3184
|
-
const expectedLength = declaredLength === null ? null : Number(declaredLength);
|
|
3185
|
-
const reader = request.body.getReader();
|
|
3186
|
-
let bytes = new Uint8Array(Math.min(1024, maxBytes));
|
|
3187
|
-
const deadline = Date.now() + EMAIL_REQUEST_DEADLINE_MS;
|
|
3188
|
-
let size = 0;
|
|
3189
|
-
try {
|
|
3190
|
-
for (; ; ) {
|
|
3191
|
-
const chunk = await beforeDeadline(deadline, () => reader.read());
|
|
3192
|
-
if (chunk.done) {
|
|
3193
|
-
break;
|
|
3194
|
-
}
|
|
3195
|
-
const nextSize = size + chunk.value.byteLength;
|
|
3196
|
-
if (nextSize > maxBytes) {
|
|
3197
|
-
throw new Error("email request body too large");
|
|
3198
|
-
}
|
|
3199
|
-
if (nextSize > bytes.byteLength) {
|
|
3200
|
-
const grown = new Uint8Array(Math.min(maxBytes, Math.max(nextSize, bytes.byteLength * 2)));
|
|
3201
|
-
grown.set(bytes.subarray(0, size));
|
|
3202
|
-
bytes = grown;
|
|
3203
|
-
}
|
|
3204
|
-
bytes.set(chunk.value, size);
|
|
3205
|
-
size = nextSize;
|
|
3206
|
-
}
|
|
3207
|
-
} finally {
|
|
3208
|
-
void reader.cancel().catch(() => {
|
|
3209
|
-
});
|
|
3210
|
-
reader.releaseLock();
|
|
3211
|
-
}
|
|
3212
|
-
if (size === 0 || expectedLength !== null && size !== expectedLength) {
|
|
3213
|
-
throw new Error("invalid email request body length");
|
|
3214
|
-
}
|
|
3215
|
-
return JSON.parse(decoder2.decode(bytes.subarray(0, size)));
|
|
3216
|
-
}
|
|
3217
|
-
__name(readEmailRequestJson, "readEmailRequestJson");
|
|
3218
|
-
|
|
3219
3156
|
// ../../home/runner/work/void/void/platform/packages/proxy/src/email.ts
|
|
3220
3157
|
import { EmailMessage } from "cloudflare:email";
|
|
3221
3158
|
|
|
3222
3159
|
// ../../home/runner/work/void/void/platform/packages/proxy/src/email-admission.ts
|
|
3223
3160
|
var encoder4 = new TextEncoder();
|
|
3224
|
-
var
|
|
3161
|
+
var decoder2 = new TextDecoder();
|
|
3225
3162
|
var EMAIL_DEFAULT_DEADLINE_MS = 5e3;
|
|
3226
3163
|
var EMAIL_ACTION_DEADLINE_MS = 15e3;
|
|
3227
3164
|
var EMAIL_ADMISSION_DEADLINE_MS = 15e3;
|
|
@@ -3307,7 +3244,7 @@ async function call(env, path, body, deadlineMs = EMAIL_DEFAULT_DEADLINE_MS) {
|
|
|
3307
3244
|
bytes.set(chunk.value, size);
|
|
3308
3245
|
size += chunk.value.byteLength;
|
|
3309
3246
|
}
|
|
3310
|
-
return JSON.parse(
|
|
3247
|
+
return JSON.parse(decoder2.decode(bytes.subarray(0, size)));
|
|
3311
3248
|
} finally {
|
|
3312
3249
|
void reader.cancel().catch(() => {
|
|
3313
3250
|
});
|
|
@@ -3353,7 +3290,7 @@ function canonicalizeVoidMime(raw2) {
|
|
|
3353
3290
|
} else if (topHeaders && (asciiPrefixEquals(raw2, lineStart, lineEnd, "Date: ") || asciiPrefixEquals(raw2, lineStart, lineEnd, "Message-ID: "))) {
|
|
3354
3291
|
replace(lineStart, nextLine, new Uint8Array());
|
|
3355
3292
|
} else if (isMultipartContentType(raw2, lineStart, lineEnd)) {
|
|
3356
|
-
const line =
|
|
3293
|
+
const line = decoder2.decode(raw2.subarray(lineStart, lineEnd));
|
|
3357
3294
|
const normalized2 = line.replace(
|
|
3358
3295
|
/boundary="(=_void_(?:mixed|alternative|related)_[A-Za-z0-9_-]+)"/g,
|
|
3359
3296
|
(_, token) => {
|
|
@@ -3371,13 +3308,13 @@ function canonicalizeVoidMime(raw2) {
|
|
|
3371
3308
|
}
|
|
3372
3309
|
} else if (raw2[lineStart] === 45 && raw2[lineStart + 1] === 45) {
|
|
3373
3310
|
const tokenStart = lineStart + 2;
|
|
3374
|
-
const token = isBoundaryToken(raw2, tokenStart, lineEnd) ?
|
|
3311
|
+
const token = isBoundaryToken(raw2, tokenStart, lineEnd) ? decoder2.decode(raw2.subarray(tokenStart, lineEnd)) : void 0;
|
|
3375
3312
|
const openingMarker = token === void 0 ? void 0 : boundaries.get(token);
|
|
3376
3313
|
if (openingMarker !== void 0) {
|
|
3377
3314
|
replace(lineStart, lineEnd, encoder4.encode(`--${openingMarker}`));
|
|
3378
3315
|
inHeaders = true;
|
|
3379
3316
|
} else if (lineEnd - tokenStart >= 2 && raw2[lineEnd - 2] === 45 && raw2[lineEnd - 1] === 45 && isBoundaryToken(raw2, tokenStart, lineEnd - 2)) {
|
|
3380
|
-
const closingToken =
|
|
3317
|
+
const closingToken = decoder2.decode(raw2.subarray(tokenStart, lineEnd - 2));
|
|
3381
3318
|
const closingMarker = boundaries.get(closingToken);
|
|
3382
3319
|
if (closingMarker !== void 0) {
|
|
3383
3320
|
replace(lineStart, lineEnd, encoder4.encode(`--${closingMarker}--`));
|
|
@@ -5380,6 +5317,104 @@ r2.post("/head", async (context) => {
|
|
|
5380
5317
|
});
|
|
5381
5318
|
});
|
|
5382
5319
|
|
|
5320
|
+
// ../../home/runner/work/void/void/platform/packages/proxy/src/request-body.ts
|
|
5321
|
+
var REQUEST_BODY_DEADLINE_MS = 5e3;
|
|
5322
|
+
var decoder3 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: false });
|
|
5323
|
+
var DEFAULT_JSON_BODY_MAX_BYTES = 1024 * 1024;
|
|
5324
|
+
var LARGE_JSON_BODY_MAX_BYTES = 8 * 1024 * 1024;
|
|
5325
|
+
var RequestBodyError = class extends Error {
|
|
5326
|
+
constructor(message, status) {
|
|
5327
|
+
super(message);
|
|
5328
|
+
this.status = status;
|
|
5329
|
+
this.name = "RequestBodyError";
|
|
5330
|
+
}
|
|
5331
|
+
status;
|
|
5332
|
+
static {
|
|
5333
|
+
__name(this, "RequestBodyError");
|
|
5334
|
+
}
|
|
5335
|
+
};
|
|
5336
|
+
function requestBodyMaxBytes(path) {
|
|
5337
|
+
switch (path) {
|
|
5338
|
+
case "/ai/run":
|
|
5339
|
+
case "/ai/provider":
|
|
5340
|
+
case "/ai/toMarkdown":
|
|
5341
|
+
case "/kv/put":
|
|
5342
|
+
case "/r2/put":
|
|
5343
|
+
case "/r2/put-conditional":
|
|
5344
|
+
return LARGE_JSON_BODY_MAX_BYTES;
|
|
5345
|
+
default:
|
|
5346
|
+
return DEFAULT_JSON_BODY_MAX_BYTES;
|
|
5347
|
+
}
|
|
5348
|
+
}
|
|
5349
|
+
__name(requestBodyMaxBytes, "requestBodyMaxBytes");
|
|
5350
|
+
async function beforeDeadline(deadline, run) {
|
|
5351
|
+
const remaining = deadline - Date.now();
|
|
5352
|
+
if (remaining <= 0) {
|
|
5353
|
+
throw new RequestBodyError("request body timeout", 408);
|
|
5354
|
+
}
|
|
5355
|
+
let timer;
|
|
5356
|
+
return Promise.race([
|
|
5357
|
+
run(),
|
|
5358
|
+
new Promise((_, reject) => {
|
|
5359
|
+
timer = setTimeout(
|
|
5360
|
+
() => reject(new RequestBodyError("request body timeout", 408)),
|
|
5361
|
+
remaining
|
|
5362
|
+
);
|
|
5363
|
+
})
|
|
5364
|
+
]).finally(() => {
|
|
5365
|
+
if (timer !== void 0) {
|
|
5366
|
+
clearTimeout(timer);
|
|
5367
|
+
}
|
|
5368
|
+
});
|
|
5369
|
+
}
|
|
5370
|
+
__name(beforeDeadline, "beforeDeadline");
|
|
5371
|
+
async function readRequestJson(request, maxBytes) {
|
|
5372
|
+
const declaredLength = request.headers.get("content-length");
|
|
5373
|
+
if (declaredLength !== null && /^\d+$/.test(declaredLength) && Number(declaredLength) > maxBytes) {
|
|
5374
|
+
void request.body?.cancel().catch(() => {
|
|
5375
|
+
});
|
|
5376
|
+
throw new RequestBodyError("request body too large", 413);
|
|
5377
|
+
}
|
|
5378
|
+
if (request.headers.has("content-encoding") || !request.body || declaredLength !== null && !/^\d+$/.test(declaredLength)) {
|
|
5379
|
+
void request.body?.cancel().catch(() => {
|
|
5380
|
+
});
|
|
5381
|
+
throw new RequestBodyError("invalid request body", 400);
|
|
5382
|
+
}
|
|
5383
|
+
const expectedLength = declaredLength === null ? null : Number(declaredLength);
|
|
5384
|
+
const reader = request.body.getReader();
|
|
5385
|
+
let bytes = new Uint8Array(Math.min(1024, maxBytes));
|
|
5386
|
+
const deadline = Date.now() + REQUEST_BODY_DEADLINE_MS;
|
|
5387
|
+
let size = 0;
|
|
5388
|
+
try {
|
|
5389
|
+
for (; ; ) {
|
|
5390
|
+
const chunk = await beforeDeadline(deadline, () => reader.read());
|
|
5391
|
+
if (chunk.done) {
|
|
5392
|
+
break;
|
|
5393
|
+
}
|
|
5394
|
+
const nextSize = size + chunk.value.byteLength;
|
|
5395
|
+
if (nextSize > maxBytes) {
|
|
5396
|
+
throw new RequestBodyError("request body too large", 413);
|
|
5397
|
+
}
|
|
5398
|
+
if (nextSize > bytes.byteLength) {
|
|
5399
|
+
const grown = new Uint8Array(Math.min(maxBytes, Math.max(nextSize, bytes.byteLength * 2)));
|
|
5400
|
+
grown.set(bytes.subarray(0, size));
|
|
5401
|
+
bytes = grown;
|
|
5402
|
+
}
|
|
5403
|
+
bytes.set(chunk.value, size);
|
|
5404
|
+
size = nextSize;
|
|
5405
|
+
}
|
|
5406
|
+
} finally {
|
|
5407
|
+
void reader.cancel().catch(() => {
|
|
5408
|
+
});
|
|
5409
|
+
reader.releaseLock();
|
|
5410
|
+
}
|
|
5411
|
+
if (size === 0 || expectedLength !== null && size !== expectedLength) {
|
|
5412
|
+
throw new RequestBodyError("invalid request body length", 400);
|
|
5413
|
+
}
|
|
5414
|
+
return JSON.parse(decoder3.decode(bytes.subarray(0, size)));
|
|
5415
|
+
}
|
|
5416
|
+
__name(readRequestJson, "readRequestJson");
|
|
5417
|
+
|
|
5383
5418
|
// ../../home/runner/work/void/void/platform/packages/proxy/src/revalidate.ts
|
|
5384
5419
|
var app2 = new Hono2();
|
|
5385
5420
|
app2.post("/", async (context) => {
|
|
@@ -5461,7 +5496,7 @@ __name(hmacSign4, "hmacSign");
|
|
|
5461
5496
|
app3.post("/email/verify-receipt", async (context) => {
|
|
5462
5497
|
let body;
|
|
5463
5498
|
try {
|
|
5464
|
-
body = await
|
|
5499
|
+
body = await readRequestJson(context.req.raw, 2 * 1024);
|
|
5465
5500
|
} catch {
|
|
5466
5501
|
return context.json({ valid: false }, 400);
|
|
5467
5502
|
}
|
|
@@ -5491,12 +5526,16 @@ app3.post("/*", async (context, next) => {
|
|
|
5491
5526
|
const path = new URL(context.req.url).pathname;
|
|
5492
5527
|
let body;
|
|
5493
5528
|
try {
|
|
5494
|
-
const
|
|
5529
|
+
const maxBytes = path === "/email" || path.startsWith("/email/") ? 8 * 1024 * 1024 : requestBodyMaxBytes(path);
|
|
5530
|
+
const json = await readRequestJson(context.req.raw, maxBytes);
|
|
5495
5531
|
if (!isProxyBody(json)) {
|
|
5496
5532
|
return context.json({ error: "invalid JSON body" }, 400);
|
|
5497
5533
|
}
|
|
5498
5534
|
body = json;
|
|
5499
|
-
} catch {
|
|
5535
|
+
} catch (error) {
|
|
5536
|
+
if (path !== "/email" && !path.startsWith("/email/") && error instanceof RequestBodyError) {
|
|
5537
|
+
return context.json({ error: error.message }, error.status);
|
|
5538
|
+
}
|
|
5500
5539
|
return context.json({ error: "invalid JSON body" }, 400);
|
|
5501
5540
|
}
|
|
5502
5541
|
context.set("body", body);
|