diff --git a/apps/generator/docs/api.md b/apps/generator/docs/api.md index b59a87e33..02bcf3a4d 100644 --- a/apps/generator/docs/api.md +++ b/apps/generator/docs/api.md @@ -8,47 +8,48 @@ Reference API documentation for AsyncAPI Generator library. ## Generator -**Kind**: global class - -* [Generator](#Generator) - * [new Generator(templateName, targetDir, options)](#new_Generator_new) - * _instance_ - * [.registry](#Generator+registry) : `Object` - * [.templateName](#Generator+templateName) : `String` - * [.targetDir](#Generator+targetDir) : `String` - * [.entrypoint](#Generator+entrypoint) : `String` - * [.noOverwriteGlobs](#Generator+noOverwriteGlobs) : `Array.` - * [.disabledHooks](#Generator+disabledHooks) : `Object.)>` - * [.output](#Generator+output) : `String` - * [.forceWrite](#Generator+forceWrite) : `Boolean` - * [.debug](#Generator+debug) : `Boolean` - * [.install](#Generator+install) : `Boolean` - * [.templateConfig](#Generator+templateConfig) : `Object` - * [.hooks](#Generator+hooks) : `Object` - * [.mapBaseUrlToFolder](#Generator+mapBaseUrlToFolder) : `Object` - * [.templateParams](#Generator+templateParams) : `Object` - * [.generate(asyncapiDocument, [parseOptions])](#Generator+generate) ⇒ `Promise.` - * [.validateAsyncAPIDocument(asyncapiDocument)](#Generator+validateAsyncAPIDocument) - * [.setupOutput()](#Generator+setupOutput) - * [.setupFSOutput()](#Generator+setupFSOutput) ⇒ `Promise.` - * [.setLogLevel()](#Generator+setLogLevel) ⇒ `void` - * [.installAndSetupTemplate()](#Generator+installAndSetupTemplate) ⇒ `Promise.<{templatePkgName: string, templatePkgPath: string}>` - * [.configureTemplateWorkflow(parseOptions)](#Generator+configureTemplateWorkflow) ⇒ `Promise.` - * [.handleEntrypoint()](#Generator+handleEntrypoint) ⇒ `Promise.` - * [.executeAfterHook()](#Generator+executeAfterHook) ⇒ `Promise.` - * [.parseInput()](#Generator+parseInput) - * [.configureTemplate()](#Generator+configureTemplate) - * ~~[.generateFromString(asyncapiString, [parseOptions])](#Generator+generateFromString) ⇒ `Promise`~~ - * [.generateFromURL(asyncapiURL)](#Generator+generateFromURL) ⇒ `Promise` - * [.generateFromFile(asyncapiFile)](#Generator+generateFromFile) ⇒ `Promise` - * [.installTemplate([force])](#Generator+installTemplate) - * _static_ - * [.getTemplateFile(templateName, filePath, [templatesDir])](#Generator.getTemplateFile) ⇒ `Promise` +**Kind**: global class + +- [Generator](#Generator) + - [new Generator(templateName, targetDir, options)](#new_Generator_new) + - _instance_ + - [.registry](#Generator+registry) : `Object` + - [.templateName](#Generator+templateName) : `String` + - [.targetDir](#Generator+targetDir) : `String` + - [.entrypoint](#Generator+entrypoint) : `String` + - [.noOverwriteGlobs](#Generator+noOverwriteGlobs) : `Array.` + - [.disabledHooks](#Generator+disabledHooks) : `Object.)>` + - [.output](#Generator+output) : `String` + - [.forceWrite](#Generator+forceWrite) : `Boolean` + - [.debug](#Generator+debug) : `Boolean` + - [.install](#Generator+install) : `Boolean` + - [.templateConfig](#Generator+templateConfig) : `Object` + - [.hooks](#Generator+hooks) : `Object` + - [.mapBaseUrlToFolder](#Generator+mapBaseUrlToFolder) : `Object` + - [.templateParams](#Generator+templateParams) : `Object` + - [.generate(asyncapiDocument, [parseOptions])](#Generator+generate) ⇒ `Promise.` + - [.validateAsyncAPIDocument(asyncapiDocument)](#Generator+validateAsyncAPIDocument) + - [.setupOutput()](#Generator+setupOutput) + - [.setupFSOutput()](#Generator+setupFSOutput) ⇒ `Promise.` + - [.setLogLevel()](#Generator+setLogLevel) ⇒ `void` + - [.installAndSetupTemplate()](#Generator+installAndSetupTemplate) ⇒ `Promise.<{templatePkgName: string, templatePkgPath: string}>` + - [.configureTemplateWorkflow(parseOptions)](#Generator+configureTemplateWorkflow) ⇒ `Promise.` + - [.handleEntrypoint()](#Generator+handleEntrypoint) ⇒ `Promise.` + - [.executeAfterHook()](#Generator+executeAfterHook) ⇒ `Promise.` + - [.parseInput()](#Generator+parseInput) + - [.configureTemplate()](#Generator+configureTemplate) + - ~~[.generateFromString(asyncapiString, [parseOptions])](#Generator+generateFromString) ⇒ `Promise`~~ + - [.generateFromURL(asyncapiURL)](#Generator+generateFromURL) ⇒ `Promise` + - [.generateFromFile(asyncapiFile)](#Generator+generateFromFile) ⇒ `Promise` + - [.installTemplate([force])](#Generator+installTemplate) + - _static_ + - [.getTemplateFile(templateName, filePath, [templatesDir])](#Generator.getTemplateFile) ⇒ `Promise` ### new Generator + Instantiates a new Generator object. **Params** @@ -56,136 +57,147 @@ Instantiates a new Generator object. - templateName `String` - Name of the template to generate. - targetDir `String` - Path to the directory where the files will be generated. - options `Object` - - [.templateParams] `Object.` - Optional parameters to pass to the template. Each template define their own params. - - [.entrypoint] `String` - Name of the file to use as the entry point for the rendering process. Use in case you want to use only a specific template file. Note: this potentially avoids rendering every file in the template. - - [.noOverwriteGlobs] `Array.` - List of globs to skip when regenerating the template. - - [.disabledHooks] `Object.)>` - Object with hooks to disable. The key is a hook type. If key has "true" value, then the generator skips all hooks from the given type. If the value associated with a key is a string with the name of a single hook, then the generator skips only this single hook name. If the value associated with a key is an array of strings, then the generator skips only hooks from the array. - - [.output] `String` ` = 'fs'` - Type of output. Can be either 'fs' (default) or 'string'. Only available when entrypoint is set. - - [.forceWrite] `Boolean` ` = false` - Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir. Default is set to false. - - [.install] `Boolean` ` = false` - Install the template and its dependencies, even when the template has already been installed. - - [.debug] `Boolean` ` = false` - Enable more specific errors in the console. At the moment it only shows specific errors about filters. Keep in mind that as a result errors about template are less descriptive. - - [.mapBaseUrlToFolder] `Object.` - Optional parameter to map schema references from a base url to a local base folder e.g. url=https://schema.example.com/crm/ folder=./test/docs/ . - - [.registry] `Object` - Optional parameter with private registry configuration - - [.url] `String` - Parameter to pass npm registry url - - [.auth] `String` - Optional parameter to pass npm registry username and password encoded with base64, formatted like username:password value should be encoded - - [.token] `String` - Optional parameter to pass npm registry auth token that you can grab from .npmrc file - -**Example** + - [.templateParams] `Object.` - Optional parameters to pass to the template. Each template define their own params. + - [.entrypoint] `String` - Name of the file to use as the entry point for the rendering process. Use in case you want to use only a specific template file. Note: this potentially avoids rendering every file in the template. + - [.noOverwriteGlobs] `Array.` - List of globs to skip when regenerating the template. + - [.disabledHooks] `Object.)>` - Object with hooks to disable. The key is a hook type. If key has "true" value, then the generator skips all hooks from the given type. If the value associated with a key is a string with the name of a single hook, then the generator skips only this single hook name. If the value associated with a key is an array of strings, then the generator skips only hooks from the array. + - [.output] `String` ` = 'fs'` - Type of output. Can be either 'fs' (default) or 'string'. Only available when entrypoint is set. + - [.forceWrite] `Boolean` ` = false` - Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir. Default is set to false. + - [.install] `Boolean` ` = false` - Install the template and its dependencies, even when the template has already been installed. + - [.debug] `Boolean` ` = false` - Enable more specific errors in the console. At the moment it only shows specific errors about filters. Keep in mind that as a result errors about template are less descriptive. + - [.mapBaseUrlToFolder] `Object.` - Optional parameter to map schema references from a base url to a local base folder e.g. url=https://schema.example.com/crm/ folder=./test/docs/ . + - [.registry] `Object` - Optional parameter with private registry configuration + - [.url] `String` - Parameter to pass npm registry url + - [.auth] `String` - Optional parameter to pass npm registry username and password encoded with base64, formatted like username:password value should be encoded + - [.token] `String` - Optional parameter to pass npm registry auth token that you can grab from .npmrc file + +**Example** + ```js -const path = require('path'); -const generator = new Generator('@asyncapi/html-template', path.resolve(__dirname, 'example')); +const path = require("path"); +const generator = new Generator( + "@asyncapi/html-template", + path.resolve(__dirname, "example") +); ``` -**Example** *(Passing custom params to the template)* + +**Example** _(Passing custom params to the template)_ + ```js -const path = require('path'); -const generator = new Generator('@asyncapi/html-template', path.resolve(__dirname, 'example'), { - templateParams: { - sidebarOrganization: 'byTags' +const path = require("path"); +const generator = new Generator( + "@asyncapi/html-template", + path.resolve(__dirname, "example"), + { + templateParams: { + sidebarOrganization: "byTags", + }, } -}); +); ``` -* generator.registry : `Object`** : -Npm registry information. +- generator.registry : `Object`\*\* : + Npm registry information. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.templateName : `String`** : -Name of the template to generate. +- generator.templateName : `String`\*\* : + Name of the template to generate. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.targetDir : `String`** : -Path to the directory where the files will be generated. +- generator.targetDir : `String`\*\* : + Path to the directory where the files will be generated. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.entrypoint : `String`** : -Name of the file to use as the entry point for the rendering process. Use in case you want to use only a specific template file. Note: this potentially avoids rendering every file in the template. +- generator.entrypoint : `String`\*\* : + Name of the file to use as the entry point for the rendering process. Use in case you want to use only a specific template file. Note: this potentially avoids rendering every file in the template. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.noOverwriteGlobs : `Array.`** : -List of globs to skip when regenerating the template. +- generator.noOverwriteGlobs : `Array.`\*\* : + List of globs to skip when regenerating the template. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.disabledHooks : `Object.)>`** : -Object with hooks to disable. The key is a hook type. If key has "true" value, then the generator skips all hooks from the given type. If the value associated with a key is a string with the name of a single hook, then the generator skips only this single hook name. If the value associated with a key is an array of strings, then the generator skips only hooks from the array. +- generator.disabledHooks : `Object.)>`\*\* : + Object with hooks to disable. The key is a hook type. If key has "true" value, then the generator skips all hooks from the given type. If the value associated with a key is a string with the name of a single hook, then the generator skips only this single hook name. If the value associated with a key is an array of strings, then the generator skips only hooks from the array. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.output : `String`** : -Type of output. Can be either 'fs' (default) or 'string'. Only available when entrypoint is set. +- generator.output : `String`\*\* : + Type of output. Can be either 'fs' (default) or 'string'. Only available when entrypoint is set. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.forceWrite : `Boolean`** : -Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir. Default is set to false. +- generator.forceWrite : `Boolean`\*\* : + Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir. Default is set to false. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.debug : `Boolean`** : -Enable more specific errors in the console. At the moment it only shows specific errors about filters. Keep in mind that as a result errors about template are less descriptive. +- generator.debug : `Boolean`\*\* : + Enable more specific errors in the console. At the moment it only shows specific errors about filters. Keep in mind that as a result errors about template are less descriptive. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.install : `Boolean`** : -Install the template and its dependencies, even when the template has already been installed. +- generator.install : `Boolean`\*\* : + Install the template and its dependencies, even when the template has already been installed. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.templateConfig : `Object`** : -The template configuration. +- generator.templateConfig : `Object`\*\* : + The template configuration. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.hooks : `Object`** : -Hooks object with hooks functions grouped by the hook type. +- generator.hooks : `Object`\*\* : + Hooks object with hooks functions grouped by the hook type. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.mapBaseUrlToFolder : `Object`** : -Maps schema URL to folder. +- generator.mapBaseUrlToFolder : `Object`\*\* : + Maps schema URL to folder. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) -* generator.templateParams : `Object`** : -The template parameters. The structure for this object is based on each individual template. +- generator.templateParams : `Object`\*\* : + The template parameters. The structure for this object is based on each individual template. -**Kind**: instance property of [`Generator`](#Generator) +**Kind**: instance property of [`Generator`](#Generator) ### generator.generate + Generates files from a given template and an AsyncAPIDocument object. **Kind**: instance method of [`Generator`](#Generator) @@ -197,25 +209,30 @@ Generates files from a given template and an AsyncAPIDocument object. Check out [@asyncapi/parser](https://www.github.com/asyncapi/parser-js) for more information. Remember to use the right options for the right parser depending on the template you are using. -**Example** +**Example** + ```js await generator.generate(myAsyncAPIdocument); -console.log('Done!'); +console.log("Done!"); ``` -**Example** + +**Example** + ```js generator .generate(myAsyncAPIdocument) .then(() => { - console.log('Done!'); + console.log("Done!"); }) .catch(console.error); ``` -**Example** *(Using async/await)* + +**Example** _(Using async/await)_ + ```js try { await generator.generate(myAsyncAPIdocument); - console.log('Done!'); + console.log("Done!"); } catch (e) { console.error(e); } @@ -224,6 +241,7 @@ try { ### generator.validateAsyncAPIDocument + Validates the provided AsyncAPI document. **Kind**: instance method of [`Generator`](#Generator) @@ -236,18 +254,18 @@ Validates the provided AsyncAPI document. - asyncapiDocument `*` - The AsyncAPI document to be validated. - -* generator.setupOutput()** : -Sets up the output configuration based on the specified output type. +- generator.setupOutput()\*\* : + Sets up the output configuration based on the specified output type. **Kind**: instance method of [`Generator`](#Generator) **Throws**: - `Error` If 'output' is set to 'string' without providing 'entrypoint'. -**Example** +**Example** + ```js const generator = new Generator(); await generator.setupOutput(); @@ -255,8 +273,8 @@ await generator.setupOutput(); -* generator.setupFSOutput() ⇒ `Promise.`** : -Sets up the file system (FS) output configuration. +- generator.setupFSOutput() ⇒ `Promise.`\*\* : + Sets up the file system (FS) output configuration. This function creates the target directory if it does not exist and verifies the target directory if forceWrite is not enabled. @@ -267,34 +285,35 @@ the target directory if forceWrite is not enabled. - `Error` If verification of the target directory fails and forceWrite is not enabled. - -* generator.setLogLevel() ⇒ `void`** : -Sets the log level based on the debug option. +- generator.setLogLevel() ⇒ `void`\*\* : + Sets the log level based on the debug option. If the debug option is enabled, the log level is set to 'debug'. -**Kind**: instance method of [`Generator`](#Generator) +**Kind**: instance method of [`Generator`](#Generator) -* generator.installAndSetupTemplate() ⇒ `Promise.<{templatePkgName: string, templatePkgPath: string}>`** : -Installs and sets up the template for code generation. +- generator.installAndSetupTemplate() ⇒ `Promise.<{templatePkgName: string, templatePkgPath: string}>`\*\* : + Installs and sets up the template for code generation. This function installs the specified template using the provided installation option, sets up the necessary directory paths, loads the template configuration, and returns information about the installed template. **Kind**: instance method of [`Generator`](#Generator) -**Returns**: `Promise.<{templatePkgName: string, templatePkgPath: string}>` - A promise that resolves to an object containing the name and path of the installed template. +**Returns**: `Promise.<{templatePkgName: string, templatePkgPath: string}>` - A promise that resolves to an object containing the name and path of the installed template. ### generator.configureTemplateWorkflow + Configures the template workflow based on provided parsing options. This function performs the following steps: + 1. Parses the input AsyncAPI document using the specified parse options. 2. Validates the template configuration and parameters. 3. Configures the template based on the parsed AsyncAPI document. @@ -306,13 +325,13 @@ This function performs the following steps: - parseOptions `*` - Options for parsing the AsyncAPI document. - -* generator.handleEntrypoint() ⇒ `Promise.`** : -Handles the logic for the template entrypoint. +- generator.handleEntrypoint() ⇒ `Promise.`\*\* : + Handles the logic for the template entrypoint. If an entrypoint is specified: + - Resolves the absolute path of the entrypoint file. - Throws an error if the entrypoint file doesn't exist. - Generates a file or renders content based on the output type. @@ -321,36 +340,37 @@ If an entrypoint is specified: If no entrypoint is specified, generates the directory structure. **Kind**: instance method of [`Generator`](#Generator) -**Returns**: `Promise.` - A promise that resolves when the entrypoint logic is completed. +**Returns**: `Promise.` - A promise that resolves when the entrypoint logic is completed. -* generator.executeAfterHook() ⇒ `Promise.`** : -Executes the 'generate:after' hook. +- generator.executeAfterHook() ⇒ `Promise.`\*\* : + Executes the 'generate:after' hook. Launches the after-hook to perform additional actions after code generation. **Kind**: instance method of [`Generator`](#Generator) -**Returns**: `Promise.` - A promise that resolves when the after-hook execution is completed. +**Returns**: `Promise.` - A promise that resolves when the after-hook execution is completed. -* generator.parseInput()** : -Parse the generator input based on the template `templateConfig.apiVersion` value. +- generator.parseInput()\*\* : + Parse the generator input based on the template `templateConfig.apiVersion` value. -**Kind**: instance method of [`Generator`](#Generator) +**Kind**: instance method of [`Generator`](#Generator) -* generator.configureTemplate()** : -Configure the templates based the desired renderer. +- generator.configureTemplate()\*\* : + Configure the templates based the desired renderer. -**Kind**: instance method of [`Generator`](#Generator) +**Kind**: instance method of [`Generator`](#Generator) ### ~~generator.generateFromString~~ -***Deprecated*** + +**_Deprecated_** Generates files from a given template and AsyncAPI string. @@ -360,7 +380,8 @@ Generates files from a given template and AsyncAPI string. - asyncapiString `String` - AsyncAPI string to use as source. - [parseOptions] `Object` ` = {}` - AsyncAPI Parser parse options. Check out [@asyncapi/parser](https://www.github.com/asyncapi/parser-js) for more information. -**Example** +**Example** + ```js const asyncapiString = ` asyncapi: '2.0.0' @@ -372,11 +393,13 @@ info: generator .generateFromString(asyncapiString) .then(() => { - console.log('Done!'); + console.log("Done!"); }) .catch(console.error); ``` -**Example** *(Using async/await)* + +**Example** _(Using async/await)_ + ```js const asyncapiString = ` asyncapi: '2.0.0' @@ -388,7 +411,7 @@ info: try { await generator.generateFromString(asyncapiString); - console.log('Done!'); + console.log("Done!"); } catch (e) { console.error(e); } @@ -397,6 +420,7 @@ try { ### generator.generateFromURL + Generates files from a given template and AsyncAPI file stored on external server. **Kind**: instance method of [`Generator`](#Generator) @@ -404,20 +428,23 @@ Generates files from a given template and AsyncAPI file stored on external serve - asyncapiURL `String` - Link to AsyncAPI file -**Example** +**Example** + ```js generator - .generateFromURL('https://example.com/asyncapi.yaml') + .generateFromURL("https://example.com/asyncapi.yaml") .then(() => { - console.log('Done!'); + console.log("Done!"); }) .catch(console.error); ``` -**Example** *(Using async/await)* + +**Example** _(Using async/await)_ + ```js try { - await generator.generateFromURL('https://example.com/asyncapi.yaml'); - console.log('Done!'); + await generator.generateFromURL("https://example.com/asyncapi.yaml"); + console.log("Done!"); } catch (e) { console.error(e); } @@ -426,6 +453,7 @@ try { ### generator.generateFromFile + Generates files from a given template and AsyncAPI file. **Kind**: instance method of [`Generator`](#Generator) @@ -433,20 +461,23 @@ Generates files from a given template and AsyncAPI file. - asyncapiFile `String` - AsyncAPI file to use as source. -**Example** +**Example** + ```js generator - .generateFromFile('asyncapi.yaml') + .generateFromFile("asyncapi.yaml") .then(() => { - console.log('Done!'); + console.log("Done!"); }) .catch(console.error); ``` -**Example** *(Using async/await)* + +**Example** _(Using async/await)_ + ```js try { - await generator.generateFromFile('asyncapi.yaml'); - console.log('Done!'); + await generator.generateFromFile("asyncapi.yaml"); + console.log("Done!"); } catch (e) { console.error(e); } @@ -455,6 +486,7 @@ try { ### generator.installTemplate + Downloads and installs a template and its dependencies **Kind**: instance method of [`Generator`](#Generator) @@ -462,10 +494,10 @@ Downloads and installs a template and its dependencies - [force] `Boolean` ` = false` - Whether to force installation (and skip cache) or not. - ### Generator.getTemplateFile + Returns the content of a given template file. **Kind**: static method of [`Generator`](#Generator) @@ -475,13 +507,23 @@ Returns the content of a given template file. - filePath `String` - Path to the file to render. Relative to the template directory. - [templatesDir] `String` ` = DEFAULT_TEMPLATES_DIR` - Path to the directory where the templates are installed. -**Example** +**Example** + ```js -const Generator = require('@asyncapi/generator'); -const content = await Generator.getTemplateFile('@asyncapi/html-template', 'partials/content.html'); +const Generator = require("@asyncapi/generator"); +const content = await Generator.getTemplateFile( + "@asyncapi/html-template", + "partials/content.html" +); ``` -**Example** *(Using a custom `templatesDir`)* + +**Example** _(Using a custom `templatesDir`)_ + ```js -const Generator = require('@asyncapi/generator'); -const content = await Generator.getTemplateFile('@asyncapi/html-template', 'partials/content.html', '~/my-templates'); +const Generator = require("@asyncapi/generator"); +const content = await Generator.getTemplateFile( + "@asyncapi/html-template", + "partials/content.html", + "~/my-templates" +); ``` diff --git a/apps/generator/docs/asyncapi-document.md b/apps/generator/docs/asyncapi-document.md index dfd2db6e8..e0e2affd7 100644 --- a/apps/generator/docs/asyncapi-document.md +++ b/apps/generator/docs/asyncapi-document.md @@ -17,11 +17,11 @@ In the following sections, you'll learn about the inner working of the generator ## AsyncAPI document generation process 1. The **Generator** receives the **AsyncAPI Document** as input. -2. The **Generator** sends to the **[Parser](parser)** the **asyncapiString** is a stringified version of the original **AsyncAPI Document** to validate and parse it. +2. The **Generator** sends to the **[Parser](parser.md)** the **asyncapiString** is a stringified version of the original **AsyncAPI Document** to validate and parse it. 3. The **Parser** validates the **AsyncAPI Document** using additional schema-related plugins, either the OpenAPI schema, RAML data types, or Avro schema. 4. If the **Parser** determines that the **AsyncAPI Document** is valid, it manipulates the original JSON/YAML document and provides a set of helper functions in return, bundling them together into an **asyncapi** variable that is an instance of [**AsyncAPIDocument**](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#asyncapidocument). -5. At this point, the **Generator** passes the **originalAsyncAPI** and the **asyncapi** which make up part of the **[Template Context](template-context)** to the **Render Engine**. -6. The **Template Context** is accessible to the template files that are passed to either the [react](react-render-engine) or [nunjucks](nunjucks-render-engine) **Render Engines**. +5. At this point, the **Generator** passes the **originalAsyncAPI** and the **asyncapi** which make up part of the **[Template Context](template-context.md)** to the **Render Engine**. +6. The **Template Context** is accessible to the template files that are passed to either the [react](react-render-engine.md) or [nunjucks](nunjucks-render-engine.md) **Render Engines**. ```mermaid graph LR @@ -77,7 +77,7 @@ function createAsyncapiFile(generator) { A major advantage of using `asyncapi` (which is an instance of `AsyncAPIDocument`) is that it enables the developer to easily access the AsyncAPI documents' content by simply invoking a function. -Once the specification YAML or JSON document is passed as input to the generator, it is passed on to the [Parser](parser) library, which then manipulates the asyncAPI document to a more structured document called the `AsyncAPIDocument`. Once the parser returns the document to the generator, the generator passes it to the render engine. The render engine makes the `AsyncAPIDocument` object accessible to your template through the `asyncapi` variable. +Once the specification YAML or JSON document is passed as input to the generator, it is passed on to the [Parser](parser.md) library, which then manipulates the asyncAPI document to a more structured document called the `AsyncAPIDocument`. Once the parser returns the document to the generator, the generator passes it to the render engine. The render engine makes the `AsyncAPIDocument` object accessible to your template through the `asyncapi` variable. For example, if you want to extract the version of your API from AsyncAPI document, you can do that by calling `asyncapi.version()`. You can say that this one is easy to access from JSON objects, but there are more complex scenarios. For example, to get access to all messages from all channels, you can call `asyncapi.allMessages()` instead of iterating through a complex JSON object on your own. diff --git a/apps/generator/docs/configuration-file.md b/apps/generator/docs/configuration-file.md index c11cfd00e..659dbe847 100644 --- a/apps/generator/docs/configuration-file.md +++ b/apps/generator/docs/configuration-file.md @@ -5,22 +5,22 @@ weight: 90 The `generator` property from `package.json` file must contain a JSON object that may have the following information: -|Name|Type|Description| -|---|---|---| -|`renderer`| String | Its value can be either `react` or `nunjucks` (default). -|`apiVersion`| String | Determines which **major** version of the [Parser-API](https://github.com/asyncapi/parser-api) the template uses. For example, `v2` for `v2.x.x`. If not specified, the Generator assumes the template is not compatible with the Parser-API so it will use the [Parser-JS v1 API](https://github.com/asyncapi/parser-js/tree/v1.18.1#api-documentation). For templates that need to support AsyncAPI specification v3 make sure to use `v3` [Parser-API](https://github.com/asyncapi/parser-api). If the template uses a version of the Parser-API that is not supported by the Generator, the Generator will throw an error. -|`supportedProtocols`| [String] | A list with all the protocols this template supports. -|`parameters`| Object[String, Object] | An object with all the parameters that can be passed when generating the template. When using the command line, it's done by indicating `--param name=value` or `-p name=value`. -|`parameters[param].description`| String | A user-friendly description about the parameter. -|`parameters[param].default`| Any | Default value of the parameter if not specified. Shouldn't be used for mandatory `required=true` parameters. -|`parameters[param].required`| Boolean | Whether the parameter is required or not. -|`conditionalFiles`| Object[String, Object] | An object containing all the file paths that should be conditionally rendered. Each key represents a file path and each value must be an object with the keys `subject` and `validation`. The file path should be relative to the `template` directory inside the template. -|`conditionalFiles[filePath].subject`| String | The `subject` is a [JMESPath](http://jmespath.org/) query to grab the value you want to apply the condition to. It queries an object with the whole AsyncAPI document and, when specified, the given server. The object looks like this: `{ asyncapi: { ... }, server: { ... } }`. If the template supports `server` parameter, you can access server details like for example protocol this way: `server.protocol`. During validation with `conditionalFiles` only the server that template user selected is available in the specification file. For more information about `server` parameter [read about special parameters](#special-parameters). -|`conditionalFiles[filePath].validation`| Object | The `validation` is a JSON Schema Draft 07 object. This JSON Schema definition will be applied to the JSON value resulting from the `subject` query. If validation doesn't have errors, the condition is met, and therefore the given file will be rendered. Otherwise, the file is ignored. Check [JSON Schema Validation](https://json-schema.org/draft-07/json-schema-validation.html#rfc.section.6) document for a list of all possible validation keywords. -|`nonRenderableFiles`| [String] | A list of file paths or [globs](https://en.wikipedia.org/wiki/Glob_(programming)) that must be copied "as-is" to the target directory, i.e., without performing any rendering process. This is useful when you want to copy binary files. -|`generator`| [String] | A string representing the generator version-range the template is compatible with. This value must follow the [semver](https://nodejs.dev/learn/semantic-versioning-using-npm) syntax. E.g., `>=1.0.0`, `>=1.0.0 <=2.0.0`, `~1.0.0`, `^1.0.0`, `1.0.0`, etc. [Read more about semver](https://docs.npmjs.com/about-semantic-versioning). -|`filters`| [String] | A list of modules containing functions that can be used as Nunjucks filters. In case of external modules, remember they need to be added as a dependency in `package.json` of your template. -|`hooks`| Object[String, String] or Object[String, Array[String]] | A list of modules containing hooks, except for the ones you keep locally in your template in default location. For each module you must specify the exact name of the hook that should be used in the template. For a single hook you can specify it as a string, for more you must pass an array of strings. In case of external modules, remember they need to be added as a dependency in `package.json` of your template. +| Name | Type | Description | +| --------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `renderer` | String | Its value can be either `react` or `nunjucks` (default). | +| `apiVersion` | String | Determines which **major** version of the [Parser-API](https://github.com/asyncapi/parser-api) the template uses. For example, `v2` for `v2.x.x`. If not specified, the Generator assumes the template is not compatible with the Parser-API so it will use the [Parser-JS v1 API](https://github.com/asyncapi/parser-js/tree/v1.18.1#api-documentation). For templates that need to support AsyncAPI specification v3 make sure to use `v3` [Parser-API](https://github.com/asyncapi/parser-api). If the template uses a version of the Parser-API that is not supported by the Generator, the Generator will throw an error. | +| `supportedProtocols` | [String] | A list with all the protocols this template supports. | +| `parameters` | Object[String, Object] | An object with all the parameters that can be passed when generating the template. When using the command line, it's done by indicating `--param name=value` or `-p name=value`. | +| `parameters[param].description` | String | A user-friendly description about the parameter. | +| `parameters[param].default` | Any | Default value of the parameter if not specified. Shouldn't be used for mandatory `required=true` parameters. | +| `parameters[param].required` | Boolean | Whether the parameter is required or not. | +| `conditionalFiles` | Object[String, Object] | An object containing all the file paths that should be conditionally rendered. Each key represents a file path and each value must be an object with the keys `subject` and `validation`. The file path should be relative to the `template` directory inside the template. | +| `conditionalFiles[filePath].subject` | String | The `subject` is a [JMESPath](http://jmespath.org/) query to grab the value you want to apply the condition to. It queries an object with the whole AsyncAPI document and, when specified, the given server. The object looks like this: `{ asyncapi: { ... }, server: { ... } }`. If the template supports `server` parameter, you can access server details like for example protocol this way: `server.protocol`. During validation with `conditionalFiles` only the server that template user selected is available in the specification file. For more information about `server` parameter [read about special parameters](#special-parameters). | +| `conditionalFiles[filePath].validation` | Object | The `validation` is a JSON Schema Draft 07 object. This JSON Schema definition will be applied to the JSON value resulting from the `subject` query. If validation doesn't have errors, the condition is met, and therefore the given file will be rendered. Otherwise, the file is ignored. Check [JSON Schema Validation](https://json-schema.org/draft-07/json-schema-validation.html#rfc.section.6) document for a list of all possible validation keywords. | +| `nonRenderableFiles` | [String] | A list of file paths or [globs]() that must be copied "as-is" to the target directory, i.e., without performing any rendering process. This is useful when you want to copy binary files. | +| `generator` | [String] | A string representing the generator version-range the template is compatible with. This value must follow the [semver](https://nodejs.dev/learn/semantic-versioning-using-npm) syntax. E.g., `>=1.0.0`, `>=1.0.0 <=2.0.0`, `~1.0.0`, `^1.0.0`, `1.0.0`, etc. [Read more about semver](https://docs.npmjs.com/about-semantic-versioning). | +| `filters` | [String] | A list of modules containing functions that can be used as Nunjucks filters. In case of external modules, remember they need to be added as a dependency in `package.json` of your template. | +| `hooks` | Object[String, String] or Object[String, Array[String]] | A list of modules containing hooks, except for the ones you keep locally in your template in default location. For each module you must specify the exact name of the hook that should be used in the template. For a single hook you can specify it as a string, for more you must pass an array of strings. In case of external modules, remember they need to be added as a dependency in `package.json` of your template. | ### Example @@ -73,8 +73,6 @@ The `generator` property from `package.json` file must contain a JSON object tha There are some template parameters that have a special meaning: -|Name|Description| -|---|---| -|`server`| It is used to let the template know which server from the AsyncAPI specification file you want to use. In some cases, this may be required. For instance, when generating code that connects to a specific server. Use this parameter in case your template relies on users' information about what server from the specification file they want to use during generation. You also need this parameter if you want to use `server.protocol` notation within `conditionalFiles` configuration option. Once you decide to specify this parameter for your template, it is recommended you make it a mandatory parameter otherwise a feature like `conditionalFiles` is not going to work if your users do not use this parameter obligatory. - - +| Name | Description | +| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `server` | It is used to let the template know which server from the AsyncAPI specification file you want to use. In some cases, this may be required. For instance, when generating code that connects to a specific server. Use this parameter in case your template relies on users' information about what server from the specification file they want to use during generation. You also need this parameter if you want to use `server.protocol` notation within `conditionalFiles` configuration option. Once you decide to specify this parameter for your template, it is recommended you make it a mandatory parameter otherwise a feature like `conditionalFiles` is not going to work if your users do not use this parameter obligatory. | diff --git a/apps/generator/docs/file-templates.md b/apps/generator/docs/file-templates.md index 7a7a8ce77..6284838dd 100644 --- a/apps/generator/docs/file-templates.md +++ b/apps/generator/docs/file-templates.md @@ -9,19 +9,20 @@ weight: 140 It is possible to generate files for each specific object in your AsyncAPI documentation using the Nunjucks render engine. For example, you can specify a filename like `$$channel$$.js` to generate a file for each channel defined in your AsyncAPI. The following file-template names and extra variables are available: - - `$$channel$$`, within the template-file you have access to two variables [`channel`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channel) and [`channelName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channels). Where the `channel` contains the current channel being rendered. - - `$$message$$`, within the template-file you have access to two variables [`message`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#message) and [`messageName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#message). Where `message` contains the current message being rendered. - - `$$schema$$`, within the template-file you have access to two variables [`schema`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema) and [`schemaName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema). Where `schema` contains the current schema being rendered. Only schemas from [Components object](https://www.asyncapi.com/docs/reference/specification/latest#componentsObject) are used. - - `$$everySchema$$`, within the template-file you have access to two variables [`schema`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema) and [`schemaName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schemas). Where `schema` contains the current schema being rendered. Every [Schema object](https://www.asyncapi.com/docs/specifications/2.0.0/#schemaObject) from the entire AsyncAPI file is used. - - `$$objectSchema$$`, within the template-file you have access to two variables [`schema`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema) and [`schemaName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schemas). Where `schema` contains the current schema being rendered. All the [Schema objects](https://www.asyncapi.com/docs/reference/specification/latest#multiFormatSchemaObject) with type object is used. - - `$$parameter$$`, within the template-file you have access to two variables [`parameter`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channelparameter) and [`parameterName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channelparameters). Where the `parameter` contains the current parameter being rendered. - - `$$securityScheme$$`, within the template-file you have access to two variables [`securityScheme`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#securityscheme) and [`securitySchemeName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#securityschemes). Where `securityScheme` contains the current security scheme being rendered. +- `$$channel$$`, within the template-file you have access to two variables [`channel`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channel) and [`channelName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channels). Where the `channel` contains the current channel being rendered. +- `$$message$$`, within the template-file you have access to two variables [`message`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#message) and [`messageName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#message). Where `message` contains the current message being rendered. +- `$$schema$$`, within the template-file you have access to two variables [`schema`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema) and [`schemaName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema). Where `schema` contains the current schema being rendered. Only schemas from [Components object](https://www.asyncapi.com/docs/reference/specification/latest#componentsObject) are used. +- `$$everySchema$$`, within the template-file you have access to two variables [`schema`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema) and [`schemaName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schemas). Where `schema` contains the current schema being rendered. Every [Schema object](https://www.asyncapi.com/docs/specifications/2.0.0/#schemaObject) from the entire AsyncAPI file is used. +- `$$objectSchema$$`, within the template-file you have access to two variables [`schema`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schema) and [`schemaName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#schemas). Where `schema` contains the current schema being rendered. All the [Schema objects](https://www.asyncapi.com/docs/reference/specification/latest#multiFormatSchemaObject) with type object is used. +- `$$parameter$$`, within the template-file you have access to two variables [`parameter`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channelparameter) and [`parameterName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#channelparameters). Where the `parameter` contains the current parameter being rendered. +- `$$securityScheme$$`, within the template-file you have access to two variables [`securityScheme`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#securityscheme) and [`securitySchemeName`](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#securityschemes). Where `securityScheme` contains the current security scheme being rendered. The file name will be equal to `*Name` variable. ### Example The file name is `$$schema$$.txt`, the content of this file is: + ``` Schema name is '{{schemaName}}' and properties are: {% for propName, prop in schema.properties() %} @@ -30,9 +31,10 @@ Schema name is '{{schemaName}}' and properties are: ``` With the following AsyncAPI: + ``` components: - schemas: + schemas: peoplePayload: type: object properties: @@ -46,12 +48,14 @@ components: ``` The generator creates two files `peoplePayload.txt` and `people.txt` with the following content: + ``` Schema name is 'peoplePayload' and properties are: - people ``` and + ``` Schema name is 'people' and properties are: - id @@ -68,13 +72,13 @@ The above method of rendering **file templates** only works for the Nunjucks ren The following is a simple hardcoded example of how to render multiple files using the React render engine: ```tsx -import { File} from "@asyncapi/generator-react-sdk"; +import { File } from "@asyncapi/generator-react-sdk"; -export default function({ asyncapi }) { +export default function ({ asyncapi }) { return [ Content, - Content - ] + Content, + ]; } ``` @@ -83,22 +87,21 @@ export default function({ asyncapi }) { In practice, to render the multiple files, that are generated from the data defined in your AsyncAPI, you'll iterate over the array of schemas and generate a file for each schema as shown in the example below: ```js -import { File} from "@asyncapi/generator-react-sdk"; +import { File } from "@asyncapi/generator-react-sdk"; /* * To render multiple files, it is enough to return an array of `File` components in the rendering component, like in following example. */ -export default function({ asyncapi }) { +export default function ({ asyncapi }) { const schemas = asyncapi.allSchemas(); const files = []; // schemas is an instance of the Map schemas.forEach((schema) => { - files.push( // We return a react file component and each time we do it, the name of the generated file will be a schema name // Content of the file will be a variable representing schema - const { schema.id() } = { JSON.stringify(schema._json, null, 2) } + const {schema.id()} = {JSON.stringify(schema._json, null, 2)} ); }); @@ -113,7 +116,6 @@ Additionally, you can generate multiple files for each channel defined in your A ```js import { File, Text } from "@asyncapi/generator-react-sdk"; - export default function ({ asyncapi }) { const files = []; @@ -124,15 +126,14 @@ export default function ({ asyncapi }) { files.push( # Channel: {channelName} - - {channel.hasDescription() && `${channel.description()}`} - + {channel.hasDescription() && `${channel.description()}`} ); }); return files; } ``` + The code snippet above uses the `Text` component to write file content to the `.md` markdown file. The `newline` property is used to ensure that the content isn't all rendered in one line in the markdown file. In summary, the code snippet above is a practical guide on generating properly formatted multiline Markdown files for each channel in an AsyncAPI document. > You can see an example of a file template that uses the React render engine [here](https://github.com/asyncapi/template-for-generator-templates/blob/master/template/schemas/schema.js). diff --git a/apps/generator/docs/generator-template.md b/apps/generator/docs/generator-template.md index e9643234e..edddebc97 100644 --- a/apps/generator/docs/generator-template.md +++ b/apps/generator/docs/generator-template.md @@ -19,8 +19,7 @@ In this tutorial: There is a list of [community maintained templates](https://www.asyncapi.com/docs/tools/generator/template#generator-templates-list), but what if you do not find what you need? In that case, you'll create a user-defined template that generates custom output from the generator. Before you create the template, you'll need to have an [AsyncAPI document](https://www.asyncapi.com/docs/tools/generator/asyncapi-document) that defines the properties you want to use in your template to test against. In this tutorial, you'll use the following template saved in the **test/fixtures/asyncapi.yml** file in your template project directory. -``` yml - +```yml asyncapi: 2.6.0 info: @@ -75,7 +74,7 @@ components: Now your directory should look like this: ``` -python-mqtt-client-template +python-mqtt-client-template ├── template │ └── index.js ├── test @@ -90,7 +89,7 @@ Lets break it down: The **package.json** file is used to define the dependencies for your template. Add the following code snippet to your **package.json** file: -``` json +```json { "name": "python-mqtt-client-template", "version": "0.0.1", @@ -122,7 +121,7 @@ Here's what is contained in the code snippet above: - **supportedProtocols** - A list that specifies which protocols are supported by your template. - **dependencies** - specifies which version of [`@asyncapi/generator-react-sdk`](https://github.com/asyncapi/generator-react-sdk) should be used. -Navigate to the ****python-mqtt-client-template** directory. Run the command `npm install` on your terminal to install the dependencies specified in **package.json**. +Navigate to the \***\*python-mqtt-client-template** directory. Run the command `npm install` on your terminal to install the dependencies specified in **package.json**. ### index.js file @@ -130,11 +129,11 @@ The **index.js** file is used to define the logic for your template. Inside the ```js //1 -import { File } from '@asyncapi/generator-react-sdk' +import { File } from "@asyncapi/generator-react-sdk"; //2 export default function ({ asyncapi }) { -//3 - return {asyncapi.info().title()} + //3 + return {asyncapi.info().title()}; } ``` @@ -144,7 +143,7 @@ The code snippet above does the following: 2. The `asyncapi` argument is an instance of the [AsyncAPI Parser](https://www.asyncapi.com/docs/tools/generator/parser). It will allow you to access the content of the AsyncAPI document in your template using helper functions. 3. The `asyncapi.info().title()` is using the info() helper function to return the info object from the AsyncAPI document illustrated in the code snippet below: -``` json +```json info: title: Temperature Service version: 1.0.0 @@ -157,7 +156,7 @@ The `asyncapi.info().title()` returns `Temperature Service`. To see this in action, navigate to the **python-mqtt-client-template** directory. Then, run `asyncapi generate fromTemplate test/fixtures/asyncapi.yml ./ -o test/project` command on your terminal. If successful, you'll see the message below on your terminal: -``` cmd +```cmd Generation in progress. Keep calm and wait a bit... done Check out your shiny new generated files at test/project. ``` @@ -187,7 +186,7 @@ In this section, you'll: Here is the sample code to be pasted in the client.py you generated above running the `asyncapi generate fromTemplate test/fixtures/asyncapi.yml ./ -o test/project` command. It uses the `paho-mqtt` package. -``` python +```python # 1 import paho.mqtt.client as mqtt # 2 @@ -195,7 +194,7 @@ mqttBroker = "test.mosquitto.org" class TemperatureServiceClient: def __init__(self): - # 3 + # 3 self.client = mqtt.Client() # 4 self.client.connect(mqttBroker) @@ -204,7 +203,7 @@ class TemperatureServiceClient: def sendTemperatureChange(self, id): # 5 topic = "temperature/changed" - # 6 + # 6 self.client.publish(topic, id) ``` @@ -239,7 +238,7 @@ python-mqtt-client-template └── test.py ``` -``` python +```python from client import TemperatureServiceClient from random import randrange import time @@ -260,7 +259,7 @@ while True: Run the code above in your terminal using the command `python test.py`. You should see output similar to the snippet below logged on your terminal: -``` cmd +```cmd New temperature detected 64250266 sent to temperature/changed New temperature detected 36947728 sent to temperature/changed New temperature detected 72955029 sent to temperature/changed @@ -272,8 +271,8 @@ To make sure your **test.py** and client code works check if the broker really r Open [**index.js**](#indexjs-file) and copy the content of [**client.py**](#1-create-the-client) and replace `{asyncapi.info().title()}` with it. It should look like the code snippet below now: -``` js -import { File } from '@asyncapi/generator-react-sdk'; +```js +import { File } from "@asyncapi/generator-react-sdk"; export default function ({ asyncapi }) { return ( @@ -292,7 +291,7 @@ class TemperatureServiceClient: topic = "temperature/changed" self.client.publish(topic, id)`} - ) + ); } ``` @@ -300,7 +299,7 @@ class TemperatureServiceClient: In **package.json** you can have the scripts property that you invoke by calling `npm run `. Add these scripts to **package.json**: -``` json +```json "scripts": { "test:clean": "rimraf test/project/client.py", "test:generate": "asyncapi generate fromTemplate test/fixtures/asyncapi.yml ./ --output test/project --force-write", @@ -365,12 +364,11 @@ You can now replace the static broker from `mqttBroker = 'test.mosquitto.org'` t Now the template code looks like this: -``` js -import { File } from '@asyncapi/generator-react-sdk'; +```js +import { File } from "@asyncapi/generator-react-sdk"; // notice that now the template not only gets the instance of parsed AsyncAPI document but also the parameters export default function ({ asyncapi, params }) { - return ( {`import paho.mqtt.client as mqtt @@ -387,7 +385,7 @@ class TemperatureServiceClient: topic = "temperature/changed" self.client.publish(topic, id)`} - ) + ); } ``` @@ -399,24 +397,25 @@ Python takes indentation very seriously, and our generated output will be Python ```js // 1 -import { File, Text } from '@asyncapi/generator-react-sdk' +import { File, Text } from "@asyncapi/generator-react-sdk"; export default function ({ asyncapi, params }) { return ( - // 2 - import paho.mqtt.client as mqtt - // 3 - mqttBroker = "{asyncapi.servers().get(params.server).url()}" - // 4 - class {asyncapi.info().title().replaceAll(' ', '')}Client: - // 5 - + // 2import paho.mqtt.client as mqtt + // 3 + mqttBroker = "{asyncapi.servers().get(params.server).url()}" + + // 4 + + class {asyncapi.info().title().replaceAll(" ", "")}Client: + + // 5 {`def __init__(self): self.client = mqtt.Client() self.client.connect(mqttBroker)`} - - ) + + ); } ``` @@ -427,7 +426,7 @@ export default function ({ asyncapi, params }) { 5. There is no templating needed in the `__init__` function, there is only hardcoded information. > If you're on the fence about which templating engine you should use in your template, check out the [React render engine](https://www.asyncapi.com/docs/tools/generator/react-render-engine) and [nunjucks render engine](https://www.asyncapi.com/docs/tools/generator/nunjucks-render-engine) documentation. -In the next section, you'll refactor your template to use React. +> In the next section, you'll refactor your template to use React. #### 5c. Creating a reusable component @@ -469,16 +468,16 @@ It's recommended to put reusable components outside the template directory in a * As input it requires a list of Channel models from the parsed AsyncAPI document */ export function TopicFunction({ channels }) { - const topicsDetails = getTopics(channels) - let functions = '' + const topicsDetails = getTopics(channels); + let functions = ""; topicsDetails.forEach((t) => { functions += `def send${t.name}(self, id): topic = "${t.topic}" - self.client.publish(topic, id)\n` - }) + self.client.publish(topic, id)\n`; + }); - return functions + return functions; } /* @@ -489,19 +488,19 @@ export function TopicFunction({ channels }) { * As input it requires a list of Channel models from the parsed AsyncAPI document */ function getTopics(channels) { - const channelsCanSendTo = channels - let topicsDetails = [] + const channelsCanSendTo = channels; + let topicsDetails = []; channelsCanSendTo.forEach((ch) => { - const topic = {} - const operationId = ch.operations().filterByReceive()[0].id() - topic.name = operationId.charAt(0).toUpperCase() + operationId.slice(1) - topic.topic = ch.address() + const topic = {}; + const operationId = ch.operations().filterByReceive()[0].id(); + topic.name = operationId.charAt(0).toUpperCase() + operationId.slice(1); + topic.topic = ch.address(); - topicsDetails.push(topic) - }) + topicsDetails.push(topic); + }); - return topicsDetails + return topicsDetails; } ``` @@ -511,17 +510,21 @@ function getTopics(channels) { Import the `TopicFunction` component in your template code in **index.js** and add the template code to generate the functions to topics that the `Temperature Service` application is subscribed to. In your case, the final version of your template code should look like this: ```js -import { File, Text } from '@asyncapi/generator-react-sdk' -import { TopicFunction } from '../components/TopicFunction' +import { File, Text } from "@asyncapi/generator-react-sdk"; +import { TopicFunction } from "../components/TopicFunction"; export default function ({ asyncapi, params }) { return ( import paho.mqtt.client as mqtt - mqttBroker = "{asyncapi.servers().get(params.server).url()}" + + mqttBroker = "{asyncapi.servers().get(params.server).url()}" + - class {asyncapi.info().title().replaceAll(' ', '')}Client: + + class {asyncapi.info().title().replaceAll(" ", "")}Client: + {`def __init__(self): @@ -533,9 +536,8 @@ export default function ({ asyncapi, params }) { - ) + ); } - ``` Now your directory should look like this: @@ -554,7 +556,6 @@ python-mqtt-client-template └── test.py ``` - Run `npm test` on your terminal to ensure everything works as expected. In the next section, you'll add another channel to **asyncapi.yml** file called `temperature/dropped` and `temperature/risen` then run the template again to make sure it still works as expected. @@ -566,7 +567,7 @@ Update the AsyncAPI document to use two channels: ```yml channels: temperature/dropped: - description: Notifies the user when the temperature drops past a certain point. + description: Notifies the user when the temperature drops past a certain point. publish: operationId: temperatureDrop message: diff --git a/apps/generator/docs/hooks.md b/apps/generator/docs/hooks.md index d2c06ddc0..009f9cb3d 100644 --- a/apps/generator/docs/hooks.md +++ b/apps/generator/docs/hooks.md @@ -6,13 +6,14 @@ weight: 130 Hooks are functions called by the generator on a specific moment in the generation process. Hooks can be anonymous functions but you can also add function names. These hooks can have arguments provided to them or being expected to return a value. The following types of hooks are currently supported: -|Hook type|Description| Return type | Arguments -|---|---|---|---| -| `generate:before` | Called after registration of all filters and before the generator starts processing of the template. | void : Nothing is expected to be returned. | [The generator instance](https://github.com/asyncapi/generator/blob/master/docs/api.md) -| `generate:after` | Called at the very end of the generation. | void : Nothing is expected to be returned. | [The generator instance](https://github.com/asyncapi/generator/blob/master/docs/api.md) -| `setFileTemplateName ` | Called right before saving a new file generated by [file template](./file-templates.md). | string : a new filename for the generator to use for the file template. | [The generator instance](https://github.com/asyncapi/generator/blob/master/docs/api.md) and object in the form of `{ "originalFilename" : string }` +| Hook type | Description | Return type | Arguments | +| ---------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| `generate:before` | Called after registration of all filters and before the generator starts processing of the template. | void : Nothing is expected to be returned. | [The generator instance](https://github.com/asyncapi/generator/blob/master/docs/api.md) | +| `generate:after` | Called at the very end of the generation. | void : Nothing is expected to be returned. | [The generator instance](https://github.com/asyncapi/generator/blob/master/docs/api.md) | +| `setFileTemplateName ` | Called right before saving a new file generated by [file template](./file-templates.md). | string : a new filename for the generator to use for the file template. | [The generator instance](https://github.com/asyncapi/generator/blob/master/docs/api.md) and object in the form of `{ "originalFilename" : string }` | The generator parses: + - All the files in the `.hooks` directory inside the template. - All modules listed in the template configuration and triggers only hooks that names were added to the config. You can use the official AsyncAPI [hooks library](https://github.com/asyncapi/generator-hooks). To learn how to add hooks to configuration [read more about the configuration file](https://www.asyncapi.com/docs/tools/generator/configuration-file). @@ -21,34 +22,40 @@ The generator parses: > Some of the examples have names of hook functions provided and some not. Keep in mind that hook functions kept in template in default location do not require a name. Name is required only if you keep hooks in non default location or in a separate library, because such hooks need to be explicitly configured in the configuration file. For more details on hooks configuration [read more about the configuration file](https://www.asyncapi.com/docs/tools/generator/configuration-file). Most basic modules with hooks look like this: + ```js module.exports = { - 'generate:after': generator => console.log('This runs after generation is complete') -} + "generate:after": (generator) => + console.log("This runs after generation is complete"), +}; ``` Below you have an example Hook that after generation creates an AsyncAPI file. ```js -const fs = require('fs'); -const path = require('path'); +const fs = require("fs"); +const path = require("path"); module.exports = { - 'generate:after': generator => { + "generate:after": (generator) => { const asyncapi = generator.originalAsyncAPI; let extension; try { JSON.parse(asyncapi); - extension = 'json'; + extension = "json"; } catch (e) { - extension = 'yaml'; + extension = "yaml"; } - fs.writeFileSync(path.resolve(generator.targetDir, `asyncapi.${extension}`), asyncapi); - } + fs.writeFileSync( + path.resolve(generator.targetDir, `asyncapi.${extension}`), + asyncapi + ); + }, }; ``` + And here an example Hook that before generation switches `publish` and `subscribe` operations for each channel. ```js @@ -70,7 +77,8 @@ module.exports = { }; ``` -Example hook for changing the filename of a template file. Replaces all '-' characters with '_'. +Example hook for changing the filename of a template file. Replaces all '-' characters with '\_'. + ```js module.exports = { 'setFileTemplateName': (generator, hookArguments) => { diff --git a/apps/generator/docs/index.md b/apps/generator/docs/index.md index a80e02531..64609bbb4 100644 --- a/apps/generator/docs/index.md +++ b/apps/generator/docs/index.md @@ -3,35 +3,38 @@ title: "Introduction" weight: 10 --- -The AsyncAPI generator is a tool that generates anything you want using the **[AsyncAPI Document](generator/asyncapi-document)** and **[Template](generator/template)** that are supplied as inputs to the AsyncAPI CLI. The generator was built with extensibility in mind; you can use the generator to generate anything you want, provided that it can be defined in a template, such as code, diagrams, markdown files, microservices, and applications. A number of [community-maintained templates](https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate) are now available for immediate usage. +The AsyncAPI generator is a tool that generates anything you want using the **[AsyncAPI Document](asyncapi-document.md)** and **[Template](template.md)** that are supplied as inputs to the AsyncAPI CLI. The generator was built with extensibility in mind; you can use the generator to generate anything you want, provided that it can be defined in a template, such as code, diagrams, markdown files, microservices, and applications. A number of [community-maintained templates](https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate) are now available for immediate usage. > **Note:** -> If your primary objective is to generate models/classes for your event-driven architecture apps, use [AsyncAPI Modelina](/docs/tools/generator/model-generation), which is supported in the AsyncAPI CLI, instead of using the AsyncAPI Generator. Modelina is specifically designed for model generation and provides utilities for working with the AsyncAPI document. +> If your primary objective is to generate models/classes for your event-driven architecture apps, use [AsyncAPI Modelina](model-generation.md), which is supported in the AsyncAPI CLI, instead of using the AsyncAPI Generator. Modelina is specifically designed for model generation and provides utilities for working with the AsyncAPI document. + +### Generator use cases -### Generator use cases - Generation of interactive and understandable API documentation - Generation of APIs' client libraries - Generation of APIs' boilerplate code ### Generator advantages + - Quick to setup and easy to use on a regular basis - Effortless generation of complex documents - Number of community maintained AsyncAPI templates ### Generation process -1. The **Generator** receives the **[Template](generator/template)** and **[AsyncAPI Document](generator/asyncapi-document)** as inputs. -2. The **Generator** sends to the **[Parser](generator/parser)** the **asyncapiString** which is a stringified version of the original **AsyncAPI Document**. + +1. The **Generator** receives the **[Template](template.md)** and **[AsyncAPI Document](asycapi-document.md)** as inputs. +2. The **Generator** sends to the **[Parser](parser.md)** the **asyncapiString** which is a stringified version of the original **AsyncAPI Document**. 3. The **Parser** uses additional plugins such as the OpenAPI, RAML, or Avro schemas to validate custom schemas of message payloads defined in the **AsyncAPI Document**. 4. If the **Parser** determines that the original **AsyncAPI Document** is valid, it manipulates the document and returns a set of helper functions and properties and bundles them together into an **asyncapi** variable that is an instance of [**AsyncAPIDocument**](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#asyncapidocument). The **asyncapi** helper functions make it easier to access the contents of the AsyncAPI Document. -5. At this point, the **Generator** passes the **[asyncapi](generator/asyncapi-document#method-2-asyncapi-and-template)**, the **[originalAsyncAPI](generator/asyncapi-document#method-1-originalasyncapi-and-template)**, and the **params** which collectively make up the **[Template Context](generator/template-context)** to the **Render Engine**. -6. AsyncAPI has two **Render Engines**([react](generator/react-render-engine) and [nunjucks](generator/nunjucks-render-engine)). Depending on which one you've specified in your `package.json`, the **Generator** knows the right **Render Engine** to pass both the **Template Files** and the **Template Context**. +5. At this point, the **Generator** passes the **[asyncapi](asyncapi-document.md#method-2-asyncapi-and-template)**, the **[originalAsyncAPI](asyncapi-document.md#method-1-originalasyncapi-and-template)**, and the **params** which collectively make up the **[Template Context](template-context.md)** to the **Render Engine**. +6. AsyncAPI has two **Render Engines**([react](react-render-engine.md) and [nunjucks](nunjucks-render-engine.md)). Depending on which one you've specified in your `package.json`, the **Generator** knows the right **Render Engine** to pass both the **Template Files** and the **Template Context**. 7. Once the **Render Engine** receives the **Template Files** and the **Template Context**, it injects all the dynamic values in your react or nunjucks based **Template Files** using the **Template Context**. As a result, the **Render Engine** generates **markdown**, **pdf**, **boilerplate code**, and **anything else** you specified to be generated as output. > You can generate anything you want using the generator as long as it can be defined in a **Template**. The diagram below depicts the entire process of passing the **Template** and **AsyncAPI Document** to the AsyncAPI generator tool, how the generator uses these inputs to generate the desired output, and example outputs you can get from the render engine. -``` mermaid +```mermaid graph LR A[Template Context] B{Generator} @@ -52,5 +55,6 @@ graph LR D --> N[Node.js] D --> J[Java Spring Boot] D --> K[Anything else] - ``` +``` + **`params`** are template-specific options passed to the `asyncapi generate fromTemplate` CLI command to customize the generated output. diff --git a/apps/generator/docs/installation-guide.md b/apps/generator/docs/installation-guide.md index 302be0497..7b6aef689 100644 --- a/apps/generator/docs/installation-guide.md +++ b/apps/generator/docs/installation-guide.md @@ -4,18 +4,23 @@ weight: 20 --- You can use the generator library to generate whatever you want in your event-driven architecture apps. Find your preferred method below: + - [AsyncAPI CLI](#asyncapi-cli) - [Generator library in Node.js apps](#generator-library-in-nodejs-apps) - + ## Prerequisites + Before you install and use the AsyncAPI CLI and the generator library, ensure you meet the prerequisites below, then [install the CLI](#installation). + 1. Node.js v18.12.0 and higher 2. Npm v8.19.0 and higher - + To verify the versions of Node and Npm you have, run the following command on your terminal: + ``` npm -v ``` + ``` node -v ``` @@ -25,6 +30,7 @@ If you don't have either Node or Npm installed, use the [official node.js instal If you have the correct versions installed, proceed to the CLI installation guide below. Otherwise, upgrading the Npm or Node version is lower than the recommended versions specified above. ## AsyncAPI CLI + The AsyncAPI CLI tool allows you to do many different things with the [AsyncAPI document](asyncapi-document). You can generate message-based API boilerplate code, documentation, or anything else you need as long as you specify it in your [template](template) or the existing template already supports it. To use the generator via the AsyncAPI CLI, you need to install the AsyncAPI CLI tool. ### Installation @@ -32,50 +38,65 @@ The AsyncAPI CLI tool allows you to do many different things with the [AsyncAPI #### Install AsyncAPI CLI using NPM The AsyncAPI CLI is a NodeJS project, so the easiest way to install it is by using the following `npm` command: + ``` npm install -g @asyncapi/cli ``` To install a specific version of the generator tool, pass the version during installation: + ``` npm install -g @asyncapi/cli@{version} ``` -#### MacOS -You can install in MacOS by using brew: `brew install asyncapi`. +#### MacOS + +You can install in MacOS by using brew: `brew install asyncapi`. + +#### Linux -#### Linux You can install in Linux by using `dpkg`, a package manager for debian: + 1. `curl -OL https://github.com/asyncapi/cli/releases/latest/download/asyncapi.deb` 2. `sudo dpkg -i asyncapi.deb` #### Other operating systems + For further installation instructions for different operating systems, read the [AsyncAPI CLI documentation](https://github.com/asyncapi/cli#installation). -> **Remember:** +> **Remember:** > Each [community-developed template](https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate) is dependent on a certain version of the generator for it to work correctly. Before you install the AsyncAPI CLI, check the template's `package.json` for the version of the AsyncAPI CLI your template is compatible with. Read the [versioning docs](versioning) to learn why it's important to use certain generator versions with your templates. ### Update AsyncAPI CLI + There are several reasons why you might want to update your generator version: -* You have the generator tool installed but want to use the latest released features. To upgrade to the latest version, use the command below: + +- You have the generator tool installed but want to use the latest released features. To upgrade to the latest version, use the command below: + ``` npm install -g @asyncapi/cli ``` -* If your template isn't compatible with the latest generator version, you can update it to a specific version of the generator. Check the [version you need](https://github.com/asyncapi/cli/releases) and specify the version you want by using the **@** symbol as shown in the command below: + +- If your template isn't compatible with the latest generator version, you can update it to a specific version of the generator. Check the [version you need](https://github.com/asyncapi/cli/releases) and specify the version you want by using the **@** symbol as shown in the command below: + ``` npm install -g @asyncapi/cli@{version} ``` + > Sometimes you have to force additional npm installation like this: `npm install -g --force @asyncapi/cli` ### Uninstall AsyncAPI CLI + To uninstall the generator, use the following command: + ``` npm uninstall @asyncapi/cli -g -``` +``` -> :memo: **Note:** To use the generator in your CI/CD pipeline to automate whatever you generate for your event-driven architecture apps, install the AsyncAPI CLI in your pipeline. If you are using GitHub Actions, use [Github Actions for Generator](https://github.com/marketplace/actions/generator-for-asyncapi-documents). +> :memo: **Note:** To use the generator in your CI/CD pipeline to automate whatever you generate for your event-driven architecture apps, install the AsyncAPI CLI in your pipeline. If you are using GitHub Actions, use [Github Actions for Generator](https://github.com/marketplace/actions/generator-for-asyncapi-documents). ## Generator library in Node.js apps + Use the generator library in your Node.js projects by installing it via the following command: `npm install @asyncapi/generator`. > Don't include the `-g` flag in the installation command above since you're not installing the generator library globally but in your Node.js project. diff --git a/apps/generator/docs/model-generation.md b/apps/generator/docs/model-generation.md index f15ea8d24..0d8795f37 100644 --- a/apps/generator/docs/model-generation.md +++ b/apps/generator/docs/model-generation.md @@ -5,7 +5,7 @@ weight: 200 This guide will walk you through the process of enabling models/types generation in a template by using [Modelina](https://www.asyncapi.com/tools/modelina). -Modelina is an AsyncAPI library designed for generating data models using inputs such as [AsyncAPI](generator/asyncapi-document), OpenAPI, or JSON schema inputs. Its functionality revolves around creating data models from the provided AsyncAPI document and the model template, which defines message payloads. It is better to use Modelina in your template to handle model generation rather than providing custom templates. +Modelina is an AsyncAPI library designed for generating data models using inputs such as [AsyncAPI](asyncapi-document.md), OpenAPI, or JSON schema inputs. Its functionality revolves around creating data models from the provided AsyncAPI document and the model template, which defines message payloads. It is better to use Modelina in your template to handle model generation rather than providing custom templates. You can integrate the work shown in this guide into a template by following the [tutorial about creating a template](https://www.asyncapi.com/docs/tools/generator/generator-template). @@ -17,12 +17,12 @@ Install Modelina in your project using npm: `npm install --save @asyncapi/modeli Ensure your template's `package.json` file now contains Modelina pointing to its latest version: - ```json - "dependencies": { - // ... - "@asyncapi/modelina": "^2.0.5" - // ... - } +```json +"dependencies": { + // ... + "@asyncapi/modelina": "^2.0.5" + // ... + } ``` ## Create a models.js file @@ -43,12 +43,12 @@ import { PythonGenerator, FormatHelpers } from '@asyncapi/modelina'; /** * Render all schema models - * @param {RenderArgument} param0 - * @returns + * @param {RenderArgument} param0 + * @returns */ // 3 export default async function schemaRender({ asyncapi }) { - // 4 + // 4 const pythonGenerator = new PythonGenerator(); // 5 const models = await pythonGenerator.generate(asyncapi); @@ -74,7 +74,7 @@ Let's break it down. The code snippet above does the following: 5. The actual model generation is one line of code, and as a result you get an array of models that later you need to turn into files. 6. You need to define an array that must be returned from `schemaRender` function. The array must contain React components, and in this case, the `` component. 7. Iterate over generated models and use their content to create proper definitions of `` components. -8. Notice how using Modelina helpers, in this case the `toPascalCase` function, let's you make sure that the filename of your model follows specific case pattern. +8. Notice how using Modelina helpers, in this case the `toPascalCase` function, let's you make sure that the filename of your model follows specific case pattern. 9. Each component must be added into the `files` array that you later return from the default function. Notice the definition of the `` component that enables you to provide the name of resulting file and the content of the model. Notice also `model.result` that shows that initially generated array with models did not contain raw models content but a set of output objects that contain not only `result` but also other info, like for example `modelName`. With such a model template that uses Modelina, as a result of generation process you would receive a set of model files in `$OUTPUT_DIR/src/models` directory. diff --git a/apps/generator/docs/nunjucks-render-engine.md b/apps/generator/docs/nunjucks-render-engine.md index 34626b49b..316f52a82 100644 --- a/apps/generator/docs/nunjucks-render-engine.md +++ b/apps/generator/docs/nunjucks-render-engine.md @@ -12,7 +12,7 @@ weight: 120 1. Templates may contain multiple files. Unless stated otherwise, all files will be rendered. 1. The default variables you have access to in any the template file are the following: - `asyncapi` that is a parsed spec file object. Read the [API](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#asyncapidocument) of the Parser to understand what structure you have access to in this parameter. - - `originalAsyncAPI` that is an original spec file before it is parsed. + - `originalAsyncAPI` that is an original spec file before it is parsed. - `params` that contain the parameters provided when generating. ### Partials @@ -20,18 +20,18 @@ weight: 120 Files from the `.partials` directory do not end up with other generated files in the target directory. In this directory you should keep reusable templates chunks that you can [include](https://mozilla.github.io/nunjucks/templating.html#include) in your templates. You can also put there [macros](https://mozilla.github.io/nunjucks/templating.html#macro) to use them in templates, like in below example: ```html -{# tags.html #} -{% macro tags(tagList) %} +{# tags.html #} {% macro tags(tagList) %}
{% for tag in tagList %} - {{tag.name()}} + {{tag.name()}} {% endfor %}
-{% endmacro %} - -{# operations.html #} -{% from "./tags.html" import tags %} -{{ tags(operation.tags()) }} +{% endmacro %} {# operations.html #} {% from "./tags.html" import tags %} {{ +tags(operation.tags()) }} ``` ### Filters @@ -52,7 +52,7 @@ const filter = module.exports; async function asyncCamelCase(str, callback) { try { const result = // logic for camel casing str - callback(null, result); + callback(null, result); } catch (error) { callback(error); } @@ -60,7 +60,11 @@ async function asyncCamelCase(str, callback) { filter.renderAsyncContent = renderAsyncContent; // using in template -{{ channelName | asyncCamelCase }} +{ + { + channelName | asyncCamelCase; + } +} ``` Unfortunately, if you need to use Promise, filter still must be annotated with the `async` keyword: @@ -75,5 +79,4 @@ async function asyncCamelCase(str, callback) { In case you have more than one template and want to reuse filters, you can put them in a single library. You can configure such a library in the template configuration under `filters` property. To learn how to add such filters to configuration [read more about the configuration file](#configuration-file). - -You can also use the official AsyncAPI [nunjucks-filters](/apps/nunjucks-filters) that are by default included in the generator library. \ No newline at end of file +You can also use the official AsyncAPI [nunjucks-filters](/apps/nunjucks-filters) that are by default included in the generator library. diff --git a/apps/generator/docs/parser.md b/apps/generator/docs/parser.md index 399308d67..6f1ff86b9 100644 --- a/apps/generator/docs/parser.md +++ b/apps/generator/docs/parser.md @@ -5,7 +5,7 @@ weight: 60 ## Parser -The AsyncAPI Parser is a package used to parse and validate the [AsyncAPI documents](asyncapi-document) in your Node.js or browser application. These documents can be either in YAML or JSON format. +The AsyncAPI Parser is a package used to parse and validate the [AsyncAPI documents](asyncapi-document.md) in your Node.js or browser application. These documents can be either in YAML or JSON format. The Parser validates these documents using dedicated schema-supported plugins. @@ -19,7 +19,7 @@ Supported schemas: The Parser allows the template developer to easily access schemas provided in the above supported formats. This is because the JavaScript parser converts all of them into JSON schema. -If the document is valid, the Parser returns an `AsyncAPIDocument instance` with a set of helper functions that enable easier access to the contents of the AsyncAPI document. The parser provides dereferenced output. During the dereference process, the AsyncAPI parser substitutes a reference with a full definition. The dereferenced output is always in JSON format. The parser provides a message listing all errors if a document is invalid. The original AsyncAPI document is part of the [Template Context](template-context) as the generator also passes the original AsyncAPI document to the template context. +If the document is valid, the Parser returns an `AsyncAPIDocument instance` with a set of helper functions that enable easier access to the contents of the AsyncAPI document. The parser provides dereferenced output. During the dereference process, the AsyncAPI parser substitutes a reference with a full definition. The dereferenced output is always in JSON format. The parser provides a message listing all errors if a document is invalid. The original AsyncAPI document is part of the [Template Context](template-context.md) as the generator also passes the original AsyncAPI document to the template context. The following AsyncAPI document example has two channels: `channelOne` and `channelTwo`. Each channel has one operation and a single message: @@ -81,7 +81,7 @@ const messages = asyncAPIDocument.allMessages(); - `invalid-yaml` - `impossible-to-convert-to-json` 1. If the document is valid, the Parser modifies the AsyncAPI document, returns a set of helper functions, and bundles them together into the **asyncapi** variable. These helper functions in the form of an **asyncapi** variable are passed to the **Template Context**. -1. The Template Context passes all of these values to the [**Render Engine**](react-render-engine) of your choice. Finally, the Render Engine generates whatever output you may have specified in your template. (i.e. code, documentation, diagrams, pdfs, applications, etc.) +1. The Template Context passes all of these values to the [**Render Engine**](react-render-engine.md) of your choice. Finally, the Render Engine generates whatever output you may have specified in your template. (i.e. code, documentation, diagrams, pdfs, applications, etc.) ```mermaid graph TD diff --git a/apps/generator/docs/react-render-engine.md b/apps/generator/docs/react-render-engine.md index 1cf74b983..18bca3d6f 100644 --- a/apps/generator/docs/react-render-engine.md +++ b/apps/generator/docs/react-render-engine.md @@ -5,14 +5,14 @@ weight: 110 [React](https://reactjs.org) is the render engine that we strongly suggest you should use for any new templates. The only reason it is not the default render engine is to stay backward compatible. -* It enables the possibility of [debugging](#debugging-react-template) your template (this is not possible with Nunjucks). -* It provides better error stack traces. -* Provides better support for separating code into more manageable chunks/components. -* The readability of the template is much better compared to Nunjucks syntax. -* Better tool support for development. -* Introduces testability of components which is not possible with Nunjucks. - -When writing React templates you decide whether to use CommonJS, ES5, or ES6 modules since everything is bundled together before the rendering process takes over. We use our own React renderer which can be found in the [Generator React SDK](https://github.com/asyncapi/generator-react-sdk). +- It enables the possibility of [debugging](#debugging-react-template) your template (this is not possible with Nunjucks). +- It provides better error stack traces. +- Provides better support for separating code into more manageable chunks/components. +- The readability of the template is much better compared to Nunjucks syntax. +- Better tool support for development. +- Introduces testability of components which is not possible with Nunjucks. + +When writing React templates you decide whether to use CommonJS, ES5, or ES6 modules since everything is bundled together before the rendering process takes over. We use our own React renderer which can be found in the [Generator React SDK](https://github.com/asyncapi/generator-react-sdk). There you can find information about how the renderer works or how we transpile your template files. Your React template always requires `@asyncapi/generator-react-sdk` as a dependency. `@asyncapi/generator-react-sdk` is required to access the `File` component which is required as a root component for a file to be rendered. Furthermore, it provides some common components to make your development easier, like `Text` or `Indent`. @@ -22,7 +22,7 @@ Let's consider a basic React template as the one below called `MyTemplate.js`: ```js import { File, Text } from "@asyncapi/generator-react-sdk"; -export default function({ asyncapi, params, originalAsyncAPI }) { +export default function ({ asyncapi, params, originalAsyncAPI }) { return ( Some text that should render as is @@ -31,21 +31,21 @@ export default function({ asyncapi, params, originalAsyncAPI }) { } ``` -The exported default function returns a `File` component as a root component which the generator uses to determine what file should be generated. In our case, we overwrite the default functionality of saving the file as `MyTemplate.js` but instead use the filename `asyncapi.md`. It is then specified that we should render `Some text that should render as is\n` within that file. Notice the `\n` character at the end, which is automatically added after the `Text` component. +The exported default function returns a `File` component as a root component which the generator uses to determine what file should be generated. In our case, we overwrite the default functionality of saving the file as `MyTemplate.js` but instead use the filename `asyncapi.md`. It is then specified that we should render `Some text that should render as is\n` within that file. Notice the `\n` character at the end, which is automatically added after the `Text` component. For further information about components, props, etc, see the [Generator React SDK](https://github.com/asyncapi/generator-react-sdk) ### Common assumptions 1. Generator renders all files located in the `template` directory if they meet the following conditions: - - `File` is the root component - - The file is not in the list of `nonRenderableFiles` in the template configuration + - `File` is the root component + - The file is not in the list of `nonRenderableFiles` in the template configuration 1. New lines are automatically added after each `Text` component. 1. The props you have access to in the rendering function are: - `asyncapi` which is a parsed spec file object. Read the [API](https://github.com/asyncapi/parser-api/blob/master/docs/api.md#asyncapidocument) of the Parser to understand what structure you have access to in this parameter. - - `originalAsyncAPI` which is an original spec file before it is parsed. + - `originalAsyncAPI` which is an original spec file before it is parsed. - `params` that contain the parameters provided when generating. -1. All the file templates are supported where the variables are provided after the default props as listed above. +1. All the file templates are supported where the variables are provided after the default props as listed above. ### Debugging React template in VSCode @@ -76,5 +76,3 @@ With React, it enables you to debug your templates. For Visual Studio Code, we h ``` Now replace `./asyncapi.yml` with your document of choice. Replace `./template` with the path to your React template. You can now debug your template by adding any breakpoints you want and inspecting your code. - - diff --git a/apps/generator/docs/special-file-names.md b/apps/generator/docs/special-file-names.md index 536eee841..2c2b77119 100644 --- a/apps/generator/docs/special-file-names.md +++ b/apps/generator/docs/special-file-names.md @@ -5,7 +5,7 @@ weight: 160 We use NPM behind the scenes to download and install the templates. Since NPM will not fetch files like `.gitignore`, you should name them differently. Luckily, the Generator will take care of renaming them back for you. The following is a table of the special file names: -|Special file name|Output file name| -|---|---| -|`{.gitignore}`|`.gitignore`| -|`{.npmignore}`|`.npmignore`| \ No newline at end of file +| Special file name | Output file name | +| ----------------- | ---------------- | +| `{.gitignore}` | `.gitignore` | +| `{.npmignore}` | `.npmignore` | diff --git a/apps/generator/docs/template-context.md b/apps/generator/docs/template-context.md index b6b01fd94..89cce3f4f 100644 --- a/apps/generator/docs/template-context.md +++ b/apps/generator/docs/template-context.md @@ -4,17 +4,18 @@ weight: 100 --- While using the generator tool, you may want dynamic values populated to your templates and rendered in the output. The generator can achieve that using the **template context**. -The **template context** allows you to access the contents of the [AsyncAPI document](asyncapi-document) and inject dynamic values to the template files passed to the asyncAPI CLI during the generation process. The render engine then displays these dynamically assigned values in the output. +The **template context** allows you to access the contents of the [AsyncAPI document](asyncapi-document.md) and inject dynamic values to the template files passed to the asyncAPI CLI during the generation process. The render engine then displays these dynamically assigned values in the output. ## Generation process + 1. The **Generator** receives **Template** and **params** as input. -2. The **Generator** sends to the **Parser** the **asyncapiString** which is a stringified version of the original **AsyncAPI document**. +2. The **Generator** sends to the **Parser** the **asyncapiString** which is a stringified version of the original **AsyncAPI document**. 3. The **Parser** validates the format of the **asyncapiString** using OpenAPI, RAML, or Avro schemas. 4. If the **asyncapiString** is valid, the **parser** manipulates it, returns a set of helper functions and properties, and bundles them into an **asyncapi** variable. The **asyncapi** variable is an instance of the **AsyncAPI document**. The helper functions and properties make it easier to access the contents of the **AsyncAPI document** in the template. 5. The **Generator** then passes the **params**, which are template-specific options used to customize the output, the **Template files**, and the **asyncapi** which collectively make up the **Template Context**. 6. The **Template Context** is then passed to the **Render Engine**. The **Render Engine** then injects all the dynamic values from the **Template Context** into the **Template files**. - -``` mermaid + +```mermaid graph LR A[Template Context] B{Generator} @@ -34,8 +35,9 @@ graph LR ``` ## Template context + The extra context passed to the render engine during the generation process and made accessible in the templates includes: - **`originalAsyncAPI`** is a stringified version of the original AsyncAPI document that the user passed to the Generator. - **`asyncapi`** is a parsed AsyncAPI document with helper functions and properties. You should use it to access document contents e.g `asyncapi.title`. -- **`params`** is an object with all the parameters passed to the Generator by the user. \ No newline at end of file +- **`params`** is an object with all the parameters passed to the Generator by the user. diff --git a/apps/generator/docs/template-development.md b/apps/generator/docs/template-development.md index 423222505..d96d12fbd 100644 --- a/apps/generator/docs/template-development.md +++ b/apps/generator/docs/template-development.md @@ -2,6 +2,7 @@ title: "Template development" weight: 80 --- + > **Note** > It is advised against attempting to manually template types and models from scratch using the AsyncAPI templating engines such as Nunjucks and React render engines. Instead, it is recommended to use [AsyncAPI Modelina](/docs/tools/generator/model-generation) a dedicated library for model generation. @@ -16,6 +17,7 @@ Let's break down the minimum template requirements: the `template` directory and The `template` directory holds all the files that will be used for generating the output. The generator will process all the files stored in this directory. The following code is an example of an `index.js` file inside the `template` folder. + ```js import { File, Text } from "@asyncapi/generator-react-sdk"; @@ -35,7 +37,7 @@ The above example will produce an `asyncapi.md` file where usage of the AsyncAPI Before the generation process begins, the generator installs the template into its dependencies. A `package.json` file is necessary to identify the template name. -The following block shows an example `package.json` file that points to the [React Render Engine](react-render-engine) and necessary dependencies: +The following block shows an example `package.json` file that points to the [React Render Engine](react-render-engine.md) and necessary dependencies: ```json { @@ -55,20 +57,20 @@ Every template must depend on the [`@asyncapi/generator-react-sdk` package](http You must configure the generator's `package.json` file to contain JSON objects with the required parameters for template configuration, such as: -|Name|Type|Description| -|---|---|---| -|`renderer`| String | Its value can be either `react` or `nunjucks` (default). -|`supportedProtocols`| [String] | A list with all the protocols this template supports. -|`parameters`| Object[String, Object] | An object with all the parameters that can be passed when generating the template. When using the command line, it's done by indicating `--param name=value` or `-p name=value`. -|`parameters[param].description`| String | A user-friendly description about the parameter. -|`parameters[param].default`| Any | Default value of the parameter if not specified. Shouldn't be used for mandatory `required=true` parameters. -|`parameters[param].required`| Boolean | Whether the parameter is required or not. +| Name | Type | Description | +| ------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `renderer` | String | Its value can be either `react` or `nunjucks` (default). | +| `supportedProtocols` | [String] | A list with all the protocols this template supports. | +| `parameters` | Object[String, Object] | An object with all the parameters that can be passed when generating the template. When using the command line, it's done by indicating `--param name=value` or `-p name=value`. | +| `parameters[param].description` | String | A user-friendly description about the parameter. | +| `parameters[param].default` | Any | Default value of the parameter if not specified. Shouldn't be used for mandatory `required=true` parameters. | +| `parameters[param].required` | Boolean | Whether the parameter is required or not. | The above table lists some configuration options that help the generator achieve a specific set of tasks throughout the generation process. The `generator` property from 'package.json' contains all the configuration information. To learn more about template configuration and various supported parameters, read the [generator configuration file](configuration-file). -> Whenever you make a change to the package.json, make sure you perform an update by running `npm install`; this command synchronizes with the `package-lock.json` and validates the file. +> Whenever you make a change to the package.json, make sure you perform an update by running `npm install`; this command synchronizes with the `package-lock.json` and validates the file. -### `package.json` configuration options +### `package.json` configuration options The following examples show some advanced configurations that we can use in our `package.json` file: @@ -77,18 +79,17 @@ The following examples show some advanced configurations that we can use in our "name": "myTemplate", "generator": { "renderer": "react", - "supportedProtocols": [ - "mqtt" - ] + "supportedProtocols": ["mqtt"] }, "dependencies": { "@asyncapi/generator-react-sdk": "^0.2.25" } } ``` -The above `package.json` file has a newly added configuration called `supportedProtocols` which is set to a list containing only `mqtt`. This configuration displays all the protocols that this template supports. You can have multiple supported protocols in our template. -For example, if you want to generate an output using the above template, you need to have an AsyncAPI document with servers that use `mqtt` to generate your desired output. If your AsyncAPI document has server connections with `kafka`, the generation process will be terminated since the only supported protocol mentioned is `mqtt`. +The above `package.json` file has a newly added configuration called `supportedProtocols` which is set to a list containing only `mqtt`. This configuration displays all the protocols that this template supports. You can have multiple supported protocols in our template. + +For example, if you want to generate an output using the above template, you need to have an AsyncAPI document with servers that use `mqtt` to generate your desired output. If your AsyncAPI document has server connections with `kafka`, the generation process will be terminated since the only supported protocol mentioned is `mqtt`. ### Accessing template parameters @@ -99,14 +100,12 @@ Additionally, we can also have a configuration called `parameters`, which is an "name": "myTemplate", "generator": { "renderer": "react", - "supportedProtocols": [ - "mqtt" - ], + "supportedProtocols": ["mqtt"], "parameters": { - "version": { - "description": "Overrides application version under `info.version` in the AsyncAPI document.", - "required": false - } + "version": { + "description": "Overrides application version under `info.version` in the AsyncAPI document.", + "required": false + } } }, "dependencies": { @@ -122,7 +121,7 @@ The changes done in the template will be as follows: Original: ```js -App name: **{ asyncapi.info().title() }** +App name: **{asyncapi.info().title()}** ``` Newer: @@ -145,12 +144,13 @@ Hooks help you change the specification version with the new `version` that you ```js module.exports = { - 'generate:before': ({ asyncapi, templateParams = {} }) => { + "generate:before": ({ asyncapi, templateParams = {} }) => { const version = templateParams.version || asyncapi.info().version(); asyncapi._json.info.version = version; - } + }, }; ``` + This can be an even better alternative to overriding the `version` parameter we discussed in the previous section. A markdown document will be generated, and the AsyncAPI document passed to the generator will be returned with the overwritten version. The updated template looks like the following: diff --git a/apps/generator/docs/template.md b/apps/generator/docs/template.md index b8f31db01..9a452e227 100644 --- a/apps/generator/docs/template.md +++ b/apps/generator/docs/template.md @@ -5,7 +5,7 @@ weight: 50 ## Template -A template is a project that specifies the generation process output by using the AsyncAPI generator and an [AsyncAPI document](asyncapi-document). These files describe the generation results depending on the AsyncAPI document's content. +A template is a project that specifies the generation process output by using the AsyncAPI generator and an [AsyncAPI document](asyncapi-document.md). These files describe the generation results depending on the AsyncAPI document's content. Examples outputs: @@ -18,13 +18,13 @@ A template is an independent Node.js project unrelated to the `generator` reposi The generator uses the official [Arborist](https://www.npmjs.com/package/@npmcli/arborist) NPM library. (This means templates do not have to be published to package managers to use them.) Arborist helps the generator fetch the template's source code and use it for the generation process. By default, this library pulls data from the default NPM registry, which is https://registry.npmjs.org. You can also configure the generator to fetch templates that are private or hosted in different NPM registry -You can store template projects on a local drive or as a `git` repository during the development process. +You can store template projects on a local drive or as a `git` repository during the development process. ## Template generation process 1. Template is provided as input to the **Generator**. 2. **asyncapi** is the original AsyncAPI document injected into your template file by default. -3. **params** are the parameters you pass to the AsyncAPI CLI. Later, you can also pass these **params** further to other components. +3. **params** are the parameters you pass to the AsyncAPI CLI. Later, you can also pass these **params** further to other components. 4. The generator passes both the original **asyncapi**, the original AsyncAPI document, and the **params** to the **Template Context**. 5. Concurrently, the generator passes **Template files** to the **Render engine** as well. AsyncAPI uses two render engines — _react_ and _nunjucks_. 6. Once the Render Engine receives both the Template Files and the Template Context, it injects all the dynamic values into your react or nunjucks engine, based on the Template Files using the Template Context. @@ -51,23 +51,22 @@ AsyncAPI has a list of available templates to enhance your generation process. T -Template Name | Description | Source code ----|---|--- -`@asyncapi/nodejs-template` | Generates Node.js service that uses Hermes package | [Node.js template](https://github.com/asyncapi/nodejs-template) -`@asyncapi/nodejs-ws-template` | Generates Node.js service that supports WebSocket protocol only | [Node.js WebSocket template](https://github.com/asyncapi/nodejs-ws-template) -`@asyncapi/java-template` | Generates Java JMS application | [Java template](https://github.com/asyncapi/java-template) -`@asyncapi/java-spring-template` | Generates Java Spring service | [Java spring template](https://github.com/asyncapi/java-spring-template) -`@asyncapi/java-spring-cloud-stream-template` | Generates Java Spring Cloud Stream service | [Java spring cloud stream template](https://github.com/asyncapi/java-spring-cloud-stream-template) -`@asyncapi/python-paho-template` | Generates Python service that uses Paho library | [Python paho template](https://github.com/asyncapi/python-paho-template) -`@asyncapi/html-template` | Generates HTML documentation site | [HTML template](https://github.com/asyncapi/html-template) -`@asyncapi/markdown-template` | Generates documentation in Markdown file | [Markdown template](https://github.com/asyncapi/markdown-template) -`@asyncapi/ts-nats-template` | Generates TypeScript NATS client | [TypeScript/Node.js NATS template](https://github.com/asyncapi/ts-nats-template/) -`@asyncapi/go-watermill-template` | Generates Go client using Watermill | [GO watermill template](https://github.com/asyncapi/go-watermill-template) -`@asyncapi/dotnet-nats-template` | Generates .NET C# client using NATS | [.NET C# NATS template](https://github.com/asyncapi/dotnet-nats-template) +| Template Name | Description | Source code | +| --------------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| `@asyncapi/nodejs-template` | Generates Node.js service that uses Hermes package | [Node.js template](https://github.com/asyncapi/nodejs-template) | +| `@asyncapi/nodejs-ws-template` | Generates Node.js service that supports WebSocket protocol only | [Node.js WebSocket template](https://github.com/asyncapi/nodejs-ws-template) | +| `@asyncapi/java-template` | Generates Java JMS application | [Java template](https://github.com/asyncapi/java-template) | +| `@asyncapi/java-spring-template` | Generates Java Spring service | [Java spring template](https://github.com/asyncapi/java-spring-template) | +| `@asyncapi/java-spring-cloud-stream-template` | Generates Java Spring Cloud Stream service | [Java spring cloud stream template](https://github.com/asyncapi/java-spring-cloud-stream-template) | +| `@asyncapi/python-paho-template` | Generates Python service that uses Paho library | [Python paho template](https://github.com/asyncapi/python-paho-template) | +| `@asyncapi/html-template` | Generates HTML documentation site | [HTML template](https://github.com/asyncapi/html-template) | +| `@asyncapi/markdown-template` | Generates documentation in Markdown file | [Markdown template](https://github.com/asyncapi/markdown-template) | +| `@asyncapi/ts-nats-template` | Generates TypeScript NATS client | [TypeScript/Node.js NATS template](https://github.com/asyncapi/ts-nats-template/) | +| `@asyncapi/go-watermill-template` | Generates Go client using Watermill | [GO watermill template](https://github.com/asyncapi/go-watermill-template) | +| `@asyncapi/dotnet-nats-template` | Generates .NET C# client using NATS | [.NET C# NATS template](https://github.com/asyncapi/dotnet-nats-template) | > Some of these templates are maintained by various third-party organizations. The README file usually contains this information and more, such as configuration options the user can pass to the template, usage, technical requirements, etc. > Check out all our community [generator templates](https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate) - diff --git a/apps/generator/docs/typescript-support.md b/apps/generator/docs/typescript-support.md index 5c785cd3c..6fc3ef9b3 100644 --- a/apps/generator/docs/typescript-support.md +++ b/apps/generator/docs/typescript-support.md @@ -9,5 +9,3 @@ The AsyncAPI generator has TypeScript support for [hooks](#hooks) and Nunjucks's - Source code of the hook/filter must have `.ts` extension. - Each package related to the typings for TypeScript like `@types/node` must be installed in the template under `dependencies` array. This is because the Generator transpiles the TypeScript code on-the-fly while rendering the template, and cannot use packages under `devDependencies`. - Each template should have `@types/node` package installed to enable support for typings for Node. - - diff --git a/apps/generator/docs/usage.md b/apps/generator/docs/usage.md index 344044680..6965ce7fd 100644 --- a/apps/generator/docs/usage.md +++ b/apps/generator/docs/usage.md @@ -4,11 +4,14 @@ weight: 30 --- There are two ways to use the generator: + - [AsyncAPI CLI](#generator-cli) - [Generator library](#using-as-a-modulepackage) ## AsyncAPI CLI + Generates whatever you want using templates compatible with AsyncAPI Generator. + ```bash USAGE $ asyncapi generate fromTemplate [ASYNCAPI] [TEMPLATE] [-h] [-d ] [-i] [--debug] [-n ] [-o ] [--force-write] [-w] [-p ] [--map-base-url ] @@ -34,6 +37,7 @@ EXAMPLES ``` All templates are installable npm packages. Therefore, the value of `template` can be anything supported by `npm install`. Here's a summary of the possibilities: + ``` npm install [<@scope>/] npm install [<@scope>/]@ @@ -59,21 +63,25 @@ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template ### CLI usage examples **The shortest possible syntax:** + ```bash asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template ``` **Generating from a URL:** + ```bash asyncapi generate fromTemplate https://bit.ly/asyncapi @asyncapi/html-template ``` **Specify where to put the result:** + ```bash asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs ``` **Passing parameters to templates:** + ```bash asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs -p title='Hello from param' ``` @@ -81,6 +89,7 @@ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs - In the template you can use it like this: ` {{ params.title }}` **Disabling the hooks:** + ```bash asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs -d generate:before generate:after=foo,bar ``` @@ -88,18 +97,21 @@ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs - The generator skips all hooks of the `generate:before` type and `foo`, `bar` hooks of the `generate:after` type. **Installing the template from a folder:** + ```bash asyncapi generate fromTemplate asyncapi.yaml ~/my-template ``` -It creates a symbolic link to the target directory (`~/my-template` in this case). +It creates a symbolic link to the target directory (`~/my-template` in this case). **Installing the template from a git URL:** + ```bash asyncapi generate fromTemplate asyncapi.yaml https://github.com/asyncapi/html-template.git ``` **Map schema references from baseUrl to local folder:** + ```bash asyncapi generate fromTemplate test/docs/apiwithref.json @asyncapi/html-template -o ./build/ --force-write --map-base-url https://schema.example.com/crm/:./test/docs/ ``` @@ -124,11 +136,12 @@ docker run --rm -it \ -v ${PWD}/output:/app/output \ asyncapi/cli generate fromTemplate -o /app/output /app/asyncapi.yml @asyncapi/html-template --force-write ``` -Note: Use ``` ` ``` instead of `\` for Windows. + +Note: Use `` ` `` instead of `\` for Windows. ### CLI usage with `npx` instead of `npm` -[npx](https://www.npmjs.com/package/npx) is very useful when you want to run the generator in a CI/CD environment. In such a scenario, do not install the generator globally because most environments that provide Node.js and Npm, also provide npx out of the box. +[npx](https://www.npmjs.com/package/npx) is very useful when you want to run the generator in a CI/CD environment. In such a scenario, do not install the generator globally because most environments that provide Node.js and Npm, also provide npx out of the box. Use the following npx command on your terminal: @@ -137,21 +150,28 @@ npx -p @asyncapi/cli asyncapi generate fromTemplate ./asyncapi.yaml @asyncapi/ht ``` ## Using as a module/package + Once you install the generator in your project, you can use it to generate whatever you want. The following code snippet is an example of HTML generation using the official `@asyncapi/html-template` template and fetching the spec document from the server using: + ``` https://raw.githubusercontent.com/asyncapi/asyncapi/2.0.0/examples/2.0.0/streetlights.yml ``` ```js -const path = require('path'); -const generator = new Generator('@asyncapi/html-template', path.resolve(__dirname, 'example')); +const path = require("path"); +const generator = new Generator( + "@asyncapi/html-template", + path.resolve(__dirname, "example") +); try { - await generator.generateFromURL('https://raw.githubusercontent.com/asyncapi/asyncapi/2.0.0/examples/2.0.0/streetlights.yml'); - console.log('Done!'); + await generator.generateFromURL( + "https://raw.githubusercontent.com/asyncapi/asyncapi/2.0.0/examples/2.0.0/streetlights.yml" + ); + console.log("Done!"); } catch (e) { console.error(e); } ``` -See the [API documentation](api) for more examples and full API reference information. \ No newline at end of file +See the [API documentation](api) for more examples and full API reference information. diff --git a/apps/generator/docs/using-private-template.md b/apps/generator/docs/using-private-template.md index 8d8d9faa9..a2ed2f11b 100644 --- a/apps/generator/docs/using-private-template.md +++ b/apps/generator/docs/using-private-template.md @@ -2,40 +2,41 @@ title: "Using private templates" weight: 180 --- -Generator allows fetching the template from private repositories like Verdaccio, Nexus, npm, etc. -By default, the generator fetches the template from the public npm registry configured in the npm configuration. -To fetch the template from a private registry, you need to provide the registry URL and authentication details in the .npmrc. For more information [read the docs](https://docs.npmjs.com/cli/v9/configuring-npm/npmrc). -However, you can override the default behavior by providing the registry URL and authentication details as arguments of the commandline. +Generator allows fetching the template from private repositories like Verdaccio, Nexus, npm, etc. +By default, the generator fetches the template from the public npm registry configured in the npm configuration. +To fetch the template from a private registry, you need to provide the registry URL and authentication details in the .npmrc. For more information [read the docs](https://docs.npmjs.com/cli/v9/configuring-npm/npmrc). +However, you can override the default behavior by providing the registry URL and authentication details as arguments of the commandline. ## Private registry using .npmrc: + ```bash npm config set registry http://verdaccio:4873 npm config set //verdaccio:4873/:_auth=$(echo -n 'username:password' | base64) ``` -* **npm config set registry** : Provide the registry URL that points to the registry URL. -* **npm config set _auth** : Provide the base64 encoded value that represents the username and password for basic auth. -* **npm config set _authToken** : Provide the access token generated by the registry. + +- **npm config set registry** : Provide the registry URL that points to the registry URL. +- **npm config set \_auth** : Provide the base64 encoded value that represents the username and password for basic auth. +- **npm config set \_authToken** : Provide the access token generated by the registry. ## Private registry overriding arguments: -* **registry.url**: The URL of the registry where the private template is located. Defaults to `registry.npmjs.org`. -* **registry.auth**: An optional parameter to pass the npm registry username and password encoded with base64, formatted as `username:password`. For example, if the username and password are `admin` and `nimda`, you need to encode them with the base64 value like `admin:nimda` which results in `YWRtaW46bmltZGE=`. -* **registry.token**: An optional parameter to pass to the npm registry authentication token. To get the token, you can first authenticate with the registry using `npm login` and then grab the generated token from the `.npmrc` file. +- **registry.url**: The URL of the registry where the private template is located. Defaults to `registry.npmjs.org`. +- **registry.auth**: An optional parameter to pass the npm registry username and password encoded with base64, formatted as `username:password`. For example, if the username and password are `admin` and `nimda`, you need to encode them with the base64 value like `admin:nimda` which results in `YWRtaW46bmltZGE=`. +- **registry.token**: An optional parameter to pass to the npm registry authentication token. To get the token, you can first authenticate with the registry using `npm login` and then grab the generated token from the `.npmrc` file. ## Pulling private template using library: ```javascript -const generator = new Generator('@asyncapi/html-template', 'output', - { - debug: true, - registry: { - url: 'http://verdaccio:4873', - auth: 'YWRtaW46bmltZGE=' - // base64 encoded username and password - // represented as admin:nimda - - } - }); +const generator = new Generator("@asyncapi/html-template", "output", { + debug: true, + registry: { + url: "http://verdaccio:4873", + auth: "YWRtaW46bmltZGE=", + // base64 encoded username and password + // represented as admin:nimda + }, +}); ``` + Assuming you host `@asyncapi/html-template` in a private package registry like Verdaccio. To pull this template, you need to provide `registry.url` option that points to the registry URL and `registry.auth` as a base64 encoded value that represents the username and password. Instead of username and password, you can also pass `registry.token`. diff --git a/apps/generator/docs/versioning.md b/apps/generator/docs/versioning.md index 5409d822b..f0c75994a 100644 --- a/apps/generator/docs/versioning.md +++ b/apps/generator/docs/versioning.md @@ -3,19 +3,21 @@ title: "Generator version vs template version" weight: 70 --- -The generator tool generates whatever you want, as long as it can be defined in a template based on the [AsyncAPI document](asyncapi-document). On the other hand, a **template** is a file or group of files that specify the kind of output you expect from using the generator's features. For example, you may want to use the [NodeJS template](https://github.com/asyncapi/nodejs-template) to generate boilerplate code for your message-based APIs. +The generator tool generates whatever you want, as long as it can be defined in a template based on the [AsyncAPI document](asyncapi-document.md). On the other hand, a **template** is a file or group of files that specify the kind of output you expect from using the generator's features. For example, you may want to use the [NodeJS template](https://github.com/asyncapi/nodejs-template) to generate boilerplate code for your message-based APIs. Templates are dependent on the generators' features. For example, the template you want to use may be compatible with the latest generator version but incompatible with the previous versions. Check the configuration file or ReadME of the template to see the version of the generator it supports. The generator has an `isTemplateCompatible` function that checks if the template is compatible with the version of the generator you want to use. If the template isn't compatible, you will see a terminal error output similar to the following: + ``` Something went wrong: Error: This template is not compatible with the current version of the generator (${generatorVersion}). This template is compatible with the following version range: ${generator}.`) ``` -> Use the following command to check the version of the AsyncAPI CLI you have installed with all its dependencies, like AsyncAPI Generator; `asyncapi config versions` +> Use the following command to check the version of the AsyncAPI CLI you have installed with all its dependencies, like AsyncAPI Generator; `asyncapi config versions` It is better to lock a specific version of the template and the generator if you plan to use the AsyncAPI CLI and a particular template in production. The differences between using the version of the AsyncAPI CLI you have installed and locking a certain version on production are demonstrated in the following code snippets. Generate HTML with the latest AsyncAPI CLI using the html-template. + ``` npm install -g @asyncapi/cli asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs @@ -28,4 +30,4 @@ npm install -g @asyncapi/cli@0.20.0 asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template@0.7.0 -o ./docs ``` -> Before using newer versions of the template, always look at the [changelog](https://github.com/asyncapi/html-template/releases) first. If the generator's features are not important to you, just make sure to use a version compatible with your template. \ No newline at end of file +> Before using newer versions of the template, always look at the [changelog](https://github.com/asyncapi/html-template/releases) first. If the generator's features are not important to you, just make sure to use a version compatible with your template.