| 1 | // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt |
| 2 | |
| 3 | import { ApiError, ApiHandlers } from './apiMiddleware' |
| 4 | import _ from 'lodash' |
| 5 | import glob from 'fast-glob' |
| 6 | import { readFile, rm, writeFile } from 'fs/promises' |
| 7 | import { HTTP_BAD_REQUEST, HTTP_NOT_ACCEPTABLE, HTTP_SERVER_ERROR } from './const' |
| 8 | import { apiAssertTypes, tryJson } from './misc' |
| 9 | import { code2file, file2code, normalizeLangCode } from './lang' |
| 10 | import EMBEDDED_TRANSLATIONS from './langs/embedded' |
| 11 | import { SendListReadable } from './SendList' |
| 12 | |
| 13 | const apis: ApiHandlers = { |
| 14 | |
| 15 | get_langs() { |
| 16 | return new SendListReadable({ |
| 17 | doAtStart: async list => { |
| 18 | for await (let name of glob.stream(code2file('*'))) { |
| 19 | name = String(name) |
| 20 | const code = file2code(name) |
| 21 | try { |
| 22 | const data = JSON.parse(await readFile(name, 'utf8')) |
| 23 | list.add({ code, ..._.omit(data, 'translate') }) |
| 24 | } |
| 25 | catch {} |
| 26 | } |
| 27 | for (const [code, data] of Object.entries(EMBEDDED_TRANSLATIONS)) |
| 28 | list.add({ code, embedded: true, ..._.omit(data, 'translate') }) |
| 29 | list.close() |
| 30 | } |
| 31 | }) |
| 32 | }, |
| 33 | |
| 34 | async del_lang({ code }) { |
| 35 | validateCode(code) |
| 36 | try { |
| 37 | await rm(code2file(code)) |
| 38 | return {} |
| 39 | } |
| 40 | catch (e: any) { |
| 41 | return new ApiError(HTTP_SERVER_ERROR, e) |
| 42 | } |
| 43 | }, |
| 44 | |
| 45 | async add_langs({ langs }) { |
| 46 | apiAssertTypes({ object: { langs } }) |
| 47 | for (let [code, content] of Object.entries(langs)) { |
| 48 | code = file2code(code) |
| 49 | validateCode(code) |
| 50 | const fn = code2file(code) |
| 51 | const s = content = String(content) |
| 52 | if (!tryJson(s)) |
| 53 | return new ApiError(HTTP_NOT_ACCEPTABLE, "bad content for file " + fn) |
| 54 | await writeFile(fn, s, 'utf8') |
| 55 | } |
| 56 | return {} |
| 57 | } |
| 58 | |
| 59 | } |
| 60 | |
| 61 | export default apis |
| 62 | |
| 63 | function validateCode(code: string) { |
| 64 | if (normalizeLangCode(code) !== code.toLowerCase()) |
| 65 | throw new ApiError(HTTP_BAD_REQUEST, 'bad code/filename') |
| 66 | } |