scratch-l10n 5.0.231 → 5.0.233
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +9 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +53 -46
- package/.github/workflows/ci-cd.yml +5 -5
- package/.github/workflows/commitlint.yml +1 -1
- package/.github/workflows/daily-help-update.yml +4 -4
- package/.github/workflows/daily-tx-pull.yml +4 -4
- package/.github/workflows/signature-assistant.yml +3 -3
- package/.prettierignore +11 -0
- package/CHANGELOG.md +14 -0
- package/README.md +12 -12
- package/commitlint.config.js +3 -3
- package/dist/l10n.js +224 -232
- package/dist/l10n.js.map +1 -1
- package/dist/localeData.js +223 -232
- package/dist/localeData.js.map +1 -1
- package/dist/supportedLocales.js +123 -130
- package/dist/supportedLocales.js.map +1 -1
- package/eslint.config.mjs +13 -0
- package/lib/batch.js +10 -12
- package/lib/progress-logger.mjs +33 -33
- package/lib/transifex.js +145 -144
- package/lib/validate.mjs +32 -31
- package/package.json +7 -8
- package/prettier.config.mjs +3 -0
- package/release.config.js +13 -13
- package/renovate.json5 +3 -5
- package/scripts/build-data.mjs +33 -49
- package/scripts/build-i18n-src.js +29 -28
- package/scripts/freshdesk-api.js +129 -144
- package/scripts/help-utils.js +129 -139
- package/scripts/tx-pull-editor.mjs +54 -51
- package/scripts/tx-pull-help-articles.js +14 -14
- package/scripts/tx-pull-help-names.js +14 -14
- package/scripts/tx-pull-locale-articles.js +19 -19
- package/scripts/tx-pull-www.mjs +79 -76
- package/scripts/tx-push-help.mjs +87 -96
- package/scripts/tx-push-src.js +65 -65
- package/scripts/validate-extension-inputs.mjs +65 -68
- package/scripts/validate-translations.mjs +33 -29
- package/scripts/validate-www.mjs +45 -43
- package/src/index.mjs +4 -3
- package/src/locale-data.mjs +148 -150
- package/src/supported-locales.mjs +124 -131
package/scripts/help-utils.js
CHANGED
@@ -1,182 +1,174 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
/**
|
4
|
-
* @
|
4
|
+
* @file
|
5
5
|
* Helper functions for syncing Freshdesk knowledge base articles with Transifex
|
6
6
|
*/
|
7
7
|
|
8
|
-
const FreshdeskApi = require('./freshdesk-api.js')
|
9
|
-
const fs = require('fs')
|
10
|
-
const fsPromises = fs.promises
|
11
|
-
const mkdirp = require('mkdirp')
|
12
|
-
const {txPull, txResourcesObjects, txAvailableLanguages} = require('../lib/transifex.js')
|
8
|
+
const FreshdeskApi = require('./freshdesk-api.js')
|
9
|
+
const fs = require('fs')
|
10
|
+
const fsPromises = fs.promises
|
11
|
+
const mkdirp = require('mkdirp')
|
12
|
+
const { txPull, txResourcesObjects, txAvailableLanguages } = require('../lib/transifex.js')
|
13
13
|
|
14
|
-
const FD = new FreshdeskApi('https://mitscratch.freshdesk.com', process.env.FRESHDESK_TOKEN)
|
15
|
-
const TX_PROJECT = 'scratch-help'
|
14
|
+
const FD = new FreshdeskApi('https://mitscratch.freshdesk.com', process.env.FRESHDESK_TOKEN)
|
15
|
+
const TX_PROJECT = 'scratch-help'
|
16
16
|
|
17
17
|
const freshdeskLocale = locale => {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
}
|
35
|
-
|
18
|
+
// map between Transifex locale and Freshdesk. Two letter codes are usually fine
|
19
|
+
const localeMap = {
|
20
|
+
es_419: 'es-LA',
|
21
|
+
ja: 'ja-JP',
|
22
|
+
'ja-Hira': 'ja-JP',
|
23
|
+
lv: 'lv-LV',
|
24
|
+
nb: 'nb-NO',
|
25
|
+
nn: 'nb-NO',
|
26
|
+
pt: 'pt-PT',
|
27
|
+
pt_BR: 'pt-BR',
|
28
|
+
ru: 'ru-RU',
|
29
|
+
sv: 'sv-SE',
|
30
|
+
zh_CN: 'zh-CN',
|
31
|
+
zh_TW: 'zh-TW',
|
32
|
+
}
|
33
|
+
return localeMap[locale] || locale
|
34
|
+
}
|
36
35
|
|
37
36
|
/**
|
38
37
|
* Pull metadata from Transifex for the scratch-help project
|
39
|
-
* @
|
38
|
+
* @returns {Promise} results array containing:
|
40
39
|
* languages: array of supported languages
|
41
|
-
* folders: array of tx resources
|
40
|
+
* folders: array of tx resources corresponding to Freshdesk folders
|
42
41
|
* names: array of tx resources corresponding to the Freshdesk metadata
|
43
42
|
*/
|
44
43
|
exports.getInputs = async () => {
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
const resources = await txResourcesObjects(TX_PROJECT)
|
45
|
+
const languages = await txAvailableLanguages(TX_PROJECT)
|
46
|
+
// there are three types of resources differentiated by the file type
|
47
|
+
const folders = resources.filter(resource => resource.i18n_type === 'STRUCTURED_JSON')
|
48
|
+
const names = resources.filter(resource => resource.i18n_type === 'KEYVALUEJSON')
|
49
|
+
// ignore the yaml type because it's not possible to update via API
|
51
50
|
|
52
|
-
|
53
|
-
}
|
51
|
+
return Promise.all([languages, folders, names])
|
52
|
+
}
|
54
53
|
|
55
|
-
|
54
|
+
/*
|
56
55
|
* internal function to serialize saving category and folder name translations to avoid Freshdesk rate limit
|
57
|
-
* @param {[type]} json [description]
|
58
|
-
* @param {[type]} resource [description]
|
59
|
-
* @param {[type]} locale [description]
|
60
|
-
* @return {Promise} [description]
|
61
56
|
*/
|
62
57
|
const serializeNameSave = async (json, resource, locale) => {
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
}
|
58
|
+
for (const [key, value] of Object.entries(json)) {
|
59
|
+
// key is of the form <name>_<id>
|
60
|
+
const words = key.split('_')
|
61
|
+
const id = words[words.length - 1]
|
62
|
+
let status = 0
|
63
|
+
if (resource.name === 'categoryNames_json') {
|
64
|
+
status = await FD.updateCategoryTranslation(id, freshdeskLocale(locale), { name: value })
|
65
|
+
}
|
66
|
+
if (resource.name === 'folderNames_json') {
|
67
|
+
status = await FD.updateFolderTranslation(id, freshdeskLocale(locale), { name: value })
|
68
|
+
}
|
69
|
+
if (status === -1) {
|
70
|
+
process.exitCode = 1
|
77
71
|
}
|
78
|
-
}
|
72
|
+
}
|
73
|
+
}
|
79
74
|
|
80
75
|
/**
|
81
76
|
* Internal function serialize Freshdesk requests to avoid getting rate limited
|
82
77
|
* @param {object} json object with keys corresponding to article ids
|
83
78
|
* @param {string} locale language code
|
84
|
-
* @
|
79
|
+
* @returns {Promise} [description]
|
85
80
|
*/
|
86
81
|
const serializeFolderSave = async (json, locale) => {
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
};
|
106
|
-
if (Object.prototype.hasOwnProperty.call(value, 'tags')) {
|
107
|
-
let tags = value.tags.string.split(',');
|
108
|
-
let validTags = tags.filter(tag => tag.length < 33);
|
109
|
-
if (validTags.length !== tags.length) {
|
110
|
-
process.stdout.write(`Warning: tags too long in ${id} for ${locale}\n`);
|
111
|
-
}
|
112
|
-
body.tags = validTags;
|
113
|
-
}
|
114
|
-
let status = await FD.updateArticleTranslation(id, freshdeskLocale(locale), body);
|
115
|
-
if (status === -1) {
|
116
|
-
process.exitCode = 1;
|
117
|
-
}
|
82
|
+
// json is a map of articles:
|
83
|
+
// {
|
84
|
+
// <id>: {
|
85
|
+
// title: {string: <title-value>},
|
86
|
+
// description: {string: <description-value>},
|
87
|
+
// tags: {string: <comma separated strings} // optional
|
88
|
+
// },
|
89
|
+
// <id>: {
|
90
|
+
// title: {string: <title-value>},
|
91
|
+
// description: {string: <description-value>},
|
92
|
+
// tags: {string: <comma separated strings} // optional
|
93
|
+
// }
|
94
|
+
// }
|
95
|
+
for (const [id, value] of Object.entries(json)) {
|
96
|
+
const body = {
|
97
|
+
title: value.title.string,
|
98
|
+
description: value.description.string,
|
99
|
+
status: 2, // set status to published
|
118
100
|
}
|
119
|
-
|
120
|
-
|
101
|
+
if (Object.prototype.hasOwnProperty.call(value, 'tags')) {
|
102
|
+
const tags = value.tags.string.split(',')
|
103
|
+
const validTags = tags.filter(tag => tag.length < 33)
|
104
|
+
if (validTags.length !== tags.length) {
|
105
|
+
process.stdout.write(`Warning: tags too long in ${id} for ${locale}\n`)
|
106
|
+
}
|
107
|
+
body.tags = validTags
|
108
|
+
}
|
109
|
+
const status = await FD.updateArticleTranslation(id, freshdeskLocale(locale), body)
|
110
|
+
if (status === -1) {
|
111
|
+
// eslint-disable-next-line require-atomic-updates -- I promise that `process` won't change across `await`
|
112
|
+
process.exitCode = 1
|
113
|
+
}
|
114
|
+
}
|
115
|
+
return 0
|
116
|
+
}
|
121
117
|
|
122
118
|
/**
|
123
119
|
* Process Transifex resource corresponding to a Knowledge base folder on Freshdesk
|
124
120
|
* @param {object} folder Transifex resource json corresponding to a KB folder
|
125
121
|
* @param {string} locale locale to pull and submit to Freshdesk
|
126
|
-
* @
|
122
|
+
* @returns {Promise} [description]
|
127
123
|
*/
|
128
124
|
exports.localizeFolder = async (folder, locale) => {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
}
|
125
|
+
txPull(TX_PROJECT, folder.slug, locale, { mode: 'default' })
|
126
|
+
.then(data => {
|
127
|
+
serializeFolderSave(data, locale)
|
128
|
+
})
|
129
|
+
.catch(e => {
|
130
|
+
process.stdout.write(`Error processing ${folder.slug}, ${locale}: ${e.message}\n`)
|
131
|
+
process.exitCode = 1 // not ok
|
132
|
+
})
|
133
|
+
}
|
138
134
|
|
139
135
|
/**
|
140
136
|
* Save Transifex resource corresponding to a Knowledge base folder locally for debugging
|
141
137
|
* @param {object} folder Transifex resource json corresponding to a KB folder
|
142
138
|
* @param {string} locale locale to pull and save
|
143
|
-
* @
|
139
|
+
* @returns {Promise} [description]
|
144
140
|
*/
|
145
141
|
exports.debugFolder = async (folder, locale) => {
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
process.exitCode = 1; // not ok
|
157
|
-
});
|
158
|
-
};
|
142
|
+
mkdirp.sync('tmpDebug')
|
143
|
+
txPull(TX_PROJECT, folder.slug, locale, { mode: 'default' })
|
144
|
+
.then(data => {
|
145
|
+
fsPromises.writeFile(`tmpDebug/${folder.slug}_${locale}.json`, JSON.stringify(data, null, 2))
|
146
|
+
})
|
147
|
+
.catch(e => {
|
148
|
+
process.stdout.write(`Error processing ${folder.slug}, ${locale}: ${e.message}\n`)
|
149
|
+
process.exitCode = 1 // not ok
|
150
|
+
})
|
151
|
+
}
|
159
152
|
|
160
153
|
/**
|
161
154
|
* Process KEYVALUEJSON resources from scratch-help on transifex
|
162
155
|
* Category and Folder names are stored as plain json
|
163
156
|
* @param {object} resource Transifex resource json for either CategoryNames or FolderNames
|
164
157
|
* @param {string} locale locale to pull and submit to Freshdesk
|
165
|
-
* @
|
158
|
+
* @returns {Promise} [description]
|
166
159
|
*/
|
167
160
|
exports.localizeNames = async (resource, locale) => {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
}
|
161
|
+
txPull(TX_PROJECT, resource.slug, locale, { mode: 'default' })
|
162
|
+
.then(data => {
|
163
|
+
serializeNameSave(data, resource, locale)
|
164
|
+
})
|
165
|
+
.catch(e => {
|
166
|
+
process.stdout.write(`Error saving ${resource.slug}, ${locale}: ${e.message}\n`)
|
167
|
+
process.exitCode = 1 // not ok
|
168
|
+
})
|
169
|
+
}
|
177
170
|
|
178
|
-
|
179
|
-
const BATCH_SIZE = 2;
|
171
|
+
const BATCH_SIZE = 2
|
180
172
|
/*
|
181
173
|
* save resource items in batches to reduce rate limiting errors
|
182
174
|
* @param {object} item Transifex resource json, used for 'slug'
|
@@ -185,16 +177,14 @@ const BATCH_SIZE = 2;
|
|
185
177
|
* @return {Promise}
|
186
178
|
*/
|
187
179
|
exports.saveItem = async (item, languages, saveFn) => {
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
}
|
200
|
-
};
|
180
|
+
const saveLanguages = languages.filter(l => l !== 'en') // exclude English from update
|
181
|
+
let batchedPromises = Promise.resolve()
|
182
|
+
for (let i = 0; i < saveLanguages.length; i += BATCH_SIZE) {
|
183
|
+
batchedPromises = batchedPromises
|
184
|
+
.then(() => Promise.all(saveLanguages.slice(i, i + BATCH_SIZE).map(l => saveFn(item, l))))
|
185
|
+
.catch(err => {
|
186
|
+
process.stdout.write(`Error saving item:${err.message}\n${JSON.stringify(item, null, 2)}\n`)
|
187
|
+
process.exitCode = 1 // not ok
|
188
|
+
})
|
189
|
+
}
|
190
|
+
}
|
@@ -1,14 +1,27 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
+
/**
|
3
|
+
* @file
|
4
|
+
* Script to pull translations from transifex and generate the editor-msgs file.
|
5
|
+
* Expects that the project and resource have already been defined in Transifex, and that
|
6
|
+
* the person running the script has the the TX_TOKEN environment variable set to an api
|
7
|
+
* token that has developer access.
|
8
|
+
*/
|
9
|
+
import fs from 'fs'
|
10
|
+
import path from 'path'
|
11
|
+
import { batchMap } from '../lib/batch.js'
|
12
|
+
import { txPull } from '../lib/transifex.js'
|
13
|
+
import { validateTranslations } from '../lib/validate.mjs'
|
14
|
+
import locales, { localeMap } from '../src/supported-locales.mjs'
|
2
15
|
|
3
16
|
/**
|
4
|
-
* @
|
17
|
+
* @file
|
5
18
|
* Script to pull translations from transifex and generate the editor-msgs file.
|
6
19
|
* Expects that the project and resource have already been defined in Transifex, and that
|
7
20
|
* the person running the script has the the TX_TOKEN environment variable set to an api
|
8
21
|
* token that has developer access.
|
9
22
|
*/
|
10
23
|
|
11
|
-
const args = process.argv.slice(2)
|
24
|
+
const args = process.argv.slice(2)
|
12
25
|
|
13
26
|
const usage = `
|
14
27
|
Pull supported language translations from Transifex. Usage:
|
@@ -18,63 +31,53 @@ const usage = `
|
|
18
31
|
path: where to put the downloaded json files
|
19
32
|
NOTE: TX_TOKEN environment variable needs to be set with a Transifex API token. See
|
20
33
|
the Localization page on the GUI wiki for information about setting up Transifex.
|
21
|
-
|
34
|
+
`
|
22
35
|
|
23
36
|
// Fail immediately if the TX_TOKEN is not defined
|
24
37
|
if (!process.env.TX_TOKEN || args.length < 3) {
|
25
|
-
|
26
|
-
|
38
|
+
process.stdout.write(usage)
|
39
|
+
process.exit(1)
|
27
40
|
}
|
28
41
|
|
29
|
-
import fs from 'fs';
|
30
|
-
import path from 'path';
|
31
|
-
import {txPull} from '../lib/transifex.js';
|
32
|
-
import {validateTranslations} from '../lib/validate.mjs';
|
33
|
-
import locales, {localeMap} from '../src/supported-locales.mjs';
|
34
|
-
import {batchMap} from '../lib/batch.js';
|
35
|
-
|
36
42
|
// Globals
|
37
|
-
const PROJECT = args[0]
|
38
|
-
const RESOURCE = args[1]
|
39
|
-
const OUTPUT_DIR = path.resolve(args[2])
|
40
|
-
const MODE = 'reviewed'
|
41
|
-
const CONCURRENCY_LIMIT = 36
|
43
|
+
const PROJECT = args[0]
|
44
|
+
const RESOURCE = args[1]
|
45
|
+
const OUTPUT_DIR = path.resolve(args[2])
|
46
|
+
const MODE = 'reviewed'
|
47
|
+
const CONCURRENCY_LIMIT = 36
|
42
48
|
|
43
49
|
const getLocaleData = async function (locale) {
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
}
|
50
|
+
const txLocale = localeMap[locale] || locale
|
51
|
+
const data = await txPull(PROJECT, RESOURCE, txLocale, MODE)
|
52
|
+
return {
|
53
|
+
locale: locale,
|
54
|
+
translations: data,
|
55
|
+
}
|
56
|
+
}
|
51
57
|
|
52
58
|
const pullTranslations = async function () {
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
process.exit(1);
|
77
|
-
}
|
78
|
-
};
|
59
|
+
try {
|
60
|
+
const values = await batchMap(Object.keys(locales), CONCURRENCY_LIMIT, getLocaleData)
|
61
|
+
const source = values.find(elt => elt.locale === 'en').translations
|
62
|
+
values.forEach(translation => {
|
63
|
+
validateTranslations({ locale: translation.locale, translations: translation.translations }, source)
|
64
|
+
// if translation has message & description, we only want the message
|
65
|
+
const txs = {}
|
66
|
+
for (const key of Object.keys(translation.translations)) {
|
67
|
+
const tx = translation.translations[key]
|
68
|
+
if (tx.message) {
|
69
|
+
txs[key] = tx.message
|
70
|
+
} else {
|
71
|
+
txs[key] = tx
|
72
|
+
}
|
73
|
+
}
|
74
|
+
const file = JSON.stringify(txs, null, 4)
|
75
|
+
fs.writeFileSync(`${OUTPUT_DIR}/${translation.locale}.json`, file)
|
76
|
+
})
|
77
|
+
} catch (err) {
|
78
|
+
process.stdout.write(err.message)
|
79
|
+
process.exit(1)
|
80
|
+
}
|
81
|
+
}
|
79
82
|
|
80
|
-
pullTranslations()
|
83
|
+
pullTranslations()
|
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
/**
|
4
|
-
* @
|
4
|
+
* @file
|
5
5
|
* Script to pull scratch-help translations from transifex and push to FreshDesk.
|
6
6
|
*/
|
7
7
|
|
8
|
-
const args = process.argv.slice(2)
|
8
|
+
const args = process.argv.slice(2)
|
9
9
|
const usage = `
|
10
10
|
Pull knowledge base articles from transifex and push to FreshDesk. Usage:
|
11
11
|
node tx-pull-help.js
|
@@ -14,21 +14,21 @@ const usage = `
|
|
14
14
|
access to the Knowledge Base.
|
15
15
|
TX_TOKEN environment variable needs to be set with a Transifex API token. See
|
16
16
|
the Localization page on the GUI wiki for information about setting up Transifex.
|
17
|
-
|
17
|
+
`
|
18
18
|
// Fail immediately if the API tokens are not defined, or there any argument
|
19
19
|
if (!process.env.TX_TOKEN || !process.env.FRESHDESK_TOKEN || args.length > 0) {
|
20
|
-
|
21
|
-
|
20
|
+
process.stdout.write(usage)
|
21
|
+
process.exit(1)
|
22
22
|
}
|
23
23
|
|
24
|
-
const {getInputs, saveItem, localizeFolder} = require('./help-utils.js')
|
24
|
+
const { getInputs, saveItem, localizeFolder } = require('./help-utils.js')
|
25
25
|
|
26
26
|
getInputs()
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
.then(([languages, folders]) => {
|
28
|
+
process.stdout.write('Processing articles pulled from Transifex\n')
|
29
|
+
return folders.map(item => saveItem(item, languages, localizeFolder))
|
30
|
+
})
|
31
|
+
.catch(e => {
|
32
|
+
process.stdout.write(`Error: ${e.message}\n`)
|
33
|
+
process.exitCode = 1 // not ok
|
34
|
+
})
|
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
/**
|
4
|
-
* @
|
4
|
+
* @file
|
5
5
|
* Script to pull scratch-help translations from transifex and push to FreshDesk.
|
6
6
|
*/
|
7
7
|
|
8
|
-
const args = process.argv.slice(2)
|
8
|
+
const args = process.argv.slice(2)
|
9
9
|
|
10
10
|
const usage = `
|
11
11
|
Pull knowledge base category and folder names from transifex and push to FreshDesk. Usage:
|
@@ -15,21 +15,21 @@ const usage = `
|
|
15
15
|
access to the Knowledge Base.
|
16
16
|
TX_TOKEN environment variable needs to be set with a Transifex API token. See
|
17
17
|
the Localization page on the GUI wiki for information about setting up Transifex.
|
18
|
-
|
18
|
+
`
|
19
19
|
// Fail immediately if the API tokens are not defined, or there any argument
|
20
20
|
if (!process.env.TX_TOKEN || !process.env.FRESHDESK_TOKEN || args.length > 0) {
|
21
|
-
|
22
|
-
|
21
|
+
process.stdout.write(usage)
|
22
|
+
process.exit(1)
|
23
23
|
}
|
24
24
|
|
25
|
-
const {getInputs, saveItem, localizeNames} = require('./help-utils.js')
|
25
|
+
const { getInputs, saveItem, localizeNames } = require('./help-utils.js')
|
26
26
|
|
27
27
|
getInputs()
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
.then(([languages, , names]) => {
|
29
|
+
process.stdout.write('Process Category and Folder Names pulled from Transifex\n')
|
30
|
+
return names.map(item => saveItem(item, languages, localizeNames))
|
31
|
+
})
|
32
|
+
.catch(e => {
|
33
|
+
process.stdout.write(`Error: ${e.message}\n`)
|
34
|
+
process.exitCode = 1 // not ok
|
35
|
+
})
|
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
/**
|
4
|
-
* @
|
4
|
+
* @file
|
5
5
|
* Script to pull scratch-help translations from transifex and push to FreshDesk.
|
6
6
|
*/
|
7
7
|
|
8
|
-
const args = process.argv.slice(2)
|
8
|
+
const args = process.argv.slice(2)
|
9
9
|
const usage = `
|
10
10
|
Pull knowledge base articles from transifexfor debugging translation errors. Usage:
|
11
11
|
node tx-pull-locale-articles.js -d locale-code
|
@@ -14,29 +14,29 @@ const usage = `
|
|
14
14
|
access to the Knowledge Base.
|
15
15
|
TX_TOKEN environment variable needs to be set with a Transifex API token. See
|
16
16
|
the Localization page on the GUI wiki for information about setting up Transifex.
|
17
|
-
|
17
|
+
`
|
18
18
|
// Fail immediately if the API tokens are not defined, or missing argument
|
19
19
|
if (!process.env.TX_TOKEN || !process.env.FRESHDESK_TOKEN || args.length === 0) {
|
20
|
-
|
21
|
-
|
20
|
+
process.stdout.write(usage)
|
21
|
+
process.exit(1)
|
22
22
|
}
|
23
23
|
|
24
|
-
const {getInputs, saveItem, localizeFolder, debugFolder} = require('./help-utils.js')
|
24
|
+
const { getInputs, saveItem, localizeFolder, debugFolder } = require('./help-utils.js')
|
25
25
|
|
26
|
-
let locale = args[0]
|
27
|
-
let debug = false
|
26
|
+
let locale = args[0]
|
27
|
+
let debug = false
|
28
28
|
if (locale === '-d') {
|
29
|
-
|
30
|
-
|
29
|
+
debug = true
|
30
|
+
locale = args[1]
|
31
31
|
}
|
32
|
-
const saveFn = debug ? debugFolder : localizeFolder
|
32
|
+
const saveFn = debug ? debugFolder : localizeFolder
|
33
33
|
|
34
34
|
getInputs()
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
.then(([, folders]) => {
|
36
|
+
process.stdout.write('Processing articles pulled from Transifex\n')
|
37
|
+
return folders.map(item => saveItem(item, [locale], saveFn))
|
38
|
+
})
|
39
|
+
.catch(e => {
|
40
|
+
process.stdout.write(`Error: ${e.message}\n`)
|
41
|
+
process.exitCode = 1 // not ok
|
42
|
+
})
|