Repository: asyncapi/generator
Pull request #1513: refactor: improve `getClientName` helper
Author: login: Adi-204
Labels: name: ready-to-merge
Created: 2025-04-23T06:11:53Z | Merged: 2025-04-28T13:48:11Z

**Description**
improve `getClientName` helper by adding 2 new params in template generation process.
1. appendClientSuffix - Add Client at the end of the class name
2. customClientName - The custom name for the generated client class

**Related issue(s)**
Fixes - #1510

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added options to customize the generated client class name for WebSocket clients in JavaScript, Python, and Dart templates, allowing specification of a custom client name or control over appending the "Client" suffix.
  - Updated example projects and documentation to reflect Hoppscotch as the default echo service client, with instructions for switching to Postman.
- **Bug Fixes**
  - Enhanced test coverage to validate the new client naming options and ensure correct client name generation across different configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/packages/helpers/src/utils.js b/packages/helpers/src/utils.js
index 49c48ace78..c7db8eb055 100644
--- a/packages/helpers/src/utils.js
+++ b/packages/helpers/src/utils.js
@@ -1,16 +1,19 @@
 /**
- * Get client name from AsyncAPI info.title
+ * Get client name from AsyncAPI info.title or uses a custom name if provided.
  *
  * @param {object} info - The AsyncAPI info object.
+ * @param {boolean} appendClientSuffix - Whether to append "Client" to the generated name
+ * @param {string} [customClientName] - Optional custom client name to use instead of generating from title
  * 
- * return {string} - The client name with "Client" appended at the end.
+ * @returns {string} The formatted client name, either the custom name or a generated name based on the title
  */
-module.exports.getClientName = (info) => {
+module.exports.getClientName = (info, appendClientSuffix, customClientName) => {
+  if (customClientName) {
+    return customClientName;
+  }
   const title = info.title();
-  
-  // Remove spaces, make the first letter uppercase, and add "Client" at the end
-  return `${title.replace(/\s+/g, '') // Remove all spaces
-    .replace(/^./, char => char.toUpperCase()) // Make the first letter uppercase
-  }Client`;
+  const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
+    .replace(/^./, char => char.toUpperCase())}`; // Make the first letter uppercase
+  return appendClientSuffix ? `${baseName}Client` : baseName;
 };
   
\ No newline at end of file
diff --git a/packages/helpers/test/utils.test.js b/packages/helpers/test/utils.test.js
index f9aff7a9fc..110c13501f 100644
--- a/packages/helpers/test/utils.test.js
+++ b/packages/helpers/test/utils.test.js
@@ -13,12 +13,36 @@ describe('getClientName integration test with AsyncAPI', () => {
     parsedAsyncAPIDocument = parseResult.document;
   });
 
-  it('should generate correct client name for the provided AsyncAPI info object', () => {
+  it('should generate correct client name for the provided AsyncAPI info object without appendClientSuffix', () => {
     const info = parsedAsyncAPIDocument.info();
+    const appendClientSuffix = false;
+    const customClientName = '';
 
-    const clientName = getClientName(info);
+    const clientName = getClientName(info, appendClientSuffix, customClientName);
+
+    // Example assertion: Check if the name is formatted correctly
+    expect(clientName).toBe('GeminiMarketDataWebsocketAPI');
+  });
+
+  it('should generate correct client name for the provided AsyncAPI info object with appendClientSuffix', () => {
+    const info = parsedAsyncAPIDocument.info();
+    const appendClientSuffix = true;
+    const customClientName = '';
+
+    const clientName = getClientName(info, appendClientSuffix, customClientName);
 
     // Example assertion: Check if the name is formatted correctly
     expect(clientName).toBe('GeminiMarketDataWebsocketAPIClient');
   });
+
+  it('should return customClientName', () => {
+    const info = parsedAsyncAPIDocument.info();
+    const appendClientSuffix = false;
+    const customClientName = 'GeminiClient';
+
+    const clientName = getClientName(info, appendClientSuffix, customClientName);
+
+    // Example assertion: Check if the name is formatted correctly
+    expect(clientName).toBe(customClientName);
+  });
 });
\ No newline at end of file
diff --git a/packages/templates/clients/websocket/dart/README.md b/packages/templates/clients/websocket/dart/README.md
index 81ba846034..d359ffa2c3 100644
--- a/packages/templates/clients/websocket/dart/README.md
+++ b/packages/templates/clients/websocket/dart/README.md
@@ -4,8 +4,8 @@ You can test this template:
 1. Clone the project and run `npm install`
 2. Navigate to `packages/templates/clients/websocket/dart`
 3. Install with `npm install` and run test with `npm run test`
-4. Navigate to the generated Postman client folder with `cd test/temp/snapshotTestResult/client_postman`
+4. Navigate to the generated Hoppscotch client folder with `cd test/temp/snapshotTestResult/custom_client_hoppscotch`
 5. Install dependencies of the generated client: `dart pub get`
 6. Start an example script that uses a client library generated by the test: `dart run --packages=.dart_tool/package_config.json ../../../../example.dart`
 
-> By default, this is testing against Postman Echo service. You can modify `packages/templates/clients/websocket/dart/example.dart` and change first line to `import 'test/temp/snapshotTestResult/client_hoppscotch/client.dart';` and line 15 `final wsClient = HoppscotchEchoWebSocketClient();` and run `dart run --packages=.dart_tool/package_config.json ../../../../example.dart` again. You will see the example still works but against a different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default, this is testing against Hoppscotch Echo service. You can modify `packages/templates/clients/websocket/dart/example.dart` and change first line to `import 'test/temp/snapshotTestResult/client_postman/client.dart';` and line 15 `final wsClient = PostmanEchoWebSocketClientClient();` and run `dart run --packages=.dart_tool/package_config.json ../../../../example.dart` again. You will see the example still works but against a different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
diff --git a/packages/templates/clients/websocket/dart/example.dart b/packages/templates/clients/websocket/dart/example.dart
index 754944ec8f..0a72020643 100644
--- a/packages/templates/clients/websocket/dart/example.dart
+++ b/packages/templates/clients/websocket/dart/example.dart
@@ -1,5 +1,5 @@
 import 'dart:async';
-import 'test/temp/snapshotTestResult/client_postman/client.dart';
+import 'test/temp/snapshotTestResult/custom_client_hoppscotch/client.dart';
 
 void myHandler(String message) {
   print('====================');
@@ -12,7 +12,7 @@ void myErrorHandler(Object error) {
 }
 
 Future<void> main() async {
-  final wsClient = PostmanEchoWebSocketClientClient();
+  final wsClient = HoppscotchClient();
   wsClient.registerMessageHandler(myHandler);
   wsClient.registerErrorHandler(myErrorHandler);
 
diff --git a/packages/templates/clients/websocket/dart/package.json b/packages/templates/clients/websocket/dart/package.json
index 310b3b3941..7449fa771c 100644
--- a/packages/templates/clients/websocket/dart/package.json
+++ b/packages/templates/clients/websocket/dart/package.json
@@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.dart"
+      },
+      "appendClientSuffix": {
+        "description": "Add 'Client' suffix at the end of the class name. This option has no effect if 'customClientName' is specified.",
+        "required": false,
+        "default": false
+      },
+      "customClientName": {
+        "description": "The custom name for the generated client class",
+        "required": false
       }
     }
   }
diff --git a/packages/templates/clients/websocket/dart/template/client.dart.js b/packages/templates/clients/websocket/dart/template/client.dart.js
index c4c29a8b0c..baca15eaf5 100644
--- a/packages/templates/clients/websocket/dart/template/client.dart.js
+++ b/packages/templates/clients/websocket/dart/template/client.dart.js
@@ -8,7 +8,7 @@ export default function ({ asyncapi, params }) {
   const server = getServer(asyncapi.servers(), params.server);
   const info = asyncapi.info();
   const title = info.title();
-  const clientName = getClientName(info);
+  const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
   const serverUrl = getServerUrl(server);
   return (  
     // The clientFileName default values can be found and modified under the package.json
diff --git a/packages/templates/clients/websocket/dart/test/__snapshots__/integration.test.js.snap b/packages/templates/clients/websocket/dart/test/__snapshots__/integration.test.js.snap
index c358a7db4c..763fb85ffc 100644
--- a/packages/templates/clients/websocket/dart/test/__snapshots__/integration.test.js.snap
+++ b/packages/templates/clients/websocket/dart/test/__snapshots__/integration.test.js.snap
@@ -1,5 +1,119 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`testing if generated client match snapshot generate simple client for hoppscotch echo with custom client name: client.dart 1`] = `
+"//////////////////////////////////////////////////////////////////////
+///
+/// Hoppscotch Echo WebSocket Client - 1.0.0
+/// Protocol: wss
+/// Host: echo-websocket.hoppscotch.io
+///
+//////////////////////////////////////////////////////////////////////
+
+import 'dart:convert';
+import 'package:web_socket_channel/web_socket_channel.dart';
+
+class HoppscotchClient {
+
+  final String _url;
+  WebSocketChannel? _channel;
+  final List<void Function(String)> _messageHandlers = [];
+  final List<void Function(Object)> _errorHandlers = [];
+
+  /// Constructor to initialize the WebSocket client
+  /// 
+  /// [url] - The WebSocket server URL. Use it if the server URL is different from the default one taken from the AsyncAPI document.
+  HoppscotchClient({String? url})
+    : _url = url ?? 'wss://echo-websocket.hoppscotch.io';
+
+
+  /// Method to establish a WebSocket connection
+  Future<void> connect() async {
+    if (_channel != null) {
+      print('Already connected to Hoppscotch Echo WebSocket Client server');
+      return;
+    }
+    try {
+      final wsUrl = Uri.parse(_url);
+      _channel = WebSocketChannel.connect(wsUrl);
+      print('Connected to Hoppscotch Echo WebSocket Client server');
+
+        /// Listen to the incoming message stream
+      _channel?.stream.listen(
+        (message) {
+          if (_messageHandlers.isNotEmpty) {
+            for (var handler in _messageHandlers) {
+              _handleMessage(message, handler);
+            }
+          } else {
+            print('Message received: $message');
+          }
+        },
+        onError: (error) {
+          if (_errorHandlers.isNotEmpty) {
+            for (var handler in _errorHandlers) {
+              handler(error);
+            }
+          } else {
+            print('WebSocket Error: $error');
+          }
+        },
+        onDone: () {
+          _channel = null;
+          print('Disconnected from Hoppscotch Echo WebSocket Client server');
+        },
+      );
+    } catch (error) {
+      print('Connection failed: $error');
+      rethrow;
+    }
+  }
+
+  /// Method to register custom message handlers
+  void registerMessageHandler(void Function(String) handler) {
+    _messageHandlers.add(handler);
+  }
+
+  /// Method to register custom error handlers
+  void registerErrorHandler(void Function(Object) handler) {
+    _errorHandlers.add(handler);
+  }
+
+  /// Method to handle message with callback
+  void _handleMessage(dynamic message, void Function(String) cb) {
+    cb(message is String ? message : message.toString());
+  }
+
+  /// Method to send an echo message to the server
+  void sendEchoMessage(dynamic message) {
+    if (_channel == null) {
+      print('Error: WebSocket is not connected.');
+      return;
+    }
+    final payload = message is String ? message : jsonEncode(message);
+    _channel!.sink.add(payload);
+    print('Sent message to echo server: $payload');
+  }
+
+  /// Method to close the WebSocket connection
+  void close() {
+    _channel?.sink.close();
+    _channel = null;
+    print('WebSocket connection closed.');
+  }
+}
+
+"
+`;
+
+exports[`testing if generated client match snapshot generate simple client for hoppscotch echo with custom client name: pubspec.yaml 1`] = `
+"name: wsclient
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+dependencies:
+  web_socket_channel: ^3.0.2
+"
+`;
+
 exports[`testing if generated client match snapshot generate simple client for hoppscotch echo: client.dart 1`] = `
 "//////////////////////////////////////////////////////////////////////
 ///
@@ -12,7 +126,7 @@ exports[`testing if generated client match snapshot generate simple client for h
 import 'dart:convert';
 import 'package:web_socket_channel/web_socket_channel.dart';
 
-class HoppscotchEchoWebSocketClientClient {
+class HoppscotchEchoWebSocketClient {
 
   final String _url;
   WebSocketChannel? _channel;
@@ -22,7 +136,7 @@ class HoppscotchEchoWebSocketClientClient {
   /// Constructor to initialize the WebSocket client
   /// 
   /// [url] - The WebSocket server URL. Use it if the server URL is different from the default one taken from the AsyncAPI document.
-  HoppscotchEchoWebSocketClientClient({String? url})
+  HoppscotchEchoWebSocketClient({String? url})
     : _url = url ?? 'wss://echo-websocket.hoppscotch.io';
 
 
diff --git a/packages/templates/clients/websocket/dart/test/integration.test.js b/packages/templates/clients/websocket/dart/test/integration.test.js
index f0256e3327..dfbd284ef0 100644
--- a/packages/templates/clients/websocket/dart/test/integration.test.js
+++ b/packages/templates/clients/websocket/dart/test/integration.test.js
@@ -10,19 +10,21 @@ const asyncapi_v3_path_hoppscotch = path.resolve(__dirname, '../../test/__fixtur
 const testResultPath = path.resolve(__dirname, './temp/snapshotTestResult');
 const testResultPathPostman = path.join(testResultPath, 'client_postman');
 const testResultPathHoppscotch = path.join(testResultPath, 'client_hoppscotch');
+const testResultPathCustomHoppscotch = path.join(testResultPath, 'custom_client_hoppscotch');
 const template = path.resolve(__dirname, '../');
 
+const testOutputFiles = ['client.dart', 'pubspec.yaml'];
+
 describe('testing if generated client match snapshot', () => {
   jest.setTimeout(100000);
-  
-  it('generate simple client for postman echo', async () => {
-    const testOutputFiles = ['client.dart', 'pubspec.yaml'];
 
+  it('generate simple client for postman echo', async () => {
     const generator = new Generator(template, testResultPathPostman, {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFiles[0]
+        clientFileName: testOutputFiles[0],
+        appendClientSuffix: true
       }
     });
 
@@ -37,8 +39,6 @@ describe('testing if generated client match snapshot', () => {
   });
 
   it('generate simple client for hoppscotch echo', async () => {
-    const testOutputFiles = ['client.dart', 'pubspec.yaml'];
-
     const generator = new Generator(template, testResultPathHoppscotch, {
       forceWrite: true,
       templateParams: {
@@ -56,4 +56,23 @@ describe('testing if generated client match snapshot', () => {
       expect(content).toMatchSnapshot(testOutputFile);
     }
   });
+
+  it('generate simple client for hoppscotch echo with custom client name', async () => {
+    const generator = new Generator(template, testResultPathCustomHoppscotch, {
+      forceWrite: true,
+      templateParams: {
+        server: 'echoServer',
+        clientFileName: testOutputFiles[0],
+        customClientName: 'HoppscotchClient'
+      }
+    });
+
+    await generator.generateFromFile(asyncapi_v3_path_hoppscotch);
+
+    for (const testOutputFile of testOutputFiles) {
+      const filePath = path.join(testResultPathCustomHoppscotch, testOutputFile);
+      const content = await readFile(filePath, 'utf8');
+      expect(content).toMatchSnapshot(testOutputFile);
+    }
+  });
 });
diff --git a/packages/templates/clients/websocket/javascript/README.md b/packages/templates/clients/websocket/javascript/README.md
index a5bdee6a13..4003c1436b 100644
--- a/packages/templates/clients/websocket/javascript/README.md
+++ b/packages/templates/clients/websocket/javascript/README.md
@@ -6,4 +6,4 @@ You can test this template:
 3. Install with `npm install` and run test with `npm run test`
 4. Start example script that uses a client library generated by the test: `node example.js`
 
-> By default this is testing against Postman echo service. You can modify `packages/templates/clients/websocket/javascript/example.js` and change first line to `const WSClient = require('./tests/temp/snapshotTestResult/client-hoppscotch.js');` and run `node example.js` again. You will see example still works but now it is using a different API. This is possible since both AsyncAPI documents define the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
\ No newline at end of file
+> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/javascript/example.js` and change first line to `const WSClient = require('./tests/temp/snapshotTestResult/client-postman.js');` and run `node example.js` again. You will see example still works but now it is using a different API. This is possible since both AsyncAPI documents define the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
\ No newline at end of file
diff --git a/packages/templates/clients/websocket/javascript/example.js b/packages/templates/clients/websocket/javascript/example.js
index b4cb1280e8..fec50d85da 100644
--- a/packages/templates/clients/websocket/javascript/example.js
+++ b/packages/templates/clients/websocket/javascript/example.js
@@ -1,4 +1,4 @@
-const WSClient = require('./test/temp/snapshotTestResult/client-postman');
+const WSClient = require('./test/temp/snapshotTestResult/custom-client-hoppscotch.js');
 // Example usage
 const wsClient = new WSClient();
 
@@ -27,7 +27,7 @@ async function main() {
 
     while (true) {
       try {
-        await wsClient.sendEchoMessage(message);
+        await WSClient.sendEchoMessage(message, wsClient.websocket);
       } catch (error) {
         console.error('Error while sending message:', error);
       }
diff --git a/packages/templates/clients/websocket/javascript/package.json b/packages/templates/clients/websocket/javascript/package.json
index 9cbb697d48..25c719db5c 100644
--- a/packages/templates/clients/websocket/javascript/package.json
+++ b/packages/templates/clients/websocket/javascript/package.json
@@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.js"
+      },
+      "appendClientSuffix": {
+        "description": "Add 'Client' suffix at the end of the class name. This option has no effect if 'customClientName' is specified.",
+        "required": false,
+        "default": false
+      },
+      "customClientName": {
+        "description": "The custom name for the generated client class",
+        "required": false
       }
     }
   }
diff --git a/packages/templates/clients/websocket/javascript/template/client.js.js b/packages/templates/clients/websocket/javascript/template/client.js.js
index f2000bfb84..b7fd0231c3 100644
--- a/packages/templates/clients/websocket/javascript/template/client.js.js
+++ b/packages/templates/clients/websocket/javascript/template/client.js.js
@@ -8,7 +8,7 @@ export default function ({ asyncapi, params }) {
   const server = getServer(asyncapi.servers(), params.server);
   const info = asyncapi.info();
   const title = info.title();
-  const clientName = getClientName(info);
+  const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
   const serverUrl = getServerUrl(server);
   return (
     <File name={params.clientFileName}>
diff --git a/packages/templates/clients/websocket/javascript/test/__snapshots__/integration.test.js.snap b/packages/templates/clients/websocket/javascript/test/__snapshots__/integration.test.js.snap
index bc7798d3df..e1dbeaf487 100644
--- a/packages/templates/clients/websocket/javascript/test/__snapshots__/integration.test.js.snap
+++ b/packages/templates/clients/websocket/javascript/test/__snapshots__/integration.test.js.snap
@@ -11,7 +11,7 @@ exports[`testing if generated client match snapshot generate simple client for h
 
 const WebSocket = require('ws');
 
-class HoppscotchEchoWebSocketClientClient {
+class HoppscotchEchoWebSocketClient {
 
   /*
     * Constructor to initialize the WebSocket client
@@ -113,7 +113,125 @@ class HoppscotchEchoWebSocketClientClient {
     }
   }
 }
-module.exports = HoppscotchEchoWebSocketClientClient;
+module.exports = HoppscotchEchoWebSocketClient;
+
+"
+`;
+
+exports[`testing if generated client match snapshot generate simple client for hoppscotch echo with custom client name 1`] = `
+"//////////////////////////////////////////////////////////////////////
+//
+// Hoppscotch Echo WebSocket Client - 1.0.0
+// Protocol: wss
+// Host: echo-websocket.hoppscotch.io
+//
+//////////////////////////////////////////////////////////////////////
+
+const WebSocket = require('ws');
+
+class HoppscotchClient {
+
+  /*
+    * Constructor to initialize the WebSocket client
+    * @param {string} url - The WebSocket server URL. Use it if the server URL is different from the default one taken from the AsyncAPI document.
+  */
+  constructor(url) {
+    this.url = url || 'wss://echo-websocket.hoppscotch.io';
+    this.websocket = null;
+    this.messageHandlers = [];
+    this.errorHandlers = [];
+  }
+
+  // Method to establish a WebSocket connection
+  connect() {
+    return new Promise((resolve, reject) => {
+      this.websocket = new WebSocket(this.url);
+
+      // On successful connection
+      this.websocket.onopen = () => {
+        console.log('Connected to Hoppscotch Echo WebSocket Client server');
+        resolve();
+      };
+
+      // On receiving a message
+      this.websocket.onmessage = (event) => {
+        if (this.messageHandlers.length > 0) {
+          // Call custom message handlers
+          this.messageHandlers.forEach(handler => {
+            if (typeof handler === 'function') {
+              this.handleMessage(event.data, handler);
+            }
+          });
+        } else {
+          // Default message logging
+          console.log('Message received:', event.data);
+        }
+      };
+
+      // On error first call custom error handlers, then default error behavior
+      this.websocket.onerror = (error) => {
+        if (this.errorHandlers.length > 0) {
+          // Call custom error handlers
+          this.errorHandlers.forEach(handler => handler(error));
+        } else {
+          // Default error behavior
+          console.error('WebSocket Error:', error);
+        }
+        reject(error);
+      };
+
+      // On connection close
+      this.websocket.onclose = () => {
+        console.log('Disconnected from Hoppscotch Echo WebSocket Client server');
+      };
+    });
+  }
+
+  // Method to register custom message handlers
+  registerMessageHandler(handler) {
+    if (typeof handler === 'function') {
+      this.messageHandlers.push(handler);
+    } else {
+      console.warn('Message handler must be a function');
+    }
+  }
+
+  // Method to register custom error handlers
+  registerErrorHandler(handler) {
+    if (typeof handler === 'function') {
+      this.errorHandlers.push(handler);
+    } else {
+      console.warn('Error handler must be a function');
+    }
+  }
+
+  // Method to handle message with callback
+  handleMessage(message, cb) {
+    if (cb) cb(message);
+  }
+
+  /**
+     * By default sends a message over a provided WebSocket connection.
+     * Useful when you already have an established WebSocket connection
+     * and want to send a message without creating a class instance.
+     *
+     * @param {Object} message - The message to send. It will be stringified to JSON.
+     * @param {WebSocket} socket - An existing WebSocket connection to use for sending the message.
+  */
+  static sendEchoMessage(message, socket) {
+    const websocket = socket || this.websocket;
+    websocket.send(JSON.stringify(message));
+  }
+
+  // Method to close the WebSocket connection
+  close() {
+    if (this.websocket) {
+      this.websocket.close();
+      console.log('WebSocket connection closed.');
+    }
+  }
+}
+module.exports = HoppscotchClient;
 
 "
 `;
diff --git a/packages/templates/clients/websocket/javascript/test/integration.test.js b/packages/templates/clients/websocket/javascript/test/integration.test.js
index d2c13cbcb3..32e6ccf4ad 100644
--- a/packages/templates/clients/websocket/javascript/test/integration.test.js
+++ b/packages/templates/clients/websocket/javascript/test/integration.test.js
@@ -20,7 +20,8 @@ describe('testing if generated client match snapshot', () => {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFile
+        clientFileName: testOutputFile,
+        appendClientSuffix: true
       }
     });
 
@@ -37,7 +38,25 @@ describe('testing if generated client match snapshot', () => {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFile
+        clientFileName: testOutputFile,
+      }
+    });
+
+    await generator.generateFromFile(asyncapi_v3_path_hoppscotch);
+
+    const client = await readFile(path.join(testResultPath, testOutputFile), 'utf8');
+    expect(client).toMatchSnapshot();
+  });
+
+  it('generate simple client for hoppscotch echo with custom client name', async () => {
+    const testOutputFile = 'custom-client-hoppscotch.js';
+
+    const generator = new Generator(template, testResultPath, {
+      forceWrite: true,
+      templateParams: {
+        server: 'echoServer',
+        clientFileName: testOutputFile,
+        customClientName: 'HoppscotchClient',
       }
     });
 
diff --git a/packages/templates/clients/websocket/python/README.md b/packages/templates/clients/websocket/python/README.md
index 490cd0fdfb..1700681186 100644
--- a/packages/templates/clients/websocket/python/README.md
+++ b/packages/templates/clients/websocket/python/README.md
@@ -6,7 +6,7 @@ You can test this template:
 2. Navigate to `packages/templates/clients/websocket/python`
 3. Install with `npm install` and run test with `npm run test`
 4. Go to test folder with `cd test`
-5. Install dependencies of the generated client: `pip install -r temp/snapshotTestResult/requirements.txt`
+5. Install dependencies of the generated client: `pip install -r temp/snapshotTestResult/custom_client_hoppscotch/requirements.txt`
 6. Start example script that uses a client library generated by the test: `python example.py`
 
-> By default this is testing against Postman echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change first line to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 21 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
diff --git a/packages/templates/clients/websocket/python/example.py b/packages/templates/clients/websocket/python/example.py
index 245a2f16db..9398490976 100644
--- a/packages/templates/clients/websocket/python/example.py
+++ b/packages/templates/clients/websocket/python/example.py
@@ -1,11 +1,10 @@
-from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient
-
 import sys
 import os
+import time
 
 sys.path.append(os.path.join(os.path.dirname(__file__), 'test'))
 
-import time
+from temp.snapshotTestResult.custom_client_hoppscotch.client import HoppscotchClient
 
 def custom_message_handler(message):
     print(f"\033[94mCustom processing of received message\033[0m: {message}")
@@ -19,7 +18,7 @@ def outgoing_message_processor(message):
     return {"Processed outgoing message": message, "timestamp": "2025-03-13T12:00:00Z"}
 
 def main():
-    client = PostmanEchoWebSocketClientClient()
+    client = HoppscotchClient()
     client.register_message_handler(custom_message_handler)
     client.register_error_handler(custom_error_handler)
     client.register_outgoing_processor(outgoing_message_processor)
diff --git a/packages/templates/clients/websocket/python/package.json b/packages/templates/clients/websocket/python/package.json
index c6fefb16fa..a2b47556a1 100644
--- a/packages/templates/clients/websocket/python/package.json
+++ b/packages/templates/clients/websocket/python/package.json
@@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.py"
+      },
+      "appendClientSuffix": {
+        "description": "Add 'Client' suffix at the end of the class name. This option has no effect if 'customClientName' is specified.",
+        "required": false,
+        "default": false
+      },
+      "customClientName": {
+        "description": "The custom name for the generated client class",
+        "required": false
       }
     }
   }
diff --git a/packages/templates/clients/websocket/python/template/client.py.js b/packages/templates/clients/websocket/python/template/client.py.js
index baadd93fd1..d22ecae21f 100644
--- a/packages/templates/clients/websocket/python/template/client.py.js
+++ b/packages/templates/clients/websocket/python/template/client.py.js
@@ -8,7 +8,7 @@ export default function ({ asyncapi, params }) {
   const server = getServer(asyncapi.servers(), params.server);
   const info = asyncapi.info();
   const title = info.title();
-  const clientName = getClientName(info);
+  const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
   const serverUrl = getServerUrl(server);
   return (
     // The clientFileName default values can be found and modified under the package.json
diff --git a/packages/templates/clients/websocket/python/test/__snapshots__/integration.test.js.snap b/packages/templates/clients/websocket/python/test/__snapshots__/integration.test.js.snap
index c848a70265..4b81a47f68 100644
--- a/packages/templates/clients/websocket/python/test/__snapshots__/integration.test.js.snap
+++ b/packages/templates/clients/websocket/python/test/__snapshots__/integration.test.js.snap
@@ -1,5 +1,174 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`testing if generated client match snapshot generate simple client for hoppscotch echo with custom client name: client.py 1`] = `
+"# //////////////////////////////////////////////////////////////////////////
+#
+# Hoppscotch Echo WebSocket Client - 1.0.0
+# Protocol: wss
+# Host: echo-websocket.hoppscotch.io
+#
+# //////////////////////////////////////////////////////////////////////////
+
+import json
+import certifi
+import threading
+import websocket
+
+class HoppscotchClient:
+
+  def __init__(self, url: str = \\"wss://echo-websocket.hoppscotch.io\\"):
+      \\"\\"\\"
+      Constructor to initialize the WebSocket client.
+
+      Args:
+          url (str, optional): The WebSocket server URL. Use it if the server URL is 
+          different from the default one taken from the AsyncAPI document.
+      \\"\\"\\"
+      self.url = url
+      self.ws_app = None  # Instance of WebSocketApp
+      self.message_handlers = []      # Callables for incoming messages
+      self.error_handlers = []        # Callables for errors
+      self.outgoing_processors = []   # Callables to process outgoing messages
+      self._stop_event = threading.Event()
+
+  def on_open(self, ws):
+      print(\\"Connected to Hoppscotch Echo WebSocket Client server\\")
+
+  def on_message(self, ws, message):
+      self.handle_message(message)
+
+  def on_error(self, ws, error):
+      print(\\"WebSocket Error:\\", error)
+      self.handle_error(error)
+
+  def on_close(self, ws, close_status_code, close_msg):
+      print(\\"Disconnected from Hoppscotch Echo WebSocket Client\\", close_status_code, close_msg)
+
+  def connect(self):
+      \\"\\"\\"Establish the connection and start the run_forever loop in a background thread.\\"\\"\\"
+      ssl_opts = {\\"ca_certs\\": certifi.where()}
+      self.ws_app = websocket.WebSocketApp(
+          self.url,
+          on_open=self.on_open,
+          on_message=self.on_message,
+          on_error=self.on_error,
+          on_close=self.on_close
+      )
+      # Run the WebSocketApp's run_forever in a separate thread with multithreading enabled.
+      def run():
+          while not self._stop_event.is_set():
+              try:
+                  print(\\"Starting WebSocket thread...\\")
+                  self.ws_app.run_forever(sslopt=ssl_opts)
+              except Exception as e:
+                  print(f\\"Exception in WebSocket thread: {e}\\")  # Print full error details
+
+      thread = threading.Thread(target=run, daemon=True)
+      thread.start()
+
+  def register_message_handler(self, handler):
+      \\"\\"\\"Register a callable to process incoming messages.\\"\\"\\"
+      if callable(handler):
+          self.message_handlers.append(handler)
+      else:
+          print(\\"Message handler must be callable\\")
+
+  def register_error_handler(self, handler):
+      \\"\\"\\"Register a callable to process errors.\\"\\"\\"
+      if callable(handler):
+          self.error_handlers.append(handler)
+      else:
+          print(\\"Error handler must be callable\\")
+
+  def register_outgoing_processor(self, processor):
+      \\"\\"\\"
+      Register a callable that processes outgoing messages automatically.
+      These processors run in sequence before each message is sent.
+      \\"\\"\\"
+      if callable(processor):
+          self.outgoing_processors.append(processor)
+      else:
+          print(\\"Outgoing processor must be callable\\")
+
+  def handle_message(self, message):
+      \\"\\"\\"Pass the incoming message to all registered message handlers. \\"\\"\\"
+      if len(self.message_handlers) == 0:
+        print(\\"\\\\033[94mReceived raw message:\\\\033[0m\\", message)
+      else:
+        for handler in self.message_handlers:
+          handler(message)
+
+  def handle_error(self, error):
+      \\"\\"\\"Pass the error to all registered error handlers. Generic log message is printed if no handlers are registered.\\"\\"\\"
+      if len(self.error_handlers) == 0:
+        print(\\"\\\\033[91mError occurred:\\\\033[0m\\", error)
+      else:
+        # Call custom error handlers
+        for handler in self.error_handlers:
+          handler(error)
+
+  async def send_message(self, message):
+      \\"\\"\\"
+      Send a message using the WebSocket connection attached to this instance.
+
+      Args:
+          message (dict or str): The message to send. Will be serialized to JSON if it's a dictionary.
+
+      Raises:
+          Exception: If sending fails or the socket is not connected.
+      \\"\\"\\"
+      await self._send(message, self.ws_app)
+
+  @staticmethod
+  async def send_message_static(message, socket):
+      \\"\\"\\"
+      Send a message using a provided WebSocket connection, without needing an instance.
+
+      Args:
+          message (dict or str): The message to send.
+          socket (websockets.WebSocketCommonProtocol): The WebSocket to send through.
+
+      Raises:
+          Exception: If sending fails or the socket is not connected.
+      \\"\\"\\"
+      await HoppscotchEchoWebSocketClient._send(message, socket)
+
+  @staticmethod
+  async def _send(message, socket):
+      \\"\\"\\"
+      Internal helper to handle the actual sending logic.
+
+      Args:
+          message (dict or str): The message to send.
+          socket (websockets.WebSocketCommonProtocol): The WebSocket to send through.
+
+      Notes:
+          If message is a dictionary, it will be automatically converted to JSON.
+      \\"\\"\\"
+      try:
+          if isinstance(message, dict):
+              message = json.dumps(message)
+          await socket.send(message)
+      except Exception as e:
+          print(\\"Error sending:\\", e)
+
+  def close(self):
+      \\"\\"\\"Cleanly close the WebSocket connection.\\"\\"\\"
+      self._stop_event.set()
+      if self.ws_app:
+          self.ws_app.close()
+          print(\\"WebSocket connection closed.\\")
+
+"
+`;
+
+exports[`testing if generated client match snapshot generate simple client for hoppscotch echo with custom client name: requirements.txt 1`] = `
+"websocket-client==1.8.0
+certifi==2025.1.31
+requests==2.32.3
+"
+`;
+
 exports[`testing if generated client match snapshot generate simple client for hoppscotch echo: client.py 1`] = `
 "# //////////////////////////////////////////////////////////////////////////
 #
@@ -14,7 +183,7 @@ import certifi
 import threading
 import websocket
 
-class HoppscotchEchoWebSocketClientClient:
+class HoppscotchEchoWebSocketClient:
 
   def __init__(self, url: str = \\"wss://echo-websocket.hoppscotch.io\\"):
       \\"\\"\\"
diff --git a/packages/templates/clients/websocket/python/test/integration.test.js b/packages/templates/clients/websocket/python/test/integration.test.js
index 9064927eb9..ca080b21c3 100644
--- a/packages/templates/clients/websocket/python/test/integration.test.js
+++ b/packages/templates/clients/websocket/python/test/integration.test.js
@@ -10,19 +10,21 @@ const asyncapi_v3_path_hoppscotch = path.resolve(__dirname, '../../test/__fixtur
 const testResultPath = path.resolve(__dirname, './temp/snapshotTestResult');
 const testResultPathPostman = path.join(testResultPath, 'client_postman');
 const testResultPathHoppscotch = path.join(testResultPath, 'client_hoppscotch');
+const testResultPathCustomHoppscotch = path.join(testResultPath, 'custom_client_hoppscotch');
 const template = path.resolve(__dirname, '../');
 
+const testOutputFiles = ['client.py', 'requirements.txt'];
+
 describe('testing if generated client match snapshot', () => {
   jest.setTimeout(100000);
   
   it('generate simple client for postman echo', async () => {
-    const testOutputFiles = ['client.py', 'requirements.txt'];
-
     const generator = new Generator(template, testResultPathPostman, {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFiles[0]
+        clientFileName: testOutputFiles[0],
+        appendClientSuffix: true
       }
     });
 
@@ -37,13 +39,11 @@ describe('testing if generated client match snapshot', () => {
   });
 
   it('generate simple client for hoppscotch echo', async () => {
-    const testOutputFiles = ['client.py', 'requirements.txt'];
-
     const generator = new Generator(template, testResultPathHoppscotch, {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFiles[0]
+        clientFileName: testOutputFiles[0],
       }
     });
 
@@ -56,4 +56,23 @@ describe('testing if generated client match snapshot', () => {
       expect(content).toMatchSnapshot(testOutputFile);
     }
   });
+
+  it('generate simple client for hoppscotch echo with custom client name', async () => {
+    const generator = new Generator(template, testResultPathCustomHoppscotch, {
+      forceWrite: true,
+      templateParams: {
+        server: 'echoServer',
+        clientFileName: testOutputFiles[0],
+        customClientName: 'HoppscotchClient'
+      }
+    });
+
+    await generator.generateFromFile(asyncapi_v3_path_hoppscotch);
+
+    for (const testOutputFile of testOutputFiles) {
+      const filePath = path.join(testResultPathCustomHoppscotch, testOutputFile);
+      const content = await readFile(filePath, 'utf8');
+      expect(content).toMatchSnapshot(testOutputFile);
+    }
+  });
 });


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>🔭 Outside diff range comments (2)</summary><blockquote>

<details>
<summary>packages/templates/clients/websocket/python/test/integration.test.js (2)</summary><blockquote>

`79-79`: _⚠️ Potential issue_

**Fix incorrect path in the custom client test**

The path used to read the generated files is incorrect. You're using `testResultPathHoppscotch` instead of `testResultPathCustomHoppscotch`.


```diff
-      const filePath = path.join(testResultPathHoppscotch, testOutputFile);
+      const filePath = path.join(testResultPathCustomHoppscotch, testOutputFile);
```

---

`20-20`: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Consider extracting duplicated string literals**

There's a linting error about duplicating the client.py string literal. Consider defining a constant for this.


```diff
+  const defaultClientFile = 'client.py';
+  const defaultRequirementsFile = 'requirements.txt';
+  
   it('generate simple client for postman echo', async () => {
-    const testOutputFiles = ['client.py', 'requirements.txt'];
+    const testOutputFiles = [defaultClientFile, defaultRequirementsFile];
```

Similarly, update the other occurrences in the file.

---

🏁 Script executed:

```shell
#!/bin/bash
# Find all occurrences of client.py and requirements.txt literals
rg "'client.py'" --type js --context 2
rg "'requirements.txt'" --type js --context 2
```

Length of output: 3458

---



</details>

**Extract duplicated file name literals into constants**

The `integration.test.js` file reuses the `['client.py', 'requirements.txt']` array in three separate tests. This triggers a lint error for duplicate string literals and makes future updates harder. Extract these strings into constants at the top of the file and reference them in each test.

• File: packages/templates/clients/websocket/python/test/integration.test.js  
• Tests to update:
  - generate simple client for postman echo  
  - generate simple client for hoppscotch echo  
  - generate simple client for hoppscotch echo with custom client name  

Proposed changes:

```diff
+// At the top of the file
+const defaultClientFile = 'client.py';
+const defaultRequirementsFile = 'requirements.txt';
+
  it('generate simple client for postman echo', async () => {
-   const testOutputFiles = ['client.py', 'requirements.txt'];
+   const testOutputFiles = [defaultClientFile, defaultRequirementsFile];
    // ...
  });

  it('generate simple client for hoppscotch echo', async () => {
-   const testOutputFiles = ['client.py', 'requirements.txt'];
+   const testOutputFiles = [defaultClientFile, defaultRequirementsFile];
    // ...
  });

  it('generate simple client for hoppscotch echo with custom client name', async () => {
-   const testOutputFiles = ['client.py', 'requirements.txt'];
+   const testOutputFiles = [defaultClientFile, defaultRequirementsFile];
    // ...
  });
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 GitHub Check: Test NodeJS PR - ubuntu-latest</summary>

[failure] 20-20: 
Define a constant instead of duplicating this literal 3 times

</details>
<details>
<summary>🪛 GitHub Actions: PR testing - if Node project</summary>

[error] 20-20: ESLint: Define a constant instead of duplicating this literal 3 times (sonarjs/no-duplicate-string)

</details>

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>packages/templates/clients/websocket/python/template/client.py.js (1)</summary><blockquote>

`7-23`: <details>
<summary>❓ Verification inconclusive</summary>

**Consider implementing a default value for appendClientSuffix**

Similar to the JavaScript template, the code doesn't handle the case where `params.appendClientSuffix` is undefined. Consider providing a default value to ensure consistent behavior.


```diff
- const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
+ const clientName = getClientName(info, params.appendClientSuffix ?? false, params.customClientName);
```

---

🏁 Script executed:

```shell
#!/bin/bash
# Check if default values are defined in package.json
echo "Checking for default params in Python template package.json"
fd --glob "package.json" --path packages/templates/clients/websocket/python | xargs cat | grep -A 10 "generatorParameters"
```

Length of output: 472

---

```bash
#!/bin/bash
echo "Checking for package.json in Python WebSocket template directories"
for dir in packages/templates/clients/websocket/python packages/templates/clients/websocket/python/template; do
  if [ -f "$dir/package.json" ]; then
    echo "----- Found $dir/package.json -----"
    echo "appendClientSuffix entries:"
    grep -R "appendClientSuffix" -n "$dir/package.json" || echo "  (none)"
    echo
    echo "generatorParameters section:"
    grep -R "generatorParameters" -n "$dir/package.json" -C 5 || echo "  (none)"
    echo
  else
    echo "No package.json at $dir"
  fi
done

echo "Searching all package.json under packages/templates for appendClientSuffix defaults"
find packages/templates -type f -name "package.json" -exec grep -R "appendClientSuffix" -n {} \; || echo "(no occurrences)"
```

---

```bash
#!/bin/bash
echo "Scanning all package.json under packages/templates for default appendClientSuffix settings..."

# Find package.json files and inspect generatorParameters and appendClientSuffix
find packages/templates -type f -name "package.json" -print | while read file; do
  echo "----- $file -----"
  echo "generatorParameters section (if any):"
  grep -n '"generatorParameters"' -C2 "$file" || echo "  (none)"
  echo
  echo "appendClientSuffix default (if defined):"
  grep -n '"appendClientSuffix"' -C2 "$file" || echo "  (none)"
  echo
done

echo "Also searching template code for usage of default values:"
rg --color=never "appendClientSuffix" -n packages/templates/clients/websocket/python
```

---

```bash
#!/bin/bash
echo "Scanning entire repository for 'appendClientSuffix' occurrences and defaults"
rg --color=never -n '"appendClientSuffix"' .
```

---



</details>

**Ensure appendClientSuffix defaults to false**

The Python WebSocket template currently passes `params.appendClientSuffix` directly, which can be undefined and lead to inconsistent client names. To align with the JavaScript template, default it to `false`:

• File: packages/templates/clients/websocket/python/template/client.py.js  
```diff
- const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
+ const clientName = getClientName(info, params.appendClientSuffix ?? false, params.customClientName);
```

Please verify that the template’s parameter definitions (e.g., in package.json or your generator schema) don’t already supply a default for `appendClientSuffix`.

</blockquote></details>
<details>
<summary>packages/helpers/test/utils.test.js (1)</summary><blockquote>

`17-21`: **Consider adding test for undefined parameters**

The tests don't cover cases where parameters might be undefined or null. Consider adding tests for these edge cases to ensure the function handles them gracefully.


```javascript
it('should handle undefined parameters gracefully', () => {
  const info = parsedAsyncAPIDocument.info();
  // Don't pass appendClientSuffix and customClientName
  const clientName = getClientName(info);
  
  // Should default to a sensible behavior
  expect(clientName).toBe('GeminiMarketDataWebsocketAPI'); // or whatever is expected
});
```


Also applies to: 28-32, 39-43

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between b1c51f9bac5e39bfb0a797d160b6bba8a14f4ac3 and d90db032acc356d20e61d3ebb81882c27419e7bc.

</details>

<details>
<summary>⛔ Files ignored due to path filters (2)</summary>

* `packages/templates/clients/websocket/javascript/test/__snapshots__/integration.test.js.snap` is excluded by `!**/*.snap`
* `packages/templates/clients/websocket/python/test/__snapshots__/integration.test.js.snap` is excluded by `!**/*.snap`

</details>

<details>
<summary>📒 Files selected for processing (8)</summary>

* `packages/helpers/src/utils.js` (1 hunks)
* `packages/helpers/test/utils.test.js` (1 hunks)
* `packages/templates/clients/websocket/javascript/package.json` (1 hunks)
* `packages/templates/clients/websocket/javascript/template/client.js.js` (1 hunks)
* `packages/templates/clients/websocket/javascript/test/integration.test.js` (3 hunks)
* `packages/templates/clients/websocket/python/package.json` (1 hunks)
* `packages/templates/clients/websocket/python/template/client.py.js` (1 hunks)
* `packages/templates/clients/websocket/python/test/integration.test.js` (3 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 GitHub Actions: PR testing - if Node project</summary>

<details>
<summary>packages/templates/clients/websocket/python/test/integration.test.js</summary>

[error] 20-20: ESLint: Define a constant instead of duplicating this literal 3 times (sonarjs/no-duplicate-string)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (2)</summary>

* GitHub Check: Test generator as dependency with Node 20
* GitHub Check: Test generator as dependency with Node 18

</details>

<details>
<summary>🔇 Additional comments (19)</summary><blockquote>

<details>
<summary>packages/helpers/src/utils.js (3)</summary>

`2-3`: **JSDoc updated correctly to reflect new parameters**

The documentation has been properly updated to describe the new functionality: custom client naming and optional suffix appending.



Also applies to: 5-6, 8-8

---

`10-13`: **Implementation of custom client name support looks good**

The new conditional logic correctly prioritizes the custom client name when provided.

---

`18-18`: **Good implementation of conditional suffix**

The ternary operator provides a clean way to conditionally append the "Client" suffix.

</details>
<details>
<summary>packages/templates/clients/websocket/javascript/template/client.js.js (2)</summary>

`11-11`: **Correctly updated to pass new parameters to getClientName**

The function call has been properly updated to pass the new parameters from the template configuration to the helper function.

---

`7-23`: <details>
<summary>❌ Incorrect review comment</summary>

**Consider implementing a default value for appendClientSuffix**

The code doesn't handle the case where `params.appendClientSuffix` is undefined. Consider providing a default value to ensure consistent behavior even if the parameter is not explicitly set.


```diff
- const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
+ const clientName = getClientName(info, params.appendClientSuffix ?? false, params.customClientName);
```

---

🏁 Script executed:

```shell
#!/bin/bash
# Check if default values are defined in package.json
echo "Checking for default params in JavaScript template package.json"
fd --glob "package.json" --path packages/templates/clients/websocket/javascript | xargs cat | grep -A 10 "generatorParameters"
```

Length of output: 484

---

🏁 Script executed:

```shell
#!/bin/bash
# List files in the JavaScript template directory and its first-level subdirectories
echo "Files in packages/templates/clients/websocket/javascript:"
find packages/templates/clients/websocket/javascript -maxdepth 2 -type f

echo
# Search for references to appendClientSuffix
echo "Searching for 'appendClientSuffix' references..."
rg "appendClientSuffix" -n packages/templates/clients/websocket/javascript || echo "No occurrences found"

echo
# Search for default value declarations in JSON/YAML files
echo "Searching for 'default' properties in template definition files..."
rg '"default"' -n packages/templates/clients/websocket/javascript || echo "No default declarations found"
```

Length of output: 2737

---

(Note: Adjusted line numbers to capture parameter definitions.)

---

🏁 Script executed:

```shell
#!/bin/bash
# Display lines around the appendClientSuffix parameter in package.json
echo "Context for 'appendClientSuffix' in package.json:"
sed -n ' sixty, ninetyp' packages/templates/clients/websocket/javascript/package.json
```

Length of output: 259

---

🏁 Script executed:

```shell
#!/bin/bash
# Show context for appendClientSuffix in package.json with surrounding lines
rg -n -C 5 '"appendClientSuffix"' packages/templates/clients/websocket/javascript/package.json
```

Length of output: 471

---



</details>

**No change needed for appendClientSuffix default**

The `appendClientSuffix` parameter already has a default value of `false` defined in  
`packages/templates/clients/websocket/javascript/package.json` (lines 71–74). The template will always receive a boolean for `params.appendClientSuffix`, so no additional default handling is required in the code.



> Likely an incorrect or invalid review comment.

</details>
<details>
<summary>packages/templates/clients/websocket/python/template/client.py.js (1)</summary>

`11-11`: **Correctly updated to pass new parameters to getClientName**

The function call has been properly updated to pass the new parameters from the template configuration to the helper function.

</details>
<details>
<summary>packages/helpers/test/utils.test.js (3)</summary>

`16-25`: **Good test for client name without suffix**

This test properly verifies the new functionality of generating a client name without appending the "Client" suffix.

---

`27-36`: **Good test for client name with suffix**

This test properly verifies the original functionality of generating a client name with the "Client" suffix.

---

`38-47`: **Good test for custom client name**

This test properly verifies the new functionality of using a custom client name.

</details>
<details>
<summary>packages/templates/clients/websocket/python/package.json (1)</summary>

`71-79`: **Great addition of configurable naming parameters!**

The new parameters `appendClientSuffix` and `customClientName` provide excellent flexibility for client class naming. The descriptions are clear, and the default values are appropriately set.

</details>
<details>
<summary>packages/templates/clients/websocket/javascript/package.json (1)</summary>

`71-79`: **Consistent implementation across templates!**

The parameter additions match those in the Python template, maintaining consistency across different language implementations.

</details>
<details>
<summary>packages/templates/clients/websocket/javascript/test/integration.test.js (4)</summary>

`24-24`: **Explicitly setting the new parameter**

Good job explicitly setting `appendClientSuffix: false` to match the default value in the package.json, making the test intent clear.

---

`41-43`: **Explicitly setting the new parameter**

Good job explicitly setting `appendClientSuffix: false` to match the default value in the package.json, making the test intent clear.

---

`52-62`: **Good test coverage for the new custom client name parameter**

The new test case properly verifies the custom client name functionality, ensuring that when `customClientName` is provided, it is correctly used in the generated output.

---

`78-78`: **Explicitly setting the new parameter**

Good job explicitly setting `appendClientSuffix: false` to match the default value in the package.json, making the test intent clear.

</details>
<details>
<summary>packages/templates/clients/websocket/python/test/integration.test.js (4)</summary>

`13-13`: **Well-defined constant for the new test case**

Good practice defining a separate path constant for the custom client name test to avoid file conflicts.

---

`27-28`: **Explicitly setting the new parameter**

Good job explicitly setting `appendClientSuffix: false` to match the default value in the package.json, making the test intent clear.

---

`48-50`: **Explicitly setting the new parameter**

Good job explicitly setting `appendClientSuffix: false` to match the default value in the package.json, making the test intent clear.

---

`63-73`: **Good test coverage for the new custom client name parameter**

Adding a dedicated test case for custom client name functionality ensures proper coverage of the new feature.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-23T06:17:25Z
user: login: nightknighto
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T15:18:55Z
user: login: derberg
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-23T16:40:21Z
user: login: Adi-204
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-23T16:59:14Z
user: login: derberg
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-23T17:04:21Z
user: login: Adi-204
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-23T17:41:00Z
user: login: derberg
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-24T16:17:46Z
user: login: derberg
state: DISMISSED
author_association: MEMBER
submitted_at: 2025-04-24T16:19:03Z
user: login: derberg
body: ah one more thing, I think it makes sense to now start using the generated client called `HoppscotchClient` in the examples, and in microcks

you know, it is much nicer, shorter, etc, wdyt?
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-24T16:22:23Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>packages/templates/clients/websocket/javascript/README.md (1)</summary><blockquote>

`9-9`: **Default testing service updated to Hoppscotch**

The documentation has been correctly updated to reflect the change from Postman to Hoppscotch as the default echo service for testing.



Consider these minor grammatical improvements:

```diff
-> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/javascript/example.js` and change first line to `const WSClient = require('./tests/temp/snapshotTestResult/client-postman.js');` and run `node example.js` again. You will see example still works but now it is using a different API. This is possible since both AsyncAPI documents define the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default, this is testing against the Hoppscotch echo service. You can modify `packages/templates/clients/websocket/javascript/example.js` and change the first line to `const WSClient = require('./tests/temp/snapshotTestResult/client-postman.js');` and run `node example.js` again. You will see the example still works, but now it is using a different API. This is possible since both AsyncAPI documents define the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 LanguageTool</summary>

[uncategorized] ~9-~9: Did you mean: “By default,”?
Context: ...rated by the test: `node example.js`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~9-~9: You might be missing the article “the” here.
Context: ...ocket/javascript/example.js` and change first line to `const WSClient = require('./te...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

---

[uncategorized] ~9-~9: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ... again. You will see example still works but now it is using a different API. This i...

(COMMA_COMPOUND_SENTENCE)

</details>

</details>

</blockquote></details>
<details>
<summary>packages/templates/clients/websocket/python/README.md (1)</summary><blockquote>

`12-12`: **Fix grammatical issues in the instructions**

The instructions have been updated to correctly reflect the change from Postman to Hoppscotch as the default echo service. However, there are a few minor grammatical issues to address.


```diff
-> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default, this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see the example still works but against a different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 LanguageTool</summary>

[uncategorized] ~12-~12: Did you mean: “By default,”?
Context: ...ted by the test: `python example.py`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...`python example.py` again. You will see example still works but agains different API. T...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

</details>

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between edaedd716302f35dc032ea90918119a5d44a2591 and bea66dda6d63dc60993766c55bb39f7a6ef43fcb.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `packages/templates/clients/websocket/dart/test/__snapshots__/integration.test.js.snap` is excluded by `!**/*.snap`

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `packages/templates/clients/websocket/dart/README.md` (1 hunks)
* `packages/templates/clients/websocket/dart/example.dart` (2 hunks)
* `packages/templates/clients/websocket/dart/package.json` (1 hunks)
* `packages/templates/clients/websocket/dart/template/client.dart.js` (1 hunks)
* `packages/templates/clients/websocket/dart/test/integration.test.js` (2 hunks)
* `packages/templates/clients/websocket/javascript/README.md` (1 hunks)
* `packages/templates/clients/websocket/javascript/example.js` (2 hunks)
* `packages/templates/clients/websocket/python/README.md` (1 hunks)
* `packages/templates/clients/websocket/python/example.py` (2 hunks)

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (1)</summary>

* packages/templates/clients/websocket/dart/README.md

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 LanguageTool</summary>

<details>
<summary>packages/templates/clients/websocket/javascript/README.md</summary>

[uncategorized] ~9-~9: Did you mean: “By default,”?
Context: ...rated by the test: `node example.js`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~9-~9: You might be missing the article “the” here.
Context: ...ocket/javascript/example.js` and change first line to `const WSClient = require('./te...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

---

[uncategorized] ~9-~9: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ... again. You will see example still works but now it is using a different API. This i...

(COMMA_COMPOUND_SENTENCE)

</details>
<details>
<summary>packages/templates/clients/websocket/python/README.md</summary>

[uncategorized] ~10-~10: You might be missing the article “an” here.
Context: ...t_hoppscotch/requirements.txt` 6. Start example script that uses a client library gener...

(AI_EN_LECTOR_MISSING_DETERMINER_AN)

---

[uncategorized] ~12-~12: Did you mean: “By default,”?
Context: ...ted by the test: `python example.py`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...`python example.py` again. You will see example still works but agains different API. T...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (4)</summary>

* GitHub Check: Test generator as dependency with Node 18
* GitHub Check: Test generator as dependency with Node 20
* GitHub Check: Test NodeJS PR - windows-latest
* GitHub Check: Test NodeJS PR - macos-13

</details>

<details>
<summary>🔇 Additional comments (11)</summary><blockquote>

<details>
<summary>packages/templates/clients/websocket/javascript/example.js (1)</summary>

`1-1`: **Import path updated to use custom Hoppscotch client**

The import has been changed from Postman to a custom Hoppscotch client, which aligns with the PR objective of providing customization options for client names.

</details>
<details>
<summary>packages/templates/clients/websocket/dart/template/client.dart.js (1)</summary>

`11-11`: **Well-implemented enhancement to the client name generation**

The updated `getClientName` call properly passes the new parameters (`appendClientSuffix` and `customClientName`) from the template configuration, enabling greater flexibility in customizing the generated client class name as intended by the PR objectives.

</details>
<details>
<summary>packages/templates/clients/websocket/dart/example.dart (2)</summary>

`2-2`: **Import path updated to reflect custom client example**

The import path has been correctly updated to use the custom Hoppscotch client, which aligns with the integration tests and demonstrates the new client naming functionality.

---

`15-15`: **Client instantiation updated to use the new custom client**

The client instantiation has been properly updated to use `HoppscotchClient()` which corresponds to the custom client name specified in the integration tests.

</details>
<details>
<summary>packages/templates/clients/websocket/dart/test/integration.test.js (4)</summary>

`13-13`: **Path constant added for custom client test**

Good addition of a dedicated path constant for the custom client test, maintaining consistency with the existing path constants structure.

---

`16-17`: **Improved code maintainability through constant extraction**

Excellent refactoring to extract the output files into a reusable constant, which reduces duplication and improves maintainability.

---

`27-27`: **Postman client test now verifies suffix appending**

The test has been correctly updated to include the `appendClientSuffix` parameter, ensuring that this new functionality is properly tested.

---

`60-77`: **Comprehensive test added for custom client name functionality**

This new test case thoroughly verifies the `customClientName` parameter functionality by generating a Hoppscotch client with a custom name and validating the output against snapshots. The test structure follows the established pattern and properly exercises the new functionality.

</details>
<details>
<summary>packages/templates/clients/websocket/dart/package.json (1)</summary>

`71-79`: **Well-defined parameters for enhanced client naming functionality**

The new parameters are properly defined with clear descriptions, appropriate defaults, and explicit precedence rules. They directly implement the PR objectives of:
1. `appendClientSuffix` - Allowing the "Client" suffix to be appended
2. `customClientName` - Enabling a completely custom client class name

The description correctly notes that the suffix option has no effect when a custom name is specified, establishing a clear precedence order.

</details>
<details>
<summary>packages/templates/clients/websocket/python/example.py (1)</summary>

`3-3`: **Consistent update for the client migration from Postman to Hoppscotch**

The changes properly update the imports and client instantiation to use the new Hoppscotch client instead of the Postman client. This aligns with the PR objective of improving the `getClientName` helper function to support custom client names.



Also applies to: 7-7, 21-21

</details>
<details>
<summary>packages/templates/clients/websocket/python/README.md (1)</summary>

`9-9`: **Path correctly updated to match the new client location**

The requirements.txt path has been properly updated to reflect the new location of the generated client files.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-24T18:55:02Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between bea66dda6d63dc60993766c55bb39f7a6ef43fcb and 475efcc42fb912392cc5d05cd94f1953369a8be6.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `packages/templates/clients/websocket/python/README.md` (1 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 LanguageTool</summary>

<details>
<summary>packages/templates/clients/websocket/python/README.md</summary>

[uncategorized] ~10-~10: You might be missing the article “an” here.
Context: ...t_hoppscotch/requirements.txt` 6. Start example script that uses a client library gener...

(AI_EN_LECTOR_MISSING_DETERMINER_AN)

---

[uncategorized] ~12-~12: Did you mean: “By default,”?
Context: ...ted by the test: `python example.py`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...`python example.py` again. You will see example still works but agains different API. T...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (4)</summary>

* GitHub Check: Test generator as dependency with Node 20
* GitHub Check: Test generator as dependency with Node 18
* GitHub Check: Test NodeJS PR - windows-latest
* GitHub Check: Test NodeJS PR - macos-13

</details>

<details>
<summary>🔇 Additional comments (1)</summary><blockquote>

<details>
<summary>packages/templates/clients/websocket/python/README.md (1)</summary>

`9-9`: **Approve updated dependency path**  
The change to reference `temp/snapshotTestResult/custom_client_hoppscotch/requirements.txt` aligns with the new output directory structure for custom client names.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-24T19:08:41Z
user: login: derberg
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T15:56:52Z
user: login: Adi-204
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T16:25:12Z
user: login: Adi-204
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T16:43:30Z
user: login: derberg
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-28T13:47:28Z
user: login: derberg
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-28T13:47:34Z

Review comments:
diff_hunk: @@ -1,16 +1,20 @@
 /**
- * Get client name from AsyncAPI info.title
+ * Get client name from AsyncAPI info.title or uses a custom name if provided.
  *
  * @param {object} info - The AsyncAPI info object.
+ * @param {boolean} appendClientSuffix - Whether to append "Client" to the generated name
+ * @param {string} [customClientName] - Optional custom client name to use instead of generating from title
  * 
- * return {string} - The client name with "Client" appended at the end.
+ * @returns {string} The formatted client name, either the custom name or a generated name based on the title
  */
-module.exports.getClientName = (info) => {
+module.exports.getClientName = (info, appendClientSuffix, customClientName) => {
+  if (customClientName) {
+    return customClientName;
+  }
   const title = info.title();
-  
-  // Remove spaces, make the first letter uppercase, and add "Client" at the end
-  return `${title.replace(/\s+/g, '') // Remove all spaces
+  const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
     .replace(/^./, char => char.toUpperCase()) // Make the first letter uppercase
-  }Client`;
+  }`;
+  return appendClientSuffix ? `${baseName}Client` : baseName;
path: packages/helpers/src/utils.js
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Fix syntax error in template literal**

There's a syntax error in the template string - an unexpected closing curly brace after the comment for making the first letter uppercase.


```diff
-  const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
-    .replace(/^./, char => char.toUpperCase()) // Make the first letter uppercase
-  }`;
+  const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
+    .replace(/^./, char => char.toUpperCase())}` // Make the first letter uppercase
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
    .replace(/^./, char => char.toUpperCase())}` // Make the first letter uppercase
  return appendClientSuffix ? `${baseName}Client` : baseName;
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 353a48c
created_at: 2025-04-23T06:17:24Z
author_association: NONE
diff_hunk: @@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.js"
+      },
+      "appendClientSuffix": {
+        "description": "Add Client at the end of the class name",
path: packages/templates/clients/websocket/javascript/package.json
user: login: nightknighto
body: ```suggestion
        "description": "Add 'Client' suffix at the end of the class name",
```
I think the original version could be confuse people in the sense that they may not quickly understand that "Client" here refers to the english word, and not a code object.
Same for the python package.
created_at: 2025-04-23T15:12:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -13,12 +13,36 @@ describe('getClientName integration test with AsyncAPI', () => {
     parsedAsyncAPIDocument = parseResult.document;
   });
 
-  it('should generate correct client name for the provided AsyncAPI info object', () => {
+  it('should generate correct client name for the provided AsyncAPI info object without appendClientSuffix', () => {
     const info = parsedAsyncAPIDocument.info();
+    const appendClientSuffix = false;
+    const customClientName = '';
 
-    const clientName = getClientName(info);
+    const clientName = getClientName(info, appendClientSuffix, customClientName);
+
+    // Example assertion: Check if the name is formatted correctly
+    expect(clientName).toBe('GeminiMarketDataWebsocketAPI');
+  });
+
+  it('should generate correct client name for the provided AsyncAPI info object with appendClientSuffix', () => {
+    const info = parsedAsyncAPIDocument.info();
+    const appendClientSuffix = true;
+    const customClientName = '';
+
+    const clientName = getClientName(info, appendClientSuffix, customClientName);
 
     // Example assertion: Check if the name is formatted correctly
     expect(clientName).toBe('GeminiMarketDataWebsocketAPIClient');
   });
+
+  it('should return customClientName', () => {
+    const info = parsedAsyncAPIDocument.info();
+    const appendClientSuffix = false;
+    const customClientName = 'GeminiClient';
+
+    const clientName = getClientName(info, appendClientSuffix, customClientName);
+
+    // Example assertion: Check if the name is formatted correctly
+    expect(clientName).toBe('GeminiClient');
path: packages/helpers/test/utils.test.js
user: login: nightknighto
body: ```suggestion
    expect(clientName).toBe(customClientName);
```
Using the constant instead of a hard-coded value, in case someone changes the constant's value.
created_at: 2025-04-23T15:16:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -20,7 +20,8 @@ describe('testing if generated client match snapshot', () => {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFile
+        clientFileName: testOutputFile,
+        appendClientSuffix: false
path: packages/templates/clients/websocket/javascript/test/integration.test.js
user: login: derberg
body: if false, no need to explicitly pass it as default is false (provided in the config - it is used by the generator)
created_at: 2025-04-23T16:38:07Z
author_association: MEMBER
diff_hunk: @@ -20,7 +20,8 @@ describe('testing if generated client match snapshot', () => {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFile
+        clientFileName: testOutputFile,
+        appendClientSuffix: false
path: packages/templates/clients/websocket/javascript/test/integration.test.js
user: login: derberg
body: probably one example should have `appendClientSuffix: true`
created_at: 2025-04-23T16:38:49Z
author_association: MEMBER
diff_hunk: @@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.js"
+      },
+      "appendClientSuffix": {
+        "description": "Add 'Client' suffix at the end of the class name",
+        "required": false,
+        "default": false
+      },
+      "customClientName": {
+        "description": "The custom name for the generated client class",
+        "required": false
path: packages/templates/clients/websocket/javascript/package.json
user: login: derberg
body: with current implementation, these are mutually exclusive, so explain it in description

so please know that if `customClientName` is used, then `appendClientSuffix` do not take any effect
created_at: 2025-04-23T16:40:06Z
author_association: MEMBER
diff_hunk: @@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.js"
+      },
+      "appendClientSuffix": {
+        "description": "Add 'Client' suffix at the end of the class name",
+        "required": false,
+        "default": false
+      },
+      "customClientName": {
+        "description": "The custom name for the generated client class",
+        "required": false
path: packages/templates/clients/websocket/javascript/package.json
user: login: Adi-204
body: @derberg what about something like 
"description": "Add 'Client' suffix at the end of the class name. This option has no effect if 'customClientName' is specified.",
ok something more explicit?
created_at: 2025-04-23T16:59:14Z
author_association: MEMBER
diff_hunk: @@ -67,6 +67,15 @@
         "description": "The name of the generated client file",
         "required": false,
         "default": "client.js"
+      },
+      "appendClientSuffix": {
+        "description": "Add 'Client' suffix at the end of the class name",
+        "required": false,
+        "default": false
+      },
+      "customClientName": {
+        "description": "The custom name for the generated client class",
+        "required": false
path: packages/templates/clients/websocket/javascript/package.json
user: login: derberg
body: sounds good
created_at: 2025-04-23T17:04:20Z
author_association: MEMBER
diff_hunk: @@ -20,7 +20,8 @@ describe('testing if generated client match snapshot', () => {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFile
+        clientFileName: testOutputFile,
+        appendClientSuffix: false
path: packages/templates/clients/websocket/javascript/test/integration.test.js
user: login: Adi-204
body: @derberg added appendClientSuffix: true in one of the testcase. I didn't create 1 more testcase because I think it would be too many generations in tests. Or I should just add 1 more testcase. wdyt 🤔?
created_at: 2025-04-23T17:41:00Z
author_association: MEMBER
diff_hunk: @@ -20,7 +20,8 @@ describe('testing if generated client match snapshot', () => {
       forceWrite: true,
       templateParams: {
         server: 'echoServer',
-        clientFileName: testOutputFile
+        clientFileName: testOutputFile,
+        appendClientSuffix: false
path: packages/templates/clients/websocket/javascript/test/integration.test.js
user: login: derberg
body: it's ok it is now
created_at: 2025-04-24T16:17:46Z
author_association: MEMBER
diff_hunk: @@ -27,7 +27,7 @@ async function main() {
 
     while (true) {
       try {
-        await wsClient.sendEchoMessage(message);
+        await WSClient.sendEchoMessage(message, wsClient.websocket);
path: packages/templates/clients/websocket/javascript/example.js
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Method call changed from instance to static**

The method call for `sendEchoMessage` has been changed from an instance method to a static method requiring the websocket instance as a parameter. This represents a significant API change.



Please verify that this API change is intentional and documented elsewhere. Static methods provide different benefits but changing from instance to static methods can break backward compatibility for existing users.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check if this API change is documented in changelog or other documentation
fd -t f "CHANGELOG.md|BREAKING.md" --exec grep -l "sendEchoMessage" {} \;

# Check if there are any other example files that might need updating
fd -t f "example" -e js --exec grep -l "sendEchoMessage" {} \;

# Check implementation of sendEchoMessage in both Postman and Hoppscotch clients
fd -t f "client-postman.js|custom-client-hoppscotch.js" --exec grep -A 10 "sendEchoMessage" {} \;
```

Length of output: 302

---



</details>

**Document Breaking Change for sendEchoMessage**  
The call to `sendEchoMessage` was converted from an instance method (`wsClient.sendEchoMessage(message)`) to a static method (`WSClient.sendEchoMessage(message, wsClient.websocket)`). No changelog entry or documentation update was found.

Please add or update the following:

- CHANGELOG.md (or BREAKING.md) under “Breaking Changes” to note the new static signature and deprecation of the old instance API.  
- Library README or API docs with the updated usage example.  
- All other client templates/examples (e.g. Postman, Hoppscotch) to use the new static call.  
- (Optionally) A deprecation warning in code for the old instance method if we want to maintain backward‐compatibility.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-24T18:55:01Z
author_association: NONE
diff_hunk: @@ -6,7 +6,7 @@ You can test this template:
 2. Navigate to `packages/templates/clients/websocket/python`
 3. Install with `npm install` and run test with `npm run test`
 4. Go to test folder with `cd test`
-5. Install dependencies of the generated client: `pip install -r temp/snapshotTestResult/requirements.txt`
+5. Install dependencies of the generated client: `pip install -r temp/snapshotTestResult/custom_client_hoppscotch/requirements.txt`
 6. Start example script that uses a client library generated by the test: `python example.py`
 
-> By default this is testing against Postman echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change first line to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
path: packages/templates/clients/websocket/python/README.md
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Line number mismatch in instructions**

The README instructs to change line 16 for the client instantiation, but in the example file this is actually line 21.


```diff
-> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default, this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 21 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see the example still works but against a different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
> By default, this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 21 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see the example still works but against a different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
`````

</details>

<!-- suggestion_end -->

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 LanguageTool</summary>

[uncategorized] ~12-~12: Did you mean: “By default,”?
Context: ...ted by the test: `python example.py`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...`python example.py` again. You will see example still works but agains different API. T...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 475efcc
created_at: 2025-04-24T18:55:02Z
author_association: NONE
diff_hunk: @@ -6,7 +6,7 @@ You can test this template:
 2. Navigate to `packages/templates/clients/websocket/python`
 3. Install with `npm install` and run test with `npm run test`
 4. Go to test folder with `cd test`
-5. Install dependencies of the generated client: `pip install -r temp/snapshotTestResult/requirements.txt`
+5. Install dependencies of the generated client: `pip install -r temp/snapshotTestResult/custom_client_hoppscotch/requirements.txt`
 6. Start example script that uses a client library generated by the test: `python example.py`
 
-> By default this is testing against Postman echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change first line to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 16 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+> By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 21 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
path: packages/templates/clients/websocket/python/README.md
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Fix typos and improve clarity in the example instructions**  
There are a few minor grammar and spelling issues in the blockquote (missing comma after “By default”, typo “agains”, and a missing “that”/“the” for clarity). Please apply the following diff to correct these:

```diff
- > By default this is testing against Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` and change line 7 to `from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient` and line 21 `client = PostmanEchoWebSocketClientClient()` and run `python example.py` again. You will see example still works but agains different API. This is possible as both AsyncAPI documents have the same name of operation for sending messages: `sendEchoMessage` so each client generated has the same API.
+ > By default, this is testing against the Hoppscotch echo service. You can modify `packages/templates/clients/websocket/python/example.py` by updating line 7 to:
+ > ```python
+ > from temp.snapshotTestResult.client_postman.client import PostmanEchoWebSocketClientClient
+ > ```
+ > and line 21 to:
+ > ```python
+ > client = PostmanEchoWebSocketClientClient()
+ > ```
+ > Then run `python example.py` again. You will see that the example still works but against a different API. This is possible because both AsyncAPI documents share the same operation name for sending messages (`sendEchoMessage`), so each client generated has the same API.
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 LanguageTool</summary>

[uncategorized] ~12-~12: Did you mean: “By default,”?
Context: ...ted by the test: `python example.py`  > By default this is testing against Hoppscotch echo...

(BY_DEFAULT_COMMA)

---

[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...`python example.py` again. You will see example still works but agains different API. T...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-24T19:08:40Z
author_association: NONE
diff_hunk: @@ -27,7 +27,7 @@ async function main() {
 
     while (true) {
       try {
-        await wsClient.sendEchoMessage(message);
+        await WSClient.sendEchoMessage(message, wsClient.websocket);
path: packages/templates/clients/websocket/javascript/example.js
user: login: derberg
body: can you explain why this changed if the implementation of send message picks websocket instance if one is not provided
created_at: 2025-04-27T15:56:52Z
author_association: MEMBER
diff_hunk: @@ -27,7 +27,7 @@ async function main() {
 
     while (true) {
       try {
-        await wsClient.sendEchoMessage(message);
+        await WSClient.sendEchoMessage(message, wsClient.websocket);
path: packages/templates/clients/websocket/javascript/example.js
user: login: Adi-204
body: ![image](https://github.com/user-attachments/assets/9377263a-361c-4718-9d5e-bf75c73da4c6)

@derberg 
we set `this.websocket` on the instance (wsClient.websocket) when call `connect()`, but we never set it on the class itself. In a static method `this` refers to the `HoppscotchClient` itself, not to wsClient instance. 
So basically `HoppscotchClient.websocket` = undefined but `wsClient.websocket` is not undefined. 
Basically `this` in static method works differently. 
created_at: 2025-04-27T16:25:12Z
author_association: MEMBER
diff_hunk: @@ -27,7 +27,7 @@ async function main() {
 
     while (true) {
       try {
-        await wsClient.sendEchoMessage(message);
+        await WSClient.sendEchoMessage(message, wsClient.websocket);
path: packages/templates/clients/websocket/javascript/example.js
user: login: Adi-204
body: so | | operator doesn't really make sense because this.websocket will always be undefined and if socket not passed it will also be undefined. Should we remove this.websocket or some other approach to take we can discuss?
wdyt 🤔?
created_at: 2025-04-27T16:43:30Z
author_association: MEMBER
diff_hunk: @@ -27,7 +27,7 @@ async function main() {
 
     while (true) {
       try {
-        await wsClient.sendEchoMessage(message);
+        await WSClient.sendEchoMessage(message, wsClient.websocket);
path: packages/templates/clients/websocket/javascript/example.js
user: login: derberg
body: we could do something like 

```
  static sendEchoMessage(message, socket) {
    socket.send(JSON.stringify(message));
  }

  sendEchoMessage(message) {
    PostmanEchoWebSocketClientClient.sendEchoMessage(message, this.websocket);
  }
```

but then you need to make sure `PostmanEchoWebSocketClientClient` value is generated.

---

let us leave what you have already and please just create a followup issue
created_at: 2025-04-28T13:47:28Z
author_association: MEMBER

PR comments:
user: login: changeset-bot[bot]
created_at: 2025-04-23T06:11:57Z
body: ###  ⚠️  No Changeset found

Latest commit: 475efcc42fb912392cc5d05cd94f1953369a8be6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/Adi-204/generator/new/helper-getClientName?filename=.changeset/afraid-houses-sneeze.md&value=---%0A%22%40asyncapi%2Fgenerator-helpers%22%3A%20patch%0A%22%40asyncapi%2Ftemplate-dart-websocket-client%22%3A%20patch%0A%22%40asyncapi%2Ftemplate-js-websocket-client%22%3A%20patch%0A%22%40asyncapi%2Ftemplate-python-websocket-client%22%3A%20patch%0A---%0A%0Arefactor%3A%20improve%20%60getClientName%60%20helper%0A)


author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-04-23T06:12:00Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

```markdown
## Walkthrough

The updates introduce enhanced configurability for client class naming in JavaScript, Python, and Dart WebSocket client templates. The utility function `getClientName` now accepts parameters to control suffix appending and to specify a custom client name, returning the custom name immediately if provided. Corresponding generator parameters (`appendClientSuffix` and `customClientName`) are added to the template configurations. Template files and their test suites are updated to utilize these new options, including new test cases verifying custom naming behavior. Additionally, example imports and README instructions were updated to reflect changes in default client names and testing services.

## Changes

| Files/Paths                                                                                                                       | Change Summary                                                                                                                                                                                                                                         |
|---------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `packages/helpers/src/utils.js`                                                                                                 | Updated `getClientName` to accept `appendClientSuffix` and `customClientName` parameters, altering client name generation logic accordingly.                                                                                                          |
| `packages/helpers/test/utils.test.js`                                                                                           | Expanded tests for `getClientName` to cover scenarios with/without suffix and with a custom client name.                                                                                                                                                |
| `packages/templates/clients/websocket/javascript/package.json`<br>`.../python/package.json`<br>`.../dart/package.json`          | Added generator parameters: `appendClientSuffix` (boolean, default false) and `customClientName` (optional string) to JavaScript, Python, and Dart client template configurations.                                                                       |
| `packages/templates/clients/websocket/javascript/template/client.js.js`<br>`.../python/template/client.py.js`<br>`.../dart/template/client.dart.js` | Updated calls to `getClientName` to pass new parameters from template configuration.                                                                                                                                                                    |
| `packages/templates/clients/websocket/javascript/test/integration.test.js`                                                     | Modified and added tests to pass `appendClientSuffix` and test custom client name generation for JavaScript client template.                                                                                                                          |
| `packages/templates/clients/websocket/python/test/integration.test.js`                                                         | Modified and added tests to pass `appendClientSuffix` and test custom client name generation for Python client template.                                                                                                                               |
| `packages/templates/clients/websocket/dart/test/integration.test.js`                                                           | Added tests for Dart client template to verify `appendClientSuffix` and `customClientName` parameters, including new output path and shared output files constant.                                                                                     |
| `packages/templates/clients/websocket/javascript/README.md`                                                                     | Updated default echo service reference from Postman to Hoppscotch and reversed instructions for switching clients accordingly.                                                                                                                        |
| `packages/templates/clients/websocket/python/README.md`                                                                         | Updated dependency installation path and default echo service to Hoppscotch; adjusted instructions for switching to Postman client.                                                                                                                  |
| `packages/templates/clients/websocket/dart/README.md`                                                                           | Changed default generated client folder and testing service from Postman to Hoppscotch; updated example modification instructions to switch from Hoppscotch to Postman.                                                                                 |
| `packages/templates/clients/websocket/javascript/example.js`                                                                    | Changed import path to Hoppscotch client and modified `sendEchoMessage` call from instance method to static method with explicit websocket parameter.                                                                                                  |
| `packages/templates/clients/websocket/python/example.py`                                                                        | Replaced import and instantiation of Postman client with Hoppscotch client.                                                                                                                                                                            |
| `packages/templates/clients/websocket/dart/example.dart`                                                                        | Changed import and client instantiation from Postman Echo client to Hoppscotch client.                                                                                                                                                                  |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Generator
    participant Template
    participant Utils

    Generator->>Template: Passes params (appendClientSuffix, customClientName)
    Template->>Utils: getClientName(info, appendClientSuffix, customClientName)
    Utils-->>Template: Returns client name (custom or generated)
    Template-->>Generator: Uses client name in generated code
```

## Suggested labels

`ready-to-merge`

## Suggested reviewers

- magicmatatjahu  
- derberg  
- Florence-Njeri  
- jonaslagoni  
- asyncapi-bot-eve  

## Poem

> In the warren of code, a name takes flight,  
> With suffix or custom, it’s tailored just right.  
> JavaScript, Python, Dart, templates anew,  
> Tests hop along, checking what’s true.  
> Now clients are named as you wish or you will—  
> A rabbit’s delight, with naming skills to thrill!  
> 🐇✨
```

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=asyncapi/generator&utm_content=1513):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: asyncapi-bot
created_at: 2025-04-23T06:12:05Z
body: Hello, @changeset-bot[bot]! 👋🏼 

        I'm 🧞🧞🧞 Genie 🧞🧞🧞 from the magic lamp. Looks like somebody needs a hand!

        At the moment the following comments are supported in pull requests:

        - `/please-take-a-look` or `/ptal` - This comment will add a comment to the PR asking for attention from the reviewrs who have not reviewed the PR yet.
        - `/ready-to-merge` or `/rtm` - This comment will trigger automerge of PR in case all required checks are green, approvals in place and do-not-merge label is not added
        - `/do-not-merge` or `/dnm` - This comment will block automerging even if all conditions are met and ready-to-merge label is added
        - `/autoupdate` or `/au` - This comment will add `autoupdate` label to the PR and keeps your PR up-to-date to the target branch's future changes. Unless there is a merge conflict or it is a draft PR. (Currently only works for upstream branches.)
        - `/update` or `/u` - This comment will update the PR with the latest changes from the target branch. Unless there is a merge conflict or it is a draft PR. NOTE: this only updates the PR once, so if you need to update again, you need to call the command again.
author_association: CONTRIBUTOR
user: login: asyncapi-bot
created_at: 2025-04-23T06:12:10Z
body: Hello, @coderabbitai[bot]! 👋🏼 

        I'm 🧞🧞🧞 Genie 🧞🧞🧞 from the magic lamp. Looks like somebody needs a hand!

        At the moment the following comments are supported in pull requests:

        - `/please-take-a-look` or `/ptal` - This comment will add a comment to the PR asking for attention from the reviewrs who have not reviewed the PR yet.
        - `/ready-to-merge` or `/rtm` - This comment will trigger automerge of PR in case all required checks are green, approvals in place and do-not-merge label is not added
        - `/do-not-merge` or `/dnm` - This comment will block automerging even if all conditions are met and ready-to-merge label is added
        - `/autoupdate` or `/au` - This comment will add `autoupdate` label to the PR and keeps your PR up-to-date to the target branch's future changes. Unless there is a merge conflict or it is a draft PR. (Currently only works for upstream branches.)
        - `/update` or `/u` - This comment will update the PR with the latest changes from the target branch. Unless there is a merge conflict or it is a draft PR. NOTE: this only updates the PR once, so if you need to update again, you need to call the command again.
author_association: CONTRIBUTOR
user: login: coderabbitai[bot]
created_at: 2025-04-23T06:12:29Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
> [!TIP]
> For best results, initiate chat on the files or code changes.

@asyncapi-bot Thanks for the information about your available commands! I appreciate you sharing these helpful PR workflow options. These commands look really useful for managing pull requests efficiently.


<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@asyncapi-bot Thanks for the information about your available commands! I appreciate you sharing these helpful PR workflow options. These commands look really useful for managing pull requests efficiently.</answer></rawResChunk> -->
author_association: NONE
user: login: Adi-204
created_at: 2025-04-23T06:40:57Z
body: @derberg any more suggestion? 
What are we planning for `js` client generations structure. In `python` and `dart` (which not merge yet) both have different folders inside `temp\snapshotTestResult` but in `js` we have directly files. For consistency purpose should we make changes in js also. we can create other issue and someone can work on it. wdyt 🤔?
author_association: MEMBER
user: login: Adi-204
created_at: 2025-04-23T16:00:13Z
body: @nightknighto changes done! @derberg any suggestion from your side?
author_association: MEMBER
user: login: Adi-204
created_at: 2025-04-24T16:32:46Z
body: @derberg yes I agree it make sense 👍.
author_association: MEMBER
user: login: derberg
created_at: 2025-04-24T17:52:40Z
body: can you update this PR then? or you prefer a followup?
author_association: MEMBER
user: login: Adi-204
created_at: 2025-04-24T18:06:31Z
body: @derberg yes I can make your changes and can I also make channges in dart client adding this 2 parameters in that one as it is merged. wdyt 🤔? If it is easy to review for you then only. 
author_association: MEMBER
user: login: derberg
created_at: 2025-04-24T18:10:47Z
body: sure

btw, another thing that must be replicated in 3 different places - something to think about
author_association: MEMBER
user: login: Adi-204
created_at: 2025-04-24T19:02:45Z
body: @derberg summary of my last commit changes - 
1. Add 2 params in dart client also. Things are working fine.

![image](https://github.com/user-attachments/assets/f3d851fc-22ef-4653-b5af-d028c95b92cb)

2. Changes done in `example.js` of js client. Their was also one issue as `sendEchoMessage` was changed to static method but it was called like a normal class function so changed that code to - `await WSClient.sendEchoMessage(message, wsClient.websocket);`

![image](https://github.com/user-attachments/assets/63ad4d94-e506-4aa6-8492-99b1879bd476)

3. Changes done in `example.py` of python client. The location of 1 import statement `from temp.snapshotTestResult.custom_client_hoppscotch.client import HoppscotchClient` was wrong so changed it. But we still have an warning because in generated client inside function `send_message_static` we have written `HoppscotchEchoWebSocketClient` hardcoded but import for it is not written in generated file. Not sure how to fix this hence I didn't change anything for now and wait for discussion.

![image](https://github.com/user-attachments/assets/18230ba2-9424-4ea8-b466-a037fab685d8)

Didn't change anything in microcks for now because I think we should wait to solve issue - https://github.com/asyncapi/generator/issues/1507 so that we can check properly the new changes done are working or not. 

 I hope this comment makes your review life easy 😄!
author_association: MEMBER
user: login: sonarqubecloud[bot]
created_at: 2025-04-24T19:06:22Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=asyncapi_generator&pullRequest=1513) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=asyncapi_generator&pullRequest=1513&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=asyncapi_generator&pullRequest=1513&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_generator&pullRequest=1513&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=asyncapi_generator&pullRequest=1513&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=asyncapi_generator&pullRequest=1513&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=asyncapi_generator&pullRequest=1513)


author_association: NONE
user: login: derberg
created_at: 2025-04-28T13:47:49Z
body: /rtm
author_association: MEMBER
user: login: derberg
created_at: 2025-05-06T07:44:43Z
body: @allcontributors please add @Adi-204 for bug, code, ideas, infra, review, test, doc
author_association: MEMBER
user: login: allcontributors[bot]
created_at: 2025-05-06T07:44:52Z
body: @derberg 

I've put up [a pull request](https://github.com/asyncapi/generator/pull/1530) to add @Adi-204! :tada:
author_association: CONTRIBUTOR