@asyncapi/generator 1.12.0 → 1.13.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.
@@ -1,2 +1,2 @@
1
1
  #we need to explicitly exclude them as some are commit to the repo
2
- sonar.exclusions=test/test-project/node_modules/@asyncapi/html-template/**/*
2
+ sonar.exclusions=test/**/*
package/lib/generator.js CHANGED
@@ -155,13 +155,19 @@ class Generator {
155
155
  * console.error(e);
156
156
  * }
157
157
  *
158
- * @param {AsyncAPIDocument} asyncapiDocument AsyncAPIDocument object to use as source.
158
+ * @param {AsyncAPIDocument | string} asyncapiDocument AsyncAPIDocument object to use as source.
159
+ * @param {Object} [parseOptions={}] AsyncAPI Parser parse options. Check out {@link https://www.github.com/asyncapi/parser-js|@asyncapi/parser} for more information. Remember to use the right options to the right parser depending on the template you are using.
159
160
  * @return {Promise}
160
161
  */
161
- async generate(asyncapiDocument) {
162
- if (!isAsyncAPIDocument(asyncapiDocument)) throw new Error('Parameter "asyncapiDocument" must be an AsyncAPIDocument object.');
162
+ // eslint-disable-next-line sonarjs/cognitive-complexity
163
+ async generate(asyncapiDocument, parseOptions = {}) {
164
+ const isAlreadyParsedDocument = isAsyncAPIDocument(asyncapiDocument);
165
+ const isParsableCompatible = asyncapiDocument && typeof asyncapiDocument === 'string';
166
+ if (!isAlreadyParsedDocument && !isParsableCompatible) {
167
+ throw new Error('Parameter "asyncapiDocument" must be a non-empty string or an already parsed AsyncAPI document.');
168
+ }
169
+ this.asyncapi = this.originalAsyncAPI = asyncapiDocument;
163
170
 
164
- this.asyncapi = asyncapiDocument;
165
171
  if (this.output === 'fs') {
166
172
  xfs.mkdirpSync(this.targetDir);
167
173
  if (!this.forceWrite) await this.verifyTargetDir(this.targetDir);
@@ -176,11 +182,11 @@ class Generator {
176
182
  this.templateName = templatePkgName;
177
183
  this.templateContentDir = path.resolve(this.templateDir, TEMPLATE_CONTENT_DIRNAME);
178
184
  await this.loadTemplateConfig();
179
- validateTemplateConfig(this.templateConfig, this.templateParams, asyncapiDocument);
180
- await this.configureTemplate();
181
185
 
182
- // use the expected document API based on `templateConfig.apiVersion` value
183
- this.asyncapi = asyncapiDocument = getProperApiDocument(asyncapiDocument, this.templateConfig);
186
+ await this.parseInput(this.asyncapi, parseOptions);
187
+
188
+ validateTemplateConfig(this.templateConfig, this.templateParams, this.asyncapi);
189
+ await this.configureTemplate();
184
190
 
185
191
  if (!isReactTemplate(this.templateConfig)) {
186
192
  await registerFilters(this.nunjucks, this.templateConfig, this.templateDir, FILTERS_DIRNAME);
@@ -192,17 +198,38 @@ class Generator {
192
198
  const entrypointPath = path.resolve(this.templateContentDir, this.entrypoint);
193
199
  if (!(await exists(entrypointPath))) throw new Error(`Template entrypoint "${entrypointPath}" couldn't be found.`);
194
200
  if (this.output === 'fs') {
195
- await this.generateFile(asyncapiDocument, path.basename(entrypointPath), path.dirname(entrypointPath));
201
+ await this.generateFile(this.asyncapi, path.basename(entrypointPath), path.dirname(entrypointPath));
196
202
  await this.launchHook('generate:after');
197
203
  } else if (this.output === 'string') {
198
- return this.renderFile(asyncapiDocument, entrypointPath);
204
+ return this.renderFile(this.asyncapi, entrypointPath);
199
205
  }
200
206
  } else {
201
- await this.generateDirectoryStructure(asyncapiDocument);
207
+ await this.generateDirectoryStructure(this.asyncapi);
202
208
  await this.launchHook('generate:after');
203
209
  }
204
210
  }
205
211
 
212
+ /**
213
+ * Parse the generator input based on the template `templateConfig.apiVersion` value.
214
+ */
215
+ async parseInput(asyncapiDocument, parseOptions = {}) {
216
+ const isAlreadyParsedDocument = isAsyncAPIDocument(asyncapiDocument);
217
+ // use the expected document API based on `templateConfig.apiVersion` value
218
+ if (isAlreadyParsedDocument) {
219
+ this.asyncapi = getProperApiDocument(asyncapiDocument, this.templateConfig);
220
+ } else {
221
+ /** @type {AsyncAPIDocument} Parsed AsyncAPI schema. See {@link https://github.com/asyncapi/parser-js/blob/master/API.md#module_@asyncapi/parser+AsyncAPIDocument|AsyncAPIDocument} for details on object structure. */
222
+ const { document, diagnostics } = await parse(asyncapiDocument, parseOptions, this);
223
+ if (!document) {
224
+ const err = new Error('Input is not a correct AsyncAPI document so it cannot be processed.');
225
+ err.diagnostics = diagnostics;
226
+ throw err;
227
+ } else {
228
+ this.asyncapi = document;
229
+ }
230
+ }
231
+ }
232
+
206
233
  /**
207
234
  * Configure the templates based the desired renderer.
208
235
  */
@@ -250,22 +277,15 @@ class Generator {
250
277
  *
251
278
  * @param {String} asyncapiString AsyncAPI string to use as source.
252
279
  * @param {Object} [parseOptions={}] AsyncAPI Parser parse options. Check out {@link https://www.github.com/asyncapi/parser-js|@asyncapi/parser} for more information.
280
+ * @deprecated Use the `generate` function instead. Just change the function name and it works out of the box.
253
281
  * @return {Promise}
254
282
  */
255
283
  async generateFromString(asyncapiString, parseOptions = {}) {
256
- if (!asyncapiString || typeof asyncapiString !== 'string') throw new Error('Parameter "asyncapiString" must be a non-empty string.');
257
-
258
- /** @type {String} AsyncAPI string to use as a source. */
259
- this.originalAsyncAPI = asyncapiString;
260
-
261
- /** @type {AsyncAPIDocument} Parsed AsyncAPI schema. See {@link https://github.com/asyncapi/parser-js/blob/master/API.md#module_@asyncapi/parser+AsyncAPIDocument|AsyncAPIDocument} for details on object structure. */
262
- const { document, diagnostics } = await parse(asyncapiString, parseOptions, this);
263
- if (!document) {
264
- const err = new Error('Input is not a correct AsyncAPI document so it cannot be processed.');
265
- err.diagnostics = diagnostics;
266
- throw err;
284
+ const isParsableCompatible = asyncapiString && typeof asyncapiString === 'string';
285
+ if (!isParsableCompatible) {
286
+ throw new Error('Parameter "asyncapiString" must be a non-empty string.');
267
287
  }
268
- return this.generate(document);
288
+ return this.generate(asyncapiString, parseOptions);
269
289
  }
270
290
 
271
291
  /**
@@ -292,7 +312,7 @@ class Generator {
292
312
  */
293
313
  async generateFromURL(asyncapiURL) {
294
314
  const doc = await fetchSpec(asyncapiURL);
295
- return this.generateFromString(doc, { path: asyncapiURL });
315
+ return this.generate(doc, { path: asyncapiURL });
296
316
  }
297
317
 
298
318
  /**
@@ -319,7 +339,7 @@ class Generator {
319
339
  */
320
340
  async generateFromFile(asyncapiFile) {
321
341
  const doc = await readFile(asyncapiFile, { encoding: 'utf8' });
322
- return this.generateFromString(doc, { path: asyncapiFile });
342
+ return this.generate(doc, { path: asyncapiFile });
323
343
  }
324
344
 
325
345
  /**
@@ -416,7 +436,6 @@ class Generator {
416
436
  */
417
437
  getAllParameters(asyncapiDocument) {
418
438
  const parameters = new Map();
419
-
420
439
  if (usesNewAPI(this.templateConfig)) {
421
440
  asyncapiDocument.channels().all().forEach(channel => {
422
441
  channel.parameters().all().forEach(parameter => {
package/lib/parser.js CHANGED
@@ -5,16 +5,16 @@ const { ConvertDocumentParserAPIVersion, NewParser } = require('@smoya/multi-par
5
5
  const parser = module.exports;
6
6
 
7
7
  /**
8
- * Conver the template defined value `apiVersion: 'v1'` to only contain the numeric value `1`.
8
+ * Convert the template defined value `apiVersion: 'v1'` to only contain the numeric value `1`.
9
9
  */
10
10
  parser.sanitizeTemplateApiVersion = (apiVersion) => {
11
11
  if (apiVersion && apiVersion.length > 1) {
12
- return apiVersion.substring('1');
12
+ return apiVersion.substring(1);
13
13
  }
14
14
  return apiVersion;
15
15
  };
16
16
 
17
- parser.parse = (asyncapi, oldOptions, generator) => {
17
+ parser.parse = async (asyncapi, oldOptions, generator) => {
18
18
  let apiVersion = this.sanitizeTemplateApiVersion(generator.templateConfig.apiVersion);
19
19
  // Defaulting to apiVersion v1 to convert it to the Parser-API v1 afterwards.
20
20
  if (!this.usesNewAPI(generator.templateConfig)) {
@@ -22,7 +22,12 @@ parser.parse = (asyncapi, oldOptions, generator) => {
22
22
  }
23
23
  const options = convertOldOptionsToNew(oldOptions, generator);
24
24
  const parser = NewParser(apiVersion, {parserOptions: options, includeSchemaParsers: true});
25
- return parser.parse(asyncapi, options);
25
+ const { document, diagnostics } = await parser.parse(asyncapi, options);
26
+ if (!document) {
27
+ return {document, diagnostics};
28
+ }
29
+ const correctDocument = this.getProperApiDocument(document, generator.templateConfig);
30
+ return {document: correctDocument, diagnostics};
26
31
  };
27
32
 
28
33
  /**
@@ -2,6 +2,9 @@ const semver = require('semver');
2
2
  const Ajv = require('ajv');
3
3
  const { getGeneratorVersion } = require('./utils');
4
4
  const levenshtein = require('levenshtein-edit-distance');
5
+ // eslint-disable-next-line no-unused-vars
6
+ const {AsyncAPIDocumentInterface, AsyncAPIDocument} = require('@asyncapi/parser');
7
+ const { usesNewAPI } = require('./parser');
5
8
 
6
9
  const ajv = new Ajv({ allErrors: true });
7
10
 
@@ -12,13 +15,13 @@ const supportedParserAPIMajorVersions = [
12
15
  ];
13
16
 
14
17
  /**
15
- * Validates the template configuration.
16
- *
17
- * @param {Object} templateConfig Template configuration.
18
- * @param {Object} templateParams Params specified when running generator.
19
- * @param {AsyncAPIDocument} asyncapiDocument AsyncAPIDocument object to use as source.
20
- * @return {Boolean}
21
- */
18
+ * Validates the template configuration.
19
+ *
20
+ * @param {Object} templateConfig Template configuration.
21
+ * @param {Object} templateParams Params specified when running generator.
22
+ * @param {AsyncAPIDocumentInterface | AsyncAPIDocument} asyncapiDocument AsyncAPIDocument object to use as source.
23
+ * @return {Boolean}
24
+ */
22
25
  module.exports.validateTemplateConfig = (templateConfig, templateParams, asyncapiDocument) => {
23
26
  const { parameters, supportedProtocols, conditionalFiles, generator, apiVersion } = templateConfig;
24
27
 
@@ -26,10 +29,15 @@ module.exports.validateTemplateConfig = (templateConfig, templateParams, asyncap
26
29
  isTemplateCompatible(generator, apiVersion);
27
30
  isRequiredParamProvided(parameters, templateParams);
28
31
  isProvidedTemplateRendererSupported(templateConfig);
29
- if (asyncapiDocument) {
30
- const server = asyncapiDocument.servers().get(templateParams.server);
31
- isServerProvidedInDocument(server, templateParams.server);
32
+ if (asyncapiDocument && templateParams.server) {
33
+ let server;
34
+ if (usesNewAPI(templateConfig)) {
35
+ server = asyncapiDocument.servers().get(templateParams.server);
36
+ } else {
37
+ server = asyncapiDocument.servers()[templateParams.server];
38
+ }
32
39
  isServerProtocolSupported(server, supportedProtocols, templateParams.server);
40
+ isServerProvidedInDocument(server, templateParams.server);
33
41
  }
34
42
 
35
43
  isProvidedParameterSupported(parameters, templateParams);
@@ -49,7 +57,7 @@ function isTemplateCompatible(generator, apiVersion) {
49
57
  }
50
58
 
51
59
  if (typeof apiVersion === 'string' && !supportedParserAPIMajorVersions.includes(apiVersion)) {
52
- throw new Error(`The version specified in apiVersion is not supported by this Generator version. Supported versions are: ${supportedParserAPIMajorVersions.toString()}`);
60
+ throw new Error(`The version specified in apiVersion is not supported by this Generator version. Supported versions are: ${supportedParserAPIMajorVersions.join(', ')}`);
53
61
  }
54
62
  }
55
63
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asyncapi/generator",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "The AsyncAPI generator. It can generate documentation, code, anything!",
5
5
  "main": "./lib/generator.js",
6
6
  "bin": {