UNPKG

@crowdin/ota-client

Version:

JavaScript library for Crowdin OTA Content Delivery

237 lines (236 loc) 8.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fetch_1 = require("./internal/http/fetch"); const strings_1 = require("./internal/util/strings"); /** * @category OtaClient */ class OtaClient { /** * @param distributionHash hash of released Crowdin project distribution * @param config client config */ constructor(distributionHash, config) { this.distributionHash = distributionHash; this.disableManifestCache = false; this.stringsCache = {}; this.disableStringsCache = false; this.disableJsonDeepMerge = false; this.httpClient = (config === null || config === void 0 ? void 0 : config.httpClient) || new fetch_1.FetchHttpClient(); this.disableManifestCache = !!(config === null || config === void 0 ? void 0 : config.disableManifestCache); this.locale = config === null || config === void 0 ? void 0 : config.languageCode; this.disableStringsCache = !!(config === null || config === void 0 ? void 0 : config.disableStringsCache); this.disableJsonDeepMerge = !!(config === null || config === void 0 ? void 0 : config.disableJsonDeepMerge); } /** * Get the distribution hash * * @category Helper */ getHash() { return this.distributionHash; } /** * Define the global language for the client instance. * Default language code to be used if language was not passed as an input argument of the method * * @param languageCode {@link https://developer.crowdin.com/language-codes Language Code} * @category Helper */ setCurrentLocale(languageCode) { this.locale = languageCode; } /** * Get the current locale * * @category Helper */ getCurrentLocale() { return this.locale; } /** * Get manifest timestamp of distribution * * @category Helper */ async getManifestTimestamp() { return (await this.manifest).timestamp; } /** * List distribution's files content * * @category Content Management */ async getContent() { return (await this.manifest).content; } /** * List distribution's files content for a specific language * * @param languageCode {@link https://developer.crowdin.com/language-codes Language Code} * * @category Content Management */ async getLanguageContent(languageCode) { const language = this.getLanguageCode(languageCode); const content = await this.getContent(); return content[language]; } /** * List Crowdin project language codes * * @category Helper */ async listLanguages() { return Object.keys(await this.getContent()); } /** * Returns all translations per each language code * * @category Content Management */ async getTranslations() { const languages = await this.listLanguages(); const translations = {}; await Promise.all(languages.map(async (language) => { translations[language] = await this.getLanguageTranslations(language); })); return translations; } /** * Returns translations for each file in the distribution for a given language * * @param languageCode {@link https://developer.crowdin.com/language-codes Language Code} * * @category Content Management */ async getLanguageTranslations(languageCode) { const language = this.getLanguageCode(languageCode); const content = await this.getContent(); const files = content[language] || []; return Promise.all(files.map(async (file) => { const content = await this.getFileTranslations(file); return { content, file }; })); } /** * Returns translations for a specific file (content) * * @param file file content path * * @category Content Management */ async getFileTranslations(file) { const content = await this.getContent(); const fileExists = Object.values(content).some((files) => files.includes(file)); if (!fileExists) { throw new Error(`File ${file} does not exists in manifest content`); } const timestamp = await this.getManifestTimestamp(); const url = `${OtaClient.BASE_URL}/${this.distributionHash}${file}?timestamp=${timestamp}`; return this.httpClient.get(url).catch(() => null); } /** * Returns translation strings from json-based files for all languages * * @category Strings Management */ async getStrings() { const content = await this.getJsonFiles(); const res = {}; await Promise.all(Object.entries(content).map(async ([lang, files]) => { res[lang] = await this.getStringsByFilesAndLocale(files); })); return res; } /** * Returns translation strings from json-based files for a given language * * @param languageCode {@link https://developer.crowdin.com/language-codes Language Code} * * @category Strings Management */ async getStringsByLocale(languageCode) { const language = this.getLanguageCode(languageCode); const content = await this.getJsonFiles(); return this.getStringsByFilesAndLocale(content[language] || []); } /** * Returns translation string for language for given key * * @param key path to the translation string in json file * @param languageCode {@link https://developer.crowdin.com/language-codes Language Code} * * @category Strings Management */ async getStringByKey(key, languageCode) { const strings = await this.getStringsByLocale(languageCode); const path = Array.isArray(key) ? key : [key]; const firstKey = path.shift(); if (!firstKey) { return undefined; } let res = strings[firstKey]; for (const keyPart of path) { res = res === null || res === void 0 ? void 0 : res[keyPart]; } return res; } /** * Clear the translation string cache * * @category Helper */ clearStringsCache() { this.stringsCache = {}; } async getStringsByFilesAndLocale(files) { let strings = {}; for (const filePath of files) { let content; if (this.disableStringsCache) { content = await this.getFileTranslations(filePath); } else { if (!this.stringsCache[filePath]) { this.stringsCache[filePath] = this.getFileTranslations(filePath); } content = await this.stringsCache[filePath]; } if (this.disableJsonDeepMerge) { strings = { ...strings, ...content }; } else { (0, strings_1.mergeDeep)(strings, content); } } return strings; } get manifest() { if (this.manifestHolder && !this.disableManifestCache) { return this.manifestHolder; } else { this.manifestHolder = this.httpClient.get(`${OtaClient.BASE_URL}/${this.distributionHash}/manifest.json`); return this.manifestHolder; } } getLanguageCode(lang) { const languageCode = lang || this.getCurrentLocale(); if (languageCode) { return languageCode; } else { throw new Error('Language code should be either provided through input arguments or by "setCurrentLocale" method'); } } async getJsonFiles() { const content = await this.getContent(); const res = {}; Object.entries(content).forEach(([lang, files]) => (res[lang] = files.filter(strings_1.isJsonFile))); return res; } } /** @internal */ OtaClient.BASE_URL = 'https://distributions.crowdin.net'; exports.default = OtaClient;