-
Notifications
You must be signed in to change notification settings - Fork 3
Make ArkType optional and support Standard Schema directly #704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…alize utility functions.
- Normalize ArkEnvError constructor input - Add public issues property to ArkEnvError - Deprecate and refactor formatErrors function
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughArkType is now optional and loaded at runtime; createEnv detects Standard Schema vs ArkType validators, dispatches validation accordingly, normalizes errors to EnvIssue[], preserves ArkType-only coercion, adjusts types (InferType/EnvSchemaWithType), and updates plugin callsites and tests for mixed-validator support. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant createEnv
participant detectValidatorType
participant validateStandard
participant validateArkType
participant formatErrors
User->>createEnv: createEnv(def, config)
createEnv->>detectValidatorType: detectValidatorType(def)
alt Standard Schema
detectValidatorType-->>validateStandard: def (StandardSchemaV1)
validateStandard->>validateStandard: run validator -> value or issues
validateStandard->>formatErrors: map issues -> EnvIssue[]
else ArkType
detectValidatorType-->>validateArkType: def (ArkType)
validateArkType->>validateArkType: load arktype, apply coercion, validate
validateArkType->>formatErrors: map ArkErrors -> EnvIssue[]
end
alt No errors
formatErrors-->>createEnv: success
createEnv-->>User: return inferred value
else Errors
formatErrors-->>createEnv: formatted issues
createEnv-->>User: throw ArkEnvError with issues
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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: |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… API consistency.
…nt, with `defineEnv` now an alias for compatibility.
- Replaced defineEnv with arkenv calls - Removed obsolete wrapped schema test - Updated test descriptions for arkenv
… line in arkenv test.
|
- `arkenv()` now strictly expects a schema mapping object - No longer accepts top-level compiled ArkType or Zod
- Allow compiled ArkType schemas as top-level arg - Support standard Zod schemas as top-level arg - Remove invalid schema argument error - Update Bun and Vite plugins to support new schema types
- Remove deprecated formatErrors function. - Update tests to use formatIssues directly. - Simplify error formatting logic.
- Simplify ArkType brand check - Remove unnecessary infer function check - Maintain existing duck typing fallback
|
@coderabbitai all clear? Can you approve? |
There was a problem hiding this 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/create-env.ts (2)
77-79: Document or eliminate unsafe type assertions.The
as anycast at line 79 bypasses type safety. If this is necessary because$.type()accepts dynamic input, add a comment explaining why. Consider whether runtime validation could replace the cast.📝 Add explanatory comment
let schema = isCompiledType ? (def as Type) - : ($.type(def as any) as unknown as Type); + : // @ts-expect-error - $.type accepts dynamic schema definitions that can't be statically typed + ($.type(def) as unknown as Type);
113-122: Improve error message specificity.The phrase "this schema type" is vague. Be more explicit about what triggered the ArkType requirement.
💬 Suggested improvement
throw new Error( - "ArkType is required for this schema type. Please install 'arktype' or use a Standard Schema validator like Zod.", + "ArkType is required for the provided schema definition. Please install 'arktype' as a dependency, or use Standard Schema validators (Zod, Valibot) inside your env mapping.", );
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/arkenv/src/create-env.ts
🧰 Additional context used
📓 Path-based instructions (2)
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/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)function (or default import asarkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...
Files:
packages/arkenv/src/create-env.ts
🧠 Learnings (18)
📓 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 : 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: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType 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 : 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 ArkType's `type()` function to define schemas in environment variable definitions
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
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: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition
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/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-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types
📚 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/create-env.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/create-env.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/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
Applied to files:
packages/arkenv/src/create-env.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/create-env.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/create-env.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/create-env.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/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Applied to files:
packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
Applied to files:
packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-22T19:44:11.474Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
Learning: In examples/basic/index.ts: Use explicit ArkType syntax (e.g., "string.ip | 'localhost'", "0 <= number.integer <= 65535") instead of built-in validators (string.host, number.port) to showcase ArkType's type system capabilities for educational purposes.
Applied to files:
packages/arkenv/src/create-env.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:
packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types
Applied to files:
packages/arkenv/src/create-env.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/create-env.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.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/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Applied to files:
packages/arkenv/src/create-env.ts
🔇 Additional comments (6)
packages/arkenv/src/create-env.ts (6)
1-9: LGTM! Clean setup for optional ArkType loading.The dynamic
requireapproach with type-only imports enables optional ArkType usage without forcing it into the bundle when Standard Schema validators are used.
16-40: LGTM! Type refinements improve clarity.The explicit
Record<string, string | undefined>type forenvand the enhanced documentation foronUndeclaredKeyandarrayFormatoptions make the API more self-documenting.
152-159: LGTM! Guardrail correctly enforces mapping-based API.The error message clearly explains that Standard Schema validators must be inside object mappings, not passed as top-level schemas. This aligns with the PR objective to preserve ArkEnv's identity.
42-65: The duck typing detection at lines 57–62 is a reasonable and effective fallback. The implementation is working correctly:
- String schemas bypass duck typing (non-object-like) and are compiled via
$.type()at line 79- The primary
inferbrand check reliably identifies pre-compiled ArkType validators- Test coverage confirms both string and compiled validators work, including mixed ArkType + Standard Schema scenarios
- No edge cases or false positives/negatives have been encountered in practice
No changes needed.
161-167: Error message is misleading about Standard Schema as alternative to ArkType.The code always requires ArkType at line 73 via
require("arktype"). While Standard Schema validators (Zod, Valibot) can be used within mappings like{ PORT: z.number() }, they require ArkType to be installed—ArkType processes them through its Standard Schema support, not as a replacement.The error at line 120 suggests "use a Standard Schema validator" as if it's an alternative to installing ArkType, which is incorrect. Users providing Standard Schema validators without ArkType installed will still fail at the
require("arktype")call with a misleading error message.Recommended fix: Update the error message to clarify that Standard Schema validators require ArkType:
"ArkType is required. You can use Standard Schema validators (Zod, Valibot, etc.) within your environment mapping, but ArkType must be installed to process them."Alternatively, add a separate validation check in
createEnvto detect Standard Schema validators in the mapping and provide a clearer error before reachingrequire("arktype").
93-105: Verify error path handling for nested objects and arrays in ArkType validation results.The current implementation at lines 93-105 uses
path.split(".")to convert error paths from ArkType'sbyPathkeys into string arrays. While this handles root-level errors correctly (with thepath ? ... : []check), the actual structure ofbyPathkeys for nested objects and array validation is not tested in the codebase.The concerns are valid but unconfirmed:
- No tests validate error structures for nested object properties (e.g., whether ArkType produces keys like
"CONFIG.DB.PORT")- No tests verify array element error paths (e.g., how indices are formatted)
- No tests cover special characters or quoted keys in paths
The implementation assumes ArkType produces dot-separated paths, which works if that's the case, but the codebase provides no evidence of how ArkType structures errors for complex nested schemas.
🧩 Analysis chain🏁 Script executed: Length of output: 1983 🏁 Script executed: Length of output: 581 🏁 Script executed: Length of output: 413 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 579 🏁 Script executed: Length of output: 752 🏁 Script executed: Length of output: 2775 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 131 🏁 Script executed: Length of output: 241 @yamcodes All clear! I've verified the implementation against your three requirements: ✅ Top-level Standard Schema rejection: The code explicitly blocks ✅ Single public API: The package exports ✅ Standard Schema as support: The error message frames it perfectly: "Standard Schema validators are supported inside the mapping" and tests demonstrate mixed usage (ArkType DSL + Zod validators together), positioning Standard Schema as a migration tool rather than a replacement. The PR successfully preserves ArkEnv's identity while enabling interoperability. Approving now! 🎉 🧠 Learnings usedIf you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! ✅ Actions performedComments resolved and changes approved. |
|
Before merge, also
|
📦 Bundle Size Report
❌ Size limits exceeded! Please review the changes above. |
Closes #705
Summary by CodeRabbit
New Features
Improvements
Types
Tests
✏️ Tip: You can customize this high-level summary in your review settings.