i18nexus-cli 3.6.0 → 3.7.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 +15 -7
- package/baseUrl.js +1 -1
- package/bin/index.js +0 -2
- package/commands/listen.js +44 -94
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -315,9 +315,20 @@ A personal access token that you have generated in your i18nexus account (Can al
|
|
|
315
315
|
i18nexus listen -k <PROJECT_API_KEY>
|
|
316
316
|
```
|
|
317
317
|
|
|
318
|
-
This command
|
|
318
|
+
This command opens a WebSocket connection from your local environment to the i18nexus servers to receive real-time updates whenever strings are added, updated, or deleted in your project.
|
|
319
319
|
|
|
320
|
-
When
|
|
320
|
+
When changes occur, your local JSON files are automatically refreshed to stay in sync.
|
|
321
|
+
|
|
322
|
+
Many developers prefer to run this automatically alongside their development server. For example, in a Next.js project, you can do the following in your `package.json` using [concurrently](https://www.npmjs.com/package/concurrently):
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
"scripts": {
|
|
326
|
+
"dev": "concurrently --raw \"next dev --turbo\" \"i18nexus listen\"",
|
|
327
|
+
"build": "i18nexus pull && next build",
|
|
328
|
+
"start": "i18nexus pull && next start",
|
|
329
|
+
"lint": "next lint"
|
|
330
|
+
}
|
|
331
|
+
```
|
|
321
332
|
|
|
322
333
|
### Options
|
|
323
334
|
|
|
@@ -325,14 +336,11 @@ When a string is added, updated, or deleted in your project, a webhook is sent t
|
|
|
325
336
|
| ------------------- | --------- | ----------------------- |
|
|
326
337
|
| `--api-key` or `-k` | ✔ | |
|
|
327
338
|
| `--path` or `-p` | | See `pull` default path |
|
|
328
|
-
| `--port` | | '3002' |
|
|
329
339
|
|
|
330
340
|
### Notes
|
|
331
341
|
|
|
332
342
|
`--api-key`
|
|
333
343
|
Your project API key (Can also be set using environment variable `I18NEXUS_API_KEY`)
|
|
334
344
|
|
|
335
|
-
`--
|
|
336
|
-
The
|
|
337
|
-
|
|
338
|
-
The tunnel will remain active as long as the CLI is running. Press `Ctrl+C` to stop listening.
|
|
345
|
+
`--path`
|
|
346
|
+
The path to the destination folder in which translation files will be downloaded
|
package/baseUrl.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = 'https://api.i18nexus.com';
|
|
1
|
+
module.exports = process.env.I18NEXUS_API_ORIGIN || 'https://api.i18nexus.com';
|
package/bin/index.js
CHANGED
|
@@ -268,11 +268,9 @@ program
|
|
|
268
268
|
'-p, --path <path>',
|
|
269
269
|
'The path to the destination folder in which translation files will be downloaded'
|
|
270
270
|
)
|
|
271
|
-
.option('--port <port>', 'Port your local dev server runs on', '3002')
|
|
272
271
|
.action(options => {
|
|
273
272
|
listen({
|
|
274
273
|
apiKey: options.apiKey,
|
|
275
|
-
port: options.port,
|
|
276
274
|
path: options.path
|
|
277
275
|
});
|
|
278
276
|
});
|
package/commands/listen.js
CHANGED
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const http = require('http');
|
|
5
|
-
const localtunnel = require('localtunnel');
|
|
2
|
+
const WebSocket = require('ws');
|
|
6
3
|
const colors = require('colors');
|
|
7
|
-
const handleFetch = require('../handleFetch');
|
|
8
|
-
const baseUrl = require('../baseUrl');
|
|
9
4
|
const pull = require('../commands/pull');
|
|
5
|
+
const baseUrl = require('../baseUrl');
|
|
6
|
+
const { URL } = require('url');
|
|
10
7
|
|
|
11
|
-
const
|
|
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
|
-
|
|
8
|
+
const listen = async ({ apiKey, path }) => {
|
|
21
9
|
await pull(
|
|
22
10
|
{
|
|
23
11
|
apiKey,
|
|
24
12
|
version: 'latest',
|
|
25
|
-
path
|
|
13
|
+
path,
|
|
26
14
|
clean: false,
|
|
27
15
|
confirmed: false
|
|
28
16
|
},
|
|
@@ -32,22 +20,37 @@ const listen = async ({ apiKey, port, path }) => {
|
|
|
32
20
|
}
|
|
33
21
|
);
|
|
34
22
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
const wsUrl = new URL(`${baseUrl.replace(/^http/, 'ws')}/cable`);
|
|
24
|
+
wsUrl.searchParams.set('api_key', apiKey);
|
|
25
|
+
|
|
26
|
+
const ws = new WebSocket(wsUrl.toString(), {
|
|
27
|
+
headers: {
|
|
28
|
+
Origin: 'http://cli.i18nexus.com'
|
|
40
29
|
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
ws.on('open', () => {
|
|
33
|
+
console.log(colors.green('Listening for i18nexus string updates...'));
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
ws.send(
|
|
36
|
+
JSON.stringify({
|
|
37
|
+
command: 'subscribe',
|
|
38
|
+
identifier: JSON.stringify({ channel: 'CliListenChannel' })
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
ws.on('message', async message => {
|
|
44
|
+
try {
|
|
45
|
+
const data = JSON.parse(message);
|
|
46
|
+
const payload = data.message;
|
|
47
|
+
|
|
48
|
+
if (payload?.event === 'strings.changed') {
|
|
46
49
|
await pull(
|
|
47
50
|
{
|
|
48
51
|
apiKey,
|
|
49
52
|
version: 'latest',
|
|
50
|
-
path
|
|
53
|
+
path,
|
|
51
54
|
clean: false,
|
|
52
55
|
confirmed: false
|
|
53
56
|
},
|
|
@@ -56,81 +59,28 @@ const listen = async ({ apiKey, port, path }) => {
|
|
|
56
59
|
successLog: ' ✔ Translations updated'
|
|
57
60
|
}
|
|
58
61
|
);
|
|
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
62
|
}
|
|
65
|
-
})
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error(colors.red('i18nexus Sync Failed'));
|
|
65
|
+
}
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
server.listen(port, async () => {
|
|
71
|
-
res(await localtunnel({ port }));
|
|
72
|
-
});
|
|
68
|
+
ws.on('close', () => {
|
|
69
|
+
process.exit(1);
|
|
73
70
|
});
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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;
|
|
72
|
+
ws.on('error', err => {
|
|
73
|
+
console.error(colors.red('i18nexus Connection Error'));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
});
|
|
100
76
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
body: JSON.stringify({ api_key: apiKey, id: webhookId })
|
|
105
|
-
});
|
|
106
|
-
} catch (e) {}
|
|
107
|
-
tunnel.close();
|
|
108
|
-
server.close();
|
|
109
|
-
process.exit(exitCode);
|
|
77
|
+
const cleanUp = () => {
|
|
78
|
+
ws.close();
|
|
79
|
+
process.exit(0);
|
|
110
80
|
};
|
|
111
81
|
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
});
|
|
82
|
+
process.on('SIGINT', cleanUp);
|
|
83
|
+
process.on('SIGTERM', cleanUp);
|
|
134
84
|
};
|
|
135
85
|
|
|
136
86
|
module.exports = listen;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18nexus-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Command line interface (CLI) for accessing the i18nexus API",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"colors": "^1.4.0",
|
|
21
21
|
"commander": "^7.2.0",
|
|
22
22
|
"https-proxy-agent": "^5.0.0",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
23
|
+
"node-fetch": "^2.6.7",
|
|
24
|
+
"ws": "^8.18.3"
|
|
25
25
|
}
|
|
26
26
|
}
|