Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: format build scripts using eslint #3401

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

JeelRajodiya
Copy link
Contributor

@JeelRajodiya JeelRajodiya commented Nov 16, 2024

This PR just formats all the build scripts using eslint, and does contain any other modifications that change the logic of the scripts. The upcoming PR will be migrating this formatted code.

The reason for this PR is that formatting the code beforehand ensures that the TypeScript migration PRs will only include relevant changes. Reviewing it would be easier.

related #3187

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • No new features introduced in this release.
  • Bug Fixes

    • Improved error handling and clarity in various functions across multiple scripts.
  • Documentation

    • Enhanced JSON schema for AsyncAPI tool discovery with new properties and modifications.
  • Refactor

    • Numerous formatting improvements across various scripts for better readability and consistency, including adjustments to function signatures and export statements.
  • Chores

    • General code style enhancements including consistent use of semicolons, single quotes, and indentation adjustments.

Copy link

coderabbitai bot commented Nov 16, 2024

Walkthrough

The pull request introduces a series of formatting and structural improvements across multiple JavaScript files within the scripts directory. Key changes include adjustments to function signatures for better readability, consistent use of semicolons, and enhancements in error handling and code clarity. The modifications focus on improving code style without altering the underlying logic or functionality of the scripts.

Changes

File Path Change Summary
scripts/adopters/index.js Reformatted writeJSON parameters for readability; added semicolon to import statement.
scripts/build-docs.js Updated semicolon usage; improved formatting in buildNavTree and convertDocPosts functions; enhanced error handling.
scripts/build-meetings.js Reformatted credentials, timeMin, and timeMax for better readability.
scripts/build-newsroom-videos.js Adjusted indentation for buildNewsroomVideos function without changing logic.
scripts/build-pages.js Modified export statement for consistent spacing.
scripts/build-post-list.js Added semicolons; reformatted object structure and function parameters for consistency.
scripts/build-rss.js Improved formatting and consistency in clean and rssFeed functions.
scripts/build-tools.js Reformatted parameters and function calls for clarity.
scripts/casestudies/index.js Reformatted parameters in buildCaseStudiesList for improved readability.
scripts/compose.js Added semicolons; reformatted choices array in inquirer.prompt.
scripts/dashboard/build-dashboard.js Reformatted functions for readability; added trailing commas.
scripts/finance/index.js Reformatted parameters in buildFinanceInfoList for clarity.
scripts/index.js Removed trailing newlines in function calls for consistency.
scripts/markdown/check-markdown.js Adjusted indentation for readability; improved error messages.
scripts/tools/categorylist.js Standardized string literals to single quotes; reformatted export statement.
scripts/tools/combine-tools.js Improved indentation and structure for better readability.
scripts/tools/extract-tools-github.js Added semicolon to require statement.
scripts/tools/tags-color.js Reformatted string literals to single quotes; added spaces in export statement.
scripts/tools/tools-object.js Standardized semicolon usage; improved formatting in createToolObject.
scripts/tools/tools-schema.json Updated schema with new properties and modifications to existing structures.
scripts/utils.js Adjusted string literals to single quotes; improved error handling in convertToJson.
scripts/utils/readAndWriteJson.js Reformatted for consistent use of single quotes; adjusted indentation.
scripts/dashboard/issue-queries.js Modified exports.Queries object to correct syntax issues.

Possibly related PRs

  • feat: added test for build-rss.js #3101: The changes in the main PR involve formatting improvements in the writeJSON function, which is related to the rssFeed function in scripts/build-rss.js that also deals with file writing operations.
  • feat: add test for build docs script #3137: The build-docs.js script has been updated to enhance error handling and code structure, which may relate to the overall improvements in code clarity and maintainability seen in the main PR.
  • fix: remove hydration errors #3262: The changes in the main PR regarding formatting and readability improvements in index.js could relate to the overall code quality improvements seen in the build-dashboard.js script.
  • fix: fixed dashboard scripts #3304: The modifications in build-dashboard.js to enhance control flow and error handling are relevant to the main PR's focus on improving code clarity and structure.
  • feat: add tests for dashboard script #3344: The introduction of tests for the build-dashboard.js script aligns with the main PR's goal of enhancing code clarity and maintainability through improved formatting and readability.

Suggested labels

ready-to-merge, autoapproved, autoupdate

Suggested reviewers

  • akshatnema
  • derberg
  • magicmatatjahu
  • Mayaleeeee
  • devilkiller-ag
  • sambhavgupta0705
  • anshgoyalevil

Poem

🐇 In the land of code, where rabbits hop,
Formatting changes make the style pop!
With semicolons added and spacing just right,
Our scripts now shine, oh what a sight!
Clarity blooms in each function's embrace,
A tidy codebase, a happy place! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

Copy link

netlify bot commented Nov 16, 2024

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 2badba7
🔍 Latest deploy log https://app.netlify.com/sites/asyncapi-website/deploys/6738673e44677b000846a480
😎 Deploy Preview https://deploy-preview-3401--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

codecov bot commented Nov 16, 2024

Codecov Report

Attention: Patch coverage is 52.91005% with 178 lines in your changes missing coverage. Please review.

Project coverage is 67.90%. Comparing base (384da22) to head (2935475).

Files with missing lines Patch % Lines
scripts/build-post-list.js 14.47% 65 Missing ⚠️
scripts/markdown/check-markdown.js 0.00% 54 Missing ⚠️
scripts/tools/combine-tools.js 35.13% 48 Missing ⚠️
scripts/tools/tools-object.js 65.38% 9 Missing ⚠️
scripts/tools/categorylist.js 0.00% 1 Missing ⚠️
scripts/tools/tags-color.js 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3401      +/-   ##
==========================================
+ Coverage   67.77%   67.90%   +0.13%     
==========================================
  Files          21       21              
  Lines         664      673       +9     
==========================================
+ Hits          450      457       +7     
- Misses        214      216       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@JeelRajodiya JeelRajodiya marked this pull request as draft November 16, 2024 09:28
@asyncapi-bot
Copy link
Contributor

asyncapi-bot commented Nov 16, 2024

⚡️ Lighthouse report for the changes in this PR:

Category Score
🔴 Performance 32
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-3401--asyncapi-website.netlify.app/

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

🧹 Outside diff range and nitpick comments (19)
scripts/casestudies/index.js (3)

9-11: Improve variable declarations and iteration pattern

Consider these improvements for better code quality:

  1. Use const for variables that aren't reassigned
  2. Replace the for...of loop with array methods
-    let files = await readdir(dirWithCaseStudy);
-    let caseStudiesList = [];
-    for (let file of files) {
+    const files = await readdir(dirWithCaseStudy);
+    const caseStudiesList = [];
+    await Promise.all(files.map(async (file) => {
🧰 Tools
🪛 eslint

[error] 9-9: 'files' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 10-10: 'caseStudiesList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 11-11: 'file' is never reassigned. Use 'const' instead.

(prefer-const)


19-21: Enhance error handling with context

The current error handling loses context about which operation failed. Consider adding more context to the error message.

   } catch (err) {
-    throw new Error(err);
+    throw new Error(`Failed to build case studies list: ${err.message}`);
   }

1-21: Note on review scope

While this PR's primary focus is on formatting, I've highlighted a critical performance issue with the file operations that should be addressed. The other suggestions for improvements (const usage, error handling) can be considered for a future PR focused on code quality.

🧰 Tools
🪛 eslint

[error] 2-2: Useless path segments for "../../scripts/utils", should be "../utils"

(import/no-useless-path-segments)


[error] 4-7: Replace ⏎··dirWithCaseStudy,⏎··writeFilePath,⏎ with dirWithCaseStudy,·writeFilePath

(prettier/prettier)


[error] 9-9: 'files' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 10-10: 'caseStudiesList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 11-18: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 11-11: 'file' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 13-13: Unexpected await inside a loop.

(no-await-in-loop)


[error] 17-17: Unexpected await inside a loop.

(no-await-in-loop)

scripts/utils.js (1)

15-25: Improve error message formatting and structure.

While the error handling logic is correct, there are some formatting improvements to consider:

    } catch (yamlError) {
      // If parsing as YAML also fails, throw an error
-      throw new Error(
-        `Invalid content format:\nJSON Parse Error: ${jsonError}\nYAML Parse Error: ${yamlError}`,
-      );
+      throw new Error(`Invalid content format:
+JSON Parse Error: ${jsonError}
+YAML Parse Error: ${yamlError}`);
    }

This change:

  • Fixes the prettier formatting issue
  • Improves readability of the error message
  • Maintains the same error information
🧰 Tools
🪛 eslint

[error] 21-23: Replace ⏎········Invalid·content·format:\nJSON·Parse·Error:·${jsonError}\nYAML·Parse·Error:·${yamlError},⏎······ with Invalid·content·format:\nJSON·Parse·Error:·${jsonError}\nYAML·Parse·Error:·${yamlError}

(prettier/prettier)

scripts/finance/index.js (1)

45-47: Consider preserving error stack trace

While this is a formatting PR, there's a potential improvement in error handling. The current implementation might lose the original stack trace.

-    throw new Error(err);
+    throw err;
scripts/build-rss.js (4)

1-15: Static analysis findings noted for future improvement

The static analysis tools have flagged some patterns that could be improved in a future PR:

  • Consider migrating to ES modules instead of CommonJS require()
  • Refactor the clean function to avoid parameter reassignment

However, since this PR focuses on formatting, these changes should be addressed in a separate PR focused on code modernization.

🧰 Tools
🪛 eslint

[error] 5-5: Unexpected require().

(global-require)


[error] 9-9: Assignment to function parameter 's'.

(no-param-reassign)


[error] 10-10: Assignment to function parameter 's'.

(no-param-reassign)


[error] 11-11: Assignment to function parameter 's'.

(no-param-reassign)


[error] 12-12: Assignment to function parameter 's'.

(no-param-reassign)


[error] 13-13: Assignment to function parameter 's'.

(no-param-reassign)


[error] 14-14: Assignment to function parameter 's'.

(no-param-reassign)


Line range hint 20-34: Apply prettier formatting to error messages

The error handling logic looks good, but prettier suggests single-line formatting for the error message:

-      throw new Error(
-        `Missing date in posts: ${missingDatePosts.map((p) => p.title || p.slug).join(', ')}`,
-      );
+      throw new Error(`Missing date in posts: ${missingDatePosts.map((p) => p.title || p.slug).join(', ')}`);
🧰 Tools
🪛 eslint

[error] 5-5: Unexpected require().

(global-require)


[error] 9-9: Assignment to function parameter 's'.

(no-param-reassign)


[error] 10-10: Assignment to function parameter 's'.

(no-param-reassign)


[error] 11-11: Assignment to function parameter 's'.

(no-param-reassign)


[error] 12-12: Assignment to function parameter 's'.

(no-param-reassign)


[error] 13-13: Assignment to function parameter 's'.

(no-param-reassign)


[error] 14-14: Assignment to function parameter 's'.

(no-param-reassign)


59-66: Apply prettier formatting to validation error messages

The validation logic is solid, but prettier suggests single-line formatting for both the filter condition and error message:

-    const invalidPosts = posts.filter(
-      (post) => !post.title || !post.slug || !post.excerpt || !post.date,
-    );
+    const invalidPosts = posts.filter((post) => !post.title || !post.slug || !post.excerpt || !post.date);

-      throw new Error(
-        `Missing required fields in posts: ${invalidPosts.map((p) => p.title || p.slug).join(', ')}`,
-      );
+      throw new Error(`Missing required fields in posts: ${invalidPosts.map((p) => p.title || p.slug).join(', ')}`);
🧰 Tools
🪛 eslint

[error] 59-61: Replace ⏎······(post)·=>·!post.title·||·!post.slug·||·!post.excerpt·||·!post.date,⏎···· with (post)·=>·!post.title·||·!post.slug·||·!post.excerpt·||·!post.date

(prettier/prettier)


[error] 64-66: Replace ⏎········Missing·required·fields·in·posts:·${invalidPosts.map((p)·=>·p.title·||·p.slug).join(',·')},⏎······ with Missing·required·fields·in·posts:·${invalidPosts.map((p)·=>·p.title·||·p.slug).join(',·')}

(prettier/prettier)


88-92: Use const for immutable variables

The tmp variable is never reassigned, so it should use const:

-          let tmp = enclosure['@url'].toLowerCase();
+          const tmp = enclosure['@url'].toLowerCase();

Note: The image type detection logic could be made more robust in a future PR by using proper MIME type detection or file extension parsing libraries.

🧰 Tools
🪛 eslint

[error] 89-89: 'tmp' is never reassigned. Use 'const' instead.

(prefer-const)

scripts/tools/combine-tools.js (3)

1-11: Organize imports for better maintainability

Consider reorganizing imports in the following order:

  1. External dependencies (ajv, fuse.js, etc.)
  2. Node.js built-ins (fs)
  3. Local modules
-const { languagesColor, technologiesColor } = require('./tags-color');
-const { categoryList } = require('./categorylist.js');
-const { createToolObject } = require('./tools-object');
-const fs = require('fs');
-const schema = require('./tools-schema.json');
-const Ajv = require('ajv');
-const addFormats = require('ajv-formats');
-const Fuse = require('fuse.js');
+const Ajv = require('ajv');
+const addFormats = require('ajv-formats');
+const Fuse = require('fuse.js');
+const fs = require('fs');
+
+const { languagesColor, technologiesColor } = require('./tags-color');
+const { categoryList } = require('./categorylist');
+const { createToolObject } = require('./tools-object');
+const schema = require('./tools-schema.json');
🧰 Tools
🪛 eslint

[error] 2-2: Unexpected use of file extension "js" for "./categorylist.js"

(import/extensions)


[error] 4-4: fs import should occur before import of ./tags-color

(import/order)


[error] 6-6: ajv import should occur before import of ./tags-color

(import/order)


[error] 7-7: ajv-formats import should occur before import of ./tags-color

(import/order)


[error] 8-8: Expected 1 empty line after require statement not followed by another require.

(import/newline-after-import)


[error] 8-8: fuse.js import should occur before import of ./tags-color

(import/order)


118-146: Consider optimizing async operations in loops

Multiple sequential await operations inside loops could impact performance. Consider using Promise.all for parallel execution.

-      for (const tool of automatedTools[key].toolsList) {
-        finalToolsList.push(await getFinalTool(tool));
-      }
+      const toolPromises = automatedTools[key].toolsList.map(tool => getFinalTool(tool));
+      finalToolsList.push(...await Promise.all(toolPromises));
🧰 Tools
🪛 Biome

[error] 122-122: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 eslint

[error] 118-120: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 119-119: Unexpected await inside a loop.

(no-await-in-loop)


[error] 123-146: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 125-125: Unexpected await inside a loop.

(no-await-in-loop)


[error] 129-131: Replace ⏎··············'https://github.com/asyncapi/',⏎············ with 'https://github.com/asyncapi/'

(prettier/prettier)


[error] 133-133: 'toolObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 133-133: Unexpected await inside a loop.

(no-await-in-loop)


[error] 134-134: Unexpected await inside a loop.

(no-await-in-loop)


[error] 136-138: Replace ⏎············'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation',⏎·········· with 'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation'

(prettier/prettier)


[error] 141-144: Replace ⏎············'Validation·errors:',⏎············JSON.stringify(validate.errors,·null,·2),⏎·········· with 'Validation·errors:',·JSON.stringify(validate.errors,·null,·2)

(prettier/prettier)


136-144: Improve error message formatting

Consolidate error messages for better readability while maintaining the same information.

-          console.error(
-            'Script is not failing, it is just dropping errors for further investigation',
-          );
-          console.error(`Invalid ${tool.title} .asyncapi-tool file.`);
-          console.error(`Located in manual-tools.json file`);
-          console.error(
-            'Validation errors:',
-            JSON.stringify(validate.errors, null, 2),
-          );
+          console.error(
+            `Warning: Invalid .asyncapi-tool file for "${tool.title}" in manual-tools.json\n` +
+            `Validation errors:\n${JSON.stringify(validate.errors, null, 2)}\n` +
+            'Note: Script continues execution, errors logged for investigation.'
+          );
🧰 Tools
🪛 eslint

[error] 136-138: Replace ⏎············'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation',⏎·········· with 'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation'

(prettier/prettier)


[error] 141-144: Replace ⏎············'Validation·errors:',⏎············JSON.stringify(validate.errors,·null,·2),⏎·········· with 'Validation·errors:',·JSON.stringify(validate.errors,·null,·2)

(prettier/prettier)

scripts/build-docs.js (4)

1-1: Add newline after require statement

Following the project's style guide, add a newline after the require statement.

const sortBy = require('lodash/sortBy');
+
function buildNavTree(navItems) {
🧰 Tools
🪛 eslint

[error] 1-1: Expected 1 empty line after require statement not followed by another require.

(import/newline-after-import)


5-24: Clean up formatting in tree initialization and sorting

The code logic is correct, but there are several formatting inconsistencies:

  • Remove trailing commas in object literals
  • Add space after comment slashes
  • Consolidate the sortBy parameters on a single line
      welcome: {
        item: {
          title: 'Welcome',
          weight: 0,
          isRootSection: true,
          isSection: true,
          rootSectionId: 'welcome',
          sectionWeight: 0,
-         slug: '/docs',
+         slug: '/docs'
-       },
+       }
-       children: {},
+       children: {}
-     },
+     }
    };

-   //first we make sure that list of items lists main section items and then sub sections, documents last
+   // first we make sure that list of items lists main section items and then sub sections, documents last
    const sortedItems = sortBy(navItems, [
-     'isRootSection',
-     'weight',
-     'isSection',
+     'isRootSection', 'weight', 'isSection'
    ]);
🧰 Tools
🪛 eslint

[error] 13-13: Delete ,

(prettier/prettier)


[error] 15-15: Delete ,

(prettier/prettier)


[error] 16-16: Delete ,

(prettier/prettier)


[error] 19-19: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 20-24: Replace ⏎······'isRootSection',⏎······'weight',⏎······'isSection',⏎···· with 'isRootSection',·'weight',·'isSection'

(prettier/prettier)


198-198: Improve error handling in addDocButtons

Include more context and the error stack in the error message for better debugging.

-   throw new Error('An error occurred while adding doc buttons:', err);
+   throw new Error(`An error occurred while adding doc buttons: ${err.message}\n${err.stack}`);

Line range hint 1-203: Consider future improvements for better maintainability

While this PR successfully formats the code, consider these improvements in a future PR:

  1. Add JSDoc comments for better documentation
  2. Consider splitting the large addDocButtons function into smaller, more focused functions
  3. Add input validation for the function parameters
  4. Consider adding unit tests for edge cases
🧰 Tools
🪛 eslint

[error] 134-134: Use array destructuring.

(prefer-destructuring)


[error] 137-137: 'countDocPages' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 141-141: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 142-142: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 146-147: Split 'let' declarations into multiple statements.

(one-var)


[error] 154-157: Replace ⏎··········!structuredPosts[index·+·1].isRootElement·&&⏎··········!structuredPosts[index·+·1].isSection⏎········ with !structuredPosts[index·+·1].isRootElement·&&·!structuredPosts[index·+·1].isSection

(prettier/prettier)


[error] 160-160: Delete ,

(prettier/prettier)


[error] 165-165: Delete ,

(prettier/prettier)


[error] 175-178: Replace ⏎··········!structuredPosts[index·-·1]?.isRootElement·&&⏎··········!structuredPosts[index·-·1]?.isSection⏎········ with !structuredPosts[index·-·1]?.isRootElement·&&·!structuredPosts[index·-·1]?.isSection

(prettier/prettier)


[error] 181-181: Delete ,

(prettier/prettier)


[error] 186-192: Unexpected if as the only statement in an else block.

(no-lonely-if)


[error] 189-189: Delete ,

(prettier/prettier)

scripts/tools/tools-schema.json (3)

14-15: Fix grammatical issues in description text

The description text has grammatical errors and could be clearer.

-  "description": "By default scripts read description of repository there project is stored. You can override this behaviour by providing custom description."
+  "description": "By default, scripts read the description from the repository where the project is stored. You can override this behavior by providing a custom description."

49-51: Remove duplicate type definitions in language property

The schema contains duplicate type definitions for the string type in the language property's enum.

              "anyOf": [
                {
-                  "type": "string",
                  "enum": [

Also applies to: 82-83


143-144: Consider expanding technology examples

The current examples are limited to "Express.js" and "Kafka". Consider adding more diverse examples to better represent the available technology options listed in the enum.

-          "examples": ["Express.js", "Kafka"]
+          "examples": ["Express.js", "Kafka", "Node js", "React JS", "Docker", "AWS"]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 384da22 and 2935475.

📒 Files selected for processing (22)
  • scripts/adopters/index.js (1 hunks)
  • scripts/build-docs.js (4 hunks)
  • scripts/build-meetings.js (2 hunks)
  • scripts/build-newsroom-videos.js (1 hunks)
  • scripts/build-pages.js (1 hunks)
  • scripts/build-post-list.js (1 hunks)
  • scripts/build-rss.js (3 hunks)
  • scripts/build-tools.js (1 hunks)
  • scripts/casestudies/index.js (1 hunks)
  • scripts/compose.js (4 hunks)
  • scripts/dashboard/build-dashboard.js (11 hunks)
  • scripts/finance/index.js (1 hunks)
  • scripts/index.js (2 hunks)
  • scripts/markdown/check-markdown.js (4 hunks)
  • scripts/tools/categorylist.js (1 hunks)
  • scripts/tools/combine-tools.js (1 hunks)
  • scripts/tools/extract-tools-github.js (3 hunks)
  • scripts/tools/tags-color.js (1 hunks)
  • scripts/tools/tools-object.js (3 hunks)
  • scripts/tools/tools-schema.json (1 hunks)
  • scripts/utils.js (1 hunks)
  • scripts/utils/readAndWriteJson.js (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • scripts/build-pages.js
🧰 Additional context used
🪛 eslint
scripts/adopters/index.js

[error] 2-2: Unexpected use of file extension "js" for "../utils/readAndWriteJson.js"

(import/extensions)


[error] 5-8: Replace ⏎····'config/adopters.yml',⏎····resolve(__dirname,·'../../config',·'adopters.json'),⏎·· with 'config/adopters.yml',·resolve(__dirname,·'../../config',·'adopters.json')

(prettier/prettier)

scripts/build-docs.js

[error] 1-1: Expected 1 empty line after require statement not followed by another require.

(import/newline-after-import)


[error] 13-13: Delete ,

(prettier/prettier)


[error] 15-15: Delete ,

(prettier/prettier)


[error] 16-16: Delete ,

(prettier/prettier)


[error] 19-19: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 20-24: Replace ⏎······'isRootSection',⏎······'weight',⏎······'isSection',⏎···· with 'isRootSection',·'weight',·'isSection'

(prettier/prettier)


[error] 27-27: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 32-32: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 35-37: Replace ⏎············Parent·section·${item.parent}·not·found·for·item·${item.title},⏎·········· with Parent·section·${item.parent}·not·found·for·item·${item.title}

(prettier/prettier)


[error] 48-48: Delete ,

(prettier/prettier)


[error] 82-84: Replace ⏎··············(c)·=>·c.isPrerelease·===·undefined,⏎············ with (c)·=>·c.isPrerelease·===·undefined

(prettier/prettier)


[error] 104-104: Use object destructuring.

(prefer-destructuring)


[error] 104-104: 'children' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 106-106: 'docChildArray' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 134-134: Use array destructuring.

(prefer-destructuring)


[error] 137-137: 'countDocPages' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 141-141: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 142-142: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 146-147: Split 'let' declarations into multiple statements.

(one-var)


[error] 154-157: Replace ⏎··········!structuredPosts[index·+·1].isRootElement·&&⏎··········!structuredPosts[index·+·1].isSection⏎········ with !structuredPosts[index·+·1].isRootElement·&&·!structuredPosts[index·+·1].isSection

(prettier/prettier)


[error] 160-160: Delete ,

(prettier/prettier)


[error] 165-165: Delete ,

(prettier/prettier)


[error] 175-178: Replace ⏎··········!structuredPosts[index·-·1]?.isRootElement·&&⏎··········!structuredPosts[index·-·1]?.isSection⏎········ with !structuredPosts[index·-·1]?.isRootElement·&&·!structuredPosts[index·-·1]?.isSection

(prettier/prettier)


[error] 181-181: Delete ,

(prettier/prettier)


[error] 186-192: Unexpected if as the only statement in an else block.

(no-lonely-if)


[error] 189-189: Delete ,

(prettier/prettier)

scripts/build-meetings.js

[error] 12-14: Replace ⏎········?·JSON.parse(process.env.CALENDAR_SERVICE_ACCOUNT)⏎········:·undefined, with ·?·JSON.parse(process.env.CALENDAR_SERVICE_ACCOUNT)·:·undefined

(prettier/prettier)

scripts/build-newsroom-videos.js

[error] 8-17: Unexpected string concatenation.

(prefer-template)


[error] 16-16: Delete ,

(prettier/prettier)


[error] 17-17: Delete ,

(prettier/prettier)


[error] 35-35: Delete ,

(prettier/prettier)

scripts/build-post-list.js

[error] 1-7: Replace ⏎··readdirSync,⏎··statSync,⏎··existsSync,⏎··readFileSync,⏎··writeFileSync,⏎ with ·readdirSync,·statSync,·existsSync,·readFileSync,·writeFileSync·

(prettier/prettier)


[error] 21-21: Delete ,

(prettier/prettier)


[error] 26-26: This line has a length of 187. Maximum allowed is 120.

(max-len)


[error] 29-29: Delete ,

(prettier/prettier)


[error] 33-33: ["docs"] is better written in dot notation.

(dot-notation)


[error] 34-34: ["blog"] is better written in dot notation.

(dot-notation)


[error] 35-35: ["about"] is better written in dot notation.

(dot-notation)


[error] 36-37: Empty block statement.

(no-empty)


[error] 41-41: 'walkDirectories' was used before it was defined.

(no-use-before-define)


[error] 42-44: Replace ⏎····result['docs'].filter((p)·=>·p.slug.startsWith('/docs/')),⏎·· with result['docs'].filter((p)·=>·p.slug.startsWith('/docs/'))

(prettier/prettier)


[error] 43-43: ["docs"] is better written in dot notation.

(dot-notation)


[error] 45-45: ["docsTree"] is better written in dot notation.

(dot-notation)


[error] 46-46: ["docs"] is better written in dot notation.

(dot-notation)


[error] 46-46: ["docs"] is better written in dot notation.

(dot-notation)


[error] 50-53: Replace ⏎····resolve(__dirname,·'..',·'config',·'posts.json'),⏎····JSON.stringify(result,·null,·'··'),⏎·· with resolve(__dirname,·'..',·'config',·'posts.json'),·JSON.stringify(result,·null,·'··')

(prettier/prettier)


[error] 56-63: Replace ⏎··directories,⏎··result,⏎··sectionWeight·=·0,⏎··sectionTitle,⏎··sectionId,⏎··rootSectionId,⏎ with directories,·result,·sectionWeight·=·0,·sectionTitle,·sectionId,·rootSectionId

(prettier/prettier)


[error] 58-58: 'result' is already declared in the upper scope on line 17 column 7.

(no-shadow)


[error] 59-59: Default parameters should be last.

(default-param-last)


[error] 64-175: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 64-64: 'dir' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 65-65: 'directory' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 66-66: 'sectionSlug' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 67-67: 'files' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 69-174: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 69-69: 'file' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 75-75: 'isDirectory' was used before it was defined.

(no-use-before-define)


[error] 78-81: Replace ⏎············readFileSync(fileNameWithSection,·'utf-8'),⏎············{},⏎·········· with readFileSync(fileNameWithSection,·'utf-8'),·{}

(prettier/prettier)


[error] 82-82: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 85-85: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 85-85: Delete ,

(prettier/prettier)


[error] 101-108: Replace ⏎··········[[fileName,·slug]],⏎··········result,⏎··········details.weight,⏎··········details.title,⏎··········details.sectionId,⏎··········rootId,⏎········ with [[fileName,·slug]],·result,·details.weight,·details.title,·details.sectionId,·rootId

(prettier/prettier)


[error] 114-114: 'slugifyToC' was used before it was defined.

(no-use-before-define)


[error] 116-117: Delete ⏎·········

(prettier/prettier)


[error] 125-127: Replace ⏎··········?·sectionSlug⏎········· with ·?·sectionSlug

(prettier/prettier)


[error] 128-131: Replace ⏎··········details.slug.includes('/reference/specification/')·&&⏎··········!details.title⏎········ with details.slug.includes('/reference/specification/')·&&·!details.title

(prettier/prettier)


[error] 133-133: 'fileName' is already declared in the upper scope on line 71 column 13.

(no-shadow)


[error] 134-134: Unary operator '--' used.

(no-plusplus)


[error] 137-137: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 139-139: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 146-149: Replace ⏎············fileBaseName.includes('next-spec')·||⏎············fileBaseName.includes('next-major-spec')⏎·········· with fileBaseName.includes('next-spec')·||·fileBaseName.includes('next-major-spec')

(prettier/prettier)


[error] 161-161: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 163-163: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 163-165: Replace ⏎············fileName_without_extension.lastIndexOf('-')·+·1,⏎·········· with fileName_without_extension.lastIndexOf('-')·+·1

(prettier/prettier)


[error] 164-164: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 167-167: This line has a length of 166. Maximum allowed is 120.

(max-len)


[error] 181-181: Unnecessary escape character: #.

(no-useless-escape)


[error] 183-183: Use array destructuring.

(prefer-destructuring)


[error] 187-187: Use array destructuring.

(prefer-destructuring)


[error] 198-198: Unnecessary escape character: -.

(no-useless-escape)

scripts/build-rss.js

[error] 5-5: Unexpected require().

(global-require)


[error] 9-9: Assignment to function parameter 's'.

(no-param-reassign)


[error] 10-10: Assignment to function parameter 's'.

(no-param-reassign)


[error] 11-11: Assignment to function parameter 's'.

(no-param-reassign)


[error] 12-12: Assignment to function parameter 's'.

(no-param-reassign)


[error] 13-13: Assignment to function parameter 's'.

(no-param-reassign)


[error] 14-14: Assignment to function parameter 's'.

(no-param-reassign)


[error] 32-34: Replace ⏎········Missing·date·in·posts:·${missingDatePosts.map((p)·=>·p.title·||·p.slug).join(',·')},⏎······ with Missing·date·in·posts:·${missingDatePosts.map((p)·=>·p.title·||·p.slug).join(',·')}

(prettier/prettier)


[error] 59-61: Replace ⏎······(post)·=>·!post.title·||·!post.slug·||·!post.excerpt·||·!post.date,⏎···· with (post)·=>·!post.title·||·!post.slug·||·!post.excerpt·||·!post.date

(prettier/prettier)


[error] 64-66: Replace ⏎········Missing·required·fields·in·posts:·${invalidPosts.map((p)·=>·p.title·||·p.slug).join(',·')},⏎······ with Missing·required·fields·in·posts:·${invalidPosts.map((p)·=>·p.title·||·p.slug).join(',·')}

(prettier/prettier)


[error] 81-81: Delete ,

(prettier/prettier)


[error] 89-89: 'tmp' is never reassigned. Use 'const' instead.

(prefer-const)

scripts/build-tools.js

[error] 7-12: Replace ⏎··automatedToolsPath,⏎··manualToolsPath,⏎··toolsPath,⏎··tagsPath,⏎ with automatedToolsPath,·manualToolsPath,·toolsPath,·tagsPath

(prettier/prettier)


[error] 14-14: 'githubExtractData' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 15-15: 'automatedTools' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 17-20: Replace ⏎······automatedToolsPath,⏎······JSON.stringify(automatedTools,·null,·'··'),⏎···· with automatedToolsPath,·JSON.stringify(automatedTools,·null,·'··')

(prettier/prettier)


[error] 22-27: Replace ⏎······automatedTools,⏎······require(manualToolsPath),⏎······toolsPath,⏎······tagsPath,⏎···· with automatedTools,·require(manualToolsPath),·toolsPath,·tagsPath

(prettier/prettier)


[error] 24-24: Calls to require() should use string literals

(import/no-dynamic-require)


[error] 24-24: Unexpected require().

(global-require)


[error] 35-39: Replace ⏎····__dirname,⏎····'../config',⏎····'tools-automated.json',⏎·· with __dirname,·'../config',·'tools-automated.json'

(prettier/prettier)

scripts/casestudies/index.js

[error] 4-7: Replace ⏎··dirWithCaseStudy,⏎··writeFilePath,⏎ with dirWithCaseStudy,·writeFilePath

(prettier/prettier)


[error] 9-9: 'files' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 10-10: 'caseStudiesList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 11-18: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 11-11: 'file' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 13-13: Unexpected await inside a loop.

(no-await-in-loop)


[error] 17-17: Unexpected await inside a loop.

(no-await-in-loop)

scripts/compose.js

[error] 6-6: 'inquirer' should be listed in the project's dependencies, not devDependencies.

(import/no-extraneous-dependencies)


[error] 7-7: 'dedent' should be listed in the project's dependencies, not devDependencies.

(import/no-extraneous-dependencies)


[error] 11-11: 'd' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 12-12: 'date' is assigned a value but never used.

(no-unused-vars)


[error] 12-16: Replace ⏎····d.getFullYear(),⏎····('0'·+·(d.getMonth()·+·1)).slice(-2),⏎····('0'·+·d.getDate()).slice(-2),⏎·· with d.getFullYear(),·('0'·+·(d.getMonth()·+·1)).slice(-2),·('0'·+·d.getDate()).slice(-2)

(prettier/prettier)


[error] 14-14: Unexpected string concatenation.

(prefer-template)


[error] 15-15: Unexpected string concatenation.

(prefer-template)


[error] 18-18: Arrow function should not return assignment.

(no-return-assign)


[error] 19-19: Unexpected string concatenation.

(prefer-template)


[error] 95-95: Assignment (=) can be replaced with operator assignment (+=).

(operator-assignment)


[error] 95-95: Unexpected string concatenation.

(prefer-template)


[error] 121-128: Replace ⏎········'Communication',⏎········'Community',⏎········'Engineering',⏎········'Marketing',⏎········'Strategy',⏎········'Video',⏎······], with 'Communication',·'Community',·'Engineering',·'Marketing',·'Strategy',·'Video']

(prettier/prettier)


[error] 144-144: Unnecessary use of conditional expression for default assignment.

(no-unneeded-ternary)

scripts/dashboard/build-dashboard.js

[error] 23-23: Delete ,

(prettier/prettier)


[error] 24-24: Delete ,

(prettier/prettier)


[error] 33-33: Delete ,

(prettier/prettier)


[error] 44-46: Replace ⏎······await·getDiscussions(query,·pageSize,·result.search.pageInfo.endCursor),⏎···· with await·getDiscussions(query,·pageSize,·result.search.pageInfo.endCursor)

(prettier/prettier)


[error] 55-57: Replace ⏎······isPR·?·Queries.pullRequestById·:·Queries.issueById,⏎····· with isPR·?·Queries.pullRequestById·:·Queries.issueById,

(prettier/prettier)


[error] 58-58: Delete ··

(prettier/prettier)


[error] 59-59: Delete ··

(prettier/prettier)


[error] 60-60: Replace ··········authorization:·token·${process.env.GITHUB_TOKEN}, with ········authorization:·token·${process.env.GITHUB_TOKEN}``

(prettier/prettier)


[error] 61-61: Replace ········}, with ······}

(prettier/prettier)


[error] 62-63: Replace ······},⏎···· with ····}

(prettier/prettier)


[error] 78-81: Replace ⏎············isPR,⏎············discussion.id,⏎·········· with isPR,·discussion.id

(prettier/prettier)


[error] 82-82: Assignment to function parameter 'discussion'.

(no-param-reassign)


[error] 88-91: Replace ⏎············(acc,·curr)·=>·acc·+·curr.reactions.totalCount,⏎············0,⏎·········· with (acc,·curr)·=>·acc·+·curr.reactions.totalCount,·0

(prettier/prettier)


[error] 96-99: Replace ⏎··············(acc,·curr)·=>·acc·+·curr.comments.totalCount,⏎··············0,⏎············ with (acc,·curr)·=>·acc·+·curr.comments.totalCount,·0

(prettier/prettier)


[error] 111-113: Replace ⏎············finalInteractionsCount·/⏎············(monthsSince(discussion.timelineItems.updatedAt)·+·2)·**·1.8, with ·finalInteractionsCount·/·(monthsSince(discussion.timelineItems.updatedAt)·+·2)·**·1.8

(prettier/prettier)


[error] 113-113: 'monthsSince' was used before it was defined.

(no-use-before-define)


[error] 116-118: Replace ⏎··········there·were·some·issues·while·parsing·this·item:·${JSON.stringify(discussion)},⏎········ with there·were·some·issues·while·parsing·this·item:·${JSON.stringify(discussion)}

(prettier/prettier)


[error] 121-121: Delete ,

(prettier/prettier)


[error] 137-139: Replace ⏎····(issue)·=>·issue.author·!==·'asyncapi-bot',⏎·· with (issue)·=>·issue.author·!==·'asyncapi-bot'

(prettier/prettier)


[error] 149-149: Delete ,

(prettier/prettier)


[error] 165-167: Replace ⏎········!label.name.startsWith('area/')·&&⏎········!label.name.startsWith('good·first·issue'), with ·!label.name.startsWith('area/')·&&·!label.name.startsWith('good·first·issue')

(prettier/prettier)


[error] 168-168: Delete ,

(prettier/prettier)


[error] 173-175: Replace ⏎····label.name.startsWith(filter),⏎·· with ·label.name.startsWith(filter)

(prettier/prettier)


[error] 190-193: Replace ⏎······Queries.goodFirstIssues,⏎······20,⏎···· with Queries.goodFirstIssues,·20

(prettier/prettier)


[error] 197-197: Delete ,

(prettier/prettier)


[error] 220-220: Delete ,

(prettier/prettier)

scripts/finance/index.js

[error] 2-2: Delete ,

(prettier/prettier)


[error] 5-5: Unexpected use of file extension "js" for "../utils/readAndWriteJson.js"

(import/extensions)


[error] 7-13: Replace ⏎··currentDir,⏎··configDir,⏎··financeDir,⏎··year,⏎··jsonDataDir,⏎ with ·currentDir,·configDir,·financeDir,·year,·jsonDataDir·

(prettier/prettier)


[error] 15-21: Replace ⏎······currentDir,⏎······configDir,⏎······financeDir,⏎······year,⏎······'Expenses.yml',⏎···· with currentDir,·configDir,·financeDir,·year,·'Expenses.yml'

(prettier/prettier)


[error] 22-28: Replace ⏎······currentDir,⏎······configDir,⏎······financeDir,⏎······year,⏎······'ExpensesLink.yml',⏎···· with currentDir,·configDir,·financeDir,·year,·'ExpensesLink.yml'

(prettier/prettier)


[error] 31-36: Replace ⏎······currentDir,⏎······configDir,⏎······financeDir,⏎······jsonDataDir,⏎···· with currentDir,·configDir,·financeDir,·jsonDataDir

(prettier/prettier)

scripts/index.js

[error] 47-47: Delete ,

(prettier/prettier)

scripts/markdown/check-markdown.js

[error] 12-12: Do not use 'new' for side effects.

(no-new)


[error] 26-33: Replace ⏎····'title',⏎····'date',⏎····'type',⏎····'tags',⏎····'cover',⏎····'authors',⏎·· with 'title',·'date',·'type',·'tags',·'cover',·'authors'

(prettier/prettier)


[error] 38-38: Do not access Object.prototype method 'hasOwnProperty' from target object.

(no-prototype-builtins)


[error] 68-70: Replace ⏎············Invalid·URL·for·author·at·index·${index}:·${author.link},⏎·········· with Invalid·URL·for·author·at·index·${index}:·${author.link}

(prettier/prettier)


[error] 97-100: Replace ⏎····frontmatter.weight·===·undefined·||⏎····typeof·frontmatter.weight·!==·'number'⏎·· with frontmatter.weight·===·undefined·||·typeof·frontmatter.weight·!==·'number'

(prettier/prettier)


[error] 129-129: 'err' is already declared in the upper scope on line 114 column 27.

(no-shadow)

scripts/tools/categorylist.js

[error] 6-7: Replace ⏎······'The·following·is·a·list·of·APIs·that·expose·functionality·related·to·AsyncAPI.', with ·'The·following·is·a·list·of·APIs·that·expose·functionality·related·to·AsyncAPI.'

(prettier/prettier)


[error] 12-13: Replace ⏎······'The·following·is·a·list·of·tools·that·generate·AsyncAPI·documents·from·your·code.', with ·'The·following·is·a·list·of·tools·that·generate·AsyncAPI·documents·from·your·code.'

(prettier/prettier)


[error] 19-19: Delete ,

(prettier/prettier)


[error] 25-25: Delete ,

(prettier/prettier)


[error] 30-31: Replace ⏎······'The·following·is·a·list·of·directories·that·index·public·AsyncAPI·documents.', with ·'The·following·is·a·list·of·directories·that·index·public·AsyncAPI·documents.'

(prettier/prettier)


[error] 37-37: Delete ,

(prettier/prettier)


[error] 42-43: Replace ⏎······'The·following·is·a·list·of·editors·or·related·tools·that·allow·editing·of·AsyncAPI·document.', with ·'The·following·is·a·list·of·editors·or·related·tools·that·allow·editing·of·AsyncAPI·document.'

(prettier/prettier)


[error] 48-49: Replace ⏎······'The·following·is·a·list·of·UI·components·to·view·AsyncAPI·documents.', with ·'The·following·is·a·list·of·UI·components·to·view·AsyncAPI·documents.'

(prettier/prettier)


[error] 55-55: This line has a length of 152. Maximum allowed is 120.

(max-len)


[error] 55-55: Delete ,

(prettier/prettier)


[error] 60-61: Replace ⏎······'The·following·is·a·list·of·API/application·frameworks·that·make·use·of·AsyncAPI.', with ·'The·following·is·a·list·of·API/application·frameworks·that·make·use·of·AsyncAPI.'

(prettier/prettier)


[error] 66-67: Replace ⏎······'The·following·is·a·list·of·GitHub·Actions·that·you·can·use·in·your·workflows', with ·'The·following·is·a·list·of·GitHub·Actions·that·you·can·use·in·your·workflows'

(prettier/prettier)


[error] 73-73: Delete ,

(prettier/prettier)


[error] 78-79: Replace ⏎······'The·following·is·a·list·of·tools·that·validate·AsyncAPI·documents.', with ·'The·following·is·a·list·of·tools·that·validate·AsyncAPI·documents.'

(prettier/prettier)


[error] 84-85: Replace ⏎······'The·following·is·a·list·of·tools·that·compare·AsyncAPI·documents.', with ·'The·following·is·a·list·of·tools·that·compare·AsyncAPI·documents.'

(prettier/prettier)


[error] 90-91: Replace ⏎······'The·following·is·a·list·of·tools·that·you·can·work·with·in·terminal·or·do·some·CI/CD·automation.', with ·'The·following·is·a·list·of·tools·that·you·can·work·with·in·terminal·or·do·some·CI/CD·automation.'

(prettier/prettier)


[error] 96-97: Replace ⏎······'The·following·is·a·list·of·tools·that·you·can·work·with·to·bundle·AsyncAPI·documents.', with ·'The·following·is·a·list·of·tools·that·you·can·work·with·to·bundle·AsyncAPI·documents.'

(prettier/prettier)


[error] 102-103: Replace ⏎······'The·following·is·a·list·of·extensions·for·different·IDEs·like·VSCode,·IntelliJ·IDEA·and·others', with ·'The·following·is·a·list·of·extensions·for·different·IDEs·like·VSCode,·IntelliJ·IDEA·and·others'

(prettier/prettier)


[error] 109-109: Delete ,

(prettier/prettier)


[error] 114-115: Replace ⏎······'The·following·is·a·list·of·tools·that·comes·under·Other·category.', with ·'The·following·is·a·list·of·tools·that·comes·under·Other·category.'

(prettier/prettier)


[error] 116-116: Delete ,

(prettier/prettier)

scripts/tools/combine-tools.js

[error] 2-2: Unexpected use of file extension "js" for "./categorylist.js"

(import/extensions)


[error] 4-4: fs import should occur before import of ./tags-color

(import/order)


[error] 6-6: ajv import should occur before import of ./tags-color

(import/order)


[error] 7-7: ajv-formats import should occur before import of ./tags-color

(import/order)


[error] 8-8: Expected 1 empty line after require statement not followed by another require.

(import/newline-after-import)


[error] 8-8: fuse.js import should occur before import of ./tags-color

(import/order)


[error] 13-13: 'finalTools' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 14-19: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 14-14: All 'var' declarations must be at the top of the function scope.

(vars-on-top)


[error] 14-14: Unexpected var, use let or const instead.

(no-var)


[error] 17-17: Delete ,

(prettier/prettier)


[error] 26-26: Delete ,

(prettier/prettier)


[error] 31-32: Split 'let' declarations into multiple statements.

(one-var)


[error] 31-31: 'languageList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 32-32: 'technologyList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 33-34: Split 'let' declarations into multiple statements.

(one-var)


[error] 39-39: 'finalObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 41-41: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 43-43: 'languageArray' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 45-47: Replace ⏎········toolObject.filters.language,⏎······ with toolObject.filters.language

(prettier/prettier)


[error] 53-53: 'languageObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 56-56: Delete ,

(prettier/prettier)


[error] 63-79: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 63-63: Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.

(no-unsafe-optional-chaining)


[error] 64-64: Unexpected await inside a loop.

(no-await-in-loop)


[error] 70-70: 'languageObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 73-73: Delete ,

(prettier/prettier)


[error] 83-83: 'technologyArray' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 85-101: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 85-85: Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.

(no-unsafe-optional-chaining)


[error] 86-86: Unexpected await inside a loop.

(no-await-in-loop)


[error] 92-92: 'technologyObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 95-95: Delete ,

(prettier/prettier)


[error] 109-114: Replace ⏎··automatedTools,⏎··manualTools,⏎··toolsPath,⏎··tagsPath,⏎ with automatedTools,·manualTools,·toolsPath,·tagsPath

(prettier/prettier)


[error] 115-152: for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.

(no-restricted-syntax)


[error] 115-152: The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.

(guard-for-in)


[error] 116-116: 'finalToolsList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 118-120: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 119-119: Unexpected await inside a loop.

(no-await-in-loop)


[error] 123-146: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 125-125: Unexpected await inside a loop.

(no-await-in-loop)


[error] 129-131: Replace ⏎··············'https://github.com/asyncapi/',⏎············ with 'https://github.com/asyncapi/'

(prettier/prettier)


[error] 133-133: 'toolObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 133-133: Unexpected await inside a loop.

(no-await-in-loop)


[error] 134-134: Unexpected await inside a loop.

(no-await-in-loop)


[error] 136-138: Replace ⏎············'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation',⏎·········· with 'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation'

(prettier/prettier)


[error] 141-144: Replace ⏎············'Validation·errors:',⏎············JSON.stringify(validate.errors,·null,·2),⏎·········· with 'Validation·errors:',·JSON.stringify(validate.errors,·null,·2)

(prettier/prettier)


[error] 148-150: Replace ⏎······tool.title.localeCompare(anotherTool.title),⏎···· with ·tool.title.localeCompare(anotherTool.title)

(prettier/prettier)


[error] 154-157: Replace ⏎····tagsPath,⏎····JSON.stringify({·languages:·languageList,·technologies:·technologyList·}),⏎·· with tagsPath,·JSON.stringify({·languages:·languageList,·technologies:·technologyList·})

(prettier/prettier)

scripts/tools/extract-tools-github.js

[error] 13-14: Replace ······},⏎···· with ····}

(prettier/prettier)

scripts/tools/tags-color.js

[error] 6-6: Delete ,

(prettier/prettier)


[error] 11-11: Delete ,

(prettier/prettier)


[error] 16-16: Delete ,

(prettier/prettier)


[error] 21-21: Delete ,

(prettier/prettier)


[error] 26-26: Delete ,

(prettier/prettier)


[error] 31-31: Delete ,

(prettier/prettier)


[error] 36-36: Delete ,

(prettier/prettier)


[error] 41-41: Delete ,

(prettier/prettier)


[error] 46-46: Delete ,

(prettier/prettier)


[error] 51-51: Delete ,

(prettier/prettier)


[error] 56-56: Delete ,

(prettier/prettier)


[error] 61-61: Delete ,

(prettier/prettier)


[error] 66-66: Delete ,

(prettier/prettier)


[error] 71-71: Delete ,

(prettier/prettier)


[error] 76-76: Delete ,

(prettier/prettier)


[error] 81-81: Delete ,

(prettier/prettier)


[error] 86-86: Delete ,

(prettier/prettier)


[error] 87-87: Delete ,

(prettier/prettier)


[error] 94-94: Delete ,

(prettier/prettier)


[error] 99-99: Delete ,

(prettier/prettier)


[error] 104-104: Delete ,

(prettier/prettier)


[error] 109-109: Delete ,

(prettier/prettier)


[error] 114-114: Delete ,

(prettier/prettier)


[error] 119-119: Delete ,

(prettier/prettier)


[error] 124-124: Delete ,

(prettier/prettier)


[error] 129-129: Delete ,

(prettier/prettier)


[error] 134-134: Delete ,

(prettier/prettier)


[error] 139-139: Delete ,

(prettier/prettier)


[error] 144-144: Delete ,

(prettier/prettier)


[error] 149-149: Delete ,

(prettier/prettier)


[error] 154-154: Delete ,

(prettier/prettier)


[error] 159-159: Delete ,

(prettier/prettier)


[error] 164-164: Delete ,

(prettier/prettier)


[error] 169-169: Delete ,

(prettier/prettier)


[error] 174-174: Delete ,

(prettier/prettier)


[error] 175-175: Delete ,

(prettier/prettier)

scripts/tools/tools-object.js

[error] 1-1: ./tools-schema.json import should occur after import of fuse.js

(import/order)


[error] 6-6: Expected 1 empty line after require statement not followed by another require.

(import/newline-after-import)


[error] 17-17: Delete ,

(prettier/prettier)


[error] 27-32: Replace ⏎··toolFile,⏎··repositoryUrl·=·'',⏎··repoDescription·=·'',⏎··isAsyncAPIrepo·=·'',⏎ with toolFile,·repositoryUrl·=·'',·repoDescription·=·'',·isAsyncAPIrepo·=·''

(prettier/prettier)


[error] 33-33: 'resultantObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 38-40: Replace ⏎········?·toolFile.links.repoUrl⏎········:·repositoryUrl, with ·?·toolFile.links.repoUrl·:·repositoryUrl

(prettier/prettier)


[error] 44-46: Replace ⏎········?·toolFile.filters.hasCommercial⏎······· with ·?·toolFile.filters.hasCommercial

(prettier/prettier)


[error] 47-47: Delete ,

(prettier/prettier)


[error] 48-48: Delete ,

(prettier/prettier)


[error] 65-65: Delete ,

(prettier/prettier)


[error] 75-75: Identifier 'reference_id' is not in camel case.

(camelcase)


[error] 75-75: 'reference_id' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 76-76: Identifier 'download_url' is not in camel case.

(camelcase)


[error] 76-76: 'download_url' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 76-76: Identifier 'reference_id' is not in camel case.

(camelcase)


[error] 78-78: Unexpected await inside a loop.

(no-await-in-loop)


[error] 80-80: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 81-81: Unexpected await inside a loop.

(no-await-in-loop)


[error] 83-83: Expected exception block, space or tab after '//' in comment.

(spaced-comment)


[error] 84-84: Unexpected await inside a loop.

(no-await-in-loop)


[error] 87-87: 'repositoryUrl' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 88-88: 'repoDescription' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 89-89: 'isAsyncAPIrepo' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 90-90: 'toolObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 90-95: Unexpected await inside a loop.

(no-await-in-loop)


[error] 90-95: Replace ⏎············jsonToolFileContent,⏎············repositoryUrl,⏎············repoDescription,⏎············isAsyncAPIrepo,⏎·········· with jsonToolFileContent,·repositoryUrl,·repoDescription,·isAsyncAPIrepo

(prettier/prettier)


[error] 102-102: 'searchedCategoryName' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 103-107: Replace ⏎················!finalToolsObject[searchedCategoryName].toolsList.find(⏎··················(element)·=>·element·===·toolObject,⏎················)⏎·············· with !finalToolsObject[searchedCategoryName].toolsList.find((element)·=>·element·===·toolObject)

(prettier/prettier)


[error] 108-110: Replace ⏎··················toolObject,⏎················ with toolObject

(prettier/prettier)


[error] 112-112: This line has a length of 131. Maximum allowed is 120.

(max-len)


[error] 113-118: Unexpected if as the only statement in an else block.

(no-lonely-if)


[error] 113-117: Replace ⏎················!finalToolsObject['Others'].toolsList.find(⏎··················(element)·=>·element·===·toolObject,⏎················)⏎·············· with !finalToolsObject['Others'].toolsList.find((element)·=>·element·===·toolObject)

(prettier/prettier)


[error] 114-114: ["Others"] is better written in dot notation.

(dot-notation)


[error] 118-118: ["Others"] is better written in dot notation.

(dot-notation)


[error] 122-124: Replace ⏎············'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation',⏎·········· with 'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation'

(prettier/prettier)


[error] 127-130: Replace ⏎············'Validation·errors:',⏎············JSON.stringify(validate.errors,·null,·2),⏎·········· with 'Validation·errors:',·JSON.stringify(validate.errors,·null,·2)

(prettier/prettier)

scripts/utils.js

[error] 21-23: Replace ⏎········Invalid·content·format:\nJSON·Parse·Error:·${jsonError}\nYAML·Parse·Error:·${yamlError},⏎······ with Invalid·content·format:\nJSON·Parse·Error:·${jsonError}\nYAML·Parse·Error:·${yamlError}

(prettier/prettier)

scripts/utils/readAndWriteJson.js

[error] 2-2: Delete ,

(prettier/prettier)

🪛 GitHub Check: codecov/patch
scripts/build-post-list.js

[warning] 33-35: scripts/build-post-list.js#L33-L35
Added lines #L33 - L35 were not covered by tests


[warning] 41-43: scripts/build-post-list.js#L41-L43
Added lines #L41 - L43 were not covered by tests


[warning] 45-46: scripts/build-post-list.js#L45-L46
Added lines #L45 - L46 were not covered by tests


[warning] 50-50: scripts/build-post-list.js#L50
Added line #L50 was not covered by tests


[warning] 65-66: scripts/build-post-list.js#L65-L66
Added lines #L65 - L66 were not covered by tests


[warning] 71-73: scripts/build-post-list.js#L71-L73
Added lines #L71 - L73 were not covered by tests


[warning] 78-78: scripts/build-post-list.js#L78
Added line #L78 was not covered by tests


[warning] 82-82: scripts/build-post-list.js#L82
Added line #L82 was not covered by tests


[warning] 88-88: scripts/build-post-list.js#L88
Added line #L88 was not covered by tests


[warning] 90-91: scripts/build-post-list.js#L90-L91
Added lines #L90 - L91 were not covered by tests


[warning] 94-95: scripts/build-post-list.js#L94-L95
Added lines #L94 - L95 were not covered by tests


[warning] 97-101: scripts/build-post-list.js#L97-L101
Added lines #L97 - L101 were not covered by tests


[warning] 110-110: scripts/build-post-list.js#L110
Added line #L110 was not covered by tests


[warning] 112-116: scripts/build-post-list.js#L112-L116
Added lines #L112 - L116 were not covered by tests


[warning] 118-125: scripts/build-post-list.js#L118-L125
Added lines #L118 - L125 were not covered by tests


[warning] 128-128: scripts/build-post-list.js#L128
Added line #L128 was not covered by tests


[warning] 132-134: scripts/build-post-list.js#L132-L134
Added lines #L132 - L134 were not covered by tests


[warning] 137-137: scripts/build-post-list.js#L137
Added line #L137 was not covered by tests


[warning] 139-139: scripts/build-post-list.js#L139
Added line #L139 was not covered by tests


[warning] 142-143: scripts/build-post-list.js#L142-L143
Added lines #L142 - L143 were not covered by tests


[warning] 146-146: scripts/build-post-list.js#L146
Added line #L146 was not covered by tests


[warning] 150-150: scripts/build-post-list.js#L150
Added line #L150 was not covered by tests


[warning] 152-152: scripts/build-post-list.js#L152
Added line #L152 was not covered by tests


[warning] 155-155: scripts/build-post-list.js#L155
Added line #L155 was not covered by tests


[warning] 160-161: scripts/build-post-list.js#L160-L161
Added lines #L160 - L161 were not covered by tests


[warning] 163-163: scripts/build-post-list.js#L163
Added line #L163 was not covered by tests


[warning] 168-168: scripts/build-post-list.js#L168
Added line #L168 was not covered by tests


[warning] 172-172: scripts/build-post-list.js#L172
Added line #L172 was not covered by tests


[warning] 181-181: scripts/build-post-list.js#L181
Added line #L181 was not covered by tests


[warning] 183-183: scripts/build-post-list.js#L183
Added line #L183 was not covered by tests

🪛 Biome
scripts/compose.js

[error] 18-18: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

scripts/markdown/check-markdown.js

[error] 38-38: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

scripts/tools/combine-tools.js

[error] 63-63: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 85-85: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 122-122: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (10)
scripts/utils.js (3)

4-8: LGTM! Well-structured input validation.

The type checking implementation is clean and well-documented, with appropriate early return pattern.


10-14: LGTM! Clean JSON parsing implementation.

The JSON parsing logic is well-structured with appropriate error handling.


1-27: Verify no logic changes were introduced.

The changes appear to be purely formatting-related, which aligns with the PR objectives. Let's verify there are no functional changes by comparing the logic with the previous version.

✅ Verification successful

Changes are purely stylistic, no logic modifications detected

The diff output confirms that the only changes are:

  1. Switching from double quotes to single quotes in string comparison
  2. Reformatting the error message string across multiple lines

These modifications are purely stylistic and do not affect the functionality of the code.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Compare the logical structure of the current and previous versions
# by removing whitespace and comments to detect any actual logic changes.

# Get the previous version of the file
git show HEAD^:scripts/utils.js | sed 's/[[:space:]]//g' | grep -v '^//' > /tmp/prev.js

# Get the current version
cat scripts/utils.js | sed 's/[[:space:]]//g' | grep -v '^//' > /tmp/curr.js

# Compare the versions
diff /tmp/prev.js /tmp/curr.js

Length of output: 485

🧰 Tools
🪛 eslint

[error] 21-23: Replace ⏎········Invalid·content·format:\nJSON·Parse·Error:·${jsonError}\nYAML·Parse·Error:·${yamlError},⏎······ with Invalid·content·format:\nJSON·Parse·Error:·${jsonError}\nYAML·Parse·Error:·${yamlError}

(prettier/prettier)

scripts/finance/index.js (4)

15-28: LGTM! Path construction is clear and consistent

The multi-line format for path resolution makes each path component easily readable and maintainable. While the linter suggests single-line format, the current style improves clarity when dealing with deep directory structures.

🧰 Tools
🪛 eslint

[error] 15-21: Replace ⏎······currentDir,⏎······configDir,⏎······financeDir,⏎······year,⏎······'Expenses.yml',⏎···· with currentDir,·configDir,·financeDir,·year,·'Expenses.yml'

(prettier/prettier)


[error] 22-28: Replace ⏎······currentDir,⏎······configDir,⏎······financeDir,⏎······year,⏎······'ExpensesLink.yml',⏎···· with currentDir,·configDir,·financeDir,·year,·'ExpensesLink.yml'

(prettier/prettier)


30-44: LGTM! Directory creation and file operations are well-structured

The code follows best practices:

  • Uses recursive directory creation
  • Separates directory creation from file operations
  • Includes helpful comments explaining the operations
🧰 Tools
🪛 eslint

[error] 31-36: Replace ⏎······currentDir,⏎······configDir,⏎······financeDir,⏎······jsonDataDir,⏎···· with currentDir,·configDir,·financeDir,·jsonDataDir

(prettier/prettier)


1-5: Verify project's import extension policy

The .js extension in the import statement might not align with the project's conventions. While ESLint flags this, some projects intentionally keep extensions for clarity.

#!/bin/bash
# Check if other files in the project use .js extensions in imports
rg -g '*.js' -l 'require.*\.js[\'"]\)'

# Check if there's an ESLint configuration that might override this rule
fd -g '.eslintrc*'
🧰 Tools
🪛 eslint

[error] 2-2: Delete ,

(prettier/prettier)


[error] 5-5: Unexpected use of file extension "js" for "../utils/readAndWriteJson.js"

(import/extensions)


7-13: LGTM! Parameter formatting enhances readability

The multi-line parameter formatting improves readability by clearly separating each parameter. While the linter suggests a single-line format, the current style is more maintainable, especially with multiple parameters.

✅ Verification successful

The previous command had syntax issues. Let's try using ripgrep to find similar function declarations and their formatting patterns. The -U flag enables multiline matching, which is necessary for checking parameter formatting across lines.


Parameter formatting is consistent with project style

Based on the codebase analysis, the multi-line parameter formatting in buildFinanceInfoList follows the project's pattern for functions with multiple parameters, especially when using object destructuring. This is evident in other similar functions like buildMeetings, buildNewsroomVideos, and other async functions throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if similar function signatures in the project use the same formatting
ast-grep --pattern 'module.exports = async function $NAME({ $$$' 

Length of output: 408


Script:

#!/bin/bash
# Search for exported async functions with object destructuring parameters
rg -U "module\.exports\s*=\s*async\s*function.*\{[\s\S]*?\}" --type js -A 5

# Also check for other async function declarations with object destructuring
rg -U "async\s+function.*\{[\s\S]*?\}" --type js -A 5

Length of output: 16942

🧰 Tools
🪛 eslint

[error] 7-13: Replace ⏎··currentDir,⏎··configDir,⏎··financeDir,⏎··year,⏎··jsonDataDir,⏎ with ·currentDir,·configDir,·financeDir,·year,·jsonDataDir·

(prettier/prettier)

scripts/build-rss.js (1)

37-57: LGTM! RSS feed configuration is well-structured

The RSS feed configuration follows the proper RSS 2.0 specification and includes all required channel elements. The formatting changes improve readability while maintaining the correct structure.

scripts/tools/tools-schema.json (2)

17-37: LGTM! Well-structured links object

The links object is well-organized with clear descriptions and proper URI format validation for all URL properties.


1-209: Note: Changes extend beyond formatting

While the PR objectives state this is a formatting-focused change, this file includes structural changes such as:

  • Addition of new description property
  • Addition of new repoUrl property
  • Addition of new hasCommercial property
  • Enhanced property descriptions

These changes improve the schema but exceed the stated scope of formatting changes.

Comment on lines 4 to 7
module.exports = async function buildCaseStudiesList(
dirWithCaseStudy,
writeFilePath,
) {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Align function signature with prettier configuration

The multi-line parameter format should be collapsed to a single line according to your prettier configuration.

-module.exports = async function buildCaseStudiesList(
-  dirWithCaseStudy,
-  writeFilePath,
-) {
+module.exports = async function buildCaseStudiesList(dirWithCaseStudy, writeFilePath) {
📝 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
module.exports = async function buildCaseStudiesList(
dirWithCaseStudy,
writeFilePath,
) {
module.exports = async function buildCaseStudiesList(dirWithCaseStudy, writeFilePath) {
🧰 Tools
🪛 eslint

[error] 4-7: Replace ⏎··dirWithCaseStudy,⏎··writeFilePath,⏎ with dirWithCaseStudy,·writeFilePath

(prettier/prettier)

Comment on lines +12 to +17
const caseStudyFileName = [dirWithCaseStudy, file].join('/');
const caseStudyContent = await readFile(caseStudyFileName, 'utf-8');
const jsonContent = convertToJson(caseStudyContent);

caseStudiesList.push(jsonContent);
await writeFile(writeFilePath, JSON.stringify(caseStudiesList))
}
} catch (err) {
throw new Error(err);
caseStudiesList.push(jsonContent);
await writeFile(writeFilePath, JSON.stringify(caseStudiesList));
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 performance issue: Inefficient file operations

The current implementation writes to the file on every iteration of the loop, which is inefficient. Consider collecting all case studies first, then writing once at the end.

     const files = await readdir(dirWithCaseStudy);
-    let caseStudiesList = [];
+    const caseStudiesList = [];
-    for (let file of files) {
-      const caseStudyFileName = [dirWithCaseStudy, file].join('/');
-      const caseStudyContent = await readFile(caseStudyFileName, 'utf-8');
-      const jsonContent = convertToJson(caseStudyContent);
-
-      caseStudiesList.push(jsonContent);
-      await writeFile(writeFilePath, JSON.stringify(caseStudiesList));
-    }
+    await Promise.all(
+      files.map(async (file) => {
+        const caseStudyFileName = [dirWithCaseStudy, file].join('/');
+        const caseStudyContent = await readFile(caseStudyFileName, 'utf-8');
+        const jsonContent = convertToJson(caseStudyContent);
+        caseStudiesList.push(jsonContent);
+      })
+    );
+    await writeFile(writeFilePath, JSON.stringify(caseStudiesList));
📝 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
const caseStudyFileName = [dirWithCaseStudy, file].join('/');
const caseStudyContent = await readFile(caseStudyFileName, 'utf-8');
const jsonContent = convertToJson(caseStudyContent);
caseStudiesList.push(jsonContent);
await writeFile(writeFilePath, JSON.stringify(caseStudiesList))
}
} catch (err) {
throw new Error(err);
caseStudiesList.push(jsonContent);
await writeFile(writeFilePath, JSON.stringify(caseStudiesList));
const files = await readdir(dirWithCaseStudy);
const caseStudiesList = [];
await Promise.all(
files.map(async (file) => {
const caseStudyFileName = [dirWithCaseStudy, file].join('/');
const caseStudyContent = await readFile(caseStudyFileName, 'utf-8');
const jsonContent = convertToJson(caseStudyContent);
caseStudiesList.push(jsonContent);
})
);
await writeFile(writeFilePath, JSON.stringify(caseStudiesList));
🧰 Tools
🪛 eslint

[error] 13-13: Unexpected await inside a loop.

(no-await-in-loop)


[error] 17-17: Unexpected await inside a loop.

(no-await-in-loop)

languageFuse = new Fuse(languageList, options);
}
} else {
for (const language of toolObject?.filters?.language) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unsafe optional chaining to prevent runtime errors

The current optional chaining usage could throw TypeError if the chain short-circuits with undefined.

-      for (const language of toolObject?.filters?.language) {
+      for (const language of toolObject?.filters?.language ?? []) {

-    for (const technology of toolObject?.filters?.technology) {
+    for (const technology of toolObject?.filters?.technology ?? []) {

Also applies to: 85-85

🧰 Tools
🪛 Biome

[error] 63-63: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🪛 eslint

[error] 63-79: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 63-63: Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.

(no-unsafe-optional-chaining)

Comment on lines 13 to 19
let finalTools = {};
for (var category of categoryList) {
finalTools[category.name] = {
description: category.description,
toolsList: []
};
finalTools[category.name] = {
description: category.description,
toolsList: [],
};
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Modernize variable declarations and fix formatting

Update variable declarations to use modern JavaScript conventions.

-let finalTools = {};
-for (var category of categoryList) {
+const finalTools = {};
+for (const category of categoryList) {
   finalTools[category.name] = {
     description: category.description,
-    toolsList: [],
+    toolsList: []
   };
 }
📝 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
let finalTools = {};
for (var category of categoryList) {
finalTools[category.name] = {
description: category.description,
toolsList: []
};
finalTools[category.name] = {
description: category.description,
toolsList: [],
};
}
const finalTools = {};
for (const category of categoryList) {
finalTools[category.name] = {
description: category.description,
toolsList: []
};
}
🧰 Tools
🪛 eslint

[error] 13-13: 'finalTools' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 14-19: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 14-14: All 'var' declarations must be at the top of the function scope.

(vars-on-top)


[error] 14-14: Unexpected var, use let or const instead.

(no-var)


[error] 17-17: Delete ,

(prettier/prettier)

Comment on lines 115 to 152
for (const key in automatedTools) {
let finalToolsList = [];
if (automatedTools[key].toolsList.length) {
for (const tool of automatedTools[key].toolsList) {
finalToolsList.push(await getFinalTool(tool));
}
}
if (manualTools[key] && manualTools[key].toolsList.length) {
for (const tool of manualTools[key].toolsList) {
let isAsyncAPIrepo;
const isValid = await validate(tool);
if (isValid) {
if (tool?.links?.repoUrl) {
const url = new URL(tool.links.repoUrl);
isAsyncAPIrepo = url.href.startsWith(
'https://github.com/asyncapi/',
);
} else isAsyncAPIrepo = false;
let toolObject = await createToolObject(tool, '', '', isAsyncAPIrepo);
finalToolsList.push(await getFinalTool(toolObject));
} else {
console.error(
'Script is not failing, it is just dropping errors for further investigation',
);
console.error(`Invalid ${tool.title} .asyncapi-tool file.`);
console.error(`Located in manual-tools.json file`);
console.error(
'Validation errors:',
JSON.stringify(validate.errors, null, 2),
);
}
finalToolsList.sort((tool, anotherTool) => tool.title.localeCompare(anotherTool.title));
finalTools[key].toolsList = finalToolsList
}
}
fs.writeFileSync(toolsPath,JSON.stringify(finalTools));
fs.writeFileSync(tagsPath,JSON.stringify({ languages: languageList, technologies: technologyList }),)
}
finalToolsList.sort((tool, anotherTool) =>
tool.title.localeCompare(anotherTool.title),
);
finalTools[key].toolsList = finalToolsList;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace for-in loop with Object.entries

Use modern iteration methods to avoid prototype chain iteration issues.

-  for (const key in automatedTools) {
+  for (const [key, value] of Object.entries(automatedTools)) {
+    if (!Object.prototype.hasOwnProperty.call(automatedTools, key)) continue;

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome

[error] 122-122: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 eslint

[error] 115-152: for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.

(no-restricted-syntax)


[error] 115-152: The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.

(guard-for-in)


[error] 116-116: 'finalToolsList' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 118-120: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 119-119: Unexpected await inside a loop.

(no-await-in-loop)


[error] 123-146: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 125-125: Unexpected await inside a loop.

(no-await-in-loop)


[error] 129-131: Replace ⏎··············'https://github.com/asyncapi/',⏎············ with 'https://github.com/asyncapi/'

(prettier/prettier)


[error] 133-133: 'toolObject' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 133-133: Unexpected await inside a loop.

(no-await-in-loop)


[error] 134-134: Unexpected await inside a loop.

(no-await-in-loop)


[error] 136-138: Replace ⏎············'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation',⏎·········· with 'Script·is·not·failing,·it·is·just·dropping·errors·for·further·investigation'

(prettier/prettier)


[error] 141-144: Replace ⏎············'Validation·errors:',⏎············JSON.stringify(validate.errors,·null,·2),⏎·········· with 'Validation·errors:',·JSON.stringify(validate.errors,·null,·2)

(prettier/prettier)


[error] 148-150: Replace ⏎······tool.title.localeCompare(anotherTool.title),⏎···· with ·tool.title.localeCompare(anotherTool.title)

(prettier/prettier)

Comment on lines 134 to 192
structuredPosts[0] = docPosts.filter((p) => p.slug === '/docs')[0];

// Traversing the structuredPosts in order to add `nextPage` and `prevPage` details for each page
let countDocPages = structuredPosts.length;
structuredPosts = structuredPosts.map((post, index) => {
// post item specifying the root Section or sub-section in the docs are excluded as
// they doesn't comprise any Doc Page or content to be shown in website.
// post item specifying the root Section or sub-section in the docs are excluded as
// they doesn't comprise any Doc Page or content to be shown in website.
if (post?.isRootSection || post?.isSection || index == 0) {
if (post?.isRootSection || index == 0)
rootSections.push(post.title)
return post
if (post?.isRootSection || index == 0) rootSections.push(post.title);
return post;
}

let nextPage = {}, prevPage = {}
let nextPage = {},
prevPage = {};
let docPost = post;

// checks whether the next page for the current docPost item exists or not
if (index + 1 < countDocPages) {
// checks whether the next item inside structuredPosts is a rootElement or a sectionElement
// if yes, it goes again to a next to next item in structuredPosts to link the nextPage
if (!structuredPosts[index + 1].isRootElement && !structuredPosts[index + 1].isSection) {
if (
!structuredPosts[index + 1].isRootElement &&
!structuredPosts[index + 1].isSection
) {
nextPage = {
title: structuredPosts[index + 1].title,
href: structuredPosts[index + 1].slug
}
href: structuredPosts[index + 1].slug,
};
} else {
nextPage = {
title: `${structuredPosts[index + 1].title} - ${structuredPosts[index + 2].title}`,
href: structuredPosts[index + 2].slug
}
href: structuredPosts[index + 2].slug,
};
}
docPost = { ...docPost, nextPage }
docPost = { ...docPost, nextPage };
}

// checks whether the previous page for the current docPost item exists or not
if (index > 0) {
// checks whether the previous item inside structuredPosts is a rootElement or a sectionElement
// if yes, it goes again to a next previous item in structuredPosts to link the prevPage
if (!structuredPosts[index - 1]?.isRootElement && !structuredPosts[index - 1]?.isSection) {
if (
!structuredPosts[index - 1]?.isRootElement &&
!structuredPosts[index - 1]?.isSection
) {
prevPage = {
title: structuredPosts[index - 1].title,
href: structuredPosts[index - 1].slug
}
docPost = { ...docPost, prevPage }
href: structuredPosts[index - 1].slug,
};
docPost = { ...docPost, prevPage };
} else {
// additonal check for the first page of Docs so that it doesn't give any Segementation fault
if (index - 2 >= 0) {
prevPage = {
title: `${structuredPosts[index - 1]?.isRootSection ? rootSections[rootSections.length - 2] : rootSections[rootSections.length - 1]} - ${structuredPosts[index - 2].title}`,
href: structuredPosts[index - 2].slug
href: structuredPosts[index - 2].slug,
};
docPost = { ...docPost, prevPage };
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve code quality in addDocButtons function

Several code quality improvements are needed:

  1. Use strict equality comparison
  2. Split variable declarations
  3. Simplify the if-else structure
  4. Use array destructuring
-   structuredPosts[0] = docPosts.filter((p) => p.slug === '/docs')[0];
+   [structuredPosts[0]] = docPosts.filter((p) => p.slug === '/docs');

    let countDocPages = structuredPosts.length;
    structuredPosts = structuredPosts.map((post, index) => {
-     if (post?.isRootSection || post?.isSection || index == 0) {
-       if (post?.isRootSection || index == 0) rootSections.push(post.title);
+     if (post?.isRootSection || post?.isSection || index === 0) {
+       if (post?.isRootSection || index === 0) rootSections.push(post.title);
        return post;
      }

-     let nextPage = {},
-       prevPage = {};
+     let nextPage = {};
+     let prevPage = {};

      // Simplify the if-else structure in the previous page logic
-     } else {
-       if (index - 2 >= 0) {
+     } else if (index - 2 >= 0) {

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 eslint

[error] 134-134: Use array destructuring.

(prefer-destructuring)


[error] 137-137: 'countDocPages' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 141-141: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 142-142: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 146-147: Split 'let' declarations into multiple statements.

(one-var)


[error] 154-157: Replace ⏎··········!structuredPosts[index·+·1].isRootElement·&&⏎··········!structuredPosts[index·+·1].isSection⏎········ with !structuredPosts[index·+·1].isRootElement·&&·!structuredPosts[index·+·1].isSection

(prettier/prettier)


[error] 160-160: Delete ,

(prettier/prettier)


[error] 165-165: Delete ,

(prettier/prettier)


[error] 175-178: Replace ⏎··········!structuredPosts[index·-·1]?.isRootElement·&&⏎··········!structuredPosts[index·-·1]?.isSection⏎········ with !structuredPosts[index·-·1]?.isRootElement·&&·!structuredPosts[index·-·1]?.isSection

(prettier/prettier)


[error] 181-181: Delete ,

(prettier/prettier)


[error] 186-192: Unexpected if as the only statement in an else block.

(no-lonely-if)


[error] 189-189: Delete ,

(prettier/prettier)

Comment on lines 96 to 114
// A recursion function, works on the logic of Depth First Search to traverse all the root and child posts of the
// DocTree to get sequential order of the Doc Posts
const convertDocPosts = (docObject) => {
try {
let docsArray = []
let docsArray = [];
// certain entries in the DocPosts are either a parent to many posts or itself a post.
docsArray.push(docObject?.item || docObject)
docsArray.push(docObject?.item || docObject);
if (docObject.children) {
let children = docObject.children
let children = docObject.children;
Object.keys(children).forEach((child) => {
let docChildArray = convertDocPosts(children[child])
docsArray = [...docsArray, ...docChildArray]
})
let docChildArray = convertDocPosts(children[child]);
docsArray = [...docsArray, ...docChildArray];
});
}
return docsArray
}
catch (err) {
return docsArray;
} catch (err) {
throw new Error('Error in convertDocPosts:', err);
}
}

};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve variable declarations and error handling in convertDocPosts

While the logic is correct, there are several improvements to be made:

  • Use const for variables that aren't reassigned
  • Use object destructuring
  • Include the error stack in the error message
const convertDocPosts = (docObject) => {
  try {
    let docsArray = [];
-   let children = docObject.children;
+   const { children } = docObject;
    Object.keys(children).forEach((child) => {
-     let docChildArray = convertDocPosts(children[child]);
+     const docChildArray = convertDocPosts(children[child]);
      docsArray = [...docsArray, ...docChildArray];
    });
    return docsArray;
  } catch (err) {
-   throw new Error('Error in convertDocPosts:', err);
+   throw new Error(`Error in convertDocPosts: ${err.message}\n${err.stack}`);
  }
};

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 eslint

[error] 104-104: Use object destructuring.

(prefer-destructuring)


[error] 104-104: 'children' is never reassigned. Use 'const' instead.

(prefer-const)


[error] 106-106: 'docChildArray' is never reassigned. Use 'const' instead.

(prefer-const)

@JeelRajodiya
Copy link
Contributor Author

JeelRajodiya commented Nov 16, 2024

@akshatnema I have formatted all the scripts using ESLint, but there are still some errors related to the syntax displayed by eslint.
Should I resolve these errors as well? Please let me know if I am not using ESlint correctly.

(Errors displayed by ESLint)

image

@JeelRajodiya JeelRajodiya changed the title refactor: format build scripts using eslint-prettier refactor: format build scripts using eslint Nov 16, 2024
@akshatnema
Copy link
Member

@JeelRajodiya Yeah, you should remove these eslint errors from the scripts. But in the migrated ts files, not in js files. Since others are also contributing, they will see so many conflicts around here. So better we should stick our eslint rules to ts files only.

@JeelRajodiya
Copy link
Contributor Author

JeelRajodiya commented Nov 17, 2024

@akshatnema Should We merge this PR? it only formats the build scripts (javascript).
in case it is difficult to review, Please Let me know.

@JeelRajodiya JeelRajodiya marked this pull request as ready for review November 17, 2024 15:04
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: 16

🧹 Outside diff range and nitpick comments (18)
scripts/adopters/index.js (1)

4-6: Consider adding error handling for file operations.

While the formatting looks clean, since this is a file operation, it would be good to add try-catch for better error handling. However, this can be addressed during the TypeScript migration to avoid conflicts.

 module.exports = async function buildAdoptersList() {
+  try {
     writeJSON('config/adopters.yml', resolve(__dirname, '../../config', 'adopters.json'));
+  } catch (error) {
+    console.error('Error building adopters list:', error);
+    throw error;
+  }
 };
scripts/tools/extract-tools-github.js (1)

4-18: Consider enhancing error handling.

While the try/catch block currently only rethrows errors, consider adding proper error logging or handling to improve debugging capabilities.

 const getData = async () => {
   try {
     const result = await axios.get('https://api.github.com/search/code?q=filename:.asyncapi-tool', {
       headers: {
         accept: 'application/vnd.github.text-match+json',
         authorization: `token ${process.env.GITHUB_TOKEN}`
       }
     });
     return result.data;
   } catch (err) {
-    throw err;
+    console.error('Failed to fetch AsyncAPI tools:', err.message);
+    throw new Error(`Failed to fetch AsyncAPI tools: ${err.message}`);
   }
 };
🧰 Tools
🪛 Biome

[error] 15-15: The catch clause that only rethrows the original error is useless.

An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.

(lint/complexity/noUselessCatch)

🪛 eslint

[error] 5-16: Unnecessary try/catch wrapper.

(no-useless-catch)

scripts/finance/index.js (1)

22-24: Consider improving error handling

The current error handling might lose valuable error details. Consider preserving the original error:

  } catch (err) {
-    throw new Error(err);
+    throw new Error(`Failed to build finance info list: ${err.message}`, { cause: err });
  }
scripts/build-meetings.js (2)

12-12: Consider improving readability while maintaining formatting.

While the single-line format complies with ESLint, breaking this into multiple lines would improve readability without compromising the formatting rules.

-      credentials: process.env.CALENDAR_SERVICE_ACCOUNT ? JSON.parse(process.env.CALENDAR_SERVICE_ACCOUNT) : undefined
+      credentials: process.env.CALENDAR_SERVICE_ACCOUNT 
+        ? JSON.parse(process.env.CALENDAR_SERVICE_ACCOUNT) 
+        : undefined

25-26: Consider using named constants for time ranges.

While the formatting changes look good, the magic numbers could be replaced with named constants for better maintainability.

+    const PAST_DAYS_RANGE = 100;
+    const FUTURE_DAYS_RANGE = 30;
-    const timeMin = new Date(Date.parse(currentTime) - 100 * 24 * 60 * 60 * 1000).toISOString();
-    const timeMax = new Date(Date.parse(currentTime) + 30 * 24 * 60 * 60 * 1000).toISOString();
+    const timeMin = new Date(Date.parse(currentTime) - PAST_DAYS_RANGE * 24 * 60 * 60 * 1000).toISOString();
+    const timeMax = new Date(Date.parse(currentTime) + FUTURE_DAYS_RANGE * 24 * 60 * 60 * 1000).toISOString();
scripts/build-rss.js (3)

1-2: LGTM! Consider using import statements in the future.

The require statements are correctly formatted. For future TypeScript migration, these will need to be converted to ES modules.


9-15: Consider refactoring the clean function for better maintainability.

While the current implementation works, consider these improvements for future PRs:

  1. Use a dedicated HTML entity decoder library like he or html-entities
  2. Use immutable string operations

Example refactor for future reference:

const he = require('he');

function clean(s) {
  return he.decode(s);
}
🧰 Tools
🪛 eslint

[error] 9-9: Assignment to function parameter 's'.

(no-param-reassign)


[error] 10-10: Assignment to function parameter 's'.

(no-param-reassign)


[error] 11-11: Assignment to function parameter 's'.

(no-param-reassign)


[error] 12-12: Assignment to function parameter 's'.

(no-param-reassign)


[error] 13-13: Assignment to function parameter 's'.

(no-param-reassign)


[error] 14-14: Assignment to function parameter 's'.

(no-param-reassign)


35-55: Consider extracting configuration values.

The RSS feed configuration is well-structured, but consider these future improvements:

  1. Move tracking parameter to constants
  2. Externalize metadata like language, copyright, etc.

Example for future reference:

const RSS_CONFIG = {
  tracking: '?utm_source=rss',
  language: 'en-gb',
  copyright: 'Made with :love: by the AsyncAPI Initiative.',
  webMaster: 'info@asyncapi.io (AsyncAPI Initiative)'
};
scripts/compose.js (1)

116-118: Improve maintainability of post type choices.

Consider extracting the post type choices into a constant array at the top of the file. This would make it easier to maintain and modify the available post types in the future.

Here's the suggested improvement:

+ const POST_TYPES = [
+   'Communication',
+   'Community',
+   'Engineering',
+   'Marketing',
+   'Strategy',
+   'Video'
+ ];

  // ... rest of the code ...

  {
    name: 'type',
    message: 'Enter the post type:',
    type: 'list',
-   choices: ['Communication', 'Community', 'Engineering', 'Marketing', 'Strategy', 'Video']
+   choices: POST_TYPES
  }
scripts/tools/tools-object.js (2)

70-87: Consider performance impact of sequential awaits in loop

Multiple await calls inside a loop can significantly impact performance as they execute sequentially.

Consider using Promise.all to parallelize the async operations:

- const { data: toolFileContent } = await axios.get(download_url);
- const jsonToolFileContent = await convertToJson(toolFileContent);
- const isValid = await validate(jsonToolFileContent);
- const toolObject = await createToolObject(
-   jsonToolFileContent,
-   repositoryUrl,
-   repoDescription,
-   isAsyncAPIrepo
- );
+ const [
+   { data: toolFileContent },
+   jsonToolFileContent,
+   isValid,
+   toolObject
+ ] = await Promise.all([
+   axios.get(downloadUrl),
+   convertToJson(toolFileContent),
+   validate(jsonToolFileContent),
+   createToolObject(jsonToolFileContent, repositoryUrl, repoDescription, isAsyncAPIrepo)
+ ]);
🧰 Tools
🪛 eslint

[error] 70-70: Unexpected await inside a loop.

(no-await-in-loop)


[error] 73-73: Unexpected await inside a loop.

(no-await-in-loop)


[error] 76-76: Unexpected await inside a loop.

(no-await-in-loop)


[error] 82-87: Unexpected await inside a loop.

(no-await-in-loop)


98-100: Simplify nested if condition

The nested if in the else block can be simplified using else if.

- } else {
-   if (!finalToolsObject.Others.toolsList.find((element) => element === toolObject))
-     finalToolsObject.Others.toolsList.push(toolObject);
- }
+ } else if (!finalToolsObject.Others.toolsList.find((element) => element === toolObject)) {
+   finalToolsObject.Others.toolsList.push(toolObject);
+ }
🧰 Tools
🪛 eslint

[error] 98-98: This line has a length of 131. Maximum allowed is 120.

(max-len)


[error] 99-100: Unexpected if as the only statement in an else block.

(no-lonely-if)

scripts/markdown/check-markdown.js (2)

11-16: Improve URL validation implementation

The current implementation triggers an ESLint error for creating a URL instance without assignment. Consider using URL.canParse() for modern Node.js or storing the URL instance.

 function isValidURL(str) {
   try {
-    new URL(str);
+    const url = new URL(str);
     return true;
   } catch (err) {
     return false;
   }
 }
🧰 Tools
🪛 eslint

[error] 12-12: Do not use 'new' for side effects.

(no-new)


102-139: Consider using async/await for better error handling

The current implementation using callbacks makes it difficult to handle errors consistently and could lead to race conditions with process.exitCode. Consider refactoring to use async/await.

Would you like me to provide an async/await implementation that addresses these concerns?

🧰 Tools
🪛 eslint

[error] 117-117: 'err' is already declared in the upper scope on line 102 column 27.

(no-shadow)

scripts/build-docs.js (2)

89-107: Enhance error handling and property access consistency

While the formatting looks good, consider these improvements:

  1. Include error details in the error message
  2. Maintain consistency in property access (either use optional chaining throughout or handle null checks explicitly)
 const convertDocPosts = (docObject) => {
   try {
     let docsArray = [];
-    docsArray.push(docObject?.item || docObject);
+    docsArray.push(docObject?.item ?? docObject);
     if (docObject.children) {
       const { children } = docObject;
       Object.keys(children).forEach((child) => {
         const docChildArray = convertDocPosts(children[child]);
         docsArray = [...docsArray, ...docChildArray];
       });
     }
     return docsArray;
   } catch (err) {
-    throw new Error('Error in convertDocPosts:', err);
+    throw new Error(`Error in convertDocPosts: ${err.message}`);
   }
 };

127-127: Use array destructuring for better readability

Consider using array destructuring for the filter result.

-    structuredPosts[0] = docPosts.filter((p) => p.slug === '/docs')[0];
+    [structuredPosts[0]] = docPosts.filter((p) => p.slug === '/docs');
🧰 Tools
🪛 eslint

[error] 127-127: Use array destructuring.

(prefer-destructuring)

scripts/build-post-list.js (3)

34-43: Consider reorganizing function declarations.

While function hoisting makes the current code work, it's better practice to declare functions before their usage. Consider moving the helper functions above buildPostList.

🧰 Tools
🪛 eslint

[error] 35-35: 'walkDirectories' was used before it was defined.

(no-use-before-define)


139-161: Clean up utility functions.

Several minor improvements can be made:

  1. Remove unnecessary escape characters in regex
  2. Use array destructuring
- const headingIdMatch = str.match(/[\s]?\{\#([\w\d\-_]+)\}/);
+ const headingIdMatch = str.match(/[\s]?\{#([\w\d\-_]+)\}/);
  if (headingIdMatch && headingIdMatch.length >= 2) {
-   slug = headingIdMatch[1];
+   [, slug] = headingIdMatch;
  }
🧰 Tools
🪛 eslint

[error] 142-142: Unnecessary escape character: #.

(no-useless-escape)


[error] 144-144: Use array destructuring.

(prefer-destructuring)


[error] 148-148: Use array destructuring.

(prefer-destructuring)


[error] 159-159: Unnecessary escape character: -.

(no-useless-escape)


Line range hint 1-161: Overall assessment of the formatting changes.

The formatting changes align with the PR's objective. However, several ESLint issues should be addressed to improve code quality:

  1. Variable shadowing and naming conventions
  2. Function organization and parameter handling
  3. Error handling in empty blocks
  4. Minor syntax improvements

These changes won't affect functionality but will make the code more maintainable and align better with JavaScript best practices.

🧰 Tools
🪛 eslint

[error] 30-31: Empty block statement.

(no-empty)


[error] 35-35: 'walkDirectories' was used before it was defined.

(no-use-before-define)


[error] 45-45: 'result' is already declared in the upper scope on line 11 column 7.

(no-shadow)


[error] 45-45: Default parameters should be last.

(default-param-last)


[error] 46-136: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 51-135: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 57-57: 'isDirectory' was used before it was defined.

(no-use-before-define)


[error] 61-61: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 64-64: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 86-86: 'slugifyToC' was used before it was defined.

(no-use-before-define)


[error] 99-99: 'fileName' is already declared in the upper scope on line 53 column 13.

(no-shadow)


[error] 100-100: Unary operator '--' used.

(no-plusplus)


[error] 103-103: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 105-105: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 124-124: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 126-126: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 126-126: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 128-128: This line has a length of 166. Maximum allowed is 120.

(max-len)


[error] 142-142: Unnecessary escape character: #.

(no-useless-escape)


[error] 144-144: Use array destructuring.

(prefer-destructuring)


[error] 148-148: Use array destructuring.

(prefer-destructuring)


[error] 159-159: Unnecessary escape character: -.

(no-useless-escape)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2935475 and 2badba7.

📒 Files selected for processing (21)
  • scripts/adopters/index.js (1 hunks)
  • scripts/build-docs.js (7 hunks)
  • scripts/build-meetings.js (2 hunks)
  • scripts/build-newsroom-videos.js (1 hunks)
  • scripts/build-post-list.js (2 hunks)
  • scripts/build-rss.js (3 hunks)
  • scripts/build-tools.js (1 hunks)
  • scripts/casestudies/index.js (1 hunks)
  • scripts/compose.js (2 hunks)
  • scripts/dashboard/build-dashboard.js (2 hunks)
  • scripts/dashboard/issue-queries.js (1 hunks)
  • scripts/finance/index.js (1 hunks)
  • scripts/index.js (1 hunks)
  • scripts/markdown/check-markdown.js (4 hunks)
  • scripts/tools/categorylist.js (1 hunks)
  • scripts/tools/combine-tools.js (1 hunks)
  • scripts/tools/extract-tools-github.js (1 hunks)
  • scripts/tools/tags-color.js (1 hunks)
  • scripts/tools/tools-object.js (3 hunks)
  • scripts/utils.js (1 hunks)
  • scripts/utils/readAndWriteJson.js (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • scripts/dashboard/issue-queries.js
🚧 Files skipped from review as they are similar to previous changes (7)
  • scripts/build-newsroom-videos.js
  • scripts/build-tools.js
  • scripts/dashboard/build-dashboard.js
  • scripts/index.js
  • scripts/tools/tags-color.js
  • scripts/utils.js
  • scripts/utils/readAndWriteJson.js
🧰 Additional context used
🪛 eslint
scripts/adopters/index.js

[error] 2-2: Unexpected use of file extension "js" for "../utils/readAndWriteJson.js"

(import/extensions)

scripts/build-docs.js

[error] 127-127: Use array destructuring.

(prefer-destructuring)


[error] 134-134: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 135-135: Expected '===' and instead saw '=='.

(eqeqeq)

scripts/build-post-list.js

[error] 30-31: Empty block statement.

(no-empty)


[error] 35-35: 'walkDirectories' was used before it was defined.

(no-use-before-define)


[error] 45-45: 'result' is already declared in the upper scope on line 11 column 7.

(no-shadow)


[error] 45-45: Default parameters should be last.

(default-param-last)


[error] 46-136: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 51-135: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 57-57: 'isDirectory' was used before it was defined.

(no-use-before-define)


[error] 61-61: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 64-64: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 86-86: 'slugifyToC' was used before it was defined.

(no-use-before-define)


[error] 99-99: 'fileName' is already declared in the upper scope on line 53 column 13.

(no-shadow)


[error] 100-100: Unary operator '--' used.

(no-plusplus)


[error] 103-103: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 105-105: 'capitalize' was used before it was defined.

(no-use-before-define)


[error] 124-124: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 126-126: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 126-126: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 128-128: This line has a length of 166. Maximum allowed is 120.

(max-len)


[error] 142-142: Unnecessary escape character: #.

(no-useless-escape)


[error] 144-144: Use array destructuring.

(prefer-destructuring)


[error] 148-148: Use array destructuring.

(prefer-destructuring)


[error] 159-159: Unnecessary escape character: -.

(no-useless-escape)

scripts/build-rss.js

[error] 5-5: Unexpected require().

(global-require)


[error] 9-9: Assignment to function parameter 's'.

(no-param-reassign)


[error] 10-10: Assignment to function parameter 's'.

(no-param-reassign)


[error] 11-11: Assignment to function parameter 's'.

(no-param-reassign)


[error] 12-12: Assignment to function parameter 's'.

(no-param-reassign)


[error] 13-13: Assignment to function parameter 's'.

(no-param-reassign)


[error] 14-14: Assignment to function parameter 's'.

(no-param-reassign)

scripts/casestudies/index.js

[error] 8-15: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 10-10: Unexpected await inside a loop.

(no-await-in-loop)


[error] 14-14: Unexpected await inside a loop.

(no-await-in-loop)

scripts/compose.js

[error] 6-6: 'inquirer' should be listed in the project's dependencies, not devDependencies.

(import/no-extraneous-dependencies)


[error] 7-7: 'dedent' should be listed in the project's dependencies, not devDependencies.

(import/no-extraneous-dependencies)


[error] 12-12: 'date' is assigned a value but never used.

(no-unused-vars)


[error] 14-14: Arrow function should not return assignment.

(no-return-assign)

scripts/finance/index.js

[error] 5-5: Unexpected use of file extension "js" for "../utils/readAndWriteJson.js"

(import/extensions)

scripts/markdown/check-markdown.js

[error] 12-12: Do not use 'new' for side effects.

(no-new)


[error] 31-31: Do not access Object.prototype method 'hasOwnProperty' from target object.

(no-prototype-builtins)


[error] 117-117: 'err' is already declared in the upper scope on line 102 column 27.

(no-shadow)

scripts/tools/categorylist.js

[error] 50-50: This line has a length of 151. Maximum allowed is 120.

(max-len)

scripts/tools/combine-tools.js

[error] 6-6: Unexpected use of file extension "js" for "./categorylist.js"

(import/extensions)


[error] 15-20: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 62-78: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 62-62: Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.

(no-unsafe-optional-chaining)


[error] 63-63: Unexpected await inside a loop.

(no-await-in-loop)


[error] 84-100: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 84-84: Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.

(no-unsafe-optional-chaining)


[error] 85-85: Unexpected await inside a loop.

(no-await-in-loop)


[error] 109-137: for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.

(no-restricted-syntax)


[error] 109-137: The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.

(guard-for-in)


[error] 112-114: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 113-113: Unexpected await inside a loop.

(no-await-in-loop)


[error] 117-133: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 119-119: Unexpected await inside a loop.

(no-await-in-loop)


[error] 125-125: Unexpected await inside a loop.

(no-await-in-loop)


[error] 126-126: Unexpected await inside a loop.

(no-await-in-loop)

scripts/tools/extract-tools-github.js

[error] 5-16: Unnecessary try/catch wrapper.

(no-useless-catch)

scripts/tools/tools-object.js

[error] 54-59: for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.

(no-restricted-syntax)


[error] 54-59: The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.

(guard-for-in)


[error] 64-64: This line has a length of 146. Maximum allowed is 120.

(max-len)


[error] 67-67: Identifier 'reference_id' is not in camel case.

(camelcase)


[error] 68-68: Identifier 'download_url' is not in camel case.

(camelcase)


[error] 68-68: Identifier 'reference_id' is not in camel case.

(camelcase)


[error] 70-70: Unexpected await inside a loop.

(no-await-in-loop)


[error] 73-73: Unexpected await inside a loop.

(no-await-in-loop)


[error] 76-76: Unexpected await inside a loop.

(no-await-in-loop)


[error] 82-87: Unexpected await inside a loop.

(no-await-in-loop)


[error] 98-98: This line has a length of 131. Maximum allowed is 120.

(max-len)


[error] 99-100: Unexpected if as the only statement in an else block.

(no-lonely-if)

🪛 Biome
scripts/build-meetings.js

[error] 41-41: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

scripts/compose.js

[error] 14-14: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

scripts/markdown/check-markdown.js

[error] 31-31: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

scripts/tools/combine-tools.js

[error] 62-62: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 84-84: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 116-116: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

scripts/tools/extract-tools-github.js

[error] 15-15: The catch clause that only rethrows the original error is useless.

An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.

(lint/complexity/noUselessCatch)

🔇 Additional comments (24)
scripts/adopters/index.js (1)

1-2: LGTM! Clean import formatting.

The import statements are well-formatted with consistent semicolon usage.

🧰 Tools
🪛 eslint

[error] 2-2: Unexpected use of file extension "js" for "../utils/readAndWriteJson.js"

(import/extensions)

scripts/tools/extract-tools-github.js (2)

1-3: LGTM! Formatting changes align with PR objectives.

The dependencies and configuration setup remain functionally unchanged.


19-19: LGTM! Module exports remain unchanged.

The export statement is properly formatted and maintains the existing functionality.

scripts/casestudies/index.js (3)

1-4: LGTM! Clean imports and function signature

The imports are well-structured using destructuring, and the function signature follows the expected format.


1-18: Summary: Formatting changes align with PR objectives

The changes in this file are purely formatting-related and maintain the original logic, which aligns perfectly with the PR's stated objective of "format build scripts using eslint". While there are ESLint warnings about async operations and loop patterns, addressing these would involve logic changes that should be handled in separate PRs, possibly during the TypeScript migration.

🧰 Tools
🪛 eslint

[error] 8-15: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 10-10: Unexpected await inside a loop.

(no-await-in-loop)


[error] 14-14: Unexpected await inside a loop.

(no-await-in-loop)


6-14: Verify: No logic changes in formatting PR

While there are opportunities for performance improvements (like using Promise.all and batching file writes), this PR's scope is limited to formatting. The existing logic has been preserved as intended.

Consider creating a separate issue to track the performance improvements suggested in previous reviews, such as:

  • Batching file writes
  • Using Promise.all with array methods
  • Implementing proper error handling for file operations
✅ Verification successful

Changes are limited to formatting and import path adjustment

The git history shows only the following changes:

  • Formatting changes: indentation, spacing, and line breaks
  • Variable declarations changed from let to const
  • Import path adjustment from '../../scripts/utils' to '../utils'

The core logic remains unchanged:

  • Same file operations
  • Same loop structure
  • Same data processing
  • Same error handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that only formatting changes were made
git diff origin/main -- scripts/casestudies/index.js | grep -v '^[+-][ ]*$' | grep -v '^[+-][ ]*\/\/' | grep -E '^[+-]' | grep -vE '^[+-]\s*$'

Length of output: 178


Script:

#!/bin/bash
# Let's first check the git history for this file
git log --pretty=format:"%H" -p -- scripts/casestudies/index.js

# Also check the current content of the file
cat scripts/casestudies/index.js

Length of output: 4431

🧰 Tools
🪛 eslint

[error] 10-10: Unexpected await inside a loop.

(no-await-in-loop)


[error] 14-14: Unexpected await inside a loop.

(no-await-in-loop)

scripts/finance/index.js (1)

8-21: LGTM! Formatting changes look clean and consistent.

The code structure is now more readable with consistent indentation and clear separation of concerns.

scripts/build-meetings.js (1)

30-31: LGTM! Clean object property shorthand usage.

The formatting changes improve code conciseness while maintaining clarity.

scripts/build-rss.js (2)

Line range hint 20-32: LGTM! Well-structured post filtering and sorting.

The code effectively handles:

  • Missing date validation
  • Post sorting by date and featured status
  • Clear error messaging
🧰 Tools
🪛 eslint

[error] 5-5: Unexpected require().

(global-require)


[error] 9-9: Assignment to function parameter 's'.

(no-param-reassign)


[error] 10-10: Assignment to function parameter 's'.

(no-param-reassign)


[error] 11-11: Assignment to function parameter 's'.

(no-param-reassign)


[error] 12-12: Assignment to function parameter 's'.

(no-param-reassign)


[error] 13-13: Assignment to function parameter 's'.

(no-param-reassign)


[error] 14-14: Assignment to function parameter 's'.

(no-param-reassign)


Line range hint 93-99: LGTM! Clean feed generation and error handling.

The feed generation and file writing logic is well-structured with proper error handling.

scripts/tools/categorylist.js (2)

1-104: LGTM! Consistent formatting across category definitions

The formatting changes maintain a clean and consistent structure across all category objects. Each category is well-defined with appropriate properties and consistent indentation.

🧰 Tools
🪛 eslint

[error] 50-50: This line has a length of 151. Maximum allowed is 120.

(max-len)


106-106: LGTM! Properly formatted export statement

The export statement follows consistent formatting with appropriate spacing and semicolon.

scripts/compose.js (1)

Line range hint 1-149: Overall assessment: Formatting changes look good.

The formatting changes align with the PR objectives. While I've suggested several improvements above, they are separate from the formatting changes and can be addressed in future PRs. The current changes maintain the existing functionality while improving code consistency.

scripts/tools/tools-object.js (3)

1-21: LGTM! Dependencies and initialization are well-structured.

The imports and configuration setup follow good practices with clear organization.


Line range hint 23-43: LGTM! Well-structured function with proper error handling.

The function makes good use of optional chaining and default parameters, with clear fallback values.


118-118: LGTM! Exports are properly formatted.

The module exports follow good practices with proper spacing.

scripts/markdown/check-markdown.js (1)

80-92: LGTM! Well-structured validation logic

The function has clear validation rules, appropriate type checks, and good error messages.

scripts/tools/combine-tools.js (4)

1-19: LGTM! Clean initialization and proper constant usage.

The import statements are well-organized and the initialization code follows good practices with proper use of const declarations.

🧰 Tools
🪛 eslint

[error] 6-6: Unexpected use of file extension "js" for "./categorylist.js"

(import/extensions)


24-28: LGTM! Well-structured Fuse configuration.

The Fuse search configuration is properly formatted with appropriate threshold and search keys.


32-35: LGTM! Proper initialization of search indices.

The language and technology lists are properly initialized with spread operator, and Fuse instances are correctly declared as mutable since they need to be updated.


62-62: ⚠️ Potential issue

Fix unsafe optional chaining to prevent runtime errors

The unsafe optional chaining usage in the loops could throw TypeError if the chain short-circuits with undefined.

This issue was previously identified. Please refer to the existing comment for the proposed fix.

Also applies to: 84-84

🧰 Tools
🪛 Biome

[error] 62-62: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🪛 eslint

[error] 62-78: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.

(no-restricted-syntax)


[error] 62-62: Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.

(no-unsafe-optional-chaining)

scripts/build-docs.js (2)

1-18: LGTM! Formatting changes look good.

The formatting changes improve readability while maintaining the original logic.


190-190: LGTM! Consistent semicolon usage.

The formatting change maintains consistency with the rest of the file.

scripts/build-post-list.js (1)

1-18: LGTM! Clean imports and initialization.

The imports are well-organized using destructuring, and the result object structure is clearly defined.

Comment on lines +6 to +11
const result = await axios.get('https://api.github.com/search/code?q=filename:.asyncapi-tool', {
headers: {
accept: 'application/vnd.github.text-match+json',
authorization: `token ${process.env.GITHUB_TOKEN}`
}
);
});
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

GitHub token configuration is missing and needs to be documented

The codebase lacks proper GitHub token configuration:

  • No .env or .env.example file containing GITHUB_TOKEN configuration
  • No GitHub token setup in CI/CD workflows
  • No documentation about the token setup in README.md

This script requires a GitHub token to search through GitHub's API, but there's no guidance on how to obtain or configure it. Please:

  1. Add a .env.example file with GITHUB_TOKEN placeholder
  2. Document the token setup process in README.md
  3. Ensure CI/CD workflows have proper token configuration
🔗 Analysis chain

Verify GitHub token configuration.

Ensure that the GitHub token is properly configured in the environment variables for both local development and CI/CD pipelines.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for GitHub token configuration in environment files and CI

# Check if .env or .env.example exists and contains GITHUB_TOKEN
echo "Checking .env files for GITHUB_TOKEN configuration..."
fd -t f "^\.env" -x grep -l "GITHUB_TOKEN"

# Check if GitHub token is configured in CI
echo "Checking CI configuration for GITHUB_TOKEN..."
fd -t f "^\.github/workflows/.*\.(yml|yaml)$" -x grep -l "GITHUB_TOKEN"

Length of output: 748


Script:

#!/bin/bash
# Description: Check for GitHub token configuration in environment files and CI with hidden files

# Check if .env or .env.example exists and contains GITHUB_TOKEN
echo "Checking .env files for GITHUB_TOKEN configuration..."
fd -H -t f "^\.env" -x grep -l "GITHUB_TOKEN"

# Check if GitHub token is configured in CI
echo "Checking CI configuration for GITHUB_TOKEN..."
fd -H -t f "^\.github/workflows/.*\.(yml|yaml)$" -x grep -l "GITHUB_TOKEN"

# Check for any documentation about GitHub token setup
echo "Checking documentation for GitHub token setup..."
rg -l "GITHUB_TOKEN" "README.md" || true

Length of output: 483

Comment on lines +41 to +42
banner: e.extendedProperties?.private && e.extendedProperties.private.BANNER,
date: new Date(e.start.dateTime)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add consistent optional chaining to prevent potential runtime errors.

The optional chaining is used inconsistently. While extendedProperties?.private is safely accessed, private.BANNER could throw an error if private is undefined.

-        banner: e.extendedProperties?.private && e.extendedProperties.private.BANNER,
+        banner: e.extendedProperties?.private?.BANNER,
📝 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
banner: e.extendedProperties?.private && e.extendedProperties.private.BANNER,
date: new Date(e.start.dateTime)
banner: e.extendedProperties?.private?.BANNER,
date: new Date(e.start.dateTime)
🧰 Tools
🪛 Biome

[error] 41-41: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines +79 to +86
enclosure['@url'] = base + post.cover;
enclosure['@length'] = 15026; // dummy value, anything works
enclosure['@type'] = 'image/jpeg';
if (typeof enclosure['@url'] === 'string') {
const tmp = enclosure['@url'].toLowerCase();
if (tmp.indexOf('.png') >= 0) enclosure['@type'] = 'image/png';
if (tmp.indexOf('.svg') >= 0) enclosure['@type'] = 'image/svg+xml';
if (tmp.indexOf('.webp') >= 0) enclosure['@type'] = 'image/webp';
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 improving image handling logic.

The current implementation has two areas for improvement:

  1. The hardcoded enclosure length (15026) should be replaced with actual file size
  2. Image type detection could use more robust methods like mime-types library

Example improvement for future reference:

const mime = require('mime-types');
const fs = require('fs');

// Inside the loop:
const imagePath = path.join(process.cwd(), 'public', post.cover);
enclosure['@type'] = mime.lookup(imagePath) || 'image/jpeg';
enclosure['@length'] = fs.statSync(imagePath).size;

Comment on lines +49 to +50
description:
"Writing YAML by hand is no fun, and maybe you don't want a GUI, so use a Domain Specific Language to write AsyncAPI in your language of choice."
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix line length violation

The description on line 50 exceeds the maximum line length of 120 characters.

Split the long line into multiple lines for better readability:

-    description:
-      "Writing YAML by hand is no fun, and maybe you don't want a GUI, so use a Domain Specific Language to write AsyncAPI in your language of choice."
+    description:
+      'Writing YAML by hand is no fun, and maybe you don\'t want a GUI, ' +
+      'so use a Domain Specific Language to write AsyncAPI in your language of choice.'
📝 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
description:
"Writing YAML by hand is no fun, and maybe you don't want a GUI, so use a Domain Specific Language to write AsyncAPI in your language of choice."
description:
'Writing YAML by hand is no fun, and maybe you don\'t want a GUI, ' +
'so use a Domain Specific Language to write AsyncAPI in your language of choice.'
🧰 Tools
🪛 eslint

[error] 50-50: This line has a length of 151. Maximum allowed is 120.

(max-len)

Comment on lines +11 to +15
const d = new Date();
const date = [d.getFullYear(), `0${d.getMonth() + 1}`.slice(-2), `0${d.getDate()}`.slice(-2)].join('-');
const tagArray = answers.tags.split(',');
tagArray.forEach((tag, index) => (tagArray[index] = tag.trim()));
const tags = `'${tagArray.join("','")}'`;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Optimize variable usage and improve array manipulation.

There are a few improvements that can be made to this code segment:

  1. The date variable is declared but never used
  2. The array manipulation can be simplified using map instead of forEach with assignment

Here's the suggested improvement:

  const d = new Date();
- const date = [d.getFullYear(), `0${d.getMonth() + 1}`.slice(-2), `0${d.getDate()}`.slice(-2)].join('-');
  const tagArray = answers.tags.split(',');
- tagArray.forEach((tag, index) => (tagArray[index] = tag.trim()));
+ const tags = `'${tagArray.map(tag => tag.trim()).join("','")}'`;
- const tags = `'${tagArray.join("','")}'`;
📝 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
const d = new Date();
const date = [d.getFullYear(), `0${d.getMonth() + 1}`.slice(-2), `0${d.getDate()}`.slice(-2)].join('-');
const tagArray = answers.tags.split(',');
tagArray.forEach((tag, index) => (tagArray[index] = tag.trim()));
const tags = `'${tagArray.join("','")}'`;
const d = new Date();
const tagArray = answers.tags.split(',');
const tags = `'${tagArray.map(tag => tag.trim()).join("','")}'`;
🧰 Tools
🪛 Biome

[error] 14-14: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🪛 eslint

[error] 12-12: 'date' is assigned a value but never used.

(no-unused-vars)


[error] 14-14: Arrow function should not return assignment.

(no-return-assign)

Comment on lines 134 to +135
if (post?.isRootSection || post?.isSection || index == 0) {
if (post?.isRootSection || index == 0)
rootSections.push(post.title)
return post
if (post?.isRootSection || index == 0) rootSections.push(post.title);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use strict equality comparison

Replace loose equality (==) with strict equality (===) for more reliable comparisons.

-      if (post?.isRootSection || post?.isSection || index == 0) {
-        if (post?.isRootSection || index == 0) rootSections.push(post.title);
+      if (post?.isRootSection || post?.isSection || index === 0) {
+        if (post?.isRootSection || index === 0) rootSections.push(post.title);
📝 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
if (post?.isRootSection || post?.isSection || index == 0) {
if (post?.isRootSection || index == 0)
rootSections.push(post.title)
return post
if (post?.isRootSection || index == 0) rootSections.push(post.title);
if (post?.isRootSection || post?.isSection || index === 0) {
if (post?.isRootSection || index === 0) rootSections.push(post.title);
🧰 Tools
🪛 eslint

[error] 134-134: Expected '===' and instead saw '=='.

(eqeqeq)


[error] 135-135: Expected '===' and instead saw '=='.

(eqeqeq)

writeFileSync(resolve(__dirname, '..', 'config', 'posts.json'), JSON.stringify(result, null, ' '))
}
writeFileSync(resolve(__dirname, '..', 'config', 'posts.json'), JSON.stringify(result, null, ' '));
};

function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix parameter declaration issues.

  1. The result parameter shadows the global variable
  2. Default parameters should be last in the parameter list
- function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, sectionId, rootSectionId)
+ function walkDirectories(directories, resultObj, sectionTitle, sectionId, rootSectionId, sectionWeight = 0)
📝 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
function walkDirectories(directories, result, sectionWeight = 0, sectionTitle, sectionId, rootSectionId) {
function walkDirectories(directories, resultObj, sectionTitle, sectionId, rootSectionId, sectionWeight = 0) {
🧰 Tools
🪛 eslint

[error] 45-45: 'result' is already declared in the upper scope on line 11 column 7.

(no-shadow)


[error] 45-45: Default parameters should be last.

(default-param-last)

Comment on lines 26 to +32
const addItem = (details) => {
if(details.slug.startsWith('/docs'))
result["docs"].push(details)
else if(details.slug.startsWith('/blog'))
result["blog"].push(details)
else if(details.slug.startsWith('/about'))
result["about"].push(details)
else {}
}
if (details.slug.startsWith('/docs')) result.docs.push(details);
else if (details.slug.startsWith('/blog')) result.blog.push(details);
else if (details.slug.startsWith('/about')) result.about.push(details);
else {
}
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling in the empty else block.

The empty else block could silently ignore invalid slugs. Consider adding error handling or logging.

  else {
+    console.warn(`Unexpected slug pattern: ${details.slug}`);
  }
📝 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
const addItem = (details) => {
if(details.slug.startsWith('/docs'))
result["docs"].push(details)
else if(details.slug.startsWith('/blog'))
result["blog"].push(details)
else if(details.slug.startsWith('/about'))
result["about"].push(details)
else {}
}
if (details.slug.startsWith('/docs')) result.docs.push(details);
else if (details.slug.startsWith('/blog')) result.blog.push(details);
else if (details.slug.startsWith('/about')) result.about.push(details);
else {
}
};
const addItem = (details) => {
if (details.slug.startsWith('/docs')) result.docs.push(details);
else if (details.slug.startsWith('/blog')) result.blog.push(details);
else if (details.slug.startsWith('/about')) result.about.push(details);
else {
console.warn(`Unexpected slug pattern: ${details.slug}`);
}
};
🧰 Tools
🪛 eslint

[error] 30-31: Empty block statement.

(no-empty)

Comment on lines +98 to +100
const fileBaseName = basename(data.slug); // ex. v2.0.0 | v2.1.0-next-spec.1
const fileName = fileBaseName.split('-')[0]; // v2.0.0 | v2.1.0
details.weight = specWeight--;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix variable shadowing and unary operator.

The fileName variable shadows the previous declaration, and the unary decrement operator makes the code less maintainable.

- const fileName = fileBaseName.split('-')[0]; // v2.0.0 | v2.1.0
- details.weight = specWeight--;
+ const versionName = fileBaseName.split('-')[0]; // v2.0.0 | v2.1.0
+ details.weight = specWeight;
+ specWeight = specWeight - 1;
📝 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
const fileBaseName = basename(data.slug); // ex. v2.0.0 | v2.1.0-next-spec.1
const fileName = fileBaseName.split('-')[0]; // v2.0.0 | v2.1.0
details.weight = specWeight--;
const fileBaseName = basename(data.slug); // ex. v2.0.0 | v2.1.0-next-spec.1
const versionName = fileBaseName.split('-')[0]; // v2.0.0 | v2.1.0
details.weight = specWeight;
specWeight = specWeight - 1;
🧰 Tools
🪛 eslint

[error] 99-99: 'fileName' is already declared in the upper scope on line 53 column 13.

(no-shadow)


[error] 100-100: Unary operator '--' used.

(no-plusplus)

Comment on lines +124 to +129
const fileName_without_extension = file.slice(0, -4);
// removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0
const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-")+1)
const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf('-') + 1);

// gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0
releaseNotes.push(version)
releaseNotes.push(version);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use camelCase for variable names.

The variable fileName_without_extension should follow JavaScript naming conventions.

- const fileName_without_extension = file.slice(0, -4);
- const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf('-') + 1);
+ const fileNameWithoutExtension = file.slice(0, -4);
+ const version = fileNameWithoutExtension.slice(fileNameWithoutExtension.lastIndexOf('-') + 1);
📝 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
const fileName_without_extension = file.slice(0, -4);
// removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0
const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf("-")+1)
const version = fileName_without_extension.slice(fileName_without_extension.lastIndexOf('-') + 1);
// gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0
releaseNotes.push(version)
releaseNotes.push(version);
const fileNameWithoutExtension = file.slice(0, -4);
// removes the file extension. For example, release-notes-2.1.0.md -> release-notes-2.1.0
const version = fileNameWithoutExtension.slice(fileNameWithoutExtension.lastIndexOf('-') + 1);
// gets the version from the name of the releaseNote .md file (from /blog). For example, version = 2.1.0 if fileName_without_extension = release-notes-2.1.0
releaseNotes.push(version);
🧰 Tools
🪛 eslint

[error] 124-124: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 126-126: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 126-126: Identifier 'fileName_without_extension' is not in camel case.

(camelcase)


[error] 128-128: This line has a length of 166. Maximum allowed is 120.

(max-len)

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.

3 participants