Skip to content

Commit

Permalink
feat: Use unofficial builds in SEA
Browse files Browse the repository at this point in the history
riscv64 and loong64 have unofficial builds at https://unofficial-builds.nodejs.org and can be used in SEA build.

This is in conjunction with yao-pkg/pkg-fetch#62.
  • Loading branch information
hack3ric committed Nov 20, 2024
1 parent 55c70fa commit ec12c5a
Showing 1 changed file with 51 additions and 13 deletions.
64 changes: 51 additions & 13 deletions lib/sea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,15 @@ function getNodeOs(platform: string) {

/** Get the node arch based on target arch */
function getNodeArch(arch: string) {
const allowedArchs = ['x64', 'arm64', 'armv7l', 'ppc64', 's390x'];
const allowedArchs = [
'x64',
'arm64',
'armv7l',
'ppc64',
's390x',
'riscv64',
'loong64',
];

if (!allowedArchs.includes(arch)) {
throw new Error(`Unsupported architecture: ${arch}`);
Expand All @@ -166,7 +174,7 @@ function getNodeArch(arch: string) {
}

/** Get latest node version based on the provided partial version */
async function getNodeVersion(nodeVersion: string) {
async function getNodeVersion(os: string, arch: string, nodeVersion: string) {
// validate nodeVersion using regex. Allowed formats: 16, 16.0, 16.0.0
const regex = /^\d{1,2}(\.\d{1,2}){0,2}$/;
if (!regex.test(nodeVersion)) {
Expand All @@ -183,23 +191,38 @@ async function getNodeVersion(nodeVersion: string) {
return nodeVersion;
}

const response = await fetch('https://nodejs.org/dist/index.json');
let url;
switch (arch) {
case 'riscv64':
case 'loong64':
url = 'https://unofficial-builds.nodejs.org/download/release/index.json';
break;
default:
url = 'https://nodejs.org/dist/index.json';
break;
}

const response = await fetch(url);

if (!response.ok) {
throw new Error('Failed to fetch node versions');
}

const versions = await response.json();

const latestVersion = versions
.map((v: { version: string }) => v.version)
.find((v: string) => v.startsWith(`v${nodeVersion}`));
const latestVersionAndFiles = versions
.map((v: { version: string; files: string[] }) => [v.version, v.files])
.find(
([v, files]: [string, string[]]) =>
v.startsWith(`v${nodeVersion}`) &&
files.find((f: string) => f.startsWith(`${os}-${arch}`)),
);

if (!latestVersion) {
if (!latestVersionAndFiles) {
throw new Error(`Node version ${nodeVersion} not found`);
}

return latestVersion;
return latestVersionAndFiles[0];
}

/** Fetch, validate and extract nodejs binary. Returns a path to it */
Expand All @@ -222,16 +245,31 @@ async function getNodejsExecutable(
return process.execPath;
}

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

const nodeVersion = await getNodeVersion(
os,
arch,
target.nodeRange.replace('node', ''),
);

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

const fileName = `node-${nodeVersion}-${os}-${arch}.${os === 'win' ? 'zip' : 'tar.gz'}`;
const url = `https://nodejs.org/dist/${nodeVersion}/${fileName}`;
const checksumUrl = `https://nodejs.org/dist/${nodeVersion}/SHASUMS256.txt`;

let url;
let checksumUrl;
switch (arch) {
case 'riscv64':
case 'loong64':
url = `https://unofficial-builds.nodejs.org/download/release/${nodeVersion}/${fileName}`;
checksumUrl = `https://unofficial-builds.nodejs.org/download/release/${nodeVersion}/SHASUMS256.txt`;
break;
default:
url = `https://nodejs.org/dist/${nodeVersion}/${fileName}`;
checksumUrl = `https://nodejs.org/dist/${nodeVersion}/SHASUMS256.txt`;
break;
}

const downloadDir = join(homedir(), '.pkg-cache', 'sea');

// Ensure the download directory exists
Expand Down

0 comments on commit ec12c5a

Please sign in to comment.