@asyncapi/generator 1.12.0 → 1.13.1
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/.sonarcloud.properties +1 -1
- package/docs/api.md +15 -12
- package/lib/generator.js +45 -26
- package/lib/parser.js +13 -7
- package/lib/templateConfigValidator.js +19 -11
- package/package.json +2 -2
package/.sonarcloud.properties
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#we need to explicitly exclude them as some are commit to the repo
|
|
2
|
-
sonar.exclusions=test
|
|
2
|
+
sonar.exclusions=test/**/*
|
package/docs/api.md
CHANGED
|
@@ -26,10 +26,10 @@ Reference API documentation for AsyncAPI Generator library.
|
|
|
26
26
|
* [.hooks](#Generator+hooks) : `Object`
|
|
27
27
|
* [.mapBaseUrlToFolder](#Generator+mapBaseUrlToFolder) : `Object`
|
|
28
28
|
* [.templateParams](#Generator+templateParams) : `Object`
|
|
29
|
-
* [.
|
|
30
|
-
* [.
|
|
29
|
+
* [.generate(asyncapiDocument, [parseOptions])](#Generator+generate) ⇒ `Promise`
|
|
30
|
+
* [.parseInput()](#Generator+parseInput)
|
|
31
31
|
* [.configureTemplate()](#Generator+configureTemplate)
|
|
32
|
-
* [.generateFromString(asyncapiString, [parseOptions])](#Generator+generateFromString) ⇒ `Promise
|
|
32
|
+
* ~~[.generateFromString(asyncapiString, [parseOptions])](#Generator+generateFromString) ⇒ `Promise`~~
|
|
33
33
|
* [.generateFromURL(asyncapiURL)](#Generator+generateFromURL) ⇒ `Promise`
|
|
34
34
|
* [.generateFromFile(asyncapiFile)](#Generator+generateFromFile) ⇒ `Promise`
|
|
35
35
|
* [.installTemplate([force])](#Generator+installTemplate)
|
|
@@ -163,13 +163,6 @@ The template parameters. The structure for this object is based on each individu
|
|
|
163
163
|
|
|
164
164
|
**Kind**: instance property of [`Generator`](#Generator)
|
|
165
165
|
|
|
166
|
-
<a name="Generator+originalAsyncAPI"></a>
|
|
167
|
-
|
|
168
|
-
* generator.originalAsyncAPI : `String`** :
|
|
169
|
-
AsyncAPI string to use as a source.
|
|
170
|
-
|
|
171
|
-
**Kind**: instance property of [`Generator`](#Generator)
|
|
172
|
-
|
|
173
166
|
<a name="Generator+generate"></a>
|
|
174
167
|
|
|
175
168
|
### generator.generate
|
|
@@ -178,7 +171,8 @@ Generates files from a given template and an AsyncAPIDocument object.
|
|
|
178
171
|
**Kind**: instance method of [`Generator`](#Generator)
|
|
179
172
|
**Params**
|
|
180
173
|
|
|
181
|
-
- asyncapiDocument `AsyncAPIDocument` - AsyncAPIDocument object to use as source.
|
|
174
|
+
- asyncapiDocument `AsyncAPIDocument` | `string` - AsyncAPIDocument object to use as source.
|
|
175
|
+
- [parseOptions] `Object` ` = {}` - AsyncAPI Parser parse options. Check out [@asyncapi/parser](https://www.github.com/asyncapi/parser-js) for more information. Remember to use the right options to the right parser depending on the template you are using.
|
|
182
176
|
|
|
183
177
|
**Example**
|
|
184
178
|
```js
|
|
@@ -199,6 +193,13 @@ try {
|
|
|
199
193
|
}
|
|
200
194
|
```
|
|
201
195
|
|
|
196
|
+
<a name="Generator+parseInput"></a>
|
|
197
|
+
|
|
198
|
+
* generator.parseInput()** :
|
|
199
|
+
Parse the generator input based on the template `templateConfig.apiVersion` value.
|
|
200
|
+
|
|
201
|
+
**Kind**: instance method of [`Generator`](#Generator)
|
|
202
|
+
|
|
202
203
|
<a name="Generator+configureTemplate"></a>
|
|
203
204
|
|
|
204
205
|
* generator.configureTemplate()** :
|
|
@@ -208,7 +209,9 @@ Configure the templates based the desired renderer.
|
|
|
208
209
|
|
|
209
210
|
<a name="Generator+generateFromString"></a>
|
|
210
211
|
|
|
211
|
-
### generator.generateFromString
|
|
212
|
+
### ~~generator.generateFromString~~
|
|
213
|
+
***Deprecated***
|
|
214
|
+
|
|
212
215
|
Generates files from a given template and AsyncAPI string.
|
|
213
216
|
|
|
214
217
|
**Kind**: instance method of [`Generator`](#Generator)
|
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
|
-
|
|
162
|
-
|
|
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
|
-
|
|
183
|
-
|
|
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(
|
|
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(
|
|
204
|
+
return this.renderFile(this.asyncapi, entrypointPath);
|
|
199
205
|
}
|
|
200
206
|
} else {
|
|
201
|
-
await this.generateDirectoryStructure(
|
|
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
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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(
|
|
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.
|
|
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.
|
|
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,31 +5,37 @@ const { ConvertDocumentParserAPIVersion, NewParser } = require('@smoya/multi-par
|
|
|
5
5
|
const parser = module.exports;
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Convert the template defined value `apiVersion: 'v1'` to only contain the numeric value `1`.
|
|
9
9
|
*/
|
|
10
10
|
parser.sanitizeTemplateApiVersion = (apiVersion) => {
|
|
11
|
+
if (!apiVersion) return;
|
|
11
12
|
if (apiVersion && apiVersion.length > 1) {
|
|
12
|
-
return apiVersion.substring(
|
|
13
|
+
return Number(apiVersion.substring(1));
|
|
13
14
|
}
|
|
14
|
-
return apiVersion;
|
|
15
|
+
return Number(apiVersion);
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
parser.parse = (asyncapi, oldOptions, generator) => {
|
|
18
|
+
parser.parse = async (asyncapi, oldOptions, generator) => {
|
|
18
19
|
let apiVersion = this.sanitizeTemplateApiVersion(generator.templateConfig.apiVersion);
|
|
19
20
|
// Defaulting to apiVersion v1 to convert it to the Parser-API v1 afterwards.
|
|
20
21
|
if (!this.usesNewAPI(generator.templateConfig)) {
|
|
21
|
-
apiVersion =
|
|
22
|
+
apiVersion = 1;
|
|
22
23
|
}
|
|
23
24
|
const options = convertOldOptionsToNew(oldOptions, generator);
|
|
24
25
|
const parser = NewParser(apiVersion, {parserOptions: options, includeSchemaParsers: true});
|
|
25
|
-
|
|
26
|
+
const { document, diagnostics } = await parser.parse(asyncapi, options);
|
|
27
|
+
if (!document) {
|
|
28
|
+
return {document, diagnostics};
|
|
29
|
+
}
|
|
30
|
+
const correctDocument = this.getProperApiDocument(document, generator.templateConfig);
|
|
31
|
+
return {document: correctDocument, diagnostics};
|
|
26
32
|
};
|
|
27
33
|
|
|
28
34
|
/**
|
|
29
35
|
* If the template expect one of the Parser-API versions, it must be above 0
|
|
30
36
|
*/
|
|
31
37
|
parser.usesNewAPI = (templateConfig = {}) => {
|
|
32
|
-
return
|
|
38
|
+
return this.sanitizeTemplateApiVersion(templateConfig.apiVersion) > 0;
|
|
33
39
|
};
|
|
34
40
|
|
|
35
41
|
/**
|
|
@@ -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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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.
|
|
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.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "The AsyncAPI generator. It can generate documentation, code, anything!",
|
|
5
5
|
"main": "./lib/generator.js",
|
|
6
6
|
"bin": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@asyncapi/generator-react-sdk": "^0.2.23",
|
|
52
52
|
"@asyncapi/parser": "2.1.0",
|
|
53
53
|
"@npmcli/arborist": "^2.2.4",
|
|
54
|
-
"@smoya/multi-parser": "
|
|
54
|
+
"@smoya/multi-parser": "^4.0.0",
|
|
55
55
|
"ajv": "^8.12.0",
|
|
56
56
|
"chokidar": "^3.4.0",
|
|
57
57
|
"commander": "^6.1.0",
|