Skip to content

release/v2.2.1#22

Merged
kodjunkie merged 16 commits into
masterfrom
release/v2.2.1
May 3, 2026
Merged

release/v2.2.1#22
kodjunkie merged 16 commits into
masterfrom
release/v2.2.1

Conversation

@kodjunkie
Copy link
Copy Markdown
Owner

@kodjunkie kodjunkie commented May 3, 2026

v2.2.1 — maintenance release

No consumer source changes. Resolves the v2.2.0 release-notes "known issue" on the c.basic-crud compound-primary-key route test, plus a round of test-suite reliability hardening, dev-tree advisory closures, and a brand refresh for GitHub dark-mode readers.

Fixed

  • cursor.spec cell 9 (soft-delete still applies in cursor mode) was selecting targetId as the last id of the first cursor page. The /users-cursor controller is configured with limit: 5, so under ?sort=id,ASC the first page returned ids [1..5] and targetId landed on user 5 — the row exercised by c.basic-crud's GET /users4/1/5 compound-key route test. The cell now POSTs a throwaway user, captures the returned id, and DELETEs that id; the seed range is no longer touched and execution order no longer matters. Test-fixture-only — no consumer code is affected.

Changed

  • test:typeorm:mysql script now passes --runInBand to jest. Single-worker execution avoids parallel-worker contention against the shared MySQL container that v2.2.0 hit.
  • The supertest done(callback) pattern is migrated to direct await across b.query-params.spec.ts, c.basic-crud.spec.ts, and the three real-db-smoke.spec.ts files (drizzle, mikro-orm, prisma). Failures now surface as Promise rejections with a clean stack instead of hanging to jest's 30s timeout.

Removed

  • The orphan mrepo.json file at the repo root is removed (the v2.2.0 mrepo→lerna swap left the config file behind; nothing reads it any more).

Internal

  • tmp 0.0.33 → ^0.2.4 (closes GHSA-52f5-9888-hmc6, low) and @conventional-changelog/git-client 1.0.1 → ^2.0.0 (closes GHSA-vh25-5764-9wcr, medium) force-pinned via root resolutions. uuid 11 → 14 (GHSA-w5hq-g745-h8pq, medium) intentionally NOT resolved — uuid 14 ships as "type": "module", breaks ts-jest CJS preset across all five jest configs. Carried concern; no consumer impact.
  • knip.json reduced to the entries knip 5 cannot auto-detect (16 hints → 0).
  • [Unreleased] sections promoted to [2.2.0] — 2026-05-03 across the 8 CHANGELOGs (the v2.2.0 publish itself missed the rename — process gap closed for next cycle).
  • img/logo.svg split into img/logo-{light,dark}.svg + matching icon pair; README.md hero now uses <picture> with prefers-color-scheme: dark so the wordmark is visible in either GitHub theme.

Verified locally

  • yarn build → exit 0
  • yarn test:typeorm:postgres → 15/15 suites
  • yarn test:typeorm:mysql → 15/15 suites (compound-key un-skipped, all 276 tests green)
  • yarn test:drizzle:postgres → 10/10 suites
  • yarn test:mikro-orm:postgres → 12/12 suites
  • yarn test:prisma:postgres → 13/13 suites
  • yarn test:parity → 1/1 suite (72 tests)
  • yarn knip → exit 0

kodjunkie added 16 commits May 3, 2026 17:08
Add `--runInBand` to `test:typeorm:mysql` so jest runs all spec files in a
single worker process. The failing v2.2.0 c.basic-crud compound-key route
test points at parallel-worker contention against the shared MySQL container
— another spec in a sibling worker mutates the User row mid-suite, so the
`WHERE companyId=1 AND profileId=5` lookup returns 0 rows.

Apply the same isolation only to MySQL because release.yml's sequential
`yarn test:all` runs typeorm:postgres FIRST (clean DB) then typeorm:mysql
SECOND (where the contention manifests). Postgres run never had the bug
because mutations across workers don't cross-pollute when each adapter run
gets its own DB-prepare drop+seed and is the first sequential pass.

Un-skips the c.basic-crud compound-key test that v2.2.0 shipped with
`it.skip` to unblock publish.
Pre-request: dump registered Express routes filtered to /users4 + total
route count. Post-failure: dump full response shape (status/body/text/headers).

The test passes locally but returns 404 in CI MySQL with zero SQL emitted —
need to determine whether the route is registered at all in CI before
applying any further fix attempt. Diagnostic is no-op on success path.
Route registration is confirmed (count: 7 incl. GET /users4/:companyId/:profileId).
Response shape confirms 404 from CrudService NotFoundException, not from NestJS
routing. So the SELECT WHERE companyId=1 AND profileId=5 is returning 0 rows.

Add a raw SQL probe via the app's DataSource right before the request:
- All rows where id=5 OR profileId=5
- Targeted lookup matching the route's WHERE clause

Will reveal whether user 5 was deleted, soft-deleted, or had its companyId/
profileId mutated mid-suite by an earlier spec.
…reAll

Earliest jest-side observation point. Will reveal whether seed actually inserted user 5 in MySQL or whether it vanished during seed itself.
Reverts 53361ad, 3a8b42f, 528e1dc, 553740c, 190c9a7. These commits
added console.log dumps of users/companies state at beforeAll and inside
the c.basic-crud compound-key test for CI investigation. Root cause has
been identified — see follow-up commit.
cursor.spec.ts cell 9 ("soft-delete still applies in cursor mode")
selected `targetId` as the last id of the first cursor page. The
/users-cursor controller is configured with `limit: 5`, so under
`?sort=id,ASC` the first page returns ids [1..5] and `targetId` lands
on user 5.

User 5 is part of the shared seed (companyId=1, profileId=5) and is
the row exercised by c.basic-crud's compound-key route test
`GET /users4/1/5`. The /users-cursor controller has no softDelete
config so the DELETE is a hard delete via TypeORM remove, dropping
the row from the shared `users` table.

Whether the bug surfaces depends on jest's file-execution order.
Locally jest tends to run c.basic-crud first (largest file in
sequencer cache) and the bug stays hidden. release.yml's MySQL
runner sequences cursor.spec before c.basic-crud and the compound-key
test then sees user 5 gone — `[diag user5 rows] []`, status 404.

Replace the seed-row target with a POST throwaway user (matching the
shape used in cell 5), capture the returned id, and DELETE that id.
The seed range is now untouched and execution order no longer matters.
Post-v2.2.0 fix for CI MySQL c.basic-crud compound-key flake.

Root cause: cursor.spec cell 9 hard-deleted seeded user 5 from the
shared `users` table when jest sequenced cursor.spec before
c.basic-crud (jest default file-order varies by environment; CI hit
the failing order, local did not).

Includes:
- d3a91ac: --runInBand on test:typeorm:mysql + un-skip compound-key
- 47cdeb4: revert 5 diagnostic instrumentation commits
- 7e5fbab: fix(test) — cursor.spec cell 9 uses POST throwaway target
The @zmotivat0r/mrepo orchestrator was replaced with native lerna +
TypeScript composite project references in v2.2.0 (see CHANGELOG
[Unreleased]). The orphan mrepo.json config file was left behind and
is no longer read by any tooling.
v2.2.0 shipped 2026-05-03 (npm + tag v2.2.0 + GitHub Release) but the
CHANGELOG sections were never promoted from [Unreleased]. Renames the
section header in:

- CHANGELOG.md
- packages/core/CHANGELOG.md
- packages/drizzle/CHANGELOG.md
- packages/mikro-orm/CHANGELOG.md
- packages/prisma/CHANGELOG.md
- packages/request/CHANGELOG.md
- packages/typeorm/CHANGELOG.md

Adds a fresh [2.2.0] — 2026-05-03 stub to packages/util/CHANGELOG.md
(version-only republish — bumped in lockstep with the rest of the
monorepo, no package-specific source changes).

Date pulled from `gh release view v2.2.0`.
knip 5 auto-detects per-package `src/index.ts` (via package.json `main`)
and `jest.config.js` (via the jest plugin), so the explicit entries in
each workspace block were redundant and surfaced as configuration
hints on every run.

Also drops:
- `@mikro-orm/knex` from root `ignoreDependencies` — was a peer of
  @nestjs-crud/mikro-orm in v2.0.0 and removed in v2.0.1; nothing in
  the root references it any more.
- `lerna` from root `ignoreDependencies` — now actually used by the
  release workflow and `yarn run rebuild` after the v2.2.0 mrepo→lerna
  swap, so it correctly resolves as a binary.
- `src/crud/swagger.helper.ts` from packages/core `ignore` — knip can
  reach the file through normal import graph traversal now that the
  v3-gate dead-code paths have been removed.

Adds `optionalPeerDependencies: "off"` so the @nestjs/swagger optional
peer (declared optional in 2.1.1, intentionally referenced via
safeRequire in swagger.helper.ts) does not flip the exit code.

`yarn knip` now exits 0 with no findings.
Migrates the supertest done(callback) pattern to direct await across
five spec files:

- packages/typeorm/test/b.query-params.spec.ts (~23 tests)
- packages/typeorm/test/c.basic-crud.spec.ts (~32 tests)
- packages/drizzle/test/real-db-smoke.spec.ts (5 tests)
- packages/mikro-orm/test/real-db-smoke.spec.ts (5 tests)
- packages/prisma/test/real-db-smoke.spec.ts (5 tests)

Why: under shared-DB stress (CI MySQL container, parallel-worker
contention) the supertest .end((_, res) => { ...; done() }) callback
can fail to fire and the test hangs to jest's 30s timeout instead of
producing a Promise rejection with a clean stack. supertest >= 7
returns a thenable from request(server).get(...), so direct `await`
removes the manual callback bridge and surfaces failures with the
expected supertest assertion.

Behavior unchanged. All assertions preserved.

Verified locally:
- yarn test:typeorm:mysql       15/15 suites, 275 passed + 1 skipped
- yarn test:drizzle:postgres    10/10 suites, 91 passed
- yarn test:mikro-orm:postgres  12/12 suites, 131 passed
- yarn test:prisma:postgres     13/13 suites, 149 passed + 1 todo

packages/mikro-orm/test/users-repo.spec.ts (4 done() refs) is excluded
— that file is user-owned per the working-tree preserve rule.
Coordinated lockstep bump across all 7 publishable packages plus the
root package.json (which lerna leaves untouched — it's outside the
`packages/*` glob). lerna.json mirrors the new floor.

Maintenance release. No consumer source changes.

- Closes the v2.2.0 release-notes "known issue" on the c.basic-crud
  compound-primary-key route test (cursor.spec cell 9 was hard-deleting
  the seeded user 5 row that compound-key relies on).
- Test-suite reliability hardening — done(callback) → async/await
  across typeorm/drizzle/mikro-orm/prisma specs; --runInBand on
  test:typeorm:mysql to dodge parallel-worker DB contention.
- Removes orphan mrepo.json (the v2.2.0 mrepo→lerna swap left the
  config file behind; nothing reads it any more).
Force-bumps two transitive dev-only deps to their patched versions:

- tmp 0.0.33 → ^0.2.4   (closes GHSA-52f5-9888-hmc6, low)
- @conventional-changelog/git-client 1.0.1 → ^2.0.0
                        (closes GHSA-vh25-5764-9wcr, medium)

Both surface only in yarn.lock — no publishable package.json declares
them. CHANGELOG entries deliberately skipped per the v2.1.1 dev-tree
advisory convention; the lockfile diff plus this commit message is
the audit trail.

uuid 11 → 14 (GHSA-w5hq-g745-h8pq, medium) is intentionally NOT
resolved. uuid 14 ships as `"type": "module"` (pure ESM, no CJS
exports). Loading it under the typeorm and core ts-jest CJS preset
breaks every spec with `SyntaxError: Unexpected token 'export'`
(verified). Fix waits on either lerna 9.x and typeorm 0.3.x
publishing transitive bumps OR a coordinated jest-config ESM
transform pass that touches all five jest configs. Carried concern;
no consumer impact.

Verified locally:
- yarn build                    exit 0
- yarn test:typeorm:postgres    15/15
- yarn test:typeorm:mysql       15/15
- yarn test:drizzle:postgres    10/10
- yarn test:mikro-orm:postgres  12/12
- yarn test:prisma:postgres     13/13
- yarn test:parity              1/1
The single `img/logo.svg` rendered the wordmark and two of the four
CRUD-grid squares in slate `#1E293B`, which is invisible on GitHub's
dark theme — the README hero collapsed to a red-only fragment for any
dark-mode reader.

Splits the asset into a light/dark pair (slate text on light, frost
text on dark). Same CRUD 2x2 mark, identical stroke and corner
radius. Wordmark viewBox tightened from 440x80 to 310x80 (drops
~130px of trailing whitespace). NestJS red `#E0234E` is preserved as
the constant accent across both variants.

- img/logo-light.svg, img/logo-dark.svg          (wordmark, 310x80)
- img/logo-icon-light.svg, img/logo-icon-dark.svg (icon, 128x128)
- img/logo.svg, img/logo-icon.svg                 (removed)
@kodjunkie kodjunkie merged commit 440b0d6 into master May 3, 2026
11 checks passed
@kodjunkie kodjunkie deployed to Release May 3, 2026 19:14 — with GitHub Actions Active
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 3, 2026

Packages with version v2.2.1 have been released

@kodjunkie kodjunkie deleted the release/v2.2.1 branch May 3, 2026 19:28
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