@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipi18n/cli",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Command-line tool for translating locale files with Shipi18n",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -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
+ }