diff --git a/.all-contributorsrc b/.all-contributorsrc
index bdacc7798f3..84715bc5283 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -179,6 +179,33 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "kaushik-rishi",
+ "name": "Rishi",
+ "avatar_url": "https://avatars.githubusercontent.com/u/52498617?v=4",
+ "profile": "https://github.com/kaushik-rishi",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "Shurtu-gal",
+ "name": "Ashish Padhy",
+ "avatar_url": "https://avatars.githubusercontent.com/u/100484401?v=4",
+ "profile": "http://ashishpadhy.live",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "meetagrawal09",
+ "name": "Meet Agrawal",
+ "avatar_url": "https://avatars.githubusercontent.com/u/73902874?v=4",
+ "profile": "https://github.com/meetagrawal09",
+ "contributions": [
+ "infra"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml
index f491d7d8235..bf11cd4ab5c 100644
--- a/.github/workflows/upload-release-assets.yml
+++ b/.github/workflows/upload-release-assets.yml
@@ -68,3 +68,12 @@ jobs:
files: dist/${{ matrix.dist_folder }}/asyncapi.${{ matrix.extension }}
tag_name: v${{ steps.extractver.outputs.version }}
token: ${{ secrets.GH_TOKEN }}
+ - if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel
+ name: Report workflow run status to Slack
+ uses: 8398a7/action-slack@v3
+ with:
+ status: ${{ job.status }}
+ fields: repo,action,workflow
+ text: 'AsyncAPI CLI release build artifacts failed'
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }}
diff --git a/README.md b/README.md
index f7511823fbb..71d70aa4be9 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,9 @@ Thanks go to these wonderful people ([emoji key](https://allcontributors.org/doc
Sambhav Gupta 💻 ⚠️ |
Hippolyte Vergnol 💻 🚇 |
Jente Vets 💻 |
+ Rishi 💻 |
+ Ashish Padhy 💻 |
+ Meet Agrawal 🚇 |
diff --git a/docs/usage.md b/docs/usage.md
index 523438e8758..2bc42daf1a8 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -6,11 +6,13 @@ weight: 40
The AsyncAPI CLI makes it easier to work with AsyncAPI documents.
To get **help**, run this command in your terminal:
+
```sh
asyncapi --help
```
It should print something similar to this:
+
```sh
All in one CLI for all AsyncAPI tools
@@ -39,5 +41,7 @@ COMMANDS
dart generate the models for Dart
rust generate the models for Rust
kotlin generate the models for Kotlin
- fromTemplate generate whatever you want using templates compatible with AsyncAPI Generator
+ php generate the models for PHP
+ cplusplus generate the models for C++
+ fromTemplate generate whatever you want using templates compatible with AsyncAPI Generator
```
diff --git a/package-lock.json b/package-lock.json
index 88de1517df9..c08b1102d67 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,20 +1,20 @@
{
"name": "@asyncapi/cli",
- "version": "0.40.6",
+ "version": "0.45.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@asyncapi/cli",
- "version": "0.40.6",
+ "version": "0.45.0",
"license": "Apache-2.0",
"dependencies": {
"@asyncapi/avro-schema-parser": "^3.0.0",
"@asyncapi/bundler": "^0.3.8",
"@asyncapi/converter": "^1.2.0",
"@asyncapi/diff": "^0.4.1",
- "@asyncapi/generator": "^1.9.17",
- "@asyncapi/modelina": "^1.5.0",
+ "@asyncapi/generator": "^1.10.1",
+ "@asyncapi/modelina": "^1.7.0",
"@asyncapi/openapi-schema-parser": "^3.0.0",
"@asyncapi/optimizer": "^0.1.18",
"@asyncapi/parser": "^2.0.0",
@@ -272,20 +272,19 @@
}
},
"node_modules/@asyncapi/generator": {
- "version": "1.9.17",
- "resolved": "https://registry.npmjs.org/@asyncapi/generator/-/generator-1.9.17.tgz",
- "integrity": "sha512-VHtZn6f+2w0rqFS+0e7QxH7vkyZGbLkuFSNOGWfVGaQqkmtCHY70pYxpF5ojCvMrqAAQyKKKXvzjIfjCabDKhA==",
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@asyncapi/generator/-/generator-1.10.1.tgz",
+ "integrity": "sha512-jSAX1mQPr/tSUNgxvdfM8G5rwBqGMgTCaQW8hhBViWhjxakzCWD/uRV4V2Tj1d51qvT7Brnj6PEWEX1ytlFV1w==",
"dependencies": {
- "@asyncapi/avro-schema-parser": "^1.1.0",
+ "@asyncapi/avro-schema-parser": "^3.0.0",
"@asyncapi/generator-react-sdk": "^0.2.23",
- "@asyncapi/openapi-schema-parser": "^2.0.1",
- "@asyncapi/parser": "^1.18.0",
- "@asyncapi/raml-dt-schema-parser": "^2.0.1",
+ "@asyncapi/openapi-schema-parser": "^3.0.0",
+ "@asyncapi/parser": "^2.0.0",
+ "@asyncapi/raml-dt-schema-parser": "^4.0.0",
"@npmcli/arborist": "^2.2.4",
- "ajv": "^6.10.2",
+ "ajv": "^8.12.0",
"chokidar": "^3.4.0",
"commander": "^6.1.0",
- "conventional-changelog-conventionalcommits": "^5.0.0",
"filenamify": "^4.1.0",
"fs.extra": "^1.3.2",
"global-dirs": "^3.0.0",
@@ -420,76 +419,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/@asyncapi/generator/node_modules/@asyncapi/avro-schema-parser": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@asyncapi/avro-schema-parser/-/avro-schema-parser-1.1.0.tgz",
- "integrity": "sha512-7J7pzSw0/jF2bXy/Mf+80VKJfXRRfyLTJz413MkKLbLXbbz9rV4sVpYfp31ofqXgyZ9bhfmHJzunbi0Bt7Jcww==",
- "dependencies": {
- "avsc": "^5.7.3"
- }
- },
- "node_modules/@asyncapi/generator/node_modules/@asyncapi/openapi-schema-parser": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@asyncapi/openapi-schema-parser/-/openapi-schema-parser-2.0.3.tgz",
- "integrity": "sha512-o9fvibjx2n3L2SKNlWUQ59CxO2x2BKhbHxh81U39NMLgowN/avk1wfxkMvzL3G9pg4FlgCdcayDhu4+TzDX47A==",
- "dependencies": {
- "@openapi-contrib/openapi-schema-to-json-schema": "~3.2.0",
- "conventional-changelog-conventionalcommits": "^5.0.0"
- }
- },
- "node_modules/@asyncapi/generator/node_modules/@asyncapi/parser": {
- "version": "1.18.1",
- "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-1.18.1.tgz",
- "integrity": "sha512-7sU9DajLV+vA2vShTYmD5lbtbTY6TOcGxB4Z4IcpRp8x5pejOsN32iU05eIYCnuamsi5SMscFxoi6fIO2vPK3Q==",
- "dependencies": {
- "@apidevtools/json-schema-ref-parser": "^9.0.6",
- "@asyncapi/specs": "^4.1.1",
- "@fmvilas/pseudo-yaml-ast": "^0.3.1",
- "ajv": "^6.10.1",
- "js-yaml": "^3.13.1",
- "json-to-ast": "^2.1.0",
- "lodash.clonedeep": "^4.5.0",
- "node-fetch": "^2.6.0",
- "tiny-merge-patch": "^0.1.2"
- }
- },
- "node_modules/@asyncapi/generator/node_modules/@asyncapi/raml-dt-schema-parser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@asyncapi/raml-dt-schema-parser/-/raml-dt-schema-parser-2.0.1.tgz",
- "integrity": "sha512-R7i35IbVbvGyPNm3t5ToPDtYUwDtVjWF/oCgCVPK/wLpNQ0uVZX5Y0JFhO78VUHEep0NKuuI2CZh6oLz0ebMVQ==",
- "dependencies": {
- "js-yaml": "^3.13.1",
- "ramldt2jsonschema": "^1.1.0"
- }
- },
- "node_modules/@asyncapi/generator/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/@asyncapi/generator/node_modules/conventional-changelog-conventionalcommits": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz",
- "integrity": "sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==",
- "dependencies": {
- "compare-func": "^2.0.0",
- "lodash": "^4.17.15",
- "q": "^1.5.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@asyncapi/generator/node_modules/simple-git": {
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.17.0.tgz",
@@ -521,18 +450,20 @@
"link": true
},
"node_modules/@asyncapi/modelina": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@asyncapi/modelina/-/modelina-1.5.0.tgz",
- "integrity": "sha512-YFoVCqf9YgZ/1xd6tVtFfkNhWcXq9cTLiVqUB/e/Fso8DHAEqYxOkKHSO/ywlhvnWdg+D3OO8BDse9x8cOZL6Q==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@asyncapi/modelina/-/modelina-1.7.0.tgz",
+ "integrity": "sha512-fIZ2pQEMubPRdShKYiUB2SN0NcxUQxvr6NEgZ1sfqInkWnkXyPQgung6LMEL5fkVOHIUa5tYBg1w23MISHF5eg==",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.9",
"@apidevtools/swagger-parser": "^10.0.3",
+ "@asyncapi/avro-schema-parser": "^3.0.0",
+ "@asyncapi/openapi-schema-parser": "^3.0.0",
"@asyncapi/parser": "^2.0.0",
+ "@asyncapi/raml-dt-schema-parser": "^4.0.0",
"@swc/core": "^1.3.5",
"@swc/jest": "^0.2.23",
"alterschema": "^1.1.2",
"change-case": "^4.1.2",
- "conventional-changelog-conventionalcommits": "^5.0.0",
"openapi-types": "9.3.0",
"typescript-json-schema": "^0.53.0"
},
@@ -540,19 +471,6 @@
"node": ">=14"
}
},
- "node_modules/@asyncapi/modelina/node_modules/conventional-changelog-conventionalcommits": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz",
- "integrity": "sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==",
- "dependencies": {
- "compare-func": "^2.0.0",
- "lodash": "^4.17.15",
- "q": "^1.5.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@asyncapi/openapi-schema-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@asyncapi/openapi-schema-parser/-/openapi-schema-parser-3.0.0.tgz",
@@ -23817,20 +23735,19 @@
}
},
"@asyncapi/generator": {
- "version": "1.9.17",
- "resolved": "https://registry.npmjs.org/@asyncapi/generator/-/generator-1.9.17.tgz",
- "integrity": "sha512-VHtZn6f+2w0rqFS+0e7QxH7vkyZGbLkuFSNOGWfVGaQqkmtCHY70pYxpF5ojCvMrqAAQyKKKXvzjIfjCabDKhA==",
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@asyncapi/generator/-/generator-1.10.1.tgz",
+ "integrity": "sha512-jSAX1mQPr/tSUNgxvdfM8G5rwBqGMgTCaQW8hhBViWhjxakzCWD/uRV4V2Tj1d51qvT7Brnj6PEWEX1ytlFV1w==",
"requires": {
- "@asyncapi/avro-schema-parser": "^1.1.0",
+ "@asyncapi/avro-schema-parser": "^3.0.0",
"@asyncapi/generator-react-sdk": "^0.2.23",
- "@asyncapi/openapi-schema-parser": "^2.0.1",
- "@asyncapi/parser": "^1.18.0",
- "@asyncapi/raml-dt-schema-parser": "^2.0.1",
+ "@asyncapi/openapi-schema-parser": "^3.0.0",
+ "@asyncapi/parser": "^2.0.0",
+ "@asyncapi/raml-dt-schema-parser": "^4.0.0",
"@npmcli/arborist": "^2.2.4",
- "ajv": "^6.10.2",
+ "ajv": "^8.12.0",
"chokidar": "^3.4.0",
"commander": "^6.1.0",
- "conventional-changelog-conventionalcommits": "^5.0.0",
"filenamify": "^4.1.0",
"fs.extra": "^1.3.2",
"global-dirs": "^3.0.0",
@@ -23851,69 +23768,6 @@
"typescript": "^4.9.3"
},
"dependencies": {
- "@asyncapi/avro-schema-parser": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@asyncapi/avro-schema-parser/-/avro-schema-parser-1.1.0.tgz",
- "integrity": "sha512-7J7pzSw0/jF2bXy/Mf+80VKJfXRRfyLTJz413MkKLbLXbbz9rV4sVpYfp31ofqXgyZ9bhfmHJzunbi0Bt7Jcww==",
- "requires": {
- "avsc": "^5.7.3"
- }
- },
- "@asyncapi/openapi-schema-parser": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@asyncapi/openapi-schema-parser/-/openapi-schema-parser-2.0.3.tgz",
- "integrity": "sha512-o9fvibjx2n3L2SKNlWUQ59CxO2x2BKhbHxh81U39NMLgowN/avk1wfxkMvzL3G9pg4FlgCdcayDhu4+TzDX47A==",
- "requires": {
- "@openapi-contrib/openapi-schema-to-json-schema": "~3.2.0",
- "conventional-changelog-conventionalcommits": "^5.0.0"
- }
- },
- "@asyncapi/parser": {
- "version": "1.18.1",
- "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-1.18.1.tgz",
- "integrity": "sha512-7sU9DajLV+vA2vShTYmD5lbtbTY6TOcGxB4Z4IcpRp8x5pejOsN32iU05eIYCnuamsi5SMscFxoi6fIO2vPK3Q==",
- "requires": {
- "@apidevtools/json-schema-ref-parser": "^9.0.6",
- "@asyncapi/specs": "^4.1.1",
- "@fmvilas/pseudo-yaml-ast": "^0.3.1",
- "ajv": "^6.10.1",
- "js-yaml": "^3.13.1",
- "json-to-ast": "^2.1.0",
- "lodash.clonedeep": "^4.5.0",
- "node-fetch": "^2.6.0",
- "tiny-merge-patch": "^0.1.2"
- }
- },
- "@asyncapi/raml-dt-schema-parser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@asyncapi/raml-dt-schema-parser/-/raml-dt-schema-parser-2.0.1.tgz",
- "integrity": "sha512-R7i35IbVbvGyPNm3t5ToPDtYUwDtVjWF/oCgCVPK/wLpNQ0uVZX5Y0JFhO78VUHEep0NKuuI2CZh6oLz0ebMVQ==",
- "requires": {
- "js-yaml": "^3.13.1",
- "ramldt2jsonschema": "^1.1.0"
- }
- },
- "ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- }
- },
- "conventional-changelog-conventionalcommits": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz",
- "integrity": "sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==",
- "requires": {
- "compare-func": "^2.0.0",
- "lodash": "^4.17.15",
- "q": "^1.5.1"
- }
- },
"simple-git": {
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.17.0.tgz",
@@ -24026,32 +23880,22 @@
}
},
"@asyncapi/modelina": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@asyncapi/modelina/-/modelina-1.5.0.tgz",
- "integrity": "sha512-YFoVCqf9YgZ/1xd6tVtFfkNhWcXq9cTLiVqUB/e/Fso8DHAEqYxOkKHSO/ywlhvnWdg+D3OO8BDse9x8cOZL6Q==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@asyncapi/modelina/-/modelina-1.7.0.tgz",
+ "integrity": "sha512-fIZ2pQEMubPRdShKYiUB2SN0NcxUQxvr6NEgZ1sfqInkWnkXyPQgung6LMEL5fkVOHIUa5tYBg1w23MISHF5eg==",
"requires": {
"@apidevtools/json-schema-ref-parser": "^9.0.9",
"@apidevtools/swagger-parser": "^10.0.3",
+ "@asyncapi/avro-schema-parser": "^3.0.0",
+ "@asyncapi/openapi-schema-parser": "^3.0.0",
"@asyncapi/parser": "^2.0.0",
+ "@asyncapi/raml-dt-schema-parser": "^4.0.0",
"@swc/core": "^1.3.5",
"@swc/jest": "^0.2.23",
"alterschema": "^1.1.2",
"change-case": "^4.1.2",
- "conventional-changelog-conventionalcommits": "^5.0.0",
"openapi-types": "9.3.0",
"typescript-json-schema": "^0.53.0"
- },
- "dependencies": {
- "conventional-changelog-conventionalcommits": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz",
- "integrity": "sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==",
- "requires": {
- "compare-func": "^2.0.0",
- "lodash": "^4.17.15",
- "q": "^1.5.1"
- }
- }
}
},
"@asyncapi/openapi-schema-parser": {
diff --git a/package.json b/package.json
index 3c1d41c5626..043bb8867e3 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@asyncapi/cli",
"description": "All in one CLI for all AsyncAPI tools",
- "version": "0.40.6",
+ "version": "0.45.0",
"author": "@asyncapi",
"bin": {
"asyncapi": "./bin/run"
@@ -12,8 +12,8 @@
"@asyncapi/bundler": "^0.3.8",
"@asyncapi/converter": "^1.2.0",
"@asyncapi/diff": "^0.4.1",
- "@asyncapi/generator": "^1.9.17",
- "@asyncapi/modelina": "^1.5.0",
+ "@asyncapi/generator": "^1.10.1",
+ "@asyncapi/modelina": "^1.7.0",
"@asyncapi/openapi-schema-parser": "^3.0.0",
"@asyncapi/optimizer": "^0.1.18",
"@asyncapi/parser": "^2.0.0",
diff --git a/src/commands/config/versions.ts b/src/commands/config/versions.ts
new file mode 100644
index 00000000000..76ce1953328
--- /dev/null
+++ b/src/commands/config/versions.ts
@@ -0,0 +1,56 @@
+import { Flags } from '@oclif/core';
+import Command from '../../base';
+
+export default class Versions extends Command {
+ static description = 'Show versions of AsyncAPI tools used';
+
+ static flags = {
+ help: Flags.help({ char: 'h' }),
+ };
+
+ async run() {
+ const dependencies: string[] = [];
+ let dependency = '';
+
+ // Preparation of the array with all dependencies '@asyncapi/*' along with
+ // their versions.
+ for (const key in this.config.pjson.dependencies) {
+ // Making sure with .indexOf() that only package names which START with
+ // string '@asyncapi' are considered.
+ if (key.indexOf('@asyncapi', 0) === 0) {
+ // Avoiding obvious crash on manual removal or alteration of an
+ // '@asyncapi' package.
+ try {
+ // Goofy name `importedPJSON` is chosen to distinguish from name `pjson`
+ // used in `@oclif` source code.
+ const importedPJSON = await import(`${key}/package.json`);
+ dependencies.push(`${key}/${importedPJSON.default.version}`);
+ } catch (e) {
+ dependencies.push(`${key}/` + '`package.json` not found');
+ }
+ }
+ }
+
+ // Showing information available with `--version` flag.
+ this.log(this.config.userAgent);
+
+ // Iteration through the array containing all dependencies '@asyncapi/*'
+ // along with their versions.
+ for (let i = 0; i < dependencies.length; i++) {
+ // Minimization of the theoretical possibility of a Generic Object
+ // Injection Sink, at the same time disabling eslint parsing for this
+ // line since it is actually a false positive.
+ // https://github.com/eslint-community/eslint-plugin-security/issues/21#issuecomment-530184612
+ // https://github.com/eslint-community/eslint-plugin-security/issues/21#issuecomment-1157887653
+ // https://web.archive.org/web/20150430062816/https://blog.liftsecurity.io/2015/01/15/the-dangers-of-square-bracket-notation
+ dependency = dependencies[i]; // eslint-disable-line
+ if (i !== dependencies.length - 1) {
+ this.log(` ├${dependency}`);
+ } else {
+ this.log(` └${dependency}\n`);
+ }
+ }
+
+ this.log(`Repository: ${this.config.pjson.homepage}`);
+ }
+}
diff --git a/src/commands/generate/models.ts b/src/commands/generate/models.ts
index ffd33d44954..e77c704ee12 100644
--- a/src/commands/generate/models.ts
+++ b/src/commands/generate/models.ts
@@ -1,4 +1,4 @@
-import { CSharpFileGenerator, JavaFileGenerator, JavaScriptFileGenerator, TypeScriptFileGenerator, GoFileGenerator, Logger, DartFileGenerator, PythonFileGenerator, RustFileGenerator, TS_COMMON_PRESET, TS_JSONBINPACK_PRESET, CSHARP_DEFAULT_PRESET, KotlinFileGenerator, TS_DESCRIPTION_PRESET } from '@asyncapi/modelina';
+import { CSharpFileGenerator, JavaFileGenerator, JavaScriptFileGenerator, TypeScriptFileGenerator, GoFileGenerator, Logger, DartFileGenerator, PythonFileGenerator, RustFileGenerator, TS_COMMON_PRESET, TS_JSONBINPACK_PRESET, CSHARP_DEFAULT_PRESET, CSHARP_NEWTONSOFT_SERIALIZER_PRESET, CSHARP_COMMON_PRESET, CSHARP_JSON_SERIALIZER_PRESET, KotlinFileGenerator, TS_DESCRIPTION_PRESET, PhpFileGenerator, CplusplusFileGenerator } from '@asyncapi/modelina';
import { Flags } from '@oclif/core';
import Command from '../../base';
import { load } from '../../models/SpecificationFile';
@@ -15,7 +15,9 @@ enum Languages {
dart = 'dart',
python = 'python',
rust = 'rust',
- kotlin='kotlin'
+ kotlin='kotlin',
+ php='php',
+ cplusplus='cplusplus'
}
const possibleLanguageValues = Object.values(Languages).join(', ');
@@ -61,7 +63,7 @@ export default class Models extends Command {
description: 'TypeScript specific, define the module system to be used.',
required: false,
default: 'ESM',
-
+
}),
tsIncludeComments: Flags.boolean({
description: 'TypeScript specific, if enabled add comments while generating models.',
@@ -87,19 +89,28 @@ export default class Models extends Command {
description: 'Go, Java and Kotlin specific, define the package to use for the generated models. This is required when language is `go`, `java` or `kotlin`.',
required: false
}),
+
/**
- * C# specific options
+ * C++ and C# and PHP specific namespace to use for the generated models
*/
namespace: Flags.string({
- description: 'C# specific, define the namespace to use for the generated models. This is required when language is `csharp`.',
+ description: 'C#, C++ and PHP specific, define the namespace to use for the generated models. This is required when language is `csharp`,`c++` or `php`.',
required: false
}),
+ /**
+ * C# specific options
+ */
csharpAutoImplement: Flags.boolean({
description: 'C# specific, define whether to generate auto-implemented properties or not.',
required: false,
default: false
}),
+ csharpNewtonsoft: Flags.boolean({
+ description: 'C# specific, generate the models with newtonsoft serialization support',
+ required: false,
+ default: false
+ }),
csharpArrayType: Flags.string({
type: 'option',
description: 'C# specific, define which type of array needs to be generated.',
@@ -107,13 +118,28 @@ export default class Models extends Command {
required: false,
default: 'Array'
}),
+ csharpHashcode: Flags.boolean({
+ description: 'C# specific, generate the models with the GetHashCode method overwritten',
+ required: false,
+ default: false
+ }),
+ csharpEqual: Flags.boolean({
+ description: 'C# specific, generate the models with the Equal method overwritten',
+ required: false,
+ default: false
+ }),
+ csharpSystemJson: Flags.boolean({
+ description: 'C# specific, generate the models with System.Text.Json serialization support',
+ required: false,
+ default: false
+ }),
...validationFlags({ logDiagnostics: false }),
};
-
+
/* eslint-disable sonarjs/cognitive-complexity */
async run() {
const { args, flags } = await this.parse(Models);
- const { tsModelType, tsEnumType, tsIncludeComments, tsModuleSystem, tsExportType, tsJsonBinPack, namespace, csharpAutoImplement, csharpArrayType, packageName, output } = flags;
+ const { tsModelType, tsEnumType, tsIncludeComments, tsModuleSystem, tsExportType, tsJsonBinPack, namespace, csharpAutoImplement, csharpArrayType, csharpNewtonsoft, csharpHashcode, csharpEqual, csharpSystemJson, packageName, output } = flags;
const { language, file } = args;
const inputFile = (await load(file)) || (await load());
const { document, status } = await parse(this, inputFile, flags);
@@ -172,22 +198,47 @@ export default class Models extends Command {
throw new Error('In order to generate models to C#, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.');
}
- fileGenerator = new CSharpFileGenerator({
- presets: csharpAutoImplement ? [
- {
- preset: CSHARP_DEFAULT_PRESET,
- options: {
- autoImplementedProperties: true
- }
+ if (csharpAutoImplement) {
+ presets.push({
+ preset: CSHARP_DEFAULT_PRESET,
+ options: {
+ autoImplementedProperties: true
}
- ] : [],
+ });
+ }
+ if (csharpNewtonsoft) {
+ presets.push(CSHARP_NEWTONSOFT_SERIALIZER_PRESET);
+ }
+ if (csharpSystemJson) {
+ presets.push(CSHARP_JSON_SERIALIZER_PRESET);
+ }
+ if (csharpHashcode || csharpEqual) {
+ presets.push({
+ preset: CSHARP_COMMON_PRESET,
+ options: {
+ hashCode: csharpHashcode,
+ equals: csharpEqual
+ }
+ });
+ }
+
+ fileGenerator = new CSharpFileGenerator({
+ presets,
collectionType: csharpArrayType as 'Array' | 'List'
});
-
+
fileOptions = {
namespace
};
break;
+ case Languages.cplusplus:
+ if (namespace === undefined) {
+ throw new Error('In order to generate models to C++, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.');
+ }
+ fileGenerator = new CplusplusFileGenerator({
+ namespace
+ });
+ break;
case Languages.golang:
if (packageName === undefined) {
throw new Error('In order to generate models to Go, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.');
@@ -227,6 +278,15 @@ export default class Models extends Command {
packageName
};
break;
+ case Languages.php:
+ if (namespace === undefined) {
+ throw new Error('In order to generate models to PHP, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.');
+ }
+ fileGenerator = new PhpFileGenerator();
+ fileOptions = {
+ namespace
+ };
+ break;
default:
throw new Error(`Could not determine generator for language ${language}, are you using one of the following values ${possibleLanguageValues}?`);
}
diff --git a/test/commands/config/versions.test.ts b/test/commands/config/versions.test.ts
new file mode 100644
index 00000000000..cf385a4a75e
--- /dev/null
+++ b/test/commands/config/versions.test.ts
@@ -0,0 +1,27 @@
+import { test } from '@oclif/test';
+
+describe('versions', () => {
+ describe('config:versions', () => {
+ test
+ .stderr()
+ .stdout()
+ .command(['config:versions'])
+ .it('should show versions of AsyncAPI tools used', (ctx, done) => {
+ expect(ctx.stdout).toContain('@asyncapi/cli/');
+ expect(ctx.stdout).toContain('├@asyncapi/');
+ expect(ctx.stdout).toContain('└@asyncapi/');
+ expect(ctx.stderr).toEqual('');
+ done();
+ });
+
+ test
+ .stderr()
+ .stdout()
+ .command(['config:versions'])
+ .it('should show address of repository of AsyncAPI CLI', (ctx, done) => {
+ expect(ctx.stdout).toContain('https://github.com/asyncapi/cli');
+ expect(ctx.stderr).toEqual('');
+ done();
+ });
+ });
+});
diff --git a/test/commands/generate/models.test.ts b/test/commands/generate/models.test.ts
index 77f7329c8d2..911b9ed22b9 100644
--- a/test/commands/generate/models.test.ts
+++ b/test/commands/generate/models.test.ts
@@ -15,17 +15,16 @@ describe('models', () => {
expect(ctx.stdout).toMatchSnapshot();
done();
});
-
+
test
.stderr()
.stdout()
.command([...generalOptions, 'random', './test/specification.yml', `-o=${ path.resolve(outputDir, './random')}`])
.it('fails when it dont know the language', (ctx, done) => {
- expect(ctx.stderr).toEqual('Error: Expected random to be one of: typescript, csharp, golang, java, javascript, dart, python, rust, kotlin\nSee more help with --help\n');
+ expect(ctx.stderr).toEqual('Error: Expected random to be one of: typescript, csharp, golang, java, javascript, dart, python, rust, kotlin, php, cplusplus\nSee more help with --help\n');
expect(ctx.stdout).toEqual('');
done();
});
-
test
.stderr()
.stdout()
@@ -35,8 +34,8 @@ describe('models', () => {
expect(ctx.stdout).toMatchSnapshot();
done();
});
-
- describe('for TypeScript', () => {
+
+ describe('for TypeScript', () => {
test
.stderr()
.stdout()
@@ -70,7 +69,7 @@ describe('models', () => {
});
});
- describe('for JavaScript', () => {
+ describe('for JavaScript', () => {
test
.stderr()
.stdout()
@@ -84,7 +83,7 @@ describe('models', () => {
});
});
- describe('for Python', () => {
+ describe('for Python', () => {
test
.stderr()
.stdout()
@@ -98,7 +97,7 @@ describe('models', () => {
});
});
- describe('for Rust', () => {
+ describe('for Rust', () => {
test
.stderr()
.stdout()
@@ -147,7 +146,54 @@ describe('models', () => {
test
.stderr()
.stdout()
- .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`, '--namespace=\'asyncapi.models\'', '--csharpArrayType=List'])
+ .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`, '--namespace=\'asyncapi.models\'', '--csharpNewtonsoft'])
+ .it('works when newtonsoft flag is passed', (ctx, done) => {
+ expect(ctx.stderr).toEqual('');
+ expect(ctx.stdout).toContain(
+ 'Successfully generated the following models: '
+ );
+ done();
+ });
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`, '--namespace=\'asyncapi.models\'', '--csharpHashcode'])
+ .it('works when hash code flag is passed', (ctx, done) => {
+ expect(ctx.stderr).toEqual('');
+ expect(ctx.stdout).toContain(
+ 'Successfully generated the following models: '
+ );
+ done();
+ });
+
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`, '--namespace=\'asyncapi.models\'', '--csharpEqual'])
+ .it('works when equal flag is passed', (ctx, done) => {
+ expect(ctx.stderr).toEqual('');
+ expect(ctx.stdout).toContain(
+ 'Successfully generated the following models: '
+ );
+ done();
+ });
+
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`, '--namespace=\'asyncapi.models\'', '--csharpSystemJson'])
+ .it('works when system json flag is passed', (ctx, done) => {
+ expect(ctx.stderr).toEqual('');
+ expect(ctx.stdout).toContain(
+ 'Successfully generated the following models: '
+ );
+ done();
+ });
+
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`, '--namespace=\'asyncapi.models\'', '--csharpArrayType=List'])
.it('works when array type is provided', (ctx, done) => {
expect(ctx.stderr).toEqual('');
expect(ctx.stdout).toContain(
@@ -157,6 +203,29 @@ describe('models', () => {
});
});
+ describe('for C++', () => {
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'cplusplus', './test/specification.yml', `-o=${path.resolve(outputDir, './cplusplus')}`, '--namespace=\'AsyncapiModels\''])
+ .it('works when file path is passed', (ctx, done) => {
+ expect(ctx.stderr).toEqual('');
+ expect(ctx.stdout).toContain(
+ 'Successfully generated the following models: '
+ );
+ done();
+ });
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'cplusplus', './test/specification.yml', `-o=${ path.resolve(outputDir, './cplusplus')}`])
+ .it('fails when no namespace provided', (ctx, done) => {
+ expect(ctx.stderr).toEqual('Error: In order to generate models to C++, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.\n');
+ expect(ctx.stdout).toEqual('');
+ done();
+ });
+ });
+
describe('for Java', () => {
test
.stderr()
@@ -179,8 +248,8 @@ describe('models', () => {
done();
});
});
-
- describe('for Go', () => {
+
+ describe('for Go', () => {
test
.stderr()
.stdout()
@@ -203,7 +272,7 @@ describe('models', () => {
});
});
- describe('for Kotlin', () => {
+ describe('for Kotlin', () => {
test
.stderr()
.stdout()
@@ -226,7 +295,7 @@ describe('models', () => {
});
});
- describe('for Dart', () => {
+ describe('for Dart', () => {
test
.stderr()
.stdout()
@@ -249,6 +318,28 @@ describe('models', () => {
});
});
+ describe('for PHP', () => {
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'php', './test/specification.yml', `-o=${ path.resolve(outputDir, './php')}`, '--namespace=\'asyncapi.models\''])
+ .it('works when file path is passed', (ctx, done) => {
+ expect(ctx.stderr).toEqual('');
+ expect(ctx.stdout).toContain(
+ 'Successfully generated the following models: '
+ );
+ done();
+ });
+ test
+ .stderr()
+ .stdout()
+ .command([...generalOptions, 'php', './test/specification.yml', `-o=${ path.resolve(outputDir, './php')}`])
+ .it('fails when no namespace defined', (ctx, done) => {
+ expect(ctx.stderr).toEqual('Error: In order to generate models to PHP, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.\n');
+ expect(ctx.stdout).toEqual('');
+ done();
+ });
+ });
describe('with logging diagnostics', () => {
test
.stderr()