@kaito-http/core 4.0.0-beta.2 → 4.0.0-beta.21
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/chunk-TL3E52YN.js +835 -0
- package/dist/cors/cors.cjs +85 -17
- package/dist/cors/cors.d.cts +122 -26
- package/dist/cors/cors.d.ts +122 -26
- package/dist/cors/cors.js +85 -17
- package/dist/index.cjs +955 -85
- package/dist/index.d.cts +97 -104
- package/dist/index.d.ts +97 -104
- package/dist/index.js +140 -84
- package/dist/schema/schema.cjs +875 -0
- package/dist/schema/schema.d.cts +333 -0
- package/dist/schema/schema.d.ts +333 -0
- package/dist/schema/schema.js +38 -0
- package/dist/stream/stream.cjs +6 -9
- package/dist/stream/stream.d.cts +11 -8
- package/dist/stream/stream.d.ts +11 -8
- package/dist/stream/stream.js +6 -9
- package/package.json +6 -9
package/dist/index.cjs
CHANGED
|
@@ -20,18 +20,35 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
BaseSchema: () => BaseSchema,
|
|
24
|
+
KArray: () => KArray,
|
|
25
|
+
KBoolean: () => KBoolean,
|
|
26
|
+
KLiteral: () => KLiteral,
|
|
27
|
+
KNull: () => KNull,
|
|
28
|
+
KNumber: () => KNumber,
|
|
29
|
+
KObject: () => KObject,
|
|
30
|
+
KObjectFromURLSearchParams: () => KObjectFromURLSearchParams,
|
|
31
|
+
KRef: () => KRef,
|
|
32
|
+
KScalar: () => KScalar,
|
|
33
|
+
KString: () => KString,
|
|
34
|
+
KUnion: () => KUnion,
|
|
23
35
|
KaitoError: () => KaitoError,
|
|
36
|
+
KaitoHead: () => KaitoHead,
|
|
24
37
|
KaitoRequest: () => KaitoRequest,
|
|
38
|
+
ParseContext: () => ParseContext,
|
|
25
39
|
Router: () => Router,
|
|
40
|
+
STRING_FORMAT_REGEXES: () => STRING_FORMAT_REGEXES,
|
|
41
|
+
SchemaError: () => SchemaError,
|
|
26
42
|
WrappedError: () => WrappedError,
|
|
27
43
|
create: () => create,
|
|
28
|
-
isNodeLikeDev: () => isNodeLikeDev
|
|
44
|
+
isNodeLikeDev: () => isNodeLikeDev,
|
|
45
|
+
isPrimitiveJSONValue: () => isPrimitiveJSONValue,
|
|
46
|
+
k: () => k
|
|
29
47
|
});
|
|
30
48
|
module.exports = __toCommonJS(index_exports);
|
|
31
49
|
|
|
32
50
|
// src/router/router.ts
|
|
33
|
-
var
|
|
34
|
-
var import_zod_openapi = require("zod-openapi");
|
|
51
|
+
var OpenAPI = require("openapi3-ts/oas31");
|
|
35
52
|
|
|
36
53
|
// src/error.ts
|
|
37
54
|
var WrappedError = class _WrappedError extends Error {
|
|
@@ -139,43 +156,865 @@ var KaitoRequest = class {
|
|
|
139
156
|
}
|
|
140
157
|
};
|
|
141
158
|
|
|
159
|
+
// src/schema/schema.ts
|
|
160
|
+
function isPrimitiveJSONValue(value) {
|
|
161
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null;
|
|
162
|
+
}
|
|
163
|
+
var SchemaError = class extends Error {
|
|
164
|
+
constructor(issues) {
|
|
165
|
+
const first = issues.values().next().value;
|
|
166
|
+
if (first === void 0) {
|
|
167
|
+
throw new Error("SchemaError expects at least one issue to be provided");
|
|
168
|
+
}
|
|
169
|
+
super(first.message);
|
|
170
|
+
this.issues = issues;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
var ParseContext = class _ParseContext {
|
|
174
|
+
static ISSUE = Symbol("ISSUE");
|
|
175
|
+
ISSUE = _ParseContext.ISSUE;
|
|
176
|
+
#issues = /* @__PURE__ */ new Set();
|
|
177
|
+
addIssue(message, path) {
|
|
178
|
+
this.#issues.add({ message, path });
|
|
179
|
+
return _ParseContext.ISSUE;
|
|
180
|
+
}
|
|
181
|
+
addIssues(issues, path) {
|
|
182
|
+
for (const issue of issues) {
|
|
183
|
+
this.#issues.add({ ...issue, path: [...path, ...issue.path] });
|
|
184
|
+
}
|
|
185
|
+
return _ParseContext.ISSUE;
|
|
186
|
+
}
|
|
187
|
+
get issues() {
|
|
188
|
+
return this.#issues;
|
|
189
|
+
}
|
|
190
|
+
static result(fn) {
|
|
191
|
+
const result = _ParseContext.with(fn);
|
|
192
|
+
if (result.type === "FATAL" || result.issues.size > 0) {
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
issues: result.issues
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
success: true,
|
|
200
|
+
result: result.data
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
static with(fn) {
|
|
204
|
+
const ctx = new _ParseContext();
|
|
205
|
+
const data = fn(ctx);
|
|
206
|
+
if (data === _ParseContext.ISSUE) {
|
|
207
|
+
return {
|
|
208
|
+
type: "FATAL",
|
|
209
|
+
issues: ctx.issues
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
type: "PARSED",
|
|
214
|
+
issues: ctx.issues,
|
|
215
|
+
data
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
var BaseSchema = class {
|
|
220
|
+
/** @internal */
|
|
221
|
+
_input;
|
|
222
|
+
/** @internal */
|
|
223
|
+
_output;
|
|
224
|
+
def;
|
|
225
|
+
getSchemaObject() {
|
|
226
|
+
const schema = {};
|
|
227
|
+
if (this.def.description !== void 0) {
|
|
228
|
+
schema.description = this.def.description;
|
|
229
|
+
}
|
|
230
|
+
if (this.def.example !== void 0) {
|
|
231
|
+
schema.example = this.def.example;
|
|
232
|
+
}
|
|
233
|
+
return schema;
|
|
234
|
+
}
|
|
235
|
+
clone(def) {
|
|
236
|
+
return new this.constructor({
|
|
237
|
+
...this.def,
|
|
238
|
+
...def
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
constructor(def) {
|
|
242
|
+
this.def = def;
|
|
243
|
+
}
|
|
244
|
+
or(other) {
|
|
245
|
+
return k.union([this, other]);
|
|
246
|
+
}
|
|
247
|
+
example(example) {
|
|
248
|
+
if (example === void 0) {
|
|
249
|
+
return this.def.example;
|
|
250
|
+
}
|
|
251
|
+
return this.clone({ example });
|
|
252
|
+
}
|
|
253
|
+
description(description) {
|
|
254
|
+
if (description === void 0) {
|
|
255
|
+
return this.def.description;
|
|
256
|
+
}
|
|
257
|
+
return this.clone({ description });
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
var STRING_FORMAT_REGEXES = {
|
|
261
|
+
uuid: /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,
|
|
262
|
+
email: /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,
|
|
263
|
+
ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,
|
|
264
|
+
ipv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
|
|
265
|
+
date: /^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/,
|
|
266
|
+
uri: /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/.+|^[a-zA-Z][a-zA-Z0-9+.-]*:[^\/].+/,
|
|
267
|
+
hostname: /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/
|
|
268
|
+
};
|
|
269
|
+
var KString = class _KString extends BaseSchema {
|
|
270
|
+
static create = () => new _KString({});
|
|
271
|
+
serialize(value) {
|
|
272
|
+
return value;
|
|
273
|
+
}
|
|
274
|
+
setCheck(check) {
|
|
275
|
+
return this.clone({ [check.type]: check });
|
|
276
|
+
}
|
|
277
|
+
toOpenAPI() {
|
|
278
|
+
const baseSchema = this.getSchemaObject();
|
|
279
|
+
const schema = {
|
|
280
|
+
...baseSchema,
|
|
281
|
+
type: "string"
|
|
282
|
+
};
|
|
283
|
+
if (this.def.regex) {
|
|
284
|
+
schema.pattern = this.def.regex.regex.source;
|
|
285
|
+
}
|
|
286
|
+
if (this.def.format) {
|
|
287
|
+
schema.format = this.def.format.format;
|
|
288
|
+
}
|
|
289
|
+
if (this.def.min !== void 0) {
|
|
290
|
+
schema.minLength = this.def.min.val;
|
|
291
|
+
}
|
|
292
|
+
if (this.def.max !== void 0) {
|
|
293
|
+
schema.maxLength = this.def.max.val;
|
|
294
|
+
}
|
|
295
|
+
return schema;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Sets the minimum length of the string
|
|
299
|
+
*
|
|
300
|
+
* @param min The minimum length of the string
|
|
301
|
+
* @returns A clone of the schema with the minimum length set
|
|
302
|
+
*/
|
|
303
|
+
min(min, message) {
|
|
304
|
+
return this.setCheck({ type: "min", val: min, message });
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Sets the maximum length of the string
|
|
308
|
+
*
|
|
309
|
+
* @param max The maximum length of the string
|
|
310
|
+
* @returns A clone of the schema with the maximum length set
|
|
311
|
+
*/
|
|
312
|
+
max(max, message) {
|
|
313
|
+
return this.setCheck({ type: "max", val: max, message });
|
|
314
|
+
}
|
|
315
|
+
regex(regex, message) {
|
|
316
|
+
return this.setCheck({ type: "regex", regex, message });
|
|
317
|
+
}
|
|
318
|
+
startsWith(prefix, message) {
|
|
319
|
+
return this.setCheck({ type: "startsWith", prefix, message });
|
|
320
|
+
}
|
|
321
|
+
endsWith(suffix, message) {
|
|
322
|
+
return this.setCheck({ type: "endsWith", suffix, message });
|
|
323
|
+
}
|
|
324
|
+
format(format, message) {
|
|
325
|
+
return this.setCheck({ type: "format", format, message });
|
|
326
|
+
}
|
|
327
|
+
uri(message) {
|
|
328
|
+
return this.format("uri", message);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Deprecated because OpenAPI uses the term "uri"
|
|
332
|
+
* but this method exists for making migration from
|
|
333
|
+
* Zod easier.
|
|
334
|
+
*
|
|
335
|
+
* @deprecated Use {@link uri} instead
|
|
336
|
+
*/
|
|
337
|
+
url(message) {
|
|
338
|
+
return this.uri(message);
|
|
339
|
+
}
|
|
340
|
+
email(message) {
|
|
341
|
+
return this.format("email", message);
|
|
342
|
+
}
|
|
343
|
+
uuid(message) {
|
|
344
|
+
return this.format("uuid", message);
|
|
345
|
+
}
|
|
346
|
+
ipv4(message) {
|
|
347
|
+
return this.format("ipv4", message);
|
|
348
|
+
}
|
|
349
|
+
ipv6(message) {
|
|
350
|
+
return this.format("ipv6", message);
|
|
351
|
+
}
|
|
352
|
+
date(message) {
|
|
353
|
+
return this.format("date", message);
|
|
354
|
+
}
|
|
355
|
+
dateTime(message) {
|
|
356
|
+
return this.format("date-time", message);
|
|
357
|
+
}
|
|
358
|
+
password(message) {
|
|
359
|
+
return this.format("password", message);
|
|
360
|
+
}
|
|
361
|
+
byte(message) {
|
|
362
|
+
return this.format("byte", message);
|
|
363
|
+
}
|
|
364
|
+
binary(message) {
|
|
365
|
+
return this.format("binary", message);
|
|
366
|
+
}
|
|
367
|
+
hostname(message) {
|
|
368
|
+
return this.format("hostname", message);
|
|
369
|
+
}
|
|
370
|
+
parseSafe(json) {
|
|
371
|
+
return ParseContext.result((ctx) => {
|
|
372
|
+
if (typeof json !== "string") {
|
|
373
|
+
return ctx.addIssue("Expected string", []);
|
|
374
|
+
}
|
|
375
|
+
if (this.def.min !== void 0 && json.length < this.def.min.val) {
|
|
376
|
+
ctx.addIssue(this.def.min.message ?? `String must be at least ${this.def.min.val} characters`, []);
|
|
377
|
+
}
|
|
378
|
+
if (this.def.max !== void 0 && json.length > this.def.max.val) {
|
|
379
|
+
ctx.addIssue(this.def.max.message ?? `String must be at most ${this.def.max.val} characters`, []);
|
|
380
|
+
}
|
|
381
|
+
if (this.def.regex !== void 0 && !this.def.regex.regex.test(json)) {
|
|
382
|
+
ctx.addIssue(this.def.regex.message ?? `String must match ${this.def.regex.regex.source}`, []);
|
|
383
|
+
}
|
|
384
|
+
if (this.def.startsWith !== void 0 && !json.startsWith(this.def.startsWith.prefix)) {
|
|
385
|
+
ctx.addIssue(this.def.startsWith.message ?? `String must start with "${this.def.startsWith.prefix}"`, []);
|
|
386
|
+
}
|
|
387
|
+
if (this.def.endsWith !== void 0 && !json.endsWith(this.def.endsWith.suffix)) {
|
|
388
|
+
ctx.addIssue(this.def.endsWith.message ?? `String must end with "${this.def.endsWith.suffix}"`, []);
|
|
389
|
+
}
|
|
390
|
+
if (this.def.format !== void 0) {
|
|
391
|
+
switch (this.def.format.format) {
|
|
392
|
+
case "uuid":
|
|
393
|
+
if (!STRING_FORMAT_REGEXES.uuid.test(json)) {
|
|
394
|
+
ctx.addIssue(this.def.format.message ?? "Invalid UUID format", []);
|
|
395
|
+
}
|
|
396
|
+
break;
|
|
397
|
+
case "email":
|
|
398
|
+
if (!STRING_FORMAT_REGEXES.email.test(json)) {
|
|
399
|
+
ctx.addIssue(this.def.format.message ?? "Invalid email format", []);
|
|
400
|
+
}
|
|
401
|
+
break;
|
|
402
|
+
case "ipv4":
|
|
403
|
+
if (!STRING_FORMAT_REGEXES.ipv4.test(json)) {
|
|
404
|
+
ctx.addIssue(this.def.format.message ?? "Invalid IPv4 address", []);
|
|
405
|
+
}
|
|
406
|
+
break;
|
|
407
|
+
case "ipv6":
|
|
408
|
+
if (!STRING_FORMAT_REGEXES.ipv6.test(json)) {
|
|
409
|
+
ctx.addIssue(this.def.format.message ?? "Invalid IPv6 address", []);
|
|
410
|
+
}
|
|
411
|
+
break;
|
|
412
|
+
case "date":
|
|
413
|
+
if (!STRING_FORMAT_REGEXES.date.test(json)) {
|
|
414
|
+
ctx.addIssue(this.def.format.message ?? "Invalid date format", []);
|
|
415
|
+
}
|
|
416
|
+
break;
|
|
417
|
+
case "date-time":
|
|
418
|
+
if (Number.isNaN(new Date(json).getTime())) {
|
|
419
|
+
ctx.addIssue(this.def.format.message ?? "Invalid date-time format", []);
|
|
420
|
+
}
|
|
421
|
+
break;
|
|
422
|
+
case "byte":
|
|
423
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(json) || json.length % 4 !== 0) {
|
|
424
|
+
ctx.addIssue(this.def.format.message ?? "Invalid base64 format", []);
|
|
425
|
+
}
|
|
426
|
+
break;
|
|
427
|
+
case "uri":
|
|
428
|
+
if (!STRING_FORMAT_REGEXES.uri.test(json)) {
|
|
429
|
+
ctx.addIssue(this.def.format.message ?? "Invalid URI format", []);
|
|
430
|
+
}
|
|
431
|
+
break;
|
|
432
|
+
case "hostname":
|
|
433
|
+
if (!STRING_FORMAT_REGEXES.hostname.test(json)) {
|
|
434
|
+
ctx.addIssue(this.def.format.message ?? "Invalid hostname format", []);
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
case "binary":
|
|
438
|
+
break;
|
|
439
|
+
case "password":
|
|
440
|
+
break;
|
|
441
|
+
default:
|
|
442
|
+
this.def.format.format;
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return json;
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
parse(json) {
|
|
450
|
+
const result = this.parseSafe(json);
|
|
451
|
+
if (!result.success) {
|
|
452
|
+
throw new SchemaError(result.issues);
|
|
453
|
+
}
|
|
454
|
+
return result.result;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
var KNumber = class _KNumber extends BaseSchema {
|
|
458
|
+
static create = () => new _KNumber({});
|
|
459
|
+
serialize(value) {
|
|
460
|
+
return value;
|
|
461
|
+
}
|
|
462
|
+
setCheck(check) {
|
|
463
|
+
return this.clone({ [check.type]: check });
|
|
464
|
+
}
|
|
465
|
+
toOpenAPI() {
|
|
466
|
+
const baseSchema = this.getSchemaObject();
|
|
467
|
+
const schema = {
|
|
468
|
+
...baseSchema,
|
|
469
|
+
type: "number"
|
|
470
|
+
};
|
|
471
|
+
if (this.def.min !== void 0) {
|
|
472
|
+
schema.minimum = this.def.min.val;
|
|
473
|
+
}
|
|
474
|
+
if (this.def.max !== void 0) {
|
|
475
|
+
schema.maximum = this.def.max.val;
|
|
476
|
+
}
|
|
477
|
+
if (this.def.multipleOf !== void 0) {
|
|
478
|
+
schema.multipleOf = this.def.multipleOf.val;
|
|
479
|
+
}
|
|
480
|
+
if (this.def.integer) {
|
|
481
|
+
schema.type = "integer";
|
|
482
|
+
}
|
|
483
|
+
if (this.def.format) {
|
|
484
|
+
switch (this.def.format.format) {
|
|
485
|
+
case "float":
|
|
486
|
+
schema.format = "float";
|
|
487
|
+
schema.type = "number";
|
|
488
|
+
break;
|
|
489
|
+
case "double":
|
|
490
|
+
schema.format = "double";
|
|
491
|
+
schema.type = "number";
|
|
492
|
+
break;
|
|
493
|
+
case "int32":
|
|
494
|
+
schema.format = "int32";
|
|
495
|
+
schema.type = "integer";
|
|
496
|
+
break;
|
|
497
|
+
case "int64":
|
|
498
|
+
schema.format = "int64";
|
|
499
|
+
schema.type = "integer";
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (this.def.format) {
|
|
504
|
+
schema.format = this.def.format.format;
|
|
505
|
+
}
|
|
506
|
+
return schema;
|
|
507
|
+
}
|
|
508
|
+
min(min) {
|
|
509
|
+
return this.setCheck({ type: "min", val: min });
|
|
510
|
+
}
|
|
511
|
+
max(max) {
|
|
512
|
+
return this.setCheck({ type: "max", val: max });
|
|
513
|
+
}
|
|
514
|
+
integer() {
|
|
515
|
+
return this.setCheck({ type: "integer" });
|
|
516
|
+
}
|
|
517
|
+
multipleOf(multipleOf) {
|
|
518
|
+
if (multipleOf <= 0) {
|
|
519
|
+
throw new Error("multipleOf must be a positive number");
|
|
520
|
+
}
|
|
521
|
+
return this.setCheck({ type: "multipleOf", val: multipleOf });
|
|
522
|
+
}
|
|
523
|
+
float() {
|
|
524
|
+
return this.setCheck({ type: "format", format: "float" });
|
|
525
|
+
}
|
|
526
|
+
double() {
|
|
527
|
+
return this.setCheck({ type: "format", format: "double" });
|
|
528
|
+
}
|
|
529
|
+
int32() {
|
|
530
|
+
return this.setCheck({ type: "format", format: "int32" }).integer();
|
|
531
|
+
}
|
|
532
|
+
int64() {
|
|
533
|
+
return this.setCheck({ type: "format", format: "int64" }).integer();
|
|
534
|
+
}
|
|
535
|
+
parseSafe(json) {
|
|
536
|
+
return ParseContext.result((ctx) => {
|
|
537
|
+
if (typeof json !== "number") {
|
|
538
|
+
return ctx.addIssue("Expected number", []);
|
|
539
|
+
}
|
|
540
|
+
if (this.def.integer && !Number.isInteger(json)) {
|
|
541
|
+
ctx.addIssue(this.def.integer.message ?? "Expected integer", []);
|
|
542
|
+
}
|
|
543
|
+
if (this.def.min !== void 0 && json < this.def.min.val) {
|
|
544
|
+
ctx.addIssue(this.def.min.message ?? `Number must be greater than or equal to ${this.def.min.val}`, []);
|
|
545
|
+
}
|
|
546
|
+
if (this.def.max !== void 0 && json > this.def.max.val) {
|
|
547
|
+
ctx.addIssue(this.def.max.message ?? `Number must be less than or equal to ${this.def.max.val}`, []);
|
|
548
|
+
}
|
|
549
|
+
if (this.def.multipleOf !== void 0 && json % this.def.multipleOf.val !== 0) {
|
|
550
|
+
ctx.addIssue(this.def.multipleOf.message ?? `Number must be multiple of ${this.def.multipleOf.val}`, []);
|
|
551
|
+
}
|
|
552
|
+
return json;
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
parse(json) {
|
|
556
|
+
const result = this.parseSafe(json);
|
|
557
|
+
if (!result.success) {
|
|
558
|
+
throw new SchemaError(result.issues);
|
|
559
|
+
}
|
|
560
|
+
return result.result;
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
var KBoolean = class _KBoolean extends BaseSchema {
|
|
564
|
+
static create = () => new _KBoolean({});
|
|
565
|
+
serialize(value) {
|
|
566
|
+
return value;
|
|
567
|
+
}
|
|
568
|
+
toOpenAPI() {
|
|
569
|
+
const baseSchema = this.getSchemaObject();
|
|
570
|
+
return {
|
|
571
|
+
...baseSchema,
|
|
572
|
+
type: "boolean"
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
parseSafe(json) {
|
|
576
|
+
return ParseContext.result((ctx) => {
|
|
577
|
+
if (typeof json !== "boolean") {
|
|
578
|
+
return ctx.addIssue("Expected boolean", []);
|
|
579
|
+
}
|
|
580
|
+
return json;
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
parse(json) {
|
|
584
|
+
const result = this.parseSafe(json);
|
|
585
|
+
if (!result.success) {
|
|
586
|
+
throw new SchemaError(result.issues);
|
|
587
|
+
}
|
|
588
|
+
return result.result;
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
var KArray = class _KArray extends BaseSchema {
|
|
592
|
+
static create = (items) => new _KArray({ items });
|
|
593
|
+
serialize(value) {
|
|
594
|
+
return value.map((item) => this.def.items.serialize(item));
|
|
595
|
+
}
|
|
596
|
+
setCheck(check) {
|
|
597
|
+
return this.clone({ [check.type]: check });
|
|
598
|
+
}
|
|
599
|
+
toOpenAPI() {
|
|
600
|
+
const baseSchema = this.getSchemaObject();
|
|
601
|
+
return {
|
|
602
|
+
...baseSchema,
|
|
603
|
+
type: "array",
|
|
604
|
+
items: this.def.items.toOpenAPI(),
|
|
605
|
+
...this.def.minItems !== void 0 ? { minItems: this.def.minItems.val } : {},
|
|
606
|
+
...this.def.maxItems !== void 0 ? { maxItems: this.def.maxItems.val } : {},
|
|
607
|
+
...this.def.uniqueItems !== void 0 ? { uniqueItems: this.def.uniqueItems.val } : {}
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
min(minItems) {
|
|
611
|
+
return this.setCheck({ type: "minItems", val: minItems });
|
|
612
|
+
}
|
|
613
|
+
max(maxItems) {
|
|
614
|
+
return this.setCheck({ type: "maxItems", val: maxItems });
|
|
615
|
+
}
|
|
616
|
+
unique() {
|
|
617
|
+
return this.setCheck({ type: "uniqueItems", val: true });
|
|
618
|
+
}
|
|
619
|
+
notUnique() {
|
|
620
|
+
return this.setCheck({ type: "uniqueItems", val: false });
|
|
621
|
+
}
|
|
622
|
+
parseSafe(json) {
|
|
623
|
+
return ParseContext.result((ctx) => {
|
|
624
|
+
if (!Array.isArray(json)) {
|
|
625
|
+
return ctx.addIssue("Expected array", []);
|
|
626
|
+
}
|
|
627
|
+
if (this.def.minItems !== void 0 && json.length < this.def.minItems.val) {
|
|
628
|
+
ctx.addIssue(this.def.minItems.message ?? `Array must have at least ${this.def.minItems.val} items`, []);
|
|
629
|
+
}
|
|
630
|
+
if (this.def.maxItems !== void 0 && json.length > this.def.maxItems.val) {
|
|
631
|
+
ctx.addIssue(this.def.maxItems.message ?? `Array must have at most ${this.def.maxItems.val} items`, []);
|
|
632
|
+
}
|
|
633
|
+
if (this.def.uniqueItems?.val === true && new Set(json).size !== json.length) {
|
|
634
|
+
ctx.addIssue(this.def.uniqueItems.message ?? "Array items must be unique", []);
|
|
635
|
+
}
|
|
636
|
+
const items = [];
|
|
637
|
+
for (let i = 0; i < json.length; i++) {
|
|
638
|
+
const item = json[i];
|
|
639
|
+
const result = this.def.items.parseSafe(item);
|
|
640
|
+
if (!result.success) {
|
|
641
|
+
ctx.addIssues(result.issues, [i.toString()]);
|
|
642
|
+
} else {
|
|
643
|
+
items.push(result.result);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return items;
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
parse(json) {
|
|
650
|
+
const result = this.parseSafe(json);
|
|
651
|
+
if (!result.success) {
|
|
652
|
+
throw new SchemaError(result.issues);
|
|
653
|
+
}
|
|
654
|
+
return result.result;
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
var KNull = class _KNull extends BaseSchema {
|
|
658
|
+
static create = () => new _KNull({});
|
|
659
|
+
serialize(value) {
|
|
660
|
+
return value;
|
|
661
|
+
}
|
|
662
|
+
toOpenAPI() {
|
|
663
|
+
const baseSchema = this.getSchemaObject();
|
|
664
|
+
return {
|
|
665
|
+
...baseSchema,
|
|
666
|
+
type: "null"
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
parseSafe(json) {
|
|
670
|
+
return ParseContext.result((ctx) => {
|
|
671
|
+
if (json !== null) {
|
|
672
|
+
return ctx.addIssue("Expected null", []);
|
|
673
|
+
}
|
|
674
|
+
return null;
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
parse(json) {
|
|
678
|
+
const result = this.parseSafe(json);
|
|
679
|
+
if (!result.success) {
|
|
680
|
+
throw new SchemaError(result.issues);
|
|
681
|
+
}
|
|
682
|
+
return result.result;
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
var KObject = class _KObject extends BaseSchema {
|
|
686
|
+
static create = (shape) => new _KObject({ shape });
|
|
687
|
+
serialize(value) {
|
|
688
|
+
const result = {};
|
|
689
|
+
for (const key in this.def.shape) {
|
|
690
|
+
if (Object.prototype.hasOwnProperty.call(this.def.shape, key)) {
|
|
691
|
+
const fieldValue = value[key];
|
|
692
|
+
if (fieldValue === void 0) {
|
|
693
|
+
throw new Error(`Missing required property: ${key}`);
|
|
694
|
+
}
|
|
695
|
+
result[key] = this.def.shape[key].serialize(fieldValue);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return result;
|
|
699
|
+
}
|
|
700
|
+
toOpenAPI() {
|
|
701
|
+
const baseSchema = this.getSchemaObject();
|
|
702
|
+
return {
|
|
703
|
+
...baseSchema,
|
|
704
|
+
type: "object",
|
|
705
|
+
properties: Object.fromEntries(
|
|
706
|
+
Object.entries(this.def.shape).map((entry) => {
|
|
707
|
+
const [key, value] = entry;
|
|
708
|
+
return [key, value.toOpenAPI()];
|
|
709
|
+
})
|
|
710
|
+
),
|
|
711
|
+
required: Object.keys(this.def.shape)
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
parseSafe(json) {
|
|
715
|
+
return ParseContext.result((ctx) => {
|
|
716
|
+
if (typeof json !== "object" || json === null || Array.isArray(json)) {
|
|
717
|
+
return ctx.addIssue(`Expected object, got ${typeof json}`, []);
|
|
718
|
+
}
|
|
719
|
+
const result = {};
|
|
720
|
+
for (const key in this.def.shape) {
|
|
721
|
+
if (Object.prototype.hasOwnProperty.call(this.def.shape, key)) {
|
|
722
|
+
const value = json[key];
|
|
723
|
+
if (value === void 0) {
|
|
724
|
+
return ctx.addIssue(`Missing required property: ${key}`, [key]);
|
|
725
|
+
}
|
|
726
|
+
const parseResult = this.def.shape[key].parseSafe(value);
|
|
727
|
+
if (!parseResult.success) {
|
|
728
|
+
return ctx.addIssues(parseResult.issues, [key]);
|
|
729
|
+
}
|
|
730
|
+
result[key] = parseResult.result;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return result;
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
parse(json) {
|
|
737
|
+
const result = this.parseSafe(json);
|
|
738
|
+
if (!result.success) {
|
|
739
|
+
throw new SchemaError(result.issues);
|
|
740
|
+
}
|
|
741
|
+
return result.result;
|
|
742
|
+
}
|
|
743
|
+
get shape() {
|
|
744
|
+
return this.def.shape;
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
var KObjectFromURLSearchParams = class _KObjectFromURLSearchParams extends KObject {
|
|
748
|
+
static create = (shape) => new _KObjectFromURLSearchParams({ shape });
|
|
749
|
+
serialize(value) {
|
|
750
|
+
return super.serialize(value);
|
|
751
|
+
}
|
|
752
|
+
toOpenAPI() {
|
|
753
|
+
return super.toOpenAPI();
|
|
754
|
+
}
|
|
755
|
+
parseSafe(json) {
|
|
756
|
+
return ParseContext.result((ctx) => {
|
|
757
|
+
if (!(json instanceof URLSearchParams)) {
|
|
758
|
+
return ctx.addIssue(`Expected URLSearchParams, got ${typeof json}`, []);
|
|
759
|
+
}
|
|
760
|
+
const result = {};
|
|
761
|
+
for (const key in this.def.shape) {
|
|
762
|
+
if (Object.prototype.hasOwnProperty.call(this.def.shape, key)) {
|
|
763
|
+
const value = json.get(key);
|
|
764
|
+
if (value === null) {
|
|
765
|
+
return ctx.addIssue(`Missing required property: ${key}`, [key]);
|
|
766
|
+
}
|
|
767
|
+
const parseResult = this.def.shape[key].parseSafe(value);
|
|
768
|
+
if (!parseResult.success) {
|
|
769
|
+
return ctx.addIssues(parseResult.issues, [key]);
|
|
770
|
+
}
|
|
771
|
+
result[key] = parseResult.result;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return result;
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
var KRef = class _KRef extends BaseSchema {
|
|
779
|
+
static create = (name, shape) => new _KRef({ name, shape });
|
|
780
|
+
serialize(value) {
|
|
781
|
+
const result = {};
|
|
782
|
+
for (const key in this.def.shape) {
|
|
783
|
+
if (Object.prototype.hasOwnProperty.call(this.def.shape, key)) {
|
|
784
|
+
const fieldValue = value[key];
|
|
785
|
+
if (fieldValue === void 0) {
|
|
786
|
+
throw new Error(`Missing required property: ${key}`);
|
|
787
|
+
}
|
|
788
|
+
result[key] = this.def.shape[key].serialize(fieldValue);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return result;
|
|
792
|
+
}
|
|
793
|
+
example() {
|
|
794
|
+
throw new Error("Cannot set an example on a KRef");
|
|
795
|
+
}
|
|
796
|
+
toOpenAPI() {
|
|
797
|
+
return {
|
|
798
|
+
$ref: `#/components/schemas/${this.def.name}`,
|
|
799
|
+
...this.def.description ? { description: this.def.description } : {},
|
|
800
|
+
...this.def.summary ? { summary: this.def.summary } : {}
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
parseSafe(json) {
|
|
804
|
+
return ParseContext.result((ctx) => {
|
|
805
|
+
if (typeof json !== "object" || json === null || Array.isArray(json)) {
|
|
806
|
+
return ctx.addIssue(`Expected object, got ${typeof json}`, []);
|
|
807
|
+
}
|
|
808
|
+
const result = {};
|
|
809
|
+
for (const key in this.def.shape) {
|
|
810
|
+
if (Object.prototype.hasOwnProperty.call(this.def.shape, key)) {
|
|
811
|
+
const value = json[key];
|
|
812
|
+
if (value === void 0) {
|
|
813
|
+
return ctx.addIssue(`Missing required property: ${key}`, [key]);
|
|
814
|
+
}
|
|
815
|
+
const parseResult = this.def.shape[key].parseSafe(value);
|
|
816
|
+
if (!parseResult.success) {
|
|
817
|
+
return ctx.addIssues(parseResult.issues, [key]);
|
|
818
|
+
}
|
|
819
|
+
result[key] = parseResult.result;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return result;
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
parse(json) {
|
|
826
|
+
const result = this.parseSafe(json);
|
|
827
|
+
if (!result.success) {
|
|
828
|
+
throw new SchemaError(result.issues);
|
|
829
|
+
}
|
|
830
|
+
return result.result;
|
|
831
|
+
}
|
|
832
|
+
summary(summary) {
|
|
833
|
+
if (summary === void 0) {
|
|
834
|
+
return this.def.summary;
|
|
835
|
+
}
|
|
836
|
+
return this.clone({ summary });
|
|
837
|
+
}
|
|
838
|
+
get shape() {
|
|
839
|
+
return this.def.shape;
|
|
840
|
+
}
|
|
841
|
+
get name() {
|
|
842
|
+
return this.def.name;
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
var KScalar = class _KScalar extends BaseSchema {
|
|
846
|
+
static create = (options) => new _KScalar(options);
|
|
847
|
+
constructor(def) {
|
|
848
|
+
super(def);
|
|
849
|
+
}
|
|
850
|
+
serialize(value) {
|
|
851
|
+
return this.def.toClient(value);
|
|
852
|
+
}
|
|
853
|
+
toOpenAPI() {
|
|
854
|
+
return this.def.schema.toOpenAPI();
|
|
855
|
+
}
|
|
856
|
+
parseSafe(json) {
|
|
857
|
+
return ParseContext.result((ctx) => {
|
|
858
|
+
const jsonValue = this.def.schema.parseSafe(json);
|
|
859
|
+
if (!jsonValue.success) {
|
|
860
|
+
return ctx.addIssues(jsonValue.issues, []);
|
|
861
|
+
}
|
|
862
|
+
try {
|
|
863
|
+
return this.def.toServer(jsonValue.result);
|
|
864
|
+
} catch (error) {
|
|
865
|
+
return ctx.addIssue(error instanceof Error ? error.message : "Conversion failed", []);
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
example(example) {
|
|
870
|
+
if (example === void 0) {
|
|
871
|
+
return this.def.example;
|
|
872
|
+
}
|
|
873
|
+
return this.clone({ example });
|
|
874
|
+
}
|
|
875
|
+
description(description) {
|
|
876
|
+
if (description === void 0) {
|
|
877
|
+
return this.def.schema.description();
|
|
878
|
+
}
|
|
879
|
+
return this.clone({ description });
|
|
880
|
+
}
|
|
881
|
+
parse(json) {
|
|
882
|
+
const result = this.parseSafe(json);
|
|
883
|
+
if (!result.success) {
|
|
884
|
+
throw new SchemaError(result.issues);
|
|
885
|
+
}
|
|
886
|
+
return result.result;
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
var KUnion = class _KUnion extends BaseSchema {
|
|
890
|
+
static create = (items) => new _KUnion({ items });
|
|
891
|
+
serialize(value) {
|
|
892
|
+
for (const option of this.def.items) {
|
|
893
|
+
try {
|
|
894
|
+
return option.serialize(value);
|
|
895
|
+
} catch {
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
throw new Error("Value does not match any union option for serialization");
|
|
899
|
+
}
|
|
900
|
+
toOpenAPI() {
|
|
901
|
+
const baseSchema = this.getSchemaObject();
|
|
902
|
+
return {
|
|
903
|
+
...baseSchema,
|
|
904
|
+
oneOf: this.def.items.map((option) => option.toOpenAPI())
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
parseSafe(json) {
|
|
908
|
+
let lastIssues;
|
|
909
|
+
for (const option of this.def.items) {
|
|
910
|
+
const result = option.parseSafe(json);
|
|
911
|
+
if (result.success) {
|
|
912
|
+
return { success: true, result: result.result };
|
|
913
|
+
} else {
|
|
914
|
+
lastIssues = result.issues;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
return { success: false, issues: lastIssues ?? /* @__PURE__ */ new Set([{ message: "No union option matched", path: [] }]) };
|
|
918
|
+
}
|
|
919
|
+
parse(json) {
|
|
920
|
+
const result = this.parseSafe(json);
|
|
921
|
+
if (!result.success) {
|
|
922
|
+
throw new SchemaError(result.issues);
|
|
923
|
+
}
|
|
924
|
+
return result.result;
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
var KLiteral = class _KLiteral extends BaseSchema {
|
|
928
|
+
parse(json) {
|
|
929
|
+
const result = this.parseSafe(json);
|
|
930
|
+
if (!result.success) {
|
|
931
|
+
throw new SchemaError(result.issues);
|
|
932
|
+
}
|
|
933
|
+
return result.result;
|
|
934
|
+
}
|
|
935
|
+
static create = (value) => new _KLiteral({ value });
|
|
936
|
+
serialize(value) {
|
|
937
|
+
return value;
|
|
938
|
+
}
|
|
939
|
+
toOpenAPI() {
|
|
940
|
+
const baseSchema = this.getSchemaObject();
|
|
941
|
+
const type = typeof this.def.value;
|
|
942
|
+
return {
|
|
943
|
+
...baseSchema,
|
|
944
|
+
type,
|
|
945
|
+
enum: [this.def.value]
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
parseSafe(json) {
|
|
949
|
+
return ParseContext.result((ctx) => {
|
|
950
|
+
if (json !== this.def.value) {
|
|
951
|
+
return ctx.addIssue(`Expected ${this.def.value}`, []);
|
|
952
|
+
}
|
|
953
|
+
return this.def.value;
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
var k = {
|
|
958
|
+
string: KString.create,
|
|
959
|
+
number: KNumber.create,
|
|
960
|
+
boolean: KBoolean.create,
|
|
961
|
+
array: KArray.create,
|
|
962
|
+
null: KNull.create,
|
|
963
|
+
ref: KRef.create,
|
|
964
|
+
object: KObject.create,
|
|
965
|
+
scalar: KScalar.create,
|
|
966
|
+
literal: KLiteral.create,
|
|
967
|
+
union: KUnion.create,
|
|
968
|
+
/**
|
|
969
|
+
* @internal
|
|
970
|
+
* @experimental
|
|
971
|
+
*/
|
|
972
|
+
objectFromURLSearchParams: KObjectFromURLSearchParams.create
|
|
973
|
+
};
|
|
974
|
+
|
|
142
975
|
// src/util.ts
|
|
143
976
|
var isNodeLikeDev = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.NODE_ENV === "development";
|
|
144
977
|
|
|
145
978
|
// src/router/router.ts
|
|
146
979
|
var Router = class _Router {
|
|
147
|
-
state;
|
|
148
|
-
static create = (config) =>
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
980
|
+
#state;
|
|
981
|
+
static create = (config = {}) => {
|
|
982
|
+
return new _Router({
|
|
983
|
+
through: (context) => context,
|
|
984
|
+
routes: /* @__PURE__ */ new Set(),
|
|
985
|
+
config
|
|
986
|
+
});
|
|
987
|
+
};
|
|
153
988
|
constructor(state) {
|
|
154
|
-
this
|
|
989
|
+
this.#state = state;
|
|
155
990
|
}
|
|
156
991
|
get routes() {
|
|
157
|
-
return this
|
|
992
|
+
return this.#state.routes;
|
|
158
993
|
}
|
|
159
994
|
add = (method, path, route) => {
|
|
160
995
|
const merged = {
|
|
161
996
|
...typeof route === "object" ? route : { run: route },
|
|
162
997
|
method,
|
|
163
998
|
path,
|
|
164
|
-
|
|
999
|
+
router: this
|
|
165
1000
|
};
|
|
166
1001
|
return new _Router({
|
|
167
|
-
...this
|
|
168
|
-
routes: /* @__PURE__ */ new Set([...this
|
|
1002
|
+
...this.#state,
|
|
1003
|
+
routes: /* @__PURE__ */ new Set([...this.#state.routes, merged])
|
|
169
1004
|
});
|
|
170
1005
|
};
|
|
1006
|
+
params = () => this;
|
|
171
1007
|
merge = (pathPrefix, other) => {
|
|
172
|
-
const newRoutes = [...other
|
|
1008
|
+
const newRoutes = [...other.#state.routes].map((route) => ({
|
|
173
1009
|
...route,
|
|
174
|
-
|
|
1010
|
+
// handle pathPrefix = / & route.path = / case causing //
|
|
1011
|
+
// we intentionally are replacing on the joining path and not the pathPrefix, in case of
|
|
1012
|
+
// /named -> merged to -> / causing /named/ not /named
|
|
1013
|
+
path: `${pathPrefix}${route.path === "/" ? "" : route.path}`
|
|
175
1014
|
}));
|
|
176
1015
|
return new _Router({
|
|
177
|
-
...this
|
|
178
|
-
routes: /* @__PURE__ */ new Set([...this
|
|
1016
|
+
...this.#state,
|
|
1017
|
+
routes: /* @__PURE__ */ new Set([...this.#state.routes, ...newRoutes])
|
|
179
1018
|
});
|
|
180
1019
|
};
|
|
181
1020
|
static getFindRoute = (routes) => (method, path) => {
|
|
@@ -203,32 +1042,22 @@ var Router = class _Router {
|
|
|
203
1042
|
}
|
|
204
1043
|
return {};
|
|
205
1044
|
};
|
|
206
|
-
static buildQuerySchema = (schema) => {
|
|
207
|
-
const keys = Object.keys(schema);
|
|
208
|
-
return import_zod.z.instanceof(URLSearchParams).transform((params) => {
|
|
209
|
-
const result = {};
|
|
210
|
-
for (const key of keys) {
|
|
211
|
-
result[key] = params.get(key);
|
|
212
|
-
}
|
|
213
|
-
return result;
|
|
214
|
-
}).pipe(import_zod.z.object(schema));
|
|
215
|
-
};
|
|
216
1045
|
serve = () => {
|
|
217
1046
|
const methodToRoutesMap = /* @__PURE__ */ new Map();
|
|
218
|
-
for (const route of this
|
|
1047
|
+
for (const route of this.#state.routes) {
|
|
219
1048
|
if (!methodToRoutesMap.has(route.method)) {
|
|
220
1049
|
methodToRoutesMap.set(route.method, /* @__PURE__ */ new Map());
|
|
221
1050
|
}
|
|
222
1051
|
methodToRoutesMap.get(route.method).set(route.path, {
|
|
223
1052
|
...route,
|
|
224
|
-
fastQuerySchema: route.query ?
|
|
1053
|
+
fastQuerySchema: route.query ? k.objectFromURLSearchParams(route.query) : void 0
|
|
225
1054
|
});
|
|
226
1055
|
}
|
|
227
1056
|
const findRoute = _Router.getFindRoute(methodToRoutesMap);
|
|
228
|
-
const handle = async (req) => {
|
|
1057
|
+
const handle = async (req, ...args) => {
|
|
229
1058
|
const url = new URL(req.url);
|
|
230
1059
|
const method = req.method;
|
|
231
|
-
const { route, params } = findRoute(method, url.pathname);
|
|
1060
|
+
const { route, params: rawParams } = findRoute(method, url.pathname);
|
|
232
1061
|
if (!route) {
|
|
233
1062
|
const body = {
|
|
234
1063
|
success: false,
|
|
@@ -240,14 +1069,17 @@ var Router = class _Router {
|
|
|
240
1069
|
const request = new KaitoRequest(url, req);
|
|
241
1070
|
const head = new KaitoHead();
|
|
242
1071
|
try {
|
|
243
|
-
const body = route.body ? await route.body.
|
|
244
|
-
const query = route.fastQuerySchema ?
|
|
245
|
-
const ctx = await route.
|
|
1072
|
+
const body = route.body ? await route.body.parse(await req.json()) : void 0;
|
|
1073
|
+
const query = route.fastQuerySchema ? route.fastQuerySchema.parse(url.searchParams) : {};
|
|
1074
|
+
const ctx = await route.router.#state.through(
|
|
1075
|
+
await this.#state.config.getContext?.(request, head, ...args) ?? null,
|
|
1076
|
+
rawParams
|
|
1077
|
+
);
|
|
246
1078
|
const result = await route.run({
|
|
247
1079
|
ctx,
|
|
248
1080
|
body,
|
|
249
1081
|
query,
|
|
250
|
-
params
|
|
1082
|
+
params: rawParams
|
|
251
1083
|
});
|
|
252
1084
|
if (result instanceof Response) {
|
|
253
1085
|
if (isNodeLikeDev) {
|
|
@@ -263,6 +1095,18 @@ var Router = class _Router {
|
|
|
263
1095
|
}
|
|
264
1096
|
return result;
|
|
265
1097
|
}
|
|
1098
|
+
if (route.openapi?.schema) {
|
|
1099
|
+
if (route.openapi.type !== "json") {
|
|
1100
|
+
throw new Error(
|
|
1101
|
+
`Cannot use openapi schema for ${route.method} ${route.path} because it is not a json output type`
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
const parsed = route.openapi.schema.serialize(result);
|
|
1105
|
+
return head.toResponse({
|
|
1106
|
+
success: true,
|
|
1107
|
+
data: parsed
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
266
1110
|
return head.toResponse({
|
|
267
1111
|
success: true,
|
|
268
1112
|
data: result
|
|
@@ -276,7 +1120,7 @@ var Router = class _Router {
|
|
|
276
1120
|
message: error.message
|
|
277
1121
|
});
|
|
278
1122
|
}
|
|
279
|
-
if (!this
|
|
1123
|
+
if (!this.#state.config.onError) {
|
|
280
1124
|
return head.status(500).toResponse({
|
|
281
1125
|
success: false,
|
|
282
1126
|
data: null,
|
|
@@ -284,14 +1128,14 @@ var Router = class _Router {
|
|
|
284
1128
|
});
|
|
285
1129
|
}
|
|
286
1130
|
try {
|
|
287
|
-
const { status, message } = await this
|
|
1131
|
+
const { status, message } = await this.#state.config.onError(error, request);
|
|
288
1132
|
return head.status(status).toResponse({
|
|
289
1133
|
success: false,
|
|
290
1134
|
data: null,
|
|
291
1135
|
message
|
|
292
1136
|
});
|
|
293
1137
|
} catch (e2) {
|
|
294
|
-
console.error("
|
|
1138
|
+
console.error("[Kaito] Failed to handle error inside `.onError()`, returning 500 and Internal Server Error");
|
|
295
1139
|
console.error(e2);
|
|
296
1140
|
return head.status(500).toResponse({
|
|
297
1141
|
success: false,
|
|
@@ -301,12 +1145,12 @@ var Router = class _Router {
|
|
|
301
1145
|
}
|
|
302
1146
|
}
|
|
303
1147
|
};
|
|
304
|
-
return async (request) => {
|
|
305
|
-
if (this
|
|
306
|
-
const result = await this
|
|
1148
|
+
return async (request, ...args) => {
|
|
1149
|
+
if (this.#state.config.before) {
|
|
1150
|
+
const result = await this.#state.config.before(request);
|
|
307
1151
|
if (result instanceof Response) {
|
|
308
|
-
if (this
|
|
309
|
-
const transformed = await this
|
|
1152
|
+
if (this.#state.config.transform) {
|
|
1153
|
+
const transformed = await this.#state.config.transform(request, result);
|
|
310
1154
|
if (transformed instanceof Response) {
|
|
311
1155
|
return result;
|
|
312
1156
|
}
|
|
@@ -314,9 +1158,9 @@ var Router = class _Router {
|
|
|
314
1158
|
return result;
|
|
315
1159
|
}
|
|
316
1160
|
}
|
|
317
|
-
const response = await handle(request);
|
|
318
|
-
if (this
|
|
319
|
-
const transformed = await this
|
|
1161
|
+
const response = await handle(request, ...args);
|
|
1162
|
+
if (this.#state.config.transform) {
|
|
1163
|
+
const transformed = await this.#state.config.transform(request, response);
|
|
320
1164
|
if (transformed instanceof Response) {
|
|
321
1165
|
return transformed;
|
|
322
1166
|
}
|
|
@@ -324,66 +1168,70 @@ var Router = class _Router {
|
|
|
324
1168
|
return response;
|
|
325
1169
|
};
|
|
326
1170
|
};
|
|
327
|
-
openapi = (
|
|
328
|
-
|
|
1171
|
+
openapi = ({
|
|
1172
|
+
info,
|
|
1173
|
+
servers
|
|
1174
|
+
}) => {
|
|
1175
|
+
const OPENAPI_VERSION = "3.1.0";
|
|
329
1176
|
const paths = {};
|
|
330
|
-
for (const route of this
|
|
331
|
-
|
|
332
|
-
|
|
1177
|
+
for (const route of this.#state.routes) {
|
|
1178
|
+
if (!route.openapi) {
|
|
1179
|
+
continue;
|
|
1180
|
+
}
|
|
1181
|
+
const pathWithColonParamsReplaceWithCurlyBraces = route.path.replace(/:(\w+)/g, "{$1}");
|
|
333
1182
|
if (!paths[pathWithColonParamsReplaceWithCurlyBraces]) {
|
|
334
1183
|
paths[pathWithColonParamsReplaceWithCurlyBraces] = {};
|
|
335
1184
|
}
|
|
1185
|
+
let contentType;
|
|
1186
|
+
const type = route.openapi.type;
|
|
1187
|
+
switch (type) {
|
|
1188
|
+
case "json":
|
|
1189
|
+
contentType = "application/json";
|
|
1190
|
+
break;
|
|
1191
|
+
case "sse":
|
|
1192
|
+
contentType = "text/event-stream";
|
|
1193
|
+
break;
|
|
1194
|
+
default:
|
|
1195
|
+
throw new Error(`Unknown output type in route ${route.method} ${route.path}: ${type}`);
|
|
1196
|
+
}
|
|
336
1197
|
const item = {
|
|
337
1198
|
description: route.openapi?.description ?? "Successful response",
|
|
338
1199
|
responses: {
|
|
339
1200
|
200: {
|
|
340
1201
|
description: route.openapi?.description ?? "Successful response",
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
1202
|
+
content: {
|
|
1203
|
+
[contentType]: {
|
|
1204
|
+
schema: k.object({
|
|
1205
|
+
success: k.literal(true),
|
|
1206
|
+
data: route.openapi.schema
|
|
1207
|
+
}).toOpenAPI()
|
|
347
1208
|
}
|
|
348
|
-
}
|
|
1209
|
+
}
|
|
349
1210
|
}
|
|
350
1211
|
}
|
|
351
1212
|
};
|
|
352
1213
|
if (route.body) {
|
|
353
1214
|
item.requestBody = {
|
|
354
1215
|
content: {
|
|
355
|
-
"application/json": { schema: route.body }
|
|
1216
|
+
"application/json": { schema: route.body.toOpenAPI() }
|
|
356
1217
|
}
|
|
357
1218
|
};
|
|
358
1219
|
}
|
|
359
|
-
const params = {};
|
|
360
|
-
if (route.query) {
|
|
361
|
-
params.query = import_zod.z.object(route.query);
|
|
362
|
-
}
|
|
363
|
-
const urlParams = path.match(/:(\w+)/g);
|
|
364
|
-
if (urlParams) {
|
|
365
|
-
const pathParams = {};
|
|
366
|
-
for (const param of urlParams) {
|
|
367
|
-
pathParams[param.slice(1)] = import_zod.z.string();
|
|
368
|
-
}
|
|
369
|
-
params.path = import_zod.z.object(pathParams);
|
|
370
|
-
}
|
|
371
|
-
item.requestParams = params;
|
|
372
1220
|
paths[pathWithColonParamsReplaceWithCurlyBraces][route.method.toLowerCase()] = item;
|
|
373
1221
|
}
|
|
374
|
-
const doc =
|
|
1222
|
+
const doc = {
|
|
375
1223
|
openapi: OPENAPI_VERSION,
|
|
1224
|
+
info,
|
|
376
1225
|
paths,
|
|
377
|
-
|
|
378
|
-
servers: Object.entries(highLevelSpec.servers ?? {}).map((entry) => {
|
|
1226
|
+
servers: Object.entries(servers ?? {}).map((entry) => {
|
|
379
1227
|
const [url, description] = entry;
|
|
380
1228
|
return {
|
|
381
1229
|
url,
|
|
382
1230
|
description
|
|
383
1231
|
};
|
|
384
1232
|
})
|
|
385
|
-
}
|
|
386
|
-
return this.
|
|
1233
|
+
};
|
|
1234
|
+
return this.get("/openapi.json", () => Response.json(doc));
|
|
387
1235
|
};
|
|
388
1236
|
method = (method) => {
|
|
389
1237
|
return (path, route) => this.add(method, path, route);
|
|
@@ -397,22 +1245,44 @@ var Router = class _Router {
|
|
|
397
1245
|
options = this.method("OPTIONS");
|
|
398
1246
|
through = (through) => {
|
|
399
1247
|
return new _Router({
|
|
400
|
-
...this
|
|
401
|
-
through:
|
|
1248
|
+
...this.#state,
|
|
1249
|
+
through: (context, params) => {
|
|
1250
|
+
const next = this.#state.through(context, params);
|
|
1251
|
+
if (next instanceof Promise) {
|
|
1252
|
+
return next.then((next2) => through(next2, params));
|
|
1253
|
+
}
|
|
1254
|
+
return through(next, params);
|
|
1255
|
+
}
|
|
402
1256
|
});
|
|
403
1257
|
};
|
|
404
1258
|
};
|
|
405
1259
|
|
|
406
|
-
// src/
|
|
407
|
-
|
|
408
|
-
return () => Router.create(config);
|
|
409
|
-
}
|
|
1260
|
+
// src/index.ts
|
|
1261
|
+
var create = Router.create;
|
|
410
1262
|
// Annotate the CommonJS export names for ESM import in node:
|
|
411
1263
|
0 && (module.exports = {
|
|
1264
|
+
BaseSchema,
|
|
1265
|
+
KArray,
|
|
1266
|
+
KBoolean,
|
|
1267
|
+
KLiteral,
|
|
1268
|
+
KNull,
|
|
1269
|
+
KNumber,
|
|
1270
|
+
KObject,
|
|
1271
|
+
KObjectFromURLSearchParams,
|
|
1272
|
+
KRef,
|
|
1273
|
+
KScalar,
|
|
1274
|
+
KString,
|
|
1275
|
+
KUnion,
|
|
412
1276
|
KaitoError,
|
|
1277
|
+
KaitoHead,
|
|
413
1278
|
KaitoRequest,
|
|
1279
|
+
ParseContext,
|
|
414
1280
|
Router,
|
|
1281
|
+
STRING_FORMAT_REGEXES,
|
|
1282
|
+
SchemaError,
|
|
415
1283
|
WrappedError,
|
|
416
1284
|
create,
|
|
417
|
-
isNodeLikeDev
|
|
1285
|
+
isNodeLikeDev,
|
|
1286
|
+
isPrimitiveJSONValue,
|
|
1287
|
+
k
|
|
418
1288
|
});
|