translatex 0.1.0 → 0.1.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
@@ -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 package itself is a shim: the binary is downloaded once from the
8
- matching GitHub release.
7
+ agents. The binary ships in a per-platform package (`translatex-win32-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
- // Thin shim: the native binary is fetched by scripts/install.js at install
5
- // time, so this package stays platform-neutral and a few kilobytes.
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 = path.join(
12
- __dirname,
13
- process.platform === 'win32' ? 'translatex.exe' : 'translatex'
14
- );
13
+ const exe = process.platform === 'win32' ? 'translatex.exe' : 'translatex';
15
14
 
16
- if (!fs.existsSync(exe)) {
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
- 'translatex: the native binary is missing from this install.',
36
+ `translatex: no binary for ${process.platform}/${process.arch}.`,
20
37
  '',
21
- 'Reinstall it:',
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 yet, use cargo.',
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(exe, process.argv.slice(2), { stdio: 'inherit' });
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 ${exe}: ${err.message}\n`);
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.0",
3
+ "version": "0.1.1",
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.1",
41
+ "translatex-darwin-x64": "0.1.1",
42
+ "translatex-linux-arm64": "0.1.1",
43
+ "translatex-linux-x64": "0.1.1",
44
+ "translatex-windows-x64": "0.1.1"
45
+ },
43
46
  "engines": {
44
47
  "node": ">=18"
45
48
  },
@@ -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();