@elysiajs/openapi 1.4.2 → 1.4.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/bun.lock +11 -2
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +98 -11
- package/dist/cjs/openapi.js +94 -11
- package/dist/cjs/types.d.ts +5 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +98 -11
- package/dist/openapi.mjs +94 -11
- package/dist/types.d.ts +5 -3
- package/package.json +3 -2
package/bun.lock
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"@scalar/types": "^0.2.13",
|
|
9
9
|
"@sinclair/typemap": "^0.10.1",
|
|
10
10
|
"@types/bun": "1.2.20",
|
|
11
|
-
"
|
|
11
|
+
"effect": "^3.17.13",
|
|
12
|
+
"elysia": "1.4.6",
|
|
12
13
|
"eslint": "9.6.0",
|
|
13
14
|
"openapi-types": "^12.1.3",
|
|
14
15
|
"tsup": "^8.5.0",
|
|
@@ -167,6 +168,8 @@
|
|
|
167
168
|
|
|
168
169
|
"@sinclair/typemap": ["@sinclair/typemap@0.10.1", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.30", "valibot": "^1.0.0", "zod": "^3.24.1" } }, "sha512-UXR0fhu/n3c9B6lB+SLI5t1eVpt9i9CdDrp2TajRe3LbKiUhCTZN2kSfJhjPnpc3I59jMRIhgew7+0HlMi08mg=="],
|
|
169
170
|
|
|
171
|
+
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
|
172
|
+
|
|
170
173
|
"@tokenizer/inflate": ["@tokenizer/inflate@0.2.7", "", { "dependencies": { "debug": "^4.4.0", "fflate": "^0.8.2", "token-types": "^6.0.0" } }, "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg=="],
|
|
171
174
|
|
|
172
175
|
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
|
@@ -239,7 +242,9 @@
|
|
|
239
242
|
|
|
240
243
|
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
|
241
244
|
|
|
242
|
-
"
|
|
245
|
+
"effect": ["effect@3.17.13", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-JMz5oBxs/6mu4FP9Csjub4jYMUwMLrp+IzUmSDVIzn2NoeoyOXMl7x1lghfr3dLKWffWrdnv/d8nFFdgrHXPqw=="],
|
|
246
|
+
|
|
247
|
+
"elysia": ["elysia@1.4.6", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.2.2", "fast-decode-uri-component": "^1.0.1" }, "optionalDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "openapi-types": ">= 12.0.0" }, "peerDependencies": { "file-type": ">= 20.0.0", "typescript": ">= 5.0.0" } }, "sha512-u2CorXLPs5ZXyWP+tQR+bgka/lJA4vNpB8lDE2w/sTmdaIwoPQmHEL4J3ai6OAlluWR1kfG7T9gO3EYT9D8viQ=="],
|
|
243
248
|
|
|
244
249
|
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
|
245
250
|
|
|
@@ -265,6 +270,8 @@
|
|
|
265
270
|
|
|
266
271
|
"exact-mirror": ["exact-mirror@0.2.2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-CrGe+4QzHZlnrXZVlo/WbUZ4qQZq8C0uATQVGVgXIrNXgHDBBNFD1VRfssRA2C9t3RYvh3MadZSdg2Wy7HBoQA=="],
|
|
267
272
|
|
|
273
|
+
"fast-check": ["fast-check@3.23.2", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="],
|
|
274
|
+
|
|
268
275
|
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
|
|
269
276
|
|
|
270
277
|
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
|
@@ -405,6 +412,8 @@
|
|
|
405
412
|
|
|
406
413
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
|
407
414
|
|
|
415
|
+
"pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
|
|
416
|
+
|
|
408
417
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
|
409
418
|
|
|
410
419
|
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
|
-
import type { ElysiaOpenAPIConfig
|
|
2
|
+
import type { ElysiaOpenAPIConfig } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Plugin for [elysia](https://github.com/elysiajs/elysia) that auto-generate OpenAPI documentation page.
|
|
5
5
|
*
|
|
6
6
|
* @see https://github.com/elysiajs/elysia-swagger
|
|
7
7
|
*/
|
|
8
|
-
export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi"
|
|
8
|
+
export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi">({ enabled, path, provider, specPath, documentation, exclude, swagger, scalar, references, mapJsonSchema }?: ElysiaOpenAPIConfig<Enabled, Path>) => Elysia<"", {
|
|
9
9
|
decorator: {};
|
|
10
10
|
store: {};
|
|
11
11
|
derive: {};
|
package/dist/cjs/index.js
CHANGED
|
@@ -317,12 +317,51 @@ var getPossiblePath = (path) => {
|
|
|
317
317
|
}
|
|
318
318
|
return paths;
|
|
319
319
|
};
|
|
320
|
-
var isValidSchema = (schema) => typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
320
|
+
var isValidSchema = (schema) => schema && typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
321
321
|
var getLoosePath = (path) => {
|
|
322
322
|
if (path.charCodeAt(path.length - 1) === 47)
|
|
323
323
|
return path.slice(0, path.length - 1);
|
|
324
324
|
return path + "/";
|
|
325
325
|
};
|
|
326
|
+
var warnings = {
|
|
327
|
+
zod4: `import openapi from '@elysiajs/openapi'
|
|
328
|
+
import * as z from 'zod'
|
|
329
|
+
|
|
330
|
+
openapi({
|
|
331
|
+
mapJsonSchema: {
|
|
332
|
+
zod: z.toJSONSchema
|
|
333
|
+
}
|
|
334
|
+
})`,
|
|
335
|
+
zod3: `import openapi from '@elysiajs/openapi'
|
|
336
|
+
import { zodToJsonSchema } from 'zod-to-json-schema'
|
|
337
|
+
|
|
338
|
+
openapi({
|
|
339
|
+
mapJsonSchema: {
|
|
340
|
+
zod: zodToJsonSchema
|
|
341
|
+
}
|
|
342
|
+
})`,
|
|
343
|
+
valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
|
|
344
|
+
|
|
345
|
+
openapi({
|
|
346
|
+
mapJsonSchema: {
|
|
347
|
+
valibot: toJsonSchema
|
|
348
|
+
}
|
|
349
|
+
})`,
|
|
350
|
+
effect: `import { JSONSchema } from 'effect'
|
|
351
|
+
|
|
352
|
+
openapi({
|
|
353
|
+
mapJsonSchema: {
|
|
354
|
+
effect: JSONSchema.make
|
|
355
|
+
}
|
|
356
|
+
})`
|
|
357
|
+
};
|
|
358
|
+
var warned = {};
|
|
359
|
+
var unwrapReference = (schema, definitions) => {
|
|
360
|
+
if (!schema?.$ref) return schema;
|
|
361
|
+
const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
|
|
362
|
+
if (schema.$ref && definitions[name]) schema = definitions[name];
|
|
363
|
+
return schema;
|
|
364
|
+
};
|
|
326
365
|
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
327
366
|
if (!schema) return;
|
|
328
367
|
if (typeof schema === "string") schema = toRef(schema);
|
|
@@ -331,8 +370,49 @@ var unwrapSchema = (schema, mapJsonSchema) => {
|
|
|
331
370
|
const vendor = schema["~standard"].vendor;
|
|
332
371
|
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
333
372
|
return mapJsonSchema[vendor](schema);
|
|
334
|
-
|
|
335
|
-
|
|
373
|
+
switch (vendor) {
|
|
374
|
+
case "zod":
|
|
375
|
+
if (warned.zod4 || warned.zod3) break;
|
|
376
|
+
console.warn(
|
|
377
|
+
"[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
|
|
378
|
+
);
|
|
379
|
+
if ("_zod" in schema) {
|
|
380
|
+
warned.zod4 = true;
|
|
381
|
+
console.warn(
|
|
382
|
+
"For Zod v4, please provide z.toJSONSchema as follows:\n"
|
|
383
|
+
);
|
|
384
|
+
console.warn(warnings.zod4);
|
|
385
|
+
} else {
|
|
386
|
+
warned.zod3 = true;
|
|
387
|
+
console.warn(
|
|
388
|
+
"For Zod v3, please install zod-to-json-schema package and use it like this:\n"
|
|
389
|
+
);
|
|
390
|
+
console.warn(warnings.zod3);
|
|
391
|
+
}
|
|
392
|
+
break;
|
|
393
|
+
case "valibot":
|
|
394
|
+
if (warned.valibot) break;
|
|
395
|
+
warned.valibot = true;
|
|
396
|
+
console.warn(
|
|
397
|
+
"[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
|
|
398
|
+
);
|
|
399
|
+
console.warn(
|
|
400
|
+
"Please install @valibot/to-json-schema package and use it like this:\n"
|
|
401
|
+
);
|
|
402
|
+
console.warn(warnings.valibot);
|
|
403
|
+
break;
|
|
404
|
+
case "effect":
|
|
405
|
+
if (warned.effect) break;
|
|
406
|
+
warned.effect = true;
|
|
407
|
+
console.warn(
|
|
408
|
+
"[@elysiajs/openapi] Effect Schema doesn't provide JSON Schema method on the schema"
|
|
409
|
+
);
|
|
410
|
+
console.warn(
|
|
411
|
+
"please provide JSONSchema from 'effect' package as follows:\n"
|
|
412
|
+
);
|
|
413
|
+
console.warn(warnings.effect);
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
336
416
|
if (vendor === "arktype")
|
|
337
417
|
return schema?.toJsonSchema?.();
|
|
338
418
|
return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
|
|
@@ -345,6 +425,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
345
425
|
} = exclude ?? {};
|
|
346
426
|
const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
|
|
347
427
|
const paths = /* @__PURE__ */ Object.create(null);
|
|
428
|
+
const definitions = app.getGlobalDefinitions?.().type;
|
|
348
429
|
const routes = app.getGlobalRoutes();
|
|
349
430
|
if (references) {
|
|
350
431
|
if (!Array.isArray(references)) references = [references];
|
|
@@ -359,7 +440,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
359
440
|
if (excludeStaticFile && route.path.includes(".") || excludePaths.includes(route.path) || excludeMethods.includes(method))
|
|
360
441
|
continue;
|
|
361
442
|
const hooks = route.hooks ?? {};
|
|
362
|
-
if (references)
|
|
443
|
+
if (references?.length)
|
|
363
444
|
for (const reference of references) {
|
|
364
445
|
if (!reference) continue;
|
|
365
446
|
const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
|
|
@@ -390,7 +471,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
390
471
|
};
|
|
391
472
|
const parameters = [];
|
|
392
473
|
if (hooks.params) {
|
|
393
|
-
const params =
|
|
474
|
+
const params = unwrapReference(
|
|
475
|
+
unwrapSchema(hooks.params, vendors),
|
|
476
|
+
definitions
|
|
477
|
+
);
|
|
394
478
|
if (params && params.type === "object" && params.properties)
|
|
395
479
|
for (const [paramName, paramSchema] of Object.entries(
|
|
396
480
|
params.properties
|
|
@@ -404,7 +488,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
404
488
|
});
|
|
405
489
|
}
|
|
406
490
|
if (hooks.query) {
|
|
407
|
-
|
|
491
|
+
const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
408
492
|
if (query && query.type === "object" && query.properties) {
|
|
409
493
|
const required = query.required || [];
|
|
410
494
|
for (const [queryName, querySchema] of Object.entries(
|
|
@@ -419,7 +503,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
419
503
|
}
|
|
420
504
|
}
|
|
421
505
|
if (hooks.headers) {
|
|
422
|
-
const headers = unwrapSchema(hooks.query, vendors);
|
|
506
|
+
const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
423
507
|
if (headers && headers.type === "object" && headers.properties) {
|
|
424
508
|
const required = headers.required || [];
|
|
425
509
|
for (const [headerName, headerSchema] of Object.entries(
|
|
@@ -434,7 +518,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
434
518
|
}
|
|
435
519
|
}
|
|
436
520
|
if (hooks.cookie) {
|
|
437
|
-
const cookie = unwrapSchema(hooks.cookie, vendors);
|
|
521
|
+
const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
|
|
438
522
|
if (cookie && cookie.type === "object" && cookie.properties) {
|
|
439
523
|
const required = cookie.required || [];
|
|
440
524
|
for (const [cookieName, cookieSchema] of Object.entries(
|
|
@@ -578,10 +662,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
578
662
|
};
|
|
579
663
|
}
|
|
580
664
|
}
|
|
581
|
-
const _schemas = app.getGlobalDefinitions?.().type;
|
|
582
665
|
const schemas = /* @__PURE__ */ Object.create(null);
|
|
583
|
-
if (
|
|
584
|
-
for (const [name, schema] of Object.entries(
|
|
666
|
+
if (definitions)
|
|
667
|
+
for (const [name, schema] of Object.entries(definitions)) {
|
|
585
668
|
const jsonSchema = unwrapSchema(schema, vendors);
|
|
586
669
|
if (jsonSchema) schemas[name] = jsonSchema;
|
|
587
670
|
}
|
|
@@ -684,6 +767,10 @@ var openapi = ({
|
|
|
684
767
|
};
|
|
685
768
|
},
|
|
686
769
|
{
|
|
770
|
+
error({ error }) {
|
|
771
|
+
console.log("[@elysiajs/openapi] error at specPath");
|
|
772
|
+
console.warn(error);
|
|
773
|
+
},
|
|
687
774
|
detail: {
|
|
688
775
|
hide: true
|
|
689
776
|
}
|
package/dist/cjs/openapi.js
CHANGED
|
@@ -60,12 +60,51 @@ var getPossiblePath = (path) => {
|
|
|
60
60
|
}
|
|
61
61
|
return paths;
|
|
62
62
|
};
|
|
63
|
-
var isValidSchema = (schema) => typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
63
|
+
var isValidSchema = (schema) => schema && typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
64
64
|
var getLoosePath = (path) => {
|
|
65
65
|
if (path.charCodeAt(path.length - 1) === 47)
|
|
66
66
|
return path.slice(0, path.length - 1);
|
|
67
67
|
return path + "/";
|
|
68
68
|
};
|
|
69
|
+
var warnings = {
|
|
70
|
+
zod4: `import openapi from '@elysiajs/openapi'
|
|
71
|
+
import * as z from 'zod'
|
|
72
|
+
|
|
73
|
+
openapi({
|
|
74
|
+
mapJsonSchema: {
|
|
75
|
+
zod: z.toJSONSchema
|
|
76
|
+
}
|
|
77
|
+
})`,
|
|
78
|
+
zod3: `import openapi from '@elysiajs/openapi'
|
|
79
|
+
import { zodToJsonSchema } from 'zod-to-json-schema'
|
|
80
|
+
|
|
81
|
+
openapi({
|
|
82
|
+
mapJsonSchema: {
|
|
83
|
+
zod: zodToJsonSchema
|
|
84
|
+
}
|
|
85
|
+
})`,
|
|
86
|
+
valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
|
|
87
|
+
|
|
88
|
+
openapi({
|
|
89
|
+
mapJsonSchema: {
|
|
90
|
+
valibot: toJsonSchema
|
|
91
|
+
}
|
|
92
|
+
})`,
|
|
93
|
+
effect: `import { JSONSchema } from 'effect'
|
|
94
|
+
|
|
95
|
+
openapi({
|
|
96
|
+
mapJsonSchema: {
|
|
97
|
+
effect: JSONSchema.make
|
|
98
|
+
}
|
|
99
|
+
})`
|
|
100
|
+
};
|
|
101
|
+
var warned = {};
|
|
102
|
+
var unwrapReference = (schema, definitions) => {
|
|
103
|
+
if (!schema?.$ref) return schema;
|
|
104
|
+
const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
|
|
105
|
+
if (schema.$ref && definitions[name]) schema = definitions[name];
|
|
106
|
+
return schema;
|
|
107
|
+
};
|
|
69
108
|
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
70
109
|
if (!schema) return;
|
|
71
110
|
if (typeof schema === "string") schema = toRef(schema);
|
|
@@ -74,8 +113,49 @@ var unwrapSchema = (schema, mapJsonSchema) => {
|
|
|
74
113
|
const vendor = schema["~standard"].vendor;
|
|
75
114
|
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
76
115
|
return mapJsonSchema[vendor](schema);
|
|
77
|
-
|
|
78
|
-
|
|
116
|
+
switch (vendor) {
|
|
117
|
+
case "zod":
|
|
118
|
+
if (warned.zod4 || warned.zod3) break;
|
|
119
|
+
console.warn(
|
|
120
|
+
"[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
|
|
121
|
+
);
|
|
122
|
+
if ("_zod" in schema) {
|
|
123
|
+
warned.zod4 = true;
|
|
124
|
+
console.warn(
|
|
125
|
+
"For Zod v4, please provide z.toJSONSchema as follows:\n"
|
|
126
|
+
);
|
|
127
|
+
console.warn(warnings.zod4);
|
|
128
|
+
} else {
|
|
129
|
+
warned.zod3 = true;
|
|
130
|
+
console.warn(
|
|
131
|
+
"For Zod v3, please install zod-to-json-schema package and use it like this:\n"
|
|
132
|
+
);
|
|
133
|
+
console.warn(warnings.zod3);
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
case "valibot":
|
|
137
|
+
if (warned.valibot) break;
|
|
138
|
+
warned.valibot = true;
|
|
139
|
+
console.warn(
|
|
140
|
+
"[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
|
|
141
|
+
);
|
|
142
|
+
console.warn(
|
|
143
|
+
"Please install @valibot/to-json-schema package and use it like this:\n"
|
|
144
|
+
);
|
|
145
|
+
console.warn(warnings.valibot);
|
|
146
|
+
break;
|
|
147
|
+
case "effect":
|
|
148
|
+
if (warned.effect) break;
|
|
149
|
+
warned.effect = true;
|
|
150
|
+
console.warn(
|
|
151
|
+
"[@elysiajs/openapi] Effect Schema doesn't provide JSON Schema method on the schema"
|
|
152
|
+
);
|
|
153
|
+
console.warn(
|
|
154
|
+
"please provide JSONSchema from 'effect' package as follows:\n"
|
|
155
|
+
);
|
|
156
|
+
console.warn(warnings.effect);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
79
159
|
if (vendor === "arktype")
|
|
80
160
|
return schema?.toJsonSchema?.();
|
|
81
161
|
return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
|
|
@@ -88,6 +168,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
88
168
|
} = exclude ?? {};
|
|
89
169
|
const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
|
|
90
170
|
const paths = /* @__PURE__ */ Object.create(null);
|
|
171
|
+
const definitions = app.getGlobalDefinitions?.().type;
|
|
91
172
|
const routes = app.getGlobalRoutes();
|
|
92
173
|
if (references) {
|
|
93
174
|
if (!Array.isArray(references)) references = [references];
|
|
@@ -102,7 +183,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
102
183
|
if (excludeStaticFile && route.path.includes(".") || excludePaths.includes(route.path) || excludeMethods.includes(method))
|
|
103
184
|
continue;
|
|
104
185
|
const hooks = route.hooks ?? {};
|
|
105
|
-
if (references)
|
|
186
|
+
if (references?.length)
|
|
106
187
|
for (const reference of references) {
|
|
107
188
|
if (!reference) continue;
|
|
108
189
|
const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
|
|
@@ -133,7 +214,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
133
214
|
};
|
|
134
215
|
const parameters = [];
|
|
135
216
|
if (hooks.params) {
|
|
136
|
-
const params =
|
|
217
|
+
const params = unwrapReference(
|
|
218
|
+
unwrapSchema(hooks.params, vendors),
|
|
219
|
+
definitions
|
|
220
|
+
);
|
|
137
221
|
if (params && params.type === "object" && params.properties)
|
|
138
222
|
for (const [paramName, paramSchema] of Object.entries(
|
|
139
223
|
params.properties
|
|
@@ -147,7 +231,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
147
231
|
});
|
|
148
232
|
}
|
|
149
233
|
if (hooks.query) {
|
|
150
|
-
|
|
234
|
+
const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
151
235
|
if (query && query.type === "object" && query.properties) {
|
|
152
236
|
const required = query.required || [];
|
|
153
237
|
for (const [queryName, querySchema] of Object.entries(
|
|
@@ -162,7 +246,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
162
246
|
}
|
|
163
247
|
}
|
|
164
248
|
if (hooks.headers) {
|
|
165
|
-
const headers = unwrapSchema(hooks.query, vendors);
|
|
249
|
+
const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
166
250
|
if (headers && headers.type === "object" && headers.properties) {
|
|
167
251
|
const required = headers.required || [];
|
|
168
252
|
for (const [headerName, headerSchema] of Object.entries(
|
|
@@ -177,7 +261,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
177
261
|
}
|
|
178
262
|
}
|
|
179
263
|
if (hooks.cookie) {
|
|
180
|
-
const cookie = unwrapSchema(hooks.cookie, vendors);
|
|
264
|
+
const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
|
|
181
265
|
if (cookie && cookie.type === "object" && cookie.properties) {
|
|
182
266
|
const required = cookie.required || [];
|
|
183
267
|
for (const [cookieName, cookieSchema] of Object.entries(
|
|
@@ -321,10 +405,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
321
405
|
};
|
|
322
406
|
}
|
|
323
407
|
}
|
|
324
|
-
const _schemas = app.getGlobalDefinitions?.().type;
|
|
325
408
|
const schemas = /* @__PURE__ */ Object.create(null);
|
|
326
|
-
if (
|
|
327
|
-
for (const [name, schema] of Object.entries(
|
|
409
|
+
if (definitions)
|
|
410
|
+
for (const [name, schema] of Object.entries(definitions)) {
|
|
328
411
|
const jsonSchema = unwrapSchema(schema, vendors);
|
|
329
412
|
if (jsonSchema) schemas[name] = jsonSchema;
|
|
330
413
|
}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export type OpenAPIProvider = 'scalar' | 'swagger-ui' | null;
|
|
|
6
6
|
type MaybeArray<T> = T | T[];
|
|
7
7
|
export type MapJsonSchema = {
|
|
8
8
|
[vendor: string]: Function;
|
|
9
|
+
} & {
|
|
10
|
+
[vendor in 'zod' | 'effect' | 'valibot' | 'arktype' | 'typemap' | 'yup' | 'joi']?: Function;
|
|
9
11
|
};
|
|
10
12
|
export type AdditionalReference = {
|
|
11
13
|
[path in string]: {
|
|
@@ -21,7 +23,7 @@ export type AdditionalReference = {
|
|
|
21
23
|
};
|
|
22
24
|
};
|
|
23
25
|
export type AdditionalReferences = MaybeArray<AdditionalReference | undefined | (() => AdditionalReference | undefined)>;
|
|
24
|
-
export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extends string = '/swagger'
|
|
26
|
+
export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extends string = '/swagger'> {
|
|
25
27
|
/**
|
|
26
28
|
* @default true
|
|
27
29
|
*/
|
|
@@ -67,7 +69,7 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
|
|
|
67
69
|
* @see https://github.com/scalar/scalar
|
|
68
70
|
* @see https://github.com/swagger-api/swagger-ui
|
|
69
71
|
*/
|
|
70
|
-
provider?:
|
|
72
|
+
provider?: OpenAPIProvider;
|
|
71
73
|
/**
|
|
72
74
|
* Additional reference for each endpoint
|
|
73
75
|
*/
|
|
@@ -81,7 +83,7 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
|
|
|
81
83
|
* import { toJsonSchema } from '@valibot/to-json-schema'
|
|
82
84
|
*
|
|
83
85
|
* openapi({
|
|
84
|
-
*
|
|
86
|
+
* mapJsonSchema: {
|
|
85
87
|
* valibot: toJsonSchema
|
|
86
88
|
* }
|
|
87
89
|
* })
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
|
-
import type { ElysiaOpenAPIConfig
|
|
2
|
+
import type { ElysiaOpenAPIConfig } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Plugin for [elysia](https://github.com/elysiajs/elysia) that auto-generate OpenAPI documentation page.
|
|
5
5
|
*
|
|
6
6
|
* @see https://github.com/elysiajs/elysia-swagger
|
|
7
7
|
*/
|
|
8
|
-
export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi"
|
|
8
|
+
export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi">({ enabled, path, provider, specPath, documentation, exclude, swagger, scalar, references, mapJsonSchema }?: ElysiaOpenAPIConfig<Enabled, Path>) => Elysia<"", {
|
|
9
9
|
decorator: {};
|
|
10
10
|
store: {};
|
|
11
11
|
derive: {};
|
package/dist/index.mjs
CHANGED
|
@@ -290,12 +290,51 @@ var getPossiblePath = (path) => {
|
|
|
290
290
|
}
|
|
291
291
|
return paths;
|
|
292
292
|
};
|
|
293
|
-
var isValidSchema = (schema) => typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
293
|
+
var isValidSchema = (schema) => schema && typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
294
294
|
var getLoosePath = (path) => {
|
|
295
295
|
if (path.charCodeAt(path.length - 1) === 47)
|
|
296
296
|
return path.slice(0, path.length - 1);
|
|
297
297
|
return path + "/";
|
|
298
298
|
};
|
|
299
|
+
var warnings = {
|
|
300
|
+
zod4: `import openapi from '@elysiajs/openapi'
|
|
301
|
+
import * as z from 'zod'
|
|
302
|
+
|
|
303
|
+
openapi({
|
|
304
|
+
mapJsonSchema: {
|
|
305
|
+
zod: z.toJSONSchema
|
|
306
|
+
}
|
|
307
|
+
})`,
|
|
308
|
+
zod3: `import openapi from '@elysiajs/openapi'
|
|
309
|
+
import { zodToJsonSchema } from 'zod-to-json-schema'
|
|
310
|
+
|
|
311
|
+
openapi({
|
|
312
|
+
mapJsonSchema: {
|
|
313
|
+
zod: zodToJsonSchema
|
|
314
|
+
}
|
|
315
|
+
})`,
|
|
316
|
+
valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
|
|
317
|
+
|
|
318
|
+
openapi({
|
|
319
|
+
mapJsonSchema: {
|
|
320
|
+
valibot: toJsonSchema
|
|
321
|
+
}
|
|
322
|
+
})`,
|
|
323
|
+
effect: `import { JSONSchema } from 'effect'
|
|
324
|
+
|
|
325
|
+
openapi({
|
|
326
|
+
mapJsonSchema: {
|
|
327
|
+
effect: JSONSchema.make
|
|
328
|
+
}
|
|
329
|
+
})`
|
|
330
|
+
};
|
|
331
|
+
var warned = {};
|
|
332
|
+
var unwrapReference = (schema, definitions) => {
|
|
333
|
+
if (!schema?.$ref) return schema;
|
|
334
|
+
const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
|
|
335
|
+
if (schema.$ref && definitions[name]) schema = definitions[name];
|
|
336
|
+
return schema;
|
|
337
|
+
};
|
|
299
338
|
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
300
339
|
if (!schema) return;
|
|
301
340
|
if (typeof schema === "string") schema = toRef(schema);
|
|
@@ -304,8 +343,49 @@ var unwrapSchema = (schema, mapJsonSchema) => {
|
|
|
304
343
|
const vendor = schema["~standard"].vendor;
|
|
305
344
|
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
306
345
|
return mapJsonSchema[vendor](schema);
|
|
307
|
-
|
|
308
|
-
|
|
346
|
+
switch (vendor) {
|
|
347
|
+
case "zod":
|
|
348
|
+
if (warned.zod4 || warned.zod3) break;
|
|
349
|
+
console.warn(
|
|
350
|
+
"[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
|
|
351
|
+
);
|
|
352
|
+
if ("_zod" in schema) {
|
|
353
|
+
warned.zod4 = true;
|
|
354
|
+
console.warn(
|
|
355
|
+
"For Zod v4, please provide z.toJSONSchema as follows:\n"
|
|
356
|
+
);
|
|
357
|
+
console.warn(warnings.zod4);
|
|
358
|
+
} else {
|
|
359
|
+
warned.zod3 = true;
|
|
360
|
+
console.warn(
|
|
361
|
+
"For Zod v3, please install zod-to-json-schema package and use it like this:\n"
|
|
362
|
+
);
|
|
363
|
+
console.warn(warnings.zod3);
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
case "valibot":
|
|
367
|
+
if (warned.valibot) break;
|
|
368
|
+
warned.valibot = true;
|
|
369
|
+
console.warn(
|
|
370
|
+
"[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
|
|
371
|
+
);
|
|
372
|
+
console.warn(
|
|
373
|
+
"Please install @valibot/to-json-schema package and use it like this:\n"
|
|
374
|
+
);
|
|
375
|
+
console.warn(warnings.valibot);
|
|
376
|
+
break;
|
|
377
|
+
case "effect":
|
|
378
|
+
if (warned.effect) break;
|
|
379
|
+
warned.effect = true;
|
|
380
|
+
console.warn(
|
|
381
|
+
"[@elysiajs/openapi] Effect Schema doesn't provide JSON Schema method on the schema"
|
|
382
|
+
);
|
|
383
|
+
console.warn(
|
|
384
|
+
"please provide JSONSchema from 'effect' package as follows:\n"
|
|
385
|
+
);
|
|
386
|
+
console.warn(warnings.effect);
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
309
389
|
if (vendor === "arktype")
|
|
310
390
|
return schema?.toJsonSchema?.();
|
|
311
391
|
return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
|
|
@@ -318,6 +398,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
318
398
|
} = exclude ?? {};
|
|
319
399
|
const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
|
|
320
400
|
const paths = /* @__PURE__ */ Object.create(null);
|
|
401
|
+
const definitions = app.getGlobalDefinitions?.().type;
|
|
321
402
|
const routes = app.getGlobalRoutes();
|
|
322
403
|
if (references) {
|
|
323
404
|
if (!Array.isArray(references)) references = [references];
|
|
@@ -332,7 +413,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
332
413
|
if (excludeStaticFile && route.path.includes(".") || excludePaths.includes(route.path) || excludeMethods.includes(method))
|
|
333
414
|
continue;
|
|
334
415
|
const hooks = route.hooks ?? {};
|
|
335
|
-
if (references)
|
|
416
|
+
if (references?.length)
|
|
336
417
|
for (const reference of references) {
|
|
337
418
|
if (!reference) continue;
|
|
338
419
|
const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
|
|
@@ -363,7 +444,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
363
444
|
};
|
|
364
445
|
const parameters = [];
|
|
365
446
|
if (hooks.params) {
|
|
366
|
-
const params =
|
|
447
|
+
const params = unwrapReference(
|
|
448
|
+
unwrapSchema(hooks.params, vendors),
|
|
449
|
+
definitions
|
|
450
|
+
);
|
|
367
451
|
if (params && params.type === "object" && params.properties)
|
|
368
452
|
for (const [paramName, paramSchema] of Object.entries(
|
|
369
453
|
params.properties
|
|
@@ -377,7 +461,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
377
461
|
});
|
|
378
462
|
}
|
|
379
463
|
if (hooks.query) {
|
|
380
|
-
|
|
464
|
+
const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
381
465
|
if (query && query.type === "object" && query.properties) {
|
|
382
466
|
const required = query.required || [];
|
|
383
467
|
for (const [queryName, querySchema] of Object.entries(
|
|
@@ -392,7 +476,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
392
476
|
}
|
|
393
477
|
}
|
|
394
478
|
if (hooks.headers) {
|
|
395
|
-
const headers = unwrapSchema(hooks.query, vendors);
|
|
479
|
+
const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
396
480
|
if (headers && headers.type === "object" && headers.properties) {
|
|
397
481
|
const required = headers.required || [];
|
|
398
482
|
for (const [headerName, headerSchema] of Object.entries(
|
|
@@ -407,7 +491,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
407
491
|
}
|
|
408
492
|
}
|
|
409
493
|
if (hooks.cookie) {
|
|
410
|
-
const cookie = unwrapSchema(hooks.cookie, vendors);
|
|
494
|
+
const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
|
|
411
495
|
if (cookie && cookie.type === "object" && cookie.properties) {
|
|
412
496
|
const required = cookie.required || [];
|
|
413
497
|
for (const [cookieName, cookieSchema] of Object.entries(
|
|
@@ -551,10 +635,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
551
635
|
};
|
|
552
636
|
}
|
|
553
637
|
}
|
|
554
|
-
const _schemas = app.getGlobalDefinitions?.().type;
|
|
555
638
|
const schemas = /* @__PURE__ */ Object.create(null);
|
|
556
|
-
if (
|
|
557
|
-
for (const [name, schema] of Object.entries(
|
|
639
|
+
if (definitions)
|
|
640
|
+
for (const [name, schema] of Object.entries(definitions)) {
|
|
558
641
|
const jsonSchema = unwrapSchema(schema, vendors);
|
|
559
642
|
if (jsonSchema) schemas[name] = jsonSchema;
|
|
560
643
|
}
|
|
@@ -657,6 +740,10 @@ var openapi = ({
|
|
|
657
740
|
};
|
|
658
741
|
},
|
|
659
742
|
{
|
|
743
|
+
error({ error }) {
|
|
744
|
+
console.log("[@elysiajs/openapi] error at specPath");
|
|
745
|
+
console.warn(error);
|
|
746
|
+
},
|
|
660
747
|
detail: {
|
|
661
748
|
hide: true
|
|
662
749
|
}
|
package/dist/openapi.mjs
CHANGED
|
@@ -31,12 +31,51 @@ var getPossiblePath = (path) => {
|
|
|
31
31
|
}
|
|
32
32
|
return paths;
|
|
33
33
|
};
|
|
34
|
-
var isValidSchema = (schema) => typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
34
|
+
var isValidSchema = (schema) => schema && typeof schema === "object" && (Kind in schema && schema[Kind] !== "Unknown" || schema.type || schema.properties || schema.items);
|
|
35
35
|
var getLoosePath = (path) => {
|
|
36
36
|
if (path.charCodeAt(path.length - 1) === 47)
|
|
37
37
|
return path.slice(0, path.length - 1);
|
|
38
38
|
return path + "/";
|
|
39
39
|
};
|
|
40
|
+
var warnings = {
|
|
41
|
+
zod4: `import openapi from '@elysiajs/openapi'
|
|
42
|
+
import * as z from 'zod'
|
|
43
|
+
|
|
44
|
+
openapi({
|
|
45
|
+
mapJsonSchema: {
|
|
46
|
+
zod: z.toJSONSchema
|
|
47
|
+
}
|
|
48
|
+
})`,
|
|
49
|
+
zod3: `import openapi from '@elysiajs/openapi'
|
|
50
|
+
import { zodToJsonSchema } from 'zod-to-json-schema'
|
|
51
|
+
|
|
52
|
+
openapi({
|
|
53
|
+
mapJsonSchema: {
|
|
54
|
+
zod: zodToJsonSchema
|
|
55
|
+
}
|
|
56
|
+
})`,
|
|
57
|
+
valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
|
|
58
|
+
|
|
59
|
+
openapi({
|
|
60
|
+
mapJsonSchema: {
|
|
61
|
+
valibot: toJsonSchema
|
|
62
|
+
}
|
|
63
|
+
})`,
|
|
64
|
+
effect: `import { JSONSchema } from 'effect'
|
|
65
|
+
|
|
66
|
+
openapi({
|
|
67
|
+
mapJsonSchema: {
|
|
68
|
+
effect: JSONSchema.make
|
|
69
|
+
}
|
|
70
|
+
})`
|
|
71
|
+
};
|
|
72
|
+
var warned = {};
|
|
73
|
+
var unwrapReference = (schema, definitions) => {
|
|
74
|
+
if (!schema?.$ref) return schema;
|
|
75
|
+
const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
|
|
76
|
+
if (schema.$ref && definitions[name]) schema = definitions[name];
|
|
77
|
+
return schema;
|
|
78
|
+
};
|
|
40
79
|
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
41
80
|
if (!schema) return;
|
|
42
81
|
if (typeof schema === "string") schema = toRef(schema);
|
|
@@ -45,8 +84,49 @@ var unwrapSchema = (schema, mapJsonSchema) => {
|
|
|
45
84
|
const vendor = schema["~standard"].vendor;
|
|
46
85
|
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
47
86
|
return mapJsonSchema[vendor](schema);
|
|
48
|
-
|
|
49
|
-
|
|
87
|
+
switch (vendor) {
|
|
88
|
+
case "zod":
|
|
89
|
+
if (warned.zod4 || warned.zod3) break;
|
|
90
|
+
console.warn(
|
|
91
|
+
"[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
|
|
92
|
+
);
|
|
93
|
+
if ("_zod" in schema) {
|
|
94
|
+
warned.zod4 = true;
|
|
95
|
+
console.warn(
|
|
96
|
+
"For Zod v4, please provide z.toJSONSchema as follows:\n"
|
|
97
|
+
);
|
|
98
|
+
console.warn(warnings.zod4);
|
|
99
|
+
} else {
|
|
100
|
+
warned.zod3 = true;
|
|
101
|
+
console.warn(
|
|
102
|
+
"For Zod v3, please install zod-to-json-schema package and use it like this:\n"
|
|
103
|
+
);
|
|
104
|
+
console.warn(warnings.zod3);
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
case "valibot":
|
|
108
|
+
if (warned.valibot) break;
|
|
109
|
+
warned.valibot = true;
|
|
110
|
+
console.warn(
|
|
111
|
+
"[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
|
|
112
|
+
);
|
|
113
|
+
console.warn(
|
|
114
|
+
"Please install @valibot/to-json-schema package and use it like this:\n"
|
|
115
|
+
);
|
|
116
|
+
console.warn(warnings.valibot);
|
|
117
|
+
break;
|
|
118
|
+
case "effect":
|
|
119
|
+
if (warned.effect) break;
|
|
120
|
+
warned.effect = true;
|
|
121
|
+
console.warn(
|
|
122
|
+
"[@elysiajs/openapi] Effect Schema doesn't provide JSON Schema method on the schema"
|
|
123
|
+
);
|
|
124
|
+
console.warn(
|
|
125
|
+
"please provide JSONSchema from 'effect' package as follows:\n"
|
|
126
|
+
);
|
|
127
|
+
console.warn(warnings.effect);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
50
130
|
if (vendor === "arktype")
|
|
51
131
|
return schema?.toJsonSchema?.();
|
|
52
132
|
return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
|
|
@@ -59,6 +139,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
59
139
|
} = exclude ?? {};
|
|
60
140
|
const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
|
|
61
141
|
const paths = /* @__PURE__ */ Object.create(null);
|
|
142
|
+
const definitions = app.getGlobalDefinitions?.().type;
|
|
62
143
|
const routes = app.getGlobalRoutes();
|
|
63
144
|
if (references) {
|
|
64
145
|
if (!Array.isArray(references)) references = [references];
|
|
@@ -73,7 +154,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
73
154
|
if (excludeStaticFile && route.path.includes(".") || excludePaths.includes(route.path) || excludeMethods.includes(method))
|
|
74
155
|
continue;
|
|
75
156
|
const hooks = route.hooks ?? {};
|
|
76
|
-
if (references)
|
|
157
|
+
if (references?.length)
|
|
77
158
|
for (const reference of references) {
|
|
78
159
|
if (!reference) continue;
|
|
79
160
|
const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
|
|
@@ -104,7 +185,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
104
185
|
};
|
|
105
186
|
const parameters = [];
|
|
106
187
|
if (hooks.params) {
|
|
107
|
-
const params =
|
|
188
|
+
const params = unwrapReference(
|
|
189
|
+
unwrapSchema(hooks.params, vendors),
|
|
190
|
+
definitions
|
|
191
|
+
);
|
|
108
192
|
if (params && params.type === "object" && params.properties)
|
|
109
193
|
for (const [paramName, paramSchema] of Object.entries(
|
|
110
194
|
params.properties
|
|
@@ -118,7 +202,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
118
202
|
});
|
|
119
203
|
}
|
|
120
204
|
if (hooks.query) {
|
|
121
|
-
|
|
205
|
+
const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
122
206
|
if (query && query.type === "object" && query.properties) {
|
|
123
207
|
const required = query.required || [];
|
|
124
208
|
for (const [queryName, querySchema] of Object.entries(
|
|
@@ -133,7 +217,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
133
217
|
}
|
|
134
218
|
}
|
|
135
219
|
if (hooks.headers) {
|
|
136
|
-
const headers = unwrapSchema(hooks.query, vendors);
|
|
220
|
+
const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
|
|
137
221
|
if (headers && headers.type === "object" && headers.properties) {
|
|
138
222
|
const required = headers.required || [];
|
|
139
223
|
for (const [headerName, headerSchema] of Object.entries(
|
|
@@ -148,7 +232,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
148
232
|
}
|
|
149
233
|
}
|
|
150
234
|
if (hooks.cookie) {
|
|
151
|
-
const cookie = unwrapSchema(hooks.cookie, vendors);
|
|
235
|
+
const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
|
|
152
236
|
if (cookie && cookie.type === "object" && cookie.properties) {
|
|
153
237
|
const required = cookie.required || [];
|
|
154
238
|
for (const [cookieName, cookieSchema] of Object.entries(
|
|
@@ -292,10 +376,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
292
376
|
};
|
|
293
377
|
}
|
|
294
378
|
}
|
|
295
|
-
const _schemas = app.getGlobalDefinitions?.().type;
|
|
296
379
|
const schemas = /* @__PURE__ */ Object.create(null);
|
|
297
|
-
if (
|
|
298
|
-
for (const [name, schema] of Object.entries(
|
|
380
|
+
if (definitions)
|
|
381
|
+
for (const [name, schema] of Object.entries(definitions)) {
|
|
299
382
|
const jsonSchema = unwrapSchema(schema, vendors);
|
|
300
383
|
if (jsonSchema) schemas[name] = jsonSchema;
|
|
301
384
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export type OpenAPIProvider = 'scalar' | 'swagger-ui' | null;
|
|
|
6
6
|
type MaybeArray<T> = T | T[];
|
|
7
7
|
export type MapJsonSchema = {
|
|
8
8
|
[vendor: string]: Function;
|
|
9
|
+
} & {
|
|
10
|
+
[vendor in 'zod' | 'effect' | 'valibot' | 'arktype' | 'typemap' | 'yup' | 'joi']?: Function;
|
|
9
11
|
};
|
|
10
12
|
export type AdditionalReference = {
|
|
11
13
|
[path in string]: {
|
|
@@ -21,7 +23,7 @@ export type AdditionalReference = {
|
|
|
21
23
|
};
|
|
22
24
|
};
|
|
23
25
|
export type AdditionalReferences = MaybeArray<AdditionalReference | undefined | (() => AdditionalReference | undefined)>;
|
|
24
|
-
export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extends string = '/swagger'
|
|
26
|
+
export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extends string = '/swagger'> {
|
|
25
27
|
/**
|
|
26
28
|
* @default true
|
|
27
29
|
*/
|
|
@@ -67,7 +69,7 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
|
|
|
67
69
|
* @see https://github.com/scalar/scalar
|
|
68
70
|
* @see https://github.com/swagger-api/swagger-ui
|
|
69
71
|
*/
|
|
70
|
-
provider?:
|
|
72
|
+
provider?: OpenAPIProvider;
|
|
71
73
|
/**
|
|
72
74
|
* Additional reference for each endpoint
|
|
73
75
|
*/
|
|
@@ -81,7 +83,7 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
|
|
|
81
83
|
* import { toJsonSchema } from '@valibot/to-json-schema'
|
|
82
84
|
*
|
|
83
85
|
* openapi({
|
|
84
|
-
*
|
|
86
|
+
* mapJsonSchema: {
|
|
85
87
|
* valibot: toJsonSchema
|
|
86
88
|
* }
|
|
87
89
|
* })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elysiajs/openapi",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "Plugin for Elysia to auto-generate API documentation",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "saltyAom",
|
|
@@ -79,7 +79,8 @@
|
|
|
79
79
|
"@scalar/types": "^0.2.13",
|
|
80
80
|
"@sinclair/typemap": "^0.10.1",
|
|
81
81
|
"@types/bun": "1.2.20",
|
|
82
|
-
"
|
|
82
|
+
"effect": "^3.17.13",
|
|
83
|
+
"elysia": "1.4.6",
|
|
83
84
|
"eslint": "9.6.0",
|
|
84
85
|
"openapi-types": "^12.1.3",
|
|
85
86
|
"tsup": "^8.5.0",
|