better-call 1.1.6 → 1.1.8
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 +35 -0
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/adapters/node/request.cjs +125 -0
- package/dist/adapters/node/request.cjs.map +1 -0
- package/dist/{node.d.ts → adapters/node/request.d.cts} +2 -6
- package/dist/adapters/node/request.d.mts +16 -0
- package/dist/{node.js → adapters/node/request.mjs} +2 -13
- package/dist/adapters/node/request.mjs.map +1 -0
- package/dist/client.cjs +3 -3
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +13 -15
- package/dist/client.d.mts +53 -0
- package/dist/{client.js → client.mjs} +3 -3
- package/dist/client.mjs.map +1 -0
- package/dist/context.cjs +103 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +340 -0
- package/dist/context.d.mts +340 -0
- package/dist/context.mjs +103 -0
- package/dist/context.mjs.map +1 -0
- package/dist/cookies.cjs +87 -0
- package/dist/cookies.cjs.map +1 -0
- package/dist/cookies.d.cts +103 -0
- package/dist/cookies.d.mts +103 -0
- package/dist/cookies.mjs +84 -0
- package/dist/cookies.mjs.map +1 -0
- package/dist/crypto.cjs +39 -0
- package/dist/crypto.cjs.map +1 -0
- package/dist/crypto.mjs +36 -0
- package/dist/crypto.mjs.map +1 -0
- package/dist/endpoint.cjs +70 -0
- package/dist/endpoint.cjs.map +1 -0
- package/dist/endpoint.d.cts +428 -0
- package/dist/endpoint.d.mts +428 -0
- package/dist/endpoint.mjs +70 -0
- package/dist/endpoint.mjs.map +1 -0
- package/dist/error.cjs +140 -7
- package/dist/error.cjs.map +1 -0
- package/dist/error.d.cts +103 -2
- package/dist/{error2.d.ts → error.d.mts} +5 -59
- package/dist/{error2.js → error.mjs} +2 -2
- package/dist/{error2.js.map → error.mjs.map} +1 -1
- package/dist/helper.d.cts +12 -0
- package/dist/helper.d.mts +12 -0
- package/dist/index.cjs +19 -829
- package/dist/index.d.cts +11 -15
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +10 -0
- package/dist/middleware.cjs +39 -0
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.cts +123 -0
- package/dist/middleware.d.mts +123 -0
- package/dist/middleware.mjs +39 -0
- package/dist/middleware.mjs.map +1 -0
- package/dist/node.cjs +4 -151
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +2 -13
- package/dist/node.d.mts +9 -0
- package/dist/node.mjs +15 -0
- package/dist/node.mjs.map +1 -0
- package/dist/openapi.cjs +191 -0
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +113 -0
- package/dist/openapi.d.mts +113 -0
- package/dist/openapi.mjs +189 -0
- package/dist/openapi.mjs.map +1 -0
- package/dist/router.cjs +117 -0
- package/dist/router.cjs.map +1 -0
- package/dist/router.d.cts +3 -1088
- package/dist/router.d.mts +97 -0
- package/dist/router.mjs +116 -0
- package/dist/router.mjs.map +1 -0
- package/dist/standard-schema.d.cts +59 -0
- package/dist/standard-schema.d.mts +59 -0
- package/dist/to-response.cjs +96 -0
- package/dist/to-response.cjs.map +1 -0
- package/dist/to-response.d.cts +12 -0
- package/dist/to-response.d.mts +12 -0
- package/dist/to-response.mjs +96 -0
- package/dist/to-response.mjs.map +1 -0
- package/dist/utils.cjs +86 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.mjs +82 -0
- package/dist/utils.mjs.map +1 -0
- package/dist/validator.cjs +58 -0
- package/dist/validator.cjs.map +1 -0
- package/dist/validator.mjs +57 -0
- package/dist/validator.mjs.map +1 -0
- package/package.json +15 -15
- package/dist/client.d.ts +0 -55
- package/dist/client.js.map +0 -1
- package/dist/error.d.ts +0 -2
- package/dist/error.js +0 -3
- package/dist/error2.cjs +0 -171
- package/dist/error2.cjs.map +0 -1
- package/dist/error2.d.cts +0 -157
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -819
- package/dist/index.js.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/router.d.ts +0 -1182
package/dist/utils.cjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const require_error = require('./error.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/utils.ts
|
|
4
|
+
const jsonContentTypeRegex = /^application\/([a-z0-9.+-]*\+)?json/i;
|
|
5
|
+
async function getBody(request, allowedMediaTypes) {
|
|
6
|
+
const contentType = request.headers.get("content-type") || "";
|
|
7
|
+
const normalizedContentType = contentType.toLowerCase();
|
|
8
|
+
if (!request.body) return;
|
|
9
|
+
if (allowedMediaTypes && allowedMediaTypes.length > 0) {
|
|
10
|
+
if (!allowedMediaTypes.some((allowed) => {
|
|
11
|
+
const normalizedContentTypeBase = normalizedContentType.split(";")[0].trim();
|
|
12
|
+
const normalizedAllowed = allowed.toLowerCase().trim();
|
|
13
|
+
return normalizedContentTypeBase === normalizedAllowed || normalizedContentTypeBase.includes(normalizedAllowed);
|
|
14
|
+
})) {
|
|
15
|
+
if (!normalizedContentType) throw new require_error.APIError(415, {
|
|
16
|
+
message: `Content-Type is required. Allowed types: ${allowedMediaTypes.join(", ")}`,
|
|
17
|
+
code: "UNSUPPORTED_MEDIA_TYPE"
|
|
18
|
+
});
|
|
19
|
+
throw new require_error.APIError(415, {
|
|
20
|
+
message: `Content-Type "${contentType}" is not allowed. Allowed types: ${allowedMediaTypes.join(", ")}`,
|
|
21
|
+
code: "UNSUPPORTED_MEDIA_TYPE"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (jsonContentTypeRegex.test(normalizedContentType)) return await request.json();
|
|
26
|
+
if (normalizedContentType.includes("application/x-www-form-urlencoded")) {
|
|
27
|
+
const formData = await request.formData();
|
|
28
|
+
const result = {};
|
|
29
|
+
formData.forEach((value, key) => {
|
|
30
|
+
result[key] = value.toString();
|
|
31
|
+
});
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
if (normalizedContentType.includes("multipart/form-data")) {
|
|
35
|
+
const formData = await request.formData();
|
|
36
|
+
const result = {};
|
|
37
|
+
formData.forEach((value, key) => {
|
|
38
|
+
result[key] = value;
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
if (normalizedContentType.includes("text/plain")) return await request.text();
|
|
43
|
+
if (normalizedContentType.includes("application/octet-stream")) return await request.arrayBuffer();
|
|
44
|
+
if (normalizedContentType.includes("application/pdf") || normalizedContentType.includes("image/") || normalizedContentType.includes("video/")) return await request.blob();
|
|
45
|
+
if (normalizedContentType.includes("application/stream") || request.body instanceof ReadableStream) return request.body;
|
|
46
|
+
return await request.text();
|
|
47
|
+
}
|
|
48
|
+
function isAPIError(error) {
|
|
49
|
+
return error instanceof require_error.APIError || error?.name === "APIError";
|
|
50
|
+
}
|
|
51
|
+
function tryDecode(str) {
|
|
52
|
+
try {
|
|
53
|
+
return str.includes("%") ? decodeURIComponent(str) : str;
|
|
54
|
+
} catch {
|
|
55
|
+
return str;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function tryCatch(promise) {
|
|
59
|
+
try {
|
|
60
|
+
return {
|
|
61
|
+
data: await promise,
|
|
62
|
+
error: null
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
data: null,
|
|
67
|
+
error
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if an object is a `Request`
|
|
73
|
+
* - `instanceof`: works for native Request instances
|
|
74
|
+
* - `toString`: handles where instanceof check fails but the object is still a valid Request
|
|
75
|
+
*/
|
|
76
|
+
function isRequest(obj) {
|
|
77
|
+
return obj instanceof Request || Object.prototype.toString.call(obj) === "[object Request]";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
exports.getBody = getBody;
|
|
82
|
+
exports.isAPIError = isAPIError;
|
|
83
|
+
exports.isRequest = isRequest;
|
|
84
|
+
exports.tryCatch = tryCatch;
|
|
85
|
+
exports.tryDecode = tryDecode;
|
|
86
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["APIError","result: Record<string, string>","result: Record<string, any>"],"sources":["../src/utils.ts"],"sourcesContent":["import { APIError } from \"./error\";\n\nconst jsonContentTypeRegex = /^application\\/([a-z0-9.+-]*\\+)?json/i;\n\nexport async function getBody(request: Request, allowedMediaTypes?: string[]) {\n\tconst contentType = request.headers.get(\"content-type\") || \"\";\n\tconst normalizedContentType = contentType.toLowerCase();\n\n\tif (!request.body) {\n\t\treturn undefined;\n\t}\n\n\t// Validate content-type if allowedMediaTypes is provided\n\tif (allowedMediaTypes && allowedMediaTypes.length > 0) {\n\t\tconst isAllowed = allowedMediaTypes.some((allowed) => {\n\t\t\t// Normalize both content types for comparison\n\t\t\tconst normalizedContentTypeBase = normalizedContentType.split(\";\")[0].trim();\n\t\t\tconst normalizedAllowed = allowed.toLowerCase().trim();\n\t\t\treturn (\n\t\t\t\tnormalizedContentTypeBase === normalizedAllowed ||\n\t\t\t\tnormalizedContentTypeBase.includes(normalizedAllowed)\n\t\t\t);\n\t\t});\n\n\t\tif (!isAllowed) {\n\t\t\tif (!normalizedContentType) {\n\t\t\t\tthrow new APIError(415, {\n\t\t\t\t\tmessage: `Content-Type is required. Allowed types: ${allowedMediaTypes.join(\", \")}`,\n\t\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow new APIError(415, {\n\t\t\t\tmessage: `Content-Type \"${contentType}\" is not allowed. Allowed types: ${allowedMediaTypes.join(\", \")}`,\n\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\",\n\t\t\t});\n\t\t}\n\t}\n\n\tif (jsonContentTypeRegex.test(normalizedContentType)) {\n\t\treturn await request.json();\n\t}\n\n\tif (normalizedContentType.includes(\"application/x-www-form-urlencoded\")) {\n\t\tconst formData = await request.formData();\n\t\tconst result: Record<string, string> = {};\n\t\tformData.forEach((value, key) => {\n\t\t\tresult[key] = value.toString();\n\t\t});\n\t\treturn result;\n\t}\n\n\tif (normalizedContentType.includes(\"multipart/form-data\")) {\n\t\tconst formData = await request.formData();\n\t\tconst result: Record<string, any> = {};\n\t\tformData.forEach((value, key) => {\n\t\t\tresult[key] = value;\n\t\t});\n\t\treturn result;\n\t}\n\n\tif (normalizedContentType.includes(\"text/plain\")) {\n\t\treturn await request.text();\n\t}\n\n\tif (normalizedContentType.includes(\"application/octet-stream\")) {\n\t\treturn await request.arrayBuffer();\n\t}\n\n\tif (\n\t\tnormalizedContentType.includes(\"application/pdf\") ||\n\t\tnormalizedContentType.includes(\"image/\") ||\n\t\tnormalizedContentType.includes(\"video/\")\n\t) {\n\t\tconst blob = await request.blob();\n\t\treturn blob;\n\t}\n\n\tif (\n\t\tnormalizedContentType.includes(\"application/stream\") ||\n\t\trequest.body instanceof ReadableStream\n\t) {\n\t\treturn request.body;\n\t}\n\n\treturn await request.text();\n}\n\nexport function isAPIError(error: any): error is APIError {\n\treturn error instanceof APIError || error?.name === \"APIError\";\n}\n\nexport function tryDecode(str: string) {\n\ttry {\n\t\treturn str.includes(\"%\") ? decodeURIComponent(str) : str;\n\t} catch {\n\t\treturn str;\n\t}\n}\n\ntype Success<T> = {\n\tdata: T;\n\terror: null;\n};\n\ntype Failure<E> = {\n\tdata: null;\n\terror: E;\n};\n\ntype Result<T, E = Error> = Success<T> | Failure<E>;\n\nexport async function tryCatch<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>> {\n\ttry {\n\t\tconst data = await promise;\n\t\treturn { data, error: null };\n\t} catch (error) {\n\t\treturn { data: null, error: error as E };\n\t}\n}\n\n/**\n * Check if an object is a `Request`\n * - `instanceof`: works for native Request instances\n * - `toString`: handles where instanceof check fails but the object is still a valid Request\n */\nexport function isRequest(obj: unknown): obj is Request {\n\treturn obj instanceof Request || Object.prototype.toString.call(obj) === \"[object Request]\";\n}\n"],"mappings":";;;AAEA,MAAM,uBAAuB;AAE7B,eAAsB,QAAQ,SAAkB,mBAA8B;CAC7E,MAAM,cAAc,QAAQ,QAAQ,IAAI,eAAe,IAAI;CAC3D,MAAM,wBAAwB,YAAY,aAAa;AAEvD,KAAI,CAAC,QAAQ,KACZ;AAID,KAAI,qBAAqB,kBAAkB,SAAS,GAWnD;MAAI,CAVc,kBAAkB,MAAM,YAAY;GAErD,MAAM,4BAA4B,sBAAsB,MAAM,IAAI,CAAC,GAAG,MAAM;GAC5E,MAAM,oBAAoB,QAAQ,aAAa,CAAC,MAAM;AACtD,UACC,8BAA8B,qBAC9B,0BAA0B,SAAS,kBAAkB;IAErD,EAEc;AACf,OAAI,CAAC,sBACJ,OAAM,IAAIA,uBAAS,KAAK;IACvB,SAAS,4CAA4C,kBAAkB,KAAK,KAAK;IACjF,MAAM;IACN,CAAC;AAEH,SAAM,IAAIA,uBAAS,KAAK;IACvB,SAAS,iBAAiB,YAAY,mCAAmC,kBAAkB,KAAK,KAAK;IACrG,MAAM;IACN,CAAC;;;AAIJ,KAAI,qBAAqB,KAAK,sBAAsB,CACnD,QAAO,MAAM,QAAQ,MAAM;AAG5B,KAAI,sBAAsB,SAAS,oCAAoC,EAAE;EACxE,MAAM,WAAW,MAAM,QAAQ,UAAU;EACzC,MAAMC,SAAiC,EAAE;AACzC,WAAS,SAAS,OAAO,QAAQ;AAChC,UAAO,OAAO,MAAM,UAAU;IAC7B;AACF,SAAO;;AAGR,KAAI,sBAAsB,SAAS,sBAAsB,EAAE;EAC1D,MAAM,WAAW,MAAM,QAAQ,UAAU;EACzC,MAAMC,SAA8B,EAAE;AACtC,WAAS,SAAS,OAAO,QAAQ;AAChC,UAAO,OAAO;IACb;AACF,SAAO;;AAGR,KAAI,sBAAsB,SAAS,aAAa,CAC/C,QAAO,MAAM,QAAQ,MAAM;AAG5B,KAAI,sBAAsB,SAAS,2BAA2B,CAC7D,QAAO,MAAM,QAAQ,aAAa;AAGnC,KACC,sBAAsB,SAAS,kBAAkB,IACjD,sBAAsB,SAAS,SAAS,IACxC,sBAAsB,SAAS,SAAS,CAGxC,QADa,MAAM,QAAQ,MAAM;AAIlC,KACC,sBAAsB,SAAS,qBAAqB,IACpD,QAAQ,gBAAgB,eAExB,QAAO,QAAQ;AAGhB,QAAO,MAAM,QAAQ,MAAM;;AAG5B,SAAgB,WAAW,OAA+B;AACzD,QAAO,iBAAiBF,0BAAY,OAAO,SAAS;;AAGrD,SAAgB,UAAU,KAAa;AACtC,KAAI;AACH,SAAO,IAAI,SAAS,IAAI,GAAG,mBAAmB,IAAI,GAAG;SAC9C;AACP,SAAO;;;AAgBT,eAAsB,SAAuB,SAA4C;AACxF,KAAI;AAEH,SAAO;GAAE,MADI,MAAM;GACJ,OAAO;GAAM;UACpB,OAAO;AACf,SAAO;GAAE,MAAM;GAAa;GAAY;;;;;;;;AAS1C,SAAgB,UAAU,KAA8B;AACvD,QAAO,eAAe,WAAW,OAAO,UAAU,SAAS,KAAK,IAAI,KAAK"}
|
package/dist/utils.mjs
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { APIError } from "./error.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/utils.ts
|
|
4
|
+
const jsonContentTypeRegex = /^application\/([a-z0-9.+-]*\+)?json/i;
|
|
5
|
+
async function getBody(request, allowedMediaTypes) {
|
|
6
|
+
const contentType = request.headers.get("content-type") || "";
|
|
7
|
+
const normalizedContentType = contentType.toLowerCase();
|
|
8
|
+
if (!request.body) return;
|
|
9
|
+
if (allowedMediaTypes && allowedMediaTypes.length > 0) {
|
|
10
|
+
if (!allowedMediaTypes.some((allowed) => {
|
|
11
|
+
const normalizedContentTypeBase = normalizedContentType.split(";")[0].trim();
|
|
12
|
+
const normalizedAllowed = allowed.toLowerCase().trim();
|
|
13
|
+
return normalizedContentTypeBase === normalizedAllowed || normalizedContentTypeBase.includes(normalizedAllowed);
|
|
14
|
+
})) {
|
|
15
|
+
if (!normalizedContentType) throw new APIError(415, {
|
|
16
|
+
message: `Content-Type is required. Allowed types: ${allowedMediaTypes.join(", ")}`,
|
|
17
|
+
code: "UNSUPPORTED_MEDIA_TYPE"
|
|
18
|
+
});
|
|
19
|
+
throw new APIError(415, {
|
|
20
|
+
message: `Content-Type "${contentType}" is not allowed. Allowed types: ${allowedMediaTypes.join(", ")}`,
|
|
21
|
+
code: "UNSUPPORTED_MEDIA_TYPE"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (jsonContentTypeRegex.test(normalizedContentType)) return await request.json();
|
|
26
|
+
if (normalizedContentType.includes("application/x-www-form-urlencoded")) {
|
|
27
|
+
const formData = await request.formData();
|
|
28
|
+
const result = {};
|
|
29
|
+
formData.forEach((value, key) => {
|
|
30
|
+
result[key] = value.toString();
|
|
31
|
+
});
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
if (normalizedContentType.includes("multipart/form-data")) {
|
|
35
|
+
const formData = await request.formData();
|
|
36
|
+
const result = {};
|
|
37
|
+
formData.forEach((value, key) => {
|
|
38
|
+
result[key] = value;
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
if (normalizedContentType.includes("text/plain")) return await request.text();
|
|
43
|
+
if (normalizedContentType.includes("application/octet-stream")) return await request.arrayBuffer();
|
|
44
|
+
if (normalizedContentType.includes("application/pdf") || normalizedContentType.includes("image/") || normalizedContentType.includes("video/")) return await request.blob();
|
|
45
|
+
if (normalizedContentType.includes("application/stream") || request.body instanceof ReadableStream) return request.body;
|
|
46
|
+
return await request.text();
|
|
47
|
+
}
|
|
48
|
+
function isAPIError(error) {
|
|
49
|
+
return error instanceof APIError || error?.name === "APIError";
|
|
50
|
+
}
|
|
51
|
+
function tryDecode(str) {
|
|
52
|
+
try {
|
|
53
|
+
return str.includes("%") ? decodeURIComponent(str) : str;
|
|
54
|
+
} catch {
|
|
55
|
+
return str;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function tryCatch(promise) {
|
|
59
|
+
try {
|
|
60
|
+
return {
|
|
61
|
+
data: await promise,
|
|
62
|
+
error: null
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
data: null,
|
|
67
|
+
error
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if an object is a `Request`
|
|
73
|
+
* - `instanceof`: works for native Request instances
|
|
74
|
+
* - `toString`: handles where instanceof check fails but the object is still a valid Request
|
|
75
|
+
*/
|
|
76
|
+
function isRequest(obj) {
|
|
77
|
+
return obj instanceof Request || Object.prototype.toString.call(obj) === "[object Request]";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
export { getBody, isAPIError, isRequest, tryCatch, tryDecode };
|
|
82
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["result: Record<string, string>","result: Record<string, any>"],"sources":["../src/utils.ts"],"sourcesContent":["import { APIError } from \"./error\";\n\nconst jsonContentTypeRegex = /^application\\/([a-z0-9.+-]*\\+)?json/i;\n\nexport async function getBody(request: Request, allowedMediaTypes?: string[]) {\n\tconst contentType = request.headers.get(\"content-type\") || \"\";\n\tconst normalizedContentType = contentType.toLowerCase();\n\n\tif (!request.body) {\n\t\treturn undefined;\n\t}\n\n\t// Validate content-type if allowedMediaTypes is provided\n\tif (allowedMediaTypes && allowedMediaTypes.length > 0) {\n\t\tconst isAllowed = allowedMediaTypes.some((allowed) => {\n\t\t\t// Normalize both content types for comparison\n\t\t\tconst normalizedContentTypeBase = normalizedContentType.split(\";\")[0].trim();\n\t\t\tconst normalizedAllowed = allowed.toLowerCase().trim();\n\t\t\treturn (\n\t\t\t\tnormalizedContentTypeBase === normalizedAllowed ||\n\t\t\t\tnormalizedContentTypeBase.includes(normalizedAllowed)\n\t\t\t);\n\t\t});\n\n\t\tif (!isAllowed) {\n\t\t\tif (!normalizedContentType) {\n\t\t\t\tthrow new APIError(415, {\n\t\t\t\t\tmessage: `Content-Type is required. Allowed types: ${allowedMediaTypes.join(\", \")}`,\n\t\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow new APIError(415, {\n\t\t\t\tmessage: `Content-Type \"${contentType}\" is not allowed. Allowed types: ${allowedMediaTypes.join(\", \")}`,\n\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\",\n\t\t\t});\n\t\t}\n\t}\n\n\tif (jsonContentTypeRegex.test(normalizedContentType)) {\n\t\treturn await request.json();\n\t}\n\n\tif (normalizedContentType.includes(\"application/x-www-form-urlencoded\")) {\n\t\tconst formData = await request.formData();\n\t\tconst result: Record<string, string> = {};\n\t\tformData.forEach((value, key) => {\n\t\t\tresult[key] = value.toString();\n\t\t});\n\t\treturn result;\n\t}\n\n\tif (normalizedContentType.includes(\"multipart/form-data\")) {\n\t\tconst formData = await request.formData();\n\t\tconst result: Record<string, any> = {};\n\t\tformData.forEach((value, key) => {\n\t\t\tresult[key] = value;\n\t\t});\n\t\treturn result;\n\t}\n\n\tif (normalizedContentType.includes(\"text/plain\")) {\n\t\treturn await request.text();\n\t}\n\n\tif (normalizedContentType.includes(\"application/octet-stream\")) {\n\t\treturn await request.arrayBuffer();\n\t}\n\n\tif (\n\t\tnormalizedContentType.includes(\"application/pdf\") ||\n\t\tnormalizedContentType.includes(\"image/\") ||\n\t\tnormalizedContentType.includes(\"video/\")\n\t) {\n\t\tconst blob = await request.blob();\n\t\treturn blob;\n\t}\n\n\tif (\n\t\tnormalizedContentType.includes(\"application/stream\") ||\n\t\trequest.body instanceof ReadableStream\n\t) {\n\t\treturn request.body;\n\t}\n\n\treturn await request.text();\n}\n\nexport function isAPIError(error: any): error is APIError {\n\treturn error instanceof APIError || error?.name === \"APIError\";\n}\n\nexport function tryDecode(str: string) {\n\ttry {\n\t\treturn str.includes(\"%\") ? decodeURIComponent(str) : str;\n\t} catch {\n\t\treturn str;\n\t}\n}\n\ntype Success<T> = {\n\tdata: T;\n\terror: null;\n};\n\ntype Failure<E> = {\n\tdata: null;\n\terror: E;\n};\n\ntype Result<T, E = Error> = Success<T> | Failure<E>;\n\nexport async function tryCatch<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>> {\n\ttry {\n\t\tconst data = await promise;\n\t\treturn { data, error: null };\n\t} catch (error) {\n\t\treturn { data: null, error: error as E };\n\t}\n}\n\n/**\n * Check if an object is a `Request`\n * - `instanceof`: works for native Request instances\n * - `toString`: handles where instanceof check fails but the object is still a valid Request\n */\nexport function isRequest(obj: unknown): obj is Request {\n\treturn obj instanceof Request || Object.prototype.toString.call(obj) === \"[object Request]\";\n}\n"],"mappings":";;;AAEA,MAAM,uBAAuB;AAE7B,eAAsB,QAAQ,SAAkB,mBAA8B;CAC7E,MAAM,cAAc,QAAQ,QAAQ,IAAI,eAAe,IAAI;CAC3D,MAAM,wBAAwB,YAAY,aAAa;AAEvD,KAAI,CAAC,QAAQ,KACZ;AAID,KAAI,qBAAqB,kBAAkB,SAAS,GAWnD;MAAI,CAVc,kBAAkB,MAAM,YAAY;GAErD,MAAM,4BAA4B,sBAAsB,MAAM,IAAI,CAAC,GAAG,MAAM;GAC5E,MAAM,oBAAoB,QAAQ,aAAa,CAAC,MAAM;AACtD,UACC,8BAA8B,qBAC9B,0BAA0B,SAAS,kBAAkB;IAErD,EAEc;AACf,OAAI,CAAC,sBACJ,OAAM,IAAI,SAAS,KAAK;IACvB,SAAS,4CAA4C,kBAAkB,KAAK,KAAK;IACjF,MAAM;IACN,CAAC;AAEH,SAAM,IAAI,SAAS,KAAK;IACvB,SAAS,iBAAiB,YAAY,mCAAmC,kBAAkB,KAAK,KAAK;IACrG,MAAM;IACN,CAAC;;;AAIJ,KAAI,qBAAqB,KAAK,sBAAsB,CACnD,QAAO,MAAM,QAAQ,MAAM;AAG5B,KAAI,sBAAsB,SAAS,oCAAoC,EAAE;EACxE,MAAM,WAAW,MAAM,QAAQ,UAAU;EACzC,MAAMA,SAAiC,EAAE;AACzC,WAAS,SAAS,OAAO,QAAQ;AAChC,UAAO,OAAO,MAAM,UAAU;IAC7B;AACF,SAAO;;AAGR,KAAI,sBAAsB,SAAS,sBAAsB,EAAE;EAC1D,MAAM,WAAW,MAAM,QAAQ,UAAU;EACzC,MAAMC,SAA8B,EAAE;AACtC,WAAS,SAAS,OAAO,QAAQ;AAChC,UAAO,OAAO;IACb;AACF,SAAO;;AAGR,KAAI,sBAAsB,SAAS,aAAa,CAC/C,QAAO,MAAM,QAAQ,MAAM;AAG5B,KAAI,sBAAsB,SAAS,2BAA2B,CAC7D,QAAO,MAAM,QAAQ,aAAa;AAGnC,KACC,sBAAsB,SAAS,kBAAkB,IACjD,sBAAsB,SAAS,SAAS,IACxC,sBAAsB,SAAS,SAAS,CAGxC,QADa,MAAM,QAAQ,MAAM;AAIlC,KACC,sBAAsB,SAAS,qBAAqB,IACpD,QAAQ,gBAAgB,eAExB,QAAO,QAAQ;AAGhB,QAAO,MAAM,QAAQ,MAAM;;AAG5B,SAAgB,WAAW,OAA+B;AACzD,QAAO,iBAAiB,YAAY,OAAO,SAAS;;AAGrD,SAAgB,UAAU,KAAa;AACtC,KAAI;AACH,SAAO,IAAI,SAAS,IAAI,GAAG,mBAAmB,IAAI,GAAG;SAC9C;AACP,SAAO;;;AAgBT,eAAsB,SAAuB,SAA4C;AACxF,KAAI;AAEH,SAAO;GAAE,MADI,MAAM;GACJ,OAAO;GAAM;UACpB,OAAO;AACf,SAAO;GAAE,MAAM;GAAa;GAAY;;;;;;;;AAS1C,SAAgB,UAAU,KAA8B;AACvD,QAAO,eAAe,WAAW,OAAO,UAAU,SAAS,KAAK,IAAI,KAAK"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/validator.ts
|
|
3
|
+
/**
|
|
4
|
+
* Runs validation on body and query
|
|
5
|
+
* @returns error and data object
|
|
6
|
+
*/
|
|
7
|
+
async function runValidation(options, context = {}) {
|
|
8
|
+
let request = {
|
|
9
|
+
body: context.body,
|
|
10
|
+
query: context.query
|
|
11
|
+
};
|
|
12
|
+
if (options.body) {
|
|
13
|
+
const result = await options.body["~standard"].validate(context.body);
|
|
14
|
+
if (result.issues) return {
|
|
15
|
+
data: null,
|
|
16
|
+
error: fromError(result.issues, "body")
|
|
17
|
+
};
|
|
18
|
+
request.body = result.value;
|
|
19
|
+
}
|
|
20
|
+
if (options.query) {
|
|
21
|
+
const result = await options.query["~standard"].validate(context.query);
|
|
22
|
+
if (result.issues) return {
|
|
23
|
+
data: null,
|
|
24
|
+
error: fromError(result.issues, "query")
|
|
25
|
+
};
|
|
26
|
+
request.query = result.value;
|
|
27
|
+
}
|
|
28
|
+
if (options.requireHeaders && !context.headers) return {
|
|
29
|
+
data: null,
|
|
30
|
+
error: {
|
|
31
|
+
message: "Headers is required",
|
|
32
|
+
issues: []
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
if (options.requireRequest && !context.request) return {
|
|
36
|
+
data: null,
|
|
37
|
+
error: {
|
|
38
|
+
message: "Request is required",
|
|
39
|
+
issues: []
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
data: request,
|
|
44
|
+
error: null
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function fromError(error, validating) {
|
|
48
|
+
return {
|
|
49
|
+
message: error.map((e) => {
|
|
50
|
+
return `[${e.path?.length ? `${validating}.` + e.path.map((x) => typeof x === "object" ? x.key : x).join(".") : validating}] ${e.message}`;
|
|
51
|
+
}).join("; "),
|
|
52
|
+
issues: error
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
exports.runValidation = runValidation;
|
|
58
|
+
//# sourceMappingURL=validator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.cjs","names":[],"sources":["../src/validator.ts"],"sourcesContent":["import type { EndpointOptions } from \"./endpoint\";\nimport type { InputContext } from \"./context\";\nimport type { StandardSchemaV1 } from \"./standard-schema\";\n\ntype ValidationResponse =\n\t| {\n\t\t\tdata: {\n\t\t\t\tbody: any;\n\t\t\t\tquery: any;\n\t\t\t};\n\t\t\terror: null;\n\t }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: {\n\t\t\t\tmessage: string;\n\t\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\t};\n\t };\n\n/**\n * Runs validation on body and query\n * @returns error and data object\n */\nexport async function runValidation(\n\toptions: EndpointOptions,\n\tcontext: InputContext<any, any> = {},\n): Promise<ValidationResponse> {\n\tlet request = {\n\t\tbody: context.body,\n\t\tquery: context.query,\n\t} as {\n\t\tbody: any;\n\t\tquery: any;\n\t};\n\tif (options.body) {\n\t\tconst result = await options.body[\"~standard\"].validate(context.body);\n\t\tif (result.issues) {\n\t\t\treturn {\n\t\t\t\tdata: null,\n\t\t\t\terror: fromError(result.issues, \"body\"),\n\t\t\t};\n\t\t}\n\t\trequest.body = result.value;\n\t}\n\n\tif (options.query) {\n\t\tconst result = await options.query[\"~standard\"].validate(context.query);\n\t\tif (result.issues) {\n\t\t\treturn {\n\t\t\t\tdata: null,\n\t\t\t\terror: fromError(result.issues, \"query\"),\n\t\t\t};\n\t\t}\n\t\trequest.query = result.value;\n\t}\n\tif (options.requireHeaders && !context.headers) {\n\t\treturn {\n\t\t\tdata: null,\n\t\t\terror: { message: \"Headers is required\", issues: [] },\n\t\t};\n\t}\n\tif (options.requireRequest && !context.request) {\n\t\treturn {\n\t\t\tdata: null,\n\t\t\terror: { message: \"Request is required\", issues: [] },\n\t\t};\n\t}\n\treturn {\n\t\tdata: request,\n\t\terror: null,\n\t};\n}\n\nfunction fromError(error: readonly StandardSchemaV1.Issue[], validating: string) {\n\tconst message = error\n\t\t.map((e) => {\n\t\t\treturn `[${e.path?.length ? `${validating}.` + e.path.map((x) => (typeof x === \"object\" ? x.key : x)).join(\".\") : validating}] ${e.message}`;\n\t\t})\n\t\t.join(\"; \");\n\n\treturn {\n\t\tmessage,\n\t\tissues: error,\n\t};\n}\n"],"mappings":";;;;;;AAwBA,eAAsB,cACrB,SACA,UAAkC,EAAE,EACN;CAC9B,IAAI,UAAU;EACb,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf;AAID,KAAI,QAAQ,MAAM;EACjB,MAAM,SAAS,MAAM,QAAQ,KAAK,aAAa,SAAS,QAAQ,KAAK;AACrE,MAAI,OAAO,OACV,QAAO;GACN,MAAM;GACN,OAAO,UAAU,OAAO,QAAQ,OAAO;GACvC;AAEF,UAAQ,OAAO,OAAO;;AAGvB,KAAI,QAAQ,OAAO;EAClB,MAAM,SAAS,MAAM,QAAQ,MAAM,aAAa,SAAS,QAAQ,MAAM;AACvE,MAAI,OAAO,OACV,QAAO;GACN,MAAM;GACN,OAAO,UAAU,OAAO,QAAQ,QAAQ;GACxC;AAEF,UAAQ,QAAQ,OAAO;;AAExB,KAAI,QAAQ,kBAAkB,CAAC,QAAQ,QACtC,QAAO;EACN,MAAM;EACN,OAAO;GAAE,SAAS;GAAuB,QAAQ,EAAE;GAAE;EACrD;AAEF,KAAI,QAAQ,kBAAkB,CAAC,QAAQ,QACtC,QAAO;EACN,MAAM;EACN,OAAO;GAAE,SAAS;GAAuB,QAAQ,EAAE;GAAE;EACrD;AAEF,QAAO;EACN,MAAM;EACN,OAAO;EACP;;AAGF,SAAS,UAAU,OAA0C,YAAoB;AAOhF,QAAO;EACN,SAPe,MACd,KAAK,MAAM;AACX,UAAO,IAAI,EAAE,MAAM,SAAS,GAAG,WAAW,KAAK,EAAE,KAAK,KAAK,MAAO,OAAO,MAAM,WAAW,EAAE,MAAM,EAAG,CAAC,KAAK,IAAI,GAAG,WAAW,IAAI,EAAE;IAClI,CACD,KAAK,KAAK;EAIX,QAAQ;EACR"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//#region src/validator.ts
|
|
2
|
+
/**
|
|
3
|
+
* Runs validation on body and query
|
|
4
|
+
* @returns error and data object
|
|
5
|
+
*/
|
|
6
|
+
async function runValidation(options, context = {}) {
|
|
7
|
+
let request = {
|
|
8
|
+
body: context.body,
|
|
9
|
+
query: context.query
|
|
10
|
+
};
|
|
11
|
+
if (options.body) {
|
|
12
|
+
const result = await options.body["~standard"].validate(context.body);
|
|
13
|
+
if (result.issues) return {
|
|
14
|
+
data: null,
|
|
15
|
+
error: fromError(result.issues, "body")
|
|
16
|
+
};
|
|
17
|
+
request.body = result.value;
|
|
18
|
+
}
|
|
19
|
+
if (options.query) {
|
|
20
|
+
const result = await options.query["~standard"].validate(context.query);
|
|
21
|
+
if (result.issues) return {
|
|
22
|
+
data: null,
|
|
23
|
+
error: fromError(result.issues, "query")
|
|
24
|
+
};
|
|
25
|
+
request.query = result.value;
|
|
26
|
+
}
|
|
27
|
+
if (options.requireHeaders && !context.headers) return {
|
|
28
|
+
data: null,
|
|
29
|
+
error: {
|
|
30
|
+
message: "Headers is required",
|
|
31
|
+
issues: []
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
if (options.requireRequest && !context.request) return {
|
|
35
|
+
data: null,
|
|
36
|
+
error: {
|
|
37
|
+
message: "Request is required",
|
|
38
|
+
issues: []
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
data: request,
|
|
43
|
+
error: null
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function fromError(error, validating) {
|
|
47
|
+
return {
|
|
48
|
+
message: error.map((e) => {
|
|
49
|
+
return `[${e.path?.length ? `${validating}.` + e.path.map((x) => typeof x === "object" ? x.key : x).join(".") : validating}] ${e.message}`;
|
|
50
|
+
}).join("; "),
|
|
51
|
+
issues: error
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { runValidation };
|
|
57
|
+
//# sourceMappingURL=validator.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.mjs","names":[],"sources":["../src/validator.ts"],"sourcesContent":["import type { EndpointOptions } from \"./endpoint\";\nimport type { InputContext } from \"./context\";\nimport type { StandardSchemaV1 } from \"./standard-schema\";\n\ntype ValidationResponse =\n\t| {\n\t\t\tdata: {\n\t\t\t\tbody: any;\n\t\t\t\tquery: any;\n\t\t\t};\n\t\t\terror: null;\n\t }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: {\n\t\t\t\tmessage: string;\n\t\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\t};\n\t };\n\n/**\n * Runs validation on body and query\n * @returns error and data object\n */\nexport async function runValidation(\n\toptions: EndpointOptions,\n\tcontext: InputContext<any, any> = {},\n): Promise<ValidationResponse> {\n\tlet request = {\n\t\tbody: context.body,\n\t\tquery: context.query,\n\t} as {\n\t\tbody: any;\n\t\tquery: any;\n\t};\n\tif (options.body) {\n\t\tconst result = await options.body[\"~standard\"].validate(context.body);\n\t\tif (result.issues) {\n\t\t\treturn {\n\t\t\t\tdata: null,\n\t\t\t\terror: fromError(result.issues, \"body\"),\n\t\t\t};\n\t\t}\n\t\trequest.body = result.value;\n\t}\n\n\tif (options.query) {\n\t\tconst result = await options.query[\"~standard\"].validate(context.query);\n\t\tif (result.issues) {\n\t\t\treturn {\n\t\t\t\tdata: null,\n\t\t\t\terror: fromError(result.issues, \"query\"),\n\t\t\t};\n\t\t}\n\t\trequest.query = result.value;\n\t}\n\tif (options.requireHeaders && !context.headers) {\n\t\treturn {\n\t\t\tdata: null,\n\t\t\terror: { message: \"Headers is required\", issues: [] },\n\t\t};\n\t}\n\tif (options.requireRequest && !context.request) {\n\t\treturn {\n\t\t\tdata: null,\n\t\t\terror: { message: \"Request is required\", issues: [] },\n\t\t};\n\t}\n\treturn {\n\t\tdata: request,\n\t\terror: null,\n\t};\n}\n\nfunction fromError(error: readonly StandardSchemaV1.Issue[], validating: string) {\n\tconst message = error\n\t\t.map((e) => {\n\t\t\treturn `[${e.path?.length ? `${validating}.` + e.path.map((x) => (typeof x === \"object\" ? x.key : x)).join(\".\") : validating}] ${e.message}`;\n\t\t})\n\t\t.join(\"; \");\n\n\treturn {\n\t\tmessage,\n\t\tissues: error,\n\t};\n}\n"],"mappings":";;;;;AAwBA,eAAsB,cACrB,SACA,UAAkC,EAAE,EACN;CAC9B,IAAI,UAAU;EACb,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf;AAID,KAAI,QAAQ,MAAM;EACjB,MAAM,SAAS,MAAM,QAAQ,KAAK,aAAa,SAAS,QAAQ,KAAK;AACrE,MAAI,OAAO,OACV,QAAO;GACN,MAAM;GACN,OAAO,UAAU,OAAO,QAAQ,OAAO;GACvC;AAEF,UAAQ,OAAO,OAAO;;AAGvB,KAAI,QAAQ,OAAO;EAClB,MAAM,SAAS,MAAM,QAAQ,MAAM,aAAa,SAAS,QAAQ,MAAM;AACvE,MAAI,OAAO,OACV,QAAO;GACN,MAAM;GACN,OAAO,UAAU,OAAO,QAAQ,QAAQ;GACxC;AAEF,UAAQ,QAAQ,OAAO;;AAExB,KAAI,QAAQ,kBAAkB,CAAC,QAAQ,QACtC,QAAO;EACN,MAAM;EACN,OAAO;GAAE,SAAS;GAAuB,QAAQ,EAAE;GAAE;EACrD;AAEF,KAAI,QAAQ,kBAAkB,CAAC,QAAQ,QACtC,QAAO;EACN,MAAM;EACN,OAAO;GAAE,SAAS;GAAuB,QAAQ,EAAE;GAAE;EACrD;AAEF,QAAO;EACN,MAAM;EACN,OAAO;EACP;;AAGF,SAAS,UAAU,OAA0C,YAAoB;AAOhF,QAAO;EACN,SAPe,MACd,KAAK,MAAM;AACX,UAAO,IAAI,EAAE,MAAM,SAAS,GAAG,WAAW,KAAK,EAAE,KAAK,KAAK,MAAO,OAAO,MAAM,WAAW,EAAE,MAAM,EAAG,CAAC,KAAK,IAAI,GAAG,WAAW,IAAI,EAAE;IAClI,CACD,KAAK,KAAK;EAIX,QAAQ;EACR"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "better-call",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "https://github.com/
|
|
7
|
+
"url": "git+https://github.com/better-auth/better-call.git"
|
|
8
8
|
},
|
|
9
9
|
"copyright": "Copyright (C) 2025 Bereket Engida",
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"main": "./dist/index.
|
|
12
|
-
"module": "./dist/index.
|
|
13
|
-
"types": "./dist/index.d.
|
|
11
|
+
"main": "./dist/index.mjs",
|
|
12
|
+
"module": "./dist/index.mjs",
|
|
13
|
+
"types": "./dist/index.d.mts",
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
16
16
|
"@biomejs/biome": "^1.8.3",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"knip": "^5.71.0",
|
|
28
28
|
"publint": "^0.3.15",
|
|
29
29
|
"supertest": "^7.1.4",
|
|
30
|
-
"tsdown": "^0.
|
|
31
|
-
"typescript": "^5.
|
|
30
|
+
"tsdown": "^0.18.0",
|
|
31
|
+
"typescript": "^5.9.3",
|
|
32
32
|
"valibot": "1.0.0-beta.15",
|
|
33
33
|
"vitest": "^3.1.1"
|
|
34
34
|
},
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"exports": {
|
|
50
50
|
".": {
|
|
51
51
|
"import": {
|
|
52
|
-
"types": "./dist/index.d.
|
|
53
|
-
"default": "./dist/index.
|
|
52
|
+
"types": "./dist/index.d.mts",
|
|
53
|
+
"default": "./dist/index.mjs"
|
|
54
54
|
},
|
|
55
55
|
"require": {
|
|
56
56
|
"types": "./dist/index.d.cts",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
},
|
|
60
60
|
"./client": {
|
|
61
61
|
"import": {
|
|
62
|
-
"types": "./dist/client.d.
|
|
63
|
-
"default": "./dist/client.
|
|
62
|
+
"types": "./dist/client.d.mts",
|
|
63
|
+
"default": "./dist/client.mjs"
|
|
64
64
|
},
|
|
65
65
|
"require": {
|
|
66
66
|
"types": "./dist/client.d.cts",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
},
|
|
70
70
|
"./error": {
|
|
71
71
|
"import": {
|
|
72
|
-
"types": "./dist/error.d.
|
|
73
|
-
"default": "./dist/error.
|
|
72
|
+
"types": "./dist/error.d.mts",
|
|
73
|
+
"default": "./dist/error.mjs"
|
|
74
74
|
},
|
|
75
75
|
"require": {
|
|
76
76
|
"types": "./dist/error.d.cts",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
},
|
|
80
80
|
"./node": {
|
|
81
81
|
"import": {
|
|
82
|
-
"types": "./dist/node.d.
|
|
83
|
-
"default": "./dist/node.
|
|
82
|
+
"types": "./dist/node.d.mts",
|
|
83
|
+
"default": "./dist/node.mjs"
|
|
84
84
|
},
|
|
85
85
|
"require": {
|
|
86
86
|
"types": "./dist/node.d.cts",
|
package/dist/client.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { et as UnionToIntersection, i as Endpoint, q as HasRequiredKeys, t as Router } from "./router.js";
|
|
2
|
-
import { a as hideInternalStackFrames, i as ValidationError, n as BetterCallError, o as makeErrorForHideStackFrame, r as Status, s as statusCodes, t as APIError } from "./error2.js";
|
|
3
|
-
import { BetterFetchOption, BetterFetchResponse } from "@better-fetch/fetch";
|
|
4
|
-
|
|
5
|
-
//#region src/client.d.ts
|
|
6
|
-
type HasRequired<T extends {
|
|
7
|
-
body?: any;
|
|
8
|
-
query?: any;
|
|
9
|
-
params?: any;
|
|
10
|
-
}> = 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;
|
|
11
|
-
type InferContext<T> = T extends ((ctx: infer Ctx) => any) ? Ctx extends object ? Ctx : never : never;
|
|
12
|
-
interface ClientOptions extends BetterFetchOption {
|
|
13
|
-
baseURL: string;
|
|
14
|
-
}
|
|
15
|
-
type WithRequired<T, K> = T & { [P in K extends string ? K : never]-?: T[P extends keyof T ? P : never] };
|
|
16
|
-
type InferClientRoutes<T extends Record<string, Endpoint>> = { [K in keyof T]: T[K] extends Endpoint<any, infer O> ? O extends {
|
|
17
|
-
metadata: {
|
|
18
|
-
scope: "http";
|
|
19
|
-
};
|
|
20
|
-
} | {
|
|
21
|
-
metadata: {
|
|
22
|
-
scope: "server";
|
|
23
|
-
};
|
|
24
|
-
} | {
|
|
25
|
-
metadata: {
|
|
26
|
-
SERVER_ONLY: true;
|
|
27
|
-
};
|
|
28
|
-
} | {
|
|
29
|
-
metadata: {
|
|
30
|
-
isAction: false;
|
|
31
|
-
};
|
|
32
|
-
} ? never : T[K] : T[K] };
|
|
33
|
-
type RequiredOptionKeys<C extends {
|
|
34
|
-
body?: any;
|
|
35
|
-
query?: any;
|
|
36
|
-
params?: any;
|
|
37
|
-
}> = (undefined extends C["body"] ? {} : {
|
|
38
|
-
body: true;
|
|
39
|
-
}) & (undefined extends C["query"] ? {} : {
|
|
40
|
-
query: true;
|
|
41
|
-
}) & (undefined extends C["params"] ? {} : {
|
|
42
|
-
params: true;
|
|
43
|
-
});
|
|
44
|
-
declare const createClient: <R extends Router | Router["endpoints"]>(options: ClientOptions) => <OPT extends (UnionToIntersection<InferClientRoutes<R extends {
|
|
45
|
-
endpoints: Record<string, Endpoint>;
|
|
46
|
-
} ? R["endpoints"] : R> extends {
|
|
47
|
-
[key: string]: infer T_1;
|
|
48
|
-
} ? 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]: UnionToIntersection<InferClientRoutes<R extends {
|
|
49
|
-
endpoints: Record<string, Endpoint>;
|
|
50
|
-
} ? R["endpoints"] : R> extends {
|
|
51
|
-
[key: string]: infer T_1;
|
|
52
|
-
} ? 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 } : {} : {}>[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>>>>;
|
|
53
|
-
//#endregion
|
|
54
|
-
export { APIError, BetterCallError, ClientOptions, RequiredOptionKeys, Status, ValidationError, createClient, hideInternalStackFrames, makeErrorForHideStackFrame, statusCodes };
|
|
55
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["options"],"sources":["../src/client.ts"],"sourcesContent":["import { type BetterFetchOption, type BetterFetchResponse, createFetch } 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\"]>(options: ClientOptions) => {\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 <OPT extends O, K extends keyof OPT, C extends InferContext<OPT[K]>>(\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<Awaited<ReturnType<OPT[K] extends Endpoint ? OPT[K] : never>>>\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":";;;;AAiFA,MAAa,gBAAwD,YAA2B;CAC/F,MAAM,QAAQ,YAAY,QAAQ;AAiBlC,QAAO,OACN,MACA,GAAGA,cAUC;AACJ,SAAQ,MAAM,MAAM,MAAgB,EACnC,GAAGA,UAAQ,IACX,CAAC"}
|
package/dist/error.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { a as hideInternalStackFrames, i as ValidationError, n as BetterCallError, o as makeErrorForHideStackFrame, r as Status, s as statusCodes, t as APIError } from "./error2.js";
|
|
2
|
-
export { APIError, BetterCallError, Status, ValidationError, hideInternalStackFrames, makeErrorForHideStackFrame, statusCodes };
|
package/dist/error.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { a as makeErrorForHideStackFrame, i as hideInternalStackFrames, n as BetterCallError, o as statusCodes, r as ValidationError, t as APIError } from "./error2.js";
|
|
2
|
-
|
|
3
|
-
export { APIError, BetterCallError, ValidationError, hideInternalStackFrames, makeErrorForHideStackFrame, statusCodes };
|
package/dist/error2.cjs
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/error.ts
|
|
3
|
-
function isErrorStackTraceLimitWritable() {
|
|
4
|
-
const desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit");
|
|
5
|
-
if (desc === void 0) return Object.isExtensible(Error);
|
|
6
|
-
return Object.prototype.hasOwnProperty.call(desc, "writable") ? desc.writable : desc.set !== void 0;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Hide internal stack frames from the error stack trace.
|
|
10
|
-
*/
|
|
11
|
-
function hideInternalStackFrames(stack) {
|
|
12
|
-
const lines = stack.split("\n at ");
|
|
13
|
-
if (lines.length <= 1) return stack;
|
|
14
|
-
lines.splice(1, 1);
|
|
15
|
-
return lines.join("\n at ");
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Creates a custom error class that hides stack frames.
|
|
19
|
-
*/
|
|
20
|
-
function makeErrorForHideStackFrame(Base, clazz) {
|
|
21
|
-
class HideStackFramesError extends Base {
|
|
22
|
-
#hiddenStack;
|
|
23
|
-
constructor(...args) {
|
|
24
|
-
if (isErrorStackTraceLimitWritable()) {
|
|
25
|
-
const limit = Error.stackTraceLimit;
|
|
26
|
-
Error.stackTraceLimit = 0;
|
|
27
|
-
super(...args);
|
|
28
|
-
Error.stackTraceLimit = limit;
|
|
29
|
-
} else super(...args);
|
|
30
|
-
const stack = (/* @__PURE__ */ new Error()).stack;
|
|
31
|
-
if (stack) this.#hiddenStack = hideInternalStackFrames(stack.replace(/^Error/, this.name));
|
|
32
|
-
}
|
|
33
|
-
get errorStack() {
|
|
34
|
-
return this.#hiddenStack;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
Object.defineProperty(HideStackFramesError.prototype, "constructor", {
|
|
38
|
-
get() {
|
|
39
|
-
return clazz;
|
|
40
|
-
},
|
|
41
|
-
enumerable: false,
|
|
42
|
-
configurable: true
|
|
43
|
-
});
|
|
44
|
-
return HideStackFramesError;
|
|
45
|
-
}
|
|
46
|
-
const statusCodes = {
|
|
47
|
-
OK: 200,
|
|
48
|
-
CREATED: 201,
|
|
49
|
-
ACCEPTED: 202,
|
|
50
|
-
NO_CONTENT: 204,
|
|
51
|
-
MULTIPLE_CHOICES: 300,
|
|
52
|
-
MOVED_PERMANENTLY: 301,
|
|
53
|
-
FOUND: 302,
|
|
54
|
-
SEE_OTHER: 303,
|
|
55
|
-
NOT_MODIFIED: 304,
|
|
56
|
-
TEMPORARY_REDIRECT: 307,
|
|
57
|
-
BAD_REQUEST: 400,
|
|
58
|
-
UNAUTHORIZED: 401,
|
|
59
|
-
PAYMENT_REQUIRED: 402,
|
|
60
|
-
FORBIDDEN: 403,
|
|
61
|
-
NOT_FOUND: 404,
|
|
62
|
-
METHOD_NOT_ALLOWED: 405,
|
|
63
|
-
NOT_ACCEPTABLE: 406,
|
|
64
|
-
PROXY_AUTHENTICATION_REQUIRED: 407,
|
|
65
|
-
REQUEST_TIMEOUT: 408,
|
|
66
|
-
CONFLICT: 409,
|
|
67
|
-
GONE: 410,
|
|
68
|
-
LENGTH_REQUIRED: 411,
|
|
69
|
-
PRECONDITION_FAILED: 412,
|
|
70
|
-
PAYLOAD_TOO_LARGE: 413,
|
|
71
|
-
URI_TOO_LONG: 414,
|
|
72
|
-
UNSUPPORTED_MEDIA_TYPE: 415,
|
|
73
|
-
RANGE_NOT_SATISFIABLE: 416,
|
|
74
|
-
EXPECTATION_FAILED: 417,
|
|
75
|
-
"I'M_A_TEAPOT": 418,
|
|
76
|
-
MISDIRECTED_REQUEST: 421,
|
|
77
|
-
UNPROCESSABLE_ENTITY: 422,
|
|
78
|
-
LOCKED: 423,
|
|
79
|
-
FAILED_DEPENDENCY: 424,
|
|
80
|
-
TOO_EARLY: 425,
|
|
81
|
-
UPGRADE_REQUIRED: 426,
|
|
82
|
-
PRECONDITION_REQUIRED: 428,
|
|
83
|
-
TOO_MANY_REQUESTS: 429,
|
|
84
|
-
REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
|
85
|
-
UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
|
86
|
-
INTERNAL_SERVER_ERROR: 500,
|
|
87
|
-
NOT_IMPLEMENTED: 501,
|
|
88
|
-
BAD_GATEWAY: 502,
|
|
89
|
-
SERVICE_UNAVAILABLE: 503,
|
|
90
|
-
GATEWAY_TIMEOUT: 504,
|
|
91
|
-
HTTP_VERSION_NOT_SUPPORTED: 505,
|
|
92
|
-
VARIANT_ALSO_NEGOTIATES: 506,
|
|
93
|
-
INSUFFICIENT_STORAGE: 507,
|
|
94
|
-
LOOP_DETECTED: 508,
|
|
95
|
-
NOT_EXTENDED: 510,
|
|
96
|
-
NETWORK_AUTHENTICATION_REQUIRED: 511
|
|
97
|
-
};
|
|
98
|
-
var InternalAPIError = class extends Error {
|
|
99
|
-
constructor(status = "INTERNAL_SERVER_ERROR", body = void 0, headers = {}, statusCode = typeof status === "number" ? status : statusCodes[status]) {
|
|
100
|
-
super(body?.message, body?.cause ? { cause: body.cause } : void 0);
|
|
101
|
-
this.status = status;
|
|
102
|
-
this.body = body;
|
|
103
|
-
this.headers = headers;
|
|
104
|
-
this.statusCode = statusCode;
|
|
105
|
-
this.name = "APIError";
|
|
106
|
-
this.status = status;
|
|
107
|
-
this.headers = headers;
|
|
108
|
-
this.statusCode = statusCode;
|
|
109
|
-
this.body = body ? {
|
|
110
|
-
code: body?.message?.toUpperCase().replace(/ /g, "_").replace(/[^A-Z0-9_]/g, ""),
|
|
111
|
-
...body
|
|
112
|
-
} : void 0;
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
var ValidationError = class extends InternalAPIError {
|
|
116
|
-
constructor(message, issues) {
|
|
117
|
-
super(400, {
|
|
118
|
-
message,
|
|
119
|
-
code: "VALIDATION_ERROR"
|
|
120
|
-
});
|
|
121
|
-
this.message = message;
|
|
122
|
-
this.issues = issues;
|
|
123
|
-
this.issues = issues;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
var BetterCallError = class extends Error {
|
|
127
|
-
constructor(message) {
|
|
128
|
-
super(message);
|
|
129
|
-
this.name = "BetterCallError";
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
const APIError = makeErrorForHideStackFrame(InternalAPIError, Error);
|
|
133
|
-
|
|
134
|
-
//#endregion
|
|
135
|
-
Object.defineProperty(exports, 'APIError', {
|
|
136
|
-
enumerable: true,
|
|
137
|
-
get: function () {
|
|
138
|
-
return APIError;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
Object.defineProperty(exports, 'BetterCallError', {
|
|
142
|
-
enumerable: true,
|
|
143
|
-
get: function () {
|
|
144
|
-
return BetterCallError;
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
Object.defineProperty(exports, 'ValidationError', {
|
|
148
|
-
enumerable: true,
|
|
149
|
-
get: function () {
|
|
150
|
-
return ValidationError;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
Object.defineProperty(exports, 'hideInternalStackFrames', {
|
|
154
|
-
enumerable: true,
|
|
155
|
-
get: function () {
|
|
156
|
-
return hideInternalStackFrames;
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
Object.defineProperty(exports, 'makeErrorForHideStackFrame', {
|
|
160
|
-
enumerable: true,
|
|
161
|
-
get: function () {
|
|
162
|
-
return makeErrorForHideStackFrame;
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
Object.defineProperty(exports, 'statusCodes', {
|
|
166
|
-
enumerable: true,
|
|
167
|
-
get: function () {
|
|
168
|
-
return statusCodes;
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
//# sourceMappingURL=error2.cjs.map
|