@asyncapi/cli 3.2.0 → 3.3.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 (191) hide show
  1. package/assets/create-template/templates/default/package-lock.json +4 -3
  2. package/lib/apps/api/app.d.ts +15 -0
  3. package/lib/apps/api/app.js +89 -0
  4. package/lib/apps/api/configs/development.json +16 -0
  5. package/lib/apps/api/configs/production.json +16 -0
  6. package/lib/apps/api/configs/test.json +16 -0
  7. package/lib/apps/api/constants.d.ts +1 -0
  8. package/lib/apps/api/constants.js +4 -0
  9. package/lib/apps/api/controllers/bundle.controller.d.ts +7 -0
  10. package/lib/apps/api/controllers/bundle.controller.js +44 -0
  11. package/lib/apps/api/controllers/convert.controller.d.ts +11 -0
  12. package/lib/apps/api/controllers/convert.controller.js +69 -0
  13. package/lib/apps/api/controllers/diff.controller.d.ts +7 -0
  14. package/lib/apps/api/controllers/diff.controller.js +42 -0
  15. package/lib/apps/api/controllers/docs.controller.d.ts +6 -0
  16. package/lib/apps/api/controllers/docs.controller.js +24 -0
  17. package/lib/apps/api/controllers/generate.controller.d.ts +22 -0
  18. package/lib/apps/api/controllers/generate.controller.js +176 -0
  19. package/lib/apps/api/controllers/help.controller.d.ts +6 -0
  20. package/lib/apps/api/controllers/help.controller.js +101 -0
  21. package/lib/apps/api/controllers/parse.controller.d.ts +10 -0
  22. package/lib/apps/api/controllers/parse.controller.js +35 -0
  23. package/lib/apps/api/controllers/validate.controller.d.ts +10 -0
  24. package/lib/apps/api/controllers/validate.controller.js +50 -0
  25. package/lib/apps/api/exceptions/problem.exception.d.ts +14 -0
  26. package/lib/apps/api/exceptions/problem.exception.js +10 -0
  27. package/lib/apps/api/index.d.ts +9 -0
  28. package/lib/apps/api/index.js +21 -0
  29. package/lib/apps/api/middlewares/problem.middleware.d.ts +6 -0
  30. package/lib/apps/api/middlewares/problem.middleware.js +27 -0
  31. package/lib/apps/api/middlewares/validation.middleware.d.ts +12 -0
  32. package/lib/apps/api/middlewares/validation.middleware.js +236 -0
  33. package/lib/apps/api/server.d.ts +3 -0
  34. package/lib/apps/api/server.js +19 -0
  35. package/lib/{commands → apps/cli/commands}/bundle.d.ts +1 -1
  36. package/lib/{commands → apps/cli/commands}/bundle.js +3 -3
  37. package/lib/{commands → apps/cli/commands}/config/analytics.d.ts +1 -1
  38. package/lib/{commands → apps/cli/commands}/config/analytics.js +4 -3
  39. package/lib/{commands → apps/cli/commands}/config/context/add.d.ts +1 -1
  40. package/lib/{commands → apps/cli/commands}/config/context/add.js +12 -6
  41. package/lib/{commands → apps/cli/commands}/config/context/current.d.ts +1 -1
  42. package/lib/{commands → apps/cli/commands}/config/context/current.js +4 -4
  43. package/lib/{commands → apps/cli/commands}/config/context/edit.d.ts +1 -1
  44. package/lib/{commands → apps/cli/commands}/config/context/edit.js +12 -6
  45. package/lib/{commands → apps/cli/commands}/config/context/index.d.ts +1 -1
  46. package/lib/{commands → apps/cli/commands}/config/context/index.js +1 -1
  47. package/lib/{commands → apps/cli/commands}/config/context/init.d.ts +1 -1
  48. package/lib/{commands → apps/cli/commands}/config/context/init.js +7 -4
  49. package/lib/{commands → apps/cli/commands}/config/context/list.d.ts +1 -1
  50. package/lib/{commands → apps/cli/commands}/config/context/list.js +4 -4
  51. package/lib/{commands → apps/cli/commands}/config/context/remove.d.ts +1 -1
  52. package/lib/{commands → apps/cli/commands}/config/context/remove.js +8 -5
  53. package/lib/{commands → apps/cli/commands}/config/context/use.d.ts +1 -1
  54. package/lib/{commands → apps/cli/commands}/config/context/use.js +8 -5
  55. package/lib/{commands → apps/cli/commands}/config/index.d.ts +1 -1
  56. package/lib/{commands → apps/cli/commands}/config/index.js +1 -1
  57. package/lib/{commands → apps/cli/commands}/config/versions.d.ts +1 -1
  58. package/lib/{commands → apps/cli/commands}/config/versions.js +2 -2
  59. package/lib/{commands → apps/cli/commands}/convert.d.ts +2 -7
  60. package/lib/apps/cli/commands/convert.js +85 -0
  61. package/lib/{commands → apps/cli/commands}/diff.d.ts +11 -2
  62. package/lib/{commands → apps/cli/commands}/diff.js +85 -31
  63. package/lib/{commands → apps/cli/commands}/format.d.ts +1 -1
  64. package/lib/{commands → apps/cli/commands}/format.js +4 -4
  65. package/lib/{commands → apps/cli/commands}/generate/fromTemplate.d.ts +4 -5
  66. package/lib/{commands → apps/cli/commands}/generate/fromTemplate.js +89 -122
  67. package/lib/{commands → apps/cli/commands}/generate/index.d.ts +1 -1
  68. package/lib/{commands → apps/cli/commands}/generate/index.js +1 -1
  69. package/lib/{commands → apps/cli/commands}/generate/models.d.ts +6 -1
  70. package/lib/{commands → apps/cli/commands}/generate/models.js +48 -9
  71. package/lib/{commands → apps/cli/commands}/new/file.d.ts +1 -1
  72. package/lib/{commands → apps/cli/commands}/new/file.js +11 -8
  73. package/lib/{commands → apps/cli/commands}/new/glee.d.ts +2 -2
  74. package/lib/{commands → apps/cli/commands}/new/glee.js +4 -4
  75. package/lib/{commands → apps/cli/commands}/new/index.d.ts +1 -1
  76. package/lib/{commands → apps/cli/commands}/new/index.js +1 -1
  77. package/lib/{commands → apps/cli/commands}/new/template.d.ts +1 -1
  78. package/lib/{commands → apps/cli/commands}/new/template.js +10 -8
  79. package/lib/{commands → apps/cli/commands}/optimize.d.ts +1 -1
  80. package/lib/{commands → apps/cli/commands}/optimize.js +71 -30
  81. package/lib/{commands → apps/cli/commands}/pretty.d.ts +1 -1
  82. package/lib/{commands → apps/cli/commands}/pretty.js +8 -5
  83. package/lib/apps/cli/commands/start/api.d.ts +11 -0
  84. package/lib/apps/cli/commands/start/api.js +23 -0
  85. package/lib/{commands → apps/cli/commands}/start/index.d.ts +1 -1
  86. package/lib/{commands → apps/cli/commands}/start/index.js +1 -1
  87. package/lib/{commands → apps/cli/commands}/start/preview.d.ts +1 -1
  88. package/lib/{commands → apps/cli/commands}/start/preview.js +9 -6
  89. package/lib/{commands → apps/cli/commands}/start/studio.d.ts +1 -1
  90. package/lib/{commands → apps/cli/commands}/start/studio.js +10 -7
  91. package/lib/{commands → apps/cli/commands}/validate.d.ts +4 -2
  92. package/lib/apps/cli/commands/validate.js +94 -0
  93. package/lib/{core → apps/cli/internal}/base.d.ts +1 -1
  94. package/lib/{core → apps/cli/internal}/base.js +12 -4
  95. package/lib/apps/cli/internal/flags/bundle.flags.js +26 -0
  96. package/lib/apps/cli/internal/flags/config/analytics.flags.js +24 -0
  97. package/lib/{core → apps/cli/internal}/flags/config/context.flags.js +1 -1
  98. package/lib/{core → apps/cli/internal}/flags/convert.flags.js +9 -2
  99. package/lib/{core → apps/cli/internal}/flags/diff.flags.d.ts +1 -1
  100. package/lib/{core → apps/cli/internal}/flags/diff.flags.js +3 -3
  101. package/lib/{core → apps/cli/internal}/flags/generate/fromTemplate.flags.js +12 -12
  102. package/lib/{core → apps/cli/internal}/flags/generate/models.flags.js +2 -2
  103. package/lib/{core → apps/cli/internal}/flags/global.flags.js +1 -1
  104. package/lib/{core → apps/cli/internal}/flags/new/file.flags.js +7 -2
  105. package/lib/{core → apps/cli/internal}/flags/optimize.flags.js +24 -4
  106. package/lib/apps/cli/internal/flags/parser.flags.d.ts +10 -0
  107. package/lib/apps/cli/internal/flags/parser.flags.js +28 -0
  108. package/lib/{core → apps/cli/internal}/flags/proxy.flags.js +3 -3
  109. package/lib/apps/cli/internal/flags/start/api.flags.d.ts +5 -0
  110. package/lib/apps/cli/internal/flags/start/api.flags.js +20 -0
  111. package/lib/apps/cli/internal/flags/start/preview.flags.js +31 -0
  112. package/lib/{core → apps/cli/internal}/flags/start/studio.flags.js +9 -2
  113. package/lib/{core → apps/cli/internal}/flags/validate.flags.d.ts +1 -1
  114. package/lib/{core → apps/cli/internal}/flags/validate.flags.js +2 -2
  115. package/lib/{core → apps/cli/internal}/globals.d.ts +1 -1
  116. package/lib/{core → apps/cli/internal}/globals.js +2 -4
  117. package/lib/{core → apps/cli/internal}/hooks/command_not_found/myhook.js +14 -4
  118. package/lib/{core → domains}/models/Context.js +1 -1
  119. package/lib/{core → domains}/models/Preview.js +35 -19
  120. package/lib/{core → domains}/models/SpecificationFile.d.ts +2 -2
  121. package/lib/{core → domains}/models/SpecificationFile.js +8 -5
  122. package/lib/{core → domains}/models/Studio.js +4 -4
  123. package/lib/domains/services/archiver.service.d.ts +17 -0
  124. package/lib/domains/services/archiver.service.js +53 -0
  125. package/lib/domains/services/base.service.d.ts +6 -0
  126. package/lib/domains/services/base.service.js +26 -0
  127. package/lib/domains/services/convert.service.d.ts +12 -0
  128. package/lib/domains/services/convert.service.js +65 -0
  129. package/lib/domains/services/generator.service.d.ts +15 -0
  130. package/lib/domains/services/generator.service.js +95 -0
  131. package/lib/domains/services/validation.service.d.ts +54 -0
  132. package/lib/domains/services/validation.service.js +288 -0
  133. package/lib/{core/errors → errors}/specification-file.js +1 -1
  134. package/lib/{core/errors → errors}/validation-error.js +6 -5
  135. package/lib/interfaces/index.d.ts +87 -0
  136. package/lib/interfaces/index.js +7 -0
  137. package/lib/utils/ajv.d.ts +2 -0
  138. package/lib/utils/ajv.js +18 -0
  139. package/lib/utils/app-openapi.d.ts +4 -0
  140. package/lib/utils/app-openapi.js +28 -0
  141. package/lib/{core/utils/generator.js → utils/fileWatcher.js} +8 -2
  142. package/lib/utils/logger.d.ts +6 -0
  143. package/lib/utils/logger.js +33 -0
  144. package/lib/utils/retrieve-language.d.ts +1 -0
  145. package/lib/utils/retrieve-language.js +9 -0
  146. package/lib/utils/temp-dir.d.ts +2 -0
  147. package/lib/utils/temp-dir.js +25 -0
  148. package/oclif.manifest.json +109 -1
  149. package/package.json +36 -10
  150. package/lib/commands/convert.js +0 -132
  151. package/lib/commands/validate.js +0 -47
  152. package/lib/core/flags/bundle.flags.js +0 -14
  153. package/lib/core/flags/config/analytics.flags.js +0 -13
  154. package/lib/core/flags/start/preview.flags.js +0 -15
  155. package/lib/core/parser.d.ts +0 -35
  156. package/lib/core/parser.js +0 -230
  157. /package/lib/{core → apps/cli/internal}/flags/bundle.flags.d.ts +0 -0
  158. /package/lib/{core → apps/cli/internal}/flags/config/analytics.flags.d.ts +0 -0
  159. /package/lib/{core → apps/cli/internal}/flags/config/context.flags.d.ts +0 -0
  160. /package/lib/{core → apps/cli/internal}/flags/convert.flags.d.ts +0 -0
  161. /package/lib/{core → apps/cli/internal}/flags/format.flags.d.ts +0 -0
  162. /package/lib/{core → apps/cli/internal}/flags/format.flags.js +0 -0
  163. /package/lib/{core → apps/cli/internal}/flags/generate/fromTemplate.flags.d.ts +0 -0
  164. /package/lib/{core → apps/cli/internal}/flags/generate/models.flags.d.ts +0 -0
  165. /package/lib/{core → apps/cli/internal}/flags/global.flags.d.ts +0 -0
  166. /package/lib/{core → apps/cli/internal}/flags/new/file.flags.d.ts +0 -0
  167. /package/lib/{core → apps/cli/internal}/flags/new/glee.flags.d.ts +0 -0
  168. /package/lib/{core → apps/cli/internal}/flags/new/glee.flags.js +0 -0
  169. /package/lib/{core → apps/cli/internal}/flags/new/template.flags.d.ts +0 -0
  170. /package/lib/{core → apps/cli/internal}/flags/new/template.flags.js +0 -0
  171. /package/lib/{core → apps/cli/internal}/flags/optimize.flags.d.ts +0 -0
  172. /package/lib/{core → apps/cli/internal}/flags/pretty.flags.d.ts +0 -0
  173. /package/lib/{core → apps/cli/internal}/flags/pretty.flags.js +0 -0
  174. /package/lib/{core → apps/cli/internal}/flags/proxy.flags.d.ts +0 -0
  175. /package/lib/{core → apps/cli/internal}/flags/start/preview.flags.d.ts +0 -0
  176. /package/lib/{core → apps/cli/internal}/flags/start/studio.flags.d.ts +0 -0
  177. /package/lib/{core → apps/cli/internal}/hooks/command_not_found/myhook.d.ts +0 -0
  178. /package/lib/{core → domains}/models/Context.d.ts +0 -0
  179. /package/lib/{core → domains}/models/Preview.d.ts +0 -0
  180. /package/lib/{core → domains}/models/Studio.d.ts +0 -0
  181. /package/lib/{core/errors → errors}/context-error.d.ts +0 -0
  182. /package/lib/{core/errors → errors}/context-error.js +0 -0
  183. /package/lib/{core/errors → errors}/diff-error.d.ts +0 -0
  184. /package/lib/{core/errors → errors}/diff-error.js +0 -0
  185. /package/lib/{core/errors → errors}/generator-error.d.ts +0 -0
  186. /package/lib/{core/errors → errors}/generator-error.js +0 -0
  187. /package/lib/{core/errors → errors}/specification-file.d.ts +0 -0
  188. /package/lib/{core/errors → errors}/validation-error.d.ts +0 -0
  189. /package/lib/{core/utils/generator.d.ts → utils/fileWatcher.d.ts} +0 -0
  190. /package/lib/{core/utils → utils}/scoreCalculator.d.ts +0 -0
  191. /package/lib/{core/utils → utils}/scoreCalculator.js +0 -0
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValidationService = exports.ValidationStatus = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const base_service_1 = require("./base.service");
6
+ const avro_schema_parser_1 = require("@asyncapi/avro-schema-parser");
7
+ const openapi_schema_parser_1 = require("@asyncapi/openapi-schema-parser");
8
+ const cjs_1 = require("@asyncapi/parser/cjs");
9
+ const raml_dt_schema_parser_1 = require("@asyncapi/raml-dt-schema-parser");
10
+ const protobuf_schema_parser_1 = require("@asyncapi/protobuf-schema-parser");
11
+ const spectral_core_1 = require("@stoplight/spectral-core");
12
+ const spectral_formatters_1 = require("@stoplight/spectral-formatters");
13
+ const chalk_1 = require("chalk");
14
+ const fs_1 = require("fs");
15
+ const path_1 = tslib_1.__importDefault(require("path"));
16
+ const scoreCalculator_1 = require("../../utils/scoreCalculator");
17
+ const { writeFile } = fs_1.promises;
18
+ var ValidationStatus;
19
+ (function (ValidationStatus) {
20
+ ValidationStatus["INVALID"] = "invalid";
21
+ ValidationStatus["VALID"] = "valid";
22
+ })(ValidationStatus || (exports.ValidationStatus = ValidationStatus = {}));
23
+ const formatExtensions = {
24
+ stylish: '.txt',
25
+ json: '.json',
26
+ junit: '.xml',
27
+ html: '.html',
28
+ text: '.txt',
29
+ teamcity: '.txt',
30
+ pretty: '.txt',
31
+ };
32
+ const validFormats = [
33
+ 'stylish',
34
+ 'json',
35
+ 'junit',
36
+ 'html',
37
+ 'text',
38
+ 'teamcity',
39
+ 'pretty',
40
+ ];
41
+ class ValidationService extends base_service_1.BaseService {
42
+ constructor(parserOptions = {}) {
43
+ var _a;
44
+ super();
45
+ this.parser = new cjs_1.Parser(Object.assign(Object.assign({}, parserOptions), { __unstable: Object.assign({ resolver: {
46
+ cache: false,
47
+ } }, (_a = parserOptions.__unstable) === null || _a === void 0 ? void 0 : _a.resolver) }));
48
+ this.parser.registerSchemaParser((0, openapi_schema_parser_1.OpenAPISchemaParser)());
49
+ this.parser.registerSchemaParser((0, raml_dt_schema_parser_1.RamlDTSchemaParser)());
50
+ this.parser.registerSchemaParser((0, avro_schema_parser_1.AvroSchemaParser)());
51
+ this.parser.registerSchemaParser((0, protobuf_schema_parser_1.ProtoBuffSchemaParser)());
52
+ }
53
+ /**
54
+ * Determine validation status from diagnostics
55
+ */
56
+ determineDiagnosticsStatus(diagnostics, options) {
57
+ var _a;
58
+ const failSeverity = (_a = options['fail-severity']) !== null && _a !== void 0 ? _a : 'error';
59
+ const hasIssues = diagnostics.length > 0;
60
+ const isFailSeverity = hasIssues && this.hasFailSeverity(diagnostics, failSeverity);
61
+ return isFailSeverity ? ValidationStatus.INVALID : ValidationStatus.VALID;
62
+ }
63
+ /**
64
+ * Parses an AsyncAPI document and returns the parsed result
65
+ */
66
+ parseDocument(specFile_1, parseOptions_1) {
67
+ return tslib_1.__awaiter(this, arguments, void 0, function* (specFile, parseOptions, options = {}) {
68
+ try {
69
+ const { document, diagnostics } = yield this.parser.parse(specFile.text(), Object.assign({ source: specFile.getSource() }, parseOptions));
70
+ if (!document) {
71
+ return this.createErrorResult('Failed to parse document');
72
+ }
73
+ const status = this.determineDiagnosticsStatus(diagnostics, options);
74
+ const result = {
75
+ document,
76
+ diagnostics,
77
+ status: status,
78
+ };
79
+ return this.createSuccessResult(result);
80
+ }
81
+ catch (error) {
82
+ return this.handleServiceError(error);
83
+ }
84
+ });
85
+ }
86
+ /**
87
+ * Validates an AsyncAPI document
88
+ */
89
+ validateDocument(specFile_1) {
90
+ return tslib_1.__awaiter(this, arguments, void 0, function* (specFile, options = {}) {
91
+ var _a, _b;
92
+ try {
93
+ const suppressAllWarnings = (_a = options.suppressAllWarnings) !== null && _a !== void 0 ? _a : false;
94
+ const suppressedWarnings = (_b = options.suppressWarnings) !== null && _b !== void 0 ? _b : [];
95
+ let activeParser;
96
+ if (suppressAllWarnings || suppressedWarnings.length) {
97
+ activeParser = yield this.buildAndRegisterCustomParser(specFile, suppressedWarnings, suppressAllWarnings);
98
+ }
99
+ else {
100
+ activeParser = this.parser;
101
+ }
102
+ const { document, diagnostics } = yield activeParser.parse(specFile.text(), {
103
+ source: specFile.getSource(),
104
+ });
105
+ const status = this.determineDiagnosticsStatus(diagnostics, options);
106
+ const result = {
107
+ status: status,
108
+ diagnostics,
109
+ score: yield (0, scoreCalculator_1.calculateScore)(document),
110
+ document: (document === null || document === void 0 ? void 0 : document.json) ? document.json() : undefined,
111
+ };
112
+ return this.createSuccessResult(result);
113
+ }
114
+ catch (error) {
115
+ return this.handleServiceError(error);
116
+ }
117
+ });
118
+ }
119
+ /**
120
+ * Helper to build and register a custom parser with suppressed rules
121
+ */
122
+ buildAndRegisterCustomParser(specFile, suppressedWarnings, suppressAllWarnings) {
123
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
124
+ // Helper to build a parser with given rules turned off
125
+ const buildCustomParser = (rulesToSuppress) => new cjs_1.Parser({
126
+ ruleset: {
127
+ extends: [],
128
+ rules: Object.fromEntries(rulesToSuppress.map((rule) => [rule, 'off'])),
129
+ },
130
+ __unstable: {
131
+ resolver: {
132
+ cache: false,
133
+ },
134
+ },
135
+ });
136
+ let activeParser;
137
+ if (suppressAllWarnings || suppressedWarnings.length) {
138
+ if (suppressAllWarnings) {
139
+ // Run the default parser to discover all rule codes
140
+ const diagnostics = yield this.parser.validate(specFile.text(), {
141
+ source: specFile.getSource(),
142
+ });
143
+ const allRuleNames = Array.from(new Set(diagnostics
144
+ .map((d) => d.code)
145
+ .filter((c) => typeof c === 'string')));
146
+ activeParser = buildCustomParser(allRuleNames);
147
+ }
148
+ else {
149
+ try {
150
+ activeParser = buildCustomParser(suppressedWarnings);
151
+ }
152
+ catch (e) {
153
+ const msg = e.message || '';
154
+ const matches = [
155
+ ...msg.matchAll(/Cannot extend non-existing rule: "([^"]+)"/g),
156
+ ];
157
+ const invalidRules = matches.map((m) => m[1]);
158
+ if (invalidRules.length > 0) {
159
+ const validRules = suppressedWarnings.filter((rule) => !invalidRules.includes(rule));
160
+ activeParser = buildCustomParser(validRules);
161
+ }
162
+ else {
163
+ throw e;
164
+ }
165
+ }
166
+ }
167
+ // Register schema parsers for active parser
168
+ activeParser.registerSchemaParser((0, avro_schema_parser_1.AvroSchemaParser)());
169
+ activeParser.registerSchemaParser((0, openapi_schema_parser_1.OpenAPISchemaParser)());
170
+ activeParser.registerSchemaParser((0, raml_dt_schema_parser_1.RamlDTSchemaParser)());
171
+ activeParser.registerSchemaParser((0, protobuf_schema_parser_1.ProtoBuffSchemaParser)());
172
+ }
173
+ else {
174
+ throw new Error('No rules to suppress provided');
175
+ }
176
+ return activeParser;
177
+ });
178
+ }
179
+ /**
180
+ * Save validation diagnostics to file
181
+ */
182
+ saveDiagnosticsToFile(outputPath, format, formatOutput) {
183
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
184
+ try {
185
+ if (!validFormats.includes(format)) {
186
+ return this.createErrorResult(`Invalid diagnostics format: "${format}"`);
187
+ }
188
+ const expectedExtension = formatExtensions[format];
189
+ const actualExtension = path_1.default.extname(outputPath);
190
+ // Validate file extension against diagnostics format
191
+ if (expectedExtension && actualExtension !== expectedExtension) {
192
+ return this.createErrorResult(`Invalid file extension for format "${format}". Expected extension: "${expectedExtension}"`);
193
+ }
194
+ yield writeFile(path_1.default.resolve(process.cwd(), outputPath), formatOutput, {
195
+ encoding: 'utf-8',
196
+ });
197
+ return this.createSuccessResult(outputPath);
198
+ }
199
+ catch (error) {
200
+ return this.handleServiceError(error);
201
+ }
202
+ });
203
+ }
204
+ /**
205
+ * Generate governance message based on validation results
206
+ */
207
+ generateGovernanceMessage(sourceString, hasIssues, isFailSeverity) {
208
+ if (!hasIssues) {
209
+ return `\n${sourceString} is valid! ${sourceString} and referenced documents don't have governance issues.`;
210
+ }
211
+ if (isFailSeverity) {
212
+ return `\n${sourceString} and/or referenced documents have governance issues.`;
213
+ }
214
+ return `\n${sourceString} is valid but has (itself and/or referenced documents) governance issues.`;
215
+ }
216
+ /**
217
+ * Check if diagnostics contain failure severity issues
218
+ */
219
+ hasFailSeverity(diagnostics, failSeverity) {
220
+ const diagnosticSeverity = (0, spectral_core_1.getDiagnosticSeverity)(failSeverity);
221
+ return diagnostics.some((diagnostic) => diagnostic.severity <= diagnosticSeverity);
222
+ }
223
+ /**
224
+ * Format validation diagnostics output
225
+ */
226
+ formatDiagnosticsOutput(diagnostics, format = 'stylish', failSeverity = 'error') {
227
+ const diagnosticSeverity = (0, spectral_core_1.getDiagnosticSeverity)(failSeverity);
228
+ const options = {
229
+ failSeverity: diagnosticSeverity !== -1
230
+ ? diagnosticSeverity
231
+ : cjs_1.DiagnosticSeverity.Error,
232
+ };
233
+ switch (format) {
234
+ case 'stylish':
235
+ return this.formatStylish(diagnostics, options);
236
+ case 'json':
237
+ return (0, spectral_formatters_1.json)(diagnostics, options);
238
+ case 'junit':
239
+ return (0, spectral_formatters_1.junit)(diagnostics, options);
240
+ case 'html':
241
+ return (0, spectral_formatters_1.html)(diagnostics, options);
242
+ case 'text':
243
+ return (0, spectral_formatters_1.text)(diagnostics, options);
244
+ case 'teamcity':
245
+ return (0, spectral_formatters_1.teamcity)(diagnostics, options);
246
+ case 'pretty':
247
+ return (0, spectral_formatters_1.pretty)(diagnostics, options);
248
+ default:
249
+ return (0, spectral_formatters_1.stylish)(diagnostics, options);
250
+ }
251
+ }
252
+ /**
253
+ * Format diagnostics in stylish format with severity grouping
254
+ */
255
+ formatStylish(diagnostics, options) {
256
+ const groupedDiagnostics = diagnostics.reduce((acc, diagnostic) => {
257
+ const severity = diagnostic.severity;
258
+ if (!acc[severity]) {
259
+ acc[severity] = [];
260
+ }
261
+ acc[severity].push(diagnostic);
262
+ return acc;
263
+ }, {});
264
+ return Object.entries(groupedDiagnostics)
265
+ .map(([severity, diagnostics]) => {
266
+ return `${this.getSeverityTitle(Number(severity))} ${(0, spectral_formatters_1.stylish)(diagnostics, options)}`;
267
+ })
268
+ .join('\n');
269
+ }
270
+ /**
271
+ * Get colored severity title
272
+ */
273
+ getSeverityTitle(severity) {
274
+ switch (severity) {
275
+ case cjs_1.DiagnosticSeverity.Error:
276
+ return (0, chalk_1.red)('Errors');
277
+ case cjs_1.DiagnosticSeverity.Warning:
278
+ return (0, chalk_1.yellow)('Warnings');
279
+ case cjs_1.DiagnosticSeverity.Information:
280
+ return (0, chalk_1.cyan)('Information');
281
+ case cjs_1.DiagnosticSeverity.Hint:
282
+ return (0, chalk_1.green)('Hints');
283
+ default:
284
+ return 'Unknown';
285
+ }
286
+ }
287
+ }
288
+ exports.ValidationService = ValidationService;
@@ -38,7 +38,7 @@ class ErrorLoadingSpec extends Error {
38
38
  constructor(from, param) {
39
39
  super();
40
40
  this.errorMessages = {
41
- default: context_error_1.NO_CONTEXTS_SAVED
41
+ default: context_error_1.NO_CONTEXTS_SAVED,
42
42
  };
43
43
  if (from === 'file') {
44
44
  this.name = 'error loading AsyncAPI document from file';
@@ -14,7 +14,8 @@ class ValidationError extends Error {
14
14
  this.message = `Syntax Error in "${error.filepath}".`;
15
15
  }
16
16
  if (error.type === 'no-spec-found') {
17
- this.message = 'Unable to perform validation. Specify what AsyncAPI file should be validated.\n\nThese are your options to specify in the CLI what AsyncAPI file should be used:\n- You can provide a path to the AsyncAPI file: asyncapi validate path/to/file/asyncapi.yml\n- You can also pass a saved context that points to your AsyncAPI file: asyncapi validate mycontext\n- In case you did not specify a context that you want to use, the CLI checks if there is a default context and uses it. To set default context run: asyncapi context use mycontext\n- In case you did not provide any reference to AsyncAPI file and there is no default context, the CLI detects if in your current working directory you have files like asyncapi.json, asyncapi.yaml, asyncapi.yml. Just rename your file accordingly.';
17
+ this.message =
18
+ 'Unable to perform validation. Specify what AsyncAPI file should be validated.\n\nThese are your options to specify in the CLI what AsyncAPI file should be used:\n- You can provide a path to the AsyncAPI file: asyncapi validate path/to/file/asyncapi.yml\n- You can also pass a saved context that points to your AsyncAPI file: asyncapi validate mycontext\n- In case you did not specify a context that you want to use, the CLI checks if there is a default context and uses it. To set default context run: asyncapi context use mycontext\n- In case you did not provide any reference to AsyncAPI file and there is no default context, the CLI detects if in your current working directory you have files like asyncapi.json, asyncapi.yaml, asyncapi.yml. Just rename your file accordingly.';
18
19
  }
19
20
  this.name = 'ValidationError';
20
21
  }
@@ -31,10 +32,10 @@ class ValidationError extends Error {
31
32
  const errorHasTitle = !!e.title;
32
33
  const errorHasLocation = !!e.location;
33
34
  /*
34
- * All the conditions below are needed since validationErrors (from ParserError) come from Parser JS library,
35
- * so we cannot assure that all the fields or properties are always provided in the error. There might be cases
36
- * that even title is not provided.
37
- */
35
+ * All the conditions below are needed since validationErrors (from ParserError) come from Parser JS library,
36
+ * so we cannot assure that all the fields or properties are always provided in the error. There might be cases
37
+ * that even title is not provided.
38
+ */
38
39
  if (errorHasTitle && errorHasLocation) {
39
40
  errorsInfo.push(`${e.title} ${e.location.startLine}:${e.location.startColumn}`);
40
41
  continue;
@@ -0,0 +1,87 @@
1
+ import { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs';
2
+ import { OutputFormat } from '@stoplight/spectral-cli/dist/services/config';
3
+ export type DiagnosticsFormat = 'stylish' | 'json' | 'junit' | 'html' | 'text' | 'teamcity' | 'pretty';
4
+ export type SeverityKind = 'error' | 'warn' | 'info' | 'hint';
5
+ export type Adapter = 'cli' | 'api';
6
+ import specs from '@asyncapi/specs';
7
+ import { Router } from 'express';
8
+ import { AsyncAPIConvertVersion } from '@asyncapi/converter';
9
+ export interface Controller {
10
+ basepath: string;
11
+ boot(): Router | Promise<Router>;
12
+ }
13
+ export interface Problem {
14
+ type: string;
15
+ title: string;
16
+ status: number;
17
+ detail?: string;
18
+ instance?: string;
19
+ [key: string]: any;
20
+ }
21
+ export type AsyncAPIDocument = {
22
+ asyncapi: string;
23
+ } & Record<string, unknown>;
24
+ export declare const ALL_SPECS: string[];
25
+ export declare const LAST_SPEC_VERSION: string;
26
+ export type SpecsEnum = keyof typeof specs | 'latest';
27
+ export interface AsyncAPIServiceOptions {
28
+ source?: string;
29
+ path?: string;
30
+ }
31
+ export interface ServiceResult<T = any> {
32
+ success: boolean;
33
+ data?: T;
34
+ error?: string;
35
+ diagnostics?: any[];
36
+ }
37
+ export interface ParsedDocument {
38
+ document: AsyncAPIDocumentInterface;
39
+ diagnostics: any[];
40
+ status: 'valid' | 'invalid';
41
+ }
42
+ export interface ValidationOptions {
43
+ 'log-diagnostics'?: boolean;
44
+ 'diagnostics-format'?: `${OutputFormat}`;
45
+ 'fail-severity'?: SeverityKind;
46
+ output?: string;
47
+ suppressWarnings?: string[];
48
+ suppressAllWarnings?: boolean;
49
+ }
50
+ export interface ValidationResult {
51
+ status: 'valid' | 'invalid';
52
+ document?: AsyncAPIDocument;
53
+ diagnostics?: any[];
54
+ score?: number;
55
+ }
56
+ export interface ConversionOptions {
57
+ format: 'asyncapi' | 'openapi' | 'postman-collection';
58
+ 'target-version'?: AsyncAPIConvertVersion;
59
+ perspective?: 'client' | 'server';
60
+ }
61
+ export interface ConversionResult {
62
+ convertedDocument: string;
63
+ originalFormat: string;
64
+ }
65
+ export interface IMapBaseUrlToFlag {
66
+ url: string;
67
+ folder: string;
68
+ }
69
+ export interface GenerationOptions {
70
+ templateParams?: Record<string, any>;
71
+ forceWrite?: boolean;
72
+ install?: boolean;
73
+ debug?: boolean;
74
+ noOverwriteGlobs?: string[];
75
+ disabledHooks?: Record<string, string>;
76
+ mapBaseUrl?: IMapBaseUrlToFlag;
77
+ registry?: {
78
+ url?: string;
79
+ auth?: string;
80
+ token?: string;
81
+ };
82
+ }
83
+ export interface GenerationResult {
84
+ success: boolean;
85
+ outputPath: string;
86
+ logs?: string[];
87
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LAST_SPEC_VERSION = exports.ALL_SPECS = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const specs_1 = tslib_1.__importDefault(require("@asyncapi/specs"));
6
+ exports.ALL_SPECS = [...Object.keys(specs_1.default)];
7
+ exports.LAST_SPEC_VERSION = exports.ALL_SPECS[exports.ALL_SPECS.length - 1];
@@ -0,0 +1,2 @@
1
+ import type AjvCore from 'ajv/dist/core';
2
+ export declare function createAjvInstance(): AjvCore;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAjvInstance = createAjvInstance;
4
+ const tslib_1 = require("tslib");
5
+ const ajv_1 = tslib_1.__importDefault(require("ajv"));
6
+ const ajv_formats_1 = tslib_1.__importDefault(require("ajv-formats"));
7
+ function createAjvInstance() {
8
+ const ajv = new ajv_1.default({
9
+ allErrors: true,
10
+ meta: true,
11
+ strict: false,
12
+ allowUnionTypes: true,
13
+ logger: false,
14
+ unicodeRegExp: false,
15
+ });
16
+ (0, ajv_formats_1.default)(ajv);
17
+ return ajv;
18
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Retrieve application's OpenAPI document.
3
+ */
4
+ export declare function getAppOpenAPI(): Promise<any>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAppOpenAPI = getAppOpenAPI;
4
+ const tslib_1 = require("tslib");
5
+ const fs_1 = require("fs");
6
+ const path_1 = tslib_1.__importDefault(require("path"));
7
+ const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
8
+ const json_schema_ref_parser_1 = tslib_1.__importDefault(require("@apidevtools/json-schema-ref-parser"));
9
+ let parsedOpenAPI = undefined;
10
+ /**
11
+ * Retrieve application's OpenAPI document.
12
+ */
13
+ function getAppOpenAPI() {
14
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
15
+ if (parsedOpenAPI) {
16
+ return parsedOpenAPI;
17
+ }
18
+ const openaAPI = yield fs_1.promises.readFile(path_1.default.join(__dirname, '../../openapi.yaml'), 'utf-8');
19
+ parsedOpenAPI = js_yaml_1.default.load(openaAPI);
20
+ // due to the fact that `@asyncapi/specs: 3.0.0` have moved to a new way of bundling schemas, it makes no sense to resolve the references for AsyncAPI specs
21
+ parsedOpenAPI.components.schemas.AsyncAPIDocument.oneOf = {
22
+ type: ['string', 'object'],
23
+ };
24
+ const refParser = new json_schema_ref_parser_1.default();
25
+ yield refParser.dereference(parsedOpenAPI);
26
+ return parsedOpenAPI;
27
+ });
28
+ }
@@ -39,7 +39,10 @@ class Watcher {
39
39
  * @param {*} errorCallback Calback to call when it is no longer possible to watch a file.
40
40
  */
41
41
  initiateWatchOnPath(path, changeCallback, errorCallback) {
42
- const watcher = chokidar_1.default.watch(path, { ignoreInitial: true, ignored: this.ignorePaths });
42
+ const watcher = chokidar_1.default.watch(path, {
43
+ ignoreInitial: true,
44
+ ignored: this.ignorePaths,
45
+ });
43
46
  watcher.on('all', (eventType, changedPath) => this.fileChanged(path, changedPath, eventType, changeCallback, errorCallback));
44
47
  this.watchers[String(path)] = watcher;
45
48
  }
@@ -67,7 +70,10 @@ class Watcher {
67
70
  try {
68
71
  if (fs.existsSync(listenerPath)) {
69
72
  const newEventType = this.convertEventType(eventType);
70
- this.filesChanged[String(changedPath)] = { eventType: newEventType, path: changedPath };
73
+ this.filesChanged[String(changedPath)] = {
74
+ eventType: newEventType,
75
+ path: changedPath,
76
+ };
71
77
  // Since multiple changes can occur at the same time, lets wait a bit before processing.
72
78
  if (this.fsWait) {
73
79
  return;
@@ -0,0 +1,6 @@
1
+ import winston from 'winston';
2
+ declare const logger: winston.Logger;
3
+ declare const stream: {
4
+ write: (message: string) => void;
5
+ };
6
+ export { logger, stream };
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stream = exports.logger = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const config_1 = tslib_1.__importDefault(require("config"));
6
+ const fs_1 = tslib_1.__importDefault(require("fs"));
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const winston_1 = tslib_1.__importDefault(require("winston"));
9
+ const logDir = path_1.default.join(__dirname, config_1.default.get('log.dir'));
10
+ if (!fs_1.default.existsSync(logDir)) {
11
+ fs_1.default.mkdirSync(logDir);
12
+ }
13
+ /*
14
+ * Log Level
15
+ * error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6
16
+ */
17
+ const logger = winston_1.default.createLogger({
18
+ format: winston_1.default.format.combine(winston_1.default.format.timestamp({
19
+ format: 'YYYY-MM-DD HH:mm:ss',
20
+ }),
21
+ // Define log format
22
+ winston_1.default.format.printf(({ timestamp, level, message }) => `${timestamp} ${level}: ${message}`)),
23
+ });
24
+ exports.logger = logger;
25
+ logger.add(new winston_1.default.transports.Console({
26
+ format: winston_1.default.format.combine(winston_1.default.format.splat(), winston_1.default.format.colorize()),
27
+ }));
28
+ const stream = {
29
+ write: (message) => {
30
+ logger.info(message.substring(0, message.lastIndexOf('\n')));
31
+ },
32
+ };
33
+ exports.stream = stream;
@@ -0,0 +1 @@
1
+ export declare function retrieveLangauge(content: string): 'json' | 'yaml';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.retrieveLangauge = retrieveLangauge;
4
+ function retrieveLangauge(content) {
5
+ if (content.trim()[0] === '{') {
6
+ return 'json';
7
+ }
8
+ return 'yaml';
9
+ }
@@ -0,0 +1,2 @@
1
+ export declare function createTempDirectory(): Promise<string>;
2
+ export declare function removeTempDirectory(tmpDir: string): Promise<void>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTempDirectory = createTempDirectory;
4
+ exports.removeTempDirectory = removeTempDirectory;
5
+ const tslib_1 = require("tslib");
6
+ const os_1 = tslib_1.__importDefault(require("os"));
7
+ const fs_1 = tslib_1.__importStar(require("fs"));
8
+ const path_1 = tslib_1.__importDefault(require("path"));
9
+ const uuid_1 = require("uuid");
10
+ const logger_1 = require("./logger");
11
+ function createTempDirectory() {
12
+ return fs_1.promises.mkdtemp(path_1.default.join(os_1.default.tmpdir(), (0, uuid_1.v4)()));
13
+ }
14
+ function removeTempDirectory(tmpDir) {
15
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
16
+ try {
17
+ tmpDir &&
18
+ fs_1.default.existsSync(tmpDir) &&
19
+ (yield fs_1.promises.rm(tmpDir, { recursive: true }));
20
+ }
21
+ catch (e) {
22
+ logger_1.logger.error(`An error has occurred while removing the temp folder at ${tmpDir}. Please remove it manually. Error: ${e}`);
23
+ }
24
+ });
25
+ }