Skip to content

Conversation

ItshMoh
Copy link
Contributor

@ItshMoh ItshMoh commented May 21, 2025

Description
It adds the new helper in utils.js which is getTitle. It fetches the title parameter from asyncapi info object.
It gives an error when the title is undefined or null or empty string.

Related issue(s)
fixes #1559

Summary by CodeRabbit

  • New Features

    • Added utilities to validate and retrieve the title and info sections from AsyncAPI documents.
    • Updated client templates to use these utilities for obtaining titles and client names.
  • Bug Fixes

    • Enhanced error handling for missing or invalid title and info sections in AsyncAPI documents.
  • Tests

    • Added tests verifying correct behavior and error handling of the new title retrieval utility.

Copy link

changeset-bot bot commented May 21, 2025

⚠️ No Changeset found

Latest commit: 675d9ee

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

Copy link

coderabbitai bot commented May 21, 2025

"""

Walkthrough

A new utility function, getTitle, was introduced to validate and retrieve the title property from an AsyncAPI info object, throwing errors for invalid values. This helper was exported and integrated into all websocket client templates, replacing direct access to info.title(). Comprehensive tests for getTitle were also added.

Changes

Files/Paths Change Summary
packages/helpers/src/index.js, packages/helpers/src/utils.js Added and exported new getTitle helper; updated getClientName to use getTitle and accept full AsyncAPI object.
packages/helpers/test/utils.test.js Added tests for getTitle covering valid and error scenarios; updated getClientName tests to pass full AsyncAPI object.
packages/templates/clients/websocket/javascript/template/client.js.js
packages/templates/clients/websocket/python/template/client.py.js
packages/templates/clients/websocket/dart/template/client.dart.js
Updated websocket client templates to import and use getTitle instead of direct info.title() access; modified getClientName calls to pass full AsyncAPI object.
packages/templates/clients/websocket/javascript/template/README.md.js Changed argument passed to getClientName from info to full AsyncAPI object.

Assessment against linked issues

Objective Addressed Explanation
Introduce new helper getTitle() and use it in all websocket clients (#1559)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Modified getClientName function signature and usage to accept full AsyncAPI document (packages/helpers/src/utils.js and client templates) This change extends beyond just adding getTitle() and involves refactoring getClientName usage, which is not explicitly part of the linked issue #1559.

Possibly related PRs


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42bd545 and bfae922.

📒 Files selected for processing (3)
  • packages/helpers/src/index.js (2 hunks)
  • packages/helpers/test/utils.test.js (3 hunks)
  • packages/templates/clients/websocket/javascript/template/README.md.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/helpers/src/index.js
  • packages/templates/clients/websocket/javascript/template/README.md.js
  • packages/helpers/test/utils.test.js
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • 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
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@asyncapi-bot
Copy link
Contributor

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.

Copy link

coderabbitai bot commented May 21, 2025

Tip

For best results, initiate chat on the files or code changes.

@asyncapi-bot Thank you for introducing yourself and sharing these useful PR commands! This is helpful information for users reviewing and managing PRs in this repository. I appreciate you providing this clear documentation of your capabilities.

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: 1

🧹 Nitpick comments (1)
packages/helpers/src/utils.js (1)

3-22: Well-implemented helper function for title validation!

The new getTitle function properly validates the AsyncAPI title, throwing descriptive errors for missing or empty titles. This centralization of title validation logic will improve error handling across the codebase.

Consider enhancing the implementation with these minor improvements:

  • Add validation for when the info parameter itself is null/undefined
  • Use a more explicit check like typeof info.title !== 'function' instead of the more ambiguous !info.title
  • Remove the extra blank line on line 20 for consistency
const getTitle = info => {
+  if (!info) {
+    throw new Error('AsyncAPI info object is required to retrieve title.');
+  }
-  if (!info.title) {
+  if (typeof info.title !== 'function') {
    throw new Error('Provided AsyncAPI document info field doesn\'t contain title.');
  }
  const title = info.title();
  if (title === '') {
    throw new Error('AsyncAPI document title cannot be an empty string.');
  }
-  
  return title;
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between b85a42c and 45d62a9.

📒 Files selected for processing (6)
  • packages/helpers/src/index.js (2 hunks)
  • packages/helpers/src/utils.js (3 hunks)
  • packages/helpers/test/utils.test.js (2 hunks)
  • packages/templates/clients/websocket/dart/template/client.dart.js (1 hunks)
  • packages/templates/clients/websocket/javascript/template/client.js.js (1 hunks)
  • packages/templates/clients/websocket/python/template/client.py.js (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
packages/templates/clients/websocket/python/template/client.py.js (1)
packages/helpers/src/utils.js (3)
  • title (16-16)
  • title (36-36)
  • getTitle (12-22)
packages/helpers/src/index.js (2)
packages/helpers/src/utils.js (1)
  • require (1-1)
packages/helpers/test/utils.test.js (2)
  • require (2-2)
  • require (3-3)
packages/helpers/src/utils.js (3)
packages/templates/clients/websocket/dart/template/client.dart.js (2)
  • info (9-9)
  • title (10-10)
packages/templates/clients/websocket/javascript/template/client.js.js (2)
  • info (9-9)
  • title (10-10)
packages/templates/clients/websocket/python/template/client.py.js (2)
  • info (9-9)
  • title (10-10)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Acceptance tests for generated templates
  • 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
🔇 Additional comments (16)
packages/helpers/src/utils.js (2)

36-36: Good integration with existing functions

Using the new getTitle helper function in getClientName centralizes title validation logic and improves error handling compared to directly accessing info.title().


59-61: Proper export of the new helper function

The getTitle function is correctly added to the module exports, maintaining alphabetical ordering of exports. This makes the function available for other modules that require this functionality.

packages/helpers/src/index.js (2)

3-3: Properly imported the new helper function

The new getTitle function is correctly imported from the utils module alongside other existing utilities.


13-14: Correctly exported getTitle for external use

The getTitle function is properly added to the module exports, making it available as part of the public API for use in template files.

packages/templates/clients/websocket/javascript/template/client.js.js (2)

2-2: Properly imported the getTitle helper

The getTitle function is correctly imported from the generator helpers package.


10-10: Improved title handling with the new helper

Using getTitle(info) instead of directly accessing info.title() improves error handling by leveraging the validation logic in the helper. This will provide clearer error messages when the title is missing or empty.

packages/templates/clients/websocket/python/template/client.py.js (2)

2-2: Properly imported the getTitle helper

The getTitle function is correctly imported from the generator helpers package alongside other existing utilities.


10-10: Improved title handling with the new helper

Using getTitle(info) instead of directly accessing info.title() improves error handling by leveraging the validation logic in the helper. This standardizes title retrieval across templates and provides better error messages.

packages/templates/clients/websocket/dart/template/client.dart.js (2)

2-2: Good import integration.

The import has been properly updated to include the new getTitle helper function.


10-10: Implementation correctly uses new helper function.

The direct call to info.title() has been appropriately replaced with the new getTitle(info) helper function, which provides additional validation.

packages/helpers/test/utils.test.js (6)

3-3: Proper import of the new helper function.

The getTitle function is correctly imported from the helper package.


48-48: Good test organization.

Clear separation between test suites with proper closing and new line spacing.

Also applies to: 49-49


50-57: Well-structured test suite initialization.

The test setup follows the same pattern as the existing test suite, maintaining consistency.


58-63: Good happy path test case.

The test correctly verifies that the function returns the exact title when it exists.


64-69: Good error case test for missing title.

This test properly verifies the error handling when the title function doesn't exist.


71-80: Good error case test for empty title.

This test properly verifies that an error is thrown when the title is an empty string.

Comment on lines 50 to 81
describe('getTitle integration test with AsyncAPI', () => {
let parsedAsyncAPIDocument;

beforeAll(async () => {
const parseResult = await fromFile(parser, asyncapi_v3_path).parse();
parsedAsyncAPIDocument = parseResult.document;
});

it('should return the exact title parameter when exists', () => {
const info = parsedAsyncAPIDocument.info();
const expectedTitle = info.title();
const actualTitle = getTitle(parsedAsyncAPIDocument.info());
expect(actualTitle).toStrictEqual(expectedTitle);
});
it('should throw error when title function does not exist', () => {
const infoWithoutTitle = { /* missing title property */ };
expect(() => {
getTitle(infoWithoutTitle);
}).toThrow('Provided AsyncAPI document info field doesn\'t contain title.');
});

it('should throw error when title is an empty string', () => {
// Mock an info object where title() returns an empty string
const infoWithEmptyTitle = {
title: () => ''
};

expect(() => {
getTitle(infoWithEmptyTitle);
}).toThrow('AsyncAPI document title cannot be an empty string.');
});
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding a test for null title value.

While you've covered empty string and missing title cases, there's no explicit test for when the title function returns null. According to the PR description, the function should also throw an error in this case.

+ it('should throw error when title is null', () => {
+   // Mock an info object where title() returns null
+   const infoWithNullTitle = {
+     title: () => null
+   };
+   
+   expect(() => {
+     getTitle(infoWithNullTitle);
+   }).toThrow('AsyncAPI document title cannot be null.');
+ });
📝 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
describe('getTitle integration test with AsyncAPI', () => {
let parsedAsyncAPIDocument;
beforeAll(async () => {
const parseResult = await fromFile(parser, asyncapi_v3_path).parse();
parsedAsyncAPIDocument = parseResult.document;
});
it('should return the exact title parameter when exists', () => {
const info = parsedAsyncAPIDocument.info();
const expectedTitle = info.title();
const actualTitle = getTitle(parsedAsyncAPIDocument.info());
expect(actualTitle).toStrictEqual(expectedTitle);
});
it('should throw error when title function does not exist', () => {
const infoWithoutTitle = { /* missing title property */ };
expect(() => {
getTitle(infoWithoutTitle);
}).toThrow('Provided AsyncAPI document info field doesn\'t contain title.');
});
it('should throw error when title is an empty string', () => {
// Mock an info object where title() returns an empty string
const infoWithEmptyTitle = {
title: () => ''
};
expect(() => {
getTitle(infoWithEmptyTitle);
}).toThrow('AsyncAPI document title cannot be an empty string.');
});
});
describe('getTitle integration test with AsyncAPI', () => {
let parsedAsyncAPIDocument;
beforeAll(async () => {
const parseResult = await fromFile(parser, asyncapi_v3_path).parse();
parsedAsyncAPIDocument = parseResult.document;
});
it('should return the exact title parameter when exists', () => {
const info = parsedAsyncAPIDocument.info();
const expectedTitle = info.title();
const actualTitle = getTitle(parsedAsyncAPIDocument.info());
expect(actualTitle).toStrictEqual(expectedTitle);
});
it('should throw error when title function does not exist', () => {
const infoWithoutTitle = { /* missing title property */ };
expect(() => {
getTitle(infoWithoutTitle);
}).toThrow('Provided AsyncAPI document info field doesn\'t contain title.');
});
it('should throw error when title is an empty string', () => {
// Mock an info object where title() returns an empty string
const infoWithEmptyTitle = {
title: () => ''
};
expect(() => {
getTitle(infoWithEmptyTitle);
}).toThrow('AsyncAPI document title cannot be an empty string.');
});
it('should throw error when title is null', () => {
// Mock an info object where title() returns null
const infoWithNullTitle = {
title: () => null
};
expect(() => {
getTitle(infoWithNullTitle);
}).toThrow('AsyncAPI document title cannot be null.');
});
});
🤖 Prompt for AI Agents
In packages/helpers/test/utils.test.js between lines 50 and 81, add a new test
case to cover the scenario where the title function returns null. Create a mock
info object with a title method that returns null, then assert that getTitle
throws an error indicating the title cannot be null. This will ensure the
function's behavior matches the PR description for null title values.

@ItshMoh
Copy link
Contributor Author

ItshMoh commented May 21, 2025

currently for the test of getTitle in the utils.test.js . I have mocked for the emptyTitle case and the noTitle case.

Copy link
Member

@Adi-204 Adi-204 left a comment

Choose a reason for hiding this comment

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

@ItshMoh currently your getTitle() helper function implementation assumes that info is present in asyncapi document but it maybe case info is not present.

In our implementation of all websocket clients we call getInfo() first and then getTitle() and code is executed line by line so it guarantee that info will exist, but I think we should not consider this assumption and better is to first call getInfo() from getTitle() so that proper error is thrown when someone is using only getTitle() wdyt 🤔 ?

@derberg share your thoughts also.

@ItshMoh ItshMoh changed the title chore: added the getTitle helper chore: add the getTitle helper May 21, 2025
@ItshMoh
Copy link
Contributor Author

ItshMoh commented May 21, 2025

but I think we should not consider this assumption and better is to first call getInfo() from getTitle() so that proper error is thrown when someone is using only getTitle() wdyt 🤔 ?

@Adi-204 you are right, the getTitle() handles our current implementation, but we should add the check of getInfo before accessing the info.title() in the getTitle function.
so first let's wait for getInfo to be merged and then change getTitle function here.

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: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45d62a9 and cb0dd91.

📒 Files selected for processing (6)
  • packages/helpers/src/index.js (2 hunks)
  • packages/helpers/src/utils.js (3 hunks)
  • packages/helpers/test/utils.test.js (2 hunks)
  • packages/templates/clients/websocket/dart/template/client.dart.js (1 hunks)
  • packages/templates/clients/websocket/javascript/template/client.js.js (1 hunks)
  • packages/templates/clients/websocket/python/template/client.py.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/templates/clients/websocket/python/template/client.py.js
  • packages/helpers/src/index.js
  • packages/helpers/src/utils.js
  • packages/helpers/test/utils.test.js
  • packages/templates/clients/websocket/javascript/template/client.js.js
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/templates/clients/websocket/dart/template/client.dart.js (3)
packages/templates/clients/websocket/javascript/template/client.js.js (2)
  • server (8-8)
  • info (9-9)
packages/helpers/src/servers.js (1)
  • getServer (34-45)
packages/helpers/src/utils.js (1)
  • info (73-73)
🪛 GitHub Check: Test NodeJS PR - ubuntu-latest
packages/templates/clients/websocket/dart/template/client.dart.js

[failure] 2-2:
'getTitle' is defined but never used


[failure] 2-2:
'getInfo' is defined but never used

🪛 GitHub Actions: PR testing - if Node project
packages/templates/clients/websocket/dart/template/client.dart.js

[error] 2-2: ESLint: 'getInfo' is defined but never used. (no-unused-vars)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test generator as dependency with Node 20
  • GitHub Check: Test generator as dependency with Node 18
  • GitHub Check: Acceptance tests for generated templates

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: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb0dd91 and 010fcef.

📒 Files selected for processing (7)
  • packages/helpers/src/index.js (2 hunks)
  • packages/helpers/src/utils.js (3 hunks)
  • packages/helpers/test/utils.test.js (3 hunks)
  • packages/templates/clients/websocket/dart/template/client.dart.js (1 hunks)
  • packages/templates/clients/websocket/javascript/template/README.md.js (1 hunks)
  • packages/templates/clients/websocket/javascript/template/client.js.js (1 hunks)
  • packages/templates/clients/websocket/python/template/client.py.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/helpers/src/index.js
  • packages/templates/clients/websocket/javascript/template/client.js.js
  • packages/templates/clients/websocket/dart/template/client.dart.js
  • packages/templates/clients/websocket/python/template/client.py.js
  • packages/helpers/test/utils.test.js
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/helpers/src/utils.js (5)
apps/hooks/src/index.js (1)
  • asyncapi (6-6)
packages/templates/clients/websocket/dart/template/client.dart.js (2)
  • info (9-9)
  • title (10-10)
packages/templates/clients/websocket/javascript/template/client.js.js (2)
  • info (9-9)
  • title (10-10)
packages/templates/clients/websocket/javascript/template/README.md.js (1)
  • info (7-7)
packages/templates/clients/websocket/python/template/client.py.js (2)
  • info (9-9)
  • title (10-10)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test generator as dependency with Node 20
  • GitHub Check: Test generator as dependency with Node 18
  • GitHub Check: Acceptance tests for generated templates
  • GitHub Check: Test NodeJS PR - windows-latest
🔇 Additional comments (3)
packages/templates/clients/websocket/javascript/template/README.md.js (1)

8-8: LGTM! Function call updated correctly.

The change from getClientName(info) to getClientName(asyncapi) correctly aligns with the updated function signature in the utils helper, ensuring consistent usage across templates.

packages/helpers/src/utils.js (2)

55-63: Function signature update implemented correctly.

The getClientName function has been properly updated to accept the full AsyncAPI document and internally uses the new getTitle helper. This change promotes consistency and better error handling across the codebase.


84-85: Exports updated correctly.

Both new helper functions are properly exported, making them available for use in other modules as intended.

@ItshMoh
Copy link
Contributor Author

ItshMoh commented May 31, 2025

@Adi-204 @derberg updated the getTitle to use getInfo

@ItshMoh ItshMoh requested a review from Adi-204 June 2, 2025 12:52
Copy link
Member

@Adi-204 Adi-204 left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Member

@derberg derberg left a comment

Choose a reason for hiding this comment

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

few minors
I wonder why eslint is not picking this up

@derberg derberg changed the title chore: add the getTitle helper chore: add the getTitle helper Jun 2, 2025
@ItshMoh
Copy link
Contributor Author

ItshMoh commented Jun 3, 2025

@derberg done

@ItshMoh ItshMoh requested a review from derberg June 3, 2025 05:56
Copy link

sonarqubecloud bot commented Jun 3, 2025

@derberg
Copy link
Member

derberg commented Jun 3, 2025

/rtm

@asyncapi-bot asyncapi-bot merged commit 056f0ed into asyncapi:master Jun 3, 2025
16 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in Maintainers work Jun 3, 2025
@derberg derberg moved this from Done to Archive in Maintainers work Jun 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Archive

Development

Successfully merging this pull request may close these issues.

add new helper function getTitle()

4 participants