Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/silly-pillows-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hyperse/config-loader": patch
---

chore: 🤖 update dependencies and add support for env config files
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,30 @@
},
"dependencies": {
"@hyperse/deep-merge": "^1.0.1",
"@hyperse/unplugin-swc": "^1.0.1",
"@hyperse/unplugin-swc": "^1.0.2",
"@manypkg/get-packages": "^3.1.0",
"@swc/core": "^1.13.5",
"@swc/core": "^1.15.8",
"cosmiconfig": "^9.0.0",
"get-tsconfig": "^4.10.1"
"get-tsconfig": "^4.13.0"
},
"devDependencies": {
"@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.29.7",
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"@hyperse/eslint-config-hyperse": "^1.4.8",
"@types/node": "^24.5.2",
"@changesets/changelog-github": "^0.5.2",
"@changesets/cli": "^2.29.8",
"@commitlint/cli": "^20.3.1",
"@commitlint/config-conventional": "^20.3.1",
"@hyperse/eslint-config-hyperse": "^1.5.0",
"@types/node": "^25.0.8",
"commitizen": "^4.3.1",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^9.36.0",
"execa": "^9.6.0",
"eslint": "^9.39.2",
"execa": "^9.6.1",
"husky": "^9.1.7",
"lint-staged": "^16.1.6",
"lint-staged": "^16.2.7",
"npm-run-all": "^4.1.5",
"rollup": "^4.52.0",
"tsup": "^8.5.0",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
"rollup": "^4.55.1",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"vitest": "^4.0.17"
},
Comment on lines 52 to 78

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

vitest 4.0 breaking changes migration guide

💡 Result:

Here are the main Vitest 4.0 breaking changes and the minimal migration actions you should take. See the official migration guide and release post for full details. [1][2]

  • V8 coverage remapping changed

    • Expect different coverage numbers; no action unless you rely on v8-to-istanbul specifics. Validate reports and update CI thresholds if needed. [1]
  • Mocking / spies behavior changed

    • vi.fn().getMockName() now defaults to no name (affects mock snapshots).
    • vi.restoreAllMocks() no longer resets automocks (only restores spies from vi.spyOn); .mockRestore still clears implementations.
    • vi.spyOn called on a mock returns the same mock.
    • Update tests that relied on the previous restore/spy behaviors and snapshot names. [1]
  • Deprecated APIs removed — update config/tests to new options

    • Replace poolMatchGlobs / environmentMatchGlobs with projects.
    • Move deps.external/inline/fallbackCJS → server.deps.external/inline/fallbackCJS.
    • Replace browser.testerScripts → browser.testerHtmlPath.
    • Remove minWorkers (use maxWorkers only).
    • Reporter hook APIs (onCollected, onSpecsCollected, onPathsCollected, onTaskUpdate, onFinished) removed — migrate to the new Reporters API. [1][5]
  • Browser mode / providers changes

    • Browser provider config now uses objects (provider factories) instead of strings; provider packages are separate (e.g. @vitest/browser-playwright). Update test config and imports accordingly. [5][2]
  • Internal/entry changes

    • vitest/execute entrypoint removed.
    • __vitest_executor injection removed; moduleRunner injected instead.
    • vite-node is no longer a dependency.
    • Custom environments should provide viteEnvironment instead of transformMode. [1][5]
  • Other renames / env vars

    • VITE_NODE_DEPS_MODULE_DIRECTORIES → VITEST_MODULE_DIRECTORIES.
    • deps.optimizer.web → deps.optimizer.client (or custom name). [1]
  • Reporters / defaults

    • Basic reporter removed; use equivalent default reporter config instead. [5]

Quick migration checklist

  1. Read your test run and coverage reports after upgrading. Adjust CI thresholds. [1]
  2. Search & update usages of removed config keys and APIs in vitest config and custom reporters. [1][5]
  3. Update mocks/spy-based tests that assume old vi.restoreAllMocks/vi.spyOn behaviors and snapshot names. [1]
  4. If you use Browser Mode, install the new provider packages and convert provider config to the new object/factory form. [5][2]
  5. Run full test suite and fix failures caused by API/behavior changes.

Sources:

  1. Vitest Migration Guide — "Migrating to Vitest 4.0". [Vitest docs]. [1]
  2. Vitest 4.0 release announcement / blog. [2]

Would you like a PR-ready patch (search-and-replace script) for your vitest config and common patterns?


🌐 Web query:

commitlint 20.0 breaking changes

💡 Result:

Summary — breaking change in commitlint v20.0.0 (released Sep 25, 2025)

  • The rule body-max-line-length now ignores lines that contain URLs (so long URL lines no longer count toward the body max-line-length). [1][2]

Impact and migration

  • If you relied on body-max-line-length to enforce max length for all body lines (including URL lines), update your checks or add a custom rule to re-include URL lines. Otherwise no other major breaking changes were listed in the v20.0.0 release. [1][2]

Sources

  • commitlint v20.0.0 release notes (GitHub). [1]
  • commitlint npm/newreleases v20.0.0 summary. [2]

🌐 Web query:

@types/node 25 breaking changes

💡 Result:

Short answer: there’s no dedicated “@types/node v25 changelog.” Breaking/type changes for @types/node v25 mainly mirror Node.js v25 API changes (removed/EOLed APIs and new globals/DOM-ish APIs) and TypeScript-compatibility updates. Check these sources to see what will break and how to migrate:

  • Node.js v25 release notes (lists semver‑major removals/changes that drive type changes — e.g. removal/finalization of SlowBuffer, global ErrorEvent, Web Storage enabled by default, new permissions like --allow-net). (nodejs.org)
  • DefinitelyTyped discussion explaining there is no centralized @types/node changelog and that you must inspect DT commits/PRs or the upstream Node changes. (github.com)
  • @types/node release history / diffs (inspect specific @types/node v25.x releases or use a package-diff/compare tool to see the exact .d.ts changes). Example release list. (releasealert.dev)

If you want, I can:

  • List the specific Node v25 API changes most likely to affect your code (based on your codebase, e.g. uses of SlowBuffer, global ErrorEvent, fs.Dir GC behavior, node:_internal modules).
  • Produce a diff of your current @types/node version → v25 and highlight breaking type changes (I can fetch the two releases and summarize).

Citations:


Verify vitest 4.0 compatibility — multiple breaking changes require attention.

The major version bumps here warrant careful testing:

  • vitest 4.0 has significant breaking changes: V8 coverage remapping (may affect CI thresholds), mocking/spy behavior changes (e.g., vi.fn().getMockName() defaults differ, vi.restoreAllMocks() no longer resets automocks), deprecated config keys removed (poolMatchGlobs, environmentMatchGlobs, deps.external/inline/fallbackCJS, reporter hooks API), browser mode provider changes, and removed internal APIs. Verify your test config and test suite runs cleanly.

  • commitlint 20.x: One minor breaking change — body-max-line-length now ignores URLs. Update config if you relied on strict line length for URL lines.

  • @types/node 25.x: Type-only update mirroring Node.js v25 API changes. Low risk for build tools; verify in CI.

Ensure CI passes with these updates before merging.

🤖 Prompt for AI Agents
In `@package.json` around lines 52 - 78, package.json updates bump several
packages with breaking changes (notably vitest to 4.0, commitlint to 20.x, and
`@types/node` to 25.x); run the full test suite and CI locally and update configs:
audit and update vitest config keys and options (remove deprecated keys like
poolMatchGlobs/environmentMatchGlobs, migrate deps.external/inline/fallbackCJS
and reporter hooks usage, adjust coverage remapping and browser provider
config), update tests that rely on vi mocking/spy semantics (replace/adjust uses
of vi.fn().getMockName(), vi.restoreAllMocks() assumptions and automock
behavior), tweak commitlint rules if you relied on body-max-line-length for
URLs, and verify TypeScript/Node typings with `@types/node`@25; if immediate
compatibility fixes are nontrivial, pin the previous working versions in
package.json (restore vitest/commitlint/@types/node) until tests and configs are
updated and CI passes.

"packageManager": "yarn@4.10.2",
"engines": {
Expand Down
3 changes: 3 additions & 0 deletions src/config-loader/searchConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export const searchConfig = async <T = any>(
`.${moduleName}rc.ts`,
`${moduleName}.config.ts`,
`${moduleName}.config.mts`,
// ENV
`env.${moduleName}.ts`,
`env.${moduleName}.mts`,
],
loaders: createLoaders(options, searchFrom),
});
Expand Down
34 changes: 34 additions & 0 deletions tests/config-loader/esm-ts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ describe('ESM-TS config loader tests', () => {
);
expect(loadedCfg).toBeNull();
});

it('should load an env .ts config file', async () => {
const loadedCfg = await loadConfig<{
cake: string;
}>(join(fixturesPath, 'env.valid.ts'), loaderOptions);
expect(typeof loadedCfg?.config).toBe('object');
expect(loadedCfg?.config.cake).toBe('a lie env');
});

it('should load an env .mts config file', async () => {
const loadedCfg = await loadConfig<{
cake: string;
}>(join(fixturesPath, 'env.valid.mts'), loaderOptions);
expect(typeof loadedCfg?.config).toBe('object');
expect(loadedCfg?.config.cake).toBe('a lie env mts');
});
});

describe('searchConfig', () => {
Expand Down Expand Up @@ -83,5 +99,23 @@ describe('ESM-TS config loader tests', () => {
}>('named-exports', fixturesPath, loaderOptions);
expect(loadedCfg?.config.test.cake).toBe('a lie');
});

it('should search and load an env .ts config file', async () => {
const envTestPath = join(fixturesPath, 'env-test');
const loadedCfg = await searchConfig<{
cake: string;
}>('valid', envTestPath, loaderOptions);
expect(typeof loadedCfg?.config).toBe('object');
expect(loadedCfg?.config.cake).toBe('a lie env');
});

it('should search and load an env .mts config file when .ts file does not exist', async () => {
const envMtsTestPath = join(fixturesPath, 'env-mts-test');
const loadedCfg = await searchConfig<{
cake: string;
}>('valid', envMtsTestPath, loaderOptions);
expect(typeof loadedCfg?.config).toBe('object');
expect(loadedCfg?.config.cake).toBe('a lie env mts');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// env config file (.mts only)
export default {
cake: 'a lie env mts',
};
4 changes: 4 additions & 0 deletions tests/config-loader/fixtures/esm-ts/env-test/env.valid.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// env config file (.mts)
export default {
cake: 'a lie env mts',
};
4 changes: 4 additions & 0 deletions tests/config-loader/fixtures/esm-ts/env-test/env.valid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// env config file
export default {
cake: 'a lie env',
};
4 changes: 4 additions & 0 deletions tests/config-loader/fixtures/esm-ts/env.valid.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// env config file (.mts)
export default {
cake: 'a lie env mts',
};
4 changes: 4 additions & 0 deletions tests/config-loader/fixtures/esm-ts/env.valid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// env config file
export default {
cake: 'a lie env',
};
Loading