Skip to content

refactor: Improve FrontMatterConverter with functional programming principles #429

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

Merged
merged 14 commits into from
Mar 30, 2025

Conversation

songkg7
Copy link
Owner

@songkg7 songkg7 commented Mar 30, 2025

Changes

  • Add Either type and utility functions for better error handling
  • Improve type safety with proper interfaces
  • Fix date and author formatting issues
  • Add comprehensive test coverage
  • Update docusaurus integration to handle Either type
  • Fix TypeScript configuration for test files

Testing

  • All tests passing (167 tests)
  • Code coverage improved
  • Type safety enhanced

Impact

  • More reliable front matter handling
  • Better error handling with Either type
  • Improved maintainability with functional programming principles

Summary by CodeRabbit

  • New Features

    • Enhanced error handling in content conversion, providing clearer notifications and fallback mechanisms.
    • Introduced new utilities for functional programming, allowing for better function composition and manipulation.
  • Bug Fixes

    • Improved handling of invalid front matter and edge cases during conversion.
  • Refactor

    • Streamlined front matter parsing and conversion logic, improving clarity and maintainability.
    • Updated the structure of tests for better organization and focus on specific functionalities.
  • Chores

    • Adjusted configuration settings to include test files in the compilation process for improved quality assurance.

songkg7 added 2 commits March 30, 2025 09:03
…inciples - Add Either type and utility functions, improve type safety, fix date/author formatting, add tests, update docusaurus integration
Copy link
Contributor

coderabbitai bot commented Mar 30, 2025

Warning

Rate limit exceeded

@songkg7 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 57 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8db0d3f and c0e31a6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • package.json (2 hunks)
  • src/tests/fp.test.ts (1 hunks)

Walkthrough

The pull request refactors the front matter conversion logic to adopt a more functional programming style. In FrontMatterConverter.ts, the parseFrontMatter function is replaced by a new extractFrontMatter that returns an Either type for improved error handling. New helper functions for formatting titles, categories, authors, tags, images, and dates have been introduced. Additionally, functional utilities have been added in a new fp.ts file, and new types and interfaces are defined in types.ts. The Docusaurus conversion and testing processes have also been updated, and the TypeScript configuration now compiles .spec.ts files.

Changes

File(s) Change Summary
src/FrontMatterConverter.ts Refactored front matter conversion: replaced parseFrontMatter with extractFrontMatter (returning an Either), added helper functions (formatTitle, formatCategories, formatAuthors, formatTags, handleImageFrontMatter, handleDateFrontMatter), and updated function signatures.
src/tests/FrontMatterConverter.test.ts Reorganized and reduced tests for convertFrontMatter with descriptive categories; expanded scenarios for image handling, mermaid blocks, error handling, and edge cases.
src/core/fp.ts Added a new file containing functional programming utilities: pipe, compose, curry, map, filter, reduce, identity, and constant functions with multiple signature overloads.
src/docusaurus/docusaurus.ts Enhanced error handling in convertToDocusaurus by capturing the result of front matter conversion and using the fold function to manage errors, falling back to the original content when needed.
src/types.ts Introduced new TypeScript types and interfaces for front matter and conversion results, including definitions for ConversionResult, ConversionError, Either, Left, Right, and related utility functions (left, right, fold, map, chain).
tsconfig.json Modified the "exclude" property to remove exclusion for .spec.ts files, ensuring that these files are now included in the compilation process.

Possibly related PRs

Suggested labels

enhancement, chirpy

Poem

I'm a rabbit with a joyful leap,
Hoping code changes make our commit deep.
With front matter now functional and bright,
Our code hops ahead with error-handling might.
CodeRabbit celebrates with a twitch in delight!
🐰✨


🪧 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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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

codecov bot commented Mar 30, 2025

Codecov Report

Attention: Patch coverage is 93.91304% with 7 lines in your changes missing coverage. Please review.

Project coverage is 93.68%. Comparing base (1ca9a67) to head (c0e31a6).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/FrontMatterConverter.ts 92.95% 2 Missing and 3 partials ⚠️
src/types.ts 88.88% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #429      +/-   ##
==========================================
- Coverage   94.23%   93.68%   -0.56%     
==========================================
  Files          12       14       +2     
  Lines         243      285      +42     
  Branches       33       39       +6     
==========================================
+ Hits          229      267      +38     
- Misses         13       15       +2     
- Partials        1        3       +2     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/FrontMatterConverter.ts (3)

2-13: Remove unused import 'chain'.

The function 'chain' is imported but never used, which triggers an ESLint error. Removing it will harmonize with the code's current usage and keep imports clean:

-import {
-  ConversionError,
-  ConversionResult,
-  Either,
-  FrontMatter,
-  chain,
-  left,
-  right,
-  map,
-} from './types';
+import {
+  ConversionError,
+  ConversionResult,
+  Either,
+  FrontMatter,
+  left,
+  right,
+  map,
+} from './types';
🧰 Tools
🪛 ESLint

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)


67-75: Potential pitfall in categories formatting.

Using JSON.stringify(frontMatter.categories) and then removing quotes/comma replacements might lead to unexpected formatting if a category name itself has commas or special characters. Consider explicitly handling arrays vs. single-string categories to avoid edge cases.


133-145: Consider multiline or complex front matter.

Serializing front matter as plain text works well for simple data. However, multiline strings or nested objects can become tricky. Use caution if your front matter may contain more complex structures.

src/core/fp.ts (1)

46-58: Replace any with more explicit types in curry.

ESLint flags the usage of any in lines 49, 51, 52, and 56. Specifying more explicit generic types or parameter constraints would enhance type safety and maintain code clarity:

 export const curry = <A extends unknown[], R>(
-  fn: (...args: A) => R
-): (((...args: any[]) => any) | ((...args: A) => R)) => {
+  fn: (...args: A) => R
+): ((...args: Partial<A>) => R | ((...args: Partial<A>) => R)) => {
   return function curried(...args: unknown[]) {
     ...
   };
 };
🧰 Tools
🪛 ESLint

[error] 49-49: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 52-52: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🪛 GitHub Check: codecov/patch

[warning] 52-52: src/core/fp.ts#L52
Added line #L52 was not covered by tests


[warning] 54-54: src/core/fp.ts#L54
Added line #L54 was not covered by tests


[warning] 56-56: src/core/fp.ts#L56
Added line #L56 was not covered by tests

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1ca9a67 and 4667a96.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • src/FrontMatterConverter.ts (1 hunks)
  • src/core/fp.ts (1 hunks)
  • src/docusaurus/docusaurus.ts (2 hunks)
  • src/tests/FrontMatterConverter.test.ts (1 hunks)
  • src/types.ts (1 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
src/tests/FrontMatterConverter.test.ts (2)
src/FrontMatterConverter.ts (1)
  • convertFrontMatter (148-185)
src/types.ts (1)
  • ConversionError (9-12)
src/types.ts (1)
src/core/fp.ts (1)
  • map (63-64)
src/FrontMatterConverter.ts (2)
src/types.ts (7)
  • Either (25-25)
  • ConversionError (9-12)
  • ConversionResult (4-7)
  • right (32-35)
  • FrontMatter (2-2)
  • left (27-30)
  • map (49-52)
src/core/fp.ts (2)
  • pipe (33-38)
  • map (63-64)
src/core/fp.ts (1)
src/types.ts (1)
  • map (49-52)
🪛 GitHub Check: codecov/patch
src/types.ts

[warning] 41-41: src/types.ts#L41
Added line #L41 was not covered by tests


[warning] 46-46: src/types.ts#L46
Added line #L46 was not covered by tests


[warning] 56-56: src/types.ts#L56
Added line #L56 was not covered by tests

src/FrontMatterConverter.ts

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests


[warning] 40-40: src/FrontMatterConverter.ts#L40
Added line #L40 was not covered by tests


[warning] 96-96: src/FrontMatterConverter.ts#L96
Added line #L96 was not covered by tests

src/core/fp.ts

[warning] 44-44: src/core/fp.ts#L44
Added line #L44 was not covered by tests


[warning] 52-52: src/core/fp.ts#L52
Added line #L52 was not covered by tests


[warning] 54-54: src/core/fp.ts#L54
Added line #L54 was not covered by tests


[warning] 56-56: src/core/fp.ts#L56
Added line #L56 was not covered by tests


[warning] 64-64: src/core/fp.ts#L64
Added line #L64 was not covered by tests


[warning] 70-70: src/core/fp.ts#L70
Added line #L70 was not covered by tests


[warning] 76-76: src/core/fp.ts#L76
Added line #L76 was not covered by tests

🪛 ESLint
src/FrontMatterConverter.ts

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)

src/core/fp.ts

[error] 49-49: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 52-52: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🔇 Additional comments (35)
tsconfig.json (1)

21-21: Improved developer experience by including test files in compilation.

Removing .spec.ts from the excluded files ensures that TypeScript will type-check these files, providing better type safety for test code and catching potential issues earlier in development.

src/docusaurus/docusaurus.ts (2)

16-16: Good import of functional programming utilities.

The addition of ConversionError and fold from the types module aligns with the functional programming approach being implemented.


50-66: Excellent error handling implementation with functional approach.

The refactored code now properly handles errors during front matter conversion using the Either type pattern. If an error occurs, it shows a notice to the user and falls back to the original content, preventing potential crashes or undefined behavior.

The use of fold function to handle both success and error cases elegantly demonstrates functional programming principles, making the code more robust and maintainable.

src/tests/FrontMatterConverter.test.ts (8)

1-2: Good imports for the functional approach.

Importing the standalone function and the error type aligns with the functional programming approach being implemented.


4-27: Well-structured test for basic front matter conversion.

The test properly validates the success case using the Either type pattern by checking the _tag property first, ensuring type safety.


30-61: Comprehensive testing of image handling with different configurations.

Good test coverage for both enabled and disabled banner settings, verifying that image paths are processed correctly in each case.


64-94: Good test coverage for mermaid code block detection.

Testing both positive and negative cases ensures the mermaid flag is only added when appropriate.


97-125: Thorough date handling tests.

Tests cover both update enabled and disabled scenarios, ensuring date fields are properly managed based on configuration.


128-155: Comprehensive author formatting tests.

Tests cover both single and multiple author scenarios, ensuring proper formatting in each case.


158-168: Proper error handling test.

The test correctly verifies that invalid YAML syntax results in a parse error, demonstrating the robustness of the error handling system.


171-205: Good coverage of edge cases.

The tests handle various edge cases like missing front matter, empty front matter, and content with multiple dividers, ensuring the converter is robust against unexpected inputs.

src/types.ts (4)

1-12: Well-defined types for front matter conversion.

The types are clear and concise, providing a solid foundation for type safety throughout the application.


14-35: Excellent implementation of the Either type pattern.

The Left and Right interfaces with readonly properties ensure immutability, following functional programming best practices. The helper functions left and right provide convenient ways to create Either instances.


37-47:

✅ Verification successful

Good type guard and folding implementations.

The type guards (isLeft and isRight) are correctly implemented with proper type narrowing. The fold function provides a clean way to handle both success and error cases.


🏁 Script executed:

#!/bin/bash
# Search for usages of the fold function to ensure it's being properly utilized
rg -A 2 "fold\s*<" --type=ts

Length of output: 270


Verified Implementation and Usage

The type guards (isLeft and isRight) and the fold function are correctly implemented and are being used appropriately in the codebase (as seen in src/docusaurus/docusaurus.ts). No further changes are required.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 41-41: src/types.ts#L41
Added line #L41 was not covered by tests


[warning] 46-46: src/types.ts#L46
Added line #L46 was not covered by tests


49-53:

❓ Verification inconclusive

Good implementation of map function for Either type.

The map function allows transforming values inside the Either container without unwrapping them, following functional programming principles.


🏁 Script executed:

#!/bin/bash
# Check if there are test cases covering the map function
rg "map\(" --type=ts src/tests | grep -v "Array"

Length of output: 48


Attention: Revisit Test Coverage for map Function

The implementation of the map function in src/types.ts (lines 49-53) is solid and follows functional programming principles well. However, our automated search did not reveal any tests explicitly covering this function, which leaves a gap in our confidence regarding its behavior in all scenarios.

  • Action Needed: Please consider adding test cases for the map function to the test suite in src/tests. This will help ensure that its behavior is properly verified in various usage contexts.
src/FrontMatterConverter.ts (12)

15-17: Consider adding tests for isNullOrEmpty.

The utility function isNullOrEmpty might be a cornerstone for validating user inputs or front matter fields. Lack of test coverage could allow regressions to go unnoticed.

Would you like me to generate a test scenario?


19-25: Add test coverage for formatDate.

Lines 22 and 24 handle distinct date cases (Date instances and other unknown types), which the code coverage warns may not be tested. Ensuring these lines are covered will help validate all date formats.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests


27-29: Good approach for handling multiple authors.

The logic to split a string by commas and output a bracketed list is straightforward and valid.


32-57: Add test for missing closing front matter delimiter.

When endOfFrontMatter is -1, the function treats the entire content as body, returning an empty frontMatter object. This scenario might not be covered per the coverage hint (line 40).

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 40-40: src/FrontMatterConverter.ts#L40
Added line #L40 was not covered by tests


59-65: Ensure consistent quoting of titles.

The function wraps titles in quotes if not already enclosed. This helps maintain consistency.


77-87: Flexible handling of authors.

If authors is bracketed or unbracketed, the logic gracefully handles both. This approach appears correct and consistent with formatAuthorList.


89-97: Add missing test coverage for formatTags.

According to coverage hints, line 96 may be untested. Consider adding tests for an array of tags and a single tag.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 96-96: src/FrontMatterConverter.ts#L96
Added line #L96 was not covered by tests


99-105: Mermaid detection is minimal but effective.

If the body contains a mermaid code block, the function sets mermaid: 'true' in front matter. This is a straightforward approach.


106-111: No issues found with convertImagePath.

Curried usage is practical for reusability.


112-124: Validate edge cases for image attachments.

ObsidianRegex.ATTACHMENT_LINK might miss special characters or unusual file names. Ensure all valid image references are captured.


126-131: Implementation of handleDateFrontMatter is correct.

Calls formatDate(updated), which covers standard date outputs. Please confirm that the updated date scenario is tested.


147-185: Functional pipeline in convertFrontMatter looks well-organized.

The code is succinct, and each transformation step is clearly defined. This approach should be reliable.

src/core/fp.ts (8)

1-4: Documentation header is clear and concise.

The introductory comments explain the file's functional programming utilities.


5-38: pipe function overloads and logic appear correct.

Multiple overload signatures provide flexibility. The reduce-based implementation is straightforward. Ensure that edge cases (e.g., zero functions) are tested, if relevant.


40-45: Add test coverage for compose.

Coverage indicates line 44 (f(g(x))) may be untested. Verifying a multi-function compose scenario ensures correctness.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 44-44: src/core/fp.ts#L44
Added line #L44 was not covered by tests


60-65: Map function is straightforward but missing coverage.

Consider a test that validates the mapping behavior on non-empty and empty arrays.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 64-64: src/core/fp.ts#L64
Added line #L64 was not covered by tests


66-71: Filter function appears correct but lacks coverage.

Line 70 might not be tested according to the patch coverage hint. A quick test can confirm everything is working.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 70-70: src/core/fp.ts#L70
Added line #L70 was not covered by tests


72-77: Reduce function could use a simple test.

Make sure the accumulator logic is tested with various array lengths (including an empty array).

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 76-76: src/core/fp.ts#L76
Added line #L76 was not covered by tests


78-82: identity function is minimal and clear.

Implementation is trivially correct.


83-86: constant function is well-defined.

Always returning a fixed value is often helpful in functional patterns.

src/types.ts Outdated
Comment on lines 54 to 57
export const chain = <E, A, B>(
f: (a: A) => Either<E, B>,
) => (ma: Either<E, A>): Either<E, B> =>
isLeft(ma) ? ma : f(ma.value);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Consider adding tests for the chain function.

The chain function is a powerful utility for composing operations that might fail, but it appears to be missing test coverage.

Would you like me to propose a test case that covers this function?


🏁 Script executed:

#!/bin/bash
# Check if there are test cases covering the chain function
rg "chain\(" --type=ts src/tests

Length of output: 34


Action Required: Add Test Coverage for the chain Function

It appears that there are currently no tests covering the chain function (as verified by running the grep command in the tests directory). Please consider adding test cases to exercise both outcomes of chain—specifically:

  • When the input ma is a Left, ensuring it is returned unchanged.
  • When the input ma is a Right, verifying that function f is correctly applied to ma.value.

For example, a possible test case (using Jest syntax) might be:

describe('chain', () => {
  // A dummy Either implementation for testing purposes
  const right = <T>(value: T) => ({ _tag: 'Right', value });
  const left = <E>(error: E) => ({ _tag: 'Left', error });

  // The chain function as defined in src/types.ts
  // export const chain = <E, A, B>(
  //   f: (a: A) => Either<E, B>,
  // ) => (ma: Either<E, A>): Either<E, B> =>
  //   isLeft(ma) ? ma : f(ma.value); 

  const addOne = (n: number) => right(n + 1);

  it('should return the passed Left value without invoking the function', () => {
    const error = left('error');
    const result = chain(addOne)(error);
    expect(result).toEqual(error);
  });

  it('should apply the function to the Right value', () => {
    const value = right(1);
    const result = chain(addOne)(value);
    expect(result).toEqual(right(2));
  });
});

Implementing and running tests like these will help confirm the correct behavior of chain and guard against regressions.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 56-56: src/types.ts#L56
Added line #L56 was not covered by tests

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/docusaurus/docusaurus.ts (1)

54-63: Improve error messaging in the failure branch (optional).

In the error branch, only the error message is shown. Consider including the error type (e.g., PARSE_ERROR, VALIDATION_ERROR) in the Notice for more diagnostic information.

-error => {
-  new Notice(`Front matter conversion failed: ${error.message}`, 5000);
-  return contents;
+error => {
+  new Notice(
+    `Front matter conversion failed [${error.type}]: ${error.message}`,
+    5000
+  );
+  return contents;
}
src/FrontMatterConverter.ts (1)

9-9: Remove unused import
The chain import is never used, causing an ESLint warning. Consider removing it or using it if intended.

-import {
-  ConversionError,
-  ConversionResult,
-  Either,
-  FrontMatter,
-  chain,
-  left,
-  right,
-  map,
-} from './types';
+import {
  ConversionError,
  ConversionResult,
  Either,
  FrontMatter,
  left,
  right,
  map,
} from './types';
🧰 Tools
🪛 ESLint

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4667a96 and 8f5f423.

📒 Files selected for processing (6)
  • src/FrontMatterConverter.ts (1 hunks)
  • src/core/fp.ts (1 hunks)
  • src/docusaurus/docusaurus.ts (2 hunks)
  • src/tests/FrontMatterConverter.test.ts (1 hunks)
  • src/tests/types.test.ts (1 hunks)
  • src/types.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (6)
src/docusaurus/docusaurus.ts (1)
src/types.ts (2)
  • fold (43-46)
  • ConversionError (9-12)
src/tests/FrontMatterConverter.test.ts (2)
src/FrontMatterConverter.ts (1)
  • convertFrontMatter (155-200)
src/types.ts (1)
  • ConversionError (9-12)
src/tests/types.test.ts (1)
src/types.ts (6)
  • Either (25-25)
  • right (32-35)
  • left (27-30)
  • chain (53-56)
  • isLeft (37-38)
  • isRight (40-41)
src/FrontMatterConverter.ts (3)
src/types.ts (7)
  • Either (25-25)
  • ConversionError (9-12)
  • ConversionResult (4-7)
  • right (32-35)
  • FrontMatter (2-2)
  • left (27-30)
  • map (48-51)
src/core/ObsidianRegex.ts (1)
  • ObsidianRegex (1-9)
src/core/fp.ts (2)
  • pipe (33-38)
  • map (63-66)
src/types.ts (1)
src/core/fp.ts (1)
  • map (63-66)
src/core/fp.ts (1)
src/types.ts (1)
  • map (48-51)
🪛 ESLint
src/FrontMatterConverter.ts

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)

src/core/fp.ts

[error] 49-49: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 52-52: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🪛 GitHub Check: codecov/patch
src/FrontMatterConverter.ts

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests


[warning] 42-42: src/FrontMatterConverter.ts#L42
Added line #L42 was not covered by tests


[warning] 102-102: src/FrontMatterConverter.ts#L102
Added line #L102 was not covered by tests

src/types.ts

[warning] 45-45: src/types.ts#L45
Added line #L45 was not covered by tests

src/core/fp.ts

[warning] 44-44: src/core/fp.ts#L44
Added line #L44 was not covered by tests


[warning] 52-52: src/core/fp.ts#L52
Added line #L52 was not covered by tests


[warning] 54-54: src/core/fp.ts#L54
Added line #L54 was not covered by tests


[warning] 56-56: src/core/fp.ts#L56
Added line #L56 was not covered by tests


[warning] 65-66: src/core/fp.ts#L65-L66
Added lines #L65 - L66 were not covered by tests


[warning] 73-74: src/core/fp.ts#L73-L74
Added lines #L73 - L74 were not covered by tests


[warning] 81-82: src/core/fp.ts#L81-L82
Added lines #L81 - L82 were not covered by tests


[warning] 94-95: src/core/fp.ts#L94-L95
Added lines #L94 - L95 were not covered by tests

🔇 Additional comments (24)
src/docusaurus/docusaurus.ts (2)

16-16: Good import usage.

The import of ConversionError and fold supports a functional error-handling approach without introducing unnecessary complexity.


50-53: Properly passing authors to convertFrontMatter.

This ensures that the converter is aware of any specified authors for subsequent processing. The code looks well-structured and consistent with the new functional approach.

src/tests/types.test.ts (2)

1-2: Great import declarations.

All relevant utilities for testing (Either, left, right, chain, isLeft, isRight) are correctly imported.


3-44: Comprehensive Either chain tests.

These tests thoroughly validate both success and error paths, including chained operations and edge cases. This ensures robust coverage of the chain function.

src/tests/FrontMatterConverter.test.ts (9)

4-29: Clear and focused tests for basic front matter conversion.

They correctly ensure the convertFrontMatter function produces the expected YAML structure and handles standard fields.


30-64: Good coverage of image handling logic.

Enabling or disabling banner image processing is tested thoroughly. The checks confirm that the processed image path or the original path appears correctly in the output.


66-97: Mermaid detection tests look solid.

These tests guarantee that mermaid flags are correctly added only when mermaid code blocks exist. The code appears consistent and reliable.


99-127: Sound approach to updating dates.

The tests confirm that front matter dates are updated or left untouched based on the isEnableUpdateFrontmatterTimeOnEdit flag, covering both branches effectively.


130-158: Proper author handling tests.

Validating single and multiple author scenarios ensures correctness of the final YAML structure. This coverage appears adequate for typical use cases.


160-170: Robust error handling validation.

The suite checks that invalid YAML or parsing issues result in a Left that includes the appropriate error type. This test aligns well with the new functional error approach.


173-182: Verifies missing front matter gracefully.

Ensuring the function behaves normally when front matter is absent helps avoid unexpected failures in real-world usage.


183-192: Checks empty front matter case thoroughly.

The test confirms the converter's resilience with empty blocks, preserving the expected content.


194-208: Validation of delimiters-only front matter case.

The function correctly retains sections below and above the YAML delimiters, proving that no unintended content is lost.

src/FrontMatterConverter.ts (4)

22-24: Add test coverage for date formatting
Lines 22 and 24 handle Date objects and fallback to String(date). These scenarios appear untested. Consider adding test cases to verify that dates are correctly formatted or stringified.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests


42-42: Cover incomplete front matter scenario
Line 42 returns an empty front matter if the front matter closing marker is not found. Please add a test to ensure this path is exercised to maintain coverage.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 42-42: src/FrontMatterConverter.ts#L42
Added line #L42 was not covered by tests


102-102: Test array and string tag scenarios
This line branches on whether frontMatter.tags is an array or a string. Consider adding test coverage for both cases.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 102-102: src/FrontMatterConverter.ts#L102
Added line #L102 was not covered by tests


191-199: Well-structured functional approach
The pipeline of transformations using pipe and map is clean and maintainable. This functional style fosters readability and well-defined data flow.

src/types.ts (2)

45-45: Add test coverage for fold
Line 45 indicates the fold function's core logic. Consider adding tests to confirm both the Left and Right branches are handled correctly.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 45-45: src/types.ts#L45
Added line #L45 was not covered by tests


53-56: Test coverage for chain
This replicates a previous suggestion to add unit tests for the chain function.

src/core/fp.ts (5)

43-45: Compose function coverage
The compose logic at line 44 is not covered by tests. Please consider adding a test to ensure composition works as intended.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 44-44: src/core/fp.ts#L44
Added line #L44 was not covered by tests


63-66: Map function test coverage
Lines 65-66 are missing test coverage. A basic test asserting the transformation on an array would help confirm correctness.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 65-66: src/core/fp.ts#L65-L66
Added lines #L65 - L66 were not covered by tests


71-74: Filter function test coverage
Lines 73-74 appear untested. Consider adding a test to confirm that elements failing the predicate are indeed removed.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 73-74: src/core/fp.ts#L73-L74
Added lines #L73 - L74 were not covered by tests


79-82: Reduce function test coverage
The accumulator logic on lines 81-82 warrants testing. Verifying how items are aggregated would solidify confidence in its correctness.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 81-82: src/core/fp.ts#L81-L82
Added lines #L81 - L82 were not covered by tests


92-95: Constant function test coverage
Lines 94-95 are not covered. A simple test verifying that the returned function consistently yields the same value would suffice.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 94-95: src/core/fp.ts#L94-L95
Added lines #L94 - L95 were not covered by tests

src/core/fp.ts Outdated
Comment on lines 49 to 58
export const curry = <A extends any[], R>(
fn: (...args: A) => R,
): ((...args: any[]) => any) | ((...args: A) => R) => {
return function curried(...args: any[]) {
if (args.length >= fn.length) {
return fn(...(args as A));
}
return (...moreArgs: any[]) => curried(...args, ...moreArgs);
};
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refine type definitions in curry & increase coverage
ESLint flags the repeated use of any in the curry function. Consider leveraging generics or more precise parameter types to adhere to best practices. Also note that lines 52, 54, and 56 appear uncovered in tests.

-export const curry = <A extends any[], R>(
-  fn: (...args: A) => R,
-): ((...args: any[]) => any) | ((...args: A) => R) => {
+export const curry = <A extends unknown[], R>(
+  fn: (...args: A) => R,
+): (...args: A) => R | ((...args: Partial<A>) => R) => {
   // ...
}
📝 Committable suggestion

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

Suggested change
export const curry = <A extends any[], R>(
fn: (...args: A) => R,
): ((...args: any[]) => any) | ((...args: A) => R) => {
return function curried(...args: any[]) {
if (args.length >= fn.length) {
return fn(...(args as A));
}
return (...moreArgs: any[]) => curried(...args, ...moreArgs);
};
};
export const curry = <A extends unknown[], R>(
fn: (...args: A) => R,
): (...args: A) => R | ((...args: Partial<A>) => R) => {
return function curried(...args: any[]) {
if (args.length >= fn.length) {
return fn(...(args as A));
}
return (...moreArgs: any[]) => curried(...args, ...moreArgs);
};
};
🧰 Tools
🪛 ESLint

[error] 49-49: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 52-52: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🪛 GitHub Check: codecov/patch

[warning] 52-52: src/core/fp.ts#L52
Added line #L52 was not covered by tests


[warning] 54-54: src/core/fp.ts#L54
Added line #L54 was not covered by tests


[warning] 56-56: src/core/fp.ts#L56
Added line #L56 was not covered by tests

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/core/fp.ts (1)

52-65: 🛠️ Refactor suggestion

Improve type definitions in curry function

The function uses any type and the generic Function type, which reduce type safety. Consider using more specific types.

-export function curry<A, B, C>(fn: (a: A, b: B, c: C) => any): (a: A) => (b: B) => (c: C) => any;
-export function curry<A, B>(fn: (a: A, b: B) => any): (a: A) => (b: B) => any;
-export function curry<A>(fn: (a: A) => any): (a: A) => any;
-export function curry(fn: Function) {
+export function curry<A, B, C, R>(fn: (a: A, b: B, c: C) => R): (a: A) => (b: B) => (c: C) => R;
+export function curry<A, B, R>(fn: (a: A, b: B) => R): (a: A) => (b: B) => R;
+export function curry<A, R>(fn: (a: A) => R): (a: A) => R;
+export function curry<Args extends unknown[], R>(fn: (...args: Args) => R) {
  return function curried(...args: unknown[]) {
    if (args.length >= fn.length) {
      return fn(...args);
    }
    return (...moreArgs: unknown[]) => curried(...args, ...moreArgs);
  };
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 58-58: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🪛 ESLint

[error] 55-55: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 55-55: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

(@typescript-eslint/no-unsafe-function-type)

🧹 Nitpick comments (4)
src/tests/fp.test.ts (2)

1-10: Check unused import

The pipe function is imported but never used in this test file, which could lead to confusion and bloated imports.

import {
-  pipe,
  compose,
  map,
  filter,
  reduce,
  identity,
  constant,
  curry,
} from '../core/fp';
🧰 Tools
🪛 ESLint

[error] 2-2: 'pipe' is defined but never used.

(@typescript-eslint/no-unused-vars)


97-103: Consider simplifying type casting in constant function test

The type casting to (always5 as unknown as (x: unknown) => number) is unnecessarily complex and makes the test harder to read.

  it('should return a function that always returns the same value', () => {
    const always5 = constant(5);
    expect(always5()).toBe(5);
-   expect((always5 as unknown as (x: unknown) => number)('anything')).toBe(5);
-   expect((always5 as unknown as (x: unknown) => number)(123)).toBe(5);
+   // The constant function ignores all arguments
+   expect(always5('anything' as any)).toBe(5);
+   expect(always5(123 as any)).toBe(5);
  });
src/core/fp.ts (2)

46-51: Unused type definition

The CurriedFunction type is defined but never used in the codebase. Consider either using it in the curry implementation or removing it.

-type CurriedFunction<Args extends unknown[], R> = Args extends [infer A]
-  ? (a: A) => R
-  : Args extends [infer A, ...infer Rest]
-  ? (a: A) => CurriedFunction<Rest, R>
-  : never;

Alternatively, you could use this type to improve the implementation of the curry function.

🧰 Tools
🪛 ESLint

[error] 46-46: 'CurriedFunction' is defined but never used.

(@typescript-eslint/no-unused-vars)


1-103: Consider adding tests for the pipe function

While you've added comprehensive tests for almost all functions in fp.test.ts, the pipe function is not tested. To ensure full test coverage, add tests for the pipe function.

Here's a sample test implementation you could add to fp.test.ts:

describe('pipe', () => {
  it('should pipe functions from left to right', () => {
    const addOne = (x: number) => x + 1;
    const double = (x: number) => x * 2;
    
    // (5 + 1) * 2 = 12
    expect(pipe(5, addOne, double)).toBe(12);
  });
  
  it('should handle a single function', () => {
    const addOne = (x: number) => x + 1;
    expect(pipe(5, addOne)).toBe(6);
  });
  
  it('should handle multiple functions', () => {
    const addOne = (x: number) => x + 1;
    const double = (x: number) => x * 2;
    const toString = (x: number) => `Result: ${x}`;
    
    expect(pipe(5, addOne, double, toString)).toBe('Result: 12');
  });
});
🧰 Tools
🪛 Biome (1.9.4)

[error] 58-58: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🪛 ESLint

[error] 46-46: 'CurriedFunction' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 55-55: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 55-55: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

(@typescript-eslint/no-unsafe-function-type)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1b9a3e4 and 6f66293.

📒 Files selected for processing (2)
  • src/core/fp.ts (1 hunks)
  • src/tests/fp.test.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/tests/fp.test.ts (1)
src/core/fp.ts (7)
  • compose (43-44)
  • map (70-73)
  • filter (78-81)
  • reduce (86-89)
  • identity (94-94)
  • constant (99-102)
  • curry (58-65)
src/core/fp.ts (1)
src/types.ts (1)
  • map (48-51)
🪛 ESLint
src/tests/fp.test.ts

[error] 2-2: 'pipe' is defined but never used.

(@typescript-eslint/no-unused-vars)

src/core/fp.ts

[error] 46-46: 'CurriedFunction' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 55-55: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 55-55: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

(@typescript-eslint/no-unsafe-function-type)

🪛 Biome (1.9.4)
src/core/fp.ts

[error] 58-58: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🔇 Additional comments (12)
src/tests/fp.test.ts (5)

14-21: LGTM! Good test case for compose function.

The test correctly verifies that compose applies functions from right to left (double first, then addOne), with clear expectations.


30-42: LGTM! Map function tests are comprehensive.

Tests cover both regular array transformation and the empty array edge case, which is good practice for functional utilities.


45-64: LGTM! Filter function tests cover all key scenarios.

Good test coverage with three test cases: successful filtering, empty array handling, and no matches scenario.


66-85: LGTM! Reduce tests handle all edge cases.

The tests comprehensively verify reduce behavior for normal arrays, empty arrays, and single-element arrays.


106-136: LGTM! Curry tests are comprehensive and cover important edge cases.

The tests verify currying with multiple arguments, single arguments, and maintaining function context - all important aspects of a curry implementation.

src/core/fp.ts (7)

5-38: Well-designed pipe function with comprehensive overloads

The pipe function implementation is clean and the multiple overloads provide excellent type safety up to 6 arguments. The reduce-based implementation is efficient.


40-44: LGTM! Compose implementation is correct and concise.

The compose function correctly implements function composition from right to left using reduce.


67-73: LGTM! Well-implemented map function.

The map function is well-implemented with proper types and currying style.


75-81: LGTM! Well-implemented filter function.

The filter function is well-implemented with proper types and currying style.


83-89: LGTM! Well-implemented reduce function.

The reduce function is well-implemented with proper types and currying style.


91-94: LGTM! Identity function is simple and correct.

The identity function correctly implements the identity concept from functional programming.


96-102: LGTM! Well-implemented constant function.

The constant function correctly creates a function that always returns the same value.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/core/fp.ts (1)

46-67: 🛠️ Refactor suggestion

Refine type definitions in curry & utilize CurriedFunction type

The curry function uses any types and the discouraged Function type. Consider utilizing the defined CurriedFunction type to provide better type safety and address the ESLint warnings.

type CurriedFunction<Args extends unknown[], R> = Args extends [infer A]
  ? (a: A) => R
  : Args extends [infer A, ...infer Rest]
    ? (a: A) => CurriedFunction<Rest, R>
    : never;

-export function curry<A, B, C>(
-  fn: (a: A, b: B, c: C) => any,
-): (a: A) => (b: B) => (c: C) => any;
-export function curry<A, B>(fn: (a: A, b: B) => any): (a: A) => (b: B) => any;
-export function curry<A>(fn: (a: A) => any): (a: A) => any;
-export function curry(fn: Function) {
+export function curry<Args extends unknown[], R>(
+  fn: (...args: Args) => R
+): CurriedFunction<Args, R> {
  return function curried(...args: unknown[]) {
    if (args.length >= fn.length) {
      return fn(...args);
    }
    return (...moreArgs: unknown[]) => curried(...args, ...moreArgs);
  };
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 60-60: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🪛 ESLint

[error] 46-46: 'CurriedFunction' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 59-59: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 59-59: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 60-60: The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

(@typescript-eslint/no-unsafe-function-type)

🧹 Nitpick comments (1)
src/core/fp.ts (1)

40-44: Consider enhancing the compose function to handle different types

The current implementation of compose only works when all functions have the same input and output type (A). This limits its usefulness compared to the pipe function, which supports varying types between functions.

-export const compose = <A>(...fns: Array<(a: A) => A>): ((a: A) => A) =>
-  fns.reduce((f, g) => x => f(g(x)));
+export function compose<A, B>(ab: (a: A) => B): (a: A) => B;
+export function compose<A, B, C>(bc: (b: B) => C, ab: (a: A) => B): (a: A) => C;
+export function compose<A, B, C, D>(cd: (c: C) => D, bc: (b: B) => C, ab: (a: A) => B): (a: A) => D;
+export function compose<A, B, C, D, E>(de: (d: D) => E, cd: (c: C) => D, bc: (b: B) => C, ab: (a: A) => B): (a: A) => E;
+export function compose<A, B, C, D, E, F>(ef: (e: E) => F, de: (d: D) => E, cd: (c: C) => D, bc: (b: B) => C, ab: (a: A) => B): (a: A) => F;
+export function compose(...fns: Array<(x: any) => any>): (x: any) => any {
+  return fns.reduce((f, g) => x => f(g(x)));
+}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6f66293 and 51159eb.

📒 Files selected for processing (1)
  • src/core/fp.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
src/core/fp.ts (1)
src/types.ts (1)
  • map (48-51)
🪛 Biome (1.9.4)
src/core/fp.ts

[error] 60-60: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🪛 ESLint
src/core/fp.ts

[error] 46-46: 'CurriedFunction' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 56-56: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 58-58: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 59-59: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 59-59: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 60-60: The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

(@typescript-eslint/no-unsafe-function-type)

🔇 Additional comments (4)
src/core/fp.ts (4)

5-38: Well-designed pipe function with proper type safety

The pipe function implementation is clean, clear, and provides good type safety through multiple function overloads. The reducer implementation is concise and follows functional programming principles.


69-75: Well-implemented map function with proper currying

The map function implementation is concise, type-safe, and follows the functional programming pattern of currying.


77-91: Clean implementations of filter and reduce

The filter and reduce functions are well-implemented with proper currying and type safety.


93-104: Well-implemented utility functions

The identity and constant functions are simple but essential utilities in functional programming. Both implementations are correct and type-safe.

- Fix template literal formatting in FrontMatterConverter

- Fix method chaining and arrow function formatting

- Run prettier on all TypeScript files
Copy link
Contributor

@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: 3

🧹 Nitpick comments (5)
src/tests/fp.test.ts (3)

1-10: Remove unused import 'pipe'

The pipe function is imported but never used in this file, which is flagged by ESLint. Either add tests for this function or remove it from the import list.

import {
-  pipe,
  compose,
  map,
  filter,
  reduce,
  identity,
  constant,
  curry,
} from '../core/fp';
🧰 Tools
🪛 ESLint

[error] 2-2: 'pipe' is defined but never used.

(@typescript-eslint/no-unused-vars)


30-43: Good coverage for map functionality

The tests for the map function appropriately verify transformation of array elements and handling of empty arrays. Consider adding a test case with more complex data types (e.g., objects) if they're relevant to your use cases.


97-106: Functional constant tests with complex type casting

The tests for the constant function verify that it returns a function that always produces the same value. The type casting on lines 101-104 is quite complex - consider using a simpler approach to test with different inputs if possible.

- expect((always5 as unknown as (x: unknown) => number)('anything')).toBe(
-   5,
- );
- expect((always5 as unknown as (x: unknown) => number)(123)).toBe(5);
+ // TypeScript knows always5 doesn't take parameters, but we can test the behavior
+ // @ts-ignore
+ expect(always5('anything')).toBe(5);
+ // @ts-ignore
+ expect(always5(123)).toBe(5);
src/FrontMatterConverter.ts (2)

73-83: Consider simplifying the categories formatting logic

The current implementation for formatting categories is a bit complex. Consider using a more direct approach to determine if categories is already an array or a string.

const formatCategories = (frontMatter: FrontMatter): FrontMatter => {
  if (!frontMatter.categories) return frontMatter;

- const categories = JSON.stringify(frontMatter.categories).startsWith('[')
-   ? JSON.stringify(frontMatter.categories)
-       .replace(/,/g, ', ')
-       .replace(/"/g, '')
-   : frontMatter.categories;
+ const categories = Array.isArray(frontMatter.categories)
+   ? `[${frontMatter.categories.join(', ')}]`
+   : frontMatter.categories.startsWith('[') && frontMatter.categories.endsWith(']')
+     ? frontMatter.categories
+     : `[${frontMatter.categories}]`;

  return { ...frontMatter, categories };
};

133-140: Consider preserving both date and updated fields

The current implementation replaces the updated field with date when isEnableUpdateFrontmatterTimeOnEdit is true. Consider preserving both fields to maintain more information about the document's history.

const handleDateFrontMatter =
  (isEnable: boolean) =>
  (frontMatter: FrontMatter): FrontMatter => {
    if (!isEnable || isNullOrEmpty(frontMatter.updated)) return frontMatter;

-   const { updated, ...rest } = frontMatter;
-   return { ...rest, date: formatDate(updated) };
+   return { 
+     ...frontMatter, 
+     date: formatDate(frontMatter.updated) 
+   };
  };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 51159eb and 7971c85.

📒 Files selected for processing (2)
  • src/FrontMatterConverter.ts (1 hunks)
  • src/tests/fp.test.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/FrontMatterConverter.ts (3)
src/types.ts (7)
  • Either (25-25)
  • ConversionError (9-12)
  • ConversionResult (4-7)
  • right (32-35)
  • FrontMatter (2-2)
  • left (27-30)
  • map (48-51)
src/core/ObsidianRegex.ts (1)
  • ObsidianRegex (1-9)
src/core/fp.ts (2)
  • pipe (33-38)
  • map (72-75)
src/tests/fp.test.ts (1)
src/core/fp.ts (7)
  • compose (43-44)
  • map (72-75)
  • filter (80-83)
  • reduce (88-91)
  • identity (96-96)
  • constant (101-104)
  • curry (60-67)
🪛 ESLint
src/FrontMatterConverter.ts

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)

src/tests/fp.test.ts

[error] 2-2: 'pipe' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 GitHub Check: codecov/patch
src/FrontMatterConverter.ts

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests


[warning] 42-42: src/FrontMatterConverter.ts#L42
Added line #L42 was not covered by tests


[warning] 104-104: src/FrontMatterConverter.ts#L104
Added line #L104 was not covered by tests

🔇 Additional comments (14)
src/tests/fp.test.ts (5)

12-28: Well-structured compose tests

The tests for the compose function are well-implemented, covering both composition of multiple functions and the single function case. The code comment "(5 * 2) + 1 = 11" on line 19 is particularly helpful for understanding the execution order.


45-64: Comprehensive filter tests

The test suite for the filter function is well-designed, covering normal filtering, empty arrays, and arrays with no matches. The isEven predicate is a clear and simple example for testing purposes.


66-85: Thorough reduce tests

The tests for the reduce function appropriately verify the reduction of arrays to single values, while also handling edge cases like empty arrays and single-element arrays.


87-95: Well-implemented identity tests

The tests for the identity function correctly verify its behavior across different data types (number, string, null, object). Good use of toBe for object identity checks rather than just equality.


108-139: Excellent curry tests showing various usage patterns

The test suite for the curry function is comprehensive, covering:

  1. Step-by-step currying
  2. All-at-once argument application
  3. Single-argument functions
  4. Function context preservation

This demonstrates good testing practices for functional programming utilities.

src/FrontMatterConverter.ts (9)

15-18: LGTM! Good utility function implementation

The isNullOrEmpty helper function is well implemented, handling undefined, null and empty string cases properly, which will make the code more robust.


27-30: Good approach for handling author lists

This helper function correctly formats author lists by properly handling both single authors and multiple authors (wrapping multiple authors in square brackets). This improves consistency in the front matter formatting.


63-71: Well-structured pure function for title formatting

The formatTitle function is a good example of a pure function that handles a specific concern. It ensures that titles are properly quoted, which helps maintain consistency in the front matter.


85-95: Good reuse of the formatAuthorList helper

The formatAuthors function properly reuses the formatAuthorList helper function, which demonstrates good adherence to the DRY principle.


107-112: Good approach for detecting and handling mermaid diagrams

The handleMermaid function correctly detects mermaid diagrams in the content and adds the appropriate front matter flag. This is a clean implementation that follows the single responsibility principle.


114-131: Well-structured curried functions for image path handling

The image path handling is well-implemented using curried functions, which aligns well with functional programming principles. The code is readable and maintainable.


142-154: Clean implementation of front matter serialization

The serializeFrontMatter function is a well-structured pure function that correctly handles both cases with and without front matter. The implementation is clean and follows functional programming principles.


156-202: Excellent use of functional programming with pipe

The main convertFrontMatter function is a great example of functional programming principles in action. By using the pipe function to chain operations, the code becomes more readable and maintainable. The function parameters are well-defined, with sensible defaults and good use of TypeScript's readonly modifier for the options object.

The use of the Either type for error handling throughout the pipeline ensures that errors are properly propagated and handled.


19-25:

❓ Verification inconclusive

Ensure complete test coverage for formatDate function

The code coverage report indicates that lines 22 and 24 aren't covered by tests. Consider adding test cases for Date objects and other data types.


🏁 Script executed:

#!/bin/bash
# Check test coverage of formatDate function
fd "FrontMatterConverter.test.ts" --exec grep -A 10 -B 10 "formatDate" {} \;

Length of output: 77


Action Required: Expand Test Coverage for formatDate Function

The current tests do not seem to invoke the branches handling Date objects and non-string inputs. Please add test cases to explicitly cover the following scenarios:

  • String Input: Confirm that a string input is returned as-is.
  • Date Instance: Verify that a Date instance returns an ISO date (e.g., "YYYY-MM-DD").
  • Fallback Case: Test with other types (e.g., numbers, booleans) to ensure they are correctly converted to strings.

Kindly manually verify the test suite to ensure it covers all these branches, as the automated search did not yield conclusive evidence of such tests.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests

Comment on lines +32 to 61
// Pure functions for front matter operations
const extractFrontMatter = (
content: string,
): Either<ConversionError, ConversionResult> => {
if (!content.startsWith('---\n')) {
return right({ frontMatter: {}, body: content });
}

// for define front matter boundary
const endOfFrontMatter = content.indexOf('---', 3);
const endOfFrontMatter = content.indexOf('\n---', 3);
if (endOfFrontMatter === -1) {
return [{}, content];
return right({ frontMatter: {}, body: content });
}

const frontMatterLines = content.substring(3, endOfFrontMatter);
const body = content.substring(endOfFrontMatter + 3).trimStart();
const frontMatterLines = content.substring(4, endOfFrontMatter);
const body = content.substring(endOfFrontMatter + 4).trimStart();

try {
const frontMatter = yaml.load(frontMatterLines) as FrontMatter;
return [frontMatter, body];
const frontMatter = yaml.load(frontMatterLines, {
schema: yaml.JSON_SCHEMA,
}) as FrontMatter;
return right({ frontMatter: frontMatter || {}, body });
} catch (e) {
console.error(e);
return [{}, content];
return left({
type: 'PARSE_ERROR',
message: `Failed to parse front matter: ${
e instanceof Error ? e.message : 'Unknown error'
}`,
});
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Excellent implementation of Either pattern for error handling

The extractFrontMatter function is a significant improvement over the previous implementation. By using the Either pattern, it properly handles error cases without throwing exceptions and provides clear error messages. This makes the code more robust and maintainable.

However, line 42 lacks test coverage. Consider adding a test case that covers the scenario where front matter is malformed.


🏁 Script executed:

#!/bin/bash
# Check test coverage for malformed front matter case
fd "FrontMatterConverter.test.ts" --exec grep -A 10 -B 10 "malformed" {} \;

Length of output: 76


Test Coverage for Malformed Front Matter Is Missing

The overall implementation using the Either pattern for error handling is excellent. However, our verification indicates that there isn’t a corresponding test case for the scenario when the front matter is malformed (i.e., when the YAML parser fails). Please add a test in FrontMatterConverter.test.ts that supplies malformed YAML input so that the error handling (the catch block in lines 42–61 of src/FrontMatterConverter.ts) is properly verified.

  • Verify that a malformed YAML input returns the appropriate ConversionError (using the left branch of the Either).
  • Ensure the error message clearly indicates a parse failure.
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 42-42: src/FrontMatterConverter.ts#L42
Added line #L42 was not covered by tests

Comment on lines 97 to 105
const formatTags = (frontMatter: FrontMatter): FrontMatter => {
if (!frontMatter.tags) return frontMatter;

constructor(
fileName: string,
resourcePath: string,
isEnableBanner = false,
isEnableUpdateFrontmatterTimeOnEdit = false,
) {
this.fileName = fileName;
this.resourcePath = resourcePath;
this.isEnableBanner = isEnableBanner;
this.isEnableUpdateFrontmatterTimeOnEdit =
isEnableUpdateFrontmatterTimeOnEdit;
}
const tags = Array.isArray(frontMatter.tags)
? `[${frontMatter.tags.join(', ')}]`
: `[${frontMatter.tags}]`;

parseFrontMatter(content: string): [FrontMatter, string] {
return parseFrontMatter(content);
}
return { ...frontMatter, tags };
};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Ensure complete test coverage for formatTags function

The code coverage report indicates that line 104 isn't covered by tests. Consider adding test cases for the tags formatting logic.


🏁 Script executed:

#!/bin/bash
# Check test coverage of formatTags function
fd "FrontMatterConverter.test.ts" --exec grep -A 10 -B 10 "tags" {} \;

Length of output: 71


Action Required: Enhance Test Coverage for formatTags Function

The current tests don’t appear to exercise the full logic of the formatTags function—specifically, the scenario at line 104 responsible for formatting the tags isn’t covered. Please verify and add tests in src/FrontMatterConverter.test.ts (or the appropriate test file) to cover:

  • Cases where frontMatter.tags is undefined (to ensure early returns work correctly).
  • Cases where frontMatter.tags is a non-array value.
  • Cases where frontMatter.tags is an array, confirming it gets formatted as a string (e.g., "[tag1, tag2]").

This should ensure complete test coverage for the tags formatting logic.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 104-104: src/FrontMatterConverter.ts#L104
Added line #L104 was not covered by tests

- Add test cases for malformed YAML handling

- Add test cases for tags formatting

- Fix empty tags handling

- Format code with prettier
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/FrontMatterConverter.ts (1)

2-13: ⚠️ Potential issue

Remove unused import 'chain'.

The 'chain' utility is imported but never used in this file. This will cause linting errors.

import {
  ConversionError,
  ConversionResult,
  Either,
  FrontMatter,
- chain,
  left,
  right,
  map,
} from './types';
🧰 Tools
🪛 ESLint

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7971c85 and a650870.

📒 Files selected for processing (2)
  • src/FrontMatterConverter.ts (1 hunks)
  • src/tests/FrontMatterConverter.test.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/tests/FrontMatterConverter.test.ts (2)
src/FrontMatterConverter.ts (1)
  • convertFrontMatter (159-204)
src/types.ts (1)
  • ConversionError (9-12)
src/FrontMatterConverter.ts (1)
src/types.ts (7)
  • Either (25-25)
  • ConversionError (9-12)
  • ConversionResult (4-7)
  • right (32-35)
  • FrontMatter (2-2)
  • left (27-30)
  • map (48-51)
🪛 ESLint
src/FrontMatterConverter.ts

[error] 9-9: 'chain' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 GitHub Check: codecov/patch
src/FrontMatterConverter.ts

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests


[warning] 42-42: src/FrontMatterConverter.ts#L42
Added line #L42 was not covered by tests

🔇 Additional comments (23)
src/tests/FrontMatterConverter.test.ts (15)

4-27: Well-structured test for basic front matter conversion.

Your test case for basic front matter conversion properly validates the functionality and uses the Either monad pattern correctly. The test ensures that the title is properly formatted with quotes and verifies the entire output structure.


30-47: Good test for image path processing when enabled.

This test correctly verifies that image paths are properly processed with the banner enabled, including path prefixing and resource path incorporation. The use of the Either type for handling results is well-implemented.


49-63: Proper verification of disabled image processing.

The test validates that when isEnableBanner is false, the image paths remain unchanged. This is an important test case to ensure the feature can be toggled without side effects.


66-81: Excellent test for mermaid code block detection.

The test properly verifies that when a mermaid code block is present in the content, the mermaid: true flag is added to the front matter. This ensures proper processing for Docusaurus rendering.


83-96: Good negative test case for mermaid detection.

This test verifies that when no mermaid code block is present, the mermaid flag is not added to the front matter, which is an important negative test case to include.


99-113: Thorough test for date updating functionality.

This test correctly verifies the behavior when isEnableUpdateFrontmatterTimeOnEdit is enabled, ensuring that the date is properly updated from the updated field and the updated field is removed.


115-127: Good test for disabled date updating.

This test ensures that when isEnableUpdateFrontmatterTimeOnEdit is disabled, the updated field remains unchanged, which is the expected behavior.


130-143: Proper validation of single author formatting.

This test verifies that a single author is correctly formatted in the front matter. Nice job on handling this edge case.


145-157: Good test for multiple authors formatting.

This test ensures that multiple authors are correctly formatted with brackets, validating that the comma-separated list is properly converted.


160-187: Comprehensive error handling tests for YAML parsing.

Your tests properly verify that malformed YAML with incorrect indentation returns a Left with PARSE_ERROR type and an appropriate error message, which is essential for robust error handling.


189-210: Good coverage of additional error scenarios.

These tests verify error handling for duplicate keys and invalid structure, providing thorough coverage of potential error cases that might occur during front matter parsing.


213-224: Proper test for single tag formatting.

The test verifies that a single tag string is correctly converted to an array format, which aligns with the expected front matter formatting requirements.


226-248: Comprehensive tag format handling tests.

These tests ensure that various tag formats (array and comma-separated string) are correctly processed, which is essential for compatibility with different input styles.


250-271: Good edge case coverage for tags.

These tests verify handling of missing and empty tags, which are important edge cases to consider for robust front matter processing.


274-309: Excellent edge case coverage.

These tests ensure the converter handles missing front matter, empty front matter, and front matter with only dividers gracefully. Edge case testing is crucial for robust functionality, and your tests cover these scenarios well.

src/FrontMatterConverter.ts (8)

45-61: Well-implemented Either pattern for error handling.

The extractFrontMatter function effectively uses the Either monad pattern to handle success and error cases without throwing exceptions. The detailed error messages with the original error text provide clear information for debugging.


63-71: Clean implementation of title formatting.

The formatTitle function is a pure function that properly handles title formatting, ensuring that titles are quoted correctly without modifying the original object.


73-83: Good implementation of categories formatting.

The formatCategories function correctly processes different formats of categories, ensuring they are properly formatted in the output. The function maintains immutability by returning a new object.


85-95: Clean implementation of authors formatting.

The formatAuthors function correctly handles the authors field, ensuring it's properly formatted for Docusaurus. The early return when the field is already properly formatted is a nice optimization.


97-107: Comprehensive tags formatting logic.

The formatTags function handles different tag formats (array, string, empty) correctly, ensuring they are properly formatted in the output. This aligns well with the test cases in the test file.


109-156: Well-structured utility functions for specific transformations.

These utility functions (handleMermaid, convertImagePath, handleImageFrontMatter, handleDateFrontMatter, serializeFrontMatter) follow the functional programming principles well:

  • They're pure functions with no side effects
  • They follow a consistent pattern of transformation
  • They maintain immutability by returning new objects
  • The curried functions provide good composability

The use of currying in handleImageFrontMatter and handleDateFrontMatter is particularly well-implemented, allowing for partial application.


159-204: Excellent functional composition with pipe pattern.

The main convertFrontMatter function effectively uses the pipe pattern to compose transformations, making the code more readable and maintainable. The function:

  1. Accepts flexible options with sensible defaults
  2. Processes front matter through a sequence of pure functions
  3. Uses the pipe and map operations for functional composition
  4. Returns an Either type for robust error handling

This is a significant improvement that adheres to functional programming principles.


32-43:

❓ Verification inconclusive

Add test for case when front matter end marker is missing.

The code handling the case where end of front matter is not found (line 42) is not covered by tests according to code coverage reports. Add a test case with malformed front matter that has a start marker but no end marker.


🏁 Script executed:

#!/bin/bash
# Check if there's any test for malformed front matter without end marker
fd "FrontMatterConverter.test.ts" --exec grep -A 5 -B 5 "missing end marker" {} \;

Length of output: 85


Action Required: Add Test for Incomplete Front Matter Parsing
It appears the scenario where front matter is started with "---\n" but never properly closed (i.e. missing the end marker) isn’t covered by any existing tests. Please add a test in FrontMatterConverter.test.ts that passes such malformed content to extractFrontMatter and verifies that it returns an object with an empty frontMatter and the original content as body.

Example test snippet for guidance:

test('extractFrontMatter returns unchanged content for missing end marker', () => {
  const input = `---\ntitle: "Missing end marker"
Body content without a closing marker.`;
  const result = extractFrontMatter(input);
  expect(result).toEqual(right({ frontMatter: {}, body: input }));
});
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 42-42: src/FrontMatterConverter.ts#L42
Added line #L42 was not covered by tests

Comment on lines +16 to +25
const isNullOrEmpty = (str: string | undefined | null): boolean =>
!str || (typeof str === 'string' && str.trim().length === 0);

const formatDate = (date: unknown): string => {
if (typeof date === 'string') return date;
if (date instanceof Date) {
return date.toISOString().split('T')[0];
}
return String(date);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Add test coverage for formatDate edge cases.

The formatDate function handles different date formats, but some paths lack test coverage:

  • Line 22 (Date object formatting)
  • Line 24 (fallback for other value types)

Add tests that pass Date objects and other value types to ensure complete coverage.


🏁 Script executed:

#!/bin/bash
# Check existing test coverage for formatDate
fd -e ts -x grep -l "formatDate" {} \;

Length of output: 71


Action Required: Add Test Cases for formatDate Edge Cases

The current implementation of formatDate in src/FrontMatterConverter.ts handles multiple input types but lacks test coverage for some paths. Specifically:

  • Line 22 (Formatting when a Date object is passed): Ensure that a Date instance correctly converts to the "YYYY-MM-DD" format.
  • Line 24 (Fallback behavior for other types): Test that non-string, non-Date values are properly converted to strings.

No separate test files appear to cover these scenarios (the grep result only references the source file itself). Please add unit tests in the appropriate test suite to cover these edge cases.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 22-22: src/FrontMatterConverter.ts#L22
Added line #L22 was not covered by tests


[warning] 24-24: src/FrontMatterConverter.ts#L24
Added line #L24 was not covered by tests

songkg7 added 4 commits March 30, 2025 10:33
- Add test for front matter without end marker

- Add test for Date object formatting

- Add test for non-string/non-Date values
- Add tests for pipe, compose, curry functions

- Add tests for map, filter, reduce operations

- Add tests for identity and constant functions

- Achieve 100% code coverage for fp.ts
- Add prettier dependency

- Add prettier configuration

- Add prettier scripts

- Format fp.test.ts
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a650870 and 8db0d3f.

📒 Files selected for processing (3)
  • src/FrontMatterConverter.ts (1 hunks)
  • src/tests/FrontMatterConverter.test.ts (1 hunks)
  • src/tests/fp.test.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/tests/FrontMatterConverter.test.ts (2)
src/FrontMatterConverter.ts (1)
  • convertFrontMatter (158-203)
src/types.ts (1)
  • ConversionError (9-12)
src/tests/fp.test.ts (1)
src/core/fp.ts (8)
  • pipe (33-38)
  • compose (43-44)
  • curry (60-67)
  • map (72-75)
  • filter (80-83)
  • reduce (88-91)
  • identity (96-96)
  • constant (101-104)
🪛 Biome (1.9.4)
src/tests/fp.test.ts

[error] 17-17: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🪛 GitHub Check: codecov/patch
src/FrontMatterConverter.ts

[warning] 21-21: src/FrontMatterConverter.ts#L21
Added line #L21 was not covered by tests

🔇 Additional comments (46)
src/tests/fp.test.ts (9)

1-10: LGTM! Clean imports of functional utilities.

The imports are organized clearly, bringing in all the necessary functional programming utilities that are tested in this file.


12-33: Excellent test coverage for the pipe utility.

The tests thoroughly verify the pipe function's behavior, covering multiple functions, single function, and empty function array cases.

🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


35-48: Good test coverage for the compose utility.

Tests appropriately verify that composition works right-to-left, confirming the mathematical definition of function composition.


50-69: Thorough test coverage for the curry utility.

Tests verify multi-argument functions, partial application, and single argument functions - all key aspects of currying.


71-84: Comprehensive tests for the map utility.

Tests verify the mapping behavior and handle edge cases like empty arrays correctly.


86-99: Good test coverage for the filter utility.

Tests verify filtering based on predicates and handle edge cases like empty arrays appropriately.


101-114: Well-structured tests for the reduce utility.

Tests verify reduction with an accumulator function and correctly handle the empty array case.


116-124: Comprehensive tests for the identity utility.

Tests verify that identity works correctly across different data types.


126-139: Clear tests for the constant utility.

Tests verify that the function consistently returns the same value regardless of input.

src/tests/FrontMatterConverter.test.ts (25)

1-3: Good imports for the tests.

Correctly importing the convertFrontMatter function and the ConversionError type to test both success and error scenarios.


4-27: Effective test for basic front matter conversion.

The test verifies that the basic front matter conversion works correctly using the new Either type, properly checking the _tag to ensure it's a Right (success) result.


30-47: Good test for image path processing when enabled.

Properly tests that image paths are transformed when the isEnableBanner option is enabled.


49-63: Comprehensive test for image path preservation when disabled.

Confirms that image paths remain unchanged when the isEnableBanner option is disabled.


66-81: Effective test for mermaid flag addition.

Verifies that the mermaid flag is added to the front matter when a mermaid code block is detected in the content.


83-96: Good test for mermaid flag absence.

Confirms that the mermaid flag is not added when there's no mermaid code block in the content.


99-113: Complete test for date updating from 'updated' field.

Properly tests that the date field is updated from the updated field when the option is enabled.


115-127: Thorough test for date preservation when updating disabled.

Confirms that the updated field remains unchanged when the date updating option is disabled.


129-142: Excellent coverage for Date object formatting.

Tests that Date objects are correctly formatted as YYYY-MM-DD strings.


144-156: Good test for handling non-string and non-Date values.

Verifies that non-string and non-Date values are converted to strings correctly.


159-172: Effective test for single author formatting.

Confirms that a single author is correctly formatted without array brackets.


174-186: Complete test for multiple authors formatting.

Verifies that multiple authors are correctly formatted with array brackets.


189-199: Good error handling test for invalid front matter.

Verifies that invalid front matter returns a Left result with a PARSE_ERROR type.


201-216: Thorough error handling test for malformed YAML indentation.

Confirms that YAML with incorrect indentation returns a Left result with an appropriate error message.


218-228: Comprehensive test for malformed YAML with duplicate keys.

Verifies that YAML with duplicate keys returns a Left result with a PARSE_ERROR type.


230-239: Good test for malformed YAML with invalid structure.

Confirms that YAML with an invalid structure returns a Left result with a PARSE_ERROR type.


241-250: Effective test for front matter without end marker.

Tests that content with a front matter start but no end marker is handled gracefully.


253-264: Thorough test for single tag as string.

Verifies that a single tag is correctly formatted as an array.


266-276: Good test for multiple tags as array.

Confirms that multiple tags specified as an array are correctly preserved.


278-288: Effective test for comma-separated tags string.

Tests that comma-separated tags are correctly converted to an array format.


290-299: Complete test for missing tags field.

Verifies that missing tags fields are handled correctly.


301-311: Good test for empty tags.

Confirms that empty tags are correctly handled as null.


314-322: Comprehensive test for missing front matter.

Tests that content without front matter is returned unchanged.


324-333: Thorough test for empty front matter.

Verifies that content with empty front matter is processed correctly.


335-348: Effective test for front matter with only dividers.

Tests that content with multiple dividers is handled correctly.

src/FrontMatterConverter.ts (12)

1-12: Good imports for functional programming support.

The imports now include the necessary functional programming utilities and types to support the refactored implementation.


26-29: Effective utility for formatting author lists.

The formatAuthorList function correctly handles both single authors and multiple authors by splitting and joining as needed.


31-60: Excellent implementation of Either pattern for error handling.

The extractFrontMatter function now returns an Either type, properly handling error cases without throwing exceptions and providing clear error messages.


62-70: Good implementation of title formatting.

The formatTitle function ensures that titles are properly quoted, handling edge cases where titles are already quoted.


72-82: Proper formatting for categories.

The formatCategories function ensures consistent formatting for category lists, handling both array and string formats.


84-94: Clean implementation of author formatting.

The formatAuthors function correctly handles different author formats, delegating to formatAuthorList for consistent results.


96-106: Comprehensive implementation of tag formatting.

The formatTags function handles various tag formats, ensuring consistent array formatting.


108-113: Effective mermaid detection and flag setting.

The handleMermaid function correctly identifies mermaid code blocks and sets the appropriate flag.


115-132: Good image path handling with functional approach.

The convertImagePath and handleImageFrontMatter functions use a functional programming style for image path processing, with proper conditional logic based on options.


134-141: Clean implementation of date front matter handling.

The handleDateFrontMatter function correctly updates the date field from the updated field when enabled, using object destructuring for clean code.


143-155: Proper serialization of front matter.

The serializeFrontMatter function correctly converts the processed front matter back to a YAML string, handling edge cases like empty front matter.


158-203: Excellent functional implementation of the main conversion function.

The convertFrontMatter function uses a functional approach with the pipe utility to apply a series of transformations to the input. The code is clean, modular, and follows functional programming principles.

it('should pipe a single value through multiple functions', () => {
const add2 = (x: number) => x + 2;
const multiply3 = (x: number) => x * 3;
const toString = (x: number) => x.toString();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Rename the toString function to avoid shadowing the global property.

The variable name toString shadows the global toString property, which can lead to confusion and potential bugs.

-  const toString = (x: number) => x.toString();
+  const numberToString = (x: number) => x.toString();

And update its usage:

-  const result = pipe(5, add2, multiply3, toString);
+  const result = pipe(5, add2, multiply3, numberToString);
📝 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 toString = (x: number) => x.toString();
// Original code context in src/tests/fp.test.ts
// Change the function declaration to avoid shadowing the global property
- const toString = (x: number) => x.toString();
+ const numberToString = (x: number) => x.toString();
// Other code lines...
// Update the usage of the renamed function in the pipe function
- const result = pipe(5, add2, multiply3, toString);
+ const result = pipe(5, add2, multiply3, numberToString);
🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

Comment on lines +14 to +24
// Helper functions
const isNullOrEmpty = (str: string | undefined | null): boolean =>
!str || (typeof str === 'string' && str.trim().length === 0);

const formatDate = (date: unknown): string => {
if (typeof date === 'string') return date;
if (date instanceof Date) {
return date.toISOString().split('T')[0];
}
return String(date);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Good helper functions for string and date handling.

The isNullOrEmpty and formatDate functions provide reusable utilities for common operations. However, one line isn't covered by tests.


🏁 Script executed:

#!/bin/bash
# Check test coverage for the formatDate function
grep -r "formatDate" src/tests

Length of output: 30


Action: Add or update tests for full coverage of the helper functions.

The helper functions in src/FrontMatterConverter.ts (specifically, isNullOrEmpty and formatDate) look well implemented. However, automated verification using grep -r "formatDate" src/tests found no references at all in the tests folder. This suggests that not only might one line be uncovered—as originally noted—but the entire formatDate function isn’t being exercised by your test suite.

  • Please verify if tests for formatDate are missing or if they’re located somewhere else.
  • If they are missing, add tests to cover all branches of the function ([e.g., when date is a string, a Date instance, or any other type]).
  • Otherwise, confirm that the current test coverage is intentional.
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 21-21: src/FrontMatterConverter.ts#L21
Added line #L21 was not covered by tests

@songkg7 songkg7 merged commit 92a1434 into main Mar 30, 2025
21 of 25 checks passed
@songkg7 songkg7 deleted the refactor branch March 30, 2025 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant