@asyncapi/generator 1.13.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +3 -1
- package/docs/api.md +15 -12
- package/lib/generator.js +139 -9
- package/lib/parser.js +5 -4
- package/package.json +2 -2
package/Dockerfile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
ARG ASYNCAPI_GENERATOR_VERSION=1.10.9
|
|
2
|
+
|
|
1
3
|
FROM node:14-alpine
|
|
2
4
|
|
|
3
5
|
WORKDIR /app
|
|
@@ -14,6 +16,6 @@ RUN apk --update add git chromium && \
|
|
|
14
16
|
rm /var/cache/apk/*
|
|
15
17
|
|
|
16
18
|
# Installing latest released npm package
|
|
17
|
-
RUN npm install -g @asyncapi/generator
|
|
19
|
+
RUN npm install -g @asyncapi/generator@$ASYNCAPI_GENERATOR_VERSION
|
|
18
20
|
|
|
19
21
|
ENTRYPOINT [ "ag" ]
|
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
|
@@ -139,6 +139,11 @@ class Generator {
|
|
|
139
139
|
/**
|
|
140
140
|
* Generates files from a given template and an AsyncAPIDocument object.
|
|
141
141
|
*
|
|
142
|
+
* @async
|
|
143
|
+
* @example
|
|
144
|
+
* await generator.generate(myAsyncAPIdocument);
|
|
145
|
+
* console.log('Done!');
|
|
146
|
+
*
|
|
142
147
|
* @example
|
|
143
148
|
* generator
|
|
144
149
|
* .generate(myAsyncAPIdocument)
|
|
@@ -155,48 +160,162 @@ class Generator {
|
|
|
155
160
|
* console.error(e);
|
|
156
161
|
* }
|
|
157
162
|
*
|
|
158
|
-
* @param
|
|
159
|
-
* @param
|
|
160
|
-
* @
|
|
163
|
+
* @param {AsyncAPIDocument | string} asyncapiDocument - AsyncAPIDocument object to use as source.
|
|
164
|
+
* @param {Object} [parseOptions={}] - AsyncAPI Parser parse options.
|
|
165
|
+
* Check out {@link https://www.github.com/asyncapi/parser-js|@asyncapi/parser} for more information.
|
|
166
|
+
* Remember to use the right options for the right parser depending on the template you are using.
|
|
167
|
+
* @return {Promise<void>} A Promise that resolves when the generation is completed.
|
|
161
168
|
*/
|
|
162
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
163
169
|
async generate(asyncapiDocument, parseOptions = {}) {
|
|
170
|
+
this.validateAsyncAPIDocument(asyncapiDocument);
|
|
171
|
+
this.setupOutput();
|
|
172
|
+
this.setLogLevel();
|
|
173
|
+
|
|
174
|
+
await this.installAndSetupTemplate();
|
|
175
|
+
await this.configureTemplateWorkflow(parseOptions);
|
|
176
|
+
await this.handleEntrypoint();
|
|
177
|
+
await this.executeAfterHook();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Validates the provided AsyncAPI document.
|
|
182
|
+
*
|
|
183
|
+
* @param {*} asyncapiDocument - The AsyncAPI document to be validated.
|
|
184
|
+
* @throws {Error} Throws an error if the document is not valid.
|
|
185
|
+
* @since 10/9/2023 - 4:26:33 PM
|
|
186
|
+
*/
|
|
187
|
+
validateAsyncAPIDocument(asyncapiDocument) {
|
|
164
188
|
const isAlreadyParsedDocument = isAsyncAPIDocument(asyncapiDocument);
|
|
165
189
|
const isParsableCompatible = asyncapiDocument && typeof asyncapiDocument === 'string';
|
|
190
|
+
|
|
166
191
|
if (!isAlreadyParsedDocument && !isParsableCompatible) {
|
|
167
192
|
throw new Error('Parameter "asyncapiDocument" must be a non-empty string or an already parsed AsyncAPI document.');
|
|
168
193
|
}
|
|
194
|
+
|
|
169
195
|
this.asyncapi = this.originalAsyncAPI = asyncapiDocument;
|
|
196
|
+
}
|
|
170
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Sets up the output configuration based on the specified output type.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* const generator = new Generator();
|
|
203
|
+
* generator.setupOutput();
|
|
204
|
+
*
|
|
205
|
+
* @throws {Error} If 'output' is set to 'string' without providing 'entrypoint'.
|
|
206
|
+
*/
|
|
207
|
+
setupOutput() {
|
|
171
208
|
if (this.output === 'fs') {
|
|
172
|
-
|
|
173
|
-
if (!this.forceWrite) await this.verifyTargetDir(this.targetDir);
|
|
209
|
+
this.setupFSOutput();
|
|
174
210
|
} else if (this.output === 'string' && this.entrypoint === undefined) {
|
|
175
211
|
throw new Error('Parameter entrypoint is required when using output = "string"');
|
|
176
212
|
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Sets up the file system (FS) output configuration.
|
|
217
|
+
*
|
|
218
|
+
* This function creates the target directory if it does not exist and verifies
|
|
219
|
+
* the target directory if forceWrite is not enabled.
|
|
220
|
+
*
|
|
221
|
+
* @async
|
|
222
|
+
* @returns {Promise<void>} A promise that fulfills when the setup is complete.
|
|
223
|
+
*
|
|
224
|
+
* @throws {Error} If verification of the target directory fails and forceWrite is not enabled.
|
|
225
|
+
*/
|
|
226
|
+
async setupFSOutput() {
|
|
227
|
+
// Create directory if not exists
|
|
228
|
+
xfs.mkdirpSync(this.targetDir);
|
|
177
229
|
|
|
230
|
+
// Verify target directory if forceWrite is not enabled
|
|
231
|
+
if (!this.forceWrite) {
|
|
232
|
+
await this.verifyTargetDir(this.targetDir);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Sets the log level based on the debug option.
|
|
238
|
+
*
|
|
239
|
+
* If the debug option is enabled, the log level is set to 'debug'.
|
|
240
|
+
*
|
|
241
|
+
* @returns {void}
|
|
242
|
+
*/
|
|
243
|
+
setLogLevel() {
|
|
178
244
|
if (this.debug) log.setLevel('debug');
|
|
245
|
+
}
|
|
179
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Installs and sets up the template for code generation.
|
|
249
|
+
*
|
|
250
|
+
* This function installs the specified template using the provided installation option,
|
|
251
|
+
* sets up the necessary directory paths, loads the template configuration, and returns
|
|
252
|
+
* information about the installed template.
|
|
253
|
+
*
|
|
254
|
+
* @async
|
|
255
|
+
* @returns {Promise<{ templatePkgName: string, templatePkgPath: string }>}
|
|
256
|
+
* A promise that resolves to an object containing the name and path of the installed template.
|
|
257
|
+
*/
|
|
258
|
+
async installAndSetupTemplate() {
|
|
180
259
|
const { name: templatePkgName, path: templatePkgPath } = await this.installTemplate(this.install);
|
|
260
|
+
|
|
181
261
|
this.templateDir = templatePkgPath;
|
|
182
262
|
this.templateName = templatePkgName;
|
|
183
263
|
this.templateContentDir = path.resolve(this.templateDir, TEMPLATE_CONTENT_DIRNAME);
|
|
264
|
+
|
|
184
265
|
await this.loadTemplateConfig();
|
|
185
266
|
|
|
186
|
-
|
|
267
|
+
return { templatePkgName, templatePkgPath };
|
|
268
|
+
}
|
|
187
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Configures the template workflow based on provided parsing options.
|
|
272
|
+
*
|
|
273
|
+
* This function performs the following steps:
|
|
274
|
+
* 1. Parses the input AsyncAPI document using the specified parse options.
|
|
275
|
+
* 2. Validates the template configuration and parameters.
|
|
276
|
+
* 3. Configures the template based on the parsed AsyncAPI document.
|
|
277
|
+
* 4. Registers filters, hooks, and launches the 'generate:before' hook if applicable.
|
|
278
|
+
*
|
|
279
|
+
* @async
|
|
280
|
+
* @param {*} parseOptions - Options for parsing the AsyncAPI document.
|
|
281
|
+
* @returns {Promise<void>} A promise that resolves when the configuration is completed.
|
|
282
|
+
*/
|
|
283
|
+
async configureTemplateWorkflow(parseOptions) {
|
|
284
|
+
// Parse input and validate template configuration
|
|
285
|
+
await this.parseInput(this.asyncapi, parseOptions);
|
|
188
286
|
validateTemplateConfig(this.templateConfig, this.templateParams, this.asyncapi);
|
|
189
287
|
await this.configureTemplate();
|
|
190
288
|
|
|
191
289
|
if (!isReactTemplate(this.templateConfig)) {
|
|
192
290
|
await registerFilters(this.nunjucks, this.templateConfig, this.templateDir, FILTERS_DIRNAME);
|
|
193
291
|
}
|
|
292
|
+
|
|
194
293
|
await registerHooks(this.hooks, this.templateConfig, this.templateDir, HOOKS_DIRNAME);
|
|
195
294
|
await this.launchHook('generate:before');
|
|
295
|
+
}
|
|
196
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Handles the logic for the template entrypoint.
|
|
299
|
+
*
|
|
300
|
+
* If an entrypoint is specified:
|
|
301
|
+
* - Resolves the absolute path of the entrypoint file.
|
|
302
|
+
* - Throws an error if the entrypoint file doesn't exist.
|
|
303
|
+
* - Generates a file or renders content based on the output type.
|
|
304
|
+
* - Launches the 'generate:after' hook if the output is 'fs'.
|
|
305
|
+
*
|
|
306
|
+
* If no entrypoint is specified, generates the directory structure.
|
|
307
|
+
*
|
|
308
|
+
* @async
|
|
309
|
+
* @returns {Promise<void>} A promise that resolves when the entrypoint logic is completed.
|
|
310
|
+
*/
|
|
311
|
+
async handleEntrypoint() {
|
|
197
312
|
if (this.entrypoint) {
|
|
198
313
|
const entrypointPath = path.resolve(this.templateContentDir, this.entrypoint);
|
|
199
|
-
|
|
314
|
+
|
|
315
|
+
if (!(await exists(entrypointPath))) {
|
|
316
|
+
throw new Error(`Template entrypoint "${entrypointPath}" couldn't be found.`);
|
|
317
|
+
}
|
|
318
|
+
|
|
200
319
|
if (this.output === 'fs') {
|
|
201
320
|
await this.generateFile(this.asyncapi, path.basename(entrypointPath), path.dirname(entrypointPath));
|
|
202
321
|
await this.launchHook('generate:after');
|
|
@@ -205,10 +324,21 @@ class Generator {
|
|
|
205
324
|
}
|
|
206
325
|
} else {
|
|
207
326
|
await this.generateDirectoryStructure(this.asyncapi);
|
|
208
|
-
await this.launchHook('generate:after');
|
|
209
327
|
}
|
|
210
328
|
}
|
|
211
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Executes the 'generate:after' hook.
|
|
332
|
+
*
|
|
333
|
+
* Launches the after-hook to perform additional actions after code generation.
|
|
334
|
+
*
|
|
335
|
+
* @async
|
|
336
|
+
* @returns {Promise<void>} A promise that resolves when the after-hook execution is completed.
|
|
337
|
+
*/
|
|
338
|
+
async executeAfterHook() {
|
|
339
|
+
await this.launchHook('generate:after');
|
|
340
|
+
}
|
|
341
|
+
|
|
212
342
|
/**
|
|
213
343
|
* Parse the generator input based on the template `templateConfig.apiVersion` value.
|
|
214
344
|
*/
|
package/lib/parser.js
CHANGED
|
@@ -8,17 +8,18 @@ const parser = module.exports;
|
|
|
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(1);
|
|
13
|
+
return Number(apiVersion.substring(1));
|
|
13
14
|
}
|
|
14
|
-
return apiVersion;
|
|
15
|
+
return Number(apiVersion);
|
|
15
16
|
};
|
|
16
17
|
|
|
17
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});
|
|
@@ -34,7 +35,7 @@ parser.parse = async (asyncapi, oldOptions, generator) => {
|
|
|
34
35
|
* If the template expect one of the Parser-API versions, it must be above 0
|
|
35
36
|
*/
|
|
36
37
|
parser.usesNewAPI = (templateConfig = {}) => {
|
|
37
|
-
return
|
|
38
|
+
return this.sanitizeTemplateApiVersion(templateConfig.apiVersion) > 0;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asyncapi/generator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
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",
|