Skip to content

Fix support for array defaults using type().default() syntax#199

Merged
yamcodes merged 12 commits intomainfrom
copilot/fix-fd4943db-97c5-42be-9d5d-2eb74e3ace48
Oct 6, 2025
Merged

Fix support for array defaults using type().default() syntax#199
yamcodes merged 12 commits intomainfrom
copilot/fix-fd4943db-97c5-42be-9d5d-2eb74e3ace48

Conversation

Copy link
Contributor

Copilot AI commented Sep 29, 2025

Fixes the issue where using type("array[]").default(() => [...]) syntax was not accepted by createEnv due to overly restrictive type constraints.

Problem

The createEnv function had a type constraint that only accepted Record<string, string | undefined>, which prevented ArkType objects with default values from being used. This meant the following syntax from the ArkType documentation didn't work:

import arkenv, { type } from "arkenv";

const Thing = arkenv({
  array: type("number.integer[]").default(() => []),
});

This would result in a TypeScript error:

Type '[Type<...>, "=", () => never[]]' is not assignable to type 'string'.

Solution

Updated the type constraint to maintain string-keyed requirement while allowing flexible value types:

Before:

export function createEnv<const T extends Record<string, string | undefined>>(
  def: EnvSchema<T>,
  // ...

After:

export function createEnv<const T extends Record<string, any>>(
  def: EnvSchema<T>,
  // ...

This approach preserves the environment variable paradigm (string keys) while supporting ArkType objects with defaults. The EnvSchema<T> type provides proper validation through ArkType's type system.

What Now Works

✅ Array defaults with type function syntax:

const env = arkenv({
  ALLOWED_ORIGINS: type("string[]").default(() => ["localhost"]),
  FEATURE_FLAGS: type("string[]").default(() => []),
  PORTS: type("number[]").default(() => [3000, 8080]),
});

✅ Complex array types:

const env = arkenv({
  numbers: type("number.integer[]").default(() => [1, 2, 3]),
});

✅ Mixed schemas with both string-based and type-based defaults work together

Backward Compatibility

All existing functionality continues to work unchanged:

  • String-based schemas: "string", "number.port", etc.
  • String-based defaults: "'development' | 'production' = 'development'"
  • Optional variables: "API_KEY?": "string"
  • Built-in validators: "string.host", "number.port"

Testing

Added comprehensive test coverage including:

  • Basic array default functionality
  • Integration tests showing the exact syntax from the issue now works
  • Mixed schema types to ensure no regressions
  • All 94 existing tests continue to pass

Documentation

Updated the quickstart guide to include examples of array defaults, helping users discover this powerful feature.

Changeset

Added changeset for minor version bump reflecting the new functionality.

Fixes #163

Original prompt

This section details on the original issue you should resolve

<issue_title>Provide a clear example of a default variable for an array</issue_title>
<issue_description>This doesn't work in ArkEnv (and ArkType):

Image

Based on the docs we should use pipes:

https://arktype.io/docs/objects#properties-defaultable

But this is not clearly possible with ArkEnv (See #162)

Also, based on this, you would expect this to work:

import arkenv, { type } from "arkenv";

const Thing = arkenv({
	array: type("number.integer[]").default(() => []),
});

Instead, we are getting:

Type '[Type<number[], { string: Submodule<{ root: string; " arkInferred": string; trim: Submodule<$ & { " arkInferred": (In: string) => To<string>; }>; normalize: Submodule<$ & { " arkInferred": (In: string) => To<...>; }>; ... 19 more ...; host: string; }>; number: Submodule<...>; }>, "=", () => never[]]' is not assignable to type 'string'.ts(2322)

I think that createEnv is defined in a way that does not allow an internal type, and the issue is probably not in the type we export since this works:

import arkenv, { type } from "arkenv";

const Thing = type({
	array: type("number.integer[]").default(() => []),
});

More specifically the signature (i/o) of the createEnv function is probably insufficient.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #163

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.


Note

Allow array defaults using type("...[]").default(() => [...]) by loosening createEnv input types; add tests, docs, and changeset.

  • Core (arkenv)
    • Update createEnv signature to accept Record<string, any> (from Record<string, string | undefined>) enabling type("...[]").default(() => [...]) schemas.
  • Tests
    • Add packages/arkenv/src/array-defaults-integration.test.ts covering array defaults, complex arrays, and env overrides.
    • Extend create-env.test.ts and type.test.ts to validate array defaults using type("...[]").default(() => [...]).
  • Docs
    • Update apps/www/content/docs/quickstart.mdx to import { type } and demonstrate array defaults (ALLOWED_ORIGINS, FEATURE_FLAGS).
  • Changeset
    • Add .changeset/array-defaults-support.md for a minor release.

Written by Cursor Bugbot for commit 77d51fb. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Sep 29, 2025

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

Project Deployment Preview Comments Updated (UTC)
arkenv Ready Ready Preview Comment Oct 6, 2025 2:27pm

@changeset-bot
Copy link

changeset-bot bot commented Sep 29, 2025

🦋 Changeset detected

Latest commit: 3ff8f4c

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

This PR includes changesets to release 2 packages
Name Type
arkenv Minor
@arkenv/vite-plugin Patch

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

Co-authored-by: yamcodes <2014360+yamcodes@users.noreply.github.com>
Co-authored-by: yamcodes <2014360+yamcodes@users.noreply.github.com>
Copilot AI changed the title [WIP] Provide a clear example of a default variable for an array Fix support for array defaults using type().default() syntax Sep 29, 2025
Copilot AI requested a review from yamcodes September 29, 2025 20:18
@yamcodes
Copy link
Owner

@copilot Since this is an environment variable valiaditor, we should still constrain it to a string-keyed record, although your note that the type is too restrictive is taken. Maybe there is a middle ground where it's a record (string keyed, but the value can be unconstrained) or, we can just somehow "copy" the type from ArkType's type.object

Also, we need a changeset.

@yamcodes yamcodes marked this pull request as ready for review September 29, 2025 20:41
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


Note

Free review on us!

CodeRabbit is offering free reviews until Wed Oct 08 2025 to showcase some of the refinements we've made.

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

@github-actions github-actions bot added docs Improvements or additions to documentation arkenv Changes to the `arkenv` npm package. www Improvements or additions to arkenv.js.org tests This issue or PR is about adding, removing or changing tests labels Sep 29, 2025
cursor[bot]

This comment was marked as outdated.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 29, 2025

Open in StackBlitz

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

commit: 8db3377

Co-authored-by: yamcodes <2014360+yamcodes@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Sep 29, 2025

@copilot Since this is an environment variable valiaditor, we should still constrain it to a string-keyed record, although your note that the type is too restrictive is taken. Maybe there is a middle ...

Updated the constraint to Record<string, any> to maintain string-keyed requirement while allowing flexible value types. This preserves the environment variable constraint (string keys) while supporting ArkType objects with defaults. Also added the changeset as requested.

The fix is in commit 80a0b2e.

yamcodes and others added 3 commits September 30, 2025 01:49
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fix to an issue where `type("array[]").default(() => [...])` syntax was not accepted by `createEnv` due to overly restrictive type constraints. The function now accepts any string-keyed record while still maintaining type safety through ArkType's validation system. Added support for array defaults using `type("string[]").default(() => [])` syntax and complex array types.
cursor[bot]

This comment was marked as outdated.

- Added ALLOWED_ORIGINS array type
- Added .env.example file
- Array defaults to empty
- Support complex array types
- Mixed schemas supported
@yamcodes yamcodes merged commit e50dba1 into main Oct 6, 2025
17 checks passed
@yamcodes yamcodes deleted the copilot/fix-fd4943db-97c5-42be-9d5d-2eb74e3ace48 branch October 6, 2025 14:28
@github-actions github-actions bot mentioned this pull request Oct 6, 2025
yamcodes pushed a commit that referenced this pull request Oct 6, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## arkenv@0.7.2

### Patch Changes

- #### Support array defaults using type().default() syntax
_[`#199`](#199)
[`e50dba1`](e50dba1)
[@copilot-swe-agent](https://github.com/apps/copilot-swe-agent)_

Fix to an issue where `type("array[]").default(() => [...])` syntax was
not accepted by `createEnv` due to overly restrictive type constraints.
The function now accepts any string-keyed record while still maintaining
type safety through ArkType's validation system.

    ##### New Features

- Array defaults to empty using `type("string[]").default(() => [])`
syntax
    -   Support for complex array types with defaults
    -   Mixed schemas combining string-based and type-based defaults

    ##### Example

    ```typescript
    const env = arkenv({
      ALLOWED_ORIGINS: type("string[]").default(() => ["localhost"]),
      FEATURE_FLAGS: type("string[]").default(() => []),
      PORT: "number.port",
    });
    ```

## @arkenv/vite-plugin@0.0.12

### Patch Changes

<details><summary>Updated 1 dependency</summary>

<small>


[`e50dba1`](e50dba1)

</small>

-   `arkenv@0.7.2`

</details>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
yamcodes added a commit that referenced this pull request Oct 13, 2025
- Updated dependencies in pnpm-lock.yaml, including vitest and jsdom.
- Added new environment variables (VITE_MY_NUMBER, VITE_MY_VAR,
VITE_MY_BOOLEAN) to the Vite development environment.
- Enhanced the Vite configuration to utilize the new environment
variables.
- Updated the App component to display the new environment variables.

These changes improve the development experience and ensure
compatibility with the latest dependencies.

Related: #162 #163 #199

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- New Features
- Added support for default values on array environment variables,
including complex array types; can initialize to empty arrays.
- Enabled mixed schemas combining string-based and type-based defaults.
  - Playground now displays example environment variables in the UI.

- Bug Fixes
- Resolved issue preventing array defaults from being accepted,
improving validation while maintaining type safety.

- Documentation
  - Documented array defaults in the Vite plugin with example usage.

- Chores
  - Added a script to manage changesets.
- Updated playground configuration to include new example environment
variables.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
yamcodes pushed a commit that referenced this pull request Nov 10, 2025
This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
| [arkenv](https://arkenv.js.org)
([source](https://redirect.github.com/yamcodes/arkenv)) | [`0.7.0` ->
`0.7.3`](https://renovatebot.com/diffs/npm/arkenv/0.7.0/0.7.3) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/arkenv/0.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/arkenv/0.7.0/0.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>yamcodes/arkenv (arkenv)</summary>

###
[`v0.7.3`](https://redirect.github.com/yamcodes/arkenv/releases/tag/arkenv%400.7.3)

[Compare
Source](https://redirect.github.com/yamcodes/arkenv/compare/arkenv@0.7.2...arkenv@0.7.3)

##### Patch Changes

- #### Automatic boolean string conversion
*[`#218`](https://redirect.github.com/yamcodes/arkenv/pull/218)
[`e554e2b`](https://redirect.github.com/yamcodes/arkenv/commit/e554e2b41aab1b8e29d873982ea587c069f4732d)
[@&#8203;yamcodes](https://redirect.github.com/yamcodes)*

The `boolean` type now accepts `"true"`/`"false"` strings from
environment variables and converts them to actual boolean values. This
also works with boolean defaults.

  Example:

  ```ts
  import arkenv from "arkenv";

  const env = arkenv({
    DEBUG: "boolean",
    ENABLE_FEATURE: "boolean = true",
  });

  console.log(env.DEBUG);
  console.log(env.ENABLE_FEATURE);
  ```

  Result:

  ```sh
  ❯ DEBUG=true npx tsx index.ts
  true
  true
  ```

###
[`v0.7.2`](https://redirect.github.com/yamcodes/arkenv/releases/tag/arkenv%400.7.2)

[Compare
Source](https://redirect.github.com/yamcodes/arkenv/compare/arkenv@0.7.1...arkenv@0.7.2)

##### Patch Changes

- #### Support array defaults using type().default() syntax
*[`#199`](https://redirect.github.com/yamcodes/arkenv/pull/199)
[`e50dba1`](https://redirect.github.com/yamcodes/arkenv/commit/e50dba1f19418f8fc007dc786df1172067e3d07c)
[@&#8203;copilot-swe-agent](https://redirect.github.com/apps/copilot-swe-agent)*

Fix to an issue where `type("array[]").default(() => [...])` syntax was
not accepted by `createEnv` due to overly restrictive type constraints.
The function now accepts any string-keyed record while still maintaining
type safety through ArkType's validation system.

  ##### New Features

- Array defaults to empty using `type("string[]").default(() => [])`
syntax
  - Support for complex array types with defaults
  - Mixed schemas combining string-based and type-based defaults

  ##### Example

  ```typescript
  const env = arkenv({
    ALLOWED_ORIGINS: type("string[]").default(() => ["localhost"]),
    FEATURE_FLAGS: type("string[]").default(() => []),
    PORT: "number.port",
  });
  ```

###
[`v0.7.1`](https://redirect.github.com/yamcodes/arkenv/releases/tag/arkenv%400.7.1)

[Compare
Source](https://redirect.github.com/yamcodes/arkenv/compare/arkenv@0.7.0...arkenv@0.7.1)

##### Patch Changes

- Export `ArkEnvError`
*[`#161`](https://redirect.github.com/yamcodes/arkenv/pull/161)
[`221f9ef`](https://redirect.github.com/yamcodes/arkenv/commit/221f9efdef65691b0c5155b12ec460404dddbe82)
[@&#8203;yamcodes](https://redirect.github.com/yamcodes)*

  You can now import `ArkEnvError` from `arkenv`:

  ```ts
  import { ArkEnvError } from "arkenv";
  ```

- Improve JSDoc
*[`#161`](https://redirect.github.com/yamcodes/arkenv/pull/161)
[`221f9ef`](https://redirect.github.com/yamcodes/arkenv/commit/221f9efdef65691b0c5155b12ec460404dddbe82)
[@&#8203;yamcodes](https://redirect.github.com/yamcodes)*

  The JSDoc for `arkenv` and `createEnv` is now more descriptive.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "on friday" (UTC), Automerge - At any
time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/yamcodes/arkenv).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNTkuNCIsInVwZGF0ZWRJblZlciI6IjQxLjE1OS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@yamcodes yamcodes mentioned this pull request Jan 1, 2026
@yamcodes yamcodes added this to the v1 milestone Jan 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide a clear example of a default variable for an array

2 participants