@shipi18n/cli 1.1.0 → 1.1.1
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/package.json +1 -1
- package/src/commands/translate.js +1 -67
- package/src/utils/incremental.js +90 -0
package/package.json
CHANGED
|
@@ -4,73 +4,7 @@ import chalk from 'chalk';
|
|
|
4
4
|
import { Shipi18nAPI } from '../lib/api.js';
|
|
5
5
|
import { getConfig } from '../lib/config.js';
|
|
6
6
|
import { logger, formatError } from '../utils/logger.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Flatten a nested object into dot-notation keys
|
|
10
|
-
*/
|
|
11
|
-
function flattenObject(obj, prefix = '') {
|
|
12
|
-
const result = {};
|
|
13
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
14
|
-
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
15
|
-
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
16
|
-
Object.assign(result, flattenObject(value, newKey));
|
|
17
|
-
} else {
|
|
18
|
-
result[newKey] = value;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return result;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Unflatten dot-notation keys back into nested object
|
|
26
|
-
*/
|
|
27
|
-
function unflattenObject(obj) {
|
|
28
|
-
const result = {};
|
|
29
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
30
|
-
const keys = key.split('.');
|
|
31
|
-
let current = result;
|
|
32
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
33
|
-
if (!current[keys[i]]) {
|
|
34
|
-
current[keys[i]] = {};
|
|
35
|
-
}
|
|
36
|
-
current = current[keys[i]];
|
|
37
|
-
}
|
|
38
|
-
current[keys[keys.length - 1]] = value;
|
|
39
|
-
}
|
|
40
|
-
return result;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Deep merge two objects
|
|
45
|
-
*/
|
|
46
|
-
function deepMerge(target, source) {
|
|
47
|
-
const result = { ...target };
|
|
48
|
-
for (const [key, value] of Object.entries(source)) {
|
|
49
|
-
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
50
|
-
result[key] = deepMerge(result[key] || {}, value);
|
|
51
|
-
} else {
|
|
52
|
-
result[key] = value;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Find keys that exist in source but not in target
|
|
60
|
-
*/
|
|
61
|
-
function findMissingKeys(sourceJson, targetJson) {
|
|
62
|
-
const sourceFlat = flattenObject(sourceJson);
|
|
63
|
-
const targetFlat = flattenObject(targetJson);
|
|
64
|
-
|
|
65
|
-
const missingKeys = {};
|
|
66
|
-
for (const [key, value] of Object.entries(sourceFlat)) {
|
|
67
|
-
if (!(key in targetFlat)) {
|
|
68
|
-
missingKeys[key] = value;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return unflattenObject(missingKeys);
|
|
73
|
-
}
|
|
7
|
+
import { flattenObject, unflattenObject, deepMerge, findMissingKeys } from '../utils/incremental.js';
|
|
74
8
|
|
|
75
9
|
export function translateCommand(program) {
|
|
76
10
|
program
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for incremental translation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Flatten a nested object into dot-notation keys
|
|
7
|
+
* @param {Object} obj - Nested object
|
|
8
|
+
* @param {string} prefix - Key prefix (used for recursion)
|
|
9
|
+
* @returns {Object} Flattened object with dot-notation keys
|
|
10
|
+
*/
|
|
11
|
+
export function flattenObject(obj, prefix = '') {
|
|
12
|
+
const result = {};
|
|
13
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
14
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
15
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
16
|
+
Object.assign(result, flattenObject(value, newKey));
|
|
17
|
+
} else {
|
|
18
|
+
result[newKey] = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Unflatten dot-notation keys back into nested object
|
|
26
|
+
* @param {Object} obj - Flattened object with dot-notation keys
|
|
27
|
+
* @returns {Object} Nested object
|
|
28
|
+
*/
|
|
29
|
+
export function unflattenObject(obj) {
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
32
|
+
const keys = key.split('.');
|
|
33
|
+
let current = result;
|
|
34
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
35
|
+
if (!current[keys[i]]) {
|
|
36
|
+
current[keys[i]] = {};
|
|
37
|
+
}
|
|
38
|
+
current = current[keys[i]];
|
|
39
|
+
}
|
|
40
|
+
current[keys[keys.length - 1]] = value;
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Deep merge two objects
|
|
47
|
+
* @param {Object} target - Target object
|
|
48
|
+
* @param {Object} source - Source object to merge in
|
|
49
|
+
* @returns {Object} Merged object
|
|
50
|
+
*/
|
|
51
|
+
export function deepMerge(target, source) {
|
|
52
|
+
const result = { ...target };
|
|
53
|
+
for (const [key, value] of Object.entries(source)) {
|
|
54
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
55
|
+
result[key] = deepMerge(result[key] || {}, value);
|
|
56
|
+
} else {
|
|
57
|
+
result[key] = value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Find keys that exist in source but not in target
|
|
65
|
+
* @param {Object} sourceJson - Source JSON object
|
|
66
|
+
* @param {Object} targetJson - Target JSON object
|
|
67
|
+
* @returns {Object} Object containing only missing keys
|
|
68
|
+
*/
|
|
69
|
+
export function findMissingKeys(sourceJson, targetJson) {
|
|
70
|
+
const sourceFlat = flattenObject(sourceJson);
|
|
71
|
+
const targetFlat = flattenObject(targetJson);
|
|
72
|
+
|
|
73
|
+
const missingKeys = {};
|
|
74
|
+
for (const [key, value] of Object.entries(sourceFlat)) {
|
|
75
|
+
if (!(key in targetFlat)) {
|
|
76
|
+
missingKeys[key] = value;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return unflattenObject(missingKeys);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Count the number of leaf keys in a nested object
|
|
85
|
+
* @param {Object} obj - Object to count keys in
|
|
86
|
+
* @returns {number} Number of leaf keys
|
|
87
|
+
*/
|
|
88
|
+
export function countKeys(obj) {
|
|
89
|
+
return Object.keys(flattenObject(obj)).length;
|
|
90
|
+
}
|