@asyncapi/generator 2.8.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/docs/api.md +2 -51
  3. package/docs/asyncapi-document.md +1 -1
  4. package/docs/configuration-file.md +0 -4
  5. package/docs/file-templates.md +1 -59
  6. package/docs/generator-template-java.md +0 -2
  7. package/docs/generator-template.md +1 -4
  8. package/docs/index.md +2 -2
  9. package/docs/jsdoc2md-handlebars/main-index/global-index/global-index-dl.hbs +13 -0
  10. package/docs/jsdoc2md-handlebars/member-index-grouped.hbs +6 -0
  11. package/docs/jsdoc2md-handlebars/member-index-list.hbs +6 -0
  12. package/docs/jsdoc2md-handlebars/members.hbs +1 -0
  13. package/docs/react-render-engine.md +5 -37
  14. package/docs/template-development.md +2 -7
  15. package/docs/template.md +2 -2
  16. package/docs/typescript-support.md +3 -5
  17. package/jest.config.js +3 -6
  18. package/lib/__mocks__/utils.js +0 -3
  19. package/lib/generator.js +4 -20
  20. package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/.ageneratorrc +2 -4
  21. package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/__transpiled/jest.config.js +13 -0
  22. package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/__transpiled/jest.config.js.map +1 -0
  23. package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/jest.config.js +14 -0
  24. package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/package.json +3 -17
  25. package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/.ageneratorrc +0 -1
  26. package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/__transpiled/jest.config.js +13 -0
  27. package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/__transpiled/jest.config.js.map +1 -0
  28. package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/jest.config.js +14 -0
  29. package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/package.json +3 -17
  30. package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/.ageneratorrc +0 -2
  31. package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/__transpiled/jest.config.js +13 -0
  32. package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/__transpiled/jest.config.js.map +1 -0
  33. package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/jest.config.js +14 -0
  34. package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/package.json +4 -18
  35. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/.ageneratorrc +8 -1
  36. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/ClientClass.js +5 -1
  37. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/ClientClass.js.map +1 -1
  38. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/CompileOperationSchemas.js +48 -0
  39. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/CompileOperationSchemas.js.map +1 -0
  40. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/Constructor.js +7 -1
  41. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/Constructor.js.map +1 -1
  42. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/jest.config.js +13 -0
  43. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/jest.config.js.map +1 -0
  44. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/template/README.md.js +5 -153
  45. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/template/README.md.js.map +1 -1
  46. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/template/client.js.js +52 -3
  47. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/template/client.js.js.map +1 -1
  48. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/components/ClientClass.js +4 -2
  49. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/components/CompileOperationSchemas.js +40 -0
  50. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/components/Constructor.js +7 -1
  51. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/jest.config.js +14 -0
  52. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/package.json +7 -20
  53. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/template/README.md.js +2 -103
  54. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/template/client.js.js +5 -1
  55. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/.ageneratorrc +0 -1
  56. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/jest.config.js +13 -0
  57. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/jest.config.js.map +1 -0
  58. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/template/README.md.js +18 -0
  59. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/template/README.md.js.map +1 -0
  60. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/jest.config.js +14 -0
  61. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/package.json +3 -17
  62. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/template/README.md.js +5 -0
  63. package/lib/templates/config/validator.js +3 -3
  64. package/lib/utils.js +0 -21
  65. package/package.json +7 -14
  66. package/Dockerfile +0 -20
  67. package/cli.js +0 -205
  68. package/docs/migration-cli.md +0 -70
  69. package/docs/migration-nunjucks-react.md +0 -144
  70. package/docs/nunjucks-render-engine.md +0 -83
  71. package/lib/filtersRegistry.js +0 -134
  72. package/lib/renderer/nunjucks.js +0 -42
  73. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/AvailableOperations.js +0 -34
  74. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/AvailableOperations.js.map +0 -1
  75. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/MessageExamples.js +0 -29
  76. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/MessageExamples.js.map +0 -1
  77. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/OperationHeader.js +0 -19
  78. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/__transpiled/components/OperationHeader.js.map +0 -1
  79. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/components/AvailableOperations.js +0 -20
  80. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/components/MessageExamples.js +0 -25
  81. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/components/OperationHeader.js +0 -12
  82. package/lib/watcher.js +0 -147
package/Dockerfile DELETED
@@ -1,20 +0,0 @@
1
- FROM node:18-alpine
2
-
3
- ARG ASYNCAPI_GENERATOR_VERSION=1.10.9
4
-
5
- WORKDIR /app
6
-
7
- # Since 0.14.0 release of html-template chromium is needed for pdf generation
8
- ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
9
- ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
10
-
11
- # Since 0.30.0 release Git is supported and required as a dependency
12
- # Since 0.14.0 release of html-template chromium is needed for pdf generation.
13
- # More custom packages for specific template should not be added to this dockerfile. Instead, we should come up with some extensibility solution.
14
- # Installing latest released npm package
15
- RUN apk --update add git chromium && \
16
- rm /var/cache/apk/* && \
17
- npm install --ignore-scripts -g "@asyncapi/generator@${ASYNCAPI_GENERATOR_VERSION}"
18
-
19
-
20
- ENTRYPOINT [ "ag" ]
package/cli.js DELETED
@@ -1,205 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const path = require('path');
4
- const os = require('os');
5
- const program = require('commander');
6
- const xfs = require('fs.extra');
7
- const { DiagnosticSeverity } = require('@asyncapi/parser/cjs');
8
- const packageInfo = require('./package.json');
9
- const Generator = require('./lib/generator');
10
- const Watcher = require('./lib/watcher');
11
- const { isLocalTemplate, isFilePath } = require('./lib/utils');
12
-
13
- const red = text => `\x1b[31m${text}\x1b[0m`;
14
- const magenta = text => `\x1b[35m${text}\x1b[0m`;
15
- const yellow = text => `\x1b[33m${text}\x1b[0m`;
16
- const green = text => `\x1b[32m${text}\x1b[0m`;
17
-
18
- let asyncapiDocPath;
19
- let template;
20
- const params = {};
21
- const noOverwriteGlobs = [];
22
- const disabledHooks = {};
23
- const mapBaseUrlToFolder = {};
24
-
25
- const parseOutput = dir => path.resolve(dir);
26
-
27
- const paramParser = v => {
28
- if (!v.includes('=')) throw new Error(`Invalid param ${v}. It must be in the format of --param name=value.`);
29
- const [paramName, paramValue] = v.split(/=(.+)/, 2);
30
- params[paramName] = paramValue;
31
- return v;
32
- };
33
-
34
- const noOverwriteParser = v => noOverwriteGlobs.push(v);
35
-
36
- const disableHooksParser = v => {
37
- const [hookType, hookNames] = v.split(/=/);
38
- if (!hookType) throw new Error('Invalid --disable-hook flag. It must be in the format of: --disable-hook <hookType> or --disable-hook <hookType>=<hookName1>,<hookName2>,...');
39
- if (hookNames) {
40
- disabledHooks[hookType] = hookNames.split(/,/);
41
- } else {
42
- disabledHooks[hookType] = true;
43
- }
44
- };
45
-
46
- const mapBaseUrlParser = v => {
47
- // Example value for regular expression: https://schema.example.com/crm/:./test/docs/
48
- // it splits on last occurrence of : into the groups all, url and folder
49
- const re = /(.*):(.*)/g;
50
- let mapping = [];
51
- if ((mapping = re.exec(v))===null || mapping.length!==3) {
52
- throw new Error('Invalid --map-base-url flag. A mapping <url>:<folder> with delimiter : expected.');
53
- }
54
-
55
- // Folder is without trailing slash, so make sure that url has also no trailing slash:
56
- mapBaseUrlToFolder.url = mapping[1].replace(/\/$/, '');
57
- mapBaseUrlToFolder.folder = path.resolve(mapping[2]);
58
-
59
- const isURL = /^https?:/;
60
- if (!isURL.test(mapBaseUrlToFolder.url.toLowerCase())) {
61
- throw new Error('Invalid --map-base-url flag. The mapping <url>:<folder> requires a valid http/https url and valid folder with delimiter `:`.');
62
- }
63
- };
64
-
65
- const showError = err => {
66
- console.error(red('Something went wrong:'));
67
- console.error(red(err.stack || err.message));
68
- if (err.diagnostics) {
69
- const errorDiagnostics = err.diagnostics.filter(diagnostic => diagnostic.severity === DiagnosticSeverity.Error);
70
- console.error(red(`Errors:\n${JSON.stringify(errorDiagnostics, undefined, 2)}`));
71
- }
72
- };
73
- const showErrorAndExit = err => {
74
- showError(err);
75
- process.exit(1);
76
- };
77
-
78
- program
79
- .version(packageInfo.version)
80
- .arguments('<asyncapi> <template>')
81
- .action((fileLoc, tmpl) => {
82
- asyncapiDocPath = fileLoc;
83
- template = tmpl;
84
- })
85
- .option('-d, --disable-hook [hooks...]', 'disable a specific hook type or hooks from given hook type', disableHooksParser)
86
- .option('--debug', 'enable more specific errors in the console')
87
- .option('-i, --install', 'installs the template and its dependencies (defaults to false)')
88
- .option('-n, --no-overwrite <glob>', 'glob or path of the file(s) to skip when regenerating', noOverwriteParser)
89
- .option('-o, --output <outputDir>', 'directory where to put the generated files (defaults to current directory)', parseOutput, process.cwd())
90
- .option('-p, --param <name=value>', 'additional param to pass to templates', paramParser)
91
- .option('--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)')
92
- .option('--disable-warning', 'disable "ag" deprecation warning (defaults to false)')
93
- .option('--watch-template', 'watches the template directory and the AsyncAPI document, and re-generate the files when changes occur. Ignores the output directory. This flag should be used only for template development.')
94
- .option('--map-base-url <url:folder>','maps all schema references from base url to local folder',mapBaseUrlParser)
95
- .parse(process.argv);
96
-
97
- if (!program.disableWarning) {
98
- console.warn(yellow(
99
- 'Warning: The "ag" CLI is deprecated and will be removed in a future release. Please use the AsyncAPI CLI instead. See release notes for details: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0. You can hide this working using --disable-warning flag.')
100
- );
101
- }
102
-
103
- if (!asyncapiDocPath) {
104
- console.error(red('> Path or URL to AsyncAPI file not provided.'));
105
- program.help(); // This exits the process
106
- }
107
- const isAsyncapiDocLocal = isFilePath(asyncapiDocPath);
108
-
109
- xfs.mkdirp(program.output, async err => {
110
- if (err) return showErrorAndExit(err);
111
- try {
112
- await generate(program.output);
113
- } catch (e) {
114
- return showErrorAndExit(e);
115
- }
116
-
117
- // If we want to watch for changes do that
118
- if (program.watchTemplate) {
119
- let watcher;
120
- const watchDir = path.resolve(template);
121
- const outputPath = path.resolve(watchDir, program.output);
122
- const transpiledTemplatePath = path.resolve(watchDir, Generator.TRANSPILED_TEMPLATE_LOCATION);
123
- const ignorePaths = [outputPath, transpiledTemplatePath];
124
- // Template name is needed as it is not always a part of the cli commad
125
- // There is a use case that you run generator from a root of the template with `./` path
126
- const templateName = require(path.resolve(watchDir,'package.json')).name;
127
-
128
- if (isAsyncapiDocLocal) {
129
- console.log(`[WATCHER] Watching for changes in the template directory ${magenta(watchDir)} and in the AsyncAPI file ${magenta(asyncapiDocPath)}`);
130
- watcher = new Watcher([asyncapiDocPath, watchDir], ignorePaths);
131
- } else {
132
- console.log(`[WATCHER] Watching for changes in the template directory ${magenta(watchDir)}`);
133
- watcher = new Watcher(watchDir, ignorePaths);
134
- }
135
- // Must check template in its installation path in generator to use isLocalTemplate function
136
- if (!await isLocalTemplate(path.resolve(Generator.DEFAULT_TEMPLATES_DIR, templateName))) {
137
- console.warn(`WARNING: ${template} is a remote template. Changes may be lost on subsequent installations.`);
138
- }
139
-
140
- await watcher.watch(watcherHandler, (paths) => {
141
- showErrorAndExit({ message: `[WATCHER] Could not find the file path ${paths}, are you sure it still exists? If it has been deleted or moved please rerun the generator.` });
142
- });
143
- }
144
- });
145
-
146
- /**
147
- * Generates the files based on the template.
148
- * @param {*} targetDir The path to the target directory.
149
- */
150
- function generate(targetDir) {
151
- return new Promise(async (resolve, reject) => {
152
- try {
153
- const generator = new Generator(template, targetDir || path.resolve(os.tmpdir(), 'asyncapi-generator'), {
154
- templateParams: params,
155
- noOverwriteGlobs,
156
- disabledHooks,
157
- forceWrite: program.forceWrite,
158
- install: program.install,
159
- debug: program.debug,
160
- mapBaseUrlToFolder
161
- });
162
-
163
- if (isAsyncapiDocLocal) {
164
- await generator.generateFromFile(path.resolve(asyncapiDocPath));
165
- } else {
166
- await generator.generateFromURL(asyncapiDocPath);
167
- }
168
- console.log(green('\n\nDone! ✨'));
169
- console.log(`${yellow('Check out your shiny new generated files at ') + magenta(program.output) + yellow('.')}\n`);
170
- resolve();
171
- } catch (e) {
172
- reject(e);
173
- }
174
- });
175
- }
176
-
177
- async function watcherHandler(changedFiles) {
178
- console.clear();
179
- console.log('[WATCHER] Change detected');
180
- for (const [, value] of Object.entries(changedFiles)) {
181
- let eventText;
182
- switch (value.eventType) {
183
- case 'changed':
184
- eventText = green(value.eventType);
185
- break;
186
- case 'removed':
187
- eventText = red(value.eventType);
188
- break;
189
- case 'renamed':
190
- eventText = yellow(value.eventType);
191
- break;
192
- default:
193
- eventText = yellow(value.eventType);
194
- }
195
- console.log(`\t${magenta(value.path)} was ${eventText}`);
196
- }
197
- console.log('Generating files');
198
- try {
199
- await generate(program.output);
200
- } catch (e) {
201
- showError(e);
202
- }
203
- }
204
-
205
- process.on('unhandledRejection', showErrorAndExit);
@@ -1,70 +0,0 @@
1
- ---
2
- title: "Migrating from `ag` CLI to AsyncAPI CLI"
3
- weight: 260
4
- ---
5
-
6
- This guide provides detailed instructions on how to transition from the old `ag` Generator CLI to the new AsyncAPI CLI.
7
-
8
- ## Options Overview
9
-
10
- Here is a list of `ag` options and their equivalents in the AsyncAPI CLI:
11
-
12
- - **-d, --disable-hook [hooks...]**
13
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --disable-hook <hookType>=<hookName>`
14
-
15
- - **--debug**
16
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --debug`
17
-
18
- - **-i, --install**
19
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --install`
20
-
21
- - **-n, --no-overwrite &#x3C;glob&#x3E;**
22
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --no-overwrite <glob>`
23
-
24
- - **-o, --output &#x3C;outputDir&#x3E;**
25
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --output <outputDir>`
26
-
27
- - **-p, --param &#x3C;name&#x3D;value&#x3E;**
28
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --param <name=value>`
29
-
30
- - **--force-write**
31
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --force-write`
32
-
33
- - **--watch-template**
34
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --watch`
35
-
36
- - **--map-base-url &#x3C;url:folder&#x3E;**
37
- - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate <ASYNCAPI> <TEMPLATE> --map-base-url <url:folder>`
38
-
39
- ## Migration Steps
40
-
41
- ### 1. Install AsyncAPI CLI
42
-
43
- There are multiple different artifacts that AsyncAPI CLI is provided as. Get familiar with the [official CLI installation guide](https://www.asyncapi.com/docs/tools/cli/installation).
44
-
45
- ### 2. Update Your Commands
46
-
47
- Replace the deprecated `ag` commands with the AsyncAPI CLI equivalents. Below are examples of how to update your commands:
48
-
49
- **Using `ag`**:
50
- ```
51
- ag ./asyncapi.yaml ./template -o ./output -p param1=value1 --debug --install --disable-hook hookType=hookName
52
- ```
53
-
54
- **Using AsyncAPI CLI**:
55
- ```
56
- asyncapi generate fromTemplate ./asyncapi.yaml ./template -o ./output -p param1=value1 --debug --install --disable-hook hookType=hookName
57
- ```
58
-
59
- Notice that the change basically related to changing from `ag` to `asyncapi generate fromTemplate`.
60
-
61
- ### 3. Verify and Test
62
-
63
- Run the updated commands to ensure they work as expected and verify that the output files are generated correctly.
64
-
65
- ## Additional Resources
66
-
67
- **CLI Documentation**: [AsyncAPI CLI Documentation](https://www.asyncapi.com/docs/tools/cli)
68
- **Installation**: [AsyncAPI CLI Installation](https://www.asyncapi.com/docs/tools/cli/installation)
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).
@@ -1,144 +0,0 @@
1
- ---
2
- title: "Migrating from Nunjucks to React render engine"
3
- weight: 250
4
- ---
5
-
6
- The AsyncAPI Generator is moving away from Nunjucks templates in favor of React templates. This guide will help you migrate your existing Nunjucks templates to React. For a comprehensive understanding of why we introduced React as an alternative in 2021 and why we're now removing Nunjucks entirely, please read our article [React as a Generator Engine](https://www.asyncapi.com/blog/react-as-generator-engine). The principles discussed in this article still apply to our current transition.
7
-
8
- ## Step-by-step migration guide
9
-
10
- ### 1. Update package.json
11
-
12
- Change your template configuration in `package.json`:
13
-
14
- ```json
15
- {
16
- "generator": {
17
- "renderer": "react"
18
- }
19
- }
20
- ```
21
-
22
- Once the deprecation period has ended, and we remove the default Nunjucks, the React render engine will be used by default and this setting will no longer be needed to configure
23
-
24
- ### 2. Install dependencies
25
-
26
- Install the necessary React dependencies:
27
-
28
- ```bash
29
- npm install @asyncapi/generator-react-sdk
30
- ```
31
-
32
- ### 3. File naming
33
-
34
- In Nunjucks, the template's filename directly corresponds to the output file. For example, a template named **index.html** will generate an **index.html** file.
35
-
36
- In React, the filename of the generated file is not controlled by the file itself, but rather by the `File` component. The React component itself can be named anything with a `.js` extension because the output filename is controlled by the `name` attribute of the `File` component used inside the template file. Below you can see some examples of filenames:
37
-
38
- Nunjucks: `index.html`
39
- React: `index.js` or `index.html.js` or `anything-you-want.js`
40
-
41
- ### 4. Basic template structure
42
-
43
- Nunjucks:
44
- ```js
45
- <h1>{{ asyncapi.info().title() }}</h1>
46
- <p>{{ asyncapi.info().description() }}</p>
47
- ```
48
-
49
- React:
50
- ```js
51
- import { File } from '@asyncapi/generator-react-sdk';
52
-
53
- export default function({ asyncapi }) {
54
- return (
55
- <File name="index.html">
56
- <h1>{asyncapi.info().title()}</h1>
57
- <p>{asyncapi.info().description()}</p>
58
- </File>
59
- );
60
- }
61
- ```
62
-
63
- ### 5. Macros and Partials
64
-
65
- Replace macros with React components:
66
-
67
- Nunjucks:
68
- ```js
69
- {% macro renderChannel(channel) %}
70
- <div class="channel">
71
- <h3>{{ channel.address() }}</h3>
72
- <p>{{ channel.description() }}</p>
73
- </div>
74
- {% endmacro %}
75
-
76
- {{ renderChannel(someChannel) }}
77
- ```
78
-
79
- React:
80
- ```js
81
- // components/Channel.js
82
- import { Text } from '@asyncapi/generator-react-sdk';
83
-
84
- export function Channel({ channel }) {
85
- return (
86
- <Text>
87
- <div className="channel">
88
- <h3>{channel.address()}</h3>
89
- <p>{channel.description()}</p>
90
- </div>
91
- </Text>
92
- );
93
- }
94
-
95
- // Main template
96
- import { File, Text } from '@asyncapi/generator-react-sdk';
97
- import { Channel } from './components/Channel';
98
-
99
- export default function({ asyncapi }) {
100
- return (
101
- <File name="channels.html">
102
- <Text>
103
- <h2>Channels</h2>
104
- </Text>
105
- {asyncapi.channels().map(channel => (
106
- <Channel channel={channel} />
107
- ))}
108
- </File>
109
- );
110
- }
111
- ```
112
-
113
- ### 6. File template
114
-
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
-
117
- ### 7. Models generation
118
-
119
- If you have a template written with Nunjucks, it is almost certain that you have your own custom models, classes, or types templates in place. Instead of migrating them to React render engine we strongly advise you to delegate models generation to AsyncAPI Modelina project. Learn more about [how to add models generation using Modelina](https://www.asyncapi.com/docs/tools/generator/model-generation).
120
-
121
- ## Additional Resources and Information
122
-
123
- ### Template Examples
124
- For a complete example of React features in use, please refer to the [AsyncAPI Template for Generator Templates](https://github.com/asyncapi/template-for-generator-templates). The `master` branch demonstrates all React features, while the `nunjucks` branch shows the old Nunjucks implementation. This comparison can be particularly helpful in understanding the differences and migration process.
125
-
126
- ### Filters to Helpers
127
- If you've been using Nunjucks filters placed in the `filters` directory, you can still use this functionality in React. However, they should be treated as normal functions that you import into your components. We recommend renaming the `filters` directory to `helpers` to better reflect their new usage in React.
128
-
129
- ### Hooks Remain Unchanged
130
- It's important to note that hooks remain unchanged in this migration process. Hooks are not related to the render engine functionality, so you can continue to use them as you have been.
131
-
132
- ### Testing your migration
133
-
134
- After migrating, test your template thoroughly:
135
-
136
- 1. Run the generator using your new React template
137
- 2. Compare the output with the previous Nunjucks template output
138
- 3. Check for any missing or incorrectly rendered content
139
-
140
- Consider implementing snapshot tests for your template before starting the migration. This will ease the review of changes in comparing the content rendered after render engine changes. Snapshot tests allow you to have tests that will persist expected output from Nunjucks template, and compare it with output generated after the migration. Check out an [example of such snapshot integration test for our internal react template we use for development and testing](https://github.com/asyncapi/generator/blob/master/apps/generator/test/integration.test.js#L66).
141
-
142
- ## Conclusion
143
-
144
- Migrating from Nunjucks to React templates may require some initial effort, but it will result in more maintainable code. You can learn more about why we introduced the React render engine from article [React as a Generator Engine](https://www.asyncapi.com/blog/react-as-generator-engine).
@@ -1,83 +0,0 @@
1
- ---
2
- title: "Nunjucks render engine"
3
- weight: 120
4
- ---
5
-
6
- > **Note**: Nunjucks renderer engine is deprecated and will be removed in the future. Use the React renderer engine 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).
7
-
8
- [Nunjucks](https://mozilla.github.io/nunjucks) is the default render engine, however, we strongly recommend adopting the [React](#react) engine.
9
-
10
- ### Common assumptions
11
-
12
- 1. Templates may contain [Nunjucks filters or helper functions](https://mozilla.github.io/nunjucks/templating.html#builtin-filters). [Read more about filters](#filters).
13
- 1. Templates may contain `partials` (reusable chunks). They must be stored in the `.partials` directory under the template directory. [Read more about partials](#partials).
14
- 1. Templates may contain multiple files. Unless stated otherwise, all files will be rendered.
15
- 1. The default variables you have access to in any the template file are the following:
16
- - `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.
17
- - `originalAsyncAPI` that is an original spec file before it is parsed.
18
- - `params` that contain the parameters provided when generating.
19
-
20
- ### Partials
21
-
22
- 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:
23
-
24
- ```html
25
- {# tags.html #}
26
- {% macro tags(tagList) %}
27
- <div class="mt-4">
28
- {% for tag in tagList %}
29
- <span class="bg-grey-dark font-normal text-sm no-underline text-white rounded lowercase mr-2 px-2 py-1" title="{{tag.description()}}">{{tag.name()}}</span>
30
- {% endfor %}
31
- </div>
32
- {% endmacro %}
33
-
34
- {# operations.html #}
35
- {% from "./tags.html" import tags %}
36
- {{ tags(operation.tags()) }}
37
- ```
38
-
39
- ### Filters
40
-
41
- A filter is a helper function that you can create to perform complex tasks. They are JavaScript files that register one or many [Nunjuck filters](https://mozilla.github.io/nunjucks/api.html#custom-filters). The generator parses all the files in the `filters` directory. Functions exported from these files are registered as filters.
42
-
43
- You can use the filter function in your template as in the following example:
44
-
45
- ```js
46
- const {{ channelName | camelCase }} = '{{ channelName }}';
47
- ```
48
-
49
- The generator also supports asynchronous filters. Asynchronous filters receive as the last argument a callback to resume rendering. Asynchronous filters must be annotated with the `async` keyword. Make sure to call the callback with two arguments: `callback(err, res)`. `err` can be `null`. See the following example of how to use asynchronous filters:
50
-
51
- ```js
52
- const filter = module.exports;
53
-
54
- async function asyncCamelCase(str, callback) {
55
- try {
56
- const result = // logic for camel casing str
57
- callback(null, result);
58
- } catch (error) {
59
- callback(error);
60
- }
61
- }
62
- filter.renderAsyncContent = renderAsyncContent;
63
-
64
- // using in template
65
- {{ channelName | asyncCamelCase }}
66
- ```
67
-
68
- Unfortunately, if you need to use Promise, filter still must be annotated with the `async` keyword:
69
-
70
- ```js
71
- async function asyncCamelCase(str, callback) {
72
- return new Promise((resolve, reject) => {
73
- // logic with callback
74
- });
75
- }
76
- ```
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).
79
-
80
-
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).
@@ -1,134 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const xfs = require('fs.extra');
4
- const { isAsyncFunction, registerTypeScript } = require('./utils');
5
- const nunjucksFilters = require('@asyncapi/nunjucks-filters');
6
-
7
- /**
8
- * Registers all template filters.
9
- * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0
10
- * @param {Object} nunjucks Nunjucks environment.
11
- * @param {Object} templateConfig Template configuration.
12
- * @param {String} templateDir Directory where template is located.
13
- * @param {String} filtersDir Directory where local filters are located.
14
- */
15
- module.exports.registerFilters = async (nunjucks, templateConfig, templateDir, filtersDir) => {
16
- await registerLocalFilters(nunjucks, templateDir, filtersDir);
17
- registerConfigFilters(nunjucks, templateDir, templateConfig);
18
-
19
- // Register Nunjucks filters from the 'nunjucks-filters' module without needing to list them in package.json or .ageneratorrc file.
20
- addFilters(nunjucks, nunjucksFilters);
21
- };
22
-
23
- /**
24
- * Registers the local template filters.
25
- * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0
26
- * @private
27
- * @param {Object} nunjucks Nunjucks environment.
28
- * @param {String} templateDir Directory where template is located.
29
- * @param {String} filtersDir Directory where local filters are located.
30
- */
31
- function registerLocalFilters(nunjucks, templateDir, filtersDir) {
32
- return new Promise((resolve, reject) => {
33
- const localFilters = path.resolve(templateDir, filtersDir);
34
-
35
- if (!fs.existsSync(localFilters)) return resolve();
36
-
37
- const walker = xfs.walk(localFilters, {
38
- followLinks: false
39
- });
40
-
41
- walker.on('file', async (root, stats, next) => {
42
- try {
43
- const filePath = path.resolve(
44
- templateDir,
45
- path.resolve(root, stats.name)
46
- );
47
-
48
- registerTypeScript(filePath);
49
- // If it's a module constructor, inject dependencies to ensure consistent usage in remote templates in other projects or plain directories.
50
- delete require.cache[require.resolve(filePath)];
51
- const mod = require(filePath);
52
-
53
- addFilters(nunjucks, mod);
54
-
55
- next();
56
- } catch (e) {
57
- reject(e);
58
- }
59
- });
60
-
61
- walker.on('errors', (root, nodeStatsArray) => {
62
- reject(nodeStatsArray);
63
- });
64
-
65
- walker.on('end', async () => {
66
- resolve();
67
- });
68
- });
69
- }
70
-
71
- /**
72
- * Registers the additionally configured filters.
73
- * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0
74
- * @private
75
- * @param {Object} nunjucks Nunjucks environment.
76
- * @param {String} templateDir Directory where template is located.
77
- * @param {Object} templateConfig Template configuration.
78
- */
79
- async function registerConfigFilters(nunjucks, templateDir, templateConfig) {
80
- const confFilters = templateConfig.filters;
81
- const DEFAULT_MODULES_DIR = 'node_modules';
82
- if (!Array.isArray(confFilters)) return;
83
-
84
- const promises = confFilters.map(async filtersModule => {
85
- let mod;
86
- let filterName = filtersModule;
87
- try {
88
- //first we try to grab module with filters by the module name
89
- //this is when generation is used on production using remote templates
90
- mod = require(filterName);
91
- } catch (error) {
92
- //in case template is local but was not installed in node_modules of the generator then we need to explicitly provide modules location
93
- try {
94
- filterName = path.resolve(templateDir, DEFAULT_MODULES_DIR, filtersModule);
95
- mod = require(filterName);
96
- } catch (e) {
97
- //sometimes it may happen that template is located in node_modules with other templates and its filter package is on the same level as template, as it is shared with other templates
98
- try {
99
- filterName = path.resolve(templateDir, '../..', filtersModule);
100
- mod = require(filterName);
101
- } catch (error) {
102
- //in rare cases, especially in isolated tests, it may happen that installation
103
- //ends but is not yet fully completed, so initial require of the same path do not work
104
- //but in next attempt it works
105
- //we need to keep this workaround until we find a solution
106
- mod = require(filterName);
107
- }
108
- }
109
- }
110
- return addFilters(nunjucks, mod);
111
- });
112
-
113
- await Promise.all(promises);
114
- }
115
-
116
- /**
117
- * Add filter functions to Nunjucks environment. Only owned functions from the module are added.
118
- * @deprecated This method is deprecated. For more details, see the release notes: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.6.0
119
- * @private
120
- * @param {Object} nunjucks Nunjucks environment.
121
- * @param {Object} filters Module with functions.
122
- */
123
- function addFilters(nunjucks, filters) {
124
- Object.getOwnPropertyNames(filters).forEach((key) => {
125
- const value = filters[key];
126
- if (!(value instanceof Function)) return;
127
-
128
- if (isAsyncFunction(value)) {
129
- nunjucks.addFilter(key, value, true);
130
- } else {
131
- nunjucks.addFilter(key, value);
132
- }
133
- });
134
- }