build(frontend): finish the React 19 move, and hold the versions that were left in prose
react-i18next was still on ^14.1.2. The E27 S1 plan named it as "the one peer that actually needs moving — React 19 support is the 15 line", and then it did not move. The 14 line's <Trans> reads `element.ref`, removed in React 19, and its withTranslation types are built on the GLOBAL JSX namespace @types/react 19 no longer declares — both latent only because this app imports neither. 15.7.4 fixes both at the source (`c.props.ref ?? c.ref`, `React.JSX.LibraryManagedAttributes`). `reactEngine.contract.test.ts` joins its Node and Python twins and holds what was only a comment: the compiler's `target` against the installed React major, react and react-dom together, the types against the runtime, and react-i18next's floor. A stale target is not a corrupt bundle — the plugin validates the option — but it is a silent one, since tsc never sees Babel's output. pythonEngine gains the seventh spelling nobody held: `requirements.lock`'s own regeneration recipe names a python image, and wheels resolve against THAT interpreter, so a recipe left behind yields a lock that does not match the image installing it. The type lane now covers `alembic` too, for the reason the ruff lane was widened to it — migrations run on every container start, so one that raises crash-loops prod. It came back at zero new errors, so the baseline is untouched. `tests/` is deliberately still out, and the config says why. vitest.config's docblock claimed the React transform is "a no-op for the plain .ts node tests". It is not: the compiler rewrites src/lib's hooks in that lane too, which is the point of sharing one factory with the build — and worth knowing before ruling the compiler out of a divergence. Tests: useCardPager had none, in either the hook or its two callers, though its page clamp moved to render in S2 — the transformation where a non-convergent condition is a crash rather than a glitch. Four cases now, including termination on an empty list. Combobox's and Avatar's close/failed-URL cases are relabelled CHARACTERIZATION: both pass against the pre-sweep code, and the tests beside them are the ones that discriminate.
This commit is contained in:
@@ -84,3 +84,17 @@ it("lints against the pinned version", () => {
|
||||
versionIn(readRoot("backend/ruff.toml"), /^target-version = "py(\d)(\d+)"$/m, "ruff.toml"),
|
||||
).toBe(pinned);
|
||||
});
|
||||
|
||||
it("resolves the lock on the pinned version", () => {
|
||||
// The seventh spelling, and the sneakiest: `requirements.lock`'s own regeneration recipe names an
|
||||
// image. Wheels and environment markers are resolved by THAT interpreter, so a recipe left behind
|
||||
// produces a lock that does not match the image installing it — the same split as the others, one
|
||||
// indirection further out, and with nothing red to show for it.
|
||||
expect(
|
||||
versionIn(
|
||||
readRoot("backend/requirements.lock"),
|
||||
/docker run [^\n]*python:(\d+)\.(\d+)-slim/,
|
||||
"requirements.lock",
|
||||
),
|
||||
).toBe(pinned);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user