theokit 0.67.0 → 0.69.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/README.md +21 -0
- package/dist/{actions-virtual-module-YIWQTI6Q.js → actions-virtual-module-DH3N34I6.js} +6 -6
- package/dist/{actions-virtual-module-WCHXKH6R.js → actions-virtual-module-OMIFGXK6.js} +4 -4
- package/dist/adapters/agent-mount.d.ts +190 -2
- package/dist/adapters/agent-mount.js +18 -3
- package/dist/adapters/security-headers.d.ts +17 -1
- package/dist/adapters/security-headers.js +7 -0
- package/dist/adapters/security-headers.js.map +1 -1
- package/dist/{agent-C7F5O5V4.js → agent-7RPGAKTY.js} +3 -3
- package/dist/{app-typed-client-2ZEGNFJP.js → app-typed-client-C4LRUSIS.js} +6 -6
- package/dist/{app-typed-client-CUM2GZ5Y.js → app-typed-client-R6OUJZEE.js} +4 -4
- package/dist/assets-map-BMQASQHW.js +70 -0
- package/dist/assets-map-BMQASQHW.js.map +1 -0
- package/dist/assets-map-CV2YZ3MY.js +69 -0
- package/dist/assets-map-CV2YZ3MY.js.map +1 -0
- package/dist/{aws-lambda-R76PWR27.js → aws-lambda-OCJM5YGB.js} +35 -23
- package/dist/aws-lambda-OCJM5YGB.js.map +1 -0
- package/dist/{build-UNBI6VKC.js → build-CGFKWZ73.js} +13 -8
- package/dist/build-CGFKWZ73.js.map +1 -0
- package/dist/{bun-NPBIAWSU.js → bun-KRUAWYRW.js} +51 -39
- package/dist/bun-KRUAWYRW.js.map +1 -0
- package/dist/{chunk-GQNBZDYK.js → chunk-2FHNJ7LI.js} +1 -1
- package/dist/{chunk-GQNBZDYK.js.map → chunk-2FHNJ7LI.js.map} +1 -1
- package/dist/chunk-3T5XLDOH.js +807 -0
- package/dist/chunk-3T5XLDOH.js.map +1 -0
- package/dist/{chunk-WAYUHS54.js → chunk-425FJKKO.js} +5 -3
- package/dist/chunk-425FJKKO.js.map +1 -0
- package/dist/chunk-46FM5AFZ.js +44 -0
- package/dist/chunk-46FM5AFZ.js.map +1 -0
- package/dist/{chunk-ASBXR57P.js → chunk-4WB62S22.js} +7 -4
- package/dist/{chunk-ASBXR57P.js.map → chunk-4WB62S22.js.map} +1 -1
- package/dist/chunk-BDPD5HEO.js +554 -0
- package/dist/chunk-BDPD5HEO.js.map +1 -0
- package/dist/{chunk-UETVDZBE.js → chunk-BINRCILF.js} +4 -1
- package/dist/{chunk-UETVDZBE.js.map → chunk-BINRCILF.js.map} +1 -1
- package/dist/{chunk-EQCSUC65.js → chunk-BTDTHXUI.js} +2 -2
- package/dist/chunk-FFGP2LGQ.js +465 -0
- package/dist/chunk-FFGP2LGQ.js.map +1 -0
- package/dist/{chunk-PRZCPSUE.js → chunk-I2H6KRCQ.js} +29 -14
- package/dist/chunk-I2H6KRCQ.js.map +1 -0
- package/dist/{chunk-ENRT6DAU.js → chunk-IDWN2OSG.js} +15 -2
- package/dist/chunk-IDWN2OSG.js.map +1 -0
- package/dist/{chunk-GAJOZJWD.js → chunk-MOGTMGGA.js} +5 -2
- package/dist/chunk-MOGTMGGA.js.map +1 -0
- package/dist/{chunk-5VLP3GQ2.js → chunk-MS4A7N77.js} +1 -1
- package/dist/chunk-MS4A7N77.js.map +1 -0
- package/dist/{chunk-YNK7DW5V.js → chunk-QVXMAHZC.js} +55 -551
- package/dist/chunk-QVXMAHZC.js.map +1 -0
- package/dist/{chunk-B4Z7KIIU.js → chunk-SJ4AW54X.js} +45 -4
- package/dist/chunk-SJ4AW54X.js.map +1 -0
- package/dist/{chunk-5AGNZXHJ.js → chunk-SRJBH5E5.js} +16 -679
- package/dist/chunk-SRJBH5E5.js.map +1 -0
- package/dist/{chunk-GQIATJEG.js → chunk-T2LDLVVV.js} +28 -3
- package/dist/chunk-T2LDLVVV.js.map +1 -0
- package/dist/{chunk-UKMOQWUC.js → chunk-TJPENLGQ.js} +3 -3
- package/dist/chunk-V5SSTT3C.js +52 -0
- package/dist/chunk-V5SSTT3C.js.map +1 -0
- package/dist/chunk-XG6SQUEP.js +27 -0
- package/dist/chunk-XG6SQUEP.js.map +1 -0
- package/dist/cli/index.js +6 -6
- package/dist/client/index.d.ts +20 -0
- package/dist/client/index.js.map +1 -1
- package/dist/{cloudflare-2WVDBHCC.js → cloudflare-GK4VD3EU.js} +71 -21
- package/dist/cloudflare-GK4VD3EU.js.map +1 -0
- package/dist/{route-config-B7FaTSby.d.ts → define-middleware-BOHpPOBs.d.ts} +39 -1
- package/dist/{deno-deploy-BXOQ45LD.js → deno-deploy-WMNXRVGL.js} +37 -36
- package/dist/deno-deploy-WMNXRVGL.js.map +1 -0
- package/dist/{dev-GLUZNBNH.js → dev-72ISY3BP.js} +7 -7
- package/dist/{index-BdIaxp0c.d.ts → index-DZ_G5iY2.d.ts} +76 -5
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/{internal-api-3JIWUI3V.js → internal-api-CEZSXGRB.js} +4 -4
- package/dist/{internal-api-OK7FS2ZF.js → internal-api-XRIBUACB.js} +8 -7
- package/dist/match-DaKsL73w.d.ts +28 -0
- package/dist/{mcp-IPDFRK4S.js → mcp-S2AOB3RE.js} +3 -3
- package/dist/{match-Dw4CNXJH.d.ts → module-loader-DCip7NoL.d.ts} +1 -28
- package/dist/{netlify-LPJAPMQ2.js → netlify-VOL54SC7.js} +23 -20
- package/dist/netlify-VOL54SC7.js.map +1 -0
- package/dist/{observability-bootstrap-H4NSILXD.js → observability-bootstrap-YQKMEYW7.js} +2 -2
- package/dist/{preview-5ONGHDKY.js → preview-WA4HORUQ.js} +3 -3
- package/dist/registry-DDBXDHJ2.js +23 -0
- package/dist/server/cost/index.d.ts +14 -1
- package/dist/server/cost/index.js +1 -1
- package/dist/server/define/index.d.ts +2 -28
- package/dist/server/define/index.js +2 -3
- package/dist/server/http/index.d.ts +4 -3
- package/dist/server/http/index.js +13 -8
- package/dist/server/index.d.ts +6 -4
- package/dist/server/index.js +15 -10
- package/dist/server/index.js.map +1 -1
- package/dist/server/scan/index.d.ts +3 -2
- package/dist/{server-boundary-6PYWFYEL.js → server-boundary-S3G4CSNK.js} +4 -4
- package/dist/{server-boundary-CNYNVFT5.js → server-boundary-YN5HAICY.js} +6 -6
- package/dist/{start-UYBVPTSV.js → start-ZTMQLNJI.js} +39 -15
- package/dist/start-ZTMQLNJI.js.map +1 -0
- package/dist/{static-SVDWIOXJ.js → static-7OJNB7D2.js} +4 -4
- package/dist/{vercel-YUZADKGV.js → vercel-LZTDSDJF.js} +42 -28
- package/dist/vercel-LZTDSDJF.js.map +1 -0
- package/dist/vite-plugin/index.js +7 -6
- package/dist/{vite-plugin-ILWLTOKK.js → vite-plugin-Z7AJG3M2.js} +7 -7
- package/package.json +4 -4
- package/dist/aws-lambda-R76PWR27.js.map +0 -1
- package/dist/build-UNBI6VKC.js.map +0 -1
- package/dist/bun-NPBIAWSU.js.map +0 -1
- package/dist/chunk-5AGNZXHJ.js.map +0 -1
- package/dist/chunk-5VLP3GQ2.js.map +0 -1
- package/dist/chunk-6B3CMPE4.js +0 -192
- package/dist/chunk-6B3CMPE4.js.map +0 -1
- package/dist/chunk-B4Z7KIIU.js.map +0 -1
- package/dist/chunk-D4VP2QPR.js +0 -16
- package/dist/chunk-D4VP2QPR.js.map +0 -1
- package/dist/chunk-ENRT6DAU.js.map +0 -1
- package/dist/chunk-GAJOZJWD.js.map +0 -1
- package/dist/chunk-GQIATJEG.js.map +0 -1
- package/dist/chunk-O55RLSGG.js +0 -127
- package/dist/chunk-O55RLSGG.js.map +0 -1
- package/dist/chunk-PRZCPSUE.js.map +0 -1
- package/dist/chunk-WAYUHS54.js.map +0 -1
- package/dist/chunk-YNK7DW5V.js.map +0 -1
- package/dist/cloudflare-2WVDBHCC.js.map +0 -1
- package/dist/deno-deploy-BXOQ45LD.js.map +0 -1
- package/dist/netlify-LPJAPMQ2.js.map +0 -1
- package/dist/registry-E5XEUKG6.js +0 -23
- package/dist/start-UYBVPTSV.js.map +0 -1
- package/dist/vercel-YUZADKGV.js.map +0 -1
- /package/dist/{actions-virtual-module-YIWQTI6Q.js.map → actions-virtual-module-DH3N34I6.js.map} +0 -0
- /package/dist/{actions-virtual-module-WCHXKH6R.js.map → actions-virtual-module-OMIFGXK6.js.map} +0 -0
- /package/dist/{agent-C7F5O5V4.js.map → agent-7RPGAKTY.js.map} +0 -0
- /package/dist/{app-typed-client-2ZEGNFJP.js.map → app-typed-client-C4LRUSIS.js.map} +0 -0
- /package/dist/{app-typed-client-CUM2GZ5Y.js.map → app-typed-client-R6OUJZEE.js.map} +0 -0
- /package/dist/{chunk-EQCSUC65.js.map → chunk-BTDTHXUI.js.map} +0 -0
- /package/dist/{chunk-UKMOQWUC.js.map → chunk-TJPENLGQ.js.map} +0 -0
- /package/dist/{dev-GLUZNBNH.js.map → dev-72ISY3BP.js.map} +0 -0
- /package/dist/{internal-api-3JIWUI3V.js.map → internal-api-CEZSXGRB.js.map} +0 -0
- /package/dist/{internal-api-OK7FS2ZF.js.map → internal-api-XRIBUACB.js.map} +0 -0
- /package/dist/{mcp-IPDFRK4S.js.map → mcp-S2AOB3RE.js.map} +0 -0
- /package/dist/{observability-bootstrap-H4NSILXD.js.map → observability-bootstrap-YQKMEYW7.js.map} +0 -0
- /package/dist/{preview-5ONGHDKY.js.map → preview-WA4HORUQ.js.map} +0 -0
- /package/dist/{registry-E5XEUKG6.js.map → registry-DDBXDHJ2.js.map} +0 -0
- /package/dist/{server-boundary-6PYWFYEL.js.map → server-boundary-S3G4CSNK.js.map} +0 -0
- /package/dist/{server-boundary-CNYNVFT5.js.map → server-boundary-YN5HAICY.js.map} +0 -0
- /package/dist/{static-SVDWIOXJ.js.map → static-7OJNB7D2.js.map} +0 -0
- /package/dist/{vite-plugin-ILWLTOKK.js.map → vite-plugin-Z7AJG3M2.js.map} +0 -0
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
incomingMessageToHandlerRequest,
|
|
3
|
+
isZodLike,
|
|
4
|
+
parseQueryAndBody,
|
|
5
|
+
runMiddlewareAndContext,
|
|
6
|
+
runZodValidation,
|
|
7
|
+
sendError,
|
|
8
|
+
sendJson
|
|
9
|
+
} from "./chunk-3T5XLDOH.js";
|
|
10
|
+
import {
|
|
11
|
+
enforceCsrf
|
|
4
12
|
} from "./chunk-P6OS7652.js";
|
|
5
13
|
import {
|
|
6
14
|
ActionError,
|
|
7
15
|
ActionInputError
|
|
8
16
|
} from "./chunk-ZDUO4IYN.js";
|
|
9
|
-
import {
|
|
10
|
-
WEB_SHAPED_MIDDLEWARE
|
|
11
|
-
} from "./chunk-D4VP2QPR.js";
|
|
12
17
|
import {
|
|
13
18
|
evaluateRoutePolicy,
|
|
14
19
|
subjectFromContext
|
|
15
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-IDWN2OSG.js";
|
|
16
21
|
import {
|
|
17
22
|
DuplicateContextKeyError,
|
|
18
23
|
createOutbox,
|
|
@@ -20,13 +25,9 @@ import {
|
|
|
20
25
|
createQueueClient
|
|
21
26
|
} from "./chunk-47FFT43U.js";
|
|
22
27
|
import {
|
|
23
|
-
RequestBodyConsumedError,
|
|
24
28
|
parseRequestBody,
|
|
25
29
|
warnOnce
|
|
26
30
|
} from "./chunk-ZDCCILMP.js";
|
|
27
|
-
import {
|
|
28
|
-
scanMiddlewares
|
|
29
|
-
} from "./chunk-V6Y2SMRG.js";
|
|
30
31
|
import {
|
|
31
32
|
envelopeCodeToStatus
|
|
32
33
|
} from "./chunk-ACKBVBUI.js";
|
|
@@ -35,659 +36,6 @@ import {
|
|
|
35
36
|
serverErrorToEnvelope
|
|
36
37
|
} from "./chunk-IZ3TIL6K.js";
|
|
37
38
|
|
|
38
|
-
// src/core/contracts/client-safe-error.ts
|
|
39
|
-
var INTERNAL_CODES = /* @__PURE__ */ new Set(["INTERNAL_ERROR", "INTERNAL_SERVER_ERROR"]);
|
|
40
|
-
var GENERIC_INTERNAL_MESSAGE = "Internal server error";
|
|
41
|
-
function redacts(code) {
|
|
42
|
-
return INTERNAL_CODES.has(code) && process.env.NODE_ENV === "production";
|
|
43
|
-
}
|
|
44
|
-
function clientSafeErrorMessage(code, message) {
|
|
45
|
-
return redacts(code) ? GENERIC_INTERNAL_MESSAGE : message;
|
|
46
|
-
}
|
|
47
|
-
function clientSafeErrorEnvelope(envelope) {
|
|
48
|
-
if (!redacts(envelope.code)) return envelope;
|
|
49
|
-
return { code: envelope.code, message: GENERIC_INTERNAL_MESSAGE };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// src/server/http/send-response.ts
|
|
53
|
-
function sendJson(res, data, status = 200, transformer) {
|
|
54
|
-
const body = transformer ? transformer.serialize(data) : JSON.stringify(data);
|
|
55
|
-
res.writeHead(status, {
|
|
56
|
-
"Content-Type": "application/json",
|
|
57
|
-
"Content-Length": Buffer.byteLength(body)
|
|
58
|
-
});
|
|
59
|
-
res.end(body);
|
|
60
|
-
}
|
|
61
|
-
function oneLine(value) {
|
|
62
|
-
return value.replace(/[\r\n]/g, "\\n");
|
|
63
|
-
}
|
|
64
|
-
function sendError(res, codeOrInput, message, status, issues, requestId, options) {
|
|
65
|
-
let code;
|
|
66
|
-
if (typeof codeOrInput === "string") {
|
|
67
|
-
code = codeOrInput;
|
|
68
|
-
message = message ?? "";
|
|
69
|
-
status = status ?? 500;
|
|
70
|
-
} else {
|
|
71
|
-
code = codeOrInput.code;
|
|
72
|
-
message = codeOrInput.message;
|
|
73
|
-
status = codeOrInput.status;
|
|
74
|
-
issues = codeOrInput.issues;
|
|
75
|
-
requestId = codeOrInput.requestId;
|
|
76
|
-
options = codeOrInput.options;
|
|
77
|
-
}
|
|
78
|
-
const errorMessage = clientSafeErrorMessage(code, message);
|
|
79
|
-
if (code === "INTERNAL_ERROR") {
|
|
80
|
-
console.error(`[${oneLine(requestId ?? "no-id")}] ${oneLine(message)}`);
|
|
81
|
-
}
|
|
82
|
-
if (status === 404 && options?.custom404Html) {
|
|
83
|
-
const body = options.custom404Html;
|
|
84
|
-
res.writeHead(404, {
|
|
85
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
86
|
-
"Content-Length": Buffer.byteLength(body)
|
|
87
|
-
});
|
|
88
|
-
res.end(body);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (status === 500 && options?.custom500Html) {
|
|
92
|
-
const body = options.custom500Html;
|
|
93
|
-
res.writeHead(500, {
|
|
94
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
95
|
-
"Content-Length": Buffer.byteLength(body)
|
|
96
|
-
});
|
|
97
|
-
res.end(body);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
sendJson(
|
|
101
|
-
res,
|
|
102
|
-
{
|
|
103
|
-
error: {
|
|
104
|
-
code,
|
|
105
|
-
message: errorMessage,
|
|
106
|
-
...requestId ? { requestId } : {},
|
|
107
|
-
...issues ? { issues } : {}
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
status
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// src/server/http/node-request.ts
|
|
115
|
-
import { Readable } from "node:stream";
|
|
116
|
-
function pickHeaderString(value) {
|
|
117
|
-
if (typeof value === "string") return value;
|
|
118
|
-
if (Array.isArray(value)) {
|
|
119
|
-
for (const v of value) if (typeof v === "string" && v.length > 0) return v;
|
|
120
|
-
}
|
|
121
|
-
return void 0;
|
|
122
|
-
}
|
|
123
|
-
function synthesizeAbsoluteUrl(req) {
|
|
124
|
-
const host = pickHeaderString(req.headers.host) ?? "localhost";
|
|
125
|
-
return `http://${host}${req.url ?? "/"}`;
|
|
126
|
-
}
|
|
127
|
-
function nodeHeadersToWeb(req) {
|
|
128
|
-
const headers = new Headers();
|
|
129
|
-
for (const [key, value] of Object.entries(req.headers)) {
|
|
130
|
-
if (value === void 0) continue;
|
|
131
|
-
if (Array.isArray(value)) {
|
|
132
|
-
headers.set(key, value.join(", "));
|
|
133
|
-
} else {
|
|
134
|
-
headers.set(key, value);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return headers;
|
|
138
|
-
}
|
|
139
|
-
function incomingMessageToWebRequest(req) {
|
|
140
|
-
const url = synthesizeAbsoluteUrl(req);
|
|
141
|
-
const headers = nodeHeadersToWeb(req);
|
|
142
|
-
const method = (req.method ?? "GET").toUpperCase();
|
|
143
|
-
const hasBody = method !== "GET" && method !== "HEAD";
|
|
144
|
-
if (!hasBody) {
|
|
145
|
-
return new Request(url, { method, headers });
|
|
146
|
-
}
|
|
147
|
-
const webStream = Readable.toWeb(req);
|
|
148
|
-
return new Request(url, {
|
|
149
|
-
method,
|
|
150
|
-
headers,
|
|
151
|
-
body: webStream,
|
|
152
|
-
// EC-2: Node 18+ requires `duplex: 'half'` when body is a stream.
|
|
153
|
-
// The `RequestInit` type omits it (Web spec gap); cast accordingly.
|
|
154
|
-
...{ duplex: "half" }
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
function createWebRequestSource(req) {
|
|
158
|
-
let converted;
|
|
159
|
-
return {
|
|
160
|
-
method: (req.method ?? "GET").toUpperCase(),
|
|
161
|
-
toRequest: () => converted ??= incomingMessageToWebRequest(req)
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
function incomingMessageToHandlerRequest(req) {
|
|
165
|
-
return new Request(synthesizeAbsoluteUrl(req), {
|
|
166
|
-
method: (req.method ?? "GET").toUpperCase(),
|
|
167
|
-
headers: nodeHeadersToWeb(req)
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// src/server/http/validate-route-input.ts
|
|
172
|
-
function validateRouteInput(config, raw) {
|
|
173
|
-
let query = raw.query;
|
|
174
|
-
if (config.query !== void 0) {
|
|
175
|
-
const parsed = config.query.safeParse(raw.query);
|
|
176
|
-
if (!parsed.success) return { ok: false, channel: "query", error: parsed.error };
|
|
177
|
-
query = parsed.data;
|
|
178
|
-
}
|
|
179
|
-
let body = raw.body;
|
|
180
|
-
if (config.body !== void 0) {
|
|
181
|
-
const parsed = config.body.safeParse(raw.body);
|
|
182
|
-
if (!parsed.success) return { ok: false, channel: "body", error: parsed.error };
|
|
183
|
-
body = parsed.data;
|
|
184
|
-
}
|
|
185
|
-
let params = raw.params;
|
|
186
|
-
if (config.params !== void 0) {
|
|
187
|
-
const parsed = config.params.safeParse(raw.params);
|
|
188
|
-
if (!parsed.success) return { ok: false, channel: "params", error: parsed.error };
|
|
189
|
-
params = parsed.data;
|
|
190
|
-
}
|
|
191
|
-
return { ok: true, query, body, params };
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// src/server/http/execute-stages.ts
|
|
195
|
-
async function parseQueryAndBody(req, res, requestId) {
|
|
196
|
-
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
197
|
-
const query = Object.fromEntries(url.searchParams);
|
|
198
|
-
let body;
|
|
199
|
-
let raw;
|
|
200
|
-
try {
|
|
201
|
-
const parsed = await parseRequestBody(req);
|
|
202
|
-
raw = parsed.raw;
|
|
203
|
-
if (parsed.json !== void 0) {
|
|
204
|
-
body = parsed.json;
|
|
205
|
-
} else if (parsed.files.length > 0 || Object.keys(parsed.fields).length > 0) {
|
|
206
|
-
body = { ...parsed.fields, _files: parsed.files };
|
|
207
|
-
} else {
|
|
208
|
-
body = void 0;
|
|
209
|
-
}
|
|
210
|
-
} catch (err) {
|
|
211
|
-
if (err instanceof RequestBodyConsumedError) {
|
|
212
|
-
sendError(res, "INTERNAL_ERROR", err.message, err.status, void 0, requestId);
|
|
213
|
-
return { ok: false };
|
|
214
|
-
}
|
|
215
|
-
const message = err.message;
|
|
216
|
-
const status = message.includes("Unsupported Content-Type") ? 415 : 400;
|
|
217
|
-
sendError(res, "VALIDATION_ERROR", message, status, void 0, requestId);
|
|
218
|
-
return { ok: false };
|
|
219
|
-
}
|
|
220
|
-
return { ok: true, data: { query, body, raw } };
|
|
221
|
-
}
|
|
222
|
-
var isZodLike = (value) => typeof value === "object" && value !== null && typeof value.safeParse === "function";
|
|
223
|
-
function runZodValidation(routeConfig, res, requestId, input) {
|
|
224
|
-
const { query, params } = input;
|
|
225
|
-
let { body } = input;
|
|
226
|
-
if (isZodLike(routeConfig.query)) {
|
|
227
|
-
const result = routeConfig.query.safeParse(query);
|
|
228
|
-
if (!result.success) {
|
|
229
|
-
sendError(
|
|
230
|
-
res,
|
|
231
|
-
"VALIDATION_ERROR",
|
|
232
|
-
"Invalid query parameters",
|
|
233
|
-
400,
|
|
234
|
-
result.error?.issues,
|
|
235
|
-
requestId
|
|
236
|
-
);
|
|
237
|
-
return { ok: false };
|
|
238
|
-
}
|
|
239
|
-
Object.assign(query, result.data);
|
|
240
|
-
}
|
|
241
|
-
if (isZodLike(routeConfig.body)) {
|
|
242
|
-
const result = routeConfig.body.safeParse(body);
|
|
243
|
-
if (!result.success) {
|
|
244
|
-
sendError(
|
|
245
|
-
res,
|
|
246
|
-
"VALIDATION_ERROR",
|
|
247
|
-
"Invalid request body",
|
|
248
|
-
400,
|
|
249
|
-
result.error?.issues,
|
|
250
|
-
requestId
|
|
251
|
-
);
|
|
252
|
-
return { ok: false };
|
|
253
|
-
}
|
|
254
|
-
body = result.data;
|
|
255
|
-
}
|
|
256
|
-
if (isZodLike(routeConfig.params)) {
|
|
257
|
-
const result = routeConfig.params.safeParse(params);
|
|
258
|
-
if (!result.success) {
|
|
259
|
-
sendError(
|
|
260
|
-
res,
|
|
261
|
-
"VALIDATION_ERROR",
|
|
262
|
-
"Invalid route parameters",
|
|
263
|
-
400,
|
|
264
|
-
result.error?.issues,
|
|
265
|
-
requestId
|
|
266
|
-
);
|
|
267
|
-
return { ok: false };
|
|
268
|
-
}
|
|
269
|
-
Object.assign(params, result.data);
|
|
270
|
-
}
|
|
271
|
-
return { ok: true, data: { query, body, params } };
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// src/server/http/web-middleware-runner.ts
|
|
275
|
-
async function runWebMiddleware(request, middleware, context) {
|
|
276
|
-
for (const mw of middleware) {
|
|
277
|
-
const result = await mw(request, context);
|
|
278
|
-
if (result instanceof Response) return result;
|
|
279
|
-
}
|
|
280
|
-
return void 0;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// src/server/web-handler.ts
|
|
284
|
-
function searchParamsToObject(params) {
|
|
285
|
-
const out = {};
|
|
286
|
-
for (const [key, value] of params.entries()) {
|
|
287
|
-
if (!Object.hasOwn(out, key)) {
|
|
288
|
-
out[key] = value;
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
const existing = out[key];
|
|
292
|
-
if (Array.isArray(existing)) {
|
|
293
|
-
existing.push(value);
|
|
294
|
-
} else {
|
|
295
|
-
out[key] = [existing, value];
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return out;
|
|
299
|
-
}
|
|
300
|
-
async function parseBodyInline(request) {
|
|
301
|
-
if (request.method === "GET" || request.method === "HEAD") return void 0;
|
|
302
|
-
const contentType = request.headers.get("content-type") ?? "";
|
|
303
|
-
if (contentType.includes("application/json")) {
|
|
304
|
-
const text = await request.text();
|
|
305
|
-
if (text.length === 0) return void 0;
|
|
306
|
-
try {
|
|
307
|
-
return JSON.parse(text);
|
|
308
|
-
} catch {
|
|
309
|
-
return void 0;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
if (contentType.startsWith("text/")) {
|
|
313
|
-
const text = await request.text();
|
|
314
|
-
return text.length === 0 ? void 0 : text;
|
|
315
|
-
}
|
|
316
|
-
return void 0;
|
|
317
|
-
}
|
|
318
|
-
async function parseBodyFull(request) {
|
|
319
|
-
if (request.method === "GET" || request.method === "HEAD") return void 0;
|
|
320
|
-
const { parseWebRequestBody } = await import("./body-parser-web-ON5CUTEL.js");
|
|
321
|
-
try {
|
|
322
|
-
const parsed = await parseWebRequestBody(request);
|
|
323
|
-
if (parsed.json === void 0 && Object.keys(parsed.fields).length === 0 && parsed.files.length === 0) {
|
|
324
|
-
return void 0;
|
|
325
|
-
}
|
|
326
|
-
return parsed;
|
|
327
|
-
} catch {
|
|
328
|
-
return void 0;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
function validationErrorResponse(zodError, field) {
|
|
332
|
-
const envelope = {
|
|
333
|
-
code: "BAD_REQUEST",
|
|
334
|
-
message: `Validation failed: ${field}`,
|
|
335
|
-
ext: {
|
|
336
|
-
fields: zodError.issues.map((issue) => ({
|
|
337
|
-
path: issue.path.join("."),
|
|
338
|
-
message: issue.message
|
|
339
|
-
}))
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
return new Response(JSON.stringify(envelope), {
|
|
343
|
-
status: 400,
|
|
344
|
-
headers: { "content-type": "application/json" }
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
async function runHandler(config, request, bodyParser = "inline", paramsInput = {}, context = {}) {
|
|
348
|
-
const url = new URL(request.url);
|
|
349
|
-
const queryRaw = searchParamsToObject(url.searchParams);
|
|
350
|
-
const bodyRaw = bodyParser === "full" ? await parseBodyFull(request) : await parseBodyInline(request);
|
|
351
|
-
const paramsRaw = paramsInput;
|
|
352
|
-
const validated = validateRouteInput(config, {
|
|
353
|
-
query: queryRaw,
|
|
354
|
-
body: bodyRaw,
|
|
355
|
-
params: paramsRaw
|
|
356
|
-
});
|
|
357
|
-
if (!validated.ok) {
|
|
358
|
-
return { ok: false, response: validationErrorResponse(validated.error, validated.channel) };
|
|
359
|
-
}
|
|
360
|
-
const { query, body, params } = validated;
|
|
361
|
-
const decision = await evaluateRoutePolicy(config.policy, {
|
|
362
|
-
subject: subjectFromContext(context),
|
|
363
|
-
query,
|
|
364
|
-
body,
|
|
365
|
-
params
|
|
366
|
-
});
|
|
367
|
-
if (!decision.allowed) {
|
|
368
|
-
return { ok: false, response: accessDeniedResponse(decision.reason) };
|
|
369
|
-
}
|
|
370
|
-
const result = await config.handler({ query, body, params, request, context });
|
|
371
|
-
return validateResponseOutput(config.response, result) ?? { ok: true, result };
|
|
372
|
-
}
|
|
373
|
-
function validateResponseOutput(response, result) {
|
|
374
|
-
const validatable = result !== void 0 && result !== null && !(result instanceof Response);
|
|
375
|
-
if (!validatable || !isZodLike(response)) return void 0;
|
|
376
|
-
const parsed = response.safeParse(result);
|
|
377
|
-
if (parsed.success) return { ok: true, result: parsed.data };
|
|
378
|
-
const err = new TheoError({
|
|
379
|
-
code: "INTERNAL_SERVER_ERROR",
|
|
380
|
-
message: "response validation failed",
|
|
381
|
-
ext: { issues: parsed.error?.issues }
|
|
382
|
-
});
|
|
383
|
-
return { ok: false, response: handlerErrorResponse(err) };
|
|
384
|
-
}
|
|
385
|
-
function toResponse(result, status) {
|
|
386
|
-
if (result === void 0) {
|
|
387
|
-
return new Response(null, { status: 204 });
|
|
388
|
-
}
|
|
389
|
-
if (result instanceof Response) {
|
|
390
|
-
return result;
|
|
391
|
-
}
|
|
392
|
-
return new Response(JSON.stringify(result), {
|
|
393
|
-
status: status ?? 200,
|
|
394
|
-
headers: { "content-type": "application/json" }
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
function handlerErrorResponse(err) {
|
|
398
|
-
const envelope = clientSafeErrorEnvelope(serverErrorToEnvelope(err));
|
|
399
|
-
const status = envelopeCodeToStatus(envelope.code);
|
|
400
|
-
return new Response(JSON.stringify(envelope), {
|
|
401
|
-
status,
|
|
402
|
-
headers: { "content-type": "application/json" }
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
var CSRF_PROTECTED_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
406
|
-
function mergeHookHeaders(response, hookHeaders) {
|
|
407
|
-
if ([...hookHeaders].length === 0) return response;
|
|
408
|
-
const merged = new Headers(response.headers);
|
|
409
|
-
for (const [k, v] of hookHeaders.entries()) {
|
|
410
|
-
if (k.toLowerCase() === "set-cookie") continue;
|
|
411
|
-
if (!merged.has(k)) merged.set(k, v);
|
|
412
|
-
}
|
|
413
|
-
for (const sc of hookHeaders.getSetCookie()) {
|
|
414
|
-
merged.append("Set-Cookie", sc);
|
|
415
|
-
}
|
|
416
|
-
return new Response(response.body, {
|
|
417
|
-
status: response.status,
|
|
418
|
-
statusText: response.statusText,
|
|
419
|
-
headers: merged
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
function methodNotAllowedResponse(method) {
|
|
423
|
-
const envelope = {
|
|
424
|
-
code: "METHOD_NOT_ALLOWED",
|
|
425
|
-
message: `Method ${method} not allowed`
|
|
426
|
-
};
|
|
427
|
-
return new Response(JSON.stringify(envelope), {
|
|
428
|
-
status: 405,
|
|
429
|
-
headers: { "content-type": "application/json" }
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
function shouldEnforceCsrf(method, config, csrfMode) {
|
|
433
|
-
if ((csrfMode ?? "strict") === "off") return false;
|
|
434
|
-
if (!CSRF_PROTECTED_METHODS.has(method)) return false;
|
|
435
|
-
return config?.csrf !== false;
|
|
436
|
-
}
|
|
437
|
-
function accessDeniedResponse(reason) {
|
|
438
|
-
const envelope = {
|
|
439
|
-
code: "FORBIDDEN",
|
|
440
|
-
message: `Access denied: ${reason}`
|
|
441
|
-
};
|
|
442
|
-
return new Response(JSON.stringify({ error: envelope }), {
|
|
443
|
-
status: 403,
|
|
444
|
-
headers: { "Content-Type": "application/json" }
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
function csrfFailedResponse(reason) {
|
|
448
|
-
const envelope = {
|
|
449
|
-
code: "FORBIDDEN",
|
|
450
|
-
message: `CSRF check failed: ${reason}`
|
|
451
|
-
};
|
|
452
|
-
return new Response(JSON.stringify(envelope), {
|
|
453
|
-
status: 403,
|
|
454
|
-
headers: { "content-type": "application/json" }
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
async function executeWebRequest(request, routeModule, opts = {}) {
|
|
458
|
-
const method = request.method.toUpperCase();
|
|
459
|
-
const config = routeModule[method];
|
|
460
|
-
if (opts.hooks === void 0) {
|
|
461
|
-
if (config === void 0 || typeof config.handler !== "function") {
|
|
462
|
-
return methodNotAllowedResponse(method);
|
|
463
|
-
}
|
|
464
|
-
if (shouldEnforceCsrf(method, config, opts.csrfMode)) {
|
|
465
|
-
const csrfCheck = validateCsrfRequest(request);
|
|
466
|
-
if (!csrfCheck.valid) return csrfFailedResponse(csrfCheck.reason);
|
|
467
|
-
}
|
|
468
|
-
try {
|
|
469
|
-
const context = {};
|
|
470
|
-
if (opts.middleware?.length) {
|
|
471
|
-
const shortCircuit = await runWebMiddleware(request, opts.middleware, context);
|
|
472
|
-
if (shortCircuit) return shortCircuit;
|
|
473
|
-
}
|
|
474
|
-
const outcome = await runHandler(
|
|
475
|
-
config,
|
|
476
|
-
request,
|
|
477
|
-
opts.bodyParser ?? "inline",
|
|
478
|
-
opts.params ?? {},
|
|
479
|
-
context
|
|
480
|
-
);
|
|
481
|
-
if (!outcome.ok) return outcome.response;
|
|
482
|
-
return toResponse(outcome.result, config.status);
|
|
483
|
-
} catch (err) {
|
|
484
|
-
return handlerErrorResponse(err);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return runWithHooks(request, config, opts, opts.hooks);
|
|
488
|
-
}
|
|
489
|
-
async function runPreHandlerPipeline(hookCtx, request, config, opts, hooks) {
|
|
490
|
-
const method = request.method.toUpperCase();
|
|
491
|
-
const runList = async (list) => {
|
|
492
|
-
for (const hook of list) {
|
|
493
|
-
if (hookCtx.response !== void 0) return;
|
|
494
|
-
await hook(hookCtx);
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
|
-
if (hooks.onRequest) await runList(hooks.onRequest);
|
|
498
|
-
if (hookCtx.response === void 0 && shouldEnforceCsrf(method, config, opts.csrfMode)) {
|
|
499
|
-
const csrfCheck = validateCsrfRequest(request);
|
|
500
|
-
if (!csrfCheck.valid) hookCtx.response = csrfFailedResponse(csrfCheck.reason);
|
|
501
|
-
}
|
|
502
|
-
if (hookCtx.response === void 0 && hooks.preHandler) {
|
|
503
|
-
await runList(hooks.preHandler);
|
|
504
|
-
}
|
|
505
|
-
if (hookCtx.response === void 0) {
|
|
506
|
-
await runHandlerStage(hookCtx, request, config, opts, method);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
async function runHandlerStage(hookCtx, request, config, opts, method) {
|
|
510
|
-
if (config === void 0 || typeof config.handler !== "function") {
|
|
511
|
-
hookCtx.response = methodNotAllowedResponse(method);
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
if (opts.middleware?.length) {
|
|
515
|
-
const shortCircuit = await runWebMiddleware(request, opts.middleware, hookCtx.ctx);
|
|
516
|
-
if (shortCircuit) {
|
|
517
|
-
hookCtx.response = shortCircuit;
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
const outcome = await runHandler(
|
|
522
|
-
config,
|
|
523
|
-
request,
|
|
524
|
-
opts.bodyParser ?? "inline",
|
|
525
|
-
opts.params ?? {},
|
|
526
|
-
hookCtx.ctx
|
|
527
|
-
);
|
|
528
|
-
hookCtx.response = outcome.ok ? toResponse(outcome.result, config.status) : outcome.response;
|
|
529
|
-
}
|
|
530
|
-
async function runWithHooks(request, config, opts, hooks) {
|
|
531
|
-
const hookCtx = {
|
|
532
|
-
request,
|
|
533
|
-
responseHeaders: new Headers(),
|
|
534
|
-
ctx: {},
|
|
535
|
-
requestId: opts.requestId ?? globalThis.crypto.randomUUID()
|
|
536
|
-
};
|
|
537
|
-
try {
|
|
538
|
-
await runPreHandlerPipeline(hookCtx, request, config, opts, hooks);
|
|
539
|
-
if (hooks.onResponse) {
|
|
540
|
-
for (const hook of hooks.onResponse) {
|
|
541
|
-
await hook(hookCtx);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
const finalResponse = hookCtx.response ?? new Response(
|
|
545
|
-
JSON.stringify({ code: "INTERNAL_SERVER_ERROR", message: "No response built" }),
|
|
546
|
-
{
|
|
547
|
-
status: 500,
|
|
548
|
-
headers: { "content-type": "application/json" }
|
|
549
|
-
}
|
|
550
|
-
);
|
|
551
|
-
return mergeHookHeaders(finalResponse, hookCtx.responseHeaders);
|
|
552
|
-
} catch (err) {
|
|
553
|
-
return runErrorHooks(err, hookCtx, hooks.onError);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
async function runErrorHooks(err, hookCtx, onError) {
|
|
557
|
-
const errorResponse = handlerErrorResponse(err);
|
|
558
|
-
if (onError !== void 0) {
|
|
559
|
-
const errorCtx = {
|
|
560
|
-
...hookCtx,
|
|
561
|
-
response: errorResponse,
|
|
562
|
-
error: err
|
|
563
|
-
};
|
|
564
|
-
for (const hook of onError) {
|
|
565
|
-
try {
|
|
566
|
-
await hook(errorCtx);
|
|
567
|
-
} catch {
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
return mergeHookHeaders(errorResponse, hookCtx.responseHeaders);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
// src/server/http/middleware-runner.ts
|
|
575
|
-
import { existsSync } from "node:fs";
|
|
576
|
-
import { join } from "node:path";
|
|
577
|
-
|
|
578
|
-
// src/server/http/node-web-adapter.ts
|
|
579
|
-
async function writeWebResponseToServerResponse(response, res) {
|
|
580
|
-
const setCookies = response.headers.getSetCookie();
|
|
581
|
-
if (setCookies.length > 0) {
|
|
582
|
-
res.setHeader("Set-Cookie", setCookies);
|
|
583
|
-
}
|
|
584
|
-
const otherHeaders = {};
|
|
585
|
-
for (const [key, value] of response.headers.entries()) {
|
|
586
|
-
if (key.toLowerCase() === "set-cookie") continue;
|
|
587
|
-
otherHeaders[key] = value;
|
|
588
|
-
}
|
|
589
|
-
res.writeHead(response.status, response.statusText, otherHeaders);
|
|
590
|
-
if (response.body === null) {
|
|
591
|
-
res.end();
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
const reader = response.body.getReader();
|
|
595
|
-
try {
|
|
596
|
-
for (; ; ) {
|
|
597
|
-
const { done, value } = await reader.read();
|
|
598
|
-
if (done) break;
|
|
599
|
-
res.write(value);
|
|
600
|
-
}
|
|
601
|
-
res.end();
|
|
602
|
-
} finally {
|
|
603
|
-
reader.releaseLock();
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// src/server/http/middleware-runner.ts
|
|
608
|
-
var middlewareCache = /* @__PURE__ */ new Map();
|
|
609
|
-
function _resetMiddlewareCacheForTests() {
|
|
610
|
-
middlewareCache.clear();
|
|
611
|
-
}
|
|
612
|
-
function getCachedScan(serverDir) {
|
|
613
|
-
let cached = middlewareCache.get(serverDir);
|
|
614
|
-
if (!cached) {
|
|
615
|
-
const singleFilePath = join(serverDir, "middleware.ts");
|
|
616
|
-
cached = {
|
|
617
|
-
singleFilePath,
|
|
618
|
-
singleFileExists: existsSync(singleFilePath),
|
|
619
|
-
dirMiddlewares: scanMiddlewares(serverDir)
|
|
620
|
-
};
|
|
621
|
-
middlewareCache.set(serverDir, cached);
|
|
622
|
-
}
|
|
623
|
-
return cached;
|
|
624
|
-
}
|
|
625
|
-
async function runWebShapedMiddleware(mw, req, res, context) {
|
|
626
|
-
const request = createWebRequestSource(req).toRequest();
|
|
627
|
-
const result = await mw(request, context);
|
|
628
|
-
if (!(result instanceof Response)) return { shortCircuited: false };
|
|
629
|
-
await writeWebResponseToServerResponse(result, res);
|
|
630
|
-
return { shortCircuited: true };
|
|
631
|
-
}
|
|
632
|
-
function isWebShaped(mw) {
|
|
633
|
-
return WEB_SHAPED_MIDDLEWARE in mw;
|
|
634
|
-
}
|
|
635
|
-
async function runScannedMiddleware(mw, req, res, context) {
|
|
636
|
-
if (isWebShaped(mw)) {
|
|
637
|
-
const { shortCircuited } = await runWebShapedMiddleware(mw, req, res, context);
|
|
638
|
-
return { aborted: shortCircuited };
|
|
639
|
-
}
|
|
640
|
-
const { nextCalled } = await runOneMiddleware(mw, req, res);
|
|
641
|
-
return { aborted: !nextCalled || res.writableEnded };
|
|
642
|
-
}
|
|
643
|
-
async function runOneMiddleware(mw, req, res) {
|
|
644
|
-
const state = { nextCalled: false };
|
|
645
|
-
await mw(req, res, () => {
|
|
646
|
-
state.nextCalled = true;
|
|
647
|
-
});
|
|
648
|
-
return state;
|
|
649
|
-
}
|
|
650
|
-
async function runMiddlewareAndContext(req, res, loadModule, serverDir) {
|
|
651
|
-
const { singleFilePath, singleFileExists, dirMiddlewares } = getCachedScan(serverDir);
|
|
652
|
-
const dirExists = dirMiddlewares.length > 0;
|
|
653
|
-
const middlewareCtx = {};
|
|
654
|
-
if (singleFileExists && dirExists) {
|
|
655
|
-
throw new Error(
|
|
656
|
-
"Ambiguous middleware configuration: found both server/middleware.ts and server/middleware/ directory. Use one or the other, not both."
|
|
657
|
-
);
|
|
658
|
-
}
|
|
659
|
-
if (dirExists) {
|
|
660
|
-
for (const mwPath of dirMiddlewares) {
|
|
661
|
-
const mod = await loadModule(mwPath);
|
|
662
|
-
const mw = mod.default;
|
|
663
|
-
if (typeof mw !== "function") continue;
|
|
664
|
-
const { aborted } = await runScannedMiddleware(mw, req, res, middlewareCtx);
|
|
665
|
-
if (aborted) return { ctx: middlewareCtx, aborted: true };
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
if (singleFileExists) {
|
|
669
|
-
const mod = await loadModule(singleFilePath);
|
|
670
|
-
const mw = mod.default;
|
|
671
|
-
if (typeof mw === "function") {
|
|
672
|
-
const { aborted } = await runScannedMiddleware(mw, req, res, middlewareCtx);
|
|
673
|
-
if (aborted) return { ctx: middlewareCtx, aborted: true };
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
const factoryCtx = await createServerContext(req, res, loadModule, serverDir);
|
|
677
|
-
if (factoryCtx === null || typeof factoryCtx !== "object") {
|
|
678
|
-
return { ctx: middlewareCtx, aborted: false };
|
|
679
|
-
}
|
|
680
|
-
return { ctx: { ...middlewareCtx, ...factoryCtx }, aborted: false };
|
|
681
|
-
}
|
|
682
|
-
async function createServerContext(req, res, loadModule, serverDir) {
|
|
683
|
-
const contextPath = join(serverDir, "context.ts");
|
|
684
|
-
if (!existsSync(contextPath)) return {};
|
|
685
|
-
const mod = await loadModule(contextPath);
|
|
686
|
-
const createContext = mod.createContext;
|
|
687
|
-
if (typeof createContext !== "function") return {};
|
|
688
|
-
return await createContext({ request: req, response: res });
|
|
689
|
-
}
|
|
690
|
-
|
|
691
39
|
// src/core/contracts/auth-error-guard.ts
|
|
692
40
|
function isAuthRequiredError(err) {
|
|
693
41
|
if (err == null || typeof err !== "object") return false;
|
|
@@ -702,7 +50,7 @@ function dispatchCsrfWarn(payload) {
|
|
|
702
50
|
}
|
|
703
51
|
|
|
704
52
|
// src/server/http/execute.ts
|
|
705
|
-
var
|
|
53
|
+
var CSRF_PROTECTED_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
706
54
|
async function waitForDrain(res) {
|
|
707
55
|
if (typeof res.once !== "function") return;
|
|
708
56
|
await new Promise((resolve) => {
|
|
@@ -833,7 +181,7 @@ async function executeRoute(ctx) {
|
|
|
833
181
|
return;
|
|
834
182
|
}
|
|
835
183
|
const routeOptOut = typeof routeConfig === "object" && routeConfig.csrf === false;
|
|
836
|
-
if (
|
|
184
|
+
if (CSRF_PROTECTED_METHODS.has(method) && !routeOptOut) {
|
|
837
185
|
const decision = enforceCsrf(
|
|
838
186
|
req,
|
|
839
187
|
csrfMode,
|
|
@@ -1279,7 +627,7 @@ function enforceCsrfForAction(req, res, ctx) {
|
|
|
1279
627
|
);
|
|
1280
628
|
return false;
|
|
1281
629
|
}
|
|
1282
|
-
async function
|
|
630
|
+
async function runPreHandlerPipeline(p) {
|
|
1283
631
|
if (p.serverDir) {
|
|
1284
632
|
const result = await runMiddlewareAndContext(p.req, p.res, p.loadModule, p.serverDir);
|
|
1285
633
|
if (result.aborted) return false;
|
|
@@ -1407,7 +755,7 @@ async function executeActionWithOptions(opts) {
|
|
|
1407
755
|
req,
|
|
1408
756
|
res
|
|
1409
757
|
};
|
|
1410
|
-
if (!await
|
|
758
|
+
if (!await runPreHandlerPipeline(pipeline)) return;
|
|
1411
759
|
ctx = pipeline.ctx;
|
|
1412
760
|
const bodyOutcome = await readActionBody(req, res, requestId, actionConfig);
|
|
1413
761
|
if (!bodyOutcome.ok) return;
|
|
@@ -1679,17 +1027,6 @@ function createCorsWebHandler(config) {
|
|
|
1679
1027
|
|
|
1680
1028
|
export {
|
|
1681
1029
|
dispatchCsrfWarn,
|
|
1682
|
-
sendJson,
|
|
1683
|
-
sendError,
|
|
1684
|
-
incomingMessageToWebRequest,
|
|
1685
|
-
createWebRequestSource,
|
|
1686
|
-
incomingMessageToHandlerRequest,
|
|
1687
|
-
validateRouteInput,
|
|
1688
|
-
executeWebRequest,
|
|
1689
|
-
writeWebResponseToServerResponse,
|
|
1690
|
-
_resetMiddlewareCacheForTests,
|
|
1691
|
-
runMiddlewareAndContext,
|
|
1692
|
-
createServerContext,
|
|
1693
1030
|
executeRoute,
|
|
1694
1031
|
handleRequestError,
|
|
1695
1032
|
handleWebRequestError,
|
|
@@ -1702,4 +1039,4 @@ export {
|
|
|
1702
1039
|
createCorsHandler,
|
|
1703
1040
|
createCorsWebHandler
|
|
1704
1041
|
};
|
|
1705
|
-
//# sourceMappingURL=chunk-
|
|
1042
|
+
//# sourceMappingURL=chunk-SRJBH5E5.js.map
|