i18nexus-cli 3.4.0 → 3.6.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 +78 -36
- package/bin/index.js +74 -18
- package/commands/addString.js +9 -2
- package/commands/listen.js +136 -0
- package/commands/pull.js +10 -3
- package/commands/updateString.js +2 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
[i18nexus](https://i18nexus.com) is a translation management web application designed for use with i18next, next-intl, and react-intl. Learn more with these quick tutorials:
|
|
8
8
|
|
|
9
|
-
- [react-i18next Walkthrough](https://i18nexus.com/tutorials/react/react-i18next)
|
|
10
|
-
- [react-intl Walkthrough](https://i18nexus.com/tutorials/react/react-intl)
|
|
11
9
|
- [next-intl for Next.js App Router Walkthrough](https://i18nexus.com/tutorials/nextjs/next-intl)
|
|
12
10
|
- [react-i18next for Next.js App Router Walkthrough](https://i18nexus.com/tutorials/nextjs/react-i18next)
|
|
13
11
|
- [next-i18next for Next.js Pages Router Walkthrough](https://i18nexus.com/tutorials/nextjs/next-i18next)
|
|
12
|
+
- [react-i18next Walkthrough](https://i18nexus.com/tutorials/react/react-i18next)
|
|
13
|
+
- [react-intl Walkthrough](https://i18nexus.com/tutorials/react/react-intl)
|
|
14
14
|
|
|
15
15
|
## Who is this CLI meant for?
|
|
16
16
|
|
|
@@ -130,14 +130,15 @@ Translations for the string will be automatically generated and machine translat
|
|
|
130
130
|
|
|
131
131
|
### Options
|
|
132
132
|
|
|
133
|
-
| Option
|
|
134
|
-
|
|
|
135
|
-
| `--api-key` or `-k`
|
|
136
|
-
| `--pat` or `-t`
|
|
137
|
-
| `--
|
|
138
|
-
| `--
|
|
139
|
-
| `--
|
|
140
|
-
| `--
|
|
133
|
+
| Option | Required? |
|
|
134
|
+
| ---------------------------- | ------------- |
|
|
135
|
+
| `--api-key` or `-k` | ✔ |
|
|
136
|
+
| `--pat` or `-t` | ✔ |
|
|
137
|
+
| `--key` or `-K` | ✔ |
|
|
138
|
+
| `--value` or `-v` | ✔ |
|
|
139
|
+
| `--namespace` or `-ns` | Conditionally |
|
|
140
|
+
| `--notes` or `-n` | |
|
|
141
|
+
| `--ai-instructions` or `-ai` | |
|
|
141
142
|
|
|
142
143
|
### Notes
|
|
143
144
|
|
|
@@ -148,7 +149,7 @@ Your project API key (Can also be set using environment variable `I18NEXUS_API_K
|
|
|
148
149
|
A personal access token that you have generated in your i18nexus account (Can also be set using environment variable `I18NEXUS_PERSONAL_ACCESS_TOKEN`)
|
|
149
150
|
|
|
150
151
|
`--namespace`
|
|
151
|
-
The namespace in which to create the string
|
|
152
|
+
The namespace in which to create the string. Only required if your project uses namespaces and has more than one namespace.
|
|
152
153
|
|
|
153
154
|
`--key`
|
|
154
155
|
The key of the string to create
|
|
@@ -156,35 +157,39 @@ The key of the string to create
|
|
|
156
157
|
`--value`
|
|
157
158
|
The value of the string to create
|
|
158
159
|
|
|
159
|
-
`--
|
|
160
|
-
|
|
160
|
+
`--notes`
|
|
161
|
+
Team notes about the string to create (optional)
|
|
162
|
+
|
|
163
|
+
`--ai-instructions`
|
|
164
|
+
Instructions or context for AI machine translator (optional)
|
|
161
165
|
|
|
162
166
|
## Updating existing strings
|
|
163
167
|
|
|
164
|
-
`i18nexus update-string <namespace
|
|
168
|
+
`i18nexus update-string <namespace:key>` or `i18nexus u <namespace:key>`
|
|
165
169
|
|
|
166
170
|
```sh
|
|
167
|
-
i18nexus u common
|
|
171
|
+
i18nexus u common:welcome_msg -v 'Welcome' -k <PROJECT_API_KEY> -t <YOUR_PERSONAL_ACCESS_TOKEN>
|
|
168
172
|
```
|
|
169
173
|
|
|
170
174
|
The above snippet will update a the value of the string with key `welcome_msg` in your `common` namespace to `Welcome`.
|
|
171
175
|
|
|
172
|
-
The
|
|
176
|
+
The required argument is the namespace and the key of the string you wish to update, joined with a colon (":"). If your project does not use namespaces or only has one namespace, only the key is necessary.
|
|
173
177
|
|
|
174
178
|
You can then update the key, value, details, and/or namespace by using the command options:
|
|
175
179
|
|
|
176
180
|
### Options
|
|
177
181
|
|
|
178
|
-
| Option
|
|
179
|
-
|
|
|
180
|
-
| `--api-key` or `-k`
|
|
181
|
-
| `--pat` or `-t`
|
|
182
|
-
| `--namespace` or `-ns`
|
|
183
|
-
| `--key` or `-K`
|
|
184
|
-
| `--value` or `-v`
|
|
185
|
-
| `--details` or `-d`
|
|
186
|
-
| `--
|
|
187
|
-
| `--
|
|
182
|
+
| Option | Required? |
|
|
183
|
+
| ---------------------------- | --------- |
|
|
184
|
+
| `--api-key` or `-k` | ✔ |
|
|
185
|
+
| `--pat` or `-t` | ✔ |
|
|
186
|
+
| `--namespace` or `-ns` | |
|
|
187
|
+
| `--key` or `-K` | |
|
|
188
|
+
| `--value` or `-v` | |
|
|
189
|
+
| `--details` or `-d` | |
|
|
190
|
+
| `--ai-instructions` or `-ai` | |
|
|
191
|
+
| `--reset-confirmed` | |
|
|
192
|
+
| `--retain-confirmed` | |
|
|
188
193
|
|
|
189
194
|
### Notes
|
|
190
195
|
|
|
@@ -203,8 +208,11 @@ The new key of the string
|
|
|
203
208
|
`--value`
|
|
204
209
|
The new value of the string
|
|
205
210
|
|
|
206
|
-
`--
|
|
207
|
-
The new
|
|
211
|
+
`--notes`
|
|
212
|
+
The new team notes of the string
|
|
213
|
+
|
|
214
|
+
`--ai-instructions`
|
|
215
|
+
Instructions or context for AI machine translator
|
|
208
216
|
|
|
209
217
|
#### If you are updating the value of a string that contains translations that have been marked confirmed in i18nexus, you will be required to include one of the following options to your command:
|
|
210
218
|
|
|
@@ -216,13 +224,13 @@ Confirmed translations of this string will be retained
|
|
|
216
224
|
|
|
217
225
|
## Deleting strings
|
|
218
226
|
|
|
219
|
-
`i18nexus delete-string <namespace
|
|
227
|
+
`i18nexus delete-string <namespace:key>` or `i18nexus d <namespace:key>`
|
|
220
228
|
|
|
221
229
|
```sh
|
|
222
|
-
i18nexus d common
|
|
230
|
+
i18nexus d common:welcome_msg -k <PROJECT_API_KEY> -t <YOUR_PERSONAL_ACCESS_TOKEN>
|
|
223
231
|
```
|
|
224
232
|
|
|
225
|
-
The
|
|
233
|
+
The required argument is the namespace and the key of the string you wish to delete, joined with a colon (":"). If your project does not use namespaces or only has one namespace, only the key is necessary.
|
|
226
234
|
|
|
227
235
|
### Options
|
|
228
236
|
|
|
@@ -253,11 +261,12 @@ This is the equivalent of using the Import tool in the i18nexus web application.
|
|
|
253
261
|
|
|
254
262
|
### Options
|
|
255
263
|
|
|
256
|
-
| Option
|
|
257
|
-
|
|
|
258
|
-
| `--api-key` or `-k`
|
|
259
|
-
| `--pat` or `-t`
|
|
260
|
-
| `--
|
|
264
|
+
| Option | Required? |
|
|
265
|
+
| ---------------------- | ------------- |
|
|
266
|
+
| `--api-key` or `-k` | ✔ |
|
|
267
|
+
| `--pat` or `-t` | ✔ |
|
|
268
|
+
| `--namespace` or `-ns` | Conditionally |
|
|
269
|
+
| `--overwrite` | |
|
|
261
270
|
|
|
262
271
|
### Notes
|
|
263
272
|
|
|
@@ -267,6 +276,9 @@ Your project API key (Can also be set using environment variable `I18NEXUS_API_K
|
|
|
267
276
|
`--pat`
|
|
268
277
|
A personal access token that you have generated in your i18nexus account (Can also be set using environment variable `I18NEXUS_PERSONAL_ACCESS_TOKEN`)
|
|
269
278
|
|
|
279
|
+
`--namespace`
|
|
280
|
+
The namespace in which your strings will be imported. (Only required if your project uses namespaces and has more than one namespace)
|
|
281
|
+
|
|
270
282
|
`--overwrite`
|
|
271
283
|
If any keys already exist in the target namespace, overwrite the values with the imported values.
|
|
272
284
|
|
|
@@ -294,3 +306,33 @@ Your project API key (Can also be set using environment variable `I18NEXUS_API_K
|
|
|
294
306
|
|
|
295
307
|
`--pat`
|
|
296
308
|
A personal access token that you have generated in your i18nexus account (Can also be set using environment variable `I18NEXUS_PERSONAL_ACCESS_TOKEN`)
|
|
309
|
+
|
|
310
|
+
## Listening for live translation updates
|
|
311
|
+
|
|
312
|
+
`i18nexus listen`
|
|
313
|
+
|
|
314
|
+
```sh
|
|
315
|
+
i18nexus listen -k <PROJECT_API_KEY>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
This command starts a tunnel to your local development server using [localtunnel](https://www.npmjs.com/package/localtunnel), allowing i18nexus to send real-time webhooks for translation updates.
|
|
319
|
+
|
|
320
|
+
When a string is added, updated, or deleted in your project, a webhook is sent to your local server, automatically updating your local JSON files.
|
|
321
|
+
|
|
322
|
+
### Options
|
|
323
|
+
|
|
324
|
+
| Option | Required? | Default |
|
|
325
|
+
| ------------------- | --------- | ----------------------- |
|
|
326
|
+
| `--api-key` or `-k` | ✔ | |
|
|
327
|
+
| `--path` or `-p` | | See `pull` default path |
|
|
328
|
+
| `--port` | | '3002' |
|
|
329
|
+
|
|
330
|
+
### Notes
|
|
331
|
+
|
|
332
|
+
`--api-key`
|
|
333
|
+
Your project API key (Can also be set using environment variable `I18NEXUS_API_KEY`)
|
|
334
|
+
|
|
335
|
+
`--port`
|
|
336
|
+
The local port your server will listen on to receive incoming webhook requests from i18nexus. Defaults to `3002`.
|
|
337
|
+
|
|
338
|
+
The tunnel will remain active as long as the CLI is running. Press `Ctrl+C` to stop listening.
|
package/bin/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const updateString = require('../commands/updateString');
|
|
|
8
8
|
const deleteString = require('../commands/deleteString');
|
|
9
9
|
const importJson = require('../commands/importJson');
|
|
10
10
|
const addNamespace = require('../commands/addNamespace');
|
|
11
|
+
const listen = require('../commands/listen');
|
|
11
12
|
|
|
12
13
|
// Using Next's env variable loader because
|
|
13
14
|
// Next supports more than just one .env file
|
|
@@ -75,27 +76,32 @@ program
|
|
|
75
76
|
'-v, --value <stringValue>',
|
|
76
77
|
'The value of the string to create'
|
|
77
78
|
)
|
|
78
|
-
.
|
|
79
|
+
.option(
|
|
79
80
|
'-ns, --namespace <stringNamespace>',
|
|
80
|
-
'The namespace in which to create the string'
|
|
81
|
+
'The namespace in which to create the string (Only required if your project uses namespaces and has more than one namespace)'
|
|
82
|
+
)
|
|
83
|
+
.option(
|
|
84
|
+
'-n, --notes <teamNotes>',
|
|
85
|
+
'Team notes about the string to create (optional)'
|
|
81
86
|
)
|
|
82
87
|
.option(
|
|
83
|
-
'-
|
|
84
|
-
'
|
|
88
|
+
'-ai, --ai-instructions <stringAiInstructions>',
|
|
89
|
+
'Instructions/Context for AI machine translator (optional)'
|
|
85
90
|
)
|
|
86
91
|
.action(options => {
|
|
87
92
|
addString({
|
|
88
93
|
key: options.key,
|
|
89
94
|
value: options.value,
|
|
90
|
-
|
|
95
|
+
notes: options.notes,
|
|
91
96
|
namespace: options.namespace,
|
|
92
97
|
apiKey: options.apiKey,
|
|
93
|
-
pat: options.pat
|
|
98
|
+
pat: options.pat,
|
|
99
|
+
aiInstructions: options.aiInstructions
|
|
94
100
|
});
|
|
95
101
|
});
|
|
96
102
|
|
|
97
103
|
program
|
|
98
|
-
.command('update-string <
|
|
104
|
+
.command('update-string <namespace:key>')
|
|
99
105
|
.alias('u')
|
|
100
106
|
.description('Update a base string through PATCH request')
|
|
101
107
|
.requiredOption(
|
|
@@ -114,7 +120,11 @@ program
|
|
|
114
120
|
'-ns, --namespace <stringNamespace>',
|
|
115
121
|
'The new namespace of the string'
|
|
116
122
|
)
|
|
117
|
-
.option('-
|
|
123
|
+
.option('-n, --notes <teamNotes>', 'The new team notes of the string')
|
|
124
|
+
.option(
|
|
125
|
+
'-ai, --ai-instructions <stringAiInstructions>',
|
|
126
|
+
'Instructions/Context for AI machine translator (optional)'
|
|
127
|
+
)
|
|
118
128
|
.option(
|
|
119
129
|
'--reset-confirmed',
|
|
120
130
|
'Reset confirmed translations of this string with machine translations.'
|
|
@@ -123,15 +133,27 @@ program
|
|
|
123
133
|
'--retain-confirmed',
|
|
124
134
|
'Do not reset confirmed translations of this string with machine translations.'
|
|
125
135
|
)
|
|
126
|
-
.action((
|
|
136
|
+
.action((nsKey, options) => {
|
|
137
|
+
let ns, key;
|
|
138
|
+
const split = nsKey.split(':');
|
|
139
|
+
|
|
140
|
+
if (split.length === 1) {
|
|
141
|
+
key = nsKey;
|
|
142
|
+
} else {
|
|
143
|
+
ns = split[0];
|
|
144
|
+
// in case key contains :
|
|
145
|
+
key = split.slice(1).join(':');
|
|
146
|
+
}
|
|
147
|
+
|
|
127
148
|
updateString({
|
|
128
149
|
id: {
|
|
129
|
-
namespace:
|
|
130
|
-
key:
|
|
150
|
+
namespace: ns,
|
|
151
|
+
key: key
|
|
131
152
|
},
|
|
132
153
|
key: options.key,
|
|
133
154
|
value: options.value,
|
|
134
|
-
|
|
155
|
+
notes: options.notes,
|
|
156
|
+
aiInstructions: options.aiInstructions,
|
|
135
157
|
namespace: options.namespace,
|
|
136
158
|
apiKey: options.apiKey,
|
|
137
159
|
pat: options.pat,
|
|
@@ -141,7 +163,7 @@ program
|
|
|
141
163
|
});
|
|
142
164
|
|
|
143
165
|
program
|
|
144
|
-
.command('delete-string <
|
|
166
|
+
.command('delete-string <namespace:key>')
|
|
145
167
|
.alias('d')
|
|
146
168
|
.description('Delete a base string and its translations')
|
|
147
169
|
.requiredOption(
|
|
@@ -154,11 +176,22 @@ program
|
|
|
154
176
|
'A personal access token generated for your account in i18nexus.',
|
|
155
177
|
process.env.I18NEXUS_PERSONAL_ACCESS_TOKEN
|
|
156
178
|
)
|
|
157
|
-
.action((
|
|
179
|
+
.action((nsKey, options) => {
|
|
180
|
+
let ns, key;
|
|
181
|
+
const split = nsKey.split(':');
|
|
182
|
+
|
|
183
|
+
if (split.length === 1) {
|
|
184
|
+
key = nsKey;
|
|
185
|
+
} else {
|
|
186
|
+
ns = split[0];
|
|
187
|
+
// in case key contains :
|
|
188
|
+
key = split.slice(1).join(':');
|
|
189
|
+
}
|
|
190
|
+
|
|
158
191
|
deleteString({
|
|
159
192
|
id: {
|
|
160
|
-
namespace:
|
|
161
|
-
key:
|
|
193
|
+
namespace: ns,
|
|
194
|
+
key: key
|
|
162
195
|
},
|
|
163
196
|
apiKey: options.apiKey,
|
|
164
197
|
pat: options.pat
|
|
@@ -180,9 +213,9 @@ program
|
|
|
180
213
|
'A personal access token generated for your account in i18nexus.',
|
|
181
214
|
process.env.I18NEXUS_PERSONAL_ACCESS_TOKEN
|
|
182
215
|
)
|
|
183
|
-
.
|
|
216
|
+
.option(
|
|
184
217
|
'-ns, --namespace <namespace>',
|
|
185
|
-
'The namespace in which your strings will be imported.'
|
|
218
|
+
'The namespace in which your strings will be imported. (Only required if your project uses namespaces and has more than one namespace)'
|
|
186
219
|
)
|
|
187
220
|
.option(
|
|
188
221
|
'--overwrite',
|
|
@@ -221,4 +254,27 @@ program
|
|
|
221
254
|
});
|
|
222
255
|
});
|
|
223
256
|
|
|
257
|
+
program
|
|
258
|
+
.command('listen')
|
|
259
|
+
.description(
|
|
260
|
+
'Register a live webhook for local development and setup tunnel to listen for updates to translations.'
|
|
261
|
+
)
|
|
262
|
+
.requiredOption(
|
|
263
|
+
'-k, --api-key <apiKey>',
|
|
264
|
+
'The API key for your project',
|
|
265
|
+
process.env.I18NEXUS_API_KEY
|
|
266
|
+
)
|
|
267
|
+
.option(
|
|
268
|
+
'-p, --path <path>',
|
|
269
|
+
'The path to the destination folder in which translation files will be downloaded'
|
|
270
|
+
)
|
|
271
|
+
.option('--port <port>', 'Port your local dev server runs on', '3002')
|
|
272
|
+
.action(options => {
|
|
273
|
+
listen({
|
|
274
|
+
apiKey: options.apiKey,
|
|
275
|
+
port: options.port,
|
|
276
|
+
path: options.path
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
224
280
|
program.parse(process.argv);
|
package/commands/addString.js
CHANGED
|
@@ -14,7 +14,8 @@ const addString = async opt => {
|
|
|
14
14
|
key: opt.key,
|
|
15
15
|
value: opt.value,
|
|
16
16
|
namespace: opt.namespace,
|
|
17
|
-
description: opt.
|
|
17
|
+
description: opt.notes,
|
|
18
|
+
ai_instructions: opt.aiInstructions
|
|
18
19
|
}),
|
|
19
20
|
headers: {
|
|
20
21
|
Authorization: `Bearer ${opt.pat}`,
|
|
@@ -28,7 +29,13 @@ const addString = async opt => {
|
|
|
28
29
|
|
|
29
30
|
await response.json();
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
if (opt.namespace) {
|
|
33
|
+
console.log(
|
|
34
|
+
colors.green(`New string added to namespace "${opt.namespace}":`)
|
|
35
|
+
);
|
|
36
|
+
} else {
|
|
37
|
+
console.log(colors.green(`New string added:`));
|
|
38
|
+
}
|
|
32
39
|
console.log(colors.green(`"${opt.key}": "${opt.value}"`));
|
|
33
40
|
};
|
|
34
41
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* commands/listen.js */
|
|
3
|
+
|
|
4
|
+
const http = require('http');
|
|
5
|
+
const localtunnel = require('localtunnel');
|
|
6
|
+
const colors = require('colors');
|
|
7
|
+
const handleFetch = require('../handleFetch');
|
|
8
|
+
const baseUrl = require('../baseUrl');
|
|
9
|
+
const pull = require('../commands/pull');
|
|
10
|
+
|
|
11
|
+
const LISTEN_PATH = '/webhook'; // fixed internal path
|
|
12
|
+
|
|
13
|
+
const listen = async ({ apiKey, port, path }) => {
|
|
14
|
+
port = Number(port);
|
|
15
|
+
|
|
16
|
+
if (!Number.isInteger(port) || port <= 0) {
|
|
17
|
+
console.log(colors.red('Invalid port'));
|
|
18
|
+
return process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await pull(
|
|
22
|
+
{
|
|
23
|
+
apiKey,
|
|
24
|
+
version: 'latest',
|
|
25
|
+
path: path,
|
|
26
|
+
clean: false,
|
|
27
|
+
confirmed: false
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
logging: false,
|
|
31
|
+
successLog: 'Latest strings downloaded'
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/* ────────────── 1. start local HTTP listener ────────────── */
|
|
36
|
+
const server = http.createServer(async (req, res) => {
|
|
37
|
+
if (req.method !== 'POST' || req.url !== LISTEN_PATH) {
|
|
38
|
+
res.writeHead(404).end();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let body = '';
|
|
43
|
+
req.on('data', chunk => (body += chunk));
|
|
44
|
+
req.on('end', async () => {
|
|
45
|
+
try {
|
|
46
|
+
await pull(
|
|
47
|
+
{
|
|
48
|
+
apiKey,
|
|
49
|
+
version: 'latest',
|
|
50
|
+
path: path,
|
|
51
|
+
clean: false,
|
|
52
|
+
confirmed: false
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
logging: false,
|
|
56
|
+
successLog: ' ✔ Translations updated'
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
res.writeHead(200).end('ok');
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error(colors.red('Failed to download translations:'), e);
|
|
63
|
+
res.writeHead(500).end('error');
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/* ────────────── 2. start tunnel ────────────── */
|
|
69
|
+
const tunnel = await new Promise(res => {
|
|
70
|
+
server.listen(port, async () => {
|
|
71
|
+
res(await localtunnel({ port }));
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const publicUrl = `${tunnel.url}${LISTEN_PATH}`;
|
|
76
|
+
|
|
77
|
+
/* ────────────── 3. register dev webhook with i18nexus ────────────── */
|
|
78
|
+
const createRes = await handleFetch(
|
|
79
|
+
`${baseUrl}/project_resources/dev_webhooks`,
|
|
80
|
+
{
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: { 'Content-Type': 'application/json' },
|
|
83
|
+
body: JSON.stringify({ api_key: apiKey, url: publicUrl })
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
let closing = false;
|
|
88
|
+
|
|
89
|
+
/* ────────────── graceful shutdown ────────────── */
|
|
90
|
+
const cleanUp = async (exitCode = 0) => {
|
|
91
|
+
if (closing) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
closing = true;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const { collection } = await createRes.json();
|
|
99
|
+
const webhookId = collection[0].id;
|
|
100
|
+
|
|
101
|
+
await handleFetch(`${baseUrl}/project_resources/dev_webhooks`, {
|
|
102
|
+
method: 'DELETE',
|
|
103
|
+
headers: { 'Content-Type': 'application/json' },
|
|
104
|
+
body: JSON.stringify({ api_key: apiKey, id: webhookId })
|
|
105
|
+
});
|
|
106
|
+
} catch (e) {}
|
|
107
|
+
tunnel.close();
|
|
108
|
+
server.close();
|
|
109
|
+
process.exit(exitCode);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
if (createRes.status !== 200) {
|
|
113
|
+
console.log(colors.red('Failed to register webhook with i18nexus'));
|
|
114
|
+
cleanUp(1);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log(colors.green('Listening for i18nexus updates…'));
|
|
119
|
+
|
|
120
|
+
process.on('SIGINT', () => cleanUp());
|
|
121
|
+
process.on('SIGTERM', () => cleanUp());
|
|
122
|
+
|
|
123
|
+
let connectionLost = false;
|
|
124
|
+
tunnel.on('error', () => {
|
|
125
|
+
if (connectionLost) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
connectionLost = true;
|
|
129
|
+
|
|
130
|
+
console.error(colors.red('i18nexus listener connection lost'));
|
|
131
|
+
|
|
132
|
+
cleanUp(1);
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
module.exports = listen;
|
package/commands/pull.js
CHANGED
|
@@ -22,7 +22,12 @@ const cleanDirectory = path => {
|
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
const pull = async opt => {
|
|
25
|
+
const pull = async (opt, internalOptions = {}) => {
|
|
26
|
+
const {
|
|
27
|
+
logging = true,
|
|
28
|
+
successLog = 'Translations downloaded successfully'
|
|
29
|
+
} = internalOptions;
|
|
30
|
+
|
|
26
31
|
let path = opt.path;
|
|
27
32
|
|
|
28
33
|
const project = await getProject(opt.apiKey);
|
|
@@ -66,7 +71,9 @@ const pull = async opt => {
|
|
|
66
71
|
return process.exit(1);
|
|
67
72
|
}
|
|
68
73
|
|
|
69
|
-
|
|
74
|
+
if (logging) {
|
|
75
|
+
console.log(`Downloading translations to ${path}...`);
|
|
76
|
+
}
|
|
70
77
|
|
|
71
78
|
const lngResponse = await handleFetch(
|
|
72
79
|
`${baseUrl}/project_resources/languages.json?api_key=${opt.apiKey}`
|
|
@@ -143,7 +150,7 @@ const pull = async opt => {
|
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
152
|
|
|
146
|
-
console.log(colors.green(
|
|
153
|
+
console.log(colors.green(successLog));
|
|
147
154
|
};
|
|
148
155
|
|
|
149
156
|
module.exports = pull;
|
package/commands/updateString.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18nexus-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Command line interface (CLI) for accessing the i18nexus API",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
"keywords": [
|
|
10
10
|
"i18nexus",
|
|
11
11
|
"cli",
|
|
12
|
-
"
|
|
12
|
+
"react-intl",
|
|
13
|
+
"i18next",
|
|
14
|
+
"next-intl"
|
|
13
15
|
],
|
|
14
16
|
"author": "i18nexus",
|
|
15
17
|
"license": "MIT",
|
|
@@ -18,6 +20,7 @@
|
|
|
18
20
|
"colors": "^1.4.0",
|
|
19
21
|
"commander": "^7.2.0",
|
|
20
22
|
"https-proxy-agent": "^5.0.0",
|
|
23
|
+
"localtunnel": "^2.0.2",
|
|
21
24
|
"node-fetch": "^2.6.7"
|
|
22
25
|
}
|
|
23
26
|
}
|