The language-code regex only allowed a 2-letter region subtag, so
locales Superset actually ships with a script subtag (e.g. sr_Latn)
were rejected by /language_pack/<lang>/<version>/script.js with a 400
and silently fell back to English. Widen the shared LANGUAGE_CODE_RE
to accept both region and script subtags, and add a regression test.
Also gives the test helper an explicit dict[str, Any] return type so
the inferred `context` locals in test_bootstrap_auth.py are annotated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add explicit type hints to the local variables left un-annotated in the
language-pack view and its tests, matching the typed style already used
for their neighbors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address CodeAnt nits (explicit type hints on new test locals) and a
short-circuit on language_pack_script so a nonexistent locale skips
the redundant pack-file read and error log once the version lookup
already returns None.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes the three real CI failures:
- unit-tests: get_spa_template_context called common_bootstrap_payload()
a second time just to derive the language pack context, which requires
user/auth request state that tests mocking get_spa_payload don't set
up. get_language_pack_template_context now takes the already-built
common payload dict, so template context and payload can't diverge
and the theme-helper tests pass unchanged.
- test-sqlite/mysql/postgres: register the deliberately-unauthenticated
language_pack_script route in test_views_are_secured's allowlist with
its justification (static public catalog data, must load for
anonymous principals).
- lint-frontend: type the preamble test fixture as LanguagePack
(plural_forms was missing) via a type-only import that the jest
module mock doesn't affect.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-up to #39357, which inlined the Jed language pack into the
bootstrap HTML to fix the code-split translation race (#35330). That
made non-English full-page loads carry ~67KB (gzipped) of pack on every
request since HTML is uncacheable.
This keeps the synchronous-configuration guarantee but moves the pack
to a content-addressed script: spa.html emits
<script src="/language_pack/<lang>/<version>/script.js"> before the
entry bundle, where <version> is a short content hash of the pack file.
The endpoint serves window.__SUPERSET_LANGUAGE_PACK__ = {...} with
Cache-Control: public, max-age=31536000, immutable, so browsers fetch
the pack once per translation change instead of once per page load, and
cache-bust automatically on upgrade (fixing the stale-pack window the
unversioned /language_pack/<lang>/ fetch had under the 1-year
SEND_FILE_MAX_AGE_DEFAULT).
Details:
- English emits no tag and pays nothing.
- A stale version in a cached HTML page still gets current content,
served no-cache so it can't pin under the wrong address.
- Packs provided via COMMON_BOOTSTRAP_OVERRIDES_FUNC still ride the
bootstrap payload and suppress the script tag (spa.html stashes them
on window instead), preserving the historical workaround.
- The endpoint is deliberately unauthenticated: catalogs are static
public repo content with no user data, and must load for anonymous
principals (login page, embedded).
- preamble.ts fallback chain unchanged: bootstrap pack, window global,
then async fetch if the script failed to load.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>