@langapi/mcp-server 1.0.7 → 1.1.0

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.
Files changed (56) hide show
  1. package/dist/handlers/index.d.ts +7 -0
  2. package/dist/handlers/index.d.ts.map +1 -0
  3. package/dist/handlers/index.js +7 -0
  4. package/dist/handlers/index.js.map +1 -0
  5. package/dist/handlers/xcstrings-sync-handler.d.ts +72 -0
  6. package/dist/handlers/xcstrings-sync-handler.d.ts.map +1 -0
  7. package/dist/handlers/xcstrings-sync-handler.js +126 -0
  8. package/dist/handlers/xcstrings-sync-handler.js.map +1 -0
  9. package/dist/locale-detection/index.d.ts.map +1 -1
  10. package/dist/locale-detection/index.js +68 -4
  11. package/dist/locale-detection/index.js.map +1 -1
  12. package/dist/locale-detection/patterns.d.ts.map +1 -1
  13. package/dist/locale-detection/patterns.js +30 -0
  14. package/dist/locale-detection/patterns.js.map +1 -1
  15. package/dist/tools/get-translation-status.d.ts.map +1 -1
  16. package/dist/tools/get-translation-status.js +34 -6
  17. package/dist/tools/get-translation-status.js.map +1 -1
  18. package/dist/tools/list-local-locales.d.ts +1 -1
  19. package/dist/tools/list-local-locales.js +2 -2
  20. package/dist/tools/list-local-locales.js.map +1 -1
  21. package/dist/tools/sync-translations.d.ts.map +1 -1
  22. package/dist/tools/sync-translations.js +199 -40
  23. package/dist/tools/sync-translations.js.map +1 -1
  24. package/dist/utils/apple-common.d.ts +63 -0
  25. package/dist/utils/apple-common.d.ts.map +1 -0
  26. package/dist/utils/apple-common.js +118 -0
  27. package/dist/utils/apple-common.js.map +1 -0
  28. package/dist/utils/apple-common.test.d.ts +2 -0
  29. package/dist/utils/apple-common.test.d.ts.map +1 -0
  30. package/dist/utils/apple-common.test.js +108 -0
  31. package/dist/utils/apple-common.test.js.map +1 -0
  32. package/dist/utils/strings-parser.d.ts +62 -0
  33. package/dist/utils/strings-parser.d.ts.map +1 -0
  34. package/dist/utils/strings-parser.js +276 -0
  35. package/dist/utils/strings-parser.js.map +1 -0
  36. package/dist/utils/strings-parser.test.d.ts +2 -0
  37. package/dist/utils/strings-parser.test.d.ts.map +1 -0
  38. package/dist/utils/strings-parser.test.js +143 -0
  39. package/dist/utils/strings-parser.test.js.map +1 -0
  40. package/dist/utils/stringsdict-parser.d.ts +106 -0
  41. package/dist/utils/stringsdict-parser.d.ts.map +1 -0
  42. package/dist/utils/stringsdict-parser.js +473 -0
  43. package/dist/utils/stringsdict-parser.js.map +1 -0
  44. package/dist/utils/stringsdict-parser.test.d.ts +2 -0
  45. package/dist/utils/stringsdict-parser.test.d.ts.map +1 -0
  46. package/dist/utils/stringsdict-parser.test.js +244 -0
  47. package/dist/utils/stringsdict-parser.test.js.map +1 -0
  48. package/dist/utils/xcstrings-parser.d.ts +128 -0
  49. package/dist/utils/xcstrings-parser.d.ts.map +1 -0
  50. package/dist/utils/xcstrings-parser.js +216 -0
  51. package/dist/utils/xcstrings-parser.js.map +1 -0
  52. package/dist/utils/xcstrings-parser.test.d.ts +2 -0
  53. package/dist/utils/xcstrings-parser.test.d.ts.map +1 -0
  54. package/dist/utils/xcstrings-parser.test.js +157 -0
  55. package/dist/utils/xcstrings-parser.test.js.map +1 -0
  56. package/package.json +1 -1
@@ -0,0 +1,244 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { parseStringsDictContent, flattenStringsDictForApi, unflattenStringsDictFromApi, reconstructStringsDictContent, mergeStringsDictContent, } from "./stringsdict-parser.js";
3
+ describe("Stringsdict Parser", () => {
4
+ const sampleXml = `<?xml version="1.0" encoding="UTF-8"?>
5
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
6
+ <plist version="1.0">
7
+ <dict>
8
+ <key>items_count</key>
9
+ <dict>
10
+ <key>NSStringLocalizedFormatKey</key>
11
+ <string>%#@count@</string>
12
+ <key>count</key>
13
+ <dict>
14
+ <key>NSStringFormatSpecTypeKey</key>
15
+ <string>NSStringPluralRuleType</string>
16
+ <key>one</key>
17
+ <string>%d item</string>
18
+ <key>other</key>
19
+ <string>%d items</string>
20
+ </dict>
21
+ </dict>
22
+ </dict>
23
+ </plist>`;
24
+ describe("parseStringsDictContent", () => {
25
+ it("should parse plural rules", () => {
26
+ const result = parseStringsDictContent(sampleXml);
27
+ expect(result).not.toBeNull();
28
+ expect(result.entries).toHaveLength(1);
29
+ expect(result.entries[0].key).toBe("items_count");
30
+ });
31
+ it("should extract NSStringLocalizedFormatKey", () => {
32
+ const result = parseStringsDictContent(sampleXml);
33
+ expect(result.entries[0].formatKey).toBe("%#@count@");
34
+ });
35
+ it("should handle multiple plural variants", () => {
36
+ const result = parseStringsDictContent(sampleXml);
37
+ const entry = result.entries[0];
38
+ const rule = entry.pluralRules["count"];
39
+ expect(rule.variants.one).toBe("%d item");
40
+ expect(rule.variants.other).toBe("%d items");
41
+ });
42
+ it("should parse nested dict structure", () => {
43
+ const result = parseStringsDictContent(sampleXml);
44
+ const entry = result.entries[0];
45
+ expect(entry.pluralRules["count"]).toBeDefined();
46
+ expect(entry.pluralRules["count"].specTypeKey).toBe("NSStringPluralRuleType");
47
+ });
48
+ it("should return null for invalid XML", () => {
49
+ const result = parseStringsDictContent("invalid xml");
50
+ expect(result).toBeNull();
51
+ });
52
+ it("should handle empty plist", () => {
53
+ const emptyXml = `<?xml version="1.0" encoding="UTF-8"?>
54
+ <plist version="1.0">
55
+ <dict>
56
+ </dict>
57
+ </plist>`;
58
+ const result = parseStringsDictContent(emptyXml);
59
+ expect(result).not.toBeNull();
60
+ expect(result.entries).toHaveLength(0);
61
+ });
62
+ });
63
+ describe("flattenStringsDictForApi", () => {
64
+ it("should flatten plural entries with dot notation", () => {
65
+ const entries = [
66
+ {
67
+ key: "items_count",
68
+ formatKey: "%#@count@",
69
+ pluralRules: {
70
+ count: {
71
+ specTypeKey: "NSStringPluralRuleType",
72
+ variants: {
73
+ one: "%d item",
74
+ other: "%d items",
75
+ },
76
+ },
77
+ },
78
+ },
79
+ ];
80
+ const result = flattenStringsDictForApi(entries);
81
+ expect(result).toContainEqual({
82
+ key: "items_count.count.one",
83
+ value: "%d item",
84
+ });
85
+ expect(result).toContainEqual({
86
+ key: "items_count.count.other",
87
+ value: "%d items",
88
+ });
89
+ });
90
+ it("should include format key", () => {
91
+ const entries = [
92
+ {
93
+ key: "test",
94
+ formatKey: "%#@var@",
95
+ pluralRules: {},
96
+ },
97
+ ];
98
+ const result = flattenStringsDictForApi(entries);
99
+ expect(result).toContainEqual({
100
+ key: "test.__formatKey",
101
+ value: "%#@var@",
102
+ });
103
+ });
104
+ });
105
+ describe("unflattenStringsDictFromApi", () => {
106
+ it("should reconstruct plural structure", () => {
107
+ const translations = [
108
+ { key: "items_count.count.one", value: "%d Artikel" },
109
+ { key: "items_count.count.other", value: "%d Artikel" },
110
+ ];
111
+ const sourceEntries = [
112
+ {
113
+ key: "items_count",
114
+ formatKey: "%#@count@",
115
+ pluralRules: {
116
+ count: {
117
+ specTypeKey: "NSStringPluralRuleType",
118
+ variants: { one: "%d item", other: "%d items" },
119
+ },
120
+ },
121
+ },
122
+ ];
123
+ const result = unflattenStringsDictFromApi(translations, sourceEntries);
124
+ expect(result[0].pluralRules.count.variants.one).toBe("%d Artikel");
125
+ expect(result[0].pluralRules.count.variants.other).toBe("%d Artikel");
126
+ });
127
+ it("should handle missing variants", () => {
128
+ const translations = [
129
+ { key: "items_count.count.one", value: "%d Artikel" },
130
+ // 'other' is missing
131
+ ];
132
+ const sourceEntries = [
133
+ {
134
+ key: "items_count",
135
+ formatKey: "%#@count@",
136
+ pluralRules: {
137
+ count: {
138
+ specTypeKey: "NSStringPluralRuleType",
139
+ variants: { one: "%d item", other: "%d items" },
140
+ },
141
+ },
142
+ },
143
+ ];
144
+ const result = unflattenStringsDictFromApi(translations, sourceEntries);
145
+ expect(result[0].pluralRules.count.variants.one).toBe("%d Artikel");
146
+ expect(result[0].pluralRules.count.variants.other).toBe("%d items"); // Kept from source
147
+ });
148
+ });
149
+ describe("reconstructStringsDictContent", () => {
150
+ it("should generate valid XML plist", () => {
151
+ const entries = [
152
+ {
153
+ key: "items_count",
154
+ formatKey: "%#@count@",
155
+ pluralRules: {
156
+ count: {
157
+ specTypeKey: "NSStringPluralRuleType",
158
+ variants: { one: "%d item", other: "%d items" },
159
+ },
160
+ },
161
+ },
162
+ ];
163
+ const result = reconstructStringsDictContent(entries);
164
+ expect(result).toContain('<?xml version="1.0"');
165
+ expect(result).toContain("<plist version=\"1.0\">");
166
+ expect(result).toContain("<key>items_count</key>");
167
+ expect(result).toContain("<key>NSStringLocalizedFormatKey</key>");
168
+ expect(result).toContain("<string>%#@count@</string>");
169
+ });
170
+ it("should maintain proper element order", () => {
171
+ const entries = [
172
+ {
173
+ key: "test",
174
+ formatKey: "%#@var@",
175
+ pluralRules: {
176
+ var: {
177
+ specTypeKey: "NSStringPluralRuleType",
178
+ variants: { zero: "none", one: "one", other: "many" },
179
+ },
180
+ },
181
+ },
182
+ ];
183
+ const result = reconstructStringsDictContent(entries);
184
+ // Variants should be in consistent order
185
+ const zeroIndex = result.indexOf("<key>zero</key>");
186
+ const oneIndex = result.indexOf("<key>one</key>");
187
+ const otherIndex = result.indexOf("<key>other</key>");
188
+ expect(zeroIndex).toBeLessThan(oneIndex);
189
+ expect(oneIndex).toBeLessThan(otherIndex);
190
+ });
191
+ it("should have trailing newline", () => {
192
+ const entries = [];
193
+ const result = reconstructStringsDictContent(entries);
194
+ expect(result.endsWith("\n")).toBe(true);
195
+ });
196
+ });
197
+ describe("mergeStringsDictContent", () => {
198
+ it("should merge new translations", () => {
199
+ const existing = sampleXml;
200
+ const newTranslations = [
201
+ { key: "items_count.count.one", value: "%d Artikel" },
202
+ { key: "items_count.count.other", value: "%d Artikel" },
203
+ ];
204
+ const sourceEntries = [
205
+ {
206
+ key: "items_count",
207
+ formatKey: "%#@count@",
208
+ pluralRules: {
209
+ count: {
210
+ specTypeKey: "NSStringPluralRuleType",
211
+ variants: { one: "%d item", other: "%d items" },
212
+ },
213
+ },
214
+ },
215
+ ];
216
+ const sourceKeys = new Set(["items_count"]);
217
+ const result = mergeStringsDictContent(existing, newTranslations, sourceEntries, sourceKeys);
218
+ expect(result).toContain("%d Artikel");
219
+ });
220
+ it("should handle empty existing content", () => {
221
+ const newTranslations = [
222
+ { key: "items_count.count.one", value: "%d élément" },
223
+ { key: "items_count.count.other", value: "%d éléments" },
224
+ ];
225
+ const sourceEntries = [
226
+ {
227
+ key: "items_count",
228
+ formatKey: "%#@count@",
229
+ pluralRules: {
230
+ count: {
231
+ specTypeKey: "NSStringPluralRuleType",
232
+ variants: { one: "%d item", other: "%d items" },
233
+ },
234
+ },
235
+ },
236
+ ];
237
+ const sourceKeys = new Set(["items_count"]);
238
+ const result = mergeStringsDictContent("", newTranslations, sourceEntries, sourceKeys);
239
+ expect(result).toContain("%d élément");
240
+ expect(result).toContain("%d éléments");
241
+ });
242
+ });
243
+ });
244
+ //# sourceMappingURL=stringsdict-parser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringsdict-parser.test.js","sourceRoot":"","sources":["../../src/utils/stringsdict-parser.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * String Catalog (.xcstrings) file parser
3
+ *
4
+ * String Catalogs are JSON-based localization files introduced in Xcode 15.
5
+ * Key characteristics:
6
+ * - Single file contains ALL languages
7
+ * - JSON structure with sourceLanguage, version, and strings
8
+ * - Each string entry can have localizations for multiple languages
9
+ * - Supports metadata like extractionState and comments
10
+ */
11
+ import type { KeyValue } from "../api/types.js";
12
+ /**
13
+ * String unit state - translation status
14
+ */
15
+ export type StringUnitState = "translated" | "needs_review" | "new" | "stale";
16
+ /**
17
+ * String unit - the actual translated value
18
+ */
19
+ export interface StringUnit {
20
+ state: StringUnitState;
21
+ value: string;
22
+ }
23
+ /**
24
+ * Localization entry for a specific language
25
+ */
26
+ export interface XCLocalization {
27
+ stringUnit?: StringUnit;
28
+ /** Variations for plurals, device-specific strings, etc. */
29
+ variations?: Record<string, unknown>;
30
+ }
31
+ /**
32
+ * Entry for a single string key
33
+ */
34
+ export interface XCStringEntry {
35
+ /** Manual, migrated, stale, etc. */
36
+ extractionState?: string;
37
+ /** Developer comment/description */
38
+ comment?: string;
39
+ /** Localizations keyed by language code */
40
+ localizations?: Record<string, XCLocalization>;
41
+ }
42
+ /**
43
+ * Root structure of an .xcstrings file
44
+ */
45
+ export interface XCStringsFile {
46
+ sourceLanguage: string;
47
+ version: string;
48
+ strings: Record<string, XCStringEntry>;
49
+ }
50
+ /**
51
+ * Parsed content from an .xcstrings file
52
+ */
53
+ export interface XCStringsContent {
54
+ /** Source language code */
55
+ sourceLanguage: string;
56
+ /** File format version */
57
+ version: string;
58
+ /** Translation entries for source language */
59
+ entries: KeyValue[];
60
+ /** All localizations by language */
61
+ allLocalizations: Map<string, KeyValue[]>;
62
+ /** Full parsed structure for preservation */
63
+ metadata: XCStringsFile;
64
+ }
65
+ /**
66
+ * Parse an .xcstrings file content
67
+ *
68
+ * @param content Raw JSON content
69
+ * @returns Parsed content or null if invalid
70
+ */
71
+ export declare function parseXCStringsContent(content: string): XCStringsContent | null;
72
+ /**
73
+ * Extract translations for a specific locale from an .xcstrings file
74
+ *
75
+ * @param xcstrings Parsed xcstrings data
76
+ * @param locale Language code to extract
77
+ * @returns Array of key-value pairs for the locale
78
+ */
79
+ export declare function extractLocaleFromXCStrings(xcstrings: XCStringsFile, locale: string): KeyValue[];
80
+ /**
81
+ * Get all language codes present in an .xcstrings file
82
+ *
83
+ * @param xcstrings Parsed xcstrings data
84
+ * @returns Set of language codes
85
+ */
86
+ export declare function getXCStringsLanguages(xcstrings: XCStringsFile): Set<string>;
87
+ /**
88
+ * Update a specific locale's translations in an .xcstrings file
89
+ *
90
+ * This adds or updates translations for a single language without
91
+ * affecting other languages in the file.
92
+ *
93
+ * @param xcstrings Original xcstrings data
94
+ * @param locale Target language code
95
+ * @param translations New translations for the locale
96
+ * @returns Updated xcstrings data
97
+ */
98
+ export declare function updateXCStringsLocale(xcstrings: XCStringsFile, locale: string, translations: KeyValue[]): XCStringsFile;
99
+ /**
100
+ * Merge new translations into an .xcstrings file for a specific locale
101
+ *
102
+ * - Preserves existing translations for the locale that aren't updated
103
+ * - Preserves all other languages completely
104
+ * - Removes keys that no longer exist in source
105
+ * - Updates state to "translated" for new translations
106
+ *
107
+ * @param existing Existing xcstrings data
108
+ * @param locale Target language code
109
+ * @param newTranslations New/updated translations
110
+ * @param sourceKeys Set of all keys in source language
111
+ * @returns Merged xcstrings data
112
+ */
113
+ export declare function mergeXCStringsContent(existing: XCStringsFile, locale: string, newTranslations: KeyValue[], sourceKeys: Set<string>): XCStringsFile;
114
+ /**
115
+ * Reconstruct .xcstrings JSON content with proper formatting
116
+ *
117
+ * @param xcstrings XCStrings data to serialize
118
+ * @returns Formatted JSON string
119
+ */
120
+ export declare function reconstructXCStringsContent(xcstrings: XCStringsFile): string;
121
+ /**
122
+ * Create a new empty .xcstrings structure
123
+ *
124
+ * @param sourceLanguage Source language code
125
+ * @returns New empty xcstrings structure
126
+ */
127
+ export declare function createEmptyXCStrings(sourceLanguage: string): XCStringsFile;
128
+ //# sourceMappingURL=xcstrings-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcstrings-parser.d.ts","sourceRoot":"","sources":["../../src/utils/xcstrings-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,cAAc,GAAG,KAAK,GAAG,OAAO,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,oCAAoC;IACpC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1C,6CAA6C;IAC7C,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA2D9E;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,MAAM,GACb,QAAQ,EAAE,CAWZ;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,CAY3E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,QAAQ,EAAE,GACvB,aAAa,CA8Bf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,QAAQ,EAAE,EAC3B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,aAAa,CA2Cf;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAG5E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CAM1E"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * String Catalog (.xcstrings) file parser
3
+ *
4
+ * String Catalogs are JSON-based localization files introduced in Xcode 15.
5
+ * Key characteristics:
6
+ * - Single file contains ALL languages
7
+ * - JSON structure with sourceLanguage, version, and strings
8
+ * - Each string entry can have localizations for multiple languages
9
+ * - Supports metadata like extractionState and comments
10
+ */
11
+ /**
12
+ * Parse an .xcstrings file content
13
+ *
14
+ * @param content Raw JSON content
15
+ * @returns Parsed content or null if invalid
16
+ */
17
+ export function parseXCStringsContent(content) {
18
+ try {
19
+ const data = JSON.parse(content);
20
+ if (!data.sourceLanguage || !data.strings) {
21
+ return null;
22
+ }
23
+ const sourceLanguage = data.sourceLanguage;
24
+ const version = data.version || "1.0";
25
+ const entries = [];
26
+ const allLocalizations = new Map();
27
+ // Extract all languages and their translations
28
+ const languages = new Set();
29
+ for (const [key, entry] of Object.entries(data.strings)) {
30
+ if (entry.localizations) {
31
+ for (const lang of Object.keys(entry.localizations)) {
32
+ languages.add(lang);
33
+ }
34
+ }
35
+ }
36
+ // Initialize language maps
37
+ for (const lang of languages) {
38
+ allLocalizations.set(lang, []);
39
+ }
40
+ // Extract translations for each key
41
+ for (const [key, entry] of Object.entries(data.strings)) {
42
+ const localizations = entry.localizations || {};
43
+ // Get source language translation for entries
44
+ const sourceLocalization = localizations[sourceLanguage];
45
+ if (sourceLocalization?.stringUnit?.value) {
46
+ entries.push({ key, value: sourceLocalization.stringUnit.value });
47
+ }
48
+ // Extract all localizations
49
+ for (const [lang, localization] of Object.entries(localizations)) {
50
+ if (localization.stringUnit?.value) {
51
+ const langEntries = allLocalizations.get(lang) || [];
52
+ langEntries.push({ key, value: localization.stringUnit.value });
53
+ allLocalizations.set(lang, langEntries);
54
+ }
55
+ }
56
+ }
57
+ return {
58
+ sourceLanguage,
59
+ version,
60
+ entries,
61
+ allLocalizations,
62
+ metadata: data,
63
+ };
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ /**
70
+ * Extract translations for a specific locale from an .xcstrings file
71
+ *
72
+ * @param xcstrings Parsed xcstrings data
73
+ * @param locale Language code to extract
74
+ * @returns Array of key-value pairs for the locale
75
+ */
76
+ export function extractLocaleFromXCStrings(xcstrings, locale) {
77
+ const entries = [];
78
+ for (const [key, entry] of Object.entries(xcstrings.strings)) {
79
+ const localization = entry.localizations?.[locale];
80
+ if (localization?.stringUnit?.value) {
81
+ entries.push({ key, value: localization.stringUnit.value });
82
+ }
83
+ }
84
+ return entries;
85
+ }
86
+ /**
87
+ * Get all language codes present in an .xcstrings file
88
+ *
89
+ * @param xcstrings Parsed xcstrings data
90
+ * @returns Set of language codes
91
+ */
92
+ export function getXCStringsLanguages(xcstrings) {
93
+ const languages = new Set();
94
+ for (const entry of Object.values(xcstrings.strings)) {
95
+ if (entry.localizations) {
96
+ for (const lang of Object.keys(entry.localizations)) {
97
+ languages.add(lang);
98
+ }
99
+ }
100
+ }
101
+ return languages;
102
+ }
103
+ /**
104
+ * Update a specific locale's translations in an .xcstrings file
105
+ *
106
+ * This adds or updates translations for a single language without
107
+ * affecting other languages in the file.
108
+ *
109
+ * @param xcstrings Original xcstrings data
110
+ * @param locale Target language code
111
+ * @param translations New translations for the locale
112
+ * @returns Updated xcstrings data
113
+ */
114
+ export function updateXCStringsLocale(xcstrings, locale, translations) {
115
+ // Deep clone to avoid mutating original
116
+ const result = JSON.parse(JSON.stringify(xcstrings));
117
+ // Create a map for quick lookup
118
+ const translationsMap = new Map();
119
+ for (const { key, value } of translations) {
120
+ translationsMap.set(key, value);
121
+ }
122
+ // Update each string entry
123
+ for (const [key, entry] of Object.entries(result.strings)) {
124
+ const translation = translationsMap.get(key);
125
+ if (translation !== undefined) {
126
+ // Ensure localizations object exists
127
+ if (!entry.localizations) {
128
+ entry.localizations = {};
129
+ }
130
+ // Add or update the locale
131
+ entry.localizations[locale] = {
132
+ stringUnit: {
133
+ state: "translated",
134
+ value: translation,
135
+ },
136
+ };
137
+ }
138
+ }
139
+ return result;
140
+ }
141
+ /**
142
+ * Merge new translations into an .xcstrings file for a specific locale
143
+ *
144
+ * - Preserves existing translations for the locale that aren't updated
145
+ * - Preserves all other languages completely
146
+ * - Removes keys that no longer exist in source
147
+ * - Updates state to "translated" for new translations
148
+ *
149
+ * @param existing Existing xcstrings data
150
+ * @param locale Target language code
151
+ * @param newTranslations New/updated translations
152
+ * @param sourceKeys Set of all keys in source language
153
+ * @returns Merged xcstrings data
154
+ */
155
+ export function mergeXCStringsContent(existing, locale, newTranslations, sourceKeys) {
156
+ // Deep clone to avoid mutating original
157
+ const result = JSON.parse(JSON.stringify(existing));
158
+ // Create a map for quick lookup
159
+ const newTranslationsMap = new Map();
160
+ for (const { key, value } of newTranslations) {
161
+ newTranslationsMap.set(key, value);
162
+ }
163
+ // Remove keys that don't exist in source
164
+ for (const key of Object.keys(result.strings)) {
165
+ if (!sourceKeys.has(key)) {
166
+ delete result.strings[key];
167
+ }
168
+ }
169
+ // Update translations for the target locale
170
+ for (const key of sourceKeys) {
171
+ const entry = result.strings[key];
172
+ if (!entry)
173
+ continue;
174
+ // Get new translation if available
175
+ const newTranslation = newTranslationsMap.get(key);
176
+ if (newTranslation !== undefined) {
177
+ // Ensure localizations object exists
178
+ if (!entry.localizations) {
179
+ entry.localizations = {};
180
+ }
181
+ // Add or update the locale
182
+ entry.localizations[locale] = {
183
+ stringUnit: {
184
+ state: "translated",
185
+ value: newTranslation,
186
+ },
187
+ };
188
+ }
189
+ // If no new translation, preserve existing (already in the cloned data)
190
+ }
191
+ return result;
192
+ }
193
+ /**
194
+ * Reconstruct .xcstrings JSON content with proper formatting
195
+ *
196
+ * @param xcstrings XCStrings data to serialize
197
+ * @returns Formatted JSON string
198
+ */
199
+ export function reconstructXCStringsContent(xcstrings) {
200
+ // Xcode uses 2-space indentation
201
+ return JSON.stringify(xcstrings, null, 2) + "\n";
202
+ }
203
+ /**
204
+ * Create a new empty .xcstrings structure
205
+ *
206
+ * @param sourceLanguage Source language code
207
+ * @returns New empty xcstrings structure
208
+ */
209
+ export function createEmptyXCStrings(sourceLanguage) {
210
+ return {
211
+ sourceLanguage,
212
+ version: "1.0",
213
+ strings: {},
214
+ };
215
+ }
216
+ //# sourceMappingURL=xcstrings-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcstrings-parser.js","sourceRoot":"","sources":["../../src/utils/xcstrings-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=xcstrings-parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcstrings-parser.test.d.ts","sourceRoot":"","sources":["../../src/utils/xcstrings-parser.test.ts"],"names":[],"mappings":""}