From 2ad2a4b198a52d42369a8ce4d14964180f4173aa Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 14 May 2021 07:47:47 +0200 Subject: [PATCH] Bump lokalize deps + support object format for args (#9155) Co-authored-by: Paulus Schoutsen --- package.json | 7 +- src/common/translations/localize.ts | 59 +++++---- .../config-flow/show-dialog-config-flow.ts | 16 +-- .../config-flow/show-dialog-options-flow.ts | 7 +- .../integrations/ha-config-integrations.ts | 11 +- .../dialog-ha-mfa-module-setup-flow.ts | 4 +- src/panels/profile/ha-panel-profile.ts | 8 +- src/panels/profile/ha-refresh-tokens-card.ts | 28 +++-- yarn.lock | 118 +++++++++--------- 9 files changed, 124 insertions(+), 134 deletions(-) diff --git a/package.json b/package.json index cc97f462af..671905fdcc 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,9 @@ "@codemirror/stream-parser": "^0.18.0", "@codemirror/text": "^0.18.0", "@codemirror/view": "^0.18.0", - "@formatjs/intl-getcanonicallocales": "^1.4.6", - "@formatjs/intl-pluralrules": "^3.4.10", + "@formatjs/intl-getcanonicallocales": "^1.5.10", + "@formatjs/intl-locale": "^2.4.24", + "@formatjs/intl-pluralrules": "^4.0.18", "@fullcalendar/common": "5.1.0", "@fullcalendar/core": "5.1.0", "@fullcalendar/daygrid": "5.1.0", @@ -111,7 +112,7 @@ "hls.js": "^1.0.3", "home-assistant-js-websocket": "^5.10.0", "idb-keyval": "^3.2.0", - "intl-messageformat": "^8.3.9", + "intl-messageformat": "^9.6.13", "js-yaml": "^3.13.1", "leaflet": "^1.7.1", "leaflet-draw": "^1.0.4", diff --git a/src/common/translations/localize.ts b/src/common/translations/localize.ts index 94edcc8a7a..72042fcd3f 100644 --- a/src/common/translations/localize.ts +++ b/src/common/translations/localize.ts @@ -3,7 +3,6 @@ import IntlMessageFormat from "intl-messageformat"; import { Resources } from "../../types"; export type LocalizeFunc = (key: string, ...args: any[]) => string; - interface FormatType { [format: string]: any; } @@ -13,12 +12,17 @@ export interface FormatsType { time: FormatType; } +let loadedPolyfillLocale: Set | undefined; + let polyfillLoaded = !shouldPolyfill(); const polyfillProm = polyfillLoaded ? undefined - : import("@formatjs/intl-pluralrules/polyfill-locales").then(() => { - polyfillLoaded = true; - }); + : import("@formatjs/intl-locale/polyfill") + .then(() => import("@formatjs/intl-pluralrules/polyfill")) + .then(() => { + loadedPolyfillLocale = new Set(); + polyfillLoaded = true; + }); /** * Adapted from Polymer app-localize-behavior. @@ -51,6 +55,15 @@ export const computeLocalize = async ( await polyfillProm; } + if (loadedPolyfillLocale && !loadedPolyfillLocale.has(language)) { + try { + loadedPolyfillLocale.add(language); + await import("@formatjs/intl-pluralrules/locale-data/en"); + } catch (_e) { + // Ignore + } + } + // Everytime any of the parameters change, invalidate the strings cache. cache._localizationCache = {}; @@ -68,7 +81,9 @@ export const computeLocalize = async ( } const messageKey = key + translatedValue; - let translatedMessage = cache._localizationCache[messageKey]; + let translatedMessage = cache._localizationCache[messageKey] as + | IntlMessageFormat + | undefined; if (!translatedMessage) { translatedMessage = new IntlMessageFormat( @@ -79,37 +94,19 @@ export const computeLocalize = async ( cache._localizationCache[messageKey] = translatedMessage; } - const argObject = {}; - for (let i = 0; i < args.length; i += 2) { - argObject[args[i]] = args[i + 1]; + let argObject = {}; + if (args.length === 1 && typeof args[0] === "object") { + argObject = args[0]; + } else { + for (let i = 0; i < args.length; i += 2) { + argObject[args[i]] = args[i + 1]; + } } try { - return translatedMessage.format(argObject); + return translatedMessage.format(argObject) as string; } catch (err) { return "Translation " + err; } }; }; - -/** - * Silly helper function that converts an object of placeholders to array so we - * can convert it back to an object again inside the localize func. - * @param localize - * @param key - * @param placeholders - */ -export const localizeKey = ( - localize: LocalizeFunc, - key: string, - placeholders?: Record -) => { - const args: [string, ...string[]] = [key]; - if (placeholders) { - Object.keys(placeholders).forEach((placeholderKey) => { - args.push(placeholderKey); - args.push(placeholders[placeholderKey]); - }); - } - return localize(...args); -}; diff --git a/src/dialogs/config-flow/show-dialog-config-flow.ts b/src/dialogs/config-flow/show-dialog-config-flow.ts index 452d83cb22..207429fcfe 100644 --- a/src/dialogs/config-flow/show-dialog-config-flow.ts +++ b/src/dialogs/config-flow/show-dialog-config-flow.ts @@ -1,6 +1,5 @@ import { html } from "lit-element"; import { caseInsensitiveCompare } from "../../common/string/compare"; -import { localizeKey } from "../../common/translations/localize"; import { createConfigFlow, deleteConfigFlow, @@ -52,8 +51,7 @@ export const showConfigFlowDialog = ( deleteFlow: deleteConfigFlow, renderAbortDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${step.handler}.config.abort.${step.reason}`, step.description_placeholders ); @@ -74,8 +72,7 @@ export const showConfigFlowDialog = ( }, renderShowFormStepDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${step.handler}.config.step.${step.step_id}.description`, step.description_placeholders ); @@ -108,8 +105,7 @@ export const showConfigFlowDialog = ( }, renderExternalStepDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${step.handler}.config.${step.step_id}.description`, step.description_placeholders ); @@ -133,8 +129,7 @@ export const showConfigFlowDialog = ( }, renderCreateEntryDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${step.handler}.config.create_entry.${ step.description || "default" }`, @@ -170,8 +165,7 @@ export const showConfigFlowDialog = ( }, renderShowFormProgressDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${step.handler}.config.progress.${step.progress_action}`, step.description_placeholders ); diff --git a/src/dialogs/config-flow/show-dialog-options-flow.ts b/src/dialogs/config-flow/show-dialog-options-flow.ts index 1113b939a6..e2346c660d 100644 --- a/src/dialogs/config-flow/show-dialog-options-flow.ts +++ b/src/dialogs/config-flow/show-dialog-options-flow.ts @@ -1,5 +1,4 @@ import { html } from "lit-element"; -import { localizeKey } from "../../common/translations/localize"; import { ConfigEntry } from "../../data/config_entries"; import { createOptionsFlow, @@ -43,8 +42,7 @@ export const showOptionsFlowDialog = ( deleteFlow: deleteOptionsFlow, renderAbortDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${configEntry.domain}.options.abort.${step.reason}`, step.description_placeholders ); @@ -69,8 +67,7 @@ export const showOptionsFlowDialog = ( }, renderShowFormStepDescription(hass, step) { - const description = localizeKey( - hass.localize, + const description = hass.localize( `component.${configEntry.domain}.options.step.${step.step_id}.description`, step.description_placeholders ); diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index 731ece01c0..e2cdcc6187 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -346,8 +346,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { ? html`
${this.hass.localize( "ui.panel.config.integrations.disable.disabled_integrations", - "number", - disabledConfigEntries.size + { number: disabledConfigEntries.size } )}
- ${this.hass.localize( - "ui.panel.profile.current_user", - "fullName", - this.hass.user!.name - )} + ${this.hass.localize("ui.panel.profile.current_user", { + fullName: this.hass.user!.name, + })} ${this.hass.user!.is_owner ? this.hass.localize("ui.panel.profile.is_owner") : ""} diff --git a/src/panels/profile/ha-refresh-tokens-card.ts b/src/panels/profile/ha-refresh-tokens-card.ts index faad31d988..738bb5760b 100644 --- a/src/panels/profile/ha-refresh-tokens-card.ts +++ b/src/panels/profile/ha-refresh-tokens-card.ts @@ -62,28 +62,31 @@ class HaRefreshTokens extends LitElement { ${this.hass.localize( "ui.panel.profile.refresh_tokens.token_title", - "clientId", - token.client_id + { clientId: token.client_id } )}
${this.hass.localize( "ui.panel.profile.refresh_tokens.created_at", - "date", - relativeTime(new Date(token.created_at), this.hass.localize) + { + date: relativeTime( + new Date(token.created_at), + this.hass.localize + ), + } )}
${token.last_used_at ? this.hass.localize( "ui.panel.profile.refresh_tokens.last_used", - "date", - relativeTime( - new Date(token.last_used_at), - this.hass.localize - ), - "location", - token.last_used_ip + { + date: relativeTime( + new Date(token.last_used_at), + this.hass.localize + ), + location: token.last_used_ip, + } ) : this.hass.localize( "ui.panel.profile.refresh_tokens.not_used" @@ -119,8 +122,7 @@ class HaRefreshTokens extends LitElement { !(await showConfirmationDialog(this, { text: this.hass.localize( "ui.panel.profile.refresh_tokens.confirm_delete", - "name", - token.client_name || token.client_id + { name: token.client_name || token.client_id } ), })) ) { diff --git a/yarn.lock b/yarn.lock index afcc8908b1..0207ccdfcd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1101,40 +1101,60 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@formatjs/ecma402-abstract@^1.2.5": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.2.5.tgz#5a61ac1990ff2df8d1348ab12e186c1ca2a2bd71" - integrity sha512-k0fqS3LBNOHueAoMdgig8Ni6TchsH+zbzWBzX2gTFm50X9mxHwnuXdCk0XLlCIbvgVVlzcO254Men/mHAheMbg== +"@formatjs/ecma402-abstract@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.7.1.tgz#1459a9dad654d5d5ec34765965b8e4f22ad6ff81" + integrity sha512-FjewVLB2DVEVCvvC7IMffzXVhysvi442i6ed0H7qcrT6xtUpO4vr0oZgpOmsv6D9I4Io0GVebIuySwteS/k3gg== dependencies: - tslib "^2.0.1" + tslib "^2.1.0" -"@formatjs/intl-getcanonicallocales@^1.4.6": - version "1.4.6" - resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-1.4.6.tgz#348a0b8dd87f2b0513a4942a6273c937dd91ead0" - integrity sha512-V54a+Ks02vke2CSmuGJ4GCvrdWfN105GSH7oZRoW5QSiwuac+fmxb5Qpu4002HetuRu0rrRTm+NMUTfZ1VB2xw== +"@formatjs/fast-memoize@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-1.1.1.tgz#3006b58aca1e39a98aca213356b42da5d173f26b" + integrity sha512-mIqBr5uigIlx13eZTOPSEh2buDiy3BCdMYUtewICREQjbb4xarDiVWoXSnrERM7NanZ+0TAHNXSqDe6HpEFQUg== + +"@formatjs/icu-messageformat-parser@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.1.tgz#a3b542542b92958f1cdd090f1cb475cb7cb4e21a" + integrity sha512-GXHsATo6/9OMgrfAuyX86fYPMLeQXDN93TOKXQeW7A7ULCy9eEOp3beNwhrVFxaGIjVy/haLLqHMT36iyhwvCA== dependencies: - cldr-core "36.0.0" - tslib "^2.0.1" + "@formatjs/ecma402-abstract" "1.7.1" + "@formatjs/icu-skeleton-parser" "1.2.2" + tslib "^2.1.0" -"@formatjs/intl-pluralrules@^3.4.10": - version "3.4.10" - resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-3.4.10.tgz#7ed3b03190971f21d482cb0e46791d90783a74d3" - integrity sha512-KcZZv38bu0pho9+9pMUOsCAi9/Kayh4+V5QZ/I9ps5OFSQlQaFMP5sX/zHBp41SsT6HxTfrPw5CHWpGrS75NQQ== +"@formatjs/icu-skeleton-parser@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.2.2.tgz#6e9a6eff16e3c7b69d67d40b292d4b499e37228e" + integrity sha512-peBBPIiNzJdPsvEzFGCicD7ARvlcaUYOVZ5dljvzzcHqc5OHlH58OrUNWwYgxFS6Dnb3Ncy4qFwlTdPGTTvw1g== dependencies: - "@formatjs/ecma402-abstract" "^1.2.5" - tslib "^2.0.1" + "@formatjs/ecma402-abstract" "1.7.1" + tslib "^2.1.0" -"@formatjs/intl-unified-numberformat@^3.3.5": - version "3.3.5" - resolved "https://registry.yarnpkg.com/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-3.3.5.tgz#b150c25eb56c1b09a03bf24fb5d1e394b945a27c" - integrity sha512-LdRs9OoqG8Ah6wKKAcaq9wfeZ0w+Icway63thbbOam5DLY9G3u44NReFYWAmVSU+MXOQ+VPATMB9RUXGZxBdig== +"@formatjs/intl-getcanonicallocales@1.5.10", "@formatjs/intl-getcanonicallocales@^1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-1.5.10.tgz#f57f12f19fd28a241767986b081331f8b26fb18b" + integrity sha512-tFqGxZ9HkAzphupybyCKdWHzL1ge/sY8TtzEK57Hs3RCxrv/y+VxIPrE+Izw2oCFowQBz76cyi0zT6PjHuWArA== dependencies: - "@formatjs/intl-utils" "^2.2.4" + cldr-core "38" + tslib "^2.1.0" -"@formatjs/intl-utils@^2.2.4": - version "2.2.4" - resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.4.tgz#fe62a96799d1f7dbe621fd38a4bd2e5a6a16cb0e" - integrity sha512-83fsJywew0o9wQsW3VuEp33HRiFd0qbQDyFFnwZCwk59eLZ33CtKyJ5ofKMrU2KK6hk1zaIdzisrZeoNfmI3Tw== +"@formatjs/intl-locale@^2.4.24": + version "2.4.24" + resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-2.4.24.tgz#c3f9dba15653b79ac7b377bb048a35aeedfc234d" + integrity sha512-+JOwvBRFS/GFuJlWiWbfAzBng0A+ANoGV1LRseXK+4uzp4Sn35GD8M/dfgU1lp2R2dTWpYie2yyoHe4k4aHF6w== + dependencies: + "@formatjs/ecma402-abstract" "1.7.1" + "@formatjs/intl-getcanonicallocales" "1.5.10" + cldr-core "38" + tslib "^2.1.0" + +"@formatjs/intl-pluralrules@^4.0.18": + version "4.0.18" + resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-4.0.18.tgz#da4bda058cce5217691836c4f46ba3e9f25b0eeb" + integrity sha512-qRFITPsNoeXfsiGc97pp8mVgqcC7aQNuXsiJjY9LpXVTkYNfjUP4ZpbYXflM4xoWCXMJNz3ilsrQhZWXy9td5g== + dependencies: + "@formatjs/ecma402-abstract" "1.7.1" + tslib "^2.1.0" "@fullcalendar/common@5.1.0", "@fullcalendar/common@~5.1.0": version "5.1.0" @@ -2568,11 +2588,6 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== -"@types/chai@^4.2.11": - version "4.2.11" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.11.tgz#d3614d6c5f500142358e6ed24e1bf16657536c50" - integrity sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw== - "@types/chrome@*": version "0.0.119" resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.119.tgz#12a2af96886d0c7210590928729ebf622eb67a58" @@ -4779,10 +4794,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cldr-core@36.0.0: - version "36.0.0" - resolved "https://registry.yarnpkg.com/cldr-core/-/cldr-core-36.0.0.tgz#1d2148ed6802411845baeeb21432d7bbfde7d4f7" - integrity sha512-QLnAjt20rZe38c8h8OJ9jPND+O4o5O8Nw0TK/P3KpNn1cmOhMu0rk6Kc3ap96c5OStQ9gAngs9+Be2sum26NOw== +cldr-core@38: + version "38.1.0" + resolved "https://registry.yarnpkg.com/cldr-core/-/cldr-core-38.1.0.tgz#3c400436b89110e2c0584469d51b7479ef0fa70c" + integrity sha512-Da9xKjDp4qGGIX0VDsBqTan09iR5nuYD2a/KkfEaUyqKhu6wFVNRiCpPDXeRbpVwPBY6PgemV8WiHatMhcpy4A== clean-css@^4.2.1: version "4.2.3" @@ -7773,28 +7788,14 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -intl-format-cache@^4.2.26: - version "4.2.26" - resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-4.2.26.tgz#ba5e2ee6cec25217f688b68ecdd58eec3703a827" - integrity sha512-RalEzK89R3rJrOo7vcGY8h1WLypF1ZRQQldIsrQM6FTEPixvHb+pAEhd2QkdUk972hFjAEBJR02GdHhaEw9v2g== +intl-messageformat@^9.6.13: + version "9.6.13" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.6.13.tgz#7c4ace385b3b8cc5010bfd774451ed0c50a73a9b" + integrity sha512-F8OHdgdZYdY3O7TSkQtIGY1qBL7ttbbfIb6g9sgjLw1SQ9SlN3rlaUa1tv9RK3sX0qVkqNLqlPVuOfHlhXpm2Q== dependencies: - "@types/chai" "^4.2.11" - chai "^4.2.0" - -intl-messageformat-parser@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-5.0.2.tgz#878c0d66459b366f4135a812007a873789875b95" - integrity sha512-7logOIMKQX4cWTAGdMSPdlzlGG2aGcpdTr/Laroi3/LTgXvYqMQ8fbC7DolygSEWUxbYrzDIuQsoQGJO6Kp8Gg== - dependencies: - "@formatjs/intl-unified-numberformat" "^3.3.5" - -intl-messageformat@^8.3.9: - version "8.3.9" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-8.3.9.tgz#fa57e6f5abdd4b5ad03dd767c965435bd38cbd78" - integrity sha512-WHIopaMiZ14UJ76d14FfqbeNE3knGJT7pJg6eJVxh1G5ziL656BqfQk6dYxPZ2VvoaY7wnT3dLlIXy1MTE0blw== - dependencies: - intl-format-cache "^4.2.26" - intl-messageformat-parser "^5.0.2" + "@formatjs/fast-memoize" "1.1.1" + "@formatjs/icu-messageformat-parser" "2.0.1" + tslib "^2.1.0" into-stream@^4.0.0: version "4.0.0" @@ -12532,6 +12533,11 @@ tslib@^2.0.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== +tslib@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + tsparticles@^1.19.2: version "1.19.2" resolved "https://registry.yarnpkg.com/tsparticles/-/tsparticles-1.19.2.tgz#056d26149e67155e99efbfb1ea8f521fcc66520c"