main
ts 66 lines 2.21 KB
Raw
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 }