Skip to content

refactor: env process into config file #1189

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

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from

Conversation

rockito10
Copy link

@rockito10 rockito10 commented Apr 22, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a robust environment variable validation system, ensuring all configuration parameters are strictly checked before application startup.
    • Added new utility functions for string and URL validation.
    • Provided a sample environment file and comprehensive test suite for configuration validation.
  • Tests

    • Added extensive tests covering various environment variable formats and validation scenarios.
  • Chores

    • Improved code style and readability with minor formatting adjustments and added blank lines for clarity in several files.

sairanjit and others added 20 commits March 12, 2025 16:11
Signed-off-by: Sai Ranjit Tummalapalli <sairanjit.tummalapalli@ayanworks.com>
Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>
* fix: added api param validations

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

* fix: removed unnecessary validations

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

* fix:resolved validations issue

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

* added comment on function for understanding

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

* fix: resolve orgid validations

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

* fix: added response message

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

* fix: added space in response messages

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>

---------

Signed-off-by: bhavanakarwade <bhavana.karwade@ayanworks.com>
Signed-off-by: pallavighule <pallavi.ghule@ayanworks.com>
* fix: removed prisma commands in build stage

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* feat: create yml file for all services

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* Updated Dockerfiles

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* Updated yml to push docker images

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* updated yml files

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

---------

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>
* fix: used single yml file using matrix instead of multiple files

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* fix: renamed yml file to cicd.yml

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* fix: renamed yml file

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* fix: renamed yml file

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

* chore: removed id-token and attestations

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>

---------

Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>
* chore: add aws into monorepo

Signed-off-by: Sai Ranjit Tummalapalli <sairanjit.tummalapalli@ayanworks.com>

* chore: update tsconfig

Signed-off-by: Sai Ranjit Tummalapalli <sairanjit.tummalapalli@ayanworks.com>

* refactor:tsconfig.build.json file

Signed-off-by: Tipu_Singh <tipu.singh@ayanworks.com>

* refactor: remove redundant .nvmrc file

Signed-off-by: Sai Ranjit Tummalapalli <sairanjit.tummalapalli@ayanworks.com>

---------

Signed-off-by: Sai Ranjit Tummalapalli <sairanjit.tummalapalli@ayanworks.com>
Signed-off-by: Tipu_Singh <tipu.singh@ayanworks.com>
Co-authored-by: Tipu_Singh <tipu.singh@ayanworks.com>
Signed-off-by: Sai Ranjit Tummalapalli <sairanjit.tummalapalli@ayanworks.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
…alhost)

Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
@GHkrishna GHkrishna changed the title Refactor/env process into config file refactor: env process into config file Apr 23, 2025
@GHkrishna GHkrishna linked an issue Apr 23, 2025 that may be closed by this pull request
Signed-off-by: rockito10 <rockito10.mfd@gmail.com>
@rockito10 rockito10 marked this pull request as ready for review April 23, 2025 13:39
@rockito10
Copy link
Author

Hello! I think the branch is ready to be merged, please tell me if there's any troubles with it, or anything I can improve

@GHkrishna
Copy link
Contributor

Hello @rockito10
Thanks for the PR!

Signed-off-by: rockito10 <107514701+rockito10@users.noreply.github.com>
Copy link

@GHkrishna GHkrishna changed the base branch from develop to main April 25, 2025 14:17
@GHkrishna GHkrishna changed the base branch from main to develop April 25, 2025 14:17
@GHkrishna
Copy link
Contributor

@coderabbitai review

Copy link

coderabbitai bot commented Jul 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

coderabbitai bot commented Jul 11, 2025

Walkthrough

This update introduces a comprehensive runtime environment validation framework in the config directory, including new validation helpers, error handling, and test coverage. It also applies minor whitespace and formatting changes to several TypeScript files in the application and library code, without affecting any functional logic or public interfaces outside the new configuration modules.

Changes

File(s) Change Summary
.eslintrc.js Added a newline at the end of the file.
apps/api-gateway/src/issuance/dtos/issuance.dto.ts Added a duplicate import of IsUUID.
apps/api-gateway/src/issuance/issuance.controller.ts Inserted a blank line after an import statement.
apps/api-gateway/src/verification/verification.controller.ts Added a blank line after an object construction in a method.
libs/common/src/NATSClient.ts Removed an extraneous blank line inside a method.
config/config.ts Introduced strict environment variable validation and export of parsed config as env.
config/core/error.ts Added custom error class VError and supporting types for validation errors.
config/core/helpers/str-helpers.ts Added string utility functions grouped under _STR.
config/core/helpers/url-helpers.ts Added URL and email validation utilities under _URL.
config/core/index.ts Added validation framework with builder classes and schema support, exported as v.
config/core/validators.ts Added a comprehensive set of string validators for config inputs.
config/test/.env.test.sample Added a sample environment file with annotated valid/invalid values for testing.
config/test/config.spec.ts Added a test suite for environment validation covering many string formats and constraints.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Config as config/config.ts
    participant Env as process.env
    participant Schema as envDemoSchema
    participant V as v (validation framework)
    participant Error as VError

    App->>Config: Import env
    Config->>Env: Read environment variables
    Config->>Schema: Define validation schema
    Config->>V: Use v.schema to validate process.env
    V->>Env: Validate each variable with StringBuilder rules
    V-->>Config: Return success or VError
    alt Validation fails
        Config->>Error: Throw VError with details
    else Validation passes
        Config->>App: Export parsed env config
    end
Loading

Poem

In the warren where configs dwell,
New helpers and schemas now excel.
With errors caught and strings made neat,
The rabbit hops—validation complete!
Whitespace swept, tests abound,
In every burrow, safety’s found.
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • 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 explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

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

@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

🧹 Nitpick comments (4)
config/core/helpers/str-helpers.ts (1)

13-15: Clarify the purpose of _isOptional function.

The function always returns true, which suggests it might be a placeholder or has a specific use case in the validation framework.

Consider adding a comment to explain the purpose:

+// Always returns true - used for optional validation scenarios
 function _isOptional(): boolean {
   return true;
 }
config/core/helpers/url-helpers.ts (2)

19-29: Improve robustness of localhost validation.

The current port extraction logic using split(':').at(-1).split('/').at(0) could be fragile with edge cases.

Consider a more robust approach:

 function _isLocalhost(input: string | undefined): boolean {
   const regex = /^(http:\/\/)?(localhost|127\.0\.0\.1|::1)(:\d{1,5})?(\/)?$/;

   if (!regex.test(input || '')) {
     return false;
   }

-  const port = input.split(':').at(-1).split('/').at(0);
+  const portMatch = input.match(/:(\d+)/);
+  const port = portMatch ? portMatch[1] : undefined;

-  return _isPort(port);
+  return !port || _isPort(port);
 }

53-55: Consider edge cases in multiple URL validation.

The current implementation splits by comma and trims each URL, but it might not handle edge cases like empty strings after splitting.

Consider adding a check for empty URLs:

 function _isMultipleURL(input: string | undefined): boolean {
-  return input?.split(',').every((url) => _isURL(url.trim()) || _isLocalhost(url.trim()));
+  return input?.split(',')
+    .map(url => url.trim())
+    .filter(url => url.length > 0)
+    .every((url) => _isURL(url) || _isLocalhost(url)) ?? false;
 }
config/core/validators.ts (1)

176-188: Consider expanding the valid port range.

The current validation restricts ports to 1024-65536, but valid port numbers are 1-65535. While ports 1-1023 are reserved for system services, applications might legitimately need to use them in certain contexts.

Consider making the port range more flexible or configurable:

 export function port(): Validator<string> {
   return (input) => {
     const success = _URL._isPort(input);
 
     if (!success) {
       return {
-        expected: 'A number between 1024 and 65536',
+        expected: 'A number between 1 and 65535',
         received: input,
-        message: 'Invalid port. Port numbers must be between 1024 and 65536.'
+        message: 'Invalid port. Port numbers must be between 1 and 65535.'
       };
     }
   };
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f2746cd and 1715b29.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • .eslintrc.js (1 hunks)
  • apps/api-gateway/src/issuance/dtos/issuance.dto.ts (1 hunks)
  • apps/api-gateway/src/issuance/issuance.controller.ts (1 hunks)
  • apps/api-gateway/src/verification/verification.controller.ts (1 hunks)
  • config/config.ts (1 hunks)
  • config/core/error.ts (1 hunks)
  • config/core/helpers/str-helpers.ts (1 hunks)
  • config/core/helpers/url-helpers.ts (1 hunks)
  • config/core/index.ts (1 hunks)
  • config/core/validators.ts (1 hunks)
  • config/test/.env.test.sample (1 hunks)
  • config/test/config.spec.ts (1 hunks)
  • libs/common/src/NATSClient.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • libs/common/src/NATSClient.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: tipusinghaw
PR: credebl/platform#1297
File: apps/api-gateway/src/tracer.ts:24-28
Timestamp: 2025-06-24T11:15:29.468Z
Learning: In the credebl/platform repository, the team prefers to create utilities for validating required environment variables rather than implementing inline validation. This approach promotes reusability across different parts of the application.
config/config.ts (1)
Learnt from: tipusinghaw
PR: credebl/platform#1297
File: apps/api-gateway/src/tracer.ts:24-28
Timestamp: 2025-06-24T11:15:29.468Z
Learning: In the credebl/platform repository, the team prefers to create utilities for validating required environment variables rather than implementing inline validation. This approach promotes reusability across different parts of the application.
config/test/config.spec.ts (1)
Learnt from: tipusinghaw
PR: credebl/platform#1297
File: apps/api-gateway/src/tracer.ts:24-28
Timestamp: 2025-06-24T11:15:29.468Z
Learning: In the credebl/platform repository, the team prefers to create utilities for validating required environment variables rather than implementing inline validation. This approach promotes reusability across different parts of the application.
🧬 Code Graph Analysis (4)
config/config.ts (1)
config/core/index.ts (1)
  • v (184-187)
config/test/config.spec.ts (1)
config/core/index.ts (1)
  • v (184-187)
config/core/helpers/url-helpers.ts (2)
config/core/index.ts (3)
  • port (88-91)
  • host (78-81)
  • url (53-56)
config/core/validators.ts (3)
  • port (176-188)
  • host (160-172)
  • url (208-220)
config/core/validators.ts (4)
config/core/error.ts (1)
  • Issue (3-8)
config/core/helpers/str-helpers.ts (1)
  • _STR (23-29)
config/core/index.ts (16)
  • v (184-187)
  • boolean (48-51)
  • notEmpty (38-41)
  • number (43-46)
  • optional (110-113)
  • startsWith (98-101)
  • domain (103-106)
  • email (68-71)
  • endpoint (93-96)
  • host (78-81)
  • port (88-91)
  • protocol (73-76)
  • url (53-56)
  • localhost (83-86)
  • multipleUrl (58-61)
  • postgresUrl (63-66)
config/core/helpers/url-helpers.ts (1)
  • _URL (66-78)
🪛 Biome (1.9.4)
apps/api-gateway/src/issuance/dtos/issuance.dto.ts

[error] 18-18: Declarations inside of a import declaration may not have duplicates

a second declaration of IsUUID is not allowed

IsUUID is first declared here

(parse)

🔇 Additional comments (12)
apps/api-gateway/src/issuance/issuance.controller.ts (1)

84-84: LGTM - Formatting improvement.

The added blank line improves code readability and maintains consistency with formatting standards.

.eslintrc.js (1)

104-104: LGTM - Formatting improvement.

Adding a trailing newline is a good practice and improves file formatting consistency.

apps/api-gateway/src/verification/verification.controller.ts (1)

220-220: LGTM - Formatting improvement.

The added blank line improves code readability by providing visual separation between the object construction and the service call.

config/core/helpers/str-helpers.ts (1)

17-19: LGTM - Proper optional chaining implementation.

The function correctly uses optional chaining to handle undefined inputs safely.

config/test/.env.test.sample (3)

20-21: Review the expected behavior for optional validation.

The test expects an empty string to fail for optional validation (TEST_OPTIONAL_1= # FAIL), but typically optional fields should allow empty values.

Please verify if this is the intended behavior for optional field validation. If optional fields should allow empty values, this test case might need adjustment.


16-18: Verify port range validation logic.

The test expects ports 1000 and 99999 to fail, suggesting a specific valid port range. Please ensure this aligns with your application's port validation requirements.

Consider documenting the valid port range in comments for clarity:

-TEST_PORT_1=1000  # FAIL
-TEST_PORT_2=99999 # FAIL
-TEST_PORT_3=3000  # PASS
+TEST_PORT_1=1000  # FAIL (below minimum allowed port)
+TEST_PORT_2=99999 # FAIL (above maximum allowed port)
+TEST_PORT_3=3000  # PASS (within valid range)

1-61: LGTM - Comprehensive test coverage.

The test file provides good coverage of various validation scenarios including protocols, URLs, emails, booleans, numbers, and PostgreSQL URLs. The expected pass/fail cases generally align with typical validation rules.

config/core/error.ts (1)

1-49: Well-structured error handling implementation.

The custom VError class provides excellent structured error handling for validation issues. The design allows for detailed error reporting with path-based grouping through the flatten() method, which will be very useful for debugging configuration issues.

config/config.ts (1)

1-170: Excellent implementation of environment validation utilities.

This implementation perfectly aligns with the team's preference for creating reusable utilities for environment variable validation. The comprehensive schema covers all necessary environment variables with appropriate validators, and the error handling with flatten() will provide clear feedback for configuration issues.

The organization by functional areas (API_GATEWAY, PLATFORM, DATABASE, etc.) makes the configuration easy to understand and maintain.

config/core/index.ts (1)

1-188: Excellent validation framework design.

The validation framework demonstrates excellent design patterns:

  1. Fluent API: The StringBuilder class provides an intuitive chaining interface for building complex validators.
  2. Type Safety: Generic types with InferShape<T> ensure compile-time type safety for validated objects.
  3. Error Handling: Proper integration with the VError class for structured error reporting.
  4. Separation of Concerns: Clean separation between string validation and object validation logic.

The public API through the v object provides a clean interface that will be easy to use across the application.

config/core/validators.ts (2)

1-7: Excellent validation framework implementation.

The overall design and implementation of the validation framework is well-structured with:

  • Consistent error message formatting
  • Proper TypeScript typing with the generic Validator<T>
  • Good separation of concerns between generic and URL-specific validators
  • Comprehensive error objects with expected/received values
  • Modular design leveraging helper functions

This aligns well with the team's preference for creating reusable validation utilities rather than inline validation logic.

Also applies to: 13-106, 112-271


208-220: Localhost URLs aren’t covered by _isURL — both checks are needed
The default validator.isURL call (used by _URL._isURL) requires a TLD and thus returns false for "localhost" or "localhost:3000". _URL._isLocalhost explicitly handles those cases. Keeping both checks is correct and the performance impact of two quick boolean calls is negligible.

Likely an incorrect or invalid review comment.

@@ -15,6 +15,7 @@ import {
IsString,
IsUUID,
IsUrl,
IsUUID,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate IsUUID from the import list

IsUUID is already imported on line 16. The second occurrence triggers a compilation error (TS2300: Duplicate identifier) and linter failure. Delete the redundant entry to restore a valid import statement.

-  IsUUID,
-  IsUrl,
-  IsUUID,
+  IsUUID,
+  IsUrl,

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

🧰 Tools
🪛 Biome (1.9.4)

[error] 18-18: Declarations inside of a import declaration may not have duplicates

a second declaration of IsUUID is not allowed

IsUUID is first declared here

(parse)

🤖 Prompt for AI Agents
In apps/api-gateway/src/issuance/dtos/issuance.dto.ts at line 18, remove the
duplicate import of IsUUID since it is already imported on line 16. Delete the
redundant IsUUID entry from the import list to fix the TS2300 duplicate
identifier compilation error and resolve the linter failure.

Comment on lines +9 to +11
function _isNotEmpty(input: string | undefined): boolean {
return '' !== input?.trim();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect handling of undefined inputs.

The function returns true for undefined inputs because '' !== undefined is true, which is likely not the intended behavior.

Apply this fix to properly handle undefined inputs:

-function _isNotEmpty(input: string | undefined): boolean {
-  return '' !== input?.trim();
-}
+function _isNotEmpty(input: string | undefined): boolean {
+  return input !== undefined && '' !== input.trim();
+}
📝 Committable suggestion

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

Suggested change
function _isNotEmpty(input: string | undefined): boolean {
return '' !== input?.trim();
}
function _isNotEmpty(input: string | undefined): boolean {
return input !== undefined && '' !== input.trim();
}
🤖 Prompt for AI Agents
In config/core/helpers/str-helpers.ts around lines 9 to 11, the function
_isNotEmpty incorrectly returns true for undefined inputs because it compares an
empty string to input?.trim(), which results in true when input is undefined. To
fix this, explicitly check if the input is defined before trimming and
comparing, ensuring the function returns false for undefined inputs and only
true for non-empty strings.

Comment on lines +5 to +7
function _isNumber(input: string | undefined): boolean {
return !Number.isNaN(Number(input));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix edge case with whitespace-only strings.

The current implementation considers whitespace-only strings as valid numbers because Number(" ") returns 0.

Apply this fix to handle whitespace-only strings properly:

-function _isNumber(input: string | undefined): boolean {
-  return !Number.isNaN(Number(input));
-}
+function _isNumber(input: string | undefined): boolean {
+  return input?.trim() !== '' && !Number.isNaN(Number(input));
+}
📝 Committable suggestion

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

Suggested change
function _isNumber(input: string | undefined): boolean {
return !Number.isNaN(Number(input));
}
function _isNumber(input: string | undefined): boolean {
return input?.trim() !== '' && !Number.isNaN(Number(input));
}
🤖 Prompt for AI Agents
In config/core/helpers/str-helpers.ts around lines 5 to 7, the _isNumber
function incorrectly treats whitespace-only strings as valid numbers because
Number("  ") returns 0. To fix this, add a check to return false if the input is
undefined or consists only of whitespace before converting it to a number. This
ensures that strings with only whitespace are not considered valid numbers.

Comment on lines +1 to +3
function _includes(inputs: string[], value: string | undefined): boolean {
return inputs?.includes(value);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix type safety issue with undefined values.

The function accepts string | undefined but inputs.includes(undefined) behavior depends on whether the array actually contains undefined values. This could lead to unexpected results.

Consider this fix to handle undefined values explicitly:

-function _includes(inputs: string[], value: string | undefined): boolean {
-  return inputs?.includes(value);
-}
+function _includes(inputs: string[], value: string | undefined): boolean {
+  return value !== undefined && inputs?.includes(value);
+}
📝 Committable suggestion

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

Suggested change
function _includes(inputs: string[], value: string | undefined): boolean {
return inputs?.includes(value);
}
function _includes(inputs: string[], value: string | undefined): boolean {
return value !== undefined && inputs?.includes(value);
}
🤖 Prompt for AI Agents
In config/core/helpers/str-helpers.ts around lines 1 to 3, the function
_includes accepts a value that can be string or undefined, but calling includes
with undefined may cause unexpected behavior. Update the function to explicitly
check if the value is undefined and handle that case separately, returning false
or handling it as appropriate, before calling includes on the inputs array.

Comment on lines +309 to +315
test('Boolean success, is uppercase false.', () => {
const mockSchema = v.schema({
TEST_BOOLEAN_4: v.str().boolean()
});

expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix contradictory test description and expectation.

The test description says "Boolean success, is uppercase false" but expects toBeFalsy(), which indicates failure, not success.

Apply this diff to fix the test description:

-test('Boolean success, is uppercase false.', () => {
+test('Boolean error, is uppercase false.', () => {
   const mockSchema = v.schema({
     TEST_BOOLEAN_4: v.str().boolean()
   });

   expect(mockSchema.safeParse(process.env).success).toBeFalsy();
 });
📝 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
test('Boolean success, is uppercase false.', () => {
const mockSchema = v.schema({
TEST_BOOLEAN_4: v.str().boolean()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
test('Boolean error, is uppercase false.', () => {
const mockSchema = v.schema({
TEST_BOOLEAN_4: v.str().boolean()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
🤖 Prompt for AI Agents
In config/test/config.spec.ts around lines 309 to 315, the test description
states "Boolean success, is uppercase false" but the expectation is toBeFalsy(),
which contradicts the description. Update the test description to accurately
reflect that the test expects failure by changing it to something like "Boolean
failure, is uppercase false" or similar wording that matches the toBeFalsy()
expectation.

Comment on lines +44 to +66
test('Host Error exceeds value of valid IP', () => {
const mockSchema = v.schema({
TEST_HOST_1: v.str().protocol()
});

expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});

test('Host Error contains letters', () => {
const mockSchema = v.schema({
TEST_HOST_2: v.str().protocol()
});

expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});

test('Host Error contains letters', () => {
const mockSchema = v.schema({
TEST_HOST_3: v.str().protocol()
});

expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix validator methods and test naming issues.

Several issues in the host error tests:

  1. Lines 46, 54, 62: These tests are checking for "Host Error" but using .protocol() instead of .host() validator.
  2. Line 60: Duplicate test name "Host Error contains letters".

Apply this diff to fix the validator methods and test names:

 test('Host Error exceeds value of valid IP', () => {
   const mockSchema = v.schema({
-    TEST_HOST_1: v.str().protocol()
+    TEST_HOST_1: v.str().host()
   });

   expect(mockSchema.safeParse(process.env).success).toBeFalsy();
 });

 test('Host Error contains letters', () => {
   const mockSchema = v.schema({
-    TEST_HOST_2: v.str().protocol()
+    TEST_HOST_2: v.str().host()
   });

   expect(mockSchema.safeParse(process.env).success).toBeFalsy();
 });

-test('Host Error contains letters', () => {
+test('Host Error invalid format', () => {
   const mockSchema = v.schema({
-    TEST_HOST_3: v.str().protocol()
+    TEST_HOST_3: v.str().host()
   });

   expect(mockSchema.safeParse(process.env).success).toBeFalsy();
 });
📝 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
test('Host Error exceeds value of valid IP', () => {
const mockSchema = v.schema({
TEST_HOST_1: v.str().protocol()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
test('Host Error contains letters', () => {
const mockSchema = v.schema({
TEST_HOST_2: v.str().protocol()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
test('Host Error contains letters', () => {
const mockSchema = v.schema({
TEST_HOST_3: v.str().protocol()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
test('Host Error exceeds value of valid IP', () => {
const mockSchema = v.schema({
TEST_HOST_1: v.str().host()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
test('Host Error contains letters', () => {
const mockSchema = v.schema({
TEST_HOST_2: v.str().host()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
test('Host Error invalid format', () => {
const mockSchema = v.schema({
TEST_HOST_3: v.str().host()
});
expect(mockSchema.safeParse(process.env).success).toBeFalsy();
});
🤖 Prompt for AI Agents
In config/test/config.spec.ts lines 44 to 66, the tests for host errors
incorrectly use the .protocol() validator instead of .host(), and there is a
duplicate test name "Host Error contains letters". Update the validator calls
from .protocol() to .host() for TEST_HOST_1, TEST_HOST_2, and TEST_HOST_3. Also,
rename the third test to a unique descriptive name to avoid duplication.

expected:
'A valid postgresURL with the format: postgresql://{postgres.user}:{postgres.password}@{your-ip}:{postgres.port}/{database-name}/schema={}',
received: input,
message: 'Invalid collection of URLs.'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect error message in postgresUrl() validator.

The error message incorrectly states "Invalid collection of URLs" when it should be about an invalid PostgreSQL URL format.

-        message: 'Invalid collection of URLs.'
+        message: 'Invalid PostgreSQL URL format.'
📝 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
message: 'Invalid collection of URLs.'
message: 'Invalid PostgreSQL URL format.'
🤖 Prompt for AI Agents
In config/core/validators.ts at line 267, the error message for the
postgresUrl() validator incorrectly states "Invalid collection of URLs." Update
this message to accurately reflect the issue by changing it to indicate an
invalid PostgreSQL URL format, such as "Invalid PostgreSQL URL format."

Comment on lines +79 to +90
export function optional(): Validator<string> {
return (input) => {
const success = _STR._isOptional();
if (!success) {
return {
expected: 'An optional value',
received: input,
message: 'Must be a valid optional value.'
};
}
};
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the optional() validator logic.

The optional() validator has a critical flaw: it calls _STR._isOptional() without passing the input parameter, and the logic seems incorrect since it always returns an error.

 export function optional(): Validator<string> {
   return (input) => {
-    const success = _STR._isOptional();
-    if (!success) {
-      return {
-        expected: 'An optional value',
-        received: input,
-        message: 'Must be a valid optional value.'
-      };
-    }
+    const success = _STR._isOptional(input);
+    if (!success) {
+      return {
+        expected: 'An optional value',
+        received: input,
+        message: 'Must be a valid optional value.'
+      };
+    }
   };
 }
📝 Committable suggestion

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

Suggested change
export function optional(): Validator<string> {
return (input) => {
const success = _STR._isOptional();
if (!success) {
return {
expected: 'An optional value',
received: input,
message: 'Must be a valid optional value.'
};
}
};
}
export function optional(): Validator<string> {
return (input) => {
const success = _STR._isOptional(input);
if (!success) {
return {
expected: 'An optional value',
received: input,
message: 'Must be a valid optional value.'
};
}
};
}
🤖 Prompt for AI Agents
In config/core/validators.ts around lines 79 to 90, the optional() validator
incorrectly calls _STR._isOptional() without passing the input parameter and
always returns an error. Fix this by passing the input to
_STR._isOptional(input) and adjust the logic to return undefined (indicating
success) when the input is optional, and return the error object only when the
input is not optional.

Comment on lines +224 to +237
export function localhost(): Validator<string> {
return (input) => {
const port = input.split(':').at(-1);
const success = _URL._isLocalhost(input) && _URL._isPort(port);

if (!success) {
return {
expected: 'A valid localhost (e.g., http://localhost:aPortNumber, 127.0.0.1:aPortNumber)',
received: input,
message: 'Invalid Localhost.'
};
}
};
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Review localhost validation for IPv6 compatibility.

The current implementation splits by ':' and takes the last part as the port, but this approach won't work correctly for IPv6 addresses like [::1]:8080 where colons are part of the IP address format.

Consider testing with IPv6 localhost addresses to ensure the validation works correctly:


🏁 Script executed:

#!/bin/bash
# Description: Check if IPv6 localhost addresses are handled correctly in the codebase

# Search for IPv6 localhost usage patterns
rg -i "localhost.*:.*:" --type ts
rg -i "\[::1\]" --type ts
rg -i "127\.0\.0\.1" --type ts

Length of output: 1083


🏁 Script executed:

#!/bin/bash
# Display import section and context for _URL in validators.ts
sed -n '1,50p' config/core/validators.ts

Length of output: 1413


🏁 Script executed:

#!/bin/bash
# Show _isLocalhost implementation in url-helpers.ts
sed -n '1,200p' config/core/helpers/url-helpers.ts

Length of output: 2084


Add IPv6 bracketed localhost support in the localhost validator

The current logic in

  • config/core/helpers/url-helpers.ts_isLocalhost
  • config/core/validators.tslocalhost()

only matches unbracketed ::1 and naïvely splits on ':' to grab the port. As a result, inputs like
http://[::1]:8080
[::1]:8080
will fail validation or mis-extract the port.

Suggested fixes:
• In _isLocalhost, extend the regex to allow optional brackets around ::1, e.g.:

const regex = /^(http:\/\/)?(\[?::1\]?|localhost|127\.0\.0\.1)(:\d{1,5})?(\/)?$/;

• Update port extraction to strip the bracket suffix before splitting, for example:

// inside _isLocalhost
const hostPort = input.replace(/^\[?(.+?)\]?$/, '$1');  // removes surrounding [ ]
const port = hostPort.split(':').at(-1).split('/').at(0);

• In config/core/validators.ts, update the expected message to include the IPv6 example:

'A valid localhost (e.g., http://localhost:3000, http://127.0.0.1:3000, http://[::1]:3000)'

Locations needing change:

  • config/core/helpers/url-helpers.ts — function _isLocalhost
  • config/core/validators.ts — function localhost(), error expected string
🤖 Prompt for AI Agents
In config/core/helpers/url-helpers.ts within the _isLocalhost function, update
the regex to allow optional brackets around ::1 by using
/^(http:\/\/)?(\[?::1\]?|localhost|127\.0\.0\.1)(:\d{1,5})?(\/)?$/. Also, modify
the port extraction logic to first remove surrounding brackets from the host
portion before splitting on ':' to get the port. In config/core/validators.ts
inside the localhost() function (lines 224-237), update the expected error
message string to include the IPv6 bracketed localhost example like 'A valid
localhost (e.g., http://localhost:3000, http://127.0.0.1:3000,
http://[::1]:3000)'. These changes will correctly handle bracketed IPv6
localhost addresses and improve validation accuracy.

@GHkrishna
Copy link
Contributor

Hello @rockito10

We were working on some releases, which meant we couldn't merge some PRs. Since that part is about to be finished, we can now merge appropriate PRs.

Do you mind having a look at the suggestions from coderabbit and also some DCO issues

@GHkrishna GHkrishna added the enhancement New feature or request label Jul 11, 2025
@rockito10
Copy link
Author

Hello! I read the reviews and worked a bit on them, just a couple of things:

-Regarding the DCO, I did sign my previous commits, these last unsigned ones seem to be from the last merge we did on this branch, from other people. Im not sure if I am allowed to change their commit messages to have signatures.

-Regarding the CodeRabbit review, I did most of the things it requested, except the isOptional conflict, because if the function would receive the input parameter, there'll be no way to use it (since what I am checking is that it could be null or undefined but it could also be anything else), so I just return true in this case. Still, I can change it if you want, no problem on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use env variables from config instead of directly from process
6 participants