Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

validator: string #650

Merged
merged 15 commits into from
Oct 9, 2024
Merged

validator: string #650

merged 15 commits into from
Oct 9, 2024

Conversation

bangarang
Copy link
Collaborator

Please explain how to summarize this PR for the Changelog:

Tell code reviewer how and what to test:

@flatfile-nullify
Copy link

flatfile-nullify bot commented Sep 27, 2024

Nullify Code Vulnerabilities

1 findings found in this pull request

🔴 CRITICAL 🟡 HIGH 🔵 MEDIUM ⚪ LOW
0 0 1 0

You can find a list of all findings here

@bangarang bangarang marked this pull request as ready for review October 1, 2024 07:48
Copy link
Contributor

coderabbitai bot commented Oct 1, 2024

Walkthrough

The changes introduce the @flatfile/plugin-validate-string, enhancing string validation capabilities within the Flatfile ecosystem. Key features include regex pattern matching, length validation, case sensitivity enforcement, and custom transformation functions. The plugin processes records during Flatfile imports, applying specified validations and transformations. A new Jest configuration file has been added for testing, along with a Rollup configuration file. Comprehensive unit tests for the validateAndTransformString function have been included, and the configuration and validation rules are defined through a new interface, improving the modularity and usability of the plugin.

Changes

Files Change Summary
validate/string/README.MD Updated README to outline the plugin's functionality, installation instructions, and example usage.
validate/string/jest.config.js Introduced Jest configuration for testing with Node.js environment and TypeScript support.
validate/string/rollup.config.mjs Introduced Rollup configuration setup for the project.
validate/string/src/index.ts Re-exported entities from validate.string.plugin and validate.string.utils.
validate/string/src/validate.string.plugin.ts Introduced string validation plugin with StringValidationConfig, validateAndTransformString, and validateString functions.
validate/string/src/validate.string.plugin.spec.ts Added unit tests for validateAndTransformString, covering various validation scenarios.
validate/string/src/validate.string.utils.ts Added utilities for string validation, including StringValidationConfig interface and validateAndTransformString function.
validate/phone/jest.config.js Added Jest configuration for the phone validation module.
validate/phone/src/validate.phone.utils.spec.ts Modified test cases for formatPhoneNumber, replacing NumberFormat enumeration with string literals.

Possibly related PRs

Suggested reviewers

  • carlbrugger

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link
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: 8

🧹 Outside diff range and nitpick comments (7)
validate/string/rollup.config.mjs (2)

3-3: Configuration creation looks good, consider customization if needed.

The configuration is correctly created using the buildConfig function. Currently, an empty object is passed, which likely uses default settings.

If there are any specific build requirements for this plugin, consider adding custom configuration options to the object passed to buildConfig.


1-5: Overall, the Rollup configuration file is well-structured and serves its purpose.

This file sets up the Rollup configuration for the string validation plugin using Flatfile's custom configuration builder. It's concise, follows best practices, and allows for easy customization if needed in the future.

As the project grows, you may want to consider adding specific configuration options to tailor the build process for this particular plugin. This could include setting up external dependencies, defining output formats, or configuring plugins specific to string validation functionality.

validate/string/README.MD (1)

69-69: Use en dash for numeric ranges

In "Validates phone numbers (10-14 digits, optional '+' prefix)", consider replacing the hyphen with an en dash for proper typographical convention.

Apply this diff to correct the hyphen:

-   - `phone`: Validates phone numbers (10-14 digits, optional '+' prefix)
+   - `phone`: Validates phone numbers (10–14 digits, optional '+' prefix)
🧰 Tools
🪛 LanguageTool

[typographical] ~69-~69: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

validate/string/src/ValidateString.e2e.spec.ts (3)

161-161: Ensure consistent error message structure

The expectation is that messages array has a length of 2, corresponding to minLength and customValidation errors. However, if the validation rules change, this test might become brittle.

Consider checking the contents of the error messages instead of relying on the array length.

- expect(records[1].values['name'].messages?.length).toBe(2)
+ expect(records[1].values['name'].messages).toEqual(
+   expect.arrayContaining([
+     expect.objectContaining({ message: expect.stringContaining('at least 3 characters') }),
+     expect.objectContaining({ message: expect.stringContaining('both first and last name') }),
+   ])
+ )

107-108: Validate regex patterns separately

The inline regular expression in customTransform may not be immediately clear to readers.

Consider defining the regex separately with a descriptive name to improve readability.

+ const codePattern = /^[A-Z]{3}-\d{3}$/;
  
  customTransform: (value) => {
-   if (!/^[A-Z]{3}-\d{3}$/.test(value)) {
+   if (!codePattern.test(value)) {
      return 'Code must be in the format XXX-000'
    }
    return value
  },

49-49: Use consistent array formatting

For better readability, align array elements vertically.

  fields: [
-   'name'],
+   'name',
+ ],
validate/string/src/index.ts (1)

45-62: Provide specific error messages for different length validations

Currently, the same error message config.errorMessages?.length is used for minLength, maxLength, and exactLength validations. This could be confusing if multiple length constraints are present. Consider allowing specific error messages for each length validation type to provide clearer feedback to users.

You might adjust the errorMessages object in the configuration:

errorMessages?: {
-  length?: string
+  minLength?: string
+  maxLength?: string
+  exactLength?: string
  pattern?: string
  case?: string
  trim?: string
}

And update the validation checks accordingly:

if (config.minLength && value.length < config.minLength) {
  return (
-   config.errorMessages?.length || `Minimum length is ${config.minLength}`
+   config.errorMessages?.minLength || `Minimum length is ${config.minLength}`
  )
}

if (config.maxLength && value.length > config.maxLength) {
  return (
-   config.errorMessages?.length || `Maximum length is ${config.maxLength}`
+   config.errorMessages?.maxLength || `Maximum length is ${config.maxLength}`
  )
}

if (config.exactLength && value.length !== config.exactLength) {
  return (
-   config.errorMessages?.length || `Exact length must be ${config.exactLength}`
+   config.errorMessages?.exactLength || `Exact length must be ${config.exactLength}`
  )
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8c6ca84 and d980290.

⛔ Files ignored due to path filters (2)
  • validate/string/metadata.json is excluded by !**/*.json
  • validate/string/package.json is excluded by !**/*.json
📒 Files selected for processing (4)
  • validate/string/README.MD (1 hunks)
  • validate/string/rollup.config.mjs (1 hunks)
  • validate/string/src/ValidateString.e2e.spec.ts (1 hunks)
  • validate/string/src/index.ts (1 hunks)
🧰 Additional context used
🪛 LanguageTool
validate/string/README.MD

[typographical] ~69-~69: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

🔇 Additional comments (5)
validate/string/rollup.config.mjs (2)

1-1: LGTM: Import statement is correct.

The import statement is properly formatted and imports the necessary buildConfig function from the '@flatfile/rollup-config' package.


5-5: LGTM: Default export is correct.

The configuration object is properly exported as the default export, which is the standard practice for Rollup configuration files.

validate/string/src/ValidateString.e2e.spec.ts (2)

141-141: Handle names with extra spaces appropriately

The custom validation checks if the name splits into at least two parts. Names with extra spaces (e.g., 'John Doe') could unintentionally pass or fail this check.

Ensure that names with multiple spaces are handled correctly.

  customTransform: (value) => {
+   const nameParts = value.trim().split(/\s+/);
    if (nameParts.length < 2) {
      return 'Name must include both first and last name'
    }
    return value
  },

36-36: Reset listener before each test

It's good practice to reset the listener before each test to ensure no residual effects from previous tests.

validate/string/src/index.ts (1)

40-43: Validate the existence of the regex pattern

When assigning the pattern, if an invalid string key is provided that does not exist in commonRegexPatterns, pattern will be undefined, which could lead to unexpected behavior. Consider adding a check to ensure that the pattern is valid.

Run the following script to check for invalid pattern keys:

validate/string/README.MD Show resolved Hide resolved
validate/string/src/ValidateString.e2e.spec.ts Outdated Show resolved Hide resolved
validate/string/src/ValidateString.e2e.spec.ts Outdated Show resolved Hide resolved
validate/string/src/ValidateString.e2e.spec.ts Outdated Show resolved Hide resolved
validate/string/src/ValidateString.e2e.spec.ts Outdated Show resolved Hide resolved
validate/string/src/ValidateString.e2e.spec.ts Outdated Show resolved Hide resolved
validate/string/src/index.ts Outdated Show resolved Hide resolved
validate/string/src/index.ts Outdated Show resolved Hide resolved
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

🧹 Outside diff range and nitpick comments (4)
validate/string/README.MD (4)

20-26: Consider adding compatibility information

The Installation section provides clear instructions for installing the plugin. To enhance user experience, consider adding a note about compatibility or prerequisites. For example:

## Installation

To install the plugin, use npm:

```bash
npm install @flatfile/plugin-validate-string

Note: This plugin requires @flatfile/listener version X.X.X or higher.


This addition would help users ensure they have the necessary environment set up before installation.

---

`28-63`: **Enhance the general usage example**

The Example Usage section provides good demonstrations of how to use the plugin. To make it even more helpful, consider expanding the general usage example to show how all the properties in the `stringConfig` object are used. For instance:

```typescript
const stringConfig = {
  fields: ['name'],
  sheetSlug: 'users',
  minLength: 2,
  maxLength: 50,
  caseType: 'titlecase',
  trim: { leading: true, trailing: true },
  emptyStringAllowed: false,
  errorMessages: {
    length: 'Name must be between 2 and 50 characters',
    case: 'Name must be in Title Case',
    empty: 'Name cannot be empty',
  },
};

listener.use(validateString(stringConfig));

This expanded example would give users a more comprehensive understanding of how to configure the plugin.


83-87: Enhance the Behavior section with more details

The Behavior section provides a good overview of how the plugin processes records. To make it more informative, consider adding more details about the validation process and error handling. For example:

## Behavior

The plugin processes each record in the Flatfile import, applying the configured validations to the specified fields. The validation process follows these steps:

1. If `trim` is specified, leading and/or trailing whitespace is removed.
2. If `pattern` is provided, the field value is checked against the regex pattern.
3. Length validations (`minLength`, `maxLength`, `exactLength`) are applied if specified.
4. If `caseType` is set, the string case is validated.
5. If `emptyStringAllowed` is false, empty strings are rejected.

If any validation fails, an error is added to the record for that field, using the custom error messages if provided. If all validations pass and a custom transformation is specified, the transformed value is set for the field.

The plugin uses the `recordHook` to process individual records, allowing for efficient and flexible validation and transformation of string fields during the import process.

This expanded explanation would give users a clearer understanding of the validation process and how errors are handled.


73-73: Minor: Consider using an en dash for number ranges

In the description of the phone pattern, you've used a hyphen to denote the range of digits (10-14). While this is commonly accepted, some style guides recommend using an en dash for number ranges. If you want to adhere to this convention, you could change it to:

- - `phone`: Validates phone numbers (10-14 digits, optional '+' prefix)
+ - `phone`: Validates phone numbers (10–14 digits, optional '+' prefix)

This is a very minor typographical suggestion and doesn't significantly impact the readability of the documentation. Feel free to implement this change at your discretion.

🧰 Tools
🪛 LanguageTool

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3a04a8c and 0bdc4d4.

📒 Files selected for processing (1)
  • validate/string/README.MD (1 hunks)
🧰 Additional context used
🪛 LanguageTool
validate/string/README.MD

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

🔇 Additional comments (3)
validate/string/README.MD (3)

9-18: LGTM: Comprehensive feature list

The Features section provides a clear and concise overview of the plugin's capabilities. It covers all the main functionalities, which is excellent for users to quickly understand what the plugin offers.


70-71: Consolidate duplicate 'pattern' property definitions

There are still two entries for the pattern property with different descriptions. To avoid confusion, please merge them into a single, comprehensive entry. Apply this diff to consolidate the pattern property definitions:

- - `pattern`: RegExp - A regular expression pattern to match against
- - `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:
+ - `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:

This change will provide a clear and complete description of the pattern property in a single entry.


1-87: Overall, well-structured and informative README

This README file provides a comprehensive overview of the @flatfile/plugin-validate-string plugin. It covers installation, usage, configuration, and behavior effectively. The suggested improvements are minor and aimed at enhancing clarity and completeness:

  1. Adding compatibility information to the Installation section.
  2. Expanding the general usage example in the Example Usage section.
  3. Consolidating the duplicate 'pattern' property definitions in the Configuration section.
  4. Enhancing the Behavior section with more detailed explanations.
  5. Optionally updating the number range notation in the phone pattern description.

Implementing these suggestions will further improve an already solid documentation. Great job on creating a clear and informative README for the plugin!

🧰 Tools
🪛 LanguageTool

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

@bangarang bangarang force-pushed the feat/StringValidator branch from 0bdc4d4 to a8353d4 Compare October 4, 2024 22:07
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

🧹 Outside diff range and nitpick comments (4)
validate/string/README.MD (3)

20-26: LGTM: Clear installation instructions

The installation section provides clear and concise instructions using npm. It's straightforward and easy to follow.

Consider adding instructions for other package managers like yarn or pnpm to cater to a wider audience:

 ## Installation

 To install the plugin, use npm:

 ```bash
 npm install @flatfile/plugin-validate-string

+Or if you're using yarn:
+
+bash +yarn add @flatfile/plugin-validate-string +
+
+Or if you're using pnpm:
+
+bash +pnpm add @flatfile/plugin-validate-string +


---

`28-63`: **LGTM: Clear and illustrative examples**

The example usage section provides clear and helpful examples for both general usage and pattern-specific usage. This is excellent for users to understand how to implement the plugin in different scenarios.



Consider adding a brief comment explaining the `titlecase` option in the first example, as it might not be immediately clear to all users:

```diff
 const stringConfig = {
   fields: ['name'],
   minLength: 2,
   maxLength: 50,
-  caseType: 'titlecase',
+  caseType: 'titlecase', // Ensures each word starts with a capital letter
   errorMessages: {
     length: 'Name must be between 2 and 50 characters',
     case: 'Name must be in Title Case',
   },
 };

73-73: Minor typographical improvement

Consider using an en dash instead of a hyphen when specifying the range of digits for phone number validation.

Apply this change:

-- `phone`: Validates phone numbers (10-14 digits, optional '+' prefix)
+- `phone`: Validates phone numbers (10–14 digits, optional '+' prefix)
🧰 Tools
🪛 LanguageTool

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

validate/string/src/index.ts (1)

25-29: Consider enhancing email and URL regex patterns

While the current regex patterns are suitable for basic validation, they might not cover all edge cases. Consider using more comprehensive patterns, especially for email and URL validation. For example:

  1. Email: The current pattern doesn't account for some valid email formats (e.g., local parts with quotes or special characters).
  2. URL: The current pattern might allow some invalid URLs and doesn't account for all TLDs.

You might want to use well-tested libraries or more robust regex patterns for these validations.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0bdc4d4 and a8353d4.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • validate/string/metadata.json is excluded by !**/*.json
  • validate/string/package.json is excluded by !**/*.json
📒 Files selected for processing (4)
  • validate/string/README.MD (1 hunks)
  • validate/string/rollup.config.mjs (1 hunks)
  • validate/string/src/ValidateString.e2e.spec.ts (1 hunks)
  • validate/string/src/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • validate/string/rollup.config.mjs
  • validate/string/src/ValidateString.e2e.spec.ts
🧰 Additional context used
🪛 LanguageTool
validate/string/README.MD

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

🔇 Additional comments (10)
validate/string/README.MD (4)

1-8: LGTM: Info card provides a clear overview

The info card effectively summarizes the plugin's functionality and specifies the event type. It's concise and informative, which is excellent for quick understanding.


9-18: LGTM: Comprehensive features list

The features section provides a well-organized and comprehensive list of the plugin's capabilities. It covers all major aspects of string validation, which is excellent for users to quickly grasp the plugin's functionality.


84-87: LGTM: Clear explanation of plugin behavior

The behavior section provides a concise and clear explanation of how the plugin processes records and applies validations. This is very helpful for users to understand the plugin's operation.


70-71: ⚠️ Potential issue

Consolidate duplicate 'pattern' property definitions

The pattern property is listed twice with different type definitions and descriptions. This duplication may cause confusion for users.

Please merge these entries into a single, comprehensive definition:

-- `pattern`: RegExp - A regular expression pattern to match against
-- `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:
+- `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:
validate/string/src/index.ts (6)

1-23: LGTM: Well-structured imports and interface definition

The imports and the StringValidationConfig interface are well-defined. The interface provides a comprehensive set of options for string validation, including pattern matching, length constraints, case formatting, and custom error messages. The optional sheetSlug parameter adds flexibility for specifying the context of validation.


31-104: LGTM: Well-implemented StringValidation function

The StringValidation function is well-structured and implements all the validation options defined in the StringValidationConfig interface. It provides comprehensive checks for empty strings, pattern matching, length constraints, case formatting, and whitespace trimming. The error messages are customizable and provide clear feedback on validation failures.


107-126: LGTM: Well-implemented validateString function

The validateString function effectively integrates the StringValidation logic with the Flatfile ecosystem. It correctly uses the recordHook to process each record, applies validation to the specified fields, and handles null and undefined values appropriately. The function also respects the optional sheetSlug parameter, providing flexibility in specifying the context for validation.


128-128: LGTM: Appropriate default export

The validateString function is correctly exported as the default export, following standard practices. This allows for easy importing and usage of the main functionality in other parts of the codebase.


1-128: Summary: Well-implemented string validation module with minor improvements needed

This new file introduces a comprehensive string validation module that integrates well with the Flatfile ecosystem. The implementation is generally well-structured and provides robust functionality. Here are the key points from the review:

  1. The StringValidationConfig interface and overall structure are well-designed.
  2. Consider enhancing the regex patterns for email and URL validation to cover more edge cases.
  3. Address the case formatting issues in the StringValidation function, including replacing the deprecated substr method and handling invalid caseType values.
  4. The validateString function effectively integrates the validation logic with Flatfile's record processing.

Once these minor improvements are addressed, this module will provide a solid foundation for string validation within the Flatfile plugins ecosystem.


63-85: ⚠️ Potential issue

Address case formatting issue

As noted in a previous review comment, there are two potential issues in the case formatting section:

  1. The substr method used in the titlecase transformation is deprecated. Replace it with substring as suggested earlier.

  2. There's no default case in the switch statement, which could lead to runtime errors if an invalid caseType is provided.

Apply this diff to address both issues:

switch (config.caseType) {
  case 'lowercase':
    transformedValue = value.toLowerCase()
    break
  case 'uppercase':
    transformedValue = value.toUpperCase()
    break
  case 'titlecase':
    transformedValue = value.replace(
      /\w\S*/g,
-     (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
+     (txt) => txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase()
    )
    break
+ default:
+   return `Invalid caseType: ${config.caseType}`
}

@bangarang bangarang force-pushed the feat/StringValidator branch from a8353d4 to c10221c Compare October 8, 2024 21:12
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: 9

🧹 Outside diff range and nitpick comments (5)
validate/string/README.MD (3)

20-26: Consider adding alternative installation methods

The installation instructions are clear for npm users. To improve accessibility, consider adding instructions for other popular package managers like yarn or pnpm.

For example, you could add:

Or with yarn:

```bash
yarn add @flatfile/plugin-validate-string

Or with pnpm:

pnpm add @flatfile/plugin-validate-string

---

`28-63`: **Clarify the difference between predefined and custom patterns in examples**

The example usage section is informative and demonstrates key features of the plugin. To enhance clarity, consider explicitly labeling the examples as "Predefined Pattern" and "Custom Pattern" in the pattern usage section.

You could update the code comments as follows:

```typescript
// Predefined pattern example:
const config = {
  fields: ['email'],
  pattern: 'email' // Uses predefined email pattern
};

// Custom pattern example:
const customConfig = {
  fields: ['customField'],
  pattern: /^[A-Z]{3}-\d{2}$/ // Custom pattern for format like 'ABC-12'
};

73-73: Consider using an en dash for number ranges

For improved typography, consider using an en dash instead of a hyphen when specifying the range of digits for phone numbers.

Update the line as follows:

- - `phone`: Validates phone numbers (10-14 digits, optional '+' prefix)
+ - `phone`: Validates phone numbers (10–14 digits, optional '+' prefix)
🧰 Tools
🪛 LanguageTool

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

validate/string/src/validate.string.plugin.spec.ts (2)

25-35: LGTM: Email pattern validation test is well-structured.

This test case correctly verifies email pattern validation for both valid and invalid inputs. The configuration and assertions are appropriate.

Consider using a more specific error message for invalid email format, such as "Invalid email format" instead of "Invalid format". This would provide clearer feedback to users.


37-47: LGTM: Custom pattern validation test is well-structured.

This test case correctly verifies custom regex pattern validation for both valid and invalid inputs. The configuration and assertions are appropriate.

Consider using a more specific error message for invalid custom pattern, such as "Input must be exactly 3 uppercase letters" instead of "Invalid format". This would provide clearer feedback to users about the expected format.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a8353d4 and c0051c4.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • validate/string/metadata.json is excluded by !**/*.json
  • validate/string/package.json is excluded by !**/*.json
📒 Files selected for processing (5)
  • validate/string/README.MD (1 hunks)
  • validate/string/rollup.config.mjs (1 hunks)
  • validate/string/src/index.ts (1 hunks)
  • validate/string/src/validate.string.plugin.spec.ts (1 hunks)
  • validate/string/src/validate.string.plugin.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • validate/string/rollup.config.mjs
  • validate/string/src/index.ts
🧰 Additional context used
🪛 LanguageTool
validate/string/README.MD

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

🔇 Additional comments (11)
validate/string/README.MD (4)

1-8: LGTM: Info card is clear and informative

The info card provides a concise and accurate summary of the plugin's capabilities and specifies the correct event type for the listener.


9-18: LGTM: Features section is comprehensive

The features section provides a clear and comprehensive list of the plugin's functionalities, covering all key aspects mentioned in the info card and providing additional details.


70-71: Consolidate duplicate 'pattern' property definitions

As mentioned in a previous review, the pattern property is listed twice with different type definitions and descriptions. To avoid confusion, please merge them into a single entry.

Apply this diff to consolidate the pattern property definitions:

- - `pattern`: RegExp - A regular expression pattern to match against
- - `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:
+ - `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:

83-87: LGTM: Behavior section is clear and informative

The behavior section provides a concise and clear explanation of how the plugin processes records during the Flatfile import. It effectively communicates the plugin's operation to users.

validate/string/src/validate.string.plugin.spec.ts (7)

1-4: LGTM: Import statements are correct.

The necessary function and interface are imported from the correct module.


7-14: LGTM: Test case for empty string validation is well-structured.

This test case correctly verifies that an empty string is not allowed when emptyStringAllowed is set to false. The configuration and assertion are appropriate.


16-23: LGTM: Test case for allowing empty string is correct.

This test case properly verifies that an empty string is allowed when emptyStringAllowed is set to true. The configuration and assertion are appropriate.


49-59: LGTM: Minimum length validation test is well-structured.

This test case correctly verifies minimum length validation for both valid and invalid inputs. The configuration, assertions, and error message are all appropriate and clear.


61-71: LGTM: Maximum length validation test is well-structured.

This test case correctly verifies maximum length validation for both valid and invalid inputs. The configuration, assertions, and error message are all appropriate and clear.


73-83: LGTM: Exact length validation test is well-structured.

This test case correctly verifies exact length validation for both valid and invalid inputs. The configuration, assertions, and error message are all appropriate and clear.


135-145: LGTM: Custom error message test is well-structured.

This test case correctly verifies the use of custom error messages for pattern validation. The configuration and assertion are appropriate, demonstrating that the function respects user-defined error messages.

validate/string/src/validate.string.plugin.spec.ts Outdated Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
@bangarang bangarang force-pushed the feat/StringValidator branch from b147e59 to 5e0a5a3 Compare October 8, 2024 21:44
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

🧹 Outside diff range and nitpick comments (11)
validate/phone/jest.config.js (6)

7-7: LGTM: Good environment setup, consider using an absolute path.

The setupFiles configuration correctly includes a script to load environment variables, which is a good practice for test isolation and configuration.

Consider using an absolute path (e.g., path.resolve(__dirname, '../../test/dotenv-config.js')) to avoid potential issues with the working directory during test execution.


8-11: LGTM: Good test setup, consider using absolute paths.

The setupFilesAfterEnv configuration correctly includes scripts for enhanced console logging and test cleanup. This promotes better test output and ensures a clean state between tests.

Consider using absolute paths (e.g., path.resolve(__dirname, '../../test/betterConsoleLog.js')) to avoid potential issues with the working directory during test execution.


12-12: LGTM: Clear timeout setting, consider adjusting based on test types.

The testTimeout is clearly set to 60 seconds using a numeric separator for improved readability. This is a good practice.

Consider if 60 seconds is appropriate for your test suite. For unit tests, this might be too long and could hide performance issues. For integration or end-to-end tests, this might be suitable. You might want to use a shorter timeout for unit tests and longer timeouts only for specific, slower tests.


13-13: LGTM: Good global setup, consider using an absolute path.

The globalSetup configuration correctly specifies a script for one-time setup before all tests, which is a good practice for test suite initialization.

Consider using an absolute path (e.g., path.resolve(__dirname, '../../test/setup-global.js')) to avoid potential issues with the working directory during test execution.


14-14: Consider removing forceExit if possible.

Setting forceExit to true forces Jest to exit after all tests complete. While this can be useful for dealing with hanging handles, it might mask issues with improper test cleanup or unhandled asynchronous operations.

If possible, consider removing this option and ensuring all tests and operations clean up properly. This will help identify and fix any lingering issues in your test suite. If it's necessary due to third-party libraries or specific testing scenarios, document the reason for its inclusion.


15-15: Consider the implications of passWithNoTests.

Setting passWithNoTests to true allows the test suite to pass even when no tests are found. This can be useful during initial project setup or active test development.

Be cautious with this setting in a production environment. It might hide issues where tests are accidentally skipped or not detected. Consider removing this option once your test suite is stable, or use it selectively in specific contexts where it's necessary.

validate/string/jest.config.js (2)

7-11: LGTM: Well-structured test setup. Consider adding comments for clarity.

The setupFiles and setupFilesAfterEnv configurations are well-structured, including necessary environment setup and custom test utilities. This approach ensures a consistent and clean test environment.

Consider adding brief comments explaining the purpose of each setup file for improved maintainability:

setupFiles: [
  '../../test/dotenv-config.js', // Load environment variables for tests
],
setupFilesAfterEnv: [
  '../../test/betterConsoleLog.js', // Enhance console logging for tests
  '../../test/unit.cleanup.js', // Perform cleanup after each test
],

13-13: LGTM: Global setup script is in place. Consider adding a brief comment.

The globalSetup configuration correctly points to a setup script that likely performs necessary initialization before all tests run.

Consider adding a brief comment explaining the purpose of the global setup:

globalSetup: '../../test/setup-global.js', // Initialize global test environment
validate/string/README.MD (2)

20-26: Consider adding alternative installation methods

The installation instructions using npm are clear and correct. To improve user experience, consider adding instructions for other popular package managers like yarn and pnpm.

Here's a suggestion to expand the installation section:

## Installation

You can install the plugin using npm, yarn, or pnpm:

```bash
# Using npm
npm install @flatfile/plugin-validate-string

# Using yarn
yarn add @flatfile/plugin-validate-string

# Using pnpm
pnpm add @flatfile/plugin-validate-string

---

`73-73`: **Consider using an en dash for number ranges**

For improved typography, consider using an en dash instead of a hyphen when specifying number ranges.

Here's the suggested change:

```diff
- - `phone`: Validates phone numbers (10-14 digits, optional '+' prefix)
+ - `phone`: Validates phone numbers (10–14 digits, optional '+' prefix)
🧰 Tools
🪛 LanguageTool

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

validate/string/src/validate.string.plugin.ts (1)

1-23: LGTM! Consider adding JSDoc comments for better documentation.

The imports and StringValidationConfig interface are well-structured and provide a comprehensive set of options for string validation. The use of optional properties allows for flexible configuration.

Consider adding JSDoc comments to the StringValidationConfig interface and its properties for better documentation and improved IDE support. For example:

/**
 * Configuration options for string validation.
 */
export interface StringValidationConfig {
  /** Fields to validate */
  fields: string[]
  /** Optional sheet slug */
  sheetSlug?: string
  // ... (add comments for other properties)
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c0051c4 and 2d94a9f.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • validate/phone/package.json is excluded by !**/*.json
  • validate/string/package.json is excluded by !**/*.json
📒 Files selected for processing (7)
  • validate/phone/jest.config.js (1 hunks)
  • validate/string/README.MD (1 hunks)
  • validate/string/jest.config.js (1 hunks)
  • validate/string/rollup.config.mjs (1 hunks)
  • validate/string/src/index.ts (1 hunks)
  • validate/string/src/validate.string.plugin.spec.ts (1 hunks)
  • validate/string/src/validate.string.plugin.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • validate/string/rollup.config.mjs
  • validate/string/src/index.ts
  • validate/string/src/validate.string.plugin.spec.ts
🧰 Additional context used
🪛 LanguageTool
validate/string/README.MD

[typographical] ~73-~73: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s - phone: Validates phone numbers (10-14 digits, optional '+' prefix) - url:...

(HYPHEN_TO_EN)

🔇 Additional comments (16)
validate/phone/jest.config.js (3)

2-2: LGTM: Appropriate test environment setting.

Setting testEnvironment to 'node' is correct for a Node.js-based project. This ensures that tests run in a Node.js environment, which is suitable for backend or non-browser JavaScript code.


4-6: LGTM: Correct TypeScript transformation setup.

The transform configuration is correctly set up to use 'ts-jest' for TypeScript files. This allows Jest to properly handle .ts and .tsx files in your test suite.


1-16: Overall, a well-structured Jest configuration with room for minor improvements.

This Jest configuration file is comprehensive and well-suited for a TypeScript project. It includes essential settings for environment setup, TypeScript handling, and test execution. However, consider the following improvements:

  1. Use absolute paths for file references to avoid working directory issues.
  2. Evaluate the necessity of forceExit and passWithNoTests in your specific testing context.
  3. Ensure the testTimeout is appropriate for your test suite.

These adjustments will enhance the robustness and maintainability of your test setup.

validate/string/jest.config.js (5)

2-2: LGTM: Appropriate test environment setting.

The testEnvironment is correctly set to 'node', which is suitable for a Node.js-based project like this Flatfile plugin.


4-6: LGTM: Correct TypeScript transformation setup.

The transform configuration correctly uses 'ts-jest' for TypeScript files, which is the standard approach for testing TypeScript projects with Jest.


15-15: ⚠️ Potential issue

Consider the implications of passWithNoTests and ensure proper test coverage.

Setting passWithNoTests to true allows Jest to pass when no tests are found. While this can be useful during development or in certain CI/CD scenarios, it might hide the issue of missing tests in some cases.

Consider the following:

  1. Evaluate if this setting is necessary for your workflow. If it's needed only in specific scenarios, consider setting it via command-line arguments instead of in the config file.
  2. Ensure that you have proper test coverage checks in place to prevent scenarios where critical code is left untested.
  3. If you decide to keep this setting, add a comment explaining the rationale:
passWithNoTests: true, // Allows CI to pass when [specific scenario]

To ensure proper test coverage, you can run Jest with coverage reporting:

#!/bin/bash
# Description: Check test coverage to ensure critical code is tested

# Navigate to the plugin directory
cd validate/string

# Run Jest with coverage reporting
npx jest --coverage

Review the coverage report to ensure that all critical parts of your code are adequately tested.


14-14: ⚠️ Potential issue

Reconsider the use of forceExit and investigate potential asynchronous issues.

Setting forceExit to true forces Jest to exit after all tests complete, even if there are ongoing asynchronous operations. While this ensures Jest always exits, it might mask issues with lingering asynchronous operations or incomplete resource cleanup.

Consider the following:

  1. Remove the forceExit option and investigate if there are any hanging asynchronous operations in your tests.
  2. Ensure all asynchronous operations are properly handled and resources are cleaned up in your test suites.
  3. If forceExit is absolutely necessary, add a comment explaining why:
forceExit: true, // Required due to [specific reason]

To identify potential asynchronous issues, run Jest with the --detectOpenHandles flag:

This will help identify any lingering asynchronous operations or open handles that might be causing Jest to hang.


12-12: Consider reviewing the need for a 60-second test timeout.

The testTimeout is set to 60 seconds, which is significantly longer than Jest's default of 5 seconds. While this may be necessary for complex operations, it could also hide potential performance issues in your tests.

To investigate if this timeout is necessary, you can run the following command to identify slow tests:

Consider optimizing slow tests or splitting them into smaller, faster units if possible. If the long timeout is indeed necessary, add a comment explaining why to improve maintainability.

validate/string/README.MD (4)

1-8: LGTM: Info card provides a clear overview

The info card effectively summarizes the plugin's capabilities and specifies the correct event type. It's concise and informative, which is ideal for a README.


9-18: LGTM: Comprehensive feature list

The features section provides a clear and comprehensive list of the plugin's capabilities. It covers all the main functionalities, making it easy for users to understand what the plugin offers.


70-71: Consolidate duplicate 'pattern' property definitions

As mentioned in a previous review, the pattern property is listed twice with different type definitions and descriptions. This should be consolidated to avoid confusion.

Apply this diff to consolidate the pattern property definitions:

- - `pattern`: RegExp - A regular expression pattern to match against
- - `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:
+ - `pattern`: keyof typeof commonRegexPatterns | RegExp - A regular expression pattern to match against. You can use one of the predefined patterns ('email', 'phone', 'url') or provide a custom RegExp. The predefined patterns are:

83-87: LGTM: Clear explanation of plugin behavior

The behavior section provides a clear and concise explanation of how the plugin processes records and applies validations. It also mentions the use of recordHook for efficient processing, which is valuable information for users.

validate/string/src/validate.string.plugin.ts (4)

127-127: LGTM! Default export is appropriate.

Exporting validateString as the default export is a good practice, allowing for easy importing of the main functionality of this module.


1-127: Overall, well-implemented string validation plugin with room for minor improvements

This file implements a comprehensive and flexible string validation plugin for Flatfile. The structure is clear, and the implementation covers various validation scenarios effectively. Here's a summary of the key points:

  1. The StringValidationConfig interface provides a robust set of options for configuring validations.
  2. The validateAndTransformString function effectively implements the validation logic.
  3. The validateString function integrates well with Flatfile's listener system.

Areas for improvement:

  1. Consider enhancing the regex patterns for email, phone, and URL validation.
  2. Review the behavior of case transformations and trimming to potentially apply changes without raising errors.
  3. Improve type checking and error handling, especially when processing field values.
  4. Add JSDoc comments to improve documentation and IDE support.

These improvements will enhance the plugin's robustness and user-friendliness.


83-86: ⚠️ Potential issue

Consider applying case transformations without returning an error

Currently, when the case transformation modifies the value, an error is returned along with the transformed value. This may lead to unnecessary errors for transformations that can be automatically corrected. Consider applying the transformation silently without raising an error, or make this behavior configurable through an additional option in StringValidationConfig.

Proposed code change:

 if (value !== transformedValue) {
-  error = config.errorMessages?.case || `Field value must be in ${config.caseType}`;
-  return { value: transformedValue, error };
+  // Optionally log a warning or add a flag to indicate the value was transformed
+  return { value: transformedValue, error: null };
 }

Likely invalid or redundant comment.


96-99: ⚠️ Potential issue

Consider applying trim transformations without returning an error

Similarly, when trimming leading or trailing whitespace, the function returns an error if the value changes after trimming. It might be more user-friendly to apply the trimming without raising an error. Consider modifying the code to perform the trimming silently or provide a configuration option to control this behavior.

Proposed code change:

 if (value !== transformedValue) {
-  error = config.errorMessages?.trim || 'Field value has leading or trailing whitespace';
-  return { value: transformedValue, error };
+  // Optionally log a warning or add a flag to indicate the value was trimmed
+  return { value: transformedValue, error: null };
 }

Likely invalid or redundant comment.

validate/string/README.MD Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
@bangarang bangarang enabled auto-merge (squash) October 8, 2024 22:32
Comment on lines +8 to +9
<!-- END_INFOCARD -->
## Features
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<!-- END_INFOCARD -->
## Features
<!-- END_INFOCARD -->
## Features

validate/string/package.json Outdated Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
validate/string/src/validate.string.plugin.ts Outdated Show resolved Hide resolved
@bangarang bangarang dismissed carlbrugger’s stale review October 9, 2024 19:28

Addressed Comments!

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

🧹 Outside diff range and nitpick comments (2)
validate/string/src/validate.string.utils.ts (2)

40-40: Implement internationalization for error messages

The error messages are currently hardcoded in English, which may not be suitable for all users. To accommodate internationalization, consider integrating a localization system that allows error messages to be translated based on the user's locale.

Also applies to: 48-48, 54-54, 60-60, 66-66, 88-88, 103-103


39-41: Ensure consistency in handling empty strings

The check for empty strings uses value.trim(), which may conflict with scenarios where trimming is not desired. If trimming is optional (as specified in the trim configuration), consider aligning the empty string check with the trimming options to ensure consistent behavior.

Apply this diff to adjust the empty string check:

- if (!config.emptyStringAllowed && value.trim() === '') {
+ const valueToCheck = config.trim ? value.trim() : value
+ if (!config.emptyStringAllowed && valueToCheck === '') {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6b696af and f2b294c.

⛔ Files ignored due to path filters (1)
  • validate/string/package.json is excluded by !**/*.json
📒 Files selected for processing (4)
  • validate/string/src/index.ts (1 hunks)
  • validate/string/src/validate.string.plugin.spec.ts (1 hunks)
  • validate/string/src/validate.string.plugin.ts (1 hunks)
  • validate/string/src/validate.string.utils.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • validate/string/src/index.ts
  • validate/string/src/validate.string.plugin.spec.ts
  • validate/string/src/validate.string.plugin.ts
🧰 Additional context used

@bangarang bangarang merged commit c84dea6 into main Oct 9, 2024
33 checks passed
@bangarang bangarang deleted the feat/StringValidator branch October 9, 2024 19:44
This was referenced Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants