From 7d85a9da3cadd84c4cef8a4178de90d74e866efc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 12 Sep 2023 11:20:30 +0200 Subject: [PATCH] core-plugin-api: add TranslationMessages Signed-off-by: Patrik Oldsberg --- .../translation/TranslationMessages.test.ts | 92 +++++++++++++++++++ .../src/translation/TranslationMessages.ts | 80 ++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 packages/core-plugin-api/src/translation/TranslationMessages.test.ts create mode 100644 packages/core-plugin-api/src/translation/TranslationMessages.ts diff --git a/packages/core-plugin-api/src/translation/TranslationMessages.test.ts b/packages/core-plugin-api/src/translation/TranslationMessages.test.ts new file mode 100644 index 0000000000..5314c8a054 --- /dev/null +++ b/packages/core-plugin-api/src/translation/TranslationMessages.test.ts @@ -0,0 +1,92 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationMessages } from './TranslationMessages'; +import { createTranslationRef } from './TranslationRef'; + +const ref = createTranslationRef({ + id: 'counting', + messages: { + one: 'one', + two: 'two', + three: 'three', + } as const, +}); + +describe('createTranslationMessages', () => { + it('should create a partial message set', () => { + expect( + createTranslationMessages({ + ref, + messages: { + one: 'uno', + }, + }), + ).toEqual({ + $$type: '@backstage/TranslationMessages', + id: 'counting', + full: false, + messages: { + one: 'uno', + }, + }); + }); + + it('should create a full message set', () => { + expect( + createTranslationMessages({ + ref, + full: true, + messages: { + one: 'uno', + two: 'dos', + three: null, + }, + }), + ).toEqual({ + $$type: '@backstage/TranslationMessages', + id: 'counting', + full: true, + messages: { + one: 'uno', + two: 'dos', + three: null, + }, + }); + }); + + it('should require all messages in a full set', () => { + expect( + createTranslationMessages({ + ref, + full: true, + // @ts-expect-error + messages: { + one: 'uno', + two: 'dos', + }, + }), + ).toEqual({ + $$type: '@backstage/TranslationMessages', + id: 'counting', + full: true, + messages: { + one: 'uno', + two: 'dos', + }, + }); + }); +}); diff --git a/packages/core-plugin-api/src/translation/TranslationMessages.ts b/packages/core-plugin-api/src/translation/TranslationMessages.ts new file mode 100644 index 0000000000..0108fb9f18 --- /dev/null +++ b/packages/core-plugin-api/src/translation/TranslationMessages.ts @@ -0,0 +1,80 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TranslationRef } from '@backstage/core-plugin-api/alpha'; + +/** + * Represents a collection of messages to be provided for a given translation ref. + * + * @alpha + * @remarks + * + * This collection of messages can either be used directly as an override for the + * default messages, or it can be used to provide translations for a language by + * by being referenced by a {@link TranslationResource}. + */ +export interface TranslationMessages< + TId extends string = string, + TMessages extends { [key in string]: string } = { [key in string]: string }, + TFull extends boolean = boolean, +> { + $$type: '@backstage/TranslationMessages'; + /** The ID of the translation ref that these messages are for */ + id: TId; + /** Whether or not these messages override all known messages */ + full: TFull; + /** The messages provided for the given translation ref */ + messages: TMessages; +} + +/** + * Options for {@link createTranslationMessages}. + * + * @alpha + */ +export interface TranslationMessagesOptions< + TId extends string, + TMessages extends { [key in string]: string }, + TFull extends boolean, +> { + ref: TranslationRef; + + full?: TFull; + + messages: false extends TFull + ? { [key in keyof TMessages]?: string | null } + : { [key in keyof TMessages]: string | null }; +} + +/** + * Creates a collection of messages for a given translation ref. + * + * @alpha + */ +export function createTranslationMessages< + TId extends string, + TMessages extends { [key in string]: string }, + TFull extends boolean, +>( + options: TranslationMessagesOptions, +): TranslationMessages { + return { + $$type: '@backstage/TranslationMessages', + id: options.ref.id, + full: Boolean(options.full) as TFull, + messages: options.messages as TMessages, + }; +}