@asyncapi/generator 2.6.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/Dockerfile +7 -8
  3. package/docs/asyncapi-document.md +2 -1
  4. package/docs/configuration-file.md +112 -33
  5. package/docs/generator-template-java.md +560 -0
  6. package/docs/generator-template.md +62 -29
  7. package/docs/hooks.md +3 -3
  8. package/docs/installation-guide.md +5 -51
  9. package/docs/migration-cli.md +5 -5
  10. package/docs/migration-nunjucks-react.md +1 -1
  11. package/docs/nunjucks-render-engine.md +4 -2
  12. package/docs/template.md +2 -2
  13. package/docs/usage.md +14 -32
  14. package/docs/versioning.md +3 -1
  15. package/lib/conditionalGeneration.js +162 -0
  16. package/lib/filtersRegistry.js +1 -1
  17. package/lib/generator.js +93 -40
  18. package/lib/hooksRegistry.js +8 -1
  19. package/lib/logMessages.js +6 -1
  20. package/lib/parser.js +10 -0
  21. package/lib/templateConfigValidator.js +30 -1
  22. package/package.json +4 -5
  23. package/test/generator.test.js +1 -1
  24. package/test/hooksRegistry.test.js +173 -0
  25. package/test/integration.test.js +47 -0
  26. package/test/parser.test.js +100 -2
  27. package/test/templateConfigValidator.test.js +18 -1
  28. package/test/test-project/README.md +5 -1
  29. package/test/test-project/docker-compose.yml +7 -15
  30. package/test/test-project/test-project.test.js +6 -2
  31. package/test/test-project/test-registry.test.js +7 -2
  32. package/test/test-project/test.sh +1 -1
  33. package/test/test-templates/nunjucks-template/package-lock.json +43 -119
  34. package/test/test-templates/nunjucks-template/package.json +1 -1
  35. package/test/test-templates/react-template/.ageneratorrc +33 -0
  36. package/test/test-templates/react-template/package.json +5 -21
  37. package/test/test-templates/react-template/template/conditionalFile.txt +0 -0
  38. package/test/test-templates/react-template/template/conditionalFolder/conditionalFile.txt +0 -0
  39. package/test/test-templates/react-template/template/conditionalFolder2/input.txt +0 -0
  40. package/test/utils.test.js +53 -0
  41. package/test/test-project/test-entrypoint.sh +0 -12
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Creating a template"
2
+ title: "Creating a template - Python"
3
3
  weight: 170
4
4
  ---
5
5
 
@@ -14,6 +14,29 @@ In this tutorial:
14
14
  - You'll create a React template that will use the MQTT broker to allow you to monitor your bedroom's temperature and notify you when the temperature drops or rises above 22 °C.
15
15
  - Lastly, create a reusable component for the output code's `sendTemperatureDrop` and `sendTemperatureRise` functions.
16
16
 
17
+ ## Prerequisites
18
+
19
+ Before you begin, make sure you have the following set up:
20
+
21
+ - **Basic Programming Knowledge** – Familiarity with JavaScript and Python.
22
+ - **NPM & PIP** – Required for installing dependencies. Install NPM from the [official guide](https://nodejs.org/en/download) and PIP from the [official guide](https://pip.pypa.io/en/stable/installation).
23
+ - **AsyncAPI CLI** – Used for code generation, install using [CLI installation guide](https://www.asyncapi.com/docs/tools/cli/installation).
24
+ - **Docker** - Required for running MQTT CLI. Install it from the official [Docker](https://docs.docker.com/) website.
25
+ - **Code Editor (VS Code recommended)** – A good code editor is essential for development and debugging.
26
+ - **Knowledge of Template Development** – Review the [Template Development Guide](template-development) to understand the structure and minimum requirements for templates.
27
+
28
+ > **Note:** In this tutorial, we are using `test.mosquitto.org` as the public broker. However, sometimes it may not be reachable. If you experience any difficulty connecting to it, you can run a broker on your localhost instead.
29
+ >
30
+ > If you choose to run the broker on localhost, then in the further steps, replace all occurrences of `test.mosquitto.org` with `localhost` and run the following Docker command:
31
+ >
32
+ > ```sh
33
+ > docker run -d --name mosquitto -p 1883:1883 eclipse-mosquitto
34
+ > ```
35
+ >
36
+ > This starts an Eclipse Mosquitto broker locally on your machine, listening on port 1883.
37
+ >
38
+ > If you don’t want to use Docker, you can install Mosquitto manually. Follow the [official installation guide](https://mosquitto.org/download/) for your operating system.
39
+
17
40
  ## Background context
18
41
 
19
42
  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.
@@ -30,7 +53,7 @@ info:
30
53
 
31
54
  servers:
32
55
  dev:
33
- url: test.mosquitto.org
56
+ url: test.mosquitto.org #in case you're using local mosquitto instance, change this value to localhost.
34
57
  protocol: mqtt
35
58
 
36
59
  channels:
@@ -56,13 +79,6 @@ components:
56
79
  type: string
57
80
  ```
58
81
 
59
- <Remember>
60
-
61
- - To generate code, use the [AsyncAPI CLI](https://www.asyncapi.com/tools/cli). If you don't have the CLI installed, follow [CLI installation guide](/docs/tools/generator/installation-guide#asyncapi-cli).
62
- - If you are new to AsyncAPI Generator, check out the following docs: [template development](/docs/tools/generator/template-development), which explains the minimum requirements for a template and possible features.
63
-
64
- </Remember>
65
-
66
82
  ## Overview of steps
67
83
 
68
84
  1. Create a new directory for your template named **python-mqtt-client-template**.
@@ -122,7 +138,7 @@ Here's what is contained in the code snippet above:
122
138
  - **supportedProtocols** - A list that specifies which protocols are supported by your template.
123
139
  - **dependencies** - specifies which version of [`@asyncapi/generator-react-sdk`](https://github.com/asyncapi/generator-react-sdk) should be used.
124
140
 
125
- Navigate to the ****python-mqtt-client-template** directory. Run the command `npm install` on your terminal to install the dependencies specified in **package.json**.
141
+ Navigate to the **python-mqtt-client-template** directory. Run the command `npm install` on your terminal to install the dependencies specified in **package.json**.
126
142
 
127
143
  ### index.js file
128
144
 
@@ -258,7 +274,7 @@ while True:
258
274
 
259
275
  ```
260
276
 
261
- 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:
277
+ Navigate to the **python-mqtt-client-template/test/project** directory. Run the command `python test.py` on your terminal. You should see output similar to the snippet below logged on your terminal:
262
278
 
263
279
  ``` cmd
264
280
  New temperature detected 64250266 sent to temperature/changed
@@ -298,18 +314,35 @@ class TemperatureServiceClient:
298
314
 
299
315
  ### 4. Write script to run the test code
300
316
 
301
- In **package.json** you can have the scripts property that you invoke by calling `npm run <your_script>`. Add these scripts to **package.json**:
317
+ In **package.json** you can have the scripts property that you invoke by calling `npm run <your_script>`. After adding these scripts in **package.json**, it will look like the following code snippet:
302
318
 
303
319
  ``` json
304
- "scripts": {
320
+ {
321
+ "name": "python-mqtt-client-template",
322
+ "version": "0.0.1",
323
+ "description": "A template that generates a Python MQTT client using MQTT.",
324
+ "scripts": {
305
325
  "test:clean": "rimraf test/project/client.py",
306
326
  "test:generate": "asyncapi generate fromTemplate test/fixtures/asyncapi.yml ./ --output test/project --force-write",
307
327
  "test:start": "python test/project/test.py",
308
328
  "test": "npm run test:clean && npm run test:generate && npm run test:start"
329
+ },
330
+ "generator": {
331
+ "renderer": "react",
332
+ "apiVersion": "v1",
333
+ "generator": ">=1.10.0 <2.0.0",
334
+ "supportedProtocols": ["mqtt"]
335
+ },
336
+ "dependencies": {
337
+ "@asyncapi/generator-react-sdk": "^0.2.25"
338
+ },
339
+ "devDependencies": {
340
+ "rimraf": "^5.0.0"
341
+ }
309
342
  }
310
343
  ```
311
344
 
312
- The 4 scripts above do the following:
345
+ The 4 scripts added in **package.json** do the following:
313
346
 
314
347
  1. `test:clean`: This script uses the `rimraf` package to remove the old version of the file **test/project/client.py** every time you run your test.
315
348
  2. `test:generate`: This script uses the AsyncAPI CLI to generate a new version of **client.py**.
@@ -456,7 +489,7 @@ class TemperatureServiceClient:
456
489
  You'll then need to template to dynamically generate `sendTemperatureDrop` and `sendTemperatureRise` functions in the generated code based off the AsyncAPI document content. The goal is to write template code that returns functions for channels that the Temperature Service application is subscribed to. The template code to generate these functions will look like this:
457
490
 
458
491
  ```js
459
- <Text newLines={2}>
492
+ <Text indent={2} newLines={2}>
460
493
  <TopicFunction channels={asyncapi.channels().filterByReceive()} />
461
494
  </Text>
462
495
  ```
@@ -469,16 +502,16 @@ It's recommended to put reusable components outside the template directory in a
469
502
  * As input it requires a list of Channel models from the parsed AsyncAPI document
470
503
  */
471
504
  export function TopicFunction({ channels }) {
472
- const topicsDetails = getTopics(channels)
473
- let functions = ''
505
+ const topicsDetails = getTopics(channels);
506
+ let functions = '';
474
507
 
475
508
  topicsDetails.forEach((t) => {
476
509
  functions += `def send${t.name}(self, id):
477
510
  topic = "${t.topic}"
478
511
  self.client.publish(topic, id)\n`
479
- })
512
+ });
480
513
 
481
- return functions
514
+ return functions;
482
515
  }
483
516
 
484
517
  /*
@@ -489,19 +522,19 @@ export function TopicFunction({ channels }) {
489
522
  * As input it requires a list of Channel models from the parsed AsyncAPI document
490
523
  */
491
524
  function getTopics(channels) {
492
- const channelsCanSendTo = channels
493
- let topicsDetails = []
525
+ const channelsCanSendTo = channels;
526
+ let topicsDetails = [];
494
527
 
495
528
  channelsCanSendTo.forEach((ch) => {
496
- const topic = {}
497
- const operationId = ch.operations().filterByReceive()[0].id()
498
- topic.name = operationId.charAt(0).toUpperCase() + operationId.slice(1)
499
- topic.topic = ch.address()
529
+ const topic = {};
530
+ const operationId = ch.operations().filterByReceive()[0].id();
531
+ topic.name = operationId.charAt(0).toUpperCase() + operationId.slice(1);
532
+ topic.topic = ch.address();
500
533
 
501
- topicsDetails.push(topic)
534
+ topicsDetails.push(topic);
502
535
  })
503
536
 
504
- return topicsDetails
537
+ return topicsDetails;
505
538
  }
506
539
  ```
507
540
 
@@ -529,7 +562,7 @@ export default function ({ asyncapi, params }) {
529
562
  self.client.connect(mqttBroker)`}
530
563
  </Text>
531
564
 
532
- <Text indent={2}>
565
+ <Text indent={2} newLines={2}>
533
566
  <TopicFunction channels={asyncapi.channels().filterByReceive()} />
534
567
  </Text>
535
568
  </File>
@@ -616,4 +649,4 @@ Great job completing this tutorial! You have learnt how to use an AsyncAPI file
616
649
 
617
650
  If you want to tinker with a completed template and see what it would look like in production, check out the [Paho-MQTT template](https://github.com/derberg/python-mqtt-client-template/tree/v1.0.0). You can also check out the accompanying [article about creating MQTT client code](https://www.brainfart.dev/blog/asyncapi-codegen-python).
618
651
 
619
- You can also check out the [MQTT beginners guide](https://medium.com/python-point/mqtt-basics-with-python-examples-7c758e605d4) tutorial to learn more about asynchronous messaging using MQTT.
652
+ You can also check out the [MQTT beginners guide](https://medium.com/python-point/mqtt-basics-with-python-examples-7c758e605d4) tutorial to learn more about asynchronous messaging using MQTT.
package/docs/hooks.md CHANGED
@@ -11,9 +11,9 @@ The following types of hooks are currently supported:
11
11
 
12
12
  |Hook type|Description| Return type | Arguments
13
13
  |---|---|---|---|
14
- | `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](/api)
15
- | `generate:after` | Called at the very end of the generation. | void : Nothing is expected to be returned. | [The generator instance](/api)
16
- | `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](/api) and object in the form of `{ "originalFilename" : string }`
14
+ | `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](api)
15
+ | `generate:after` | Called at the very end of the generation. | void : Nothing is expected to be returned. | [The generator instance](api)
16
+ | `setFileTemplateName` | Called right before saving a new file generated by [file template](file-templates). | string : a new filename for the generator to use for the file template. | [The generator instance](api) and object in the form of `{ "originalFilename" : string }`
17
17
 
18
18
  ## Location
19
19
 
@@ -8,9 +8,9 @@ You can use the generator library to generate whatever you want in your event-dr
8
8
  - [Generator library in Node.js apps](#generator-library-in-nodejs-apps)
9
9
 
10
10
  ## Prerequisites
11
- Before you install and use the AsyncAPI CLI and the generator library, ensure you meet the prerequisites below, then [install the CLI](#installation).
12
- 1. Node.js v18.12.0 and higher
13
- 2. Npm v8.19.0 and higher
11
+ Before you install and use the AsyncAPI CLI and the generator library, ensure you meet the prerequisites below, then [install the CLI](https://www.asyncapi.com/docs/tools/cli/installation).
12
+ 1. Node.js v18.12.0 or higher
13
+ 2. Npm v8.19.0 or higher
14
14
 
15
15
  To verify the versions of Node and Npm you have, run the following command on your terminal:
16
16
  ```
@@ -25,55 +25,9 @@ If you don't have either Node or Npm installed, use the [official node.js instal
25
25
  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.
26
26
 
27
27
  ## AsyncAPI CLI
28
- 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.
28
+ 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. For the latest installation instructions, visit the official AsyncAPI CLI [installation guide](https://www.asyncapi.com/docs/tools/cli/installation).
29
29
 
30
- ### Installation
31
-
32
- #### Install AsyncAPI CLI using NPM
33
-
34
- The AsyncAPI CLI is a NodeJS project, so the easiest way to install it is by using the following `npm` command:
35
- ```
36
- npm install -g @asyncapi/cli
37
- ```
38
-
39
- To install a specific version of the generator tool, pass the version during installation:
40
- ```
41
- npm install -g @asyncapi/cli@{version}
42
- ```
43
-
44
- #### MacOS
45
- You can install in MacOS by using brew: `brew install asyncapi`.
46
-
47
- #### Linux
48
- You can install in Linux by using `dpkg`, a package manager for debian:
49
- 1. `curl -OL https://github.com/asyncapi/cli/releases/latest/download/asyncapi.deb`
50
- 2. `sudo dpkg -i asyncapi.deb`
51
-
52
- #### Other operating systems
53
- For further installation instructions for different operating systems, read the [AsyncAPI CLI documentation](https://github.com/asyncapi/cli#installation).
54
-
55
- > **Remember:**
56
- > 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.
57
-
58
- ### Update AsyncAPI CLI
59
- There are several reasons why you might want to update your generator version:
60
- * You have the generator tool installed but want to use the latest released features. To upgrade to the latest version, use the command below:
61
- ```
62
- npm install -g @asyncapi/cli
63
- ```
64
- * 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:
65
- ```
66
- npm install -g @asyncapi/cli@{version}
67
- ```
68
- > Sometimes you have to force additional npm installation like this: `npm install -g --force @asyncapi/cli`
69
-
70
- ### Uninstall AsyncAPI CLI
71
- To uninstall the generator, use the following command:
72
- ```
73
- npm uninstall @asyncapi/cli -g
74
- ```
75
-
76
- > :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).
30
+ > :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/asyncapi-cli-action).
77
31
 
78
32
  ## Generator library in Node.js apps
79
33
  Use the generator library in your Node.js projects by installing it via the following command: `npm install @asyncapi/generator`.
@@ -18,13 +18,13 @@ Here is a list of `ag` options and their equivalents in the AsyncAPI CLI:
18
18
  - **-i, --install**
19
19
  - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --install`
20
20
 
21
- - **-n, --no-overwrite <glob>**
21
+ - **-n, --no-overwrite &#x3C;glob&#x3E;**
22
22
  - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --no-overwrite <glob>`
23
23
 
24
- - **-o, --output <outputDir>**
24
+ - **-o, --output &#x3C;outputDir&#x3E;**
25
25
  - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --output <outputDir>`
26
26
 
27
- - **-p, --param <name=value>**
27
+ - **-p, --param &#x3C;name&#x3D;value&#x3E;**
28
28
  - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --param <name=value>`
29
29
 
30
30
  - **--force-write**
@@ -33,7 +33,7 @@ Here is a list of `ag` options and their equivalents in the AsyncAPI CLI:
33
33
  - **--watch-template**
34
34
  - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --watch`
35
35
 
36
- - **--map-base-url <url:folder>**
36
+ - **--map-base-url &#x3C;url:folder&#x3E;**
37
37
  - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --map-base-url <url:folder>`
38
38
 
39
39
  ## Migration Steps
@@ -67,4 +67,4 @@ Run the updated commands to ensure they work as expected and verify that the out
67
67
  **CLI Documentation**: [AsyncAPI CLI Documentation](https://www.asyncapi.com/docs/tools/cli)
68
68
  **Installation**: [AsyncAPI CLI Installation](https://www.asyncapi.com/docs/tools/cli/installation)
69
69
  **Usage**: [AsyncAPI CLI Usage](https://www.asyncapi.com/docs/tools/cli/usage)
70
- **Support**: For any issues with CLI, create an issue in [CLI repository](https://github.com/asyncapi/cli).
70
+ **Support**: For any issues with CLI, create an issue in [CLI repository](https://github.com/asyncapi/cli).
@@ -112,7 +112,7 @@ export default function({ asyncapi }) {
112
112
 
113
113
  ### 6. File template
114
114
 
115
- Check the [detailed guide on file templates](file-templates.md) to learn what is the difference between templating multiple file outputs in Nunjucks and React.
115
+ Check the [detailed guide on file templates](file-templates) to learn what is the difference between templating multiple file outputs in Nunjucks and React.
116
116
 
117
117
  ### 7. Models generation
118
118
 
@@ -75,7 +75,9 @@ async function asyncCamelCase(str, callback) {
75
75
  }
76
76
  ```
77
77
 
78
- 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).
78
+ 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).
79
79
 
80
80
 
81
- You can also use the official AsyncAPI [nunjucks-filters](/apps/nunjucks-filters) that are by default included in the generator library.
81
+ You can also use the official AsyncAPI [nunjucks-filters](https://github.com/asyncapi/generator/tree/master/apps/nunjucks-filters) which is included by default in the generator library.
82
+
83
+ > **Note:** The nunjucks-filters is deprecated, and you should migrate to react-renderer instead. For more details, read notes from release [@asyncapi/generator@2.6.0](https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0).
package/docs/template.md CHANGED
@@ -23,9 +23,9 @@ You can store template projects on a local drive or as a `git` repository during
23
23
  ## Template generation process
24
24
 
25
25
  1. Template is provided as input to the **Generator**.
26
- 2. **asyncapi** is the original AsyncAPI document injected into your template file by default.
26
+ 2. **asyncapi** (which is an instance of AsyncAPIDocument) is injected into your template file by default.
27
27
  3. **params** are the parameters you pass to the AsyncAPI CLI. Later, you can also pass these **params** further to other components.
28
- 4. The generator passes both the original **asyncapi**, the original AsyncAPI document, and the **params** to the **Template Context**.
28
+ 4. The generator passes both the **asyncapi**, the **originalAsyncAPI**, and the **params** to the **Template Context**.
29
29
  5. Concurrently, the generator passes **Template files** to the **Render engine** as well. AsyncAPI uses two render engines — _react_ and _nunjucks_.
30
30
  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.
31
31
  7. The render engine generates whatever output you may have specified in your template. (i.e. code, documentation, diagrams, pdfs, applications, etc.)
package/docs/usage.md CHANGED
@@ -8,30 +8,10 @@ There are two ways to use the generator:
8
8
  - [Generator library](#using-as-a-modulepackage)
9
9
 
10
10
  ## AsyncAPI CLI
11
- Generates whatever you want using templates compatible with AsyncAPI Generator.
12
- ```bash
13
- USAGE
14
- $ asyncapi generate fromTemplate [ASYNCAPI] [TEMPLATE] [-h] [-d <value>] [-i] [--debug] [-n <value>] [-o <value>] [--force-write] [-w] [-p <value>] [--map-base-url <value>]
15
-
16
- ARGUMENTS
17
- ASYNCAPI - Local path, url or context-name pointing to AsyncAPI file
18
- TEMPLATE - Name of the generator template like for example @asyncapi/html-template or https://github.com/asyncapi/html-template
19
11
 
20
- FLAGS
21
- -d, --disable-hook=<value>... Disable a specific hook type or hooks from a given hook type
22
- -h, --help Show CLI help.
23
- -i, --install Installs the template and its dependencies (defaults to false)
24
- -n, --no-overwrite=<value>... Glob or path of the file(s) to skip when regenerating
25
- -o, --output=<value> Directory where to put the generated files (defaults to current directory)
26
- -p, --param=<value>... Additional param to pass to templates
27
- -w, --watch Watches the template directory and the AsyncAPI document, and re-generate the files when changes occur. Ignores the output directory.
28
- --debug Enable more specific errors in the console
29
- --force-write Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir (defaults to false)
30
- --map-base-url=<value> Maps all schema references from base url to local folder
12
+ ### `asyncapi generate fromTemplate ASYNCAPI TEMPLATE`
31
13
 
32
- EXAMPLES
33
- $ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template --param version=1.0.0 singleFile=true --output ./docs --force-write
34
- ```
14
+ Generates whatever you want using templates compatible with AsyncAPI Generator. For complete command usage and options, refer to the official [AsyncAPI CLI documentation](https://www.asyncapi.com/docs/tools/cli/usage#asyncapi-generate-fromtemplate-asyncapi-template).
35
15
 
36
16
  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:
37
17
  ```
@@ -60,29 +40,29 @@ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template
60
40
 
61
41
  **The shortest possible syntax:**
62
42
  ```bash
63
- asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template
43
+ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template@3.0.0 --use-new-generator
64
44
  ```
65
45
 
66
46
  **Generating from a URL:**
67
47
  ```bash
68
- asyncapi generate fromTemplate https://bit.ly/asyncapi @asyncapi/html-template
48
+ asyncapi generate fromTemplate https://bit.ly/asyncapi @asyncapi/html-template@3.0.0 --use-new-generator
69
49
  ```
70
50
 
71
51
  **Specify where to put the result:**
72
52
  ```bash
73
- asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs
53
+ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template@3.0.0 --use-new-generator -o ./docs
74
54
  ```
75
55
 
76
56
  **Passing parameters to templates:**
77
57
  ```bash
78
- asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs -p title='Hello from param'
58
+ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template@3.0.0 --use-new-generator -o ./docs -p title='Hello from param'
79
59
  ```
80
60
 
81
61
  In the template you can use it like this: ` {{ params.title }}`
82
62
 
83
63
  **Disabling the hooks:**
84
64
  ```bash
85
- asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs -d generate:before generate:after=foo,bar
65
+ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template@3.0.0 --use-new-generator -o ./docs -d generate:before generate:after=foo,bar
86
66
  ```
87
67
 
88
68
  The generator skips all hooks of the `generate:before` type and `foo`, `bar` hooks of the `generate:after` type.
@@ -101,7 +81,7 @@ asyncapi generate fromTemplate asyncapi.yaml https://github.com/asyncapi/html-te
101
81
 
102
82
  **Map schema references from baseUrl to local folder:**
103
83
  ```bash
104
- asyncapi generate fromTemplate test/docs/apiwithref.json @asyncapi/html-template -o ./build/ --force-write --map-base-url https://schema.example.com/crm/:./test/docs/
84
+ asyncapi generate fromTemplate test/docs/apiwithref.json @asyncapi/html-template@3.0.0 --use-new-generator -o ./build/ --force-write --map-base-url https://schema.example.com/crm/:./test/docs/
105
85
  ```
106
86
 
107
87
  The parameter `--map-base-url` maps external schema references to local folders.
@@ -114,15 +94,17 @@ Install [Docker](https://docs.docker.com/get-docker/) first, then use docker to
114
94
 
115
95
  ```bash
116
96
  docker run --rm -it \
97
+ --user=root \
117
98
  -v [ASYNCAPI SPEC FILE LOCATION]:/app/asyncapi.yml \
118
99
  -v [GENERATED FILES LOCATION]:/app/output \
119
- asyncapi/cli [COMMAND HERE]
100
+ asyncapi/cli # docker image [COMMAND HERE]
120
101
 
121
102
  # Example that you can run inside the cli directory after cloning this repository. First, you specify the mount in the location of your AsyncAPI specification file and then you mount it in the directory where the generation result should be saved.
122
103
  docker run --rm -it \
104
+ --user=root \
123
105
  -v ${PWD}/test/fixtures/asyncapi_v1.yml:/app/asyncapi.yml \
124
106
  -v ${PWD}/output:/app/output \
125
- asyncapi/cli generate fromTemplate -o /app/output /app/asyncapi.yml @asyncapi/html-template --force-write
107
+ asyncapi/cli generate fromTemplate -o /app/output /app/asyncapi.yml @asyncapi/html-template@3.0.0 --use-new-generator --force-write
126
108
  ```
127
109
  Note: Use ``` ` ``` instead of `\` for Windows.
128
110
 
@@ -133,7 +115,7 @@ Note: Use ``` ` ``` instead of `\` for Windows.
133
115
  Use the following npx command on your terminal:
134
116
 
135
117
  ```bash
136
- npx -p @asyncapi/cli asyncapi generate fromTemplate ./asyncapi.yaml @asyncapi/html-template
118
+ npx -p @asyncapi/cli asyncapi generate fromTemplate ./asyncapi.yaml @asyncapi/html-template@3.0.0 --use-new-generator
137
119
  ```
138
120
 
139
121
  ## Using as a module/package
@@ -154,4 +136,4 @@ try {
154
136
  }
155
137
  ```
156
138
 
157
- See the [API documentation](api) for more examples and full API reference information.
139
+ See the [API documentation](api) for more examples and full API reference information.
@@ -18,9 +18,11 @@ It is better to lock a specific version of the template and the generator if you
18
18
  Generate HTML with the latest AsyncAPI CLI using the html-template.
19
19
  ```
20
20
  npm install -g @asyncapi/cli
21
- asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template -o ./docs
21
+ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template@3.0.0 --use-new-generator
22
22
  ```
23
23
 
24
+ > AsyncAPI CLI has multiple versions of the generator, and to use the latest version, you may need to pass the `--use-new-generator` flag. For more details you can also check [asyncapi generate fromTemplate ASYNCAPI TEMPLATE](https://www.asyncapi.com/docs/tools/cli/usage#asyncapi-generate-fromtemplate-asyncapi-template)
25
+
24
26
  Generate HTML using a particular version of the AsyncAPI CLI using the html-template.
25
27
 
26
28
  ```
@@ -0,0 +1,162 @@
1
+ const log = require('loglevel');
2
+ const logMessage = require('./logMessages');
3
+ const jmespath = require('jmespath');
4
+
5
+ /**
6
+ * Determines whether the generation of a file or folder should be skipped
7
+ * based on conditions defined in the template configuration.
8
+ *
9
+ * @param {Object} templateConfig - The template configuration containing conditional logic.
10
+ * @param {string} matchedConditionPath - The matched path used to find applicable conditions.
11
+ * @param {Object} templateParams - Parameters passed to the template.
12
+ * @param {AsyncAPIDocument} asyncapiDocument - The AsyncAPI document used for evaluating conditions.
13
+ * @returns {Promise<boolean>} A promise that resolves to `true` if the condition is met, allowing the file or folder to render; otherwise, resolves to `false`.
14
+ */
15
+ async function isGenerationConditionMet (
16
+ templateConfig,
17
+ matchedConditionPath,
18
+ templateParams,
19
+ asyncapiDocument
20
+ ) {
21
+ const conditionFilesGeneration = templateConfig?.conditionalFiles?.[matchedConditionPath] || {};
22
+ const conditionalGeneration = templateConfig?.conditionalGeneration?.[matchedConditionPath] || {};
23
+
24
+ const config = Object.keys(conditionFilesGeneration).length > 0
25
+ ? conditionFilesGeneration
26
+ : conditionalGeneration;
27
+
28
+ const subject = config?.subject;
29
+
30
+ // conditionalFiles becomes deprecated with this PR, and soon will be removed.
31
+ // TODO: https://github.com/asyncapi/generator/issues/1553
32
+ if (Object.keys(conditionFilesGeneration).length > 0 && subject) {
33
+ return conditionalFilesGenerationDeprecatedVersion(
34
+ asyncapiDocument,
35
+ templateConfig,
36
+ matchedConditionPath,
37
+ templateParams
38
+ );
39
+ } else if (Object.keys(conditionalGeneration).length > 0) {
40
+ // Case when the subject is present in conditionalGeneration
41
+ if (subject) {
42
+ return conditionalSubjectGeneration(
43
+ asyncapiDocument,
44
+ templateConfig,
45
+ matchedConditionPath
46
+ );
47
+ }
48
+ return conditionalParameterGeneration(templateConfig,matchedConditionPath,templateParams);
49
+ }
50
+ };
51
+
52
+ /**
53
+ * Evaluates whether a template path should be conditionally generated
54
+ * based on a parameter defined in the template configuration.
55
+ * @private
56
+ * @async
57
+ * @function conditionalParameterGeneration
58
+ * @param {Object} templateConfig - The full template configuration object.
59
+ * @param {string} matchedConditionPath - The path of the file/folder being conditionally generated.
60
+ * @param {Object} templateParams - The parameters passed to the generator, usually user input or default values.
61
+ * @returns {Promise<boolean>} - Resolves to `true` if the parameter passes validation, `false` otherwise.
62
+ */
63
+ async function conditionalParameterGeneration(templateConfig, matchedConditionPath, templateParams) {
64
+ const conditionalGenerationConfig = templateConfig.conditionalGeneration?.[matchedConditionPath];
65
+ const parameterName = conditionalGenerationConfig.parameter;
66
+ const parameterValue = templateParams[parameterName];
67
+ return validateStatus(parameterValue, matchedConditionPath, templateConfig);
68
+ }
69
+
70
+ /**
71
+ * Determines whether a file should be conditionally included based on the provided subject expression
72
+ * and optional validation logic defined in the template configuration.
73
+ * @private
74
+ * @param {Object} asyncapiDocument - The parsed AsyncAPI document instance used for context evaluation.
75
+ * @param {Object} templateConfig - The configuration object that contains `conditionalFiles` rules.
76
+ * @param {string} matchedConditionPath - The path of the file/folder being conditionally generated.
77
+ * @param {Object} templateParams - The parameters passed to the generator, usually user input or default values.
78
+ * @returns {Boolean} - Returns `true` if the file should be included; `false` if it should be skipped.
79
+ */
80
+ async function conditionalFilesGenerationDeprecatedVersion (
81
+ asyncapiDocument,
82
+ templateConfig,
83
+ matchedConditionPath,
84
+ templateParams
85
+ ) {
86
+ return conditionalSubjectGeneration(asyncapiDocument, templateConfig, matchedConditionPath, templateParams);
87
+ };
88
+
89
+ /**
90
+ * Determines whether a file should be conditionally included based on the provided subject expression
91
+ * and optional validation logic defined in the template configuration.
92
+ * @private
93
+ * @param {Object} asyncapiDocument - The parsed AsyncAPI document instance used for context evaluation.
94
+ * @param {Object} templateConfig - The configuration object that contains `conditionalFiles` rules.
95
+ * @param {String} matchedConditionPath - The relative path to the directory of the source file.
96
+ * @param {Object} templateParams - Parameters passed to the template.
97
+ * @returns {Boolean} - Returns `true` if the file should be included; `false` if it should be skipped.
98
+ */
99
+ async function conditionalSubjectGeneration (
100
+ asyncapiDocument,
101
+ templateConfig,
102
+ matchedConditionPath,
103
+ templateParams
104
+
105
+ ) {
106
+ const fileCondition = templateConfig.conditionalGeneration?.[matchedConditionPath] || templateConfig.conditionalFiles?.[matchedConditionPath];
107
+ if (!fileCondition || !fileCondition.subject) {
108
+ return true;
109
+ }
110
+ const { subject } = fileCondition;
111
+ const server = templateParams.server && asyncapiDocument.servers().get(templateParams.server);
112
+ const source = jmespath.search({
113
+ ...asyncapiDocument.json(),
114
+ ...{
115
+ server: server ? server.json() : undefined,
116
+ },
117
+ }, subject);
118
+
119
+ if (!source) {
120
+ log.debug(logMessage.relativeSourceFileNotGenerated(matchedConditionPath, subject));
121
+ return false;
122
+ }
123
+ return validateStatus(source, matchedConditionPath, templateConfig);
124
+ }
125
+
126
+ /**
127
+ * Validates the argument value based on the provided validation schema.
128
+ *
129
+ * @param {any} argument The value to validate.
130
+ * @param {String} matchedConditionPath The matched condition path.
131
+ * @param {Object} templateConfig - The template configuration containing conditional logic.
132
+ * @return {Promise<Boolean>} A promise that resolves to false if the generation should be skipped, true otherwise.
133
+ */
134
+ async function validateStatus(
135
+ argument,
136
+ matchedConditionPath,
137
+ templateConfig
138
+ ) {
139
+ const validation = templateConfig.conditionalGeneration?.[matchedConditionPath]?.validate || templateConfig.conditionalFiles?.[matchedConditionPath]?.validate;
140
+ if (!validation) {
141
+ return false;
142
+ }
143
+
144
+ const isValid = validation(argument);
145
+
146
+ if (!isValid) {
147
+ if (templateConfig.conditionalGeneration?.[matchedConditionPath]) {
148
+ log.debug(logMessage.conditionalGenerationMatched(matchedConditionPath));
149
+ } else {
150
+ // conditionalFiles becomes deprecated with this PR, and soon will be removed.
151
+ // TODO: https://github.com/asyncapi/generator/issues/1553
152
+ log.debug(logMessage.conditionalFilesMatched(matchedConditionPath));
153
+ }
154
+
155
+ return false;
156
+ }
157
+ return true;
158
+ }
159
+
160
+ module.exports = {
161
+ isGenerationConditionMet
162
+ };
@@ -16,7 +16,7 @@ module.exports.registerFilters = async (nunjucks, templateConfig, templateDir, f
16
16
  await registerLocalFilters(nunjucks, templateDir, filtersDir);
17
17
  registerConfigFilters(nunjucks, templateDir, templateConfig);
18
18
 
19
- // Register Nunjucks filters from the 'nunjucks-filters' module without needing to list them explicitly in package.json
19
+ // Register Nunjucks filters from the 'nunjucks-filters' module without needing to list them in package.json or .ageneratorrc file.
20
20
  addFilters(nunjucks, nunjucksFilters);
21
21
  };
22
22