forked from JohnXLivingston/peertube-plugin-livechat
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild-languages.js
More file actions
154 lines (135 loc) · 4.66 KB
/
Copy pathbuild-languages.js
File metadata and controls
154 lines (135 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* This script is used to build the translations files.
*
* Indeed, some strings used in plugin settings are not easy to write
* in JSON format (contains html, double quotes, line breaks, ...).
* So we use YAML files to translates these strings,
* including the english version.
*
* This scripts takes the standard JSON files, the YAML translation files,
* and mixes everything up in dist/languages/xx.json.
*/
const fs = require('fs')
const path = require('path')
const YAML = require('yaml')
class BuildLanguages {
destinationDir = null
langs = []
translationsStrings = {}
monoLingualReferences = {}
constructor () {
this.destinationDir = path.resolve(__dirname, 'dist', 'languages')
}
async generateFiles () {
await this.loadLangs()
await this.initTranslationStrings()
await this.readJSONTranslations()
await this.readSettingsTranslations()
await this.ensureDestinationDir()
await this.writeJSONTranslations()
await this.writeMonoLingualReferences()
}
loadLangs () {
const packagejson = require('./package.json')
const translations = packagejson.translations || {}
this.langs = Object.values(translations).map(filename => {
return filename.match(/^.*\/(\w+)\.json$/)[1]
})
console.log('Existing languages: ', this.langs)
}
initTranslationStrings () {
console.log('Initializing translations strings...')
const translationsStrings = {}
for (const l of this.langs) {
translationsStrings[l] = {}
}
this.translationsStrings = translationsStrings
}
async readJSONTranslations () {
console.log('Reading standard JSON translation strings...')
const translationsStrings = this.translationsStrings
for (const l of this.langs) {
const filePath = path.resolve(__dirname, 'languages', l + '.json')
if (!fs.existsSync(filePath)) {
console.warn(`File ${filePath} missing, ignoring.`)
continue
}
const t = require(filePath)
for (const k in t) {
const v = t[k]
if (k in translationsStrings[l]) {
throw new Error(`Duplicate translation for key ${k} in lang ${l}.`)
}
translationsStrings[l][k] = v
}
}
}
async readSettingsTranslations () {
console.log('Reading Settings Yaml translation strings...')
// First we must get the english reference file,
// that will give us the keys to use in final JSON.
const reference = await this.getYmlFileContent(path.resolve(__dirname, 'languages', 'settings', 'en.yml'))
this.monoLingualReferences['settings'] = reference
const translationsStrings = this.translationsStrings
for (const l of this.langs) {
const filePath = path.resolve(__dirname, 'languages', 'settings', l + '.yml')
const o = await this.getYmlFileContent(filePath)
for (const k in o) {
if (!(k in reference)) {
throw new Error(`File ${filePath} contains unknown keys. Key=${k}.`)
}
const newKey = reference[k]
this.translationsStrings[l][newKey] = o[k]
}
}
}
async getYmlFileContent (filePath) {
if (!fs.existsSync(filePath)) {
console.warn(`File ${filePath} missing, ignoring.`)
return {}
}
const content = await fs.promises.readFile(filePath, 'utf8')
const o = YAML.parse(content) || {}
for (const k in o) {
let v = o[k]
if (v === null) {
// this value is ok!
continue
}
if ((typeof v) !== 'string') {
throw new Error(`File ${filePath} contains strings that are not strings! Key=${k}`)
}
// We are normalizing the string, to avoid problems.
// As it is supposed to be html, we will strip newlines and multiple adjacent spaces.
v = v.replace(/\n/g, ' ')
v = v.replace(/\s\s+/g, ' ')
v = v.trim()
o[k] = v
}
return o
}
async ensureDestinationDir () {
if (!fs.existsSync(this.destinationDir)) {
await fs.promises.mkdir(this.destinationDir)
}
}
async writeJSONTranslations () {
console.log('Writing JSON files...')
for (const l of this.langs) {
const filePath = path.resolve(this.destinationDir, l + '.json')
await fs.promises.writeFile(filePath, JSON.stringify(this.translationsStrings[l]))
}
}
async writeMonoLingualReferences () {
console.log('Writing JSON reference files...')
for (const name in this.monoLingualReferences) {
const filePath = path.resolve(this.destinationDir, name + '.reference.json')
await fs.promises.writeFile(filePath, JSON.stringify(this.monoLingualReferences[name]))
}
}
}
const bl = new BuildLanguages()
bl.generateFiles().then(() => {}, (err) => {
console.error(err)
throw err
})