14 Commits

Author SHA1 Message Date
75309d0945 fix build
Some checks failed
Publish documentation / docs (push) Failing after 2s
Check Semantic Commit / Validate PR Title (pull_request) Failing after 2s
Test / Test (22.12.x) (pull_request) Has been cancelled
2025-12-12 17:11:16 +01:00
6f0968cdce Merge branch 'main' into esm-asar-entrypoints 2025-12-12 14:42:02 +01:00
dependabot[bot]
bf1269fe21 build(deps): bump glob from 10.4.5 to 10.5.0 (#159)
Some checks failed
Release / test (push) Failing after 1s
Release / Release (push) Has been skipped
Bumps [glob](https://github.com/isaacs/node-glob) from 10.4.5 to 10.5.0.
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v10.4.5...v10.5.0)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 10.5.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 13:54:26 -08:00
dependabot[bot]
ca53e14488 build(deps): bump actions/checkout from 5.0.0 to 6.0.0 (#158)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](08c6903cd8...1af3b93b68)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 10:59:33 -08:00
dependabot[bot]
1b9f5eb340 build(deps): bump tar from 7.5.1 to 7.5.2 (#157)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.1 to 7.5.2.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.1...v7.5.2)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-26 16:07:54 -08:00
Keeley Hammond
53c72d8c47 ci: use npm trusted publishing instead of CFA (#156) 2025-11-13 15:33:47 -08:00
Erick Zhao
b61638598d docs: add API docs and clean up README (#155) 2025-11-12 13:09:18 -08:00
dependabot[bot]
0a0b41d115 build(deps): bump vite from 6.3.6 to 6.4.1 (#154)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.3.6 to 6.4.1.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@6.4.1/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.4.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-03 17:51:24 -08:00
dependabot[bot]
ed0459457f build(deps): bump actions/setup-node from 5.0.0 to 6.0.0 (#153)
* build(deps): bump actions/setup-node from 5.0.0 to 6.0.0

Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](a0853c2454...2028fbc5c2)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* ci: use yarn cache

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2025-11-03 15:24:25 -08:00
Erick Zhao
b3059564b7 Merge branch 'main' into esm-asar-entrypoints 2024-06-21 16:12:39 -07:00
Erick Zhao
f7d15b8d34 Merge remote-tracking branch 'origin' into esm-asar-entrypoints 2024-06-17 15:18:33 -07:00
Erick Zhao
1c55526cdb Update package.json
Co-authored-by: Erik Moura <erikian@erikian.dev>
2024-06-16 21:04:57 -07:00
Erick Zhao
e9a5812213 add no-asar 2024-06-12 20:50:35 -07:00
Erick Zhao
ed1efe60a0 beep boop 2024-06-12 20:34:54 -07:00
17 changed files with 161 additions and 65 deletions

View File

@@ -14,10 +14,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: docs-publish environment: docs-publish
steps: steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies - name: Install dependencies
run: yarn --immutable run: yarn --immutable
- name: Build API documentation - name: Build API documentation

View File

@@ -13,24 +13,25 @@ jobs:
name: Release name: Release
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test needs: test
environment: npm environment: npm-trusted-publisher
permissions: permissions:
id-token: write # for CFA and npm provenance id-token: write # for publishing releases
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
- name: Install - name: Install
run: yarn install --immutable run: yarn install --immutable
- uses: continuousauth/action@4e8a2573eeb706f6d7300d6a9f3ca6322740b72d # v1.0.5 - name: Get GitHub App Token
timeout-minutes: 60 id: secret-service
uses: electron/secret-service-action@3476425e8b30555aac15b1b7096938e254b0e155 # v1.0.0
- name: Run Semantic Release
uses: electron/semantic-trusted-release@5eceb399ac8de8863205cf6e34109bce473ba566 # v1.0.1
with: with:
project-id: ${{ secrets.CFA_PROJECT_ID }} github-token: ${{ fromJSON(steps.secret-service.outputs.secrets).GITHUB_TOKEN }}
secret: ${{ secrets.CFA_SECRET }}
npm-token: ${{ secrets.NPM_TOKEN }}

View File

@@ -22,9 +22,9 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with: with:
node-version: "${{ matrix.node-version }}" node-version: "${{ matrix.node-version }}"
cache: 'yarn' cache: 'yarn'

6
.gitignore vendored
View File

@@ -1,7 +1,9 @@
node_modules node_modules
dist dist
entry-asar/*.js* entry-asar/cjs/*.js*
entry-asar/*.ts entry-asar/cjs/*.d.ts
entry-asar/esm/*.?js*
entry-asar/esm/*.d.?ts
*.app *.app
test/fixtures/apps test/fixtures/apps
coverage coverage

5
.npmignore Normal file
View File

@@ -0,0 +1,5 @@
# npmignore overrides .gitignore for yarn pack
# Only exclude source files, not built files
entry-asar/**/*.mts
entry-asar/**/*.ts
entry-asar/**/tsconfig.json

View File

@@ -2,7 +2,7 @@
"plugins": [ "plugins": [
"@semantic-release/commit-analyzer", "@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator", "@semantic-release/release-notes-generator",
"@continuous-auth/semantic-release-npm", "@semantic-release/npm",
"@semantic-release/github" "@semantic-release/github"
], ],
"branches": [ "main" ] "branches": [ "main" ]

View File

@@ -4,6 +4,7 @@
[![Test](https://github.com/electron/universal/actions/workflows/test.yml/badge.svg)](https://github.com/electron/universal/actions/workflows/test.yml) [![Test](https://github.com/electron/universal/actions/workflows/test.yml/badge.svg)](https://github.com/electron/universal/actions/workflows/test.yml)
[![NPM package](https://img.shields.io/npm/v/@electron/universal)](https://npm.im/@electron/universal) [![NPM package](https://img.shields.io/npm/v/@electron/universal)](https://npm.im/@electron/universal)
[![API docs](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fregistry.npmjs.org%2F%40electron%2Funiversal%2Flatest&query=%24.version&logo=typescript&logoColor=white&label=API%20Docs)](https://packages.electronjs.org/universal)
## Usage ## Usage
@@ -22,6 +23,8 @@ await makeUniversalApp({
}); });
``` ```
For full API usage, see the [API documentation](https://packages.electronjs.org/universal).
## Advanced configuration ## Advanced configuration
The basic usage patterns will work for most apps out of the box. Additional configuration The basic usage patterns will work for most apps out of the box. Additional configuration
@@ -118,8 +121,4 @@ Note that if you are using `mergeASARs`, you may need to add architecture-specif
binary resources to the `singleArchFiles` pattern. binary resources to the `singleArchFiles` pattern.
See [Merging ASARs usage](#merging-asar-archives-to-reduce-app-size) for an example. See [Merging ASARs usage](#merging-asar-archives-to-reduce-app-size) for an example.
#### How do I build my app for Apple silicon in the first place?
Check out the [Electron Apple silicon blog post](https://www.electronjs.org/blog/apple-silicon).
[`minimatch`]: https://github.com/isaacs/minimatch?tab=readme-ov-file#features [`minimatch`]: https://github.com/isaacs/minimatch?tab=readme-ov-file#features

View File

@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": ".",
},
"include": [
".",
"../ambient.d.ts"
],
"exclude": []
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,14 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"target":"ESNext",
"outDir": ".",
"moduleResolution": "bundler"
},
"include": [
".",
"../ambient.d.ts"
],
"exclude": []
}

View File

@@ -19,8 +19,12 @@
}, },
"files": [ "files": [
"dist/*", "dist/*",
"entry-asar/*", "entry-asar/**/*",
"!entry-asar/**/*.ts", "!entry-asar/**/has-asar.ts",
"!entry-asar/**/no-asar.ts",
"!entry-asar/**/has-asar.mts",
"!entry-asar/**/no-asar.mts",
"!entry-asar/**/tsconfig.json",
"README.md" "README.md"
], ],
"author": "Samuel Attard", "author": "Samuel Attard",
@@ -28,7 +32,7 @@
"provenance": true "provenance": true
}, },
"scripts": { "scripts": {
"build": "tsc -p tsconfig.json && tsc -p tsconfig.entry-asar.json", "build": "tsc -p tsconfig.json && tsc -p entry-asar/esm/tsconfig.json && tsc -p entry-asar/cjs/tsconfig.json",
"build:docs": "npx typedoc", "build:docs": "npx typedoc",
"lint": "prettier --check \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"", "lint": "prettier --check \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"",
"prettier:write": "prettier --write \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"", "prettier:write": "prettier --write \"{src,entry-asar,test}/**/*.ts\" \"*.ts\"",

View File

@@ -254,17 +254,30 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
const entryAsar = path.resolve(tmpDir, 'entry-asar'); const entryAsar = path.resolve(tmpDir, 'entry-asar');
await fs.promises.mkdir(entryAsar, { recursive: true }); await fs.promises.mkdir(entryAsar, { recursive: true });
await fs.promises.cp(
path.resolve(import.meta.dirname, '..', 'entry-asar', 'no-asar.js'),
path.resolve(entryAsar, 'index.js'),
);
let pj = JSON.parse( let pj = JSON.parse(
await fs.promises.readFile( await fs.promises.readFile(
path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'), path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'),
'utf8', 'utf8',
), ),
); );
// 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.promises.cp(
path.resolve(import.meta.dirname, '..', 'entry-asar', 'esm', 'no-asar.mjs'),
path.resolve(entryAsar, 'index.mjs'),
);
pj.main = 'index.mjs';
} else {
await fs.promises.cp(
path.resolve(import.meta.dirname, '..', 'entry-asar', 'cjs', 'no-asar.js'),
path.resolve(entryAsar, 'index.js'),
);
pj.main = 'index.js'; pj.main = 'index.js';
}
await fs.promises.writeFile( await fs.promises.writeFile(
path.resolve(entryAsar, 'package.json'), path.resolve(entryAsar, 'package.json'),
JSON.stringify(pj) + '\n', JSON.stringify(pj) + '\n',
@@ -337,10 +350,6 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
const entryAsar = path.resolve(tmpDir, 'entry-asar'); const entryAsar = path.resolve(tmpDir, 'entry-asar');
await fs.promises.mkdir(entryAsar, { recursive: true }); await fs.promises.mkdir(entryAsar, { recursive: true });
await fs.promises.cp(
path.resolve(import.meta.dirname, '..', 'entry-asar', 'has-asar.js'),
path.resolve(entryAsar, 'index.js'),
);
let pj = JSON.parse( let pj = JSON.parse(
( (
await asar.extractFile( await asar.extractFile(
@@ -349,7 +358,23 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
) )
).toString('utf8'), ).toString('utf8'),
); );
// 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.promises.cp(
path.resolve(import.meta.dirname, '..', 'entry-asar', 'esm', 'has-asar.mjs'),
path.resolve(entryAsar, 'index.mjs'),
);
pj.main = 'index.mjs';
} else {
await fs.promises.cp(
path.resolve(import.meta.dirname, '..', 'entry-asar', 'cjs', 'has-asar.js'),
path.resolve(entryAsar, 'index.js'),
);
pj.main = 'index.js'; pj.main = 'index.js';
}
await fs.promises.writeFile( await fs.promises.writeFile(
path.resolve(entryAsar, 'package.json'), path.resolve(entryAsar, 'package.json'),
JSON.stringify(pj) + '\n', JSON.stringify(pj) + '\n',

View File

@@ -1,23 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"lib": [
"es2017"
],
"sourceMap": true,
"strict": true,
"outDir": "entry-asar",
"types": [
"node",
],
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"esModuleInterop": true,
"declaration": false
},
"include": [
"entry-asar"
],
"exclude": []
}

View File

@@ -1332,8 +1332,8 @@ __metadata:
linkType: hard linkType: hard
"glob@npm:^10.2.2": "glob@npm:^10.2.2":
version: 10.4.5 version: 10.5.0
resolution: "glob@npm:10.4.5" resolution: "glob@npm:10.5.0"
dependencies: dependencies:
foreground-child: "npm:^3.1.0" foreground-child: "npm:^3.1.0"
jackspeak: "npm:^3.1.2" jackspeak: "npm:^3.1.2"
@@ -1343,7 +1343,7 @@ __metadata:
path-scurry: "npm:^1.11.1" path-scurry: "npm:^1.11.1"
bin: bin:
glob: dist/esm/bin.mjs glob: dist/esm/bin.mjs
checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e checksum: 10c0/100705eddbde6323e7b35e1d1ac28bcb58322095bd8e63a7d0bef1a2cdafe0d0f7922a981b2b48369a4f8c1b077be5c171804534c3509dfe950dde15fbe6d828
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2549,15 +2549,15 @@ __metadata:
linkType: hard linkType: hard
"tar@npm:^7.4.3": "tar@npm:^7.4.3":
version: 7.5.1 version: 7.5.2
resolution: "tar@npm:7.5.1" resolution: "tar@npm:7.5.2"
dependencies: dependencies:
"@isaacs/fs-minipass": "npm:^4.0.0" "@isaacs/fs-minipass": "npm:^4.0.0"
chownr: "npm:^3.0.0" chownr: "npm:^3.0.0"
minipass: "npm:^7.1.2" minipass: "npm:^7.1.2"
minizlib: "npm:^3.1.0" minizlib: "npm:^3.1.0"
yallist: "npm:^5.0.0" yallist: "npm:^5.0.0"
checksum: 10c0/0dad0596a61586180981133b20c32cfd93c5863c5b7140d646714e6ea8ec84583b879e5dc3928a4d683be6e6109ad7ea3de1cf71986d5194f81b3a016c8858c9 checksum: 10c0/a7d8b801139b52f93a7e34830db0de54c5aa45487c7cb551f6f3d44a112c67f1cb8ffdae856b05fd4f17b1749911f1c26f1e3a23bbe0279e17fd96077f13f467
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2723,8 +2723,8 @@ __metadata:
linkType: hard linkType: hard
"vite@npm:^5.0.0 || ^6.0.0": "vite@npm:^5.0.0 || ^6.0.0":
version: 6.3.6 version: 6.4.1
resolution: "vite@npm:6.3.6" resolution: "vite@npm:6.4.1"
dependencies: dependencies:
esbuild: "npm:^0.25.0" esbuild: "npm:^0.25.0"
fdir: "npm:^6.4.4" fdir: "npm:^6.4.4"
@@ -2773,7 +2773,7 @@ __metadata:
optional: true optional: true
bin: bin:
vite: bin/vite.js vite: bin/vite.js
checksum: 10c0/add701f1e72596c002275782e38d0389ab400c1be330c93a3009804d62db68097a936ca1c53c3301df3aaacfe5e328eab547060f31ef9c49a277ae50df6ad4fb checksum: 10c0/77bb4c5b10f2a185e7859cc9a81c789021bc18009b02900347d1583b453b58e4b19ff07a5e5a5b522b68fc88728460bb45a63b104d969e8c6a6152aea3b849f7
languageName: node languageName: node
linkType: hard linkType: hard