Selective Path Coercion (100% Public API Coercion implementation)#576
Selective Path Coercion (100% Public API Coercion implementation)#576yamcodes wants to merge 38 commits into
Conversation
…chema definitions and refinements, and refine various type and regex functionalities.
… handling and new unit tests.
…ort` to use `parsedNumber`, and integrate `port` into the ArkType scope.
…, and enhance `number` and `boolean` coercion in `arkenv`.
…ransformation, supporting numeric refinements.
…ding numeric and boolean values.
…and boolean type coercion and add new playground debug files.
…oerce` utility and remove playground files.
…ve boolean from the root scope.
…t coercion from their definitions and from the `type` export, relying on global coercion instead.
…bers, booleans, ranges, and optional properties.
…lity to improve type inference
…m-lock.yaml to streamline the project
…oolean nodes, improving internal handling and type inference
… and boolean types, enhancing type handling
… boolean types, ensuring correct application order and type handling
…numeric and boolean types, adding warnings for reliance on undocumented ArkType APIs
…e type assertions in the `coerce` function.
…internal type and removing `any` casts.
… `coerce` utility.
…pe union coercion.
|
| Name | Type |
|---|---|
| arkenv | Patch |
| @repo/keywords | Minor |
| @repo/scope | Minor |
| @arkenv/bun-plugin | Patch |
| @arkenv/vite-plugin | Patch |
| @repo/types | Major |
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
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis PR refactors arkenv's coercion mechanism from relying on internal ArkType APIs to using public APIs. It replaces internal schema mutation with a pipeline-based approach that introspects schemas via Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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 |
…rcion to public APIs via `type.pipe` and `schema.in.json`.
…d introduce a PoC for generic path-based coercion.
…schema introspection and data-level coercion, removing reliance on internal APIs and updating documentation.
…ted playground files.
…arsing keywords and internal ArkType API usage, and simplifying the `port` keyword.
…amples workflow - Removed the `id-token: write` permission from the `sync-examples.yml` workflow to streamline permissions and enhance security.
…th improved type annotations, null checks, and compatibility fixes.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
openspec/changes/coercion-public-api/proposal.md (1)
1-32: Proposal structure doesn't match required format.Per coding guidelines, proposals should include sections: Why, What Changes (with BREAKING markers), and Impact. Currently the document has:
- "Problem" → should be renamed to "Why"
- "Solution" → should be restructured as "What Changes" with explicit BREAKING markers if applicable
- "Impact" ✓ (correctly named)
- "Implementation Rules" → optional, but good to have
Consider restructuring to match the expected format. As per coding guidelines for
openspec/changes/*/proposal.md.packages/arkenv/src/utils/coerce.ts (3)
9-11: Consider usingtypeinstead ofinterface.Per coding guidelines, prefer
typeoverinterfacefor type definitions in TypeScript.🔎 Proposed fix
-interface CoercionTarget { - path: string[]; -} +type CoercionTarget = { + path: string[]; +};
119-136: Minor optimization opportunity: redundant nested object cloning.When multiple targets share a common path prefix, the current implementation may re-clone the same intermediate objects multiple times (line 130 clones unconditionally). This is functionally correct but could be optimized by tracking already-cloned paths.
For typical env var schemas (flat structures), this is unlikely to be a performance concern.
16-31: Add JSDoc comment explaining which ArkType constructs produce each numeric pattern.The logic correctly handles multiple representations of numeric types that ArkType generates. Consider documenting which patterns correspond to which ArkType constructs to aid future maintainers:
node === "number"→ simple"number"typedomain === "number"→ constrained numbers like"number >= 18"or"number % 2"typeof n.unit === "number"→ numeric literals like1,2, or"1 | 2"n.kind === "intersection" && domain === "number"→ intersection constraints
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
.changeset/cyan-loops-hear.md.changeset/few-rabbits-battle.md.changeset/humble-lizards-judge.md.changeset/open-spiders-tan.mdapps/playgrounds/node/index.tsopenspec/changes/coercion-public-api/design.mdopenspec/changes/coercion-public-api/proposal.mdopenspec/changes/coercion-public-api/specs/coercion-refactor/spec.mdopenspec/changes/coercion-public-api/tasks.mdpackages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonpackages/arkenv/src/utils/coerce.tspackages/internal/keywords/src/index.ts
💤 Files with no reviewable changes (1)
- .changeset/few-rabbits-battle.md
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{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/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonopenspec/changes/coercion-public-api/design.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tsopenspec/changes/coercion-public-api/specs/coercion-refactor/spec.mdopenspec/changes/coercion-public-api/tasks.mdpackages/internal/keywords/src/index.tsapps/playgrounds/node/index.ts
packages/*/package.json
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions
Files:
packages/arkenv/package.json
**/package.json
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Use workspace:* protocol for workspace dependencies between packages
Files:
packages/arkenv/package.json
{packages,apps,tooling}/**/package.json
📄 CodeRabbit inference engine (.cursor/rules/pnpm.mdc)
When referencing workspace packages in dependencies, use the
workspace:*protocol instead of version numbers
Files:
packages/arkenv/package.json
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
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/utils/coerce.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/utils/coerce.tspackages/internal/keywords/src/index.tsapps/playgrounds/node/index.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/utils/coerce.ts
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/coercion-public-api/specs/coercion-refactor/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/coercion-public-api/specs/coercion-refactor/spec.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/coercion-public-api/tasks.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.ts
🧠 Learnings (23)
📓 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/**/*.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: 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/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 ArkType's `type()` function to define schemas in environment variable definitions
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 : Leverage ArkType's type inference for TypeScript types instead of manual type definitions
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 type inference for TypeScript types instead of manual type definitions
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.ts.changeset/cyan-loops-hear.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 : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonopenspec/changes/coercion-public-api/design.md.changeset/open-spiders-tan.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tsopenspec/changes/coercion-public-api/specs/coercion-refactor/spec.mdpackages/internal/keywords/src/index.tsapps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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 built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonopenspec/changes/coercion-public-api/design.md.changeset/open-spiders-tan.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tsopenspec/changes/coercion-public-api/specs/coercion-refactor/spec.mdpackages/internal/keywords/src/index.tsapps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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 ArkType's `type()` function to define schemas in environment variable definitions
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tspackages/internal/keywords/src/index.tsapps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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 : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tsapps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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 union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonopenspec/changes/coercion-public-api/design.md.changeset/open-spiders-tan.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tspackages/internal/keywords/src/index.tsapps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.json.changeset/open-spiders-tan.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.json.changeset/open-spiders-tan.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.tsapps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition
Applied to files:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.jsonpackages/arkenv/src/utils/coerce.tsapps/playgrounds/node/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:
packages/arkenv/ARKTYPE_INTERNALS.mdpackages/arkenv/package.json.changeset/open-spiders-tan.mdopenspec/changes/coercion-public-api/proposal.mdpackages/arkenv/src/utils/coerce.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/package.json.changeset/cyan-loops-hear.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: packages/arkenv should not depend on other workspace packages; packages/vite-plugin depends on arkenv; apps/www may depend on workspace packages
Applied to files:
packages/arkenv/package.json
📚 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:
.changeset/open-spiders-tan.mdpackages/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: For breaking changes, always create an OpenSpec proposal first
Applied to files:
openspec/changes/coercion-public-api/proposal.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:
openspec/changes/coercion-public-api/proposal.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: For architecture changes, review `openspec/project.md` for conventions
Applied to files:
openspec/changes/coercion-public-api/specs/coercion-refactor/spec.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 **/*.{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-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:
apps/playgrounds/node/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:
apps/playgrounds/node/index.ts.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 **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
Applied to files:
apps/playgrounds/node/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:
apps/playgrounds/node/index.ts.changeset/cyan-loops-hear.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 PascalCase for type names (e.g., `ArkEnvError`)
Applied to files:
.changeset/cyan-loops-hear.md
🧬 Code graph analysis (2)
packages/arkenv/src/utils/coerce.ts (3)
packages/internal/keywords/src/index.ts (2)
maybeParsedNumber(12-17)maybeParsedBoolean(28-32)packages/internal/scope/src/index.ts (2)
$(9-18)$(20-20)packages/arkenv/src/type.ts (1)
type(3-3)
apps/playgrounds/node/index.ts (3)
apps/playgrounds/vite/vite.config.ts (1)
Env(11-16)packages/vite-plugin/src/__fixtures__/basic/config.ts (1)
Env(3-6)packages/arkenv/src/type.ts (1)
type(3-3)
🪛 LanguageTool
openspec/changes/coercion-public-api/proposal.md
[style] ~5-~5: To elevate your writing, try using a synonym here.
Context: ...codebase fragile to ArkType updates and hard to maintain as it requires deep knowled...
(HARD_TO)
[style] ~5-~5: Consider a different adjective to strengthen your wording.
Context: ...tes and hard to maintain as it requires deep knowledge of ArkType's node architectur...
(DEEP_PROFOUND)
🔇 Additional comments (17)
.changeset/cyan-loops-hear.md (3)
2-2: Patch version bump is appropriate.The changeset correctly uses a
patchbump for this internal refactoring that eliminates internal API dependencies without altering the user-facing API surface.
5-12: Changelog entry clearly documents the refactor.The entry effectively communicates the architectural shift to public-API–based coercion, explains the mechanism (introspection via
.in.jsonand.pipe()), and highlights key benefits. The structure and language are professional and appropriate for release notes.
7-9: Public API is stable—no user-facing changes detected.The refactoring correctly uses only public ArkType introspection methods (
.in.jsonand.pipe()) to implement the new Selective Path Coercion approach. All arkenv exports (createEnv,arkenv,EnvSchema,type,ArkEnvError) remain unchanged, and function signatures are compatible with previous versions. No internal API dependencies were found in the implementation..changeset/open-spiders-tan.md (1)
5-8: LGTM! Clear and well-documented breaking changes.The changeset accurately describes the migration to central coercion using public ArkType APIs. The breaking changes are appropriately flagged, and the reference to the Selective Path Coercion layer aligns with the PR objectives.
apps/playgrounds/node/index.ts (3)
1-9: LGTM! Improved schema definition pattern.Extracting the schema into a separate
Envconstant usingtype()is a best practice that improves reusability and enables introspection. This aligns with the public API approach and the patterns shown in other files (e.g.,vite.config.ts).
11-14: Good demonstration of introspection capabilities.The debug logging showcases the public API's introspection features (
toJsonSchema()andtoJSON()). This is appropriate for playground code and helps developers understand the new public API capabilities introduced by this PR.
15-16: LGTM! Consistent with schema refactor.Passing the
Envschema constant toarkenv()is consistent with the refactored pattern and enables better schema reuse and introspection.openspec/changes/coercion-public-api/tasks.md (1)
1-16: LGTM! Comprehensive and completed task checklist.The three-phase approach (Research, Implementation, Validation) is well-structured and covers all necessary aspects of the refactor. The inclusion of validation steps (tests, bundle size, documentation, playground verification) demonstrates thorough engineering discipline.
openspec/changes/coercion-public-api/design.md (1)
1-48: LGTM! Excellent design documentation.The Pipeline Wrapper Pattern is well-articulated with clear rationale for key decisions:
- Using
in.jsonovertoJsonSchema()for better fidelity and simpler traversal- Performance justification (one-time introspection at startup)
- Pragmatic union handling strategy (loose coercion with validation)
The design aligns perfectly with the PR objectives of migrating to public APIs.
openspec/changes/coercion-public-api/specs/coercion-refactor/spec.md (1)
1-25: LGTM! Well-structured specification.The specification properly follows the openspec format with:
- Clear ADDED and MODIFIED requirement sections
- Normative MUST language for requirements
- Testable scenarios with Given/When/Then format
- Concrete examples (nested numeric paths, pipeline coercion)
The requirements align with the PR objectives and design documentation.
.changeset/humble-lizards-judge.md (1)
5-9: LGTM! Clear documentation of keyword simplification.The changeset accurately describes the shift from keyword-level coercion to central coercion:
- Breaking changes are appropriately flagged
- The rationale (delegating to arkenv's central coercion) is clear
- Internal morphs (
maybeParsedNumber,maybeParsedBoolean) supporting the new architecture are documentedThis aligns with the overall PR objective of using public APIs for coercion.
packages/arkenv/ARKTYPE_INTERNALS.md (1)
1-32: LGTM! Excellent documentation of the migration.This document provides comprehensive tracking of the internal API migration:
- Clear status update indicating removal of internal dependencies
- Historical context for future maintainers
- Transparent acknowledgment of remaining internal usage (
$.type.raw())- Well-articulated risk mitigation strategies
The documentation demonstrates good engineering discipline and will help with long-term maintainability.
packages/arkenv/package.json (1)
43-43: Use catalog protocol for @ark/schema to maintain consistency with other external dependencies.The exact version
"0.56.0"is inconsistent with the workspace pattern used throughoutdevDependencies. Other external packages likearktype,@types/node, and@size-limit/*reference the pnpm catalog via"catalog:". Since@ark/schemais not defined in the catalog (unlikearktype), either add it to the catalog inpnpm-workspace.yamland update the reference to"catalog:", or use a flexible version range like"^0.56.0"to align with standard npm package management practices.⛔ Skipped due to learnings
Learnt from: CR Repo: yamcodes/arkenv PR: 0 File: .cursor/rules/pnpm.mdc:0-0 Timestamp: 2025-11-29T08:00:08.044Z Learning: Applies to {packages,apps,tooling}/**/package.json : When referencing workspace packages in dependencies, use the `workspace:*` protocol instead of version numbersLearnt 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 schemasLearnt 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 syntaxLearnt from: CR Repo: yamcodes/arkenv PR: 0 File: .cursor/rules/monorepo.mdc:0-0 Timestamp: 2025-11-24T16:04:11.901Z Learning: Applies to **/package.json : Use workspace:* protocol for workspace dependencies between packagesLearnt 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 definitionsLearnt 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 definitionsLearnt 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 definitionsLearnt 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 patternLearnt from: CR Repo: yamcodes/arkenv PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-29T22:11:39.931Z Learning: Always run `pnpm changeset` for version bumps in published packages - never skip changesetsLearnt 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.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 definitionLearnt 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 schemasLearnt 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 definitionpackages/internal/keywords/src/index.ts (1)
1-42: LGTM!The loose morphs (
maybeParsedNumberandmaybeParsedBoolean) are well-designed for union coercion scenarios. They correctly pass through values they can't coerce, allowing other union branches to match. Theportandhosttypes appropriately leverage ArkType's built-in types per the coding guidelines.packages/arkenv/src/utils/coerce.ts (3)
36-49: LGTM!The boolean detection logic appropriately mirrors the numeric detection pattern and correctly handles domain, expression, and unit representations. The comment on line 47 clarifies union boolean handling.
97-102: Clarify sequence (array) coercion behavior.When processing sequences, the path isn't extended with an index marker. This means array element coercion will share the same path as the parent. For typical env var use cases (comma-separated values parsed as arrays), clarify whether:
- The coercion applies at the array level before splitting, or
- Individual elements should be coerced (would need path extension like
[*]or similar)If intended, consider adding a comment explaining the expected behavior for array coercion in the env var context.
148-160: Clean implementation using public ArkType APIs.The function correctly uses
schema.in.jsonfor introspection (public API), performs efficient early-return when no coercion is needed, and builds a proper pipeline for data transformation. Theas nevercast on line 160 aligns with the proposal's guidance for handling ArkType generics.
This is an attempt to implement coercion, this time by relying on 100% public API which makes ArkEnv much, much more reliable (100% reliable) instead of having to compromise on reliability.
Closes #577
Summary by CodeRabbit
Release Notes
Breaking Changes
parsedNumberandparsedBooleankeywords.booleankeyword removed; numeric and boolean coercion now centralized across the package.Refactor
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.