Skip to content

Commit

Permalink
fix: make it work
Browse files Browse the repository at this point in the history
  • Loading branch information
robertsLando committed Oct 22, 2024
1 parent d51b02f commit d38118f
Show file tree
Hide file tree
Showing 3 changed files with 532 additions and 228 deletions.
66 changes: 57 additions & 9 deletions lib/sea.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { exec as cExec } from 'child_process';
import util from 'util';
import { dirname, join, resolve } from 'path';
import { basename, dirname, join, resolve } from 'path';
import { copyFile, writeFile, rm, mkdir, stat, readFile } from 'fs/promises';
import { createWriteStream } from 'fs';
import { pipeline } from 'stream/promises';
import { ReadableStream } from 'stream/web';
import { createHash } from 'crypto';
import { homedir, tmpdir } from 'os';
import unzipper from 'unzipper';
import { extract as tarExtract } from 'tar';
import { log } from './log';
import { NodeTarget } from './types';

Expand Down Expand Up @@ -53,6 +55,48 @@ async function downloadFile(url: string, filePath: string): Promise<void> {
return pipeline(response.body as unknown as ReadableStream, fileStream);
}

async function extract(os: string, archivePath: string): Promise<string> {
const nodeDir = basename(archivePath, os === 'win32' ? '.zip' : '.tar.gz')
const archiveDir = dirname(archivePath)
let nodePath = ''

if (os === 'win32') {
// use unzipper to extract the archive
const { files } = await unzipper.Open.file(archivePath)
const nodeBinPath = `${nodeDir}/node.exe`

const nodeBin = files.find((file) => file.path === nodeBinPath)

if (!nodeBin) {
throw new Error('Node executable not found in the archive')
}

nodePath = join(archiveDir, `${nodeDir}.exe`)

// extract the node executable
await pipeline(nodeBin.stream(), createWriteStream(nodePath))
} else {
const nodeBinPath = `${nodeDir}/bin/node`

// use tar to extract the archive
await tarExtract({
file: archivePath,
cwd: archiveDir,
filter: (path) => path === nodeBinPath
})

// check if the node executable exists
nodePath = join(archiveDir, nodeBinPath)
}

// check if the node executable exists
if (!await exists(nodePath)) {
throw new Error('Node executable not found in the archive')
}

return nodePath
}

async function verifyChecksum(
filePath: string,
checksumUrl: string,
Expand Down Expand Up @@ -136,7 +180,7 @@ async function getNodeVersion(nodeVersion: string) {

const latestVersion = versions
.map((v: { version: string }) => v.version)
.find((v: string) => v.startsWith(nodeVersion));
.find((v: string) => v.startsWith(`v${nodeVersion}`));

if (!latestVersion) {
throw new Error(`Node version ${nodeVersion} not found`);
Expand All @@ -162,15 +206,15 @@ async function getNodejsExecutable(opts: GetNodejsExecutableOptions) {
}

const nodeVersion = await getNodeVersion(
opts.target.nodeRange.replace('nodev', ''),
opts.target.nodeRange.replace('node', ''),
);

const os = getNodeOs(opts.target.platform);
const arch = getNodeArch(opts.target.arch);

const fileName = `node-v${nodeVersion}-${os}-${arch}.tar.gz`;
const url = `https://nodejs.org/dist/v${nodeVersion}/${fileName}`;
const checksumUrl = `https://nodejs.org/dist/v${nodeVersion}/SHASUMS256.txt`;
const fileName = `node-${nodeVersion}-${os}-${arch}.${os === 'win32' ? 'zip' : 'tar.gz'}`;
const url = `https://nodejs.org/dist/${nodeVersion}/${fileName}`;
const checksumUrl = `https://nodejs.org/dist/${nodeVersion}/SHASUMS256.txt`;
const downloadDir = join(homedir(), '.pkg-cache', 'sea');

// Ensure the download directory exists
Expand All @@ -180,10 +224,14 @@ async function getNodejsExecutable(opts: GetNodejsExecutableOptions) {

const filePath = join(downloadDir, fileName);

await downloadFile(url, filePath);
// skip download if file exists
if (!(await exists(filePath))) {
await downloadFile(url, filePath);
}

await verifyChecksum(filePath, checksumUrl, fileName);

return filePath;
return extract(os, filePath);
}

export default async function sea(
Expand Down Expand Up @@ -236,7 +284,7 @@ export default async function sea(
...{
...defaultSeaConfig,
...(opts.seaConfig || {}),
}
},
};

log.info('Preparing the executable');
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
"prebuild-install": "^7.1.1",
"resolve": "^1.22.0",
"stream-meter": "^1.0.4",
"tinyglobby": "^0.2.9"
"tar": "^7.4.3",
"tinyglobby": "^0.2.9",
"unzipper": "^0.12.3"
},
"devDependencies": {
"@babel/core": "^7.23.0",
Expand All @@ -46,8 +48,12 @@
"@types/picomatch": "^3.0.1",
"@types/resolve": "^1.20.2",
"@types/stream-meter": "^0.0.22",
"@types/tar": "^6.1.13",
"@types/unzipper": "^0.10.10",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"esbuild": "^0.24.0",
"esbuild-register": "^3.6.0",
"eslint": "^8.50.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.1.0",
Expand Down
Loading

0 comments on commit d38118f

Please sign in to comment.