Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/marketplace-preview-locale-keys-3546-slice5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
"@object-ui/i18n": patch
---

Backfill the `marketplace` and `preview` namespaces' 37 missing locale keys plus the `marketplace.disclosure.runtime.` template-key family (objectui#3546, slice five)

`scripts/check-i18n-call-site-keys.mjs` (objectui#3530) measured 37 keys that a
`t()` call site asks for and that **no locale pack defined** — 37 distinct keys at
37 call sites across five console components — plus one `missing-prefix` family
whose static head matched no `en` key at all, so every expansion missed. All 37
carried an inline `t(key, { defaultValue: 'English' })`, which is exactly the
objectui#3517 class: English rendered correctly, and **all ten languages were
stuck on it** for months. Nothing here rendered a raw key — slice one (PR #3583)
held those sites.

What that meant on the page for a `zh` (or `ja`, `de`, `ar`, …) user: the
marketplace's "Your organization" strip, its Install / Installing… / Installed
buttons and the version-update affordances were English; the whole ADR-0025 PD4
**pre-install permission disclosure** was English — "This package contains code",
the trust-tier badge, "Reviewed & approved" / "Not yet reviewed" / "Signed", the
four permission group labels (platform services, lifecycle hooks, network,
filesystem) and the consent checkbox the user ticks to accept them; the ADR-0045
unpublished-app banner and its publish toasts were English; and the entire
ADR-0067 build-history sheet — title, description, the per-commit labels, the
Revert button and both of its result toasts — was English.

`marketplace.disclosure.runtime.` is repaired as an **enumeration, not a
wildcard**: its value surface is the closed trust-tier enum
(`PluginRuntimeSchema` = `z.enum(['node', 'sandbox', 'worker'])`, ADR-0025 §3.6),
so all three members are backfilled and the family leaves the ratchet's
`missingPrefixes` (3 → 2). A test reads the component's own fallback map and
fails if a fourth tier is ever added without a key — the job the prefix entry
used to do.

Each `en` value is byte-identical to the inline `defaultValue` it replaces (36 of
36 literal sites; the 37th's `defaultValue` is a template literal whose
`${pkg.display_name}` becomes the `{{name}}` hole its call site already passes),
so no English string a user sees today changes. The nine translations follow each
pack's own neighbourhood — including two namespaces that legitimately take
**different** second persons in `zh` (`marketplace` 你, `preview` 您) — and reuse
an existing neighbour's translation wherever the `en` string already existed
verbatim, so one English string never renders as two different sentences in the
same language.

No component changed: an AST sweep of the whole `marketplace.*`/`preview.*`
call-site surface found the slice's own dead-`||`-fallback count to be zero.
15 changes: 8 additions & 7 deletions packages/i18n/src/__tests__/auth-namespace-3546.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,18 @@ describe('objectui#3546 slice three — the auth / oauth / acceptInvitation name
);
expect(stillBaselined).toEqual([]);
// 163 before this slice, 54 removed — then slice four (console, 41 keys) took
// it to 68. The other namespaces' debt is not this slice's to spend, and this
// number is what catches a slice that overreaches; it moves once per slice,
// and only downwards.
expect(Object.keys(baseline.missingKeys).length).toBe(68);
// it to 68 and slice five (marketplace + preview, 37 keys) to 31. The other
// namespaces' debt is not this slice's to spend, and this number is what
// catches a slice that overreaches; it moves once per slice, and only
// downwards.
expect(Object.keys(baseline.missingKeys).length).toBe(31);
// None of the template-key FAMILIES belonged to the auth family, so this slice
// left all four. Slice four then took `console.ai.group.` (it is a `console`
// key), leaving three. This assertion is what stops a later slice from
// thinking one of the remaining three was already handled.
// key) and slice five `marketplace.disclosure.runtime.`, leaving two. This
// assertion is what stops a later slice from thinking one of the remaining
// two was already handled.
expect(Object.keys(baseline.missingPrefixes).sort()).toEqual([
'gantt.linkEnd.',
'marketplace.disclosure.runtime.',
'organization.invitations.status.',
]);
});
Expand Down
13 changes: 7 additions & 6 deletions packages/i18n/src/__tests__/console-namespace-3546.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,15 @@ describe('objectui#3546 slice four — the console namespace', () => {
missingPrefixes: Record<string, unknown>;
};
expect(Object.keys(baseline.missingKeys).filter((k) => k.startsWith('console.'))).toEqual([]);
// 109 before this slice, 41 removed. The other namespaces' debt is not this
// slice's to spend; this number moves once per slice, and only downwards.
expect(Object.keys(baseline.missingKeys).length).toBe(68);
// The prefix family this slice handled is GONE from the ratchet, and the other
// three are untouched — none of them belongs to `console`.
// 109 before this slice, 41 removed — then slice five (marketplace + preview,
// 37 keys) took it to 31. The other namespaces' debt is not this slice's to
// spend; this number moves once per slice, and only downwards.
expect(Object.keys(baseline.missingKeys).length).toBe(31);
// The prefix family this slice handled is GONE from the ratchet, and the ones
// that remain are untouched — none of them belongs to `console`. Slice five
// then took `marketplace.disclosure.runtime.`, leaving two.
expect(Object.keys(baseline.missingPrefixes).sort()).toEqual([
'gantt.linkEnd.',
'marketplace.disclosure.runtime.',
'organization.invitations.status.',
]);
expect(Object.keys(baseline.missingPrefixes)).not.toContain('console.ai.group.');
Expand Down
Loading
Loading