Skip to content

Global schema transformer#570

Merged
yamcodes merged 25 commits intocoercionfrom
coercion-improvements
Dec 21, 2025
Merged

Global schema transformer#570
yamcodes merged 25 commits intocoercionfrom
coercion-improvements

Conversation

@yamcodes
Copy link
Owner

@yamcodes yamcodes commented Dec 20, 2025

Closes #571

Summary by CodeRabbit

  • New Features

    • Environment variables are now auto-coerced from strings to numbers and booleans during env parsing, including numeric refinements (ranges, divisors) and strict literal handling. Parsed-number/boolean behavior applies globally so defaults and dotenv strings become proper numbers/booleans.
  • Breaking Changes

    • Legacy boolean keyword renamed to parsedBoolean.
    • number.port now accepts numbers only (string-parsing removed).

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Dec 20, 2025

🦋 Changeset detected

Latest commit: 2d542cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
arkenv Minor
@repo/keywords Minor
@repo/scope Minor
@arkenv/bun-plugin Patch
@arkenv/vite-plugin Patch
@repo/types Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Dec 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
arkenv Ready Ready Preview, Comment Dec 21, 2025 1:41pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 20, 2025

Walkthrough

Global schema-transform coercion added: new parsedNumber/maybeParsedNumber and parsedBoolean/maybeParsedBoolean morphs, a coerce(schema) transformer, and createEnv now applies coerce before validation. Keywords and scope adjusted (port becomes numeric constraint; root boolean removed). Tests and changelogs updated accordingly.

Changes

Cohort / File(s) Summary
Changeset docs
.changeset/cyan-loops-hear.md, .changeset/few-rabbits-battle.md, .changeset/humble-lizards-judge.md, .changeset/open-spiders-tan.md, .changeset/plain-webs-dig.md
Added/updated changelog entries documenting parsedNumber/parsedBoolean, renames/simplifications, and BREAKING notes about the boolean keyword and number.port.
OpenSpec & archive
openspec/changes/add-coercion/*, openspec/changes/archive/2025-12-20-add-coercion/*, openspec/specs/coercion/spec.md, openspec/changes/.../tasks.md
Removed older design/proposal docs and added/archived new design, proposal, spec, and tasks describing a schema-transform (coerce) approach and edge cases.
Keywords module
packages/internal/keywords/src/index.ts, packages/internal/keywords/src/index.test.ts
Added maybeParsedNumber/parsedNumber and maybeParsedBoolean/parsedBoolean; changed port to type("0 <= number.integer <= 65535"); updated tests to use numeric inputs.
Scope module
packages/internal/scope/src/index.ts, packages/internal/scope/src/index.test.ts
Removed root $ boolean export and reverted number keywords to base definitions; tests updated for numeric port semantics.
Coercion utility
packages/arkenv/src/utils/coerce.ts, packages/arkenv/src/utils/coerce.test.ts, packages/arkenv/src/utils/index.ts
New exported coerce(schema) that traverses/transforms ArkType schemas to wrap numeric/boolean leaves with parsed/maybe-parsed morphs using ArkType internals; tests added and re-exported.
ArkEnv integration
packages/arkenv/src/create-env.ts, packages/arkenv/src/create-env.test.ts, packages/arkenv/src/coercion.integration.test.ts
createEnv applies coerce(schema) after parsing and before validation; tests updated/added to exercise coercion and test env preservation.
Tests & integrations
packages/arkenv/src/custom-types.integration.test.ts, packages/arkenv/src/error.integration.test.ts, packages/arkenv/src/type.test.ts, packages/internal/keywords/src/index.test.ts, packages/internal/scope/src/index.test.ts
Tests updated to provide numeric/boolean inputs and to reflect new port semantics and coercion behavior; some expectations adjusted.
Utils exports
packages/arkenv/src/utils/index.ts
Re-exported coerce.
Git config
.gitignore
Minor newline/whitespace adjustments and added an arktype clone entry.

Sequence Diagram(s)

sequenceDiagram
    participant Client as createEnv
    participant Parser as Schema Parser
    participant Coerce as coerce(schema)
    participant Keywords as keywords (parsed/maybeParsed)
    participant Validator as ArkType.validate

    Note over Client,Validator: createEnv flow: parse → transform → validate
    Client->>Parser: parse user schema (type(...) or raw)
    Parser-->>Client: parsed ArkType schema
    Client->>Coerce: coerce(parsed schema)
    Coerce->>Keywords: wrap numeric/boolean leaf nodes with parsed/maybeParsed morphs
    Coerce-->>Client: transformed schema
    Client->>Validator: validate process.env against transformed schema
    Validator-->>Client: validated/coerced env or validation errors
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • packages/arkenv/src/utils/coerce.ts — schema traversal, union/intersection handling, root wrapping, and heavy use of ArkType internals.
    • packages/internal/keywords/src/index.ts — correctness and error messages for parsing morphs and port semantics.
    • packages/arkenv/src/create-env.ts & integration tests — ensure transform ordering and test environment setup preserve expected behavior.

Possibly related PRs

Poem

🐰 I nibble at keys by lantern glow,
Strings hop, become numbers in a row,
"true" sheds quotes and dons boolean fur,
Coerce hums softly — types purr and concur,
A rabbit hops off, pleased with tidy lore.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues check ❓ Inconclusive The linked issue #571 provides no coding requirements or objectives, only a title match. No specific requirements to validate against. Review the linked issue #571 to clarify specific coding requirements and objectives for this PR.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Global schema transformer' is concise and directly reflects the main architectural change in the PR.
Out of Scope Changes check ✅ Passed The PR includes comprehensive coercion implementation, test coverage, documentation updates, and keyword exports that align with the stated transformer objective.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch coercion-improvements

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c00dbec and 2d542cc.

📒 Files selected for processing (1)
  • packages/arkenv/src/utils/coerce.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/arkenv/src/utils/coerce.test.ts

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added docs Improvements or additions to documentation arkenv Changes to the `arkenv` npm package. example Issues or Pull Requests concerning at least one ArkEnv example. (Found in the `examples/` directory) tests This issue or PR is about adding, removing or changing tests labels Dec 20, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 20, 2025

Open in StackBlitz

npm i https://pkg.pr.new/arkenv@570
npm i https://pkg.pr.new/@arkenv/bun-plugin@570
npm i https://pkg.pr.new/@arkenv/vite-plugin@570

commit: 74e426d

@arkenv-bot
Copy link
Contributor

arkenv-bot bot commented Dec 20, 2025

📦 Bundle Size Report

Package Size Limit Diff Status
arkenv 956 B 2 kB +31.3%

All size limits passed!

…chema definitions and refinements, and refine various type and regex functionalities.
@yamcodes yamcodes changed the base branch from main to coercion December 20, 2025 21:50
@github-actions github-actions bot removed docs Improvements or additions to documentation example Issues or Pull Requests concerning at least one ArkEnv example. (Found in the `examples/` directory) labels Dec 20, 2025
…ort` to use `parsedNumber`, and integrate `port` into the ArkType scope.
@github-actions github-actions bot added the docs Improvements or additions to documentation label Dec 20, 2025
@yamcodes yamcodes marked this pull request as ready for review December 20, 2025 22:17
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 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
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

🧹 Nitpick comments (2)
packages/arkenv/src/utils/coerce.ts (2)

39-65: Consider adding error handling for internal API access.

The function accesses .internal and calls .pipe() on the morphs without validation. If these properties are missing or the internal API changes, the function will fail with unclear errors.

Consider wrapping the internal API access in try-catch blocks or validating that the required properties exist before using them.

🔎 Proposed defensive checks
 export function coerce(schema: any): any {
+	// Validate internal API availability
+	if (!maybeParsedNumber || !(maybeParsedNumber as any).internal?.pipe) {
+		throw new Error("maybeParsedNumber internal API not available");
+	}
+	if (!maybeParsedBoolean || !(maybeParsedBoolean as any).internal?.pipe) {
+		throw new Error("maybeParsedBoolean internal API not available");
+	}
+
 	// biome-ignore lint/suspicious/noExplicitAny: Internal ArkType properties are not typed in public API.
 	const numInternal = (maybeParsedNumber as any).internal;
 	// biome-ignore lint/suspicious/noExplicitAny: Internal ArkType properties are not typed in public API.
 	const boolInternal = (maybeParsedBoolean as any).internal;

53-59: Consider adding explicit test coverage for mixed numeric/boolean union types.

Sequential morph application does occur for unions containing both numeric and boolean branches (e.g., type("number | boolean")). The current loose morph design (maybeParsedNumber and maybeParsedBoolean return unchanged input on parse failure) handles this safely—e.g., "123" → 123 (number morph) → 123 (boolean morph returns unchanged), and "true" → "true" (number morph) → true (boolean morph). However, the absence of explicit tests for this pattern leaves the behavior undocumented. Add a test case for mixed unions to ensure the sequential application remains safe if morphs are refactored.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b28e432 and dfaf69a.

📒 Files selected for processing (2)
  • packages/arkenv/src/utils/coerce.test.ts (1 hunks)
  • packages/arkenv/src/utils/coerce.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/arkenv/src/utils/coerce.test.ts
🧰 Additional context used
📓 Path-based instructions (4)
packages/arkenv/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/arktype.mdc)

packages/arkenv/**/*.ts: Use ArkType's type() function to define schemas in environment variable definitions
Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Use the scoped $ type system for custom types defined in scope.ts
Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Use union types for enums in ArkType schemas (e.g., "'dev' | 'prod'") instead of separate enum definitions
Leverage ArkType's built-in types (e.g., string.host, number.port) where possible in environment schemas
Convert ArkType validation errors to ArkEnvError for user-friendly error messages that include variable name and expected type

Files:

  • packages/arkenv/src/utils/coerce.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

**/*.{ts,tsx}: Prefer type over interface for type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverage const type parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypes error)
Use as const where appropriate for immutable values (useAsConstAssertion error)
Don't reassign function parameters (noParameterAssign error)
Place default parameters last in function signatures (useDefaultParameterLast error)
Always initialize enum values (useEnumInitializers error)
Declare one variable per statement (useSingleVarDeclarator error)
Avoid unnecessary template literals (noUnusedTemplateLiteral error)
Prefer Number.parseInt over global parseInt (useNumberNamespace error)
Use kebab-case for TypeScript filenames (e.g., create-env.ts)
Use camelCase for function names (e.g., createEnv)
Use PascalCase for type names (e.g., ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
Use ArkEnvError for environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type

**/*.{ts,tsx}: Use createEnv(schema) as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) from src/types.ts when available instead of custom validation
Use ArkEnvError for environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...

Files:

  • packages/arkenv/src/utils/coerce.ts
packages/arkenv/src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Main library implementation should be in src/create-env.ts, built-in validators in src/types.ts, error handling in src/errors.ts, and utilities in src/utils.ts

Files:

  • packages/arkenv/src/utils/coerce.ts
**/*.{ts,tsx,json,md}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Biome for linting and formatting instead of ESLint and Prettier

Files:

  • packages/arkenv/src/utils/coerce.ts
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use ArkType's `type()` function to define schemas in environment variable definitions

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's type inference for TypeScript types instead of manual type definitions

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use the scoped `$` type system for custom types defined in `scope.ts`

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
🧬 Code graph analysis (1)
packages/arkenv/src/utils/coerce.ts (1)
packages/internal/keywords/src/index.ts (2)
  • maybeParsedNumber (11-16)
  • maybeParsedBoolean (45-49)
🔇 Additional comments (3)
packages/arkenv/src/utils/coerce.ts (3)

1-1: LGTM!

The imports correctly reference the coercion morphs from the internal keywords package.


3-16: LGTM!

The internal interface documents the ArkType node structure well and provides type safety within the coercion logic.


18-28: LGTM!

The helper functions correctly identify numeric and boolean nodes using optional chaining and recursive union branch checking.

@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 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
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

🧹 Nitpick comments (1)
packages/arkenv/src/utils/coerce.test.ts (1)

6-111: Consider additional edge case tests for robustness.

The test suite is comprehensive for common scenarios. For increased robustness, you might consider adding tests for edge cases such as:

  • Empty strings ("")
  • Whitespace-only strings (" ")
  • Invalid inputs that should fail coercion (e.g., "abc" for numbers)
  • Nested object structures with mixed coercible properties

However, the current coverage is solid for the main use cases of the coerce utility.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dfaf69a and c00dbec.

📒 Files selected for processing (2)
  • packages/arkenv/src/utils/coerce.test.ts (1 hunks)
  • packages/arkenv/src/utils/coerce.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/arkenv/src/utils/coerce.ts
🧰 Additional context used
📓 Path-based instructions (5)
packages/arkenv/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/arktype.mdc)

packages/arkenv/**/*.ts: Use ArkType's type() function to define schemas in environment variable definitions
Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Use the scoped $ type system for custom types defined in scope.ts
Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Use union types for enums in ArkType schemas (e.g., "'dev' | 'prod'") instead of separate enum definitions
Leverage ArkType's built-in types (e.g., string.host, number.port) where possible in environment schemas
Convert ArkType validation errors to ArkEnvError for user-friendly error messages that include variable name and expected type

Files:

  • packages/arkenv/src/utils/coerce.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

**/*.{ts,tsx}: Prefer type over interface for type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverage const type parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypes error)
Use as const where appropriate for immutable values (useAsConstAssertion error)
Don't reassign function parameters (noParameterAssign error)
Place default parameters last in function signatures (useDefaultParameterLast error)
Always initialize enum values (useEnumInitializers error)
Declare one variable per statement (useSingleVarDeclarator error)
Avoid unnecessary template literals (noUnusedTemplateLiteral error)
Prefer Number.parseInt over global parseInt (useNumberNamespace error)
Use kebab-case for TypeScript filenames (e.g., create-env.ts)
Use camelCase for function names (e.g., createEnv)
Use PascalCase for type names (e.g., ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
Use ArkEnvError for environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type

**/*.{ts,tsx}: Use createEnv(schema) as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) from src/types.ts when available instead of custom validation
Use ArkEnvError for environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...

Files:

  • packages/arkenv/src/utils/coerce.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Co-locate tests with components: Component.tsx next to Component.test.tsx

**/*.test.{ts,tsx}: Test individual functions, components, and hooks in isolation with mocked dependencies using the *.test.ts or *.test.tsx suffix
Mock process.env in tests for different scenarios and save/restore original env in beforeEach/afterEach hooks
Use Vitest's describe/it structure in test files
Test edge cases including invalid and missing environment variable values
Use Vitest for testing framework

**/*.test.{ts,tsx}: Use Vitest for unit and integration tests
Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Unit tests should execute in less than 100ms per test
Mock external dependencies (clipboard, network, etc.) in unit tests
Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)
Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Use Testing Library with user-event for real user simulation in component tests
Query by role, name, label, and text (accessibility first) in component tests
Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible
Keep tests fast, deterministic, and parallelizable
Mock at component boundaries (network, time, context)

Files:

  • packages/arkenv/src/utils/coerce.test.ts
packages/arkenv/src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Main library implementation should be in src/create-env.ts, built-in validators in src/types.ts, error handling in src/errors.ts, and utilities in src/utils.ts

Files:

  • packages/arkenv/src/utils/coerce.test.ts
**/*.{ts,tsx,json,md}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Biome for linting and formatting instead of ESLint and Prettier

Files:

  • packages/arkenv/src/utils/coerce.test.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use ArkType's `type()` function to define schemas in environment variable definitions

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to packages/arkenv/src/**/*.ts : Main library implementation should be in `src/create-env.ts`, built-in validators in `src/types.ts`, error handling in `src/errors.ts`, and utilities in `src/utils.ts`

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's type inference for TypeScript types instead of manual type definitions

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests

Applied to files:

  • packages/arkenv/src/utils/coerce.test.ts
🧬 Code graph analysis (1)
packages/arkenv/src/utils/coerce.test.ts (2)
packages/arkenv/src/type.ts (1)
  • type (3-3)
packages/arkenv/src/utils/coerce.ts (1)
  • coerce (39-93)
🔇 Additional comments (8)
packages/arkenv/src/utils/coerce.test.ts (8)

1-3: LGTM!

Imports are correct and follow project conventions. All imports are properly used throughout the test suite.


5-5: LGTM!

Test suite structure follows Vitest conventions and coding guidelines. Tests are well-organized and progress logically from basic to complex scenarios.


6-39: LGTM!

Numeric coercion tests are comprehensive and well-structured. They properly validate both successful coercion and constraint validation, ensuring that string-to-number conversion happens before applying numeric constraints.


41-48: LGTM!

Boolean coercion test correctly validates string-to-boolean conversion for the standard "true" and "false" strings.


50-57: LGTM!

Optional property test correctly validates that coercion works with optional properties while preserving optional semantics.


59-66: LGTM!

Root-level primitive test correctly validates that coercion works on schemas that aren't object types, which is an important edge case for the utility.


68-75: LGTM!

Strict number literals test validates that numeric literal unions work correctly with coercion, including proper passthrough of actual numeric values.


77-111: LGTM!

Mixed union tests comprehensively validate coercion behavior in complex type scenarios. The tests properly cover both root-level and property-level unions, including success and error paths.

…lid string inputs for numbers and booleans, and nested object coercion.
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arkenv Changes to the `arkenv` npm package. docs Improvements or additions to documentation tests This issue or PR is about adding, removing or changing tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Global schema transformer

1 participant