diff --git a/src/languages.js b/src/languages.js index eeb01d090..ff05e4deb 100644 --- a/src/languages.js +++ b/src/languages.js @@ -1,87 +1,85 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const utils = require('./utils'); -const { paths } = require('./constants'); -const plugins = require('./plugins'); - -const Languages = module.exports; -const languagesPath = path.join(__dirname, '../build/public/language'); - -const files = fs.readdirSync(path.join(paths.nodeModules, '/timeago/locales')); -Languages.timeagoCodes = files.filter(f => f.startsWith('jquery.timeago')).map(f => f.split('.')[2]); - -Languages.get = async function (language, namespace) { - const pathToLanguageFile = path.join(languagesPath, language, `${namespace}.json`); - if (!pathToLanguageFile.startsWith(languagesPath)) { - throw new Error('[[error:invalid-path]]'); - } - const data = await fs.promises.readFile(pathToLanguageFile, 'utf8'); - const parsed = JSON.parse(data) || {}; - const result = await plugins.hooks.fire('filter:languages.get', { - language, - namespace, - data: parsed, +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); }); - return result.data; }; - -let codeCache = null; -Languages.listCodes = async function () { - if (codeCache && codeCache.length) { - return codeCache; - } - try { - const file = await fs.promises.readFile(path.join(languagesPath, 'metadata.json'), 'utf8'); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.userTimeagoCode = exports.list = exports.listCodes = exports.get = void 0; +const promises_1 = __importDefault(require("fs/promises")); +const path_1 = __importDefault(require("path")); +const utils_1 = __importDefault(require("./utils")); +const plugins_1 = __importDefault(require("./plugins")); +const constants_1 = require("./constants"); +function get(language, namespace) { + return __awaiter(this, void 0, void 0, function* () { + const languagesPath = path_1.default.join(__dirname, '../build/public/language'); + const pathToLanguageFile = path_1.default.join(languagesPath, language, `${namespace}.json`); + if (!pathToLanguageFile.startsWith(languagesPath)) { + throw new Error('[[error:invalid-path]]'); + } + const data = yield promises_1.default.readFile(pathToLanguageFile, 'utf8'); + const parsed = JSON.parse(data); + const result = yield plugins_1.default.hooks.fire('filter:languages.get', { + language, + namespace, + data: parsed, + }); + return result.data; + }); +} +exports.get = get; +let codeCache; +function listCodes() { + return __awaiter(this, void 0, void 0, function* () { + if (codeCache && codeCache.length) { + return codeCache; + } + const languagesPath = path_1.default.join(__dirname, '../build/public/language'); + const file = yield promises_1.default.readFile(path_1.default.join(languagesPath, 'metadata.json'), 'utf8'); const parsed = JSON.parse(file); - codeCache = parsed.languages; return parsed.languages; - } catch (err) { - if (err.code === 'ENOENT') { - return []; + }); +} +exports.listCodes = listCodes; +let listCache; +function list() { + return __awaiter(this, void 0, void 0, function* () { + if (listCache && listCache.length) { + return listCache; } - throw err; - } -}; - -let listCache = null; -Languages.list = async function () { - if (listCache && listCache.length) { - return listCache; - } - - const codes = await Languages.listCodes(); - - let languages = await Promise.all(codes.map(async (folder) => { - try { - const configPath = path.join(languagesPath, folder, 'language.json'); - const file = await fs.promises.readFile(configPath, 'utf8'); + const codes = yield listCodes(); + let languages = yield Promise.all(codes.map((folder) => __awaiter(this, void 0, void 0, function* () { + const languagesPath = path_1.default.join(__dirname, '../build/public/language'); + const configPath = path_1.default.join(languagesPath, folder, 'language.json'); + const file = yield promises_1.default.readFile(configPath, 'utf8'); const lang = JSON.parse(file); return lang; - } catch (err) { - if (err.code === 'ENOENT') { - return; - } - throw err; + }))); + languages = languages.filter(lang => lang && lang.code && lang.name && lang.dir); + listCache = languages; + return languages; + }); +} +exports.list = list; +function userTimeagoCode(userLang) { + return __awaiter(this, void 0, void 0, function* () { + const files = yield promises_1.default.readdir(path_1.default.join(constants_1.paths.nodeModules, '/timeago/locales')); + const timeagoCodes = files.filter(f => f.startsWith('jquery.timeago')).map(f => f.split('.')[2]); + const languageCodes = yield listCodes(); + const timeagoCode = utils_1.default.userLangToTimeagoCode(userLang); + if (languageCodes.includes(userLang) && timeagoCodes.includes(timeagoCode)) { + return timeagoCode; } - })); - - // filter out invalid ones - languages = languages.filter(lang => lang && lang.code && lang.name && lang.dir); - - listCache = languages; - return languages; -}; - -Languages.userTimeagoCode = async function (userLang) { - const languageCodes = await Languages.listCodes(); - const timeagoCode = utils.userLangToTimeagoCode(userLang); - if (languageCodes.includes(userLang) && Languages.timeagoCodes.includes(timeagoCode)) { - return timeagoCode; - } - return ''; -}; - -require('./promisify')(Languages); + return ''; + }); +} +exports.userTimeagoCode = userTimeagoCode; diff --git a/src/languages.ts b/src/languages.ts new file mode 100644 index 000000000..9784b6417 --- /dev/null +++ b/src/languages.ts @@ -0,0 +1,88 @@ +import fs from 'fs/promises'; +import path from 'path'; +import utils from './utils'; +import plugins from './plugins'; +import { paths } from './constants'; + +interface Language { + code: string, + name: string, + dir: string +} + +interface ParseResult { + languages: string[] +} + +interface Result { + data: Language[] +} + + +export async function get(language: string, namespace: string) { + const languagesPath = path.join(__dirname, '../build/public/language'); + const pathToLanguageFile = path.join(languagesPath, language, `${namespace}.json`); + + if (!pathToLanguageFile.startsWith(languagesPath)) { + throw new Error('[[error:invalid-path]]'); + } + + const data = await fs.readFile(pathToLanguageFile, 'utf8'); + const parsed: ParseResult = JSON.parse(data) as ParseResult; + + const result: Result = await plugins.hooks.fire('filter:languages.get', { + language, + namespace, + data: parsed, + }) as Result; + + return result.data; +} + +let codeCache: string[]; + +export async function listCodes() { + if (codeCache && codeCache.length) { + return codeCache; + } + const languagesPath = path.join(__dirname, '../build/public/language'); + const file = await fs.readFile(path.join(languagesPath, 'metadata.json'), 'utf8'); + const parsed: ParseResult = JSON.parse(file) as ParseResult; + codeCache = parsed.languages; + return parsed.languages; +} + +let listCache: Language[]; + +export async function list() { + if (listCache && listCache.length) { + return listCache; + } + + const codes = await listCodes(); + + let languages: Language[] = await Promise.all(codes.map(async (folder) => { + const languagesPath = path.join(__dirname, '../build/public/language'); + const configPath = path.join(languagesPath, folder, 'language.json'); + const file = await fs.readFile(configPath, 'utf8'); + const lang: Language = JSON.parse(file) as Language; + return lang; + })); + + languages = languages.filter(lang => lang && lang.code && lang.name && lang.dir); + + listCache = languages; + return languages; +} + +export async function userTimeagoCode(userLang: string) { + const files = await fs.readdir(path.join(paths.nodeModules, '/timeago/locales')); + const timeagoCodes = files.filter(f => f.startsWith('jquery.timeago')).map(f => f.split('.')[2]); + const languageCodes = await listCodes(); + const timeagoCode: string = utils.userLangToTimeagoCode(userLang) as string; + + if (languageCodes.includes(userLang) && timeagoCodes.includes(timeagoCode)) { + return timeagoCode; + } + return ''; +}