From 2fcadae9df42e0decb73127828f688125c3153c1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 12 Sep 2023 11:19:52 +0200 Subject: [PATCH] core-plugin-api: additional translation ref refactor Signed-off-by: Patrik Oldsberg --- .../src/translation/TranslationRef.test.ts | 62 +++++++++----- .../src/translation/TranslationRef.ts | 80 ++++++++++++------- 2 files changed, 92 insertions(+), 50 deletions(-) diff --git a/packages/core-plugin-api/src/translation/TranslationRef.test.ts b/packages/core-plugin-api/src/translation/TranslationRef.test.ts index 41d5d9ab85..b73b521774 100644 --- a/packages/core-plugin-api/src/translation/TranslationRef.test.ts +++ b/packages/core-plugin-api/src/translation/TranslationRef.test.ts @@ -17,39 +17,57 @@ import { createTranslationRef, toInternalTranslationRef, } from './TranslationRef'; +import { toInternalTranslationResource } from './TranslationResource'; describe('TranslationRefImpl', () => { it('should create a TranslationRef instance using the factory function', () => { - const config = { - id: 'testId', + const ref = createTranslationRef({ + id: 'test', messages: { key: 'value' }, - }; + }); - const translationRef = toInternalTranslationRef( - createTranslationRef(config), - ); + const internalRef = toInternalTranslationRef(ref); - expect(translationRef.id).toBe('testId'); - expect(translationRef.getDefaultMessages()).toEqual({ key: 'value' }); + expect(internalRef.$$type).toBe('@backstage/TranslationRef'); + expect(internalRef.version).toBe('v1'); + expect(internalRef.id).toBe('test'); + expect(internalRef.getDefaultMessages()).toEqual({ key: 'value' }); }); - it('should get lazy resources', async () => { - const config = { - id: 'testId', + it('should be created with lazy translations', async () => { + const ref = createTranslationRef({ + id: 'test', messages: { key: 'value' }, - lazyResources: { - en: () => Promise.resolve({ messages: { key: 'value' } }), + translations: { + de: () => Promise.resolve({ default: { key: 'other-value' } }), }, - }; + }); - const translationRef = toInternalTranslationRef( - createTranslationRef(config), + const internalRef = toInternalTranslationRef(ref); + + expect(internalRef.$$type).toBe('@backstage/TranslationRef'); + expect(internalRef.version).toBe('v1'); + expect(internalRef.id).toBe('test'); + expect(internalRef.getDefaultMessages()).toEqual({ key: 'value' }); + + const internalResource = toInternalTranslationResource( + internalRef.getDefaultResource()!, ); - - const lazyResources = translationRef.getLazyResources(); - - const messages = await lazyResources?.en(); - - expect(messages).toEqual({ messages: { key: 'value' } }); + expect(internalResource).toEqual({ + $$type: '@backstage/TranslationResource', + version: 'v1', + id: 'test', + resources: [ + { + language: 'de', + loader: expect.any(Function), + }, + ], + }); + await expect(internalResource.resources[0].loader()).resolves.toEqual({ + messages: { + key: 'other-value', + }, + }); }); }); diff --git a/packages/core-plugin-api/src/translation/TranslationRef.ts b/packages/core-plugin-api/src/translation/TranslationRef.ts index 2a135fe825..91b5d7850d 100644 --- a/packages/core-plugin-api/src/translation/TranslationRef.ts +++ b/packages/core-plugin-api/src/translation/TranslationRef.ts @@ -14,10 +14,15 @@ * limitations under the License. */ +import { + createTranslationResource, + TranslationResource, +} from './TranslationResource'; + /** @alpha */ export interface TranslationRef< - TMessages extends { [key in string]: string } = { [key in string]: string }, TId extends string = string, + TMessages extends { [key in string]: string } = { [key in string]: string }, > { $$type: '@backstage/TranslationRef'; @@ -31,47 +36,54 @@ type AnyMessages = { [key in string]: string }; /** @internal */ export interface InternalTranslationRef< - TMessages extends { [key in string]: string } = { [key in string]: string }, TId extends string = string, -> extends TranslationRef { + TMessages extends { [key in string]: string } = { [key in string]: string }, +> extends TranslationRef { version: 'v1'; getDefaultMessages(): AnyMessages; - getResources(): Record | undefined; - - getLazyResources(): - | Record Promise<{ messages: AnyMessages }>> - | undefined; + getDefaultResource(): TranslationResource | undefined; } +export type NoInfer = T extends infer S ? S : never; + /** @alpha */ export interface TranslationRefOptions< + TId extends string, TMessages extends { [key in string]: string }, - TId extends string = string, + TTranslations extends { + [language in string]: () => Promise<{ + default: { [key in keyof TMessages]: string | null }; + }>; + }, > { id: TId; messages: TMessages; - lazyResources?: Record Promise<{ messages: TMessages }>>; - resources?: Record; + translations?: TTranslations; } /** @internal */ class TranslationRefImpl< + TId extends string, TMessages extends { [key in string]: string }, - TId extends string = string, -> implements InternalTranslationRef +> implements InternalTranslationRef { - constructor( - private readonly options: TranslationRefOptions, - ) {} + #id: TId; + #messages: TMessages; + #resources: TranslationResource | undefined; + + constructor(options: TranslationRefOptions) { + this.#id = options.id; + this.#messages = options.messages; + } $$type = '@backstage/TranslationRef' as const; version = 'v1' as const; get id(): TId { - return this.options.id; + return this.#id; } get T(): never { @@ -79,17 +91,15 @@ class TranslationRefImpl< } getDefaultMessages(): AnyMessages { - return this.options.messages; + return this.#messages; } - getLazyResources(): - | Record Promise<{ messages: AnyMessages }>> - | undefined { - return this.options.lazyResources; + setDefaultResource(resources: TranslationResource): void { + this.#resources = resources; } - getResources(): Record | undefined { - return this.options.resources; + getDefaultResource(): TranslationResource | undefined { + return this.#resources; } toString() { @@ -99,12 +109,26 @@ class TranslationRefImpl< /** @alpha */ export function createTranslationRef< + TId extends string, TMessages extends { [key in string]: string }, - TId extends string = string, + TTranslations extends { + [language in string]: () => Promise<{ + default: { [key in keyof TMessages]: string | null }; + }>; + }, >( - config: TranslationRefOptions, -): TranslationRef { - return new TranslationRefImpl(config); + config: TranslationRefOptions, +): TranslationRef { + const ref = new TranslationRefImpl(config); + if (config.translations) { + ref.setDefaultResource( + createTranslationResource({ + ref, + translations: config.translations as any, + }), + ); + } + return ref; } /** @internal */