@transifex/cli 4.3.0 → 5.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/README.md CHANGED
@@ -78,6 +78,7 @@ $ npm run push
78
78
  # Commands
79
79
  * [`txjs-cli help [COMMAND]`](#txjs-cli-help-command)
80
80
  * [`txjs-cli push [PATTERN]`](#txjs-cli-push-pattern)
81
+ * [`txjs-cli pull [PATTERN]`](#txjs-cli-pull-pattern)
81
82
  * [`txjs-cli invalidate`](#txjs-cli-invalidate)
82
83
 
83
84
  ## `txjs-cli help [COMMAND]`
@@ -101,27 +102,32 @@ detect and push source content to Transifex
101
102
 
102
103
  ```
103
104
  USAGE
104
- $ txjs-cli push [PATTERN]
105
+ $ txjs-cli push [PATTERN] [--dry-run] [--fake] [-v] [--purge] [--no-wait] [--token <value>] [--secret <value>] [--append-tags <value>] [--with-tags-only <value>] [--without-tags-only <value>]
106
+ [--cds-host <value>] [--parser auto|i18next|txnativejson] [--key-generator source|hash]
105
107
 
106
108
  ARGUMENTS
107
- PATTERN [default: **/*.{js,jsx,ts,tsx,vue}] file pattern to scan for strings
108
-
109
- OPTIONS
110
- -v, --verbose verbose output
111
- --append-tags=append-tags append tags to strings
112
- --cds-host=cds-host CDS host URL
113
- --dry-run dry run, do not push to Transifex
114
- --key-generator=source|hash [default: source] use hashed or source based keys
115
- --no-wait disable polling for upload results
116
- --parser=auto|i18next [default: auto] file parser to use
117
- --purge purge content on Transifex
118
- --secret=secret native project secret
119
- --token=token native project public token
120
- --with-tags-only=with-tags-only push strings with specific tags
121
- --without-tags-only=without-tags-only push strings without specific tags
109
+ PATTERN [default: **/*.{js,jsx,ts,tsx,html,vue,pug,ejs}] file pattern to scan for strings
110
+
111
+ FLAGS
112
+ -v, --verbose verbose output
113
+ --append-tags=<value> append tags to strings
114
+ --cds-host=<value> CDS host URL
115
+ --dry-run dry run, do not apply changes in Transifex
116
+ --fake do not push content to remote server
117
+ --key-generator=<option> [default: source] use hashed or source based keys
118
+ <options: source|hash>
119
+ --no-wait disable polling for upload results
120
+ --parser=<option> [default: auto] file parser to use
121
+ <options: auto|i18next|txnativejson>
122
+ --purge purge content on Transifex
123
+ --secret=<value> native project secret
124
+ --token=<value> native project public token
125
+ --with-tags-only=<value> push strings with specific tags
126
+ --without-tags-only=<value> push strings without specific tags
122
127
 
123
128
  DESCRIPTION
124
- Parse .js, .ts, .jsx, .tsx, .html and .vue files and detect phrases marked for
129
+ Detect and push source content to Transifex
130
+ Parse .js, .ts, .jsx, .tsx and .html files and detect phrases marked for
125
131
  translation by Transifex Native toolkit for Javascript and
126
132
  upload them to Transifex for translation.
127
133
 
@@ -140,6 +146,7 @@ DESCRIPTION
140
146
  txjs-cli push /home/repo/src
141
147
  txjs-cli push "*.js"
142
148
  txjs-cli push --dry-run
149
+ txjs-cli push --fake -v
143
150
  txjs-cli push --no-wait
144
151
  txjs-cli push --key-generator=hash
145
152
  txjs-cli push --append-tags="master,release:2.5"
@@ -147,29 +154,79 @@ DESCRIPTION
147
154
  txjs-cli push --without-tags-only="custom"
148
155
  txjs-cli push --token=mytoken --secret=mysecret
149
156
  txjs-cli push en.json --parser=i18next
157
+ txjs-cli push en.json --parser=txnativejson
150
158
  TRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli push
151
159
  ```
152
160
 
161
+ ## `txjs-cli pull [PATTERN]`
162
+
163
+ Pull content from Transifex for offline caching
164
+
165
+ ```
166
+ USAGE
167
+ $ txjs-cli pull [--token <value>] [--secret <value>] [-f <value>] [-l <value>] [--pretty] [--filter-tags <value>] [--filter-status reviewed|proofread|finalized] [--cds-host <value>]
168
+
169
+ FLAGS
170
+ -f, --folder=<value> output as files to folder
171
+ -l, --locale=<value> pull specific language locale code
172
+ --cds-host=<value> CDS host URL
173
+ --filter-status=<option> filter over translation status
174
+ <options: reviewed|proofread|finalized>
175
+ --filter-tags=<value> filter over specific tags
176
+ --pretty beautify JSON output
177
+ --secret=<value> native project secret
178
+ --token=<value> native project public token
179
+
180
+ DESCRIPTION
181
+ Pull content from Transifex for offline caching
182
+ Get content as JSON files, to be used by mobile Javascript SDKs for
183
+ offline support or warming up the cache with initial translations.
184
+
185
+ By default, JSON files are printed in the console,
186
+ unless the "-f foldername" parameter is provided. In that case
187
+ the JSON files will be downloaded to that folder with the <locale>.json format.
188
+
189
+ To pull content some environment variables must be set:
190
+ TRANSIFEX_TOKEN=<Transifex Native Project Token>
191
+ TRANSIFEX_SECRET=<Transifex Native Project Secret>
192
+ (optional) TRANSIFEX_CDS_HOST=<CDS HOST>
193
+
194
+ or passed as --token=<TOKEN> --secret=<SECRET> parameters
195
+
196
+ Default CDS Host is https://cds.svc.transifex.net
197
+
198
+ Examples:
199
+ txjs-cli pull
200
+ txjs-cli pull --pretty
201
+ txjs-cli pull -f languages/
202
+ txjs-cli pull --locale=fr -f .
203
+ txjs-cli pull --filter-tags="foo,bar"
204
+ txjs-cli pull --filter-status="reviewed"
205
+ txjs-cli pull --token=mytoken --secret=mysecret
206
+ TRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli pull
207
+ ```
208
+
153
209
  ## `txjs-cli invalidate`
154
210
 
155
211
  invalidate and refresh CDS cache
156
212
 
157
213
  ```
158
214
  USAGE
159
- $ txjs-cli invalidate
215
+ $ txjs-cli invalidate [--purge] [--token <value>] [--secret <value>] [--cds-host <value>]
160
216
 
161
- OPTIONS
162
- --cds-host=cds-host CDS host URL
163
- --purge force delete CDS cached content
164
- --secret=secret native project secret
165
- --token=token native project public token
217
+ FLAGS
218
+ --cds-host=<value> CDS host URL
219
+ --purge force delete CDS cached content
220
+ --secret=<value> native project secret
221
+ --token=<value> native project public token
166
222
 
167
223
  DESCRIPTION
224
+ Invalidate and refresh CDS cache
168
225
  Content for delivery is cached in CDS and refreshed automatically every hour.
169
226
  This command triggers a refresh of cached content on the fly.
170
227
 
171
- By default, invalidation does not remove existing cached content, but
172
- starts the process of updating with latest translations from Transifex.
228
+ By default, invalidation does not remove existing cached content,
229
+ but starts the process of updating with latest translations from Transifex.
173
230
 
174
231
  Passing the --purge option, cached content will be forced to be deleted,
175
232
  however use that with caution, as it may introduce downtime of
package/bin/run CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('@oclif/command').run()
4
- .then(require('@oclif/command/flush'))
5
- .catch(require('@oclif/errors/handle'));
3
+ const oclif = require('@oclif/core');
4
+
5
+ oclif.run().then(require('@oclif/core/flush')).catch(require('@oclif/core/handle'));
@@ -1 +1 @@
1
- {"version":"4.3.0","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, but\nstarts 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":[]},"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 --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\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 push to Transifex","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":""},"parser":{"name":"parser","type":"option","description":"file parser to use","options":["auto","i18next"],"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":"5.0.1","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":""},"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": "4.3.0",
4
+ "version": "5.0.1",
5
5
  "author": "Transifex",
6
6
  "keywords": [
7
7
  "transifex",
@@ -24,34 +24,29 @@
24
24
  "access": "public"
25
25
  },
26
26
  "dependencies": {
27
- "@babel/parser": "^7.18.9",
28
- "@babel/traverse": "^7.18.9",
27
+ "@babel/parser": "^7.20.3",
28
+ "@babel/traverse": "^7.20.1",
29
29
  "@colors/colors": "^1.5.0",
30
- "@oclif/command": "^1.8.16",
31
- "@oclif/config": "^1.18.3",
32
- "@oclif/errors": "^1.3.5",
33
- "@oclif/plugin-help": "^5.1.12",
34
- "@transifex/native": "^4.3.0",
30
+ "@oclif/core": "^1.20.4",
31
+ "@transifex/native": "^5.0.1",
32
+ "@vue/compiler-sfc": "^3.2.45",
35
33
  "angular-html-parser": "^1.8.0",
36
- "axios": "^0.27.2",
37
- "cli-ux": "^6.0.9",
34
+ "axios": "^1.1.3",
38
35
  "ejs": "^3.1.8",
39
36
  "glob": "^8.0.3",
40
37
  "lodash": "^4.17.21",
41
38
  "pug": "^3.0.2",
42
- "shelljs": "^0.8.5",
43
- "vue-template-compiler": "^2.7.7"
39
+ "shelljs": "^0.8.5"
44
40
  },
45
41
  "devDependencies": {
46
42
  "@oclif/dev-cli": "^1.26.10",
47
- "@oclif/test": "^2.1.0",
48
- "chai": "^4.3.6",
49
- "eslint": "^7.32.0",
50
- "eslint-config-airbnb-base": "^14.2.1",
43
+ "@oclif/test": "^2.2.12",
44
+ "chai": "^4.3.7",
45
+ "eslint": "^8.28.0",
46
+ "eslint-config-airbnb-base": "^15.0.0",
51
47
  "eslint-plugin-import": "^2.26.0",
52
- "globby": "^11.1.0",
53
- "mocha": "^10.0.0",
54
- "nock": "^13.2.8",
48
+ "mocha": "^10.1.0",
49
+ "nock": "^13.2.9",
55
50
  "nyc": "^15.1.0"
56
51
  },
57
52
  "engines": {
@@ -66,6 +61,9 @@
66
61
  "main": "src/index.js",
67
62
  "oclif": {
68
63
  "commands": "./src/commands",
64
+ "additionalHelpFlags": [
65
+ "-h"
66
+ ],
69
67
  "bin": "txjs-cli",
70
68
  "plugins": [
71
69
  "@oclif/plugin-help"
@@ -0,0 +1,83 @@
1
+ const axios = require('axios');
2
+ const { version } = require('../../package.json');
3
+ const { sleep } = require('./utils');
4
+
5
+ /**
6
+ * Download languages
7
+ *
8
+ * @param {*} { cdsHost, token, secret }
9
+ * @return {Promise}
10
+ */
11
+ async function downloadLanguages({ cdsHost, token, secret }) {
12
+ let response;
13
+ let lastResponseStatus = 202;
14
+ while (lastResponseStatus === 202) {
15
+ /* eslint-disable no-await-in-loop */
16
+ response = await axios.get(`${cdsHost}/languages`, {
17
+ headers: {
18
+ Authorization: `Bearer ${token}:${secret}`,
19
+ 'Accept-version': 'v2',
20
+ 'Content-Type': 'application/json;charset=utf-8',
21
+ 'X-NATIVE-SDK': `txjs/cli/${version}`,
22
+ },
23
+ });
24
+ lastResponseStatus = response.status;
25
+ if (lastResponseStatus === 202) {
26
+ await sleep(1000);
27
+ }
28
+ /* eslint-enable no-await-in-loop */
29
+ }
30
+
31
+ return response.data;
32
+ }
33
+
34
+ /**
35
+ * Download phrases
36
+ *
37
+ * @param {*} {
38
+ * cdsHost, locale, filterTags, filterStatus, token, secret,
39
+ * }
40
+ * @return {Promise}
41
+ */
42
+ async function downloadPhrases({
43
+ cdsHost, locale, filterTags, filterStatus, token, secret,
44
+ }) {
45
+ let response;
46
+ let lastResponseStatus = 202;
47
+ while (lastResponseStatus === 202) {
48
+ let url = `${cdsHost}/content/${locale}`;
49
+
50
+ const getOptions = [];
51
+ if (filterTags) {
52
+ getOptions.push(`filter[tags]=${filterTags}`);
53
+ }
54
+ if (filterStatus) {
55
+ getOptions.push(`filter[status]=${filterStatus}`);
56
+ }
57
+ if (getOptions.length) {
58
+ url = `${url}?${getOptions.join('&')}`;
59
+ }
60
+
61
+ /* eslint-disable no-await-in-loop */
62
+ response = await axios.get(url, {
63
+ headers: {
64
+ Authorization: `Bearer ${token}:${secret}`,
65
+ 'Accept-version': 'v2',
66
+ 'Content-Type': 'application/json;charset=utf-8',
67
+ 'X-NATIVE-SDK': `txjs/cli/${version}`,
68
+ },
69
+ });
70
+ lastResponseStatus = response.status;
71
+ if (lastResponseStatus === 202) {
72
+ await sleep(1000);
73
+ }
74
+ /* eslint-enable no-await-in-loop */
75
+ }
76
+
77
+ return response.data;
78
+ }
79
+
80
+ module.exports = {
81
+ downloadPhrases,
82
+ downloadLanguages,
83
+ };
@@ -10,6 +10,7 @@ const { parseHTMLTemplateFile } = require('./parsers/angularHTML');
10
10
  const { babelExtractPhrases } = require('./parsers/babel');
11
11
  const { extractVuePhrases } = require('./parsers/vue');
12
12
  const { extractI18NextPhrases } = require('./parsers/i18next');
13
+ const { extractTXNativeJSONPhrases } = require('./parsers/txnativejson');
13
14
 
14
15
  /**
15
16
  * Parse file and extract phrases using AST
@@ -34,6 +35,12 @@ function extractPhrases(file, relativeFile, options = {}) {
34
35
  return HASHES;
35
36
  }
36
37
 
38
+ // Transifex Native JSON
39
+ if (options.parser === 'txnativejson') {
40
+ extractTXNativeJSONPhrases(HASHES, source, relativeFile, options);
41
+ return HASHES;
42
+ }
43
+
37
44
  // PUBG templates
38
45
  if (path.extname(file) === '.pug') {
39
46
  source = pug.compileClient(source);
@@ -0,0 +1,41 @@
1
+ const _ = require('lodash');
2
+ const { mergePayload } = require('../merge');
3
+
4
+ /**
5
+ * Parse i18next JSON v3 & v4 files
6
+ *
7
+ * @param {Object} HASHES A map of keys and content for phrases
8
+ * @param {String} source The content we want to parse
9
+ * @param {String} relativeFile occurence
10
+ * @param {Object} options
11
+ * @param {String[]} options.appendTags
12
+ * @param {String[]} options.filterWithTags
13
+ * @param {String[]} options.filterWithoutTags
14
+ * @param {Boolean} options.useHashedKeys
15
+ */
16
+ function extractTXNativeJSONPhrases(HASHES, source, relativeFile, options) {
17
+ let json = {};
18
+ try {
19
+ json = JSON.parse(source);
20
+ } catch (err) {
21
+ return;
22
+ }
23
+ _.each(json, (value, key) => {
24
+ mergePayload(HASHES, {
25
+ [key]: value,
26
+ });
27
+ if (options.appendTags) {
28
+ mergePayload(HASHES, {
29
+ [key]: {
30
+ meta: {
31
+ tags: options.appendTags,
32
+ },
33
+ },
34
+ });
35
+ }
36
+ });
37
+ }
38
+
39
+ module.exports = {
40
+ extractTXNativeJSONPhrases,
41
+ };
@@ -1,11 +1,11 @@
1
1
  const _ = require('lodash');
2
- const vueTemplateCompiler = require('vue-template-compiler');
2
+ const vueTemplateCompiler = require('@vue/compiler-sfc');
3
3
  const { createPayload, isPayloadValid } = require('./utils');
4
4
  const { mergePayload } = require('../merge');
5
5
  const { babelExtractPhrases } = require('./babel');
6
6
 
7
7
  /**
8
- * A function to traverse the AST provided by the vue-template-compiler package
8
+ * A function to traverse the AST provided by the vue/compiler-sfc package
9
9
  *
10
10
  * @param {*} ast
11
11
  * @param {*} visitor
@@ -14,7 +14,7 @@ function traverseVueTemplateAst(ast, visitor = {}) {
14
14
  // Use this in order to identify expressions in the AST since there is no
15
15
  // Tag to identify it with when traversing
16
16
  const VISITORS = {
17
- 2: 'Expression',
17
+ 5: 'Expression',
18
18
  };
19
19
 
20
20
  function traverseArray(array, parent) {
@@ -28,10 +28,13 @@ function traverseVueTemplateAst(ast, visitor = {}) {
28
28
  if (visitor.enter) visitor.enter(node, parent);
29
29
  if (visitor[node.tag]) visitor[node.tag](node, parent);
30
30
  // Take care of expressions
31
- if (visitor[VISITORS[node.type]] && node.expression) {
32
- visitor[VISITORS[node.type]](node, parent);
31
+ if (visitor[VISITORS[node.type]] && node.content) {
32
+ if (node.content.loc.source) visitor[VISITORS[node.type]](node, parent);
33
33
  }
34
34
  if (node.children) traverseArray(node.children, node);
35
+ if (node.content) {
36
+ if (node.content.children) traverseArray(node.content.children, node);
37
+ }
35
38
  if (visitor.exit) visitor.exit(node, parent);
36
39
  }
37
40
  traverseNode(ast, null);
@@ -54,11 +57,11 @@ function vueElementVisitor(HASHES, relativeFile, options) {
54
57
  return (node) => {
55
58
  let string;
56
59
  const params = {};
57
- _.each(node.attrsList, (attr) => {
60
+ _.each(node.props, (attr) => {
58
61
  const property = attr.name;
59
62
  if (!property || !attr.value) return;
60
63
 
61
- const attrValue = attr.value;
64
+ const attrValue = attr.value.content;
62
65
 
63
66
  if (!attrValue) return;
64
67
 
@@ -102,25 +105,25 @@ function vueElementVisitor(HASHES, relativeFile, options) {
102
105
  */
103
106
  function extractVuePhrases(HASHES, source, relativeFile, options) {
104
107
  // Use the vue-template-compiler API to parse content
105
- const vueContent = vueTemplateCompiler.parseComponent(source);
106
-
108
+ const vueContent = vueTemplateCompiler.parse(source);
107
109
  // Get the JS Content from the file and extract hashes/phrases with Babel
108
- if (vueContent.script && vueContent.script.content) {
109
- const script = vueContent.script.content;
110
+ if (vueContent.descriptor.script && vueContent.descriptor.script.content) {
111
+ const script = vueContent.descriptor.script.content;
110
112
  babelExtractPhrases(HASHES, script, relativeFile, options);
111
113
  }
112
114
 
113
115
  // Get the template content from the file and extract hashes/phrases with
114
116
  // custom traverse function
115
- if (vueContent.template && vueContent.template.content) {
117
+ if (vueContent.descriptor.template && vueContent.descriptor.template.content) {
116
118
  // Compile to get the AST
117
- const template = vueTemplateCompiler.compile(vueContent.template.content, {
118
- preserveWhitespace: false,
119
+ const template = vueTemplateCompiler.compileTemplate({
120
+ id: 'sfc-compiler',
121
+ source: vueContent.descriptor.template.content,
119
122
  });
120
123
 
121
124
  traverseVueTemplateAst(template.ast, {
122
125
  Expression(node) {
123
- babelExtractPhrases(HASHES, node.expression, relativeFile, options);
126
+ babelExtractPhrases(HASHES, node.content.loc.source, relativeFile, options);
124
127
  },
125
128
  T: vueElementVisitor(HASHES, relativeFile, options),
126
129
  UT: vueElementVisitor(HASHES, relativeFile, options),
package/src/api/upload.js CHANGED
@@ -18,6 +18,7 @@ async function uploadPhrases(payload, params) {
18
18
  data: payload,
19
19
  meta: {
20
20
  purge: !!params.purge,
21
+ dry_run: !!params.dry_run,
21
22
  },
22
23
  }, {
23
24
  headers: {
package/src/api/utils.js CHANGED
@@ -23,7 +23,22 @@ function mergeArrays(array1, array2) {
23
23
  return _.uniq(_.concat(array1 || [], array2 || []));
24
24
  }
25
25
 
26
+ /**
27
+ * Async/await sleep
28
+ *
29
+ * @param {Number} msec
30
+ * @return {Promise}
31
+ */
32
+ function sleep(msec) {
33
+ return new Promise((resolve) => {
34
+ setTimeout(() => {
35
+ resolve();
36
+ }, msec);
37
+ });
38
+ }
39
+
26
40
  module.exports = {
27
41
  stringToArray,
28
42
  mergeArrays,
43
+ sleep,
29
44
  };
@@ -1,13 +1,13 @@
1
1
  /* eslint no-shadow: 0 */
2
2
 
3
3
  require('@colors/colors');
4
- const { Command, flags } = require('@oclif/command');
5
- const { cli } = require('cli-ux');
4
+ const { Command, Flags } = require('@oclif/core');
5
+ const { CliUx } = require('@oclif/core');
6
6
  const { invalidateCDS } = require('../api/invalidate');
7
7
 
8
8
  class InvalidateCommand extends Command {
9
9
  async run() {
10
- const { flags } = this.parse(InvalidateCommand);
10
+ const { flags } = await this.parse(InvalidateCommand);
11
11
 
12
12
  let cdsHost = process.env.TRANSIFEX_CDS_HOST || 'https://cds.svc.transifex.net';
13
13
  let projectToken = process.env.TRANSIFEX_TOKEN;
@@ -24,9 +24,9 @@ class InvalidateCommand extends Command {
24
24
  }
25
25
 
26
26
  if (flags.purge) {
27
- cli.action.start('Invalidating and purging CDS cache', '', { stdout: true });
27
+ CliUx.ux.action.start('Invalidating and purging CDS cache', '', { stdout: true });
28
28
  } else {
29
- cli.action.start('Invalidating CDS cache', '', { stdout: true });
29
+ CliUx.ux.action.start('Invalidating CDS cache', '', { stdout: true });
30
30
  }
31
31
 
32
32
  try {
@@ -36,22 +36,22 @@ class InvalidateCommand extends Command {
36
36
  secret: projectSecret,
37
37
  purge: flags.purge,
38
38
  });
39
- cli.action.stop('Success'.green);
39
+ CliUx.ux.action.stop('Success'.green);
40
40
  this.log(`${(res.data.count || 0).toString().green} records invalidated`);
41
41
  this.log('Note: It might take a few minutes for fresh content to be available'.yellow);
42
42
  } catch (err) {
43
- cli.action.stop('Failed'.red);
43
+ CliUx.ux.action.stop('Failed'.red);
44
44
  this.error(err);
45
45
  }
46
46
  }
47
47
  }
48
48
 
49
- InvalidateCommand.description = `invalidate and refresh CDS cache
49
+ InvalidateCommand.description = `Invalidate and refresh CDS cache
50
50
  Content for delivery is cached in CDS and refreshed automatically every hour.
51
51
  This command triggers a refresh of cached content on the fly.
52
52
 
53
- By default, invalidation does not remove existing cached content, but
54
- starts the process of updating with latest translations from Transifex.
53
+ By default, invalidation does not remove existing cached content,
54
+ but starts the process of updating with latest translations from Transifex.
55
55
 
56
56
  Passing the --purge option, cached content will be forced to be deleted,
57
57
  however use that with caution, as it may introduce downtime of
@@ -76,19 +76,19 @@ TRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli invalidate
76
76
  InvalidateCommand.args = [];
77
77
 
78
78
  InvalidateCommand.flags = {
79
- purge: flags.boolean({
79
+ purge: Flags.boolean({
80
80
  description: 'force delete CDS cached content',
81
81
  default: false,
82
82
  }),
83
- token: flags.string({
83
+ token: Flags.string({
84
84
  description: 'native project public token',
85
85
  default: '',
86
86
  }),
87
- secret: flags.string({
87
+ secret: Flags.string({
88
88
  description: 'native project secret',
89
89
  default: '',
90
90
  }),
91
- 'cds-host': flags.string({
91
+ 'cds-host': Flags.string({
92
92
  description: 'CDS host URL',
93
93
  default: '',
94
94
  }),
@@ -0,0 +1,142 @@
1
+ /* eslint-disable no-await-in-loop */
2
+ require('@colors/colors');
3
+ const _ = require('lodash');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const { Command, Flags } = require('@oclif/core');
7
+ const { CliUx } = require('@oclif/core');
8
+ const { downloadLanguages, downloadPhrases } = require('../api/download');
9
+
10
+ class PullCommand extends Command {
11
+ async run() {
12
+ const { flags } = await this.parse(PullCommand);
13
+
14
+ let cdsHost = process.env.TRANSIFEX_CDS_HOST || 'https://cds.svc.transifex.net';
15
+ let projectToken = process.env.TRANSIFEX_TOKEN;
16
+ let projectSecret = process.env.TRANSIFEX_SECRET;
17
+
18
+ if (flags.token) projectToken = flags.token;
19
+ if (flags.secret) projectSecret = flags.secret;
20
+ if (flags['cds-host']) cdsHost = flags['cds-host'];
21
+
22
+ if (!projectToken || !projectSecret) {
23
+ this.log(`${'✘'.red} Cannot pull content, credentials are missing.`);
24
+ this.log('Tip: Set TRANSIFEX_TOKEN and TRANSIFEX_SECRET environment variables'.yellow);
25
+ process.exit();
26
+ }
27
+
28
+ try {
29
+ // get source lang
30
+ const params = {
31
+ cdsHost,
32
+ token: projectToken,
33
+ secret: projectSecret,
34
+ filterTags: flags['filter-tags'],
35
+ filterStatus: flags['filter-status'],
36
+ locale: '',
37
+ };
38
+ const locales = [];
39
+ if (flags.locale) {
40
+ locales.push(flags.locale);
41
+ } else {
42
+ CliUx.ux.action.start('Getting available languages', '', { stdout: true });
43
+ const languages = await downloadLanguages(params);
44
+ _.each(languages.data, (entry) => {
45
+ if (entry.code) {
46
+ locales.push(entry.code);
47
+ }
48
+ });
49
+ }
50
+ for (let i = 0; i < locales.length; i += 1) {
51
+ params.locale = locales[i];
52
+ CliUx.ux.action.start(
53
+ `Pulling content for ${params.locale.green} locale (${i + 1} of ${locales.length})`,
54
+ '',
55
+ { stdout: true },
56
+ );
57
+ const { data } = await downloadPhrases(params);
58
+ const json = flags.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
59
+ if (flags.folder) {
60
+ fs.writeFileSync(path.join(flags.folder, `${params.locale}.json`), json);
61
+ }
62
+ if (!flags.folder) {
63
+ this.log(json);
64
+ }
65
+ }
66
+ CliUx.ux.action.stop('Done'.green);
67
+ } catch (err) {
68
+ CliUx.ux.action.stop('Failed'.red);
69
+ this.error(err);
70
+ }
71
+ }
72
+ }
73
+
74
+ PullCommand.description = `Pull content from Transifex for offline caching
75
+ Get content as JSON files, to be used by mobile Javascript SDKs for
76
+ offline support or warming up the cache with initial translations.
77
+
78
+ By default, JSON files are printed in the console,
79
+ unless the "-f foldername" parameter is provided. In that case
80
+ the JSON files will be downloaded to that folder with the <locale>.json format.
81
+
82
+ To pull content some environment variables must be set:
83
+ TRANSIFEX_TOKEN=<Transifex Native Project Token>
84
+ TRANSIFEX_SECRET=<Transifex Native Project Secret>
85
+ (optional) TRANSIFEX_CDS_HOST=<CDS HOST>
86
+
87
+ or passed as --token=<TOKEN> --secret=<SECRET> parameters
88
+
89
+ Default CDS Host is https://cds.svc.transifex.net
90
+
91
+ Examples:
92
+ txjs-cli pull
93
+ txjs-cli pull --pretty
94
+ txjs-cli pull -f languages/
95
+ txjs-cli pull --locale=fr -f .
96
+ txjs-cli pull --filter-tags="foo,bar"
97
+ txjs-cli pull --filter-status="reviewed"
98
+ txjs-cli pull --token=mytoken --secret=mysecret
99
+ TRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli pull
100
+ `;
101
+
102
+ PullCommand.args = [];
103
+
104
+ PullCommand.flags = {
105
+ token: Flags.string({
106
+ description: 'native project public token',
107
+ default: '',
108
+ }),
109
+ secret: Flags.string({
110
+ description: 'native project secret',
111
+ default: '',
112
+ }),
113
+ folder: Flags.string({
114
+ char: 'f',
115
+ description: 'output as files to folder',
116
+ default: '',
117
+ }),
118
+ locale: Flags.string({
119
+ char: 'l',
120
+ description: 'pull specific language locale code',
121
+ default: '',
122
+ }),
123
+ pretty: Flags.boolean({
124
+ description: 'beautify JSON output',
125
+ default: false,
126
+ }),
127
+ 'filter-tags': Flags.string({
128
+ description: 'filter over specific tags',
129
+ default: '',
130
+ }),
131
+ 'filter-status': Flags.string({
132
+ description: 'filter over translation status',
133
+ default: '',
134
+ options: ['reviewed', 'proofread', 'finalized'],
135
+ }),
136
+ 'cds-host': Flags.string({
137
+ description: 'CDS host URL',
138
+ default: '',
139
+ }),
140
+ };
141
+
142
+ module.exports = PullCommand;
@@ -5,10 +5,10 @@ require('@colors/colors');
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
7
  const _ = require('lodash');
8
- const { Command, flags } = require('@oclif/command');
8
+ const { Command, Flags } = require('@oclif/core');
9
9
  const shelljs = require('shelljs');
10
10
  const { glob } = require('glob');
11
- const { cli } = require('cli-ux');
11
+ const { CliUx } = require('@oclif/core');
12
12
  const { extractPhrases } = require('../api/extract');
13
13
  const { uploadPhrases, pollJob } = require('../api/upload');
14
14
  const { mergePayload } = require('../api/merge');
@@ -31,7 +31,7 @@ function isFolder(path) {
31
31
 
32
32
  class PushCommand extends Command {
33
33
  async run() {
34
- const { args, flags } = this.parse(PushCommand);
34
+ const { args, flags } = await this.parse(PushCommand);
35
35
  const pwd = `${shelljs.pwd()}`;
36
36
  let filePattern = path.isAbsolute(args.pattern)
37
37
  ? args.pattern
@@ -61,7 +61,7 @@ class PushCommand extends Command {
61
61
  const payload = {};
62
62
  const tree = {};
63
63
 
64
- const bar = cli.progress({
64
+ const bar = CliUx.ux.progress({
65
65
  format: '⸨{bar}⸩ {value}/{total} {file}',
66
66
  barCompleteChar: '\u2588',
67
67
  barIncompleteChar: '⠂',
@@ -137,7 +137,7 @@ class PushCommand extends Command {
137
137
  }
138
138
  }
139
139
 
140
- if (!flags['dry-run']) {
140
+ if (!flags.fake) {
141
141
  if (_.isEmpty(payload)) {
142
142
  this.log('⚠ Nothing to upload.'.yellow);
143
143
  process.exit();
@@ -157,20 +157,23 @@ class PushCommand extends Command {
157
157
  process.exit();
158
158
  }
159
159
 
160
- const uploadMessage = 'Uploading content to Transifex';
160
+ const uploadMessage = flags['dry-run']
161
+ ? 'Uploading content to Transifex (dry run, no changes will be applied)'
162
+ : 'Uploading content to Transifex';
161
163
 
162
164
  this.log('');
163
- cli.action.start(uploadMessage, '', { stdout: true });
165
+ CliUx.ux.action.start(uploadMessage, '', { stdout: true });
164
166
  try {
165
167
  let res = await uploadPhrases(payload, {
166
168
  url: cdsHost,
167
169
  token: projectToken,
168
170
  secret: projectSecret,
169
171
  purge: flags.purge,
172
+ dry_run: flags['dry-run'],
170
173
  });
171
174
 
172
175
  if (flags['no-wait']) {
173
- cli.action.stop('Queued'.green);
176
+ CliUx.ux.action.stop('Queued'.green);
174
177
  return;
175
178
  }
176
179
 
@@ -178,7 +181,7 @@ class PushCommand extends Command {
178
181
  const jobUrl = `${cdsHost}${res.jobUrl}`;
179
182
  let status = '';
180
183
  do {
181
- await cli.wait(1500);
184
+ await CliUx.ux.wait(1500);
182
185
  res = await pollJob({
183
186
  url: jobUrl,
184
187
  token: projectToken,
@@ -188,10 +191,10 @@ class PushCommand extends Command {
188
191
  status = res.status;
189
192
  switch (status) {
190
193
  case 'pending':
191
- cli.action.start(uploadMessage, 'In queue', { stdout: true });
194
+ CliUx.ux.action.start(uploadMessage, 'In queue', { stdout: true });
192
195
  break;
193
196
  case 'processing':
194
- cli.action.start(uploadMessage, 'Processing', { stdout: true });
197
+ CliUx.ux.action.start(uploadMessage, 'Processing', { stdout: true });
195
198
  break;
196
199
  default:
197
200
  break;
@@ -200,7 +203,7 @@ class PushCommand extends Command {
200
203
  } while (status === 'pending' || status === 'processing');
201
204
 
202
205
  if (status === 'completed') {
203
- cli.action.stop('Success'.green);
206
+ CliUx.ux.action.stop('Success'.green);
204
207
  this.log(`${'✓'.green} Successfully pushed strings to Transifex:`);
205
208
  if (res.created > 0) {
206
209
  this.log(` Created strings: ${res.created.toString().green}`);
@@ -218,20 +221,20 @@ class PushCommand extends Command {
218
221
  this.log(` Failed strings: ${res.failed.toString().red}`);
219
222
  }
220
223
  } else {
221
- cli.action.stop('Failed'.red);
224
+ CliUx.ux.action.stop('Failed'.red);
222
225
  }
223
226
  _.each(res.errors, (error) => {
224
227
  this.log(`Error: ${JSON.stringify(error).red}`);
225
228
  });
226
229
  } catch (err) {
227
- cli.action.stop('Failed'.red);
230
+ CliUx.ux.action.stop('Failed'.red);
228
231
  this.error(err);
229
232
  }
230
233
  }
231
234
  }
232
235
  }
233
236
 
234
- PushCommand.description = `detect and push source content to Transifex
237
+ PushCommand.description = `Detect and push source content to Transifex
235
238
  Parse .js, .ts, .jsx, .tsx and .html files and detect phrases marked for
236
239
  translation by Transifex Native toolkit for Javascript and
237
240
  upload them to Transifex for translation.
@@ -251,6 +254,7 @@ txjs-cli push src/
251
254
  txjs-cli push /home/repo/src
252
255
  txjs-cli push "*.js"
253
256
  txjs-cli push --dry-run
257
+ txjs-cli push --fake -v
254
258
  txjs-cli push --no-wait
255
259
  txjs-cli push --key-generator=hash
256
260
  txjs-cli push --append-tags="master,release:2.5"
@@ -258,6 +262,7 @@ txjs-cli push --with-tags-only="home,error"
258
262
  txjs-cli push --without-tags-only="custom"
259
263
  txjs-cli push --token=mytoken --secret=mysecret
260
264
  txjs-cli push en.json --parser=i18next
265
+ txjs-cli push en.json --parser=txnativejson
261
266
  TRANSIFEX_TOKEN=mytoken TRANSIFEX_SECRET=mysecret txjs-cli push
262
267
  `;
263
268
 
@@ -269,53 +274,57 @@ PushCommand.args = [{
269
274
  }];
270
275
 
271
276
  PushCommand.flags = {
272
- 'dry-run': flags.boolean({
273
- description: 'dry run, do not push to Transifex',
277
+ 'dry-run': Flags.boolean({
278
+ description: 'dry run, do not apply changes in Transifex',
274
279
  default: false,
275
280
  }),
276
- verbose: flags.boolean({
281
+ fake: Flags.boolean({
282
+ description: 'do not push content to remote server',
283
+ default: false,
284
+ }),
285
+ verbose: Flags.boolean({
277
286
  char: 'v',
278
287
  description: 'verbose output',
279
288
  default: false,
280
289
  }),
281
- purge: flags.boolean({
290
+ purge: Flags.boolean({
282
291
  description: 'purge content on Transifex',
283
292
  default: false,
284
293
  }),
285
- 'no-wait': flags.boolean({
294
+ 'no-wait': Flags.boolean({
286
295
  description: 'disable polling for upload results',
287
296
  default: false,
288
297
  }),
289
- token: flags.string({
298
+ token: Flags.string({
290
299
  description: 'native project public token',
291
300
  default: '',
292
301
  }),
293
- secret: flags.string({
302
+ secret: Flags.string({
294
303
  description: 'native project secret',
295
304
  default: '',
296
305
  }),
297
- 'append-tags': flags.string({
306
+ 'append-tags': Flags.string({
298
307
  description: 'append tags to strings',
299
308
  default: '',
300
309
  }),
301
- 'with-tags-only': flags.string({
310
+ 'with-tags-only': Flags.string({
302
311
  description: 'push strings with specific tags',
303
312
  default: '',
304
313
  }),
305
- 'without-tags-only': flags.string({
314
+ 'without-tags-only': Flags.string({
306
315
  description: 'push strings without specific tags',
307
316
  default: '',
308
317
  }),
309
- 'cds-host': flags.string({
318
+ 'cds-host': Flags.string({
310
319
  description: 'CDS host URL',
311
320
  default: '',
312
321
  }),
313
- parser: flags.string({
322
+ parser: Flags.string({
314
323
  description: 'file parser to use',
315
324
  default: 'auto',
316
- options: ['auto', 'i18next'],
325
+ options: ['auto', 'i18next', 'txnativejson'],
317
326
  }),
318
- 'key-generator': flags.string({
327
+ 'key-generator': Flags.string({
319
328
  description: 'use hashed or source based keys',
320
329
  default: 'source',
321
330
  options: ['source', 'hash'],
package/src/index.js CHANGED
@@ -1 +1,3 @@
1
- module.exports = require('@oclif/command');
1
+ const { run } = require('@oclif/core');
2
+
3
+ module.exports = run;