@asyncapi/generator 1.13.1 → 1.14.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/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,7 +26,15 @@ 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
- * [.generate(asyncapiDocument, [parseOptions])](#Generator+generate) ⇒ `Promise`
29
+ * [.generate(asyncapiDocument, [parseOptions])](#Generator+generate) ⇒ `Promise.<void>`
30
+ * [.validateAsyncAPIDocument(asyncapiDocument)](#Generator+validateAsyncAPIDocument)
31
+ * [.setupOutput()](#Generator+setupOutput)
32
+ * [.setupFSOutput()](#Generator+setupFSOutput) ⇒ `Promise.<void>`
33
+ * [.setLogLevel()](#Generator+setLogLevel) ⇒ `void`
34
+ * [.installAndSetupTemplate()](#Generator+installAndSetupTemplate) ⇒ `Promise.<{templatePkgName: string, templatePkgPath: string}>`
35
+ * [.configureTemplateWorkflow(parseOptions)](#Generator+configureTemplateWorkflow) ⇒ `Promise.<void>`
36
+ * [.handleEntrypoint()](#Generator+handleEntrypoint) ⇒ `Promise.<void>`
37
+ * [.executeAfterHook()](#Generator+executeAfterHook) ⇒ `Promise.<void>`
30
38
  * [.parseInput()](#Generator+parseInput)
31
39
  * [.configureTemplate()](#Generator+configureTemplate)
32
40
  * ~~[.generateFromString(asyncapiString, [parseOptions])](#Generator+generateFromString) ⇒ `Promise`~~
@@ -169,11 +177,19 @@ The template parameters. The structure for this object is based on each individu
169
177
  Generates files from a given template and an AsyncAPIDocument object.
170
178
 
171
179
  **Kind**: instance method of [`Generator`](#Generator)
180
+ **Returns**: `Promise.<void>` - A Promise that resolves when the generation is completed.
172
181
  **Params**
173
182
 
174
183
  - 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.
184
+ - [parseOptions] `Object` ` = {}` - AsyncAPI Parser parse options.
185
+ Check out [@asyncapi/parser](https://www.github.com/asyncapi/parser-js) for more information.
186
+ Remember to use the right options for the right parser depending on the template you are using.
176
187
 
188
+ **Example**
189
+ ```js
190
+ await generator.generate(myAsyncAPIdocument);
191
+ console.log('Done!');
192
+ ```
177
193
  **Example**
178
194
  ```js
179
195
  generator
@@ -193,6 +209,118 @@ try {
193
209
  }
194
210
  ```
195
211
 
212
+ <a name="Generator+validateAsyncAPIDocument"></a>
213
+
214
+ ### generator.validateAsyncAPIDocument
215
+ Validates the provided AsyncAPI document.
216
+
217
+ **Kind**: instance method of [`Generator`](#Generator)
218
+ **Throws**:
219
+
220
+ - `Error` Throws an error if the document is not valid.
221
+
222
+ **Since**: 10/9/2023 - 4:26:33 PM
223
+ **Params**
224
+
225
+ - asyncapiDocument `*` - The AsyncAPI document to be validated.
226
+
227
+
228
+ <a name="Generator+setupOutput"></a>
229
+
230
+ * generator.setupOutput()** :
231
+ Sets up the output configuration based on the specified output type.
232
+
233
+ **Kind**: instance method of [`Generator`](#Generator)
234
+ **Throws**:
235
+
236
+ - `Error` If 'output' is set to 'string' without providing 'entrypoint'.
237
+
238
+ **Example**
239
+ ```js
240
+ const generator = new Generator();
241
+ generator.setupOutput();
242
+ ```
243
+
244
+ <a name="Generator+setupFSOutput"></a>
245
+
246
+ * generator.setupFSOutput() ⇒ `Promise.<void>`** :
247
+ Sets up the file system (FS) output configuration.
248
+
249
+ This function creates the target directory if it does not exist and verifies
250
+ the target directory if forceWrite is not enabled.
251
+
252
+ **Kind**: instance method of [`Generator`](#Generator)
253
+ **Returns**: `Promise.<void>` - A promise that fulfills when the setup is complete.
254
+ **Throws**:
255
+
256
+ - `Error` If verification of the target directory fails and forceWrite is not enabled.
257
+
258
+
259
+ <a name="Generator+setLogLevel"></a>
260
+
261
+ * generator.setLogLevel() ⇒ `void`** :
262
+ Sets the log level based on the debug option.
263
+
264
+ If the debug option is enabled, the log level is set to 'debug'.
265
+
266
+ **Kind**: instance method of [`Generator`](#Generator)
267
+
268
+ <a name="Generator+installAndSetupTemplate"></a>
269
+
270
+ * generator.installAndSetupTemplate() ⇒ `Promise.<{templatePkgName: string, templatePkgPath: string}>`** :
271
+ Installs and sets up the template for code generation.
272
+
273
+ This function installs the specified template using the provided installation option,
274
+ sets up the necessary directory paths, loads the template configuration, and returns
275
+ information about the installed template.
276
+
277
+ **Kind**: instance method of [`Generator`](#Generator)
278
+ **Returns**: `Promise.<{templatePkgName: string, templatePkgPath: string}>` - A promise that resolves to an object containing the name and path of the installed template.
279
+
280
+ <a name="Generator+configureTemplateWorkflow"></a>
281
+
282
+ ### generator.configureTemplateWorkflow
283
+ Configures the template workflow based on provided parsing options.
284
+
285
+ This function performs the following steps:
286
+ 1. Parses the input AsyncAPI document using the specified parse options.
287
+ 2. Validates the template configuration and parameters.
288
+ 3. Configures the template based on the parsed AsyncAPI document.
289
+ 4. Registers filters, hooks, and launches the 'generate:before' hook if applicable.
290
+
291
+ **Kind**: instance method of [`Generator`](#Generator)
292
+ **Returns**: `Promise.<void>` - A promise that resolves when the configuration is completed.
293
+ **Params**
294
+
295
+ - parseOptions `*` - Options for parsing the AsyncAPI document.
296
+
297
+
298
+ <a name="Generator+handleEntrypoint"></a>
299
+
300
+ * generator.handleEntrypoint() ⇒ `Promise.<void>`** :
301
+ Handles the logic for the template entrypoint.
302
+
303
+ If an entrypoint is specified:
304
+ - Resolves the absolute path of the entrypoint file.
305
+ - Throws an error if the entrypoint file doesn't exist.
306
+ - Generates a file or renders content based on the output type.
307
+ - Launches the 'generate:after' hook if the output is 'fs'.
308
+
309
+ If no entrypoint is specified, generates the directory structure.
310
+
311
+ **Kind**: instance method of [`Generator`](#Generator)
312
+ **Returns**: `Promise.<void>` - A promise that resolves when the entrypoint logic is completed.
313
+
314
+ <a name="Generator+executeAfterHook"></a>
315
+
316
+ * generator.executeAfterHook() ⇒ `Promise.<void>`** :
317
+ Executes the 'generate:after' hook.
318
+
319
+ Launches the after-hook to perform additional actions after code generation.
320
+
321
+ **Kind**: instance method of [`Generator`](#Generator)
322
+ **Returns**: `Promise.<void>` - A promise that resolves when the after-hook execution is completed.
323
+
196
324
  <a name="Generator+parseInput"></a>
197
325
 
198
326
  * generator.parseInput()** :
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 {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.
160
- * @return {Promise}
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
- xfs.mkdirpSync(this.targetDir);
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
- await this.parseInput(this.asyncapi, parseOptions);
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
- if (!(await exists(entrypointPath))) throw new Error(`Template entrypoint "${entrypointPath}" couldn't be found.`);
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asyncapi/generator",
3
- "version": "1.13.1",
3
+ "version": "1.14.1",
4
4
  "description": "The AsyncAPI generator. It can generate documentation, code, anything!",
5
5
  "main": "./lib/generator.js",
6
6
  "bin": {
@@ -49,7 +49,7 @@
49
49
  "homepage": "https://github.com/asyncapi/generator",
50
50
  "dependencies": {
51
51
  "@asyncapi/generator-react-sdk": "^0.2.23",
52
- "@asyncapi/parser": "2.1.0",
52
+ "@asyncapi/parser": "^2.1.1",
53
53
  "@npmcli/arborist": "^2.2.4",
54
54
  "@smoya/multi-parser": "^4.0.0",
55
55
  "ajv": "^8.12.0",