locize-cli 9.0.1 → 9.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/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  Project versioning adheres to [Semantic Versioning](http://semver.org/).
6
6
  Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
7
7
 
8
+ ## [9.1.0](https://github.com/locize/locize-cli/compare/v9.0.2...v9.1.0) - 2025-05-07
9
+
10
+ - introduce `remove-version` command
11
+
12
+ ## [9.0.2](https://github.com/locize/locize-cli/compare/v9.0.1...v9.0.2) - 2025-04-25
13
+
14
+ - Hint: `Using the "--auto-translate true" option together with the "--reference-language-only false" option might result in inconsistent target language translations (automatic translation vs. what is sent direcly to locize).`
15
+
8
16
  ## [9.0.1](https://github.com/locize/locize-cli/compare/v9.0.0...v9.0.1) - 2025-04-04
9
17
 
10
18
  - optimize xcstrings format [106](https://github.com/locize/locize-cli/issues/106)
package/README.md CHANGED
@@ -237,6 +237,20 @@ locize publish-version --api-key my-api-key-d9de-4f55-9855-a9ef0ed44672 --projec
237
237
  ```
238
238
 
239
239
 
240
+ ## Delete version
241
+
242
+ *It uses this [API endpoint](https://www.locize.com/docs/api#remove-version).*
243
+
244
+ ### Step 1: execute
245
+
246
+ Add your api-key and your project-id and let's go...
247
+
248
+ ```sh
249
+ # this will remove version tmp-ver
250
+ locize remove-version tmp-ver --api-key my-api-key-d9de-4f55-9855-a9ef0ed44672 --project-id my-project-id-93e1-442a-ab35-24331fa294ba
251
+ ```
252
+
253
+
240
254
  ## Delete namespace
241
255
  ### Step 1: execute
242
256
 
package/bin/locize CHANGED
@@ -22,6 +22,7 @@ const get = require('../get');
22
22
  const sync = require('../sync');
23
23
  const missing = require('../missing');
24
24
  const copyVersion = require('../copyVersion');
25
+ const removeVersion = require('../removeVersion.js');
25
26
  const publishVersion = require('../publishVersion');
26
27
  const deleteNamespace = require('../deleteNamespace');
27
28
  const formatFn = require('../format');
@@ -588,7 +589,50 @@ program
588
589
  console.log();
589
590
  console.log(' $ locize copy-version latest"');
590
591
  console.log(' $ locize copy-version latest --ver production"');
591
- console.log(' $ locize copy-version latest production --api-key <apiKey> --project-id <projectId> --ver <version>');
592
+ console.log(' $ locize copy-version latest --api-key <apiKey> --project-id <projectId> --ver <version>');
593
+ console.log();
594
+ });
595
+
596
+ program
597
+ .command('remove-version <version>')
598
+ .alias('rv')
599
+ .description('remove version')
600
+ .option('-k, --api-key <apiKey>', 'The api-key that should be used')
601
+ .option('-i, --project-id <projectId>', 'The project-id that should be used')
602
+ .option('-C, --config-path <configPath>', `Specify the path to the optional locize config file (default: ${configInWorkingDirectory} or ${configInHome})`)
603
+ .action((version, options) => {
604
+ try {
605
+ config = ini.parse(fs.readFileSync(options.configPath, 'utf-8')) || config;
606
+ } catch (e) {}
607
+
608
+ const apiKey = options.apiKey || config.apiKey || process.env.LOCIZE_API_KEY || process.env.LOCIZE_KEY;
609
+ if (!apiKey) {
610
+ console.error(' error: missing required argument `apiKey`');
611
+ process.exit(1);
612
+ return;
613
+ }
614
+
615
+ const projectId = options.projectId || config.projectId || process.env.LOCIZE_PROJECTID || process.env.LOCIZE_PID;
616
+ if (!projectId) {
617
+ console.error(' error: missing required argument `projectId`');
618
+ process.exit(1);
619
+ return;
620
+ }
621
+
622
+ const getPath = options.getPath || config.getPath || getPathUrl;
623
+
624
+ removeVersion({
625
+ apiKey: apiKey,
626
+ projectId: projectId,
627
+ apiPath: url.parse(getPath).protocol + '//' + url.parse(getPath).host,
628
+ version: version
629
+ });
630
+ })
631
+ .on('--help', () => {
632
+ console.log(' Examples:');
633
+ console.log();
634
+ console.log(' $ locize remove-version tmp-ver"');
635
+ console.log(' $ locize remove-version tmp-ver --api-key <apiKey> --project-id <projectId>');
592
636
  console.log();
593
637
  });
594
638
 
package/download.js CHANGED
@@ -93,7 +93,7 @@ function handleDownload(opt, url, err, res, downloads, cb) {
93
93
  if (clb) clb(null);
94
94
  }
95
95
 
96
- const fileContent = opt.format !== 'xlsx' ? (converted + '\n') : converted;
96
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
97
97
  if (!opt.version) {
98
98
  if (mkdirPath) mkdirp.sync(path.join(opt.path, version, mkdirPath));
99
99
  fs.writeFile(path.join(opt.path, version, filledMask), fileContent, logAndClb);
@@ -145,7 +145,7 @@ function handleDownload(opt, url, err, res, downloads, cb) {
145
145
  if (filledMask.lastIndexOf(path.sep) > 0) {
146
146
  mkdirPath = filledMask.substring(0, filledMask.lastIndexOf(path.sep));
147
147
  }
148
- const fileContent = opt.format !== 'xlsx' ? (converted + '\n') : converted;
148
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
149
149
  if (!opt.version) {
150
150
  if (mkdirPath) mkdirp.sync(path.join(opt.path, version, mkdirPath));
151
151
  fs.writeFile(path.join(opt.path, version, filledMask), fileContent, clb);
@@ -232,7 +232,7 @@ function handlePull(opt, toDownload, cb) {
232
232
  }
233
233
 
234
234
  if (mkdirPath) mkdirp.sync(path.join(opt.path, mkdirPath));
235
- const fileContent = opt.format !== 'xlsx' ? (converted + '\n') : converted;
235
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
236
236
  fs.writeFile(path.join(opt.path, filledMask), fileContent, logAndClb);
237
237
  } catch (e) {
238
238
  err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '');
@@ -276,7 +276,7 @@ function handlePull(opt, toDownload, cb) {
276
276
  if (filledMask.lastIndexOf(path.sep) > 0) {
277
277
  mkdirPath = filledMask.substring(0, filledMask.lastIndexOf(path.sep));
278
278
  }
279
- const fileContent = opt.format !== 'xlsx' ? (converted + '\n') : converted;
279
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
280
280
  if (!opt.language) {
281
281
  if (mkdirPath) mkdirp.sync(path.join(opt.path, mkdirPath));
282
282
  fs.writeFile(path.join(opt.path, filledMask), fileContent, clb);
package/format.js CHANGED
@@ -113,7 +113,7 @@ function writeLocalFile(opt, file, clb) {
113
113
  return clb(null, true);
114
114
  }
115
115
 
116
- const fileContent = opt.format !== 'xlsx' ? (file.converted + '\n') : file.converted;
116
+ const fileContent = (opt.format !== 'xlsx' && !file.converted.endsWith('\n')) ? (file.converted + '\n') : file.converted;
117
117
 
118
118
  fs.writeFile(file.path, fileContent, (err) => clb(err, true));
119
119
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locize-cli",
3
- "version": "9.0.1",
3
+ "version": "9.1.0",
4
4
  "description": "locize cli to import locales",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -15,7 +15,7 @@
15
15
  "commander": "9.5.0",
16
16
  "csvjson": "5.1.0",
17
17
  "diff": "7.0.0",
18
- "dotenv": "16.4.7",
18
+ "dotenv": "16.5.0",
19
19
  "flat": "5.0.2",
20
20
  "fluent_conv": "3.3.0",
21
21
  "gettext-converter": "1.3.0",
@@ -31,11 +31,11 @@
31
31
  "rimraf": "4.4.1",
32
32
  "strings-file": "0.0.5",
33
33
  "tmexchange": "2.0.5",
34
- "xliff": "6.2.1",
34
+ "xliff": "6.2.2",
35
35
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
36
36
  },
37
37
  "devDependencies": {
38
- "@yao-pkg/pkg": "6.3.1",
38
+ "@yao-pkg/pkg": "6.4.0",
39
39
  "eslint": "8.56.0",
40
40
  "gh-release": "7.0.2"
41
41
  },
@@ -0,0 +1,64 @@
1
+ const colors = require('colors');
2
+ const request = require('./request');
3
+ const getJob = require('./getJob');
4
+
5
+ const removeVersion = (opt, cb) => {
6
+ request(opt.apiPath + '/version/' + opt.projectId + '/' + opt.version, {
7
+ method: 'delete',
8
+ headers: {
9
+ 'Authorization': opt.apiKey
10
+ }
11
+ }, (err, res, obj) => {
12
+ if (err || (obj && (obj.errorMessage || obj.message))) {
13
+ if (!cb) console.log(colors.red(`remove failed for version ${opt.version}...`));
14
+
15
+ if (err) {
16
+ if (!cb) { console.error(colors.red(err.message)); process.exit(1); }
17
+ if (cb) cb(err);
18
+ return;
19
+ }
20
+ if (obj && (obj.errorMessage || obj.message)) {
21
+ if (!cb) { console.error(colors.red((obj.errorMessage || obj.message))); process.exit(1); }
22
+ if (cb) cb(new Error((obj.errorMessage || obj.message)));
23
+ return;
24
+ }
25
+ }
26
+ if (res.status >= 300) {
27
+ if (!cb) { console.error(colors.red(res.statusText + ' (' + res.status + ')')); process.exit(1); }
28
+ if (cb) cb(new Error(res.statusText + ' (' + res.status + ')'));
29
+ return;
30
+ }
31
+
32
+ if (!obj || !obj.jobId) {
33
+ if (!cb) { console.error(colors.red('No jobId! Something went wrong!')); process.exit(1); }
34
+ if (cb) cb(new Error('No jobId! Something went wrong!'));
35
+ return;
36
+ }
37
+
38
+ (function waitForJob() {
39
+ getJob(opt, obj.jobId, (err, job) => {
40
+ if (err) {
41
+ if (!cb) { console.error(colors.red(err.message)); process.exit(1); }
42
+ if (cb) cb(err);
43
+ return;
44
+ }
45
+
46
+ if (job && !job.timeouted) {
47
+ setTimeout(waitForJob, 2000);
48
+ return;
49
+ }
50
+
51
+ if (job && job.timeouted) {
52
+ if (!cb) { console.error(colors.red('Job timeouted!')); process.exit(1); }
53
+ if (cb) cb(new Error('Job timeouted!'));
54
+ return;
55
+ }
56
+
57
+ if (!cb) console.log(colors.green(`remove version ${opt.version} succesfully requested`));
58
+ if (cb) cb(null);
59
+ });
60
+ })();
61
+ });
62
+ };
63
+
64
+ module.exports = removeVersion;
package/sync.js CHANGED
@@ -267,7 +267,7 @@ const downloadAll = (opt, remoteLanguages, omitRef, manipulate, cb) => {
267
267
  }
268
268
  const parentDir = path.dirname(path.join(opt.path, filledMask));
269
269
  mkdirp.sync(parentDir);
270
- const fileContent = opt.format !== 'xlsx' ? (converted + '\n') : converted;
270
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
271
271
  fs.writeFile(path.join(opt.path, filledMask), fileContent, clb);
272
272
  } catch (e) {
273
273
  err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '');
@@ -307,7 +307,7 @@ const downloadAll = (opt, remoteLanguages, omitRef, manipulate, cb) => {
307
307
  }
308
308
  const parentDir = path.dirname(path.join(opt.path, filledMask));
309
309
  mkdirp.sync(parentDir);
310
- const fileContent = opt.format !== 'xlsx' ? (converted + '\n') : converted;
310
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
311
311
  fs.writeFile(path.join(opt.path, filledMask), fileContent, clb);
312
312
  });
313
313
  });
@@ -335,7 +335,7 @@ const update = (opt, lng, ns, shouldOmit, cb) => {
335
335
 
336
336
  function send(d, so, clb, isRetrying) {
337
337
  const queryParams = new URLSearchParams();
338
- if (opt.autoTranslate) {
338
+ if (opt.autoTranslate && lng === opt.referenceLanguage) {
339
339
  /** @See https://www.locize.com/docs/api#optional-autotranslate */
340
340
  queryParams.append('autotranslate', 'true');
341
341
  }
@@ -489,7 +489,7 @@ const backupDeleted = (opt, ns, now) => {
489
489
  }, {});
490
490
  mkdirp.sync(path.join(currentBackupPath, ns.language));
491
491
  const content = JSON.stringify(removingRemote, null, 2);
492
- const fileContent = opt.format !== 'xlsx' ? (content + '\n') : content;
492
+ const fileContent = (opt.format !== 'xlsx' && !content.endsWith('\n')) ? (content + '\n') : content;
493
493
  fs.writeFileSync(path.join(currentBackupPath, ns.language, `${ns.namespace}.json`), fileContent);
494
494
  };
495
495
 
@@ -665,6 +665,10 @@ const sync = (opt, cb) => {
665
665
  return handleError(new Error(`${opt.format} is not a valid format!`), cb);
666
666
  }
667
667
 
668
+ if (opt.autoTranslate && !opt.referenceLanguageOnly) {
669
+ console.log(colors.yellow('Using the "--auto-translate true" option together with the "--reference-language-only false" option might result in inconsistent target language translations (automatic translation vs. what is sent direcly to locize).'));
670
+ }
671
+
668
672
  opt.version = opt.version || 'latest';
669
673
  opt.apiPath = opt.apiPath || 'https://api.locize.app';
670
674