Skip to content

fix(coerce): support schemas with morphs#593

Merged
yamcodes merged 2 commits intocoercionfrom
592-coercion-fix-manual-morphs-pipes
Dec 22, 2025
Merged

fix(coerce): support schemas with morphs#593
yamcodes merged 2 commits intocoercionfrom
592-coercion-fix-manual-morphs-pipes

Conversation

@yamcodes
Copy link
Owner

@yamcodes yamcodes commented Dec 22, 2025

  • Correctly process in schema for coercion
  • Add tests for createEnv with morphed schemas
  • Add tests for coerce utility with morphed schemas

Summary by CodeRabbit

  • Bug Fixes

    • Environment variable coercion now correctly handles schemas containing type transformations and pipes without errors.
  • Documentation

    • Updated schema introspection methodology to explain input-side schema analysis approach.
    • Added guidance on union handling during coercion.
  • Tests

    • Added comprehensive test coverage for schemas with transformations across multiple test suites.

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

- Correctly process `in` schema for coercion
- Add tests for createEnv with morphed schemas
- Add tests for coerce utility with morphed schemas
@changeset-bot
Copy link

changeset-bot bot commented Dec 22, 2025

⚠️ No Changeset found

Latest commit: c5def82

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link

vercel bot commented Dec 22, 2025

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

Project Deployment Review Updated (UTC)
arkenv Ready Ready Preview, Comment Dec 22, 2025 6:34pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Walkthrough

This PR extends the coercion system to support ArkType morphs (pipe transformations) by switching introspection from schema.toJsonSchema() to schema.in.toJsonSchema(), which inspects only the input side of schemas. Documentation is updated to reflect this change, and test coverage is added to verify the functionality.

Changes

Cohort / File(s) Change Summary
Documentation & Specification
openspec/changes/coercion-public-api/design.md, openspec/changes/coercion-public-api/proposal.md, openspec/specs/coercion/spec.md
Updated design and proposal documents to reference schema.in.toJsonSchema() for introspection instead of schema.toJsonSchema(), with added justification for avoiding ToJsonSchema errors when morphs are present. Specification now includes support for schemas containing morphs and example scenario with manual morph transformation.
Implementation
packages/arkenv/src/utils/coerce.ts
Modified coercion path discovery to use schema.in.toJsonSchema() instead of schema.toJsonSchema(), allowing proper handling of morphs by inspecting the input side of schemas. Downstream logic remains unchanged.
Test Coverage
packages/arkenv/src/coercion.integration.test.ts, packages/arkenv/src/create-env.test.ts, packages/arkenv/src/utils/coerce.test.ts
Added test cases verifying that schemas containing morphs (type transformations via pipes) are correctly coerced, with assertions that manual morph pipelines transform environment variable strings to expected types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Implementation change: Single file modification (coerce.ts) with straightforward introspection source swap, but requires understanding of the .in pathway and morph handling rationale
  • Documentation updates: Multiple files with consistent narrative about the schema introspection change; relatively quick to verify alignment
  • Test additions: Four test files with similar test patterns; homogeneous additions reduce review burden

Possibly related PRs

Poem

🐰 The morphs are tamed, the input side revealed,
No more ToJsonSchema errors sealed,
With pipes and transformations in place,
Environment variables find their space!
Schema.in leads the way so bright,
Coercion works—hoppy day, alright! 🌿

Pre-merge checks and finishing touches

✅ 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 clearly summarizes the main change: fixing coercion to support schemas with morphs, which aligns with the primary objective and changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ 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 592-coercion-fix-manual-morphs-pipes

📜 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 a03eee6 and c5def82.

📒 Files selected for processing (7)
  • openspec/changes/coercion-public-api/design.md
  • openspec/changes/coercion-public-api/proposal.md
  • openspec/specs/coercion/spec.md
  • packages/arkenv/src/coercion.integration.test.ts
  • packages/arkenv/src/create-env.test.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/utils/coerce.ts
🧰 Additional context used
📓 Path-based instructions (8)
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/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.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/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.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/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.test.ts
**/*.integration.test.{ts,tsx}

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

**/*.integration.test.{ts,tsx}: Use integration tests with *.integration.test.ts or *.integration.test.tsx suffix to test how multiple units work together without mocking their interactions
Integration tests should verify interactions between multiple units (like components + hooks + services) without mocking their interactions

**/*.integration.test.{ts,tsx}: Test how multiple units (components, hooks, functions) work together without mocking their interactions in integration tests
Integration tests should focus on component and hook interactions, function composition and data flow, real dependencies between units, and state synchronization across boundaries
Integration tests should execute between 100ms - 2000ms per test
Use *.integration.test.ts suffix to distinguish integration tests from unit tests

Files:

  • packages/arkenv/src/coercion.integration.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/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.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/coercion.integration.test.ts
  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • openspec/changes/coercion-public-api/design.md
  • packages/arkenv/src/create-env.test.ts
openspec/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/**/spec.md: Include at least one scenario per requirement using #### Scenario: header format with WHEN and THEN bullet points
Use SHALL/MUST for normative requirements rather than should/may unless intentionally non-normative

Files:

  • openspec/specs/coercion/spec.md
openspec/changes/*/proposal.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Create proposal.md with sections: Why, What Changes (with BREAKING markers), and Impact

Files:

  • openspec/changes/coercion-public-api/proposal.md
🧠 Learnings (26)
📓 Common learnings
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition
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
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: .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
📚 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/coercion.integration.test.ts
  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • openspec/changes/coercion-public-api/design.md
  • packages/arkenv/src/create-env.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 : Keep environment variable schemas readable and TypeScript-like using ArkType syntax

Applied to files:

  • packages/arkenv/src/coercion.integration.test.ts
  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • openspec/changes/coercion-public-api/design.md
  • packages/arkenv/src/create-env.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 **/*.integration.test.{ts,tsx} : Test how multiple units (components, hooks, functions) work together without mocking their interactions in integration tests

Applied to files:

  • packages/arkenv/src/coercion.integration.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 **/*.integration.test.{ts,tsx} : Integration tests should focus on component and hook interactions, function composition and data flow, real dependencies between units, and state synchronization across boundaries

Applied to files:

  • packages/arkenv/src/coercion.integration.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 **/*.integration.test.{ts,tsx} : Integration tests should verify interactions between multiple units (like components + hooks + services) without mocking their interactions

Applied to files:

  • packages/arkenv/src/coercion.integration.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/coercion.integration.test.ts
  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.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 **/*.integration.test.{ts,tsx} : Use integration tests with `*.integration.test.ts` or `*.integration.test.tsx` suffix to test how multiple units work together without mocking their interactions

Applied to files:

  • packages/arkenv/src/coercion.integration.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/coercion.integration.test.ts
  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • 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/coercion.integration.test.ts
  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • openspec/changes/coercion-public-api/design.md
  • packages/arkenv/src/create-env.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 **/*.integration.test.{ts,tsx} : Use *.integration.test.ts suffix to distinguish integration tests from unit tests

Applied to files:

  • packages/arkenv/src/coercion.integration.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} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export

Applied to files:

  • packages/arkenv/src/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/create-env.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 **/*.test.{ts,tsx} : Test edge cases including invalid and missing environment variable values

Applied to files:

  • packages/arkenv/src/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.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} : Use logical grouping for related environment variables in schemas

Applied to files:

  • packages/arkenv/src/coercion.integration.test.ts
  • packages/arkenv/src/create-env.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 **/*.test.{ts,tsx} : Mock `process.env` in tests for different scenarios and save/restore original env in `beforeEach`/`afterEach` hooks

Applied to files:

  • packages/arkenv/src/coercion.integration.test.ts
  • packages/arkenv/src/create-env.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 packages/vite-plugin/src/**/*.test.ts : Test the Vite plugin using the with-vite-react example as a fixture and validate that the plugin works with real Vite projects

Applied to files:

  • packages/arkenv/src/coercion.integration.test.ts
  • packages/arkenv/src/utils/coerce.test.ts
  • packages/arkenv/src/create-env.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:

  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-12-05T20:33:10.676Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition

Applied to files:

  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • openspec/changes/coercion-public-api/design.md
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors

Applied to files:

  • openspec/specs/coercion/spec.md
  • packages/arkenv/src/create-env.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:

  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • packages/arkenv/src/utils/coerce.ts
  • packages/arkenv/src/create-env.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: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition

Applied to files:

  • openspec/specs/coercion/spec.md
  • openspec/changes/coercion-public-api/proposal.md
  • openspec/changes/coercion-public-api/design.md
  • packages/arkenv/src/create-env.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} : Use `ArkEnvError` for environment variable errors, not generic errors

Applied to files:

  • openspec/specs/coercion/spec.md
📚 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:

  • openspec/changes/coercion-public-api/proposal.md
  • 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 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:

  • openspec/changes/coercion-public-api/proposal.md
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to packages/*/package.json : Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions

Applied to files:

  • openspec/changes/coercion-public-api/proposal.md
📚 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:

  • openspec/changes/coercion-public-api/proposal.md
🧬 Code graph analysis (2)
packages/arkenv/src/coercion.integration.test.ts (2)
packages/arkenv/src/type.ts (1)
  • type (3-3)
packages/arkenv/src/create-env.ts (1)
  • createEnv (36-56)
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 (215-232)
🔇 Additional comments (9)
packages/arkenv/src/utils/coerce.ts (1)

215-217: LGTM! Correct fix for morph support.

The switch to schema.in.toJsonSchema() correctly handles schemas containing morphs by introspecting only the input side. For non-morph schemas, .in returns the schema itself, maintaining backward compatibility.

openspec/specs/coercion/spec.md (1)

54-62: LGTM! Clear specification for morph support.

The requirement and scenario clearly document the expected behavior for schemas containing ArkType morphs. The spec follows the established pattern and provides a concrete, testable scenario.

openspec/changes/coercion-public-api/design.md (2)

7-9: LGTM! Clear documentation of introspection approach.

The documentation correctly explains the use of schema.in.toJsonSchema() and provides clear technical rationale for accessing the input side to handle morphs.


41-46: Excellent rationale for the implementation choice.

The documentation clearly explains:

  1. Why toJsonSchema() is preferred over in.json (standardization and type safety)
  2. Why .in prefix is needed (to avoid errors with morph-containing schemas)

This provides valuable context for future maintainers.

openspec/changes/coercion-public-api/proposal.md (2)

12-12: LGTM! Documentation correctly reflects the implementation.

The proposal accurately describes the use of schema.in.toJsonSchema() and explains its necessity for morph compatibility.


33-33: LGTM! Implementation rules updated correctly.

The strict type safety rule now correctly references schema.in.toJsonSchema() for all introspection, maintaining consistency with the implementation.

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

177-193: LGTM! Comprehensive test coverage for morph support.

The test correctly verifies that:

  1. Automatic coercion works (PORT: "number")
  2. Schemas with morphs are handled correctly (pipe transformation)
  3. Both coercion paths produce the expected numeric results

The test follows existing patterns and provides good coverage of the new functionality.

packages/arkenv/src/create-env.test.ts (1)

79-94: LGTM! Good functional-level test coverage.

This test complements the unit tests by verifying morph support through the createEnv API. Using number.port for PORT provides additional coverage of ArkType subtypes with morphs.

packages/arkenv/src/coercion.integration.test.ts (1)

117-132: LGTM! Comprehensive integration test coverage.

The integration test verifies the complete flow from schema definition through coercion to final validation, ensuring morph support works correctly in realistic usage scenarios. This completes the test coverage at unit, functional, and integration levels.


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 arkenv Changes to the `arkenv` npm package. tests This issue or PR is about adding, removing or changing tests labels Dec 22, 2025
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

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

- Updated introspection to `.in.toJsonSchema()`
- Justified using standard JSON Schema
- Explained `.in` for morph compatibility
-
@github-actions github-actions bot added the docs Improvements or additions to documentation label Dec 22, 2025
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

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

@yamcodes yamcodes merged commit 32522e3 into coercion Dec 22, 2025
5 checks passed
@yamcodes yamcodes deleted the 592-coercion-fix-manual-morphs-pipes branch December 22, 2025 18:37
@yamcodes yamcodes linked an issue Dec 22, 2025 that may be closed by this pull request
@coderabbitai coderabbitai bot mentioned this pull request Jan 4, 2026
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.

Coercion: Fix manual morphs (pipes)

1 participant