From 3bb6776880d5f65b65c2f8a33b73ea05ef34115b Mon Sep 17 00:00:00 2001 From: Simon J Date: Wed, 25 Aug 2021 09:41:04 +1000 Subject: [PATCH] Distinguish between supported lang and lang in type system (#29) --- src/i8n.ts | 22 ++++++++++++---------- src/sonos.ts | 3 ++- tests/i8n.test.ts | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/i8n.ts b/src/i8n.ts index 7995859..96168c4 100644 --- a/src/i8n.ts +++ b/src/i8n.ts @@ -3,7 +3,8 @@ import { pipe } from "fp-ts/lib/function"; import { option as O } from "fp-ts"; import _ from "underscore"; -export type LANG = "en-US" | "nl-NL"; +export type LANG = "en-US" | "da-DK" | "de-DE" | "es-ES" | "fr-FR" | "it-IT" | "ja-JP" | "nb-NO" | "nl-NL" | "pt-BR" | "sv-SE" | "zh-CN" +export type SUPPORTED_LANG = "en-US" | "nl-NL"; export type KEY = | "AppLinkMessage" | "artists" @@ -37,7 +38,7 @@ export type KEY = | "loginSuccessful" | "loginFailed"; -const translations: Record> = { +const translations: Record> = { "en-US": { AppLinkMessage: "Linking sonos with $BONOB_SONOS_SERVICE_NAME", artists: "Artists", @@ -107,15 +108,15 @@ const translations: Record> = { }; const translationsLookup = Object.keys(translations).reduce((lookups, lang) => { - lookups.set(lang, translations[lang as LANG]); - lookups.set(lang.toLocaleLowerCase(), translations[lang as LANG]); - lookups.set(lang.toLocaleLowerCase().split("-")[0]!, translations[lang as LANG]); + lookups.set(lang, translations[lang as SUPPORTED_LANG]); + lookups.set(lang.toLocaleLowerCase(), translations[lang as SUPPORTED_LANG]); + lookups.set(lang.toLocaleLowerCase().split("-")[0]!, translations[lang as SUPPORTED_LANG]); return lookups; }, new Map>()) export const randomLang = () => _.shuffle(["en-US", "nl-NL"])[0]!; -export const asLANGs = (acceptLanguageHeader: string | undefined) => +export const asLANGs = (acceptLanguageHeader: string | undefined): LANG[] => pipe( acceptLanguageHeader, O.fromNullable, @@ -125,7 +126,8 @@ export const asLANGs = (acceptLanguageHeader: string | undefined) => pipe( it.split(","), A.map((it) => it.trim()), - A.filter((it) => it != "") + A.filter((it) => it != ""), + A.map(it => it as LANG) ) ), O.getOrElseW(() => []) @@ -137,12 +139,12 @@ export type Lang = (key: KEY) => string; export const langs = () => Object.keys(translations); -export const keys = (lang: LANG = "en-US") => Object.keys(translations[lang]); +export const keys = (lang: SUPPORTED_LANG = "en-US") => Object.keys(translations[lang]); export default (serviceName: string): I8N => (...langs: string[]): Lang => { - const langToUse = - langs.map((l) => translationsLookup.get(l as LANG)).find((it) => it) || + const langToUse = + langs.map((l) => translationsLookup.get(l as SUPPORTED_LANG)).find((it) => it) || translations["en-US"]; return (key: KEY) => { const value = langToUse[key]?.replace( diff --git a/src/sonos.ts b/src/sonos.ts index be7cde1..e13e765 100644 --- a/src/sonos.ts +++ b/src/sonos.ts @@ -7,8 +7,9 @@ import logger from "./logger"; import { SOAP_PATH, STRINGS_ROUTE, PRESENTATION_MAP_ROUTE } from "./smapi"; import qs from "querystring"; import { URLBuilder } from "./url_builder"; +import { LANG } from "./i8n"; -export const SONOS_LANG = ["en-US", "da-DK", "de-DE", "es-ES", "fr-FR", "it-IT", "ja-JP", "nb-NO", "nl-NL", "pt-BR", "sv-SE", "zh-CN"] +export const SONOS_LANG: LANG[] = ["en-US", "da-DK", "de-DE", "es-ES", "fr-FR", "it-IT", "ja-JP", "nb-NO", "nl-NL", "pt-BR", "sv-SE", "zh-CN"] export const PRESENTATION_AND_STRINGS_VERSION = "21"; diff --git a/tests/i8n.test.ts b/tests/i8n.test.ts index f939dfc..7ac608f 100644 --- a/tests/i8n.test.ts +++ b/tests/i8n.test.ts @@ -1,4 +1,4 @@ -import i8n, { langs, LANG, KEY, keys, asLANGs } from "../src/i8n"; +import i8n, { langs, LANG, KEY, keys, asLANGs, SUPPORTED_LANG } from "../src/i8n"; describe("i8n", () => { describe("asLANGs", () => { @@ -41,7 +41,7 @@ describe("i8n", () => { describe("validity of translations", () => { it("all langs should have same keys as US", () => { langs().forEach((l) => { - expect(keys(l as LANG)).toEqual(keys("en-US")); + expect(keys(l as SUPPORTED_LANG)).toEqual(keys("en-US")); }); }); });