@elysiajs/openapi 1.3.11 → 1.4.0-exp.0
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 +545 -537
- package/dist/cjs/gen/index.js +21 -13
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +122 -81
- package/dist/cjs/openapi.d.ts +7 -4
- package/dist/cjs/openapi.js +122 -79
- package/dist/gen/index.d.ts +16 -1
- package/dist/gen/index.mjs +21 -13
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +122 -81
- package/dist/openapi.d.ts +7 -4
- package/dist/openapi.mjs +121 -79
- package/package.json +96 -92
- package/bunfig.toml +0 -2
package/dist/cjs/gen/index.js
CHANGED
|
@@ -36,9 +36,10 @@ var fromTypes = (targetFilePath, {
|
|
|
36
36
|
instanceName,
|
|
37
37
|
projectRoot = process.cwd(),
|
|
38
38
|
overrideOutputPath,
|
|
39
|
-
debug = false
|
|
39
|
+
debug = false,
|
|
40
|
+
compilerOptions,
|
|
41
|
+
tmpRoot = (0, import_path.join)((0, import_os.tmpdir)(), ".ElysiaAutoOpenAPI")
|
|
40
42
|
} = {}) => () => {
|
|
41
|
-
const tmpRoot = (0, import_path.join)((0, import_os.tmpdir)(), ".ElysiaAutoOpenAPI");
|
|
42
43
|
try {
|
|
43
44
|
if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
|
|
44
45
|
throw new Error("Only .ts files are supported");
|
|
@@ -57,25 +58,27 @@ var fromTypes = (targetFilePath, {
|
|
|
57
58
|
(0, import_fs.mkdirSync)(tmpRoot, { recursive: true });
|
|
58
59
|
const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : (0, import_path.join)(projectRoot, tsconfigPath);
|
|
59
60
|
let extendsRef = (0, import_fs.existsSync)(tsconfig) ? `"extends": "${(0, import_path.join)(projectRoot, "tsconfig.json")}",` : "";
|
|
61
|
+
let distDir = (0, import_path.join)(tmpRoot, "dist");
|
|
60
62
|
if (typeof process !== "undefined" && process.platform === "win32") {
|
|
61
63
|
extendsRef = extendsRef.replace(/\\/g, "/");
|
|
62
64
|
src = src.replace(/\\/g, "/");
|
|
65
|
+
distDir = distDir.replace(/\\/g, "/");
|
|
63
66
|
}
|
|
64
67
|
(0, import_fs.writeFileSync)(
|
|
65
68
|
(0, import_path.join)(tmpRoot, "tsconfig.json"),
|
|
66
69
|
`{
|
|
67
70
|
${extendsRef}
|
|
68
|
-
"compilerOptions": {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
"compilerOptions": ${compilerOptions ? JSON.stringify(compilerOptions) : `{
|
|
72
|
+
"lib": ["ESNext"],
|
|
73
|
+
"module": "ESNext",
|
|
74
|
+
"noEmit": false,
|
|
75
|
+
"declaration": true,
|
|
76
|
+
"emitDeclarationOnly": true,
|
|
77
|
+
"moduleResolution": "bundler",
|
|
78
|
+
"skipLibCheck": true,
|
|
79
|
+
"skipDefaultLibCheck": true,
|
|
80
|
+
"outDir": "${distDir}"
|
|
81
|
+
}`},
|
|
79
82
|
"include": ["${src}"]
|
|
80
83
|
}`
|
|
81
84
|
);
|
|
@@ -117,6 +120,11 @@ var fromTypes = (targetFilePath, {
|
|
|
117
120
|
);
|
|
118
121
|
console.warn(tempFiles);
|
|
119
122
|
}
|
|
123
|
+
} else {
|
|
124
|
+
console.log(
|
|
125
|
+
"reason: root folder doesn't exists",
|
|
126
|
+
(0, import_path.join)(tmpRoot, "dist")
|
|
127
|
+
);
|
|
120
128
|
}
|
|
121
129
|
return;
|
|
122
130
|
}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -19,16 +19,19 @@ export declare const openapi: <const Enabled extends boolean = true, const Path
|
|
|
19
19
|
macro: {};
|
|
20
20
|
macroFn: {};
|
|
21
21
|
parser: {};
|
|
22
|
+
response: {};
|
|
22
23
|
}, {}, {
|
|
23
24
|
derive: {};
|
|
24
25
|
resolve: {};
|
|
25
26
|
schema: {};
|
|
26
27
|
standaloneSchema: {};
|
|
28
|
+
response: {};
|
|
27
29
|
}, {
|
|
28
30
|
derive: {};
|
|
29
31
|
resolve: {};
|
|
30
32
|
schema: {};
|
|
31
33
|
standaloneSchema: {};
|
|
34
|
+
response: {};
|
|
32
35
|
}>;
|
|
33
36
|
export { toOpenAPISchema, withHeaders } from './openapi';
|
|
34
37
|
export type { ElysiaOpenAPIConfig };
|
package/dist/cjs/index.js
CHANGED
|
@@ -295,6 +295,7 @@ var Hint = Symbol.for("TypeBox.Hint");
|
|
|
295
295
|
var Kind = Symbol.for("TypeBox.Kind");
|
|
296
296
|
|
|
297
297
|
// src/openapi.ts
|
|
298
|
+
var import_xsschema = require("xsschema");
|
|
298
299
|
var capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
|
|
299
300
|
var toRef = (name) => import_elysia.t.Ref(`#/components/schemas/${name}`);
|
|
300
301
|
var toOperationId = (method, paths) => {
|
|
@@ -323,7 +324,14 @@ var getLoosePath = (path) => {
|
|
|
323
324
|
return path.slice(0, path.length - 1);
|
|
324
325
|
return path + "/";
|
|
325
326
|
};
|
|
326
|
-
|
|
327
|
+
var unwrapSchema = (schema) => {
|
|
328
|
+
if (!schema) return;
|
|
329
|
+
if (typeof schema === "string") schema = toRef(schema);
|
|
330
|
+
if (Kind in schema) return schema;
|
|
331
|
+
if (Kind in schema === false && schema["~standard"])
|
|
332
|
+
return (0, import_xsschema.toJsonSchema)(schema);
|
|
333
|
+
};
|
|
334
|
+
async function toOpenAPISchema(app, exclude, references) {
|
|
327
335
|
const {
|
|
328
336
|
methods: excludeMethods = ["OPTIONS"],
|
|
329
337
|
staticFile: excludeStaticFile = true,
|
|
@@ -376,11 +384,11 @@ function toOpenAPISchema(app, exclude, references) {
|
|
|
376
384
|
};
|
|
377
385
|
const parameters = [];
|
|
378
386
|
if (hooks.params) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
if (
|
|
387
|
+
let params = unwrapSchema(hooks.params);
|
|
388
|
+
if (params) params = await params;
|
|
389
|
+
if (params && params.type === "object" && params.properties)
|
|
382
390
|
for (const [paramName, paramSchema] of Object.entries(
|
|
383
|
-
|
|
391
|
+
params.properties
|
|
384
392
|
))
|
|
385
393
|
parameters.push({
|
|
386
394
|
name: paramName,
|
|
@@ -389,15 +397,14 @@ function toOpenAPISchema(app, exclude, references) {
|
|
|
389
397
|
// Path parameters are always required
|
|
390
398
|
schema: paramSchema
|
|
391
399
|
});
|
|
392
|
-
}
|
|
393
400
|
}
|
|
394
401
|
if (hooks.query) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (
|
|
398
|
-
const required =
|
|
402
|
+
let query = unwrapSchema(hooks.query);
|
|
403
|
+
if (query) query = await query;
|
|
404
|
+
if (query && query.type === "object" && query.properties) {
|
|
405
|
+
const required = query.required || [];
|
|
399
406
|
for (const [queryName, querySchema] of Object.entries(
|
|
400
|
-
|
|
407
|
+
query.properties
|
|
401
408
|
))
|
|
402
409
|
parameters.push({
|
|
403
410
|
name: queryName,
|
|
@@ -408,12 +415,12 @@ function toOpenAPISchema(app, exclude, references) {
|
|
|
408
415
|
}
|
|
409
416
|
}
|
|
410
417
|
if (hooks.headers) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (
|
|
414
|
-
const required =
|
|
418
|
+
let headers = unwrapSchema(hooks.query);
|
|
419
|
+
if (headers) headers = await headers;
|
|
420
|
+
if (headers && headers.type === "object" && headers.properties) {
|
|
421
|
+
const required = headers.required || [];
|
|
415
422
|
for (const [headerName, headerSchema] of Object.entries(
|
|
416
|
-
|
|
423
|
+
headers.properties
|
|
417
424
|
))
|
|
418
425
|
parameters.push({
|
|
419
426
|
name: headerName,
|
|
@@ -424,12 +431,12 @@ function toOpenAPISchema(app, exclude, references) {
|
|
|
424
431
|
}
|
|
425
432
|
}
|
|
426
433
|
if (hooks.cookie) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
if (
|
|
430
|
-
const required =
|
|
434
|
+
let cookie = unwrapSchema(hooks.cookie);
|
|
435
|
+
if (cookie) cookie = await cookie;
|
|
436
|
+
if (cookie && cookie.type === "object" && cookie.properties) {
|
|
437
|
+
const required = cookie.required || [];
|
|
431
438
|
for (const [cookieName, cookieSchema] of Object.entries(
|
|
432
|
-
|
|
439
|
+
cookie.properties
|
|
433
440
|
))
|
|
434
441
|
parameters.push({
|
|
435
442
|
name: cookieName,
|
|
@@ -441,80 +448,107 @@ function toOpenAPISchema(app, exclude, references) {
|
|
|
441
448
|
}
|
|
442
449
|
if (parameters.length > 0) operation.parameters = parameters;
|
|
443
450
|
if (hooks.body && method !== "get" && method !== "head") {
|
|
444
|
-
|
|
445
|
-
if (
|
|
446
|
-
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
451
|
+
let body = unwrapSchema(hooks.body);
|
|
452
|
+
if (body) body = await body;
|
|
453
|
+
if (body) {
|
|
454
|
+
const { type: _type, description, ...options } = body;
|
|
455
|
+
const type = _type;
|
|
456
|
+
if (hooks.parse) {
|
|
457
|
+
const content = {};
|
|
458
|
+
const parsers = hooks.parse;
|
|
459
|
+
for (const parser of parsers) {
|
|
460
|
+
if (typeof parser.fn === "function") continue;
|
|
461
|
+
switch (parser.fn) {
|
|
462
|
+
case "text":
|
|
463
|
+
case "text/plain":
|
|
464
|
+
content["text/plain"] = { schema: body };
|
|
465
|
+
continue;
|
|
466
|
+
case "urlencoded":
|
|
467
|
+
case "application/x-www-form-urlencoded":
|
|
468
|
+
content["application/x-www-form-urlencoded"] = {
|
|
469
|
+
schema: body
|
|
470
|
+
};
|
|
471
|
+
continue;
|
|
472
|
+
case "json":
|
|
473
|
+
case "application/json":
|
|
474
|
+
content["application/json"] = { schema: body };
|
|
475
|
+
continue;
|
|
476
|
+
case "formdata":
|
|
477
|
+
case "multipart/form-data":
|
|
478
|
+
content["multipart/form-data"] = {
|
|
479
|
+
schema: body
|
|
480
|
+
};
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
471
483
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
"
|
|
481
|
-
|
|
484
|
+
operation.requestBody = {
|
|
485
|
+
description,
|
|
486
|
+
content,
|
|
487
|
+
required: true
|
|
488
|
+
};
|
|
489
|
+
} else {
|
|
490
|
+
operation.requestBody = {
|
|
491
|
+
description,
|
|
492
|
+
content: type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
|
|
493
|
+
"text/plain": body
|
|
494
|
+
} : {
|
|
495
|
+
"application/json": {
|
|
496
|
+
schema: body
|
|
497
|
+
},
|
|
498
|
+
"application/x-www-form-urlencoded": {
|
|
499
|
+
schema: body
|
|
500
|
+
},
|
|
501
|
+
"multipart/form-data": {
|
|
502
|
+
schema: body
|
|
503
|
+
}
|
|
482
504
|
},
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
},
|
|
487
|
-
required: true
|
|
488
|
-
};
|
|
505
|
+
required: true
|
|
506
|
+
};
|
|
507
|
+
}
|
|
489
508
|
}
|
|
490
509
|
}
|
|
491
510
|
if (hooks.response) {
|
|
492
511
|
operation.responses = {};
|
|
493
512
|
if (typeof hooks.response === "object" && !hooks.response.type && !hooks.response.$ref) {
|
|
494
513
|
for (let [status, schema] of Object.entries(hooks.response)) {
|
|
495
|
-
|
|
496
|
-
|
|
514
|
+
let response = unwrapSchema(schema);
|
|
515
|
+
if (response) response = await response;
|
|
516
|
+
if (!response) continue;
|
|
517
|
+
const { type: _type, description, ...options } = response;
|
|
518
|
+
const type = _type;
|
|
497
519
|
operation.responses[status] = {
|
|
498
|
-
description: `Response for status ${status}`,
|
|
520
|
+
description: description ?? `Response for status ${status}`,
|
|
499
521
|
...options,
|
|
500
|
-
content: type === "void" || type === "null" || type === "undefined" ?
|
|
522
|
+
content: type === "void" || type === "null" || type === "undefined" ? response : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
|
|
523
|
+
"text/plain": {
|
|
524
|
+
schema: response
|
|
525
|
+
}
|
|
526
|
+
} : {
|
|
501
527
|
"application/json": {
|
|
502
|
-
schema
|
|
528
|
+
schema: response
|
|
503
529
|
}
|
|
504
530
|
}
|
|
505
531
|
};
|
|
506
532
|
}
|
|
507
533
|
} else {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
534
|
+
let response = unwrapSchema(hooks.response);
|
|
535
|
+
if (response) response = await response;
|
|
536
|
+
if (response) {
|
|
537
|
+
const { type: _type, description, ...options } = response;
|
|
538
|
+
const type = _type;
|
|
539
|
+
operation.responses["200"] = {
|
|
540
|
+
description: description ?? `Response for status 200`,
|
|
541
|
+
content: type === "void" || type === "null" || type === "undefined" ? response : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
|
|
542
|
+
"text/plain": {
|
|
543
|
+
schema: response
|
|
544
|
+
}
|
|
545
|
+
} : {
|
|
546
|
+
"application/json": {
|
|
547
|
+
schema: response
|
|
548
|
+
}
|
|
515
549
|
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
518
552
|
}
|
|
519
553
|
}
|
|
520
554
|
for (let path of getPossiblePath(route.path)) {
|
|
@@ -545,7 +579,14 @@ function toOpenAPISchema(app, exclude, references) {
|
|
|
545
579
|
};
|
|
546
580
|
}
|
|
547
581
|
}
|
|
548
|
-
const
|
|
582
|
+
const _schemas = app.getGlobalDefinitions?.().type;
|
|
583
|
+
const schemas = /* @__PURE__ */ Object.create(null);
|
|
584
|
+
if (_schemas)
|
|
585
|
+
for (const [name, schema] of Object.entries(_schemas)) {
|
|
586
|
+
let jsonSchema = unwrapSchema(schema);
|
|
587
|
+
if (jsonSchema instanceof Promise) jsonSchema = await jsonSchema;
|
|
588
|
+
if (jsonSchema) schemas[name] = jsonSchema;
|
|
589
|
+
}
|
|
549
590
|
return {
|
|
550
591
|
components: {
|
|
551
592
|
schemas
|
|
@@ -611,13 +652,13 @@ var openapi = ({
|
|
|
611
652
|
);
|
|
612
653
|
}).get(
|
|
613
654
|
specPath,
|
|
614
|
-
function openAPISchema() {
|
|
655
|
+
async function openAPISchema() {
|
|
615
656
|
if (totalRoutes === app.routes.length) return cachedSchema;
|
|
616
657
|
totalRoutes = app.routes.length;
|
|
617
658
|
const {
|
|
618
659
|
paths,
|
|
619
660
|
components: { schemas }
|
|
620
|
-
} = toOpenAPISchema(app, exclude, references);
|
|
661
|
+
} = await toOpenAPISchema(app, exclude, references);
|
|
621
662
|
return cachedSchema = {
|
|
622
663
|
openapi: "3.0.3",
|
|
623
664
|
...documentation,
|
package/dist/cjs/openapi.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AnyElysia, type TSchema } from 'elysia';
|
|
1
|
+
import { type AnyElysia, type TSchema, type InputSchema } from 'elysia';
|
|
2
2
|
import type { OpenAPIV3 } from 'openapi-types';
|
|
3
3
|
import { type TProperties } from '@sinclair/typebox';
|
|
4
4
|
import type { AdditionalReferences, ElysiaOpenAPIConfig } from './types';
|
|
@@ -10,17 +10,20 @@ export declare const capitalize: (word: string) => string;
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const getPossiblePath: (path: string) => string[];
|
|
12
12
|
export declare const getLoosePath: (path: string) => string;
|
|
13
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
14
|
+
export declare const unwrapSchema: (schema: InputSchema["body"]) => MaybePromise<OpenAPIV3.SchemaObject | undefined>;
|
|
13
15
|
/**
|
|
14
16
|
* Converts Elysia routes to OpenAPI 3.0.3 paths schema
|
|
15
17
|
* @param routes Array of Elysia route objects
|
|
16
18
|
* @returns OpenAPI paths object
|
|
17
19
|
*/
|
|
18
|
-
export declare function toOpenAPISchema(app: AnyElysia, exclude?: ElysiaOpenAPIConfig['exclude'], references?: AdditionalReferences): {
|
|
20
|
+
export declare function toOpenAPISchema(app: AnyElysia, exclude?: ElysiaOpenAPIConfig['exclude'], references?: AdditionalReferences): Promise<{
|
|
19
21
|
components: {
|
|
20
|
-
schemas:
|
|
22
|
+
schemas: any;
|
|
21
23
|
};
|
|
22
24
|
paths: OpenAPIV3.PathsObject<{}, {}>;
|
|
23
|
-
}
|
|
25
|
+
}>;
|
|
24
26
|
export declare const withHeaders: (schema: TSchema, headers: TProperties) => TSchema & {
|
|
25
27
|
headers: TProperties;
|
|
26
28
|
};
|
|
29
|
+
export {};
|