gdx 0.4.5 → 0.5.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/LICENSE +21 -21
- package/README.md +142 -20
- package/dist/diagnostics/postinstall.validator.js +54 -0
- package/dist/index.js +757 -723
- package/package.json +24 -9
- package/scripts/launcher.cjs +52 -29
- package/scripts/postinstall.cjs +210 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Git, but with better DX. The raw power of Git, aligned with human workflows.",
|
|
5
5
|
"homepage": "https://github.com/Type-Delta/gdx#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -25,12 +25,13 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist/*.js",
|
|
27
27
|
"dist/workers/*.js",
|
|
28
|
+
"dist/diagnostics/*.js",
|
|
28
29
|
"scripts/postinstall.cjs",
|
|
29
30
|
"scripts/launcher.cjs",
|
|
30
31
|
"README.md",
|
|
31
32
|
"LICENSE"
|
|
32
33
|
],
|
|
33
|
-
"packageManager": "bun@1.3.
|
|
34
|
+
"packageManager": "bun@1.3.14",
|
|
34
35
|
"scripts": {
|
|
35
36
|
"prepare-dev": "bun i && bun run transpile-esm",
|
|
36
37
|
"start": "bun run src/index.ts",
|
|
@@ -38,11 +39,17 @@
|
|
|
38
39
|
"start:node": "tsx src/index.ts",
|
|
39
40
|
"transpile-esm": "bunx tsc -p lib/tsconfig.json && bun run scripts/transform-tools.mjs",
|
|
40
41
|
"check": "bun run ts-check && bun run lint && bun run build",
|
|
41
|
-
"lint": "bun run ts-check && eslint src --ext .ts -c eslint.config.ts
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"lint": "bun run ts-check && eslint src --ext .ts -c eslint.config.ts",
|
|
43
|
+
"lint:fix": "bun run ts-check && eslint src --ext .ts -c eslint.config.ts --fix",
|
|
44
|
+
"test:serial": "bun test",
|
|
45
|
+
"test": "bun test --parallel --timeout 20000",
|
|
46
|
+
"build": "bun run transpile-esm && bun run build:diagnostics:bin && GDX_BUILD=$(git describe --tags --always --dirty) bun build ./src/index.ts --env='GDX_BUILD*' --outfile=./bin/gdx --compile --bytecode --production --keep-names",
|
|
47
|
+
"build:release:win32-x64": "bun run transpile-esm && bun run build:diagnostics:bin && GDX_BUILD=$(git describe --tags --always --dirty) bun build ./src/index.ts --env='GDX_BUILD*' --outfile=./bin/gdx-win32-x64.exe --compile --bytecode --production --keep-names",
|
|
48
|
+
"build:diagnostics:bin": "bun build ./test/postinstall.validator.ts --outfile=./bin/diagnostics/postinstall.validator.js --target=bun --format=esm --production --minify --keep-names",
|
|
49
|
+
"build:diagnostics:node": "bun build ./test/postinstall.validator.ts --outfile=./dist/diagnostics/postinstall.validator.js --target=node --format=esm --production --minify --keep-names",
|
|
44
50
|
"ts-check": "bunx tsc --noEmit",
|
|
45
|
-
"package:node": "bun run transpile-esm && bun build ./src/index.ts --outdir=./dist --target=node --external=keytar --external=cspell-lib --external=@shikijs/cli --external=yaml --external=openai --external=fflate --format=esm --production --keep-names && bun build ./src/workers/generic.worker.ts --outfile=./dist/workers/generic.worker.min.js --target=node --external=@shikijs/cli --format=esm --production --minify --keep-names",
|
|
51
|
+
"package:node": "bun run transpile-esm && GDX_BUILD=$(git describe --tags --always --dirty) bun build ./src/index.ts --env='GDX_BUILD*' --outdir=./dist --target=node --external=keytar --external=cspell-lib --external=@shikijs/cli --external=shiki --external=yaml --external=openai --external=fflate --external=diff --external=@leeoniya/ufuzzy --format=esm --production --keep-names && bun build ./src/workers/generic.worker.ts --outfile=./dist/workers/generic.worker.min.js --target=node --external=@shikijs/cli --format=esm --production --minify --keep-names && bun run build:diagnostics:node",
|
|
52
|
+
"publish:npm": "npm login && npm publish --access public",
|
|
46
53
|
"prepack": "bun run package:node",
|
|
47
54
|
"postinstall": "node scripts/postinstall.cjs",
|
|
48
55
|
"prettier": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"./*.md\"",
|
|
@@ -56,13 +63,14 @@
|
|
|
56
63
|
"@babel/core": "^7.29.0",
|
|
57
64
|
"@babel/preset-env": "^7.29.5",
|
|
58
65
|
"@babel/preset-typescript": "^7.28.5",
|
|
59
|
-
"@eslint/js": "^
|
|
66
|
+
"@eslint/js": "^10.0.1",
|
|
60
67
|
"@sinclair/typebox": "^0.34.49",
|
|
61
68
|
"@types/chai": "^5.2.3",
|
|
62
69
|
"@types/ini": "^4.1.1",
|
|
70
|
+
"@types/which": "^3.0.4",
|
|
63
71
|
"@typescript-eslint/eslint-plugin": "^8.59.4",
|
|
64
72
|
"@typescript-eslint/parser": "^8.59.4",
|
|
65
|
-
"bun-types": "
|
|
73
|
+
"bun-types": "1.3.14",
|
|
66
74
|
"chai": "^6.2.2",
|
|
67
75
|
"dedent": "^1.7.2",
|
|
68
76
|
"eslint": "^10.4.0",
|
|
@@ -73,11 +81,14 @@
|
|
|
73
81
|
"smol-toml": "^1.6.1",
|
|
74
82
|
"tinybench": "^6.0.2",
|
|
75
83
|
"tsx": "^4.22.3",
|
|
84
|
+
"tty-strings": "^1.5.2",
|
|
76
85
|
"typescript": "^6.0.3",
|
|
77
86
|
"typescript-eslint": "^8.59.4",
|
|
78
|
-
"unicode-animations": "^1.0.3"
|
|
87
|
+
"unicode-animations": "^1.0.3",
|
|
88
|
+
"which": "2.0.2"
|
|
79
89
|
},
|
|
80
90
|
"dependencies": {
|
|
91
|
+
"@leeoniya/ufuzzy": "^1.0.19",
|
|
81
92
|
"@shikijs/cli": "^4.1.0",
|
|
82
93
|
"cspell-lib": "10.0.0",
|
|
83
94
|
"diff": "^9.0.0",
|
|
@@ -85,5 +96,9 @@
|
|
|
85
96
|
"keytar": "^7.9.0",
|
|
86
97
|
"openai": "^6.38.0",
|
|
87
98
|
"yaml": "^2.9.0"
|
|
99
|
+
},
|
|
100
|
+
"patchedDependencies": {
|
|
101
|
+
"tty-strings@1.5.2": "patches/tty-strings@1.5.2.patch",
|
|
102
|
+
"execa@9.6.1": "patches/execa@9.6.1.patch"
|
|
88
103
|
}
|
|
89
104
|
}
|
package/scripts/launcher.cjs
CHANGED
|
@@ -6,32 +6,55 @@ const fs = require('fs');
|
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const { spawn } = require('child_process');
|
|
8
8
|
|
|
9
|
-
const DIST_DIR = path.join(__dirname, '../dist');
|
|
10
|
-
const NATIVE_DIR = path.join(
|
|
11
|
-
const isWin = process.platform === 'win32';
|
|
12
|
-
const binaryName = isWin ? 'gdx.exe' : 'gdx';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
9
|
+
const DIST_DIR = path.join(__dirname, '../dist');
|
|
10
|
+
const NATIVE_DIR = path.join(__dirname, '../bin/native');
|
|
11
|
+
const isWin = process.platform === 'win32';
|
|
12
|
+
const binaryName = isWin ? 'gdx.exe' : 'gdx';
|
|
13
|
+
|
|
14
|
+
if (
|
|
15
|
+
(process.env.GDX_RUNTIME_SHIM === '1' || process.env.GDX_NODE_SHIM === '1') &&
|
|
16
|
+
process.argv[2] === '--'
|
|
17
|
+
) {
|
|
18
|
+
process.argv.splice(2, 1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getNativeBinaryPath() {
|
|
22
|
+
return path.join(NATIVE_DIR, binaryName);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function runLauncher() {
|
|
26
|
+
const binaryPath = getNativeBinaryPath();
|
|
27
|
+
|
|
28
|
+
// Check if native binary exists
|
|
29
|
+
if (fs.existsSync(binaryPath)) {
|
|
30
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
31
|
+
stdio: 'inherit'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
child.on('close', (code) => {
|
|
35
|
+
process.exit(code);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
child.on('error', (err) => {
|
|
39
|
+
console.error('Failed to start native binary:', err);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
// Fallback to Node.js runtime (dist/index.js)
|
|
44
|
+
// Since dist/index.js is ESM, we use dynamic import
|
|
45
|
+
const jsEntry = path.join(DIST_DIR, 'index.js');
|
|
46
|
+
import(require('url').pathToFileURL(jsEntry)).catch(err => {
|
|
47
|
+
console.error('Failed to load JS fallback:', err);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (require.main === module) {
|
|
54
|
+
runLauncher();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
getNativeBinaryPath,
|
|
59
|
+
runLauncher,
|
|
60
|
+
};
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
+
const crypto = require('crypto');
|
|
5
6
|
const { spawnSync, execFileSync } = require('child_process');
|
|
6
7
|
|
|
7
8
|
// Configuration
|
|
8
9
|
const PACKAGE_JSON_PATH = path.join(__dirname, '../package.json');
|
|
10
|
+
const PACKAGE_DIR = path.join(__dirname, '..');
|
|
9
11
|
const BIN_DIR = path.join(__dirname, '../bin');
|
|
10
12
|
const NATIVE_DIR = path.join(BIN_DIR, 'native');
|
|
11
13
|
const PKG_SRC_PATH = path.join(__dirname, '../dist/index.js');
|
|
@@ -33,9 +35,39 @@ function error(message) {
|
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
function writeInstallInfo(info) {
|
|
38
|
+
ensureBinDir();
|
|
36
39
|
fs.writeFileSync(INSTALL_INFO_PATH, JSON.stringify(info, null, 2));
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
function getNativeBinaryName(platform = process.platform) {
|
|
43
|
+
return platform === 'win32' ? 'gdx.exe' : 'gdx';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getNativeBuildArgs(finalPath) {
|
|
47
|
+
return [
|
|
48
|
+
'build',
|
|
49
|
+
PKG_SRC_PATH,
|
|
50
|
+
`--outfile=${finalPath}`,
|
|
51
|
+
'--compile',
|
|
52
|
+
'--bytecode',
|
|
53
|
+
'--production',
|
|
54
|
+
'--keep-names',
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function createInstallInfo(mode, finalPath, useNativeShim) {
|
|
59
|
+
return {
|
|
60
|
+
mode,
|
|
61
|
+
platform: process.platform,
|
|
62
|
+
arch: process.arch,
|
|
63
|
+
version: getPackageVersion(),
|
|
64
|
+
userAgent: process.env.npm_config_user_agent || null,
|
|
65
|
+
useNativeShim,
|
|
66
|
+
ts: (new Date).toLocaleString(),
|
|
67
|
+
binaryPath: finalPath
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
39
71
|
function isTruthy(v) {
|
|
40
72
|
return v === '1' || v === 'true' || v === 'yes';
|
|
41
73
|
}
|
|
@@ -49,11 +81,10 @@ function getPrefixFromEnvOrNpm() {
|
|
|
49
81
|
const npmExecPath = process.env.npm_execpath;
|
|
50
82
|
if (!npmExecPath) return null;
|
|
51
83
|
|
|
52
|
-
const prefix = execFileSync(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
).trim();
|
|
84
|
+
const prefix = execFileSync(npmExecPath, ['config', 'get', 'prefix'], {
|
|
85
|
+
encoding: 'utf8',
|
|
86
|
+
shell: false,
|
|
87
|
+
}).trim();
|
|
57
88
|
|
|
58
89
|
return prefix || null;
|
|
59
90
|
}
|
|
@@ -64,7 +95,10 @@ async function checkUrlExists(url) {
|
|
|
64
95
|
const res = await fetch(url, { method: 'HEAD', redirect: 'follow' });
|
|
65
96
|
return res.ok;
|
|
66
97
|
} catch (err) {
|
|
67
|
-
throw new Error(
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Network error while checking prebuilt availability: ${err.message} (${url})`,
|
|
100
|
+
{ cause: err }
|
|
101
|
+
);
|
|
68
102
|
}
|
|
69
103
|
}
|
|
70
104
|
|
|
@@ -74,13 +108,38 @@ async function downloadFile(url, tmpPath, destPath) {
|
|
|
74
108
|
throw new Error(`Failed to download: ${res.statusText} (${url})`);
|
|
75
109
|
}
|
|
76
110
|
|
|
77
|
-
const fileStream = fs.createWriteStream(
|
|
111
|
+
const fileStream = fs.createWriteStream(tmpPath);
|
|
78
112
|
const stream = require('stream');
|
|
79
113
|
const { promisify } = require('util');
|
|
80
114
|
const pipeline = promisify(stream.pipeline);
|
|
81
115
|
|
|
82
116
|
await pipeline(res.body, fileStream);
|
|
83
|
-
|
|
117
|
+
if (tmpPath !== destPath) {
|
|
118
|
+
fs.renameSync(tmpPath, destPath);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function readSha256FromText(text, assetName) {
|
|
123
|
+
const trimmed = text.trim();
|
|
124
|
+
const match = trimmed.match(/\b([a-fA-F0-9]{64})\b/);
|
|
125
|
+
if (!match) {
|
|
126
|
+
throw new Error(`Invalid SHA256 checksum for ${assetName}.`);
|
|
127
|
+
}
|
|
128
|
+
return match[1].toLowerCase();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function sha256File(filePath) {
|
|
132
|
+
return crypto.createHash('sha256').update(fs.readFileSync(filePath)).digest('hex');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function verifySha256(filePath, checksumText, assetName) {
|
|
136
|
+
const expected = readSha256FromText(checksumText, assetName);
|
|
137
|
+
const actual = sha256File(filePath);
|
|
138
|
+
if (actual !== expected) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Checksum mismatch for ${assetName}. Expected ${expected}, got ${actual}.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
84
143
|
}
|
|
85
144
|
|
|
86
145
|
function setExecutable(filePath) {
|
|
@@ -90,10 +149,59 @@ function setExecutable(filePath) {
|
|
|
90
149
|
}
|
|
91
150
|
|
|
92
151
|
function writeFileExecutable(filePath, content) {
|
|
152
|
+
// Remove any existing entry first. npm links bin entries as symlinks
|
|
153
|
+
// (e.g. <bindir>/gdx -> ../gdx/scripts/launcher.cjs); writing without
|
|
154
|
+
// unlinking would follow that symlink and overwrite its target
|
|
155
|
+
// (launcher.cjs) with shim content instead of replacing the bin entry.
|
|
156
|
+
// fs.rmSync unlinks the symlink itself; force ignores a missing path.
|
|
157
|
+
fs.rmSync(filePath, { force: true });
|
|
93
158
|
fs.writeFileSync(filePath, content, { encoding: 'utf8' });
|
|
94
159
|
setExecutable(filePath);
|
|
95
160
|
}
|
|
96
161
|
|
|
162
|
+
function buildRuntimeShimContents(runtimeAbsPath, launcherAbsPath) {
|
|
163
|
+
return {
|
|
164
|
+
cmd: [
|
|
165
|
+
'@echo off',
|
|
166
|
+
'set "GDX_RUNTIME_SHIM=1"',
|
|
167
|
+
`"${runtimeAbsPath}" "${launcherAbsPath}" -- %*`,
|
|
168
|
+
'exit /b %ERRORLEVEL%',
|
|
169
|
+
''
|
|
170
|
+
].join('\r\n'),
|
|
171
|
+
ps1: [
|
|
172
|
+
'$env:GDX_RUNTIME_SHIM = "1"',
|
|
173
|
+
`& "${runtimeAbsPath}" "${launcherAbsPath}" -- @args`,
|
|
174
|
+
'exit $LASTEXITCODE',
|
|
175
|
+
''
|
|
176
|
+
].join('\r\n'),
|
|
177
|
+
sh: [
|
|
178
|
+
'#!/usr/bin/env sh',
|
|
179
|
+
'export GDX_RUNTIME_SHIM=1',
|
|
180
|
+
`exec "${runtimeAbsPath}" "${launcherAbsPath}" -- "$@"`,
|
|
181
|
+
''
|
|
182
|
+
].join('\n'),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function getLocalNodeModulesBinDir() {
|
|
187
|
+
return path.resolve(PACKAGE_DIR, '..', '.bin');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function overwriteRuntimeShim(binDir, launcherAbsPath, runtime) {
|
|
191
|
+
if (!binDir || !fs.existsSync(binDir)) return false;
|
|
192
|
+
|
|
193
|
+
const shims = buildRuntimeShimContents(runtime.executable, launcherAbsPath);
|
|
194
|
+
|
|
195
|
+
if (process.platform === 'win32') {
|
|
196
|
+
writeFileExecutable(path.join(binDir, 'gdx.cmd'), shims.cmd);
|
|
197
|
+
writeFileExecutable(path.join(binDir, 'gdx.ps1'), shims.ps1);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
writeFileExecutable(path.join(binDir, 'gdx'), shims.sh);
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
|
|
97
205
|
function getNpmGlobalBinDir() {
|
|
98
206
|
if (!isTruthy(process.env.npm_config_global)) return null;
|
|
99
207
|
|
|
@@ -116,7 +224,7 @@ function overwriteGlobalShim(nativeAbsPath) {
|
|
|
116
224
|
|
|
117
225
|
if (!(process.env.npm_config_user_agent || '').includes('npm/')) {
|
|
118
226
|
log('Non-npm global install detected; skipping global shim overwrite.');
|
|
119
|
-
log('This may result in overhead introduced by the
|
|
227
|
+
log('This may result in overhead introduced by the JavaScript launch script.');
|
|
120
228
|
return false;
|
|
121
229
|
}
|
|
122
230
|
|
|
@@ -156,6 +264,49 @@ function overwriteGlobalShim(nativeAbsPath) {
|
|
|
156
264
|
return true;
|
|
157
265
|
}
|
|
158
266
|
|
|
267
|
+
function findRuntimeExecutable(name, platform = process.platform) {
|
|
268
|
+
const locator = platform === 'win32' ? 'where.exe' : 'which';
|
|
269
|
+
const located = spawnSync(locator, [name], {
|
|
270
|
+
encoding: 'utf8',
|
|
271
|
+
windowsHide: true,
|
|
272
|
+
});
|
|
273
|
+
if (located.error || located.status !== 0) return null;
|
|
274
|
+
|
|
275
|
+
for (const executable of String(located.stdout || '').split(/\r?\n/).filter(Boolean)) {
|
|
276
|
+
const needsShell = platform === 'win32' && /\.(?:cmd|bat)$/i.test(executable);
|
|
277
|
+
const probe = spawnSync(
|
|
278
|
+
executable,
|
|
279
|
+
['-e', "require('path');process.stdout.write('gdx-runtime')"],
|
|
280
|
+
{
|
|
281
|
+
encoding: 'utf8',
|
|
282
|
+
shell: needsShell,
|
|
283
|
+
windowsHide: true,
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
if (!probe.error && probe.status === 0 && probe.stdout === 'gdx-runtime') return executable;
|
|
287
|
+
}
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function selectFallbackRuntime(findExecutable = findRuntimeExecutable) {
|
|
292
|
+
for (const name of ['bun']) { // FIXME: waiting to runtimes with latency lower than Bun's
|
|
293
|
+
const executable = findExecutable(name);
|
|
294
|
+
if (executable) return { name, executable };
|
|
295
|
+
}
|
|
296
|
+
return { name: 'node', executable: process.execPath };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function installRuntimeFallbackShims(runtime) {
|
|
300
|
+
const launcherAbsPath = path.join(__dirname, 'launcher.cjs');
|
|
301
|
+
const localBin = getLocalNodeModulesBinDir();
|
|
302
|
+
const globalBin = getNpmGlobalBinDir();
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
local: overwriteRuntimeShim(localBin, launcherAbsPath, runtime),
|
|
306
|
+
global: overwriteRuntimeShim(globalBin, launcherAbsPath, runtime),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
159
310
|
async function tryDownloadPrebuilt() {
|
|
160
311
|
const version = getPackageVersion();
|
|
161
312
|
const platform = process.platform;
|
|
@@ -169,6 +320,7 @@ async function tryDownloadPrebuilt() {
|
|
|
169
320
|
const ext = platform === 'win32' ? '.exe' : '';
|
|
170
321
|
const assetName = `gdx-${platform}-${arch}${ext}`;
|
|
171
322
|
const url = `${PREBUILT_BASE_URL}/v${version}/${assetName}`;
|
|
323
|
+
const checksumUrl = `${url}.sha256`;
|
|
172
324
|
|
|
173
325
|
log(`Checking availability of prebuilt binary: ${url}`);
|
|
174
326
|
const exists = await checkUrlExists(url);
|
|
@@ -178,11 +330,21 @@ async function tryDownloadPrebuilt() {
|
|
|
178
330
|
|
|
179
331
|
log(`Downloading prebuilt binary...`);
|
|
180
332
|
const tmpPath = path.join(NATIVE_DIR, `${assetName}.tmp`);
|
|
333
|
+
const checksumTmpPath = path.join(NATIVE_DIR, `${assetName}.sha256.tmp`);
|
|
334
|
+
const checksumPath = path.join(NATIVE_DIR, `${assetName}.sha256`);
|
|
181
335
|
const finalPath = path.join(NATIVE_DIR, 'gdx' + ext);
|
|
182
336
|
|
|
183
337
|
ensureBinDir();
|
|
184
|
-
|
|
185
|
-
|
|
338
|
+
try {
|
|
339
|
+
await downloadFile(url, tmpPath, tmpPath);
|
|
340
|
+
await downloadFile(checksumUrl, checksumTmpPath, checksumPath);
|
|
341
|
+
verifySha256(tmpPath, fs.readFileSync(checksumPath, 'utf8'), assetName);
|
|
342
|
+
fs.renameSync(tmpPath, finalPath);
|
|
343
|
+
setExecutable(finalPath);
|
|
344
|
+
} finally {
|
|
345
|
+
fs.rmSync(tmpPath, { force: true });
|
|
346
|
+
fs.rmSync(checksumTmpPath, { force: true });
|
|
347
|
+
}
|
|
186
348
|
|
|
187
349
|
log(`Prebuilt binary installed to ${finalPath}`);
|
|
188
350
|
|
|
@@ -208,21 +370,11 @@ function tryBuildNative() {
|
|
|
208
370
|
}
|
|
209
371
|
|
|
210
372
|
const platform = process.platform;
|
|
211
|
-
const
|
|
212
|
-
const isWin = platform === 'win32';
|
|
213
|
-
const binaryName = isWin ? 'gdx.exe' : 'gdx';
|
|
373
|
+
const binaryName = getNativeBinaryName(platform);
|
|
214
374
|
const finalPath = path.join(NATIVE_DIR, binaryName);
|
|
215
375
|
|
|
216
376
|
// Build command
|
|
217
|
-
const args =
|
|
218
|
-
'build',
|
|
219
|
-
PKG_SRC_PATH,
|
|
220
|
-
`--outfile=${finalPath}`,
|
|
221
|
-
'--compile',
|
|
222
|
-
'--bytecode',
|
|
223
|
-
'--production',
|
|
224
|
-
'--keep-names',
|
|
225
|
-
];
|
|
377
|
+
const args = getNativeBuildArgs(finalPath);
|
|
226
378
|
|
|
227
379
|
ensureBinDir();
|
|
228
380
|
log(`Running: bun ${args.join(' ')}`);
|
|
@@ -234,16 +386,7 @@ function tryBuildNative() {
|
|
|
234
386
|
|
|
235
387
|
log(`Native binary built at ${finalPath}`);
|
|
236
388
|
|
|
237
|
-
writeInstallInfo(
|
|
238
|
-
mode: 'built',
|
|
239
|
-
platform,
|
|
240
|
-
arch,
|
|
241
|
-
version: getPackageVersion(),
|
|
242
|
-
userAgent: process.env.npm_config_user_agent || null,
|
|
243
|
-
useNativeShim: overwriteGlobalShim(finalPath),
|
|
244
|
-
ts: (new Date).toLocaleString(),
|
|
245
|
-
binaryPath: finalPath
|
|
246
|
-
});
|
|
389
|
+
writeInstallInfo(createInstallInfo('built', finalPath, overwriteGlobalShim(finalPath)));
|
|
247
390
|
}
|
|
248
391
|
|
|
249
392
|
async function main() {
|
|
@@ -260,8 +403,22 @@ async function main() {
|
|
|
260
403
|
} else if (isTruthy(process.env.GDX_BUILD_NATIVE)) {
|
|
261
404
|
tryBuildNative();
|
|
262
405
|
} else {
|
|
263
|
-
|
|
264
|
-
|
|
406
|
+
const runtime = selectFallbackRuntime();
|
|
407
|
+
log(`No native install requested (default). Using ${runtime.name} fallback.`);
|
|
408
|
+
const shimInstall = installRuntimeFallbackShims(runtime);
|
|
409
|
+
writeInstallInfo({
|
|
410
|
+
mode: 'runtime',
|
|
411
|
+
runtime: runtime.name,
|
|
412
|
+
runtimePath: runtime.executable,
|
|
413
|
+
platform: process.platform,
|
|
414
|
+
arch: process.arch,
|
|
415
|
+
version: getPackageVersion(),
|
|
416
|
+
userAgent: process.env.npm_config_user_agent || null,
|
|
417
|
+
useGlobalShim: shimInstall.global,
|
|
418
|
+
useLocalShim: shimInstall.local,
|
|
419
|
+
ts: (new Date).toLocaleString(),
|
|
420
|
+
launcherPath: path.join(__dirname, 'launcher.cjs')
|
|
421
|
+
});
|
|
265
422
|
}
|
|
266
423
|
} catch (err) {
|
|
267
424
|
error(err.message);
|
|
@@ -269,4 +426,21 @@ async function main() {
|
|
|
269
426
|
}
|
|
270
427
|
}
|
|
271
428
|
|
|
272
|
-
main
|
|
429
|
+
if (require.main === module) {
|
|
430
|
+
main();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
module.exports = {
|
|
434
|
+
buildRuntimeShimContents,
|
|
435
|
+
createInstallInfo,
|
|
436
|
+
downloadFile,
|
|
437
|
+
getNativeBinaryName,
|
|
438
|
+
getNativeBuildArgs,
|
|
439
|
+
getLocalNodeModulesBinDir,
|
|
440
|
+
findRuntimeExecutable,
|
|
441
|
+
installRuntimeFallbackShims,
|
|
442
|
+
overwriteRuntimeShim,
|
|
443
|
+
readSha256FromText,
|
|
444
|
+
selectFallbackRuntime,
|
|
445
|
+
verifySha256,
|
|
446
|
+
};
|