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