Merge pull request #19981 from backstage/rugvip/const

core-plugin-api: remove the need to declare translation messages as const
This commit is contained in:
Patrik Oldsberg
2023-09-19 00:52:44 +02:00
committed by GitHub
9 changed files with 45 additions and 29 deletions
+12 -3
View File
@@ -64,8 +64,6 @@ import { SessionState } from '@backstage/core-plugin-api';
import { StorageApi } from '@backstage/core-plugin-api';
import { StorageValueSnapshot } from '@backstage/core-plugin-api';
import { SubRouteRef } from '@backstage/core-plugin-api';
import { TranslationMessages } from '@backstage/core-plugin-api/alpha';
import { TranslationResource } from '@backstage/core-plugin-api/alpha';
// @public
export class AlertApiForwarder implements AlertApi {
@@ -225,7 +223,18 @@ export type AppOptions = {
__experimentalTranslations?: {
defaultLanguage?: string;
availableLanguages?: string[];
resources?: Array<TranslationMessages | TranslationResource>;
resources?: Array<
| {
$$type: '@backstage/TranslationResource';
id: string;
}
| {
$$type: '@backstage/TranslationMessages';
id: string;
full: boolean;
messages: Record<string, string>;
}
>;
};
};
@@ -360,7 +360,9 @@ describe('I18nextTranslationApi', () => {
await new Promise<void>(resolve => {
const subscription = translationApi.translation$(plainRef).subscribe({
next(snapshot) {
const translation = snapshot.ready ? snapshot.t('foo') : null;
const translation = snapshot.ready
? (snapshot.t('foo') as string)
: null;
translations.push(translation);
if (translation === 'foo') {
@@ -381,7 +383,7 @@ describe('I18nextTranslationApi', () => {
describe('formatting', () => {
function snapshotWithMessages<
TMessages extends { [key in string]: string },
const TMessages extends { [key in string]: string },
>(messages: TMessages) {
const translationApi = I18nextTranslationApi.create({
languageApi: AppLanguageSelector.create(),
@@ -398,7 +400,7 @@ describe('I18nextTranslationApi', () => {
foo: 'Foo',
bar: 'Bar',
baz: 'Baz',
} as const);
});
expect(snapshot.t('foo')).toBe('Foo');
expect(snapshot.t('bar')).toBe('Bar');
@@ -410,7 +412,7 @@ describe('I18nextTranslationApi', () => {
shallow: 'Foo {{ bar }}',
multiple: 'Foo {{ bar }} {{ baz }}',
deep: 'Foo {{ bar.baz }}',
} as const);
});
// @ts-expect-error
expect(snapshot.t('shallow')).toBe('Foo {{ bar }}');
@@ -439,7 +441,7 @@ describe('I18nextTranslationApi', () => {
it('should not escape by default', () => {
const snapshot = snapshotWithMessages({
foo: 'Foo {{ foo }}',
} as const);
});
expect(snapshot.t('foo', { replace: { foo: '<div>' } })).toBe(
'Foo <div>',
@@ -457,7 +459,7 @@ describe('I18nextTranslationApi', () => {
foo: 'Foo $t(bar) $t(baz)',
bar: 'Nested',
baz: 'Baz {{ qux }}',
} as const);
});
expect(snapshot.t('foo', { qux: 'Deep' })).toBe('Foo Nested Baz Deep');
});
@@ -472,7 +474,7 @@ describe('I18nextTranslationApi', () => {
relativeSecondsShort:
'= {{ x, relativeTime(range: second; style: short) }}',
list: '= {{ x, list }}',
} as const);
});
expect(snapshot.t('plain', { replace: { x: '5' } })).toBe('= 5');
expect(snapshot.t('number', { replace: { x: 5 } })).toBe('= 5');
@@ -528,7 +530,7 @@ describe('I18nextTranslationApi', () => {
derp_other: 'derps',
derpWithCount_one: '{{ count }} derp',
derpWithCount_other: '{{ count }} derps',
} as const);
});
expect(snapshot.t('derp', { count: 1 })).toBe('derp');
expect(snapshot.t('derp', { count: 2 })).toBe('derps');
+10 -5
View File
@@ -27,10 +27,6 @@ import {
FeatureFlag,
} from '@backstage/core-plugin-api';
import { AppConfig } from '@backstage/config';
import {
TranslationMessages,
TranslationResource,
} from '@backstage/core-plugin-api/alpha';
/**
* Props for the `BootErrorPage` component of {@link AppComponents}.
@@ -286,7 +282,16 @@ export type AppOptions = {
__experimentalTranslations?: {
defaultLanguage?: string;
availableLanguages?: string[];
resources?: Array<TranslationMessages | TranslationResource>;
resources?: Array<
// Separate declaration for now to avoid dependency on core-plugin-api/alpha and TS 5.0
| { $$type: '@backstage/TranslationResource'; id: string }
| {
$$type: '@backstage/TranslationMessages';
id: string;
full: boolean;
messages: Record<string, string>;
}
>;
};
};
+1 -1
View File
@@ -41,7 +41,7 @@ export function createTranslationMessages<
// @alpha (undocumented)
export function createTranslationRef<
TId extends string,
TMessages extends {
const TMessages extends {
[key in string]: string;
},
TTranslations extends {
@@ -23,7 +23,7 @@ const ref = createTranslationRef({
one: 'one',
two: 'two',
three: 'three',
} as const,
},
});
describe('createTranslationMessages', () => {
@@ -108,7 +108,7 @@ class TranslationRefImpl<
/** @alpha */
export function createTranslationRef<
TId extends string,
TMessages extends { [key in string]: string },
const TMessages extends { [key in string]: string },
TTranslations extends {
[language in string]: () => Promise<{
default: { [key in keyof TMessages]: string | null };
@@ -18,9 +18,9 @@ import { createTranslationRef } from '@backstage/core-plugin-api/alpha';
import { MockTranslationApi } from './MockTranslationApi';
describe('MockTranslationApi', () => {
function snapshotWithMessages<TMessages extends { [key in string]: string }>(
messages: TMessages,
) {
function snapshotWithMessages<
const TMessages extends { [key in string]: string },
>(messages: TMessages) {
const translationApi = MockTranslationApi.create();
const ref = createTranslationRef({
id: 'test',
@@ -50,7 +50,7 @@ describe('MockTranslationApi', () => {
shallow: 'Foo {{ bar }}',
multiple: 'Foo {{ bar }} {{ baz }}',
deep: 'Foo {{ bar.baz }}',
} as const);
});
// @ts-expect-error
expect(snapshot.t('shallow')).toBe('Foo {{ bar }}');
@@ -73,7 +73,7 @@ describe('MockTranslationApi', () => {
it('should not escape by default', () => {
const snapshot = snapshotWithMessages({
foo: 'Foo {{ foo }}',
} as const);
});
expect(snapshot.t('foo', { foo: '<div>' })).toBe('Foo <div>');
expect(
@@ -89,7 +89,7 @@ describe('MockTranslationApi', () => {
foo: 'Foo $t(bar) $t(baz)',
bar: 'Nested',
baz: 'Baz {{ qux }}',
} as const);
});
expect(snapshot.t('foo', { qux: 'Deep' })).toBe('Foo Nested Baz Deep');
});
@@ -104,7 +104,7 @@ describe('MockTranslationApi', () => {
relativeSecondsShort:
'= {{ x, relativeTime(range: second; style: short) }}',
list: '= {{ x, list }}',
} as const);
});
expect(snapshot.t('plain', { x: '5' })).toBe('= 5');
expect(snapshot.t('number', { x: 5 })).toBe('= 5');
@@ -154,7 +154,7 @@ describe('MockTranslationApi', () => {
derp_other: 'derps',
derpWithCount_one: '{{ count }} derp',
derpWithCount_other: '{{ count }} derps',
} as const);
});
expect(snapshot.t('derp', { count: 1 })).toBe('derp');
expect(snapshot.t('derp', { count: 2 })).toBe('derps');
+1 -1
View File
@@ -22,5 +22,5 @@ export const adrTranslationRef = createTranslationRef({
content_header_title: 'Architecture Decision Records',
failed_to_fetch: 'Failed to fetch ADRs',
no_adrs: 'No ADRs found',
} as const,
},
});
+1 -1
View File
@@ -30,5 +30,5 @@ export const userSettingsTranslationRef = createTranslationRef({
select_theme: 'Select {{theme}}',
select_theme_auto: 'Select Auto Theme',
select_lng: 'Select language {{language}}',
} as const,
},
});