@transifex/cli 7.1.4 → 7.1.6

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.
@@ -1 +1 @@
1
- {"version":"7.1.4","commands":{"invalidate":{"id":"invalidate","description":"Invalidate and refresh CDS cache\nContent for delivery is cached in CDS and refreshed automatically every hour.\nThis command triggers a refresh of cached content on the fly.\n\nBy default, invalidation does not remove existing cached content,\nbut starts the process of updating with latest translations from Transifex.\n\nPassing the --purge option, cached content will be forced to be deleted,\nhowever use that with caution, as it may introduce downtime of\ntranslation delivery to the apps until fresh content is cached in the CDS.\n\nTo invalidate translations some environment variables must be set:\nTRANSIFEX_TOKEN=<Transifex Native Project Token>\nTRANSIFEX_SECRET=<Transifex Native Project Secret>\n(optional) TRANSIFEX_CDS_HOST=<CDS HOST>\n\nor passed as --token=<TOKEN> --secret=<SECRET> parameters\n\nDefault CDS Host is https://cds.svc.transifex.net\n\nExamples:\ntxjs-cli invalidate\ntxjs-cli invalidate --purge\ntxjs-cli invalidate --token=mytoken --secret=mysecret\nTRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli invalidate\n","pluginName":"@transifex/cli","pluginType":"core","aliases":[],"flags":{"purge":{"name":"purge","type":"boolean","description":"force delete CDS cached content","allowNo":false},"token":{"name":"token","type":"option","description":"native project public token","default":""},"secret":{"name":"secret","type":"option","description":"native project secret","default":""},"cds-host":{"name":"cds-host","type":"option","description":"CDS host URL","default":""}},"args":[]},"pull":{"id":"pull","description":"Pull content from Transifex for offline caching\nGet content as JSON files, to be used by mobile Javascript SDKs for\noffline support or warming up the cache with initial translations.\n\nBy default, JSON files are printed in the console,\nunless the \"-f foldername\" parameter is provided. In that case\nthe JSON files will be downloaded to that folder with the <locale>.json format.\n\nTo pull content some environment variables must be set:\nTRANSIFEX_TOKEN=<Transifex Native Project Token>\nTRANSIFEX_SECRET=<Transifex Native Project Secret>\n(optional) TRANSIFEX_CDS_HOST=<CDS HOST>\n\nor passed as --token=<TOKEN> --secret=<SECRET> parameters\n\nDefault CDS Host is https://cds.svc.transifex.net\n\nExamples:\ntxjs-cli pull\ntxjs-cli pull --pretty\ntxjs-cli pull -f languages/\ntxjs-cli pull --locale=fr -f .\ntxjs-cli pull --filter-tags=\"foo,bar\"\ntxjs-cli pull --filter-status=\"reviewed\"\ntxjs-cli pull --token=mytoken --secret=mysecret\nTRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli pull\n","pluginName":"@transifex/cli","pluginType":"core","aliases":[],"flags":{"token":{"name":"token","type":"option","description":"native project public token","default":""},"secret":{"name":"secret","type":"option","description":"native project secret","default":""},"folder":{"name":"folder","type":"option","char":"f","description":"output as files to folder","default":""},"locale":{"name":"locale","type":"option","char":"l","description":"pull specific language locale code","default":""},"pretty":{"name":"pretty","type":"boolean","description":"beautify JSON output","allowNo":false},"filter-tags":{"name":"filter-tags","type":"option","description":"filter over specific tags","default":""},"filter-status":{"name":"filter-status","type":"option","description":"filter over translation status","options":["reviewed","proofread","finalized"],"default":""},"cds-host":{"name":"cds-host","type":"option","description":"CDS host URL","default":""}},"args":[]},"push":{"id":"push","description":"Detect and push source content to Transifex\nParse .js, .ts, .jsx, .tsx and .html files and detect phrases marked for\ntranslation by Transifex Native toolkit for Javascript and\nupload them to Transifex for translation.\n\nTo push content some environment variables must be set:\nTRANSIFEX_TOKEN=<Transifex Native Project Token>\nTRANSIFEX_SECRET=<Transifex Native Project Secret>\n(optional) TRANSIFEX_CDS_HOST=<CDS HOST>\n\nor passed as --token=<TOKEN> --secret=<SECRET> parameters\n\nDefault CDS Host is https://cds.svc.transifex.net\n\nExamples:\ntxjs-cli push -v\ntxjs-cli push src/\ntxjs-cli push /home/repo/src\ntxjs-cli push \"*.js\"\ntxjs-cli push --dry-run\ntxjs-cli push --fake -v\ntxjs-cli push --no-wait\ntxjs-cli push --key-generator=hash\ntxjs-cli push --append-tags=\"master,release:2.5\"\ntxjs-cli push --with-tags-only=\"home,error\"\ntxjs-cli push --without-tags-only=\"custom\"\ntxjs-cli push --token=mytoken --secret=mysecret\ntxjs-cli push en.json --parser=i18next\ntxjs-cli push en.json --parser=txnativejson\nTRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli push\n","pluginName":"@transifex/cli","pluginType":"core","aliases":[],"flags":{"dry-run":{"name":"dry-run","type":"boolean","description":"dry run, do not apply changes in Transifex","allowNo":false},"fake":{"name":"fake","type":"boolean","description":"do not push content to remote server","allowNo":false},"verbose":{"name":"verbose","type":"boolean","char":"v","description":"verbose output","allowNo":false},"purge":{"name":"purge","type":"boolean","description":"purge content on Transifex","allowNo":false},"no-wait":{"name":"no-wait","type":"boolean","description":"disable polling for upload results","allowNo":false},"token":{"name":"token","type":"option","description":"native project public token","default":""},"secret":{"name":"secret","type":"option","description":"native project secret","default":""},"append-tags":{"name":"append-tags","type":"option","description":"append tags to strings","default":""},"with-tags-only":{"name":"with-tags-only","type":"option","description":"push strings with specific tags","default":""},"without-tags-only":{"name":"without-tags-only","type":"option","description":"push strings without specific tags","default":""},"cds-host":{"name":"cds-host","type":"option","description":"CDS host URL","default":""},"do-not-keep-translations":{"name":"do-not-keep-translations","type":"boolean","description":"remove translations when source strings change","allowNo":false},"override-tags":{"name":"override-tags","type":"boolean","description":"override tags when pushing content","allowNo":false},"override-occurrences":{"name":"override-occurrences","type":"boolean","description":"override occurrences when pushing content","allowNo":false},"parser":{"name":"parser","type":"option","description":"file parser to use","options":["auto","i18next","txnativejson"],"default":"auto"},"key-generator":{"name":"key-generator","type":"option","description":"use hashed or source based keys","options":["source","hash"],"default":"source"}},"args":[{"name":"pattern","description":"file pattern to scan for strings","required":false,"default":"**/*.{js,jsx,ts,tsx,html,vue,pug,ejs}"}]}}}
1
+ {"version":"7.1.6","commands":{"invalidate":{"id":"invalidate","description":"Invalidate and refresh CDS cache\nContent for delivery is cached in CDS and refreshed automatically every hour.\nThis command triggers a refresh of cached content on the fly.\n\nBy default, invalidation does not remove existing cached content,\nbut starts the process of updating with latest translations from Transifex.\n\nPassing the --purge option, cached content will be forced to be deleted,\nhowever use that with caution, as it may introduce downtime of\ntranslation delivery to the apps until fresh content is cached in the CDS.\n\nTo invalidate translations some environment variables must be set:\nTRANSIFEX_TOKEN=<Transifex Native Project Token>\nTRANSIFEX_SECRET=<Transifex Native Project Secret>\n(optional) TRANSIFEX_CDS_HOST=<CDS HOST>\n\nor passed as --token=<TOKEN> --secret=<SECRET> parameters\n\nDefault CDS Host is https://cds.svc.transifex.net\n\nExamples:\ntxjs-cli invalidate\ntxjs-cli invalidate --purge\ntxjs-cli invalidate --token=mytoken --secret=mysecret\nTRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli invalidate\n","pluginName":"@transifex/cli","pluginType":"core","aliases":[],"flags":{"purge":{"name":"purge","type":"boolean","description":"force delete CDS cached content","allowNo":false},"token":{"name":"token","type":"option","description":"native project public token","default":""},"secret":{"name":"secret","type":"option","description":"native project secret","default":""},"cds-host":{"name":"cds-host","type":"option","description":"CDS host URL","default":""}},"args":[]},"pull":{"id":"pull","description":"Pull content from Transifex for offline caching\nGet content as JSON files, to be used by mobile Javascript SDKs for\noffline support or warming up the cache with initial translations.\n\nBy default, JSON files are printed in the console,\nunless the \"-f foldername\" parameter is provided. In that case\nthe JSON files will be downloaded to that folder with the <locale>.json format.\n\nTo pull content some environment variables must be set:\nTRANSIFEX_TOKEN=<Transifex Native Project Token>\nTRANSIFEX_SECRET=<Transifex Native Project Secret>\n(optional) TRANSIFEX_CDS_HOST=<CDS HOST>\n\nor passed as --token=<TOKEN> --secret=<SECRET> parameters\n\nDefault CDS Host is https://cds.svc.transifex.net\n\nExamples:\ntxjs-cli pull\ntxjs-cli pull --pretty\ntxjs-cli pull -f languages/\ntxjs-cli pull --locale=fr -f .\ntxjs-cli pull --filter-tags=\"foo,bar\"\ntxjs-cli pull --filter-status=\"reviewed\"\ntxjs-cli pull --token=mytoken --secret=mysecret\nTRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli pull\n","pluginName":"@transifex/cli","pluginType":"core","aliases":[],"flags":{"token":{"name":"token","type":"option","description":"native project public token","default":""},"secret":{"name":"secret","type":"option","description":"native project secret","default":""},"folder":{"name":"folder","type":"option","char":"f","description":"output as files to folder","default":""},"locale":{"name":"locale","type":"option","char":"l","description":"pull specific language locale code","default":""},"pretty":{"name":"pretty","type":"boolean","description":"beautify JSON output","allowNo":false},"filter-tags":{"name":"filter-tags","type":"option","description":"filter over specific tags","default":""},"filter-status":{"name":"filter-status","type":"option","description":"filter over translation status","options":["reviewed","proofread","finalized"],"default":""},"cds-host":{"name":"cds-host","type":"option","description":"CDS host URL","default":""}},"args":[]},"push":{"id":"push","description":"Detect and push source content to Transifex\nParse .js, .ts, .jsx, .tsx and .html files and detect phrases marked for\ntranslation by Transifex Native toolkit for Javascript and\nupload them to Transifex for translation.\n\nTo push content some environment variables must be set:\nTRANSIFEX_TOKEN=<Transifex Native Project Token>\nTRANSIFEX_SECRET=<Transifex Native Project Secret>\n(optional) TRANSIFEX_CDS_HOST=<CDS HOST>\n\nor passed as --token=<TOKEN> --secret=<SECRET> parameters\n\nDefault CDS Host is https://cds.svc.transifex.net\n\nExamples:\ntxjs-cli push -v\ntxjs-cli push src/\ntxjs-cli push /home/repo/src\ntxjs-cli push \"*.js\"\ntxjs-cli push --dry-run\ntxjs-cli push --fake -v\ntxjs-cli push --no-wait\ntxjs-cli push --key-generator=hash\ntxjs-cli push --append-tags=\"master,release:2.5\"\ntxjs-cli push --with-tags-only=\"home,error\"\ntxjs-cli push --without-tags-only=\"custom\"\ntxjs-cli push --token=mytoken --secret=mysecret\ntxjs-cli push en.json --parser=i18next\ntxjs-cli push en.json --parser=txnativejson\nTRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli push\n","pluginName":"@transifex/cli","pluginType":"core","aliases":[],"flags":{"dry-run":{"name":"dry-run","type":"boolean","description":"dry run, do not apply changes in Transifex","allowNo":false},"fake":{"name":"fake","type":"boolean","description":"do not push content to remote server","allowNo":false},"verbose":{"name":"verbose","type":"boolean","char":"v","description":"verbose output","allowNo":false},"purge":{"name":"purge","type":"boolean","description":"purge content on Transifex","allowNo":false},"no-wait":{"name":"no-wait","type":"boolean","description":"disable polling for upload results","allowNo":false},"token":{"name":"token","type":"option","description":"native project public token","default":""},"secret":{"name":"secret","type":"option","description":"native project secret","default":""},"append-tags":{"name":"append-tags","type":"option","description":"append tags to strings","default":""},"with-tags-only":{"name":"with-tags-only","type":"option","description":"push strings with specific tags","default":""},"without-tags-only":{"name":"without-tags-only","type":"option","description":"push strings without specific tags","default":""},"cds-host":{"name":"cds-host","type":"option","description":"CDS host URL","default":""},"do-not-keep-translations":{"name":"do-not-keep-translations","type":"boolean","description":"remove translations when source strings change","allowNo":false},"override-tags":{"name":"override-tags","type":"boolean","description":"override tags when pushing content","allowNo":false},"override-occurrences":{"name":"override-occurrences","type":"boolean","description":"override occurrences when pushing content","allowNo":false},"parser":{"name":"parser","type":"option","description":"file parser to use","options":["auto","i18next","txnativejson"],"default":"auto"},"key-generator":{"name":"key-generator","type":"option","description":"use hashed or source based keys","options":["source","hash"],"default":"source"}},"args":[{"name":"pattern","description":"file pattern to scan for strings","required":false,"default":"**/*.{js,jsx,ts,tsx,html,vue,pug,ejs}"}]}}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@transifex/cli",
3
3
  "description": "i18n CLI tool for Transifex Native",
4
- "version": "7.1.4",
4
+ "version": "7.1.6",
5
5
  "author": "Transifex",
6
6
  "keywords": [
7
7
  "transifex",
@@ -28,10 +28,10 @@
28
28
  "@babel/traverse": "^7.23.7",
29
29
  "@colors/colors": "^1.6.0",
30
30
  "@oclif/core": "^1.26.2",
31
- "@transifex/native": "^7.1.4",
31
+ "@transifex/native": "^7.1.6",
32
32
  "@vue/compiler-sfc": "^3.4.7",
33
33
  "angular-html-parser": "^1.8.0",
34
- "axios": "^1.6.5",
34
+ "axios": "^1.15.0",
35
35
  "ejs": "^3.1.9",
36
36
  "glob": "^8.1.0",
37
37
  "lodash": "^4.17.21",
package/src/api/utils.js CHANGED
@@ -23,6 +23,26 @@ function mergeArrays(array1, array2) {
23
23
  return _.uniq(_.concat(array1 || [], array2 || []));
24
24
  }
25
25
 
26
+ /**
27
+ * Normalize input to array format
28
+ *
29
+ * @param {*} value - Input that might be an array, string, or other type
30
+ * @returns {Array} Normalized array
31
+ */
32
+ function normalizeArray(value) {
33
+ if (!value) return [];
34
+ if (Array.isArray(value)) return value;
35
+ if (typeof value === 'string') {
36
+ try {
37
+ const parsed = JSON.parse(value);
38
+ return Array.isArray(parsed) ? parsed : [];
39
+ } catch (_e) {
40
+ return [];
41
+ }
42
+ }
43
+ return [];
44
+ }
45
+
26
46
  /**
27
47
  * Async/await sleep
28
48
  *
@@ -40,5 +60,6 @@ function sleep(msec) {
40
60
  module.exports = {
41
61
  stringToArray,
42
62
  mergeArrays,
63
+ normalizeArray,
43
64
  sleep,
44
65
  };
@@ -11,7 +11,7 @@ const { CliUx } = require('@oclif/core');
11
11
  const { extractPhrases } = require('../api/extract');
12
12
  const { uploadPhrases, pollJob } = require('../api/upload');
13
13
  const { mergePayload } = require('../api/merge');
14
- const { stringToArray } = require('../api/utils');
14
+ const { stringToArray, normalizeArray } = require('../api/utils');
15
15
 
16
16
  /**
17
17
  * Test if path is folder
@@ -161,6 +161,41 @@ class PushCommand extends Command {
161
161
  : 'Uploading content to Transifex';
162
162
 
163
163
  this.log('');
164
+
165
+ /**
166
+ * Print detailed verbose output for a group of items
167
+ *
168
+ * @param {String} label - Label for the group
169
+ * @param {Array} items - Items to display
170
+ * @param {String} groupColor - Color for the group label
171
+ */
172
+ const printVerboseGroup = (label, items, groupColor = 'white') => {
173
+ const arr = normalizeArray(items);
174
+ if (!arr.length) return;
175
+ this.log(` ${label}: ${arr.length}`[groupColor]);
176
+ arr.forEach((item) => {
177
+ const {
178
+ key = '',
179
+ string = '',
180
+ context = [],
181
+ occurrences = [],
182
+ } = item;
183
+ if (string) {
184
+ if (key !== string) {
185
+ this.log(` └─ ${key}: ${string.underline}`);
186
+ } else {
187
+ this.log(` └─ ${string.underline}`);
188
+ }
189
+ if (occurrences.length) {
190
+ this.log(` └─ occurrences: ${occurrences.join(', ')}`.gray);
191
+ }
192
+ if (context.length) {
193
+ this.log(` └─ context: ${context}`.gray);
194
+ }
195
+ }
196
+ });
197
+ };
198
+
164
199
  CliUx.ux.action.start(uploadMessage, '', { stdout: true });
165
200
  try {
166
201
  let res = await uploadPhrases(payload, {
@@ -207,20 +242,29 @@ class PushCommand extends Command {
207
242
  if (status === 'completed') {
208
243
  CliUx.ux.action.stop('Success'.green);
209
244
  this.log(`${'✓'.green} Successfully pushed strings to Transifex:`);
210
- if (res.created > 0) {
211
- this.log(` Created strings: ${res.created.toString().green}`);
212
- }
213
- if (res.updated > 0) {
214
- this.log(` Updated strings: ${res.updated.toString().green}`);
215
- }
216
- if (res.skipped > 0) {
217
- this.log(` Skipped strings: ${res.skipped.toString().green}`);
218
- }
219
- if (res.deleted > 0) {
220
- this.log(` Deleted strings: ${res.deleted.toString().green}`);
221
- }
222
- if (res.failed > 0) {
223
- this.log(` Failed strings: ${res.failed.toString().red}`);
245
+
246
+ if (res.verbose && flags.verbose) {
247
+ printVerboseGroup('Created strings', res.verbose.created, 'green');
248
+ printVerboseGroup('Updated strings', res.verbose.updated, 'yellow');
249
+ printVerboseGroup('Deleted strings', res.verbose.deleted, 'red');
250
+ printVerboseGroup('Skipped strings', res.verbose.skipped, 'green');
251
+ printVerboseGroup('Failed strings', res.verbose.failed, 'red');
252
+ } else {
253
+ if (res.created > 0) {
254
+ this.log(` Created strings: ${res.created}`.green);
255
+ }
256
+ if (res.updated > 0) {
257
+ this.log(` Updated strings: ${res.updated}`.yellow);
258
+ }
259
+ if (res.deleted > 0) {
260
+ this.log(` Deleted strings: ${res.deleted}`.red);
261
+ }
262
+ if (res.skipped > 0) {
263
+ this.log(` Skipped strings: ${res.skipped}`.green);
264
+ }
265
+ if (res.failed > 0) {
266
+ this.log(` Failed strings: ${res.failed}`.red);
267
+ }
224
268
  }
225
269
  } else {
226
270
  CliUx.ux.action.stop('Failed'.red);