Repository navigation
chore(router): regenerate per-module route type files and gate them in CI - #1127
Merged
Merged
Conversation
commit: |
…very locale generatePerModuleTypesSource and generateRouteTypesSource sorted route names with a bare `localeCompare`, so the order in `*.gen.ts` followed the machine's default locale (Czech sorts "ch" after "h"). Two machines could write different files from the same routes, and a freshness check on one reported the other's files as stale. Both sorts pin the "en" locale. The new test stubs `localeCompare` to default to Czech: without the pin `["hat", "charts"]` comes out as hat, charts; with it, charts, hat.
The per-module route-type files (`<module>.gen.ts`) are written only by the `rango generate` CLI, which nothing in CI or the hooks ran, so the committed copies drifted from their sources. tools/generate-route-types.mjs runs the router's per-module writer over every app that depends on @rangojs/router and rewrites the files; `--check` compares the generator output to the committed files and exits 1 listing stale, missing, placeholder and orphan files. apps/docs/src/content.gen.ts stays under its own writer, which gains a `--check` flag the tool drives and sorts its pages with a pinned "en" locale. The tool aborts instead of touching the disk when its fs shim over the writer does not apply (no matching import, `fs/promises`, a write moved to a helper), when the writer produces no files, or when a write run would delete more files than it generates. `--verbose` lists the modules whose includes the static parser skipped (the three committed partial maps). The writer's placeholder comment no longer claims runtime discovery fills placeholders in. Wired into the CI lint job (`pnpm check:route-gen`) and a lefthook pre-commit job gated on app sources, the generator and its inputs. AGENTS.md Hard rule 2 names the command.
Ran tools/generate-route-types.mjs: 18 stale files refreshed (including apps/docs/src/content.gen.ts, from its own writer) and 139 added (every urls()/clientUrls() module in the apps now has its `<module>.gen.ts`). Four modules whose includes the static parser cannot resolve (test-app urls/dev-routes and urls/revalidation-contract, cloudflare-stress-demo groups/hub and site-admin-patterns) get no file; the tool header explains why.
ivogt
force-pushed
the
chore/regenerate-gen-files
branch
from
October 13, 2026 02:38
4c04a7e to
2792db0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
devcorner: dc-t21
Per-module
<module>.gen.tsfiles were committed but never kept current: only therango generateCLI writes them, and nothing in CI or the hooks ran it. At 8a843aa, 16 of 60 files were stale (test-apptype-stress-test.gen.tshad 214 lines against 1,114 generated;pages/articles.gen.tslacked a route) and 131 modules had no file. A second problem hid underneath: the route names in*.gen.tswere sorted with a barelocaleCompare, so the order followed the machine's locale (Czech sorts "ch" after "h"). Two machines wrote different files from the same routes, so a freshness check on one would report the other's files as stale.Before and after
Consumers of
@rangojs/routersee one change: generated route files list names in the same order on every machine. Nothing to change in app code.End-to-end example
A contributor adds
path("/archive", ..., { name: "archive" })tosrc/urls/blog.tsxand forgets the gen file.route-genjob, gated on app sources,src/build/route-types/**and the tool) runsnode tools/generate-route-types.mjs --checkand fails, listingblog.gen.tsas stale.node tools/generate-route-types.mjs, commit the rewritten file, and the check passes.pnpm check:route-genas well, so--no-verifydoes not get around it.Semantics
--checkurls/dev-routes,urls/revalidation-contract; stress-demogroups/hub,site-admin-patterns)--verboselists the skipped includesapps/docs/src/content.gen.ts--checkCode changes
tools/generate-route-types.mjs(new): bundles the router's per-module writer from src with esbuild (in memory,packages: "external", no router build), runs it over every app that depends on@rangojs/router.--checktakes about 0.45 s.src/build/route-types/per-module-writer.ts: split into a pureplanPerModuleRouteTypesForFileand the unchanged write wrapper (placeholder only if missing, diff-before-write, catch-and-warn), so the tool needs no fs shim. Not a package export.src/build/route-types/codegen.ts:generatePerModuleTypesSourceandgenerateRouteTypesSourcesort withlocaleCompare(b, "en"). Why here: both generators feed every writer, so the pin covers the CLI, Vite and the tool.apps/docs/scripts/gen-content.mjs:--checkflag, "en" sort.package.json(check:route-gen,generate:route-types),.github/workflows/e2e.ymllint job,lefthook.ymlpre-commit job, AGENTS.md Hard rule 2 clause.*.gen.ts, plus the above.Locale fix, key lines:
Test plan
packages/rangojs-router/src/build/__tests__/generate-route-types.test.ts(new): stubslocaleCompareto default to Czech;["hat", "charts"]comes outhat, chartswithout the pin andcharts, hatwith it. Red before the pin, green after.pnpm check:route-genon the rebased tree: 198 per-module files, 198 current, 0 stale, 0 missing, 0 orphan (16 apps, 1,028 source files).--checkexit 1; a broken writer exits non-zero without deleting anything; write mode on a clean tree gives zero diff.pnpm run typecheck16/16pnpm run test:unit:all: router 8,716 passed (5 skipped, 6 todo), rsc 830 passed (2 expected fail), plus consumer suites 1, 3, 20, 25, 26, 27, 85 passedpnpm run lint: 0 warnings, 0 errorspnpm run format: cleanpnpm check:e2e-bucketing: OKNotes
node tools/generate-route-types.mjsand commit the result (Nested unnamed include() never matches: its routes answer 404 with no warning #1104/testing: after serveShellRequest serves a router, dispatch on the same router stops 308-redirecting a trailing-slash URL #1107 and the intercept redesign are the next ones). Branches opened before this lands do not have the files.## Unreleasedabove## 0.24.1).