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.
Files changed (102) hide show
  1. package/README.md +35 -0
  2. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  3. package/dist/adapters/node/request.cjs +125 -0
  4. package/dist/adapters/node/request.cjs.map +1 -0
  5. package/dist/{node.d.ts → adapters/node/request.d.cts} +2 -6
  6. package/dist/adapters/node/request.d.mts +16 -0
  7. package/dist/{node.js → adapters/node/request.mjs} +2 -13
  8. package/dist/adapters/node/request.mjs.map +1 -0
  9. package/dist/client.cjs +3 -3
  10. package/dist/client.cjs.map +1 -1
  11. package/dist/client.d.cts +13 -15
  12. package/dist/client.d.mts +53 -0
  13. package/dist/{client.js → client.mjs} +3 -3
  14. package/dist/client.mjs.map +1 -0
  15. package/dist/context.cjs +103 -0
  16. package/dist/context.cjs.map +1 -0
  17. package/dist/context.d.cts +340 -0
  18. package/dist/context.d.mts +340 -0
  19. package/dist/context.mjs +103 -0
  20. package/dist/context.mjs.map +1 -0
  21. package/dist/cookies.cjs +87 -0
  22. package/dist/cookies.cjs.map +1 -0
  23. package/dist/cookies.d.cts +103 -0
  24. package/dist/cookies.d.mts +103 -0
  25. package/dist/cookies.mjs +84 -0
  26. package/dist/cookies.mjs.map +1 -0
  27. package/dist/crypto.cjs +39 -0
  28. package/dist/crypto.cjs.map +1 -0
  29. package/dist/crypto.mjs +36 -0
  30. package/dist/crypto.mjs.map +1 -0
  31. package/dist/endpoint.cjs +70 -0
  32. package/dist/endpoint.cjs.map +1 -0
  33. package/dist/endpoint.d.cts +428 -0
  34. package/dist/endpoint.d.mts +428 -0
  35. package/dist/endpoint.mjs +70 -0
  36. package/dist/endpoint.mjs.map +1 -0
  37. package/dist/error.cjs +140 -7
  38. package/dist/error.cjs.map +1 -0
  39. package/dist/error.d.cts +103 -2
  40. package/dist/{error2.d.ts → error.d.mts} +5 -59
  41. package/dist/{error2.js → error.mjs} +2 -2
  42. package/dist/{error2.js.map → error.mjs.map} +1 -1
  43. package/dist/helper.d.cts +12 -0
  44. package/dist/helper.d.mts +12 -0
  45. package/dist/index.cjs +19 -829
  46. package/dist/index.d.cts +11 -15
  47. package/dist/index.d.mts +11 -0
  48. package/dist/index.mjs +10 -0
  49. package/dist/middleware.cjs +39 -0
  50. package/dist/middleware.cjs.map +1 -0
  51. package/dist/middleware.d.cts +123 -0
  52. package/dist/middleware.d.mts +123 -0
  53. package/dist/middleware.mjs +39 -0
  54. package/dist/middleware.mjs.map +1 -0
  55. package/dist/node.cjs +4 -151
  56. package/dist/node.cjs.map +1 -1
  57. package/dist/node.d.cts +2 -13
  58. package/dist/node.d.mts +9 -0
  59. package/dist/node.mjs +15 -0
  60. package/dist/node.mjs.map +1 -0
  61. package/dist/openapi.cjs +191 -0
  62. package/dist/openapi.cjs.map +1 -0
  63. package/dist/openapi.d.cts +113 -0
  64. package/dist/openapi.d.mts +113 -0
  65. package/dist/openapi.mjs +189 -0
  66. package/dist/openapi.mjs.map +1 -0
  67. package/dist/router.cjs +117 -0
  68. package/dist/router.cjs.map +1 -0
  69. package/dist/router.d.cts +3 -1088
  70. package/dist/router.d.mts +97 -0
  71. package/dist/router.mjs +116 -0
  72. package/dist/router.mjs.map +1 -0
  73. package/dist/standard-schema.d.cts +59 -0
  74. package/dist/standard-schema.d.mts +59 -0
  75. package/dist/to-response.cjs +96 -0
  76. package/dist/to-response.cjs.map +1 -0
  77. package/dist/to-response.d.cts +12 -0
  78. package/dist/to-response.d.mts +12 -0
  79. package/dist/to-response.mjs +96 -0
  80. package/dist/to-response.mjs.map +1 -0
  81. package/dist/utils.cjs +86 -0
  82. package/dist/utils.cjs.map +1 -0
  83. package/dist/utils.mjs +82 -0
  84. package/dist/utils.mjs.map +1 -0
  85. package/dist/validator.cjs +58 -0
  86. package/dist/validator.cjs.map +1 -0
  87. package/dist/validator.mjs +57 -0
  88. package/dist/validator.mjs.map +1 -0
  89. package/package.json +15 -15
  90. package/dist/client.d.ts +0 -55
  91. package/dist/client.js.map +0 -1
  92. package/dist/error.d.ts +0 -2
  93. package/dist/error.js +0 -3
  94. package/dist/error2.cjs +0 -171
  95. package/dist/error2.cjs.map +0 -1
  96. package/dist/error2.d.cts +0 -157
  97. package/dist/index.cjs.map +0 -1
  98. package/dist/index.d.ts +0 -15
  99. package/dist/index.js +0 -819
  100. package/dist/index.js.map +0 -1
  101. package/dist/node.js.map +0 -1
  102. 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.6",
3
+ "version": "1.1.8",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/Bekacru/better-call"
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.cjs",
12
- "module": "./dist/index.js",
13
- "types": "./dist/index.d.ts",
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.15.7",
31
- "typescript": "^5.6.0-beta",
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.ts",
53
- "default": "./dist/index.js"
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.ts",
63
- "default": "./dist/client.js"
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.ts",
73
- "default": "./dist/error.js"
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.ts",
83
- "default": "./dist/node.js"
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
@@ -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