From ed1efe60a094892da57ca643ab52a872839de121 Mon Sep 17 00:00:00 2001 From: Erick Zhao Date: Wed, 12 Jun 2024 20:34:54 -0700 Subject: [PATCH 1/3] beep boop --- .gitignore | 6 ++++-- entry-asar/{ => cjs}/has-asar.ts | 0 entry-asar/{ => cjs}/no-asar.ts | 0 entry-asar/cjs/tsconfig.json | 11 +++++++++++ entry-asar/esm/has-asar.mts | 28 ++++++++++++++++++++++++++++ entry-asar/esm/tsconfig.json | 13 +++++++++++++ package.json | 2 +- src/index.ts | 22 +++++++++++++++++----- tsconfig.entry-asar.json | 10 ---------- tsconfig.json | 5 ++--- 10 files changed, 76 insertions(+), 21 deletions(-) rename entry-asar/{ => cjs}/has-asar.ts (100%) rename entry-asar/{ => cjs}/no-asar.ts (100%) create mode 100644 entry-asar/cjs/tsconfig.json create mode 100644 entry-asar/esm/has-asar.mts create mode 100644 entry-asar/esm/tsconfig.json delete mode 100644 tsconfig.entry-asar.json diff --git a/.gitignore b/.gitignore index 8dead59..347140b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ node_modules dist -entry-asar/*.js* -entry-asar/*.ts +entry-asar/cjs/*.?js* +entry-asar/cjs/*.d.?ts +entry-asar/esm/*.?js* +entry-asar/esm/*.d.?ts *.app test/fixtures/apps coverage \ No newline at end of file diff --git a/entry-asar/has-asar.ts b/entry-asar/cjs/has-asar.ts similarity index 100% rename from entry-asar/has-asar.ts rename to entry-asar/cjs/has-asar.ts diff --git a/entry-asar/no-asar.ts b/entry-asar/cjs/no-asar.ts similarity index 100% rename from entry-asar/no-asar.ts rename to entry-asar/cjs/no-asar.ts diff --git a/entry-asar/cjs/tsconfig.json b/entry-asar/cjs/tsconfig.json new file mode 100644 index 0000000..ea4d52f --- /dev/null +++ b/entry-asar/cjs/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + }, + "include": [ + ".", + "../ambient.d.ts" + ], + "exclude": [] +} diff --git a/entry-asar/esm/has-asar.mts b/entry-asar/esm/has-asar.mts new file mode 100644 index 0000000..3bee10f --- /dev/null +++ b/entry-asar/esm/has-asar.mts @@ -0,0 +1,28 @@ +import { app } from 'electron'; +import { createRequire } from 'node:module'; +import path from 'node:path'; + +if (process.arch === 'arm64') { + await setPaths('arm64'); +} else { + await setPaths('x64'); +} + +async function setPaths(platform: string) { + // This should return the full path, ending in something like + // Notion.app/Contents/Resources/app.asar + const appPath = app.getAppPath(); + const asarFile = `app-${platform}.asar`; + + // Maybe we'll handle this in Electron one day + if (path.basename(appPath) === 'app.asar') { + const platformAppPath = path.join(path.dirname(appPath), asarFile); + + // This is an undocumented API. It exists. + app.setAppPath(platformAppPath); + } + + const require = createRequire(import.meta.url); + process._archPath = require.resolve(`../${asarFile}`); + await import(process._archPath); +} diff --git a/entry-asar/esm/tsconfig.json b/entry-asar/esm/tsconfig.json new file mode 100644 index 0000000..00475c1 --- /dev/null +++ b/entry-asar/esm/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.esm.json", + "compilerOptions": { + "module": "ESNext", + "target":"ESNext", + "outDir": ".", + }, + "include": [ + ".", + "../ambient.d.ts" + ], + "exclude": [] +} diff --git a/package.json b/package.json index 03b8ef2..e3ec4f1 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ ], "author": "Samuel Attard", "scripts": { - "build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && tsc -p tsconfig.entry-asar.json", + "build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && tsc -p tsconfig.entry-asar.json && tsc -p tsconfig.entry-asar.esm.json", "lint": "prettier --check \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"", "prettier:write": "prettier --write \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"", "prepublishOnly": "npm run build", diff --git a/src/index.ts b/src/index.ts index a0bd4f7..feb537a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -290,10 +290,6 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = const entryAsar = path.resolve(tmpDir, 'entry-asar'); await fs.mkdir(entryAsar); - await fs.copy( - path.resolve(__dirname, '..', '..', 'entry-asar', 'has-asar.js'), - path.resolve(entryAsar, 'index.js'), - ); let pj = JSON.parse( ( await asar.extractFile( @@ -302,7 +298,23 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = ) ).toString('utf8'), ); - pj.main = 'index.js'; + + if (pj.type === 'module') { + d('ERICK TEST!!!!'); + await fs.copy( + path.resolve(__dirname, '..', '..', 'entry-asar', 'esm', 'has-asar.mjs'), + path.resolve(entryAsar, 'index.mjs'), + ); + pj.main = 'index.mjs'; + } else { + await fs.copy( + path.resolve(__dirname, '..', '..', 'entry-asar', 'has-asar.js'), + path.resolve(entryAsar, 'index.js'), + ); + pj.main = 'index.js'; + } + d(JSON.stringify(pj, null, 2)); + await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj); const asarPath = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'); await asar.createPackage(entryAsar, asarPath); diff --git a/tsconfig.entry-asar.json b/tsconfig.entry-asar.json deleted file mode 100644 index 33a1928..0000000 --- a/tsconfig.entry-asar.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "entry-asar", - }, - "include": [ - "entry-asar" - ], - "exclude": [] -} diff --git a/tsconfig.json b/tsconfig.json index fcac990..706f3f7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,6 @@ "declaration": true }, "include": [ - "src", - "entry-asar" - ] + "src" + ], } From e9a5812213a237bff1b94c6030faac2aedc4c937 Mon Sep 17 00:00:00 2001 From: Erick Zhao Date: Wed, 12 Jun 2024 20:50:35 -0700 Subject: [PATCH 2/3] add no-asar --- .gitignore | 4 ++-- entry-asar/esm/no-asar.mts | 29 +++++++++++++++++++++++++++++ package.json | 3 ++- src/index.ts | 31 ++++++++++++++++++++++--------- 4 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 entry-asar/esm/no-asar.mts diff --git a/.gitignore b/.gitignore index 347140b..a4d488f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ node_modules dist -entry-asar/cjs/*.?js* -entry-asar/cjs/*.d.?ts +entry-asar/cjs/*.js* +entry-asar/cjs/*.d.ts entry-asar/esm/*.?js* entry-asar/esm/*.d.?ts *.app diff --git a/entry-asar/esm/no-asar.mts b/entry-asar/esm/no-asar.mts new file mode 100644 index 0000000..72b28e7 --- /dev/null +++ b/entry-asar/esm/no-asar.mts @@ -0,0 +1,29 @@ +import { app } from 'electron'; +import { createRequire } from 'node:module'; +import path from 'node:path'; + +if (process.arch === 'arm64') { + await setPaths('arm64'); +} else { + await setPaths('x64'); +} + +async function setPaths(platform: string) { + // This should return the full path, ending in something like + // Notion.app/Contents/Resources/app + const appPath = app.getAppPath(); + const appFolder = `app-${platform}`; + + // Maybe we'll handle this in Electron one day + if (path.basename(appPath) === 'app') { + const platformAppPath = path.join(path.dirname(appPath), appFolder); + + // This is an undocumented private API. It exists. + app.setAppPath(platformAppPath); + } + + const require = createRequire(import.meta.url); + process._archPath = require.resolve(`../${appFolder}`); + + await import(process._archPath); +} diff --git a/package.json b/package.json index e3ec4f1..9c1f424 100644 --- a/package.json +++ b/package.json @@ -21,11 +21,12 @@ "dist/*", "entry-asar/*", "!entry-asar/**/*.ts", + "!entry-asar/**/tsconfig.json", "README.md" ], "author": "Samuel Attard", "scripts": { - "build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && tsc -p tsconfig.entry-asar.json && tsc -p tsconfig.entry-asar.esm.json", + "build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && tsc -p entry-asar/esm/tsconfig.json && tsc -p entry-asar/cjs/tsconfig.json", "lint": "prettier --check \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"", "prettier:write": "prettier --write \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"", "prepublishOnly": "npm run build", diff --git a/src/index.ts b/src/index.ts index feb537a..876ec05 100644 --- a/src/index.ts +++ b/src/index.ts @@ -210,14 +210,27 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = const entryAsar = path.resolve(tmpDir, 'entry-asar'); await fs.mkdir(entryAsar); - await fs.copy( - path.resolve(__dirname, '..', '..', 'entry-asar', 'no-asar.js'), - path.resolve(entryAsar, 'index.js'), - ); + let pj = await fs.readJson( path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'), ); - pj.main = 'index.js'; + + // Load a shim that redirects to the correct folder for the architecture. + // This needs to be a different file depending on if the app entrypoint is CommonJS or ESM. + if (pj.type === 'module' || pj.main.endsWith('.mjs')) { + await fs.copy( + path.resolve(__dirname, '..', '..', 'entry-asar', 'esm', 'no-asar.mjs'), + path.resolve(entryAsar, 'index.mjs'), + ); + pj.main = 'index.mjs'; + } else { + await fs.copy( + path.resolve(__dirname, '..', '..', 'entry-asar', 'cjs', 'no-asar.js'), + path.resolve(entryAsar, 'index.js'), + ); + pj.main = 'index.js'; + } + await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj); await asar.createPackage( entryAsar, @@ -299,8 +312,9 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = ).toString('utf8'), ); - if (pj.type === 'module') { - d('ERICK TEST!!!!'); + // Load a shim that redirects to the correct `app.asar` for the architecture. + // This needs to be a different file depending on if the app entrypoint is CommonJS or ESM. + if (pj.type === 'module' || pj.main.endsWith('.mjs')) { await fs.copy( path.resolve(__dirname, '..', '..', 'entry-asar', 'esm', 'has-asar.mjs'), path.resolve(entryAsar, 'index.mjs'), @@ -308,12 +322,11 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = pj.main = 'index.mjs'; } else { await fs.copy( - path.resolve(__dirname, '..', '..', 'entry-asar', 'has-asar.js'), + path.resolve(__dirname, '..', '..', 'entry-asar', 'cjs', 'has-asar.js'), path.resolve(entryAsar, 'index.js'), ); pj.main = 'index.js'; } - d(JSON.stringify(pj, null, 2)); await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj); const asarPath = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'); From 1c55526cdbd1e0a6bebbbbc6f399f8ce6336c436 Mon Sep 17 00:00:00 2001 From: Erick Zhao Date: Sun, 16 Jun 2024 21:04:57 -0700 Subject: [PATCH 3/3] Update package.json Co-authored-by: Erik Moura --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c1f424..7ac07cb 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "files": [ "dist/*", "entry-asar/*", - "!entry-asar/**/*.ts", + "!entry-asar/**/*.{ts,mts}", "!entry-asar/**/tsconfig.json", "README.md" ],