better-call 1.2.1 → 1.2.4
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/_virtual/{rolldown_runtime.cjs → _rolldown/runtime.cjs} +1 -1
- package/dist/adapters/node/request.cjs +13 -7
- package/dist/adapters/node/request.cjs.map +1 -1
- package/dist/adapters/node/request.mjs +11 -5
- package/dist/adapters/node/request.mjs.map +1 -1
- package/dist/client.cjs +6 -5
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +7 -7
- package/dist/client.d.mts +7 -7
- package/dist/client.mjs +2 -2
- package/dist/client.mjs.map +1 -1
- package/dist/context.cjs +6 -6
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.cts +8 -7
- package/dist/context.d.mts +8 -7
- package/dist/context.mjs +6 -6
- package/dist/context.mjs.map +1 -1
- package/dist/cookies.cjs.map +1 -1
- package/dist/cookies.mjs.map +1 -1
- package/dist/crypto.cjs +5 -5
- package/dist/crypto.cjs.map +1 -1
- package/dist/crypto.mjs.map +1 -1
- package/dist/endpoint.cjs.map +1 -1
- package/dist/endpoint.mjs.map +1 -1
- package/dist/error.cjs +2 -4
- package/dist/error.cjs.map +1 -1
- package/dist/error.d.cts +0 -1
- package/dist/error.d.mts +0 -1
- package/dist/error.mjs +1 -4
- package/dist/error.mjs.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.mjs.map +1 -1
- package/dist/node.cjs +1 -0
- package/dist/node.cjs.map +1 -1
- package/dist/node.mjs.map +1 -1
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.mjs.map +1 -1
- package/dist/router.cjs +4 -4
- package/dist/router.cjs.map +1 -1
- package/dist/router.mjs +3 -3
- package/dist/router.mjs.map +1 -1
- package/dist/to-response.cjs +9 -9
- package/dist/to-response.cjs.map +1 -1
- package/dist/to-response.mjs +9 -9
- package/dist/to-response.mjs.map +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/validator.cjs.map +1 -1
- package/dist/validator.mjs.map +1 -1
- package/package.json +15 -30
- package/README.md +0 -862
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
2
2
|
let set_cookie_parser = require("set-cookie-parser");
|
|
3
|
-
set_cookie_parser =
|
|
3
|
+
set_cookie_parser = require_runtime.__toESM(set_cookie_parser);
|
|
4
4
|
|
|
5
5
|
//#region src/adapters/node/request.ts
|
|
6
6
|
function get_raw_body(req, body_size_limit) {
|
|
@@ -51,9 +51,14 @@ function get_raw_body(req, body_size_limit) {
|
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
+
function constructRelativeUrl(req) {
|
|
55
|
+
const baseUrl = req.baseUrl;
|
|
56
|
+
const originalUrl = req.originalUrl;
|
|
57
|
+
if (!baseUrl || !originalUrl) return baseUrl ? baseUrl + req.url : req.url;
|
|
58
|
+
if (baseUrl + req.url === originalUrl) return baseUrl + req.url;
|
|
59
|
+
return originalUrl.split("?")[0].at(-1) === "/" ? baseUrl + req.url : baseUrl;
|
|
60
|
+
}
|
|
54
61
|
function getRequest({ request, base, bodySizeLimit }) {
|
|
55
|
-
const baseUrl = request?.baseUrl;
|
|
56
|
-
const fullPath = baseUrl ? baseUrl + request.url : request.url;
|
|
57
62
|
const maybeConsumedReq = request;
|
|
58
63
|
let body = void 0;
|
|
59
64
|
const method = request.method;
|
|
@@ -64,7 +69,7 @@ function getRequest({ request, base, bodySizeLimit }) {
|
|
|
64
69
|
controller.close();
|
|
65
70
|
} });
|
|
66
71
|
} else body = get_raw_body(request, bodySizeLimit);
|
|
67
|
-
return new Request(base +
|
|
72
|
+
return new Request(base + constructRelativeUrl(request), {
|
|
68
73
|
duplex: "half",
|
|
69
74
|
method: request.method,
|
|
70
75
|
body,
|
|
@@ -108,12 +113,13 @@ async function setResponse(res, response) {
|
|
|
108
113
|
for (;;) {
|
|
109
114
|
const { done, value } = await reader.read();
|
|
110
115
|
if (done) break;
|
|
111
|
-
if (!res.write(value))
|
|
116
|
+
if (!res.write(value)) if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.LAMBDA_TASK_ROOT) continue;
|
|
117
|
+
else {
|
|
112
118
|
res.once("drain", next);
|
|
113
119
|
return;
|
|
114
120
|
}
|
|
121
|
+
res.end();
|
|
115
122
|
}
|
|
116
|
-
res.end();
|
|
117
123
|
} catch (error) {
|
|
118
124
|
cancel(error instanceof Error ? error : new Error(String(error)));
|
|
119
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.cjs","names":[],"sources":["../../../src/adapters/node/request.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport * as set_cookie_parser from \"set-cookie-parser\";\n\nfunction get_raw_body(req: IncomingMessage, body_size_limit?: number) {\n\tconst h = req.headers;\n\n\tif (!h[\"content-type\"]) return null;\n\n\tconst content_length = Number(h[\"content-length\"]);\n\n\t// check if no request body\n\tif (\n\t\t(req.httpVersionMajor === 1
|
|
1
|
+
{"version":3,"file":"request.cjs","names":[],"sources":["../../../src/adapters/node/request.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport * as set_cookie_parser from \"set-cookie-parser\";\n\nfunction get_raw_body(req: IncomingMessage, body_size_limit?: number) {\n\tconst h = req.headers;\n\n\tif (!h[\"content-type\"]) return null;\n\n\tconst content_length = Number(h[\"content-length\"]);\n\n\t// check if no request body\n\tif (\n\t\t(req.httpVersionMajor === 1 &&\n\t\t\tisNaN(content_length) &&\n\t\t\th[\"transfer-encoding\"] == null) ||\n\t\tcontent_length === 0\n\t) {\n\t\treturn null;\n\t}\n\n\tlet length = content_length;\n\n\tif (body_size_limit) {\n\t\tif (!length) {\n\t\t\tlength = body_size_limit;\n\t\t} else if (length > body_size_limit) {\n\t\t\tthrow Error(\n\t\t\t\t`Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif (req.destroyed) {\n\t\tconst readable = new ReadableStream();\n\t\treadable.cancel();\n\t\treturn readable;\n\t}\n\n\tlet size = 0;\n\tlet cancelled = false;\n\n\treturn new ReadableStream({\n\t\tstart(controller) {\n\t\t\treq.on(\"error\", (error) => {\n\t\t\t\tcancelled = true;\n\t\t\t\tcontroller.error(error);\n\t\t\t});\n\n\t\t\treq.on(\"end\", () => {\n\t\t\t\tif (cancelled) return;\n\t\t\t\tcontroller.close();\n\t\t\t});\n\n\t\t\treq.on(\"data\", (chunk) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tsize += chunk.length;\n\n\t\t\t\tif (size > length) {\n\t\t\t\t\tcancelled = true;\n\n\t\t\t\t\tcontroller.error(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`request body size exceeded ${\n\t\t\t\t\t\t\t\tcontent_length ? \"'content-length'\" : \"BODY_SIZE_LIMIT\"\n\t\t\t\t\t\t\t} of ${length}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontroller.enqueue(chunk);\n\n\t\t\t\tif (controller.desiredSize === null || controller.desiredSize <= 0) {\n\t\t\t\t\treq.pause();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tpull() {\n\t\t\treq.resume();\n\t\t},\n\n\t\tcancel(reason) {\n\t\t\tcancelled = true;\n\t\t\treq.destroy(reason);\n\t\t},\n\t});\n}\n\nfunction constructRelativeUrl(\n\treq: IncomingMessage & { baseUrl?: string; originalUrl?: string },\n) {\n\tconst baseUrl = req.baseUrl;\n\tconst originalUrl = req.originalUrl;\n\n\tif (!baseUrl || !originalUrl) {\n\t\t// In express.js sub-routers `req.url` is relative to the mount\n\t\t// path (e.g., '/auth/xxx'), and `req.baseUrl` will hold the mount\n\t\t// path (e.g., '/api'). Build the full path as baseUrl + url when\n\t\t// available to preserve the full route. For application level routes\n\t\t// baseUrl will be an empty string\n\t\treturn baseUrl ? baseUrl + req.url : req.url;\n\t}\n\n\tif (baseUrl + req.url === originalUrl) {\n\t\treturn baseUrl + req.url;\n\t}\n\n\t// For certain subroutes or when mounting wildcard middlewares in express\n\t// it is possible `baseUrl + req.url` will result in a url constructed\n\t// which has a trailing forward slash the original url did not have.\n\t// Checking the `req.originalUrl` path ending can prevent this issue.\n\n\tconst originalPathEnding = originalUrl.split(\"?\")[0]!.at(-1);\n\treturn originalPathEnding === \"/\" ? baseUrl + req.url : baseUrl;\n}\n\nexport function getRequest({\n\trequest,\n\tbase,\n\tbodySizeLimit,\n}: {\n\tbase: string;\n\tbodySizeLimit?: number;\n\trequest: IncomingMessage;\n}) {\n\t// Check if body has already been parsed by Express middleware\n\tconst maybeConsumedReq = request as any;\n\tlet body = undefined;\n\n\tconst method = request.method;\n\t// Request with GET/HEAD method cannot have body.\n\tif (method !== \"GET\" && method !== \"HEAD\") {\n\t\t// If body was already parsed by Express body-parser middleware\n\t\tif (maybeConsumedReq.body !== undefined) {\n\t\t\t// Convert parsed body back to a ReadableStream\n\t\t\tconst bodyContent =\n\t\t\t\ttypeof maybeConsumedReq.body === \"string\"\n\t\t\t\t\t? maybeConsumedReq.body\n\t\t\t\t\t: JSON.stringify(maybeConsumedReq.body);\n\n\t\t\tbody = new ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.enqueue(new TextEncoder().encode(bodyContent));\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\t// Otherwise, get the raw body stream\n\t\t\tbody = get_raw_body(request, bodySizeLimit);\n\t\t}\n\t}\n\n\treturn new Request(base + constructRelativeUrl(request), {\n\t\t// @ts-expect-error\n\t\tduplex: \"half\",\n\t\tmethod: request.method,\n\t\tbody,\n\t\theaders: request.headers as Record<string, string>,\n\t});\n}\n\nexport async function setResponse(res: ServerResponse, response: Response) {\n\tfor (const [key, value] of response.headers as any) {\n\t\ttry {\n\t\t\tres.setHeader(\n\t\t\t\tkey,\n\t\t\t\tkey === \"set-cookie\"\n\t\t\t\t\t? set_cookie_parser.splitCookiesString(\n\t\t\t\t\t\t\tresponse.headers.get(key) as string,\n\t\t\t\t\t\t)\n\t\t\t\t\t: value,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tres.getHeaderNames().forEach((name) => res.removeHeader(name));\n\t\t\tres.writeHead(500).end(String(error));\n\t\t\treturn;\n\t\t}\n\t}\n\n\tres.statusCode = response.status;\n\tres.writeHead(response.status);\n\n\tif (!response.body) {\n\t\tres.end();\n\t\treturn;\n\t}\n\n\tif (response.body.locked) {\n\t\tres.end(\n\t\t\t\"Fatal error: Response body is locked. \" +\n\t\t\t\t\"This can happen when the response was already read (for example through 'response.json()' or 'response.text()').\",\n\t\t);\n\t\treturn;\n\t}\n\n\tconst reader = response.body.getReader();\n\n\tif (res.destroyed) {\n\t\treader.cancel();\n\t\treturn;\n\t}\n\n\tconst cancel = (error?: Error) => {\n\t\tres.off(\"close\", cancel);\n\t\tres.off(\"error\", cancel);\n\n\t\t// If the reader has already been interrupted with an error earlier,\n\t\t// then it will appear here, it is useless, but it needs to be catch.\n\t\treader.cancel(error).catch(() => {});\n\t\tif (error) res.destroy(error);\n\t};\n\n\tres.on(\"close\", cancel);\n\tres.on(\"error\", cancel);\n\n\tnext();\n\tasync function next() {\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst { done, value } = await reader.read();\n\n\t\t\t\tif (done) break;\n\n\t\t\t\tconst writeResult = res.write(value);\n\t\t\t\tif (!writeResult) {\n\t\t\t\t\t// In AWS Lambda/serverless environments, drain events may not work properly\n\t\t\t\t\t// Check if we're in a Lambda-like environment and handle differently\n\t\t\t\t\tif (\n\t\t\t\t\t\tprocess.env.AWS_LAMBDA_FUNCTION_NAME ||\n\t\t\t\t\t\tprocess.env.LAMBDA_TASK_ROOT\n\t\t\t\t\t) {\n\t\t\t\t\t\t// In Lambda, continue without waiting for drain\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Standard Node.js behavior\n\t\t\t\t\t\tres.once(\"drain\", next);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tres.end();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tcancel(error instanceof Error ? error : new Error(String(error)));\n\t\t}\n\t}\n}\n"],"mappings":";;;;;AAGA,SAAS,aAAa,KAAsB,iBAA0B;CACrE,MAAM,IAAI,IAAI;AAEd,KAAI,CAAC,EAAE,gBAAiB,QAAO;CAE/B,MAAM,iBAAiB,OAAO,EAAE,kBAAkB;AAGlD,KACE,IAAI,qBAAqB,KACzB,MAAM,eAAe,IACrB,EAAE,wBAAwB,QAC3B,mBAAmB,EAEnB,QAAO;CAGR,IAAI,SAAS;AAEb,KAAI,iBACH;MAAI,CAAC,OACJ,UAAS;WACC,SAAS,gBACnB,OAAM,MACL,8BAA8B,OAAO,0BAA0B,gBAAgB,SAC/E;;AAIH,KAAI,IAAI,WAAW;EAClB,MAAM,WAAW,IAAI,gBAAgB;AACrC,WAAS,QAAQ;AACjB,SAAO;;CAGR,IAAI,OAAO;CACX,IAAI,YAAY;AAEhB,QAAO,IAAI,eAAe;EACzB,MAAM,YAAY;AACjB,OAAI,GAAG,UAAU,UAAU;AAC1B,gBAAY;AACZ,eAAW,MAAM,MAAM;KACtB;AAEF,OAAI,GAAG,aAAa;AACnB,QAAI,UAAW;AACf,eAAW,OAAO;KACjB;AAEF,OAAI,GAAG,SAAS,UAAU;AACzB,QAAI,UAAW;AAEf,YAAQ,MAAM;AAEd,QAAI,OAAO,QAAQ;AAClB,iBAAY;AAEZ,gBAAW,sBACV,IAAI,MACH,8BACC,iBAAiB,qBAAqB,kBACtC,MAAM,SACP,CACD;AACD;;AAGD,eAAW,QAAQ,MAAM;AAEzB,QAAI,WAAW,gBAAgB,QAAQ,WAAW,eAAe,EAChE,KAAI,OAAO;KAEX;;EAGH,OAAO;AACN,OAAI,QAAQ;;EAGb,OAAO,QAAQ;AACd,eAAY;AACZ,OAAI,QAAQ,OAAO;;EAEpB,CAAC;;AAGH,SAAS,qBACR,KACC;CACD,MAAM,UAAU,IAAI;CACpB,MAAM,cAAc,IAAI;AAExB,KAAI,CAAC,WAAW,CAAC,YAMhB,QAAO,UAAU,UAAU,IAAI,MAAM,IAAI;AAG1C,KAAI,UAAU,IAAI,QAAQ,YACzB,QAAO,UAAU,IAAI;AAStB,QAD2B,YAAY,MAAM,IAAI,CAAC,GAAI,GAAG,GAAG,KAC9B,MAAM,UAAU,IAAI,MAAM;;AAGzD,SAAgB,WAAW,EAC1B,SACA,MACA,iBAKE;CAEF,MAAM,mBAAmB;CACzB,IAAI,OAAO;CAEX,MAAM,SAAS,QAAQ;AAEvB,KAAI,WAAW,SAAS,WAAW,OAElC,KAAI,iBAAiB,SAAS,QAAW;EAExC,MAAM,cACL,OAAO,iBAAiB,SAAS,WAC9B,iBAAiB,OACjB,KAAK,UAAU,iBAAiB,KAAK;AAEzC,SAAO,IAAI,eAAe,EACzB,MAAM,YAAY;AACjB,cAAW,QAAQ,IAAI,aAAa,CAAC,OAAO,YAAY,CAAC;AACzD,cAAW,OAAO;KAEnB,CAAC;OAGF,QAAO,aAAa,SAAS,cAAc;AAI7C,QAAO,IAAI,QAAQ,OAAO,qBAAqB,QAAQ,EAAE;EAExD,QAAQ;EACR,QAAQ,QAAQ;EAChB;EACA,SAAS,QAAQ;EACjB,CAAC;;AAGH,eAAsB,YAAY,KAAqB,UAAoB;AAC1E,MAAK,MAAM,CAAC,KAAK,UAAU,SAAS,QACnC,KAAI;AACH,MAAI,UACH,KACA,QAAQ,eACL,kBAAkB,mBAClB,SAAS,QAAQ,IAAI,IAAI,CACzB,GACA,MACH;UACO,OAAO;AACf,MAAI,gBAAgB,CAAC,SAAS,SAAS,IAAI,aAAa,KAAK,CAAC;AAC9D,MAAI,UAAU,IAAI,CAAC,IAAI,OAAO,MAAM,CAAC;AACrC;;AAIF,KAAI,aAAa,SAAS;AAC1B,KAAI,UAAU,SAAS,OAAO;AAE9B,KAAI,CAAC,SAAS,MAAM;AACnB,MAAI,KAAK;AACT;;AAGD,KAAI,SAAS,KAAK,QAAQ;AACzB,MAAI,IACH,yJAEA;AACD;;CAGD,MAAM,SAAS,SAAS,KAAK,WAAW;AAExC,KAAI,IAAI,WAAW;AAClB,SAAO,QAAQ;AACf;;CAGD,MAAM,UAAU,UAAkB;AACjC,MAAI,IAAI,SAAS,OAAO;AACxB,MAAI,IAAI,SAAS,OAAO;AAIxB,SAAO,OAAO,MAAM,CAAC,YAAY,GAAG;AACpC,MAAI,MAAO,KAAI,QAAQ,MAAM;;AAG9B,KAAI,GAAG,SAAS,OAAO;AACvB,KAAI,GAAG,SAAS,OAAO;AAEvB,OAAM;CACN,eAAe,OAAO;AACrB,MAAI;AACH,YAAS;IACR,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAE3C,QAAI,KAAM;AAGV,QAAI,CADgB,IAAI,MAAM,MAAM,CAInC,KACC,QAAQ,IAAI,4BACZ,QAAQ,IAAI,iBAGZ;SACM;AAEN,SAAI,KAAK,SAAS,KAAK;AACvB;;AAGF,QAAI,KAAK;;WAEF,OAAO;AACf,UAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC"}
|
|
@@ -49,9 +49,14 @@ function get_raw_body(req, body_size_limit) {
|
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
+
function constructRelativeUrl(req) {
|
|
53
|
+
const baseUrl = req.baseUrl;
|
|
54
|
+
const originalUrl = req.originalUrl;
|
|
55
|
+
if (!baseUrl || !originalUrl) return baseUrl ? baseUrl + req.url : req.url;
|
|
56
|
+
if (baseUrl + req.url === originalUrl) return baseUrl + req.url;
|
|
57
|
+
return originalUrl.split("?")[0].at(-1) === "/" ? baseUrl + req.url : baseUrl;
|
|
58
|
+
}
|
|
52
59
|
function getRequest({ request, base, bodySizeLimit }) {
|
|
53
|
-
const baseUrl = request?.baseUrl;
|
|
54
|
-
const fullPath = baseUrl ? baseUrl + request.url : request.url;
|
|
55
60
|
const maybeConsumedReq = request;
|
|
56
61
|
let body = void 0;
|
|
57
62
|
const method = request.method;
|
|
@@ -62,7 +67,7 @@ function getRequest({ request, base, bodySizeLimit }) {
|
|
|
62
67
|
controller.close();
|
|
63
68
|
} });
|
|
64
69
|
} else body = get_raw_body(request, bodySizeLimit);
|
|
65
|
-
return new Request(base +
|
|
70
|
+
return new Request(base + constructRelativeUrl(request), {
|
|
66
71
|
duplex: "half",
|
|
67
72
|
method: request.method,
|
|
68
73
|
body,
|
|
@@ -106,12 +111,13 @@ async function setResponse(res, response) {
|
|
|
106
111
|
for (;;) {
|
|
107
112
|
const { done, value } = await reader.read();
|
|
108
113
|
if (done) break;
|
|
109
|
-
if (!res.write(value))
|
|
114
|
+
if (!res.write(value)) if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.LAMBDA_TASK_ROOT) continue;
|
|
115
|
+
else {
|
|
110
116
|
res.once("drain", next);
|
|
111
117
|
return;
|
|
112
118
|
}
|
|
119
|
+
res.end();
|
|
113
120
|
}
|
|
114
|
-
res.end();
|
|
115
121
|
} catch (error) {
|
|
116
122
|
cancel(error instanceof Error ? error : new Error(String(error)));
|
|
117
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.mjs","names":[],"sources":["../../../src/adapters/node/request.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport * as set_cookie_parser from \"set-cookie-parser\";\n\nfunction get_raw_body(req: IncomingMessage, body_size_limit?: number) {\n\tconst h = req.headers;\n\n\tif (!h[\"content-type\"]) return null;\n\n\tconst content_length = Number(h[\"content-length\"]);\n\n\t// check if no request body\n\tif (\n\t\t(req.httpVersionMajor === 1
|
|
1
|
+
{"version":3,"file":"request.mjs","names":[],"sources":["../../../src/adapters/node/request.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport * as set_cookie_parser from \"set-cookie-parser\";\n\nfunction get_raw_body(req: IncomingMessage, body_size_limit?: number) {\n\tconst h = req.headers;\n\n\tif (!h[\"content-type\"]) return null;\n\n\tconst content_length = Number(h[\"content-length\"]);\n\n\t// check if no request body\n\tif (\n\t\t(req.httpVersionMajor === 1 &&\n\t\t\tisNaN(content_length) &&\n\t\t\th[\"transfer-encoding\"] == null) ||\n\t\tcontent_length === 0\n\t) {\n\t\treturn null;\n\t}\n\n\tlet length = content_length;\n\n\tif (body_size_limit) {\n\t\tif (!length) {\n\t\t\tlength = body_size_limit;\n\t\t} else if (length > body_size_limit) {\n\t\t\tthrow Error(\n\t\t\t\t`Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif (req.destroyed) {\n\t\tconst readable = new ReadableStream();\n\t\treadable.cancel();\n\t\treturn readable;\n\t}\n\n\tlet size = 0;\n\tlet cancelled = false;\n\n\treturn new ReadableStream({\n\t\tstart(controller) {\n\t\t\treq.on(\"error\", (error) => {\n\t\t\t\tcancelled = true;\n\t\t\t\tcontroller.error(error);\n\t\t\t});\n\n\t\t\treq.on(\"end\", () => {\n\t\t\t\tif (cancelled) return;\n\t\t\t\tcontroller.close();\n\t\t\t});\n\n\t\t\treq.on(\"data\", (chunk) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tsize += chunk.length;\n\n\t\t\t\tif (size > length) {\n\t\t\t\t\tcancelled = true;\n\n\t\t\t\t\tcontroller.error(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`request body size exceeded ${\n\t\t\t\t\t\t\t\tcontent_length ? \"'content-length'\" : \"BODY_SIZE_LIMIT\"\n\t\t\t\t\t\t\t} of ${length}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontroller.enqueue(chunk);\n\n\t\t\t\tif (controller.desiredSize === null || controller.desiredSize <= 0) {\n\t\t\t\t\treq.pause();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tpull() {\n\t\t\treq.resume();\n\t\t},\n\n\t\tcancel(reason) {\n\t\t\tcancelled = true;\n\t\t\treq.destroy(reason);\n\t\t},\n\t});\n}\n\nfunction constructRelativeUrl(\n\treq: IncomingMessage & { baseUrl?: string; originalUrl?: string },\n) {\n\tconst baseUrl = req.baseUrl;\n\tconst originalUrl = req.originalUrl;\n\n\tif (!baseUrl || !originalUrl) {\n\t\t// In express.js sub-routers `req.url` is relative to the mount\n\t\t// path (e.g., '/auth/xxx'), and `req.baseUrl` will hold the mount\n\t\t// path (e.g., '/api'). Build the full path as baseUrl + url when\n\t\t// available to preserve the full route. For application level routes\n\t\t// baseUrl will be an empty string\n\t\treturn baseUrl ? baseUrl + req.url : req.url;\n\t}\n\n\tif (baseUrl + req.url === originalUrl) {\n\t\treturn baseUrl + req.url;\n\t}\n\n\t// For certain subroutes or when mounting wildcard middlewares in express\n\t// it is possible `baseUrl + req.url` will result in a url constructed\n\t// which has a trailing forward slash the original url did not have.\n\t// Checking the `req.originalUrl` path ending can prevent this issue.\n\n\tconst originalPathEnding = originalUrl.split(\"?\")[0]!.at(-1);\n\treturn originalPathEnding === \"/\" ? baseUrl + req.url : baseUrl;\n}\n\nexport function getRequest({\n\trequest,\n\tbase,\n\tbodySizeLimit,\n}: {\n\tbase: string;\n\tbodySizeLimit?: number;\n\trequest: IncomingMessage;\n}) {\n\t// Check if body has already been parsed by Express middleware\n\tconst maybeConsumedReq = request as any;\n\tlet body = undefined;\n\n\tconst method = request.method;\n\t// Request with GET/HEAD method cannot have body.\n\tif (method !== \"GET\" && method !== \"HEAD\") {\n\t\t// If body was already parsed by Express body-parser middleware\n\t\tif (maybeConsumedReq.body !== undefined) {\n\t\t\t// Convert parsed body back to a ReadableStream\n\t\t\tconst bodyContent =\n\t\t\t\ttypeof maybeConsumedReq.body === \"string\"\n\t\t\t\t\t? maybeConsumedReq.body\n\t\t\t\t\t: JSON.stringify(maybeConsumedReq.body);\n\n\t\t\tbody = new ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.enqueue(new TextEncoder().encode(bodyContent));\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\t// Otherwise, get the raw body stream\n\t\t\tbody = get_raw_body(request, bodySizeLimit);\n\t\t}\n\t}\n\n\treturn new Request(base + constructRelativeUrl(request), {\n\t\t// @ts-expect-error\n\t\tduplex: \"half\",\n\t\tmethod: request.method,\n\t\tbody,\n\t\theaders: request.headers as Record<string, string>,\n\t});\n}\n\nexport async function setResponse(res: ServerResponse, response: Response) {\n\tfor (const [key, value] of response.headers as any) {\n\t\ttry {\n\t\t\tres.setHeader(\n\t\t\t\tkey,\n\t\t\t\tkey === \"set-cookie\"\n\t\t\t\t\t? set_cookie_parser.splitCookiesString(\n\t\t\t\t\t\t\tresponse.headers.get(key) as string,\n\t\t\t\t\t\t)\n\t\t\t\t\t: value,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tres.getHeaderNames().forEach((name) => res.removeHeader(name));\n\t\t\tres.writeHead(500).end(String(error));\n\t\t\treturn;\n\t\t}\n\t}\n\n\tres.statusCode = response.status;\n\tres.writeHead(response.status);\n\n\tif (!response.body) {\n\t\tres.end();\n\t\treturn;\n\t}\n\n\tif (response.body.locked) {\n\t\tres.end(\n\t\t\t\"Fatal error: Response body is locked. \" +\n\t\t\t\t\"This can happen when the response was already read (for example through 'response.json()' or 'response.text()').\",\n\t\t);\n\t\treturn;\n\t}\n\n\tconst reader = response.body.getReader();\n\n\tif (res.destroyed) {\n\t\treader.cancel();\n\t\treturn;\n\t}\n\n\tconst cancel = (error?: Error) => {\n\t\tres.off(\"close\", cancel);\n\t\tres.off(\"error\", cancel);\n\n\t\t// If the reader has already been interrupted with an error earlier,\n\t\t// then it will appear here, it is useless, but it needs to be catch.\n\t\treader.cancel(error).catch(() => {});\n\t\tif (error) res.destroy(error);\n\t};\n\n\tres.on(\"close\", cancel);\n\tres.on(\"error\", cancel);\n\n\tnext();\n\tasync function next() {\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst { done, value } = await reader.read();\n\n\t\t\t\tif (done) break;\n\n\t\t\t\tconst writeResult = res.write(value);\n\t\t\t\tif (!writeResult) {\n\t\t\t\t\t// In AWS Lambda/serverless environments, drain events may not work properly\n\t\t\t\t\t// Check if we're in a Lambda-like environment and handle differently\n\t\t\t\t\tif (\n\t\t\t\t\t\tprocess.env.AWS_LAMBDA_FUNCTION_NAME ||\n\t\t\t\t\t\tprocess.env.LAMBDA_TASK_ROOT\n\t\t\t\t\t) {\n\t\t\t\t\t\t// In Lambda, continue without waiting for drain\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Standard Node.js behavior\n\t\t\t\t\t\tres.once(\"drain\", next);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tres.end();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tcancel(error instanceof Error ? error : new Error(String(error)));\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
package/dist/client.cjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
2
3
|
const require_error = require('./error.cjs');
|
|
3
|
-
let
|
|
4
|
+
let _better_fetch_fetch = require("@better-fetch/fetch");
|
|
4
5
|
|
|
5
6
|
//#region src/client.ts
|
|
6
7
|
const createClient = (options) => {
|
|
7
|
-
const fetch = (0,
|
|
8
|
-
return async (path, ...options
|
|
9
|
-
return await fetch(path, { ...options
|
|
8
|
+
const fetch = (0, _better_fetch_fetch.createFetch)(options ?? {});
|
|
9
|
+
return async (path, ...options) => {
|
|
10
|
+
return await fetch(path, { ...options[0] });
|
|
10
11
|
};
|
|
11
12
|
};
|
|
12
13
|
|
package/dist/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":[
|
|
1
|
+
{"version":3,"file":"client.cjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype BetterFetchOption,\n\ttype BetterFetchResponse,\n\tcreateFetch,\n} from \"@better-fetch/fetch\";\nimport type { Router } from \"./router\";\nimport type { HasRequiredKeys, Prettify, UnionToIntersection } from \"./helper\";\nimport type { Endpoint } from \"./endpoint\";\n\ntype HasRequired<\n\tT extends {\n\t\tbody?: any;\n\t\tquery?: any;\n\t\tparams?: any;\n\t},\n> = T[\"body\"] extends object\n\t? HasRequiredKeys<T[\"body\"]> extends true\n\t\t? true\n\t\t: T[\"query\"] extends object\n\t\t\t? HasRequiredKeys<T[\"query\"]> extends true\n\t\t\t\t? true\n\t\t\t\t: T[\"params\"] extends object\n\t\t\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t\t\t: false\n\t\t\t: T[\"params\"] extends object\n\t\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t\t: false\n\t: T[\"query\"] extends object\n\t\t? HasRequiredKeys<T[\"query\"]> extends true\n\t\t\t? true\n\t\t\t: T[\"params\"] extends object\n\t\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t\t: false\n\t\t: T[\"params\"] extends object\n\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t: false;\n\ntype InferContext<T> = T extends (ctx: infer Ctx) => any\n\t? Ctx extends object\n\t\t? Ctx\n\t\t: never\n\t: never;\n\nexport interface ClientOptions extends BetterFetchOption {\n\tbaseURL?: string;\n}\n\ntype WithRequired<T, K> = T & {\n\t[P in K extends string ? K : never]-?: T[P extends keyof T ? P : never];\n};\n\ntype InferClientRoutes<T extends Record<string, Endpoint>> = {\n\t[K in keyof T]: T[K] extends Endpoint<any, infer O>\n\t\t? O extends\n\t\t\t\t| { metadata: { scope: \"http\" } }\n\t\t\t\t| { metadata: { scope: \"server\" } }\n\t\t\t\t| { metadata: { SERVER_ONLY: true } }\n\t\t\t\t| { metadata: { isAction: false } }\n\t\t\t? never\n\t\t\t: T[K]\n\t\t: T[K];\n};\n\nexport type RequiredOptionKeys<\n\tC extends {\n\t\tbody?: any;\n\t\tquery?: any;\n\t\tparams?: any;\n\t},\n> = (undefined extends C[\"body\"]\n\t? {}\n\t: {\n\t\t\tbody: true;\n\t\t}) &\n\t(undefined extends C[\"query\"]\n\t\t? {}\n\t\t: {\n\t\t\t\tquery: true;\n\t\t\t}) &\n\t(undefined extends C[\"params\"]\n\t\t? {}\n\t\t: {\n\t\t\t\tparams: true;\n\t\t\t});\n\nexport const createClient = <R extends Router | Router[\"endpoints\"]>(\n\toptions?: ClientOptions,\n) => {\n\tconst fetch = createFetch(options ?? {});\n\ttype API = InferClientRoutes<\n\t\tR extends { endpoints: Record<string, Endpoint> } ? R[\"endpoints\"] : R\n\t>;\n\ttype Options = API extends {\n\t\t[key: string]: infer T;\n\t}\n\t\t? T extends Endpoint\n\t\t\t? {\n\t\t\t\t\t[key in T[\"options\"][\"method\"] extends \"GET\"\n\t\t\t\t\t\t? T[\"path\"]\n\t\t\t\t\t\t: `@${T[\"options\"][\"method\"] extends string ? Lowercase<T[\"options\"][\"method\"]> : never}${T[\"path\"]}`]: T;\n\t\t\t\t}\n\t\t\t: {}\n\t\t: {};\n\n\ttype O = Prettify<UnionToIntersection<Options>>;\n\treturn async <\n\t\tOPT extends O,\n\t\tK extends keyof OPT,\n\t\tC extends InferContext<OPT[K]>,\n\t>(\n\t\tpath: K,\n\t\t...options: HasRequired<C> extends true\n\t\t\t? [\n\t\t\t\t\tWithRequired<\n\t\t\t\t\t\tBetterFetchOption<C[\"body\"], C[\"query\"], C[\"params\"]>,\n\t\t\t\t\t\tkeyof RequiredOptionKeys<C>\n\t\t\t\t\t>,\n\t\t\t\t]\n\t\t\t: [BetterFetchOption<C[\"body\"], C[\"query\"], C[\"params\"]>?]\n\t): Promise<\n\t\tBetterFetchResponse<\n\t\t\tAwaited<ReturnType<OPT[K] extends Endpoint ? OPT[K] : never>>\n\t\t>\n\t> => {\n\t\treturn (await fetch(path as string, {\n\t\t\t...options[0],\n\t\t})) as any;\n\t};\n};\n\nexport * from \"./error\";\n"],"mappings":";;;;;;AAqFA,MAAa,gBACZ,YACI;CACJ,MAAM,6CAAoB,WAAW,EAAE,CAAC;AAiBxC,QAAO,OAKN,MACA,GAAG,YAYC;AACJ,SAAQ,MAAM,MAAM,MAAgB,EACnC,GAAG,QAAQ,IACX,CAAC"}
|
package/dist/client.d.cts
CHANGED
|
@@ -5,17 +5,17 @@ import { Router } from "./router.cjs";
|
|
|
5
5
|
import { BetterFetchOption, BetterFetchResponse } from "@better-fetch/fetch";
|
|
6
6
|
|
|
7
7
|
//#region src/client.d.ts
|
|
8
|
-
type HasRequired<T
|
|
8
|
+
type HasRequired<T extends {
|
|
9
9
|
body?: any;
|
|
10
10
|
query?: any;
|
|
11
11
|
params?: any;
|
|
12
|
-
}> = T
|
|
13
|
-
type InferContext<T
|
|
12
|
+
}> = T["body"] extends object ? HasRequiredKeys<T["body"]> extends true ? true : T["query"] extends object ? HasRequiredKeys<T["query"]> extends true ? true : T["params"] extends object ? HasRequiredKeys<T["params"]> : false : T["params"] extends object ? HasRequiredKeys<T["params"]> : false : T["query"] extends object ? HasRequiredKeys<T["query"]> extends true ? true : T["params"] extends object ? HasRequiredKeys<T["params"]> : false : T["params"] extends object ? HasRequiredKeys<T["params"]> : false;
|
|
13
|
+
type InferContext<T> = T extends ((ctx: infer Ctx) => any) ? Ctx extends object ? Ctx : never : never;
|
|
14
14
|
interface ClientOptions extends BetterFetchOption {
|
|
15
15
|
baseURL?: string;
|
|
16
16
|
}
|
|
17
|
-
type WithRequired<T
|
|
18
|
-
type InferClientRoutes<T
|
|
17
|
+
type WithRequired<T, K> = T & { [P in K extends string ? K : never]-?: T[P extends keyof T ? P : never] };
|
|
18
|
+
type InferClientRoutes<T extends Record<string, Endpoint>> = { [K in keyof T]: T[K] extends Endpoint<any, infer O> ? O extends {
|
|
19
19
|
metadata: {
|
|
20
20
|
scope: "http";
|
|
21
21
|
};
|
|
@@ -31,7 +31,7 @@ type InferClientRoutes<T$1 extends Record<string, Endpoint>> = { [K in keyof T$1
|
|
|
31
31
|
metadata: {
|
|
32
32
|
isAction: false;
|
|
33
33
|
};
|
|
34
|
-
} ? never : T
|
|
34
|
+
} ? never : T[K] : T[K] };
|
|
35
35
|
type RequiredOptionKeys<C extends {
|
|
36
36
|
body?: any;
|
|
37
37
|
query?: any;
|
|
@@ -47,7 +47,7 @@ declare const createClient: <R extends Router | Router["endpoints"]>(options?: C
|
|
|
47
47
|
endpoints: Record<string, Endpoint>;
|
|
48
48
|
} ? R["endpoints"] : R> extends {
|
|
49
49
|
[key: string]: infer T_1;
|
|
50
|
-
} ? T_1 extends Endpoint ? { [key in T_1["options"]["method"] extends "GET" ? T_1["path"] : `@${T_1["options"]["method"] extends string ? Lowercase<T_1["options"]["method"]> : never}${T_1["path"]}`]: T_1 } : {} : {}> extends infer T ? { [K_1 in keyof T]: T[K_1] } : never), K
|
|
50
|
+
} ? T_1 extends Endpoint ? { [key in T_1["options"]["method"] extends "GET" ? T_1["path"] : `@${T_1["options"]["method"] extends string ? Lowercase<T_1["options"]["method"]> : never}${T_1["path"]}`]: T_1 } : {} : {}> extends infer T ? { [K_1 in keyof T]: T[K_1] } : never), K extends keyof OPT, C extends InferContext<OPT[K]>>(path: K, ...options: HasRequired<C> extends true ? [WithRequired<BetterFetchOption<C["body"], C["query"], C["params"]>, keyof RequiredOptionKeys<C>>] : [BetterFetchOption<C["body"], C["query"], C["params"]>?]) => Promise<BetterFetchResponse<Awaited<ReturnType<OPT[K] extends Endpoint ? OPT[K] : never>>>>;
|
|
51
51
|
//#endregion
|
|
52
52
|
export { APIError, BetterCallError, ClientOptions, RequiredOptionKeys, Status, ValidationError, createClient, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, statusCodes };
|
|
53
53
|
//# sourceMappingURL=client.d.cts.map
|
package/dist/client.d.mts
CHANGED
|
@@ -5,17 +5,17 @@ import { Router } from "./router.mjs";
|
|
|
5
5
|
import { BetterFetchOption, BetterFetchResponse } from "@better-fetch/fetch";
|
|
6
6
|
|
|
7
7
|
//#region src/client.d.ts
|
|
8
|
-
type HasRequired<T
|
|
8
|
+
type HasRequired<T extends {
|
|
9
9
|
body?: any;
|
|
10
10
|
query?: any;
|
|
11
11
|
params?: any;
|
|
12
|
-
}> = T
|
|
13
|
-
type InferContext<T
|
|
12
|
+
}> = T["body"] extends object ? HasRequiredKeys<T["body"]> extends true ? true : T["query"] extends object ? HasRequiredKeys<T["query"]> extends true ? true : T["params"] extends object ? HasRequiredKeys<T["params"]> : false : T["params"] extends object ? HasRequiredKeys<T["params"]> : false : T["query"] extends object ? HasRequiredKeys<T["query"]> extends true ? true : T["params"] extends object ? HasRequiredKeys<T["params"]> : false : T["params"] extends object ? HasRequiredKeys<T["params"]> : false;
|
|
13
|
+
type InferContext<T> = T extends ((ctx: infer Ctx) => any) ? Ctx extends object ? Ctx : never : never;
|
|
14
14
|
interface ClientOptions extends BetterFetchOption {
|
|
15
15
|
baseURL?: string;
|
|
16
16
|
}
|
|
17
|
-
type WithRequired<T
|
|
18
|
-
type InferClientRoutes<T
|
|
17
|
+
type WithRequired<T, K> = T & { [P in K extends string ? K : never]-?: T[P extends keyof T ? P : never] };
|
|
18
|
+
type InferClientRoutes<T extends Record<string, Endpoint>> = { [K in keyof T]: T[K] extends Endpoint<any, infer O> ? O extends {
|
|
19
19
|
metadata: {
|
|
20
20
|
scope: "http";
|
|
21
21
|
};
|
|
@@ -31,7 +31,7 @@ type InferClientRoutes<T$1 extends Record<string, Endpoint>> = { [K in keyof T$1
|
|
|
31
31
|
metadata: {
|
|
32
32
|
isAction: false;
|
|
33
33
|
};
|
|
34
|
-
} ? never : T
|
|
34
|
+
} ? never : T[K] : T[K] };
|
|
35
35
|
type RequiredOptionKeys<C extends {
|
|
36
36
|
body?: any;
|
|
37
37
|
query?: any;
|
|
@@ -47,7 +47,7 @@ declare const createClient: <R extends Router | Router["endpoints"]>(options?: C
|
|
|
47
47
|
endpoints: Record<string, Endpoint>;
|
|
48
48
|
} ? R["endpoints"] : R> extends {
|
|
49
49
|
[key: string]: infer T_1;
|
|
50
|
-
} ? T_1 extends Endpoint ? { [key in T_1["options"]["method"] extends "GET" ? T_1["path"] : `@${T_1["options"]["method"] extends string ? Lowercase<T_1["options"]["method"]> : never}${T_1["path"]}`]: T_1 } : {} : {}> extends infer T ? { [K_1 in keyof T]: T[K_1] } : never), K
|
|
50
|
+
} ? T_1 extends Endpoint ? { [key in T_1["options"]["method"] extends "GET" ? T_1["path"] : `@${T_1["options"]["method"] extends string ? Lowercase<T_1["options"]["method"]> : never}${T_1["path"]}`]: T_1 } : {} : {}> extends infer T ? { [K_1 in keyof T]: T[K_1] } : never), K extends keyof OPT, C extends InferContext<OPT[K]>>(path: K, ...options: HasRequired<C> extends true ? [WithRequired<BetterFetchOption<C["body"], C["query"], C["params"]>, keyof RequiredOptionKeys<C>>] : [BetterFetchOption<C["body"], C["query"], C["params"]>?]) => Promise<BetterFetchResponse<Awaited<ReturnType<OPT[K] extends Endpoint ? OPT[K] : never>>>>;
|
|
51
51
|
//#endregion
|
|
52
52
|
export { APIError, BetterCallError, ClientOptions, RequiredOptionKeys, Status, ValidationError, createClient, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, statusCodes };
|
|
53
53
|
//# sourceMappingURL=client.d.mts.map
|
package/dist/client.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import { createFetch } from "@better-fetch/fetch";
|
|
|
4
4
|
//#region src/client.ts
|
|
5
5
|
const createClient = (options) => {
|
|
6
6
|
const fetch = createFetch(options ?? {});
|
|
7
|
-
return async (path, ...options
|
|
8
|
-
return await fetch(path, { ...options
|
|
7
|
+
return async (path, ...options) => {
|
|
8
|
+
return await fetch(path, { ...options[0] });
|
|
9
9
|
};
|
|
10
10
|
};
|
|
11
11
|
|
package/dist/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype BetterFetchOption,\n\ttype BetterFetchResponse,\n\tcreateFetch,\n} from \"@better-fetch/fetch\";\nimport type { Router } from \"./router\";\nimport type { HasRequiredKeys, Prettify, UnionToIntersection } from \"./helper\";\nimport type { Endpoint } from \"./endpoint\";\n\ntype HasRequired<\n\tT extends {\n\t\tbody?: any;\n\t\tquery?: any;\n\t\tparams?: any;\n\t},\n> = T[\"body\"] extends object\n\t? HasRequiredKeys<T[\"body\"]> extends true\n\t\t? true\n\t\t: T[\"query\"] extends object\n\t\t\t? HasRequiredKeys<T[\"query\"]> extends true\n\t\t\t\t? true\n\t\t\t\t: T[\"params\"] extends object\n\t\t\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t\t\t: false\n\t\t\t: T[\"params\"] extends object\n\t\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t\t: false\n\t: T[\"query\"] extends object\n\t\t? HasRequiredKeys<T[\"query\"]> extends true\n\t\t\t? true\n\t\t\t: T[\"params\"] extends object\n\t\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t\t: false\n\t\t: T[\"params\"] extends object\n\t\t\t? HasRequiredKeys<T[\"params\"]>\n\t\t\t: false;\n\ntype InferContext<T> = T extends (ctx: infer Ctx) => any\n\t? Ctx extends object\n\t\t? Ctx\n\t\t: never\n\t: never;\n\nexport interface ClientOptions extends BetterFetchOption {\n\tbaseURL?: string;\n}\n\ntype WithRequired<T, K> = T & {\n\t[P in K extends string ? K : never]-?: T[P extends keyof T ? P : never];\n};\n\ntype InferClientRoutes<T extends Record<string, Endpoint>> = {\n\t[K in keyof T]: T[K] extends Endpoint<any, infer O>\n\t\t? O extends\n\t\t\t\t| { metadata: { scope: \"http\" } }\n\t\t\t\t| { metadata: { scope: \"server\" } }\n\t\t\t\t| { metadata: { SERVER_ONLY: true } }\n\t\t\t\t| { metadata: { isAction: false } }\n\t\t\t? never\n\t\t\t: T[K]\n\t\t: T[K];\n};\n\nexport type RequiredOptionKeys<\n\tC extends {\n\t\tbody?: any;\n\t\tquery?: any;\n\t\tparams?: any;\n\t},\n> = (undefined extends C[\"body\"]\n\t? {}\n\t: {\n\t\t\tbody: true;\n\t\t}) &\n\t(undefined extends C[\"query\"]\n\t\t? {}\n\t\t: {\n\t\t\t\tquery: true;\n\t\t\t}) &\n\t(undefined extends C[\"params\"]\n\t\t? {}\n\t\t: {\n\t\t\t\tparams: true;\n\t\t\t});\n\nexport const createClient = <R extends Router | Router[\"endpoints\"]>(\n\toptions?: ClientOptions,\n) => {\n\tconst fetch = createFetch(options ?? {});\n\ttype API = InferClientRoutes<\n\t\tR extends { endpoints: Record<string, Endpoint> } ? R[\"endpoints\"] : R\n\t>;\n\ttype Options = API extends {\n\t\t[key: string]: infer T;\n\t}\n\t\t? T extends Endpoint\n\t\t\t? {\n\t\t\t\t\t[key in T[\"options\"][\"method\"] extends \"GET\"\n\t\t\t\t\t\t? T[\"path\"]\n\t\t\t\t\t\t: `@${T[\"options\"][\"method\"] extends string ? Lowercase<T[\"options\"][\"method\"]> : never}${T[\"path\"]}`]: T;\n\t\t\t\t}\n\t\t\t: {}\n\t\t: {};\n\n\ttype O = Prettify<UnionToIntersection<Options>>;\n\treturn async <\n\t\tOPT extends O,\n\t\tK extends keyof OPT,\n\t\tC extends InferContext<OPT[K]>,\n\t>(\n\t\tpath: K,\n\t\t...options: HasRequired<C> extends true\n\t\t\t? [\n\t\t\t\t\tWithRequired<\n\t\t\t\t\t\tBetterFetchOption<C[\"body\"], C[\"query\"], C[\"params\"]>,\n\t\t\t\t\t\tkeyof RequiredOptionKeys<C>\n\t\t\t\t\t>,\n\t\t\t\t]\n\t\t\t: [BetterFetchOption<C[\"body\"], C[\"query\"], C[\"params\"]>?]\n\t): Promise<\n\t\tBetterFetchResponse<\n\t\t\tAwaited<ReturnType<OPT[K] extends Endpoint ? OPT[K] : never>>\n\t\t>\n\t> => {\n\t\treturn (await fetch(path as string, {\n\t\t\t...options[0],\n\t\t})) as any;\n\t};\n};\n\nexport * from \"./error\";\n"],"mappings":";;;;AAqFA,MAAa,gBACZ,YACI;CACJ,MAAM,QAAQ,YAAY,WAAW,EAAE,CAAC;AAiBxC,QAAO,OAKN,MACA,GAAG,YAYC;AACJ,SAAQ,MAAM,MAAM,MAAgB,EACnC,GAAG,QAAQ,IACX,CAAC"}
|
package/dist/context.cjs
CHANGED
|
@@ -48,13 +48,13 @@ const createInternalContext = async (context, { options, path }) => {
|
|
|
48
48
|
if (signature.length !== 44 || !signature.endsWith("=")) return null;
|
|
49
49
|
return await require_crypto.verifySignature(signature, signedValue, await require_crypto.getCryptoKey(secret)) ? signedValue : false;
|
|
50
50
|
},
|
|
51
|
-
setCookie: (key, value, options
|
|
52
|
-
const cookie = require_cookies.serializeCookie(key, value, options
|
|
51
|
+
setCookie: (key, value, options) => {
|
|
52
|
+
const cookie = require_cookies.serializeCookie(key, value, options);
|
|
53
53
|
headers.append("set-cookie", cookie);
|
|
54
54
|
return cookie;
|
|
55
55
|
},
|
|
56
|
-
setSignedCookie: async (key, value, secret, options
|
|
57
|
-
const cookie = await require_cookies.serializeSignedCookie(key, value, secret, options
|
|
56
|
+
setSignedCookie: async (key, value, secret, options) => {
|
|
57
|
+
const cookie = await require_cookies.serializeSignedCookie(key, value, secret, options);
|
|
58
58
|
headers.append("set-cookie", cookie);
|
|
59
59
|
return cookie;
|
|
60
60
|
},
|
|
@@ -62,8 +62,8 @@ const createInternalContext = async (context, { options, path }) => {
|
|
|
62
62
|
headers.set("location", url);
|
|
63
63
|
return new require_error.APIError("FOUND", void 0, headers);
|
|
64
64
|
},
|
|
65
|
-
error: (status, body, headers
|
|
66
|
-
return new require_error.APIError(status, body, headers
|
|
65
|
+
error: (status, body, headers) => {
|
|
66
|
+
return new require_error.APIError(status, body, headers);
|
|
67
67
|
},
|
|
68
68
|
setStatus: (status) => {
|
|
69
69
|
responseStatus = status;
|
package/dist/context.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.cjs","names":["responseStatus: Status | undefined","runValidation","ValidationError","requestHeaders: Headers | null","isRequest","parseCookies","getCookieKey","verifySignature","getCryptoKey","serializeCookie","options","serializeSignedCookie","APIError","headers"],"sources":["../src/context.ts"],"sourcesContent":["import type { EndpointOptions } from \"./endpoint\";\nimport { type statusCodes, APIError, ValidationError, type Status } from \"./error\";\nimport type {\n\tInferParamPath,\n\tInferParamWildCard,\n\tIsEmptyObject,\n\tPrettify,\n\tUnionToIntersection,\n} from \"./helper\";\nimport type { Middleware, MiddlewareContext, MiddlewareOptions } from \"./middleware\";\nimport { runValidation } from \"./validator\";\nimport {\n\tgetCookieKey,\n\tparseCookies,\n\tserializeCookie,\n\tserializeSignedCookie,\n\ttype CookieOptions,\n\ttype CookiePrefixOptions,\n} from \"./cookies\";\nimport { getCryptoKey, verifySignature } from \"./crypto\";\nimport type { StandardSchemaV1 } from \"./standard-schema\";\nimport { isRequest } from \"./utils\";\n\nexport type HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\nexport type Method = HTTPMethod | \"*\";\n\nexport type InferBodyInput<\n\tOptions extends EndpointOptions | MiddlewareOptions,\n\tBody = Options[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tbody: infer B;\n\t\t};\n\t}\n\t\t? B\n\t\t: Options[\"body\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferInput<Options[\"body\"]>\n\t\t\t: undefined,\n> = undefined extends Body\n\t? {\n\t\t\tbody?: Body;\n\t\t}\n\t: {\n\t\t\tbody: Body;\n\t\t};\n\nexport type InferBody<Options extends EndpointOptions | MiddlewareOptions> =\n\tOptions[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tbody: infer Body;\n\t\t};\n\t}\n\t\t? Body\n\t\t: Options[\"body\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferOutput<Options[\"body\"]>\n\t\t\t: any;\n\nexport type InferQueryInput<\n\tOptions extends EndpointOptions | MiddlewareOptions,\n\tQuery = Options[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tquery: infer Query;\n\t\t};\n\t}\n\t\t? Query\n\t\t: Options[\"query\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferInput<Options[\"query\"]>\n\t\t\t: Record<string, any> | undefined,\n> = undefined extends Query\n\t? {\n\t\t\tquery?: Query;\n\t\t}\n\t: {\n\t\t\tquery: Query;\n\t\t};\n\nexport type InferQuery<Options extends EndpointOptions | MiddlewareOptions> =\n\tOptions[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tquery: infer Query;\n\t\t};\n\t}\n\t\t? Query\n\t\t: Options[\"query\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferOutput<Options[\"query\"]>\n\t\t\t: Record<string, any> | undefined;\n\nexport type InferMethod<Options extends EndpointOptions> = Options[\"method\"] extends Array<Method>\n\t? Options[\"method\"][number]\n\t: Options[\"method\"] extends \"*\"\n\t\t? HTTPMethod\n\t\t: Options[\"method\"];\n\nexport type InferInputMethod<\n\tOptions extends EndpointOptions,\n\tMethod = Options[\"method\"] extends Array<any>\n\t\t? Options[\"method\"][number] | undefined\n\t\t: Options[\"method\"] extends \"*\"\n\t\t\t? HTTPMethod\n\t\t\t: Options[\"method\"] | undefined,\n> = undefined extends Method\n\t? {\n\t\t\tmethod?: Method;\n\t\t}\n\t: {\n\t\t\tmethod: Method;\n\t\t};\n\nexport type InferParam<Path extends string> = [Path] extends [never]\n\t? Record<string, any> | undefined\n\t: IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true\n\t\t? Record<string, any> | undefined\n\t\t: Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;\n\nexport type InferParamInput<Path extends string> = [Path] extends [never]\n\t? { params?: Record<string, any> }\n\t: IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true\n\t\t? {\n\t\t\t\tparams?: Record<string, any>;\n\t\t\t}\n\t\t: {\n\t\t\t\tparams: Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;\n\t\t\t};\n\nexport type InferRequest<Option extends EndpointOptions | MiddlewareOptions> =\n\tOption[\"requireRequest\"] extends true ? Request : Request | undefined;\n\nexport type InferRequestInput<Option extends EndpointOptions | MiddlewareOptions> =\n\tOption[\"requireRequest\"] extends true\n\t\t? {\n\t\t\t\trequest: Request;\n\t\t\t}\n\t\t: {\n\t\t\t\trequest?: Request;\n\t\t\t};\n\nexport type InferHeaders<Option extends EndpointOptions | MiddlewareOptions> =\n\tOption[\"requireHeaders\"] extends true ? Headers : Headers | undefined;\n\nexport type InferHeadersInput<Option extends EndpointOptions | MiddlewareOptions> =\n\tOption[\"requireHeaders\"] extends true\n\t\t? {\n\t\t\t\theaders: HeadersInit;\n\t\t\t}\n\t\t: {\n\t\t\t\theaders?: HeadersInit;\n\t\t\t};\n\nexport type InferUse<Opts extends EndpointOptions[\"use\"]> = Opts extends Middleware[]\n\t? UnionToIntersection<Awaited<ReturnType<Opts[number]>>>\n\t: {};\n\nexport type InferMiddlewareBody<Options extends MiddlewareOptions> =\n\tOptions[\"body\"] extends StandardSchemaV1<infer T> ? T : any;\n\nexport type InferMiddlewareQuery<Options extends MiddlewareOptions> =\n\tOptions[\"query\"] extends StandardSchemaV1<infer T> ? T : Record<string, any> | undefined;\n\nexport type InputContext<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n> = InferBodyInput<Options> &\n\tInferInputMethod<Options> &\n\tInferQueryInput<Options> &\n\tInferParamInput<Path> &\n\tInferRequestInput<Options> &\n\tInferHeadersInput<Options> & {\n\t\tasResponse?: boolean;\n\t\treturnHeaders?: boolean;\n\t\treturnStatus?: boolean;\n\t\tuse?: Middleware[];\n\t\tpath?: string;\n\t};\n\nexport const createInternalContext = async (\n\tcontext: InputContext<any, any>,\n\t{\n\t\toptions,\n\t\tpath,\n\t}: {\n\t\toptions: EndpointOptions;\n\t\tpath?: string;\n\t},\n) => {\n\tconst headers = new Headers();\n\tlet responseStatus: Status | undefined = undefined;\n\n\tconst { data, error } = await runValidation(options, context);\n\tif (error) {\n\t\tthrow new ValidationError(error.message, error.issues);\n\t}\n\tconst requestHeaders: Headers | null =\n\t\t\"headers\" in context\n\t\t\t? context.headers instanceof Headers\n\t\t\t\t? context.headers\n\t\t\t\t: new Headers(context.headers)\n\t\t\t: \"request\" in context && isRequest(context.request)\n\t\t\t\t? context.request.headers\n\t\t\t\t: null;\n\tconst requestCookies = requestHeaders?.get(\"cookie\");\n\tconst parsedCookies = requestCookies ? parseCookies(requestCookies) : undefined;\n\n\tconst internalContext = {\n\t\t...context,\n\t\tbody: data.body,\n\t\tquery: data.query,\n\t\tpath: context.path || path || \"virtual:\",\n\t\tcontext: \"context\" in context && context.context ? context.context : {},\n\t\treturned: undefined as any,\n\t\theaders: context?.headers,\n\t\trequest: context?.request,\n\t\tparams: \"params\" in context ? context.params : undefined,\n\t\tmethod:\n\t\t\tcontext.method ??\n\t\t\t(Array.isArray(options.method)\n\t\t\t\t? options.method[0]\n\t\t\t\t: options.method === \"*\"\n\t\t\t\t\t? \"GET\"\n\t\t\t\t\t: options.method),\n\t\tsetHeader: (key: string, value: string) => {\n\t\t\theaders.set(key, value);\n\t\t},\n\t\tgetHeader: (key: string) => {\n\t\t\tif (!requestHeaders) return null;\n\t\t\treturn requestHeaders.get(key);\n\t\t},\n\t\tgetCookie: (key: string, prefix?: CookiePrefixOptions) => {\n\t\t\tconst finalKey = getCookieKey(key, prefix);\n\t\t\tif (!finalKey) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn parsedCookies?.get(finalKey) || null;\n\t\t},\n\t\tgetSignedCookie: async (key: string, secret: string, prefix?: CookiePrefixOptions) => {\n\t\t\tconst finalKey = getCookieKey(key, prefix);\n\t\t\tif (!finalKey) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst value = parsedCookies?.get(finalKey);\n\t\t\tif (!value) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst signatureStartPos = value.lastIndexOf(\".\");\n\t\t\tif (signatureStartPos < 1) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst signedValue = value.substring(0, signatureStartPos);\n\t\t\tconst signature = value.substring(signatureStartPos + 1);\n\t\t\tif (signature.length !== 44 || !signature.endsWith(\"=\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst secretKey = await getCryptoKey(secret);\n\t\t\tconst isVerified = await verifySignature(signature, signedValue, secretKey);\n\t\t\treturn isVerified ? signedValue : false;\n\t\t},\n\t\tsetCookie: (key: string, value: string, options?: CookieOptions) => {\n\t\t\tconst cookie = serializeCookie(key, value, options);\n\t\t\theaders.append(\"set-cookie\", cookie);\n\t\t\treturn cookie;\n\t\t},\n\t\tsetSignedCookie: async (\n\t\t\tkey: string,\n\t\t\tvalue: string,\n\t\t\tsecret: string,\n\t\t\toptions?: CookieOptions,\n\t\t) => {\n\t\t\tconst cookie = await serializeSignedCookie(key, value, secret, options);\n\t\t\theaders.append(\"set-cookie\", cookie);\n\t\t\treturn cookie;\n\t\t},\n\t\tredirect: (url: string) => {\n\t\t\theaders.set(\"location\", url);\n\t\t\treturn new APIError(\"FOUND\", undefined, headers);\n\t\t},\n\t\terror: (\n\t\t\tstatus: keyof typeof statusCodes | Status,\n\t\t\tbody?:\n\t\t\t\t| {\n\t\t\t\t\t\tmessage?: string;\n\t\t\t\t\t\tcode?: string;\n\t\t\t\t }\n\t\t\t\t| undefined,\n\t\t\theaders?: HeadersInit,\n\t\t) => {\n\t\t\treturn new APIError(status, body, headers);\n\t\t},\n\t\tsetStatus: (status: Status) => {\n\t\t\tresponseStatus = status;\n\t\t},\n\t\tjson: (\n\t\t\tjson: Record<string, any>,\n\t\t\trouterResponse?:\n\t\t\t\t| {\n\t\t\t\t\t\tstatus?: number;\n\t\t\t\t\t\theaders?: Record<string, string>;\n\t\t\t\t\t\tresponse?: Response;\n\t\t\t\t\t\tbody?: Record<string, any>;\n\t\t\t\t }\n\t\t\t\t| Response,\n\t\t) => {\n\t\t\tif (!context.asResponse) {\n\t\t\t\treturn json;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tbody: routerResponse?.body || json,\n\t\t\t\trouterResponse,\n\t\t\t\t_flag: \"json\",\n\t\t\t};\n\t\t},\n\t\tresponseHeaders: headers,\n\t\tget responseStatus() {\n\t\t\treturn responseStatus;\n\t\t},\n\t};\n\t//if context was shimmed through the input we want to apply it\n\tfor (const middleware of options.use || []) {\n\t\tconst response = (await middleware({\n\t\t\t...internalContext,\n\t\t\treturnHeaders: true,\n\t\t\tasResponse: false,\n\t\t})) as {\n\t\t\tresponse?: any;\n\t\t\theaders?: Headers;\n\t\t};\n\t\tif (response.response) {\n\t\t\tObject.assign(internalContext.context, response.response);\n\t\t}\n\t\t/**\n\t\t * Apply headers from the middleware to the endpoint headers\n\t\t */\n\t\tif (response.headers) {\n\t\t\tresponse.headers.forEach((value, key) => {\n\t\t\t\tinternalContext.responseHeaders.set(key, value);\n\t\t\t});\n\t\t}\n\t}\n\treturn internalContext;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"context.cjs","names":["runValidation","ValidationError","isRequest","parseCookies","getCookieKey","verifySignature","getCryptoKey","serializeCookie","serializeSignedCookie","APIError"],"sources":["../src/context.ts"],"sourcesContent":["import type { EndpointOptions } from \"./endpoint\";\nimport {\n\ttype statusCodes,\n\tAPIError,\n\tValidationError,\n\ttype Status,\n} from \"./error\";\nimport type {\n\tInferParamPath,\n\tInferParamWildCard,\n\tIsEmptyObject,\n\tPrettify,\n\tUnionToIntersection,\n} from \"./helper\";\nimport type {\n\tMiddleware,\n\tMiddlewareContext,\n\tMiddlewareOptions,\n} from \"./middleware\";\nimport { runValidation } from \"./validator\";\nimport {\n\tgetCookieKey,\n\tparseCookies,\n\tserializeCookie,\n\tserializeSignedCookie,\n\ttype CookieOptions,\n\ttype CookiePrefixOptions,\n} from \"./cookies\";\nimport { getCryptoKey, verifySignature } from \"./crypto\";\nimport type { StandardSchemaV1 } from \"./standard-schema\";\nimport { isRequest } from \"./utils\";\n\nexport type HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\nexport type Method = HTTPMethod | \"*\";\n\nexport type InferBodyInput<\n\tOptions extends EndpointOptions | MiddlewareOptions,\n\tBody = Options[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tbody: infer B;\n\t\t};\n\t}\n\t\t? B\n\t\t: Options[\"body\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferInput<Options[\"body\"]>\n\t\t\t: undefined,\n> = undefined extends Body\n\t? {\n\t\t\tbody?: Body;\n\t\t}\n\t: {\n\t\t\tbody: Body;\n\t\t};\n\nexport type InferBody<Options extends EndpointOptions | MiddlewareOptions> =\n\tOptions[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tbody: infer Body;\n\t\t};\n\t}\n\t\t? Body\n\t\t: Options[\"body\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferOutput<Options[\"body\"]>\n\t\t\t: any;\n\nexport type InferQueryInput<\n\tOptions extends EndpointOptions | MiddlewareOptions,\n\tQuery = Options[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tquery: infer Query;\n\t\t};\n\t}\n\t\t? Query\n\t\t: Options[\"query\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferInput<Options[\"query\"]>\n\t\t\t: Record<string, any> | undefined,\n> = undefined extends Query\n\t? {\n\t\t\tquery?: Query;\n\t\t}\n\t: {\n\t\t\tquery: Query;\n\t\t};\n\nexport type InferQuery<Options extends EndpointOptions | MiddlewareOptions> =\n\tOptions[\"metadata\"] extends {\n\t\t$Infer: {\n\t\t\tquery: infer Query;\n\t\t};\n\t}\n\t\t? Query\n\t\t: Options[\"query\"] extends StandardSchemaV1\n\t\t\t? StandardSchemaV1.InferOutput<Options[\"query\"]>\n\t\t\t: Record<string, any> | undefined;\n\nexport type InferMethod<Options extends EndpointOptions> =\n\tOptions[\"method\"] extends Array<Method>\n\t\t? Options[\"method\"][number]\n\t\t: Options[\"method\"] extends \"*\"\n\t\t\t? HTTPMethod\n\t\t\t: Options[\"method\"];\n\nexport type InferInputMethod<\n\tOptions extends EndpointOptions,\n\tMethod = Options[\"method\"] extends Array<any>\n\t\t? Options[\"method\"][number] | undefined\n\t\t: Options[\"method\"] extends \"*\"\n\t\t\t? HTTPMethod\n\t\t\t: Options[\"method\"] | undefined,\n> = undefined extends Method\n\t? {\n\t\t\tmethod?: Method;\n\t\t}\n\t: {\n\t\t\tmethod: Method;\n\t\t};\n\nexport type InferParam<Path extends string> = [Path] extends [never]\n\t? Record<string, any> | undefined\n\t: IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true\n\t\t? Record<string, any> | undefined\n\t\t: Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;\n\nexport type InferParamInput<Path extends string> = [Path] extends [never]\n\t? { params?: Record<string, any> }\n\t: IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true\n\t\t? {\n\t\t\t\tparams?: Record<string, any>;\n\t\t\t}\n\t\t: {\n\t\t\t\tparams: Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;\n\t\t\t};\n\nexport type InferRequest<Option extends EndpointOptions | MiddlewareOptions> =\n\tOption[\"requireRequest\"] extends true ? Request : Request | undefined;\n\nexport type InferRequestInput<\n\tOption extends EndpointOptions | MiddlewareOptions,\n> = Option[\"requireRequest\"] extends true\n\t? {\n\t\t\trequest: Request;\n\t\t}\n\t: {\n\t\t\trequest?: Request;\n\t\t};\n\nexport type InferHeaders<Option extends EndpointOptions | MiddlewareOptions> =\n\tOption[\"requireHeaders\"] extends true ? Headers : Headers | undefined;\n\nexport type InferHeadersInput<\n\tOption extends EndpointOptions | MiddlewareOptions,\n> = Option[\"requireHeaders\"] extends true\n\t? {\n\t\t\theaders: HeadersInit;\n\t\t}\n\t: {\n\t\t\theaders?: HeadersInit;\n\t\t};\n\nexport type InferUse<Opts extends EndpointOptions[\"use\"]> =\n\tOpts extends Middleware[]\n\t\t? UnionToIntersection<Awaited<ReturnType<Opts[number]>>>\n\t\t: {};\n\nexport type InferMiddlewareBody<Options extends MiddlewareOptions> =\n\tOptions[\"body\"] extends StandardSchemaV1<infer T> ? T : any;\n\nexport type InferMiddlewareQuery<Options extends MiddlewareOptions> =\n\tOptions[\"query\"] extends StandardSchemaV1<infer T>\n\t\t? T\n\t\t: Record<string, any> | undefined;\n\nexport type InputContext<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n> = InferBodyInput<Options> &\n\tInferInputMethod<Options> &\n\tInferQueryInput<Options> &\n\tInferParamInput<Path> &\n\tInferRequestInput<Options> &\n\tInferHeadersInput<Options> & {\n\t\tasResponse?: boolean;\n\t\treturnHeaders?: boolean;\n\t\treturnStatus?: boolean;\n\t\tuse?: Middleware[];\n\t\tpath?: string;\n\t\tcontext?: Record<string, any>;\n\t};\n\nexport const createInternalContext = async (\n\tcontext: InputContext<any, any>,\n\t{\n\t\toptions,\n\t\tpath,\n\t}: {\n\t\toptions: EndpointOptions;\n\t\tpath?: string;\n\t},\n) => {\n\tconst headers = new Headers();\n\tlet responseStatus: Status | undefined = undefined;\n\n\tconst { data, error } = await runValidation(options, context);\n\tif (error) {\n\t\tthrow new ValidationError(error.message, error.issues);\n\t}\n\tconst requestHeaders: Headers | null =\n\t\t\"headers\" in context\n\t\t\t? context.headers instanceof Headers\n\t\t\t\t? context.headers\n\t\t\t\t: new Headers(context.headers)\n\t\t\t: \"request\" in context && isRequest(context.request)\n\t\t\t\t? context.request.headers\n\t\t\t\t: null;\n\tconst requestCookies = requestHeaders?.get(\"cookie\");\n\tconst parsedCookies = requestCookies\n\t\t? parseCookies(requestCookies)\n\t\t: undefined;\n\n\tconst internalContext = {\n\t\t...context,\n\t\tbody: data.body,\n\t\tquery: data.query,\n\t\tpath: context.path || path || \"virtual:\",\n\t\tcontext: \"context\" in context && context.context ? context.context : {},\n\t\treturned: undefined as any,\n\t\theaders: context?.headers,\n\t\trequest: context?.request,\n\t\tparams: \"params\" in context ? context.params : undefined,\n\t\tmethod:\n\t\t\tcontext.method ??\n\t\t\t(Array.isArray(options.method)\n\t\t\t\t? options.method[0]\n\t\t\t\t: options.method === \"*\"\n\t\t\t\t\t? \"GET\"\n\t\t\t\t\t: options.method),\n\t\tsetHeader: (key: string, value: string) => {\n\t\t\theaders.set(key, value);\n\t\t},\n\t\tgetHeader: (key: string) => {\n\t\t\tif (!requestHeaders) return null;\n\t\t\treturn requestHeaders.get(key);\n\t\t},\n\t\tgetCookie: (key: string, prefix?: CookiePrefixOptions) => {\n\t\t\tconst finalKey = getCookieKey(key, prefix);\n\t\t\tif (!finalKey) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn parsedCookies?.get(finalKey) || null;\n\t\t},\n\t\tgetSignedCookie: async (\n\t\t\tkey: string,\n\t\t\tsecret: string,\n\t\t\tprefix?: CookiePrefixOptions,\n\t\t) => {\n\t\t\tconst finalKey = getCookieKey(key, prefix);\n\t\t\tif (!finalKey) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst value = parsedCookies?.get(finalKey);\n\t\t\tif (!value) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst signatureStartPos = value.lastIndexOf(\".\");\n\t\t\tif (signatureStartPos < 1) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst signedValue = value.substring(0, signatureStartPos);\n\t\t\tconst signature = value.substring(signatureStartPos + 1);\n\t\t\tif (signature.length !== 44 || !signature.endsWith(\"=\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst secretKey = await getCryptoKey(secret);\n\t\t\tconst isVerified = await verifySignature(\n\t\t\t\tsignature,\n\t\t\t\tsignedValue,\n\t\t\t\tsecretKey,\n\t\t\t);\n\t\t\treturn isVerified ? signedValue : false;\n\t\t},\n\t\tsetCookie: (key: string, value: string, options?: CookieOptions) => {\n\t\t\tconst cookie = serializeCookie(key, value, options);\n\t\t\theaders.append(\"set-cookie\", cookie);\n\t\t\treturn cookie;\n\t\t},\n\t\tsetSignedCookie: async (\n\t\t\tkey: string,\n\t\t\tvalue: string,\n\t\t\tsecret: string,\n\t\t\toptions?: CookieOptions,\n\t\t) => {\n\t\t\tconst cookie = await serializeSignedCookie(key, value, secret, options);\n\t\t\theaders.append(\"set-cookie\", cookie);\n\t\t\treturn cookie;\n\t\t},\n\t\tredirect: (url: string) => {\n\t\t\theaders.set(\"location\", url);\n\t\t\treturn new APIError(\"FOUND\", undefined, headers);\n\t\t},\n\t\terror: (\n\t\t\tstatus: keyof typeof statusCodes | Status,\n\t\t\tbody?:\n\t\t\t\t| {\n\t\t\t\t\t\tmessage?: string;\n\t\t\t\t\t\tcode?: string;\n\t\t\t\t }\n\t\t\t\t| undefined,\n\t\t\theaders?: HeadersInit,\n\t\t) => {\n\t\t\treturn new APIError(status, body, headers);\n\t\t},\n\t\tsetStatus: (status: Status) => {\n\t\t\tresponseStatus = status;\n\t\t},\n\t\tjson: (\n\t\t\tjson: Record<string, any>,\n\t\t\trouterResponse?:\n\t\t\t\t| {\n\t\t\t\t\t\tstatus?: number;\n\t\t\t\t\t\theaders?: Record<string, string>;\n\t\t\t\t\t\tresponse?: Response;\n\t\t\t\t\t\tbody?: Record<string, any>;\n\t\t\t\t }\n\t\t\t\t| Response,\n\t\t) => {\n\t\t\tif (!context.asResponse) {\n\t\t\t\treturn json;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tbody: routerResponse?.body || json,\n\t\t\t\trouterResponse,\n\t\t\t\t_flag: \"json\",\n\t\t\t};\n\t\t},\n\t\tresponseHeaders: headers,\n\t\tget responseStatus() {\n\t\t\treturn responseStatus;\n\t\t},\n\t};\n\t//if context was shimmed through the input we want to apply it\n\tfor (const middleware of options.use || []) {\n\t\tconst response = (await middleware({\n\t\t\t...internalContext,\n\t\t\treturnHeaders: true,\n\t\t\tasResponse: false,\n\t\t})) as {\n\t\t\tresponse?: any;\n\t\t\theaders?: Headers;\n\t\t};\n\t\tif (response.response) {\n\t\t\tObject.assign(internalContext.context, response.response);\n\t\t}\n\t\t/**\n\t\t * Apply headers from the middleware to the endpoint headers\n\t\t */\n\t\tif (response.headers) {\n\t\t\tresponse.headers.forEach((value, key) => {\n\t\t\t\tinternalContext.responseHeaders.set(key, value);\n\t\t\t});\n\t\t}\n\t}\n\treturn internalContext;\n};\n"],"mappings":"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"}
|
package/dist/context.d.cts
CHANGED
|
@@ -37,10 +37,10 @@ type InferQuery<Options extends EndpointOptions | MiddlewareOptions> = Options["
|
|
|
37
37
|
};
|
|
38
38
|
} ? Query : Options["query"] extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Options["query"]> : Record<string, any> | undefined;
|
|
39
39
|
type InferMethod<Options extends EndpointOptions> = Options["method"] extends Array<Method> ? Options["method"][number] : Options["method"] extends "*" ? HTTPMethod : Options["method"];
|
|
40
|
-
type InferInputMethod<Options extends EndpointOptions, Method
|
|
41
|
-
method?: Method
|
|
40
|
+
type InferInputMethod<Options extends EndpointOptions, Method = (Options["method"] extends Array<any> ? Options["method"][number] | undefined : Options["method"] extends "*" ? HTTPMethod : Options["method"] | undefined)> = undefined extends Method ? {
|
|
41
|
+
method?: Method;
|
|
42
42
|
} : {
|
|
43
|
-
method: Method
|
|
43
|
+
method: Method;
|
|
44
44
|
};
|
|
45
45
|
type InferParam<Path extends string> = [Path] extends [never] ? Record<string, any> | undefined : IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true ? Record<string, any> | undefined : Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;
|
|
46
46
|
type InferParamInput<Path extends string> = [Path] extends [never] ? {
|
|
@@ -71,6 +71,7 @@ type InputContext<Path extends string, Options extends EndpointOptions> = InferB
|
|
|
71
71
|
returnStatus?: boolean;
|
|
72
72
|
use?: Middleware[];
|
|
73
73
|
path?: string;
|
|
74
|
+
context?: Record<string, any>;
|
|
74
75
|
};
|
|
75
76
|
declare const createInternalContext: (context: InputContext<any, any>, {
|
|
76
77
|
options,
|
|
@@ -82,7 +83,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
82
83
|
body: any;
|
|
83
84
|
query: any;
|
|
84
85
|
path: string;
|
|
85
|
-
context:
|
|
86
|
+
context: Record<string, any>;
|
|
86
87
|
returned: any;
|
|
87
88
|
headers: HeadersInit | undefined;
|
|
88
89
|
request: Request | undefined;
|
|
@@ -146,7 +147,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
146
147
|
body: any;
|
|
147
148
|
query: any;
|
|
148
149
|
path: string;
|
|
149
|
-
context:
|
|
150
|
+
context: Record<string, any>;
|
|
150
151
|
returned: any;
|
|
151
152
|
headers: HeadersInit | undefined;
|
|
152
153
|
request: Request | undefined;
|
|
@@ -210,7 +211,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
210
211
|
body: any;
|
|
211
212
|
query: any;
|
|
212
213
|
path: string;
|
|
213
|
-
context:
|
|
214
|
+
context: Record<string, any>;
|
|
214
215
|
returned: any;
|
|
215
216
|
headers: HeadersInit | undefined;
|
|
216
217
|
request: Request | undefined;
|
|
@@ -274,7 +275,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
274
275
|
body: any;
|
|
275
276
|
query: any;
|
|
276
277
|
path: string;
|
|
277
|
-
context:
|
|
278
|
+
context: Record<string, any>;
|
|
278
279
|
returned: any;
|
|
279
280
|
headers: HeadersInit | undefined;
|
|
280
281
|
request: Request | undefined;
|
package/dist/context.d.mts
CHANGED
|
@@ -37,10 +37,10 @@ type InferQuery<Options extends EndpointOptions | MiddlewareOptions> = Options["
|
|
|
37
37
|
};
|
|
38
38
|
} ? Query : Options["query"] extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Options["query"]> : Record<string, any> | undefined;
|
|
39
39
|
type InferMethod<Options extends EndpointOptions> = Options["method"] extends Array<Method> ? Options["method"][number] : Options["method"] extends "*" ? HTTPMethod : Options["method"];
|
|
40
|
-
type InferInputMethod<Options extends EndpointOptions, Method
|
|
41
|
-
method?: Method
|
|
40
|
+
type InferInputMethod<Options extends EndpointOptions, Method = (Options["method"] extends Array<any> ? Options["method"][number] | undefined : Options["method"] extends "*" ? HTTPMethod : Options["method"] | undefined)> = undefined extends Method ? {
|
|
41
|
+
method?: Method;
|
|
42
42
|
} : {
|
|
43
|
-
method: Method
|
|
43
|
+
method: Method;
|
|
44
44
|
};
|
|
45
45
|
type InferParam<Path extends string> = [Path] extends [never] ? Record<string, any> | undefined : IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true ? Record<string, any> | undefined : Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;
|
|
46
46
|
type InferParamInput<Path extends string> = [Path] extends [never] ? {
|
|
@@ -71,6 +71,7 @@ type InputContext<Path extends string, Options extends EndpointOptions> = InferB
|
|
|
71
71
|
returnStatus?: boolean;
|
|
72
72
|
use?: Middleware[];
|
|
73
73
|
path?: string;
|
|
74
|
+
context?: Record<string, any>;
|
|
74
75
|
};
|
|
75
76
|
declare const createInternalContext: (context: InputContext<any, any>, {
|
|
76
77
|
options,
|
|
@@ -82,7 +83,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
82
83
|
body: any;
|
|
83
84
|
query: any;
|
|
84
85
|
path: string;
|
|
85
|
-
context:
|
|
86
|
+
context: Record<string, any>;
|
|
86
87
|
returned: any;
|
|
87
88
|
headers: HeadersInit | undefined;
|
|
88
89
|
request: Request | undefined;
|
|
@@ -146,7 +147,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
146
147
|
body: any;
|
|
147
148
|
query: any;
|
|
148
149
|
path: string;
|
|
149
|
-
context:
|
|
150
|
+
context: Record<string, any>;
|
|
150
151
|
returned: any;
|
|
151
152
|
headers: HeadersInit | undefined;
|
|
152
153
|
request: Request | undefined;
|
|
@@ -210,7 +211,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
210
211
|
body: any;
|
|
211
212
|
query: any;
|
|
212
213
|
path: string;
|
|
213
|
-
context:
|
|
214
|
+
context: Record<string, any>;
|
|
214
215
|
returned: any;
|
|
215
216
|
headers: HeadersInit | undefined;
|
|
216
217
|
request: Request | undefined;
|
|
@@ -274,7 +275,7 @@ declare const createInternalContext: (context: InputContext<any, any>, {
|
|
|
274
275
|
body: any;
|
|
275
276
|
query: any;
|
|
276
277
|
path: string;
|
|
277
|
-
context:
|
|
278
|
+
context: Record<string, any>;
|
|
278
279
|
returned: any;
|
|
279
280
|
headers: HeadersInit | undefined;
|
|
280
281
|
request: Request | undefined;
|
package/dist/context.mjs
CHANGED
|
@@ -48,13 +48,13 @@ const createInternalContext = async (context, { options, path }) => {
|
|
|
48
48
|
if (signature.length !== 44 || !signature.endsWith("=")) return null;
|
|
49
49
|
return await verifySignature(signature, signedValue, await getCryptoKey(secret)) ? signedValue : false;
|
|
50
50
|
},
|
|
51
|
-
setCookie: (key, value, options
|
|
52
|
-
const cookie = serializeCookie(key, value, options
|
|
51
|
+
setCookie: (key, value, options) => {
|
|
52
|
+
const cookie = serializeCookie(key, value, options);
|
|
53
53
|
headers.append("set-cookie", cookie);
|
|
54
54
|
return cookie;
|
|
55
55
|
},
|
|
56
|
-
setSignedCookie: async (key, value, secret, options
|
|
57
|
-
const cookie = await serializeSignedCookie(key, value, secret, options
|
|
56
|
+
setSignedCookie: async (key, value, secret, options) => {
|
|
57
|
+
const cookie = await serializeSignedCookie(key, value, secret, options);
|
|
58
58
|
headers.append("set-cookie", cookie);
|
|
59
59
|
return cookie;
|
|
60
60
|
},
|
|
@@ -62,8 +62,8 @@ const createInternalContext = async (context, { options, path }) => {
|
|
|
62
62
|
headers.set("location", url);
|
|
63
63
|
return new APIError("FOUND", void 0, headers);
|
|
64
64
|
},
|
|
65
|
-
error: (status, body, headers
|
|
66
|
-
return new APIError(status, body, headers
|
|
65
|
+
error: (status, body, headers) => {
|
|
66
|
+
return new APIError(status, body, headers);
|
|
67
67
|
},
|
|
68
68
|
setStatus: (status) => {
|
|
69
69
|
responseStatus = status;
|