Skip to content

chore(deps): bump devDependencies across majors - #302

Draft
mfal wants to merge 9 commits into
masterfrom
claude/deps-dev-major
Draft

mfal wants to merge 9 commits into
masterfrom
claude/deps-dev-major

Conversation

@mfal

@mfal mfal commented Sep 4, 2026

Copy link
Copy Markdown
Member

Major-version bumps of devDependencies only. No dependencies, no peerDependencies.

Not breaking. devDependencies do not reach consumers, and regenerating both clients on this branch produces an empty diff.

Eight commits, one per dependency group, so anything contentious can be dropped individually.

Landed

commit dependency from → to scope
fdc2121d rimraf ^5.0.10 → ^6.1.3 all 4
fdc2121d read-pkg ^9.0.1 → ^10.1.0 mittwald
fdc2121d prettier-plugin-sort-json ^3.1.0 → ^4.2.0 root, commons, generator, mittwald
0d475774 @typescript-eslint/{eslint-plugin,parser} ^7.18.0 → ^8.68.0 root + all 4
1703e883 jest, @jest/globals, jest-environment-jsdom ^29.7.0 → ^30.5.0 commons, generator, models
1703e883 @types/jest ^29.5.14 → ^30.0.0 commons, generator, models
a903026b @testing-library/jest-dom ^6.9.1 → ^7.0.1 models
dd77e2b1 @types/node ^22.18.11 → ^26.4.0 mittwald
4d72cca5 @lerna-lite/{cli,publish} ^4.9.1 → ^5.6.1 root
4d72cca5 conventional-commits-filter ^5.0.0 → ^6.0.1 root
428bc2bd license-checker-rseidelsohn ^4.4.2 → ^5.0.1 root
428bc2bd concurrently ^8.2.2 → ^10.0.5 root, mittwald
0009b9a9 nx ^21.6.5 → ^23.1.2 root

Four targets sit one release below the newest because npmMinimalAgeGate: 10080 quarantines them — verbatim: ➤ YN0016: │ @typescript-eslint/eslint-plugin@npm:^8.69.0: All versions satisfying "^8.69.0" are quarantined. So @typescript-eslint/* → 8.68.0, @types/node → 26.4.0, nx → 23.1.2, jest → 30.5.0.

Code changes the bumps forced

  • packages/generator/src/loading/UniversalContentLoader.ts — typescript-eslint v8 defaults no-unused-vars to caughtErrors: "all"; two unused catch bindings now use optional catch binding (catch {).
  • config/.eslintrc.yml — disables @typescript-eslint/no-unused-expressions for *.test-types.ts(x). v8 moved that rule into recommended and it flagged the deliberate bare member expressions (paired with @ts-expect-error) in the tsd-style type tests — 6 errors in commons.
  • packages/commons/src/core/ApiClientBase.test.ts, packages/models/src/domain/IngressPath/IngressPath.test.ts — jest 30 removed the deprecated matcher aliases (TypeError: expect(...).toBeCalledWith is not a function, ...rejects.toThrowError is not a function). Migrated to toHaveBeenCalledWith / toHaveBeenCalledTimes / toThrow.
  • ts-jest re-resolved in the lockfile only. Its declared range ^29.2.5 is untouched, but the lock was pinned to 29.2.5, which peers on jest ^29.0.0 (ts-jest[versions] (WARN) Version 30.5.0 of jest installed has not been tested with ts-jest). yarn up "ts-jest@^29.2.5" re-resolved to 29.4.12, whose peer is ^29.0.0 || ^30.0.0.

Excluded, with the reason

eslint 8 → 10 (whole group with eslint-config-prettier, eslint-plugin-json). Installs, then every lint task dies:

ESLint couldn't find an eslint.config.* file.
From ESLint v9.0.0, the default configuration file is now eslint.config.*.

Needs a full flat-config migration — 5 .eslintrc.yml files, 5 .eslintignore files, and re-expressing eslint:recommended → @eslint/js, plugin:@typescript-eslint/recommended → the typescript-eslint package, plugin:prettier/recommended → eslint-plugin-prettier/recommended. Rewriting rule resolution can silently drop rules, so it wants its own PR with a rule-set diff. @typescript-eslint v8 was kept because its peer is eslint ^8.57.0 || ^9 || ^10 — it does not require eslint 9.

typescript 5.7 → 7.0.2. Blocked three ways. It does not even install under Yarn 4.13 — the builtin TypeScript compat patch cannot handle the TS 7 native package layout:

Error: typescript@patch:typescript@npm%3A7.0.2#optional!builtin<compat/typescript>::version=7.0.2&hash=5786d5:
ENOENT: no such file or directory, lstat '/node_modules/typescript/lib/_tsc.js'

On top of that ts-jest@29.4.12 peers typescript: ">=4.3 <7" and @typescript-eslint/*@8.68.0 peers >=4.8.4 <6.1.0.

nock 14 → 15. The candidate is not a real release. latest is 14.0.17; 15.0.0 is deprecated upstream — "v15.0.0 was released accidentally and is unstable. Please use v14.x until v15 is officially ready." The only 15.x artifacts are betas.

@types/dinero.js 1 → 2. @types/dinero.js@2.0.0 is a deprecated stub that depends on dinero.js: *. But packages/models uses dinero.js@^1.9.1 (no bundled types) and Money.ts uses the v1 default-import API, so installing the stub would strip the types and break the build. The correct move is bumping dinero.js itself to v2 plus a Money.ts migration, then removing @types/dinero.js — that is a dependencies change and belongs to the prod-deps line.

react/react-dom/@types/react/@types/react-dom 18 → 19. Deliberately not bumped — see below.

The React 18-vs-19 question

Not bumped, and the situation is worse than assumed: none of the three published packages declares a react peer range at all. Each declares only peerDependencies: { "@mittwald/react-use-promise": "^2.6.0" }. packages/models additionally has peerDependenciesMeta.react: { optional: true } — an entry for a peer that is not in peerDependencies, which is inert.

So there is no declared lower bound; the effective one is transitive via @mittwald/react-use-promise@2.6.2, whose peer is react: ">=17.0". That makes the devDependency the only thing determining which React is exercised. Bumping it to 19 would mean advertising React ≥17 while testing only 19 — strictly less coverage of the claimed range, and it would fight #295, which keeps 18.3.1 on purpose.

Options: (1) stay on 18.3.1, as here; (2) add an explicit react peer (e.g. ^18.3 || ^19) to the three packages and test a 18/19 matrix — the only option that fixes the underlying gap, but it is a peerDependencies change; (3) bump devDeps to 19 alone, which loses coverage. Note that #295 moves the effective floor from 17 to 18.3, which changes the answer.

Merge-order note

This branch and #298 (devDeps minor) both touch @lerna-lite/{cli,publish}, @testing-library/jest-dom, @types/node, nx and ts-jest. A yarn.lock conflict is expected; this branch supersedes #298 for those five, and the ts-jest resolution converges on 29.4.12 either way.

Verification

All from a clean tree at 0009b9a9, and again after each group before its commit:

yarn install --immutable (no lockfile drift) · yarn lint (4 projects) · build --skip-nx-cache (4) · test:compile --skip-nx-cache (3 + 3 deps) · test --skip-nx-cache (4 + 9 deps — 12 suites, 45 tests, 0 failures) · yarn test:licenses · yarn lerna --version → 5.6.1 · build:write-version-file → writes 4.455.0 (exercises read-pkg 10) · prettier --check on the 4 edited files. Regeneration of both clients: empty diff.

yarn format was not run, so none of the pre-existing CHANGELOG/README drift is in the diff.

Follow-ups this surfaced

  1. .github/workflows/test.yml pins Node 20, and several of these majors declare higher engines: @testing-library/jest-dom@7 (>=22), concurrently@10 (>=22), license-checker-rseidelsohn@5 (>=24), @lerna-lite/cli@5 (^22.17 || >=24). Only jest-dom sits in the Node 20 test path; the rest are release-only (publish.yml is on Node 24) or unused. Yarn treats engine mismatches as warnings, so CI will not fail on install — but jest-dom 7 on Node 20 is untested. Bumping test.yml to Node 24 is the honest companion change; left alone as out of scope.
  2. @types/node@26 is several majors ahead of both CI runtimes (20 test / 24 publish). ^24 would match reality better.
  3. concurrently is referenced by no script in the repo — a removal candidate rather than a bump target. Same for root conventional-commits-filter.
  4. lerna.json's $schema points at node_modules/lerna/schemas/lerna-schema.json, which does not exist — this repo uses lerna-lite. Pre-existing.
  5. ts-jest 29.4.12 emits TS151002 ("hybrid module kind is only supported in isolatedModules: true"). Tests pass; fixing it is a tsconfig change.

🤖 Generated with Claude Code

mfal and others added 8 commits September 4, 2026 14:56
…ext major

- rimraf ^5.0.10 -> ^6.1.3 (all packages)
- read-pkg ^9.0.1 -> ^10.1.0 (@mittwald/api-client)
- prettier-plugin-sort-json ^3.1.0 -> ^4.2.0 (root, commons, generator, mittwald)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@typescript-eslint/eslint-plugin and @typescript-eslint/parser
^7.18.0 -> ^8.68.0 (root and all packages). ESLint stays on v8.57;
typescript-eslint v8 supports eslint ^8.57 || ^9 || ^10.

Two rule changes needed adjustments:

- no-unused-vars now defaults to caughtErrors: "all", which flagged two
  unused catch bindings in UniversalContentLoader; they now use optional
  catch binding.
- no-unused-expressions is part of the v8 recommended set and flagged the
  deliberate bare member expressions in *.test-types.ts type assertions;
  disabled for those files via an eslint override.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- jest ^29.7.0 -> ^30.5.0 (commons, generator, models)
- @jest/globals ^29.7.0 -> ^30.5.0 (commons, generator, models)
- jest-environment-jsdom ^29.7.0 -> ^30.5.0 (models)
- @types/jest ^29.5.14 -> ^30.0.0 (commons, generator, models)

jest 30 removed the deprecated matcher aliases toBeCalledWith,
toBeCalledTimes and toThrowError; the three call sites now use
toHaveBeenCalledWith, toHaveBeenCalledTimes and toThrow.

ts-jest keeps its declared ^29.2.5 range but is re-resolved in the
lockfile from 29.2.5 to 29.4.12, the first line that declares
jest ^30 as a supported peer. No ts-jest manifest entry is changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
^6.9.1 -> ^7.0.1 in @mittwald/api-models. The only matcher used
(toBeInTheDocument) is unchanged in v7.

Note: jest-dom v7 declares engines.node >= 22, while .github/workflows/test.yml
still runs on Node 20.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
^22.18.11 -> ^26.4.0 in @mittwald/api-client. 26.4.1 is still inside the
npmMinimalAgeGate window, hence 26.4.0.

Note: CI runs Node 20 (test.yml) and Node 24 (publish.yml), so the type
surface is now several majors ahead of the runtime actually exercised.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- @lerna-lite/cli ^4.9.1 -> ^5.6.1
- @lerna-lite/publish ^4.9.1 -> ^5.6.1
- conventional-commits-filter ^5.0.0 -> ^6.0.1

Verified that every flag the publish workflow passes still exists in
lerna-lite v5: --message, --skip-bump-only-releases, --conventional-commits,
--create-release, --no-private, --tag-version-prefix and the from-package
positional. lerna-lite v5 requires Node ^22.17 || >=24; publish.yml runs
Node 24.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…to v10

- license-checker-rseidelsohn ^4.4.2 -> ^5.0.1 (root)
- concurrently ^8.2.2 -> ^10.0.5 (root, @mittwald/api-client)

'yarn test:licenses' still exits 0 with the v5 CLI and unchanged flags.

Note: license-checker-rseidelsohn v5 declares engines node >= 24 / npm >= 11,
and concurrently v10 node >= 22. Neither runs in the Node 20 test workflow.
concurrently is not referenced by any script in this repo and looks like a
removal candidate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
^21.6.5 -> ^23.1.2 (23.2.0 is still inside the npmMinimalAgeGate window).

No nx.json migration was needed: this repo only uses nx as a task runner
with targetDefaults, no plugins and no project.json files. run-many,
affected and the local cache all behave as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Keep master's `@mittwald/react-use-promise` at ^4.2.3 in all three manifests;
it was bumped on master and is a production peer, not one of this branch's
devDependency majors. The major bumps of this branch (`@jest/globals`,
`@types/jest`, `@typescript-eslint/*`, `@types/node`) are kept.

yarn.lock was regenerated from master's lockfile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant