Conversation
…variable coercion.
…or using preprocessing for coercion.
…aw schema definitions.
…/github.com/yamcodes/ark.env into 228-coercion-stringnumber-stringboolean-etc
…m Bun build config.
… add related playground tests.
…ypes and include verification tests.
🦋 Changeset detectedLatest commit: 8ce91d5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds scope-level coercion so arkenv accepts string inputs for Changes
Sequence DiagramsequenceDiagram
participant App as User/App
participant Env as arkenv()
participant Scope as Scope (coerced keywords)
participant Type as ArkType Validation
participant Result as Validated Env
App->>Env: call arkenv(schema) with string env values
Env->>Env: read raw env (strings)
Env->>Type: invoke validation(parse) with schema
Type->>Scope: resolve "number"/"boolean" keywords
Scope->>Scope: coercedNumber("3000") => 3000
Scope->>Scope: coercedBoolean("true") => true
Type->>Type: validate coerced values against constraints
Type->>Result: return typed env object
Result->>App: { PORT: 3000, DEBUG: true }
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related issues
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
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. Comment |
commit: |
📦 Bundle Size Report
✅ All size limits passed! |
…-dom, and arkregex dependencies.
…bles and complex type definitions
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (7)
examples/basic/.env.example (1)
2-2: Add a blank line at the end of the file.The file is missing a trailing newline, which is a common convention for text files and is expected by formatting tools.
🔎 Proposed fix
HOST=localhost PORT=3000 +.changeset/humble-lizards-judge.md (1)
7-7: Consider adding a reference to the new coercion documentation.To help users transition smoothly, consider adding a link to the arkenv coercion documentation or a brief note explaining how the new scope-based coercion works with
numberandbooleantypes. This would give users immediate guidance on the recommended migration path.apps/playgrounds/node/index.ts (1)
1-19: LGTM! Clean implementation of env schema with coercion.The simplified structure effectively demonstrates arkenv usage with proper built-in validators and default values. The changes remove unnecessary complexity while maintaining type safety.
Based on learnings: Uses built-in validators (string.host, number.port), union types for enums, and follows the ArkType schema pattern.
💡 Optional: Enhance coercion demonstration
Since this PR introduces coercion for
numberandbooleantypes, consider adding comments that explicitly highlight this behavior:const env = arkenv({ HOST: "string.host", - PORT: "number.port", + PORT: "number.port", // Coerces string "8080" → number 8080 NODE_ENV: "'development' | 'production' | 'test' = 'development'", - DEBUG: "boolean = true", + DEBUG: "boolean = true", // Coerces string "true"/"false" → boolean });This would make the coercion feature more apparent to users exploring the playground.
examples/basic/index.ts (2)
1-19: LGTM! Follows arkenv patterns correctly.The example demonstrates clean usage of arkenv with appropriate built-in validators and default values. The implementation follows all coding guidelines and leverages ArkType's syntax effectively.
Based on learnings: Uses built-in validators, maintains readable schema syntax, and demonstrates real-world usage patterns.
💡 Optional: Strengthen coercion demonstration for example
Since this PR introduces coercion and this file serves as a basic example, consider making the coercion behavior more explicit:
// Automatically validate and parse process.env // TypeScript knows the ✨exact✨ types! +// Environment variables (strings) are automatically coerced to target types: +// - PORT: string "8080" → number 8080 +// - DEBUG: string "true" → boolean true console.log({ host: env.HOST, - port: env.PORT, + port: env.PORT, // type: number (coerced from string) - nodeEnv: env.NODE_ENV, + nodeEnv: env.NODE_ENV, // type: "development" | "production" | "test" - debug: env.DEBUG, + debug: env.DEBUG, // type: boolean (coerced from string) });Alternatively, add type verification:
console.log({ host: env.HOST, port: env.PORT, nodeEnv: env.NODE_ENV, debug: env.DEBUG, // Demonstrate coercion: portType: typeof env.PORT, // "number" debugType: typeof env.DEBUG, // "boolean" });This would better showcase the coercion feature that is the focus of this PR.
1-19: Note: Code duplication with playground.This file is identical to
apps/playgrounds/node/index.ts. While having separate example and playground files is a common pattern, consider whether they need to remain in sync or if they should demonstrate different aspects of arkenv.packages/internal/keywords/src/index.ts (1)
6-14: Consider simplifying port to accept onlynumbertype.The
porttype currently acceptsstring | numberand includes string-to-number parsing logic. However, sincepackages/internal/scope/src/index.ts(line 77) wraps all number keywords withcoercedNumber, string inputs are already coerced to numbers before reaching theportvalidator. This makes the string handling at line 7 unreachable code whenportis used through the$scope.🔎 Simplified implementation
/** - * A `number` (or a `string` that can be parsed into a `number`) between 0 and 65535 + * A `number` between 0 and 65535 */ -export const port = type("string | number", "=>", (data, ctx) => { - const asNumber = typeof data === "string" ? Number.parseInt(data, 10) : data; +export const port = type("number", "=>", (data, ctx) => { const isInteger = Number.isInteger(asNumber); const isBetween = 0 <= asNumber && asNumber <= 65535; if (!isInteger || !isBetween) { ctx.mustBe("an integer between 0 and 65535"); } - return asNumber; + return data; });Note: Only apply this change if
portis exclusively used through the wrapped scope. If there are direct usages outside the scope that rely on string input handling, keep the current implementation.packages/internal/scope/src/index.ts (1)
29-41: Consider supporting additional boolean string variants.The
coercedBooleanimplementation only accepts literal"true"and"false"strings (lines 32-33). Common environment variable patterns also use"1"/"0","yes"/"no","on"/"off", or case variations like"True"/"FALSE".The current strict behavior may be intentional for type safety and clarity. However, if broader compatibility with common environment variable conventions is desired, consider extending the coercion logic:
🔎 Extended boolean coercion example
const coercedBoolean = type("string | boolean") .pipe((s) => { if (typeof s === "boolean") return s; - if (s === "true") return true; - if (s === "false") return false; + const lower = s.toLowerCase(); + if (lower === "true" || lower === "1" || lower === "yes" || lower === "on") return true; + if (lower === "false" || lower === "0" || lower === "no" || lower === "off") return false; return s; }) .narrow((data, ctx): data is boolean => { if (typeof data !== "boolean") { return ctx.mustBe("a boolean"); } return true; });If the strict behavior is preferred, consider documenting this decision to guide users on expected boolean string formats.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
examples/with-bun-react/bun.lockis excluded by!**/*.lockexamples/with-bun/bun.lockis excluded by!**/*.lock
📒 Files selected for processing (17)
.changeset/cyan-loops-hear.md(1 hunks).changeset/humble-lizards-judge.md(1 hunks).changeset/plain-webs-dig.md(1 hunks)apps/playgrounds/node/.env.example(1 hunks)apps/playgrounds/node/index.ts(1 hunks)examples/basic/.env.example(1 hunks)examples/basic/index.ts(1 hunks)openspec/changes/add-coercion/design.md(1 hunks)openspec/changes/add-coercion/proposal.md(1 hunks)openspec/changes/add-coercion/specs/coercion/spec.md(1 hunks)openspec/changes/add-coercion/tasks.md(1 hunks)packages/arkenv/README.md(1 hunks)packages/arkenv/src/coercion.integration.test.ts(1 hunks)packages/arkenv/src/create-env.test.ts(1 hunks)packages/arkenv/src/create-env.ts(1 hunks)packages/internal/keywords/src/index.ts(1 hunks)packages/internal/scope/src/index.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
packages/arkenv/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/arktype.mdc)
packages/arkenv/**/*.ts: Use ArkType'stype()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 inscope.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 toArkEnvErrorfor user-friendly error messages that include variable name and expected type
Files:
packages/arkenv/src/coercion.integration.test.tspackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype 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 (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
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
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) fromsrc/types.tswhen available instead of custom validation
UseArkEnvErrorfor 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.tspackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.tspackages/internal/keywords/src/index.tsapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Co-locate tests with components:
Component.tsxnext toComponent.test.tsx
**/*.test.{ts,tsx}: Test individual functions, components, and hooks in isolation with mocked dependencies using the*.test.tsor*.test.tsxsuffix
Mockprocess.envin tests for different scenarios and save/restore original env inbeforeEach/afterEachhooks
Use Vitest'sdescribe/itstructure 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.tspackages/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.tsor*.integration.test.tsxsuffix 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 insrc/types.ts, error handling insrc/errors.ts, and utilities insrc/utils.ts
Files:
packages/arkenv/src/coercion.integration.test.tspackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.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.tsopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.mdopenspec/changes/add-coercion/tasks.mdpackages/arkenv/src/create-env.test.tsopenspec/changes/add-coercion/specs/coercion/spec.mdpackages/arkenv/src/create-env.tspackages/internal/keywords/src/index.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.ts
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/add-coercion/proposal.md
openspec/changes/*/tasks.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Create tasks.md with numbered implementation checklist items as checkboxes (- [ ] format)
Files:
openspec/changes/add-coercion/tasks.md
openspec/changes/*/specs/**/spec.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/changes/*/specs/**/spec.md: Use ## ADDED|MODIFIED|REMOVED|RENAMED Requirements as delta headers in spec.md files under changes
Ensure change proposals contain delta specs for each affected capability under changes/[change-id]/specs/[capability]/spec.md
Files:
openspec/changes/add-coercion/specs/coercion/spec.md
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/changes/add-coercion/specs/coercion/spec.md
**/index.ts
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Use barrel exports (
index.ts) for package entry points
Files:
packages/internal/keywords/src/index.tsapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.ts
**/README.md
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Document environment requirements in README files
Files:
packages/arkenv/README.md
{bin,examples,playgrounds}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Console usage is allowed in
bin/and example/playground directories, otherwise treated as warning
Files:
examples/basic/index.ts
examples/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
examples/**/*.{ts,tsx}: Ensure examples demonstrate secure default practices
Add examples in theexamples/directory for new functionality, demonstrating real-world usage patterns
Files:
examples/basic/index.ts
🧠 Learnings (33)
📓 Common learnings
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/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
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 : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
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
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
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
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
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
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 : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Applied to files:
.changeset/cyan-loops-hear.mdpackages/arkenv/src/coercion.integration.test.tsopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.md.changeset/plain-webs-dig.mdopenspec/changes/add-coercion/tasks.mdpackages/arkenv/src/create-env.test.tsopenspec/changes/add-coercion/specs/coercion/spec.mdpackages/arkenv/src/create-env.tspackages/internal/keywords/src/index.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdpackages/arkenv/src/coercion.integration.test.tsopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.mdpackages/arkenv/src/create-env.test.tsopenspec/changes/add-coercion/specs/coercion/spec.mdpackages/arkenv/src/create-env.tspackages/internal/keywords/src/index.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.mdpackages/arkenv/src/create-env.test.tsopenspec/changes/add-coercion/specs/coercion/spec.mdpackages/arkenv/src/create-env.tspackages/internal/keywords/src/index.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdpackages/arkenv/src/coercion.integration.test.tsopenspec/changes/add-coercion/proposal.mdpackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdpackages/arkenv/src/coercion.integration.test.tsopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.md.changeset/plain-webs-dig.mdpackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.tspackages/internal/keywords/src/index.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdopenspec/changes/add-coercion/proposal.mdpackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.ts
📚 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:
.changeset/cyan-loops-hear.mdopenspec/changes/add-coercion/proposal.mdpackages/arkenv/src/create-env.test.tspackages/arkenv/src/create-env.tspackages/arkenv/README.mdapps/playgrounds/node/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.mdpackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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:
.changeset/cyan-loops-hear.mdpackages/arkenv/src/coercion.integration.test.tsopenspec/changes/add-coercion/proposal.mdopenspec/changes/add-coercion/design.mdpackages/arkenv/src/create-env.test.tsopenspec/changes/add-coercion/specs/coercion/spec.mdpackages/arkenv/src/create-env.tspackages/arkenv/README.mdapps/playgrounds/node/index.tsexamples/basic/index.ts
📚 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 PascalCase for type names (e.g., `ArkEnvError`)
Applied to files:
.changeset/cyan-loops-hear.md
📚 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.tspackages/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} : 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-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-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-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 **/*.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 **/*.test.{ts,tsx} : Use Vitest's `describe`/`it` structure in test files
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 **/*.test.{ts,tsx} : Use Vitest for unit and 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 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
📚 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/changes/add-coercion/proposal.mdpackages/arkenv/src/create-env.tspackages/arkenv/README.mdapps/playgrounds/node/index.tspackages/internal/scope/src/index.tsexamples/basic/index.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/changes/add-coercion/design.md.changeset/plain-webs-dig.mdpackages/internal/scope/src/index.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:
openspec/changes/add-coercion/design.md.changeset/plain-webs-dig.mdopenspec/changes/add-coercion/tasks.mdpackages/internal/scope/src/index.ts
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/changes/*/tasks.md : Create tasks.md with numbered implementation checklist items as checkboxes (- [ ] format)
Applied to files:
openspec/changes/add-coercion/tasks.md
📚 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/create-env.test.tsapps/playgrounds/node/index.tsexamples/basic/index.ts
📚 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} : Provide clear, actionable error messages that include the variable name and expected type
Applied to files:
packages/arkenv/src/create-env.test.ts
📚 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} : Prefer `Number.parseInt` over global `parseInt` (`useNumberNamespace` error)
Applied to files:
packages/arkenv/src/create-env.test.tspackages/internal/keywords/src/index.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/create-env.tsapps/playgrounds/node/index.tsexamples/basic/index.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 built-in validators (host, port, url, email) from `src/types.ts` when available instead of custom validation
Applied to files:
packages/internal/keywords/src/index.ts
📚 Learning: 2025-09-10T19:35:18.179Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 136
File: .changeset/vast-bananas-win.md:2-3
Timestamp: 2025-09-10T19:35:18.179Z
Learning: The arkenv package is currently in v0.x.x (pre-1.0) development phase, where breaking changes are acceptable in minor version bumps according to semantic versioning conventions.
Applied to files:
packages/arkenv/README.md
📚 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: Never modify `.env` files in examples or apps - these may contain sensitive configuration
Applied to files:
apps/playgrounds/node/.env.exampleexamples/basic/.env.example
📚 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 UPPER_SNAKE_CASE for environment variables and constants
Applied to files:
apps/playgrounds/node/index.tsexamples/basic/index.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 descriptive environment variable names that indicate purpose and format
Applied to files:
examples/basic/.env.exampleexamples/basic/index.ts
🧬 Code graph analysis (6)
packages/arkenv/src/coercion.integration.test.ts (2)
packages/arkenv/src/create-env.ts (1)
createEnv(35-52)packages/arkenv/src/type.ts (1)
type(3-3)
packages/arkenv/src/create-env.ts (2)
packages/internal/scope/src/index.ts (2)
$(71-81)$(83-83)packages/arkenv/src/index.ts (1)
EnvSchema(1-1)
packages/internal/keywords/src/index.ts (1)
packages/arkenv/src/type.ts (1)
type(3-3)
apps/playgrounds/node/index.ts (1)
packages/vite-plugin/src/index.ts (1)
arkenv(49-86)
packages/internal/scope/src/index.ts (1)
packages/arkenv/src/type.ts (1)
type(3-3)
examples/basic/index.ts (3)
apps/playgrounds/js/index.js (1)
env(3-7)examples/basic-js/index.js (1)
env(3-7)packages/vite-plugin/src/index.ts (1)
arkenv(49-86)
🪛 dotenv-linter (4.0.0)
apps/playgrounds/node/.env.example
[warning] 2-2: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
examples/basic/.env.example
[warning] 2-2: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
🪛 markdownlint-cli2 (0.18.1)
.changeset/cyan-loops-hear.md
13-13: Hard tabs
Column: 1
(MD010, no-hard-tabs)
openspec/changes/add-coercion/proposal.md
26-26: Multiple headings with the same content
(MD024, no-duplicate-heading)
🔇 Additional comments (13)
.changeset/humble-lizards-judge.md (1)
1-7: Changeset correctly documents the breaking change with a clear migration path.The YAML front matter is properly formatted, the breaking change is clearly marked, and users are guided toward both the standard ArkType
booleankeyword and the new arkenv coercion feature. Approved.apps/playgrounds/node/.env.example (1)
1-2: Clarify the removal ofNODE_ENV,DEBUG, andZED_ENVvariables.The changes remove three environment variables without documented justification. Based on learnings in the repository,
.envfiles in examples should be carefully managed, especially when removing previously required configuration.Please verify:
- Whether the playground still functions correctly without
NODE_ENV,DEBUG, andZED_ENV.- Whether this simplification is intentional for the coercion example, or if these variables are still required.
- Update documentation or comments if this removal is intentional to avoid confusion for developers using the example.
packages/arkenv/src/create-env.test.ts (1)
65-65: LGTM! Improved error message specificity.The updated error message now shows the exact string value with quotes, making it clearer what value failed validation. This improves the developer experience when debugging type mismatches.
.changeset/plain-webs-dig.md (1)
1-9: LGTM! Clear and concise changeset.The changeset properly documents the scope-based coercion feature with appropriate detail for a patch-level change.
openspec/changes/add-coercion/tasks.md (1)
1-8: LGTM! Well-structured task checklist.The task list follows the required format and comprehensively covers both implementation and verification steps for the coercion feature.
Based on learnings, the format adheres to the guideline for openspec/changes/*/tasks.md files.
packages/arkenv/README.md (1)
62-76: LGTM! Excellent documentation addition.The Coercion section clearly explains the automatic type conversion feature with practical examples. The placement and formatting are appropriate for user-facing documentation.
openspec/changes/add-coercion/specs/coercion/spec.md (1)
1-42: LGTM! Well-structured specification.The specification follows the required format with proper delta headers (## ADDED Requirements), uses MUST for normative requirements, and includes clear Given-When-Then scenarios for each requirement.
As per coding guidelines, the spec properly uses delta headers for change proposals.
packages/arkenv/src/create-env.ts (1)
41-44: LGTM! Good readability improvement.Extracting the compiled type check into a named boolean variable improves code clarity without changing behavior. The added comment also helps document the validation step.
openspec/changes/add-coercion/proposal.md (1)
1-29: Good proposal structure and content.The proposal clearly articulates the problem, shows practical before/after examples, and explains the scope-based solution approach. The content effectively communicates the value of the coercion feature.
.changeset/cyan-loops-hear.md (1)
1-31: Good changeset documentation.The changeset clearly documents the Native Coercion Support feature with practical examples showing usage and expected results. Well-written for end users.
packages/arkenv/src/coercion.integration.test.ts (1)
1-96: Excellent integration test coverage!The test suite comprehensively validates the coercion feature across multiple scenarios:
- Basic number and boolean coercion
- Number subtypes (port, integer, epoch)
- Error cases (invalid strings, out-of-range values)
- Mixed coerced and non-coerced schemas
- Compiled type definitions
- Natural type inputs without coercion
The tests appropriately verify interactions between
createEnv,type, and the scope's coercion logic without mocking, which aligns with integration test best practices.openspec/changes/add-coercion/design.md (1)
1-46: Clear design documentation.The design document provides a well-structured explanation of the scope-based coercion approach, including architecture flow, decision rationale, and implementation guidance. The documented approach aligns with the actual implementation in
packages/internal/scope/src/index.tsandpackages/internal/keywords/src/index.ts.packages/internal/scope/src/index.ts (1)
11-22: The NaN handling and narrow check are correct.When
Number(s)producesNaN(line 15), the string is returned and passed to thenarrow()check, which rejects it with "must be a number". This prevents any non-numeric strings from reaching number sub-keywords (likenumber.port,number.integer,number.epoch) because thewrapModulefunction pipescoercedNumberinto each sub-keyword, ensuring the narrow check always validates output before sub-keyword processing. The implementation is safe and properly guards sub-keywords from receiving invalid string values.
…oolean coercion, and add known limitations with workarounds.
…kKind` validation for sub-keywords.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/internal/scope/src/index.ts (2)
11-22: Consider clarifying the NaN handling logic.The ternary on line 15 returns the original string
swhenNumber.isNaN(n)is true, which then gets rejected by the.narrow()validator. While this follows ArkType's pattern of letting validation happen in.narrow(), the logic could be more explicit about the failure path.Alternative: Add a comment to clarify intent
const coercedNumber = type("string | number") .pipe((s) => { if (typeof s === "number") return s; const n = Number(s); + // Return original string if conversion fails; narrow() will reject it return Number.isNaN(n) ? s : n; }) .narrow((data, ctx): data is number => { if (typeof data !== "number") { return ctx.mustBe("a number"); } return true; });
24-34: LGTM with a minor naming suggestion.The coercion logic correctly handles both string and boolean inputs. The parameter name
strmight be slightly misleading since the input can be a boolean, but the implementation is correct.Optional: Rename parameter for clarity
const coercedBoolean = type( "'true' | 'false' | true | false", "=>", - (str) => str === "true" || str === true, + (value) => value === "true" || value === true, );
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.changeset/cyan-loops-hear.md(1 hunks)apps/playgrounds/node/.env.example(0 hunks)examples/basic/.env.example(0 hunks)openspec/changes/add-coercion/proposal.md(1 hunks)packages/internal/scope/src/index.ts(2 hunks)
💤 Files with no reviewable changes (2)
- examples/basic/.env.example
- apps/playgrounds/node/.env.example
🚧 Files skipped from review as they are similar to previous changes (2)
- openspec/changes/add-coercion/proposal.md
- .changeset/cyan-loops-hear.md
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype 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 (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
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
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) fromsrc/types.tswhen available instead of custom validation
UseArkEnvErrorfor 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/internal/scope/src/index.ts
**/index.ts
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Use barrel exports (
index.ts) for package entry points
Files:
packages/internal/scope/src/index.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/internal/scope/src/index.ts
🧠 Learnings (12)
📓 Common learnings
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/**/*.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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across 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 : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
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 : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
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`
📚 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/internal/scope/src/index.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/internal/scope/src/index.ts
📚 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 `as const` where appropriate for immutable values (`useAsConstAssertion` error)
Applied to files:
packages/internal/scope/src/index.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/internal/scope/src/index.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/internal/scope/src/index.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/internal/scope/src/index.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/internal/scope/src/index.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/internal/scope/src/index.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/internal/scope/src/index.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:
packages/internal/scope/src/index.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/internal/scope/src/index.ts
🧬 Code graph analysis (1)
packages/internal/scope/src/index.ts (1)
packages/arkenv/src/type.ts (1)
type(3-3)
🔇 Additional comments (3)
packages/internal/scope/src/index.ts (3)
1-2: LGTM!The imports correctly bring in the necessary dependencies for the coercion functionality.
75-85: LGTM!The scope integration correctly applies coercion to the
numbermodule (including all its sub-keywords likeintegerandport) and replaces thebooleankeyword with the coerced variant. This aligns with the PR objectives for scope-level coercion of strings to numbers and booleans.
36-70: The runtimearkKindcheck provides sufficient type safety for thepipeoperation.The
as anycasting on line 62 is justified by the complexity of ArkType's internal Module typing. Thepipe()method is a standard feature of ArkType's Type interface, and the runtime checkarkKind === "type"(lines 54–56) verifies that the value is an ArkType instance. All ArkTypes have thepipemethod available by design, so the runtime check provides sufficient guarantees. The explanatory comment adequately documents why the cast is necessary, making this a pragmatic solution to the typing limitations without introducing runtime safety risks.
Closes #566
Summary by CodeRabbit
New Features
Breaking Changes
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.