diff --git a/apps/generator/package.json b/apps/generator/package.json
index 40fb159dc..f53207bb3 100644
--- a/apps/generator/package.json
+++ b/apps/generator/package.json
@@ -49,7 +49,6 @@
"license": "Apache-2.0",
"homepage": "https://github.com/asyncapi/generator",
"dependencies": {
- "@asyncapi/generator-components": "*",
"@asyncapi/generator-react-sdk": "^1.1.2",
"@asyncapi/multi-parser": "^2.1.1",
"@asyncapi/nunjucks-filters": "*",
@@ -88,6 +87,7 @@
"jsdoc-to-markdown": "^7.1.1",
"markdown-toc": "^1.2.0",
"rimraf": "^3.0.2",
- "unixify": "^1.0.0"
+ "unixify": "^1.0.0",
+ "@asyncapi/generator-components": "*"
}
}
diff --git a/apps/generator/test/test-templates/react-template/template/models.js b/apps/generator/test/test-templates/react-template/template/models.js
index adad74d80..eddfc92d2 100644
--- a/apps/generator/test/test-templates/react-template/template/models.js
+++ b/apps/generator/test/test-templates/react-template/template/models.js
@@ -1,3 +1,4 @@
+//TODO: at the moment this template as devDependency set to "@asyncapi/generator-components": "*" in generator root but this is temporary to not complicate one PR too much. We still need to explore concept of having just one dependency in the template pointing to @asyncapi/generator and noting else, and components, react sdks and others should be just part of @asyncapi/generator dependency
import { Models } from '@asyncapi/generator-components';
export default async function({ asyncapi }) {
diff --git a/package-lock.json b/package-lock.json
index 6e7a4e466..cc1a04efa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "1.0.0",
"workspaces": [
"apps/*",
- "packages/*"
+ "packages/**"
],
"devDependencies": {
"markdown-toc": "^1.2.0",
@@ -22,6 +22,7 @@
"apps/components": {
"name": "@asyncapi/generator-components",
"version": "1.0.0",
+ "extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"@asyncapi/generator-react-sdk": "^1.1.2",
@@ -40,7 +41,6 @@
"version": "2.5.0",
"license": "Apache-2.0",
"dependencies": {
- "@asyncapi/generator-components": "*",
"@asyncapi/generator-hooks": "*",
"@asyncapi/generator-react-sdk": "^1.1.2",
"@asyncapi/multi-parser": "^2.1.1",
@@ -74,6 +74,7 @@
"asyncapi-generator": "cli.js"
},
"devDependencies": {
+ "@asyncapi/generator-components": "*",
"eslint": "^6.8.0",
"eslint-plugin-jest": "^23.8.2",
"eslint-plugin-react": "^7.34.1",
@@ -272,7 +273,7 @@
"link": true
},
"node_modules/@asyncapi/generator-components": {
- "resolved": "apps/components",
+ "resolved": "packages/components",
"link": true
},
"node_modules/@asyncapi/generator-hooks": {
@@ -542,6 +543,10 @@
"@types/json-schema": "^7.0.11"
}
},
+ "node_modules/@asyncapi/template-js-websocket-client": {
+ "resolved": "packages/templates/clients/js/websocket",
+ "link": true
+ },
"node_modules/@babel/cli": {
"version": "7.25.9",
"dev": true,
@@ -15715,6 +15720,40 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "packages/components": {
+ "name": "@asyncapi/generator-components",
+ "version": "1.0.0",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@asyncapi/generator-react-sdk": "^1.1.2",
+ "@asyncapi/modelina": "^4.0.0-next.62"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.25.9",
+ "@babel/core": "^7.26.0",
+ "@babel/preset-env": "^7.26.0",
+ "@babel/preset-react": "^7.25.9",
+ "jest-esm-transformer": "^1.0.0"
+ }
+ },
+ "packages/templates/clients/js/websocket": {
+ "name": "@asyncapi/template-js-websocket-client",
+ "version": "0.0.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@asyncapi/generator-react-sdk": "^1.1.2",
+ "@asyncapi/parser": "^3.0.14",
+ "rimraf": "^3.0.2"
+ },
+ "devDependencies": {
+ "@asyncapi/generator": "*",
+ "@babel/cli": "^7.25.9",
+ "@babel/core": "^7.26.0",
+ "@babel/preset-env": "^7.26.0",
+ "@babel/preset-react": "^7.25.9",
+ "jest-esm-transformer": "^1.0.0"
+ }
}
}
}
diff --git a/package.json b/package.json
index 5411d56f4..cf0e0c05a 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,6 @@
"build": "turbo build",
"dev": "turbo dev",
"test": "turbo run test",
- "test:update": "turbo run test:update",
"lint": "turbo lint",
"lint:fix": "turbo run lint:fix",
"generate:assets": "turbo run generate:assets && npm run generate:readme:toc",
@@ -25,7 +24,8 @@
"nunjucks-filters:test": "turbo run test --filter=@asyncapi/nunjucks-filters",
"components:test": "turbo run test --filter=@asyncapi/generator-components",
"components:build": "turbo run build --filter=@asyncapi/generator-components",
- "components:lint": "turbo run lint --filter=@asyncapi/generator-components"
+ "components:lint": "turbo run lint --filter=@asyncapi/generator-components",
+ "templates:test": "turbo run test --filter=@asyncapi/template*"
},
"devDependencies": {
"markdown-toc": "^1.2.0",
@@ -37,6 +37,6 @@
"packageManager": "npm@9.5.0",
"workspaces": [
"apps/*",
- "packages/*"
+ "packages/**"
]
}
diff --git a/packages/README.md b/packages/README.md
index dfdc89b19..ca7ecdfdc 100644
--- a/packages/README.md
+++ b/packages/README.md
@@ -21,12 +21,13 @@ This approach with templates developed as part of `generator` repository is a wo
3. `components` package should contain a set of reusable react components that could be shared between templates
4. `helpers` package should contain a set of reusable helpers. They would focus mainly on smart extract of info from AsyncAPI document using Parser API. Templates should avoid using AsyncAPI Parser API directly, but through well tested `helpers`
5. Each new template or new feature in existing template must be done with reusability in mind. Custom helpers and components should be limited to minimum
-6. Helpers need dedicated tests. Still to agree if we should base these on dummy AsyncAPI documents or just mock fake Parser objects inside tests.
+6. Helpers need dedicated tests. Still to agree if we should base these on dummy AsyncAPI documents or just mock fake Parser objects inside tests
7. Components should also be tested separately, expecially if they are reused across templates
8. Each template should have a set of snapshot tests that help understand if changes in the PR affect the output of the template
9. Every time new template feature is added it must be consulted with:
- Spec reference docs using [raw docs](https://www.asyncapi.com/docs/reference/specification/v3.0.0) or [visualizer](https://www.asyncapi.com/docs/reference/specification/v3.0.0-explorer)
- [Parser API](https://github.com/asyncapi/parser-api/blob/master/docs/api.md) to use it's capabilities instead of doing workarounds like for example `binding.json()["query"]["properties"]`
+10. Turporepo gives us a lot of control on tests running. We can for example have `templates:test` script that will run tests only for templates. So we can get very generic and also very granular on tests execution. This is needed in case we want to improve PR testing speed and for example, denending on what was changed in the PR scope, run only selected tests
//TODO: we still need to figure out how not only test output changes but also if the output will work with real service: contract testing with mocks. To evaluate Microcks and Specmatic
diff --git a/apps/components/.gitignore b/packages/components/.gitignore
similarity index 100%
rename from apps/components/.gitignore
rename to packages/components/.gitignore
diff --git a/apps/components/package.json b/packages/components/package.json
similarity index 95%
rename from apps/components/package.json
rename to packages/components/package.json
index 93f9cde35..03c030a51 100644
--- a/apps/components/package.json
+++ b/packages/components/package.json
@@ -3,8 +3,7 @@
"version": "1.0.0",
"description": "Package with reusable components for generation using React render engine",
"scripts": {
- "test": "jest --coverage",
- "test:update": "jest --coverage -u",
+ "test": "jest --coverage --updateSnapshot",
"build": "babel src --out-dir lib",
"prepublishOnly": "npm run build",
"lint": "eslint --max-warnings 0 --config ../../.eslintrc --ignore-path ../../.eslintignore .",
diff --git a/apps/components/src/components/models.js b/packages/components/src/components/models.js
similarity index 100%
rename from apps/components/src/components/models.js
rename to packages/components/src/components/models.js
diff --git a/apps/components/src/index.js b/packages/components/src/index.js
similarity index 100%
rename from apps/components/src/index.js
rename to packages/components/src/index.js
diff --git a/apps/components/test/__fixtures__/asyncapi-v3.yml b/packages/components/test/__fixtures__/asyncapi-v3.yml
similarity index 100%
rename from apps/components/test/__fixtures__/asyncapi-v3.yml
rename to packages/components/test/__fixtures__/asyncapi-v3.yml
diff --git a/apps/components/test/components/__snapshots__/models.test.js.snap b/packages/components/test/components/__snapshots__/models.test.js.snap
similarity index 100%
rename from apps/components/test/components/__snapshots__/models.test.js.snap
rename to packages/components/test/components/__snapshots__/models.test.js.snap
diff --git a/apps/components/test/components/models.test.js b/packages/components/test/components/models.test.js
similarity index 100%
rename from apps/components/test/components/models.test.js
rename to packages/components/test/components/models.test.js
diff --git a/packages/templates/clients/js/websocket/__transpiled/client.js.js b/packages/templates/clients/js/websocket/__transpiled/client.js.js
index 0b42382db..a3b24c13d 100644
--- a/packages/templates/clients/js/websocket/__transpiled/client.js.js
+++ b/packages/templates/clients/js/websocket/__transpiled/client.js.js
@@ -2,7 +2,7 @@
require('source-map-support/register');
var generatorReactSdk = require('@asyncapi/generator-react-sdk');
-var jsxRuntime = require('/Users/karinagornicka/Documents/GitHub/generator/packages/templates/clients/js/websocket/node_modules/react/cjs/react-jsx-runtime.production.min.js');
+var jsxRuntime = require('/Users/karinagornicka/Documents/GitHub/generator/node_modules/react/cjs/react-jsx-runtime.production.min.js');
/**
* Get client name from AsyncAPI info.title
@@ -81,6 +81,7 @@ function client_js ({
const server = asyncapi.servers().get(params.server);
const info = asyncapi.info();
const title = info.title();
+ //TODO at this moment this template shows usage of granular components and also generic Text component with lots of code but also not so nice to read. We need to figure the best way of handling this.
return /*#__PURE__*/jsxRuntime.jsxs(generatorReactSdk.File, {
name: params.clientFileName,
children: [/*#__PURE__*/jsxRuntime.jsx(FileHeaderInfo, {
diff --git a/packages/templates/clients/js/websocket/__transpiled/client.js.js.map b/packages/templates/clients/js/websocket/__transpiled/client.js.js.map
index b23e48c2f..22df034a0 100644
--- a/packages/templates/clients/js/websocket/__transpiled/client.js.js.map
+++ b/packages/templates/clients/js/websocket/__transpiled/client.js.js.map
@@ -1 +1 @@
-{"version":3,"file":"client.js.js","sources":["../helpers/utils.js","../helpers/servers.js","../components/FileHeaderInfo.js","../components/Requires.js","../template/client.js.js"],"sourcesContent":["/**\n * Get client name from AsyncAPI info.title\n *\n * @param {object} info - The AsyncAPI info object.\n * \n * return {string} - The client name with \"Client\" appended at the end.\n */\nfunction getClientName(info) {\n const title = info.title();\n \n // Remove spaces, make the first letter uppercase, and add \"Client\" at the end\n return `${title.replace(/\\s+/g, '') // Remove all spaces\n .replace(/^./, char => char.toUpperCase()) // Make the first letter uppercase\n }Client`;\n};\n\nexport { getClientName };\n ","/**\n * Get server URL from AsyncAPI server object.\n *\n * @param {object} server - The AsyncAPI server object.\n * \n * return {string} - The server URL.\n */\nfunction getServerUrl(server) {\n let url = server.host();\n\n //might be that somebody by mistake duplicated protocol info inside the host field\n //we need to make sure host do not hold protocol info\n if (server.protocol() && !url.includes(server.protocol())) {\n url = `${server.protocol()}://${url}`;\n }\n \n if (server.hasPathname()) {\n url = `${url}${server.pathname()}`;\n }\n \n return url;\n}\n\n//TODO: this separate file for helpers for servers represents approach to keep all helpers in separate files related to extractions of data from specific high level AsyncAPI objects. Here we will have more helpers for example related to variables extraction from servers, security, etc.\n \nexport { getServerUrl };\n ","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function FileHeaderInfo({ info, server }) {\n return (\n \n \n {'//////////////////////////////////////////////////////////////////////'}\n \n \n \n {'//'}\n \n\n \n {'//'} {info.title()} - {info.version()}\n \n\n \n {'//'} Protocol: {server.protocol()}\n \n\n \n {'//'} Host: {server.host()}\n \n\n {server.hasPathname() && (\n \n {'//'} Path: {server.pathname()}\n \n )}\n\n \n {'//'}\n \n\n \n {'//////////////////////////////////////////////////////////////////////'}\n \n \n );\n}","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function Requires() {\n return (\n \n \n const WebSocket = require('ws');\n \n \n );\n}\n\n","import { File, Text } from '@asyncapi/generator-react-sdk';\nimport { getClientName } from '../helpers/utils';\nimport { getServerUrl } from '../helpers/servers';\nimport { FileHeaderInfo } from '../components/FileHeaderInfo';\nimport { Requires } from '../components/Requires';\n\nexport default function({ asyncapi, params }) {\n const server = asyncapi.servers().get(params.server);\n const info = asyncapi.info();\n const title = info.title();\n\n return (\n \n \n \n \n {`class ${getClientName(info)} {\n constructor() {\n this.url = '${getServerUrl(server)}';\n this.websocket = null;\n this.messageHandlers = [];\n this.errorHandlers = [];\n }\n\n // Method to establish a WebSocket connection\n connect() {\n return new Promise((resolve, reject) => {\n this.websocket = new WebSocket(this.url);\n\n // On successful connection\n this.websocket.onopen = () => {\n console.log('Connected to ${title} server');\n resolve();\n };\n\n // On receiving a message\n this.websocket.onmessage = (event) => {\n console.log('Message received:', event.data);\n\n this.messageHandlers.forEach(handler => {\n if (typeof handler === 'function') {\n this.handleMessage(event.data, handler);\n }\n });\n };\n\n // On error first call custom error handlers, then default error behavior\n this.websocket.onerror = (error) => {\n if (this.errorHandlers.length > 0) {\n // Call custom error handlers\n this.errorHandlers.forEach(handler => handler(error));\n } else {\n // Default error behavior\n console.error('WebSocket Error:', error);\n }\n reject(error);\n };\n\n // On connection close\n this.websocket.onclose = () => {\n console.log('Disconnected from ${title} server');\n };\n });\n }\n\n // Method to register custom error handlers\n registerMessageHandler(handler) {\n if (typeof handler === 'function') {\n this.messageHandlers.push(handler);\n } else {\n console.warn('Message handler must be a function');\n }\n }\n\n // Method to register custom error handlers\n registerErrorHandler(handler) {\n if (typeof handler === 'function') {\n this.errorHandlers.push(handler);\n } else {\n console.warn('Error handler must be a function');\n }\n }\n\n // Method to handle message with callback\n handleMessage(message, cb) {\n if (cb) cb(message);\n }\n\n // Method to send an echo message to the server\n sendEchoMessage(message) {\n this.websocket.send(JSON.stringify(message));\n console.log('Sent message to echo server:', message);\n }\n\n // Method to close the WebSocket connection\n close() {\n if (this.websocket) {\n this.websocket.close();\n console.log('WebSocket connection closed.');\n }\n }\n}\n\nmodule.exports = ${getClientName(info)};`}\n \n );\n}"],"names":["getClientName","info","title","replace","char","toUpperCase","getServerUrl","server","url","host","protocol","includes","hasPathname","pathname","FileHeaderInfo","_jsxs","Text","children","_jsx","version","Requires","asyncapi","params","servers","get","File","name","clientFileName"],"mappings":"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AA,QAAA,EACF,CAAA,MAAA,EAASjB,aAAa,CAACC,IAAI,CAAC,CAAA;AACrC;AACA,gBAAkBK,EAAAA,YAAY,CAACC,MAAM,CAAC,CAAA;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAA,EAAoCL,KAAK,CAAA;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAA,EAAyCA,KAAK,CAAA;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAmBF,EAAAA,aAAa,CAACC,IAAI,CAAC,CAAA,CAAA,CAAA;AAAG,KAC7B,CAAC,CAAA;AAAA,GACH,CAAC,CAAA;AACX;;;;"}
\ No newline at end of file
+{"version":3,"file":"client.js.js","sources":["../helpers/utils.js","../helpers/servers.js","../components/FileHeaderInfo.js","../components/Requires.js","../template/client.js.js"],"sourcesContent":["/**\n * Get client name from AsyncAPI info.title\n *\n * @param {object} info - The AsyncAPI info object.\n * \n * return {string} - The client name with \"Client\" appended at the end.\n */\nfunction getClientName(info) {\n const title = info.title();\n \n // Remove spaces, make the first letter uppercase, and add \"Client\" at the end\n return `${title.replace(/\\s+/g, '') // Remove all spaces\n .replace(/^./, char => char.toUpperCase()) // Make the first letter uppercase\n }Client`;\n};\n\nexport { getClientName };\n ","/**\n * Get server URL from AsyncAPI server object.\n *\n * @param {object} server - The AsyncAPI server object.\n * \n * return {string} - The server URL.\n */\nfunction getServerUrl(server) {\n let url = server.host();\n\n //might be that somebody by mistake duplicated protocol info inside the host field\n //we need to make sure host do not hold protocol info\n if (server.protocol() && !url.includes(server.protocol())) {\n url = `${server.protocol()}://${url}`;\n }\n \n if (server.hasPathname()) {\n url = `${url}${server.pathname()}`;\n }\n \n return url;\n}\n\n//TODO: this separate file for helpers for servers represents approach to keep all helpers in separate files related to extractions of data from specific high level AsyncAPI objects. Here we will have more helpers for example related to variables extraction from servers, security, etc.\n \nexport { getServerUrl };\n ","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function FileHeaderInfo({ info, server }) {\n return (\n \n \n {'//////////////////////////////////////////////////////////////////////'}\n \n \n \n {'//'}\n \n\n \n {'//'} {info.title()} - {info.version()}\n \n\n \n {'//'} Protocol: {server.protocol()}\n \n\n \n {'//'} Host: {server.host()}\n \n\n {server.hasPathname() && (\n \n {'//'} Path: {server.pathname()}\n \n )}\n\n \n {'//'}\n \n\n \n {'//////////////////////////////////////////////////////////////////////'}\n \n \n );\n}","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function Requires() {\n return (\n \n \n const WebSocket = require('ws');\n \n \n );\n}\n\n","import { File, Text } from '@asyncapi/generator-react-sdk';\nimport { getClientName } from '../helpers/utils';\nimport { getServerUrl } from '../helpers/servers';\nimport { FileHeaderInfo } from '../components/FileHeaderInfo';\nimport { Requires } from '../components/Requires';\n\nexport default function({ asyncapi, params }) {\n const server = asyncapi.servers().get(params.server);\n const info = asyncapi.info();\n const title = info.title();\n //TODO at this moment this template shows usage of granular components and also generic Text component with lots of code but also not so nice to read. We need to figure the best way of handling this.\n return (\n \n \n \n \n {`class ${getClientName(info)} {\n constructor() {\n this.url = '${getServerUrl(server)}';\n this.websocket = null;\n this.messageHandlers = [];\n this.errorHandlers = [];\n }\n\n // Method to establish a WebSocket connection\n connect() {\n return new Promise((resolve, reject) => {\n this.websocket = new WebSocket(this.url);\n\n // On successful connection\n this.websocket.onopen = () => {\n console.log('Connected to ${title} server');\n resolve();\n };\n\n // On receiving a message\n this.websocket.onmessage = (event) => {\n console.log('Message received:', event.data);\n\n this.messageHandlers.forEach(handler => {\n if (typeof handler === 'function') {\n this.handleMessage(event.data, handler);\n }\n });\n };\n\n // On error first call custom error handlers, then default error behavior\n this.websocket.onerror = (error) => {\n if (this.errorHandlers.length > 0) {\n // Call custom error handlers\n this.errorHandlers.forEach(handler => handler(error));\n } else {\n // Default error behavior\n console.error('WebSocket Error:', error);\n }\n reject(error);\n };\n\n // On connection close\n this.websocket.onclose = () => {\n console.log('Disconnected from ${title} server');\n };\n });\n }\n\n // Method to register custom error handlers\n registerMessageHandler(handler) {\n if (typeof handler === 'function') {\n this.messageHandlers.push(handler);\n } else {\n console.warn('Message handler must be a function');\n }\n }\n\n // Method to register custom error handlers\n registerErrorHandler(handler) {\n if (typeof handler === 'function') {\n this.errorHandlers.push(handler);\n } else {\n console.warn('Error handler must be a function');\n }\n }\n\n // Method to handle message with callback\n handleMessage(message, cb) {\n if (cb) cb(message);\n }\n\n // Method to send an echo message to the server\n sendEchoMessage(message) {\n this.websocket.send(JSON.stringify(message));\n console.log('Sent message to echo server:', message);\n }\n\n // Method to close the WebSocket connection\n close() {\n if (this.websocket) {\n this.websocket.close();\n console.log('WebSocket connection closed.');\n }\n }\n}\n\nmodule.exports = ${getClientName(info)};`}\n \n );\n}"],"names":["getClientName","info","title","replace","char","toUpperCase","getServerUrl","server","url","host","protocol","includes","hasPathname","pathname","FileHeaderInfo","_jsxs","Text","children","_jsx","version","Requires","asyncapi","params","servers","get","File","name","clientFileName"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,aAAaA,CAACC,IAAI,EAAE;AAC3B,EAAA,MAAMC,KAAK,GAAGD,IAAI,CAACC,KAAK,EAAE,CAAA;;AAE1B;EACA,OAAO,CAAA,EAAGA,KAAK,CAACC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;AAAC,GACjCA,OAAO,CAAC,IAAI,EAAEC,IAAI,IAAIA,IAAI,CAACC,WAAW,EAAE,CAAC;GACpC,MAAA,CAAA,CAAA;AACV;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,YAAYA,CAACC,MAAM,EAAE;AAC5B,EAAA,IAAIC,GAAG,GAAGD,MAAM,CAACE,IAAI,EAAE,CAAA;;AAEvB;AACA;AACA,EAAA,IAAIF,MAAM,CAACG,QAAQ,EAAE,IAAI,CAACF,GAAG,CAACG,QAAQ,CAACJ,MAAM,CAACG,QAAQ,EAAE,CAAC,EAAE;IACzDF,GAAG,GAAG,GAAGD,MAAM,CAACG,QAAQ,EAAE,CAAMF,GAAAA,EAAAA,GAAG,CAAE,CAAA,CAAA;AACvC,GAAA;AAEA,EAAA,IAAID,MAAM,CAACK,WAAW,EAAE,EAAE;IACxBJ,GAAG,GAAG,GAAGA,GAAG,CAAA,EAAGD,MAAM,CAACM,QAAQ,EAAE,CAAE,CAAA,CAAA;AACpC,GAAA;AAEA,EAAA,OAAOL,GAAG,CAAA;AACZ;;ACnBO,SAASM,cAAcA,CAAC;EAAEb,IAAI;AAAEM,EAAAA,MAAAA;AAAO,CAAC,EAAE;EAC/C,oBACEQ,eAAA,CAACC,sBAAI,EAAA;IAAAC,QAAA,EAAA,cACHC,cAAA,CAACF,sBAAI,EAAA;AAAAC,MAAAA,QAAA,EACF,wEAAA;AAAwE,KACrE,CAAC,eAEPC,cAAA,CAACF,sBAAI,EAAA;AAAAC,MAAAA,QAAA,EACF,IAAA;AAAI,KACD,CAAC,eAEPF,eAAA,CAACC,sBAAI,EAAA;AAAAC,MAAAA,QAAA,GACF,IAAI,EAAC,GAAC,EAAChB,IAAI,CAACC,KAAK,EAAE,EAAC,KAAG,EAACD,IAAI,CAACkB,OAAO,EAAE,CAAA;AAAA,KACnC,CAAC,eAEPJ,eAAA,CAACC,sBAAI,EAAA;MAAAC,QAAA,EAAA,CACF,IAAI,EAAC,aAAW,EAACV,MAAM,CAACG,QAAQ,EAAE,CAAA;AAAA,KAC/B,CAAC,eAEPK,eAAA,CAACC,sBAAI,EAAA;MAAAC,QAAA,EAAA,CACF,IAAI,EAAC,SAAO,EAACV,MAAM,CAACE,IAAI,EAAE,CAAA;KACvB,CAAC,EAENF,MAAM,CAACK,WAAW,EAAE,iBACnBG,eAAA,CAACC,sBAAI,EAAA;MAAAC,QAAA,EAAA,CACF,IAAI,EAAC,SAAO,EAACV,MAAM,CAACM,QAAQ,EAAE,CAAA;AAAA,KAC3B,CACP,eAEDK,cAAA,CAACF,sBAAI,EAAA;AAAAC,MAAAA,QAAA,EACF,IAAA;AAAI,KACD,CAAC,eAEPC,cAAA,CAACF,sBAAI,EAAA;AAAAC,MAAAA,QAAA,EACF,wEAAA;AAAwE,KACrE,CAAC,CAAA;AAAA,GACH,CAAC,CAAA;AAEX;;ACtCO,SAASG,QAAQA,GAAG;EACzB,oBACEF,cAAA,CAACF,sBAAI,EAAA;IAAAC,QAAA,eACHC,cAAA,CAACF,sBAAI,EAAA;AAAAC,MAAAA,QAAA,EAAC,kCAAA;KAEA,CAAA;AAAC,GACH,CAAC,CAAA;AAEX;;ACJe,kBAAS,EAAA;EAAEI,QAAQ;AAAEC,EAAAA,MAAAA;AAAO,CAAC,EAAE;AAC5C,EAAA,MAAMf,MAAM,GAAGc,QAAQ,CAACE,OAAO,EAAE,CAACC,GAAG,CAACF,MAAM,CAACf,MAAM,CAAC,CAAA;AACpD,EAAA,MAAMN,IAAI,GAAGoB,QAAQ,CAACpB,IAAI,EAAE,CAAA;AAC5B,EAAA,MAAMC,KAAK,GAAGD,IAAI,CAACC,KAAK,EAAE,CAAA;AAC1B;EACA,oBACEa,eAAA,CAACU,sBAAI,EAAA;IAACC,IAAI,EAAEJ,MAAM,CAACK,cAAe;IAAAV,QAAA,EAAA,cAChCC,cAAA,CAACJ,cAAc,EAAA;AACbb,MAAAA,IAAI,EAAEA,IAAK;AACXM,MAAAA,MAAM,EAAEA,MAAAA;KACT,CAAC,eACFW,cAAA,CAACE,QAAQ,IAAC,CAAC,eACXF,cAAA,CAACF,sBAAI,EAAA;AAAAC,MAAAA,QAAA,EACF,CAAA,MAAA,EAASjB,aAAa,CAACC,IAAI,CAAC,CAAA;AACrC;AACA,gBAAkBK,EAAAA,YAAY,CAACC,MAAM,CAAC,CAAA;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAA,EAAoCL,KAAK,CAAA;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAA,EAAyCA,KAAK,CAAA;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAmBF,EAAAA,aAAa,CAACC,IAAI,CAAC,CAAA,CAAA,CAAA;AAAG,KAC7B,CAAC,CAAA;AAAA,GACH,CAAC,CAAA;AACX;;;;"}
\ No newline at end of file
diff --git a/packages/templates/clients/js/websocket/package.json b/packages/templates/clients/js/websocket/package.json
index 828ebe855..b5a1de8a0 100644
--- a/packages/templates/clients/js/websocket/package.json
+++ b/packages/templates/clients/js/websocket/package.json
@@ -1,7 +1,7 @@
{
- "name": "js-websocket-client",
+ "name": "@asyncapi/template-js-websocket-client",
"version": "0.0.1",
- "description": "This is a template generating JavaScript client",
+ "description": "This is a template generating JavaScript websocket client",
"scripts": {
"test": "npm run test:cleanup && jest --updateSnapshot",
"test:cleanup": "rimraf \"tests/temp\""