xcstrings-cli 1.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,659 @@
1
+ #!/usr/bin/env node
2
+ import we from "yargs";
3
+ import { hideBin as ve } from "yargs/helpers";
4
+ import { readFile as je, writeFile as ie, readdir as ae } from "node:fs/promises";
5
+ import { relative as X, resolve as D } from "node:path";
6
+ import d from "chalk";
7
+ import { checkbox as te, confirm as Oe, select as xe } from "@inquirer/prompts";
8
+ import { XcodeProject as Se } from "@bacons/xcode";
9
+ import { cosmiconfig as ke } from "cosmiconfig";
10
+ import ze from "json5";
11
+ async function U(t) {
12
+ const r = await je(t, "utf-8");
13
+ return JSON.parse(r);
14
+ }
15
+ async function ce(t, r) {
16
+ const n = JSON.stringify(r, null, 2), s = Ee(n);
17
+ await ie(t, s + `
18
+ `, "utf-8");
19
+ }
20
+ function Ee(t) {
21
+ let r = "", n = !1, s = !1;
22
+ for (let c = 0; c < t.length; c++) {
23
+ const l = t[c];
24
+ if (n && l === "\\" && !s) {
25
+ s = !0, r += l;
26
+ continue;
27
+ }
28
+ if (s) {
29
+ s = !1, r += l;
30
+ continue;
31
+ }
32
+ if (l === '"') {
33
+ n = !n, r += l;
34
+ continue;
35
+ }
36
+ if (!n && l === ":") {
37
+ r += " :";
38
+ continue;
39
+ }
40
+ r += l;
41
+ }
42
+ return r;
43
+ }
44
+ async function _e(t, r, n, s) {
45
+ const c = await U(t);
46
+ c.strings || (c.strings = {});
47
+ const l = {
48
+ ...c.strings[r],
49
+ extractionState: "manual"
50
+ };
51
+ if (n && (l.comment = n), s) {
52
+ l.localizations = l.localizations || {};
53
+ for (const [x, z] of Object.entries(s))
54
+ l.localizations[x] = {
55
+ stringUnit: {
56
+ state: "translated",
57
+ value: z
58
+ }
59
+ };
60
+ }
61
+ c.strings[r] = l, await ce(t, c);
62
+ }
63
+ async function Le(t, r) {
64
+ const n = await U(t);
65
+ n.strings && n.strings[r] && (delete n.strings[r], await ce(t, n));
66
+ }
67
+ const I = "xcstrings-cli.json5";
68
+ async function Pe(t) {
69
+ const r = [];
70
+ async function n(s) {
71
+ try {
72
+ const c = await ae(s, { withFileTypes: !0 });
73
+ for (const l of c) {
74
+ const x = D(s, l.name);
75
+ l.isDirectory() ? !l.name.startsWith(".") && l.name !== "node_modules" && await n(x) : l.name.endsWith(".xcstrings") && r.push(x);
76
+ }
77
+ } catch {
78
+ }
79
+ }
80
+ return await n(t), r;
81
+ }
82
+ async function Fe(t) {
83
+ const r = [];
84
+ let n = t;
85
+ try {
86
+ const s = await ae(n, { withFileTypes: !0 });
87
+ for (const c of s)
88
+ c.isDirectory() && c.name.endsWith(".xcodeproj") && r.push(D(n, c.name));
89
+ } catch {
90
+ }
91
+ return r;
92
+ }
93
+ async function Ce() {
94
+ const t = process.cwd();
95
+ console.log(), console.log(d.bold.cyan("🚀 xcstrings-cli Configuration Setup")), console.log(d.dim("─".repeat(40))), console.log(), console.log(d.yellow("🔍 Searching for .xcstrings files..."));
96
+ const r = await Pe(t);
97
+ console.log(d.yellow("🔍 Searching for .xcodeproj directories..."));
98
+ const n = await Fe(t);
99
+ console.log();
100
+ let s = [];
101
+ if (r.length > 0) {
102
+ console.log(d.green(`✓ Found ${r.length} .xcstrings file(s)`));
103
+ const b = r.map((h) => ({
104
+ name: d.white(X(t, h)) + d.dim(` (${h})`),
105
+ value: X(t, h),
106
+ checked: !0
107
+ }));
108
+ s = await te({
109
+ message: d.bold("Select .xcstrings files to manage:"),
110
+ choices: b
111
+ });
112
+ } else
113
+ console.log(d.dim(" No .xcstrings files found in current directory"));
114
+ console.log();
115
+ let c = [];
116
+ if (n.length > 0) {
117
+ console.log(d.green(`✓ Found ${n.length} .xcodeproj director${n.length === 1 ? "y" : "ies"}`));
118
+ const b = n.map((h) => ({
119
+ name: d.white(X(t, h) || h) + d.dim(` (${h})`),
120
+ value: X(t, h) || h,
121
+ checked: !0
122
+ }));
123
+ c = await te({
124
+ message: d.bold("Select .xcodeproj directories for language detection:"),
125
+ choices: b
126
+ });
127
+ } else
128
+ console.log(d.dim(" No .xcodeproj directories found"));
129
+ if (console.log(), console.log(d.dim("─".repeat(40))), console.log(), console.log(d.bold("📋 Configuration Summary:")), console.log(), console.log(d.cyan(" xcstringsPaths:")), s.length > 0 ? s.forEach((b) => console.log(d.white(` • ${b}`))) : console.log(d.dim(" (none)")), console.log(), console.log(d.cyan(" xcodeprojPaths:")), c.length > 0 ? c.forEach((b) => console.log(d.white(` • ${b}`))) : console.log(d.dim(" (none)")), console.log(), !await Oe({
130
+ message: d.bold(`Create ${d.yellow(I)}?`),
131
+ default: !0
132
+ })) {
133
+ console.log(d.dim(" Configuration cancelled."));
134
+ return;
135
+ }
136
+ const x = s.map((b) => ` "${b}"`).join(`,
137
+ `), z = c.map((b) => ` "${b}"`).join(`,
138
+ `), _ = `{
139
+ // Array of paths to .xcstrings files to manage. Specify relative or absolute paths.
140
+ xcstringsPaths: [
141
+ ${x}
142
+ ],
143
+ // Array of paths to .xcodeproj directories. Used for discovering supported languages.
144
+ xcodeprojPaths: [
145
+ ${z}
146
+ ]
147
+ }
148
+ `;
149
+ await ie(I, _, "utf-8"), console.log(), console.log(d.bold.green(`✓ Created ${I}`)), console.log(d.dim(` Run ${d.cyan("xcstrings --help")} to see available commands.`)), console.log();
150
+ }
151
+ const M = "xcstrings-cli", ne = ke(M, {
152
+ searchPlaces: [
153
+ `${M}.json`,
154
+ `${M}.json5`
155
+ ],
156
+ loaders: {
157
+ ".json5": async (t, r) => ze.parse(r)
158
+ },
159
+ cache: !1
160
+ });
161
+ async function le(t) {
162
+ if (t) {
163
+ const n = await ne.load(t);
164
+ return n ? n.config : null;
165
+ }
166
+ const r = await ne.search();
167
+ return r ? r.config : null;
168
+ }
169
+ function Te(t) {
170
+ const r = D(t, "project.pbxproj");
171
+ return Se.open(r).rootObject.props.knownRegions ?? [];
172
+ }
173
+ async function $e(t) {
174
+ const r = await U(t), n = /* @__PURE__ */ new Set();
175
+ for (const s of Object.keys(r.strings)) {
176
+ const c = r.strings[s];
177
+ if (c.localizations)
178
+ for (const l of Object.keys(c.localizations))
179
+ n.add(l);
180
+ }
181
+ return Array.from(n).sort();
182
+ }
183
+ async function Ae(t, r) {
184
+ const n = await le(r);
185
+ if (n?.xcodeprojPaths && n.xcodeprojPaths.length > 0) {
186
+ const s = /* @__PURE__ */ new Set();
187
+ for (const c of n.xcodeprojPaths)
188
+ Te(c).forEach((x) => s.add(x));
189
+ return Array.from(s).sort();
190
+ }
191
+ return await $e(t);
192
+ }
193
+ function Ne(t) {
194
+ return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
195
+ }
196
+ var C = { exports: {} }, W, re;
197
+ function Ve() {
198
+ if (re) return W;
199
+ re = 1;
200
+ function t(n) {
201
+ try {
202
+ return JSON.stringify(n);
203
+ } catch {
204
+ return '"[Circular]"';
205
+ }
206
+ }
207
+ W = r;
208
+ function r(n, s, c) {
209
+ var l = c && c.stringify || t, x = 1;
210
+ if (typeof n == "object" && n !== null) {
211
+ var z = s.length + x;
212
+ if (z === 1) return n;
213
+ var _ = new Array(z);
214
+ _[0] = l(n);
215
+ for (var b = 1; b < z; b++)
216
+ _[b] = l(s[b]);
217
+ return _.join(" ");
218
+ }
219
+ if (typeof n != "string")
220
+ return n;
221
+ var h = s.length;
222
+ if (h === 0) return n;
223
+ for (var w = "", y = 1 - x, g = -1, k = n && n.length || 0, f = 0; f < k; ) {
224
+ if (n.charCodeAt(f) === 37 && f + 1 < k) {
225
+ switch (g = g > -1 ? g : 0, n.charCodeAt(f + 1)) {
226
+ case 100:
227
+ // 'd'
228
+ case 102:
229
+ if (y >= h || s[y] == null) break;
230
+ g < f && (w += n.slice(g, f)), w += Number(s[y]), g = f + 2, f++;
231
+ break;
232
+ case 105:
233
+ if (y >= h || s[y] == null) break;
234
+ g < f && (w += n.slice(g, f)), w += Math.floor(Number(s[y])), g = f + 2, f++;
235
+ break;
236
+ case 79:
237
+ // 'O'
238
+ case 111:
239
+ // 'o'
240
+ case 106:
241
+ if (y >= h || s[y] === void 0) break;
242
+ g < f && (w += n.slice(g, f));
243
+ var T = typeof s[y];
244
+ if (T === "string") {
245
+ w += "'" + s[y] + "'", g = f + 2, f++;
246
+ break;
247
+ }
248
+ if (T === "function") {
249
+ w += s[y].name || "<anonymous>", g = f + 2, f++;
250
+ break;
251
+ }
252
+ w += l(s[y]), g = f + 2, f++;
253
+ break;
254
+ case 115:
255
+ if (y >= h)
256
+ break;
257
+ g < f && (w += n.slice(g, f)), w += String(s[y]), g = f + 2, f++;
258
+ break;
259
+ case 37:
260
+ g < f && (w += n.slice(g, f)), w += "%", g = f + 2, f++, y--;
261
+ break;
262
+ }
263
+ ++y;
264
+ }
265
+ ++f;
266
+ }
267
+ return g === -1 ? n : (g < k && (w += n.slice(g)), w);
268
+ }
269
+ return W;
270
+ }
271
+ var oe;
272
+ function Xe() {
273
+ if (oe) return C.exports;
274
+ oe = 1;
275
+ const t = Ve();
276
+ C.exports = h;
277
+ const r = pe().console || {}, n = {
278
+ mapHttpRequest: A,
279
+ mapHttpResponse: A,
280
+ wrapRequestSerializer: q,
281
+ wrapResponseSerializer: q,
282
+ wrapErrorSerializer: q,
283
+ req: A,
284
+ res: A,
285
+ err: H,
286
+ errWithCause: H
287
+ };
288
+ function s(e, o) {
289
+ return e === "silent" ? 1 / 0 : o.levels.values[e];
290
+ }
291
+ const c = Symbol("pino.logFuncs"), l = Symbol("pino.hierarchy"), x = {
292
+ error: "log",
293
+ fatal: "error",
294
+ warn: "error",
295
+ info: "log",
296
+ debug: "log",
297
+ trace: "log"
298
+ };
299
+ function z(e, o) {
300
+ const a = {
301
+ logger: o,
302
+ parent: e[l]
303
+ };
304
+ o[l] = a;
305
+ }
306
+ function _(e, o, a) {
307
+ const u = {};
308
+ o.forEach((m) => {
309
+ u[m] = a[m] ? a[m] : r[m] || r[x[m] || "log"] || F;
310
+ }), e[c] = u;
311
+ }
312
+ function b(e, o) {
313
+ return Array.isArray(e) ? e.filter(function(u) {
314
+ return u !== "!stdSerializers.err";
315
+ }) : e === !0 ? Object.keys(o) : !1;
316
+ }
317
+ function h(e) {
318
+ e = e || {}, e.browser = e.browser || {};
319
+ const o = e.browser.transmit;
320
+ if (o && typeof o.send != "function")
321
+ throw Error("pino: transmit option must have a send function");
322
+ const a = e.browser.write || r;
323
+ e.browser.write && (e.browser.asObject = !0);
324
+ const u = e.serializers || {}, m = b(e.browser.serialize, u);
325
+ let j = e.browser.serialize;
326
+ Array.isArray(e.browser.serialize) && e.browser.serialize.indexOf("!stdSerializers.err") > -1 && (j = !1);
327
+ const E = Object.keys(e.customLevels || {}), p = ["error", "fatal", "warn", "info", "debug", "trace"].concat(E);
328
+ typeof a == "function" && p.forEach(function(O) {
329
+ a[O] = a;
330
+ }), (e.enabled === !1 || e.browser.disabled) && (e.level = "silent");
331
+ const v = e.level || "info", i = Object.create(a);
332
+ i.log || (i.log = F), _(i, p, a), z({}, i), Object.defineProperty(i, "levelVal", {
333
+ get: N
334
+ }), Object.defineProperty(i, "level", {
335
+ get: L,
336
+ set: be
337
+ });
338
+ const S = {
339
+ transmit: o,
340
+ serialize: m,
341
+ asObject: e.browser.asObject,
342
+ formatters: e.browser.formatters,
343
+ levels: p,
344
+ timestamp: me(e)
345
+ };
346
+ i.levels = w(e), i.level = v, i.setMaxListeners = i.getMaxListeners = i.emit = i.addListener = i.on = i.prependListener = i.once = i.prependOnceListener = i.removeListener = i.removeAllListeners = i.listeners = i.listenerCount = i.eventNames = i.write = i.flush = F, i.serializers = u, i._serialize = m, i._stdErrSerialize = j, i.child = ye, o && (i._logEvent = R());
347
+ function N() {
348
+ return s(this.level, this);
349
+ }
350
+ function L() {
351
+ return this._level;
352
+ }
353
+ function be(O) {
354
+ if (O !== "silent" && !this.levels.values[O])
355
+ throw Error("unknown level " + O);
356
+ this._level = O, k(this, S, i, "error"), k(this, S, i, "fatal"), k(this, S, i, "warn"), k(this, S, i, "info"), k(this, S, i, "debug"), k(this, S, i, "trace"), E.forEach((P) => {
357
+ k(this, S, i, P);
358
+ });
359
+ }
360
+ function ye(O, P) {
361
+ if (!O)
362
+ throw new Error("missing bindings for child Pino");
363
+ P = P || {}, m && O.serializers && (P.serializers = O.serializers);
364
+ const K = P.serializers;
365
+ if (m && K) {
366
+ var V = Object.assign({}, u, K), Y = e.browser.serialize === !0 ? Object.keys(V) : m;
367
+ delete O.serializers, $([O], Y, V, this._stdErrSerialize);
368
+ }
369
+ function Z(ee) {
370
+ this._childLevel = (ee._childLevel | 0) + 1, this.bindings = O, V && (this.serializers = V, this._serialize = Y), o && (this._logEvent = R(
371
+ [].concat(ee._logEvent.bindings, O)
372
+ ));
373
+ }
374
+ Z.prototype = this;
375
+ const J = new Z(this);
376
+ return z(this, J), J.level = this.level, J;
377
+ }
378
+ return i;
379
+ }
380
+ function w(e) {
381
+ const o = e.customLevels || {}, a = Object.assign({}, h.levels.values, o), u = Object.assign({}, h.levels.labels, y(o));
382
+ return {
383
+ values: a,
384
+ labels: u
385
+ };
386
+ }
387
+ function y(e) {
388
+ const o = {};
389
+ return Object.keys(e).forEach(function(a) {
390
+ o[e[a]] = a;
391
+ }), o;
392
+ }
393
+ h.levels = {
394
+ values: {
395
+ fatal: 60,
396
+ error: 50,
397
+ warn: 40,
398
+ info: 30,
399
+ debug: 20,
400
+ trace: 10
401
+ },
402
+ labels: {
403
+ 10: "trace",
404
+ 20: "debug",
405
+ 30: "info",
406
+ 40: "warn",
407
+ 50: "error",
408
+ 60: "fatal"
409
+ }
410
+ }, h.stdSerializers = n, h.stdTimeFunctions = Object.assign({}, { nullTime: G, epochTime: Q, unixTime: he, isoTime: ge });
411
+ function g(e) {
412
+ const o = [];
413
+ e.bindings && o.push(e.bindings);
414
+ let a = e[l];
415
+ for (; a.parent; )
416
+ a = a.parent, a.logger.bindings && o.push(a.logger.bindings);
417
+ return o.reverse();
418
+ }
419
+ function k(e, o, a, u) {
420
+ if (Object.defineProperty(e, u, {
421
+ value: s(e.level, a) > s(u, a) ? F : a[c][u],
422
+ writable: !0,
423
+ enumerable: !0,
424
+ configurable: !0
425
+ }), !o.transmit && e[u] === F)
426
+ return;
427
+ e[u] = T(e, o, a, u);
428
+ const m = g(e);
429
+ m.length !== 0 && (e[u] = f(m, e[u]));
430
+ }
431
+ function f(e, o) {
432
+ return function() {
433
+ return o.apply(this, [...e, ...arguments]);
434
+ };
435
+ }
436
+ function T(e, o, a, u) {
437
+ return /* @__PURE__ */ (function(m) {
438
+ return function() {
439
+ const E = o.timestamp(), p = new Array(arguments.length), v = Object.getPrototypeOf && Object.getPrototypeOf(this) === r ? r : this;
440
+ for (var i = 0; i < p.length; i++) p[i] = arguments[i];
441
+ if (o.serialize && !o.asObject && $(p, this._serialize, this.serializers, this._stdErrSerialize), o.asObject || o.formatters ? m.call(v, ue(this, u, p, E, o.formatters)) : m.apply(v, p), o.transmit) {
442
+ const S = o.transmit.level || e._level, N = a.levels.values[S], L = a.levels.values[u];
443
+ if (L < N) return;
444
+ de(this, {
445
+ ts: E,
446
+ methodLevel: u,
447
+ methodValue: L,
448
+ transmitValue: a.levels.values[o.transmit.level || e._level],
449
+ send: o.transmit.send,
450
+ val: s(e._level, a)
451
+ }, p);
452
+ }
453
+ };
454
+ })(e[c][u]);
455
+ }
456
+ function ue(e, o, a, u, m = {}) {
457
+ const {
458
+ level: j = () => e.levels.values[o],
459
+ log: E = (L) => L
460
+ } = m;
461
+ e._serialize && $(a, e._serialize, e.serializers, e._stdErrSerialize);
462
+ const p = a.slice();
463
+ let v = p[0];
464
+ const i = {};
465
+ u && (i.time = u), i.level = j(o, e.levels.values[o]);
466
+ let S = (e._childLevel | 0) + 1;
467
+ if (S < 1 && (S = 1), v !== null && typeof v == "object") {
468
+ for (; S-- && typeof p[0] == "object"; )
469
+ Object.assign(i, p.shift());
470
+ v = p.length ? t(p.shift(), p) : void 0;
471
+ } else typeof v == "string" && (v = t(p.shift(), p));
472
+ return v !== void 0 && (i.msg = v), E(i);
473
+ }
474
+ function $(e, o, a, u) {
475
+ for (const m in e)
476
+ if (u && e[m] instanceof Error)
477
+ e[m] = h.stdSerializers.err(e[m]);
478
+ else if (typeof e[m] == "object" && !Array.isArray(e[m]))
479
+ for (const j in e[m])
480
+ o && o.indexOf(j) > -1 && j in a && (e[m][j] = a[j](e[m][j]));
481
+ }
482
+ function de(e, o, a) {
483
+ const u = o.send, m = o.ts, j = o.methodLevel, E = o.methodValue, p = o.val, v = e._logEvent.bindings;
484
+ $(
485
+ a,
486
+ e._serialize || Object.keys(e.serializers),
487
+ e.serializers,
488
+ e._stdErrSerialize === void 0 ? !0 : e._stdErrSerialize
489
+ ), e._logEvent.ts = m, e._logEvent.messages = a.filter(function(i) {
490
+ return v.indexOf(i) === -1;
491
+ }), e._logEvent.level.label = j, e._logEvent.level.value = E, u(j, e._logEvent, p), e._logEvent = R(v);
492
+ }
493
+ function R(e) {
494
+ return {
495
+ ts: 0,
496
+ messages: [],
497
+ bindings: e || [],
498
+ level: { label: "", value: 0 }
499
+ };
500
+ }
501
+ function H(e) {
502
+ const o = {
503
+ type: e.constructor.name,
504
+ msg: e.message,
505
+ stack: e.stack
506
+ };
507
+ for (const a in e)
508
+ o[a] === void 0 && (o[a] = e[a]);
509
+ return o;
510
+ }
511
+ function me(e) {
512
+ return typeof e.timestamp == "function" ? e.timestamp : e.timestamp === !1 ? G : Q;
513
+ }
514
+ function A() {
515
+ return {};
516
+ }
517
+ function q(e) {
518
+ return e;
519
+ }
520
+ function F() {
521
+ }
522
+ function G() {
523
+ return !1;
524
+ }
525
+ function Q() {
526
+ return Date.now();
527
+ }
528
+ function he() {
529
+ return Math.round(Date.now() / 1e3);
530
+ }
531
+ function ge() {
532
+ return new Date(Date.now()).toISOString();
533
+ }
534
+ function pe() {
535
+ function e(o) {
536
+ return typeof o < "u" && o;
537
+ }
538
+ try {
539
+ return typeof globalThis < "u" || Object.defineProperty(Object.prototype, "globalThis", {
540
+ get: function() {
541
+ return delete Object.prototype.globalThis, this.globalThis = this;
542
+ },
543
+ configurable: !0
544
+ }), globalThis;
545
+ } catch {
546
+ return e(self) || e(window) || e(this) || {};
547
+ }
548
+ }
549
+ return C.exports.default = h, C.exports.pino = h, C.exports;
550
+ }
551
+ var De = Xe();
552
+ const Re = /* @__PURE__ */ Ne(De), B = Re({
553
+ level: process.env.LOG_LEVEL || "info"
554
+ });
555
+ async function fe() {
556
+ return new Promise((t) => {
557
+ let r = "";
558
+ process.stdin.setEncoding("utf8"), process.stdin.on("data", (n) => {
559
+ r += n;
560
+ }), process.stdin.on("end", () => {
561
+ t(r);
562
+ }), process.stdin.readableEnded && t("");
563
+ });
564
+ }
565
+ async function qe(t, r = fe) {
566
+ if (t !== void 0) {
567
+ if (t === "") {
568
+ const n = await r();
569
+ return n.trim() ? JSON.parse(n) : void 0;
570
+ }
571
+ if (typeof t == "string")
572
+ return JSON.parse(t);
573
+ if (Array.isArray(t)) {
574
+ const n = {};
575
+ for (const s of t)
576
+ typeof s == "string" && Object.assign(n, JSON.parse(s));
577
+ return n;
578
+ }
579
+ if (typeof t == "boolean" && t === !0) {
580
+ const n = await r();
581
+ return n.trim() ? JSON.parse(n) : void 0;
582
+ }
583
+ }
584
+ }
585
+ async function Je(t, r, n, s, c = fe) {
586
+ const l = await qe(s, c);
587
+ await _e(t, r, n, l);
588
+ }
589
+ const se = D(process.cwd(), "Localizable.xcstrings");
590
+ we(ve(process.argv)).scriptName("xcstrings").usage("$0 <cmd> [args]").option("config", {
591
+ type: "string",
592
+ describe: "Path to config file"
593
+ }).option("path", {
594
+ type: "string",
595
+ describe: "Path to xcstrings file",
596
+ default: se
597
+ }).middleware(async (t) => {
598
+ if (t.path !== se)
599
+ return;
600
+ const r = await le(t.config);
601
+ if (!(!r || !r.xcstringsPaths || r.xcstringsPaths.length === 0))
602
+ if (r.xcstringsPaths.length === 1) {
603
+ const n = r.xcstringsPaths[0];
604
+ t.path = typeof n == "string" ? n : n.path;
605
+ } else {
606
+ const n = r.xcstringsPaths.map((c) => typeof c == "string" ? { name: c, value: c } : { name: `${c.alias} (${c.path})`, value: c.path }), s = await xe({
607
+ message: "Select xcstrings file:",
608
+ choices: n
609
+ });
610
+ t.path = s;
611
+ }
612
+ }).command(
613
+ "add",
614
+ "Add a string",
615
+ (t) => t.option("key", {
616
+ type: "string",
617
+ describe: "The key of the string",
618
+ demandOption: !0
619
+ }).option("comment", {
620
+ type: "string",
621
+ describe: "The comment for the string"
622
+ }).option("strings", {
623
+ type: "string",
624
+ describe: "The strings JSON"
625
+ }),
626
+ async (t) => {
627
+ await Je(t.path, t.key, t.comment, t.strings), B.info(d.green(`✓ Added key "${t.key}"`));
628
+ }
629
+ ).command(
630
+ "remove",
631
+ "Remove a string",
632
+ (t) => t.option("key", {
633
+ type: "string",
634
+ describe: "The key to remove",
635
+ demandOption: !0
636
+ }),
637
+ async (t) => {
638
+ await Le(t.path, t.key), B.info(d.green(`✓ Removed key "${t.key}"`));
639
+ }
640
+ ).command(
641
+ "init",
642
+ "Initialize configuration file",
643
+ (t) => t,
644
+ async () => {
645
+ await Ce();
646
+ }
647
+ ).command(
648
+ "languages",
649
+ "List supported languages from xcodeproj or xcstrings",
650
+ (t) => t,
651
+ async (t) => {
652
+ const r = await Ae(t.path, t.config);
653
+ B.info(r.join(" "));
654
+ }
655
+ ).demandCommand(1, "").strictCommands().recommendCommands().showHelpOnFail(!0).fail((t, r, n) => {
656
+ if (r)
657
+ throw console.error(r), r;
658
+ t && (console.error(d.red(t)), console.log()), n.showHelp(), process.exit(1);
659
+ }).help().argv;
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "xcstrings-cli",
3
+ "version": "1.0.0",
4
+ "description": "A command line tool for handling xcstrings files.",
5
+ "type": "module",
6
+ "bin": {
7
+ "xcstrings": "./dist/index.js"
8
+ },
9
+ "keywords": [
10
+ "xcstrings",
11
+ "cli",
12
+ "localization",
13
+ "i18n",
14
+ "ios",
15
+ "macos",
16
+ "xcode"
17
+ ],
18
+ "author": "",
19
+ "license": "MIT",
20
+ "devDependencies": {
21
+ "@changesets/cli": "^2.29.8",
22
+ "@types/json5": "^2.2.0",
23
+ "@types/node": "^24.10.1",
24
+ "@types/yargs": "^17.0.35",
25
+ "prettier": "^3.7.4",
26
+ "typescript": "^5.9.3",
27
+ "vite": "^7.2.6",
28
+ "vitest": "^4.0.15",
29
+ "yargs": "^18.0.0"
30
+ },
31
+ "dependencies": {
32
+ "@bacons/xcode": "1.0.0-alpha.27",
33
+ "@inquirer/prompts": "^8.0.2",
34
+ "chalk": "^5.6.2",
35
+ "cosmiconfig": "^9.0.0",
36
+ "json5": "^2.2.3",
37
+ "pino": "^8.16.0"
38
+ },
39
+ "scripts": {
40
+ "dev": "vite",
41
+ "build": "vite build",
42
+ "pretest": "pnpm build",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "lint": "prettier --check .",
46
+ "format": "prettier --write .",
47
+ "changeset": "changeset",
48
+ "version": "changeset version",
49
+ "release": "pnpm build && changeset publish"
50
+ }
51
+ }