@metasyncsite/translations-client-ts 1.0.0 → 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.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  TypeScript client for pushing and pulling i18n translations to/from the Translation Manager. Works with any Node.js project: Vue, React, Next.js, Nuxt, etc.
4
4
 
5
+ Translations themselves are edited in the Translation Manager UI — **[translation.metasync.site](https://translation.metasync.site/)**. Translators work there, this package moves the result in and out of your `locales/` directory. No hosting required to try it.
6
+
5
7
  ---
6
8
 
7
9
  ## Requirements
@@ -25,7 +27,8 @@ yarn add @metasyncsite/translations-client-ts
25
27
 
26
28
  ## Local Installation (without npm registry)
27
29
 
28
- If the package is not yet published, you have three options:
30
+ For working against an unreleased build a fix you are testing, or a fork — there are
31
+ three options:
29
32
 
30
33
  ### Option 1 — file path in package.json (recommended)
31
34
 
@@ -184,6 +187,44 @@ npx translations-pull \
184
187
 
185
188
  ---
186
189
 
190
+ ## Exit codes
191
+
192
+ Both commands are meant to run in CI and deploy steps, so they only exit `0` when the
193
+ work they were asked to do actually happened:
194
+
195
+ | Situation | Exit code |
196
+ |---|---|
197
+ | Everything pushed / pulled | `0` |
198
+ | A locale failed to fetch, write or upload | `1`, and the locale is named |
199
+ | `--locale=xx` names a locale that does not exist | `1` |
200
+ | Push finds no locale files at `--path` | `1` |
201
+ | Credentials missing | `1` |
202
+
203
+ A locale that fails does not abort the run — the remaining locales are still processed,
204
+ and the failures are listed together at the end.
205
+
206
+ ---
207
+
208
+ ## Write safety
209
+
210
+ Pull writes each file to a temporary name and renames it into place. `rename()` within a
211
+ directory is atomic, so an interrupted pull leaves the previous file intact instead of a
212
+ truncated one that no longer parses.
213
+
214
+ Locale codes and group names arrive in the API response and become path segments, so they
215
+ are validated before use: anything containing a path separator, or equal to `.` or `..`,
216
+ is refused rather than written outside your locales directory.
217
+
218
+ ---
219
+
220
+ ## Testing
221
+
222
+ ```bash
223
+ npm test # builds, then runs node --test
224
+ ```
225
+
226
+ ---
227
+
187
228
  ## Locale Layouts
188
229
 
189
230
  The client auto-detects which layout your project uses:
@@ -293,6 +334,14 @@ Returns: `string[]` — paths of written files.
293
334
 
294
335
  ---
295
336
 
337
+ ### `assertSafeSegment(segment, kind)`
338
+
339
+ Throws if `segment` cannot be used as a single path segment — empty, `.`, `..`, or
340
+ containing `/`, `\\` or a null byte. Returns the segment unchanged otherwise. Used
341
+ internally on locale codes and group names before they reach the filesystem.
342
+
343
+ ---
344
+
296
345
  ### `unflatten(flat)`
297
346
 
298
347
  Converts dot-notation keys back to a nested object.
package/dist/bin/pull.js CHANGED
@@ -49,6 +49,26 @@ function parseArgs(argv) {
49
49
  }
50
50
  return args;
51
51
  }
52
+ /**
53
+ * The response shape is not guaranteed: a group that comes back as null or a string
54
+ * would otherwise blow up in Object.keys() halfway through the run.
55
+ */
56
+ function asGroups(data) {
57
+ if (data === null || typeof data !== 'object' || Array.isArray(data)) {
58
+ throw new Error('unexpected response, expected a data object.');
59
+ }
60
+ const groups = {};
61
+ for (const [name, value] of Object.entries(data)) {
62
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
63
+ throw new Error(`unexpected response, group "${name}" is not an object.`);
64
+ }
65
+ groups[name] = value;
66
+ }
67
+ return groups;
68
+ }
69
+ function countKeys(groups) {
70
+ return Object.values(groups).reduce((sum, group) => sum + Object.keys(group).length, 0);
71
+ }
52
72
  async function main() {
53
73
  const cwd = process.cwd();
54
74
  loadDotEnv(cwd);
@@ -71,29 +91,44 @@ async function main() {
71
91
  if (onlyLocale) {
72
92
  locales = locales.filter((c) => c === onlyLocale);
73
93
  if (locales.length === 0) {
74
- console.warn(`Locale "${onlyLocale}" not found in Translation Manager.`);
75
- process.exit(0);
94
+ console.error(`Error: locale "${onlyLocale}" not found in Translation Manager.`);
95
+ process.exit(1);
76
96
  }
77
97
  }
78
98
  const layout = forcedLayout ?? detectLayout(localesPath) ?? 'grouped';
79
99
  const prefix = dryRun ? '[DRY RUN] ' : '';
80
100
  console.log(`${prefix}Pulling ${locales.length} locale(s) [${layout} layout]: ${locales.join(', ')}`);
101
+ const failed = [];
81
102
  for (const locale of locales) {
82
- const data = await fetchJson(`${base}/api/v1/translations/${locale}?format=nested`, token);
83
- const groups = data.data ?? {};
84
- const keyCount = Object.values(groups).reduce((sum, g) => sum + Object.keys(g).length, 0);
85
- if (dryRun) {
86
- console.log(` ${locale}: ${keyCount} keys across ${Object.keys(groups).length} group(s).`);
87
- continue;
103
+ try {
104
+ const data = await fetchJson(`${base}/api/v1/translations/${locale}?format=nested`, token);
105
+ const groups = asGroups(data?.data);
106
+ const keyCount = countKeys(groups);
107
+ if (dryRun) {
108
+ console.log(` ${locale}: ${keyCount} keys across ${Object.keys(groups).length} group(s).`);
109
+ continue;
110
+ }
111
+ const written = layout === 'grouped'
112
+ ? writeGroupedLocale(localesPath, locale, groups)
113
+ : writeFlatLocale(localesPath, locale, groups);
114
+ console.log(` ✓ ${locale}: ${keyCount} keys → ${written.length} file(s) written.`);
115
+ }
116
+ catch (error) {
117
+ // Keep going: one unreachable locale should not hide the state of the others.
118
+ console.error(` ✗ ${locale}: ${error instanceof Error ? error.message : String(error)}`);
119
+ failed.push(locale);
88
120
  }
89
- const written = layout === 'grouped'
90
- ? writeGroupedLocale(localesPath, locale, groups)
91
- : writeFlatLocale(localesPath, locale, groups);
92
- console.log(` ✓ ${locale}: ${keyCount} keys → ${written.length} file(s) written.`);
121
+ }
122
+ if (failed.length > 0) {
123
+ console.error(`\nFailed locale(s): ${failed.join(', ')}. Nothing was written for them.`);
124
+ process.exit(1);
93
125
  }
94
126
  if (!dryRun) {
95
127
  console.log('\nDone.');
96
128
  }
97
129
  }
98
- main();
130
+ main().catch((error) => {
131
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
132
+ process.exit(1);
133
+ });
99
134
  //# sourceMappingURL=pull.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/bin/pull.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/bin/pull.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAe3C,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAEjC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAE3B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,SAAQ;QACV,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAEpC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,SAAQ;QACV,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;QAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;QAElD,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QAC1B,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,IAAI,GAAe,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAA;QAEpB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC9B,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;YAChE,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;YAE1E,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;YACxC,CAAC;iBAAM,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAA;gBAC9B,CAAC,EAAE,CAAA;YACL,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,IAAa;IAC7B,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,MAAM,GAAiB,EAAE,CAAA;IAE/B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAA+B,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxE,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,qBAAqB,CAAC,CAAA;QAC3E,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,GAAG,KAA6B,CAAA;IAC9C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,SAAS,CAAC,MAAoB;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AACzF,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,UAAU,CAAC,GAAG,CAAC,CAAA;IAEf,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAElD,MAAM,GAAG,GAAI,KAAK,CAAC,KAAK,CAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IACnF,MAAM,KAAK,GAAI,KAAK,CAAC,OAAO,CAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;IACzF,MAAM,WAAW,GAAG,OAAO,CACzB,GAAG,EACF,KAAK,CAAC,MAAM,CAAwB;QACnC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;QACxC,aAAa,CAChB,CAAA;IACD,MAAM,UAAU,GAAI,KAAK,CAAC,QAAQ,CAAwB,IAAI,IAAI,CAAA;IAClE,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAA;IACrE,MAAM,YAAY,GAAI,KAAK,CAAC,QAAQ,CAA8B,IAAI,IAAI,CAAA;IAE1E,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAA;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAEnC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAoB,GAAG,IAAI,mBAAmB,EAAE,KAAK,CAAC,CAAA;IACtF,IAAI,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAE9C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAA;QAEjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,kBAAkB,UAAU,qCAAqC,CAAC,CAAA;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAiB,YAAY,IAAI,YAAY,CAAC,WAAW,CAAC,IAAI,SAAS,CAAA;IAEnF,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAA;IACzC,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,WAAW,OAAO,CAAC,MAAM,eAAe,MAAM,aAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACzF,CAAA;IAED,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAC1B,GAAG,IAAI,wBAAwB,MAAM,gBAAgB,EACrD,KAAK,CACN,CAAA;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACnC,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;YAElC,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,KAAK,QAAQ,gBAAgB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,YAAY,CAAC,CAAA;gBAC3F,SAAQ;YACV,CAAC;YAED,MAAM,OAAO,GACX,MAAM,KAAK,SAAS;gBAClB,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjD,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;YAElD,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,WAAW,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAA;QACrF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,8EAA8E;YAC9E,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACzF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,uBAAuB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACxB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
package/dist/bin/push.js CHANGED
@@ -71,14 +71,15 @@ async function main() {
71
71
  }
72
72
  let locales = readLocales(localesPath, excludeFiles);
73
73
  if (locales.length === 0) {
74
- console.warn(`No locale files found in: ${localesPath}`);
75
- process.exit(0);
74
+ // Asked to push and pushed nothing — usually a wrong --path, so do not call it a success.
75
+ console.error(`Error: no locale files found in: ${localesPath}`);
76
+ process.exit(1);
76
77
  }
77
78
  if (onlyLocale) {
78
79
  locales = locales.filter((l) => l.locale === onlyLocale);
79
80
  if (locales.length === 0) {
80
- console.warn(`Locale "${onlyLocale}" not found in: ${localesPath}`);
81
- process.exit(0);
81
+ console.error(`Error: locale "${onlyLocale}" not found in: ${localesPath}`);
82
+ process.exit(1);
82
83
  }
83
84
  }
84
85
  const prefix = dryRun ? '[DRY RUN] ' : '';
@@ -86,6 +87,7 @@ async function main() {
86
87
  let totalNew = 0;
87
88
  let totalUpdated = 0;
88
89
  let totalKeys = 0;
90
+ const failed = [];
89
91
  for (const { locale, groups } of locales) {
90
92
  const keyCount = Object.values(groups).reduce((sum, g) => sum + Object.keys(g).length, 0);
91
93
  if (dryRun) {
@@ -100,12 +102,22 @@ async function main() {
100
102
  console.log(` ✓ ${locale}: ${data.total ?? keyCount} keys — ${data.new ?? 0} new, ${data.updated ?? 0} updated.`);
101
103
  }
102
104
  catch (err) {
105
+ // Keep going so the remaining locales still get a chance, but remember the
106
+ // failure: exiting 0 here would let a CI step report a push that never landed.
103
107
  console.error(` ✗ ${locale}: ${err instanceof Error ? err.message : String(err)}`);
108
+ failed.push(locale);
104
109
  }
105
110
  }
111
+ if (failed.length > 0) {
112
+ console.error(`\nFailed locale(s): ${failed.join(', ')}. Nothing was pushed for them.`);
113
+ process.exit(1);
114
+ }
106
115
  if (!dryRun) {
107
116
  console.log(`\nDone. Total: ${totalKeys} keys — ${totalNew} new, ${totalUpdated} updated.`);
108
117
  }
109
118
  }
110
- main();
119
+ main().catch((error) => {
120
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
121
+ process.exit(1);
122
+ });
111
123
  //# sourceMappingURL=push.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/bin/push.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/bin/push.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { readLocales, readFlatLayout, readGroupedLayout, detectLayout } from './langReader.js';
2
2
  export { pushLocale, fetchJson } from './apiClient.js';
3
- export { unflatten, writeGroupedLocale, writeFlatLocale } from './langWriter.js';
3
+ export { unflatten, writeGroupedLocale, writeFlatLocale, assertSafeSegment } from './langWriter.js';
4
4
  export type { FlatKeys, LocaleGroups, LocaleLayout, LocaleData, PushLocaleParams, PushResult, PullOptions, PushOptions, } from './types.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAChF,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnG,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { readLocales, readFlatLayout, readGroupedLayout, detectLayout } from './langReader.js';
2
2
  export { pushLocale, fetchJson } from './apiClient.js';
3
- export { unflatten, writeGroupedLocale, writeFlatLocale } from './langWriter.js';
3
+ export { unflatten, writeGroupedLocale, writeFlatLocale, assertSafeSegment } from './langWriter.js';
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -4,6 +4,13 @@ import type { FlatKeys, LocaleGroups } from './types.js';
4
4
  * { 'auth.login': 'Login' } → { auth: { login: 'Login' } }
5
5
  */
6
6
  export declare function unflatten(flat: FlatKeys): Record<string, unknown>;
7
+ /**
8
+ * Reject a locale code or group name that would escape the locales directory.
9
+ *
10
+ * Both values come straight from the API response and are used to build a file path,
11
+ * so a name like `../../package` would write outside the folder the caller chose.
12
+ */
13
+ export declare function assertSafeSegment(segment: string, kind: string): string;
7
14
  /**
8
15
  * Write translations for a single locale in grouped layout.
9
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"langWriter.d.ts","sourceRoot":"","sources":["../src/langWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAExD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBjE;AAeD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAkBV;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAYV"}
1
+ {"version":3,"file":"langWriter.d.ts","sourceRoot":"","sources":["../src/langWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAExD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBjE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAUvE;AAqCD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAoBV;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAYV"}
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  /**
4
4
  * Restore dot-notation flat keys back to a nested object.
@@ -21,14 +21,50 @@ export function unflatten(flat) {
21
21
  return result;
22
22
  }
23
23
  /**
24
- * Write a JSON file, creating parent directories as needed.
24
+ * Reject a locale code or group name that would escape the locales directory.
25
+ *
26
+ * Both values come straight from the API response and are used to build a file path,
27
+ * so a name like `../../package` would write outside the folder the caller chose.
28
+ */
29
+ export function assertSafeSegment(segment, kind) {
30
+ if (segment === '' || segment === '.' || segment === '..') {
31
+ return failSegment(segment, kind);
32
+ }
33
+ if (segment.includes('/') || segment.includes('\\') || segment.includes('\0')) {
34
+ return failSegment(segment, kind);
35
+ }
36
+ return segment;
37
+ }
38
+ function failSegment(segment, kind) {
39
+ throw new Error(`Refusing to write: ${kind} ${JSON.stringify(segment)} is not a safe path segment.`);
40
+ }
41
+ /**
42
+ * Write a JSON file through a temporary file, then rename it into place.
43
+ *
44
+ * Locale files are read by the application at build or run time. A direct write that is
45
+ * cut short — killed process, full disk — leaves a truncated file that no longer parses.
46
+ * rename() within the same directory is atomic, so a reader sees the old file or the new
47
+ * one, never half of either.
25
48
  */
26
49
  function writeJson(filePath, data) {
27
50
  const dir = dirname(filePath);
28
51
  if (!existsSync(dir)) {
29
52
  mkdirSync(dir, { recursive: true });
30
53
  }
31
- writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
54
+ const temporary = `${filePath}.${process.pid}.tmp`;
55
+ try {
56
+ writeFileSync(temporary, JSON.stringify(data, null, 2) + '\n', 'utf8');
57
+ renameSync(temporary, filePath);
58
+ }
59
+ catch (error) {
60
+ try {
61
+ unlinkSync(temporary);
62
+ }
63
+ catch {
64
+ // The temporary file may never have been created; nothing to clean up.
65
+ }
66
+ throw error;
67
+ }
32
68
  }
33
69
  /**
34
70
  * Write translations for a single locale in grouped layout.
@@ -38,15 +74,17 @@ function writeJson(filePath, data) {
38
74
  */
39
75
  export function writeGroupedLocale(localesPath, locale, groups) {
40
76
  const written = [];
77
+ const safeLocale = assertSafeSegment(locale, 'locale');
41
78
  for (const [groupName, flatKeys] of Object.entries(groups)) {
42
79
  const nested = unflatten(flatKeys);
43
80
  if (groupName === '_json') {
44
- const filePath = join(localesPath, `${locale}.json`);
81
+ const filePath = join(localesPath, `${safeLocale}.json`);
45
82
  writeJson(filePath, nested);
46
83
  written.push(filePath);
47
84
  }
48
85
  else {
49
- const filePath = join(localesPath, locale, `${groupName}.json`);
86
+ const safeGroup = assertSafeSegment(groupName, 'group name');
87
+ const filePath = join(localesPath, safeLocale, `${safeGroup}.json`);
50
88
  writeJson(filePath, nested);
51
89
  written.push(filePath);
52
90
  }
@@ -64,7 +102,7 @@ export function writeFlatLocale(localesPath, locale, groups) {
64
102
  Object.assign(merged, flatKeys);
65
103
  }
66
104
  const nested = unflatten(merged);
67
- const filePath = join(localesPath, `${locale}.json`);
105
+ const filePath = join(localesPath, `${assertSafeSegment(locale, 'locale')}.json`);
68
106
  writeJson(filePath, nested);
69
107
  return [filePath];
70
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"langWriter.js","sourceRoot":"","sources":["../src/langWriter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"langWriter.js","sourceRoot":"","sources":["../src/langWriter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasyncsite/translations-client-ts",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Push/pull i18n translations (Vue, React, Next.js, etc.) to the MetaSyncSite Translation Manager — TypeScript edition",
5
5
  "type": "module",
6
6
  "engines": {
@@ -24,7 +24,8 @@
24
24
  "scripts": {
25
25
  "build": "tsc",
26
26
  "dev": "tsc --watch",
27
- "prepublishOnly": "npm run build"
27
+ "prepublishOnly": "npm run build",
28
+ "test": "npm run build && node --test tests/*.test.js"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@types/node": "^22.0.0",
@@ -37,4 +38,4 @@
37
38
  "localization",
38
39
  "typescript"
39
40
  ]
40
- }
41
+ }