nestjs-openapi-next 1.0.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/LICENSE +21 -0
- package/README.md +211 -0
- package/bun.lock +2154 -0
- package/dist/constants.d.ts +23 -0
- package/dist/constants.js +26 -0
- package/dist/decorators/api-basic.decorator.d.ts +1 -0
- package/dist/decorators/api-basic.decorator.js +7 -0
- package/dist/decorators/api-bearer.decorator.d.ts +1 -0
- package/dist/decorators/api-bearer.decorator.js +7 -0
- package/dist/decorators/api-body.decorator.d.ts +16 -0
- package/dist/decorators/api-body.decorator.js +22 -0
- package/dist/decorators/api-callbacks.decorator.d.ts +2 -0
- package/dist/decorators/api-callbacks.decorator.js +8 -0
- package/dist/decorators/api-consumes.decorator.d.ts +1 -0
- package/dist/decorators/api-consumes.decorator.js +8 -0
- package/dist/decorators/api-cookie.decorator.d.ts +1 -0
- package/dist/decorators/api-cookie.decorator.js +7 -0
- package/dist/decorators/api-default-getter.decorator.d.ts +2 -0
- package/dist/decorators/api-default-getter.decorator.js +12 -0
- package/dist/decorators/api-exclude-controller.decorator.d.ts +1 -0
- package/dist/decorators/api-exclude-controller.decorator.js +8 -0
- package/dist/decorators/api-exclude-endpoint.decorator.d.ts +1 -0
- package/dist/decorators/api-exclude-endpoint.decorator.js +10 -0
- package/dist/decorators/api-extension.decorator.d.ts +1 -0
- package/dist/decorators/api-extension.decorator.js +38 -0
- package/dist/decorators/api-extra-models.decorator.d.ts +1 -0
- package/dist/decorators/api-extra-models.decorator.js +17 -0
- package/dist/decorators/api-header.decorator.d.ts +7 -0
- package/dist/decorators/api-header.decorator.js +37 -0
- package/dist/decorators/api-hide-property.decorator.d.ts +1 -0
- package/dist/decorators/api-hide-property.decorator.js +6 -0
- package/dist/decorators/api-link.decorator.d.ts +7 -0
- package/dist/decorators/api-link.decorator.js +21 -0
- package/dist/decorators/api-oauth2.decorator.d.ts +1 -0
- package/dist/decorators/api-oauth2.decorator.js +7 -0
- package/dist/decorators/api-operation.decorator.d.ts +5 -0
- package/dist/decorators/api-operation.decorator.js +12 -0
- package/dist/decorators/api-param.decorator.d.ts +22 -0
- package/dist/decorators/api-param.decorator.js +17 -0
- package/dist/decorators/api-produces.decorator.d.ts +1 -0
- package/dist/decorators/api-produces.decorator.js +8 -0
- package/dist/decorators/api-property.decorator.d.ts +15 -0
- package/dist/decorators/api-property.decorator.js +48 -0
- package/dist/decorators/api-query-method.decorator.d.ts +1 -0
- package/dist/decorators/api-query-method.decorator.js +8 -0
- package/dist/decorators/api-query.decorator.d.ts +24 -0
- package/dist/decorators/api-query.decorator.js +25 -0
- package/dist/decorators/api-response.decorator.d.ts +39 -0
- package/dist/decorators/api-response.decorator.js +55 -0
- package/dist/decorators/api-schema.decorator.d.ts +6 -0
- package/dist/decorators/api-schema.decorator.js +8 -0
- package/dist/decorators/api-security-device-flow.decorator.d.ts +1 -0
- package/dist/decorators/api-security-device-flow.decorator.js +7 -0
- package/dist/decorators/api-security.decorator.d.ts +2 -0
- package/dist/decorators/api-security.decorator.js +25 -0
- package/dist/decorators/api-streaming-response.decorator.d.ts +7 -0
- package/dist/decorators/api-streaming-response.decorator.js +9 -0
- package/dist/decorators/api-tag-group.decorator.d.ts +11 -0
- package/dist/decorators/api-tag-group.decorator.js +13 -0
- package/dist/decorators/api-use-tags.decorator.d.ts +1 -0
- package/dist/decorators/api-use-tags.decorator.js +8 -0
- package/dist/decorators/helpers.d.ts +8 -0
- package/dist/decorators/helpers.js +123 -0
- package/dist/decorators/index.d.ts +28 -0
- package/dist/decorators/index.js +48 -0
- package/dist/document-builder.d.ts +29 -0
- package/dist/document-builder.js +142 -0
- package/dist/explorers/api-callbacks.explorer.d.ts +2 -0
- package/dist/explorers/api-callbacks.explorer.js +36 -0
- package/dist/explorers/api-consumes.explorer.d.ts +5 -0
- package/dist/explorers/api-consumes.explorer.js +11 -0
- package/dist/explorers/api-exclude-controller.explorer.d.ts +2 -0
- package/dist/explorers/api-exclude-controller.explorer.js +10 -0
- package/dist/explorers/api-exclude-endpoint.explorer.d.ts +2 -0
- package/dist/explorers/api-exclude-endpoint.explorer.js +6 -0
- package/dist/explorers/api-extra-models.explorer.d.ts +3 -0
- package/dist/explorers/api-extra-models.explorer.js +11 -0
- package/dist/explorers/api-headers.explorer.d.ts +7 -0
- package/dist/explorers/api-headers.explorer.js +9 -0
- package/dist/explorers/api-operation.explorer.d.ts +2 -0
- package/dist/explorers/api-operation.explorer.js +43 -0
- package/dist/explorers/api-parameters.explorer.d.ts +71 -0
- package/dist/explorers/api-parameters.explorer.js +47 -0
- package/dist/explorers/api-produces.explorer.d.ts +5 -0
- package/dist/explorers/api-produces.explorer.js +11 -0
- package/dist/explorers/api-response.explorer.d.ts +13 -0
- package/dist/explorers/api-response.explorer.js +103 -0
- package/dist/explorers/api-security.explorer.d.ts +5 -0
- package/dist/explorers/api-security.explorer.js +13 -0
- package/dist/explorers/api-use-tags.explorer.d.ts +5 -0
- package/dist/explorers/api-use-tags.explorer.js +18 -0
- package/dist/extra/swagger-shim.d.ts +100 -0
- package/dist/extra/swagger-shim.js +367 -0
- package/dist/fixtures/document.base.d.ts +2 -0
- package/dist/fixtures/document.base.js +16 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +23 -0
- package/dist/interfaces/callback-object.interface.d.ts +12 -0
- package/dist/interfaces/callback-object.interface.js +2 -0
- package/dist/interfaces/denormalized-doc-resolvers.interface.d.ts +7 -0
- package/dist/interfaces/denormalized-doc-resolvers.interface.js +2 -0
- package/dist/interfaces/denormalized-doc.interface.d.ts +8 -0
- package/dist/interfaces/denormalized-doc.interface.js +2 -0
- package/dist/interfaces/enum-schema-attributes.interface.d.ts +2 -0
- package/dist/interfaces/enum-schema-attributes.interface.js +2 -0
- package/dist/interfaces/index.d.ts +3 -0
- package/dist/interfaces/index.js +18 -0
- package/dist/interfaces/module-route.interface.d.ts +2 -0
- package/dist/interfaces/module-route.interface.js +2 -0
- package/dist/interfaces/open-api-spec.interface.d.ts +252 -0
- package/dist/interfaces/open-api-spec.interface.js +2 -0
- package/dist/interfaces/schema-object-metadata.interface.d.ts +30 -0
- package/dist/interfaces/schema-object-metadata.interface.js +2 -0
- package/dist/interfaces/swagger-custom-options.interface.d.ts +24 -0
- package/dist/interfaces/swagger-custom-options.interface.js +2 -0
- package/dist/interfaces/swagger-document-options.interface.d.ts +10 -0
- package/dist/interfaces/swagger-document-options.interface.js +2 -0
- package/dist/interfaces/swagger-ui-init-options.interface.d.ts +7 -0
- package/dist/interfaces/swagger-ui-init-options.interface.js +2 -0
- package/dist/interfaces/swagger-ui-options.interface.d.ts +15 -0
- package/dist/interfaces/swagger-ui-options.interface.js +2 -0
- package/dist/plugin/compiler-plugin.d.ts +2 -0
- package/dist/plugin/compiler-plugin.js +30 -0
- package/dist/plugin/index.d.ts +2 -0
- package/dist/plugin/index.js +18 -0
- package/dist/plugin/merge-options.d.ts +17 -0
- package/dist/plugin/merge-options.js +37 -0
- package/dist/plugin/metadata-loader.d.ts +7 -0
- package/dist/plugin/metadata-loader.js +51 -0
- package/dist/plugin/plugin-constants.d.ts +3 -0
- package/dist/plugin/plugin-constants.js +6 -0
- package/dist/plugin/plugin-debug-logger.d.ts +5 -0
- package/dist/plugin/plugin-debug-logger.js +7 -0
- package/dist/plugin/utils/ast-utils.d.ts +30 -0
- package/dist/plugin/utils/ast-utils.js +273 -0
- package/dist/plugin/utils/is-filename-matched.util.d.ts +1 -0
- package/dist/plugin/utils/is-filename-matched.util.js +5 -0
- package/dist/plugin/utils/plugin-utils.d.ts +30 -0
- package/dist/plugin/utils/plugin-utils.js +307 -0
- package/dist/plugin/utils/type-reference-to-identifier.util.d.ts +7 -0
- package/dist/plugin/utils/type-reference-to-identifier.util.js +52 -0
- package/dist/plugin/visitors/abstract.visitor.d.ts +4 -0
- package/dist/plugin/visitors/abstract.visitor.js +30 -0
- package/dist/plugin/visitors/controller-class.visitor.d.ts +20 -0
- package/dist/plugin/visitors/controller-class.visitor.js +265 -0
- package/dist/plugin/visitors/model-class.visitor.d.ts +35 -0
- package/dist/plugin/visitors/model-class.visitor.js +514 -0
- package/dist/plugin/visitors/readonly.visitor.d.ts +21 -0
- package/dist/plugin/visitors/readonly.visitor.js +40 -0
- package/dist/services/constants.d.ts +1 -0
- package/dist/services/constants.js +4 -0
- package/dist/services/decorators-properties.d.ts +21 -0
- package/dist/services/decorators-properties.js +149 -0
- package/dist/services/mimetype-content-wrapper.d.ts +4 -0
- package/dist/services/mimetype-content-wrapper.js +11 -0
- package/dist/services/model-properties-accessor.d.ts +6 -0
- package/dist/services/model-properties-accessor.js +37 -0
- package/dist/services/parameter-metadata-accessor.d.ts +22 -0
- package/dist/services/parameter-metadata-accessor.js +41 -0
- package/dist/services/parameters-metadata-mapper.d.ts +9 -0
- package/dist/services/parameters-metadata-mapper.js +38 -0
- package/dist/services/response-object-factory.d.ts +28 -0
- package/dist/services/response-object-factory.js +120 -0
- package/dist/services/response-object-mapper.d.ts +39 -0
- package/dist/services/response-object-mapper.js +38 -0
- package/dist/services/schema-object-factory.d.ts +156 -0
- package/dist/services/schema-object-factory.js +471 -0
- package/dist/services/swagger-types-mapper.d.ts +260 -0
- package/dist/services/swagger-types-mapper.js +107 -0
- package/dist/storages/global-parameters.storage.d.ts +8 -0
- package/dist/storages/global-parameters.storage.js +22 -0
- package/dist/storages/global-responses.storage.d.ts +10 -0
- package/dist/storages/global-responses.storage.js +21 -0
- package/dist/swagger-explorer.d.ts +41 -0
- package/dist/swagger-explorer.js +326 -0
- package/dist/swagger-module.d.ts +27 -0
- package/dist/swagger-module.js +223 -0
- package/dist/swagger-scanner.d.ts +25 -0
- package/dist/swagger-scanner.js +116 -0
- package/dist/swagger-transformer.d.ts +4 -0
- package/dist/swagger-transformer.js +22 -0
- package/dist/swagger-ui/constants.d.ts +3 -0
- package/dist/swagger-ui/constants.js +132 -0
- package/dist/swagger-ui/helpers.d.ts +2 -0
- package/dist/swagger-ui/helpers.js +16 -0
- package/dist/swagger-ui/index.d.ts +1 -0
- package/dist/swagger-ui/index.js +17 -0
- package/dist/swagger-ui/swagger-ui.d.ts +4 -0
- package/dist/swagger-ui/swagger-ui.js +62 -0
- package/dist/type-helpers/index.d.ts +4 -0
- package/dist/type-helpers/index.js +20 -0
- package/dist/type-helpers/intersection-type.helper.d.ts +8 -0
- package/dist/type-helpers/intersection-type.helper.js +42 -0
- package/dist/type-helpers/mapped-types.utils.d.ts +2 -0
- package/dist/type-helpers/mapped-types.utils.js +31 -0
- package/dist/type-helpers/omit-type.helper.d.ts +2 -0
- package/dist/type-helpers/omit-type.helper.js +40 -0
- package/dist/type-helpers/partial-type.helper.d.ts +4 -0
- package/dist/type-helpers/partial-type.helper.js +49 -0
- package/dist/type-helpers/pick-type.helper.d.ts +2 -0
- package/dist/type-helpers/pick-type.helper.js +40 -0
- package/dist/types/swagger-enum.type.d.ts +1 -0
- package/dist/types/swagger-enum.type.js +2 -0
- package/dist/utils/assign-two-levels-deep.d.ts +1 -0
- package/dist/utils/assign-two-levels-deep.js +12 -0
- package/dist/utils/enum.utils.d.ts +9 -0
- package/dist/utils/enum.utils.js +65 -0
- package/dist/utils/extend-metadata.util.d.ts +2 -0
- package/dist/utils/extend-metadata.util.js +11 -0
- package/dist/utils/get-global-prefix.d.ts +2 -0
- package/dist/utils/get-global-prefix.js +7 -0
- package/dist/utils/get-schema-path.util.d.ts +4 -0
- package/dist/utils/get-schema-path.util.js +26 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +17 -0
- package/dist/utils/is-body-parameter.util.d.ts +2 -0
- package/dist/utils/is-body-parameter.util.js +6 -0
- package/dist/utils/is-built-in-type.util.d.ts +2 -0
- package/dist/utils/is-built-in-type.util.js +8 -0
- package/dist/utils/is-date-ctor.util.d.ts +2 -0
- package/dist/utils/is-date-ctor.util.js +6 -0
- package/dist/utils/merge-and-uniq.util.d.ts +1 -0
- package/dist/utils/merge-and-uniq.util.js +7 -0
- package/dist/utils/normalize-rel-path.d.ts +1 -0
- package/dist/utils/normalize-rel-path.js +7 -0
- package/dist/utils/remove-undefined-keys.d.ts +5 -0
- package/dist/utils/remove-undefined-keys.js +11 -0
- package/dist/utils/resolve-path.util.d.ts +1 -0
- package/dist/utils/resolve-path.util.js +7 -0
- package/dist/utils/reverse-object-keys.util.d.ts +1 -0
- package/dist/utils/reverse-object-keys.util.js +11 -0
- package/dist/utils/sort-object-lexicographically.d.ts +5 -0
- package/dist/utils/sort-object-lexicographically.js +11 -0
- package/dist/utils/strip-last-slash.util.d.ts +1 -0
- package/dist/utils/strip-last-slash.util.js +8 -0
- package/dist/utils/validate-global-prefix.util.d.ts +1 -0
- package/dist/utils/validate-global-prefix.util.js +5 -0
- package/dist/utils/validate-path.util.d.ts +1 -0
- package/dist/utils/validate-path.util.js +5 -0
- package/eslint.config.mjs +47 -0
- package/nest-cli.json +6 -0
- package/package.json +116 -0
- package/plugin.js +10 -0
- package/tsconfig.build.json +21 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractFileVisitor = void 0;
|
|
4
|
+
const ts = require("typescript");
|
|
5
|
+
const plugin_constants_1 = require("../plugin-constants");
|
|
6
|
+
const [major, minor] = ts.versionMajorMinor.split('.').map((x) => +x);
|
|
7
|
+
class AbstractFileVisitor {
|
|
8
|
+
updateImports(sourceFile, factory, program) {
|
|
9
|
+
if (major <= 4 && minor < 8) {
|
|
10
|
+
throw new Error('Nest CLI plugin does not support TypeScript < v4.8');
|
|
11
|
+
}
|
|
12
|
+
const importEqualsDeclaration = factory.createImportEqualsDeclaration(undefined, false, factory.createIdentifier(plugin_constants_1.OPENAPI_NAMESPACE), factory.createExternalModuleReference(factory.createStringLiteral(plugin_constants_1.OPENAPI_PACKAGE_NAME)));
|
|
13
|
+
const compilerOptions = program.getCompilerOptions();
|
|
14
|
+
if (compilerOptions.module >= ts.ModuleKind.ES2015 &&
|
|
15
|
+
compilerOptions.module <= ts.ModuleKind.ESNext) {
|
|
16
|
+
const importAsDeclaration = factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamespaceImport(factory.createIdentifier(plugin_constants_1.OPENAPI_NAMESPACE))), factory.createStringLiteral(plugin_constants_1.OPENAPI_PACKAGE_NAME), undefined);
|
|
17
|
+
return factory.updateSourceFile(sourceFile, [
|
|
18
|
+
importAsDeclaration,
|
|
19
|
+
...sourceFile.statements
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return factory.updateSourceFile(sourceFile, [
|
|
24
|
+
importEqualsDeclaration,
|
|
25
|
+
...sourceFile.statements
|
|
26
|
+
]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.AbstractFileVisitor = AbstractFileVisitor;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { PluginOptions } from '../merge-options';
|
|
3
|
+
import { AbstractFileVisitor } from './abstract.visitor';
|
|
4
|
+
type ClassMetadata = Record<string, ts.ObjectLiteralExpression>;
|
|
5
|
+
export declare class ControllerClassVisitor extends AbstractFileVisitor {
|
|
6
|
+
private readonly _collectedMetadata;
|
|
7
|
+
private readonly _typeImports;
|
|
8
|
+
get typeImports(): Record<string, string>;
|
|
9
|
+
collectedMetadata(options: PluginOptions): Array<[ts.CallExpression, Record<string, ClassMetadata>]>;
|
|
10
|
+
visit(sourceFile: ts.SourceFile, ctx: ts.TransformationContext, program: ts.Program, options: PluginOptions): ts.Node;
|
|
11
|
+
addDecoratorToNode(factory: ts.NodeFactory, compilerNode: ts.MethodDeclaration, typeChecker: ts.TypeChecker, options: PluginOptions, sourceFile: ts.SourceFile, metadata: ClassMetadata): ts.MethodDeclaration;
|
|
12
|
+
createApiOperationDecorator(factory: ts.NodeFactory, node: ts.MethodDeclaration, decorators: readonly ts.Decorator[], options: PluginOptions, sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, metadata: ClassMetadata): ts.Decorator[];
|
|
13
|
+
createApiResponseDecorator(factory: ts.NodeFactory, node: ts.MethodDeclaration, options: PluginOptions, metadata: ClassMetadata): ts.Decorator[];
|
|
14
|
+
createDecoratorObjectLiteralExpr(factory: ts.NodeFactory, node: ts.MethodDeclaration, typeChecker: ts.TypeChecker, existingProperties: ts.NodeArray<ts.PropertyAssignment>, hostFilename: string, metadata: ClassMetadata, options: PluginOptions): ts.ObjectLiteralExpression;
|
|
15
|
+
createTypePropertyAssignment(factory: ts.NodeFactory, node: ts.MethodDeclaration, typeChecker: ts.TypeChecker, existingProperties: ts.NodeArray<ts.PropertyAssignment>, hostFilename: string, options: PluginOptions): ts.PropertyAssignment;
|
|
16
|
+
createStatusPropertyAssignment(factory: ts.NodeFactory, node: ts.MethodDeclaration, existingProperties: ts.NodeArray<ts.PropertyAssignment>): ts.PropertyAssignment;
|
|
17
|
+
getStatusCodeIdentifier(factory: ts.NodeFactory, node: ts.MethodDeclaration): any;
|
|
18
|
+
private normalizeImportPath;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ControllerClassVisitor = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const ts = require("typescript");
|
|
7
|
+
const decorators_1 = require("../../decorators");
|
|
8
|
+
const plugin_constants_1 = require("../plugin-constants");
|
|
9
|
+
const ast_utils_1 = require("../utils/ast-utils");
|
|
10
|
+
const plugin_utils_1 = require("../utils/plugin-utils");
|
|
11
|
+
const type_reference_to_identifier_util_1 = require("../utils/type-reference-to-identifier.util");
|
|
12
|
+
const abstract_visitor_1 = require("./abstract.visitor");
|
|
13
|
+
class ControllerClassVisitor extends abstract_visitor_1.AbstractFileVisitor {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this._collectedMetadata = {};
|
|
17
|
+
this._typeImports = {};
|
|
18
|
+
}
|
|
19
|
+
get typeImports() {
|
|
20
|
+
return this._typeImports;
|
|
21
|
+
}
|
|
22
|
+
collectedMetadata(options) {
|
|
23
|
+
const metadataWithImports = [];
|
|
24
|
+
Object.keys(this._collectedMetadata).forEach((filePath) => {
|
|
25
|
+
const metadata = this._collectedMetadata[filePath];
|
|
26
|
+
const fileExt = options.esmCompatible ? (0, plugin_utils_1.getOutputExtension)(filePath) : '';
|
|
27
|
+
const path = filePath.replace(/\.[jt]s$/, fileExt);
|
|
28
|
+
const importExpr = ts.factory.createCallExpression(ts.factory.createToken(ts.SyntaxKind.ImportKeyword), undefined, [ts.factory.createStringLiteral(path)]);
|
|
29
|
+
metadataWithImports.push([importExpr, metadata]);
|
|
30
|
+
});
|
|
31
|
+
return metadataWithImports;
|
|
32
|
+
}
|
|
33
|
+
visit(sourceFile, ctx, program, options) {
|
|
34
|
+
const typeChecker = program.getTypeChecker();
|
|
35
|
+
if (!options.readonly) {
|
|
36
|
+
sourceFile = this.updateImports(sourceFile, ctx.factory, program);
|
|
37
|
+
}
|
|
38
|
+
const visitNode = (node) => {
|
|
39
|
+
var _a;
|
|
40
|
+
if (ts.isMethodDeclaration(node)) {
|
|
41
|
+
try {
|
|
42
|
+
const metadata = {};
|
|
43
|
+
const updatedNode = this.addDecoratorToNode(ctx.factory, node, typeChecker, options, sourceFile, metadata);
|
|
44
|
+
if (!options.readonly) {
|
|
45
|
+
return updatedNode;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const filePath = this.normalizeImportPath(options.pathToSource, sourceFile.fileName);
|
|
49
|
+
if (!this._collectedMetadata[filePath]) {
|
|
50
|
+
this._collectedMetadata[filePath] = {};
|
|
51
|
+
}
|
|
52
|
+
const parent = node.parent;
|
|
53
|
+
const clsName = (_a = parent.name) === null || _a === void 0 ? void 0 : _a.getText();
|
|
54
|
+
if (clsName) {
|
|
55
|
+
if (!this._collectedMetadata[filePath][clsName]) {
|
|
56
|
+
this._collectedMetadata[filePath][clsName] = {};
|
|
57
|
+
}
|
|
58
|
+
Object.assign(this._collectedMetadata[filePath][clsName], metadata);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (_b) {
|
|
63
|
+
if (!options.readonly) {
|
|
64
|
+
return node;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (options.readonly) {
|
|
69
|
+
ts.forEachChild(node, visitNode);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return ts.visitEachChild(node, visitNode, ctx);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
return ts.visitNode(sourceFile, visitNode);
|
|
76
|
+
}
|
|
77
|
+
addDecoratorToNode(factory, compilerNode, typeChecker, options, sourceFile, metadata) {
|
|
78
|
+
var _a;
|
|
79
|
+
const hostFilename = sourceFile.fileName;
|
|
80
|
+
const decorators = ts.canHaveDecorators(compilerNode) && ts.getDecorators(compilerNode);
|
|
81
|
+
if (!decorators) {
|
|
82
|
+
return compilerNode;
|
|
83
|
+
}
|
|
84
|
+
const apiOperationDecoratorsArray = this.createApiOperationDecorator(factory, compilerNode, decorators, options, sourceFile, typeChecker, metadata);
|
|
85
|
+
const apiResponseDecoratorsArray = this.createApiResponseDecorator(factory, compilerNode, options, metadata);
|
|
86
|
+
const removeExistingApiOperationDecorator = apiOperationDecoratorsArray.length > 0;
|
|
87
|
+
const existingDecorators = removeExistingApiOperationDecorator
|
|
88
|
+
? decorators.filter((item) => (0, ast_utils_1.getDecoratorName)(item) !== decorators_1.ApiOperation.name)
|
|
89
|
+
: decorators;
|
|
90
|
+
const modifiers = (_a = ts.getModifiers(compilerNode)) !== null && _a !== void 0 ? _a : [];
|
|
91
|
+
const objectLiteralExpr = this.createDecoratorObjectLiteralExpr(factory, compilerNode, typeChecker, factory.createNodeArray(), hostFilename, metadata, options);
|
|
92
|
+
const updatedDecorators = [
|
|
93
|
+
...apiOperationDecoratorsArray,
|
|
94
|
+
...apiResponseDecoratorsArray,
|
|
95
|
+
...existingDecorators,
|
|
96
|
+
factory.createDecorator(factory.createCallExpression(factory.createIdentifier(`${plugin_constants_1.OPENAPI_NAMESPACE}.${decorators_1.ApiResponse.name}`), undefined, [factory.createObjectLiteralExpression(objectLiteralExpr.properties)]))
|
|
97
|
+
];
|
|
98
|
+
if (!options.readonly) {
|
|
99
|
+
return factory.updateMethodDeclaration(compilerNode, [...updatedDecorators, ...modifiers], compilerNode.asteriskToken, compilerNode.name, compilerNode.questionToken, compilerNode.typeParameters, compilerNode.parameters, compilerNode.type, compilerNode.body);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
return compilerNode;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
createApiOperationDecorator(factory, node, decorators, options, sourceFile, typeChecker, metadata) {
|
|
106
|
+
if (!options.introspectComments) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
const apiOperationDecorator = (0, plugin_utils_1.getDecoratorOrUndefinedByNames)([decorators_1.ApiOperation.name], decorators, factory);
|
|
110
|
+
let apiOperationExistingProps = undefined;
|
|
111
|
+
if (apiOperationDecorator && !options.readonly) {
|
|
112
|
+
const apiOperationExpr = (0, lodash_1.head)((0, ast_utils_1.getDecoratorArguments)(apiOperationDecorator));
|
|
113
|
+
if (apiOperationExpr) {
|
|
114
|
+
apiOperationExistingProps =
|
|
115
|
+
apiOperationExpr.properties;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const extractedComments = (0, ast_utils_1.getMainCommentOfNode)(node);
|
|
119
|
+
if (!extractedComments) {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
const properties = [
|
|
123
|
+
...(apiOperationExistingProps !== null && apiOperationExistingProps !== void 0 ? apiOperationExistingProps : factory.createNodeArray())
|
|
124
|
+
];
|
|
125
|
+
const tags = (0, ast_utils_1.getTsDocTagsOfNode)(node, typeChecker);
|
|
126
|
+
const hasRemarksKey = (0, plugin_utils_1.hasPropertyKey)('description', factory.createNodeArray(apiOperationExistingProps));
|
|
127
|
+
if (!hasRemarksKey && tags.remarks) {
|
|
128
|
+
const remarksPropertyAssignment = factory.createPropertyAssignment('description', (0, ast_utils_1.createLiteralFromAnyValue)(factory, tags.remarks));
|
|
129
|
+
properties.push(remarksPropertyAssignment);
|
|
130
|
+
if (options.controllerKeyOfComment === 'description') {
|
|
131
|
+
properties.unshift(factory.createPropertyAssignment('summary', factory.createStringLiteral(extractedComments)));
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const keyToGenerate = options.controllerKeyOfComment;
|
|
135
|
+
properties.unshift(factory.createPropertyAssignment(keyToGenerate, factory.createStringLiteral(extractedComments)));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const keyToGenerate = options.controllerKeyOfComment;
|
|
140
|
+
properties.unshift(factory.createPropertyAssignment(keyToGenerate, factory.createStringLiteral(extractedComments)));
|
|
141
|
+
}
|
|
142
|
+
const hasDeprecatedKey = (0, plugin_utils_1.hasPropertyKey)('deprecated', factory.createNodeArray(apiOperationExistingProps));
|
|
143
|
+
if (!hasDeprecatedKey && tags.deprecated) {
|
|
144
|
+
const deprecatedPropertyAssignment = factory.createPropertyAssignment('deprecated', (0, ast_utils_1.createLiteralFromAnyValue)(factory, tags.deprecated));
|
|
145
|
+
properties.push(deprecatedPropertyAssignment);
|
|
146
|
+
}
|
|
147
|
+
const objectLiteralExpr = factory.createObjectLiteralExpression((0, lodash_1.compact)(properties));
|
|
148
|
+
const apiOperationDecoratorArguments = factory.createNodeArray([objectLiteralExpr]);
|
|
149
|
+
const methodKey = node.name.getText();
|
|
150
|
+
if (metadata[methodKey]) {
|
|
151
|
+
const existingObjectLiteralExpr = metadata[methodKey];
|
|
152
|
+
const existingProperties = existingObjectLiteralExpr.properties;
|
|
153
|
+
const updatedProperties = factory.createNodeArray([
|
|
154
|
+
...existingProperties,
|
|
155
|
+
...(0, lodash_1.compact)(properties)
|
|
156
|
+
]);
|
|
157
|
+
const updatedObjectLiteralExpr = factory.createObjectLiteralExpression(updatedProperties);
|
|
158
|
+
metadata[methodKey] = updatedObjectLiteralExpr;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
metadata[methodKey] = objectLiteralExpr;
|
|
162
|
+
}
|
|
163
|
+
if (apiOperationDecorator) {
|
|
164
|
+
const expr = apiOperationDecorator.expression;
|
|
165
|
+
const updatedCallExpr = factory.updateCallExpression(expr, expr.expression, undefined, apiOperationDecoratorArguments);
|
|
166
|
+
return [factory.updateDecorator(apiOperationDecorator, updatedCallExpr)];
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
return [
|
|
170
|
+
factory.createDecorator(factory.createCallExpression(factory.createIdentifier(`${plugin_constants_1.OPENAPI_NAMESPACE}.${decorators_1.ApiOperation.name}`), undefined, apiOperationDecoratorArguments))
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
createApiResponseDecorator(factory, node, options, metadata) {
|
|
175
|
+
if (!options.introspectComments) {
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
const tags = (0, ast_utils_1.getTsDocErrorsOfNode)(node);
|
|
179
|
+
if (!tags.length) {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
return tags.map((tag) => {
|
|
183
|
+
const properties = [];
|
|
184
|
+
properties.push(factory.createPropertyAssignment('status', factory.createNumericLiteral(tag.status)));
|
|
185
|
+
properties.push(factory.createPropertyAssignment('description', factory.createNumericLiteral(tag.description)));
|
|
186
|
+
const objectLiteralExpr = factory.createObjectLiteralExpression((0, lodash_1.compact)(properties));
|
|
187
|
+
const methodKey = node.name.getText();
|
|
188
|
+
metadata[methodKey] = objectLiteralExpr;
|
|
189
|
+
const apiResponseDecoratorArguments = factory.createNodeArray([objectLiteralExpr]);
|
|
190
|
+
return factory.createDecorator(factory.createCallExpression(factory.createIdentifier(`${plugin_constants_1.OPENAPI_NAMESPACE}.${decorators_1.ApiResponse.name}`), undefined, apiResponseDecoratorArguments));
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
createDecoratorObjectLiteralExpr(factory, node, typeChecker, existingProperties = factory.createNodeArray(), hostFilename, metadata, options) {
|
|
194
|
+
let properties = [];
|
|
195
|
+
if (!options.readonly && !options.skipAutoHttpCode) {
|
|
196
|
+
properties = properties.concat(existingProperties, this.createStatusPropertyAssignment(factory, node, existingProperties));
|
|
197
|
+
}
|
|
198
|
+
properties = properties.concat([
|
|
199
|
+
this.createTypePropertyAssignment(factory, node, typeChecker, existingProperties, hostFilename, options)
|
|
200
|
+
]);
|
|
201
|
+
const objectLiteralExpr = factory.createObjectLiteralExpression((0, lodash_1.compact)(properties));
|
|
202
|
+
const methodKey = node.name.getText();
|
|
203
|
+
const existingExprOrUndefined = metadata[methodKey];
|
|
204
|
+
if (existingExprOrUndefined) {
|
|
205
|
+
const existingProperties = existingExprOrUndefined.properties;
|
|
206
|
+
const updatedProperties = factory.createNodeArray([
|
|
207
|
+
...existingProperties,
|
|
208
|
+
...(0, lodash_1.compact)(properties)
|
|
209
|
+
]);
|
|
210
|
+
const updatedObjectLiteralExpr = factory.createObjectLiteralExpression(updatedProperties);
|
|
211
|
+
metadata[methodKey] = updatedObjectLiteralExpr;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
metadata[methodKey] = objectLiteralExpr;
|
|
215
|
+
}
|
|
216
|
+
return objectLiteralExpr;
|
|
217
|
+
}
|
|
218
|
+
createTypePropertyAssignment(factory, node, typeChecker, existingProperties, hostFilename, options) {
|
|
219
|
+
if ((0, plugin_utils_1.hasPropertyKey)('type', existingProperties)) {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
const signature = typeChecker.getSignatureFromDeclaration(node);
|
|
223
|
+
const type = typeChecker.getReturnTypeOfSignature(signature);
|
|
224
|
+
if (!type) {
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
const typeReferenceDescriptor = (0, plugin_utils_1.getTypeReferenceAsString)(type, typeChecker);
|
|
228
|
+
if (!typeReferenceDescriptor.typeName) {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
if (typeReferenceDescriptor.typeName.includes('node_modules')) {
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
const identifier = (0, type_reference_to_identifier_util_1.typeReferenceToIdentifier)(typeReferenceDescriptor, hostFilename, options, factory, type, this._typeImports);
|
|
235
|
+
return factory.createPropertyAssignment('type', identifier);
|
|
236
|
+
}
|
|
237
|
+
createStatusPropertyAssignment(factory, node, existingProperties) {
|
|
238
|
+
if ((0, plugin_utils_1.hasPropertyKey)('status', existingProperties)) {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
const statusNode = this.getStatusCodeIdentifier(factory, node);
|
|
242
|
+
return factory.createPropertyAssignment('status', statusNode);
|
|
243
|
+
}
|
|
244
|
+
getStatusCodeIdentifier(factory, node) {
|
|
245
|
+
const decorators = ts.canHaveDecorators(node) && ts.getDecorators(node);
|
|
246
|
+
const httpCodeDecorator = (0, plugin_utils_1.getDecoratorOrUndefinedByNames)(['HttpCode'], decorators, factory);
|
|
247
|
+
if (httpCodeDecorator) {
|
|
248
|
+
const argument = (0, lodash_1.head)((0, ast_utils_1.getDecoratorArguments)(httpCodeDecorator));
|
|
249
|
+
if (argument) {
|
|
250
|
+
return argument;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const postDecorator = (0, plugin_utils_1.getDecoratorOrUndefinedByNames)(['Post'], decorators, factory);
|
|
254
|
+
if (postDecorator) {
|
|
255
|
+
return factory.createIdentifier('201');
|
|
256
|
+
}
|
|
257
|
+
return factory.createIdentifier('200');
|
|
258
|
+
}
|
|
259
|
+
normalizeImportPath(pathToSource, path) {
|
|
260
|
+
let relativePath = path_1.posix.relative((0, plugin_utils_1.convertPath)(pathToSource), (0, plugin_utils_1.convertPath)(path));
|
|
261
|
+
relativePath = relativePath[0] !== '.' ? './' + relativePath : relativePath;
|
|
262
|
+
return relativePath;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.ControllerClassVisitor = ControllerClassVisitor;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { PropertyAssignment } from 'typescript';
|
|
3
|
+
import { PluginOptions } from '../merge-options';
|
|
4
|
+
import { AbstractFileVisitor } from './abstract.visitor';
|
|
5
|
+
type ClassMetadata = Record<string, ts.ObjectLiteralExpression>;
|
|
6
|
+
export declare class ModelClassVisitor extends AbstractFileVisitor {
|
|
7
|
+
private readonly _typeImports;
|
|
8
|
+
private readonly _collectedMetadata;
|
|
9
|
+
get typeImports(): Record<string, string>;
|
|
10
|
+
collectedMetadata(options: PluginOptions): Array<[ts.CallExpression, Record<string, ClassMetadata>]>;
|
|
11
|
+
visit(sourceFile: ts.SourceFile, ctx: ts.TransformationContext, program: ts.Program, options: PluginOptions): ts.Node;
|
|
12
|
+
visitPropertyNodeDeclaration(node: ts.PropertyDeclaration, ctx: ts.TransformationContext, typeChecker: ts.TypeChecker, options: PluginOptions, sourceFile: ts.SourceFile, metadata: ClassMetadata): ts.PropertyDeclaration;
|
|
13
|
+
visitConstructorDeclarationNode(constructorNode: ts.ConstructorDeclaration, typeChecker: ts.TypeChecker, options: PluginOptions, sourceFile: ts.SourceFile, metadata: ClassMetadata): void;
|
|
14
|
+
addMetadataFactory(factory: ts.NodeFactory, node: ts.ClassDeclaration, classMetadata: ClassMetadata, sourceFile: ts.SourceFile, options: PluginOptions): ts.ClassDeclaration;
|
|
15
|
+
inspectPropertyDeclaration(factory: ts.NodeFactory, compilerNode: ts.PropertyDeclaration, typeChecker: ts.TypeChecker, options: PluginOptions, hostFilename: string, sourceFile: ts.SourceFile, metadata: ClassMetadata): void;
|
|
16
|
+
createDecoratorObjectLiteralExpr(factory: ts.NodeFactory, node: ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration, typeChecker: ts.TypeChecker, existingProperties?: ts.NodeArray<ts.PropertyAssignment>, options?: PluginOptions, hostFilename?: string, sourceFile?: ts.SourceFile): ts.ObjectLiteralExpression;
|
|
17
|
+
private createTypePropertyAssignments;
|
|
18
|
+
createInitializerForArrayLiteralTypeNode(node: ts.ArrayTypeNode, factory: ts.NodeFactory, typeChecker: ts.TypeChecker, existingProperties: ts.NodeArray<ts.PropertyAssignment>, hostFilename: string, options: PluginOptions): ts.ArrowFunction;
|
|
19
|
+
createInitializerForTypeLiteralNode(node: ts.TypeLiteralNode, factory: ts.NodeFactory, typeChecker: ts.TypeChecker, existingProperties: ts.NodeArray<ts.PropertyAssignment>, hostFilename: string, options: PluginOptions): ts.ArrowFunction;
|
|
20
|
+
isNullableUnion(node: ts.UnionTypeNode): {
|
|
21
|
+
nullableType: ts.TypeNode;
|
|
22
|
+
isNullable: boolean;
|
|
23
|
+
};
|
|
24
|
+
createEnumPropertyAssignment(factory: ts.NodeFactory, node: ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration, typeChecker: ts.TypeChecker, existingProperties: ts.NodeArray<ts.PropertyAssignment>, hostFilename: string, options: PluginOptions): ts.PropertyAssignment | ts.PropertyAssignment[];
|
|
25
|
+
createDefaultPropertyAssignment(factory: ts.NodeFactory, node: ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration, existingProperties: ts.NodeArray<ts.PropertyAssignment>, options: PluginOptions): ts.PropertyAssignment;
|
|
26
|
+
createValidationPropertyAssignments(factory: ts.NodeFactory, node: ts.PropertyDeclaration | ts.PropertySignature, options: PluginOptions): ts.PropertyAssignment[];
|
|
27
|
+
addPropertyByValidationDecorator(factory: ts.NodeFactory, decoratorName: string, propertyKey: string, decorators: readonly ts.Decorator[], assignments: ts.PropertyAssignment[], options: PluginOptions): void;
|
|
28
|
+
addPropertiesByValidationDecorator(factory: ts.NodeFactory, decoratorName: string, decorators: readonly ts.Decorator[], assignments: ts.PropertyAssignment[], addPropertyAssignments: (decoratorRef: ts.Decorator) => PropertyAssignment[]): void;
|
|
29
|
+
addClassMetadata(node: ts.PropertyDeclaration, objectLiteral: ts.ObjectLiteralExpression, sourceFile: ts.SourceFile, metadata: ClassMetadata): void;
|
|
30
|
+
createDescriptionAndTsDocTagPropertyAssignments(factory: ts.NodeFactory, node: ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration, typeChecker: ts.TypeChecker, existingProperties?: ts.NodeArray<ts.PropertyAssignment>, options?: PluginOptions, sourceFile?: ts.SourceFile): ts.PropertyAssignment[];
|
|
31
|
+
private normalizeImportPath;
|
|
32
|
+
private clonePrimitiveLiteral;
|
|
33
|
+
private getInitializerPrimitiveTypeName;
|
|
34
|
+
}
|
|
35
|
+
export {};
|