Repository navigation
Fix NormalizeLocales to extract path instead of codes for i18n type checking - #18467
Conversation
🦋 Changeset detectedLatest commit: e0358c2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
astro-author owns this pull requestFactory's code author persona works on this branch when a maintainer or Factory's reviewer requests changes, or when checks fail: it pushes follow-up commits, replies to review threads, and asks for another review. It never merges. Unassign astro-author to take the pull request back; reassign it to start a fresh budget. Rounds used: 0 of 5 — astro-author (Factory persona) |
There was a problem hiding this comment.
Verdict: approved. No blocking findings remain.
GitHub doesn't let Factory approve a pull request it opened, so this verdict is recorded as a comment.
Findings
No findings.
Merge Requirement Assessment
Status: satisfied
i18n.defaultLocale,i18n.fallback, andi18n.domainstypes accept a custom locale'spathinstead of itscodes.NormalizeLocalesnow maps object locales toT[K]['path']. This matchesvalidateI18nDefaultLocale,validateI18nFallback, andvalidateI18nDomainsincore/config/schemas/refined-validators.ts. Each of those validators turns locales into a list oflocale.pathvalues before checking keys and values against it.- The change is type-only, with no runtime behavior change. Only the public type alias changed. No runtime files are touched.
- Type tests cover the corrected behavior.
- The existing assertion now expects
'en' | 'french'. - A new positive case uses only object locales, with
fallbackanddomainskeyed by path. Before this change, it would not have compiled. - A new
@ts-expect-errorcase rejects acodesvalue used asdefaultLocale. Before this change, that value was accepted, so the case would have failed.
- The existing assertion now expects
Review Status
Verdict: ready to merge based on static review
Context: PR #18467 plus linked issue #18423, as referenced in the PR body
Scope: PR base d7f5c54 to head e0358c2: .changeset/hip-worlds-grab.md, packages/astro/src/types/public/config.ts, packages/astro/test/types/define-config.ts.
Changeset: present and covers astro (patch).
Limitations: I didn't read the full text of linked issue #18423. I took the requirements from the PR description and checked them against the config validators.
Validation: Static review only; no project code, tests, builds, or checks were run.
GitHub context: collected
Git scope: PR base/head verified
This review was made by an LLM. The analysis may be wrong, and reports might be incorrect.
|
| 📦 Package | 📋 Versions |
|---|---|
| vitest | 2 versions
vitest@5.0.4 |
| find-up | 4 versionsfind-up@4.1.0
find-up@6.3.0 find-up@7.0.0 |
| tinybench | 2 versions
tinybench@6.2.2 |
| @vitest/spy | 2 versions
@vitest/spy@5.0.4 |
| @vitest/mocker | 2 versions
@vitest/mocker@5.0.4 |
| why-is-node-running | 2 versions
why-is-node-running@3.2.1 |
💡 To find out what depends on a specific package, run: pnpm -r why example-package
⚠️ Package Trust Level Decreased
Caution
Decreased trust levels may indicate a higher risk of supply chain attacks. Please review these changes carefully.
| 📦 Package | 🔒 Before | 🔓 After |
|---|---|---|
| @codspeed/core | trustedPublisher | provenance |
| @codspeed/vitest-plugin | trustedPublisher | provenance |
| tinybench | stagedPublish | none |
| tinyrainbow | stagedPublish | none |
| why-is-node-running | provenance | none |
Merging this PR will not alter performance
|
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@astrojs/check](https://github.com/withastro/astro/tree/main/packages/language-tools/astro-check) ([source](https://github.com/withastro/astro/tree/HEAD/packages/language-tools/astro-check)) | [`0.9.11` → `0.9.12`](https://renovatebot.com/diffs/npm/@astrojs%2fcheck/0.9.11/0.9.12) |  |  | | [@astrojs/markdown-remark](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/markdown/remark)) | [`7.3.3` → `7.3.4`](https://renovatebot.com/diffs/npm/@astrojs%2fmarkdown-remark/7.3.3/7.3.4) |  |  | | [astro](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/astro)) | [`7.4.1` → `7.4.2`](https://renovatebot.com/diffs/npm/astro/7.4.1/7.4.2) |  |  | --- ### Release Notes <details> <summary>withastro/astro (@​astrojs/check)</summary> ### [`v0.9.12`](https://github.com/withastro/astro/blob/HEAD/packages/language-tools/astro-check/CHANGELOG.md#0912) [Compare Source](https://github.com/withastro/astro/compare/@astrojs/check@0.9.11...@astrojs/check@0.9.12) ##### Patch Changes - [#​18455](withastro/astro#18455) [`7af66fc`](withastro/astro@7af66fc) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Fixes the `astro-check` binary ignoring its first two command-line arguments, so flags such as `--help`, `--root`, `--watch`, and `--tsconfig` are respected again. If your scripts padded the arguments to work around this (for example, `astro-check -- -- --tsconfig ./tsconfig.app.json`), remove the padding. - Updated dependencies \[[`044148d`](withastro/astro@044148d)]: - [@​astrojs/language-server](https://github.com/astrojs/language-server)@2.17.3 </details> <details> <summary>withastro/astro (@​astrojs/markdown-remark)</summary> ### [`v7.3.4`](https://github.com/withastro/astro/blob/HEAD/packages/markdown/remark/CHANGELOG.md#734) [Compare Source](https://github.com/withastro/astro/compare/@astrojs/markdown-remark@7.3.3...@astrojs/markdown-remark@7.3.4) ##### Patch Changes - Updated dependencies \[[`cf27e70`](withastro/astro@cf27e70)]: - [@​astrojs/prism](https://github.com/astrojs/prism)@4.1.1 </details> <details> <summary>withastro/astro (astro)</summary> ### [`v7.4.2`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#742) [Compare Source](https://github.com/withastro/astro/compare/astro@7.4.1...astro@7.4.2) ##### Patch Changes - [#​18430](withastro/astro#18430) [`dda9ec3`](withastro/astro@dda9ec3) Thanks [@​Abhirup-99](https://github.com/Abhirup-99)! - Speeds up content sync with `experimental.collectionStorage: "chunked"` by computing each character's UTF-8 width from its code point instead of encoding every character through `TextEncoder`. On a store of \~44k entries this cuts the chunking step from about 60 seconds to well under a second, with byte-identical output. - [#​18438](withastro/astro#18438) [`5e0eaa4`](withastro/astro@5e0eaa4) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Fixes `astro dev` with `@astrojs/cloudflare` failing with ``Calling `require` for "node-fetch"`` when a server dependency such as `cross-fetch` requires `node-fetch` - [#​18376](withastro/astro#18376) [`a4e201d`](withastro/astro@a4e201d) Thanks [@​okxint](https://github.com/okxint)! - Fixes `astro dev` treating a stale lock file containing a Linux thread ID as a running Astro server. A successful process lookup with no matching PID now marks the lock as stale, preventing `astro dev stop` and `astro dev --force` from killing the unrelated process that owns the thread. - [#​18467](withastro/astro#18467) [`d1fb7d3`](withastro/astro@d1fb7d3) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Fixes the `defineConfig()` types for `i18n.defaultLocale`, `i18n.fallback`, and `i18n.domains` so they accept a custom locale's `path` instead of its `codes`, matching how Astro validates and uses these values - [#​18475](withastro/astro#18475) [`cf27e70`](withastro/astro@cf27e70) Thanks [@​ematipico](https://github.com/ematipico)! - Bumps the minimum supported Node.js version to 22.23.4, which includes the fixes from the [October 2026 Node.js security releases](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases) This is a patch release because the [Node.js support and upgrade policy](https://docs.astro.build/en/upgrade-astro/#nodejs-support-and-upgrade-policies) allows the Core team to raise the minimum Maintenance LTS version in a patch release when a disclosed and fixed Node.js security flaw affects Astro. - [#​18451](withastro/astro#18451) [`7a0ba6f`](withastro/astro@7a0ba6f) Thanks [@​DenisCDev](https://github.com/DenisCDev)! - Fixes `astro sync`, `astro check` and `astro build` replacing the optimized dependencies of a dev server running in the same project, which broke framework islands in that dev server until it was restarted with `--force` - [#​18336](withastro/astro#18336) [`e943003`](withastro/astro@e943003) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Fixes inline styles in dev so that framework-transformed CSS is used, such as scoped styles and `v-bind()` in Vue single-file components - [#​18399](withastro/astro#18399) [`829fc00`](withastro/astro@829fc00) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Fixes a dev server error (`Could not find server component name`) for a `server:defer` island that imports `astro:actions` or `astro:config/server`, when its page was not the first island page loaded after starting the server - [#​18330](withastro/astro#18330) [`4db9e0d`](withastro/astro@4db9e0d) Thanks [@​Samuteg](https://github.com/Samuteg)! - Fixes the `astro:env/server` virtual module being generated with invalid JS in dev when any environment variable contains `$` replacement patterns (`` $` ``, `$&`, `$'`, `$1`, …). The inlined env JSON was passed as a string to `String.replace`, so e.g. the `KITTY_PUBLIC_KEY` value set by default in Kitty terminals corrupted the module and broke dev with `Failed to parse source for import analysis` - Updated dependencies \[[`cf27e70`](withastro/astro@cf27e70)]: - [@​astrojs/telemetry](https://github.com/astrojs/telemetry)@3.4.1 - [@​astrojs/markdown-satteri](https://github.com/astrojs/markdown-satteri)@0.4.5 </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xODEuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjE4MS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
* Fix corrupted `astro:env/server` module when env vars contain `$` replacement patterns (#18330) * [ci] format * Fix inlined Vue styles in dev serving untransformed (unscoped, raw v-bind) CSS (#18336) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(deps): update vitest monorepo to v5 (#18403) Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev> * Update Partytown to 1.0.1 (#18439) * fix(cloudflare): return 4xx instead of 500 from `/_image` when the source isn't an image (#18422) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * Skip server island manifest in CSS ensureModulesLoaded to fix late-discovery 500 in dev (#18399) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Fix astro-check binary silently dropping the first two CLI arguments (#18455) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Preserve sharpImageService() options when imageService: 'compile' is used in the Cloudflare adapter (#18461) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(check): skip Volar's cancellation polling sleep in `astro check` (#18460) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(content): compute UTF-8 width arithmetically in getChunkEnd (#18430) * fix(content): compute UTF-8 width arithmetically in getChunkEnd * test(content): cover UTF-8 width boundaries and lone surrogates in chunkString * chore: changeset * fix(cloudflare): don't prebundle Astro in the Node prerender environment so a custom src/fetch.ts renders through the dev environment (#18465) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Respect exact version argument in @astrojs/upgrade (#18466) * fix(upgrade): respect exact version argument in @astrojs/upgrade * fix(upgrade): only pin exact version for the astro package Integrations are versioned independently, so a published version string matching the requested Astro version must not be used for them; they keep the dist-tag/latest fallback instead of being downgraded. --------- Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(i18n): use locale path instead of codes in defineConfig i18n types (#18467) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(cloudflare): skip Prism optimizeDeps include during type generation so sync/check/build don't overwrite a running dev server's deps_ssr (#18468) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Use a separate Vite cache for the temporary sync server (#18451) `astro sync`, which `astro check` and `astro build` also run, starts a temporary Vite server with `optimizeDeps: { noDiscovery: true }`. Astro and integrations still add `optimizeDeps.include` entries, so Vite keeps the dependency optimizer running there, and it wrote to the default Vite cache. That replaced the optimized dependencies of a dev server running in the same project, so framework islands in that dev server broke (for example React's production `jsx-dev-runtime`, where `jsxDEV` is undefined) until it was restarted with `--force`. The temporary server now writes to `<cacheDir>/vite-sync/`. It optimizes the same dependencies as before; only the output location changes. Fixes #18449 Tested: `astro-sync.test.ts` passes 10/10; the new test fails without the change in `sync/index.ts`. * fix(dev): treat missing ps row as stale in lockfile process check (#18376) Co-authored-by: Princesseuh <3019731+Princesseuh@users.noreply.github.com> * fix(astro): stop excluding node-fetch from server dep optimization in workerd dev (#18438) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Update dependency @playwright/test to v1.64.1 (#18441) * Update @astrojs/node (#18440) * Close duplicate pull requests when an issue is fixed (#18472) * fix: minimal support node version (#18475) * [ci] release (#18459) * Fix release workflow package list after the Changesets v3 upgrade (#18104) Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: Armand Philippot <git@armand.philippot.eu> * Fix DataCloneError when importing SVGs with parallelPrerender enabled (#18476) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> Co-authored-by: Princesseuh <3019731+Princesseuh@users.noreply.github.com> * fix(telemetry): look up the project ID without blocking (#18481) * Skip CSP hashes for external stylesheets and scripts. (#18488) * [ci] format * fix(astro): allow Node.js >=22.22.0 on StackBlitz WebContainers (#18494) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(assets): dedupe equivalent densities in image srcset (#18500) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * docs: update legacy flags JSDocs to generate their reference in docs (#18378) Co-authored-by: ematipico <602478+ematipico@users.noreply.github.com> * Restore scroll position instantly on back/forward navigation when smooth scrolling is enabled (#18506) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(transitions): silence ready rejection before skipTransition in ClientRouter (#18517) * Merge commit from fork * ci: pass issue author login to needs-repro step via env (#18518) * Restore CSS tree-shaking for unused barrel-imported Astro components (#18493) * Mark $$createComponent pure so unused barrel-exported components drop their scoped CSS * Bump Vite to 8.3.5 (Rolldown 1.2.15) and exercise the image service at runtime in the Sharp test Rolldown 1.2.13 could fold its runtime helpers into a dynamically imported page chunk, making the SSR entry statically import (and eagerly evaluate) that page. Rolldown 1.2.14+ keeps the runtime out of entry chunks. With unused components tree-shaken, the Cloudflare worker only bundles the Sharp chain when an on-demand route uses the image service, so the Sharp test now makes api.ts call getImage(). --------- Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> Co-authored-by: Matthew Phillips <matthew@matthewphillips.info> * Update @astrojs/markdoc (#18513) * fix(@astrojs/vercel): make redirects match when trailingSlash is always/never (#18085) * fix(@astrojs/vercel): make redirects match when trailingSlash is always/never * refactor(@astrojs/vercel): use path slash utilities in adjustSourceForTrailingSlash * fix(@astrojs/vercel): make spread redirects match under trailingSlash always * fix(@astrojs/vercel): match Vercel's dot rule for trailing-slash redirects Vercel's normalizer only appends a slash when the last segment has no dot, so a dotted source must stay unslashed and a dynamic or spread last segment has to match both forms. Verified against @vercel/routing-utils output. * fix(@astrojs/vercel): avoid super-linear backtracking in dot check eslint's regexp/no-super-linear-backtracking rejects the two overlapping [^/]* quantifiers; anchoring on the last dot is equivalent and linear. * fix(csp): include hashes inserted by body components in the CSP meta tag for non-streaming renders (#18512) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(server-islands): keep fallback instead of throwing when the island fetch fails (#18497) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(assets): avoid duplicate 1x candidate in Picture source srcset when densities includes 1 (#18504) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * [ci] format * fix(cloudflare): scope process.env define to server environments so client bundles get Vite's default replacement (#18526) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Fix type errors in shipped components under the `strictest` TypeScript preset (#18524) * Fix strictest tsc errors in shipped Image, Picture, Code, Debug and ClientRouter components * test(astro): type-check shipped components under strictest tsconfig Add an astro check fixture whose tsconfig extends astro/tsconfigs/strictest and includes node_modules/astro/components/*.astro, so the strictest errors from #18471 cannot come back without CI failing. --------- Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * fix(cli): drop shell: true from astro info package manager calls to avoid DEP0190 warning (#18525) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Pass the React id prefix to `renderToString` when streaming is disabled (#18482) * fix(react): pass identifierPrefix to renderToString when streaming is disabled * test(react): give the disable-streaming fixture its own outDir * Merge commit from fork * Merge commit from fork * Fix transition:name styles silently dropped in dev when component is nested under a non-propagating component (#18511) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * Prevent memory cache from storing empty 404/500 responses that would be rerouted to error pages (#18522) Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> * [ci] release (#18478) * astro add: configure tagged official adapters (#18344) Recognize resolved official package names when tagged specifiers are used so installation and Astro config updates stay aligned. Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com> --------- Co-authored-by: Samuteg <151961384+Samuteg@users.noreply.github.com> Co-authored-by: Samuteg <Princesseuh@users.noreply.github.com> Co-authored-by: astro-factory[bot] <316791938+astro-factory[bot]@users.noreply.github.com> Co-authored-by: factory[bot] <factory[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev> Co-authored-by: Jack Hanford <jackhanford@gmail.com> Co-authored-by: Tim L. White <tim@cyface.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> Co-authored-by: Abhirup Pal <abhiruppalmethodist@gmail.com> Co-authored-by: Denis Scarabelli <87149177+DenisCDev@users.noreply.github.com> Co-authored-by: okxint <130782884+okxint@users.noreply.github.com> Co-authored-by: Emanuele Stoppa <estoppa@cloudflare.com> Co-authored-by: Houston (Bot) <108291165+astrobot-houston@users.noreply.github.com> Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: Armand Philippot <git@armand.philippot.eu> Co-authored-by: Muhammad Umer Aamir <93091750+umeraamir69@users.noreply.github.com> Co-authored-by: ematipico <602478+ematipico@users.noreply.github.com> Co-authored-by: Nikolas Sapalidis <84yk8btb9f@privaterelay.appleid.com> Co-authored-by: knj <kenji.tomita1996@gmail.com> Co-authored-by: Waleed Rostom 🐦⬛ <waleed.rostom@meetsmore.com> Co-authored-by: Edmund Hung <me@edmund.dev>
Changes
NormalizeLocalesnow extractsT[K]['path']instead ofT[K]['codes'][number]from object locales, so the TypeScript type fori18n.defaultLocale(andi18n.fallback/i18n.domainskeys) matches what config validation and the i18n runtime actually require. Previously, passing a localepathasdefaultLocalewas a type error, while passing acodesvalue was a runtime error — making it impossible to satisfy both at once.Testing
packages/astro/test/types/define-config.tsto assert thatdefaultLocaleaccepts a localepathvalue, and added positive/negative cases covering the corrected type.Docs
Closes #18423