translatex 0.1.0 → 0.1.2
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 +3 -2
- package/bin/translatex.js +29 -14
- package/package.json +8 -5
- package/scripts/install.js +0 -126
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
`npm install -g translatex` puts a 6 MB static binary on `PATH`. 26 translation
|
|
6
6
|
providers raced in parallel, structured JSON out, one skill file for 24 coding
|
|
7
|
-
agents. The
|
|
8
|
-
|
|
7
|
+
agents. The binary ships in a per-platform package (`translatex-windows-x64`,
|
|
8
|
+
`translatex-darwin-arm64`, …) pulled in as an optional dependency, so the
|
|
9
|
+
install runs no scripts at all.
|
|
9
10
|
|
|
10
11
|
```bash
|
|
11
12
|
npm install -g translatex
|
package/bin/translatex.js
CHANGED
|
@@ -1,40 +1,55 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
//
|
|
4
|
+
// The native binary ships in a per-platform package declared as an optional
|
|
5
|
+
// dependency, so nothing runs at install time. That matters because npm 12
|
|
6
|
+
// blocks dependency install scripts by default: a download-on-install shim
|
|
7
|
+
// would silently install nothing.
|
|
6
8
|
|
|
7
9
|
const { spawn } = require('node:child_process');
|
|
8
10
|
const fs = require('node:fs');
|
|
9
11
|
const path = require('node:path');
|
|
10
12
|
|
|
11
|
-
const exe =
|
|
12
|
-
__dirname,
|
|
13
|
-
process.platform === 'win32' ? 'translatex.exe' : 'translatex'
|
|
14
|
-
);
|
|
13
|
+
const exe = process.platform === 'win32' ? 'translatex.exe' : 'translatex';
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
// npm blocks package names that look machine-generated, and "win32" trips its
|
|
16
|
+
// spam filter, so the Windows package is published as translatex-windows-x64.
|
|
17
|
+
const platformName = process.platform === 'win32' ? 'windows' : process.platform;
|
|
18
|
+
const platformPackage = `translatex-${platformName}-${process.arch}`;
|
|
19
|
+
|
|
20
|
+
function binaryFromPlatformPackage() {
|
|
21
|
+
let packageJson;
|
|
22
|
+
try {
|
|
23
|
+
packageJson = require.resolve(`${platformPackage}/package.json`);
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const candidate = path.join(path.dirname(packageJson), exe);
|
|
28
|
+
return fs.existsSync(candidate) ? candidate : null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const binary = process.env.TRANSLATEX_BINARY_PATH || binaryFromPlatformPackage();
|
|
32
|
+
|
|
33
|
+
if (!binary) {
|
|
17
34
|
process.stderr.write(
|
|
18
35
|
[
|
|
19
|
-
|
|
36
|
+
`translatex: no binary for ${process.platform}/${process.arch}.`,
|
|
20
37
|
'',
|
|
21
|
-
|
|
38
|
+
`The package ${platformPackage} is missing. Reinstall, or install from source:`,
|
|
22
39
|
' npm install -g translatex --force',
|
|
23
|
-
'',
|
|
24
|
-
'Or build from source:',
|
|
25
40
|
' cargo install translatex --locked',
|
|
26
41
|
'',
|
|
27
|
-
'If your platform has no prebuilt binary
|
|
42
|
+
'If your platform has no prebuilt binary, cargo is the way.',
|
|
28
43
|
'',
|
|
29
44
|
].join('\n')
|
|
30
45
|
);
|
|
31
46
|
process.exit(1);
|
|
32
47
|
}
|
|
33
48
|
|
|
34
|
-
const child = spawn(
|
|
49
|
+
const child = spawn(binary, process.argv.slice(2), { stdio: 'inherit' });
|
|
35
50
|
|
|
36
51
|
child.on('error', (err) => {
|
|
37
|
-
process.stderr.write(`translatex: failed to start ${
|
|
52
|
+
process.stderr.write(`translatex: failed to start ${binary}: ${err.message}\n`);
|
|
38
53
|
process.exit(1);
|
|
39
54
|
});
|
|
40
55
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "translatex",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Free translation CLI for AI agents: no API key, no signup, no config. 26 providers, JSON output, one 6 MB binary.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "w21180239",
|
|
@@ -32,14 +32,17 @@
|
|
|
32
32
|
"bin": {
|
|
33
33
|
"translatex": "bin/translatex.js"
|
|
34
34
|
},
|
|
35
|
-
"scripts": {
|
|
36
|
-
"postinstall": "node scripts/install.js"
|
|
37
|
-
},
|
|
38
35
|
"files": [
|
|
39
36
|
"bin/translatex.js",
|
|
40
|
-
"scripts/install.js",
|
|
41
37
|
"README.md"
|
|
42
38
|
],
|
|
39
|
+
"optionalDependencies": {
|
|
40
|
+
"translatex-darwin-arm64": "0.1.2",
|
|
41
|
+
"translatex-darwin-x64": "0.1.2",
|
|
42
|
+
"translatex-linux-arm64": "0.1.2",
|
|
43
|
+
"translatex-linux-x64": "0.1.2",
|
|
44
|
+
"translatex-windows-x64": "0.1.2"
|
|
45
|
+
},
|
|
43
46
|
"engines": {
|
|
44
47
|
"node": ">=18"
|
|
45
48
|
},
|
package/scripts/install.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// Downloads the prebuilt binary for this platform from the matching GitHub
|
|
5
|
-
// release. Falls back with a clear message when no asset exists, so the package
|
|
6
|
-
// never installs a broken shim silently.
|
|
7
|
-
|
|
8
|
-
const fs = require('node:fs');
|
|
9
|
-
const path = require('node:path');
|
|
10
|
-
const https = require('node:https');
|
|
11
|
-
|
|
12
|
-
const pkg = require('../package.json');
|
|
13
|
-
const REPO = 'w21180239/translatex';
|
|
14
|
-
|
|
15
|
-
const TARGETS = {
|
|
16
|
-
'darwin-x64': 'translatex-x86_64-apple-darwin',
|
|
17
|
-
'darwin-arm64': 'translatex-aarch64-apple-darwin',
|
|
18
|
-
'linux-x64': 'translatex-x86_64-unknown-linux-gnu',
|
|
19
|
-
'linux-arm64': 'translatex-aarch64-unknown-linux-gnu',
|
|
20
|
-
'win32-x64': 'translatex-x86_64-pc-windows-msvc',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
function target() {
|
|
24
|
-
const key = `${process.platform}-${process.arch}`;
|
|
25
|
-
const name = TARGETS[key];
|
|
26
|
-
if (!name) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
return name;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function download(url, destination, redirects = 0) {
|
|
33
|
-
return new Promise((resolve, reject) => {
|
|
34
|
-
if (redirects > 5) {
|
|
35
|
-
reject(new Error(`too many redirects for ${url}`));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
https
|
|
39
|
-
.get(url, { headers: { 'user-agent': `translatex-npm/${pkg.version}` } }, (res) => {
|
|
40
|
-
const { statusCode, headers } = res;
|
|
41
|
-
if (statusCode >= 300 && statusCode < 400 && headers.location) {
|
|
42
|
-
res.resume();
|
|
43
|
-
download(headers.location, destination, redirects + 1).then(resolve, reject);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
if (statusCode !== 200) {
|
|
47
|
-
res.resume();
|
|
48
|
-
reject(new Error(`HTTP ${statusCode} for ${url}`));
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
const out = fs.createWriteStream(destination);
|
|
52
|
-
res.pipe(out);
|
|
53
|
-
out.on('finish', () => out.close(resolve));
|
|
54
|
-
out.on('error', reject);
|
|
55
|
-
})
|
|
56
|
-
.on('error', reject);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function main() {
|
|
61
|
-
// Escape hatch for air-gapped installs and for trying a local build.
|
|
62
|
-
if (process.env.TRANSLATEX_BINARY_PATH) {
|
|
63
|
-
const from = process.env.TRANSLATEX_BINARY_PATH;
|
|
64
|
-
const to = path.join(__dirname, '..', 'bin', path.basename(from));
|
|
65
|
-
fs.copyFileSync(from, to);
|
|
66
|
-
process.stderr.write(`translatex: using ${from}\n`);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const name = target();
|
|
71
|
-
if (!name) {
|
|
72
|
-
process.stderr.write(
|
|
73
|
-
[
|
|
74
|
-
`translatex: no prebuilt binary for ${process.platform}/${process.arch}.`,
|
|
75
|
-
'',
|
|
76
|
-
'Install from source instead:',
|
|
77
|
-
' cargo install translatex --locked',
|
|
78
|
-
'',
|
|
79
|
-
].join('\n')
|
|
80
|
-
);
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const exe = process.platform === 'win32' ? 'translatex.exe' : 'translatex';
|
|
85
|
-
const destination = path.join(__dirname, '..', 'bin', exe);
|
|
86
|
-
|
|
87
|
-
if (fs.existsSync(destination)) {
|
|
88
|
-
fs.chmodSync(destination, 0o755);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const base = process.env.TRANSLATEX_RELEASE_BASE
|
|
93
|
-
|| `https://github.com/${REPO}/releases/download/v${pkg.version}`;
|
|
94
|
-
const url = `${base}/${name}.tar.gz`;
|
|
95
|
-
const tmp = `${destination}.tar.gz`;
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
process.stderr.write(`translatex: downloading ${url}\n`);
|
|
99
|
-
await download(url, tmp);
|
|
100
|
-
// The release asset is a .tar.gz holding the binary at its root.
|
|
101
|
-
await new Promise((resolve, reject) => {
|
|
102
|
-
const { execFile } = require('node:child_process');
|
|
103
|
-
execFile('tar', ['-xzf', tmp, '-C', path.dirname(destination)], (err) => {
|
|
104
|
-
if (err) reject(err);
|
|
105
|
-
else resolve();
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
fs.rmSync(tmp, { force: true });
|
|
109
|
-
fs.chmodSync(destination, 0o755);
|
|
110
|
-
process.stderr.write(`translatex: installed ${destination}\n`);
|
|
111
|
-
} catch (err) {
|
|
112
|
-
fs.rmSync(tmp, { force: true });
|
|
113
|
-
process.stderr.write(
|
|
114
|
-
[
|
|
115
|
-
`translatex: could not download the prebuilt binary (${err.message}).`,
|
|
116
|
-
'',
|
|
117
|
-
'Install from source instead:',
|
|
118
|
-
' cargo install translatex --locked',
|
|
119
|
-
'',
|
|
120
|
-
].join('\n')
|
|
121
|
-
);
|
|
122
|
-
process.exit(1);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
main();
|