locize-cli 8.7.1 → 9.0.1

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,15 @@ 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.0.1](https://github.com/locize/locize-cli/compare/v9.0.0...v9.0.1) - 2025-04-04
9
+
10
+ - optimize xcstrings format [106](https://github.com/locize/locize-cli/issues/106)
11
+
12
+ ## [9.0.0](https://github.com/locize/locize-cli/compare/v8.7.1...v9.0.0) - 2025-04-03
13
+
14
+ - the format `yaml-rails-ns`/`yml-rails-ns` is the old `yaml-rails`/`yml-rails`
15
+ - `yaml-rails`/`yml-rails` does not scope the yaml content with the namespace anymore => use `yaml-rails-ns`/`yml-rails-ns` instead
16
+
8
17
  ## [8.7.1](https://github.com/locize/locize-cli/compare/v8.7.0...v8.7.1) - 2025-04-02
9
18
 
10
19
  - make generated files POSIX compliant, addresses [107](https://github.com/locize/locize-cli/issues/107)
package/README.md CHANGED
@@ -84,7 +84,11 @@ or
84
84
  locize download
85
85
  ```
86
86
 
87
- or add a format like (json, nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings)
87
+ or add a format like (json, nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings)
88
+
89
+ *Special formats:*
90
+ - use yaml-rails to have the language code in the resulting yaml as root object
91
+ - use yaml-rails-ns to have the namespace in the resulting yaml as first key scope
88
92
 
89
93
  ```sh
90
94
  locize download --project-id my-project-id-93e1-442a-ab35-24331fa294ba --ver latest --language en --namespace namespace1 --path ./backup --format android
@@ -133,7 +137,11 @@ Add your api-key and your project-id and let's go...
133
137
  locize sync --api-key my-api-key-d9de-4f55-9855-a9ef0ed44672 --project-id my-project-id-93e1-442a-ab35-24331fa294ba
134
138
  ```
135
139
 
136
- or add a format like (json, nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings)
140
+ or add a format like (json, nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings)
141
+
142
+ *Special formats:*
143
+ - use yaml-rails to have the language code in the resulting yaml as root object
144
+ - use yaml-rails-ns to have the namespace in the resulting yaml as first key scope
137
145
 
138
146
  ```sh
139
147
  locize sync --api-key my-api-key-d9de-4f55-9855-a9ef0ed44672 --project-id my-project-id-93e1-442a-ab35-24331fa294ba --format android
@@ -193,7 +201,7 @@ Add your api-key and your project-id and let's go...
193
201
  locize save-missing --api-key my-api-key-d9de-4f55-9855-a9ef0ed44672 --project-id my-project-id-93e1-442a-ab35-24331fa294ba
194
202
  ```
195
203
 
196
- or add a format like (json, nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings)
204
+ or add a format like (json, nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings)
197
205
 
198
206
  ```sh
199
207
  locize save-missing --api-key my-api-key-d9de-4f55-9855-a9ef0ed44672 --project-id my-project-id-93e1-442a-ab35-24331fa294ba --format android
package/bin/locize CHANGED
@@ -232,7 +232,7 @@ program
232
232
  .option('-p, --path <path>', `Specify the path that should be used (default: ${process.cwd()})`, process.cwd())
233
233
  .option('-g, --get-path <url>', `Specify the get-path url that should be used (default: ${getPathUrl})`)
234
234
  .option('-k, --api-key <apiKey>', 'The api-key that should be used')
235
- .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
235
+ .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
236
236
  .option('-s, --skip-empty <true|false>', 'Skips to download empty files (default: true)', 'true')
237
237
  .option('-P, --language-folder-prefix <prefix>', 'This will be added as a local folder name prefix in front of the language.', '')
238
238
  .option('-m, --path-mask <mask>', 'This will define the folder and file structure; do not add a file extension (default: {{language}}/{{namespace}})', `{{language}}${path.sep}{{namespace}}`)
@@ -361,7 +361,7 @@ program
361
361
  .option('-p, --path <path>', `Specify the path that should be used (default: ${process.cwd()})`, process.cwd())
362
362
  .option('-B, --backup-deleted-path <path>', 'Saves the segments that will be deleted in this path')
363
363
  .option('-A, --auto-create-path <true|false>', 'This will automatically make sure the --path is created. (default: true)', 'true')
364
- .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
364
+ .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
365
365
  .option('-s, --skip-empty <true|false>', 'Skips to download empty files (default: false)', 'false')
366
366
  .option('-c, --clean <true|false>', 'Removes all local files by removing the whole folder (default: false)', 'false')
367
367
  .option('-cf, --clean-local-files <true|false>', 'Removes all local files without removing any folder (default: false)', 'false')
@@ -472,7 +472,7 @@ program
472
472
  .option('-i, --project-id <projectId>', 'The project-id that should be used')
473
473
  .option('-v, --ver <version>', 'Found namespaces will be matched to this version (default: latest)')
474
474
  .option('-p, --path <path>', `Specify the path that should be used (default: ${process.cwd()})`, process.cwd())
475
- .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
475
+ .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
476
476
  .option('-m, --path-mask <mask>', 'This will define the folder and file structure; do not add a file extension (default: {{language}}/{{namespace}})', `{{language}}${path.sep}{{namespace}}`)
477
477
  .option('-P, --language-folder-prefix <prefix>', 'This will be added as a local folder name prefix in front of the language.', '')
478
478
  .option('-d, --dry <true|false>', 'Dry run (default: false)', 'false')
@@ -695,7 +695,7 @@ program
695
695
  .command('format [fileOrDirectory]')
696
696
  .alias('ft')
697
697
  .description('format local files')
698
- .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
698
+ .option('-f, --format <json>', 'File format of namespaces (default: json; [nested, flat, xliff2, xliff12, xlf2, xlf12, android, yaml, yaml-rails, yaml-rails-ns, yaml-nested, yml, yml-rails, yml-nested, csv, xlsx, po, strings, resx, fluent, tmx, laravel, properties, xcstrings])', 'json')
699
699
  .option('-l, --reference-language <lng>', 'Some format conversions need to know the reference language.', 'en')
700
700
  .option('-d, --dry <true|false>', 'Dry run (default: false)', 'false')
701
701
  .option('-C, --config-path <configPath>', `Specify the path to the optional locize config file (default: ${configInWorkingDirectory} or ${configInHome})`)
@@ -161,11 +161,21 @@ const convertToDesiredFormat = (
161
161
  ) {
162
162
  if (isEmpty) return cb(null, '');
163
163
  var newData = {};
164
- newData[lng] = {};
165
- newData[lng][namespace] = shouldUnflatten(data) ? unflatten(data) : data;
164
+ newData[lng] = shouldUnflatten(data) ? unflatten(data) : data;
166
165
  cb(null, jsyaml.dump(removeUndefinedFromArrays(newData)));
167
166
  return;
168
167
  }
168
+ if (
169
+ opt.format === 'yaml-rails-ns' ||
170
+ opt.format === 'yml-rails-ns'
171
+ ) {
172
+ if (isEmpty) return cb(null, '');
173
+ var newDataNs = {};
174
+ newDataNs[lng] = {};
175
+ newDataNs[lng][namespace] = shouldUnflatten(data) ? unflatten(data) : data;
176
+ cb(null, jsyaml.dump(removeUndefinedFromArrays(newDataNs)));
177
+ return;
178
+ }
169
179
  if (opt.format === 'android') {
170
180
  js2asr(flatten(data), cb);
171
181
  return;
@@ -141,13 +141,28 @@ const convertToFlatFormat = (opt, data, lng, cb) => {
141
141
  opt.format === 'yml-rails'
142
142
  ) {
143
143
  const d = data.toString();
144
- if (!d || d === '') return cb(null, {});
144
+ if (!d || d.trim() === '') return cb(null, {});
145
145
  const jsObj = jsyaml.load(d);
146
146
  cb(
147
147
  null,
148
148
  flatten(
149
- jsObj[Object.keys(jsObj)[0]][
150
- Object.keys(jsObj[Object.keys(jsObj)[0]])[0]
149
+ jsObj[Object.keys(jsObj)[0]]
150
+ )
151
+ );
152
+ return;
153
+ }
154
+ if (
155
+ opt.format === 'yaml-rails-ns' ||
156
+ opt.format === 'yml-rails-ns'
157
+ ) {
158
+ const dn = data.toString();
159
+ if (!dn || dn.trim() === '') return cb(null, {});
160
+ const jsObjn = jsyaml.load(dn);
161
+ cb(
162
+ null,
163
+ flatten(
164
+ jsObjn[Object.keys(jsObjn)[0]][
165
+ Object.keys(jsObjn[Object.keys(jsObjn)[0]])[0]
151
166
  ]
152
167
  )
153
168
  );
package/download.js CHANGED
@@ -79,8 +79,7 @@ function handleDownload(opt, url, err, res, downloads, cb) {
79
79
  if (err) return clb(err);
80
80
 
81
81
  try {
82
- const result = locize2xcstrings(locizeData);
83
- const converted = JSON.stringify(result, null, 2);
82
+ const converted = locize2xcstrings(locizeData);
84
83
 
85
84
  var filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, '').replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, ns) + reversedFileExtensionsMap[opt.format];
86
85
  var mkdirPath;
package/formats.js CHANGED
@@ -5,8 +5,8 @@ const fileExtensionsMap = {
5
5
  '.strings': ['strings'],
6
6
  '.csv': ['csv'],
7
7
  '.resx': ['resx'],
8
- '.yaml': ['yaml', 'yaml-rails', 'yaml-nested'],
9
- '.yml': ['yml', 'yml-rails', 'yml-nested'],
8
+ '.yaml': ['yaml', 'yaml-rails', 'yaml-rails-ns', 'yaml-nested'],
9
+ '.yml': ['yml', 'yml-rails', 'yml-rails-ns', 'yml-nested'],
10
10
  '.xlsx': ['xlsx'],
11
11
  '.xliff': ['xliff2', 'xliff12'],
12
12
  '.xlf': ['xlf2', 'xlf12'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locize-cli",
3
- "version": "8.7.1",
3
+ "version": "9.0.1",
4
4
  "description": "locize cli to import locales",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -23,7 +23,7 @@
23
23
  "ini": "4.1.3",
24
24
  "js-yaml": "4.1.0",
25
25
  "laravelphp": "2.0.4",
26
- "locize-xcstrings": "1.0.0",
26
+ "locize-xcstrings": "2.0.0",
27
27
  "lodash.clonedeep": "4.5.0",
28
28
  "mkdirp": "3.0.1",
29
29
  "node-fetch": "2.7.0",
@@ -141,7 +141,7 @@ const parseLocalLanguage = (opt, lng, cb) => {
141
141
 
142
142
  if (opt.format === 'xcstrings') { // 1 file per namespace including all languages
143
143
  try {
144
- const content = xcstrings2locize(JSON.parse(data));
144
+ const content = xcstrings2locize(data);
145
145
 
146
146
  fs.stat(fPath, (err, stat) => {
147
147
  if (err) return clb(err);
package/sync.js CHANGED
@@ -258,8 +258,7 @@ const downloadAll = (opt, remoteLanguages, omitRef, manipulate, cb) => {
258
258
  if (err) return clb(err);
259
259
 
260
260
  try {
261
- const result = locize2xcstrings(locizeData);
262
- const converted = JSON.stringify(result, null, 2);
261
+ const converted = locize2xcstrings(locizeData);
263
262
 
264
263
  const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, '').replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format];
265
264
  if (opt.dry) return clb(null);