@crowdin/ota-client
Version:
JavaScript library for Crowdin OTA Content Delivery
237 lines (236 loc) • 8.07 kB
JavaScript
"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;