vona-module-a-openapi 5.0.10 → 5.0.12
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/.metadata/index.d.ts +222 -0
- package/dist/.metadata/index.js +39 -0
- package/dist/.metadata/this.d.ts +2 -0
- package/dist/.metadata/this.js +2 -0
- package/dist/config/config.d.ts +12 -0
- package/dist/config/config.js +30 -0
- package/dist/config/locale/en-us.d.ts +80 -0
- package/dist/config/locale/en-us.js +2 -0
- package/dist/config/locale/zh-cn.d.ts +80 -0
- package/dist/config/locale/zh-cn.js +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/lib/decorator/api.d.ts +23 -0
- package/dist/lib/decorator/api.js +71 -0
- package/dist/lib/decorator/arguments.d.ts +38 -0
- package/dist/lib/decorator/arguments.js +39 -0
- package/dist/lib/decorator/field.d.ts +2 -0
- package/dist/lib/decorator/field.js +15 -0
- package/dist/lib/decorator/index.d.ts +3 -0
- package/dist/lib/decorator/index.js +3 -0
- package/dist/lib/decorator/pipesArgument.d.ts +2 -0
- package/dist/lib/decorator/pipesArgument.js +35 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +4 -0
- package/dist/lib/schema/bodySchemaWrapper.d.ts +14 -0
- package/dist/lib/schema/bodySchemaWrapper.js +8 -0
- package/dist/lib/schema/index.d.ts +4 -0
- package/dist/lib/schema/index.js +4 -0
- package/dist/lib/schema/makeSchemaLikes.d.ts +4 -0
- package/dist/lib/schema/makeSchemaLikes.js +29 -0
- package/dist/lib/schema/schema.d.ts +11 -0
- package/dist/lib/schema/schema.js +40 -0
- package/dist/lib/schema/v/helpers.d.ts +13 -0
- package/dist/lib/schema/v/helpers.js +36 -0
- package/dist/lib/schema/v/openapi.d.ts +7 -0
- package/dist/lib/schema/v/openapi.js +20 -0
- package/dist/lib/schema/v/system.d.ts +9 -0
- package/dist/lib/schema/v/system.js +34 -0
- package/dist/lib/schema/v.d.ts +20 -0
- package/dist/lib/schema/v.js +22 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/utils.js +43 -0
- package/dist/lib/zod/errorUtil.d.ts +9 -0
- package/dist/lib/zod/errorUtil.js +1 -0
- package/dist/lib/zod/errorsAdapter.d.ts +2 -0
- package/dist/lib/zod/errorsAdapter.js +9 -0
- package/dist/lib/zod/index.d.ts +2 -0
- package/dist/lib/zod/index.js +2 -0
- package/dist/main.d.ts +7 -0
- package/dist/main.js +9 -0
- package/dist/service/openapi.d.ts +19 -0
- package/dist/service/openapi.js +352 -0
- package/dist/types/actions.d.ts +15 -0
- package/dist/types/actions.js +1 -0
- package/dist/types/api.d.ts +33 -0
- package/dist/types/api.js +1 -0
- package/dist/types/behavior.d.ts +10 -0
- package/dist/types/behavior.js +1 -0
- package/dist/types/component.d.ts +11 -0
- package/dist/types/component.js +1 -0
- package/dist/types/database.d.ts +4 -0
- package/dist/types/database.js +4 -0
- package/dist/types/decorator.d.ts +30 -0
- package/dist/types/decorator.js +4 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +8 -0
- package/dist/types/rest.d.ts +37 -0
- package/dist/types/rest.js +2 -0
- package/package.json +9 -5
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { OpenApiGeneratorV3, OpenApiGeneratorV31, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
|
|
8
|
+
import * as ModuleInfo from '@cabloy/module-info';
|
|
9
|
+
import { isEmptyObject } from '@cabloy/utils';
|
|
10
|
+
import { toUpperCaseFirstChar } from '@cabloy/word-utils';
|
|
11
|
+
import { appMetadata, appResource, BeanBase, cast, HttpStatus, LocaleModuleNameSeparator, } from 'vona';
|
|
12
|
+
import { RequestMethod, Service, SymbolRequestMappingHandler, } from 'vona-module-a-web';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { bodySchemaWrapperDefault } from "../lib/schema/bodySchemaWrapper.js";
|
|
15
|
+
import { $schema } from "../lib/schema/schema.js";
|
|
16
|
+
import { SymbolOpenApiOptions } from "../types/api.js";
|
|
17
|
+
import { SymbolRouteHandlersArgumentsMeta } from "../types/decorator.js";
|
|
18
|
+
const __ArgumentTypes = ['param', 'query', 'body', 'headers', 'fields', 'field', 'files', 'file'];
|
|
19
|
+
let ServiceOpenapi = class ServiceOpenapi extends BeanBase {
|
|
20
|
+
generateJson(version = 'V31') {
|
|
21
|
+
const registry = this._collectRegistry();
|
|
22
|
+
const generator = version === 'V30' ? new OpenApiGeneratorV3(registry.definitions) : new OpenApiGeneratorV31(registry.definitions);
|
|
23
|
+
const apiObj = generator.generateDocument(this.scope.config.generateDocument[version]);
|
|
24
|
+
this._translate(apiObj);
|
|
25
|
+
return apiObj;
|
|
26
|
+
}
|
|
27
|
+
generateJsonOfControllerAction(controller, actionKey, version = 'V31') {
|
|
28
|
+
const registry = new OpenAPIRegistry();
|
|
29
|
+
const beanOptions = appResource.getBean(controller);
|
|
30
|
+
if (!beanOptions)
|
|
31
|
+
throw new Error('invalid controller');
|
|
32
|
+
this._collectController(registry, beanOptions.module, controller, actionKey);
|
|
33
|
+
const generator = version === 'V30' ? new OpenApiGeneratorV3(registry.definitions) : new OpenApiGeneratorV31(registry.definitions);
|
|
34
|
+
const apiObj = generator.generateDocument(this.scope.config.generateDocument[version]);
|
|
35
|
+
this._translate(apiObj);
|
|
36
|
+
return apiObj;
|
|
37
|
+
}
|
|
38
|
+
_translate(apiObj) {
|
|
39
|
+
// paths
|
|
40
|
+
if (apiObj.paths) {
|
|
41
|
+
for (const key in apiObj.paths) {
|
|
42
|
+
const pathObj = apiObj.paths[key];
|
|
43
|
+
for (const method in pathObj) {
|
|
44
|
+
const methodObj = pathObj[method];
|
|
45
|
+
this._translateStrings(methodObj, ['description', 'summary']);
|
|
46
|
+
// parameters
|
|
47
|
+
for (const parameterObj of methodObj.parameters || []) {
|
|
48
|
+
this._translateSchema(parameterObj.schema);
|
|
49
|
+
}
|
|
50
|
+
// requestBody
|
|
51
|
+
this._translateSchema(methodObj.requestBody?.content?.['application/json']?.schema);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// components
|
|
56
|
+
if (apiObj.components?.schemas) {
|
|
57
|
+
for (const key in apiObj.components.schemas) {
|
|
58
|
+
const schema = apiObj.components.schemas[key];
|
|
59
|
+
this._translateSchema(schema);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
_translateSchema(schema) {
|
|
64
|
+
if (!schema)
|
|
65
|
+
return;
|
|
66
|
+
if (schema.type === 'object' && schema.required === undefined)
|
|
67
|
+
schema.required = [];
|
|
68
|
+
this._translateStrings(schema, ['title', 'description']);
|
|
69
|
+
const properties = cast(schema).properties;
|
|
70
|
+
if (properties && typeof properties === 'object') {
|
|
71
|
+
for (const prop in properties) {
|
|
72
|
+
const propObj = properties[prop];
|
|
73
|
+
this._translateSchema(propObj);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
_translateStrings(obj, keys) {
|
|
78
|
+
for (const key of keys) {
|
|
79
|
+
this._translateString(obj, key);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
_translateString(obj, key) {
|
|
83
|
+
if (!obj)
|
|
84
|
+
return;
|
|
85
|
+
if (obj[key] && obj[key].includes(LocaleModuleNameSeparator)) {
|
|
86
|
+
obj[key] = this.app.meta.text(obj[key]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
_collectRegistry() {
|
|
90
|
+
const registry = new OpenAPIRegistry();
|
|
91
|
+
// securitySchemes
|
|
92
|
+
const configSecuritySchemes = this.scope.config.securitySchemes;
|
|
93
|
+
for (const key in configSecuritySchemes) {
|
|
94
|
+
let securityScheme = configSecuritySchemes[key];
|
|
95
|
+
if (typeof securityScheme === 'function') {
|
|
96
|
+
securityScheme = securityScheme.call(this.app);
|
|
97
|
+
}
|
|
98
|
+
registry.registerComponent('securitySchemes', key, securityScheme);
|
|
99
|
+
}
|
|
100
|
+
// schema: independent
|
|
101
|
+
for (const sceneName of ['dto', 'entity']) {
|
|
102
|
+
const onionSlices = this.bean.onion[sceneName].getOnionsEnabled();
|
|
103
|
+
for (const onionSlice of onionSlices) {
|
|
104
|
+
if (onionSlice.beanOptions.options?.independent) {
|
|
105
|
+
const schema = $schema(onionSlice.beanOptions.beanClass);
|
|
106
|
+
registry.register(onionSlice.beanOptions.beanFullName, schema);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// controller
|
|
111
|
+
for (const controller of this.bean.onion.controller.getOnionsEnabled()) {
|
|
112
|
+
this._collectController(registry, controller.beanOptions.module, controller.beanOptions.beanClass);
|
|
113
|
+
}
|
|
114
|
+
return registry;
|
|
115
|
+
}
|
|
116
|
+
_collectController(registry, moduleName, controller, actionKey) {
|
|
117
|
+
// info
|
|
118
|
+
const info = ModuleInfo.parseInfo(moduleName);
|
|
119
|
+
// controller options
|
|
120
|
+
const beanOptions = appResource.getBean(controller);
|
|
121
|
+
if (!beanOptions)
|
|
122
|
+
return;
|
|
123
|
+
const controllerBeanFullName = beanOptions.beanFullName;
|
|
124
|
+
const controllerOptions = beanOptions.options;
|
|
125
|
+
const controllerPath = controllerOptions.path;
|
|
126
|
+
const controllerOpenApiOptions = appMetadata.getMetadata(SymbolOpenApiOptions, controller);
|
|
127
|
+
if (controllerOpenApiOptions?.exclude)
|
|
128
|
+
return;
|
|
129
|
+
// descs
|
|
130
|
+
const descs = Object.getOwnPropertyDescriptors(controller.prototype);
|
|
131
|
+
const actionKeys = actionKey ? [actionKey] : Object.keys(descs);
|
|
132
|
+
for (const actionKey of actionKeys) {
|
|
133
|
+
const desc = descs[actionKey];
|
|
134
|
+
if (['constructor'].includes(actionKey))
|
|
135
|
+
continue;
|
|
136
|
+
if (!desc.value || typeof desc.value !== 'function')
|
|
137
|
+
continue;
|
|
138
|
+
this._registerControllerAction(registry, info, controller, beanOptions, controllerBeanFullName, controllerPath, controllerOpenApiOptions, actionKey, desc);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
_registerControllerAction(registry, info, controller, beanOptions, _controllerBeanFullName, controllerPath, controllerOpenApiOptions, actionKey, _desc) {
|
|
142
|
+
// app
|
|
143
|
+
const app = this.app;
|
|
144
|
+
// action options: should not extend controllerOpenApiOptions
|
|
145
|
+
const actionOpenApiOptions = appMetadata.getMetadata(SymbolOpenApiOptions, controller.prototype, actionKey);
|
|
146
|
+
if (actionOpenApiOptions?.exclude)
|
|
147
|
+
return;
|
|
148
|
+
// actionPath/actionMethod
|
|
149
|
+
if (!appMetadata.hasMetadata(SymbolRequestMappingHandler, controller.prototype, actionKey))
|
|
150
|
+
return;
|
|
151
|
+
const handlerMetadata = appMetadata.getMetadata(SymbolRequestMappingHandler, controller.prototype, actionKey);
|
|
152
|
+
const actionPath = handlerMetadata.path || '';
|
|
153
|
+
const actionMethod = handlerMetadata.method || RequestMethod.GET;
|
|
154
|
+
// routePath
|
|
155
|
+
const routePath = app.util.combineApiPathControllerAndAction(info.relativeName, controllerPath, actionPath, true, true);
|
|
156
|
+
// :id -> {id}
|
|
157
|
+
const routePath2 = routePath.replace(/:([^/]+)/g, '{$1}');
|
|
158
|
+
// tags
|
|
159
|
+
let tags = actionOpenApiOptions?.tags ?? controllerOpenApiOptions?.tags;
|
|
160
|
+
if (!tags || tags.length === 0) {
|
|
161
|
+
tags = [toUpperCaseFirstChar(this.app.util.combineResourceName(beanOptions.name, info.relativeName, true, true))];
|
|
162
|
+
}
|
|
163
|
+
// operationId
|
|
164
|
+
let operationId = actionOpenApiOptions?.operationId ?? actionKey;
|
|
165
|
+
operationId = `${tags[0]}_${operationId}`;
|
|
166
|
+
// security
|
|
167
|
+
const _public = actionOpenApiOptions?.public ?? controllerOpenApiOptions?.public;
|
|
168
|
+
let security;
|
|
169
|
+
if (!_public) {
|
|
170
|
+
security = [
|
|
171
|
+
{
|
|
172
|
+
bearerAuth: [],
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
// registerPath
|
|
177
|
+
registry.registerPath({
|
|
178
|
+
tags,
|
|
179
|
+
method: actionMethod,
|
|
180
|
+
path: routePath2,
|
|
181
|
+
operationId,
|
|
182
|
+
security,
|
|
183
|
+
description: actionOpenApiOptions?.description,
|
|
184
|
+
summary: actionOpenApiOptions?.summary,
|
|
185
|
+
request: this._collectRequest(controller, actionKey, actionOpenApiOptions, controllerOpenApiOptions),
|
|
186
|
+
responses: this._collectResponses(controller, actionKey, actionOpenApiOptions),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
_collectRequest(controller, actionKey, actionOpenApiOptions, controllerOpenApiOptions) {
|
|
190
|
+
// meta
|
|
191
|
+
const argsMeta = this._prepareArgsMeta(controller, actionKey, actionOpenApiOptions, controllerOpenApiOptions);
|
|
192
|
+
if (!argsMeta)
|
|
193
|
+
return;
|
|
194
|
+
// args
|
|
195
|
+
const argsMapWithField = {};
|
|
196
|
+
const argsMapIsolate = {};
|
|
197
|
+
let isUpload;
|
|
198
|
+
for (const argMeta of argsMeta) {
|
|
199
|
+
if (!__ArgumentTypes.includes(argMeta.type))
|
|
200
|
+
continue;
|
|
201
|
+
if (['fields', 'field', 'files', 'file'].includes(argMeta.type)) {
|
|
202
|
+
isUpload = true;
|
|
203
|
+
}
|
|
204
|
+
if (argMeta.field) {
|
|
205
|
+
if (!argsMapWithField[argMeta.type]) {
|
|
206
|
+
argsMapWithField[argMeta.type] = {};
|
|
207
|
+
}
|
|
208
|
+
argsMapWithField[argMeta.type][argMeta.field] = argMeta.schema;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
if (!argsMapIsolate[argMeta.type]) {
|
|
212
|
+
argsMapIsolate[argMeta.type] = argMeta.schema;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// request
|
|
217
|
+
const request = {};
|
|
218
|
+
if (isUpload) {
|
|
219
|
+
const schemaObj = {};
|
|
220
|
+
// not check argsMapIsolate.fields
|
|
221
|
+
if (argsMapWithField.fields)
|
|
222
|
+
Object.assign(schemaObj, argsMapWithField.fields);
|
|
223
|
+
if (argsMapWithField.field)
|
|
224
|
+
Object.assign(schemaObj, argsMapWithField.field);
|
|
225
|
+
if (argsMapWithField.files)
|
|
226
|
+
Object.assign(schemaObj, argsMapWithField.files);
|
|
227
|
+
if (argsMapWithField.file)
|
|
228
|
+
Object.assign(schemaObj, argsMapWithField.file);
|
|
229
|
+
if (argsMapIsolate.files)
|
|
230
|
+
schemaObj.blobs = argsMapIsolate.files;
|
|
231
|
+
const schema = z.object(schemaObj);
|
|
232
|
+
// body
|
|
233
|
+
request.body = {
|
|
234
|
+
required: true,
|
|
235
|
+
content: {
|
|
236
|
+
'multipart/form-data': {
|
|
237
|
+
schema,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
for (const argumentType of __ArgumentTypes) {
|
|
244
|
+
let schema = argsMapIsolate[argumentType];
|
|
245
|
+
if (argsMapWithField[argumentType]) {
|
|
246
|
+
if (!schema) {
|
|
247
|
+
schema = z.object(argsMapWithField[argumentType]);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
schema = schema.extend(argsMapWithField[argumentType]);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (!schema)
|
|
254
|
+
continue;
|
|
255
|
+
// record
|
|
256
|
+
if (argumentType === 'body') {
|
|
257
|
+
// body
|
|
258
|
+
request.body = {
|
|
259
|
+
required: !schema.isOptional(),
|
|
260
|
+
content: {
|
|
261
|
+
'application/json': {
|
|
262
|
+
schema,
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
// others
|
|
269
|
+
const name = argumentType === 'param' ? 'params' : argumentType;
|
|
270
|
+
request[name] = schema;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return request;
|
|
275
|
+
}
|
|
276
|
+
_collectResponses(controller, actionKey, actionOpenApiOptions) {
|
|
277
|
+
// contentType
|
|
278
|
+
const contentType = actionOpenApiOptions?.contentType || 'application/json';
|
|
279
|
+
// body schema
|
|
280
|
+
const bodySchema = this._parseBodySchema(controller, actionKey, actionOpenApiOptions, contentType);
|
|
281
|
+
// response
|
|
282
|
+
const response = {
|
|
283
|
+
description: '',
|
|
284
|
+
content: {
|
|
285
|
+
[contentType]: {
|
|
286
|
+
schema: bodySchema,
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
// responses
|
|
291
|
+
const responses = { [HttpStatus.OK]: response };
|
|
292
|
+
return responses;
|
|
293
|
+
}
|
|
294
|
+
_parseBodySchema(controller, actionKey, actionOpenApiOptions, contentType) {
|
|
295
|
+
// bodySchema
|
|
296
|
+
let bodySchema;
|
|
297
|
+
if (actionOpenApiOptions?.bodySchema) {
|
|
298
|
+
bodySchema = actionOpenApiOptions.bodySchema;
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
const metaType = appMetadata.getDesignReturntype(controller.prototype, actionKey);
|
|
302
|
+
bodySchema = $schema(metaType);
|
|
303
|
+
}
|
|
304
|
+
// wrapper
|
|
305
|
+
if (contentType !== 'application/json')
|
|
306
|
+
return bodySchema;
|
|
307
|
+
if (actionOpenApiOptions?.bodySchemaWrapper === false)
|
|
308
|
+
return bodySchema;
|
|
309
|
+
const wrapper = actionOpenApiOptions?.bodySchemaWrapper ?? bodySchemaWrapperDefault;
|
|
310
|
+
return wrapper(bodySchema);
|
|
311
|
+
}
|
|
312
|
+
_prepareArgsMeta(controller, actionKey, actionOpenApiOptions, controllerOpenApiOptions) {
|
|
313
|
+
// meta
|
|
314
|
+
let argsMeta = appMetadata.getMetadata(SymbolRouteHandlersArgumentsMeta, controller.prototype, actionKey);
|
|
315
|
+
// headers
|
|
316
|
+
const objHeaders = Object.assign({}, this._combineArgHeaders(controllerOpenApiOptions?.headers), this._combineArgHeaders(actionOpenApiOptions?.headers));
|
|
317
|
+
// public
|
|
318
|
+
const _public = actionOpenApiOptions?.public ?? controllerOpenApiOptions?.public;
|
|
319
|
+
if (!_public && !objHeaders.Authorization) {
|
|
320
|
+
objHeaders.Authorization = z.string().optional();
|
|
321
|
+
}
|
|
322
|
+
if (isEmptyObject(objHeaders))
|
|
323
|
+
return argsMeta;
|
|
324
|
+
// merge
|
|
325
|
+
if (!argsMeta)
|
|
326
|
+
argsMeta = [];
|
|
327
|
+
let argHeaders = argsMeta.find(item => item.type === 'headers' && !item.field);
|
|
328
|
+
if (!argHeaders) {
|
|
329
|
+
argHeaders = { type: 'headers', field: undefined, schema: z.object(objHeaders) };
|
|
330
|
+
argsMeta.push(argHeaders);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
if (!argHeaders.schema.extend)
|
|
334
|
+
throw new Error(`headers schema is not valid: ${actionKey}`);
|
|
335
|
+
argHeaders.schema = argHeaders.schema.extend(objHeaders);
|
|
336
|
+
}
|
|
337
|
+
return argsMeta;
|
|
338
|
+
}
|
|
339
|
+
_combineArgHeaders(headers) {
|
|
340
|
+
if (!headers)
|
|
341
|
+
return;
|
|
342
|
+
const objHeaders = {};
|
|
343
|
+
for (const header of headers) {
|
|
344
|
+
objHeaders[header.name] = z.string().openapi({ description: header.description });
|
|
345
|
+
}
|
|
346
|
+
return objHeaders;
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
ServiceOpenapi = __decorate([
|
|
350
|
+
Service()
|
|
351
|
+
], ServiceOpenapi);
|
|
352
|
+
export { ServiceOpenapi };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface IResourceActionTableOptions {
|
|
2
|
+
}
|
|
3
|
+
export interface IResourceActionRowOptions {
|
|
4
|
+
}
|
|
5
|
+
export interface TypeResourceActionTableRecord {
|
|
6
|
+
create: IResourceActionTableOptions;
|
|
7
|
+
}
|
|
8
|
+
export interface TypeResourceActionRowRecord {
|
|
9
|
+
view: IResourceActionRowOptions;
|
|
10
|
+
update: IResourceActionRowOptions;
|
|
11
|
+
delete: IResourceActionRowOptions;
|
|
12
|
+
}
|
|
13
|
+
export type TypeResourceActionRowRecordRender = {
|
|
14
|
+
[key in keyof TypeResourceActionRowRecord as `action${Capitalize<key>}`]: TypeResourceActionRowRecord[key];
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { OpenAPIObject as OpenAPIObject30, SchemaObject as SchemaObject30 } from 'openapi3-ts/oas30';
|
|
2
|
+
import type { OpenAPIObject as OpenAPIObject31, SchemaObject as SchemaObject31 } from 'openapi3-ts/oas31';
|
|
3
|
+
import type { VonaApplication } from 'vona';
|
|
4
|
+
import type { z } from 'zod';
|
|
5
|
+
import type { SchemaLikeCreate } from './decorator.ts';
|
|
6
|
+
export declare const SymbolOpenApiOptions: unique symbol;
|
|
7
|
+
export interface IOpenApiHeader {
|
|
8
|
+
name: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface IOpenApiOptions {
|
|
12
|
+
public?: boolean;
|
|
13
|
+
description?: string;
|
|
14
|
+
summary?: string;
|
|
15
|
+
contentType?: TypeResponseContentType;
|
|
16
|
+
bodySchema?: z.ZodSchema;
|
|
17
|
+
bodySchemaWrapper?: SchemaLikeCreate | false;
|
|
18
|
+
exclude?: boolean;
|
|
19
|
+
tags?: string[];
|
|
20
|
+
operationId?: string;
|
|
21
|
+
headers?: IOpenApiHeader[];
|
|
22
|
+
}
|
|
23
|
+
export type TypeOpenApiVersion = 'V30' | 'V31';
|
|
24
|
+
export interface IOpenAPIObject {
|
|
25
|
+
V30: OpenAPIObject30;
|
|
26
|
+
V31: OpenAPIObject31;
|
|
27
|
+
}
|
|
28
|
+
export interface IOpenAPISchemaObject {
|
|
29
|
+
V30: SchemaObject30;
|
|
30
|
+
V31: SchemaObject31;
|
|
31
|
+
}
|
|
32
|
+
export type TypeSecuritySchemes = Record<string, ((this: VonaApplication) => object) | object>;
|
|
33
|
+
export type TypeResponseContentType = 'application/json' | 'application/xml' | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain' | 'text/html' | 'application/octet-stream' | 'application/pdf' | 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp' | 'image/svg+xml' | 'image/bmp' | 'image/tiff' | 'image/vnd.microsoft.icon' | 'image/vnd.wap.wbmp' | 'image/x-icon' | 'image/x-jng' | 'image/x-ms-bmp' | 'image/x-portable-bitmap' | 'image/x-portable-graymap' | 'image/x-portable-pixmap' | 'image/x-xbitmap' | 'image/x-xpixmap' | 'image/x-xwindowdump' | 'image/bmp' | 'image/x-bmp' | 'image/x-xbitmap' | 'image/x-win-bitmap' | 'image/x-windows-bmp' | 'image/ms-bmp' | 'image/x-ms-bmp' | 'image/x-icon' | 'image/x-ico' | 'image/vnd.microsoft.icon' | 'image/ico' | 'image/icon' | 'text/css' | 'text/csv' | 'text/html' | 'text/javascript' | 'text/plain' | 'text/xml' | 'application/javascript' | 'application/ecmascript' | 'application/json' | 'application/ld+json' | 'application/manifest+json' | 'application/javascript' | 'application/x-javascript' | 'application/x-json' | 'application/x-ms-application';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SymbolOpenApiOptions = Symbol('SymbolOpenApiOptions');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface IBehaviorRecord {
|
|
2
|
+
}
|
|
3
|
+
export type TypeBehaviorRecordSelector<PREFIX extends string> = {
|
|
4
|
+
[K in keyof IBehaviorRecord as K extends `${string}:${PREFIX}${string}` ? K : never]: IBehaviorRecord[K];
|
|
5
|
+
};
|
|
6
|
+
export type TypeBehaviorRecordSelectorKeys<PREFIX extends string> = keyof TypeBehaviorRecordSelector<PREFIX>;
|
|
7
|
+
export type TypeBehaviorRecordSelectorStrict<PREFIX extends string> = {
|
|
8
|
+
[K in keyof IBehaviorRecord as K extends `${string}:${PREFIX}` ? K : never]: IBehaviorRecord[K];
|
|
9
|
+
};
|
|
10
|
+
export type TypeBehaviorRecordSelectorKeysStrict<PREFIX extends string> = keyof TypeBehaviorRecordSelectorStrict<PREFIX>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface IComponentRecord {
|
|
2
|
+
}
|
|
3
|
+
export type TypeComponentRecordSelector<PREFIX extends string> = {
|
|
4
|
+
[K in keyof IComponentRecord as K extends `${string}:${PREFIX}${string}` ? K : never]: IComponentRecord[K];
|
|
5
|
+
};
|
|
6
|
+
export type TypeComponentRecordSelectorKeys<PREFIX extends string> = keyof TypeComponentRecordSelector<PREFIX>;
|
|
7
|
+
export type TypeComponentRecordSelectorStrict<PREFIX extends string> = {
|
|
8
|
+
[K in keyof IComponentRecord as K extends `${string}:${PREFIX}` ? K : never]: IComponentRecord[K];
|
|
9
|
+
};
|
|
10
|
+
export type TypeComponentRecordSelectorKeysStrict<PREFIX extends string> = keyof TypeComponentRecordSelectorStrict<PREFIX>;
|
|
11
|
+
export type TypeComponentLayoutRecord = TypeComponentRecordSelector<'layout'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Constructable, Type, VonaContext } from 'vona';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
export declare const SymbolDecoratorRule: unique symbol;
|
|
4
|
+
export declare const SymbolDecoratorRuleColumn: unique symbol;
|
|
5
|
+
export type SchemaLikeCreate = (schema: any) => any;
|
|
6
|
+
export type SchemaLike = SchemaLikeCreate | z.ZodSchema | Constructable;
|
|
7
|
+
export interface ISchemaObjectOptions {
|
|
8
|
+
passthrough?: boolean;
|
|
9
|
+
strict?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface RouteHandlerArgumentMetaDecorator {
|
|
12
|
+
index: number;
|
|
13
|
+
type: RouteHandlerArgumentType;
|
|
14
|
+
field?: string;
|
|
15
|
+
pipes: (Function | z.ZodSchema)[];
|
|
16
|
+
schema: z.ZodSchema;
|
|
17
|
+
extractValue?: TypeExtractValue;
|
|
18
|
+
}
|
|
19
|
+
export interface RouteHandlerArgumentMeta {
|
|
20
|
+
type: RouteHandlerArgumentType;
|
|
21
|
+
field?: string;
|
|
22
|
+
metaType?: Type<any>;
|
|
23
|
+
controller: Constructable;
|
|
24
|
+
method: string;
|
|
25
|
+
index: number;
|
|
26
|
+
}
|
|
27
|
+
export type RouteHandlerArgumentType = 'request' | 'response' | 'body' | 'query' | 'param' | 'headers' | 'session' | 'fields' | 'field' | 'files' | 'file' | 'host' | 'ip' | 'rawBody' | 'string' | 'user';
|
|
28
|
+
export declare const SymbolRouteHandlersArgumentsMeta: unique symbol;
|
|
29
|
+
export declare const SymbolRouteHandlersArgumentsValue: unique symbol;
|
|
30
|
+
export type TypeExtractValue = (ctx: VonaContext, argMeta: RouteHandlerArgumentMetaDecorator) => Promise<any>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export const SymbolDecoratorRule = Symbol('SymbolDecoratorRule');
|
|
2
|
+
export const SymbolDecoratorRuleColumn = Symbol('SymbolDecoratorRuleColumn');
|
|
3
|
+
export const SymbolRouteHandlersArgumentsMeta = Symbol('SymbolRouteHandlersArgumentsMeta');
|
|
4
|
+
export const SymbolRouteHandlersArgumentsValue = Symbol('SymbolRouteHandlersArgumentsValue');
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ZodOpenAPIMetadata } from '@asteasolutions/zod-to-openapi';
|
|
2
|
+
import type { CurrencyOptions } from '@zhennann/currency';
|
|
3
|
+
import type { z, ZodTypeAny } from 'zod';
|
|
4
|
+
import type { TypeResourceActionRowRecordRender } from './actions.ts';
|
|
5
|
+
import type { IOpenApiOptions } from './api.ts';
|
|
6
|
+
import type { IComponentRecord } from './component.ts';
|
|
7
|
+
import 'openapi3-ts/oas30';
|
|
8
|
+
import 'openapi3-ts/oas31';
|
|
9
|
+
export interface ISchemaObjectExtensionFieldRest {
|
|
10
|
+
render?: TypeFieldRenderComponent;
|
|
11
|
+
currency?: CurrencyOptions | boolean;
|
|
12
|
+
visible?: boolean;
|
|
13
|
+
order?: number;
|
|
14
|
+
table?: Omit<ISchemaObjectExtensionFieldRest, 'table' | 'form'>;
|
|
15
|
+
form?: Omit<ISchemaObjectExtensionFieldRest, 'table' | 'form'>;
|
|
16
|
+
}
|
|
17
|
+
export interface ISchemaObjectExtensionField {
|
|
18
|
+
rest?: ISchemaObjectExtensionFieldRest;
|
|
19
|
+
}
|
|
20
|
+
declare module 'openapi3-ts/oas30' {
|
|
21
|
+
interface SchemaObject extends ISchemaObjectExtensionField {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
declare module 'openapi3-ts/oas31' {
|
|
25
|
+
interface SchemaObject extends ISchemaObjectExtensionField {
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export type TypeFieldRenderComponent = (keyof IComponentRecord) | (keyof TypeResourceActionRowRecordRender) | 'text' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'switch' | 'image' | 'file' | 'color' | 'password' | 'email' | 'url';
|
|
29
|
+
export type TypeFieldRenderComponentProvider = (keyof IComponentRecord) | (keyof TypeResourceActionRowRecordRender) | 'input' | 'textarea' | 'select';
|
|
30
|
+
export type TypeSchemaScene = 'table' | 'form';
|
|
31
|
+
export type TypeOpenAPIMetadata<T extends ZodTypeAny = ZodTypeAny> = Partial<ZodOpenAPIMetadata<z.input<T>>>;
|
|
32
|
+
export type TypeEntityOptionsFields<T extends {}, More extends string | undefined = never> = {
|
|
33
|
+
[key in ((keyof Omit<T, '$column' | '$columns' | '$table'>) | (More extends string ? More : never))]?: TypeOpenAPIMetadata | z.ZodSchema;
|
|
34
|
+
};
|
|
35
|
+
export type TypeControllerOptionsActions<T extends {}> = {
|
|
36
|
+
[key in (keyof T)]?: IOpenApiOptions;
|
|
37
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona-module-a-openapi",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.12",
|
|
5
5
|
"title": "a-openapi",
|
|
6
6
|
"vonaModule": {
|
|
7
7
|
"capabilities": {
|
|
@@ -34,15 +34,19 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@asteasolutions/zod-to-openapi": "^7.3.0",
|
|
37
|
-
"@cabloy/zod-errors-custom": "^1.0.
|
|
38
|
-
"@cabloy/zod-query": "^1.0.
|
|
37
|
+
"@cabloy/zod-errors-custom": "^1.0.13",
|
|
38
|
+
"@cabloy/zod-query": "^1.0.14",
|
|
39
39
|
"@zhennann/currency": "^2.0.0",
|
|
40
40
|
"openapi3-ts": "^4.4.0",
|
|
41
41
|
"zod": "^3.23.8"
|
|
42
42
|
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"clean-package": "^2.2.0",
|
|
45
|
+
"rimraf": "^6.0.1"
|
|
46
|
+
},
|
|
43
47
|
"gitHead": "0eab9dc4a5622caffe89e7b1b3f02c08ccbc4c4b",
|
|
44
48
|
"scripts": {
|
|
45
|
-
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
46
|
-
"tsc:publish": "npm run clean && tsc"
|
|
49
|
+
"clean": "rimraf dist tsconfig.build.tsbuildinfo",
|
|
50
|
+
"tsc:publish": "npm run clean && tsc -p tsconfig.build.json"
|
|
47
51
|
}
|
|
48
52
|
}
|