From 9a1ec36ea6adbd57e58834981260e7fca8f19231 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sat, 2 Nov 2024 15:23:43 -0300 Subject: [PATCH] add GetWebappTranslationCallback type --- .../angular/support/translate-angular.spec.ts | 5 +-- .../angular/support/translate-angular.ts | 34 ++++++++----------- generators/base/types.d.ts | 3 +- generators/languages/generator.ts | 2 +- generators/languages/support/translate.ts | 10 +++--- generators/react/generator.ts | 2 +- .../react/support/translate-react.spec.ts | 9 +++-- generators/react/support/translate-react.ts | 7 ++-- generators/vue/support/translate-vue.spec.ts | 3 +- generators/vue/support/translate-vue.ts | 17 ++++++---- lib/types/base/translation.d.ts | 1 + 11 files changed, 50 insertions(+), 43 deletions(-) create mode 100644 lib/types/base/translation.d.ts diff --git a/generators/angular/support/translate-angular.spec.ts b/generators/angular/support/translate-angular.spec.ts index c4b6f0cd0710..e72e4e1e77b4 100644 --- a/generators/angular/support/translate-angular.spec.ts +++ b/generators/angular/support/translate-angular.spec.ts @@ -18,6 +18,7 @@ */ import { inspect } from 'node:util'; import { beforeEach, describe, esmocha, expect, it } from 'esmocha'; +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; import { createTranslationReplacer } from './translate-angular.js'; describe('generator - angular - transform', () => { @@ -28,11 +29,11 @@ describe('generator - angular - transform', () => { beforeEach(() => { let value = 0; const testImpl = (key, data) => (key === 'blank' ? '' : `translated-value-${key}-${data ? `${inspect(data)}-` : ''}${value++}`); - replaceAngularTranslations = createTranslationReplacer(esmocha.fn().mockImplementation(testImpl), { + replaceAngularTranslations = createTranslationReplacer(esmocha.fn().mockImplementation(testImpl), { jhiPrefix: 'jhi', enableTranslation: false, }); - enabledAngularTranslations = createTranslationReplacer(esmocha.fn().mockImplementation(testImpl), { + enabledAngularTranslations = createTranslationReplacer(esmocha.fn().mockImplementation(testImpl), { jhiPrefix: 'jhi', enableTranslation: true, }); diff --git a/generators/angular/support/translate-angular.ts b/generators/angular/support/translate-angular.ts index 54dfb1eb75d9..a24a67d2139c 100644 --- a/generators/angular/support/translate-angular.ts +++ b/generators/angular/support/translate-angular.ts @@ -28,6 +28,7 @@ import { escapeHtmlTranslationValue, escapeTsTranslationValue, } from '../../languages/support/index.js'; +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; const PLACEHOLDER_REGEX = /(?:placeholder|title)=['|"](\{\{\s?['|"]([a-zA-Z0-9.\-_]+)['|"]\s?\|\s?translate\s?\}\})['|"]/.source; @@ -50,7 +51,7 @@ export type ReplacerOptions = { jhiPrefix: string; enableTranslation: boolean }; * @returns {string} */ function replaceTranslationKeysWithText( - getWebappTranslation, + getWebappTranslation: GetWebappTranslationCallback, content, regexSource, { @@ -81,7 +82,7 @@ function replaceTranslationKeysWithText( * @param {string} jsKey * @returns string with jsKey value replaced */ -function replaceJSTranslation(getWebappTranslation, content, jsKey) { +function replaceJSTranslation(getWebappTranslation: GetWebappTranslationCallback, content, jsKey) { return replaceTranslationKeysWithText( getWebappTranslation, content, @@ -98,23 +99,18 @@ function replaceJSTranslation(getWebappTranslation, content, jsKey) { * @param {string} content html content * @returns string with pageTitle replaced */ -function replacePageTitles(getWebappTranslation, content) { +function replacePageTitles(getWebappTranslation: GetWebappTranslationCallback, content) { return replaceJSTranslation(getWebappTranslation, content, 'title'); } -/** - * @type {function(import('../generator-base.js'), string): string} - */ -function replacePlaceholders(getWebappTranslation, content) { +function replacePlaceholders(getWebappTranslation: GetWebappTranslationCallback, content) { return replaceTranslationKeysWithText(getWebappTranslation, content, PLACEHOLDER_REGEX, { keyIndex: 2 }); } /** * Replace error code translation key with translated message - * - * @type {function(import('../generator-base.js'), string): string} */ -function replaceErrorMessage(getWebappTranslation, content) { +function replaceErrorMessage(getWebappTranslation: GetWebappTranslationCallback, content) { return replaceJSTranslation(getWebappTranslation, content, 'errorMessage'); } @@ -123,7 +119,7 @@ function replaceErrorMessage(getWebappTranslation, content) { * Or the translation value if translation is disabled. */ const tagTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, { enableTranslation, jhiPrefix }: ReplacerOptions, { key, parsedInterpolate, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -149,7 +145,7 @@ const tagTranslation = ( * Or the translation value if translation is disabled. */ const validationTagTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, { enableTranslation, jhiPrefix }: ReplacerOptions, { key, parsedInterpolate, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -175,7 +171,7 @@ const validationTagTranslation = ( * Or the translation value if translation is disabled. */ const tagPipeTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, { enableTranslation, jhiPrefix }: ReplacerOptions, { key, parsedInterpolate, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -201,7 +197,7 @@ const tagPipeTranslation = ( * Or the translation value if translation is disabled. */ const tagEnumTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, { enableTranslation, jhiPrefix }: ReplacerOptions, { key, parsedInterpolate, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -222,7 +218,7 @@ const tagEnumTranslation = ( * Or the translation value if translation is disabled. */ const pipeTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, { enableTranslation }: ReplacerOptions, { key, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -237,7 +233,7 @@ const pipeTranslation = ( * Get translation value. */ const valueTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, _replacerOptions: ReplacerOptions, { filePath, key, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -256,7 +252,7 @@ const valueTranslation = ( * Or the translation value if translation is disabled. */ const pipeEnumTranslation = ( - getWebappTranslation: any, + getWebappTranslation: GetWebappTranslationCallback, { enableTranslation }: ReplacerOptions, { key, parsedInterpolate, prefix, suffix }: JHITranslateConverterOptions, ) => { @@ -274,7 +270,7 @@ const pipeEnumTranslation = ( const replaceImplementations: Record< string, - (getWebappTranslation: any, replacerOpts: ReplacerOptions, translateOpts: JHITranslateConverterOptions) => string + (getWebappTranslation: GetWebappTranslationCallback, replacerOpts: ReplacerOptions, translateOpts: JHITranslateConverterOptions) => string > = { Tag: tagTranslation, TagPipe: tagPipeTranslation, @@ -291,7 +287,7 @@ const replaceImplementations: Record< * @type {import('../generator-base.js').EditFileCallback} * @this {import('../generator-base.js')} */ -export const createTranslationReplacer = (getWebappTranslation, opts: ReplacerOptions | boolean) => { +export const createTranslationReplacer = (getWebappTranslation: GetWebappTranslationCallback, opts: ReplacerOptions | boolean) => { const htmlJhiTranslateReplacer = createJhiTransformTranslateReplacer(getWebappTranslation, { escapeHtml: true }); const htmlJhiTranslateStringifyReplacer = createJhiTransformTranslateStringifyReplacer(getWebappTranslation); let translationReplacer: ((content: string, filePath: string) => string) | undefined; diff --git a/generators/base/types.d.ts b/generators/base/types.d.ts index e4ce9a51f3c0..c4e675f4e5b6 100644 --- a/generators/base/types.d.ts +++ b/generators/base/types.d.ts @@ -1,5 +1,6 @@ import type { Entity } from '../base-application/index.js'; import type { ExportControlPropertiesFromCommand } from '../../lib/command/index.js'; +import type { GetWebappTranslationCallback } from '../../lib/types/base/translation.js'; import type command from './command.ts'; type BaseApplicationControlProperties = ExportControlPropertiesFromCommand; @@ -24,5 +25,5 @@ export type Control = BaseApplicationControlProperties & { * cleanupFiles({ '6.0.0': ['file1', 'file2', [application.shouldRemove, 'file3']] }) */ cleanupFiles: (cleanup: Record) => Promise; - getWebappTranslation?: (s: string, data?: Record) => string; + getWebappTranslation?: GetWebappTranslationCallback; }; diff --git a/generators/languages/generator.ts b/generators/languages/generator.ts index 3f39291f2f94..469d67e533c6 100644 --- a/generators/languages/generator.ts +++ b/generators/languages/generator.ts @@ -46,7 +46,7 @@ const { NO: NO_CLIENT_FRAMEWORK, ANGULAR } = clientFrameworkTypes; export default class LanguagesGenerator extends BaseApplicationGenerator { askForMoreLanguages!: boolean; askForNativeLanguage!: boolean; - translationData; + translationData: TranslationData; supportedLanguages; languages; /** diff --git a/generators/languages/support/translate.ts b/generators/languages/support/translate.ts index 95fd699a05c5..a8096a379a25 100644 --- a/generators/languages/support/translate.ts +++ b/generators/languages/support/translate.ts @@ -16,6 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; const TRANSLATE_FUNCTION_ARGS = /\(\s*'(?[^']+)'(?:,\s*(?\{(?:(?!\}\))[\s\S])*\}))?\)/gs.source; @@ -36,7 +37,7 @@ export type TranslationReplaceOptions = { }; export const replaceTranslationKeysWithText = ( - getWebappTranslation, + getWebappTranslation: GetWebappTranslationCallback, body: string, regexp: string, { keyPattern, interpolatePattern, wrapTranslation, escapeHtml, stringify }: TranslationReplaceOptions = {}, @@ -91,10 +92,11 @@ export const replaceTranslationKeysWithText = ( return body; }; -export const createJhiTransformTranslateReplacer = (getWebappTranslation, translateOptions?: TranslationReplaceOptions) => (body: string) => - replaceTranslationKeysWithText(getWebappTranslation, body, `__jhiTransformTranslate__${TRANSLATE_FUNCTION_ARGS}`, translateOptions); +export const createJhiTransformTranslateReplacer = + (getWebappTranslation: GetWebappTranslationCallback, translateOptions?: TranslationReplaceOptions) => (body: string) => + replaceTranslationKeysWithText(getWebappTranslation, body, `__jhiTransformTranslate__${TRANSLATE_FUNCTION_ARGS}`, translateOptions); -export const createJhiTransformTranslateStringifyReplacer = getWebappTranslation => (body: string) => +export const createJhiTransformTranslateStringifyReplacer = (getWebappTranslation: GetWebappTranslationCallback) => (body: string) => replaceTranslationKeysWithText(getWebappTranslation, body, `__jhiTransformTranslateStringify__${TRANSLATE_FUNCTION_ARGS}`, { stringify: true, }); diff --git a/generators/react/generator.ts b/generators/react/generator.ts index 114ce1840e51..5affccfdd8d5 100644 --- a/generators/react/generator.ts +++ b/generators/react/generator.ts @@ -142,7 +142,7 @@ export default class ReactGenerator extends BaseApplicationGenerator { filter: file => isFileStateModified(file) && file.path.startsWith(this.destinationPath()) && isTranslatedReactFile(file), refresh: false, }, - translateReactFilesTransform(control.getWebappTranslation), + translateReactFilesTransform(control.getWebappTranslation!), ); } }, diff --git a/generators/react/support/translate-react.spec.ts b/generators/react/support/translate-react.spec.ts index 78d961dcfa21..db1bd8d66a48 100644 --- a/generators/react/support/translate-react.spec.ts +++ b/generators/react/support/translate-react.spec.ts @@ -17,6 +17,7 @@ * limitations under the License. */ import { beforeEach, describe, esmocha, expect, it } from 'esmocha'; +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; import { createTranslationReplacer } from './translate-react.js'; describe('generator - react - transform', () => { @@ -25,11 +26,9 @@ describe('generator - react - transform', () => { beforeEach(() => { let value = 0; replaceReactTranslations = createTranslationReplacer( - esmocha.fn().mockImplementation((key, interpolation = '') => { - if (interpolation) { - interpolation = `-${JSON.stringify(interpolation)}`; - } - return `${key}${interpolation}-translated-value-${value++}`; + esmocha.fn().mockImplementation((key, interpolation) => { + const stringifiedInterpolation = interpolation ? `-${JSON.stringify(interpolation)}` : ''; + return `${key}${stringifiedInterpolation}-translated-value-${value++}`; }), ); }); diff --git a/generators/react/support/translate-react.ts b/generators/react/support/translate-react.ts index d1d61b1a2652..55d5f801b719 100644 --- a/generators/react/support/translate-react.ts +++ b/generators/react/support/translate-react.ts @@ -18,6 +18,7 @@ */ import { passthrough } from '@yeoman/transform'; import { Minimatch } from 'minimatch'; +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; const TRANSLATE_IMPORT_1 = /import { ?[T|t]ranslate(?:, ?[T|t]ranslate)? ?} from 'react-jhipster';?/.source; // Translate imports const TRANSLATE_IMPORT_2 = / *[T|t]ranslate,|, ?[T|t]ranslate/.source; // Translate import @@ -33,7 +34,7 @@ const TRANSLATE_TAG = ` +export const createTranslationReplacer = (getWebappTranslation: GetWebappTranslationCallback) => function replaceReactTranslations(body: string, filePath: string) { if (filePath.endsWith('.tsx')) { body = body.replace(new RegExp(TRANSLATE_IMPORT, 'g'), ''); @@ -124,7 +125,7 @@ export const createTranslationReplacer = getWebappTranslation => const minimatch = new Minimatch('**/*.tsx'); export const isTranslatedReactFile = file => minimatch.match(file.path); -const translateReactFilesTransform = getWebappTranslation => { +const translateReactFilesTransform = (getWebappTranslation: GetWebappTranslationCallback) => { const translate = createTranslationReplacer(getWebappTranslation); return passthrough(file => { file.contents = Buffer.from(translate(file.contents.toString(), file.path)); diff --git a/generators/vue/support/translate-vue.spec.ts b/generators/vue/support/translate-vue.spec.ts index 26a7f50a7cd9..44bda6230f9a 100644 --- a/generators/vue/support/translate-vue.spec.ts +++ b/generators/vue/support/translate-vue.spec.ts @@ -18,6 +18,7 @@ */ import { inspect } from 'node:util'; import { describe, expect, it } from 'esmocha'; +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; import { removeDeclarations, replaceTranslationTags, replaceTranslations } from './translate-vue.js'; const FULL_BODY = ` @@ -52,7 +53,7 @@ const FULL_BODY = ` `; -const getWebappTranslation = (s, data) => `getWebappTranslation('${s}'${data ? `, ${inspect(data)}` : ''})`; +const getWebappTranslation: GetWebappTranslationCallback = (s, data) => `getWebappTranslation('${s}'${data ? `, ${inspect(data)}` : ''})`; describe('generator - vue - transform', () => { describe('removeDeclarations', () => { diff --git a/generators/vue/support/translate-vue.ts b/generators/vue/support/translate-vue.ts index cef43430177a..a5437b7b0fcb 100644 --- a/generators/vue/support/translate-vue.ts +++ b/generators/vue/support/translate-vue.ts @@ -19,10 +19,15 @@ import { passthrough } from '@yeoman/transform'; import { Minimatch } from 'minimatch'; import type CoreGenerator from '../../base-core/index.js'; +import type { GetWebappTranslationCallback } from '../../../lib/types/base/translation.js'; -type GetWebappTranslation = (s: string, data?: Record) => string; - -function replaceTranslationAttributes({ content, getWebappTranslation }: { content: string; getWebappTranslation: GetWebappTranslation }) { +function replaceTranslationAttributes({ + content, + getWebappTranslation, +}: { + content: string; + getWebappTranslation: GetWebappTranslationCallback; +}) { return content.replaceAll(/:(?(?:placeholder|title|label))="(?t\$\([^"]+\))"/g, (_complete, ...args) => { const groups: Record = args.pop(); if (groups.translate.includes('+')) { @@ -49,7 +54,7 @@ export function replaceTranslationTags( }: { body: string; enableTranslation: boolean; - getWebappTranslation: GetWebappTranslation; + getWebappTranslation: GetWebappTranslationCallback; }, ) { body = body.replaceAll( @@ -93,7 +98,7 @@ export function replaceTranslations({ }: { content: string; type: 'vue' | 'ts'; - getWebappTranslation: GetWebappTranslation; + getWebappTranslation: GetWebappTranslationCallback; }) { const regex = type === 'ts' @@ -155,7 +160,7 @@ function translateVueFilesTransform( getWebappTranslation, }: { enableTranslation: boolean; - getWebappTranslation: GetWebappTranslation; + getWebappTranslation: GetWebappTranslationCallback; }, ) { return passthrough(file => { diff --git a/lib/types/base/translation.d.ts b/lib/types/base/translation.d.ts new file mode 100644 index 000000000000..2c773a2ea9f7 --- /dev/null +++ b/lib/types/base/translation.d.ts @@ -0,0 +1 @@ +export type GetWebappTranslationCallback = (s: string, data?: Record) => string;