@asyncapi/generator 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @asyncapi/generator
2
2
 
3
+ ## 2.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2d16234: - Package `@asyncapi/generator-hooks` is now part of `generator` repo and won't be released separately. Theource code is stored under `apps/hooks` but the `package/library` name stays as it was originally for backward compatibility,
8
+ - By default, the `@asyncapi/generator-hooks` package, known as **package** contains many different hooks used in templates and is available in the generator. You no longer have to configure it in your `package.json` in `dependencies`. The package, `@asyncapi/generator-hooks` will no longer be published to NPM separately and is deprecated. You can still have your own hooks, store them in a separate package, and configure them with your template.
9
+ - Remember that the fact that the hooks package is now included by default, doesn't mean all hooks from it are enabled by default. You still have to enable a given hook in the configuration file explicitly because some hooks can execute automatically without passing a specific parameter. Also, a hook's supported parameters need to be defined in your template's config.
10
+
11
+ ## 2.4.1
12
+
13
+ ### Patch Changes
14
+
15
+ - 3a372c4: Removed the source-map-support package from the AsyncAPI Generator, as it is no longer required for version 2, which now supports Node.js version 18.12.0 and above.
16
+
3
17
  ## 2.4.0
4
18
 
5
19
  ### Minor Changes
@@ -20,7 +20,7 @@ The `generator` property from `package.json` file must contain a JSON object tha
20
20
  |`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.
21
21
  |`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).
22
22
  |`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.
23
- |`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.
23
+ |`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 the 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 hooks, you must pass an array of strings. In the case of external modules, remember they need to be added as a dependency in `package.json` of your template. There is also [an official hooks library](hooks#official-library) always included in the generator. As this is a library of multiple hooks, you still need to explicitly specify in the configuration which one you want to use. Use `@asyncapi/generator-hooks` as the library name.
24
24
 
25
25
  ### Example
26
26
 
@@ -64,7 +64,8 @@ The `generator` property from `package.json` file must contain a JSON object tha
64
64
  "my-package-with-filters"
65
65
  ],
66
66
  "hooks": {
67
- "@asyncapi/generator-hooks": "hookFunctionName"
67
+ "@asyncapi/generator-hooks": "hookFunctionName",
68
+ "my-custom-hooks-package": ["myHook", "andAnotherOne"]
68
69
  }
69
70
  }
70
71
  ```
@@ -3,7 +3,11 @@ title: "File templates"
3
3
  weight: 140
4
4
  ---
5
5
 
6
- It is possible to generate files for each specific object in your AsyncAPI documentation. 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 in them are available:
6
+ ## Generating files with the Nunjucks render engine
7
+
8
+ > **Note**: This section applies only to the Nunjucks render engine. For information on using the React render engine, refer to the [Generating files with the React render engine](#generating-files-with-the-react-render-engine) section below.
9
+
10
+ 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:
7
11
 
8
12
  - `$$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.
9
13
  - `$$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.
@@ -25,7 +29,7 @@ Schema name is '{{schemaName}}' and properties are:
25
29
  {% endfor %}
26
30
  ```
27
31
 
28
- With following AsyncAPI:
32
+ With the following AsyncAPI:
29
33
  ```
30
34
  components:
31
35
  schemas:
@@ -53,15 +57,82 @@ Schema name is 'people' and properties are:
53
57
  - id
54
58
  ```
55
59
 
56
- ### React
60
+ > You can see an example of a file template that uses the Nunjucks render engine [here](https://github.com/asyncapi/template-for-generator-templates/tree/nunjucks/template/schemas).
61
+
62
+ ## Generating files with the React render engine
57
63
 
58
- The above way of rendering **file templates** works for both `nunjucks` and `react` render engines, but `react` also has another, more generic way to render multiple files. It is enough to return an array of `File` components in the rendering component. See the following example:
64
+ The above method of rendering **file templates** only works for the Nunjucks render engine. To use the React render engine, you need to follow a different approach. The React render engine allows for a more generic way to render multiple files by returning an array of `File` components in the rendering component. This can be particularly useful for complex templates or when you need to generate a large number of files with varying content.
65
+
66
+ ### Example 1: Rendering hardcoded files
67
+
68
+ The following is a simple hardcoded example of how to render multiple files using the React render engine:
59
69
 
60
70
  ```tsx
71
+ import { File} from "@asyncapi/generator-react-sdk";
72
+
61
73
  export default function({ asyncapi }) {
62
74
  return [
63
75
  <File name={`file1.html`}>Content</File>,
64
76
  <File name={`file2.html`}>Content</File>
65
77
  ]
66
78
  }
67
- ```
79
+ ```
80
+
81
+ ### Example 2: Rendering files based on the AsyncAPI Schema
82
+
83
+ 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:
84
+
85
+ ```js
86
+ import { File} from "@asyncapi/generator-react-sdk";
87
+
88
+ /*
89
+ * To render multiple files, it is enough to return an array of `File` components in the rendering component, like in following example.
90
+ */
91
+ export default function({ asyncapi }) {
92
+ const schemas = asyncapi.allSchemas();
93
+ const files = [];
94
+ // schemas is an instance of the Map
95
+ schemas.forEach((schema) => {
96
+
97
+ files.push(
98
+ // We return a react file component and each time we do it, the name of the generated file will be a schema name
99
+ // Content of the file will be a variable representing schema
100
+ <File name={`${schema.id()}.js`}>
101
+ const { schema.id() } = { JSON.stringify(schema._json, null, 2) }
102
+ </File>
103
+ );
104
+ });
105
+ return files;
106
+ }
107
+ ```
108
+
109
+ ### Example 3: Rendering files for each channel
110
+
111
+ Additionally, you can generate multiple files for each channel defined in your AsyncAPI specification using the React render engine as shown in the example below:
112
+
113
+ ```js
114
+ import { File, Text } from "@asyncapi/generator-react-sdk";
115
+
116
+
117
+ export default function ({ asyncapi }) {
118
+ const files = [];
119
+
120
+ // Generate files for channels
121
+ asyncapi.channels().forEach((channel) => {
122
+ const channelName = channel.id();
123
+
124
+ files.push(
125
+ <File name={`${channelName}.md`}>
126
+ <Text newLines={2}># Channel: {channelName}</Text>
127
+ <Text>
128
+ {channel.hasDescription() && `${channel.description()}`}
129
+ </Text>
130
+ </File>
131
+ );
132
+ });
133
+ return files;
134
+ }
135
+ ```
136
+ 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.
137
+
138
+ > 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).
@@ -159,7 +159,7 @@ To see this in action, navigate to the **python-mqtt-client-template** directory
159
159
 
160
160
  ``` cmd
161
161
  Generation in progress. Keep calm and wait a bit... done
162
- Check out your shiny new generated files at output.
162
+ Check out your shiny new generated files at test/project.
163
163
  ```
164
164
 
165
165
  Navigating to the **test/project** directory. You should see a **client.py** file; the only content is `Temperature Service`.
package/docs/hooks.md CHANGED
@@ -4,21 +4,26 @@ weight: 130
4
4
  ---
5
5
 
6
6
  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.
7
+
8
+ ## Types
9
+
7
10
  The following types of hooks are currently supported:
8
11
 
9
12
  |Hook type|Description| Return type | Arguments
10
13
  |---|---|---|---|
11
- | `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)
12
- | `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)
13
- | `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 }`
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 }`
17
+
18
+ ## Location
14
19
 
15
20
  The generator parses:
16
21
  - All the files in the `.hooks` directory inside the template.
17
- - 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).
22
+ - All modules listed in the template configuration and triggers only hooks whose names were added to the config. You can use an [official hooks library](#official-library) that is bundled together with the generator. To learn how to add hooks to configuration [read more about the configuration file](configuration-file).
18
23
 
19
- ### Examples
24
+ ## Examples
20
25
 
21
- > 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).
26
+ > 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](configuration-file).
22
27
 
23
28
  Most basic modules with hooks look like this:
24
29
  ```js
@@ -79,3 +84,35 @@ module.exports = {
79
84
  };
80
85
  };
81
86
  ```
87
+
88
+ ## Official library
89
+
90
+ It is a library of reusable hooks that you can use in your templates. You only have to add its name to the configuration: `@asyncapi/generator-hooks` and specify which hook you want to enable.
91
+
92
+ This library consists of the following hooks:
93
+ |Hook name|Hook type|Description|
94
+ |---|---|---|
95
+ | `createAsyncapiFile` | `generate:after` | It creates an AsyncAPI file with the content of the spec file passed to the generator. By default, it creates the file in the root of the generation output directory. This hook also supports custom parameters that the user can pass to template generation. The parameter called `asyncapiFileDir` allows the user to specify the location where the spec file should be created. To make your template users use this parameter, you need to add it to the configuration of your template like other parameters |
96
+
97
+ 1. In your template configuration in `package.json` specify you want to use this library and what hook exactly:
98
+ ```json
99
+ {
100
+ "generator": {
101
+ "hooks": {
102
+ "@asyncapi/generator-hooks": "createAsyncapiFile"
103
+ }
104
+ }
105
+ }
106
+ ```
107
+ 1. Some hooks support custom parameters that template's user can use to specify different behaviour of the hook. To enable these, you need to also add them to the list of your template's parameters:
108
+ ```json
109
+ {
110
+ "generator": {
111
+ "parameters": {
112
+ "asyncapiFileDir": {
113
+ "description": "This template by default also outputs the AsyncAPI document that was passed as input. You can specify with this parameter what should be the location of this AsyncAPI document, relative to specified template output."
114
+ }
115
+ }
116
+ }
117
+ }
118
+ ```
package/lib/generator.js CHANGED
@@ -27,7 +27,6 @@ const {
27
27
  fetchSpec,
28
28
  isReactTemplate,
29
29
  isJsFile,
30
- registerSourceMap,
31
30
  getTemplateDetails,
32
31
  convertCollectionToObject,
33
32
  } = require('./utils');
@@ -57,8 +56,6 @@ const shouldIgnoreDir = dirPath =>
57
56
  dirPath === '.git'
58
57
  || dirPath.startsWith(`.git${path.sep}`);
59
58
 
60
- registerSourceMap();
61
-
62
59
  class Generator {
63
60
  /**
64
61
  * Instantiates a new Generator object.
@@ -137,7 +134,7 @@ class Generator {
137
134
  Object.defineProperty(this.templateParams, key, {
138
135
  enumerable: true,
139
136
  get() {
140
- if (!self.templateConfig.parameters || !self.templateConfig.parameters[key]) {
137
+ if (!self.templateConfig.parameters?.[key]) {
141
138
  throw new Error(`Template parameter "${key}" has not been defined in the package.json file under generator property. Please make sure it's listed there before you use it in your template.`);
142
139
  }
143
140
  return templateParams[key];
@@ -565,8 +562,8 @@ class Generator {
565
562
 
566
563
  try {
567
564
  installedPkg = getTemplateDetails(this.templateName, PACKAGE_JSON_FILENAME);
568
- pkgPath = installedPkg && installedPkg.pkgPath;
569
- packageVersion = installedPkg && installedPkg.version;
565
+ pkgPath = installedPkg?.pkgPath;
566
+ packageVersion = installedPkg?.version;
570
567
  log.debug(logMessage.templateSource(pkgPath));
571
568
  if (packageVersion) log.debug(logMessage.templateVersion(packageVersion));
572
569
 
@@ -762,7 +759,7 @@ class Generator {
762
759
  // Check if the filename dictates it should be separated
763
760
  let wasSeparated = false;
764
761
  for (const prop in fileNamesForSeparation) {
765
- if (Object.prototype.hasOwnProperty.call(fileNamesForSeparation, prop) && stats.name.includes(`$$${prop}$$`)) {
762
+ if (Object.hasOwn(fileNamesForSeparation, prop) && stats.name.includes(`$$${prop}$$`)) {
766
763
  await this.generateSeparateFiles(asyncapiDocument, fileNamesForSeparation[prop], prop, stats.name, root);
767
764
  const templateFilePath = path.relative(this.templateContentDir, path.resolve(root, stats.name));
768
765
  fs.unlink(path.resolve(this.targetDir, templateFilePath), next);
@@ -878,7 +875,7 @@ class Generator {
878
875
  const shouldOverwriteFile = await this.shouldOverwriteFile(relativeTargetFile);
879
876
  if (!shouldOverwriteFile) return;
880
877
 
881
- if (this.templateConfig.conditionalFiles && this.templateConfig.conditionalFiles[relativeSourceFile]) {
878
+ if (this.templateConfig.conditionalFiles?.[relativeSourceFile]) {
882
879
  const server = this.templateParams.server && asyncapiDocument.servers().get(this.templateParams.server);
883
880
  const source = jmespath.search({
884
881
  ...asyncapiDocument.json(),
@@ -2,7 +2,7 @@ const TEMPLATE_INSTALL_FLAG_MSG = 'because you passed --install flag';
2
2
 
3
3
  const TEMPLATE_INSTALL_DISK_MSG = 'because the template cannot be found on disk';
4
4
 
5
- const NODE_MODULES_INSTALL ='Remember that your local template must have its own node_modules installed first, \"npm install\" is not triggered by the generator.';
5
+ const NODE_MODULES_INSTALL = 'Remember that your local template must have its own node_modules installed first, "npm install" is not triggered by the generator.';
6
6
 
7
7
  const NPM_INSTALL_TRIGGER = 'Installation of template located on disk technically means symlink creation betweed node_modules of the generator and template sources. Your local template must have its own node_modules, "npm install" is not triggered.';
8
8
 
@@ -19,7 +19,7 @@ function templateNotFound(templateName) {
19
19
  }
20
20
 
21
21
  function packageNotAvailable(packageDetails) {
22
- if (packageDetails && packageDetails.pkgPath) {
22
+ if (packageDetails?.pkgPath) {
23
23
  return `Unable to resolve template location at ${packageDetails.pkgPath}. Package is not available locally.`;
24
24
  }
25
25
 
package/lib/parser.js CHANGED
@@ -63,7 +63,7 @@ function convertOldOptionsToNew(oldOptions, generator) {
63
63
  }
64
64
 
65
65
  const resolvers = [];
66
- if (generator && generator.mapBaseUrlToFolder && generator.mapBaseUrlToFolder.url) {
66
+ if (generator?.mapBaseUrlToFolder?.url) {
67
67
  resolvers.push(...getMapBaseUrlToFolderResolvers(generator.mapBaseUrlToFolder));
68
68
  }
69
69
  if (oldOptions.resolve) {
@@ -97,7 +97,7 @@ function getParamSuggestion(wrongParam, configParams) {
97
97
  * @param {Object} templateParams All parameters provided to generator
98
98
  */
99
99
  function isProvidedParameterSupported(configParams, templateParams) {
100
- const wrongParams = Object.keys(templateParams || {}).filter(key => !configParams || !configParams[key]);
100
+ const wrongParams = Object.keys(templateParams || {}).filter(key => !configParams?.[key]);
101
101
 
102
102
  if (!wrongParams.length) return;
103
103
  if (!configParams) throw new Error('This template doesn\'t have any params.');
package/lib/utils.js CHANGED
@@ -131,17 +131,7 @@ utils.getGeneratorVersion = () => {
131
131
  * @returns {Boolean} is function asynchronous
132
132
  */
133
133
  utils.isAsyncFunction = (fn) => {
134
- return fn && fn.constructor && fn.constructor.name === 'AsyncFunction';
135
- };
136
-
137
- /**
138
- * Register `source-map-support` package.
139
- * This package provides source map support for stack traces in Node - also for transpiled code from TS.
140
- *
141
- * @private
142
- */
143
- utils.registerSourceMap = () => {
144
- require('source-map-support').install();
134
+ return fn?.constructor?.name === 'AsyncFunction';
145
135
  };
146
136
 
147
137
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asyncapi/generator",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "The AsyncAPI generator. It can generate documentation, code, anything!",
5
5
  "main": "./lib/generator.js",
6
6
  "bin": {
@@ -49,9 +49,10 @@
49
49
  "license": "Apache-2.0",
50
50
  "homepage": "https://github.com/asyncapi/generator",
51
51
  "dependencies": {
52
- "@asyncapi/generator-react-sdk": "^1.1.1",
52
+ "@asyncapi/generator-react-sdk": "^1.1.2",
53
53
  "@asyncapi/multi-parser": "^2.1.1",
54
54
  "@asyncapi/nunjucks-filters": "*",
55
+ "@asyncapi/generator-hooks": "*",
55
56
  "@asyncapi/parser": "^3.0.14",
56
57
  "@npmcli/arborist": "5.6.3",
57
58
  "@npmcli/config": "^8.0.2",
@@ -73,7 +74,6 @@
73
74
  "resolve-pkg": "^2.0.0",
74
75
  "semver": "^7.3.2",
75
76
  "simple-git": "^3.3.0",
76
- "source-map-support": "^0.5.19",
77
77
  "ts-node": "^10.9.1",
78
78
  "typescript": "^4.9.3"
79
79
  },
@@ -82,11 +82,11 @@
82
82
  "eslint-plugin-jest": "^23.8.2",
83
83
  "eslint-plugin-react": "^7.34.1",
84
84
  "eslint-plugin-sonarjs": "^0.5.0",
85
+ "fs-extra": "9.1.0",
85
86
  "jest": "^27.3.1",
86
87
  "jsdoc-to-markdown": "^7.1.1",
87
88
  "markdown-toc": "^1.2.0",
88
89
  "rimraf": "^3.0.2",
89
- "unixify": "^1.0.0",
90
- "fs-extra": "9.1.0"
90
+ "unixify": "^1.0.0"
91
91
  }
92
92
  }
@@ -14,6 +14,400 @@ Version v1 running on production mode
14
14
  "
15
15
  `;
16
16
 
17
+ exports[`Integration testing generateFromFile() to make sure the result of the generation is not changend comparing to snapshot generate using React template 2`] = `
18
+ "asyncapi: '2.3.0'
19
+
20
+ externalDocs:
21
+ description: Find more info here
22
+ url: https://www.asyncapi.com
23
+
24
+ info:
25
+ title: Dummy example with all spec features included
26
+ version: '0.0.1'
27
+ description: |
28
+ This is an example of AsyncAPI specification file that is suppose to include all possible features of the AsyncAPI specification. Do not use it on production.
29
+
30
+ It's goal is to support development of documentation and code generation with the [AsyncAPI Generator](https://github.com/asyncapi/generator/) and [Template projects](https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate)
31
+ license:
32
+ name: Apache 2.0
33
+ url: https://www.apache.org/licenses/LICENSE-2.0
34
+ contact:
35
+ name: API Support
36
+ url: http://www.asyncapi.com/support
37
+ email: info@asyncapi.io
38
+ x-twitter: '@AsyncAPISpec'
39
+
40
+ tags:
41
+ - name: root-tag1
42
+ externalDocs:
43
+ description: External docs description 1
44
+ url: https://www.asyncapi.com/
45
+ - name: root-tag2
46
+ description: Description 2
47
+ externalDocs:
48
+ url: \\"https://www.asyncapi.com/\\"
49
+ - name: root-tag3
50
+ - name: root-tag4
51
+ description: Description 4
52
+ - name: root-tag5
53
+ externalDocs:
54
+ url: \\"https://www.asyncapi.com/\\"
55
+
56
+ servers:
57
+ dummy-mqtt:
58
+ $ref: '#/components/servers/dummyMQTT'
59
+ dummy-amqp:
60
+ url: amqp://localhost:{port}
61
+ protocol: amqp
62
+ description: dummy AMQP broker
63
+ protocolVersion: \\"0.9.1\\"
64
+ variables:
65
+ port:
66
+ enum:
67
+ - '15672'
68
+ - '5672'
69
+ security:
70
+ - user-password: []
71
+ dummy-kafka:
72
+ url: http://localhost:{port}
73
+ protocol: kafka
74
+ description: dummy Kafka broker
75
+ variables:
76
+ port:
77
+ default: '9092'
78
+
79
+ defaultContentType: application/json
80
+
81
+ channels:
82
+ dummy/channel/with/{dummy}/parameter/create:
83
+ x-dummy-security:
84
+ $ref: '#/components/securitySchemes/supportedOauthFlows/flows/clientCredentials'
85
+ description: Dummy channel description.
86
+ parameters:
87
+ dummy:
88
+ $ref: '#/components/parameters/dummy'
89
+ publish:
90
+ summary: Inform whenever something dummy is created.
91
+ description: |
92
+ Longer description.
93
+
94
+ Still dummy though.
95
+ operationId: receiveNewDummyInfo
96
+ tags:
97
+ - name: oparation-tag1
98
+ externalDocs:
99
+ description: External docs description 1
100
+ url: https://www.asyncapi.com/
101
+ - name: oparation-tag2
102
+ description: Description 2
103
+ externalDocs:
104
+ url: \\"https://www.asyncapi.com/\\"
105
+ - name: oparation-tag3
106
+ - name: oparation-tag4
107
+ description: Description 4
108
+ - name: oparation-tag5
109
+ externalDocs:
110
+ url: \\"https://www.asyncapi.com/\\"
111
+ traits:
112
+ - $ref: '#/components/operationTraits/kafka'
113
+ message:
114
+ $ref: '#/components/messages/dummyCreated'
115
+
116
+ dummy/channel/without/parameter:
117
+ $ref: '#/components/channels/dummyChannel'
118
+ components:
119
+ servers:
120
+ dummyMQTT:
121
+ url: mqtt://localhost
122
+ protocol: mqtt
123
+ description: dummy MQTT broker
124
+ bindings:
125
+ mqtt:
126
+ clientId: guest
127
+ cleanSession: true
128
+ channels:
129
+ dummyChannel:
130
+ bindings:
131
+ amqp:
132
+ is: routingKey
133
+ subscribe:
134
+ operationId: receiveSystemInfo
135
+ bindings:
136
+ amqp:
137
+ expiration: 100000
138
+ userId: guest
139
+ cc: [ 'user.logs' ]
140
+ priority: 10
141
+ deliveryMode: 2
142
+ mandatory: false
143
+ bcc: [ 'external.audit' ]
144
+ replyTo: user.signedup
145
+ timestamp: true
146
+ ack: false
147
+ bindingVersion: 0.1.0
148
+ message:
149
+ $ref: '#/components/messages/dummyInfo'
150
+ messages:
151
+ dummyCreated:
152
+ name: dummyCreated
153
+ title: Dummy created message
154
+ summary: This is just a dummy create message
155
+ correlationId:
156
+ description: This is a dummy correlation ID.
157
+ location: $message.header#/correlationId
158
+ tags:
159
+ - name: message-tag1
160
+ externalDocs:
161
+ description: External docs description 1
162
+ url: https://www.asyncapi.com/
163
+ - name: message-tag2
164
+ description: Description 2
165
+ externalDocs:
166
+ url: \\"https://www.asyncapi.com/\\"
167
+ - name: message-tag3
168
+ - name: message-tag4
169
+ description: Description 4
170
+ - name: message-tag5
171
+ externalDocs:
172
+ url: \\"https://www.asyncapi.com/\\"
173
+ headers:
174
+ type: object
175
+ properties:
176
+ my-custom-app-header:
177
+ type: string
178
+ correlationId:
179
+ type: string
180
+ payload:
181
+ $ref: \\"#/components/schemas/dummyCreated\\"
182
+ bindings:
183
+ kafka:
184
+ key:
185
+ type: object
186
+ properties:
187
+ id:
188
+ type: string
189
+ format: uuid
190
+ type:
191
+ type: string
192
+ enum: [ 'type1', \\"type2\\" ]
193
+ bindingVersion: '0.1.0'
194
+ amqp:
195
+ contentEncoding: gzip
196
+ messageType: 'user.signup'
197
+ bindingVersion: 0.1.0
198
+ x-response:
199
+ $ref: \\"#/components/messages/dummyInfo\\"
200
+ dummyInfo:
201
+ name: dummyInfo
202
+ title: Dummy system info
203
+ summary: This is just a dummy info message
204
+ correlationId:
205
+ location: $message.header#/correlationId
206
+ description: |
207
+ More description for a dummy message.
208
+
209
+ It is a dummy system info message.
210
+ traits:
211
+ - $ref: '#/components/messageTraits/commonHeaders'
212
+ payload:
213
+ $ref: \\"#/components/schemas/dummyInfo\\"
214
+ examples:
215
+ - name: option1example
216
+ summary: this is dummy summary for option1example
217
+ headers:
218
+ my-app-header: 12
219
+ payload:
220
+ prop1: option1
221
+ sentAt: 2020-01-31T13:24:53Z
222
+ - name: headerExample
223
+ headers:
224
+ my-app-header: 13
225
+ - payload:
226
+ prop1: option2
227
+ sentAt: 2020-01-31T13:24:53Z
228
+
229
+
230
+ schemas:
231
+ dummyCreated:
232
+ type: object
233
+ required:
234
+ - prop2
235
+ x-schema-extensions-as-object:
236
+ type: object
237
+ properties:
238
+ prop1:
239
+ type: string
240
+ prop2:
241
+ type: integer
242
+ minimum: 0
243
+ x-schema-extensions-as-primitive: dummy
244
+ x-schema-extensions-as-array:
245
+ - \\"item1\\"
246
+ - \\"item2\\"
247
+ properties:
248
+ prop1:
249
+ type: integer
250
+ minimum: 0
251
+ description: Dummy prop1
252
+ x-prop1-dummy: dummy extension
253
+ prop2:
254
+ type: string
255
+ description: Dummy prop2
256
+ sentAt:
257
+ $ref: \\"#/components/schemas/sentAt\\"
258
+ dummyArrayWithObject:
259
+ $ref: \\"#/components/schemas/dummyArrayWithObject\\"
260
+ dummyArrayWithArray:
261
+ $ref: \\"#/components/schemas/dummyArrayWithArray\\"
262
+ dummyObject:
263
+ $ref: \\"#/components/schemas/dummyObject\\"
264
+ dummyArrayRank:
265
+ $ref: '#/components/schemas/dummyArrayRank'
266
+ dummyInfo:
267
+ type: object
268
+ required:
269
+ - prop1
270
+ properties:
271
+ prop1:
272
+ type: string
273
+ enum:
274
+ - option1
275
+ - option2
276
+ description: Dummy prop1
277
+ sentAt:
278
+ $ref: \\"#/components/schemas/sentAt\\"
279
+ dummyArrayWithObject:
280
+ type: array
281
+ items:
282
+ $ref: \\"#/components/schemas/dummyInfo\\"
283
+ dummyArrayWithArray:
284
+ type: array
285
+ items:
286
+ - $ref: \\"#/components/schemas/dummyInfo\\"
287
+ - type: string
288
+ - type: number
289
+ dummyObject:
290
+ type: object
291
+ properties:
292
+ dummyObjectProp1:
293
+ $ref: \\"#/components/schemas/sentAt\\"
294
+ dummyObjectProp2:
295
+ $ref: \\"#/components/schemas/dummyRecursiveObject\\"
296
+ dummyObjectProp3:
297
+ type: object
298
+ additionalProperties: true
299
+ dummyObjectProp4:
300
+ type: object
301
+ additionalProperties: false
302
+ dummyRecursiveObject:
303
+ type: object
304
+ properties:
305
+ dummyRecursiveProp1:
306
+ $ref: \\"#/components/schemas/dummyObject\\"
307
+ dummyRecursiveProp2:
308
+ type: string
309
+ sentAt:
310
+ type: string
311
+ format: date-time
312
+ description: Date and time when the message was sent.
313
+ dummyArrayRank:
314
+ type: object
315
+ properties:
316
+ dummyArrayValueRank:
317
+ $ref: '#/components/schemas/dummyArrayValueRank'
318
+ dummyArrayDimensions:
319
+ $ref: '#/components/schemas/dummyArrayArrayDimensions'
320
+ dummyArrayValueRank:
321
+ description: >
322
+ This Attribute indicates whether the val Attribute of the datapoint is an
323
+ array and how many dimensions the array has.
324
+ type: integer
325
+ default: -1
326
+ examples:
327
+ - 2
328
+ oneOf:
329
+ - const: -1
330
+ description: 'Scalar: The value is not an array.'
331
+ - const: 0
332
+ description: 'OneOrMoreDimensions: The value is an array with one or more dimensions.'
333
+ - const: 1
334
+ description: 'OneDimension: The value is an array with one dimension.'
335
+ - const: 2
336
+ description: 'The value is an array with two dimensions.'
337
+ dummyArrayArrayDimensions:
338
+ type: array
339
+ items:
340
+ type: integer
341
+ minimum: 0
342
+ examples:
343
+ - [3, 5]
344
+
345
+ securitySchemes:
346
+ user-password:
347
+ type: userPassword
348
+ apiKey:
349
+ type: apiKey
350
+ in: user
351
+ description: Provide your API key as the user and leave the password empty.
352
+ supportedOauthFlows:
353
+ type: oauth2
354
+ description: Flows to support OAuth 2.0
355
+ flows:
356
+ implicit:
357
+ authorizationUrl: 'https://authserver.example/auth'
358
+ scopes:
359
+ 'dummy:created': Ability to create dummy message
360
+ 'dymmy:read': Ability to read dummy info
361
+ password:
362
+ tokenUrl: 'https://authserver.example/token'
363
+ scopes:
364
+ 'dummy:created': Ability to create dummy message
365
+ 'dymmy:read': Ability to read dummy info
366
+ clientCredentials:
367
+ tokenUrl: 'https://authserver.example/token'
368
+ scopes:
369
+ 'dummy:created': Ability to create dummy message
370
+ 'dymmy:read': Ability to read dummy info
371
+ authorizationCode:
372
+ authorizationUrl: 'https://authserver.example/auth'
373
+ tokenUrl: 'https://authserver.example/token'
374
+ refreshUrl: 'https://authserver.example/refresh'
375
+ scopes:
376
+ 'dummy:created': Ability to create dummy message
377
+ 'dymmy:read': Ability to read dummy info
378
+ openIdConnectWellKnown:
379
+ type: openIdConnect
380
+ openIdConnectUrl: 'https://authserver.example/.well-known'
381
+
382
+ parameters:
383
+ dummy:
384
+ description: The ID of the new dummy message.
385
+ schema:
386
+ type: string
387
+ description: Description that not be rendered, as parameter has explicit description.
388
+
389
+ messageTraits:
390
+ commonHeaders:
391
+ headers:
392
+ type: object
393
+ properties:
394
+ my-app-header:
395
+ type: integer
396
+ minimum: 0
397
+ maximum: 100
398
+ correlationId:
399
+ type: string
400
+
401
+ operationTraits:
402
+ kafka:
403
+ bindings:
404
+ kafka:
405
+ groupId: my-app-group-id
406
+ clientId: my-app-client-id
407
+ bindingVersion: '0.1.0'
408
+ "
409
+ `;
410
+
17
411
  exports[`Integration testing generateFromFile() to make sure the result of the generation is not changend comparing to snapshot generated using Nunjucks template 1`] = `
18
412
  "This is a markdown file for my application.
19
413
  App name is: **Dummy example with all spec features included**
@@ -62,8 +62,11 @@ describe('Integration testing generateFromFile() to make sure the result of the
62
62
  templateParams: { version: 'v1', mode: 'production' }
63
63
  });
64
64
  await generator.generateFromFile(dummySpecPath);
65
- const file = await readFile(path.join(outputDir, testOutputFile), 'utf8');
66
- expect(file).toMatchSnapshot();
65
+ const mdFile = await readFile(path.join(outputDir, testOutputFile), 'utf8');
66
+ //react template has hooks lib enabled and generation of asyncapi document that was passed as input should work out of the box without adding @asyncapi/generator-hooks to dependencies
67
+ const asyncAPIFile = await readFile(path.join(outputDir, 'asyncapi.yaml'), 'utf8');
68
+ expect(mdFile).toMatchSnapshot();
69
+ expect(asyncAPIFile).toMatchSnapshot();
67
70
  });
68
71
 
69
72
  it('generate json based api with referenced JSON Schema', async () => {
@@ -10,8 +10,8 @@ jest.mock('@asyncapi/generator-react-sdk');
10
10
 
11
11
  describe('React renderer', () => {
12
12
  describe('saveRenderedReactContent', () => {
13
- let util = undefined;
14
- let AsyncReactSDK = undefined;
13
+ let util;
14
+ let AsyncReactSDK;
15
15
  beforeAll(() => {
16
16
  util = require('../lib/utils');
17
17
  AsyncReactSDK = require('@asyncapi/generator-react-sdk');
@@ -8,7 +8,7 @@
8
8
  "name": "nunjucks-template",
9
9
  "version": "0.0.1",
10
10
  "dependencies": {
11
- "@asyncapi/generator-react-sdk": "^1.1.1"
11
+ "@asyncapi/generator-react-sdk": "^1.1.2"
12
12
  }
13
13
  },
14
14
  "node_modules/@ampproject/remapping": {
@@ -25,9 +25,9 @@
25
25
  }
26
26
  },
27
27
  "node_modules/@asyncapi/generator-react-sdk": {
28
- "version": "1.1.1",
29
- "resolved": "https://registry.npmjs.org/@asyncapi/generator-react-sdk/-/generator-react-sdk-1.1.1.tgz",
30
- "integrity": "sha512-R86Xa20wLtzI4fVf9HECR+UCSYvNE1B4WZs3eI5jAvGtONBTFOvkixd4SUL+uLP4DP96pU2DuKhih/PQbmMneQ==",
28
+ "version": "1.1.2",
29
+ "resolved": "https://registry.npmjs.org/@asyncapi/generator-react-sdk/-/generator-react-sdk-1.1.2.tgz",
30
+ "integrity": "sha512-hU9ux8hEMhXwQWWzySZlZ+L5SsM0r4uXdPFvYRTX5uVGeLKGoj4Ok8hY2gPhahKcvMELOIU2mw3O6h9h9AcskQ==",
31
31
  "dependencies": {
32
32
  "@asyncapi/parser": "^3.1.0",
33
33
  "@babel/core": "7.12.9",
@@ -3693,9 +3693,9 @@
3693
3693
  }
3694
3694
  },
3695
3695
  "node_modules/rollup": {
3696
- "version": "2.79.1",
3697
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
3698
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
3696
+ "version": "2.79.2",
3697
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
3698
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
3699
3699
  "bin": {
3700
3700
  "rollup": "dist/bin/rollup"
3701
3701
  },
@@ -16,6 +16,6 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@asyncapi/generator-react-sdk": "^1.1.1"
19
+ "@asyncapi/generator-react-sdk": "^1.1.2"
20
20
  }
21
21
  }
@@ -8,7 +8,7 @@
8
8
  "name": "react-template",
9
9
  "version": "0.0.1",
10
10
  "dependencies": {
11
- "@asyncapi/generator-react-sdk": "^1.1.1"
11
+ "@asyncapi/generator-react-sdk": "^1.1.2"
12
12
  }
13
13
  },
14
14
  "node_modules/@ampproject/remapping": {
@@ -25,9 +25,9 @@
25
25
  }
26
26
  },
27
27
  "node_modules/@asyncapi/generator-react-sdk": {
28
- "version": "1.1.1",
29
- "resolved": "https://registry.npmjs.org/@asyncapi/generator-react-sdk/-/generator-react-sdk-1.1.1.tgz",
30
- "integrity": "sha512-R86Xa20wLtzI4fVf9HECR+UCSYvNE1B4WZs3eI5jAvGtONBTFOvkixd4SUL+uLP4DP96pU2DuKhih/PQbmMneQ==",
28
+ "version": "1.1.2",
29
+ "resolved": "https://registry.npmjs.org/@asyncapi/generator-react-sdk/-/generator-react-sdk-1.1.2.tgz",
30
+ "integrity": "sha512-hU9ux8hEMhXwQWWzySZlZ+L5SsM0r4uXdPFvYRTX5uVGeLKGoj4Ok8hY2gPhahKcvMELOIU2mw3O6h9h9AcskQ==",
31
31
  "dependencies": {
32
32
  "@asyncapi/parser": "^3.1.0",
33
33
  "@babel/core": "7.12.9",
@@ -3693,9 +3693,9 @@
3693
3693
  }
3694
3694
  },
3695
3695
  "node_modules/rollup": {
3696
- "version": "2.79.1",
3697
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
3698
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
3696
+ "version": "2.79.2",
3697
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
3698
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
3699
3699
  "bin": {
3700
3700
  "rollup": "dist/bin/rollup"
3701
3701
  },
@@ -7,17 +7,23 @@
7
7
  },
8
8
  "generator": {
9
9
  "renderer": "react",
10
- "api": "v3",
10
+ "apiVersion": "v3",
11
+ "hooks": {
12
+ "@asyncapi/generator-hooks": "createAsyncapiFile"
13
+ },
11
14
  "parameters": {
12
15
  "version": {
13
16
  "description": "Custom version to be used"
14
17
  },
15
18
  "mode": {
16
19
  "description": "development or production"
20
+ },
21
+ "asyncapiFileDir": {
22
+ "description": "This template by default also outputs the AsyncAPI document that was passed as input. You can specify with this parameter what should be the location of this AsyncAPI document, relative to specified template output."
17
23
  }
18
24
  }
19
25
  },
20
26
  "dependencies": {
21
- "@asyncapi/generator-react-sdk": "^1.1.1"
27
+ "@asyncapi/generator-react-sdk": "^1.1.2"
22
28
  }
23
29
  }