From 72670515a90671665573fe6c07031625d816e4b4 Mon Sep 17 00:00:00 2001 From: Tryggvi Larusson Date: Fri, 11 Oct 2024 21:56:52 +0000 Subject: [PATCH] Improving compatability with MacOS - Fixing CR line endings in scripts/sea.js - Updating dependencies - Adding codesign for macOS - Adding better compatability with esbuild --- package.json | 4 ++-- scripts/sea.js | 56 +++++++++++++++++++++++++++++++++++----------- src/configure.ts | 4 ++-- src/filenames.ts | 4 ++++ src/injection.ts | 27 +++++++++++++++++----- src/resolutions.ts | 7 +----- src/runtime.ts | 2 -- 7 files changed, 73 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 405c01a..653c28a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pipobscure/sea", - "version": "1.0.5", + "version": "1.0.6", "description": "Node SEA Builder", "main": "dist/resolutions.js", "bin": { @@ -37,7 +37,7 @@ "typescript": "^5.2.2" }, "dependencies": { - "glob": "^10.3.10", + "glob": "11.0.0", "minimatch": "^9.0.3", "postject": "^1.0.0-alpha.6", "terser": "^5.26.0" diff --git a/scripts/sea.js b/scripts/sea.js index fe11dbb..317e53c 100644 --- a/scripts/sea.js +++ b/scripts/sea.js @@ -1,13 +1,43 @@ -#!/usr/bin/env node - -async function main() { - console.error('writing configuration'); - await (require('../dist/configure.js').configure()); - console.error('assembling bundle'); - await (require('../dist/bundlefiles.js').bundle()); - console.error('building executable'); - await (require('../dist/injection.js').inject()); - console.error('done'); -} - -if (require.main === module) main(); +#!/usr/bin/env node + +const { exec } = require("node:child_process"); +const { platform } = require("node:os"); + + +async function codesign() { + let osPlatform = platform(); + if ( osPlatform == "darwin" ){ + const fs = require('fs'); + const Path = require('path'); + const { base } = require("../dist/packagebase.js"); + const PackageBase = base(process.cwd()); + const PKG = JSON.parse(fs.readFileSync(Path.join(PackageBase, 'package.json'), 'utf-8')); + const exe_name = `${PKG?.sea?.executable ?? 'bundle'}`; + console.log(`signing ${exe_name}`); + exec(`codesign --sign - ${exe_name}`, (error, stdout, stderr) => { + if (error) { + console.log(`error: ${error.message}`); + return; + } + if (stderr) { + console.log(`codesign err: ${stderr}`); + return; + } + console.log(`codesign: ${stdout}`); + }); + } +} + +async function main() { + console.error('writing configuration'); + await (require('../dist/configure.js').configure()); + console.error('assembling bundle'); + await (require('../dist/bundlefiles.js').bundle()); + console.error('building executable'); + await (require('../dist/injection.js').inject()); + console.error('codesign'); + await codesign(); + console.error('done'); +} + +if (require.main === module) main(); diff --git a/src/configure.ts b/src/configure.ts index 9d9c496..7c001ce 100644 --- a/src/configure.ts +++ b/src/configure.ts @@ -32,8 +32,8 @@ export async function configure() { main: File.runtime, output: File.bundle, disableExperimentalSEAWarning: true, - useSnapshot: false, - useCodeCache: true, + useSnapshot: File.useSnapshot, + useCodeCache: File.useCodeCache, assets: { resolv: File.resolutions, bundle: File.blobs, diff --git a/src/filenames.ts b/src/filenames.ts index dbfa954..26d303c 100644 --- a/src/filenames.ts +++ b/src/filenames.ts @@ -11,6 +11,8 @@ export default function names(PKG: any) { const runtime = `${name}.js`; const bundle = `${name}.sea`; const executable = `${name}${isWindows ? '.exe' : ''}`; + const useSnapshot = PKG?.sea?.useSnapshot ?? false; + const useCodeCache = PKG?.sea?.useCodeCache ?? false; const files = { config, blobs, @@ -19,6 +21,8 @@ export default function names(PKG: any) { runtime, bundle, executable, + useSnapshot, + useCodeCache, }; return files; } diff --git a/src/injection.ts b/src/injection.ts index d6b1cf7..b31e4b4 100644 --- a/src/injection.ts +++ b/src/injection.ts @@ -1,7 +1,8 @@ -import { readFileSync } from 'node:fs'; +import { readFileSync, statSync, chmodSync, constants as fsConstants } from 'node:fs'; import * as Path from 'node:path'; import * as FS from 'node:fs/promises'; import * as Proc from 'node:child_process'; +import * as OS from 'node:os'; //@ts-ignore import { inject } from 'postject'; @@ -17,14 +18,28 @@ export async function inject() { await exec(process.execPath, '--experimental-sea-config', Path.join(PackageBase, File.config)); console.error(`copying ${process.execPath} to ${File.executable}`); - await FS.copyFile(process.execPath, Path.join(PackageBase, File.executable)); + let newExeFilePath = Path.join(PackageBase, File.executable); + await FS.copyFile(process.execPath, newExeFilePath); + + let newFileExeStat = statSync(newExeFilePath); + let newFileExeStatMode = newFileExeStat.mode; + chmodSync(Path.join(PackageBase, File.executable), newFileExeStatMode | fsConstants.S_IWUSR); console.error(`injecting ${File.bundle} into ${File.executable}`); const runtime = await FS.readFile(Path.join(PackageBase, File.bundle)); - //@ts-ignore - await inject(Path.join(PackageBase, File.executable), 'NODE_SEA_BLOB', runtime, { - sentinelFuse: 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2', - }); + const osPlatform = OS.platform(); + if ( osPlatform == "darwin") { + //@ts-ignore + await inject(Path.join(PackageBase, File.executable), 'NODE_SEA_BLOB', runtime, { + sentinelFuse: 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2', + machoSegmentName: 'NODE_SEA', + }); + } else { + //@ts-ignore + await inject(Path.join(PackageBase, File.executable), 'NODE_SEA_BLOB', runtime, { + sentinelFuse: 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2', + }); + } } function exec(cmd: string, ...args: string[]) { diff --git a/src/resolutions.ts b/src/resolutions.ts index 9b81554..4c7bc5a 100644 --- a/src/resolutions.ts +++ b/src/resolutions.ts @@ -15,12 +15,7 @@ const resolutions: Record> = {}; function replacementResolveFilename(this: Module, request: string, parent: Module, isMain: boolean) { const resolved = _resolveFilename.call(this, request, parent, isMain); - const parentfile = parent?.filename - ? '/' + - Path.relative(PackageBase, parent?.filename) - .split(Path.sep) - .join('/') - : '
'; + const parentfile = parent?.filename ? '/' + Path.relative(PackageBase, parent?.filename).split(Path.sep).join('/') : '
'; const cache = (resolutions[parentfile] = resolutions[parentfile] ?? {}); const specifier = (request === process.argv[1] ? '
' : request).split(Path.sep).join('/'); if (!Module.isBuiltin(request)) { diff --git a/src/runtime.ts b/src/runtime.ts index 3053f6f..be05ff7 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -133,8 +133,6 @@ function resolve(parent?: string, specifier?: string) { } } function patch(id: string, exports: object) { - // @ts-expect-error - exports.__esModule = true; switch (id) { case 'node:fs': return patchFS(exports as typeof FS);