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.
Files changed (244) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -0
  3. package/bun.lock +2154 -0
  4. package/dist/constants.d.ts +23 -0
  5. package/dist/constants.js +26 -0
  6. package/dist/decorators/api-basic.decorator.d.ts +1 -0
  7. package/dist/decorators/api-basic.decorator.js +7 -0
  8. package/dist/decorators/api-bearer.decorator.d.ts +1 -0
  9. package/dist/decorators/api-bearer.decorator.js +7 -0
  10. package/dist/decorators/api-body.decorator.d.ts +16 -0
  11. package/dist/decorators/api-body.decorator.js +22 -0
  12. package/dist/decorators/api-callbacks.decorator.d.ts +2 -0
  13. package/dist/decorators/api-callbacks.decorator.js +8 -0
  14. package/dist/decorators/api-consumes.decorator.d.ts +1 -0
  15. package/dist/decorators/api-consumes.decorator.js +8 -0
  16. package/dist/decorators/api-cookie.decorator.d.ts +1 -0
  17. package/dist/decorators/api-cookie.decorator.js +7 -0
  18. package/dist/decorators/api-default-getter.decorator.d.ts +2 -0
  19. package/dist/decorators/api-default-getter.decorator.js +12 -0
  20. package/dist/decorators/api-exclude-controller.decorator.d.ts +1 -0
  21. package/dist/decorators/api-exclude-controller.decorator.js +8 -0
  22. package/dist/decorators/api-exclude-endpoint.decorator.d.ts +1 -0
  23. package/dist/decorators/api-exclude-endpoint.decorator.js +10 -0
  24. package/dist/decorators/api-extension.decorator.d.ts +1 -0
  25. package/dist/decorators/api-extension.decorator.js +38 -0
  26. package/dist/decorators/api-extra-models.decorator.d.ts +1 -0
  27. package/dist/decorators/api-extra-models.decorator.js +17 -0
  28. package/dist/decorators/api-header.decorator.d.ts +7 -0
  29. package/dist/decorators/api-header.decorator.js +37 -0
  30. package/dist/decorators/api-hide-property.decorator.d.ts +1 -0
  31. package/dist/decorators/api-hide-property.decorator.js +6 -0
  32. package/dist/decorators/api-link.decorator.d.ts +7 -0
  33. package/dist/decorators/api-link.decorator.js +21 -0
  34. package/dist/decorators/api-oauth2.decorator.d.ts +1 -0
  35. package/dist/decorators/api-oauth2.decorator.js +7 -0
  36. package/dist/decorators/api-operation.decorator.d.ts +5 -0
  37. package/dist/decorators/api-operation.decorator.js +12 -0
  38. package/dist/decorators/api-param.decorator.d.ts +22 -0
  39. package/dist/decorators/api-param.decorator.js +17 -0
  40. package/dist/decorators/api-produces.decorator.d.ts +1 -0
  41. package/dist/decorators/api-produces.decorator.js +8 -0
  42. package/dist/decorators/api-property.decorator.d.ts +15 -0
  43. package/dist/decorators/api-property.decorator.js +48 -0
  44. package/dist/decorators/api-query-method.decorator.d.ts +1 -0
  45. package/dist/decorators/api-query-method.decorator.js +8 -0
  46. package/dist/decorators/api-query.decorator.d.ts +24 -0
  47. package/dist/decorators/api-query.decorator.js +25 -0
  48. package/dist/decorators/api-response.decorator.d.ts +39 -0
  49. package/dist/decorators/api-response.decorator.js +55 -0
  50. package/dist/decorators/api-schema.decorator.d.ts +6 -0
  51. package/dist/decorators/api-schema.decorator.js +8 -0
  52. package/dist/decorators/api-security-device-flow.decorator.d.ts +1 -0
  53. package/dist/decorators/api-security-device-flow.decorator.js +7 -0
  54. package/dist/decorators/api-security.decorator.d.ts +2 -0
  55. package/dist/decorators/api-security.decorator.js +25 -0
  56. package/dist/decorators/api-streaming-response.decorator.d.ts +7 -0
  57. package/dist/decorators/api-streaming-response.decorator.js +9 -0
  58. package/dist/decorators/api-tag-group.decorator.d.ts +11 -0
  59. package/dist/decorators/api-tag-group.decorator.js +13 -0
  60. package/dist/decorators/api-use-tags.decorator.d.ts +1 -0
  61. package/dist/decorators/api-use-tags.decorator.js +8 -0
  62. package/dist/decorators/helpers.d.ts +8 -0
  63. package/dist/decorators/helpers.js +123 -0
  64. package/dist/decorators/index.d.ts +28 -0
  65. package/dist/decorators/index.js +48 -0
  66. package/dist/document-builder.d.ts +29 -0
  67. package/dist/document-builder.js +142 -0
  68. package/dist/explorers/api-callbacks.explorer.d.ts +2 -0
  69. package/dist/explorers/api-callbacks.explorer.js +36 -0
  70. package/dist/explorers/api-consumes.explorer.d.ts +5 -0
  71. package/dist/explorers/api-consumes.explorer.js +11 -0
  72. package/dist/explorers/api-exclude-controller.explorer.d.ts +2 -0
  73. package/dist/explorers/api-exclude-controller.explorer.js +10 -0
  74. package/dist/explorers/api-exclude-endpoint.explorer.d.ts +2 -0
  75. package/dist/explorers/api-exclude-endpoint.explorer.js +6 -0
  76. package/dist/explorers/api-extra-models.explorer.d.ts +3 -0
  77. package/dist/explorers/api-extra-models.explorer.js +11 -0
  78. package/dist/explorers/api-headers.explorer.d.ts +7 -0
  79. package/dist/explorers/api-headers.explorer.js +9 -0
  80. package/dist/explorers/api-operation.explorer.d.ts +2 -0
  81. package/dist/explorers/api-operation.explorer.js +43 -0
  82. package/dist/explorers/api-parameters.explorer.d.ts +71 -0
  83. package/dist/explorers/api-parameters.explorer.js +47 -0
  84. package/dist/explorers/api-produces.explorer.d.ts +5 -0
  85. package/dist/explorers/api-produces.explorer.js +11 -0
  86. package/dist/explorers/api-response.explorer.d.ts +13 -0
  87. package/dist/explorers/api-response.explorer.js +103 -0
  88. package/dist/explorers/api-security.explorer.d.ts +5 -0
  89. package/dist/explorers/api-security.explorer.js +13 -0
  90. package/dist/explorers/api-use-tags.explorer.d.ts +5 -0
  91. package/dist/explorers/api-use-tags.explorer.js +18 -0
  92. package/dist/extra/swagger-shim.d.ts +100 -0
  93. package/dist/extra/swagger-shim.js +367 -0
  94. package/dist/fixtures/document.base.d.ts +2 -0
  95. package/dist/fixtures/document.base.js +16 -0
  96. package/dist/index.d.ts +7 -0
  97. package/dist/index.js +23 -0
  98. package/dist/interfaces/callback-object.interface.d.ts +12 -0
  99. package/dist/interfaces/callback-object.interface.js +2 -0
  100. package/dist/interfaces/denormalized-doc-resolvers.interface.d.ts +7 -0
  101. package/dist/interfaces/denormalized-doc-resolvers.interface.js +2 -0
  102. package/dist/interfaces/denormalized-doc.interface.d.ts +8 -0
  103. package/dist/interfaces/denormalized-doc.interface.js +2 -0
  104. package/dist/interfaces/enum-schema-attributes.interface.d.ts +2 -0
  105. package/dist/interfaces/enum-schema-attributes.interface.js +2 -0
  106. package/dist/interfaces/index.d.ts +3 -0
  107. package/dist/interfaces/index.js +18 -0
  108. package/dist/interfaces/module-route.interface.d.ts +2 -0
  109. package/dist/interfaces/module-route.interface.js +2 -0
  110. package/dist/interfaces/open-api-spec.interface.d.ts +252 -0
  111. package/dist/interfaces/open-api-spec.interface.js +2 -0
  112. package/dist/interfaces/schema-object-metadata.interface.d.ts +30 -0
  113. package/dist/interfaces/schema-object-metadata.interface.js +2 -0
  114. package/dist/interfaces/swagger-custom-options.interface.d.ts +24 -0
  115. package/dist/interfaces/swagger-custom-options.interface.js +2 -0
  116. package/dist/interfaces/swagger-document-options.interface.d.ts +10 -0
  117. package/dist/interfaces/swagger-document-options.interface.js +2 -0
  118. package/dist/interfaces/swagger-ui-init-options.interface.d.ts +7 -0
  119. package/dist/interfaces/swagger-ui-init-options.interface.js +2 -0
  120. package/dist/interfaces/swagger-ui-options.interface.d.ts +15 -0
  121. package/dist/interfaces/swagger-ui-options.interface.js +2 -0
  122. package/dist/plugin/compiler-plugin.d.ts +2 -0
  123. package/dist/plugin/compiler-plugin.js +30 -0
  124. package/dist/plugin/index.d.ts +2 -0
  125. package/dist/plugin/index.js +18 -0
  126. package/dist/plugin/merge-options.d.ts +17 -0
  127. package/dist/plugin/merge-options.js +37 -0
  128. package/dist/plugin/metadata-loader.d.ts +7 -0
  129. package/dist/plugin/metadata-loader.js +51 -0
  130. package/dist/plugin/plugin-constants.d.ts +3 -0
  131. package/dist/plugin/plugin-constants.js +6 -0
  132. package/dist/plugin/plugin-debug-logger.d.ts +5 -0
  133. package/dist/plugin/plugin-debug-logger.js +7 -0
  134. package/dist/plugin/utils/ast-utils.d.ts +30 -0
  135. package/dist/plugin/utils/ast-utils.js +273 -0
  136. package/dist/plugin/utils/is-filename-matched.util.d.ts +1 -0
  137. package/dist/plugin/utils/is-filename-matched.util.js +5 -0
  138. package/dist/plugin/utils/plugin-utils.d.ts +30 -0
  139. package/dist/plugin/utils/plugin-utils.js +307 -0
  140. package/dist/plugin/utils/type-reference-to-identifier.util.d.ts +7 -0
  141. package/dist/plugin/utils/type-reference-to-identifier.util.js +52 -0
  142. package/dist/plugin/visitors/abstract.visitor.d.ts +4 -0
  143. package/dist/plugin/visitors/abstract.visitor.js +30 -0
  144. package/dist/plugin/visitors/controller-class.visitor.d.ts +20 -0
  145. package/dist/plugin/visitors/controller-class.visitor.js +265 -0
  146. package/dist/plugin/visitors/model-class.visitor.d.ts +35 -0
  147. package/dist/plugin/visitors/model-class.visitor.js +514 -0
  148. package/dist/plugin/visitors/readonly.visitor.d.ts +21 -0
  149. package/dist/plugin/visitors/readonly.visitor.js +40 -0
  150. package/dist/services/constants.d.ts +1 -0
  151. package/dist/services/constants.js +4 -0
  152. package/dist/services/decorators-properties.d.ts +21 -0
  153. package/dist/services/decorators-properties.js +149 -0
  154. package/dist/services/mimetype-content-wrapper.d.ts +4 -0
  155. package/dist/services/mimetype-content-wrapper.js +11 -0
  156. package/dist/services/model-properties-accessor.d.ts +6 -0
  157. package/dist/services/model-properties-accessor.js +37 -0
  158. package/dist/services/parameter-metadata-accessor.d.ts +22 -0
  159. package/dist/services/parameter-metadata-accessor.js +41 -0
  160. package/dist/services/parameters-metadata-mapper.d.ts +9 -0
  161. package/dist/services/parameters-metadata-mapper.js +38 -0
  162. package/dist/services/response-object-factory.d.ts +28 -0
  163. package/dist/services/response-object-factory.js +120 -0
  164. package/dist/services/response-object-mapper.d.ts +39 -0
  165. package/dist/services/response-object-mapper.js +38 -0
  166. package/dist/services/schema-object-factory.d.ts +156 -0
  167. package/dist/services/schema-object-factory.js +471 -0
  168. package/dist/services/swagger-types-mapper.d.ts +260 -0
  169. package/dist/services/swagger-types-mapper.js +107 -0
  170. package/dist/storages/global-parameters.storage.d.ts +8 -0
  171. package/dist/storages/global-parameters.storage.js +22 -0
  172. package/dist/storages/global-responses.storage.d.ts +10 -0
  173. package/dist/storages/global-responses.storage.js +21 -0
  174. package/dist/swagger-explorer.d.ts +41 -0
  175. package/dist/swagger-explorer.js +326 -0
  176. package/dist/swagger-module.d.ts +27 -0
  177. package/dist/swagger-module.js +223 -0
  178. package/dist/swagger-scanner.d.ts +25 -0
  179. package/dist/swagger-scanner.js +116 -0
  180. package/dist/swagger-transformer.d.ts +4 -0
  181. package/dist/swagger-transformer.js +22 -0
  182. package/dist/swagger-ui/constants.d.ts +3 -0
  183. package/dist/swagger-ui/constants.js +132 -0
  184. package/dist/swagger-ui/helpers.d.ts +2 -0
  185. package/dist/swagger-ui/helpers.js +16 -0
  186. package/dist/swagger-ui/index.d.ts +1 -0
  187. package/dist/swagger-ui/index.js +17 -0
  188. package/dist/swagger-ui/swagger-ui.d.ts +4 -0
  189. package/dist/swagger-ui/swagger-ui.js +62 -0
  190. package/dist/type-helpers/index.d.ts +4 -0
  191. package/dist/type-helpers/index.js +20 -0
  192. package/dist/type-helpers/intersection-type.helper.d.ts +8 -0
  193. package/dist/type-helpers/intersection-type.helper.js +42 -0
  194. package/dist/type-helpers/mapped-types.utils.d.ts +2 -0
  195. package/dist/type-helpers/mapped-types.utils.js +31 -0
  196. package/dist/type-helpers/omit-type.helper.d.ts +2 -0
  197. package/dist/type-helpers/omit-type.helper.js +40 -0
  198. package/dist/type-helpers/partial-type.helper.d.ts +4 -0
  199. package/dist/type-helpers/partial-type.helper.js +49 -0
  200. package/dist/type-helpers/pick-type.helper.d.ts +2 -0
  201. package/dist/type-helpers/pick-type.helper.js +40 -0
  202. package/dist/types/swagger-enum.type.d.ts +1 -0
  203. package/dist/types/swagger-enum.type.js +2 -0
  204. package/dist/utils/assign-two-levels-deep.d.ts +1 -0
  205. package/dist/utils/assign-two-levels-deep.js +12 -0
  206. package/dist/utils/enum.utils.d.ts +9 -0
  207. package/dist/utils/enum.utils.js +65 -0
  208. package/dist/utils/extend-metadata.util.d.ts +2 -0
  209. package/dist/utils/extend-metadata.util.js +11 -0
  210. package/dist/utils/get-global-prefix.d.ts +2 -0
  211. package/dist/utils/get-global-prefix.js +7 -0
  212. package/dist/utils/get-schema-path.util.d.ts +4 -0
  213. package/dist/utils/get-schema-path.util.js +26 -0
  214. package/dist/utils/index.d.ts +1 -0
  215. package/dist/utils/index.js +17 -0
  216. package/dist/utils/is-body-parameter.util.d.ts +2 -0
  217. package/dist/utils/is-body-parameter.util.js +6 -0
  218. package/dist/utils/is-built-in-type.util.d.ts +2 -0
  219. package/dist/utils/is-built-in-type.util.js +8 -0
  220. package/dist/utils/is-date-ctor.util.d.ts +2 -0
  221. package/dist/utils/is-date-ctor.util.js +6 -0
  222. package/dist/utils/merge-and-uniq.util.d.ts +1 -0
  223. package/dist/utils/merge-and-uniq.util.js +7 -0
  224. package/dist/utils/normalize-rel-path.d.ts +1 -0
  225. package/dist/utils/normalize-rel-path.js +7 -0
  226. package/dist/utils/remove-undefined-keys.d.ts +5 -0
  227. package/dist/utils/remove-undefined-keys.js +11 -0
  228. package/dist/utils/resolve-path.util.d.ts +1 -0
  229. package/dist/utils/resolve-path.util.js +7 -0
  230. package/dist/utils/reverse-object-keys.util.d.ts +1 -0
  231. package/dist/utils/reverse-object-keys.util.js +11 -0
  232. package/dist/utils/sort-object-lexicographically.d.ts +5 -0
  233. package/dist/utils/sort-object-lexicographically.js +11 -0
  234. package/dist/utils/strip-last-slash.util.d.ts +1 -0
  235. package/dist/utils/strip-last-slash.util.js +8 -0
  236. package/dist/utils/validate-global-prefix.util.d.ts +1 -0
  237. package/dist/utils/validate-global-prefix.util.js +5 -0
  238. package/dist/utils/validate-path.util.d.ts +1 -0
  239. package/dist/utils/validate-path.util.js +5 -0
  240. package/eslint.config.mjs +47 -0
  241. package/nest-cli.json +6 -0
  242. package/package.json +116 -0
  243. package/plugin.js +10 -0
  244. 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 {};