better-call 0.3.3 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +4 -4
- package/dist/client.d.ts +4 -4
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +785 -865
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -125
- package/dist/index.d.ts +4 -125
- package/dist/index.js +771 -855
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +186 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +14 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.js +147 -0
- package/dist/node.js.map +1 -0
- package/dist/router-DNpkEV0c.d.cts +1209 -0
- package/dist/router-DNpkEV0c.d.ts +1209 -0
- package/package.json +30 -15
- package/dist/router-DtwxtvxY.d.cts +0 -426
- package/dist/router-DtwxtvxY.d.ts +0 -426
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
10
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
-
};
|
|
12
6
|
var __export = (target, all) => {
|
|
13
7
|
for (var name in all)
|
|
14
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -21,264 +15,240 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
15
|
}
|
|
22
16
|
return to;
|
|
23
17
|
};
|
|
24
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
-
mod
|
|
31
|
-
));
|
|
32
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
34
|
-
|
|
35
|
-
// node_modules/set-cookie-parser/lib/set-cookie.js
|
|
36
|
-
var require_set_cookie = __commonJS({
|
|
37
|
-
"node_modules/set-cookie-parser/lib/set-cookie.js"(exports2, module2) {
|
|
38
|
-
"use strict";
|
|
39
|
-
var defaultParseOptions = {
|
|
40
|
-
decodeValues: true,
|
|
41
|
-
map: false,
|
|
42
|
-
silent: false
|
|
43
|
-
};
|
|
44
|
-
function isNonEmptyString(str) {
|
|
45
|
-
return typeof str === "string" && !!str.trim();
|
|
46
|
-
}
|
|
47
|
-
function parseString(setCookieValue, options) {
|
|
48
|
-
var parts = setCookieValue.split(";").filter(isNonEmptyString);
|
|
49
|
-
var nameValuePairStr = parts.shift();
|
|
50
|
-
var parsed = parseNameValuePair(nameValuePairStr);
|
|
51
|
-
var name = parsed.name;
|
|
52
|
-
var value = parsed.value;
|
|
53
|
-
options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;
|
|
54
|
-
try {
|
|
55
|
-
value = options.decodeValues ? decodeURIComponent(value) : value;
|
|
56
|
-
} catch (e) {
|
|
57
|
-
console.error(
|
|
58
|
-
"set-cookie-parser encountered an error while decoding a cookie with value '" + value + "'. Set options.decodeValues to false to disable this feature.",
|
|
59
|
-
e
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
var cookie = {
|
|
63
|
-
name,
|
|
64
|
-
value
|
|
65
|
-
};
|
|
66
|
-
parts.forEach(function(part) {
|
|
67
|
-
var sides = part.split("=");
|
|
68
|
-
var key = sides.shift().trimLeft().toLowerCase();
|
|
69
|
-
var value2 = sides.join("=");
|
|
70
|
-
if (key === "expires") {
|
|
71
|
-
cookie.expires = new Date(value2);
|
|
72
|
-
} else if (key === "max-age") {
|
|
73
|
-
cookie.maxAge = parseInt(value2, 10);
|
|
74
|
-
} else if (key === "secure") {
|
|
75
|
-
cookie.secure = true;
|
|
76
|
-
} else if (key === "httponly") {
|
|
77
|
-
cookie.httpOnly = true;
|
|
78
|
-
} else if (key === "samesite") {
|
|
79
|
-
cookie.sameSite = value2;
|
|
80
|
-
} else if (key === "partitioned") {
|
|
81
|
-
cookie.partitioned = true;
|
|
82
|
-
} else {
|
|
83
|
-
cookie[key] = value2;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
return cookie;
|
|
87
|
-
}
|
|
88
|
-
function parseNameValuePair(nameValuePairStr) {
|
|
89
|
-
var name = "";
|
|
90
|
-
var value = "";
|
|
91
|
-
var nameValueArr = nameValuePairStr.split("=");
|
|
92
|
-
if (nameValueArr.length > 1) {
|
|
93
|
-
name = nameValueArr.shift();
|
|
94
|
-
value = nameValueArr.join("=");
|
|
95
|
-
} else {
|
|
96
|
-
value = nameValuePairStr;
|
|
97
|
-
}
|
|
98
|
-
return { name, value };
|
|
99
|
-
}
|
|
100
|
-
function parse2(input, options) {
|
|
101
|
-
options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;
|
|
102
|
-
if (!input) {
|
|
103
|
-
if (!options.map) {
|
|
104
|
-
return [];
|
|
105
|
-
} else {
|
|
106
|
-
return {};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (input.headers) {
|
|
110
|
-
if (typeof input.headers.getSetCookie === "function") {
|
|
111
|
-
input = input.headers.getSetCookie();
|
|
112
|
-
} else if (input.headers["set-cookie"]) {
|
|
113
|
-
input = input.headers["set-cookie"];
|
|
114
|
-
} else {
|
|
115
|
-
var sch = input.headers[Object.keys(input.headers).find(function(key) {
|
|
116
|
-
return key.toLowerCase() === "set-cookie";
|
|
117
|
-
})];
|
|
118
|
-
if (!sch && input.headers.cookie && !options.silent) {
|
|
119
|
-
console.warn(
|
|
120
|
-
"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning."
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
input = sch;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (!Array.isArray(input)) {
|
|
127
|
-
input = [input];
|
|
128
|
-
}
|
|
129
|
-
if (!options.map) {
|
|
130
|
-
return input.filter(isNonEmptyString).map(function(str) {
|
|
131
|
-
return parseString(str, options);
|
|
132
|
-
});
|
|
133
|
-
} else {
|
|
134
|
-
var cookies = {};
|
|
135
|
-
return input.filter(isNonEmptyString).reduce(function(cookies2, str) {
|
|
136
|
-
var cookie = parseString(str, options);
|
|
137
|
-
cookies2[cookie.name] = cookie;
|
|
138
|
-
return cookies2;
|
|
139
|
-
}, cookies);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
function splitCookiesString2(cookiesString) {
|
|
143
|
-
if (Array.isArray(cookiesString)) {
|
|
144
|
-
return cookiesString;
|
|
145
|
-
}
|
|
146
|
-
if (typeof cookiesString !== "string") {
|
|
147
|
-
return [];
|
|
148
|
-
}
|
|
149
|
-
var cookiesStrings = [];
|
|
150
|
-
var pos = 0;
|
|
151
|
-
var start;
|
|
152
|
-
var ch;
|
|
153
|
-
var lastComma;
|
|
154
|
-
var nextStart;
|
|
155
|
-
var cookiesSeparatorFound;
|
|
156
|
-
function skipWhitespace() {
|
|
157
|
-
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
|
|
158
|
-
pos += 1;
|
|
159
|
-
}
|
|
160
|
-
return pos < cookiesString.length;
|
|
161
|
-
}
|
|
162
|
-
function notSpecialChar() {
|
|
163
|
-
ch = cookiesString.charAt(pos);
|
|
164
|
-
return ch !== "=" && ch !== ";" && ch !== ",";
|
|
165
|
-
}
|
|
166
|
-
while (pos < cookiesString.length) {
|
|
167
|
-
start = pos;
|
|
168
|
-
cookiesSeparatorFound = false;
|
|
169
|
-
while (skipWhitespace()) {
|
|
170
|
-
ch = cookiesString.charAt(pos);
|
|
171
|
-
if (ch === ",") {
|
|
172
|
-
lastComma = pos;
|
|
173
|
-
pos += 1;
|
|
174
|
-
skipWhitespace();
|
|
175
|
-
nextStart = pos;
|
|
176
|
-
while (pos < cookiesString.length && notSpecialChar()) {
|
|
177
|
-
pos += 1;
|
|
178
|
-
}
|
|
179
|
-
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
|
|
180
|
-
cookiesSeparatorFound = true;
|
|
181
|
-
pos = nextStart;
|
|
182
|
-
cookiesStrings.push(cookiesString.substring(start, lastComma));
|
|
183
|
-
start = pos;
|
|
184
|
-
} else {
|
|
185
|
-
pos = lastComma + 1;
|
|
186
|
-
}
|
|
187
|
-
} else {
|
|
188
|
-
pos += 1;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
|
|
192
|
-
cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return cookiesStrings;
|
|
196
|
-
}
|
|
197
|
-
module2.exports = parse2;
|
|
198
|
-
module2.exports.parse = parse2;
|
|
199
|
-
module2.exports.parseString = parseString;
|
|
200
|
-
module2.exports.splitCookiesString = splitCookiesString2;
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
19
|
|
|
204
20
|
// src/index.ts
|
|
205
21
|
var src_exports = {};
|
|
206
22
|
__export(src_exports, {
|
|
207
23
|
APIError: () => APIError,
|
|
208
|
-
|
|
209
|
-
|
|
24
|
+
_statusCode: () => _statusCode,
|
|
25
|
+
createEndpoint: () => createEndpoint2,
|
|
26
|
+
createInternalContext: () => createInternalContext,
|
|
210
27
|
createMiddleware: () => createMiddleware,
|
|
211
|
-
createMiddlewareCreator: () => createMiddlewareCreator,
|
|
212
28
|
createRouter: () => createRouter,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
serialize: () => serialize,
|
|
221
|
-
serializeSigned: () => serializeSigned,
|
|
222
|
-
setCookie: () => setCookie,
|
|
223
|
-
setResponse: () => setResponse,
|
|
224
|
-
setSignedCookie: () => setSignedCookie,
|
|
225
|
-
shouldSerialize: () => shouldSerialize,
|
|
226
|
-
signCookieValue: () => signCookieValue,
|
|
227
|
-
statusCode: () => statusCode,
|
|
228
|
-
toNodeHandler: () => toNodeHandler
|
|
29
|
+
generator: () => generator,
|
|
30
|
+
getCookieKey: () => getCookieKey,
|
|
31
|
+
getHTML: () => getHTML,
|
|
32
|
+
parseCookies: () => parseCookies,
|
|
33
|
+
serializeCookie: () => serializeCookie,
|
|
34
|
+
serializeSignedCookie: () => serializeSignedCookie,
|
|
35
|
+
toResponse: () => toResponse
|
|
229
36
|
});
|
|
230
37
|
module.exports = __toCommonJS(src_exports);
|
|
231
38
|
|
|
232
|
-
// src/endpoint.ts
|
|
233
|
-
var import_zod = require("zod");
|
|
234
|
-
|
|
235
39
|
// src/error.ts
|
|
40
|
+
var _statusCode = {
|
|
41
|
+
OK: 200,
|
|
42
|
+
CREATED: 201,
|
|
43
|
+
ACCEPTED: 202,
|
|
44
|
+
NO_CONTENT: 204,
|
|
45
|
+
MULTIPLE_CHOICES: 300,
|
|
46
|
+
MOVED_PERMANENTLY: 301,
|
|
47
|
+
FOUND: 302,
|
|
48
|
+
SEE_OTHER: 303,
|
|
49
|
+
NOT_MODIFIED: 304,
|
|
50
|
+
TEMPORARY_REDIRECT: 307,
|
|
51
|
+
BAD_REQUEST: 400,
|
|
52
|
+
UNAUTHORIZED: 401,
|
|
53
|
+
PAYMENT_REQUIRED: 402,
|
|
54
|
+
FORBIDDEN: 403,
|
|
55
|
+
NOT_FOUND: 404,
|
|
56
|
+
METHOD_NOT_ALLOWED: 405,
|
|
57
|
+
NOT_ACCEPTABLE: 406,
|
|
58
|
+
PROXY_AUTHENTICATION_REQUIRED: 407,
|
|
59
|
+
REQUEST_TIMEOUT: 408,
|
|
60
|
+
CONFLICT: 409,
|
|
61
|
+
GONE: 410,
|
|
62
|
+
LENGTH_REQUIRED: 411,
|
|
63
|
+
PRECONDITION_FAILED: 412,
|
|
64
|
+
PAYLOAD_TOO_LARGE: 413,
|
|
65
|
+
URI_TOO_LONG: 414,
|
|
66
|
+
UNSUPPORTED_MEDIA_TYPE: 415,
|
|
67
|
+
RANGE_NOT_SATISFIABLE: 416,
|
|
68
|
+
EXPECTATION_FAILED: 417,
|
|
69
|
+
"I'M_A_TEAPOT": 418,
|
|
70
|
+
MISDIRECTED_REQUEST: 421,
|
|
71
|
+
UNPROCESSABLE_ENTITY: 422,
|
|
72
|
+
LOCKED: 423,
|
|
73
|
+
FAILED_DEPENDENCY: 424,
|
|
74
|
+
TOO_EARLY: 425,
|
|
75
|
+
UPGRADE_REQUIRED: 426,
|
|
76
|
+
PRECONDITION_REQUIRED: 428,
|
|
77
|
+
TOO_MANY_REQUESTS: 429,
|
|
78
|
+
REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
|
79
|
+
UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
|
80
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
81
|
+
NOT_IMPLEMENTED: 501,
|
|
82
|
+
BAD_GATEWAY: 502,
|
|
83
|
+
SERVICE_UNAVAILABLE: 503,
|
|
84
|
+
GATEWAY_TIMEOUT: 504,
|
|
85
|
+
HTTP_VERSION_NOT_SUPPORTED: 505,
|
|
86
|
+
VARIANT_ALSO_NEGOTIATES: 506,
|
|
87
|
+
INSUFFICIENT_STORAGE: 507,
|
|
88
|
+
LOOP_DETECTED: 508,
|
|
89
|
+
NOT_EXTENDED: 510,
|
|
90
|
+
NETWORK_AUTHENTICATION_REQUIRED: 511
|
|
91
|
+
};
|
|
236
92
|
var APIError = class extends Error {
|
|
237
|
-
constructor(status, body, headers) {
|
|
238
|
-
super(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
93
|
+
constructor(status = "INTERNAL_SERVER_ERROR", body = void 0, headers = {}, statusCode = typeof status === "number" ? status : _statusCode[status]) {
|
|
94
|
+
super(body?.message);
|
|
95
|
+
this.status = status;
|
|
96
|
+
this.body = body;
|
|
97
|
+
this.headers = headers;
|
|
98
|
+
this.statusCode = statusCode;
|
|
99
|
+
this.name = "APIError";
|
|
244
100
|
this.status = status;
|
|
245
|
-
this.
|
|
246
|
-
this.
|
|
101
|
+
this.headers = headers;
|
|
102
|
+
this.statusCode = statusCode;
|
|
103
|
+
this.body = body ? {
|
|
104
|
+
code: body?.message?.toUpperCase().replace(/ /g, "_").replace(/[^A-Z0-9_]/g, ""),
|
|
105
|
+
...body
|
|
106
|
+
} : void 0;
|
|
247
107
|
this.stack = "";
|
|
248
|
-
this.headers = headers ?? new Headers();
|
|
249
|
-
if (!this.headers.has("Content-Type")) {
|
|
250
|
-
this.headers.set("Content-Type", "application/json");
|
|
251
|
-
}
|
|
252
|
-
this.name = "BetterCallAPIError";
|
|
253
108
|
}
|
|
254
109
|
};
|
|
255
110
|
|
|
256
|
-
// src/
|
|
257
|
-
|
|
111
|
+
// src/to-response.ts
|
|
112
|
+
function isJSONSerializable(value) {
|
|
113
|
+
if (value === void 0) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const t = typeof value;
|
|
117
|
+
if (t === "string" || t === "number" || t === "boolean" || t === null) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
if (t !== "object") {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
if (Array.isArray(value)) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
if (value.buffer) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
|
|
130
|
+
}
|
|
131
|
+
function toResponse(data, init) {
|
|
132
|
+
if (data instanceof Response) {
|
|
133
|
+
if (init?.headers instanceof Headers) {
|
|
134
|
+
init.headers.forEach((value, key) => {
|
|
135
|
+
data.headers.set(key, value);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return data;
|
|
139
|
+
}
|
|
140
|
+
if (data?._flag === "json") {
|
|
141
|
+
const routerResponse = data.routerResponse;
|
|
142
|
+
if (routerResponse instanceof Response) {
|
|
143
|
+
return routerResponse;
|
|
144
|
+
}
|
|
145
|
+
return toResponse(data.body, {
|
|
146
|
+
headers: data.headers,
|
|
147
|
+
status: data.status
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (data instanceof APIError) {
|
|
151
|
+
return toResponse(data.body, {
|
|
152
|
+
status: data.statusCode,
|
|
153
|
+
statusText: data.status.toString(),
|
|
154
|
+
headers: {
|
|
155
|
+
...data.headers instanceof Headers ? Object.fromEntries(data.headers.entries()) : data?.headers,
|
|
156
|
+
...init?.headers instanceof Headers ? Object.fromEntries(init.headers.entries()) : init?.headers
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
let body = data;
|
|
161
|
+
let headers = new Headers(init?.headers);
|
|
162
|
+
if (!data) {
|
|
163
|
+
headers.set("content-type", "application/json");
|
|
164
|
+
} else if (typeof data === "string") {
|
|
165
|
+
body = data;
|
|
166
|
+
headers.set("Content-Type", "text/plain");
|
|
167
|
+
} else if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
|
168
|
+
body = data;
|
|
169
|
+
headers.set("Content-Type", "application/octet-stream");
|
|
170
|
+
} else if (data instanceof Blob) {
|
|
171
|
+
body = data;
|
|
172
|
+
headers.set("Content-Type", data.type || "application/octet-stream");
|
|
173
|
+
} else if (data instanceof FormData) {
|
|
174
|
+
body = data;
|
|
175
|
+
} else if (data instanceof URLSearchParams) {
|
|
176
|
+
body = data;
|
|
177
|
+
headers.set("Content-Type", "application/x-www-form-urlencoded");
|
|
178
|
+
} else if (data instanceof ReadableStream) {
|
|
179
|
+
body = data;
|
|
180
|
+
headers.set("Content-Type", "application/octet-stream");
|
|
181
|
+
} else if (isJSONSerializable(data)) {
|
|
182
|
+
body = JSON.stringify(data);
|
|
183
|
+
headers.set("Content-Type", "application/json");
|
|
184
|
+
}
|
|
185
|
+
return new Response(body, {
|
|
186
|
+
...init,
|
|
187
|
+
headers
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/validator.ts
|
|
192
|
+
async function runValidation(options, context = {}) {
|
|
193
|
+
let request = {
|
|
194
|
+
body: context.body,
|
|
195
|
+
query: context.query
|
|
196
|
+
};
|
|
197
|
+
if (options.body) {
|
|
198
|
+
const result = await options.body["~standard"].validate(context.body);
|
|
199
|
+
if (result.issues) {
|
|
200
|
+
return {
|
|
201
|
+
data: null,
|
|
202
|
+
error: fromError(result.issues, "body")
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
request.body = result.value;
|
|
206
|
+
}
|
|
207
|
+
if (options.query) {
|
|
208
|
+
const result = await options.query["~standard"].validate(context.query);
|
|
209
|
+
if (result.issues) {
|
|
210
|
+
return {
|
|
211
|
+
data: null,
|
|
212
|
+
error: fromError(result.issues, "query")
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
request.query = result.value;
|
|
216
|
+
}
|
|
217
|
+
if (options.requireHeaders && !context.headers) {
|
|
218
|
+
return {
|
|
219
|
+
data: null,
|
|
220
|
+
error: { message: "Headers is required" }
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (options.requireRequest && !context.request) {
|
|
224
|
+
return {
|
|
225
|
+
data: null,
|
|
226
|
+
error: { message: "Request is required" }
|
|
227
|
+
};
|
|
228
|
+
}
|
|
258
229
|
return {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
status: option?.status ?? 200,
|
|
262
|
-
statusText: option?.statusText ?? "OK",
|
|
263
|
-
headers: option?.headers
|
|
264
|
-
},
|
|
265
|
-
body,
|
|
266
|
-
_flag: "json"
|
|
230
|
+
data: request,
|
|
231
|
+
error: null
|
|
267
232
|
};
|
|
268
|
-
}
|
|
233
|
+
}
|
|
234
|
+
function fromError(error, validating) {
|
|
235
|
+
const errorMessages = [];
|
|
236
|
+
for (const issue of error) {
|
|
237
|
+
const message = issue.message;
|
|
238
|
+
errorMessages.push(message);
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
message: `Invalid ${validating} parameters`
|
|
242
|
+
};
|
|
243
|
+
}
|
|
269
244
|
|
|
270
|
-
// src/
|
|
245
|
+
// src/crypto.ts
|
|
271
246
|
var import_uncrypto = require("uncrypto");
|
|
272
247
|
var algorithm = { name: "HMAC", hash: "SHA-256" };
|
|
273
248
|
var getCryptoKey = async (secret) => {
|
|
274
249
|
const secretBuf = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
275
250
|
return await import_uncrypto.subtle.importKey("raw", secretBuf, algorithm, false, ["sign", "verify"]);
|
|
276
251
|
};
|
|
277
|
-
var makeSignature = async (value, secret) => {
|
|
278
|
-
const key = await getCryptoKey(secret);
|
|
279
|
-
const signature = await import_uncrypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value));
|
|
280
|
-
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
281
|
-
};
|
|
282
252
|
var verifySignature = async (base64Signature, value, secret) => {
|
|
283
253
|
try {
|
|
284
254
|
const signatureBinStr = atob(base64Signature);
|
|
@@ -291,54 +261,54 @@ var verifySignature = async (base64Signature, value, secret) => {
|
|
|
291
261
|
return false;
|
|
292
262
|
}
|
|
293
263
|
};
|
|
294
|
-
var
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return pairs.reduce((parsedCookie, pairStr) => {
|
|
299
|
-
pairStr = pairStr.trim();
|
|
300
|
-
const valueStartPos = pairStr.indexOf("=");
|
|
301
|
-
if (valueStartPos === -1) {
|
|
302
|
-
return parsedCookie;
|
|
303
|
-
}
|
|
304
|
-
const cookieName = pairStr.substring(0, valueStartPos).trim();
|
|
305
|
-
if (name && name !== cookieName || !validCookieNameRegEx.test(cookieName)) {
|
|
306
|
-
return parsedCookie;
|
|
307
|
-
}
|
|
308
|
-
let cookieValue = pairStr.substring(valueStartPos + 1).trim();
|
|
309
|
-
if (cookieValue.startsWith('"') && cookieValue.endsWith('"')) {
|
|
310
|
-
cookieValue = cookieValue.slice(1, -1);
|
|
311
|
-
}
|
|
312
|
-
if (validCookieValueRegEx.test(cookieValue)) {
|
|
313
|
-
parsedCookie[cookieName] = decodeURIComponent(cookieValue);
|
|
314
|
-
}
|
|
315
|
-
return parsedCookie;
|
|
316
|
-
}, {});
|
|
264
|
+
var makeSignature = async (value, secret) => {
|
|
265
|
+
const key = await getCryptoKey(secret);
|
|
266
|
+
const signature = await import_uncrypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value));
|
|
267
|
+
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
317
268
|
};
|
|
318
|
-
var
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
269
|
+
var signCookieValue = async (value, secret) => {
|
|
270
|
+
const signature = await makeSignature(value, secret);
|
|
271
|
+
value = `${value}.${signature}`;
|
|
272
|
+
value = encodeURIComponent(value);
|
|
273
|
+
return value;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// src/cookies.ts
|
|
277
|
+
var getCookieKey = (key, prefix) => {
|
|
278
|
+
let finalKey = key;
|
|
279
|
+
if (prefix) {
|
|
280
|
+
if (prefix === "secure") {
|
|
281
|
+
finalKey = "__Secure-" + key;
|
|
282
|
+
} else if (prefix === "host") {
|
|
283
|
+
finalKey = "__Host-" + key;
|
|
284
|
+
} else {
|
|
285
|
+
return void 0;
|
|
330
286
|
}
|
|
331
|
-
const isVerified = await verifySignature(signature, signedValue, secretKey);
|
|
332
|
-
parsedCookie[key] = isVerified ? signedValue : false;
|
|
333
287
|
}
|
|
334
|
-
return
|
|
288
|
+
return finalKey;
|
|
335
289
|
};
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
290
|
+
function parseCookies(cookieHeader) {
|
|
291
|
+
const cookies = cookieHeader.split(";");
|
|
292
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
293
|
+
cookies.forEach((cookie) => {
|
|
294
|
+
const [name, value] = cookie.trim().split("=");
|
|
295
|
+
cookieMap.set(name, decodeURIComponent(value));
|
|
296
|
+
});
|
|
297
|
+
return cookieMap;
|
|
298
|
+
}
|
|
299
|
+
var _serialize = (key, value, opt = {}) => {
|
|
300
|
+
let cookie;
|
|
301
|
+
if (opt?.prefix === "secure") {
|
|
302
|
+
cookie = `${`__Secure-${key}`}=${value}`;
|
|
303
|
+
} else if (opt?.prefix === "host") {
|
|
304
|
+
cookie = `${`__Host-${key}`}=${value}`;
|
|
305
|
+
} else {
|
|
306
|
+
cookie = `${key}=${value}`;
|
|
307
|
+
}
|
|
308
|
+
if (key.startsWith("__Secure-") && !opt.secure) {
|
|
339
309
|
opt.secure = true;
|
|
340
310
|
}
|
|
341
|
-
if (
|
|
311
|
+
if (key.startsWith("__Host-")) {
|
|
342
312
|
if (!opt.secure) {
|
|
343
313
|
opt.secure = true;
|
|
344
314
|
}
|
|
@@ -382,111 +352,209 @@ var _serialize = (name, value, opt = {}) => {
|
|
|
382
352
|
}
|
|
383
353
|
if (opt.partitioned) {
|
|
384
354
|
if (!opt.secure) {
|
|
385
|
-
|
|
355
|
+
opt.secure = true;
|
|
386
356
|
}
|
|
387
357
|
cookie += "; Partitioned";
|
|
388
358
|
}
|
|
389
359
|
return cookie;
|
|
390
360
|
};
|
|
391
|
-
var
|
|
361
|
+
var serializeCookie = (key, value, opt) => {
|
|
392
362
|
value = encodeURIComponent(value);
|
|
393
|
-
return _serialize(
|
|
363
|
+
return _serialize(key, value, opt);
|
|
394
364
|
};
|
|
395
|
-
var
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
value = encodeURIComponent(value);
|
|
399
|
-
return _serialize(name, value, opt);
|
|
400
|
-
};
|
|
401
|
-
var signCookieValue = async (value, secret) => {
|
|
402
|
-
const signature = await makeSignature(value, secret);
|
|
403
|
-
value = `${value}.${signature}`;
|
|
404
|
-
value = encodeURIComponent(value);
|
|
405
|
-
return value;
|
|
365
|
+
var serializeSignedCookie = async (key, value, secret, opt) => {
|
|
366
|
+
value = await signCookieValue(value, secret);
|
|
367
|
+
return _serialize(key, value, opt);
|
|
406
368
|
};
|
|
407
369
|
|
|
408
|
-
// src/
|
|
409
|
-
var
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
} else {
|
|
420
|
-
return void 0;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
const obj = parse(cookie, finalKey);
|
|
424
|
-
return obj[finalKey];
|
|
425
|
-
};
|
|
426
|
-
var setCookie = (header, name, value, opt) => {
|
|
427
|
-
const existingCookies = header.get("Set-Cookie");
|
|
428
|
-
if (existingCookies) {
|
|
429
|
-
const cookies = existingCookies.split(", ");
|
|
430
|
-
const updatedCookies = cookies.filter((cookie2) => !cookie2.startsWith(`${name}=`));
|
|
431
|
-
header.delete("Set-Cookie");
|
|
432
|
-
updatedCookies.forEach((cookie2) => header.append("Set-Cookie", cookie2));
|
|
433
|
-
}
|
|
434
|
-
let cookie;
|
|
435
|
-
if (opt?.prefix === "secure") {
|
|
436
|
-
cookie = serialize("__Secure-" + name, value, { path: "/", ...opt, secure: true });
|
|
437
|
-
} else if (opt?.prefix === "host") {
|
|
438
|
-
cookie = serialize("__Host-" + name, value, {
|
|
439
|
-
...opt,
|
|
440
|
-
path: "/",
|
|
441
|
-
secure: true,
|
|
442
|
-
domain: void 0
|
|
370
|
+
// src/context.ts
|
|
371
|
+
var createInternalContext = async (context, {
|
|
372
|
+
options,
|
|
373
|
+
path
|
|
374
|
+
}) => {
|
|
375
|
+
const headers = new Headers();
|
|
376
|
+
const { data, error } = await runValidation(options, context);
|
|
377
|
+
if (error) {
|
|
378
|
+
throw new APIError(400, {
|
|
379
|
+
message: error.message,
|
|
380
|
+
code: "VALIDATION_ERROR"
|
|
443
381
|
});
|
|
444
|
-
} else {
|
|
445
|
-
cookie = serialize(name, value, { path: "/", ...opt });
|
|
446
382
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
383
|
+
const requestHeaders = "headers" in context ? context.headers instanceof Headers ? context.headers : new Headers(context.headers) : "request" in context && context.request instanceof Request ? context.request.headers : null;
|
|
384
|
+
const requestCookies = requestHeaders?.get("cookie");
|
|
385
|
+
const parsedCookies = requestCookies ? parseCookies(requestCookies) : void 0;
|
|
386
|
+
const internalContext = {
|
|
387
|
+
...context,
|
|
388
|
+
body: data.body,
|
|
389
|
+
query: data.query,
|
|
390
|
+
path: context.path || path,
|
|
391
|
+
context: "context" in context && context.context ? context.context : {},
|
|
392
|
+
returned: void 0,
|
|
393
|
+
headers: context?.headers,
|
|
394
|
+
request: context?.request,
|
|
395
|
+
params: "params" in context ? context.params : void 0,
|
|
396
|
+
method: context.method,
|
|
397
|
+
setHeader: (key, value) => {
|
|
398
|
+
headers.set(key, value);
|
|
399
|
+
},
|
|
400
|
+
getHeader: (key) => {
|
|
401
|
+
if (!requestHeaders) return null;
|
|
402
|
+
return requestHeaders.get(key);
|
|
403
|
+
},
|
|
404
|
+
getCookie: (key, prefix) => {
|
|
405
|
+
const finalKey = getCookieKey(key, prefix);
|
|
406
|
+
if (!finalKey) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
return parsedCookies?.get(finalKey) || null;
|
|
410
|
+
},
|
|
411
|
+
getSignedCookie: async (key, secret, prefix) => {
|
|
412
|
+
const finalKey = getCookieKey(key, prefix);
|
|
413
|
+
if (!finalKey) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
const value = parsedCookies?.get(finalKey);
|
|
417
|
+
if (!value) {
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
const signatureStartPos = value.lastIndexOf(".");
|
|
421
|
+
if (signatureStartPos < 1) {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
const signedValue = value.substring(0, signatureStartPos);
|
|
425
|
+
const signature = value.substring(signatureStartPos + 1);
|
|
426
|
+
if (signature.length !== 44 || !signature.endsWith("=")) {
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
const secretKey = await getCryptoKey(secret);
|
|
430
|
+
const isVerified = await verifySignature(signature, signedValue, secretKey);
|
|
431
|
+
return isVerified ? signedValue : false;
|
|
432
|
+
},
|
|
433
|
+
setCookie: (key, value, options2) => {
|
|
434
|
+
const cookie = serializeCookie(key, value, options2);
|
|
435
|
+
headers.append("set-cookie", cookie);
|
|
436
|
+
return cookie;
|
|
437
|
+
},
|
|
438
|
+
setSignedCookie: async (key, value, secret, options2) => {
|
|
439
|
+
const cookie = await serializeSignedCookie(key, value, secret, options2);
|
|
440
|
+
headers.append("set-cookie", cookie);
|
|
441
|
+
return cookie;
|
|
442
|
+
},
|
|
443
|
+
redirect: (url) => {
|
|
444
|
+
headers.set("location", url);
|
|
445
|
+
return new APIError("FOUND", void 0, headers);
|
|
446
|
+
},
|
|
447
|
+
error: (status, body, headers2) => {
|
|
448
|
+
return new APIError(status, body, headers2);
|
|
449
|
+
},
|
|
450
|
+
json: (json, routerResponse) => {
|
|
451
|
+
if (!context.asResponse) {
|
|
452
|
+
return json;
|
|
453
|
+
}
|
|
454
|
+
return {
|
|
455
|
+
body: routerResponse?.body || json,
|
|
456
|
+
routerResponse,
|
|
457
|
+
_flag: "json"
|
|
458
|
+
};
|
|
459
|
+
},
|
|
460
|
+
responseHeaders: headers
|
|
461
|
+
};
|
|
462
|
+
for (const middleware of options.use || []) {
|
|
463
|
+
const response = await middleware({
|
|
464
|
+
...internalContext,
|
|
465
|
+
returnHeaders: true,
|
|
466
|
+
asResponse: false
|
|
463
467
|
});
|
|
464
|
-
|
|
465
|
-
|
|
468
|
+
if (response.response) {
|
|
469
|
+
Object.assign(internalContext.context, response.response);
|
|
470
|
+
}
|
|
471
|
+
if (response.headers) {
|
|
472
|
+
response.headers.forEach((value, key) => {
|
|
473
|
+
internalContext.responseHeaders.set(key, value);
|
|
474
|
+
});
|
|
475
|
+
}
|
|
466
476
|
}
|
|
467
|
-
|
|
477
|
+
return internalContext;
|
|
468
478
|
};
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
479
|
+
|
|
480
|
+
// src/middleware.ts
|
|
481
|
+
function createMiddleware(optionsOrHandler, handler) {
|
|
482
|
+
const internalHandler = async (inputCtx) => {
|
|
483
|
+
const context = inputCtx;
|
|
484
|
+
const _handler = typeof optionsOrHandler === "function" ? optionsOrHandler : handler;
|
|
485
|
+
const options = typeof optionsOrHandler === "function" ? {} : optionsOrHandler;
|
|
486
|
+
const internalContext = await createInternalContext(context, {
|
|
487
|
+
options,
|
|
488
|
+
path: "/"
|
|
489
|
+
});
|
|
490
|
+
if (!_handler) {
|
|
491
|
+
throw new Error("handler must be defined");
|
|
492
|
+
}
|
|
493
|
+
const response = await _handler(internalContext);
|
|
494
|
+
const headers = internalContext.responseHeaders;
|
|
495
|
+
return context.returnHeaders ? {
|
|
496
|
+
headers,
|
|
497
|
+
response
|
|
498
|
+
} : response;
|
|
499
|
+
};
|
|
500
|
+
internalHandler.options = typeof optionsOrHandler === "function" ? {} : optionsOrHandler;
|
|
501
|
+
return internalHandler;
|
|
502
|
+
}
|
|
503
|
+
createMiddleware.create = (opts) => {
|
|
504
|
+
function fn(optionsOrHandler, handler) {
|
|
505
|
+
if (typeof optionsOrHandler === "function") {
|
|
506
|
+
return createMiddleware(
|
|
507
|
+
{
|
|
508
|
+
use: opts?.use
|
|
509
|
+
},
|
|
510
|
+
optionsOrHandler
|
|
511
|
+
);
|
|
480
512
|
}
|
|
513
|
+
if (!handler) {
|
|
514
|
+
throw new Error("Middleware handler is required");
|
|
515
|
+
}
|
|
516
|
+
const middleware = createMiddleware(
|
|
517
|
+
{
|
|
518
|
+
...optionsOrHandler,
|
|
519
|
+
method: "*",
|
|
520
|
+
use: [...opts?.use || [], ...optionsOrHandler.use || []]
|
|
521
|
+
},
|
|
522
|
+
handler
|
|
523
|
+
);
|
|
524
|
+
return middleware;
|
|
481
525
|
}
|
|
482
|
-
|
|
483
|
-
return obj[finalKey];
|
|
526
|
+
return fn;
|
|
484
527
|
};
|
|
485
528
|
|
|
486
529
|
// src/endpoint.ts
|
|
487
|
-
|
|
530
|
+
var createEndpoint2 = (path, options, handler) => {
|
|
531
|
+
const internalHandler = async (...inputCtx) => {
|
|
532
|
+
const context = inputCtx[0] || {};
|
|
533
|
+
const internalContext = await createInternalContext(context, {
|
|
534
|
+
options,
|
|
535
|
+
path
|
|
536
|
+
});
|
|
537
|
+
const response = await handler(internalContext).catch((e) => {
|
|
538
|
+
if (e instanceof APIError && context.asResponse) {
|
|
539
|
+
return e;
|
|
540
|
+
}
|
|
541
|
+
throw e;
|
|
542
|
+
});
|
|
543
|
+
const headers = internalContext.responseHeaders;
|
|
544
|
+
return context.asResponse ? toResponse(response, {
|
|
545
|
+
headers
|
|
546
|
+
}) : context.returnHeaders ? {
|
|
547
|
+
headers,
|
|
548
|
+
response
|
|
549
|
+
} : response;
|
|
550
|
+
};
|
|
551
|
+
internalHandler.options = options;
|
|
552
|
+
internalHandler.path = path;
|
|
553
|
+
return internalHandler;
|
|
554
|
+
};
|
|
555
|
+
createEndpoint2.create = (opts) => {
|
|
488
556
|
return (path, options, handler) => {
|
|
489
|
-
return
|
|
557
|
+
return createEndpoint2(
|
|
490
558
|
path,
|
|
491
559
|
{
|
|
492
560
|
...options,
|
|
@@ -495,152 +563,300 @@ function createEndpointCreator(opts) {
|
|
|
495
563
|
handler
|
|
496
564
|
);
|
|
497
565
|
};
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
// src/router.ts
|
|
569
|
+
var import_rou3 = require("rou3");
|
|
570
|
+
|
|
571
|
+
// src/openapi.ts
|
|
572
|
+
var import_zod = require("zod");
|
|
573
|
+
var paths = {};
|
|
574
|
+
function getTypeFromZodType(zodType) {
|
|
575
|
+
switch (zodType.constructor.name) {
|
|
576
|
+
case "ZodString":
|
|
577
|
+
return "string";
|
|
578
|
+
case "ZodNumber":
|
|
579
|
+
return "number";
|
|
580
|
+
case "ZodBoolean":
|
|
581
|
+
return "boolean";
|
|
582
|
+
case "ZodObject":
|
|
583
|
+
return "object";
|
|
584
|
+
case "ZodArray":
|
|
585
|
+
return "array";
|
|
586
|
+
default:
|
|
587
|
+
return "string";
|
|
588
|
+
}
|
|
498
589
|
}
|
|
499
|
-
function
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
590
|
+
function getParameters(options) {
|
|
591
|
+
const parameters = [];
|
|
592
|
+
if (options.metadata?.openAPI?.parameters) {
|
|
593
|
+
parameters.push(...options.metadata.openAPI.parameters);
|
|
594
|
+
return parameters;
|
|
595
|
+
}
|
|
596
|
+
if (options.query instanceof import_zod.ZodObject) {
|
|
597
|
+
Object.entries(options.query.shape).forEach(([key, value]) => {
|
|
598
|
+
if (value instanceof import_zod.ZodSchema) {
|
|
599
|
+
parameters.push({
|
|
600
|
+
name: key,
|
|
601
|
+
in: "query",
|
|
602
|
+
schema: {
|
|
603
|
+
type: getTypeFromZodType(value),
|
|
604
|
+
..."minLength" in value && value.minLength ? {
|
|
605
|
+
minLength: value.minLength
|
|
606
|
+
} : {},
|
|
607
|
+
description: value.description
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
return parameters;
|
|
614
|
+
}
|
|
615
|
+
function getRequestBody(options) {
|
|
616
|
+
if (options.metadata?.openAPI?.requestBody) {
|
|
617
|
+
return options.metadata.openAPI.requestBody;
|
|
618
|
+
}
|
|
619
|
+
if (!options.body) return void 0;
|
|
620
|
+
if (options.body instanceof import_zod.ZodObject || options.body instanceof import_zod.ZodOptional) {
|
|
621
|
+
const shape = options.body.shape;
|
|
622
|
+
if (!shape) return void 0;
|
|
623
|
+
const properties = {};
|
|
624
|
+
const required = [];
|
|
625
|
+
Object.entries(shape).forEach(([key, value]) => {
|
|
626
|
+
if (value instanceof import_zod.ZodSchema) {
|
|
627
|
+
properties[key] = {
|
|
628
|
+
type: getTypeFromZodType(value),
|
|
629
|
+
description: value.description
|
|
630
|
+
};
|
|
631
|
+
if (!(value instanceof import_zod.ZodOptional)) {
|
|
632
|
+
required.push(key);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
return {
|
|
637
|
+
required: options.body instanceof import_zod.ZodOptional ? false : options.body ? true : false,
|
|
638
|
+
content: {
|
|
639
|
+
"application/json": {
|
|
640
|
+
schema: {
|
|
641
|
+
type: "object",
|
|
642
|
+
properties,
|
|
643
|
+
required
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
return void 0;
|
|
650
|
+
}
|
|
651
|
+
function getResponse(responses) {
|
|
652
|
+
return {
|
|
653
|
+
"400": {
|
|
654
|
+
content: {
|
|
655
|
+
"application/json": {
|
|
656
|
+
schema: {
|
|
657
|
+
type: "object",
|
|
658
|
+
properties: {
|
|
659
|
+
message: {
|
|
660
|
+
type: "string"
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
required: ["message"]
|
|
664
|
+
}
|
|
665
|
+
}
|
|
514
666
|
},
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
667
|
+
description: "Bad Request. Usually due to missing parameters, or invalid parameters."
|
|
668
|
+
},
|
|
669
|
+
"401": {
|
|
670
|
+
content: {
|
|
671
|
+
"application/json": {
|
|
672
|
+
schema: {
|
|
673
|
+
type: "object",
|
|
674
|
+
properties: {
|
|
675
|
+
message: {
|
|
676
|
+
type: "string"
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
required: ["message"]
|
|
680
|
+
}
|
|
519
681
|
}
|
|
520
|
-
const cookie = getSignedCookie(header, secret, key, prefix);
|
|
521
|
-
return cookie;
|
|
522
682
|
},
|
|
523
|
-
|
|
524
|
-
|
|
683
|
+
description: "Unauthorized. Due to missing or invalid authentication."
|
|
684
|
+
},
|
|
685
|
+
"403": {
|
|
686
|
+
content: {
|
|
687
|
+
"application/json": {
|
|
688
|
+
schema: {
|
|
689
|
+
type: "object",
|
|
690
|
+
properties: {
|
|
691
|
+
message: {
|
|
692
|
+
type: "string"
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
525
697
|
},
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
698
|
+
description: "Forbidden. You do not have permission to access this resource or to perform this action."
|
|
699
|
+
},
|
|
700
|
+
"404": {
|
|
701
|
+
content: {
|
|
702
|
+
"application/json": {
|
|
703
|
+
schema: {
|
|
704
|
+
type: "object",
|
|
705
|
+
properties: {
|
|
706
|
+
message: {
|
|
707
|
+
type: "string"
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
529
712
|
},
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
middleware
|
|
544
|
-
});
|
|
545
|
-
continue;
|
|
713
|
+
description: "Not Found. The requested resource was not found."
|
|
714
|
+
},
|
|
715
|
+
"429": {
|
|
716
|
+
content: {
|
|
717
|
+
"application/json": {
|
|
718
|
+
schema: {
|
|
719
|
+
type: "object",
|
|
720
|
+
properties: {
|
|
721
|
+
message: {
|
|
722
|
+
type: "string"
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
546
726
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
727
|
+
},
|
|
728
|
+
description: "Too Many Requests. You have exceeded the rate limit. Try again later."
|
|
729
|
+
},
|
|
730
|
+
"500": {
|
|
731
|
+
content: {
|
|
732
|
+
"application/json": {
|
|
733
|
+
schema: {
|
|
734
|
+
type: "object",
|
|
735
|
+
properties: {
|
|
736
|
+
message: {
|
|
737
|
+
type: "string"
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
558
741
|
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
742
|
+
},
|
|
743
|
+
description: "Internal Server Error. This is a problem with the server that you cannot fix."
|
|
744
|
+
},
|
|
745
|
+
...responses
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
async function generator(endpoints, config) {
|
|
749
|
+
const components = {
|
|
750
|
+
schemas: {}
|
|
751
|
+
};
|
|
752
|
+
Object.entries(endpoints).forEach(([_, value]) => {
|
|
753
|
+
const options = value.options;
|
|
754
|
+
if (options.metadata?.SERVER_ONLY) return;
|
|
755
|
+
if (options.method === "GET") {
|
|
756
|
+
paths[value.path] = {
|
|
757
|
+
get: {
|
|
758
|
+
tags: ["Default", ...options.metadata?.openAPI?.tags || []],
|
|
759
|
+
description: options.metadata?.openAPI?.description,
|
|
760
|
+
operationId: options.metadata?.openAPI?.operationId,
|
|
761
|
+
security: [
|
|
762
|
+
{
|
|
763
|
+
bearerAuth: []
|
|
764
|
+
}
|
|
765
|
+
],
|
|
766
|
+
parameters: getParameters(options),
|
|
767
|
+
responses: getResponse(options.metadata?.openAPI?.responses)
|
|
569
768
|
}
|
|
570
769
|
};
|
|
571
770
|
}
|
|
572
|
-
|
|
573
|
-
const body = options
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
771
|
+
if (options.method === "POST") {
|
|
772
|
+
const body = getRequestBody(options);
|
|
773
|
+
paths[value.path] = {
|
|
774
|
+
post: {
|
|
775
|
+
tags: ["Default", ...options.metadata?.openAPI?.tags || []],
|
|
776
|
+
description: options.metadata?.openAPI?.description,
|
|
777
|
+
operationId: options.metadata?.openAPI?.operationId,
|
|
778
|
+
security: [
|
|
779
|
+
{
|
|
780
|
+
bearerAuth: []
|
|
781
|
+
}
|
|
782
|
+
],
|
|
783
|
+
parameters: getParameters(options),
|
|
784
|
+
...body ? { requestBody: body } : {
|
|
785
|
+
requestBody: {
|
|
786
|
+
//set body none
|
|
787
|
+
content: {
|
|
788
|
+
"application/json": {
|
|
789
|
+
schema: {
|
|
790
|
+
type: "object",
|
|
791
|
+
properties: {}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
responses: getResponse(options.metadata?.openAPI?.responses)
|
|
798
|
+
}
|
|
580
799
|
};
|
|
581
|
-
internalCtx.query = options.query ? options.query.parse(internalCtx.query) : internalCtx.query;
|
|
582
|
-
} catch (e) {
|
|
583
|
-
if (e instanceof import_zod.ZodError) {
|
|
584
|
-
throw new APIError("BAD_REQUEST", {
|
|
585
|
-
message: e.message,
|
|
586
|
-
details: e.errors
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
throw e;
|
|
590
|
-
}
|
|
591
|
-
if (options.requireHeaders && !internalCtx.headers) {
|
|
592
|
-
throw new APIError("BAD_REQUEST", {
|
|
593
|
-
message: "Headers are required"
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
if (options.requireRequest && !internalCtx.request) {
|
|
597
|
-
throw new APIError("BAD_REQUEST", {
|
|
598
|
-
message: "Request is required"
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
if (internalCtx.request && !internalCtx.headers) {
|
|
602
|
-
internalCtx.headers = internalCtx.request.headers;
|
|
603
800
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
statusText: res.response.statusText,
|
|
617
|
-
headers: responseHeader
|
|
618
|
-
});
|
|
619
|
-
} else {
|
|
620
|
-
actualResponse = res.body;
|
|
621
|
-
}
|
|
801
|
+
});
|
|
802
|
+
const res = {
|
|
803
|
+
openapi: "3.1.1",
|
|
804
|
+
info: {
|
|
805
|
+
title: "Better Auth",
|
|
806
|
+
description: "API Reference for your Better Auth Instance",
|
|
807
|
+
version: "1.1.0"
|
|
808
|
+
},
|
|
809
|
+
components,
|
|
810
|
+
security: [
|
|
811
|
+
{
|
|
812
|
+
apiKeyCookie: []
|
|
622
813
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
responseHeader.set("Content-Type", "application/json");
|
|
628
|
-
e.headers = responseHeader;
|
|
629
|
-
responseHeader = new Headers();
|
|
630
|
-
throw e;
|
|
814
|
+
],
|
|
815
|
+
servers: [
|
|
816
|
+
{
|
|
817
|
+
url: config?.url
|
|
631
818
|
}
|
|
632
|
-
|
|
633
|
-
|
|
819
|
+
],
|
|
820
|
+
tags: [
|
|
821
|
+
{
|
|
822
|
+
name: "Default",
|
|
823
|
+
description: "Default endpoints that are included with Better Auth by default. These endpoints are not part of any plugin."
|
|
824
|
+
}
|
|
825
|
+
],
|
|
826
|
+
paths
|
|
634
827
|
};
|
|
635
|
-
|
|
636
|
-
handle.options = options;
|
|
637
|
-
handle.method = options.method;
|
|
638
|
-
handle.headers = responseHeader;
|
|
639
|
-
return handle;
|
|
828
|
+
return res;
|
|
640
829
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
830
|
+
var getHTML = (apiReference, config) => `<!doctype html>
|
|
831
|
+
<html>
|
|
832
|
+
<head>
|
|
833
|
+
<title>Scalar API Reference</title>
|
|
834
|
+
<meta charset="utf-8" />
|
|
835
|
+
<meta
|
|
836
|
+
name="viewport"
|
|
837
|
+
content="width=device-width, initial-scale=1" />
|
|
838
|
+
</head>
|
|
839
|
+
<body>
|
|
840
|
+
<script
|
|
841
|
+
id="api-reference"
|
|
842
|
+
type="application/json">
|
|
843
|
+
${JSON.stringify(apiReference)}
|
|
844
|
+
</script>
|
|
845
|
+
<script>
|
|
846
|
+
var configuration = {
|
|
847
|
+
favicon: ${config?.logo ? `data:image/svg+xml;utf8,${encodeURIComponent(config.logo)}` : void 0} ,
|
|
848
|
+
theme: ${config?.theme || "saturn"},
|
|
849
|
+
metaData: {
|
|
850
|
+
title: ${config?.title || "Open API Reference"},
|
|
851
|
+
description: ${config?.description || "Better Call Open API"},
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
document.getElementById('api-reference').dataset.configuration =
|
|
855
|
+
JSON.stringify(configuration)
|
|
856
|
+
</script>
|
|
857
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
858
|
+
</body>
|
|
859
|
+
</html>`;
|
|
644
860
|
|
|
645
861
|
// src/utils.ts
|
|
646
862
|
async function getBody(request) {
|
|
@@ -682,180 +898,89 @@ async function getBody(request) {
|
|
|
682
898
|
}
|
|
683
899
|
return await request.text();
|
|
684
900
|
}
|
|
685
|
-
function shouldSerialize(body) {
|
|
686
|
-
return typeof body === "object" && body !== null && !(body instanceof Blob) && !(body instanceof FormData);
|
|
687
|
-
}
|
|
688
|
-
var statusCode = {
|
|
689
|
-
OK: 200,
|
|
690
|
-
CREATED: 201,
|
|
691
|
-
ACCEPTED: 202,
|
|
692
|
-
NO_CONTENT: 204,
|
|
693
|
-
MULTIPLE_CHOICES: 300,
|
|
694
|
-
MOVED_PERMANENTLY: 301,
|
|
695
|
-
FOUND: 302,
|
|
696
|
-
SEE_OTHER: 303,
|
|
697
|
-
NOT_MODIFIED: 304,
|
|
698
|
-
TEMPORARY_REDIRECT: 307,
|
|
699
|
-
BAD_REQUEST: 400,
|
|
700
|
-
UNAUTHORIZED: 401,
|
|
701
|
-
PAYMENT_REQUIRED: 402,
|
|
702
|
-
FORBIDDEN: 403,
|
|
703
|
-
NOT_FOUND: 404,
|
|
704
|
-
METHOD_NOT_ALLOWED: 405,
|
|
705
|
-
NOT_ACCEPTABLE: 406,
|
|
706
|
-
PROXY_AUTHENTICATION_REQUIRED: 407,
|
|
707
|
-
REQUEST_TIMEOUT: 408,
|
|
708
|
-
CONFLICT: 409,
|
|
709
|
-
GONE: 410,
|
|
710
|
-
LENGTH_REQUIRED: 411,
|
|
711
|
-
PRECONDITION_FAILED: 412,
|
|
712
|
-
PAYLOAD_TOO_LARGE: 413,
|
|
713
|
-
URI_TOO_LONG: 414,
|
|
714
|
-
UNSUPPORTED_MEDIA_TYPE: 415,
|
|
715
|
-
RANGE_NOT_SATISFIABLE: 416,
|
|
716
|
-
EXPECTATION_FAILED: 417,
|
|
717
|
-
"I'M_A_TEAPOT": 418,
|
|
718
|
-
MISDIRECTED_REQUEST: 421,
|
|
719
|
-
UNPROCESSABLE_ENTITY: 422,
|
|
720
|
-
LOCKED: 423,
|
|
721
|
-
FAILED_DEPENDENCY: 424,
|
|
722
|
-
TOO_EARLY: 425,
|
|
723
|
-
UPGRADE_REQUIRED: 426,
|
|
724
|
-
PRECONDITION_REQUIRED: 428,
|
|
725
|
-
TOO_MANY_REQUESTS: 429,
|
|
726
|
-
REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
|
727
|
-
UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
|
728
|
-
INTERNAL_SERVER_ERROR: 500,
|
|
729
|
-
NOT_IMPLEMENTED: 501,
|
|
730
|
-
BAD_GATEWAY: 502,
|
|
731
|
-
SERVICE_UNAVAILABLE: 503,
|
|
732
|
-
GATEWAY_TIMEOUT: 504,
|
|
733
|
-
HTTP_VERSION_NOT_SUPPORTED: 505,
|
|
734
|
-
VARIANT_ALSO_NEGOTIATES: 506,
|
|
735
|
-
INSUFFICIENT_STORAGE: 507,
|
|
736
|
-
LOOP_DETECTED: 508,
|
|
737
|
-
NOT_EXTENDED: 510,
|
|
738
|
-
NETWORK_AUTHENTICATION_REQUIRED: 511
|
|
739
|
-
};
|
|
740
901
|
|
|
741
902
|
// src/router.ts
|
|
742
903
|
var createRouter = (endpoints, config) => {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
904
|
+
if (!config?.openAPI?.disabled) {
|
|
905
|
+
const openAPI = {
|
|
906
|
+
path: "/api/reference",
|
|
907
|
+
...config?.openAPI
|
|
908
|
+
};
|
|
909
|
+
endpoints["openAPI"] = createEndpoint2(
|
|
910
|
+
openAPI.path,
|
|
911
|
+
{
|
|
912
|
+
method: "GET"
|
|
913
|
+
},
|
|
914
|
+
async (c) => {
|
|
915
|
+
const schema = await generator(endpoints);
|
|
916
|
+
return new Response(getHTML(schema, openAPI.scalar), {
|
|
917
|
+
headers: {
|
|
918
|
+
"Content-Type": "text/html"
|
|
919
|
+
}
|
|
920
|
+
});
|
|
750
921
|
}
|
|
751
|
-
|
|
752
|
-
(0, import_rou3.addRoute)(router, endpoint.options.method, endpoint.path, endpoint);
|
|
753
|
-
}
|
|
922
|
+
);
|
|
754
923
|
}
|
|
924
|
+
const router = (0, import_rou3.createRouter)();
|
|
755
925
|
const middlewareRouter = (0, import_rou3.createRouter)();
|
|
756
|
-
for (const
|
|
757
|
-
(
|
|
926
|
+
for (const endpoint of Object.values(endpoints)) {
|
|
927
|
+
if (!endpoint.options) {
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
if (endpoint.options?.metadata?.SERVER_ONLY) continue;
|
|
931
|
+
const methods = Array.isArray(endpoint.options?.method) ? endpoint.options.method : [endpoint.options?.method];
|
|
932
|
+
for (const method of methods) {
|
|
933
|
+
(0, import_rou3.addRoute)(router, method, endpoint.path, endpoint);
|
|
934
|
+
}
|
|
758
935
|
}
|
|
759
|
-
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
if (config?.basePath) {
|
|
763
|
-
path = path.split(config.basePath)[1];
|
|
936
|
+
if (config?.routerMiddleware?.length) {
|
|
937
|
+
for (const { path, middleware } of config.routerMiddleware) {
|
|
938
|
+
(0, import_rou3.addRoute)(middlewareRouter, "*", path, middleware);
|
|
764
939
|
}
|
|
940
|
+
}
|
|
941
|
+
const processRequest = async (request) => {
|
|
942
|
+
const url = new URL(request.url);
|
|
943
|
+
const path = config?.basePath ? url.pathname.split(config.basePath)[1] : url.pathname;
|
|
765
944
|
if (!path?.length) {
|
|
766
|
-
config?.onError?.(new
|
|
767
|
-
|
|
768
|
-
`[better-call]: Make sure the URL has the basePath (${config?.basePath}).`
|
|
769
|
-
);
|
|
770
|
-
return new Response(null, {
|
|
771
|
-
status: 404,
|
|
772
|
-
statusText: "Not Found"
|
|
773
|
-
});
|
|
945
|
+
config?.onError?.(new Error("NOT_FOUND"));
|
|
946
|
+
return new Response(null, { status: 404, statusText: "Not Found" });
|
|
774
947
|
}
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
const body = await getBody(request);
|
|
779
|
-
const headers = request.headers;
|
|
780
|
-
const query = Object.fromEntries(url.searchParams);
|
|
781
|
-
const routerMiddleware = (0, import_rou3.findAllRoutes)(middlewareRouter, "*", path);
|
|
782
|
-
if (!handler2) {
|
|
783
|
-
return new Response(null, {
|
|
784
|
-
status: 404,
|
|
785
|
-
statusText: "Not Found"
|
|
786
|
-
});
|
|
948
|
+
const route = (0, import_rou3.findRoute)(router, request.method, path);
|
|
949
|
+
if (!route?.data) {
|
|
950
|
+
return new Response(null, { status: 404, statusText: "Not Found" });
|
|
787
951
|
}
|
|
952
|
+
const handler = route.data;
|
|
953
|
+
const context = {
|
|
954
|
+
path,
|
|
955
|
+
method: request.method,
|
|
956
|
+
headers: request.headers,
|
|
957
|
+
params: route.params,
|
|
958
|
+
request,
|
|
959
|
+
body: await getBody(handler.options.cloneRequest ? request.clone() : request),
|
|
960
|
+
query: Object.fromEntries(url.searchParams),
|
|
961
|
+
_flag: "router",
|
|
962
|
+
asResponse: true,
|
|
963
|
+
context: config?.routerContext
|
|
964
|
+
};
|
|
788
965
|
try {
|
|
789
|
-
|
|
790
|
-
if (
|
|
791
|
-
for (const
|
|
792
|
-
const middleware = route2.data;
|
|
966
|
+
const middlewareRoutes = (0, import_rou3.findAllRoutes)(middlewareRouter, "*", path);
|
|
967
|
+
if (middlewareRoutes?.length) {
|
|
968
|
+
for (const { data: middleware, params } of middlewareRoutes) {
|
|
793
969
|
const res = await middleware({
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
params: route2?.params,
|
|
798
|
-
request,
|
|
799
|
-
body,
|
|
800
|
-
query,
|
|
801
|
-
context: {
|
|
802
|
-
...config?.extraContext
|
|
803
|
-
}
|
|
970
|
+
...context,
|
|
971
|
+
params,
|
|
972
|
+
asResponse: false
|
|
804
973
|
});
|
|
805
|
-
if (res instanceof Response)
|
|
806
|
-
return res;
|
|
807
|
-
}
|
|
808
|
-
if (res?._flag === "json") {
|
|
809
|
-
return new Response(JSON.stringify(res), {
|
|
810
|
-
headers: res.headers
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
if (res) {
|
|
814
|
-
middlewareContext = {
|
|
815
|
-
...res,
|
|
816
|
-
...middlewareContext
|
|
817
|
-
};
|
|
818
|
-
}
|
|
974
|
+
if (res instanceof Response) return res;
|
|
819
975
|
}
|
|
820
976
|
}
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
request,
|
|
827
|
-
body,
|
|
828
|
-
query,
|
|
829
|
-
_flag: "router",
|
|
830
|
-
context: {
|
|
831
|
-
...middlewareContext,
|
|
832
|
-
...config?.extraContext
|
|
833
|
-
}
|
|
834
|
-
});
|
|
835
|
-
if (handlerRes instanceof Response) {
|
|
836
|
-
return handlerRes;
|
|
837
|
-
}
|
|
838
|
-
const resBody = shouldSerialize(handlerRes) ? JSON.stringify(handlerRes) : handlerRes;
|
|
839
|
-
return new Response(resBody, {
|
|
840
|
-
headers: handler2.headers
|
|
841
|
-
});
|
|
842
|
-
} catch (e) {
|
|
843
|
-
if (config?.onError) {
|
|
844
|
-
const onErrorRes = await config.onError(e);
|
|
845
|
-
if (onErrorRes instanceof Response) {
|
|
846
|
-
return onErrorRes;
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
if (e instanceof APIError) {
|
|
850
|
-
return new Response(e.body ? JSON.stringify(e.body) : null, {
|
|
851
|
-
status: statusCode[e.status],
|
|
852
|
-
statusText: e.status,
|
|
853
|
-
headers: e.headers
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
|
-
if (config?.throwError) {
|
|
857
|
-
throw e;
|
|
977
|
+
const response = await handler(context);
|
|
978
|
+
return response;
|
|
979
|
+
} catch (error) {
|
|
980
|
+
if (error instanceof APIError) {
|
|
981
|
+
return toResponse(error);
|
|
858
982
|
}
|
|
983
|
+
console.error(`# SERVER_ERROR: `, error);
|
|
859
984
|
return new Response(null, {
|
|
860
985
|
status: 500,
|
|
861
986
|
statusText: "Internal Server Error"
|
|
@@ -869,7 +994,7 @@ var createRouter = (endpoints, config) => {
|
|
|
869
994
|
return onReq;
|
|
870
995
|
}
|
|
871
996
|
const req = onReq instanceof Request ? onReq : request;
|
|
872
|
-
const res = await
|
|
997
|
+
const res = await processRequest(req);
|
|
873
998
|
const onRes = await config?.onResponse?.(res);
|
|
874
999
|
if (onRes instanceof Response) {
|
|
875
1000
|
return onRes;
|
|
@@ -879,225 +1004,20 @@ var createRouter = (endpoints, config) => {
|
|
|
879
1004
|
endpoints
|
|
880
1005
|
};
|
|
881
1006
|
};
|
|
882
|
-
|
|
883
|
-
// src/middleware.ts
|
|
884
|
-
function createMiddleware(optionsOrHandler, handler) {
|
|
885
|
-
if (typeof optionsOrHandler === "function") {
|
|
886
|
-
return createEndpoint(
|
|
887
|
-
"*",
|
|
888
|
-
{
|
|
889
|
-
method: "*"
|
|
890
|
-
},
|
|
891
|
-
optionsOrHandler
|
|
892
|
-
);
|
|
893
|
-
}
|
|
894
|
-
if (!handler) {
|
|
895
|
-
throw new Error("Middleware handler is required");
|
|
896
|
-
}
|
|
897
|
-
const endpoint = createEndpoint(
|
|
898
|
-
"*",
|
|
899
|
-
{
|
|
900
|
-
...optionsOrHandler,
|
|
901
|
-
method: "*"
|
|
902
|
-
},
|
|
903
|
-
handler
|
|
904
|
-
);
|
|
905
|
-
return endpoint;
|
|
906
|
-
}
|
|
907
|
-
var createMiddlewareCreator = (opts) => {
|
|
908
|
-
function fn(optionsOrHandler, handler) {
|
|
909
|
-
if (typeof optionsOrHandler === "function") {
|
|
910
|
-
return createEndpoint(
|
|
911
|
-
"*",
|
|
912
|
-
{
|
|
913
|
-
method: "*"
|
|
914
|
-
},
|
|
915
|
-
optionsOrHandler
|
|
916
|
-
);
|
|
917
|
-
}
|
|
918
|
-
if (!handler) {
|
|
919
|
-
throw new Error("Middleware handler is required");
|
|
920
|
-
}
|
|
921
|
-
const endpoint = createEndpoint(
|
|
922
|
-
"*",
|
|
923
|
-
{
|
|
924
|
-
...optionsOrHandler,
|
|
925
|
-
method: "*"
|
|
926
|
-
},
|
|
927
|
-
handler
|
|
928
|
-
);
|
|
929
|
-
return endpoint;
|
|
930
|
-
}
|
|
931
|
-
return fn;
|
|
932
|
-
};
|
|
933
|
-
|
|
934
|
-
// src/types.ts
|
|
935
|
-
var import_zod2 = require("zod");
|
|
936
|
-
|
|
937
|
-
// src/adapter/request.ts
|
|
938
|
-
var set_cookie_parser = __toESM(require_set_cookie(), 1);
|
|
939
|
-
function get_raw_body(req, body_size_limit) {
|
|
940
|
-
const h = req.headers;
|
|
941
|
-
if (!h["content-type"]) return null;
|
|
942
|
-
const content_length = Number(h["content-length"]);
|
|
943
|
-
if (req.httpVersionMajor === 1 && isNaN(content_length) && h["transfer-encoding"] == null || content_length === 0) {
|
|
944
|
-
return null;
|
|
945
|
-
}
|
|
946
|
-
let length = content_length;
|
|
947
|
-
if (body_size_limit) {
|
|
948
|
-
if (!length) {
|
|
949
|
-
length = body_size_limit;
|
|
950
|
-
} else if (length > body_size_limit) {
|
|
951
|
-
throw Error(
|
|
952
|
-
`Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`
|
|
953
|
-
);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
if (req.destroyed) {
|
|
957
|
-
const readable = new ReadableStream();
|
|
958
|
-
readable.cancel();
|
|
959
|
-
return readable;
|
|
960
|
-
}
|
|
961
|
-
let size = 0;
|
|
962
|
-
let cancelled = false;
|
|
963
|
-
return new ReadableStream({
|
|
964
|
-
start(controller) {
|
|
965
|
-
req.on("error", (error) => {
|
|
966
|
-
cancelled = true;
|
|
967
|
-
controller.error(error);
|
|
968
|
-
});
|
|
969
|
-
req.on("end", () => {
|
|
970
|
-
if (cancelled) return;
|
|
971
|
-
controller.close();
|
|
972
|
-
});
|
|
973
|
-
req.on("data", (chunk) => {
|
|
974
|
-
if (cancelled) return;
|
|
975
|
-
size += chunk.length;
|
|
976
|
-
if (size > length) {
|
|
977
|
-
cancelled = true;
|
|
978
|
-
controller.error(
|
|
979
|
-
new Error(
|
|
980
|
-
`request body size exceeded ${content_length ? "'content-length'" : "BODY_SIZE_LIMIT"} of ${length}`
|
|
981
|
-
)
|
|
982
|
-
);
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
controller.enqueue(chunk);
|
|
986
|
-
if (controller.desiredSize === null || controller.desiredSize <= 0) {
|
|
987
|
-
req.pause();
|
|
988
|
-
}
|
|
989
|
-
});
|
|
990
|
-
},
|
|
991
|
-
pull() {
|
|
992
|
-
req.resume();
|
|
993
|
-
},
|
|
994
|
-
cancel(reason) {
|
|
995
|
-
cancelled = true;
|
|
996
|
-
req.destroy(reason);
|
|
997
|
-
}
|
|
998
|
-
});
|
|
999
|
-
}
|
|
1000
|
-
function getRequest({
|
|
1001
|
-
request,
|
|
1002
|
-
base,
|
|
1003
|
-
bodySizeLimit
|
|
1004
|
-
}) {
|
|
1005
|
-
return new Request(base + request.url, {
|
|
1006
|
-
// @ts-expect-error
|
|
1007
|
-
duplex: "half",
|
|
1008
|
-
method: request.method,
|
|
1009
|
-
body: get_raw_body(request, bodySizeLimit),
|
|
1010
|
-
headers: request.headers
|
|
1011
|
-
});
|
|
1012
|
-
}
|
|
1013
|
-
async function setResponse(res, response) {
|
|
1014
|
-
for (const [key, value] of response.headers) {
|
|
1015
|
-
try {
|
|
1016
|
-
res.setHeader(
|
|
1017
|
-
key,
|
|
1018
|
-
key === "set-cookie" ? set_cookie_parser.splitCookiesString(response.headers.get(key)) : value
|
|
1019
|
-
);
|
|
1020
|
-
} catch (error) {
|
|
1021
|
-
res.getHeaderNames().forEach((name) => res.removeHeader(name));
|
|
1022
|
-
res.writeHead(500).end(String(error));
|
|
1023
|
-
return;
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
res.writeHead(response.status);
|
|
1027
|
-
if (!response.body) {
|
|
1028
|
-
res.end();
|
|
1029
|
-
return;
|
|
1030
|
-
}
|
|
1031
|
-
if (response.body.locked) {
|
|
1032
|
-
res.end(
|
|
1033
|
-
"Fatal error: Response body is locked. This can happen when the response was already read (for example through 'response.json()' or 'response.text()')."
|
|
1034
|
-
);
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
|
-
const reader = response.body.getReader();
|
|
1038
|
-
if (res.destroyed) {
|
|
1039
|
-
reader.cancel();
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
const cancel = (error) => {
|
|
1043
|
-
res.off("close", cancel);
|
|
1044
|
-
res.off("error", cancel);
|
|
1045
|
-
reader.cancel(error).catch(() => {
|
|
1046
|
-
});
|
|
1047
|
-
if (error) res.destroy(error);
|
|
1048
|
-
};
|
|
1049
|
-
res.on("close", cancel);
|
|
1050
|
-
res.on("error", cancel);
|
|
1051
|
-
next();
|
|
1052
|
-
async function next() {
|
|
1053
|
-
try {
|
|
1054
|
-
for (; ; ) {
|
|
1055
|
-
const { done, value } = await reader.read();
|
|
1056
|
-
if (done) break;
|
|
1057
|
-
if (!res.write(value)) {
|
|
1058
|
-
res.once("drain", next);
|
|
1059
|
-
return;
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
res.end();
|
|
1063
|
-
} catch (error) {
|
|
1064
|
-
cancel(error instanceof Error ? error : new Error(String(error)));
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
// src/adapter/node.ts
|
|
1070
|
-
function toNodeHandler(handler) {
|
|
1071
|
-
return async (req, res) => {
|
|
1072
|
-
const protocol = req.headers["x-forwarded-proto"] || (req.socket.encrypted ? "https" : "http");
|
|
1073
|
-
const base = `${protocol}://${req.headers[":authority"] || req.headers.host}`;
|
|
1074
|
-
const response = await handler(getRequest({ base, request: req }));
|
|
1075
|
-
setResponse(res, response);
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1078
1007
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1079
1008
|
0 && (module.exports = {
|
|
1080
1009
|
APIError,
|
|
1010
|
+
_statusCode,
|
|
1081
1011
|
createEndpoint,
|
|
1082
|
-
|
|
1012
|
+
createInternalContext,
|
|
1083
1013
|
createMiddleware,
|
|
1084
|
-
createMiddlewareCreator,
|
|
1085
1014
|
createRouter,
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
serialize,
|
|
1094
|
-
serializeSigned,
|
|
1095
|
-
setCookie,
|
|
1096
|
-
setResponse,
|
|
1097
|
-
setSignedCookie,
|
|
1098
|
-
shouldSerialize,
|
|
1099
|
-
signCookieValue,
|
|
1100
|
-
statusCode,
|
|
1101
|
-
toNodeHandler
|
|
1015
|
+
generator,
|
|
1016
|
+
getCookieKey,
|
|
1017
|
+
getHTML,
|
|
1018
|
+
parseCookies,
|
|
1019
|
+
serializeCookie,
|
|
1020
|
+
serializeSignedCookie,
|
|
1021
|
+
toResponse
|
|
1102
1022
|
});
|
|
1103
1023
|
//# sourceMappingURL=index.cjs.map
|