@byyuurin/nitro-openapi 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +5 -5
- package/dist/index.cjs +64 -94
- package/dist/index.d.cts +14 -30
- package/dist/index.d.mts +14 -30
- package/dist/index.d.ts +14 -30
- package/dist/index.mjs +66 -95
- package/package.json +21 -18
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) Yuurin<https://github.com/byyuurin>
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Yuurin<https://github.com/byyuurin>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -55,16 +55,16 @@ Or custom register
|
|
|
55
55
|
|
|
56
56
|
```ts
|
|
57
57
|
// utils/swagger.ts
|
|
58
|
-
import type {
|
|
58
|
+
import type { OperationType, PathOperation } from '@byyuurin/nitro-openapi'
|
|
59
59
|
import type { InternalApi } from 'nitropack'
|
|
60
60
|
import type { configExtends } from '../plugins/swagger'
|
|
61
61
|
import { register } from '../plugins/swagger'
|
|
62
62
|
|
|
63
|
-
type RouteMeta =
|
|
64
|
-
method?:
|
|
63
|
+
type RouteMeta = OperationType<typeof configExtends> & {
|
|
64
|
+
method?: keyof PathOperation
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
export function
|
|
67
|
+
export function defineApiResponse(
|
|
68
68
|
route: keyof InternalApi,
|
|
69
69
|
meta: RouteMeta,
|
|
70
70
|
) {
|
|
@@ -78,7 +78,7 @@ Then use the register
|
|
|
78
78
|
```ts
|
|
79
79
|
// route/**/*.ts
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
defineApiResponse('/api/...', {
|
|
82
82
|
/* ... */
|
|
83
83
|
})
|
|
84
84
|
|
package/dist/index.cjs
CHANGED
|
@@ -10,11 +10,11 @@ function createOpenApiRegister(options) {
|
|
|
10
10
|
const { paths = {}, components = {}, security = [], servers = [], info, tags = [] } = options;
|
|
11
11
|
const defineOperation = (operation) => operation;
|
|
12
12
|
function register(route, routeOperation, method = "get") {
|
|
13
|
-
const
|
|
14
|
-
paths[
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const path = normalizeRoute(route);
|
|
14
|
+
paths[path] = {
|
|
15
|
+
...paths[path],
|
|
16
|
+
[method]: routeOperation
|
|
17
|
+
};
|
|
18
18
|
}
|
|
19
19
|
function merge(config) {
|
|
20
20
|
return mergeConfig(
|
|
@@ -49,111 +49,81 @@ function normalizeRoute(_route) {
|
|
|
49
49
|
return route;
|
|
50
50
|
}
|
|
51
51
|
function mergeConfig(defaults, appends) {
|
|
52
|
-
const methods = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put", "trace"]);
|
|
53
52
|
const { info } = appends;
|
|
54
|
-
const { paths = {} } = defaults;
|
|
53
|
+
const { openapi, servers, security, tags, paths = {} } = defaults;
|
|
55
54
|
for (const path in paths) {
|
|
56
55
|
const operations = paths[path];
|
|
56
|
+
const operationsAppend = appends.paths?.[path] ?? {};
|
|
57
|
+
if ("$ref" in operationsAppend) {
|
|
58
|
+
paths[path] = operationsAppend;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
57
61
|
if ("$ref" in operations)
|
|
58
62
|
continue;
|
|
59
|
-
paths[path] = Object.fromEntries(Object.entries(operations).map(([
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return [key, obj];
|
|
63
|
+
paths[path] = Object.fromEntries(Object.entries(operations).map(([method, operation]) => {
|
|
64
|
+
const extendOperation = operationsAppend[method] ?? {};
|
|
65
|
+
return [method, defu__default(operation, extendOperation)];
|
|
63
66
|
}));
|
|
64
67
|
}
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return defu__default(p, {
|
|
75
|
-
schema: { type: "string" }
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
return obj;
|
|
68
|
+
return {
|
|
69
|
+
openapi,
|
|
70
|
+
info,
|
|
71
|
+
servers,
|
|
72
|
+
security,
|
|
73
|
+
tags,
|
|
74
|
+
...defu__default(defaults, appends),
|
|
75
|
+
paths
|
|
76
|
+
};
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
function
|
|
82
|
-
const {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
function toExampleSchema(example, description, options = {}) {
|
|
80
|
+
const { withExample = true, ...overrides } = options;
|
|
81
|
+
const createSchemaObject = (schema2) => {
|
|
82
|
+
const merged = {
|
|
83
|
+
...schema2,
|
|
84
|
+
...typeof description === "string" && description !== "" ? { description } : {},
|
|
85
|
+
...withExample ? { example } : {},
|
|
86
|
+
...overrides
|
|
87
|
+
};
|
|
88
|
+
return merged;
|
|
87
89
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
);
|
|
90
|
+
let schema = createSchemaObject({
|
|
91
|
+
type: "null"
|
|
92
|
+
});
|
|
93
|
+
if (typeof example === "number") {
|
|
94
|
+
schema = createSchemaObject({
|
|
95
|
+
type: "number"
|
|
96
|
+
});
|
|
96
97
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
case "undefined":
|
|
102
|
-
return { type: "null" };
|
|
103
|
-
case "object":
|
|
104
|
-
return resolveResult(
|
|
105
|
-
{
|
|
106
|
-
type: "object",
|
|
107
|
-
properties: Object.fromEntries(Object.entries(value).map(([k, v]) => [
|
|
108
|
-
k,
|
|
109
|
-
resolveSchemaObject(v, {
|
|
110
|
-
allowExample: false
|
|
111
|
-
})
|
|
112
|
-
]))
|
|
113
|
-
},
|
|
114
|
-
value
|
|
115
|
-
);
|
|
116
|
-
case "bigint":
|
|
117
|
-
return resolveResult(
|
|
118
|
-
{ type: "integer" },
|
|
119
|
-
value
|
|
120
|
-
);
|
|
121
|
-
case "string":
|
|
122
|
-
return resolveResult(
|
|
123
|
-
{ type: "string" },
|
|
124
|
-
value || null
|
|
125
|
-
);
|
|
126
|
-
default:
|
|
127
|
-
return resolveResult(
|
|
128
|
-
{ type: _type },
|
|
129
|
-
value
|
|
130
|
-
);
|
|
98
|
+
if (typeof example === "string") {
|
|
99
|
+
schema = createSchemaObject({
|
|
100
|
+
type: "string"
|
|
101
|
+
});
|
|
131
102
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
example,
|
|
137
|
-
typeof description === "string" ? { ...options, description } : {}
|
|
138
|
-
);
|
|
103
|
+
if (typeof example === "boolean") {
|
|
104
|
+
schema = createSchemaObject({
|
|
105
|
+
type: "boolean"
|
|
106
|
+
});
|
|
139
107
|
}
|
|
140
|
-
if (
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
108
|
+
if (typeof example === "object" && example !== null) {
|
|
109
|
+
if (Array.isArray(example)) {
|
|
110
|
+
const value = typeof example[0] === "object" ? defu.defu({}, ...example) : example[0];
|
|
111
|
+
schema = createSchemaObject({
|
|
112
|
+
type: "array",
|
|
113
|
+
items: toExampleSchema(value, typeof description === "string" ? "" : description, { withExample: false })
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
schema = createSchemaObject({
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: Object.fromEntries(Object.entries(example).map(([k, v]) => {
|
|
119
|
+
const _description = typeof description === "object" ? description[k] : description;
|
|
120
|
+
return [k, toExampleSchema(v, _description, { withExample: false })];
|
|
121
|
+
}))
|
|
122
|
+
});
|
|
123
|
+
}
|
|
146
124
|
}
|
|
147
|
-
if (typeof description === "string")
|
|
148
|
-
return resolveSchemaObject(example, { ...options, description });
|
|
149
|
-
const schema = resolveSchemaObject(example, options);
|
|
150
|
-
schema.properties = Object.fromEntries(Object.entries(schema.properties).map(([p, item]) => [p, {
|
|
151
|
-
...item,
|
|
152
|
-
...typeof description === "object" ? { description: description?.[p] } : {}
|
|
153
|
-
}]));
|
|
154
125
|
return schema;
|
|
155
126
|
}
|
|
156
127
|
|
|
157
128
|
exports.createOpenApiRegister = createOpenApiRegister;
|
|
158
|
-
exports.resolveSchemaObject = resolveSchemaObject;
|
|
159
129
|
exports.toExampleSchema = toExampleSchema;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ReferenceObject, SchemaObject, PathItemObject, OperationObject, SecurityRequirementObject, OpenAPI3 } from 'openapi-typescript';
|
|
1
|
+
import { NumberSubtype, StringSubtype, BooleanSubtype, ArraySubtype, ObjectSubtype, NullSubtype, SchemaObject, ReferenceObject, PathItemObject, OperationObject, SecurityRequirementObject, OpenAPI3 } from 'openapi-typescript';
|
|
3
2
|
|
|
3
|
+
type SchemaSubType<T> = T extends number ? NumberSubtype : T extends string ? StringSubtype : T extends boolean ? BooleanSubtype : T extends Array<any> ? ArraySubtype : T extends Record<string, any> ? ObjectSubtype : NullSubtype;
|
|
4
|
+
type SchemaObjectType<T> = Omit<SchemaObject, 'example'> & SchemaSubType<T> & {
|
|
5
|
+
example?: T;
|
|
6
|
+
};
|
|
7
|
+
type ExampleDescription<T> = T extends (infer V)[] ? SchemaObjectType<V> extends ObjectSubtype ? ({
|
|
8
|
+
[Key in keyof V]?: string;
|
|
9
|
+
} | string) : string : SchemaObjectType<T> extends ObjectSubtype ? {
|
|
10
|
+
[Key in keyof T]?: string;
|
|
11
|
+
} : string;
|
|
4
12
|
type ReferenceType<T extends ApiRegisterOptions> = T extends {
|
|
5
13
|
components: infer C;
|
|
6
14
|
} ? {
|
|
@@ -41,32 +49,8 @@ declare function createOpenApiRegister<T extends ApiRegisterOptions = ApiRegiste
|
|
|
41
49
|
merge: (config: Partial<OpenAPI3>) => Partial<OpenAPI3>;
|
|
42
50
|
};
|
|
43
51
|
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
declare function resolveSchemaObject(value: any, options?: SchemaObjectOptions): SchemaObject;
|
|
48
|
-
type ExampleDescription<ExampleT> = MaybeValueOrObject<ExampleT, string>;
|
|
49
|
-
declare function toExampleSchema<T = any>(example: T, description?: ExampleDescription<T>, options?: SchemaObject): {
|
|
50
|
-
[key: `x-${string}`]: any;
|
|
51
|
-
discriminator?: openapi_typescript.DiscriminatorObject | undefined;
|
|
52
|
-
xml?: openapi_typescript.XMLObject | undefined;
|
|
53
|
-
externalDocs?: openapi_typescript.ExternalDocumentationObject | undefined;
|
|
54
|
-
example?: any;
|
|
55
|
-
title?: string | undefined;
|
|
56
|
-
description?: string | undefined;
|
|
57
|
-
$comment?: string | undefined;
|
|
58
|
-
deprecated?: boolean | undefined;
|
|
59
|
-
readOnly?: boolean | undefined;
|
|
60
|
-
writeOnly?: boolean | undefined;
|
|
61
|
-
enum?: unknown[] | undefined;
|
|
62
|
-
const?: unknown;
|
|
63
|
-
default?: unknown;
|
|
64
|
-
format?: string | undefined;
|
|
65
|
-
nullable?: boolean | undefined;
|
|
66
|
-
oneOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
67
|
-
allOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
68
|
-
anyOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
69
|
-
required?: string[] | undefined;
|
|
70
|
-
};
|
|
52
|
+
declare function toExampleSchema<T>(example: T, description: ExampleDescription<T> | undefined, options?: Partial<Omit<SchemaObjectType<T>, 'type' | 'example'> & {
|
|
53
|
+
withExample?: boolean;
|
|
54
|
+
}>): SchemaObjectType<T>;
|
|
71
55
|
|
|
72
|
-
export { type ApiRegisterOptions, type MaybeReference, type MaybeValueOrObject, type OperationType, type PathOperation, type ReferenceType, type ReplaceRef, type SchemaType, type WithTypedRef, createOpenApiRegister,
|
|
56
|
+
export { type ApiRegisterOptions, type ExampleDescription, type MaybeReference, type MaybeValueOrObject, type OperationType, type PathOperation, type ReferenceType, type ReplaceRef, type SchemaObjectType, type SchemaSubType, type SchemaType, type WithTypedRef, createOpenApiRegister, toExampleSchema };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ReferenceObject, SchemaObject, PathItemObject, OperationObject, SecurityRequirementObject, OpenAPI3 } from 'openapi-typescript';
|
|
1
|
+
import { NumberSubtype, StringSubtype, BooleanSubtype, ArraySubtype, ObjectSubtype, NullSubtype, SchemaObject, ReferenceObject, PathItemObject, OperationObject, SecurityRequirementObject, OpenAPI3 } from 'openapi-typescript';
|
|
3
2
|
|
|
3
|
+
type SchemaSubType<T> = T extends number ? NumberSubtype : T extends string ? StringSubtype : T extends boolean ? BooleanSubtype : T extends Array<any> ? ArraySubtype : T extends Record<string, any> ? ObjectSubtype : NullSubtype;
|
|
4
|
+
type SchemaObjectType<T> = Omit<SchemaObject, 'example'> & SchemaSubType<T> & {
|
|
5
|
+
example?: T;
|
|
6
|
+
};
|
|
7
|
+
type ExampleDescription<T> = T extends (infer V)[] ? SchemaObjectType<V> extends ObjectSubtype ? ({
|
|
8
|
+
[Key in keyof V]?: string;
|
|
9
|
+
} | string) : string : SchemaObjectType<T> extends ObjectSubtype ? {
|
|
10
|
+
[Key in keyof T]?: string;
|
|
11
|
+
} : string;
|
|
4
12
|
type ReferenceType<T extends ApiRegisterOptions> = T extends {
|
|
5
13
|
components: infer C;
|
|
6
14
|
} ? {
|
|
@@ -41,32 +49,8 @@ declare function createOpenApiRegister<T extends ApiRegisterOptions = ApiRegiste
|
|
|
41
49
|
merge: (config: Partial<OpenAPI3>) => Partial<OpenAPI3>;
|
|
42
50
|
};
|
|
43
51
|
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
declare function resolveSchemaObject(value: any, options?: SchemaObjectOptions): SchemaObject;
|
|
48
|
-
type ExampleDescription<ExampleT> = MaybeValueOrObject<ExampleT, string>;
|
|
49
|
-
declare function toExampleSchema<T = any>(example: T, description?: ExampleDescription<T>, options?: SchemaObject): {
|
|
50
|
-
[key: `x-${string}`]: any;
|
|
51
|
-
discriminator?: openapi_typescript.DiscriminatorObject | undefined;
|
|
52
|
-
xml?: openapi_typescript.XMLObject | undefined;
|
|
53
|
-
externalDocs?: openapi_typescript.ExternalDocumentationObject | undefined;
|
|
54
|
-
example?: any;
|
|
55
|
-
title?: string | undefined;
|
|
56
|
-
description?: string | undefined;
|
|
57
|
-
$comment?: string | undefined;
|
|
58
|
-
deprecated?: boolean | undefined;
|
|
59
|
-
readOnly?: boolean | undefined;
|
|
60
|
-
writeOnly?: boolean | undefined;
|
|
61
|
-
enum?: unknown[] | undefined;
|
|
62
|
-
const?: unknown;
|
|
63
|
-
default?: unknown;
|
|
64
|
-
format?: string | undefined;
|
|
65
|
-
nullable?: boolean | undefined;
|
|
66
|
-
oneOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
67
|
-
allOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
68
|
-
anyOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
69
|
-
required?: string[] | undefined;
|
|
70
|
-
};
|
|
52
|
+
declare function toExampleSchema<T>(example: T, description: ExampleDescription<T> | undefined, options?: Partial<Omit<SchemaObjectType<T>, 'type' | 'example'> & {
|
|
53
|
+
withExample?: boolean;
|
|
54
|
+
}>): SchemaObjectType<T>;
|
|
71
55
|
|
|
72
|
-
export { type ApiRegisterOptions, type MaybeReference, type MaybeValueOrObject, type OperationType, type PathOperation, type ReferenceType, type ReplaceRef, type SchemaType, type WithTypedRef, createOpenApiRegister,
|
|
56
|
+
export { type ApiRegisterOptions, type ExampleDescription, type MaybeReference, type MaybeValueOrObject, type OperationType, type PathOperation, type ReferenceType, type ReplaceRef, type SchemaObjectType, type SchemaSubType, type SchemaType, type WithTypedRef, createOpenApiRegister, toExampleSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ReferenceObject, SchemaObject, PathItemObject, OperationObject, SecurityRequirementObject, OpenAPI3 } from 'openapi-typescript';
|
|
1
|
+
import { NumberSubtype, StringSubtype, BooleanSubtype, ArraySubtype, ObjectSubtype, NullSubtype, SchemaObject, ReferenceObject, PathItemObject, OperationObject, SecurityRequirementObject, OpenAPI3 } from 'openapi-typescript';
|
|
3
2
|
|
|
3
|
+
type SchemaSubType<T> = T extends number ? NumberSubtype : T extends string ? StringSubtype : T extends boolean ? BooleanSubtype : T extends Array<any> ? ArraySubtype : T extends Record<string, any> ? ObjectSubtype : NullSubtype;
|
|
4
|
+
type SchemaObjectType<T> = Omit<SchemaObject, 'example'> & SchemaSubType<T> & {
|
|
5
|
+
example?: T;
|
|
6
|
+
};
|
|
7
|
+
type ExampleDescription<T> = T extends (infer V)[] ? SchemaObjectType<V> extends ObjectSubtype ? ({
|
|
8
|
+
[Key in keyof V]?: string;
|
|
9
|
+
} | string) : string : SchemaObjectType<T> extends ObjectSubtype ? {
|
|
10
|
+
[Key in keyof T]?: string;
|
|
11
|
+
} : string;
|
|
4
12
|
type ReferenceType<T extends ApiRegisterOptions> = T extends {
|
|
5
13
|
components: infer C;
|
|
6
14
|
} ? {
|
|
@@ -41,32 +49,8 @@ declare function createOpenApiRegister<T extends ApiRegisterOptions = ApiRegiste
|
|
|
41
49
|
merge: (config: Partial<OpenAPI3>) => Partial<OpenAPI3>;
|
|
42
50
|
};
|
|
43
51
|
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
declare function resolveSchemaObject(value: any, options?: SchemaObjectOptions): SchemaObject;
|
|
48
|
-
type ExampleDescription<ExampleT> = MaybeValueOrObject<ExampleT, string>;
|
|
49
|
-
declare function toExampleSchema<T = any>(example: T, description?: ExampleDescription<T>, options?: SchemaObject): {
|
|
50
|
-
[key: `x-${string}`]: any;
|
|
51
|
-
discriminator?: openapi_typescript.DiscriminatorObject | undefined;
|
|
52
|
-
xml?: openapi_typescript.XMLObject | undefined;
|
|
53
|
-
externalDocs?: openapi_typescript.ExternalDocumentationObject | undefined;
|
|
54
|
-
example?: any;
|
|
55
|
-
title?: string | undefined;
|
|
56
|
-
description?: string | undefined;
|
|
57
|
-
$comment?: string | undefined;
|
|
58
|
-
deprecated?: boolean | undefined;
|
|
59
|
-
readOnly?: boolean | undefined;
|
|
60
|
-
writeOnly?: boolean | undefined;
|
|
61
|
-
enum?: unknown[] | undefined;
|
|
62
|
-
const?: unknown;
|
|
63
|
-
default?: unknown;
|
|
64
|
-
format?: string | undefined;
|
|
65
|
-
nullable?: boolean | undefined;
|
|
66
|
-
oneOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
67
|
-
allOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
68
|
-
anyOf?: (openapi_typescript.ReferenceObject | SchemaObject)[] | undefined;
|
|
69
|
-
required?: string[] | undefined;
|
|
70
|
-
};
|
|
52
|
+
declare function toExampleSchema<T>(example: T, description: ExampleDescription<T> | undefined, options?: Partial<Omit<SchemaObjectType<T>, 'type' | 'example'> & {
|
|
53
|
+
withExample?: boolean;
|
|
54
|
+
}>): SchemaObjectType<T>;
|
|
71
55
|
|
|
72
|
-
export { type ApiRegisterOptions, type MaybeReference, type MaybeValueOrObject, type OperationType, type PathOperation, type ReferenceType, type ReplaceRef, type SchemaType, type WithTypedRef, createOpenApiRegister,
|
|
56
|
+
export { type ApiRegisterOptions, type ExampleDescription, type MaybeReference, type MaybeValueOrObject, type OperationType, type PathOperation, type ReferenceType, type ReplaceRef, type SchemaObjectType, type SchemaSubType, type SchemaType, type WithTypedRef, createOpenApiRegister, toExampleSchema };
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import defu from 'defu';
|
|
1
|
+
import defu, { defu as defu$1 } from 'defu';
|
|
2
2
|
|
|
3
3
|
function createOpenApiRegister(options) {
|
|
4
4
|
const { paths = {}, components = {}, security = [], servers = [], info, tags = [] } = options;
|
|
5
5
|
const defineOperation = (operation) => operation;
|
|
6
6
|
function register(route, routeOperation, method = "get") {
|
|
7
|
-
const
|
|
8
|
-
paths[
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const path = normalizeRoute(route);
|
|
8
|
+
paths[path] = {
|
|
9
|
+
...paths[path],
|
|
10
|
+
[method]: routeOperation
|
|
11
|
+
};
|
|
12
12
|
}
|
|
13
13
|
function merge(config) {
|
|
14
14
|
return mergeConfig(
|
|
@@ -43,109 +43,80 @@ function normalizeRoute(_route) {
|
|
|
43
43
|
return route;
|
|
44
44
|
}
|
|
45
45
|
function mergeConfig(defaults, appends) {
|
|
46
|
-
const methods = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put", "trace"]);
|
|
47
46
|
const { info } = appends;
|
|
48
|
-
const { paths = {} } = defaults;
|
|
47
|
+
const { openapi, servers, security, tags, paths = {} } = defaults;
|
|
49
48
|
for (const path in paths) {
|
|
50
49
|
const operations = paths[path];
|
|
50
|
+
const operationsAppend = appends.paths?.[path] ?? {};
|
|
51
|
+
if ("$ref" in operationsAppend) {
|
|
52
|
+
paths[path] = operationsAppend;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
51
55
|
if ("$ref" in operations)
|
|
52
56
|
continue;
|
|
53
|
-
paths[path] = Object.fromEntries(Object.entries(operations).map(([
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return [key, obj];
|
|
57
|
+
paths[path] = Object.fromEntries(Object.entries(operations).map(([method, operation]) => {
|
|
58
|
+
const extendOperation = operationsAppend[method] ?? {};
|
|
59
|
+
return [method, defu(operation, extendOperation)];
|
|
57
60
|
}));
|
|
58
61
|
}
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return defu(p, {
|
|
69
|
-
schema: { type: "string" }
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
return obj;
|
|
62
|
+
return {
|
|
63
|
+
openapi,
|
|
64
|
+
info,
|
|
65
|
+
servers,
|
|
66
|
+
security,
|
|
67
|
+
tags,
|
|
68
|
+
...defu(defaults, appends),
|
|
69
|
+
paths
|
|
70
|
+
};
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
function
|
|
76
|
-
const {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
function toExampleSchema(example, description, options = {}) {
|
|
74
|
+
const { withExample = true, ...overrides } = options;
|
|
75
|
+
const createSchemaObject = (schema2) => {
|
|
76
|
+
const merged = {
|
|
77
|
+
...schema2,
|
|
78
|
+
...typeof description === "string" && description !== "" ? { description } : {},
|
|
79
|
+
...withExample ? { example } : {},
|
|
80
|
+
...overrides
|
|
81
|
+
};
|
|
82
|
+
return merged;
|
|
81
83
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
);
|
|
84
|
+
let schema = createSchemaObject({
|
|
85
|
+
type: "null"
|
|
86
|
+
});
|
|
87
|
+
if (typeof example === "number") {
|
|
88
|
+
schema = createSchemaObject({
|
|
89
|
+
type: "number"
|
|
90
|
+
});
|
|
90
91
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
case "undefined":
|
|
96
|
-
return { type: "null" };
|
|
97
|
-
case "object":
|
|
98
|
-
return resolveResult(
|
|
99
|
-
{
|
|
100
|
-
type: "object",
|
|
101
|
-
properties: Object.fromEntries(Object.entries(value).map(([k, v]) => [
|
|
102
|
-
k,
|
|
103
|
-
resolveSchemaObject(v, {
|
|
104
|
-
allowExample: false
|
|
105
|
-
})
|
|
106
|
-
]))
|
|
107
|
-
},
|
|
108
|
-
value
|
|
109
|
-
);
|
|
110
|
-
case "bigint":
|
|
111
|
-
return resolveResult(
|
|
112
|
-
{ type: "integer" },
|
|
113
|
-
value
|
|
114
|
-
);
|
|
115
|
-
case "string":
|
|
116
|
-
return resolveResult(
|
|
117
|
-
{ type: "string" },
|
|
118
|
-
value || null
|
|
119
|
-
);
|
|
120
|
-
default:
|
|
121
|
-
return resolveResult(
|
|
122
|
-
{ type: _type },
|
|
123
|
-
value
|
|
124
|
-
);
|
|
92
|
+
if (typeof example === "string") {
|
|
93
|
+
schema = createSchemaObject({
|
|
94
|
+
type: "string"
|
|
95
|
+
});
|
|
125
96
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
example,
|
|
131
|
-
typeof description === "string" ? { ...options, description } : {}
|
|
132
|
-
);
|
|
97
|
+
if (typeof example === "boolean") {
|
|
98
|
+
schema = createSchemaObject({
|
|
99
|
+
type: "boolean"
|
|
100
|
+
});
|
|
133
101
|
}
|
|
134
|
-
if (
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
102
|
+
if (typeof example === "object" && example !== null) {
|
|
103
|
+
if (Array.isArray(example)) {
|
|
104
|
+
const value = typeof example[0] === "object" ? defu$1({}, ...example) : example[0];
|
|
105
|
+
schema = createSchemaObject({
|
|
106
|
+
type: "array",
|
|
107
|
+
items: toExampleSchema(value, typeof description === "string" ? "" : description, { withExample: false })
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
schema = createSchemaObject({
|
|
111
|
+
type: "object",
|
|
112
|
+
properties: Object.fromEntries(Object.entries(example).map(([k, v]) => {
|
|
113
|
+
const _description = typeof description === "object" ? description[k] : description;
|
|
114
|
+
return [k, toExampleSchema(v, _description, { withExample: false })];
|
|
115
|
+
}))
|
|
116
|
+
});
|
|
117
|
+
}
|
|
140
118
|
}
|
|
141
|
-
if (typeof description === "string")
|
|
142
|
-
return resolveSchemaObject(example, { ...options, description });
|
|
143
|
-
const schema = resolveSchemaObject(example, options);
|
|
144
|
-
schema.properties = Object.fromEntries(Object.entries(schema.properties).map(([p, item]) => [p, {
|
|
145
|
-
...item,
|
|
146
|
-
...typeof description === "object" ? { description: description?.[p] } : {}
|
|
147
|
-
}]));
|
|
148
119
|
return schema;
|
|
149
120
|
}
|
|
150
121
|
|
|
151
|
-
export { createOpenApiRegister,
|
|
122
|
+
export { createOpenApiRegister, toExampleSchema };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byyuurin/nitro-openapi",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.8",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/byyuurin/nitro-openapi",
|
|
@@ -22,21 +22,6 @@
|
|
|
22
22
|
"*.d.ts",
|
|
23
23
|
"dist"
|
|
24
24
|
],
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"defu": "^6.1.4",
|
|
27
|
-
"openapi-typescript": "^6.7.6"
|
|
28
|
-
},
|
|
29
|
-
"devDependencies": {
|
|
30
|
-
"@byyuurin/eslint-config": "^1.2.0",
|
|
31
|
-
"bumpp": "^9.4.1",
|
|
32
|
-
"eslint-plugin-format": "^0.1.1",
|
|
33
|
-
"nitropack": "^2.9.6",
|
|
34
|
-
"unbuild": "^2.0.0",
|
|
35
|
-
"vitest": "^1.6.0"
|
|
36
|
-
},
|
|
37
|
-
"resolutions": {
|
|
38
|
-
"@byyuurin/nitro-openapi": "link:."
|
|
39
|
-
},
|
|
40
25
|
"scripts": {
|
|
41
26
|
"build": "unbuild",
|
|
42
27
|
"dev": "nitropack dev playground",
|
|
@@ -46,6 +31,24 @@
|
|
|
46
31
|
"lint": "eslint .",
|
|
47
32
|
"test": "vitest",
|
|
48
33
|
"release": "bumpp && pnpm publish",
|
|
49
|
-
"stub": "unbuild --stub"
|
|
34
|
+
"stub": "unbuild --stub",
|
|
35
|
+
"prepack": "pnpm build"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"defu": "^6.1.4",
|
|
39
|
+
"openapi-typescript": "^6.7.6"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@byyuurin/eslint-config": "^1.8.3",
|
|
43
|
+
"bumpp": "^9.11.1",
|
|
44
|
+
"eslint": "^9.30.1",
|
|
45
|
+
"eslint-plugin-format": "^0.1.3",
|
|
46
|
+
"nitropack": "^2.11.13",
|
|
47
|
+
"typescript": "^5.8.3",
|
|
48
|
+
"unbuild": "^2.0.0",
|
|
49
|
+
"vitest": "^1.6.1"
|
|
50
|
+
},
|
|
51
|
+
"resolutions": {
|
|
52
|
+
"@byyuurin/nitro-openapi": "link:."
|
|
50
53
|
}
|
|
51
|
-
}
|
|
54
|
+
}
|