browser-extension-manager 1.3.30 → 1.3.32
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/dist/commands/clean.js +0 -33
- package/dist/gulp/main.js +1 -1
- package/dist/gulp/tasks/package.js +46 -0
- package/dist/gulp/tasks/translate.js +84 -39
- package/package.json +1 -1
package/dist/commands/clean.js
CHANGED
|
@@ -3,11 +3,6 @@ const Manager = new (require('../build.js'));
|
|
|
3
3
|
const logger = Manager.logger('clean');
|
|
4
4
|
const { execSync } = require('child_process');
|
|
5
5
|
const jetpack = require('fs-jetpack');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
|
|
8
|
-
// Load package
|
|
9
|
-
const package = Manager.getPackage('main');
|
|
10
|
-
const project = Manager.getPackage('project');
|
|
11
6
|
|
|
12
7
|
// Dirs to clean
|
|
13
8
|
const dirs = [
|
|
@@ -17,29 +12,11 @@ const dirs = [
|
|
|
17
12
|
// 'src/assets/themes',
|
|
18
13
|
]
|
|
19
14
|
|
|
20
|
-
// Dirs to preserve inside cleaned dirs
|
|
21
|
-
const preserve = [
|
|
22
|
-
'packaged/translations',
|
|
23
|
-
]
|
|
24
|
-
|
|
25
15
|
module.exports = async function (options) {
|
|
26
16
|
// Log
|
|
27
17
|
logger.log(`Cleaning up .temp, dist, and packaged directories...`);
|
|
28
18
|
|
|
29
19
|
try {
|
|
30
|
-
// Back up preserved dirs
|
|
31
|
-
const backups = {};
|
|
32
|
-
for (const dir of preserve) {
|
|
33
|
-
if (!jetpack.exists(dir)) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const backupPath = path.join('.temp', '_preserve', dir);
|
|
38
|
-
jetpack.dir(path.dirname(backupPath));
|
|
39
|
-
jetpack.move(dir, backupPath, { overwrite: true });
|
|
40
|
-
backups[dir] = backupPath;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
20
|
// Loop through dirs
|
|
44
21
|
dirs.forEach((dir) => {
|
|
45
22
|
// Remove (use rm -rf on Unix for speed, fallback to jetpack on Windows)
|
|
@@ -52,16 +29,6 @@ module.exports = async function (options) {
|
|
|
52
29
|
// Create empty dir
|
|
53
30
|
jetpack.dir(dir);
|
|
54
31
|
});
|
|
55
|
-
|
|
56
|
-
// Restore preserved dirs
|
|
57
|
-
for (const [dir, backupPath] of Object.entries(backups)) {
|
|
58
|
-
jetpack.dir(path.dirname(dir));
|
|
59
|
-
jetpack.move(backupPath, dir, { overwrite: true });
|
|
60
|
-
logger.log(`Preserved: ${dir}`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Clean up temp preserve dir
|
|
64
|
-
jetpack.remove(path.join('.temp', '_preserve'));
|
|
65
32
|
} catch (e) {
|
|
66
33
|
logger.error(`Error clearing directories: ${e}`);
|
|
67
34
|
}
|
package/dist/gulp/main.js
CHANGED
|
@@ -44,8 +44,8 @@ exports.build = series(
|
|
|
44
44
|
// exports.clean,
|
|
45
45
|
// exports.themes,
|
|
46
46
|
exports.defaults,
|
|
47
|
-
exports.translate,
|
|
48
47
|
exports.distribute,
|
|
48
|
+
exports.translate,
|
|
49
49
|
parallel(exports.sass, exports.webpack, exports.icons, exports.html),
|
|
50
50
|
exports.package,
|
|
51
51
|
exports.audit,
|
|
@@ -529,6 +529,49 @@ function liveReload() {
|
|
|
529
529
|
return;
|
|
530
530
|
}
|
|
531
531
|
|
|
532
|
+
// Deploy store submission assets to packaged/assets/
|
|
533
|
+
async function deployStoreAssets() {
|
|
534
|
+
const assetsDir = path.join('packaged', 'assets');
|
|
535
|
+
|
|
536
|
+
// Copy 128x128 icon for store submission
|
|
537
|
+
const iconSrc = path.join('dist', 'assets', 'images', 'icons', 'icon-128x.png');
|
|
538
|
+
if (jetpack.exists(iconSrc)) {
|
|
539
|
+
const iconDest = path.join(assetsDir, 'icon', 'icon-128x.png');
|
|
540
|
+
jetpack.dir(path.dirname(iconDest));
|
|
541
|
+
jetpack.copy(iconSrc, iconDest, { overwrite: true });
|
|
542
|
+
logger.log('Store asset: icon-128x.png');
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Copy English description
|
|
546
|
+
const enDescSrc = path.join(process.cwd(), 'config', 'description.md');
|
|
547
|
+
if (jetpack.exists(enDescSrc)) {
|
|
548
|
+
const descDir = path.join(assetsDir, 'description');
|
|
549
|
+
jetpack.dir(descDir);
|
|
550
|
+
jetpack.copy(enDescSrc, path.join(descDir, 'en.md'), { overwrite: true });
|
|
551
|
+
logger.log('Store asset: description/en.md');
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// Copy cached translated descriptions
|
|
555
|
+
const cacheDescDir = path.join(process.cwd(), '.cache', 'translations', 'description');
|
|
556
|
+
if (jetpack.exists(cacheDescDir)) {
|
|
557
|
+
const descDir = path.join(assetsDir, 'description');
|
|
558
|
+
jetpack.dir(descDir);
|
|
559
|
+
|
|
560
|
+
let count = 0;
|
|
561
|
+
const files = jetpack.find(cacheDescDir, { matching: '*.md' });
|
|
562
|
+
|
|
563
|
+
for (const file of files) {
|
|
564
|
+
const fileName = path.basename(file);
|
|
565
|
+
jetpack.copy(file, path.join(descDir, fileName), { overwrite: true });
|
|
566
|
+
count++;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (count > 0) {
|
|
570
|
+
logger.log(`Store asset: ${count} translated descriptions`);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
532
575
|
// Package Task
|
|
533
576
|
async function packageFn(complete) {
|
|
534
577
|
try {
|
|
@@ -550,6 +593,9 @@ async function packageFn(complete) {
|
|
|
550
593
|
// Run packageSource
|
|
551
594
|
await packageSource();
|
|
552
595
|
|
|
596
|
+
// Deploy store submission assets
|
|
597
|
+
await deployStoreAssets();
|
|
598
|
+
|
|
553
599
|
// Run build:post hook
|
|
554
600
|
await hook('build:post', index);
|
|
555
601
|
|
|
@@ -14,55 +14,55 @@ const { limits: LOCALE_LIMITS, languages: LANGUAGES } = require('../config/local
|
|
|
14
14
|
// Paths
|
|
15
15
|
const configMessagesPath = path.join(process.cwd(), 'config', 'messages.json');
|
|
16
16
|
const configDescriptionPath = path.join(process.cwd(), 'config', 'description.md');
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const descriptionDir = path.join(translationsDir, 'description');
|
|
17
|
+
const distLocalesDir = path.join(process.cwd(), 'dist', '_locales');
|
|
18
|
+
|
|
19
|
+
// Cache paths — translations are persisted in .cache/ so they survive clean
|
|
21
20
|
const cacheDir = path.join(process.cwd(), '.cache');
|
|
22
|
-
const
|
|
21
|
+
const cacheHashPath = path.join(cacheDir, 'translate.json');
|
|
22
|
+
const cacheMessagesDir = path.join(cacheDir, 'translations', 'messages');
|
|
23
|
+
const cacheDescriptionDir = path.join(cacheDir, 'translations', 'description');
|
|
23
24
|
|
|
24
|
-
// Helper: Compute hash of a string
|
|
25
|
+
// Helper: Compute MD5 hash of a string
|
|
25
26
|
function hash(content) {
|
|
26
27
|
return crypto.createHash('md5').update(content).digest('hex');
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
// Helper: Read cache
|
|
30
|
-
function
|
|
31
|
-
if (!jetpack.exists(
|
|
30
|
+
// Helper: Read cache hashes
|
|
31
|
+
function readCacheHashes() {
|
|
32
|
+
if (!jetpack.exists(cacheHashPath)) {
|
|
32
33
|
return {};
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
try {
|
|
36
|
-
return JSON.parse(jetpack.read(
|
|
37
|
+
return JSON.parse(jetpack.read(cacheHashPath));
|
|
37
38
|
} catch (e) {
|
|
38
39
|
return {};
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
// Helper: Write cache
|
|
43
|
-
function
|
|
43
|
+
// Helper: Write cache hashes
|
|
44
|
+
function writeCacheHashes(cache) {
|
|
44
45
|
jetpack.dir(cacheDir);
|
|
45
|
-
jetpack.write(
|
|
46
|
+
jetpack.write(cacheHashPath, JSON.stringify(cache, null, 2));
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
// Helper: Check if source has changed since last translation
|
|
49
50
|
function hasSourceChanged(cacheKey, content) {
|
|
50
|
-
const cache =
|
|
51
|
-
const currentHash = hash(content);
|
|
51
|
+
const cache = readCacheHashes();
|
|
52
52
|
|
|
53
|
-
return cache[cacheKey] !==
|
|
53
|
+
return cache[cacheKey] !== hash(content);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// Helper: Update cache hash for a source
|
|
57
57
|
function updateCacheHash(cacheKey, content) {
|
|
58
|
-
const cache =
|
|
58
|
+
const cache = readCacheHashes();
|
|
59
59
|
|
|
60
60
|
cache[cacheKey] = hash(content);
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
writeCacheHashes(cache);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
// Helper: Read and parse config/messages.json
|
|
65
|
+
// Helper: Read and parse config/messages.json (JSON5 → object)
|
|
66
66
|
function readConfigMessages() {
|
|
67
67
|
if (!jetpack.exists(configMessagesPath)) {
|
|
68
68
|
return null;
|
|
@@ -122,19 +122,42 @@ function chunkObject(obj, size) {
|
|
|
122
122
|
return chunks;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
//
|
|
126
|
-
// Always runs (dev + build) so
|
|
127
|
-
async function
|
|
128
|
-
//
|
|
125
|
+
// Deploy cached translations to dist/_locales/
|
|
126
|
+
// Always runs (dev + build) so package task has all locale files
|
|
127
|
+
async function deployTranslations(complete) {
|
|
128
|
+
// Deploy EN messages from config/messages.json → dist/_locales/en/messages.json
|
|
129
129
|
const enMessages = readConfigMessages();
|
|
130
130
|
if (enMessages) {
|
|
131
|
-
|
|
132
|
-
jetpack.
|
|
133
|
-
|
|
131
|
+
const enDir = path.join(distLocalesDir, 'en');
|
|
132
|
+
jetpack.dir(enDir);
|
|
133
|
+
jetpack.write(path.join(enDir, 'messages.json'), JSON.stringify(enMessages, null, 2));
|
|
134
|
+
logger.log('Deployed config/messages.json → dist/_locales/en/messages.json');
|
|
134
135
|
} else {
|
|
135
136
|
logger.warn('config/messages.json not found or invalid, skipping');
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
// Deploy cached message translations → dist/_locales/{lang}/messages.json
|
|
140
|
+
if (jetpack.exists(cacheMessagesDir)) {
|
|
141
|
+
let count = 0;
|
|
142
|
+
|
|
143
|
+
for (const lang of Object.keys(LANGUAGES)) {
|
|
144
|
+
const cachedPath = path.join(cacheMessagesDir, `${lang}.json`);
|
|
145
|
+
|
|
146
|
+
if (!jetpack.exists(cachedPath)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const langDir = path.join(distLocalesDir, lang);
|
|
151
|
+
jetpack.dir(langDir);
|
|
152
|
+
jetpack.copy(cachedPath, path.join(langDir, 'messages.json'), { overwrite: true });
|
|
153
|
+
count++;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (count > 0) {
|
|
157
|
+
logger.log(`Deployed ${count} cached message translations to dist/_locales/`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
138
161
|
// Complete
|
|
139
162
|
return complete();
|
|
140
163
|
}
|
|
@@ -211,23 +234,38 @@ OUTPUT FORMAT:
|
|
|
211
234
|
|
|
212
235
|
Output the translated JSON:`);
|
|
213
236
|
|
|
214
|
-
//
|
|
237
|
+
// Ensure cache directory exists
|
|
238
|
+
jetpack.dir(cacheMessagesDir);
|
|
239
|
+
|
|
240
|
+
let savedCount = 0;
|
|
241
|
+
|
|
242
|
+
// Write each translation to cache and dist
|
|
215
243
|
for (const lang of Object.keys(LANGUAGES)) {
|
|
216
244
|
if (!translations[lang]) {
|
|
217
245
|
logger.warn(`[${lang}] No translation returned`);
|
|
218
246
|
continue;
|
|
219
247
|
}
|
|
220
248
|
|
|
221
|
-
const
|
|
222
|
-
const langMessagesPath = path.join(langDir, 'messages.json');
|
|
249
|
+
const content = JSON.stringify(translations[lang], null, 2);
|
|
223
250
|
|
|
251
|
+
// Save to cache
|
|
252
|
+
jetpack.write(path.join(cacheMessagesDir, `${lang}.json`), content);
|
|
253
|
+
|
|
254
|
+
// Save to dist
|
|
255
|
+
const langDir = path.join(distLocalesDir, lang);
|
|
224
256
|
jetpack.dir(langDir);
|
|
225
|
-
jetpack.write(
|
|
257
|
+
jetpack.write(path.join(langDir, 'messages.json'), content);
|
|
258
|
+
|
|
226
259
|
logger.log(`[${lang}] Messages translation saved`);
|
|
260
|
+
savedCount++;
|
|
227
261
|
}
|
|
228
262
|
|
|
229
|
-
//
|
|
230
|
-
|
|
263
|
+
// Only update cache hash if we saved all translations
|
|
264
|
+
if (savedCount === Object.keys(LANGUAGES).length) {
|
|
265
|
+
updateCacheHash('messages', sourceContent);
|
|
266
|
+
} else {
|
|
267
|
+
logger.warn(`Only ${savedCount}/${Object.keys(LANGUAGES).length} translations saved, not updating cache hash`);
|
|
268
|
+
}
|
|
231
269
|
} catch (e) {
|
|
232
270
|
logger.error(`Messages translation failed: ${e.message}`);
|
|
233
271
|
}
|
|
@@ -278,8 +316,10 @@ async function translateDescription(complete) {
|
|
|
278
316
|
|
|
279
317
|
logger.log(`Translating description into ${Object.keys(LANGUAGES).length} languages (${batches.length} batches of ${BATCH_SIZE})...`);
|
|
280
318
|
|
|
281
|
-
// Ensure
|
|
282
|
-
jetpack.dir(
|
|
319
|
+
// Ensure cache directory exists
|
|
320
|
+
jetpack.dir(cacheDescriptionDir);
|
|
321
|
+
|
|
322
|
+
let totalSaved = 0;
|
|
283
323
|
|
|
284
324
|
try {
|
|
285
325
|
for (let i = 0; i < batches.length; i++) {
|
|
@@ -314,20 +354,25 @@ ${Object.keys(batch).map((code) => ` "${code}": "full translated description he
|
|
|
314
354
|
|
|
315
355
|
Output the translated JSON:`);
|
|
316
356
|
|
|
317
|
-
// Write each translation in this batch
|
|
357
|
+
// Write each translation in this batch to cache
|
|
318
358
|
for (const lang of Object.keys(batch)) {
|
|
319
359
|
if (!translations[lang]) {
|
|
320
360
|
logger.warn(`[${lang}] No description translation returned`);
|
|
321
361
|
continue;
|
|
322
362
|
}
|
|
323
363
|
|
|
324
|
-
jetpack.write(path.join(
|
|
364
|
+
jetpack.write(path.join(cacheDescriptionDir, `${lang}.md`), translations[lang]);
|
|
325
365
|
logger.log(`[${lang}] Description translation saved`);
|
|
366
|
+
totalSaved++;
|
|
326
367
|
}
|
|
327
368
|
}
|
|
328
369
|
|
|
329
|
-
//
|
|
330
|
-
|
|
370
|
+
// Only update cache hash if we saved all translations
|
|
371
|
+
if (totalSaved === Object.keys(LANGUAGES).length) {
|
|
372
|
+
updateCacheHash('description', enDescription);
|
|
373
|
+
} else {
|
|
374
|
+
logger.warn(`Only ${totalSaved}/${Object.keys(LANGUAGES).length} description translations saved, not updating cache hash`);
|
|
375
|
+
}
|
|
331
376
|
} catch (e) {
|
|
332
377
|
logger.error(`Description translation failed: ${e.message}`);
|
|
333
378
|
}
|
|
@@ -340,4 +385,4 @@ Output the translated JSON:`);
|
|
|
340
385
|
}
|
|
341
386
|
|
|
342
387
|
// Export task
|
|
343
|
-
module.exports = series(
|
|
388
|
+
module.exports = series(deployTranslations, translateMessages, translateDescription);
|