Skip to content

Conversation

@lightning-sagar
Copy link
Contributor

@lightning-sagar lightning-sagar commented Nov 25, 2025

Description

This PR fixes an issue where template parameters with a default value of false (e.g., singleFile) were not being applied, causing them to appear as undefined inside templates.

The problem was caused by this check:

 const defaultValues = Object.keys(parameters || {}).filter(key => parameters[key].default);

Since false is falsy, it was incorrectly ignored.
The fix updates the condition to properly detect all default values:

const defaultValues = Object.keys(parameters || {}).filter(key => parameters[key].default !== undefined);

How I verified the fix


Related issue(s)

Fixes #1768

Summary by CodeRabbit

  • Bug Fixes

    • Default value detection now correctly treats falsy defaults (0, false, "") as defined so they are applied reliably.
  • New Features

    • Added per-schema compilation and single-schema validation utilities for message schema workflows, and adjusted validation flows to return structured results.
  • Documentation

    • Updated contributor and onboarding guidance.
  • Chores

    • Consolidated shared test configuration and moved local test settings into directory configs.
  • Tests

    • Expanded and adapted tests to cover new compile/validate behaviors and error cases.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Nov 25, 2025

⚠️ No Changeset found

Latest commit: 802b021

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.

This PR includes no changesets

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

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@asyncapi-bot
Copy link
Contributor

What reviewer looks at during PR review

The following are ideal points maintainers look for during review. Reviewing these points yourself beforehand can help streamline the review process and reduce time to merge.

  1. PR Title: Use a concise title that follows our Conventional Commits guidelines and clearly summarizes the change using imperative mood (it means spoken or written as if giving a command or instruction, like "add new helper for listing operations")

    Note - In Generator, prepend feat: or fix: in PR title only when PATCH/MINOR release must be triggered.

  2. PR Description: Clearly explain the issue being solved, summarize the changes made, and mention the related issue.

    Note - In Generator, we use Maintainers Work board to track progress. Ensure the PR Description includes Resolves #<issue-number> or Fixes #<issue-number> this will automatically close the linked issue when the PR is merged and helps automate the maintainers workflow.

  3. Documentation: Update the relevant Generator documentation to accurately reflect the changes introduced in the PR, ensuring users and contributors have up-to-date guidance.

  4. Comments and JSDoc: Write clear and consistent JSDoc comments for functions, including parameter types, return values, and error conditions, so others can easily understand and use the code.

  5. DRY Code: Ensure the code follows the Don't Repeat Yourself principle. Look out for duplicate logic that can be reused.

  6. Test Coverage: Ensure the new code is well-tested with meaningful test cases that pass consistently and cover all relevant edge cases.

  7. Commit History: Contributors should avoid force-pushing as much as possible. It makes it harder to track incremental changes and review the latest updates.

  8. Template Design Principles Alignment: While reviewing template-related changes in the packages/ directory, ensure they align with the Assumptions and Principles. If any principle feels outdated or no longer applicable, start a discussion these principles are meant to evolve with the project.

  9. Reduce Scope When Needed: If an issue or PR feels too large or complex, consider splitting it and creating follow-up issues. Smaller, focused PRs are easier to review and merge.

  10. Bot Comments: As reviewers, check that contributors have appropriately addressed comments or suggestions made by automated bots. If there are bot comments the reviewer disagrees with, react to them or mark them as resolved, so the review history remains clear and accurate.

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Walkthrough

Changed default-detection in the template config loader: parameters are now treated as having a declared default if they explicitly include a default property (including falsy values like false, 0, or "") by using Object.hasOwn instead of a truthy check.

Changes

Cohort / File(s) Summary
Default detection change
apps/generator/lib/templates/config/loader.js
Replace truthy check on parameters[key].default with Object.hasOwn(parameters[key], 'default') to detect declared defaults including falsy values; no other logic or control flow altered.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify the Object.hasOwn usage (compatibility / polyfill concerns) and that it targets only the intended object shapes.
  • Check or add tests for falsy defaults: false, 0, "".
  • Confirm lazy-default getters still behave as expected in downstream consumers.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning While the primary fix targets template parameter defaults (apps/generator/lib/templates/config/loader.js), the PR includes extensive unrelated changes to workflows, documentation, Jest configuration, and keeper package refactoring that fall outside the stated objective. Separate out-of-scope changes (workflows, documentation, keeper refactoring, Jest configs) into distinct PRs focused on the template parameter fix and test coverage.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and clearly summarizes the main change: fixing detection of falsy default values (specifically false) in template parameters.
Linked Issues check ✅ Passed The PR addresses the core requirement from issue #1768: correctly detecting and injecting default values set to false into template context, enabling conditional logic to work properly.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@lightning-sagar
Copy link
Contributor Author

lightning-sagar commented Nov 26, 2025

Note: After fixing this and changing the value from the string "false" to the boolean false, the CSS/JS will generate correctly🫡

By using asyncapi generate fromTemplate test/spec/asyncapi_v3.yml ./ -o dupa --use-new-generator --force-write -p singleFile="false" this command not by -p singleFile=false

@Jatin24062005
Copy link

@lightning-sagar I reviewed the changes you made. Using: filter(key => parameters[key].default !== undefined); which i say is not bad does fix the false issue, but it may introduce new problems. For example, templates can intentionally set: "default": null or even: "default": undefined In those cases, !== undefined would incorrectly treat these values as valid defaults. to Avoid that problem @derberg Solution to use const defaultValues = Object.keys(parameters || {}).filter(key => hasOwnProperty('default')); but it also have a major issue This checks whether the template author actually defined the default field, regardless of its value. It avoids accidentally ignoring defaults like false, 0, or "".

We avoid using obj.hasOwnProperty() directly because it can throw errors if the object does not inherit from Object.prototype. So to Avoid crashing and error we can use explicit version of js something like const defaultValues = Object.keys(parameters || {}).filter(key => Object.prototype.hasOwnProperty.call(parameters[key], "default") );
this guarantees no crashes and works with all template config objects.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

image

@lightning-sagar
Copy link
Contributor Author

lightning-sagar commented Dec 6, 2025

yes, that makes sense. your solution is definitely more robust.
using Object.prototype.hasOwnProperty.call(...) handles both JSON and JS-generated templates safely, and avoids any issues with falsy defaults or prototype-less objects. thanks for the help!

update: I switched to Object.hasOwn(...) initially since it reads cleaner.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/generator/lib/templates/config/loader.js (1)

48-56: Default detection fix looks correct; consider small cleanup and Object.hasOwn if supported

The switch to Object.prototype.hasOwnProperty.call(parameters[key], "default") correctly treats any explicitly declared default (including false, 0, '', null, undefined) as a default and fixes the original false-is-ignored bug. 👍

Two small, optional refinements:

  1. Normalize parameters once to avoid repeating || {} and slightly tighten the types:
 function loadDefaultValues(templateConfig, templateParams) {
-    const parameters = templateConfig.parameters;
-    const defaultValues = Object.keys(parameters || {}).filter(key => Object.prototype.hasOwnProperty.call(parameters[key],"default"));
+    const parameters = templateConfig.parameters || {};
+    const defaultValues = Object.keys(parameters).filter(key =>
+        Object.prototype.hasOwnProperty.call(parameters[key], 'default')
+    );
  1. If your minimum Node/JS runtime supports it and you want to satisfy Sonar, you can switch to Object.hasOwn in both places:
-    const defaultValues = Object.keys(parameters).filter(key =>
-        Object.prototype.hasOwnProperty.call(parameters[key], 'default')
-    );
+    const defaultValues = Object.keys(parameters).filter(key =>
+        Object.hasOwn(parameters[key], 'default')
+    );
 
-    defaultValues.filter(dv => !Object.prototype.hasOwnProperty.call(templateParams, dv)).forEach(dv =>
+    defaultValues.filter(dv => !Object.hasOwn(templateParams, dv)).forEach(dv =>
         Object.defineProperty(templateParams, dv, {
             enumerable: true,
             get() {
                 return parameters[dv].default;
             }
         })
     );

Please double‑check that Object.hasOwn is available in all Node versions you support before adopting this; otherwise the current implementation is fine and you may just want to tune the static‑analysis rule instead.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a2d80f and a45bc1f.

📒 Files selected for processing (1)
  • apps/generator/lib/templates/config/loader.js (1 hunks)
🧰 Additional context used
🪛 GitHub Check: SonarCloud Code Analysis
apps/generator/lib/templates/config/loader.js

[warning] 49-49: Use 'Object.hasOwn()' instead of 'Object.prototype.hasOwnProperty.call()'.

See more on https://sonarcloud.io/project/issues?id=asyncapi_generator&issues=AZr1oGE4FDjduF-gLNra&open=AZr1oGE4FDjduF-gLNra&pullRequest=1769

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Test generator as dependency with Node 20
  • GitHub Check: Acceptance tests for generated templates
  • GitHub Check: Test generator as dependency with Node 18
  • GitHub Check: Test NodeJS PR - macos-latest
  • GitHub Check: Test NodeJS PR - windows-latest
  • GitHub Check: Test NodeJS PR - ubuntu-latest

derberg and others added 13 commits December 7, 2025 12:15
…S` websocket client (asyncapi#1747)

Co-authored-by: Adi-204 <[email protected]>
Co-authored-by: Adi Boghawala <[email protected]>
Co-authored-by: Chan <[email protected]>
Co-authored-by: Lukasz Gornicki <[email protected]>
…i#1753)

Co-authored-by: kartikayy007 <[email protected]>
Co-authored-by: Adi Boghawala <[email protected]>
Co-authored-by: Lukasz Gornicki <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (8)
packages/templates/clients/websocket/javascript/template/client.js.js (2)

13-13: Consider a defensive fallback when params.asyncapiFileDir is absent

If params.asyncapiFileDir is not set, this will produce an invalid "undefined/asyncapi.yaml" path. If the param isn’t guaranteed required by the template config, consider adding a simple fallback to keep the generated code usable:

-  const asyncapiFilepath = `${params.asyncapiFileDir}/asyncapi.yaml`;
+  const asyncapiFilepath = params.asyncapiFileDir
+    ? `${params.asyncapiFileDir}/asyncapi.yaml`
+    : 'asyncapi.yaml';

21-24: DependencyProvider wiring looks correct; validate asyncapi path behavior at runtime

The additionalDependencies wiring looks good and the ordering ensures path is required before asyncapiFilepath is defined. One thing to double‑check: when asyncapiFileDir is absolute, path.resolve(__dirname, '<abs>/asyncapi.yaml') will effectively ignore __dirname and hard‑code the generation‑time path, which may not match where the spec lives when the generated client is consumed. Please confirm that this is the intended behavior (i.e., the spec path is expected to be stable across environments).

The use of single quotes inside the generated code strings is also consistent with the existing template style. Based on learnings, ...

packages/templates/clients/websocket/javascript/.ageneratorrc (1)

18-23: Quote the default value for YAML clarity.

The bare dot in default: . should be quoted as default: "." to make it explicit that this is a string value representing the current directory, avoiding any potential YAML parsing ambiguity.

Apply this diff:

   asyncapiFileDir:
     description: >-
       Custom location of the AsyncAPI file that you provided as an input in generation. By default it is located in the
       root of the output directory
     required: false
-    default: .
+    default: "."
apps/keeper/CHANGELOG.md (1)

7-7: Wrap bare URLs in angle brackets for markdown compliance.

The URLs should be wrapped in angle brackets to comply with markdown linting rules (MD034).

Apply this pattern for each bare URL:

-- ced1404: Pushing of release https://github.com/asyncapi/generator/pull/1747 that failed due to pipeline issues.
+- ced1404: Pushing of release <https://github.com/asyncapi/generator/pull/1747> that failed due to pipeline issues.

Also applies to: 13-13, 19-19

packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js (1)

26-29: Consider adding per-operation error context.

If schema compilation fails for a specific operation, the current error handling (line 33) doesn't indicate which operationId caused the failure, making debugging harder.

Consider wrapping each iteration:

   for (const operationId of this.sendOperationsId) {
-    this.compiledSchemas[operationId] = await compileSchemasByOperationId(asyncapiFilepath, operationId);
+    try {
+      this.compiledSchemas[operationId] = await compileSchemasByOperationId(asyncapiFilepath, operationId);
+    } catch (error) {
+      console.error(`Error compiling schema for operation '${operationId}':`, error);
+      throw error;
+    }
   }
packages/components/src/components/SendOperations.js (2)

74-100: Inconsistent return values from static method.

When schemas is empty/missing, the method returns { isValid: true } (line 78). However, when schemas are provided and validation is performed, the method doesn't return anything (implicitly returns undefined). This inconsistency could confuse callers trying to check validation results.

Consider returning a consistent result object:

     for(const compiledSchema of schemas){
       const validationResult = validateMessage(compiledSchema, message);
       if (validationResult.isValid) {
         isValid = true;
         socket.send(JSON.stringify(message));
-        break;
+        return { isValid: true };
       } else {
         if (validationResult.validationErrors) {
           allValidationErrors.push(...validationResult.validationErrors);
         }
       }
     }
+    if (!isValid) {
+      console.error('Validation errors:', JSON.stringify(allValidationErrors, null, 2));
+      return { isValid: false, errors: allValidationErrors };
+    }
   } catch (error) {
     console.error('Error sending ${methodName} message:', error);
+    return { isValid: false, error };
   }
 }

56-63: Instance method ignores static method return value.

The instance method is marked async but doesn't await the static method call (line 62), and the result is discarded. If validation fails or sending throws, the caller has no way to know.

Consider returning/propagating the result:

 async ${methodName}(message){
   if(!this.websocket){
     throw new Error('WebSocket connection not established. Call connect() first.');
   }
   await this.compileOperationSchemas();
   const schemas = this.compiledSchemas['${methodName}'];
-  ${clientName}.${methodName}(message, this.websocket, schemas);
+  return ${clientName}.${methodName}(message, this.websocket, schemas);
 }
apps/keeper/test/index.test.js (1)

64-70: Consider adding test for null message.

The test covers undefined message (line 65), but the JSDoc in validateMessage claims it throws for "null/undefined". Consider adding a test for null to ensure consistent behavior, or update the implementation to handle null explicitly.

test('should throw error if message is null', () => {
  expect(() => validateMessage(compiledSchema, null)).toThrow('Invalid "message" parameter');
});
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a45bc1f and 4046fa5.

⛔ Files ignored due to path filters (4)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/components/test/components/__snapshots__/DependencyProvider.test.js.snap is excluded by !**/*.snap
  • packages/components/test/components/__snapshots__/SendOperations.test.js.snap is excluded by !**/*.snap
  • packages/templates/clients/websocket/test/integration-test/__snapshots__/integration.test.js.snap is excluded by !**/*.snap
📒 Files selected for processing (45)
  • .github/workflows/release-with-changesets.yml (4 hunks)
  • .github/workflows/update-docs-on-docs-commits.yml (1 hunks)
  • CONTRIBUTING.md (3 hunks)
  • Development.md (2 hunks)
  • apps/generator/CHANGELOG.md (1 hunks)
  • apps/generator/jest.config.js (1 hunks)
  • apps/generator/lib/templates/config/loader.js (1 hunks)
  • apps/generator/package.json (1 hunks)
  • apps/keeper/CHANGELOG.md (1 hunks)
  • apps/keeper/jest.config.js (1 hunks)
  • apps/keeper/jest.setup.js (0 hunks)
  • apps/keeper/package.json (2 hunks)
  • apps/keeper/src/index.js (2 hunks)
  • apps/keeper/src/utils.js (0 hunks)
  • apps/keeper/test/__fixtures__/asyncapi-message-validation.yml (1 hunks)
  • apps/keeper/test/index.test.js (2 hunks)
  • jest.config.base.js (1 hunks)
  • packages/components/jest.config.js (1 hunks)
  • packages/components/package.json (0 hunks)
  • packages/components/src/components/DependencyProvider.js (1 hunks)
  • packages/components/src/components/SendOperations.js (1 hunks)
  • packages/helpers/jest.config.js (1 hunks)
  • packages/helpers/package.json (0 hunks)
  • packages/templates/clients/kafka/java/quarkus/.ageneratorrc (1 hunks)
  • packages/templates/clients/kafka/java/quarkus/jest.config.js (1 hunks)
  • packages/templates/clients/kafka/java/quarkus/package.json (0 hunks)
  • packages/templates/clients/kafka/test/integration-test/jest.config.js (1 hunks)
  • packages/templates/clients/kafka/test/integration-test/package.json (0 hunks)
  • packages/templates/clients/websocket/dart/jest.config.js (1 hunks)
  • packages/templates/clients/websocket/dart/package.json (0 hunks)
  • packages/templates/clients/websocket/java/quarkus/jest.config.js (1 hunks)
  • packages/templates/clients/websocket/java/quarkus/package.json (0 hunks)
  • packages/templates/clients/websocket/javascript/.ageneratorrc (1 hunks)
  • packages/templates/clients/websocket/javascript/components/ClientClass.js (2 hunks)
  • packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js (1 hunks)
  • packages/templates/clients/websocket/javascript/components/Constructor.js (2 hunks)
  • packages/templates/clients/websocket/javascript/jest.config.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/python/jest.config.js (1 hunks)
  • packages/templates/clients/websocket/python/package.json (0 hunks)
  • packages/templates/clients/websocket/test/integration-test/jest.config.js (1 hunks)
  • packages/templates/clients/websocket/test/integration-test/package.json (0 hunks)
  • packages/templates/clients/websocket/test/javascript/jest.config.js (1 hunks)
  • packages/templates/clients/websocket/test/javascript/package.json (0 hunks)
💤 Files with no reviewable changes (11)
  • apps/keeper/src/utils.js
  • packages/templates/clients/websocket/test/integration-test/package.json
  • packages/templates/clients/kafka/java/quarkus/package.json
  • packages/helpers/package.json
  • packages/templates/clients/websocket/test/javascript/package.json
  • apps/keeper/jest.setup.js
  • packages/templates/clients/websocket/dart/package.json
  • packages/templates/clients/websocket/python/package.json
  • packages/templates/clients/kafka/test/integration-test/package.json
  • packages/components/package.json
  • packages/templates/clients/websocket/java/quarkus/package.json
✅ Files skipped from review due to trivial changes (2)
  • CONTRIBUTING.md
  • packages/templates/clients/kafka/java/quarkus/.ageneratorrc
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/generator/lib/templates/config/loader.js
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-05-12T14:57:35.024Z
Learnt from: Adi-204
Repo: asyncapi/generator PR: 1557
File: packages/templates/clients/websocket/javascript/components/SendOperation.js:21-21
Timestamp: 2025-05-12T14:57:35.024Z
Learning: In the AsyncAPI generator templates, particularly in the JavaScript WebSocket client, single quotes are used for string literals inside template-generated code (which is itself inside backticks) to preserve template placeholders like ${variable} as literal text in the generated code output.

Applied to files:

  • packages/templates/clients/websocket/javascript/template/client.js.js
  • packages/templates/clients/websocket/javascript/.ageneratorrc
📚 Learning: 2025-04-23T09:18:38.333Z
Learnt from: derberg
Repo: asyncapi/generator PR: 1512
File: packages/templates/clients/websocket/javascript/components/AvailableOperations.js:10-15
Timestamp: 2025-04-23T09:18:38.333Z
Learning: In the asyncapi/generator repository, keys aren't required when mapping over operations array in the AvailableOperations component, contrary to the typical React pattern.

Applied to files:

  • packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js
📚 Learning: 2025-05-12T14:23:48.919Z
Learnt from: derberg
Repo: asyncapi/generator PR: 1551
File: apps/generator/docs/generator-template.md:45-73
Timestamp: 2025-05-12T14:23:48.919Z
Learning: AsyncAPI 3.0.0 specification introduces significant structural changes from 2.x:
1. Operations become top-level elements with action property (send/receive) and references to channels
2. Channels use 'address' for the topic path instead of having nested publish/subscribe operations
3. Messages are defined under a 'messages' container in channels
4. The specification decouples operations, channels and messages to improve reusability
5. Servers can use a 'host' property

Applied to files:

  • packages/components/src/components/SendOperations.js
📚 Learning: 2025-05-12T14:23:48.919Z
Learnt from: derberg
Repo: asyncapi/generator PR: 1551
File: apps/generator/docs/generator-template.md:45-73
Timestamp: 2025-05-12T14:23:48.919Z
Learning: AsyncAPI 3.0.0 specification introduces significant structural changes from 2.x:
1. Operations become top-level elements with references to channels
2. Channels use 'address' for the topic path instead of having nested publish/subscribe
3. Messages are defined under a 'messages' container in channels
4. Servers can use a 'host' property

Applied to files:

  • packages/components/src/components/SendOperations.js
🧬 Code graph analysis (16)
packages/templates/clients/kafka/java/quarkus/jest.config.js (10)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/components/ClientClass.js (2)
packages/templates/clients/websocket/javascript/components/Constructor.js (1)
  • Constructor (3-27)
packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js (1)
  • CompileOperationSchemas (3-40)
packages/templates/clients/websocket/javascript/template/client.js.js (1)
packages/components/src/components/DependencyProvider.js (1)
  • DependencyProvider (106-116)
packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js (1)
packages/templates/clients/websocket/javascript/template/client.js.js (1)
  • sendOperations (12-12)
packages/components/src/components/SendOperations.js (2)
packages/templates/clients/websocket/javascript/template/client.js.js (1)
  • clientName (10-10)
packages/templates/clients/websocket/python/components/ClientClass.js (1)
  • clientName (13-13)
packages/templates/clients/websocket/dart/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
apps/generator/jest.config.js (3)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/test/integration-test/jest.config.js (11)
apps/generator/jest.config.js (1)
  • baseConfig (2-2)
apps/keeper/jest.config.js (1)
  • baseConfig (1-1)
packages/components/jest.config.js (1)
  • baseConfig (1-1)
packages/helpers/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/kafka/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/dart/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/java/quarkus/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/javascript/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/python/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/integration-test/jest.config.js (1)
  • baseConfig (1-1)
packages/templates/clients/websocket/test/javascript/jest.config.js (1)
  • baseConfig (1-1)
apps/keeper/src/index.js (1)
apps/keeper/src/utils.js (3)
  • asyncapi (16-16)
  • parseAsyncAPIDocumentFromFile (12-24)
  • parseAsyncAPIDocumentFromFile (12-24)
apps/keeper/test/index.test.js (1)
apps/keeper/src/index.js (5)
  • compileSchema (12-14)
  • validateMessage (70-85)
  • compiledSchemas (26-26)
  • compileSchemas (22-31)
  • compileSchemasByOperationId (41-59)
🪛 markdownlint-cli2 (0.18.1)
apps/generator/CHANGELOG.md

7-7: Bare URL used

(MD034, no-bare-urls)


13-13: Bare URL used

(MD034, no-bare-urls)


19-19: Bare URL used

(MD034, no-bare-urls)

apps/keeper/CHANGELOG.md

7-7: Bare URL used

(MD034, no-bare-urls)


13-13: Bare URL used

(MD034, no-bare-urls)


19-19: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Test generator as dependency with Node 18
  • GitHub Check: Test generator as dependency with Node 20
  • GitHub Check: Acceptance tests for generated templates
  • GitHub Check: Test NodeJS PR - windows-latest
  • GitHub Check: Test NodeJS PR - ubuntu-latest
  • GitHub Check: Test NodeJS PR - macos-latest
🔇 Additional comments (36)
apps/generator/package.json (1)

3-3: Verify version bump strategy aligns with release plan.

The version is bumped from 2.8.4 to 2.11.0, which skips intermediate minor versions. While the CHANGELOG includes entries for 2.10.0 and 2.9.0, confirm this version bump is intentional and aligns with your release and deployment strategy.

apps/generator/CHANGELOG.md (1)

21-32: Verify the loader.js fix implementation directly in the repository.

The CHANGELOG documents a 2.8.4 release with WebSocket handler improvements. However, per the PR summary, the main objective is to fix template parameter default value detection in apps/generator/lib/templates/config/loader.js. Confirm that this file has been updated to use Object.prototype.hasOwnProperty.call(parameters[key], "default") or Object.hasOwn(parameters[key], "default") to correctly detect defined defaults including falsy values (false, 0, "").

packages/templates/clients/websocket/javascript/.ageneratorrc (2)

11-14: This parameter benefits from the PR fix.

The appendClientSuffix parameter with default: false (line 14) would have been incorrectly excluded before this PR's fix in loader.js. With the corrected default-value detection logic, this false default will now properly inject into the template context.


28-29: The createAsyncapiFile hook exists and is properly exported by the @asyncapi/generator-hooks package. It correctly handles the asyncapiFileDir parameter, allowing template users to customize the output location of the generated AsyncAPI file. The hook configuration syntax in this file is correct.

Development.md (1)

5-23: Excellent addition for new contributors!

The new onboarding section with the webinar recommendation provides valuable context about the Generator's architecture and development workflow. This will help new contributors understand the project more effectively before diving into development.

.github/workflows/release-with-changesets.yml (3)

32-32: Good update to use macos-latest.

Using macos-latest instead of the pinned macos-13 ensures the workflow automatically benefits from the latest macOS runner improvements and keeps the CI environment current.


81-84: Excellent security practice with explicit permissions.

Adding explicit permissions for the release job follows GitHub Actions security best practices and implements the principle of least privilege. The id-token: write permission likely enables provenance or signing capabilities.


98-100: Verify the temporary action reference is intentional.

The action reference uses a personal fork (derberg/.github-asyncapi) with branch fixnodereelase. This branch name suggests it may be a temporary fix (likely "fix-node-release"), and using a personal repository fork in a production workflow is unusual.

Please confirm:

  1. Is this change intentional and necessary for this PR?
  2. Should this reference be reverted to the organization repository once the fix is merged upstream?
  3. Is there a tracking issue for migrating back to the org repository?
.github/workflows/update-docs-on-docs-commits.yml (1)

25-30: Clean implementation of centralized node version management.

The addition of the node-version input sourced from workflow variables enables centralized control of the Node.js version used across workflows. The NOSONAR comment appropriately documents the intentional use of the master branch reference.

packages/templates/clients/websocket/dart/jest.config.js (1)

1-13: Consistent Jest configuration following repository patterns.

This Jest configuration correctly extends the base config and customizes settings for JavaScript/JSX testing with babel-jest. The pattern is consistent with other template Jest configurations throughout the repository.

packages/templates/clients/kafka/java/quarkus/jest.config.js (1)

1-13: Consistent Jest configuration following repository patterns.

This Jest configuration correctly extends the base config with appropriate settings for JavaScript/JSX testing. The relative path and configuration structure align with repository standards.

packages/helpers/jest.config.js (1)

1-5: Clean and minimal Jest configuration.

This configuration appropriately extends the base config without unnecessary overrides, which is suitable for the helpers package. The pattern is consistent with the repository's testing setup.

packages/components/src/components/DependencyProvider.js (1)

19-19: Ensure @asyncapi/keeper is declared as a dependency in package.json.

The @asyncapi/keeper package exists on npm and provides message validation functionality via the compileSchemasByOperationId and validateMessage functions being imported. Confirm this package is listed in the project's dependencies.

packages/templates/clients/websocket/test/javascript/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration correctly extends the base config and applies appropriate overrides for JavaScript/JSX test files.

packages/templates/clients/websocket/javascript/components/ClientClass.js (2)

5-5: LGTM! Import added correctly.

The new component import follows the existing pattern.


13-13: LGTM! Proper prop forwarding for schema compilation.

The sendOperations prop is correctly passed to both the Constructor (line 13) and the new CompileOperationSchemas component (line 27), enabling runtime schema compilation functionality.

Also applies to: 27-27

packages/templates/clients/websocket/python/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration correctly extends the base config with appropriate path depth for this package location.

apps/keeper/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration correctly extends the base config with the appropriate path for the keeper app.

packages/components/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration follows the established pattern and correctly references the base config.

packages/templates/clients/kafka/test/integration-test/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration correctly extends the base config with the appropriate path depth (7 levels) for this nested location.

packages/templates/clients/websocket/java/quarkus/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration correctly extends the base config for the Java Quarkus WebSocket client tests.

packages/templates/clients/websocket/javascript/jest.config.js (1)

1-13: LGTM! Standard Jest configuration.

The configuration correctly extends the base config with the appropriate path (6 levels up) for the JavaScript WebSocket client.

jest.config.base.js (1)

12-24: LGTM! Clean abstraction for shared Jest configuration.

The path computation logic correctly handles both same-level and nested consumers. The function provides centralized nimma module mappings while allowing consumers to override or extend via options.moduleNameMapper.

packages/templates/clients/websocket/test/integration-test/jest.config.js (1)

1-13: LGTM! Consistent with the established Jest configuration pattern.

The configuration correctly extends the base config and adds appropriate JSX support for integration tests.

apps/generator/jest.config.js (1)

2-10: LGTM! Clean migration to base configuration pattern.

The base config integration correctly preserves the nunjucks-filters mapping while delegating nimma mappings to the shared base configuration. The spread order ensures local overrides take precedence.

packages/templates/clients/websocket/javascript/components/Constructor.js (1)

19-21: LGTM! Fields correctly support schema compilation feature.

The new fields (compiledSchemas, schemasCompiled, sendOperationsId) are properly initialized and integrate with the compileOperationSchemas() method added by CompileOperationSchemas component.

apps/keeper/package.json (3)

35-35: LGTM! babel-jest version matches jest version.

The addition of babel-jest ^27.3.1 aligns with the existing jest ^27.3.1 dependency and supports the Babel transpilation configured in the babel field. The Jest configuration migration to a separate jest.config.js file (confirmed in relevant snippets) completes the pattern.


16-20: Verify LICENSE file exists in the repository.

The files field references LICENSE (line 19), but confirmation that this file exists in the keeper directory or at the repository root is needed before publication.


29-29: Verify that all keeper source code properly migrated to use the ajv API.

The swap from @hyperjump/json-schema to ajv ^8.17.1 requires code updates since these libraries have different APIs. While ajv 8.17.1 (released July 2024) contains no breaking API changes, the migration from a different JSON Schema validator library requires confirming all keeper source code has been properly refactored.

Ensure:

  • All @hyperjump/json-schema imports have been removed from keeper source
  • Code properly uses ajv's validation API
  • Any custom validation logic has been refactored for ajv compatibility
packages/templates/clients/websocket/javascript/package.json (1)

15-17: Verify jest.config.js exists for this package.

The inline Jest configuration was removed (aligning with the base config pattern), but the corresponding jest.config.js file for this package is not in the review set. Please confirm that packages/templates/clients/websocket/javascript/jest.config.js exists and properly extends the base configuration.

apps/keeper/test/__fixtures__/asyncapi-message-validation.yml (1)

34-36: Confirm that all tests referencing this fixture have been updated for the field change.

The property was renamed from timestamp to messageId with a type change (string/date-time → number). Any test files that validate message payloads against asyncapi-message-validation.yml must have their expectations updated to reference messageId instead of timestamp, and type assertions must expect a number value.

apps/keeper/test/index.test.js (2)

29-36: LGTM!

Test correctly validates a message against the compiled schema and checks both isValid and validationErrors properties.


73-90: LGTM!

Good test coverage for compileSchemas utility, including validation that the output is an array of functions and proper error handling for invalid input types.

apps/keeper/src/index.js (3)

4-4: Consider potential schema caching behavior.

Ajv caches compiled schemas by their $id (or URI). If schemas with the same $id but different content are compiled over time, Ajv will return the cached version. This is typically fine, but worth noting if schemas evolve between calls.

Verify whether schemas in your AsyncAPI documents use $id properties, and if so, whether schema evolution is a concern for your use case.


41-59: LGTM!

The function has comprehensive error handling: validates operationId is a non-empty string, throws clear errors for missing operations, and gracefully handles operations with no messages. The payload filtering ensures only messages with schemas are compiled.


12-14: LGTM!

Simple and effective wrapper around Ajv's compile method. The JSDoc correctly documents that it throws if Ajv cannot compile the schema.

Comment on lines 70 to 73
export function validateMessage(compiledSchema, message) {
if (message === undefined) {
throw new Error(`Invalid "message" parameter: expected a value to validate, but received ${message}`);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

JSDoc/implementation mismatch for null message handling.

The JSDoc on line 68 states the function throws "When message parameter is null/undefined", but line 71 only checks for undefined. A null message would bypass this check and proceed to validation.

Either update the check to include null, or correct the JSDoc:

 export function validateMessage(compiledSchema, message) {
-  if (message === undefined) {
+  if (message === undefined || message === null) {
     throw new Error(`Invalid "message" parameter: expected a value to validate, but received ${message}`);
   }
🤖 Prompt for AI Agents
In apps/keeper/src/index.js around lines 70 to 73, the implementation only
checks for undefined but the JSDoc says the function throws for null/undefined;
update the runtime check to treat null the same as undefined (e.g., check
message === undefined || message === null or message == null) and adjust the
thrown Error message if needed so it correctly reports when message is null or
undefined.

Comment on lines 82 to 96
for(const compiledSchema of schemas){
const validationResult = validateMessage(compiledSchema, message);
if (validationResult.isValid) {
isValid = true;
socket.send(JSON.stringify(message));
break;
} else {
if (validationResult.validationErrors) {
allValidationErrors.push(...validationResult.validationErrors);
}
}
if (!isValid) {
console.error('Validation errors:', JSON.stringify(allValidationErrors, null, 2));
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: validateMessage is undefined in the generated code.

The generated JavaScript code calls validateMessage(compiledSchema, message) on line 83, but this function is never imported or defined in the generated client code. This will cause a ReferenceError at runtime when any schema validation is attempted.

You need to either:

  1. Import validateMessage from @asyncapi/keeper in the generated client, or
  2. Inline the validation logic directly in the generated code.

Additionally, the error logging on lines 93-95 is inside the for loop. This means validation errors are logged after each failed schema, rather than only when all schemas fail. Move the error logging outside the loop:

     for(const compiledSchema of schemas){
       const validationResult = validateMessage(compiledSchema, message);
       if (validationResult.isValid) {
         isValid = true;
         socket.send(JSON.stringify(message));
         break;
       } else {
         if (validationResult.validationErrors) {
           allValidationErrors.push(...validationResult.validationErrors);
         }
       }
-      if (!isValid) {
-        console.error('Validation errors:', JSON.stringify(allValidationErrors, null, 2));
-      }
     }
+    if (!isValid && allValidationErrors.length > 0) {
+      console.error('Validation errors:', JSON.stringify(allValidationErrors, null, 2));
+    }
🤖 Prompt for AI Agents
In packages/components/src/components/SendOperations.js around lines 82 to 96,
the code calls validateMessage(compiledSchema, message) which is not defined or
imported and therefore will throw a ReferenceError; import validateMessage from
"@asyncapi/keeper" at the top of this file (or alternatively inline the
validation logic here) and replace the call accordingly, and move the
console.error that logs allValidationErrors so it runs after the for loop (i.e.,
only when no schema set isValid to true) instead of inside the loop.

Comment on lines 20 to 35
async compileOperationSchemas() {
if (this.schemasCompiled) {
return;
}
try {
// Compile schemas for all send operations
for (const operationId of this.sendOperationsId) {
this.compiledSchemas[operationId] = await compileSchemasByOperationId(asyncapiFilepath, operationId);
}
this.schemasCompiled = true;
console.log('Schemas initialized successfully for operations:', this.sendOperationsId.join(', '));
} catch (error) {
console.error('Error initializing schemas:', error);
}
}`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Undefined variable asyncapiFilepath will cause runtime error.

Line 28 references asyncapiFilepath, but this variable is not defined anywhere in the generated code. This will throw a ReferenceError when the method is called.

Additionally, compileSchemasByOperationId is called but not imported, which will also cause a ReferenceError.

Please clarify:

  1. How should asyncapiFilepath be provided? Should it be:

    • A constructor parameter stored as this.asyncapiFilepath?
    • Passed as a parameter to compileOperationSchemas()?
    • A module-level import/constant?
  2. Where is compileSchemasByOperationId defined, and how should it be imported in the generated client code?

🤖 Prompt for AI Agents
In
packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js
around lines 20 to 35, the method references an undefined asyncapiFilepath and
an unimported compileSchemasByOperationId; update the component to accept and
store the asyncapiFilepath (add a constructor parameter and assign to
this.asyncapiFilepath) and use that instance property inside
compileOperationSchemas, and add/import the compileSchemasByOperationId helper
at the top of the file from the correct helper module (or expose it from the
codegen runtime) so the function call resolves; ensure compileOperationSchemas
uses await compileSchemasByOperationId(this.asyncapiFilepath, operationId) and
adjust any callers if you chose to change the constructor signature.

Comment on lines 25 to 34
try {
// Compile schemas for all send operations
for (const operationId of this.sendOperationsId) {
this.compiledSchemas[operationId] = await compileSchemasByOperationId(asyncapiFilepath, operationId);
}
this.schemasCompiled = true;
console.log('Schemas initialized successfully for operations:', this.sendOperationsId.join(', '));
} catch (error) {
console.error('Error initializing schemas:', error);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Error handling doesn't match JSDoc specification.

The JSDoc at line 18 states @throws {Error} If schema compilation fails for any operation, but the implementation catches all errors and only logs them (line 33) without re-throwing. This silently swallows errors, making debugging difficult and violating the documented contract.

Consider one of these approaches:

Option 1: Re-throw errors to match JSDoc

   } catch (error) {
     console.error('Error initializing schemas:', error);
+    throw error;
   }

Option 2: Update JSDoc to reflect actual behavior

- * @throws {Error} If schema compilation fails for any operation
+ * Logs any schema compilation errors without throwing
📝 Committable suggestion

‼️ 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.

Suggested change
try {
// Compile schemas for all send operations
for (const operationId of this.sendOperationsId) {
this.compiledSchemas[operationId] = await compileSchemasByOperationId(asyncapiFilepath, operationId);
}
this.schemasCompiled = true;
console.log('Schemas initialized successfully for operations:', this.sendOperationsId.join(', '));
} catch (error) {
console.error('Error initializing schemas:', error);
}
try {
// Compile schemas for all send operations
for (const operationId of this.sendOperationsId) {
this.compiledSchemas[operationId] = await compileSchemasByOperationId(asyncapiFilepath, operationId);
}
this.schemasCompiled = true;
console.log('Schemas initialized successfully for operations:', this.sendOperationsId.join(', '));
} catch (error) {
console.error('Error initializing schemas:', error);
throw error;
}
🤖 Prompt for AI Agents
In
packages/templates/clients/websocket/javascript/components/CompileOperationSchemas.js
around lines 25 to 34, the code currently catches all errors and only logs them,
which conflicts with the JSDoc that declares the function throws on failure;
either rethrow the caught error after logging (e.g., log then throw error) so
the behavior matches the @throws contract, or update the JSDoc to remove the
@throws and document that errors are logged and suppressed; choose one approach
and implement it consistently (if rethrowing, ensure callers handle the
exception; if changing JSDoc, update the comment at line 18 to reflect that
errors are logged and not thrown).

Comment on lines 3 to 5
export function Constructor({ serverUrl, sendOperations }) {
const sendOperationsId = sendOperations.map((operation) => operation.id());
const sendOperationsArray = JSON.stringify(sendOperationsId);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add validation for sendOperations parameter.

Lines 4-5 assume sendOperations is always a valid array, but there's no validation. If sendOperations is undefined or null, line 4 will throw a TypeError. This is inconsistent with CompileOperationSchemas which checks !sendOperations || sendOperations.length === 0 (line 4 in CompileOperationSchemas.js).

Add a guard at the beginning:

 export function Constructor({ serverUrl, sendOperations }) {
+  if (!sendOperations || !Array.isArray(sendOperations)) {
+    throw new Error('sendOperations must be a non-empty array');
+  }
   const sendOperationsId = sendOperations.map((operation) => operation.id());
   const sendOperationsArray = JSON.stringify(sendOperationsId);

Alternatively, if sendOperations can legitimately be empty, handle it gracefully:

 export function Constructor({ serverUrl, sendOperations }) {
-  const sendOperationsId = sendOperations.map((operation) => operation.id());
+  const sendOperationsId = sendOperations?.map((operation) => operation.id()) || [];
   const sendOperationsArray = JSON.stringify(sendOperationsId);
📝 Committable suggestion

‼️ 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.

Suggested change
export function Constructor({ serverUrl, sendOperations }) {
const sendOperationsId = sendOperations.map((operation) => operation.id());
const sendOperationsArray = JSON.stringify(sendOperationsId);
export function Constructor({ serverUrl, sendOperations }) {
if (!sendOperations || !Array.isArray(sendOperations)) {
throw new Error('sendOperations must be a non-empty array');
}
const sendOperationsId = sendOperations.map((operation) => operation.id());
const sendOperationsArray = JSON.stringify(sendOperationsId);
🤖 Prompt for AI Agents
In packages/templates/clients/websocket/javascript/components/Constructor.js
around lines 3 to 5, the code assumes sendOperations is a non-null array and
calls map which will throw if sendOperations is null/undefined; add a defensive
guard at the top (e.g., treat falsy values as empty array) or explicitly
validate and throw a clear error; then derive sendOperationsId from the
validated array (empty array produces empty JSON string) so subsequent
JSON.stringify never fails.

@lightning-sagar
Copy link
Contributor Author

@derberg I noticed coderabbit flagged a bunch of issues in files I didnt touch (Keeper, WebSocket client templates, Constructor.js, etc) looks like these came in from the recent merge into master, not from the changes in this pr

before I do anything, could you let me know what you'd prefer?

  • should I rebase/merge my branch with the latest master and fix those warnings here or

  • should this pr stay focused only on the default-parameter fix, and the other warnings be handled separately?

just want to keep the scope clean and avoid mixing unrelated fixes

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 9, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generator do not handle template params that default to false

6 participants