Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb304ce10b | ||
|
|
8e2842b4a3 | ||
|
|
02119d5a83 | ||
|
|
1948f1caa9 | ||
|
|
52fa9a2a78 | ||
|
|
4e631b7ca2 | ||
|
|
fe1a0e06b0 | ||
|
|
9a808beecc | ||
|
|
381ca1a748 | ||
|
|
0d2b974dcc | ||
|
|
0cfaddcc77 | ||
|
|
fddff57c15 | ||
|
|
b02ce7697f | ||
|
|
85b1f90f2c | ||
|
|
3ecbbd5710 | ||
|
|
8bff0b7579 | ||
|
|
283773eb45 | ||
|
|
a99ae94fc2 | ||
|
|
0d70c1c39f | ||
|
|
ba587f0a08 | ||
|
|
580002844b |
@@ -1,43 +1,33 @@
|
|||||||
step-restore-cache: &step-restore-cache
|
|
||||||
restore_cache:
|
|
||||||
keys:
|
|
||||||
- v1-dependencies-{{ arch }}-{{ checksum "yarn.lock" }}
|
|
||||||
- v1-dependencies-{{ arch }}
|
|
||||||
|
|
||||||
steps-test: &steps-test
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- *step-restore-cache
|
|
||||||
- run: yarn --frozen-lockfile
|
|
||||||
- save_cache:
|
|
||||||
paths:
|
|
||||||
- node_modules
|
|
||||||
key: v1-dependencies-{{ arch }}-{{ checksum "yarn.lock" }}
|
|
||||||
- run: yarn build
|
|
||||||
- run: yarn test
|
|
||||||
|
|
||||||
version: 2.1
|
version: 2.1
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
macos:
|
|
||||||
xcode: "13.4.1"
|
|
||||||
<<: *steps-test
|
|
||||||
|
|
||||||
release:
|
orbs:
|
||||||
docker:
|
cfa: continuousauth/npm@1.0.2
|
||||||
- image: circleci/node:14.15
|
node: electronjs/node@1.4.1
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- *step-restore-cache
|
|
||||||
- run: yarn --frozen-lockfile
|
|
||||||
- run: npx @continuous-auth/circleci-oidc-github-auth@1.0.5
|
|
||||||
- run: npx semantic-release
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
|
||||||
test_and_release:
|
test_and_release:
|
||||||
|
# Run the test jobs first, then the release only when all the test jobs are successful
|
||||||
jobs:
|
jobs:
|
||||||
- test
|
- node/test:
|
||||||
- release:
|
executor: node/macos
|
||||||
|
name: test-mac-<< matrix.node-version >>
|
||||||
|
override-ci-command: yarn install --frozen-lockfile --ignore-engines
|
||||||
|
test-steps:
|
||||||
|
- run: yarn build
|
||||||
|
- run: yarn lint
|
||||||
|
- run: yarn test
|
||||||
|
use-test-steps: true
|
||||||
|
matrix:
|
||||||
|
alias: test
|
||||||
|
parameters:
|
||||||
|
node-version:
|
||||||
|
- 20.5.0
|
||||||
|
- 18.17.0
|
||||||
|
- 16.20.1
|
||||||
|
- 14.21.3
|
||||||
|
- 12.22.12
|
||||||
|
- 10.24.1
|
||||||
|
- cfa/release:
|
||||||
requires:
|
requires:
|
||||||
- test
|
- test
|
||||||
filters:
|
filters:
|
||||||
@@ -45,4 +35,3 @@ workflows:
|
|||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
context: cfa-release
|
context: cfa-release
|
||||||
|
|
||||||
|
|||||||
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @electron/wg-ecosystem
|
||||||
29
.github/workflows/add-to-project.yml
vendored
Normal file
29
.github/workflows/add-to-project.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Add to Ecosystem WG Project
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
pull_request_target:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add-to-project:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Generate GitHub App token
|
||||||
|
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
|
||||||
|
id: generate-token
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.ECOSYSTEM_ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||||
|
org: electron
|
||||||
|
- name: Add to Project
|
||||||
|
uses: dsanders11/project-actions/add-item@3a81985616963f32fae17d1d1b406c631f3201a1 # v1.1.0
|
||||||
|
with:
|
||||||
|
field: Opened
|
||||||
|
field-value: ${{ github.event.pull_request.created_at || github.event.issue.created_at }}
|
||||||
|
project-number: 89
|
||||||
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
26
.github/workflows/semantic.yml
vendored
Normal file
26
.github/workflows/semantic.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: "Check Semantic Commit"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- edited
|
||||||
|
- synchronize
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
permissions:
|
||||||
|
pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
|
||||||
|
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
|
||||||
|
name: Validate PR Title
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: semantic-pull-request
|
||||||
|
uses: amannn/action-semantic-pull-request@c3cd5d1ea3580753008872425915e343e351ab54 # v5.2.0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
validateSingleCommit: false
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
*.app
|
entry-asar/*.js*
|
||||||
|
entry-asar/*.ts
|
||||||
|
*.app
|
||||||
|
|||||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
yarn lint-staged
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Contributors to the Electron project
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
> Create universal macOS Electron applications
|
> Create universal macOS Electron applications
|
||||||
|
|
||||||
[](https://circleci.com/gh/electron/universal)
|
[](https://circleci.com/gh/electron/universal)
|
||||||
|
[](https://npm.im/@electron/universal)
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
19
entry-asar/ambient.d.ts
vendored
Normal file
19
entry-asar/ambient.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
declare namespace NodeJS {
|
||||||
|
interface Process extends EventEmitter {
|
||||||
|
// This is an undocumented private API. It exists.
|
||||||
|
_archPath: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'electron' {
|
||||||
|
const app: Electron.App;
|
||||||
|
|
||||||
|
namespace Electron {
|
||||||
|
interface App {
|
||||||
|
getAppPath: () => string;
|
||||||
|
setAppPath: (p: string) => void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { app };
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
if (process.arch === 'arm64') {
|
|
||||||
process._archPath = require.resolve('../app-arm64.asar');
|
|
||||||
} else {
|
|
||||||
process._archPath = require.resolve('../app-x64.asar');
|
|
||||||
}
|
|
||||||
|
|
||||||
require(process._archPath);
|
|
||||||
27
entry-asar/has-asar.ts
Normal file
27
entry-asar/has-asar.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { app } from 'electron';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
if (process.arch === 'arm64') {
|
||||||
|
setPaths('arm64');
|
||||||
|
} else {
|
||||||
|
setPaths('x64');
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
process._archPath = require.resolve(`../${asarFile}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
require(process._archPath);
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
if (process.arch === 'arm64') {
|
|
||||||
process._archPath = require.resolve('../app-arm64');
|
|
||||||
} else {
|
|
||||||
process._archPath = require.resolve('../app-x64');
|
|
||||||
}
|
|
||||||
|
|
||||||
require(process._archPath);
|
|
||||||
27
entry-asar/no-asar.ts
Normal file
27
entry-asar/no-asar.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { app } from 'electron';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
if (process.arch === 'arm64') {
|
||||||
|
setPaths('arm64');
|
||||||
|
} else {
|
||||||
|
setPaths('x64');
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
process._archPath = require.resolve(`../${appFolder}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
require(process._archPath);
|
||||||
19
package.json
19
package.json
@@ -20,26 +20,28 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"dist/*",
|
"dist/*",
|
||||||
"entry-asar/*",
|
"entry-asar/*",
|
||||||
|
"!entry-asar/**/*.ts",
|
||||||
"README.md"
|
"README.md"
|
||||||
],
|
],
|
||||||
"author": "Samuel Attard",
|
"author": "Samuel Attard",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
"build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && tsc -p tsconfig.entry-asar.json",
|
||||||
"lint": "prettier --check \"src/**/*.ts\"",
|
"lint": "prettier --check \"{src,entry-asar}/**/*.ts\"",
|
||||||
|
"prettier:write": "prettier --write \"{src,entry-asar}/**/*.ts\"",
|
||||||
"prepublishOnly": "npm run build",
|
"prepublishOnly": "npm run build",
|
||||||
"test": "exit 0"
|
"test": "exit 0",
|
||||||
|
"prepare": "husky install"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@continuous-auth/semantic-release-npm": "^2.0.0",
|
"@continuous-auth/semantic-release-npm": "^3.0.0",
|
||||||
"@types/debug": "^4.1.5",
|
"@types/debug": "^4.1.5",
|
||||||
"@types/fs-extra": "^9.0.4",
|
"@types/fs-extra": "^9.0.4",
|
||||||
"@types/minimatch": "^3.0.5",
|
"@types/minimatch": "^3.0.5",
|
||||||
"@types/node": "^14.14.7",
|
"@types/node": "^14.14.7",
|
||||||
"@types/plist": "^3.0.2",
|
"@types/plist": "^3.0.2",
|
||||||
"husky": "^4.3.0",
|
"husky": "^8.0.0",
|
||||||
"lint-staged": "^10.5.1",
|
"lint-staged": "^10.5.1",
|
||||||
"prettier": "^2.1.2",
|
"prettier": "^2.1.2",
|
||||||
"semantic-release": "^17.2.2",
|
|
||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -51,11 +53,6 @@
|
|||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"plist": "^3.0.4"
|
"plist": "^3.0.4"
|
||||||
},
|
},
|
||||||
"husky": {
|
|
||||||
"hooks": {
|
|
||||||
"pre-commit": "lint-staged"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.ts": [
|
"*.ts": [
|
||||||
"prettier --write"
|
"prettier --write"
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import * as asar from '@electron/asar';
|
import asar from '@electron/asar';
|
||||||
import { execFileSync } from 'child_process';
|
import { execFileSync } from 'child_process';
|
||||||
import * as crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import * as fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import * as path from 'path';
|
import path from 'path';
|
||||||
import * as minimatch from 'minimatch';
|
import minimatch from 'minimatch';
|
||||||
import * as os from 'os';
|
import os from 'os';
|
||||||
import { d } from './debug';
|
import { d } from './debug';
|
||||||
|
|
||||||
const LIPO = 'lipo';
|
const LIPO = 'lipo';
|
||||||
@@ -33,6 +33,12 @@ const MACHO_MAGIC = new Set([
|
|||||||
0xcffaedfe,
|
0xcffaedfe,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const MACHO_UNIVERSAL_MAGIC = new Set([
|
||||||
|
// universal
|
||||||
|
0xcafebabe,
|
||||||
|
0xbebafeca,
|
||||||
|
]);
|
||||||
|
|
||||||
export const detectAsarMode = async (appPath: string) => {
|
export const detectAsarMode = async (appPath: string) => {
|
||||||
d('checking asar mode of', appPath);
|
d('checking asar mode of', appPath);
|
||||||
const asarPath = path.resolve(appPath, 'Contents', 'Resources', 'app.asar');
|
const asarPath = path.resolve(appPath, 'Contents', 'Resources', 'app.asar');
|
||||||
@@ -147,6 +153,13 @@ export const mergeASARs = async ({
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
MACHO_UNIVERSAL_MAGIC.has(x64Content.readUInt32LE(0)) &&
|
||||||
|
MACHO_UNIVERSAL_MAGIC.has(arm64Content.readUInt32LE(0))
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!MACHO_MAGIC.has(x64Content.readUInt32LE(0))) {
|
if (!MACHO_MAGIC.has(x64Content.readUInt32LE(0))) {
|
||||||
throw new Error(`Can't reconcile two non-macho files ${file}`);
|
throw new Error(`Can't reconcile two non-macho files ${file}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import * as debug from 'debug';
|
import debug from 'debug';
|
||||||
|
|
||||||
export const d = debug('electron-universal');
|
export const d = debug('electron-universal');
|
||||||
|
|||||||
13
src/index.ts
13
src/index.ts
@@ -2,7 +2,7 @@ import { spawn } from '@malept/cross-spawn-promise';
|
|||||||
import * as asar from '@electron/asar';
|
import * as asar from '@electron/asar';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import * as minimatch from 'minimatch';
|
import minimatch from 'minimatch';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as plist from 'plist';
|
import * as plist from 'plist';
|
||||||
@@ -44,6 +44,10 @@ export type MakeUniversalOpts = {
|
|||||||
* Minimatch pattern of binaries that are expected to be the same x64 binary in both of the ASAR files.
|
* Minimatch pattern of binaries that are expected to be the same x64 binary in both of the ASAR files.
|
||||||
*/
|
*/
|
||||||
x64ArchFiles?: string;
|
x64ArchFiles?: string;
|
||||||
|
/**
|
||||||
|
* Minimatch pattern of paths that should not receive an injected ElectronAsarIntegrity value
|
||||||
|
*/
|
||||||
|
infoPlistsToIgnore?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const dupedFiles = (files: AppFile[]) =>
|
const dupedFiles = (files: AppFile[]) =>
|
||||||
@@ -321,7 +325,12 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergedPlist = { ...x64Plist, ElectronAsarIntegrity: generatedIntegrity };
|
const injectAsarIntegrity =
|
||||||
|
!opts.infoPlistsToIgnore ||
|
||||||
|
minimatch(plistFile.relativePath, opts.infoPlistsToIgnore, { matchBase: true });
|
||||||
|
const mergedPlist = injectAsarIntegrity
|
||||||
|
? { ...x64Plist, ElectronAsarIntegrity: generatedIntegrity }
|
||||||
|
: { ...x64Plist };
|
||||||
|
|
||||||
await fs.writeFile(path.resolve(tmpApp, plistFile.relativePath), plist.build(mergedPlist));
|
await fs.writeFile(path.resolve(tmpApp, plistFile.relativePath), plist.build(mergedPlist));
|
||||||
}
|
}
|
||||||
|
|||||||
4
tsconfig.cjs.json
Normal file
4
tsconfig.cjs.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
10
tsconfig.entry-asar.json
Normal file
10
tsconfig.entry-asar.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "entry-asar",
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"entry-asar"
|
||||||
|
],
|
||||||
|
"exclude": []
|
||||||
|
}
|
||||||
@@ -3,5 +3,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"outDir": "dist/esm"
|
"outDir": "dist/esm"
|
||||||
}
|
},
|
||||||
}
|
"include": ["src"]
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,9 +13,11 @@
|
|||||||
],
|
],
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
"esModuleInterop": true,
|
||||||
"declaration": true
|
"declaration": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src",
|
||||||
|
"entry-asar"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user