Delete 100 files via Git Manager GUI
This commit is contained in:
-44
@@ -1,44 +0,0 @@
|
||||
import { Filesystem, FilesystemFileEntry } from './filesystem';
|
||||
import { CrawledFileType } from './crawlfs';
|
||||
import { Stats } from 'fs';
|
||||
export type InputMetadata = {
|
||||
[property: string]: CrawledFileType;
|
||||
};
|
||||
export type BasicFilesArray = {
|
||||
filename: string;
|
||||
unpack: boolean;
|
||||
}[];
|
||||
export type BasicStreamArray = {
|
||||
filename: string;
|
||||
streamGenerator: () => NodeJS.ReadableStream;
|
||||
mode: Stats['mode'];
|
||||
unpack: boolean;
|
||||
link: string | undefined;
|
||||
}[];
|
||||
export type FilesystemFilesAndLinks<T extends BasicFilesArray | BasicStreamArray> = {
|
||||
files: T;
|
||||
links: T;
|
||||
};
|
||||
export declare function writeFilesystem(dest: string, filesystem: Filesystem, lists: FilesystemFilesAndLinks<BasicFilesArray>, metadata: InputMetadata): Promise<NodeJS.WritableStream>;
|
||||
export declare function streamFilesystem(dest: string, filesystem: Filesystem, lists: FilesystemFilesAndLinks<BasicStreamArray>): Promise<import("fs").WriteStream>;
|
||||
export interface FileRecord extends FilesystemFileEntry {
|
||||
integrity: {
|
||||
hash: string;
|
||||
algorithm: 'SHA256';
|
||||
blocks: string[];
|
||||
blockSize: number;
|
||||
};
|
||||
}
|
||||
export type DirectoryRecord = {
|
||||
files: Record<string, DirectoryRecord | FileRecord>;
|
||||
};
|
||||
export type ArchiveHeader = {
|
||||
header: DirectoryRecord;
|
||||
headerString: string;
|
||||
headerSize: number;
|
||||
};
|
||||
export declare function readArchiveHeaderSync(archivePath: string): ArchiveHeader;
|
||||
export declare function readFilesystemSync(archivePath: string): Filesystem;
|
||||
export declare function uncacheFilesystem(archivePath: string): boolean;
|
||||
export declare function uncacheAll(): void;
|
||||
export declare function readFileSync(filesystem: Filesystem, filename: string, info: FilesystemFileEntry): Buffer;
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var m = o[Symbol.asyncIterator], i;
|
||||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
||||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
||||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.writeFilesystem = writeFilesystem;
|
||||
exports.streamFilesystem = streamFilesystem;
|
||||
exports.readArchiveHeaderSync = readArchiveHeaderSync;
|
||||
exports.readFilesystemSync = readFilesystemSync;
|
||||
exports.uncacheFilesystem = uncacheFilesystem;
|
||||
exports.uncacheAll = uncacheAll;
|
||||
exports.readFileSync = readFileSync;
|
||||
const path = __importStar(require("path"));
|
||||
const wrapped_fs_1 = __importDefault(require("./wrapped-fs"));
|
||||
const pickle_1 = require("./pickle");
|
||||
const filesystem_1 = require("./filesystem");
|
||||
const util_1 = require("util");
|
||||
const stream = __importStar(require("stream"));
|
||||
const pipeline = (0, util_1.promisify)(stream.pipeline);
|
||||
let filesystemCache = Object.create(null);
|
||||
async function copyFile(dest, src, filename) {
|
||||
const srcFile = path.join(src, filename);
|
||||
const targetFile = path.join(dest, filename);
|
||||
const [content, stats] = await Promise.all([
|
||||
wrapped_fs_1.default.readFile(srcFile),
|
||||
wrapped_fs_1.default.stat(srcFile),
|
||||
wrapped_fs_1.default.mkdirp(path.dirname(targetFile)),
|
||||
]);
|
||||
return wrapped_fs_1.default.writeFile(targetFile, content, { mode: stats.mode });
|
||||
}
|
||||
async function streamTransformedFile(stream, outStream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.pipe(outStream, { end: false });
|
||||
stream.on('error', reject);
|
||||
stream.on('end', () => resolve());
|
||||
});
|
||||
}
|
||||
const writeFileListToStream = async function (dest, filesystem, out, lists, metadata) {
|
||||
const { files, links } = lists;
|
||||
for (const file of files) {
|
||||
if (file.unpack) {
|
||||
// the file should not be packed into archive
|
||||
const filename = path.relative(filesystem.getRootPath(), file.filename);
|
||||
await copyFile(`${dest}.unpacked`, filesystem.getRootPath(), filename);
|
||||
}
|
||||
else {
|
||||
const transformed = metadata[file.filename].transformed;
|
||||
const stream = wrapped_fs_1.default.createReadStream(transformed ? transformed.path : file.filename);
|
||||
await streamTransformedFile(stream, out);
|
||||
}
|
||||
}
|
||||
for (const file of links.filter((f) => f.unpack)) {
|
||||
// the symlink needs to be recreated outside in .unpacked
|
||||
const filename = path.relative(filesystem.getRootPath(), file.filename);
|
||||
const link = await wrapped_fs_1.default.readlink(file.filename);
|
||||
await createSymlink(dest, filename, link);
|
||||
}
|
||||
return out.end();
|
||||
};
|
||||
async function writeFilesystem(dest, filesystem, lists, metadata) {
|
||||
const out = await createFilesystemWriteStream(filesystem, dest);
|
||||
return writeFileListToStream(dest, filesystem, out, lists, metadata);
|
||||
}
|
||||
async function streamFilesystem(dest, filesystem, lists) {
|
||||
var _a, e_1, _b, _c;
|
||||
const out = await createFilesystemWriteStream(filesystem, dest);
|
||||
const { files, links } = lists;
|
||||
try {
|
||||
for (var _d = true, files_1 = __asyncValues(files), files_1_1; files_1_1 = await files_1.next(), _a = files_1_1.done, !_a; _d = true) {
|
||||
_c = files_1_1.value;
|
||||
_d = false;
|
||||
const file = _c;
|
||||
// the file should not be packed into archive
|
||||
if (file.unpack) {
|
||||
const targetFile = path.join(`${dest}.unpacked`, file.filename);
|
||||
await wrapped_fs_1.default.mkdirp(path.dirname(targetFile));
|
||||
const writeStream = wrapped_fs_1.default.createWriteStream(targetFile, { mode: file.mode });
|
||||
await pipeline(file.streamGenerator(), writeStream);
|
||||
}
|
||||
else {
|
||||
await streamTransformedFile(file.streamGenerator(), out);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (!_d && !_a && (_b = files_1.return)) await _b.call(files_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
for (const file of links.filter((f) => f.unpack && f.link)) {
|
||||
// the symlink needs to be recreated outside in .unpacked
|
||||
await createSymlink(dest, file.filename, file.link);
|
||||
}
|
||||
return out.end();
|
||||
}
|
||||
function readArchiveHeaderSync(archivePath) {
|
||||
const fd = wrapped_fs_1.default.openSync(archivePath, 'r');
|
||||
let size;
|
||||
let headerBuf;
|
||||
try {
|
||||
const sizeBuf = Buffer.alloc(8);
|
||||
if (wrapped_fs_1.default.readSync(fd, sizeBuf, 0, 8, null) !== 8) {
|
||||
throw new Error('Unable to read header size');
|
||||
}
|
||||
const sizePickle = pickle_1.Pickle.createFromBuffer(sizeBuf);
|
||||
size = sizePickle.createIterator().readUInt32();
|
||||
headerBuf = Buffer.alloc(size);
|
||||
if (wrapped_fs_1.default.readSync(fd, headerBuf, 0, size, null) !== size) {
|
||||
throw new Error('Unable to read header');
|
||||
}
|
||||
}
|
||||
finally {
|
||||
wrapped_fs_1.default.closeSync(fd);
|
||||
}
|
||||
const headerPickle = pickle_1.Pickle.createFromBuffer(headerBuf);
|
||||
const header = headerPickle.createIterator().readString();
|
||||
return { headerString: header, header: JSON.parse(header), headerSize: size };
|
||||
}
|
||||
function readFilesystemSync(archivePath) {
|
||||
if (!filesystemCache[archivePath]) {
|
||||
const header = readArchiveHeaderSync(archivePath);
|
||||
const filesystem = new filesystem_1.Filesystem(archivePath);
|
||||
filesystem.setHeader(header.header, header.headerSize);
|
||||
filesystemCache[archivePath] = filesystem;
|
||||
}
|
||||
return filesystemCache[archivePath];
|
||||
}
|
||||
function uncacheFilesystem(archivePath) {
|
||||
if (filesystemCache[archivePath]) {
|
||||
filesystemCache[archivePath] = undefined;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function uncacheAll() {
|
||||
filesystemCache = {};
|
||||
}
|
||||
function readFileSync(filesystem, filename, info) {
|
||||
let buffer = Buffer.alloc(info.size);
|
||||
if (info.size <= 0) {
|
||||
return buffer;
|
||||
}
|
||||
if (info.unpacked) {
|
||||
// it's an unpacked file, copy it.
|
||||
buffer = wrapped_fs_1.default.readFileSync(path.join(`${filesystem.getRootPath()}.unpacked`, filename));
|
||||
}
|
||||
else {
|
||||
// Node throws an exception when reading 0 bytes into a 0-size buffer,
|
||||
// so we short-circuit the read in this case.
|
||||
const fd = wrapped_fs_1.default.openSync(filesystem.getRootPath(), 'r');
|
||||
try {
|
||||
const offset = 8 + filesystem.getHeaderSize() + parseInt(info.offset);
|
||||
wrapped_fs_1.default.readSync(fd, buffer, 0, info.size, offset);
|
||||
}
|
||||
finally {
|
||||
wrapped_fs_1.default.closeSync(fd);
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
async function createFilesystemWriteStream(filesystem, dest) {
|
||||
const headerPickle = pickle_1.Pickle.createEmpty();
|
||||
headerPickle.writeString(JSON.stringify(filesystem.getHeader()));
|
||||
const headerBuf = headerPickle.toBuffer();
|
||||
const sizePickle = pickle_1.Pickle.createEmpty();
|
||||
sizePickle.writeUInt32(headerBuf.length);
|
||||
const sizeBuf = sizePickle.toBuffer();
|
||||
const out = wrapped_fs_1.default.createWriteStream(dest);
|
||||
await new Promise((resolve, reject) => {
|
||||
out.on('error', reject);
|
||||
out.write(sizeBuf);
|
||||
return out.write(headerBuf, () => resolve());
|
||||
});
|
||||
return out;
|
||||
}
|
||||
async function createSymlink(dest, filepath, link) {
|
||||
// if symlink is within subdirectories, then we need to recreate dir structure
|
||||
await wrapped_fs_1.default.mkdirp(path.join(`${dest}.unpacked`, path.dirname(filepath)));
|
||||
// create symlink within unpacked dir
|
||||
await wrapped_fs_1.default.symlink(link, path.join(`${dest}.unpacked`, filepath)).catch(async (error) => {
|
||||
if (error.code === 'EPERM' && error.syscall === 'symlink') {
|
||||
throw new Error('Could not create symlinks for unpacked assets. On Windows, consider activating Developer Mode to allow non-admin users to create symlinks by following the instructions at https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development.');
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=disk.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-44
@@ -1,44 +0,0 @@
|
||||
import { FileIntegrity } from './integrity';
|
||||
import { CrawledFileType } from './crawlfs';
|
||||
export type EntryMetadata = {
|
||||
unpacked?: boolean;
|
||||
};
|
||||
export type FilesystemDirectoryEntry = {
|
||||
files: Record<string, FilesystemEntry>;
|
||||
} & EntryMetadata;
|
||||
export type FilesystemFileEntry = {
|
||||
unpacked: boolean;
|
||||
executable: boolean;
|
||||
offset: string;
|
||||
size: number;
|
||||
integrity: FileIntegrity;
|
||||
} & EntryMetadata;
|
||||
export type FilesystemLinkEntry = {
|
||||
link: string;
|
||||
} & EntryMetadata;
|
||||
export type FilesystemEntry = FilesystemDirectoryEntry | FilesystemFileEntry | FilesystemLinkEntry;
|
||||
export declare class Filesystem {
|
||||
private src;
|
||||
private header;
|
||||
private headerSize;
|
||||
private offset;
|
||||
constructor(src: string);
|
||||
getRootPath(): string;
|
||||
getHeader(): FilesystemEntry;
|
||||
getHeaderSize(): number;
|
||||
setHeader(header: FilesystemEntry, headerSize: number): void;
|
||||
searchNodeFromDirectory(p: string): FilesystemEntry;
|
||||
searchNodeFromPath(p: string): FilesystemEntry;
|
||||
insertDirectory(p: string, shouldUnpack: boolean): Record<string, FilesystemEntry>;
|
||||
insertFile(p: string, streamGenerator: () => NodeJS.ReadableStream, shouldUnpack: boolean, file: CrawledFileType, options?: {
|
||||
transform?: (filePath: string) => NodeJS.ReadWriteStream | void;
|
||||
}): Promise<void>;
|
||||
insertLink(p: string, shouldUnpack: boolean, parentPath?: string, symlink?: string, // /var/tmp => /private/var
|
||||
src?: string): string;
|
||||
private resolveLink;
|
||||
listFiles(options?: {
|
||||
isPack: boolean;
|
||||
}): string[];
|
||||
getNode(p: string, followLinks?: boolean): FilesystemEntry;
|
||||
getFile(p: string, followLinks?: boolean): FilesystemEntry;
|
||||
}
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Filesystem = void 0;
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const util_1 = require("util");
|
||||
const stream = __importStar(require("stream"));
|
||||
const integrity_1 = require("./integrity");
|
||||
const wrapped_fs_1 = __importDefault(require("./wrapped-fs"));
|
||||
const UINT32_MAX = 2 ** 32 - 1;
|
||||
const pipeline = (0, util_1.promisify)(stream.pipeline);
|
||||
class Filesystem {
|
||||
constructor(src) {
|
||||
this.src = path.resolve(src);
|
||||
this.header = { files: Object.create(null) };
|
||||
this.headerSize = 0;
|
||||
this.offset = BigInt(0);
|
||||
}
|
||||
getRootPath() {
|
||||
return this.src;
|
||||
}
|
||||
getHeader() {
|
||||
return this.header;
|
||||
}
|
||||
getHeaderSize() {
|
||||
return this.headerSize;
|
||||
}
|
||||
setHeader(header, headerSize) {
|
||||
this.header = header;
|
||||
this.headerSize = headerSize;
|
||||
}
|
||||
searchNodeFromDirectory(p) {
|
||||
let json = this.header;
|
||||
const dirs = p.split(path.sep);
|
||||
for (const dir of dirs) {
|
||||
if (dir !== '.') {
|
||||
if ('files' in json) {
|
||||
if (!json.files[dir]) {
|
||||
json.files[dir] = { files: Object.create(null) };
|
||||
}
|
||||
json = json.files[dir];
|
||||
}
|
||||
else {
|
||||
throw new Error('Unexpected directory state while traversing: ' + p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
searchNodeFromPath(p) {
|
||||
p = path.relative(this.src, p);
|
||||
if (!p) {
|
||||
return this.header;
|
||||
}
|
||||
const name = path.basename(p);
|
||||
const node = this.searchNodeFromDirectory(path.dirname(p));
|
||||
if (!node.files) {
|
||||
node.files = Object.create(null);
|
||||
}
|
||||
if (!node.files[name]) {
|
||||
node.files[name] = Object.create(null);
|
||||
}
|
||||
return node.files[name];
|
||||
}
|
||||
insertDirectory(p, shouldUnpack) {
|
||||
const node = this.searchNodeFromPath(p);
|
||||
if (shouldUnpack) {
|
||||
node.unpacked = shouldUnpack;
|
||||
}
|
||||
node.files = node.files || Object.create(null);
|
||||
return node.files;
|
||||
}
|
||||
async insertFile(p, streamGenerator, shouldUnpack, file, options = {}) {
|
||||
const dirNode = this.searchNodeFromPath(path.dirname(p));
|
||||
const node = this.searchNodeFromPath(p);
|
||||
if (shouldUnpack || dirNode.unpacked) {
|
||||
node.size = file.stat.size;
|
||||
node.unpacked = true;
|
||||
node.integrity = await (0, integrity_1.getFileIntegrity)(streamGenerator());
|
||||
return Promise.resolve();
|
||||
}
|
||||
let size;
|
||||
const transformed = options.transform && options.transform(p);
|
||||
if (transformed) {
|
||||
const tmpdir = await wrapped_fs_1.default.mkdtemp(path.join(os.tmpdir(), 'asar-'));
|
||||
const tmpfile = path.join(tmpdir, path.basename(p));
|
||||
const out = wrapped_fs_1.default.createWriteStream(tmpfile);
|
||||
await pipeline(streamGenerator(), transformed, out);
|
||||
file.transformed = {
|
||||
path: tmpfile,
|
||||
stat: await wrapped_fs_1.default.lstat(tmpfile),
|
||||
};
|
||||
size = file.transformed.stat.size;
|
||||
}
|
||||
else {
|
||||
size = file.stat.size;
|
||||
}
|
||||
// JavaScript cannot precisely present integers >= UINT32_MAX.
|
||||
if (size > UINT32_MAX) {
|
||||
throw new Error(`${p}: file size can not be larger than 4.2GB`);
|
||||
}
|
||||
node.size = size;
|
||||
node.offset = this.offset.toString();
|
||||
node.integrity = await (0, integrity_1.getFileIntegrity)(streamGenerator());
|
||||
if (process.platform !== 'win32' && file.stat.mode & 0o100) {
|
||||
node.executable = true;
|
||||
}
|
||||
this.offset += BigInt(size);
|
||||
}
|
||||
insertLink(p, shouldUnpack, parentPath = wrapped_fs_1.default.realpathSync(path.dirname(p)), symlink = wrapped_fs_1.default.readlinkSync(p), // /var/tmp => /private/var
|
||||
src = wrapped_fs_1.default.realpathSync(this.src)) {
|
||||
const link = this.resolveLink(src, parentPath, symlink);
|
||||
if (link.startsWith('..')) {
|
||||
throw new Error(`${p}: file "${link}" links out of the package`);
|
||||
}
|
||||
const node = this.searchNodeFromPath(p);
|
||||
const dirNode = this.searchNodeFromPath(path.dirname(p));
|
||||
if (shouldUnpack || dirNode.unpacked) {
|
||||
node.unpacked = true;
|
||||
}
|
||||
node.link = link;
|
||||
return link;
|
||||
}
|
||||
resolveLink(src, parentPath, symlink) {
|
||||
const target = path.join(parentPath, symlink);
|
||||
const link = path.relative(src, target);
|
||||
return link;
|
||||
}
|
||||
listFiles(options) {
|
||||
const files = [];
|
||||
const fillFilesFromMetadata = function (basePath, metadata) {
|
||||
if (!('files' in metadata)) {
|
||||
return;
|
||||
}
|
||||
for (const [childPath, childMetadata] of Object.entries(metadata.files)) {
|
||||
const fullPath = path.join(basePath, childPath);
|
||||
const packState = 'unpacked' in childMetadata && childMetadata.unpacked ? 'unpack' : 'pack ';
|
||||
files.push(options && options.isPack ? `${packState} : ${fullPath}` : fullPath);
|
||||
fillFilesFromMetadata(fullPath, childMetadata);
|
||||
}
|
||||
};
|
||||
fillFilesFromMetadata('/', this.header);
|
||||
return files;
|
||||
}
|
||||
getNode(p, followLinks = true) {
|
||||
const node = this.searchNodeFromDirectory(path.dirname(p));
|
||||
const name = path.basename(p);
|
||||
if ('link' in node && followLinks) {
|
||||
return this.getNode(path.join(node.link, name));
|
||||
}
|
||||
if (name) {
|
||||
return node.files[name];
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
getFile(p, followLinks = true) {
|
||||
const info = this.getNode(p, followLinks);
|
||||
if (!info) {
|
||||
throw new Error(`"${p}" was not found in this archive`);
|
||||
}
|
||||
// if followLinks is false we don't resolve symlinks
|
||||
if ('link' in info && followLinks) {
|
||||
return this.getFile(info.link, followLinks);
|
||||
}
|
||||
else {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Filesystem = Filesystem;
|
||||
//# sourceMappingURL=filesystem.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-7
@@ -1,7 +0,0 @@
|
||||
export type FileIntegrity = {
|
||||
algorithm: 'SHA256';
|
||||
hash: string;
|
||||
blockSize: number;
|
||||
blocks: string[];
|
||||
};
|
||||
export declare function getFileIntegrity(inputFileStream: NodeJS.ReadableStream): Promise<FileIntegrity>;
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getFileIntegrity = getFileIntegrity;
|
||||
const crypto = __importStar(require("crypto"));
|
||||
const stream = __importStar(require("stream"));
|
||||
const util_1 = require("util");
|
||||
const ALGORITHM = 'SHA256';
|
||||
// 4MB default block size
|
||||
const BLOCK_SIZE = 4 * 1024 * 1024;
|
||||
const pipeline = (0, util_1.promisify)(stream.pipeline);
|
||||
function hashBlock(block) {
|
||||
return crypto.createHash(ALGORITHM).update(block).digest('hex');
|
||||
}
|
||||
async function getFileIntegrity(inputFileStream) {
|
||||
const fileHash = crypto.createHash(ALGORITHM);
|
||||
const blockHashes = [];
|
||||
let currentBlockSize = 0;
|
||||
let currentBlock = [];
|
||||
await pipeline(inputFileStream, new stream.PassThrough({
|
||||
decodeStrings: false,
|
||||
transform(_chunk, encoding, callback) {
|
||||
fileHash.update(_chunk);
|
||||
function handleChunk(chunk) {
|
||||
const diffToSlice = Math.min(BLOCK_SIZE - currentBlockSize, chunk.byteLength);
|
||||
currentBlockSize += diffToSlice;
|
||||
currentBlock.push(chunk.slice(0, diffToSlice));
|
||||
if (currentBlockSize === BLOCK_SIZE) {
|
||||
blockHashes.push(hashBlock(Buffer.concat(currentBlock)));
|
||||
currentBlock = [];
|
||||
currentBlockSize = 0;
|
||||
}
|
||||
if (diffToSlice < chunk.byteLength) {
|
||||
handleChunk(chunk.slice(diffToSlice));
|
||||
}
|
||||
}
|
||||
handleChunk(_chunk);
|
||||
callback();
|
||||
},
|
||||
flush(callback) {
|
||||
blockHashes.push(hashBlock(Buffer.concat(currentBlock)));
|
||||
currentBlock = [];
|
||||
callback();
|
||||
},
|
||||
}));
|
||||
return {
|
||||
algorithm: ALGORITHM,
|
||||
hash: fileHash.digest('hex'),
|
||||
blockSize: BLOCK_SIZE,
|
||||
blocks: blockHashes,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=integrity.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,4CA8CC;AApED,+CAAiC;AAEjC,+CAAiC;AACjC,+BAAiC;AAEjC,MAAM,SAAS,GAAG,QAAQ,CAAC;AAC3B,yBAAyB;AACzB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnC,MAAM,QAAQ,GAAG,IAAA,gBAAS,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAE5C,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AASM,KAAK,UAAU,gBAAgB,CACpC,eAAsC;IAEtC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAE9C,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,YAAY,GAAa,EAAE,CAAC;IAEhC,MAAM,QAAQ,CACZ,eAAe,EACf,IAAI,MAAM,CAAC,WAAW,CAAC;QACrB,aAAa,EAAE,KAAK;QACpB,SAAS,CAAC,MAAc,EAAE,QAAQ,EAAE,QAAQ;YAC1C,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAExB,SAAS,WAAW,CAAC,KAAa;gBAChC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,gBAAgB,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC9E,gBAAgB,IAAI,WAAW,CAAC;gBAChC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;gBAC/C,IAAI,gBAAgB,KAAK,UAAU,EAAE,CAAC;oBACpC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBACzD,YAAY,GAAG,EAAE,CAAC;oBAClB,gBAAgB,GAAG,CAAC,CAAC;gBACvB,CAAC;gBACD,IAAI,WAAW,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;oBACnC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,KAAK,CAAC,QAAQ;YACZ,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACzD,YAAY,GAAG,EAAE,CAAC;YAClB,QAAQ,EAAE,CAAC;QACb,CAAC;KACF,CAAC,CACH,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;QAC5B,SAAS,EAAE,UAAU;QACrB,MAAM,EAAE,WAAW;KACpB,CAAC;AACJ,CAAC"}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
declare class PickleIterator {
|
||||
private payload;
|
||||
private payloadOffset;
|
||||
private readIndex;
|
||||
private endIndex;
|
||||
constructor(pickle: Pickle);
|
||||
readBool(): boolean;
|
||||
readInt(): number;
|
||||
readUInt32(): number;
|
||||
readInt64(): bigint;
|
||||
readUInt64(): bigint;
|
||||
readFloat(): number;
|
||||
readDouble(): number;
|
||||
readString(): string;
|
||||
readBytes(length: number): Buffer;
|
||||
readBytes<R, F extends (...args: any[]) => R>(length: number, method: F): R;
|
||||
getReadPayloadOffsetAndAdvance(length: number): number;
|
||||
advance(size: number): void;
|
||||
}
|
||||
export declare class Pickle {
|
||||
private header;
|
||||
private headerSize;
|
||||
private capacityAfterHeader;
|
||||
private writeOffset;
|
||||
private constructor();
|
||||
static createEmpty(): Pickle;
|
||||
static createFromBuffer(buffer: Buffer): Pickle;
|
||||
getHeader(): Buffer;
|
||||
getHeaderSize(): number;
|
||||
createIterator(): PickleIterator;
|
||||
toBuffer(): Buffer;
|
||||
writeBool(value: boolean): boolean;
|
||||
writeInt(value: number): boolean;
|
||||
writeUInt32(value: number): boolean;
|
||||
writeInt64(value: number): boolean;
|
||||
writeUInt64(value: number): boolean;
|
||||
writeFloat(value: number): boolean;
|
||||
writeDouble(value: number): boolean;
|
||||
writeString(value: string): boolean;
|
||||
setPayloadSize(payloadSize: number): number;
|
||||
getPayloadSize(): number;
|
||||
writeBytes(data: string, length: number, method?: undefined): boolean;
|
||||
writeBytes(data: number | BigInt, length: number, method: Function): boolean;
|
||||
resize(newCapacity: number): void;
|
||||
}
|
||||
export {};
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Pickle = void 0;
|
||||
// sizeof(T).
|
||||
const SIZE_INT32 = 4;
|
||||
const SIZE_UINT32 = 4;
|
||||
const SIZE_INT64 = 8;
|
||||
const SIZE_UINT64 = 8;
|
||||
const SIZE_FLOAT = 4;
|
||||
const SIZE_DOUBLE = 8;
|
||||
// The allocation granularity of the payload.
|
||||
const PAYLOAD_UNIT = 64;
|
||||
// Largest JS number.
|
||||
const CAPACITY_READ_ONLY = 9007199254740992;
|
||||
// Aligns 'i' by rounding it up to the next multiple of 'alignment'.
|
||||
const alignInt = function (i, alignment) {
|
||||
return i + ((alignment - (i % alignment)) % alignment);
|
||||
};
|
||||
// PickleIterator reads data from a Pickle. The Pickle object must remain valid
|
||||
// while the PickleIterator object is in use.
|
||||
class PickleIterator {
|
||||
constructor(pickle) {
|
||||
this.payload = pickle.getHeader();
|
||||
this.payloadOffset = pickle.getHeaderSize();
|
||||
this.readIndex = 0;
|
||||
this.endIndex = pickle.getPayloadSize();
|
||||
}
|
||||
readBool() {
|
||||
return this.readInt() !== 0;
|
||||
}
|
||||
readInt() {
|
||||
return this.readBytes(SIZE_INT32, Buffer.prototype.readInt32LE);
|
||||
}
|
||||
readUInt32() {
|
||||
return this.readBytes(SIZE_UINT32, Buffer.prototype.readUInt32LE);
|
||||
}
|
||||
readInt64() {
|
||||
return this.readBytes(SIZE_INT64, Buffer.prototype.readBigInt64LE);
|
||||
}
|
||||
readUInt64() {
|
||||
return this.readBytes(SIZE_UINT64, Buffer.prototype.readBigUInt64LE);
|
||||
}
|
||||
readFloat() {
|
||||
return this.readBytes(SIZE_FLOAT, Buffer.prototype.readFloatLE);
|
||||
}
|
||||
readDouble() {
|
||||
return this.readBytes(SIZE_DOUBLE, Buffer.prototype.readDoubleLE);
|
||||
}
|
||||
readString() {
|
||||
return this.readBytes(this.readInt()).toString();
|
||||
}
|
||||
readBytes(length, method) {
|
||||
const readPayloadOffset = this.getReadPayloadOffsetAndAdvance(length);
|
||||
if (method != null) {
|
||||
return method.call(this.payload, readPayloadOffset, length);
|
||||
}
|
||||
else {
|
||||
return this.payload.slice(readPayloadOffset, readPayloadOffset + length);
|
||||
}
|
||||
}
|
||||
getReadPayloadOffsetAndAdvance(length) {
|
||||
if (length > this.endIndex - this.readIndex) {
|
||||
this.readIndex = this.endIndex;
|
||||
throw new Error('Failed to read data with length of ' + length);
|
||||
}
|
||||
const readPayloadOffset = this.payloadOffset + this.readIndex;
|
||||
this.advance(length);
|
||||
return readPayloadOffset;
|
||||
}
|
||||
advance(size) {
|
||||
const alignedSize = alignInt(size, SIZE_UINT32);
|
||||
if (this.endIndex - this.readIndex < alignedSize) {
|
||||
this.readIndex = this.endIndex;
|
||||
}
|
||||
else {
|
||||
this.readIndex += alignedSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
// This class provides facilities for basic binary value packing and unpacking.
|
||||
//
|
||||
// The Pickle class supports appending primitive values (ints, strings, etc.)
|
||||
// to a pickle instance. The Pickle instance grows its internal memory buffer
|
||||
// dynamically to hold the sequence of primitive values. The internal memory
|
||||
// buffer is exposed as the "data" of the Pickle. This "data" can be passed
|
||||
// to a Pickle object to initialize it for reading.
|
||||
//
|
||||
// When reading from a Pickle object, it is important for the consumer to know
|
||||
// what value types to read and in what order to read them as the Pickle does
|
||||
// not keep track of the type of data written to it.
|
||||
//
|
||||
// The Pickle's data has a header which contains the size of the Pickle's
|
||||
// payload. It can optionally support additional space in the header. That
|
||||
// space is controlled by the header_size parameter passed to the Pickle
|
||||
// constructor.
|
||||
class Pickle {
|
||||
constructor(buffer) {
|
||||
if (buffer) {
|
||||
this.header = buffer;
|
||||
this.headerSize = buffer.length - this.getPayloadSize();
|
||||
this.capacityAfterHeader = CAPACITY_READ_ONLY;
|
||||
this.writeOffset = 0;
|
||||
if (this.headerSize > buffer.length) {
|
||||
this.headerSize = 0;
|
||||
}
|
||||
if (this.headerSize !== alignInt(this.headerSize, SIZE_UINT32)) {
|
||||
this.headerSize = 0;
|
||||
}
|
||||
if (this.headerSize === 0) {
|
||||
this.header = Buffer.alloc(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.header = Buffer.alloc(0);
|
||||
this.headerSize = SIZE_UINT32;
|
||||
this.capacityAfterHeader = 0;
|
||||
this.writeOffset = 0;
|
||||
this.resize(PAYLOAD_UNIT);
|
||||
this.setPayloadSize(0);
|
||||
}
|
||||
}
|
||||
static createEmpty() {
|
||||
return new Pickle();
|
||||
}
|
||||
static createFromBuffer(buffer) {
|
||||
return new Pickle(buffer);
|
||||
}
|
||||
getHeader() {
|
||||
return this.header;
|
||||
}
|
||||
getHeaderSize() {
|
||||
return this.headerSize;
|
||||
}
|
||||
createIterator() {
|
||||
return new PickleIterator(this);
|
||||
}
|
||||
toBuffer() {
|
||||
return this.header.slice(0, this.headerSize + this.getPayloadSize());
|
||||
}
|
||||
writeBool(value) {
|
||||
return this.writeInt(value ? 1 : 0);
|
||||
}
|
||||
writeInt(value) {
|
||||
return this.writeBytes(value, SIZE_INT32, Buffer.prototype.writeInt32LE);
|
||||
}
|
||||
writeUInt32(value) {
|
||||
return this.writeBytes(value, SIZE_UINT32, Buffer.prototype.writeUInt32LE);
|
||||
}
|
||||
writeInt64(value) {
|
||||
return this.writeBytes(BigInt(value), SIZE_INT64, Buffer.prototype.writeBigInt64LE);
|
||||
}
|
||||
writeUInt64(value) {
|
||||
return this.writeBytes(BigInt(value), SIZE_UINT64, Buffer.prototype.writeBigUInt64LE);
|
||||
}
|
||||
writeFloat(value) {
|
||||
return this.writeBytes(value, SIZE_FLOAT, Buffer.prototype.writeFloatLE);
|
||||
}
|
||||
writeDouble(value) {
|
||||
return this.writeBytes(value, SIZE_DOUBLE, Buffer.prototype.writeDoubleLE);
|
||||
}
|
||||
writeString(value) {
|
||||
const length = Buffer.byteLength(value, 'utf8');
|
||||
if (!this.writeInt(length)) {
|
||||
return false;
|
||||
}
|
||||
return this.writeBytes(value, length);
|
||||
}
|
||||
setPayloadSize(payloadSize) {
|
||||
return this.header.writeUInt32LE(payloadSize, 0);
|
||||
}
|
||||
getPayloadSize() {
|
||||
return this.header.readUInt32LE(0);
|
||||
}
|
||||
writeBytes(data, length, method) {
|
||||
const dataLength = alignInt(length, SIZE_UINT32);
|
||||
const newSize = this.writeOffset + dataLength;
|
||||
if (newSize > this.capacityAfterHeader) {
|
||||
this.resize(Math.max(this.capacityAfterHeader * 2, newSize));
|
||||
}
|
||||
if (method) {
|
||||
method.call(this.header, data, this.headerSize + this.writeOffset);
|
||||
}
|
||||
else {
|
||||
this.header.write(data, this.headerSize + this.writeOffset, length);
|
||||
}
|
||||
const endOffset = this.headerSize + this.writeOffset + length;
|
||||
this.header.fill(0, endOffset, endOffset + dataLength - length);
|
||||
this.setPayloadSize(newSize);
|
||||
this.writeOffset = newSize;
|
||||
return true;
|
||||
}
|
||||
resize(newCapacity) {
|
||||
newCapacity = alignInt(newCapacity, PAYLOAD_UNIT);
|
||||
this.header = Buffer.concat([this.header, Buffer.alloc(newCapacity)]);
|
||||
this.capacityAfterHeader = newCapacity;
|
||||
}
|
||||
}
|
||||
exports.Pickle = Pickle;
|
||||
//# sourceMappingURL=pickle.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-157
@@ -1,157 +0,0 @@
|
||||
/**
|
||||
* TODO(erikian): remove this file once we upgrade to the latest `glob` version.
|
||||
* https://github.com/electron/asar/pull/332#issuecomment-2435407933
|
||||
*/
|
||||
interface IMinimatchOptions {
|
||||
/**
|
||||
* Dump a ton of stuff to stderr.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
debug?: boolean | undefined;
|
||||
/**
|
||||
* Do not expand `{a,b}` and `{1..3}` brace sets.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
nobrace?: boolean | undefined;
|
||||
/**
|
||||
* Disable `**` matching against multiple folder names.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
noglobstar?: boolean | undefined;
|
||||
/**
|
||||
* Allow patterns to match filenames starting with a period,
|
||||
* even if the pattern does not explicitly have a period in that spot.
|
||||
*
|
||||
* Note that by default, `'a/**' + '/b'` will **not** match `a/.d/b`, unless `dot` is set.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
dot?: boolean | undefined;
|
||||
/**
|
||||
* Disable "extglob" style patterns like `+(a|b)`.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
noext?: boolean | undefined;
|
||||
/**
|
||||
* Perform a case-insensitive match.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
nocase?: boolean | undefined;
|
||||
/**
|
||||
* When a match is not found by `minimatch.match`,
|
||||
* return a list containing the pattern itself if this option is set.
|
||||
* Otherwise, an empty list is returned if there are no matches.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
nonull?: boolean | undefined;
|
||||
/**
|
||||
* If set, then patterns without slashes will be matched
|
||||
* against the basename of the path if it contains slashes. For example,
|
||||
* `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
matchBase?: boolean | undefined;
|
||||
/**
|
||||
* Suppress the behavior of treating `#` at the start of a pattern as a comment.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
nocomment?: boolean | undefined;
|
||||
/**
|
||||
* Suppress the behavior of treating a leading `!` character as negation.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
nonegate?: boolean | undefined;
|
||||
/**
|
||||
* Returns from negate expressions the same as if they were not negated.
|
||||
* (Ie, true on a hit, false on a miss.)
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
flipNegate?: boolean | undefined;
|
||||
/**
|
||||
* Compare a partial path to a pattern. As long as the parts of the path that
|
||||
* are present are not contradicted by the pattern, it will be treated as a
|
||||
* match. This is useful in applications where you're walking through a
|
||||
* folder structure, and don't yet have the full path, but want to ensure that
|
||||
* you do not walk down paths that can never be a match.
|
||||
*
|
||||
* @default false
|
||||
*
|
||||
* @example
|
||||
* import minimatch = require("minimatch");
|
||||
*
|
||||
* minimatch('/a/b', '/a/*' + '/c/d', { partial: true }) // true, might be /a/b/c/d
|
||||
* minimatch('/a/b', '/**' + '/d', { partial: true }) // true, might be /a/b/.../d
|
||||
* minimatch('/x/y/z', '/a/**' + '/z', { partial: true }) // false, because x !== a
|
||||
*/
|
||||
partial?: boolean;
|
||||
/**
|
||||
* Use `\\` as a path separator _only_, and _never_ as an escape
|
||||
* character. If set, all `\\` characters are replaced with `/` in
|
||||
* the pattern. Note that this makes it **impossible** to match
|
||||
* against paths containing literal glob pattern characters, but
|
||||
* allows matching with patterns constructed using `path.join()` and
|
||||
* `path.resolve()` on Windows platforms, mimicking the (buggy!)
|
||||
* behavior of earlier versions on Windows. Please use with
|
||||
* caution, and be mindful of the caveat about Windows paths
|
||||
*
|
||||
* For legacy reasons, this is also set if
|
||||
* `options.allowWindowsEscape` is set to the exact value `false`.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
windowsPathsNoEscape?: boolean;
|
||||
}
|
||||
export interface IOptions extends IMinimatchOptions {
|
||||
cwd?: string | undefined;
|
||||
root?: string | undefined;
|
||||
dot?: boolean | undefined;
|
||||
nomount?: boolean | undefined;
|
||||
mark?: boolean | undefined;
|
||||
nosort?: boolean | undefined;
|
||||
stat?: boolean | undefined;
|
||||
silent?: boolean | undefined;
|
||||
strict?: boolean | undefined;
|
||||
cache?: {
|
||||
[path: string]: boolean | 'DIR' | 'FILE' | ReadonlyArray<string>;
|
||||
} | undefined;
|
||||
statCache?: {
|
||||
[path: string]: false | {
|
||||
isDirectory(): boolean;
|
||||
} | undefined;
|
||||
} | undefined;
|
||||
symlinks?: {
|
||||
[path: string]: boolean | undefined;
|
||||
} | undefined;
|
||||
realpathCache?: {
|
||||
[path: string]: string;
|
||||
} | undefined;
|
||||
sync?: boolean | undefined;
|
||||
nounique?: boolean | undefined;
|
||||
nonull?: boolean | undefined;
|
||||
debug?: boolean | undefined;
|
||||
nobrace?: boolean | undefined;
|
||||
noglobstar?: boolean | undefined;
|
||||
noext?: boolean | undefined;
|
||||
nocase?: boolean | undefined;
|
||||
matchBase?: any;
|
||||
nodir?: boolean | undefined;
|
||||
ignore?: string | ReadonlyArray<string> | undefined;
|
||||
follow?: boolean | undefined;
|
||||
realpath?: boolean | undefined;
|
||||
nonegate?: boolean | undefined;
|
||||
nocomment?: boolean | undefined;
|
||||
absolute?: boolean | undefined;
|
||||
allowWindowsEscape?: boolean | undefined;
|
||||
fs?: typeof import('fs');
|
||||
}
|
||||
export {};
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=glob.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/types/glob.ts"],"names":[],"mappings":""}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
type AsarFS = typeof import('fs') & {
|
||||
mkdirp(dir: string): Promise<void>;
|
||||
mkdirpSync(dir: string): void;
|
||||
lstat: (typeof import('fs'))['promises']['lstat'];
|
||||
mkdtemp: (typeof import('fs'))['promises']['mkdtemp'];
|
||||
readFile: (typeof import('fs'))['promises']['readFile'];
|
||||
stat: (typeof import('fs'))['promises']['stat'];
|
||||
writeFile: (typeof import('fs'))['promises']['writeFile'];
|
||||
symlink: (typeof import('fs'))['promises']['symlink'];
|
||||
readlink: (typeof import('fs'))['promises']['readlink'];
|
||||
};
|
||||
declare const promisified: AsarFS;
|
||||
export default promisified;
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = 'electron' in process.versions ? require('original-fs') : require('fs');
|
||||
const promisifiedMethods = [
|
||||
'lstat',
|
||||
'mkdtemp',
|
||||
'readFile',
|
||||
'stat',
|
||||
'writeFile',
|
||||
'symlink',
|
||||
'readlink',
|
||||
];
|
||||
const promisified = {};
|
||||
for (const method of Object.keys(fs)) {
|
||||
if (promisifiedMethods.includes(method)) {
|
||||
promisified[method] = fs.promises[method];
|
||||
}
|
||||
else {
|
||||
promisified[method] = fs[method];
|
||||
}
|
||||
}
|
||||
// To make it more like fs-extra
|
||||
promisified.mkdirp = (dir) => fs.promises.mkdir(dir, { recursive: true });
|
||||
promisified.mkdirpSync = (dir) => fs.mkdirSync(dir, { recursive: true });
|
||||
exports.default = promisified;
|
||||
//# sourceMappingURL=wrapped-fs.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"wrapped-fs.js","sourceRoot":"","sources":["../src/wrapped-fs.ts"],"names":[],"mappings":";;AAAA,MAAM,EAAE,GAAG,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,MAAM,kBAAkB,GAAG;IACzB,OAAO;IACP,SAAS;IACT,UAAU;IACV,MAAM;IACN,WAAW;IACX,SAAS;IACT,UAAU;CACX,CAAC;AAcF,MAAM,WAAW,GAAG,EAAY,CAAC;AAEjC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACrC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,WAAmB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACL,WAAmB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AACD,gCAAgC;AAChC,WAAW,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1E,WAAW,CAAC,UAAU,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAEzE,kBAAe,WAAW,CAAC"}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
{
|
||||
"name": "@electron/asar",
|
||||
"description": "Creating Electron app packages",
|
||||
"version": "3.4.1",
|
||||
"main": "./lib/asar.js",
|
||||
"types": "./lib/asar.d.ts",
|
||||
"bin": {
|
||||
"asar": "./bin/asar.js"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"lib"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10.12.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/electron/asar",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/electron/asar.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/electron/asar/issues"
|
||||
},
|
||||
"publishConfig": {
|
||||
"provenance": true
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"mocha": "xvfb-maybe electron-mocha && mocha",
|
||||
"mocha:update": "mocha --update",
|
||||
"mocha:watch": "mocha --watch",
|
||||
"test": "yarn lint && yarn mocha",
|
||||
"lint": "yarn prettier:check",
|
||||
"prettier": "prettier \"src/**/*.ts\" \"test/**/*.js\" \"*.js\"",
|
||||
"prettier:check": "yarn prettier --check",
|
||||
"prettier:write": "yarn prettier --write",
|
||||
"prepare": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "^5.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/minimatch": "^3.0.5",
|
||||
"@types/node": "^12.0.0",
|
||||
"chai": "^4.5.0",
|
||||
"electron": "^22.0.0",
|
||||
"electron-mocha": "^13.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"mocha": "^10.1.0",
|
||||
"mocha-chai-jest-snapshot": "^1.1.6",
|
||||
"prettier": "^3.3.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^5.5.4",
|
||||
"xvfb-maybe": "^0.2.1"
|
||||
}
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
Copyright (c) 2020 Electron Maintainers.
|
||||
|
||||
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.
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
# @electron/fuses
|
||||
|
||||
> Flip [Electron Fuses](https://github.com/electron/electron/blob/main/docs/tutorial/fuses.md) and customize your packaged build of Electron
|
||||
|
||||
[](https://circleci.com/gh/electron/fuses)
|
||||
[](https://npmjs.org/package/@electron/fuses)
|
||||
|
||||
## Usage
|
||||
|
||||
### Via JavaScript
|
||||
|
||||
```typescript
|
||||
import { flipFuses, FuseVersion, FuseV1Options } from '@electron/fuses';
|
||||
|
||||
// During your build / package process
|
||||
await flipFuses(
|
||||
require('electron'), // Returns the path to the electron binary
|
||||
{
|
||||
version: FuseVersion.V1,
|
||||
[FuseV1Options.RunAsNode]: false, // Disables ELECTRON_RUN_AS_NODE
|
||||
[FuseV1Options.EnableCookieEncryption]: true, // Enables cookie encryption
|
||||
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false, // Disables the NODE_OPTIONS environment variable
|
||||
[FuseV1Options.EnableNodeCliInspectArguments]: false, // Disables the --inspect and --inspect-brk family of CLI options
|
||||
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true, // Enables validation of the app.asar archive on macOS
|
||||
[FuseV1Options.OnlyLoadAppFromAsar]: true, // Enforces that Electron will only load your app from "app.asar" instead of its normal search paths
|
||||
[FuseV1Options.LoadBrowserProcessSpecificV8Snapshot]: true, // Loads V8 Snapshot from `browser_v8_context_snapshot.bin` for the browser process
|
||||
[FuseV1Options.GrantFileProtocolExtraPrivileges]: true, // Grants the file protocol extra privileges
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### From the command line
|
||||
|
||||
```sh
|
||||
$ npx @electron/fuses read --app /Applications/Foo.app
|
||||
$ npx @electron/fuses write --app /Applications/Foo.app <...key=on/off>
|
||||
```
|
||||
|
||||
### Apple Silicon
|
||||
|
||||
For `arm64` macOS builds of your app if you are not immediately codesigning your app after flipping
|
||||
the fuses you will need to pass `resetAdHocDarwinSignature: true` to the `flipFuses` method. Otherwise
|
||||
the app will refuse to launch with code signature validation errors. This is a new security measure on
|
||||
Apple Silicon devices.
|
||||
|
||||
```typescript
|
||||
import { flipFuses, FuseVersion, FuseV1Options } from '@electron/fuses';
|
||||
|
||||
await flipFuses(
|
||||
require('electron'),
|
||||
{
|
||||
version: FuseVersion.V1,
|
||||
resetAdHocDarwinSignature: targetPlatform === 'darwin' && targetArch === 'arm64',
|
||||
[FuseV1Options.RunAsNode]: false,
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### New Fuses
|
||||
|
||||
If you want to ensure you provide a config for every fuse, even newly added fuses during Electron upgrades
|
||||
you can set the `strictlyRequireAllFuses` option to `true`. This will hard fail the build if you are on
|
||||
a version of `@electron/fuses` that doesn't have configuration options for every fuse in the Electron binary
|
||||
you are targetting or if you don't provide a configuration for a specific fuse present in the Electron binary
|
||||
you are targetting.
|
||||
|
||||
```typescript
|
||||
import { flipFuses, FuseVersion, FuseV1Options } from '@electron/fuses';
|
||||
|
||||
await flipFuses(
|
||||
require('electron'),
|
||||
{
|
||||
version: FuseVersion.V1,
|
||||
strictlyRequireAllFuses: true,
|
||||
[FuseV1Options.RunAsNode]: false,
|
||||
},
|
||||
);
|
||||
```
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
export {};
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const chalk = require("chalk");
|
||||
const minimist = require("minimist");
|
||||
const path = require("path");
|
||||
const _1 = require(".");
|
||||
const config_1 = require("./config");
|
||||
const constants_1 = require("./constants");
|
||||
const mode = process.argv[2];
|
||||
const readHelpText = `electron-fuses read --app [path-to-app]`;
|
||||
const writeHelpText = `electron-fuses write --app [path-to-app] <...key=on/off>`;
|
||||
if (mode !== 'read' && mode !== 'write') {
|
||||
console.error('Invalid mode, check the usage below:');
|
||||
console.info(readHelpText);
|
||||
console.info(writeHelpText);
|
||||
process.exit(0);
|
||||
}
|
||||
function stringForState(state) {
|
||||
switch (state) {
|
||||
case constants_1.FuseState.ENABLE:
|
||||
return chalk.green('Enabled');
|
||||
case constants_1.FuseState.DISABLE:
|
||||
return chalk.red('Disabled');
|
||||
case constants_1.FuseState.INHERIT:
|
||||
return chalk.yellow('Inherited');
|
||||
case constants_1.FuseState.REMOVED:
|
||||
return chalk.strikethrough(chalk.red('Removed'));
|
||||
}
|
||||
}
|
||||
if (mode === 'read') {
|
||||
const argv = minimist(process.argv.slice(3), {
|
||||
string: ['app'],
|
||||
boolean: ['help'],
|
||||
});
|
||||
if (argv.help) {
|
||||
console.log(readHelpText);
|
||||
process.exit(0);
|
||||
}
|
||||
if (!argv.app) {
|
||||
console.error('--app argument is required');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('Analyzing app:', chalk.cyan(path.basename(argv.app)));
|
||||
(0, _1.getCurrentFuseWire)(argv.app)
|
||||
.then((config) => {
|
||||
const { version, resetAdHocDarwinSignature, strictlyRequireAllFuses } = config, rest = __rest(config, ["version", "resetAdHocDarwinSignature", "strictlyRequireAllFuses"]);
|
||||
console.log(`Fuse Version: ${chalk.cyan(`v${version}`)}`);
|
||||
switch (config.version) {
|
||||
case config_1.FuseVersion.V1:
|
||||
for (const key of Object.keys(rest)) {
|
||||
console.log(` ${chalk.yellow(config_1.FuseV1Options[key])} is ${stringForState(rest[key])}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
else {
|
||||
const argv = minimist(process.argv.slice(3), {
|
||||
string: ['app'],
|
||||
boolean: ['help'],
|
||||
});
|
||||
if (argv.help) {
|
||||
console.log(writeHelpText);
|
||||
process.exit(0);
|
||||
}
|
||||
if (!argv.app) {
|
||||
console.error('--app argument is required');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('Analyzing app:', chalk.cyan(path.basename(argv.app)));
|
||||
(0, _1.getCurrentFuseWire)(argv.app)
|
||||
.then((config) => {
|
||||
const { version, resetAdHocDarwinSignature } = config, rest = __rest(config, ["version", "resetAdHocDarwinSignature"]);
|
||||
console.log(`Fuse Version: ${chalk.cyan(`v${version}`)}`);
|
||||
const keyPairs = argv._ || [];
|
||||
for (const keyPair of keyPairs) {
|
||||
const [key, state] = keyPair.split('=');
|
||||
if (!key || !state) {
|
||||
console.error('Invalid fuse:', keyPair);
|
||||
console.error('Must be in the format FuseName=on/off');
|
||||
process.exit(1);
|
||||
}
|
||||
if (state !== 'on' && state !== 'off') {
|
||||
console.error('Invalid fuse state:', chalk.yellow(keyPair));
|
||||
console.error(`Fuses can only be set to the "${chalk.green('on')}" or "${chalk.red('off')}" state`);
|
||||
process.exit(1);
|
||||
}
|
||||
switch (config.version) {
|
||||
case config_1.FuseVersion.V1:
|
||||
const validFuseNames = Object.keys(config_1.FuseV1Options).filter((k) => !/^[0-9]+$/.test(k));
|
||||
if (!validFuseNames.includes(key)) {
|
||||
console.error('Invalid fuse name', chalk.yellow(key));
|
||||
console.error('Expected name to be one of', chalk.yellow(JSON.stringify(validFuseNames)));
|
||||
process.exit(1);
|
||||
}
|
||||
const currentState = config[config_1.FuseV1Options[key]];
|
||||
const newState = state === 'on' ? constants_1.FuseState.ENABLE : constants_1.FuseState.DISABLE;
|
||||
if (currentState === newState) {
|
||||
console.log(` ${chalk.yellow(key)} is already ${stringForState(currentState)} and will not be changed`);
|
||||
}
|
||||
else {
|
||||
console.log(` ${chalk.yellow(key)} is ${stringForState(currentState)} and will become ${stringForState(newState)}`);
|
||||
}
|
||||
config[config_1.FuseV1Options[key]] = newState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log('Writing to app:', chalk.cyan(path.basename(argv.app)));
|
||||
function adaptConfig(config) {
|
||||
const { version, resetAdHocDarwinSignature } = config, rest = __rest(config, ["version", "resetAdHocDarwinSignature"]);
|
||||
const fuseConfig = {
|
||||
version,
|
||||
resetAdHocDarwinSignature,
|
||||
};
|
||||
for (const key of Object.keys(rest)) {
|
||||
fuseConfig[key] = rest[key] === constants_1.FuseState.ENABLE;
|
||||
}
|
||||
return fuseConfig;
|
||||
}
|
||||
return (0, _1.flipFuses)(argv.app, adaptConfig(config));
|
||||
})
|
||||
.then(() => {
|
||||
console.log(chalk.green('Fuses written to disk'));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=bin.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-34
@@ -1,34 +0,0 @@
|
||||
export declare enum FuseVersion {
|
||||
V1 = "1"
|
||||
}
|
||||
/**
|
||||
* Maps config keys to their index in the fuse wire
|
||||
*/
|
||||
export declare enum FuseV1Options {
|
||||
RunAsNode = 0,
|
||||
EnableCookieEncryption = 1,
|
||||
EnableNodeOptionsEnvironmentVariable = 2,
|
||||
EnableNodeCliInspectArguments = 3,
|
||||
EnableEmbeddedAsarIntegrityValidation = 4,
|
||||
OnlyLoadAppFromAsar = 5,
|
||||
LoadBrowserProcessSpecificV8Snapshot = 6,
|
||||
GrantFileProtocolExtraPrivileges = 7
|
||||
}
|
||||
export declare type FuseV1Config<T = boolean> = {
|
||||
version: FuseVersion.V1;
|
||||
resetAdHocDarwinSignature?: boolean;
|
||||
/**
|
||||
* Ensures that all fuses in the fuse wire being set have been defined to a set value
|
||||
* by the provided config. Set this to true to ensure you don't accidentally miss a
|
||||
* fuse being added in future Electron upgrades.
|
||||
*
|
||||
* This option may default to "true" in a future version of @electron/fuses but currently
|
||||
* defaults to "false"
|
||||
*/
|
||||
strictlyRequireAllFuses?: boolean;
|
||||
} & ((Partial<Record<FuseV1Options, T>> & {
|
||||
strictlyRequireAllFuses?: false | undefined;
|
||||
}) | (Record<FuseV1Options, T> & {
|
||||
strictlyRequireAllFuses: true;
|
||||
}));
|
||||
export declare type FuseConfig<T = boolean> = FuseV1Config<T>;
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FuseV1Options = exports.FuseVersion = void 0;
|
||||
var FuseVersion;
|
||||
(function (FuseVersion) {
|
||||
FuseVersion["V1"] = "1";
|
||||
})(FuseVersion = exports.FuseVersion || (exports.FuseVersion = {}));
|
||||
/**
|
||||
* Maps config keys to their index in the fuse wire
|
||||
*/
|
||||
var FuseV1Options;
|
||||
(function (FuseV1Options) {
|
||||
FuseV1Options[FuseV1Options["RunAsNode"] = 0] = "RunAsNode";
|
||||
FuseV1Options[FuseV1Options["EnableCookieEncryption"] = 1] = "EnableCookieEncryption";
|
||||
FuseV1Options[FuseV1Options["EnableNodeOptionsEnvironmentVariable"] = 2] = "EnableNodeOptionsEnvironmentVariable";
|
||||
FuseV1Options[FuseV1Options["EnableNodeCliInspectArguments"] = 3] = "EnableNodeCliInspectArguments";
|
||||
FuseV1Options[FuseV1Options["EnableEmbeddedAsarIntegrityValidation"] = 4] = "EnableEmbeddedAsarIntegrityValidation";
|
||||
FuseV1Options[FuseV1Options["OnlyLoadAppFromAsar"] = 5] = "OnlyLoadAppFromAsar";
|
||||
FuseV1Options[FuseV1Options["LoadBrowserProcessSpecificV8Snapshot"] = 6] = "LoadBrowserProcessSpecificV8Snapshot";
|
||||
FuseV1Options[FuseV1Options["GrantFileProtocolExtraPrivileges"] = 7] = "GrantFileProtocolExtraPrivileges";
|
||||
})(FuseV1Options = exports.FuseV1Options || (exports.FuseV1Options = {}));
|
||||
//# sourceMappingURL=config.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAA,IAAY,WAEX;AAFD,WAAY,WAAW;IACrB,uBAAQ,CAAA;AACV,CAAC,EAFW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAEtB;AAED;;GAEG;AACH,IAAY,aASX;AATD,WAAY,aAAa;IACvB,2DAAa,CAAA;IACb,qFAA0B,CAAA;IAC1B,iHAAwC,CAAA;IACxC,mGAAiC,CAAA;IACjC,mHAAyC,CAAA;IACzC,+EAAuB,CAAA;IACvB,iHAAwC,CAAA;IACxC,yGAAoC,CAAA;AACtC,CAAC,EATW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QASxB"}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
export declare const SENTINEL = "dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX";
|
||||
export declare enum FuseState {
|
||||
DISABLE = 48,
|
||||
ENABLE = 49,
|
||||
REMOVED = 114,
|
||||
INHERIT = 144
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FuseState = exports.SENTINEL = void 0;
|
||||
exports.SENTINEL = 'dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX';
|
||||
var FuseState;
|
||||
(function (FuseState) {
|
||||
FuseState[FuseState["DISABLE"] = 48] = "DISABLE";
|
||||
FuseState[FuseState["ENABLE"] = 49] = "ENABLE";
|
||||
FuseState[FuseState["REMOVED"] = 114] = "REMOVED";
|
||||
FuseState[FuseState["INHERIT"] = 144] = "INHERIT";
|
||||
})(FuseState = exports.FuseState || (exports.FuseState = {}));
|
||||
//# sourceMappingURL=constants.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,QAAQ,GAAG,kCAAkC,CAAC;AAE3D,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,gDAAc,CAAA;IACd,8CAAa,CAAA;IACb,iDAAc,CAAA;IACd,iDAAc,CAAA;AAChB,CAAC,EALW,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAKpB"}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { FuseConfig } from './config';
|
||||
import { FuseState } from './constants';
|
||||
export * from './config';
|
||||
export declare const getCurrentFuseWire: (pathToElectron: string) => Promise<FuseConfig<FuseState>>;
|
||||
export declare const flipFuses: (pathToElectron: string, fuseConfig: FuseConfig) => Promise<number>;
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.flipFuses = exports.getCurrentFuseWire = void 0;
|
||||
const cp = require("child_process");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const config_1 = require("./config");
|
||||
const constants_1 = require("./constants");
|
||||
__exportStar(require("./config"), exports);
|
||||
const state = (b) => b === undefined ? constants_1.FuseState.INHERIT : b ? constants_1.FuseState.ENABLE : constants_1.FuseState.DISABLE;
|
||||
const buildFuseV1Wire = (config, wireLength) => {
|
||||
const { version } = config, nonVersionConfig = __rest(config, ["version"]);
|
||||
const badFuseOption = Object.keys(nonVersionConfig).find((fuseOption) => parseInt(fuseOption, 10) >= wireLength);
|
||||
if (badFuseOption !== undefined) {
|
||||
throw new Error(`Trying to configure ${config_1.FuseV1Options[badFuseOption]} but the fuse wire in this version of Electron is not long enough`);
|
||||
}
|
||||
return [
|
||||
state(config[config_1.FuseV1Options.RunAsNode]),
|
||||
state(config[config_1.FuseV1Options.EnableCookieEncryption]),
|
||||
state(config[config_1.FuseV1Options.EnableNodeOptionsEnvironmentVariable]),
|
||||
state(config[config_1.FuseV1Options.EnableNodeCliInspectArguments]),
|
||||
state(config[config_1.FuseV1Options.EnableEmbeddedAsarIntegrityValidation]),
|
||||
state(config[config_1.FuseV1Options.OnlyLoadAppFromAsar]),
|
||||
state(config[config_1.FuseV1Options.LoadBrowserProcessSpecificV8Snapshot]),
|
||||
state(config[config_1.FuseV1Options.GrantFileProtocolExtraPrivileges]),
|
||||
];
|
||||
};
|
||||
const pathToFuseFile = (pathToElectron) => {
|
||||
if (pathToElectron.endsWith('.app')) {
|
||||
return path.resolve(pathToElectron, 'Contents', 'Frameworks', 'Electron Framework.framework', 'Electron Framework');
|
||||
}
|
||||
if (pathToElectron.includes('.app')) {
|
||||
return path.resolve(pathToElectron, '..', '..', 'Frameworks', 'Electron Framework.framework', 'Electron Framework');
|
||||
}
|
||||
return pathToElectron;
|
||||
};
|
||||
const setFuseWire = async (pathToElectron, fuseVersion, strictlyRequireAllFuses, fuseWireBuilder, fuseNamer) => {
|
||||
const fuseFilePath = pathToFuseFile(pathToElectron);
|
||||
const electron = await fs.readFile(fuseFilePath);
|
||||
const firstSentinel = electron.indexOf(constants_1.SENTINEL);
|
||||
const lastSentinel = electron.lastIndexOf(constants_1.SENTINEL);
|
||||
// If the last sentinel is different to the first sentinel we are probably in a universal build
|
||||
// We should flip the fuses in both sentinels to affect both slices of the universal binary
|
||||
const sentinels = firstSentinel === lastSentinel ? [firstSentinel] : [firstSentinel, lastSentinel];
|
||||
for (const indexOfSentinel of sentinels) {
|
||||
if (indexOfSentinel === -1) {
|
||||
throw new Error('Could not find sentinel in the provided Electron binary, fuses are only supported in Electron 12 and higher');
|
||||
}
|
||||
const fuseWirePosition = indexOfSentinel + constants_1.SENTINEL.length;
|
||||
const fuseWireVersion = electron[fuseWirePosition];
|
||||
if (parseInt(fuseVersion, 10) !== fuseWireVersion) {
|
||||
throw new Error(`Provided fuse wire version "${parseInt(fuseVersion, 10)}" does not match watch was found in the binary "${fuseWireVersion}". You should update your usage of @electron/fuses.`);
|
||||
}
|
||||
const fuseWireLength = electron[fuseWirePosition + 1];
|
||||
const wire = fuseWireBuilder(fuseWireLength).slice(0, fuseWireLength);
|
||||
if (wire.length < fuseWireLength && strictlyRequireAllFuses) {
|
||||
throw new Error(`strictlyRequireAllFuses: The fuse wire in the Electron binary has ${fuseWireLength} fuses but you only provided a config for ${wire.length} fuses, you may need to update @electron/fuses or provide additional fuse settings`);
|
||||
}
|
||||
for (let i = 0; i < wire.length; i++) {
|
||||
const idx = fuseWirePosition + 2 + i;
|
||||
const currentState = electron[idx];
|
||||
const newState = wire[i];
|
||||
if (currentState === constants_1.FuseState.REMOVED && newState !== constants_1.FuseState.INHERIT) {
|
||||
console.warn(`Overriding fuse "${fuseNamer(i)}" that has been marked as removed, setting this fuse is a noop`);
|
||||
}
|
||||
if (newState === constants_1.FuseState.INHERIT) {
|
||||
if (strictlyRequireAllFuses) {
|
||||
throw new Error(`strictlyRequireAllFuses: Missing explicit configuration for fuse ${fuseNamer(i)}`);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
electron[idx] = newState;
|
||||
}
|
||||
}
|
||||
await fs.writeFile(fuseFilePath, electron);
|
||||
return sentinels.length;
|
||||
};
|
||||
const getCurrentFuseWire = async (pathToElectron) => {
|
||||
const fuseFilePath = pathToFuseFile(pathToElectron);
|
||||
const electron = await fs.readFile(fuseFilePath);
|
||||
const fuseWirePosition = electron.indexOf(constants_1.SENTINEL) + constants_1.SENTINEL.length;
|
||||
if (fuseWirePosition - constants_1.SENTINEL.length === -1) {
|
||||
throw new Error('Could not find sentinel in the provided Electron binary, fuses are only supported in Electron 12 and higher');
|
||||
}
|
||||
const fuseWireVersion = electron[fuseWirePosition];
|
||||
const fuseWireLength = electron[fuseWirePosition + 1];
|
||||
const fuseConfig = {
|
||||
version: `${fuseWireVersion}`,
|
||||
};
|
||||
for (let i = 0; i < fuseWireLength; i++) {
|
||||
const idx = fuseWirePosition + 2 + i;
|
||||
const currentState = electron[idx];
|
||||
switch (fuseConfig.version) {
|
||||
case config_1.FuseVersion.V1:
|
||||
fuseConfig[i] = currentState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fuseConfig;
|
||||
};
|
||||
exports.getCurrentFuseWire = getCurrentFuseWire;
|
||||
const flipFuses = async (pathToElectron, fuseConfig) => {
|
||||
let numSentinels;
|
||||
switch (fuseConfig.version) {
|
||||
case config_1.FuseVersion.V1:
|
||||
numSentinels = await setFuseWire(pathToElectron, fuseConfig.version, fuseConfig.strictlyRequireAllFuses || false, buildFuseV1Wire.bind(null, fuseConfig), (i) => config_1.FuseV1Options[i]);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported fuse version number: ${fuseConfig.version}`);
|
||||
}
|
||||
// Reset the ad-hoc signature on macOS, should only be done for arm64 apps
|
||||
if (fuseConfig.resetAdHocDarwinSignature && pathToElectron.includes('.app')) {
|
||||
const pathToApp = `${pathToElectron.split('.app')[0]}.app`;
|
||||
const result = cp.spawnSync('codesign', [
|
||||
'--sign',
|
||||
'-',
|
||||
'--force',
|
||||
'--preserve-metadata=entitlements,requirements,flags,runtime',
|
||||
'--deep',
|
||||
pathToApp,
|
||||
]);
|
||||
if (result.status !== 0) {
|
||||
console.error(result.stderr.toString());
|
||||
throw new Error(`Ad-hoc codesign failed with status: ${result.status}`);
|
||||
}
|
||||
}
|
||||
return numSentinels;
|
||||
};
|
||||
exports.flipFuses = flipFuses;
|
||||
//# sourceMappingURL=index.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
-58
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"name": "@electron/fuses",
|
||||
"version": "1.8.0",
|
||||
"main": "dist/index.js",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"electron-fuses": "dist/bin.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"prepublishOnly": "tsc",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/get": "^2.0.1",
|
||||
"@electron/universal": "^1.3.0",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/jest": "^29.0.3",
|
||||
"@types/minimist": "^1.2.1",
|
||||
"@types/node": "^14.11.2",
|
||||
"extract-zip": "^2.0.1",
|
||||
"husky": "^8.0.0",
|
||||
"jest": "^29.0.3",
|
||||
"lint-staged": "^10.4.0",
|
||||
"prettier": "^2.1.2",
|
||||
"ts-jest": "^29.0.1",
|
||||
"typescript": "^4.3.3"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"minimist": "^1.2.5"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
],
|
||||
"description": "Flip Electron Fuses and customize your packaged build of Electron",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/electron/fuses.git"
|
||||
},
|
||||
"keywords": [
|
||||
"electron",
|
||||
"fuses"
|
||||
],
|
||||
"author": "Electron Community",
|
||||
"bugs": {
|
||||
"url": "https://github.com/electron/fuses/issues"
|
||||
},
|
||||
"homepage": "https://github.com/electron/fuses#readme"
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
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.
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
# @electron/get
|
||||
|
||||
> Download Electron release artifacts
|
||||
|
||||
[](https://github.com/electron/get/actions/workflows/test.yml)
|
||||
[](https://npm.im/@electron/get)
|
||||
[](https://packages.electronjs.org/get)
|
||||
|
||||
## Usage
|
||||
|
||||
For full API details, see the [API documentation](https://packages.electronjs.org/get).
|
||||
|
||||
### Simple: Downloading an Electron Binary ZIP
|
||||
|
||||
```typescript
|
||||
import { download } from '@electron/get';
|
||||
|
||||
// NB: Use this syntax within an async function, Node does not have support for
|
||||
// top-level await as of Node 12.
|
||||
const zipFilePath = await download('4.0.4');
|
||||
```
|
||||
|
||||
### Advanced: Downloading a macOS Electron Symbol File
|
||||
|
||||
```typescript
|
||||
import { downloadArtifact } from '@electron/get';
|
||||
|
||||
// NB: Use this syntax within an async function, Node does not have support for
|
||||
// top-level await as of Node 12.
|
||||
const zipFilePath = await downloadArtifact({
|
||||
version: '4.0.4',
|
||||
platform: 'darwin',
|
||||
artifactName: 'electron',
|
||||
artifactSuffix: 'symbols',
|
||||
arch: 'x64',
|
||||
});
|
||||
```
|
||||
|
||||
### Specifying a mirror
|
||||
|
||||
To specify another location to download Electron assets from, the following options are
|
||||
available:
|
||||
|
||||
* `mirrorOptions` Object
|
||||
* `mirror` String (optional) - The base URL of the mirror to download from.
|
||||
* `nightlyMirror` String (optional) - The Electron nightly-specific mirror URL.
|
||||
* `customDir` String (optional) - The name of the directory to download from, often scoped by version number.
|
||||
* `customFilename` String (optional) - The name of the asset to download.
|
||||
* `resolveAssetURL` Function (optional) - A function allowing customization of the url used to download the asset.
|
||||
|
||||
Anatomy of a download URL, in terms of `mirrorOptions`:
|
||||
|
||||
```
|
||||
https://github.com/electron/electron/releases/download/v4.0.4/electron-v4.0.4-linux-x64.zip
|
||||
| | | |
|
||||
------------------------------------------------------- -----------------------------
|
||||
| |
|
||||
mirror / nightlyMirror | | customFilename
|
||||
------
|
||||
||
|
||||
customDir
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
import { download } from '@electron/get';
|
||||
|
||||
const zipFilePath = await download('4.0.4', {
|
||||
mirrorOptions: {
|
||||
mirror: 'https://mirror.example.com/electron/',
|
||||
customDir: 'custom',
|
||||
customFilename: 'unofficial-electron-linux.zip'
|
||||
}
|
||||
});
|
||||
// Will download from https://mirror.example.com/electron/custom/unofficial-electron-linux.zip
|
||||
|
||||
const nightlyZipFilePath = await download('8.0.0-nightly.20190901', {
|
||||
mirrorOptions: {
|
||||
nightlyMirror: 'https://nightly.example.com/',
|
||||
customDir: 'nightlies',
|
||||
customFilename: 'nightly-linux.zip'
|
||||
}
|
||||
});
|
||||
// Will download from https://nightly.example.com/nightlies/nightly-linux.zip
|
||||
```
|
||||
|
||||
`customDir` can have the placeholder `{{ version }}`, which will be replaced by the version
|
||||
specified (without the leading `v`). For example:
|
||||
|
||||
```javascript
|
||||
const zipFilePath = await download('4.0.4', {
|
||||
mirrorOptions: {
|
||||
mirror: 'https://mirror.example.com/electron/',
|
||||
customDir: 'version-{{ version }}',
|
||||
platform: 'linux',
|
||||
arch: 'x64'
|
||||
}
|
||||
});
|
||||
// Will download from https://mirror.example.com/electron/version-4.0.4/electron-v4.0.4-linux-x64.zip
|
||||
```
|
||||
|
||||
#### Using environment variables for mirror options
|
||||
Mirror options can also be specified via the following environment variables:
|
||||
* `ELECTRON_CUSTOM_DIR` - Specifies the custom directory to download from.
|
||||
* `ELECTRON_CUSTOM_FILENAME` - Specifies the custom file name to download.
|
||||
* `ELECTRON_MIRROR` - Specifies the URL of the server to download from if the version is not a nightly version.
|
||||
* `ELECTRON_NIGHTLY_MIRROR` - Specifies the URL of the server to download from if the version is a nightly version.
|
||||
|
||||
### Overriding the version downloaded
|
||||
|
||||
The version downloaded can be overriden by setting the `ELECTRON_CUSTOM_VERSION` environment variable.
|
||||
Setting this environment variable will override the version passed in to `download` or `downloadArtifact`.
|
||||
|
||||
## How It Works
|
||||
|
||||
This module downloads Electron to a known place on your system and caches it
|
||||
so that future requests for that asset can be returned instantly. The cache
|
||||
locations are:
|
||||
|
||||
* Linux: `$XDG_CACHE_HOME` or `~/.cache/electron/`
|
||||
* MacOS: `~/Library/Caches/electron/`
|
||||
* Windows: `%LOCALAPPDATA%/electron/Cache` or `~/AppData/Local/electron/Cache/`
|
||||
|
||||
By default, the module uses the built-in [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
|
||||
as the downloader. As a result, you can pass [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit)
|
||||
options via `downloadOptions`.
|
||||
|
||||
### Progress Bar
|
||||
|
||||
By default, a progress bar is shown when downloading an artifact for more than 30 seconds. To
|
||||
disable, set the `ELECTRON_GET_NO_PROGRESS` environment variable to any non-empty value, or set
|
||||
`quiet` to `true` in `downloadOptions`. If you need to monitor progress yourself via the API, set
|
||||
`getProgressCallback` in `downloadOptions`, which receives a `Progress` object with `transferred`,
|
||||
`total`, and `percent` properties.
|
||||
|
||||
### Proxies
|
||||
|
||||
Downstream packages should utilize the `initializeProxy` function to add HTTP(S) proxy support. If
|
||||
the environment variable `ELECTRON_GET_USE_PROXY` is set, it is called automatically.
|
||||
|
||||
### Debug
|
||||
|
||||
[`debug`](https://www.npmjs.com/package/debug) is used to display logs and messages.
|
||||
Set the `DEBUG=@electron/get*` environment variable to log additional
|
||||
debug information from this module.
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
export declare class Cache {
|
||||
private cacheRoot;
|
||||
constructor(cacheRoot?: string);
|
||||
static getCacheDirectory(downloadUrl: string): string;
|
||||
getCachePath(downloadUrl: string, fileName: string): string;
|
||||
getPathForFileInCache(url: string, fileName: string): string | null;
|
||||
private hashFile;
|
||||
putFileInCache(url: string, currentPath: string, fileName: string): Promise<string>;
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
import debug from 'debug';
|
||||
import envPaths from 'env-paths';
|
||||
import fs from 'graceful-fs';
|
||||
import crypto from 'node:crypto';
|
||||
import path from 'node:path';
|
||||
import { pipeline } from 'node:stream/promises';
|
||||
const d = debug('@electron/get:cache');
|
||||
const defaultCacheRoot = envPaths('electron', {
|
||||
suffix: '',
|
||||
}).cache;
|
||||
export class Cache {
|
||||
cacheRoot;
|
||||
constructor(cacheRoot = defaultCacheRoot) {
|
||||
this.cacheRoot = cacheRoot;
|
||||
}
|
||||
static getCacheDirectory(downloadUrl) {
|
||||
const parsed = new URL(downloadUrl);
|
||||
parsed.hash = '';
|
||||
parsed.search = '';
|
||||
parsed.pathname = path.posix.dirname(parsed.pathname);
|
||||
return crypto.createHash('sha256').update(parsed.toString()).digest('hex');
|
||||
}
|
||||
getCachePath(downloadUrl, fileName) {
|
||||
return path.resolve(this.cacheRoot, Cache.getCacheDirectory(downloadUrl), fileName);
|
||||
}
|
||||
getPathForFileInCache(url, fileName) {
|
||||
const cachePath = this.getCachePath(url, fileName);
|
||||
if (fs.existsSync(cachePath)) {
|
||||
return cachePath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async hashFile(path) {
|
||||
const hasher = crypto.createHash('sha256');
|
||||
await pipeline(fs.createReadStream(path), hasher);
|
||||
return hasher.digest('hex');
|
||||
}
|
||||
async putFileInCache(url, currentPath, fileName) {
|
||||
const attempt = async (attemptsLeft = 3) => {
|
||||
try {
|
||||
const cachePath = this.getCachePath(url, fileName);
|
||||
d(`Moving ${currentPath} to ${cachePath}`);
|
||||
if (!fs.existsSync(path.dirname(cachePath))) {
|
||||
await fs.promises.mkdir(path.dirname(cachePath), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(cachePath)) {
|
||||
const [existingHash, currentHash] = await Promise.all([
|
||||
this.hashFile(cachePath),
|
||||
this.hashFile(currentPath),
|
||||
]);
|
||||
if (existingHash !== currentHash) {
|
||||
d('* Replacing existing file as it does not match our inbound file');
|
||||
await fs.promises.rm(cachePath, { recursive: true, force: true });
|
||||
}
|
||||
else {
|
||||
d('* Using existing file as the hash matches our inbound file, no need to replace');
|
||||
return cachePath;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await fs.promises.rename(currentPath, cachePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'EXDEV') {
|
||||
// Cross-device link, fallback to copy and delete
|
||||
await fs.promises.cp(currentPath, cachePath, {
|
||||
force: true,
|
||||
recursive: true,
|
||||
verbatimSymlinks: true,
|
||||
});
|
||||
await fs.promises.rm(currentPath, { force: true, recursive: true });
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return cachePath;
|
||||
}
|
||||
catch (err) {
|
||||
if (process.platform === 'win32' && err.code === 'EPERM') {
|
||||
// On windows this normally means we're fighting another instance of @electron/get
|
||||
// also trying to write this file to the cache
|
||||
d('Experienced error putting thing in cache', err);
|
||||
if (attemptsLeft > 0) {
|
||||
d('Trying again in a few seconds');
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 2000);
|
||||
});
|
||||
return await attempt(attemptsLeft - 1);
|
||||
}
|
||||
d('We have already tried too many times, giving up...');
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
return await attempt();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=Cache.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"Cache.js","sourceRoot":"","sources":["../src/Cache.ts"],"names":[],"mappings":"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"}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* Generic interface for the artifact downloader library.
|
||||
* The default implementation is {@link FetchDownloader},
|
||||
* but any custom downloader can be passed to `@electron/get` via
|
||||
* the {@link ElectronDownloadRequestOptions.downloader} option.
|
||||
*
|
||||
* @typeParam T - Options to pass to the downloader
|
||||
* @category Downloader
|
||||
*/
|
||||
export interface Downloader<T> {
|
||||
/**
|
||||
* Download an artifact from an arbitrary URL to a file path on system
|
||||
* @param url URL of the file to download
|
||||
* @param targetFilePath Filesystem path to download the artifact to (including the file name)
|
||||
* @param options Options to pass to the downloader
|
||||
*/
|
||||
download(url: string, targetFilePath: string, options: T): Promise<void>;
|
||||
}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
export {};
|
||||
//# sourceMappingURL=Downloader.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"Downloader.js","sourceRoot":"","sources":["../src/Downloader.ts"],"names":[],"mappings":""}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
import { Downloader } from './Downloader.js';
|
||||
/**
|
||||
* @category Downloader
|
||||
*/
|
||||
export interface Progress {
|
||||
/** Bytes downloaded so far. */
|
||||
transferred: number;
|
||||
/** Total bytes to download, or `null` if the response had no `Content-Length` header. */
|
||||
total: number | null;
|
||||
/**
|
||||
* Ratio of `transferred` to `total` between 0 and 1.
|
||||
* If `total` is unknown, this is 0 until the download completes, then 1.
|
||||
*/
|
||||
percent: number;
|
||||
}
|
||||
/**
|
||||
* @category Downloader
|
||||
*/
|
||||
export declare class HTTPError extends Error {
|
||||
readonly response: Response;
|
||||
constructor(response: Response);
|
||||
}
|
||||
/**
|
||||
* @category Downloader
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/RequestInit | `RequestInit`} for possible keys/values.
|
||||
*/
|
||||
export type FetchDownloaderOptions = RequestInit & {
|
||||
/** Called on each chunk with the current download {@link Progress}. */
|
||||
getProgressCallback?: (progress: Progress) => Promise<void>;
|
||||
/**
|
||||
* Disables the console progress bar. Setting the `ELECTRON_GET_NO_PROGRESS`
|
||||
* environment variable to a non-empty value also does this.
|
||||
*/
|
||||
quiet?: boolean;
|
||||
};
|
||||
/**
|
||||
* Default {@link Downloader} implemented with the built-in
|
||||
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API}.
|
||||
* @category Downloader
|
||||
*/
|
||||
export declare class FetchDownloader implements Downloader<FetchDownloaderOptions> {
|
||||
download(url: string, targetFilePath: string, options?: FetchDownloaderOptions): Promise<void>;
|
||||
}
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
import fs from 'graceful-fs';
|
||||
import path from 'node:path';
|
||||
import ProgressBar from 'progress';
|
||||
import { pipeline } from 'node:stream/promises';
|
||||
import { Readable } from 'node:stream';
|
||||
const PROGRESS_BAR_DELAY_IN_SECONDS = 30;
|
||||
/**
|
||||
* @category Downloader
|
||||
*/
|
||||
export class HTTPError extends Error {
|
||||
response;
|
||||
constructor(response) {
|
||||
super(`Response code ${response.status} (${response.statusText}) for ${response.url}`);
|
||||
this.response = response;
|
||||
this.name = 'HTTPError';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Default {@link Downloader} implemented with the built-in
|
||||
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API}.
|
||||
* @category Downloader
|
||||
*/
|
||||
export class FetchDownloader {
|
||||
async download(url, targetFilePath, options = {}) {
|
||||
const { quiet, getProgressCallback, ...fetchOptions } = options;
|
||||
let downloadCompleted = false;
|
||||
let bar;
|
||||
let progressPercent;
|
||||
let timeout = undefined;
|
||||
await fs.promises.mkdir(path.dirname(targetFilePath), { recursive: true });
|
||||
if (!quiet && !process.env.ELECTRON_GET_NO_PROGRESS) {
|
||||
const start = new Date();
|
||||
timeout = setTimeout(() => {
|
||||
if (!downloadCompleted) {
|
||||
bar = new ProgressBar(`Downloading ${path.basename(url)}: [:bar] :percent ETA: :eta seconds `, {
|
||||
curr: progressPercent,
|
||||
total: 100,
|
||||
});
|
||||
// https://github.com/visionmedia/node-progress/issues/159
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
bar.start = start;
|
||||
}
|
||||
}, PROGRESS_BAR_DELAY_IN_SECONDS * 1000);
|
||||
}
|
||||
try {
|
||||
const response = await fetch(url, fetchOptions);
|
||||
if (!response.ok) {
|
||||
throw new HTTPError(response);
|
||||
}
|
||||
if (!response.body) {
|
||||
throw new Error('Response body is empty');
|
||||
}
|
||||
const contentLength = response.headers.get('content-length');
|
||||
const total = contentLength ? parseInt(contentLength, 10) : null;
|
||||
let transferred = 0;
|
||||
const onProgress = (percent) => {
|
||||
progressPercent = percent;
|
||||
if (bar) {
|
||||
bar.update(percent);
|
||||
}
|
||||
if (getProgressCallback) {
|
||||
void getProgressCallback({ transferred, total, percent });
|
||||
}
|
||||
};
|
||||
await pipeline(Readable.fromWeb(response.body), async function* (source) {
|
||||
for await (const chunk of source) {
|
||||
transferred += chunk.length;
|
||||
onProgress(total ? transferred / total : 0);
|
||||
yield chunk;
|
||||
}
|
||||
}, fs.createWriteStream(targetFilePath));
|
||||
onProgress(1);
|
||||
}
|
||||
finally {
|
||||
downloadCompleted = true;
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=FetchDownloader.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"FetchDownloader.js","sourceRoot":"","sources":["../src/FetchDownloader.ts"],"names":[],"mappings":"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"}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
import { ElectronArtifactDetails } from './types.js';
|
||||
export declare function getArtifactFileName(details: ElectronArtifactDetails): string;
|
||||
export declare function getArtifactRemoteURL(details: ElectronArtifactDetails): Promise<string>;
|
||||
export declare function getArtifactVersion(details: ElectronArtifactDetails): string;
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
import { ensureIsTruthyString, normalizeVersion } from './utils.js';
|
||||
const BASE_URL = 'https://github.com/electron/electron/releases/download/';
|
||||
const NIGHTLY_BASE_URL = 'https://github.com/electron/nightlies/releases/download/';
|
||||
export function getArtifactFileName(details) {
|
||||
ensureIsTruthyString(details, 'artifactName');
|
||||
if (details.isGeneric) {
|
||||
return details.artifactName;
|
||||
}
|
||||
ensureIsTruthyString(details, 'arch');
|
||||
ensureIsTruthyString(details, 'platform');
|
||||
ensureIsTruthyString(details, 'version');
|
||||
return `${[
|
||||
details.artifactName,
|
||||
details.version,
|
||||
details.platform,
|
||||
details.arch,
|
||||
...(details.artifactSuffix ? [details.artifactSuffix] : []),
|
||||
].join('-')}.zip`;
|
||||
}
|
||||
function mirrorVar(name, options, defaultValue) {
|
||||
// Convert camelCase to camel_case for env var reading
|
||||
const snakeName = name.replace(/([a-z])([A-Z])/g, (_, a, b) => `${a}_${b}`).toLowerCase();
|
||||
return (
|
||||
// .npmrc
|
||||
process.env[`npm_config_electron_${name.toLowerCase()}`] ||
|
||||
process.env[`NPM_CONFIG_ELECTRON_${snakeName.toUpperCase()}`] ||
|
||||
process.env[`npm_config_electron_${snakeName}`] ||
|
||||
// package.json
|
||||
process.env[`npm_package_config_electron_${name}`] ||
|
||||
process.env[`npm_package_config_electron_${snakeName.toLowerCase()}`] ||
|
||||
// env
|
||||
process.env[`ELECTRON_${snakeName.toUpperCase()}`] ||
|
||||
options[name] ||
|
||||
defaultValue);
|
||||
}
|
||||
export async function getArtifactRemoteURL(details) {
|
||||
const opts = details.mirrorOptions || {};
|
||||
let base = mirrorVar('mirror', opts, BASE_URL);
|
||||
if (details.version.includes('nightly')) {
|
||||
base = mirrorVar('nightlyMirror', opts, NIGHTLY_BASE_URL);
|
||||
}
|
||||
const path = mirrorVar('customDir', opts, details.version).replace('{{ version }}', details.version.replace(/^v/, ''));
|
||||
const file = mirrorVar('customFilename', opts, getArtifactFileName(details));
|
||||
// Allow customized download URL resolution.
|
||||
if (opts.resolveAssetURL) {
|
||||
const url = await opts.resolveAssetURL(details);
|
||||
return url;
|
||||
}
|
||||
return `${base}${path}/${file}`;
|
||||
}
|
||||
export function getArtifactVersion(details) {
|
||||
return normalizeVersion(mirrorVar('customVersion', details.mirrorOptions || {}, details.version));
|
||||
}
|
||||
//# sourceMappingURL=artifact-utils.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"artifact-utils.js","sourceRoot":"","sources":["../src/artifact-utils.ts"],"names":[],"mappings":"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"}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
import { DownloadOptions } from './types.js';
|
||||
import { Downloader } from './Downloader.js';
|
||||
export declare function getDownloaderForSystem(): Promise<Downloader<DownloadOptions>>;
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { FetchDownloader } from './FetchDownloader.js';
|
||||
export async function getDownloaderForSystem() {
|
||||
return new FetchDownloader();
|
||||
}
|
||||
//# sourceMappingURL=downloader-resolver.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"downloader-resolver.js","sourceRoot":"","sources":["../src/downloader-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,IAAI,eAAe,EAAE,CAAC;AAC/B,CAAC"}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
import { ElectronDownloadRequestOptions, ElectronGenericArtifactDetails, ElectronPlatformArtifactDetailsWithDefaults } from './types.js';
|
||||
export { getHostArch } from './utils.js';
|
||||
export { initializeProxy } from './proxy.js';
|
||||
export * from './types.js';
|
||||
/**
|
||||
* Downloads an artifact from an Electron release and returns an absolute path
|
||||
* to the downloaded file.
|
||||
*
|
||||
* Each release of Electron comes with artifacts, many of which are
|
||||
* platform/arch-specific (e.g. `ffmpeg-v31.0.0-darwin-arm64.zip`) and others that
|
||||
* are generic (e.g. `SHASUMS256.txt`).
|
||||
*
|
||||
*
|
||||
* @param artifactDetails - The information required to download the artifact
|
||||
* @category Download Artifact
|
||||
*/
|
||||
export declare function downloadArtifact(artifactDetails: ElectronPlatformArtifactDetailsWithDefaults | ElectronGenericArtifactDetails): Promise<string>;
|
||||
/**
|
||||
* Downloads the Electron binary for a specific version and returns an absolute path to a
|
||||
* ZIP file.
|
||||
*
|
||||
* @param version - The version of Electron you want to download (e.g. `31.0.0`)
|
||||
* @param options - Options to customize the download behavior
|
||||
* @returns An absolute path to the downloaded ZIP file
|
||||
* @category Download Electron
|
||||
*/
|
||||
export declare function download(version: string, options?: ElectronDownloadRequestOptions): Promise<string>;
|
||||
-188
@@ -1,188 +0,0 @@
|
||||
import debug from 'debug';
|
||||
import fs from 'graceful-fs';
|
||||
import path from 'node:path';
|
||||
import util from 'node:util';
|
||||
import semver from 'semver';
|
||||
import sumchecker from 'sumchecker';
|
||||
import { getArtifactFileName, getArtifactRemoteURL, getArtifactVersion } from './artifact-utils.js';
|
||||
import { ElectronDownloadCacheMode, } from './types.js';
|
||||
import { Cache } from './Cache.js';
|
||||
import { getDownloaderForSystem } from './downloader-resolver.js';
|
||||
import { initializeProxy } from './proxy.js';
|
||||
import { withTempDirectoryIn, getHostArch, getNodeArch, ensureIsTruthyString, isOfficialDropped32BitDownload, isOfficialLinuxIA32Download, mkdtemp, doesCallerOwnTemporaryOutput, effectiveCacheMode, shouldTryReadCache, TempDirCleanUpMode, } from './utils.js';
|
||||
export { getHostArch } from './utils.js';
|
||||
export { initializeProxy } from './proxy.js';
|
||||
export * from './types.js';
|
||||
const d = debug('@electron/get:index');
|
||||
if (process.env.ELECTRON_GET_USE_PROXY) {
|
||||
initializeProxy();
|
||||
}
|
||||
async function validateArtifact(artifactDetails, downloadedAssetPath, _downloadArtifact) {
|
||||
return await withTempDirectoryIn(artifactDetails.tempDirectory, async (tempFolder) => {
|
||||
// Don't try to verify the hash of the hash file itself
|
||||
// and for older versions that don't have a SHASUMS256.txt
|
||||
if (!artifactDetails.artifactName.startsWith('SHASUMS256') &&
|
||||
!artifactDetails.unsafelyDisableChecksums &&
|
||||
semver.gte(artifactDetails.version, '1.3.2')) {
|
||||
let shasumPath;
|
||||
const checksums = artifactDetails.checksums;
|
||||
if (checksums) {
|
||||
shasumPath = path.resolve(tempFolder, 'SHASUMS256.txt');
|
||||
const fileNames = Object.keys(checksums);
|
||||
if (fileNames.length === 0) {
|
||||
throw new Error('Provided "checksums" object is empty, cannot generate a valid SHASUMS256.txt');
|
||||
}
|
||||
const generatedChecksums = fileNames
|
||||
.map((fileName) => `${checksums[fileName]} *${fileName}`)
|
||||
.join('\n');
|
||||
await util.promisify(fs.writeFile)(shasumPath, generatedChecksums);
|
||||
}
|
||||
else {
|
||||
shasumPath = await _downloadArtifact({
|
||||
isGeneric: true,
|
||||
version: artifactDetails.version,
|
||||
artifactName: 'SHASUMS256.txt',
|
||||
downloadOptions: artifactDetails.downloadOptions,
|
||||
cacheRoot: artifactDetails.cacheRoot,
|
||||
downloader: artifactDetails.downloader,
|
||||
mirrorOptions: artifactDetails.mirrorOptions,
|
||||
tempDirectory: artifactDetails.tempDirectory,
|
||||
// Never use the cache for loading checksums, load
|
||||
// them fresh every time
|
||||
cacheMode: ElectronDownloadCacheMode.Bypass,
|
||||
});
|
||||
}
|
||||
try {
|
||||
// For versions 1.3.2 - 1.3.4, need to overwrite the `defaultTextEncoding` option:
|
||||
// https://github.com/electron/electron/pull/6676#discussion_r75332120
|
||||
if (semver.satisfies(artifactDetails.version, '1.3.2 - 1.3.4')) {
|
||||
const validatorOptions = {};
|
||||
validatorOptions.defaultTextEncoding = 'binary';
|
||||
const checker = new sumchecker.ChecksumValidator('sha256', shasumPath, validatorOptions);
|
||||
await checker.validate(path.dirname(downloadedAssetPath), path.basename(downloadedAssetPath));
|
||||
}
|
||||
else {
|
||||
await sumchecker('sha256', shasumPath, path.dirname(downloadedAssetPath), [
|
||||
path.basename(downloadedAssetPath),
|
||||
]);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Once we're done make sure we clean up the shasum temp dir
|
||||
await fs.promises.rm(path.dirname(shasumPath), { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
}, TempDirCleanUpMode.CLEAN);
|
||||
}
|
||||
/**
|
||||
* Downloads an artifact from an Electron release and returns an absolute path
|
||||
* to the downloaded file.
|
||||
*
|
||||
* Each release of Electron comes with artifacts, many of which are
|
||||
* platform/arch-specific (e.g. `ffmpeg-v31.0.0-darwin-arm64.zip`) and others that
|
||||
* are generic (e.g. `SHASUMS256.txt`).
|
||||
*
|
||||
*
|
||||
* @param artifactDetails - The information required to download the artifact
|
||||
* @category Download Artifact
|
||||
*/
|
||||
export async function downloadArtifact(artifactDetails) {
|
||||
const details = {
|
||||
...artifactDetails,
|
||||
};
|
||||
if (!artifactDetails.isGeneric) {
|
||||
const platformArtifactDetails = details;
|
||||
if (!platformArtifactDetails.platform) {
|
||||
d('No platform found, defaulting to the host platform');
|
||||
platformArtifactDetails.platform = process.platform;
|
||||
}
|
||||
if (platformArtifactDetails.arch) {
|
||||
platformArtifactDetails.arch = getNodeArch(platformArtifactDetails.arch);
|
||||
}
|
||||
else {
|
||||
d('No arch found, defaulting to the host arch');
|
||||
platformArtifactDetails.arch = getHostArch();
|
||||
}
|
||||
}
|
||||
ensureIsTruthyString(details, 'version');
|
||||
details.version = getArtifactVersion(details);
|
||||
const fileName = getArtifactFileName(details);
|
||||
const url = await getArtifactRemoteURL(details);
|
||||
const cache = new Cache(details.cacheRoot);
|
||||
const cacheMode = effectiveCacheMode(details);
|
||||
// Do not check if the file exists in the cache when force === true
|
||||
if (shouldTryReadCache(cacheMode)) {
|
||||
d(`Checking the cache (${details.cacheRoot}) for ${fileName} (${url})`);
|
||||
const cachedPath = cache.getPathForFileInCache(url, fileName);
|
||||
if (cachedPath === null) {
|
||||
d('Cache miss');
|
||||
}
|
||||
else {
|
||||
d('Cache hit');
|
||||
let artifactPath = cachedPath;
|
||||
if (doesCallerOwnTemporaryOutput(cacheMode)) {
|
||||
// Copy out of cache into temporary directory if readOnly cache so
|
||||
// that the caller can take ownership of the returned file
|
||||
const tempDir = await mkdtemp(artifactDetails.tempDirectory);
|
||||
artifactPath = path.resolve(tempDir, fileName);
|
||||
await util.promisify(fs.copyFile)(cachedPath, artifactPath);
|
||||
}
|
||||
try {
|
||||
await validateArtifact(details, artifactPath, downloadArtifact);
|
||||
return artifactPath;
|
||||
}
|
||||
catch (err) {
|
||||
if (doesCallerOwnTemporaryOutput(cacheMode)) {
|
||||
await fs.promises.rm(path.dirname(artifactPath), { recursive: true, force: true });
|
||||
}
|
||||
d("Artifact in cache didn't match checksums", err);
|
||||
d('falling back to re-download');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!details.isGeneric &&
|
||||
isOfficialLinuxIA32Download(details.platform, details.arch, details.version, details.mirrorOptions)) {
|
||||
console.warn('Official Linux/ia32 support is deprecated.');
|
||||
console.warn('For more info: https://electronjs.org/blog/linux-32bit-support');
|
||||
}
|
||||
if (!details.isGeneric &&
|
||||
isOfficialDropped32BitDownload(details.platform, details.arch, details.version, details.mirrorOptions)) {
|
||||
throw new Error(`Electron ${details.version} does not have a published ${details.platform}/${details.arch} artifact. ` +
|
||||
'Electron 44 and newer no longer publish win32/ia32 or linux/armv7l builds; ' +
|
||||
'the last release line with 32-bit support is Electron 43, which is supported until January 2027.');
|
||||
}
|
||||
return await withTempDirectoryIn(details.tempDirectory, async (tempFolder) => {
|
||||
const tempDownloadPath = path.resolve(tempFolder, getArtifactFileName(details));
|
||||
const downloader = details.downloader || (await getDownloaderForSystem());
|
||||
d(`Downloading ${url} to ${tempDownloadPath} with options: ${JSON.stringify(details.downloadOptions)}`);
|
||||
await downloader.download(url, tempDownloadPath, details.downloadOptions);
|
||||
d('attempting to validate artifact...', { details });
|
||||
await validateArtifact(details, tempDownloadPath, downloadArtifact);
|
||||
d('artifact validated');
|
||||
if (doesCallerOwnTemporaryOutput(cacheMode)) {
|
||||
return tempDownloadPath;
|
||||
}
|
||||
else {
|
||||
return await cache.putFileInCache(url, tempDownloadPath, fileName);
|
||||
}
|
||||
}, doesCallerOwnTemporaryOutput(cacheMode) ? TempDirCleanUpMode.ORPHAN : TempDirCleanUpMode.CLEAN);
|
||||
}
|
||||
/**
|
||||
* Downloads the Electron binary for a specific version and returns an absolute path to a
|
||||
* ZIP file.
|
||||
*
|
||||
* @param version - The version of Electron you want to download (e.g. `31.0.0`)
|
||||
* @param options - Options to customize the download behavior
|
||||
* @returns An absolute path to the downloaded ZIP file
|
||||
* @category Download Electron
|
||||
*/
|
||||
export function download(version, options) {
|
||||
return downloadArtifact({
|
||||
...options,
|
||||
version,
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
artifactName: 'electron',
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-14
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Initializes a third-party proxy module for HTTP(S) requests. Call this function before
|
||||
* using the {@link download} and {@link downloadArtifact} APIs if you need proxy support.
|
||||
*
|
||||
* If the `ELECTRON_GET_USE_PROXY` environment variable is set to `true`, this function will be
|
||||
* called automatically for `@electron/get` requests.
|
||||
*
|
||||
* Supported environment variables are `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`.
|
||||
*
|
||||
* @category Utility
|
||||
* @see {@link https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent | `EnvHttpProxyAgent`}
|
||||
* documentation for available environment variables.
|
||||
*/
|
||||
export declare function initializeProxy(): void;
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
import { createRequire } from 'node:module';
|
||||
import debug from 'debug';
|
||||
const d = debug('@electron/get:proxy');
|
||||
const require = createRequire(import.meta.url);
|
||||
/**
|
||||
* Initializes a third-party proxy module for HTTP(S) requests. Call this function before
|
||||
* using the {@link download} and {@link downloadArtifact} APIs if you need proxy support.
|
||||
*
|
||||
* If the `ELECTRON_GET_USE_PROXY` environment variable is set to `true`, this function will be
|
||||
* called automatically for `@electron/get` requests.
|
||||
*
|
||||
* Supported environment variables are `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`.
|
||||
*
|
||||
* @category Utility
|
||||
* @see {@link https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent | `EnvHttpProxyAgent`}
|
||||
* documentation for available environment variables.
|
||||
*/
|
||||
export function initializeProxy() {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
|
||||
setGlobalDispatcher(new EnvHttpProxyAgent());
|
||||
}
|
||||
catch (e) {
|
||||
d('Could not load undici, built-in proxy support not available:', e);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=proxy.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,GAAG,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrE,mBAAmB,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,CAAC,CAAC,8DAA8D,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;AACH,CAAC"}
|
||||
-244
@@ -1,244 +0,0 @@
|
||||
import { Downloader } from './Downloader.js';
|
||||
import { FetchDownloader, FetchDownloaderOptions, HTTPError, Progress } from './FetchDownloader.js';
|
||||
export { Downloader, FetchDownloader, FetchDownloaderOptions, HTTPError, Progress };
|
||||
/**
|
||||
* Custom downloaders can implement any set of options.
|
||||
* @category Downloader
|
||||
*/
|
||||
export type DownloadOptions = any;
|
||||
/**
|
||||
* Options for specifying an alternative download mirror for Electron.
|
||||
*
|
||||
* @category Utility
|
||||
* @example
|
||||
*
|
||||
* To download the Electron v4.0.4 release for x64 Linux from
|
||||
* https://github.com/electron/electron/releases/download/v4.0.4/electron-v4.0.4-linux-x64.zip
|
||||
*
|
||||
* ```js
|
||||
* const opts = {
|
||||
* mirror: 'https://github.com/electron/electron/releases/download',
|
||||
* customDir: 'v4.0.4',
|
||||
* customFilename: 'electron-v4.0.4-linux-x64.zip',
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface MirrorOptions {
|
||||
/**
|
||||
* The mirror URL for [`electron-nightly`](https://npmjs.com/package/electron-nightly),
|
||||
* which lives in a separate npm package.
|
||||
*/
|
||||
nightlyMirror?: string;
|
||||
/**
|
||||
* The base URL of the mirror to download from.
|
||||
* e.g https://github.com/electron/electron/releases/download
|
||||
*/
|
||||
mirror?: string;
|
||||
/**
|
||||
* The name of the directory to download from,
|
||||
* often scoped by version number e.g 'v4.0.4'
|
||||
*/
|
||||
customDir?: string;
|
||||
/**
|
||||
* The name of the asset to download,
|
||||
* e.g 'electron-v4.0.4-linux-x64.zip'
|
||||
*/
|
||||
customFilename?: string;
|
||||
/**
|
||||
* The version of the asset to download,
|
||||
* e.g '4.0.4'
|
||||
*/
|
||||
customVersion?: string;
|
||||
/**
|
||||
* A function allowing customization of the url returned
|
||||
* from getArtifactRemoteURL().
|
||||
*/
|
||||
resolveAssetURL?: (opts: DownloadOptions) => Promise<string>;
|
||||
}
|
||||
/**
|
||||
* @category Download Artifact
|
||||
* @internal
|
||||
*/
|
||||
export interface ElectronDownloadRequest {
|
||||
/**
|
||||
* The version of Electron associated with the artifact.
|
||||
*/
|
||||
version: string;
|
||||
/**
|
||||
* The type of artifact. For example:
|
||||
* * `electron`
|
||||
* * `ffmpeg`
|
||||
*/
|
||||
artifactName: string;
|
||||
}
|
||||
export declare enum ElectronDownloadCacheMode {
|
||||
/**
|
||||
* Reads from the cache if present
|
||||
* Writes to the cache after fetch if not present
|
||||
*/
|
||||
ReadWrite = 0,
|
||||
/**
|
||||
* Reads from the cache if present
|
||||
* Will **not** write back to the cache after fetching missing artifact
|
||||
*/
|
||||
ReadOnly = 1,
|
||||
/**
|
||||
* Skips reading from the cache
|
||||
* Will write back into the cache, overwriting anything currently in the cache after fetch
|
||||
*/
|
||||
WriteOnly = 2,
|
||||
/**
|
||||
* Bypasses the cache completely, neither reads from nor writes to the cache
|
||||
*/
|
||||
Bypass = 3
|
||||
}
|
||||
/**
|
||||
* @category Download Electron
|
||||
*/
|
||||
export interface ElectronDownloadRequestOptions {
|
||||
/**
|
||||
* When set to `true`, disables checking that the artifact download completed successfully
|
||||
* with the correct payload.
|
||||
*
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
unsafelyDisableChecksums?: boolean;
|
||||
/**
|
||||
* Provides checksums for the artifact as strings.
|
||||
* Can be used if you already know the checksums of the Electron artifact
|
||||
* you are downloading and want to skip the checksum file download
|
||||
* without skipping the checksum validation.
|
||||
*
|
||||
* This should be an object whose keys are the file names of the artifacts and
|
||||
* the values are their respective SHA256 checksums.
|
||||
*
|
||||
* @example
|
||||
* ```json
|
||||
* {
|
||||
* "electron-v4.0.4-linux-x64.zip": "877617029f4c0f2b24f3805a1c3554ba166fda65c4e88df9480ae7b6ffa26a22"
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
checksums?: Record<string, string>;
|
||||
/**
|
||||
* The directory that caches Electron artifact downloads.
|
||||
*
|
||||
* @defaultValue The default value is dependent upon the host platform:
|
||||
*
|
||||
* * Linux: `$XDG_CACHE_HOME` or `~/.cache/electron/`
|
||||
* * MacOS: `~/Library/Caches/electron/`
|
||||
* * Windows: `%LOCALAPPDATA%/electron/Cache` or `~/AppData/Local/electron/Cache/`
|
||||
*/
|
||||
cacheRoot?: string;
|
||||
/**
|
||||
* Options passed to the downloader module.
|
||||
*
|
||||
* @see {@link FetchDownloaderOptions} for options for the default {@link FetchDownloader}.
|
||||
*/
|
||||
downloadOptions?: DownloadOptions;
|
||||
/**
|
||||
* Options related to specifying an artifact mirror.
|
||||
*/
|
||||
mirrorOptions?: MirrorOptions;
|
||||
/**
|
||||
* A custom {@link Downloader} class used to download artifacts. Defaults to the
|
||||
* built-in {@link FetchDownloader}.
|
||||
*/
|
||||
downloader?: Downloader<DownloadOptions>;
|
||||
/**
|
||||
* A temporary directory for downloads.
|
||||
* It is used before artifacts are put into cache.
|
||||
*
|
||||
* @defaultValue the OS default temporary directory via [`os.tmpdir()`](https://nodejs.org/api/os.html#ostmpdir)
|
||||
*/
|
||||
tempDirectory?: string;
|
||||
/**
|
||||
* Controls the cache read and write behavior.
|
||||
*
|
||||
* When set to either {@link ElectronDownloadCacheMode.ReadOnly | ReadOnly} or
|
||||
* {@link ElectronDownloadCacheMode.Bypass | Bypass}, the caller is responsible
|
||||
* for cleaning up the returned file path once they are done using it
|
||||
* (e.g. via `fs.remove(path.dirname(pathFromElectronGet))`).
|
||||
*
|
||||
* When set to either {@link ElectronDownloadCacheMode.WriteOnly | WriteOnly} or
|
||||
* {@link ElectronDownloadCacheMode.ReadWrite | ReadWrite} (the default), the caller
|
||||
* should not move or delete the file path that is returned as the path
|
||||
* points directly to the disk cache.
|
||||
*
|
||||
* @defaultValue {@link ElectronDownloadCacheMode.ReadWrite}
|
||||
*/
|
||||
cacheMode?: ElectronDownloadCacheMode;
|
||||
}
|
||||
/**
|
||||
* @category Download Artifact
|
||||
* @internal
|
||||
*/
|
||||
export type ElectronPlatformArtifactDetails = {
|
||||
/**
|
||||
* The target artifact platform. These are Node-style platform names, for example:
|
||||
* * `win32`
|
||||
* * `darwin`
|
||||
* * `linux`
|
||||
*
|
||||
* @see Node.js {@link https://nodejs.org/api/process.html#processplatform | process.platform} docs
|
||||
*/
|
||||
platform: string;
|
||||
/**
|
||||
* The target artifact architecture. These are Node-style architecture names, for example:
|
||||
* * `ia32` (Electron 43 and earlier)
|
||||
* * `x64`
|
||||
* * `armv7l` (Electron 43 and earlier)
|
||||
*
|
||||
* @see Node.js {@link https://nodejs.org/api/process.html#processarch | process.arch} docs
|
||||
*/
|
||||
arch: string;
|
||||
artifactSuffix?: string;
|
||||
isGeneric?: false;
|
||||
} & ElectronDownloadRequest & ElectronDownloadRequestOptions;
|
||||
/**
|
||||
* Options to download a generic (i.e. platform and architecture-agnostic)
|
||||
* Electron artifact. Contains all options from {@link ElectronDownloadRequestOptions},
|
||||
* but specifies a `version` and `artifactName` for the artifact to download.
|
||||
*
|
||||
* @category Download Artifact
|
||||
* @interface
|
||||
*/
|
||||
export type ElectronGenericArtifactDetails = {
|
||||
isGeneric: true;
|
||||
} & ElectronDownloadRequest & ElectronDownloadRequestOptions;
|
||||
/**
|
||||
* @category Download Artifact
|
||||
* @internal
|
||||
*/
|
||||
export type ElectronArtifactDetails = ElectronPlatformArtifactDetails | ElectronGenericArtifactDetails;
|
||||
/**
|
||||
* Options to download a platform and architecture-specific Electron artifact.
|
||||
* Contains all options from {@link ElectronDownloadRequestOptions}, but
|
||||
* specifies a `version` and `artifactName` for the artifact to download.
|
||||
*
|
||||
* If `platform` and `arch` are omitted, they will be inferred using the host
|
||||
* system platform and architecture.
|
||||
*
|
||||
* @category Download Artifact
|
||||
* @interface
|
||||
*/
|
||||
export type ElectronPlatformArtifactDetailsWithDefaults = Omit<ElectronPlatformArtifactDetails, 'platform' | 'arch'> & {
|
||||
/**
|
||||
* The target artifact platform. These are Node-style platform names, for example:
|
||||
* * `win32`
|
||||
* * `darwin`
|
||||
* * `linux`
|
||||
*
|
||||
* @see Node.js {@link https://nodejs.org/api/process.html#processplatform | process.platform} docs
|
||||
*/
|
||||
platform?: string;
|
||||
/**
|
||||
* The target artifact architecture. These are Node-style architecture names, for example:
|
||||
* * `ia32` (Electron 43 and earlier)
|
||||
* * `x64`
|
||||
* * `armv7l` (Electron 43 and earlier)
|
||||
*
|
||||
* @see Node.js {@link https://nodejs.org/api/process.html#processarch | process.arch} docs
|
||||
*/
|
||||
arch?: string;
|
||||
};
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
import { FetchDownloader, HTTPError } from './FetchDownloader.js';
|
||||
export { FetchDownloader, HTTPError };
|
||||
export var ElectronDownloadCacheMode;
|
||||
(function (ElectronDownloadCacheMode) {
|
||||
/**
|
||||
* Reads from the cache if present
|
||||
* Writes to the cache after fetch if not present
|
||||
*/
|
||||
ElectronDownloadCacheMode[ElectronDownloadCacheMode["ReadWrite"] = 0] = "ReadWrite";
|
||||
/**
|
||||
* Reads from the cache if present
|
||||
* Will **not** write back to the cache after fetching missing artifact
|
||||
*/
|
||||
ElectronDownloadCacheMode[ElectronDownloadCacheMode["ReadOnly"] = 1] = "ReadOnly";
|
||||
/**
|
||||
* Skips reading from the cache
|
||||
* Will write back into the cache, overwriting anything currently in the cache after fetch
|
||||
*/
|
||||
ElectronDownloadCacheMode[ElectronDownloadCacheMode["WriteOnly"] = 2] = "WriteOnly";
|
||||
/**
|
||||
* Bypasses the cache completely, neither reads from nor writes to the cache
|
||||
*/
|
||||
ElectronDownloadCacheMode[ElectronDownloadCacheMode["Bypass"] = 3] = "Bypass";
|
||||
})(ElectronDownloadCacheMode || (ElectronDownloadCacheMode = {}));
|
||||
//# sourceMappingURL=types.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA0B,SAAS,EAAY,MAAM,sBAAsB,CAAC;AAEpG,OAAO,EAAc,eAAe,EAA0B,SAAS,EAAY,CAAC;AA4EpF,MAAM,CAAN,IAAY,yBAoBX;AApBD,WAAY,yBAAyB;IACnC;;;OAGG;IACH,mFAAS,CAAA;IACT;;;OAGG;IACH,iFAAQ,CAAA;IACR;;;OAGG;IACH,mFAAS,CAAA;IACT;;OAEG;IACH,6EAAM,CAAA;AACR,CAAC,EApBW,yBAAyB,KAAzB,yBAAyB,QAoBpC"}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
import { ElectronDownloadCacheMode, ElectronGenericArtifactDetails, ElectronPlatformArtifactDetailsWithDefaults } from './types.js';
|
||||
export declare function mkdtemp(parentDirectory?: string): Promise<string>;
|
||||
export declare enum TempDirCleanUpMode {
|
||||
CLEAN = 0,
|
||||
ORPHAN = 1
|
||||
}
|
||||
export declare function withTempDirectoryIn<T>(parentDirectory: string | undefined, fn: (directory: string) => Promise<T>, cleanUp: TempDirCleanUpMode): Promise<T>;
|
||||
export declare function withTempDirectory<T>(fn: (directory: string) => Promise<T>, cleanUp: TempDirCleanUpMode): Promise<T>;
|
||||
export declare function normalizeVersion(version: string): string;
|
||||
/**
|
||||
* Runs the `uname` command and returns the trimmed output.
|
||||
*/
|
||||
export declare function uname(): string;
|
||||
/**
|
||||
* Generates an architecture name that would be used in an Electron or Node.js
|
||||
* download file name.
|
||||
*/
|
||||
export declare function getNodeArch(arch: string): string;
|
||||
/**
|
||||
* Generates an architecture name that would be used in an Electron or Node.js
|
||||
* download file name from the `process` module information.
|
||||
*
|
||||
* @category Utility
|
||||
*/
|
||||
export declare function getHostArch(): string;
|
||||
export declare function ensureIsTruthyString<T, K extends keyof T>(obj: T, key: K): void;
|
||||
export declare function isOfficialLinuxIA32Download(platform: string, arch: string, version: string, mirrorOptions?: object): boolean;
|
||||
export declare function isOfficialDropped32BitDownload(platform: string, arch: string, version: string, mirrorOptions?: object): boolean;
|
||||
/**
|
||||
* Find the value of a environment variable which may or may not have the
|
||||
* prefix, in a case-insensitive manner.
|
||||
*/
|
||||
export declare function getEnv(prefix?: string): (name: string) => string | undefined;
|
||||
export declare function setEnv(key: string, value: string | undefined): void;
|
||||
export declare function effectiveCacheMode(artifactDetails: ElectronPlatformArtifactDetailsWithDefaults | ElectronGenericArtifactDetails): ElectronDownloadCacheMode;
|
||||
export declare function shouldTryReadCache(cacheMode: ElectronDownloadCacheMode): boolean;
|
||||
export declare function shouldWriteCache(cacheMode: ElectronDownloadCacheMode): boolean;
|
||||
export declare function doesCallerOwnTemporaryOutput(cacheMode: ElectronDownloadCacheMode): boolean;
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
import childProcess from 'node:child_process';
|
||||
import fs from 'graceful-fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import semver from 'semver';
|
||||
import { ElectronDownloadCacheMode, } from './types.js';
|
||||
async function useAndRemoveDirectory(directory, fn) {
|
||||
let result;
|
||||
try {
|
||||
result = await fn(directory);
|
||||
}
|
||||
finally {
|
||||
await fs.promises.rm(directory, { recursive: true, force: true });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export async function mkdtemp(parentDirectory = os.tmpdir()) {
|
||||
const tempDirectoryPrefix = 'electron-download-';
|
||||
return await fs.promises.mkdtemp(path.resolve(parentDirectory, tempDirectoryPrefix));
|
||||
}
|
||||
export var TempDirCleanUpMode;
|
||||
(function (TempDirCleanUpMode) {
|
||||
TempDirCleanUpMode[TempDirCleanUpMode["CLEAN"] = 0] = "CLEAN";
|
||||
TempDirCleanUpMode[TempDirCleanUpMode["ORPHAN"] = 1] = "ORPHAN";
|
||||
})(TempDirCleanUpMode || (TempDirCleanUpMode = {}));
|
||||
export async function withTempDirectoryIn(parentDirectory = os.tmpdir(), fn, cleanUp) {
|
||||
const tempDirectory = await mkdtemp(parentDirectory);
|
||||
if (cleanUp === TempDirCleanUpMode.CLEAN) {
|
||||
return useAndRemoveDirectory(tempDirectory, fn);
|
||||
}
|
||||
else {
|
||||
return fn(tempDirectory);
|
||||
}
|
||||
}
|
||||
export async function withTempDirectory(fn, cleanUp) {
|
||||
return withTempDirectoryIn(undefined, fn, cleanUp);
|
||||
}
|
||||
export function normalizeVersion(version) {
|
||||
if (!version.startsWith('v')) {
|
||||
return `v${version}`;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
/**
|
||||
* Runs the `uname` command and returns the trimmed output.
|
||||
*/
|
||||
export function uname() {
|
||||
return childProcess.execSync('uname -m').toString().trim();
|
||||
}
|
||||
/**
|
||||
* Generates an architecture name that would be used in an Electron or Node.js
|
||||
* download file name.
|
||||
*/
|
||||
export function getNodeArch(arch) {
|
||||
if (arch === 'arm') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
switch (process.config.variables.arm_version) {
|
||||
case '6':
|
||||
return uname();
|
||||
case '7':
|
||||
default:
|
||||
return 'armv7l';
|
||||
}
|
||||
}
|
||||
return arch;
|
||||
}
|
||||
/**
|
||||
* Generates an architecture name that would be used in an Electron or Node.js
|
||||
* download file name from the `process` module information.
|
||||
*
|
||||
* @category Utility
|
||||
*/
|
||||
export function getHostArch() {
|
||||
return getNodeArch(process.arch);
|
||||
}
|
||||
export function ensureIsTruthyString(obj, key) {
|
||||
if (!obj[key] || typeof obj[key] !== 'string') {
|
||||
throw new Error(`Expected property "${String(key)}" to be provided as a string but it was not`);
|
||||
}
|
||||
}
|
||||
export function isOfficialLinuxIA32Download(platform, arch, version, mirrorOptions) {
|
||||
return (platform === 'linux' &&
|
||||
arch === 'ia32' &&
|
||||
Number(version.slice(1).split('.')[0]) >= 4 &&
|
||||
typeof mirrorOptions === 'undefined');
|
||||
}
|
||||
// Electron 44 dropped support for 32-bit Windows (win32/ia32) and for
|
||||
// armv7l Linux. The last official releases to ship these artifacts are
|
||||
// v44.0.0-alpha.3 on the release channel and v45.0.0-nightly.20260713 on
|
||||
// the nightly channel.
|
||||
const FIRST_RELEASE_WITHOUT_32_BIT_SUPPORT = '44.0.0-alpha.4';
|
||||
const FIRST_NIGHTLY_WITHOUT_32_BIT_SUPPORT = '45.0.0-nightly.20260714';
|
||||
export function isOfficialDropped32BitDownload(platform, arch, version, mirrorOptions) {
|
||||
// Custom mirrors may legitimately host their own builds for these platforms
|
||||
if (typeof mirrorOptions !== 'undefined') {
|
||||
return false;
|
||||
}
|
||||
if (!((platform === 'win32' && arch === 'ia32') || (platform === 'linux' && arch === 'armv7l'))) {
|
||||
return false;
|
||||
}
|
||||
const parsedVersion = semver.parse(version);
|
||||
if (parsedVersion === null) {
|
||||
return false;
|
||||
}
|
||||
const firstVersionWithoutArtifacts = parsedVersion.prerelease.includes('nightly')
|
||||
? FIRST_NIGHTLY_WITHOUT_32_BIT_SUPPORT
|
||||
: FIRST_RELEASE_WITHOUT_32_BIT_SUPPORT;
|
||||
return semver.gte(parsedVersion, firstVersionWithoutArtifacts);
|
||||
}
|
||||
/**
|
||||
* Find the value of a environment variable which may or may not have the
|
||||
* prefix, in a case-insensitive manner.
|
||||
*/
|
||||
export function getEnv(prefix = '') {
|
||||
const envsLowerCase = {};
|
||||
for (const envKey in process.env) {
|
||||
envsLowerCase[envKey.toLowerCase()] = process.env[envKey];
|
||||
}
|
||||
return (name) => {
|
||||
return (envsLowerCase[`${prefix}${name}`.toLowerCase()] ||
|
||||
envsLowerCase[name.toLowerCase()] ||
|
||||
undefined);
|
||||
};
|
||||
}
|
||||
export function setEnv(key, value) {
|
||||
// The `void` operator always returns `undefined`.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
|
||||
if (value !== void 0) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
export function effectiveCacheMode(artifactDetails) {
|
||||
return artifactDetails.cacheMode || ElectronDownloadCacheMode.ReadWrite;
|
||||
}
|
||||
export function shouldTryReadCache(cacheMode) {
|
||||
return (cacheMode === ElectronDownloadCacheMode.ReadOnly ||
|
||||
cacheMode === ElectronDownloadCacheMode.ReadWrite);
|
||||
}
|
||||
export function shouldWriteCache(cacheMode) {
|
||||
return (cacheMode === ElectronDownloadCacheMode.WriteOnly ||
|
||||
cacheMode === ElectronDownloadCacheMode.ReadWrite);
|
||||
}
|
||||
export function doesCallerOwnTemporaryOutput(cacheMode) {
|
||||
return (cacheMode === ElectronDownloadCacheMode.Bypass ||
|
||||
cacheMode === ElectronDownloadCacheMode.ReadOnly);
|
||||
}
|
||||
//# sourceMappingURL=utils.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EACL,yBAAyB,GAG1B,MAAM,YAAY,CAAC;AAEpB,KAAK,UAAU,qBAAqB,CAClC,SAAiB,EACjB,EAAqC;IAErC,IAAI,MAAS,CAAC;IACd,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,kBAA0B,EAAE,CAAC,MAAM,EAAE;IACjE,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;IACjD,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;AACvF,CAAC;AAED,MAAM,CAAN,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC5B,6DAAK,CAAA;IACL,+DAAM,CAAA;AACR,CAAC,EAHW,kBAAkB,KAAlB,kBAAkB,QAG7B;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,kBAA0B,EAAE,CAAC,MAAM,EAAE,EACrC,EAAqC,EACrC,OAA2B;IAE3B,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,kBAAkB,CAAC,KAAK,EAAE,CAAC;QACzC,OAAO,qBAAqB,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAqC,EACrC,OAA2B;IAE3B,OAAO,mBAAmB,CAAC,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,OAAO,EAAE,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,8DAA8D;QAC9D,QAAS,OAAO,CAAC,MAAM,CAAC,SAAiB,CAAC,WAAW,EAAE,CAAC;YACtD,KAAK,GAAG;gBACN,OAAO,KAAK,EAAE,CAAC;YACjB,KAAK,GAAG,CAAC;YACT;gBACE,OAAO,QAAQ,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAuB,GAAM,EAAE,GAAM;IACvE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAClG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAgB,EAChB,IAAY,EACZ,OAAe,EACf,aAAsB;IAEtB,OAAO,CACL,QAAQ,KAAK,OAAO;QACpB,IAAI,KAAK,MAAM;QACf,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3C,OAAO,aAAa,KAAK,WAAW,CACrC,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,uEAAuE;AACvE,yEAAyE;AACzE,uBAAuB;AACvB,MAAM,oCAAoC,GAAG,gBAAgB,CAAC;AAC9D,MAAM,oCAAoC,GAAG,yBAAyB,CAAC;AAEvE,MAAM,UAAU,8BAA8B,CAC5C,QAAgB,EAChB,IAAY,EACZ,OAAe,EACf,aAAsB;IAEtB,4EAA4E;IAC5E,IAAI,OAAO,aAAa,KAAK,WAAW,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC;QAChG,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,4BAA4B,GAAG,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC/E,CAAC,CAAC,oCAAoC;QACtC,CAAC,CAAC,oCAAoC,CAAC;IACzC,OAAO,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,4BAA4B,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,MAAM,GAAG,EAAE;IAChC,MAAM,aAAa,GAAsB,EAAE,CAAC;IAE5C,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,CAAC,IAAY,EAAsB,EAAE;QAC1C,OAAO,CACL,aAAa,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,SAAS,CACV,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,KAAyB;IAC3D,kDAAkD;IAClD,wFAAwF;IACxF,IAAI,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,eAA6F;IAE7F,OAAO,eAAe,CAAC,SAAS,IAAI,yBAAyB,CAAC,SAAS,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAoC;IACrE,OAAO,CACL,SAAS,KAAK,yBAAyB,CAAC,QAAQ;QAChD,SAAS,KAAK,yBAAyB,CAAC,SAAS,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAoC;IACnE,OAAO,CACL,SAAS,KAAK,yBAAyB,CAAC,SAAS;QACjD,SAAS,KAAK,yBAAyB,CAAC,SAAS,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,SAAoC;IAC/E,OAAO,CACL,SAAS,KAAK,yBAAyB,CAAC,MAAM;QAC9C,SAAS,KAAK,yBAAyB,CAAC,QAAQ,CACjD,CAAC;AACJ,CAAC"}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
{
|
||||
"name": "@electron/get",
|
||||
"version": "5.1.0",
|
||||
"type": "module",
|
||||
"exports": "./dist/index.js",
|
||||
"description": "Utility for downloading artifacts from different versions of Electron",
|
||||
"repository": "https://github.com/electron/get",
|
||||
"author": "Samuel Attard",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"provenance": true
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build:docs": "typedoc",
|
||||
"lint": "oxfmt --check . && oxlint",
|
||||
"lint:fix": "oxfmt --write . && oxlint --fix",
|
||||
"prepare": "husky",
|
||||
"prepublishOnly": "npm run build",
|
||||
"test": "vitest run --coverage",
|
||||
"test:nonetwork": "npm run lint && vitest run --coverage --testPathIgnorePatterns network.spec"
|
||||
},
|
||||
"files": [
|
||||
"dist/",
|
||||
"README.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^3.0.0",
|
||||
"graceful-fs": "^4.2.11",
|
||||
"progress": "^2.0.3",
|
||||
"semver": "^7.6.3",
|
||||
"sumchecker": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node22": "^22.0.0",
|
||||
"@types/debug": "^4.1.4",
|
||||
"@types/graceful-fs": "^4.1.9",
|
||||
"@types/node": "~22.12.0",
|
||||
"@types/progress": "^2.0.3",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@vitest/coverage-v8": "^4.1.2",
|
||||
"esbuild-plugin-file-path-extensions": "^2.1.4",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.2.7",
|
||||
"oxfmt": "^0.44.0",
|
||||
"oxlint": "^1.59.0",
|
||||
"oxlint-tsgolint": "^0.20.0",
|
||||
"typedoc": "~0.28.0",
|
||||
"typescript": "^6.0.2",
|
||||
"vitest": "^4.1.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,ts}": [
|
||||
"oxfmt --write",
|
||||
"oxlint --fix"
|
||||
],
|
||||
"*.{json}": [
|
||||
"oxfmt --write"
|
||||
]
|
||||
},
|
||||
"keywords": [
|
||||
"electron",
|
||||
"download",
|
||||
"prebuild",
|
||||
"get",
|
||||
"artifact",
|
||||
"release"
|
||||
],
|
||||
"optionalDependencies": {
|
||||
"undici": "^7.24.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"fsevents": "npm:@electron/fsevents@2.3.3-fork"
|
||||
},
|
||||
"packageManager": "yarn@4.10.3+sha512.c38cafb5c7bb273f3926d04e55e1d8c9dfa7d9c3ea1f36a4868fa028b9e5f72298f0b7f401ad5eb921749eb012eb1c3bb74bf7503df3ee43fd600d14a018266f"
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
Copyright 2018 Samuel Attard and contributors
|
||||
|
||||
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.
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
Electron Notarize
|
||||
-----------
|
||||
|
||||
> Notarize your Electron apps seamlessly for macOS
|
||||
|
||||
[](https://circleci.com/gh/electron/notarize)
|
||||
[](https://npm.im/@electron/notarize)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @electron/notarize --save-dev
|
||||
```
|
||||
|
||||
## What is app "notarization"?
|
||||
|
||||
From Apple's docs in XCode:
|
||||
|
||||
> A notarized app is a macOS app that was uploaded to Apple for processing before it was distributed.
|
||||
> When you export a notarized app from Xcode, it code signs the app with a Developer ID certificate
|
||||
> and staples a ticket from Apple to the app. The ticket confirms that you previously uploaded the app to Apple.
|
||||
|
||||
> On macOS 10.14 and later, the user can launch notarized apps when Gatekeeper is enabled.
|
||||
> When the user first launches a notarized app, Gatekeeper looks for the app’s ticket online.
|
||||
> If the user is offline, Gatekeeper looks for the ticket that was stapled to the app.
|
||||
|
||||
As macOS 10.15 (Catalina), Apple has made notarization a hard requirement for all applications
|
||||
distributed outside of the Mac App Store. App Store applications do not need to be notarized.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
For notarization, you need the following things:
|
||||
|
||||
1. Xcode 13 or later installed on your Mac.
|
||||
1. An [Apple Developer](https://developer.apple.com/) account.
|
||||
1. [An app-specific password for your ADC account’s Apple ID](https://support.apple.com/HT204397).
|
||||
1. Your app may need to be signed with `hardenedRuntime: true` option, with the `com.apple.security.cs.allow-jit` entitlement.
|
||||
|
||||
> [!NOTE]
|
||||
> If you are using Electron 11 or below, you must add the `com.apple.security.cs.allow-unsigned-executable-memory` entitlement too.
|
||||
> When using version 12+, this entitlement should not be applied as it increases your app's attack surface.
|
||||
|
||||
### Notarization on older macOS versions
|
||||
|
||||
Xcode 13 is available from macOS 11.3, but notarization can be performed on systems down to macOS 10.15
|
||||
(see [TN3147](https://developer.apple.com/documentation/technotes/tn3147-migrating-to-the-latest-notarization-tool#Enable-notarization-on-an-older-version-of-macOS) for more information).
|
||||
|
||||
To achieve this, you can copy notarytool binary from a newer macOS version and provide its path as `notarytoolPath` option.
|
||||
|
||||
## API
|
||||
|
||||
`@electron/notarize` exposes a single `notarize` function that accepts the following parameters:
|
||||
* `appPath` — the absolute path to your codesigned and packaged Electron application.
|
||||
* `notarytoolPath` - String (optional) - Path of the notarytool binary ([more details](#notarization-on-older-macos-versions))
|
||||
* additional options required for authenticating your Apple ID (see below)
|
||||
|
||||
The method returns a void Promise once app notarization is complete. Please note that notarization may take
|
||||
many minutes.
|
||||
|
||||
If the notarization process is unusually log for your application, see Apple Developer's docs to
|
||||
[Avoid long notarization response times and size limits](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow#3561440).
|
||||
|
||||
### Usage with app-specific password
|
||||
|
||||
You can generate an [app-specific password](https://support.apple.com/en-us/102654) for your Apple ID
|
||||
to notarize your Electron applications.
|
||||
|
||||
This method also requires you to specify the [Team ID](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id/)
|
||||
of the Developer Team you want to notarize under. An Apple ID may be part of multiple Teams.
|
||||
|
||||
```javascript
|
||||
import { notarize } from '@electron/notarize';
|
||||
|
||||
await notarize({
|
||||
appPath,
|
||||
appleId, // Login name of your Apple Developer account
|
||||
appleIdPassword, // App-specific password
|
||||
teamId, // Team ID for your developer team
|
||||
});
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Never hard code your app-specific password into your packaging scripts.** Use an environment
|
||||
> variable at a minimum.
|
||||
|
||||
### Usage with App Store Connect API key
|
||||
|
||||
Alternatively, you can also authenticate via JSON Web Token (JWT) with App Store Connect.
|
||||
|
||||
You can obtain an API key from [App Store Connect](https://appstoreconnect.apple.com/access/integrations/api).
|
||||
Create a **Team Key** (not an _Individual Key_) with **App Manager** access.
|
||||
|
||||
Note down the Issuer ID (UUID format) and Key ID (10-character alphanumeric string),
|
||||
and download the `.p8` API key file (`AuthKey_<appleApiKeyId>.p8`).
|
||||
For security purposes, the private key can only be downloaded once.
|
||||
|
||||
Provide the absolute path to your API key as the `appleApiKey` argument.
|
||||
|
||||
```javascript
|
||||
import { notarize } from '@electron/notarize';
|
||||
|
||||
await notarize({
|
||||
appPath,
|
||||
appleApiKey, // Absolute path to API key (e.g. `/path/to/AuthKey_X0X0X0X0X0.p8`)
|
||||
appleApiIssuer, // Issuer ID (e.g. `d5631714-a680-4b4b-8156-b4ed624c0845`)
|
||||
});
|
||||
```
|
||||
|
||||
### Usage with Keychain credentials
|
||||
|
||||
As an alternative to passing authentication options, you can also store your authentication
|
||||
credentials (for both API key and app-specific password strategies) in the macOS Keychain
|
||||
via the `xcrun notarytool` command-line utility.
|
||||
|
||||
This method has the advantage of validating your notarization credentials before submitting
|
||||
your application for notarization.
|
||||
|
||||
For example:
|
||||
|
||||
```sh
|
||||
# App-specific password strategy
|
||||
xcrun notarytool store-credentials "my-app-password-profile"
|
||||
--apple-id "<AppleID>"
|
||||
--team-id <DeveloperTeamID>
|
||||
--password <app_specific_password>
|
||||
```
|
||||
|
||||
```sh
|
||||
# App Store Connect API key strategy
|
||||
xcrun notarytool store-credentials "my-api-key-profile"
|
||||
--key "<PathToAPIKey>"
|
||||
--key-id <KeyID>
|
||||
--issuer <IssuerID>
|
||||
```
|
||||
|
||||
Successful storage of your credentials will look like this:
|
||||
|
||||
```
|
||||
This process stores your credentials securely in the Keychain. You reference these credentials later using a profile name.
|
||||
|
||||
Validating your credentials...
|
||||
Success. Credentials validated.
|
||||
Credentials saved to Keychain.
|
||||
To use them, specify `--keychain-profile "my-api-key-profile"`
|
||||
```
|
||||
|
||||
After successfully storing your credentials, pass the keychain profile name into
|
||||
the `keychainProfile` parameter.
|
||||
|
||||
```javascript
|
||||
import { notarize } from '@electron/notarize';
|
||||
|
||||
await notarize({
|
||||
appPath,
|
||||
keychainProfile,
|
||||
});
|
||||
```
|
||||
## Troubleshooting
|
||||
|
||||
### Debug logging
|
||||
|
||||
[`debug`](https://www.npmjs.com/package/debug) is used to display logs and messages.
|
||||
Run your notarization scripts with the `DEBUG=electron-notarize*` environment variable to log additional
|
||||
debug information from this module.
|
||||
|
||||
### Validating credentials
|
||||
|
||||
When notarizing your application, you may run into issues with validating your notarization
|
||||
credentials.
|
||||
|
||||
```
|
||||
Error: HTTP status code: 401. Invalid credentials. Username or password is incorrect.
|
||||
Use the app-specific password generated at appleid.apple.com. Ensure that all authentication arguments are correct.
|
||||
```
|
||||
|
||||
[Storing your credentials in Keychain](#usage-with-keychain-credentials) will validate your credentials before
|
||||
even GitHub.
|
||||
|
||||
### Validating app notarization
|
||||
|
||||
To validate that notarization worked, you can use the `stapler` command-line utility:
|
||||
|
||||
```sh
|
||||
stapler validate path/to/notarized.app
|
||||
```
|
||||
|
||||
### Apple documentation
|
||||
|
||||
Apple also provides additional debugging documentation on
|
||||
[Resolving common notarization issues](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues).
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
import { NotaryToolNotarizeAppOptions } from './types';
|
||||
export declare function checkSignatures(opts: NotaryToolNotarizeAppOptions): Promise<void>;
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.checkSignatures = void 0;
|
||||
const path = __importStar(require("path"));
|
||||
const spawn_1 = require("./spawn");
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const d = (0, debug_1.default)('electron-notarize');
|
||||
const codesignDisplay = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const result = yield (0, spawn_1.spawn)('codesign', ['-dv', '-vvvv', '--deep', path.basename(opts.appPath)], {
|
||||
cwd: path.dirname(opts.appPath),
|
||||
});
|
||||
return result;
|
||||
});
|
||||
const codesign = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
d('attempting to check codesign of app:', opts.appPath);
|
||||
const result = yield (0, spawn_1.spawn)('codesign', ['-vvv', '--deep', '--strict', path.basename(opts.appPath)], {
|
||||
cwd: path.dirname(opts.appPath),
|
||||
});
|
||||
return result;
|
||||
});
|
||||
function checkSignatures(opts) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const fileExt = path.extname(opts.appPath);
|
||||
if (fileExt === '.dmg' || fileExt === '.pkg') {
|
||||
d('skipping codesign check for dmg or pkg file');
|
||||
return;
|
||||
}
|
||||
const [codesignResult, codesignInfo] = yield Promise.all([codesign(opts), codesignDisplay(opts)]);
|
||||
let error = '';
|
||||
if (codesignInfo.code !== 0) {
|
||||
d('codesignInfo failed');
|
||||
error = `Failed to display codesign info on your application with code: ${codesignInfo.code}\n\n${codesignInfo.output}\n`;
|
||||
}
|
||||
if (codesignResult.code !== 0) {
|
||||
d('codesign check failed');
|
||||
error += `Failed to codesign your application with code: ${codesignResult.code}\n\n${codesignResult.output}\n\n${codesignInfo.output}`;
|
||||
}
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
d('codesign assess succeeded');
|
||||
});
|
||||
}
|
||||
exports.checkSignatures = checkSignatures;
|
||||
//# sourceMappingURL=check-signature.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"check-signature.js","sourceRoot":"","sources":["../src/check-signature.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,mCAAgC;AAEhC,kDAA0B;AAC1B,MAAM,CAAC,GAAG,IAAA,eAAK,EAAC,mBAAmB,CAAC,CAAC;AAErC,MAAM,eAAe,GAAG,CAAO,IAAkC,EAAE,EAAE;IACnE,MAAM,MAAM,GAAG,MAAM,IAAA,aAAK,EAAC,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;QAC9F,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;KAChC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAA,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAO,IAAkC,EAAE,EAAE;IAC5D,CAAC,CAAC,sCAAsC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,IAAA,aAAK,EACxB,UAAU,EACV,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAC3D;QACE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;KAChC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC,CAAA,CAAC;AACF,SAAsB,eAAe,CAAC,IAAkC;;QACtE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,MAAM,EAAE;YAC5C,CAAC,CAAC,6CAA6C,CAAC,CAAC;YACjD,OAAO;SACR;QACD,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClG,IAAI,KAAK,GAAG,EAAE,CAAC;QAEf,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,EAAE;YAC3B,CAAC,CAAC,qBAAqB,CAAC,CAAC;YACzB,KAAK,GAAG,kEAAkE,YAAY,CAAC,IAAI,OAAO,YAAY,CAAC,MAAM,IAAI,CAAC;SAC3H;QACD,IAAI,cAAc,CAAC,IAAI,KAAK,CAAC,EAAE;YAC7B,CAAC,CAAC,uBAAuB,CAAC,CAAC;YAC3B,KAAK,IAAI,kDAAkD,cAAc,CAAC,IAAI,OAAO,cAAc,CAAC,MAAM,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC;SACxI;QAED,IAAI,KAAK,EAAE;YACT,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;SACxB;QACD,CAAC,CAAC,2BAA2B,CAAC,CAAC;IACjC,CAAC;CAAA;AAtBD,0CAsBC"}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
export declare function withTempDir<T>(fn: (dir: string) => Promise<T>): Promise<T>;
|
||||
export declare function makeSecret(s: string): string;
|
||||
export declare function isSecret(s: string): boolean;
|
||||
export interface NotarizationInfo {
|
||||
uuid: string;
|
||||
date: Date;
|
||||
status: 'invalid' | 'in progress' | 'success';
|
||||
logFileUrl: string | null;
|
||||
statusCode?: 0 | 2;
|
||||
statusMessage?: string;
|
||||
}
|
||||
export declare function parseNotarizationInfo(info: string): NotarizationInfo;
|
||||
export declare function delay(ms: number): Promise<void>;
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.delay = exports.parseNotarizationInfo = exports.isSecret = exports.makeSecret = exports.withTempDir = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const fs = __importStar(require("fs-extra"));
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const d = (0, debug_1.default)('electron-notarize:helpers');
|
||||
function withTempDir(fn) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const dir = yield fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-notarize-'));
|
||||
d('doing work inside temp dir:', dir);
|
||||
let result;
|
||||
try {
|
||||
result = yield fn(dir);
|
||||
}
|
||||
catch (err) {
|
||||
d('work failed');
|
||||
yield fs.remove(dir);
|
||||
throw err;
|
||||
}
|
||||
d('work succeeded');
|
||||
yield fs.remove(dir);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.withTempDir = withTempDir;
|
||||
class Secret {
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
}
|
||||
toString() {
|
||||
return this.value;
|
||||
}
|
||||
inspect() {
|
||||
return '******';
|
||||
}
|
||||
}
|
||||
function makeSecret(s) {
|
||||
return new Secret(s);
|
||||
}
|
||||
exports.makeSecret = makeSecret;
|
||||
function isSecret(s) {
|
||||
return s instanceof Secret;
|
||||
}
|
||||
exports.isSecret = isSecret;
|
||||
function parseNotarizationInfo(info) {
|
||||
const out = {};
|
||||
const matchToProperty = (key, r, modifier) => {
|
||||
const exec = r.exec(info);
|
||||
if (exec) {
|
||||
out[key] = modifier ? modifier(exec[1]) : exec[1];
|
||||
}
|
||||
};
|
||||
matchToProperty('uuid', /\n *RequestUUID: (.+?)\n/);
|
||||
matchToProperty('date', /\n *Date: (.+?)\n/, d => new Date(d));
|
||||
matchToProperty('status', /\n *Status: (.+?)\n/);
|
||||
matchToProperty('logFileUrl', /\n *LogFileURL: (.+?)\n/);
|
||||
matchToProperty('statusCode', /\n *Status Code: (.+?)\n/, n => parseInt(n, 10));
|
||||
matchToProperty('statusMessage', /\n *Status Message: (.+?)\n/);
|
||||
if (out.logFileUrl === '(null)') {
|
||||
out.logFileUrl = null;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
exports.parseNotarizationInfo = parseNotarizationInfo;
|
||||
function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
exports.delay = delay;
|
||||
//# sourceMappingURL=helpers.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA0B;AAC1B,6CAA+B;AAC/B,uCAAyB;AACzB,2CAA6B;AAE7B,MAAM,CAAC,GAAG,IAAA,eAAK,EAAC,2BAA2B,CAAC,CAAC;AAE7C,SAAsB,WAAW,CAAI,EAA+B;;QAClE,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAC9E,CAAC,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,MAAS,CAAC;QACd,IAAI;YACF,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;SACxB;QAAC,OAAO,GAAG,EAAE;YACZ,CAAC,CAAC,aAAa,CAAC,CAAC;YACjB,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrB,MAAM,GAAG,CAAC;SACX;QACD,CAAC,CAAC,gBAAgB,CAAC,CAAC;QACpB,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,OAAO,MAAM,CAAC;IAChB,CAAC;CAAA;AAdD,kCAcC;AAED,MAAM,MAAM;IACV,YAAoB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAErC,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,OAAO;QACL,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAED,SAAgB,UAAU,CAAC,CAAS;IAClC,OAAQ,IAAI,MAAM,CAAC,CAAC,CAAmB,CAAC;AAC1C,CAAC;AAFD,gCAEC;AAED,SAAgB,QAAQ,CAAC,CAAS;IAChC,OAAQ,CAAS,YAAY,MAAM,CAAC;AACtC,CAAC;AAFD,4BAEC;AAYD,SAAgB,qBAAqB,CAAC,IAAY;IAChD,MAAM,GAAG,GAAG,EAAS,CAAC;IACtB,MAAM,eAAe,GAAG,CACtB,GAAM,EACN,CAAS,EACT,QAA6C,EAC7C,EAAE;QACF,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,EAAE;YACR,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACnD;IACH,CAAC,CAAC;IACF,eAAe,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IACpD,eAAe,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,eAAe,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;IACjD,eAAe,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;IACzD,eAAe,CAAC,YAAY,EAAE,0BAA0B,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAQ,CAAC,CAAC;IACvF,eAAe,CAAC,eAAe,EAAE,6BAA6B,CAAC,CAAC;IAEhE,IAAI,GAAG,CAAC,UAAU,KAAK,QAAQ,EAAE;QAC/B,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;KACvB;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAxBD,sDAwBC;AAED,SAAgB,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAFD,sBAEC"}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
import { NotarizeOptions, NotarizeOptionsLegacy, NotarizeOptionsNotaryTool } from './types';
|
||||
export { NotarizeOptions };
|
||||
export { validateNotaryToolAuthorizationArgs as validateAuthorizationArgs } from './validate-args';
|
||||
/**
|
||||
* Sends your app to Apple for notarization with `notarytool` and staples a successful
|
||||
* notarization result to the app bundle. This includes your {@link NotaryToolNotarizeAppOptions.appPath | appPath}
|
||||
* as well as one of three valid credential authentication strategies.
|
||||
*
|
||||
* See {@link NotaryToolCredentials} for authentication options.
|
||||
*
|
||||
* @category Core
|
||||
* @param args Options for notarization
|
||||
* @returns The Promise resolves once notarization is complete. Note that this may take a few minutes.
|
||||
*/
|
||||
declare function notarize(args: NotarizeOptionsNotaryTool): Promise<void>;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
declare function notarize(args: NotarizeOptionsLegacy): Promise<void>;
|
||||
export { notarize };
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.notarize = exports.validateAuthorizationArgs = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const promise_retry_1 = __importDefault(require("promise-retry"));
|
||||
const check_signature_1 = require("./check-signature");
|
||||
const notarytool_1 = require("./notarytool");
|
||||
const staple_1 = require("./staple");
|
||||
const d = (0, debug_1.default)('electron-notarize');
|
||||
var validate_args_1 = require("./validate-args");
|
||||
Object.defineProperty(exports, "validateAuthorizationArgs", { enumerable: true, get: function () { return validate_args_1.validateNotaryToolAuthorizationArgs; } });
|
||||
function notarize(_a) {
|
||||
var { appPath } = _a, otherOptions = __rest(_a, ["appPath"]);
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (otherOptions.tool === 'legacy') {
|
||||
throw new Error('Notarization with the legacy altool system was decommisioned as of November 2023');
|
||||
}
|
||||
yield (0, check_signature_1.checkSignatures)({ appPath });
|
||||
d('notarizing using notarytool');
|
||||
if (!(yield (0, notarytool_1.isNotaryToolAvailable)())) {
|
||||
throw new Error('notarytool is not available, you must be on at least Xcode 13 or provide notarytoolPath');
|
||||
}
|
||||
yield (0, notarytool_1.notarizeAndWaitForNotaryTool)(Object.assign({ appPath }, otherOptions));
|
||||
yield (0, promise_retry_1.default)(() => (0, staple_1.stapleApp)({ appPath }), {
|
||||
retries: 3,
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.notarize = notarize;
|
||||
//# sourceMappingURL=index.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA0B;AAC1B,kEAAkC;AAElC,uDAAoD;AACpD,6CAAmF;AACnF,qCAAqC;AAQrC,MAAM,CAAC,GAAG,IAAA,eAAK,EAAC,mBAAmB,CAAC,CAAC;AAIrC,iDAAmG;AAA1F,0HAAA,mCAAmC,OAA6B;AAmBzE,SAAe,QAAQ,CAAC,EAA6C;QAA7C,EAAE,OAAO,OAAoC,EAA/B,YAAY,cAA1B,WAA4B,CAAF;;QAChD,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE;YAClC,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;SACH;QAED,MAAM,IAAA,iCAAe,EAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnC,CAAC,CAAC,6BAA6B,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,MAAM,IAAA,kCAAqB,GAAE,CAAC,EAAE;YACpC,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;SACH;QAED,MAAM,IAAA,yCAA4B,EAAC,gBACjC,OAAO,IACJ,YAAY,CACU,CAAC,CAAC;QAE7B,MAAM,IAAA,uBAAK,EAAC,GAAG,EAAE,CAAC,IAAA,kBAAS,EAAC,EAAE,OAAO,EAAE,CAAC,EAAE;YACxC,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;;CACJ;AAEQ,4BAAQ"}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { LegacyNotarizeStartOptions, LegacyNotarizeWaitOptions } from './types';
|
||||
/** @deprecated */
|
||||
export declare function startLegacyNotarize(opts: LegacyNotarizeStartOptions): Promise<never>;
|
||||
/** @deprecated */
|
||||
export declare function waitForLegacyNotarize(opts: LegacyNotarizeWaitOptions): Promise<never>;
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.waitForLegacyNotarize = exports.startLegacyNotarize = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const d = (0, debug_1.default)('electron-notarize:legacy');
|
||||
/** @deprecated */
|
||||
function startLegacyNotarize(opts) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
d('starting notarize process for app:', opts.appPath);
|
||||
throw new Error('Cannot start notarization. Legacy notarization (altool) is no longer available');
|
||||
});
|
||||
}
|
||||
exports.startLegacyNotarize = startLegacyNotarize;
|
||||
/** @deprecated */
|
||||
function waitForLegacyNotarize(opts) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
throw new Error('Cannot wait for notarization. Legacy notarization (altool) is no longer available');
|
||||
});
|
||||
}
|
||||
exports.waitForLegacyNotarize = waitForLegacyNotarize;
|
||||
//# sourceMappingURL=legacy.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../src/legacy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,kDAA0B;AAI1B,MAAM,CAAC,GAAG,IAAA,eAAK,EAAC,0BAA0B,CAAC,CAAC;AAE5C,kBAAkB;AAClB,SAAsB,mBAAmB,CAAC,IAAgC;;QACxE,CAAC,CAAC,oCAAoC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;CAAA;AAHD,kDAGC;AAED,kBAAkB;AAClB,SAAsB,qBAAqB,CAAC,IAA+B;;QACzE,MAAM,IAAI,KAAK,CACb,mFAAmF,CACpF,CAAC;IACJ,CAAC;CAAA;AAJD,sDAIC"}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
import { NotaryToolStartOptions } from './types';
|
||||
export declare function isNotaryToolAvailable(notarytoolPath?: string): Promise<boolean>;
|
||||
export declare function notarizeAndWaitForNotaryTool(opts: NotaryToolStartOptions): Promise<void>;
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.notarizeAndWaitForNotaryTool = exports.isNotaryToolAvailable = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const path = __importStar(require("path"));
|
||||
const spawn_1 = require("./spawn");
|
||||
const helpers_1 = require("./helpers");
|
||||
const validate_args_1 = require("./validate-args");
|
||||
const d = (0, debug_1.default)('electron-notarize:notarytool');
|
||||
function runNotaryTool(args, notarytoolPath) {
|
||||
const useXcrun = notarytoolPath === undefined;
|
||||
const cmd = useXcrun ? 'xcrun' : notarytoolPath;
|
||||
return (0, spawn_1.spawn)(cmd, useXcrun ? ['notarytool', ...args] : args);
|
||||
}
|
||||
function authorizationArgs(rawOpts) {
|
||||
const opts = (0, validate_args_1.validateNotaryToolAuthorizationArgs)(rawOpts);
|
||||
if ((0, validate_args_1.isNotaryToolPasswordCredentials)(opts)) {
|
||||
return [
|
||||
'--apple-id',
|
||||
(0, helpers_1.makeSecret)(opts.appleId),
|
||||
'--password',
|
||||
(0, helpers_1.makeSecret)(opts.appleIdPassword),
|
||||
'--team-id',
|
||||
(0, helpers_1.makeSecret)(opts.teamId),
|
||||
];
|
||||
}
|
||||
else if ((0, validate_args_1.isNotaryToolApiKeyCredentials)(opts)) {
|
||||
return [
|
||||
'--key',
|
||||
(0, helpers_1.makeSecret)(opts.appleApiKey),
|
||||
'--key-id',
|
||||
(0, helpers_1.makeSecret)(opts.appleApiKeyId),
|
||||
'--issuer',
|
||||
(0, helpers_1.makeSecret)(opts.appleApiIssuer),
|
||||
];
|
||||
}
|
||||
else {
|
||||
// --keychain is optional -- when not specified, the iCloud keychain is used by notarytool
|
||||
if (opts.keychain) {
|
||||
return ['--keychain', opts.keychain, '--keychain-profile', opts.keychainProfile];
|
||||
}
|
||||
return ['--keychain-profile', opts.keychainProfile];
|
||||
}
|
||||
}
|
||||
function getNotarizationLogs(opts, id) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const logResult = yield runNotaryTool(['log', id, ...authorizationArgs(opts)], opts.notarytoolPath);
|
||||
d('notarization log', logResult.output);
|
||||
return logResult.output;
|
||||
}
|
||||
catch (e) {
|
||||
d('failed to pull notarization logs', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
function isNotaryToolAvailable(notarytoolPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (notarytoolPath !== undefined) {
|
||||
const result = yield (0, spawn_1.spawn)(notarytoolPath, ['--version']);
|
||||
return result.code === 0;
|
||||
}
|
||||
else {
|
||||
const result = yield (0, spawn_1.spawn)('xcrun', ['--find', 'notarytool']);
|
||||
return result.code === 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.isNotaryToolAvailable = isNotaryToolAvailable;
|
||||
function notarizeAndWaitForNotaryTool(opts) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
d('starting notarize process for app:', opts.appPath);
|
||||
return yield (0, helpers_1.withTempDir)((dir) => __awaiter(this, void 0, void 0, function* () {
|
||||
const fileExt = path.extname(opts.appPath);
|
||||
let filePath;
|
||||
if (fileExt === '.dmg' || fileExt === '.pkg') {
|
||||
filePath = path.resolve(dir, opts.appPath);
|
||||
d('attempting to upload file to Apple: ', filePath);
|
||||
}
|
||||
else {
|
||||
filePath = path.resolve(dir, `${path.parse(opts.appPath).name}.zip`);
|
||||
d('zipping application to:', filePath);
|
||||
const zipResult = yield (0, spawn_1.spawn)('ditto', ['-c', '-k', '--sequesterRsrc', '--keepParent', path.basename(opts.appPath), filePath], {
|
||||
cwd: path.dirname(opts.appPath),
|
||||
});
|
||||
if (zipResult.code !== 0) {
|
||||
throw new Error(`Failed to zip application, exited with code: ${zipResult.code}\n\n${zipResult.output}`);
|
||||
}
|
||||
d('zip succeeded, attempting to upload to Apple');
|
||||
}
|
||||
const notarizeArgs = [
|
||||
'submit',
|
||||
filePath,
|
||||
...authorizationArgs(opts),
|
||||
'--wait',
|
||||
'--output-format',
|
||||
'json',
|
||||
];
|
||||
const result = yield runNotaryTool(notarizeArgs, opts.notarytoolPath);
|
||||
const rawOut = result.output.trim();
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(rawOut);
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`Failed to notarize via notarytool. Failed with unexpected result: \n\n${rawOut}`);
|
||||
}
|
||||
let logOutput;
|
||||
if (typeof parsed.id === 'string') {
|
||||
logOutput = yield getNotarizationLogs(opts, parsed.id);
|
||||
}
|
||||
if (result.code === 0 && parsed.status === 'Accepted') {
|
||||
d(`notarization success (id: ${parsed.id})`);
|
||||
return;
|
||||
}
|
||||
let message = `Failed to notarize via notarytool\n\n${result.output}`;
|
||||
if (logOutput) {
|
||||
message += `\n\nDiagnostics from notarytool log: ${logOutput}`;
|
||||
}
|
||||
throw new Error(message);
|
||||
}));
|
||||
});
|
||||
}
|
||||
exports.notarizeAndWaitForNotaryTool = notarizeAndWaitForNotaryTool;
|
||||
//# sourceMappingURL=notarytool.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"notarytool.js","sourceRoot":"","sources":["../src/notarytool.ts"],"names":[],"mappings":"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"}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
import { SpawnOptions } from 'child_process';
|
||||
export interface SpawnResult {
|
||||
code: number | null;
|
||||
output: string;
|
||||
}
|
||||
export declare const spawn: (cmd: string, args?: string[], opts?: SpawnOptions) => Promise<SpawnResult>;
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.spawn = void 0;
|
||||
const child_process_1 = require("child_process");
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const helpers_1 = require("./helpers");
|
||||
const d = (0, debug_1.default)('electron-notarize:spawn');
|
||||
const spawn = (cmd, args = [], opts = {}) => {
|
||||
d('spawning cmd:', cmd, 'args:', args.map(arg => ((0, helpers_1.isSecret)(arg) ? '*********' : arg)), 'opts:', opts);
|
||||
const child = (0, child_process_1.spawn)(cmd, args, opts);
|
||||
const out = [];
|
||||
const dataHandler = (data) => out.push(data.toString());
|
||||
child.stdout.on('data', dataHandler);
|
||||
child.stderr.on('data', dataHandler);
|
||||
return new Promise((resolve, reject) => {
|
||||
child.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
child.on('exit', code => {
|
||||
d(`cmd ${cmd} terminated with code: ${code}`);
|
||||
resolve({
|
||||
code,
|
||||
output: out.join(''),
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.spawn = spawn;
|
||||
//# sourceMappingURL=spawn.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":";;;;;;AAAA,iDAA+D;AAC/D,kDAA0B;AAC1B,uCAAqC;AAErC,MAAM,CAAC,GAAG,IAAA,eAAK,EAAC,yBAAyB,CAAC,CAAC;AAOpC,MAAM,KAAK,GAAG,CACnB,GAAW,EACX,OAAiB,EAAE,EACnB,OAAqB,EAAE,EACD,EAAE;IACxB,CAAC,CACC,eAAe,EACf,GAAG,EACH,OAAO,EACP,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAA,kBAAQ,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACpD,OAAO,EACP,IAAI,CACL,CAAC;IACF,MAAM,KAAK,GAAG,IAAA,qBAAO,EAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChE,KAAK,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,KAAK,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAClD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;YACtB,CAAC,CAAC,OAAO,GAAG,0BAA0B,IAAI,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC;gBACN,IAAI;gBACJ,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;aACrB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AA9BW,QAAA,KAAK,SA8BhB"}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
import { NotaryToolNotarizeAppOptions } from './types';
|
||||
export declare function stapleApp(opts: NotaryToolNotarizeAppOptions): Promise<void>;
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.stapleApp = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const path = __importStar(require("path"));
|
||||
const spawn_1 = require("./spawn");
|
||||
const d = (0, debug_1.default)('electron-notarize:staple');
|
||||
function stapleApp(opts) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
d('attempting to staple app:', opts.appPath);
|
||||
const result = yield (0, spawn_1.spawn)('xcrun', ['stapler', 'staple', '-v', path.basename(opts.appPath)], {
|
||||
cwd: path.dirname(opts.appPath),
|
||||
});
|
||||
if (result.code !== 0) {
|
||||
throw new Error(`Failed to staple your application with code: ${result.code}\n\n${result.output}`);
|
||||
}
|
||||
d('staple succeeded');
|
||||
return;
|
||||
});
|
||||
}
|
||||
exports.stapleApp = stapleApp;
|
||||
//# sourceMappingURL=staple.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"staple.js","sourceRoot":"","sources":["../src/staple.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA0B;AAC1B,2CAA6B;AAE7B,mCAAgC;AAGhC,MAAM,CAAC,GAAG,IAAA,eAAK,EAAC,0BAA0B,CAAC,CAAC;AAE5C,SAAsB,SAAS,CAAC,IAAkC;;QAChE,CAAC,CAAC,2BAA2B,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAA,aAAK,EAAC,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;YAC5F,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,gDAAgD,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,MAAM,EAAE,CAClF,CAAC;SACH;QAED,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACtB,OAAO;IACT,CAAC;CAAA;AAdD,8BAcC"}
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
/**
|
||||
* @deprecated This interface was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export interface LegacyNotarizePasswordCredentials {
|
||||
appleId: string;
|
||||
appleIdPassword: string;
|
||||
}
|
||||
/**
|
||||
* You can generate an [app-specific password](https://support.apple.com/en-us/102654) for your Apple ID
|
||||
* to notarize your Electron applications.
|
||||
*
|
||||
* This method also requires you to specify the [Team ID](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id/)
|
||||
* of the Developer Team you want to notarize under. An Apple ID may be part of multiple Teams.
|
||||
*
|
||||
* @category Credential Strategies
|
||||
*/
|
||||
export interface NotaryToolPasswordCredentials {
|
||||
/**
|
||||
* The login username of your Apple Developer account.
|
||||
*/
|
||||
appleId: string;
|
||||
/**
|
||||
* An [app-specific password](https://support.apple.com/en-us/102654) for your
|
||||
* Apple ID (**not** your Apple ID password).
|
||||
*
|
||||
* Do **not** hard code this password into your packaging scripts.
|
||||
*/
|
||||
appleIdPassword: string;
|
||||
/**
|
||||
* The [Team ID](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id/)
|
||||
* for the Developer Team you want to notarize under. Your Apple ID may be a member of multiple
|
||||
* teams.
|
||||
*/
|
||||
teamId: string;
|
||||
}
|
||||
/**
|
||||
* @deprecated This interface was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export interface LegacyNotarizeApiKeyCredentials {
|
||||
appleApiKey: string;
|
||||
appleApiIssuer: string;
|
||||
}
|
||||
/**
|
||||
* Credentials required for JSON Web Token (JWT) notarization using App Store Connect API keys.
|
||||
*
|
||||
* @category Credential Strategies
|
||||
*/
|
||||
export interface NotaryToolApiKeyCredentials {
|
||||
/**
|
||||
* File system path to the `.p8` private key of your App Store Connect API key.
|
||||
*/
|
||||
appleApiKey: string;
|
||||
/**
|
||||
* App Store Connect API Key ID (e.g. `T9GPZ92M7K`).
|
||||
*
|
||||
*/
|
||||
appleApiKeyId: string;
|
||||
/**
|
||||
* App Store Connect API Issuer ID. The issuer ID is a UUID format string
|
||||
* (e.g. `c055ca8c-e5a8-4836-b61d-aa5794eeb3f4`).
|
||||
*/
|
||||
appleApiIssuer: string;
|
||||
}
|
||||
/**
|
||||
* Options required for authenticating notarytool by storing
|
||||
* credentials inside the system Keychain item.
|
||||
*
|
||||
* You can store {@link NotaryToolPasswordCredentials} or
|
||||
* {@link NotaryToolApiKeyCredentials} into the Keychain
|
||||
* using `xcrun notarytool store-credentials` and access the
|
||||
* stored secrets when signing your code.
|
||||
*
|
||||
* @category Credential Strategies
|
||||
*/
|
||||
export interface NotaryToolKeychainCredentials {
|
||||
/**
|
||||
* The name of the profile you provided when storing notarization credentials.
|
||||
*/
|
||||
keychainProfile: string;
|
||||
/**
|
||||
* The name of the keychain or path to the keychain you stored notarization credentials in.
|
||||
* @defaultValue If omitted, the system default `login` keychain will be used.
|
||||
*/
|
||||
keychain?: string;
|
||||
}
|
||||
/**
|
||||
* @deprecated This interface was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export type LegacyNotarizeCredentials = LegacyNotarizePasswordCredentials | LegacyNotarizeApiKeyCredentials;
|
||||
/**
|
||||
* Credential options for authenticating `notarytool`. There are three valid stategies available:
|
||||
*
|
||||
* - {@link NotaryToolPasswordCredentials} — Using an Apple ID and app-specific password
|
||||
* - {@link NotaryToolApiKeyCredentials} — Using an App Store Connect API key
|
||||
* - {@link NotaryToolKeychainCredentials} — Using one of the two above credential sets stored within the macOS Keychain
|
||||
* @category Credential Strategies
|
||||
*/
|
||||
export type NotaryToolCredentials = NotaryToolPasswordCredentials | NotaryToolApiKeyCredentials | NotaryToolKeychainCredentials;
|
||||
/**
|
||||
* @deprecated This interface was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export interface LegacyNotarizeAppOptions {
|
||||
appPath: string;
|
||||
appBundleId: string;
|
||||
}
|
||||
/**
|
||||
* Non-credential options for notarizing your application with `notarytool`.
|
||||
* @category Core
|
||||
*/
|
||||
export interface NotaryToolNotarizeAppOptions {
|
||||
/**
|
||||
* Absolute path to your packaged and codesigned Electron application.
|
||||
*/
|
||||
appPath: string;
|
||||
notarytoolPath?: string;
|
||||
}
|
||||
/**
|
||||
* @deprecated This interface was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
interface TransporterOptions {
|
||||
ascProvider?: string;
|
||||
}
|
||||
/**
|
||||
* @deprecated This interface was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
interface NotarizeResult {
|
||||
uuid: string;
|
||||
}
|
||||
/**
|
||||
* @deprecated This type was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export type LegacyNotarizeStartOptions = LegacyNotarizeAppOptions & LegacyNotarizeCredentials & TransporterOptions;
|
||||
/**
|
||||
* @deprecated This type was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export type LegacyNotarizeWaitOptions = NotarizeResult & LegacyNotarizeCredentials;
|
||||
/**
|
||||
* @deprecated This type was used for Apple's `altool`, which was sunset in 2023 and no longer works.
|
||||
* @category Legacy
|
||||
*/
|
||||
export type NotarizeOptionsLegacy = {
|
||||
tool: 'legacy';
|
||||
} & LegacyNotarizeStartOptions;
|
||||
/**
|
||||
* Options for notarizing your Electron app with `notarytool`.
|
||||
* @category Core
|
||||
*/
|
||||
export type NotaryToolStartOptions = NotaryToolNotarizeAppOptions & NotaryToolCredentials;
|
||||
/**
|
||||
* Helper type that specifies that `@electron/notarize` is using the `notarytool` strategy.
|
||||
* @category Utility Types
|
||||
*/
|
||||
export type NotarizeOptionsNotaryTool = {
|
||||
tool?: 'notarytool';
|
||||
} & NotaryToolStartOptions;
|
||||
/**
|
||||
* Options accepted by the `notarize` method.
|
||||
* @internal
|
||||
*/
|
||||
export type NotarizeOptions = NotarizeOptionsLegacy | NotarizeOptionsNotaryTool;
|
||||
export {};
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=types.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
import { LegacyNotarizeApiKeyCredentials, LegacyNotarizeCredentials, LegacyNotarizePasswordCredentials, NotaryToolApiKeyCredentials, NotaryToolCredentials, NotaryToolKeychainCredentials, NotaryToolPasswordCredentials } from './types';
|
||||
/** @deprecated */
|
||||
export declare function isLegacyPasswordCredentials(opts: LegacyNotarizeCredentials): opts is LegacyNotarizePasswordCredentials;
|
||||
/** @deprecated */
|
||||
export declare function isLegacyApiKeyCredentials(opts: LegacyNotarizeCredentials): opts is LegacyNotarizeApiKeyCredentials;
|
||||
/** @deprecated */
|
||||
export declare function validateLegacyAuthorizationArgs(opts: LegacyNotarizeCredentials): LegacyNotarizeCredentials;
|
||||
export declare function isNotaryToolPasswordCredentials(opts: NotaryToolCredentials): opts is NotaryToolPasswordCredentials;
|
||||
export declare function isNotaryToolApiKeyCredentials(opts: NotaryToolCredentials): opts is NotaryToolApiKeyCredentials;
|
||||
export declare function isNotaryToolKeychainCredentials(opts: NotaryToolCredentials): opts is NotaryToolKeychainCredentials;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export declare function validateNotaryToolAuthorizationArgs(opts: NotaryToolCredentials): NotaryToolCredentials;
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.validateNotaryToolAuthorizationArgs = exports.isNotaryToolKeychainCredentials = exports.isNotaryToolApiKeyCredentials = exports.isNotaryToolPasswordCredentials = exports.validateLegacyAuthorizationArgs = exports.isLegacyApiKeyCredentials = exports.isLegacyPasswordCredentials = void 0;
|
||||
/** @deprecated */
|
||||
function isLegacyPasswordCredentials(opts) {
|
||||
const creds = opts;
|
||||
return creds.appleId !== undefined || creds.appleIdPassword !== undefined;
|
||||
}
|
||||
exports.isLegacyPasswordCredentials = isLegacyPasswordCredentials;
|
||||
/** @deprecated */
|
||||
function isLegacyApiKeyCredentials(opts) {
|
||||
const creds = opts;
|
||||
return creds.appleApiKey !== undefined || creds.appleApiIssuer !== undefined;
|
||||
}
|
||||
exports.isLegacyApiKeyCredentials = isLegacyApiKeyCredentials;
|
||||
/** @deprecated */
|
||||
function validateLegacyAuthorizationArgs(opts) {
|
||||
const isPassword = isLegacyPasswordCredentials(opts);
|
||||
const isApiKey = isLegacyApiKeyCredentials(opts);
|
||||
if (isPassword && isApiKey) {
|
||||
throw new Error('Cannot use both password credentials and API key credentials at once');
|
||||
}
|
||||
if (isPassword) {
|
||||
const passwordCreds = opts;
|
||||
if (!passwordCreds.appleId) {
|
||||
throw new Error('The appleId property is required when using notarization with appleIdPassword');
|
||||
}
|
||||
else if (!passwordCreds.appleIdPassword) {
|
||||
throw new Error('The appleIdPassword property is required when using notarization with appleId');
|
||||
}
|
||||
return passwordCreds;
|
||||
}
|
||||
if (isApiKey) {
|
||||
const apiKeyCreds = opts;
|
||||
if (!apiKeyCreds.appleApiKey) {
|
||||
throw new Error('The appleApiKey property is required when using notarization with appleApiIssuer');
|
||||
}
|
||||
else if (!apiKeyCreds.appleApiIssuer) {
|
||||
throw new Error('The appleApiIssuer property is required when using notarization with appleApiKey');
|
||||
}
|
||||
return apiKeyCreds;
|
||||
}
|
||||
throw new Error('No authentication properties provided (e.g. appleId, appleApiKey)');
|
||||
}
|
||||
exports.validateLegacyAuthorizationArgs = validateLegacyAuthorizationArgs;
|
||||
function isNotaryToolPasswordCredentials(opts) {
|
||||
const creds = opts;
|
||||
return (creds.appleId !== undefined || creds.appleIdPassword !== undefined || creds.teamId !== undefined);
|
||||
}
|
||||
exports.isNotaryToolPasswordCredentials = isNotaryToolPasswordCredentials;
|
||||
function isNotaryToolApiKeyCredentials(opts) {
|
||||
const creds = opts;
|
||||
return (creds.appleApiIssuer !== undefined ||
|
||||
creds.appleApiKey !== undefined ||
|
||||
creds.appleApiKeyId !== undefined);
|
||||
}
|
||||
exports.isNotaryToolApiKeyCredentials = isNotaryToolApiKeyCredentials;
|
||||
function isNotaryToolKeychainCredentials(opts) {
|
||||
const creds = opts;
|
||||
return creds.keychain !== undefined || creds.keychainProfile !== undefined;
|
||||
}
|
||||
exports.isNotaryToolKeychainCredentials = isNotaryToolKeychainCredentials;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function validateNotaryToolAuthorizationArgs(opts) {
|
||||
const isPassword = isNotaryToolPasswordCredentials(opts);
|
||||
const isApiKey = isNotaryToolApiKeyCredentials(opts);
|
||||
const isKeychain = isNotaryToolKeychainCredentials(opts);
|
||||
if ((isPassword ? 1 : 0) + (isApiKey ? 1 : 0) + (isKeychain ? 1 : 0) > 1) {
|
||||
throw new Error('Cannot use password credentials, API key credentials and keychain credentials at once');
|
||||
}
|
||||
if (isPassword) {
|
||||
const passwordCreds = opts;
|
||||
if (!passwordCreds.appleId) {
|
||||
throw new Error('The appleId property is required when using notarization with password credentials');
|
||||
}
|
||||
else if (!passwordCreds.appleIdPassword) {
|
||||
throw new Error('The appleIdPassword property is required when using notarization with password credentials');
|
||||
}
|
||||
else if (!passwordCreds.teamId) {
|
||||
throw new Error('The teamId property is required when using notarization with password credentials');
|
||||
}
|
||||
return passwordCreds;
|
||||
}
|
||||
if (isApiKey) {
|
||||
const apiKeyCreds = opts;
|
||||
if (!apiKeyCreds.appleApiKey) {
|
||||
throw new Error('The appleApiKey property is required when using notarization with ASC credentials');
|
||||
}
|
||||
else if (!apiKeyCreds.appleApiIssuer) {
|
||||
throw new Error('The appleApiIssuer property is required when using notarization with ASC credentials');
|
||||
}
|
||||
else if (!apiKeyCreds.appleApiKeyId) {
|
||||
throw new Error('The appleApiKeyId property is required when using notarization with ASC credentials');
|
||||
}
|
||||
return apiKeyCreds;
|
||||
}
|
||||
if (isKeychain) {
|
||||
const keychainCreds = opts;
|
||||
if (!keychainCreds.keychainProfile) {
|
||||
throw new Error('The keychainProfile property is required when using notarization with keychain credentials');
|
||||
}
|
||||
return keychainCreds;
|
||||
}
|
||||
throw new Error('No authentication properties provided (e.g. appleId, appleApiKey, keychain)');
|
||||
}
|
||||
exports.validateNotaryToolAuthorizationArgs = validateNotaryToolAuthorizationArgs;
|
||||
//# sourceMappingURL=validate-args.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"validate-args.js","sourceRoot":"","sources":["../src/validate-args.ts"],"names":[],"mappings":"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"}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"name": "@electron/notarize",
|
||||
"version": "2.5.0",
|
||||
"description": "Notarize your Electron app",
|
||||
"main": "lib/index.js",
|
||||
"typings": "lib/index.d.ts",
|
||||
"author": "Samuel Attard",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/electron/notarize#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/electron/notarize.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/electron/notarize/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"lint": "prettier --check \"src/**/*.ts\"",
|
||||
"prepare": "yarn build",
|
||||
"test": "jest"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/debug": "^4.1.5",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/node": "^13.7.7",
|
||||
"@types/promise-retry": "^1.1.3",
|
||||
"jest": "^29.0.0",
|
||||
"prettier": "^1.18.2",
|
||||
"ts-jest": "^29.0.0",
|
||||
"typedoc": "~0.25.13",
|
||||
"typedoc-plugin-missing-exports": "^2.2.0",
|
||||
"typescript": "4.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"promise-retry": "^2.0.1"
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
Copyright (c) Electron contributors
|
||||
Copyright (c) 2015-2016 Zhuo Lu, Jason Hinkle, et al.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-282
@@ -1,282 +0,0 @@
|
||||
# @electron/osx-sign [![npm][npm_img]][npm_url] [![Test][gha_img]][gha_url]
|
||||
|
||||
Codesign Electron macOS apps
|
||||
|
||||
## About
|
||||
|
||||
[`@electron/osx-sign`][electron-osx-sign] minimizes the extra work needed to eventually prepare
|
||||
your apps for shipping, providing options that work out of the box for most applications.
|
||||
Additional configuration is available via its API.
|
||||
|
||||
There are two main functionalities exposed via this package:
|
||||
* Signing macOS apps via `sign` functions. Under the hood, this uses the `codesign` utility.
|
||||
* Creating `.pkg` installer packages via `flat` functions. Under the hood, this uses the `productbuild` utility.
|
||||
|
||||
## Installation
|
||||
|
||||
`@electron/osx-sign` is integrated into other Electron packaging tools, and can be configured accordingly:
|
||||
* [Electron Packager](https://electron.github.io/packager/main/types/OsxSignOptions.html)
|
||||
* [Electron Forge](https://www.electronforge.io/guides/code-signing/code-signing-macos)
|
||||
|
||||
You can also install `@electron/osx-sign` separately if your packaging pipeline does not involve those tools:
|
||||
|
||||
```sh
|
||||
npm install --save-dev @electron/osx-sign
|
||||
```
|
||||
|
||||
## Code signing
|
||||
|
||||
The signing procedure implemented in this package is based on what described in Electron's [Code Signing Guide](https://github.com/electron/electron/blob/main/docs/tutorial/code-signing.md).
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* You must be a registered member of the [Apple Developer Program](https://developer.apple.com/programs/).
|
||||
Please note that you could be charged by Apple in order to get issued with the required certificates.
|
||||
* You must have [Xcode](https://developer.apple.com/xcode/) installed from the
|
||||
[Mac App Store](https://apps.apple.com/us/app/xcode/id497799835). It is not recommended to download your
|
||||
copy from other 3rd party sources for security reasons.
|
||||
* You must have Xcode Command Line Tools installed. To check whether it is available,
|
||||
try `xcode-select --install` and follow the instructions.
|
||||
* To distribute your app on the Mac App Store, You must create a Mac App on [App Store Connect](https://appstoreconnect.apple.com/).
|
||||
* You must give your app a unique Bundle ID.
|
||||
* You must give your app a version number.
|
||||
|
||||
### Certificates
|
||||
|
||||
In order to distribute your application either inside or outside the Mac App Store,
|
||||
you will have to have the following certificates from Apple after becoming a registered developer.
|
||||
|
||||
Certificates can be created through the
|
||||
[Certificates, Identities & Profiles](https://developer.apple.com/account/resources/certificates/add)
|
||||
page in the Apple Developer website or via [Account Preferences in Xcode](https://help.apple.com/xcode/mac/current/#/dev3a05256b8).
|
||||
|
||||
For distribution inside the Mac App Store, you will need to create:
|
||||
* Mac App Distribution: `3rd Party Mac Developer Application: * (*)`
|
||||
* Mac Installer Distribution: `3rd Party Mac Developer Installer: * (*)`
|
||||
|
||||
For distribution outside the Mac App Store:
|
||||
* Developer ID Application: `Developer ID Application: * (*)`
|
||||
* Developer ID Installer: `Developer ID Installer: * (*)`
|
||||
|
||||
After you create the necessary certifications, download them and open each so that they are
|
||||
installed in your keychain. We recommend installing them in your system default keychain so
|
||||
that `@electron/osx-sign` can detect them automatically.
|
||||
|
||||
**Note:** They appear to come in pairs. It is preferred to have every one of them installed so not to
|
||||
are about which is not yet installed for future works. However, if you may only want to distribute
|
||||
outside the Mac App Store, there is no need to have the 3rd Party Mac Developer ones installed and vice versa.
|
||||
|
||||
### API
|
||||
|
||||
```javascript
|
||||
const { signAsync } = require('@electron/osx-sign')
|
||||
const opts = {
|
||||
app: 'path/to/my.app'
|
||||
};
|
||||
signAsync(opts)
|
||||
.then(function () {
|
||||
// Application signed
|
||||
})
|
||||
.catch(function (err) {
|
||||
// Handle the error
|
||||
})
|
||||
```
|
||||
|
||||
The only mandatory option for `signAsync` is a path to your `.app` package.
|
||||
Configuration for most Electron apps should work out of the box.
|
||||
For full configuration options, see the [API documentation].
|
||||
|
||||
### Usage examples
|
||||
|
||||
#### Signing for Mac App Store distribution
|
||||
|
||||
```javascript
|
||||
const { signAsync } = require('@electron/osx-sign')
|
||||
const opts = {
|
||||
app: 'path/to/my.app',
|
||||
// optional parameters for additional customization
|
||||
platform: "mas", // should be auto-detected if your app was packaged for MAS via Packager or Forge
|
||||
type: "distribution", // defaults to "distribution" for submission to App Store Connect
|
||||
provisioningProfile: 'path/to/my.provisionprofile', // defaults to the current working directory
|
||||
keychain: 'my-keychain', // defaults to the system default login keychain
|
||||
};
|
||||
signAsync(opts)
|
||||
.then(function () {
|
||||
// Application signed
|
||||
})
|
||||
.catch(function (err) {
|
||||
// Handle the error
|
||||
})
|
||||
```
|
||||
|
||||
Mac App Store apps require a [Provisioning Profile](https://www.electronjs.org/docs/latest/tutorial/mac-app-store-submission-guide#prepare-provisioning-profile)
|
||||
for submission to App Store Connect. We recommend having the provisioning profile for distribution
|
||||
placed in the current working directory and the signing identity installed in the default keychain.
|
||||
|
||||
The app is not expected to run after codesigning since there is no provisioned device, and it is
|
||||
intended only for submission to App Store Connect. Since `@electron/osx-sign` adds the entry
|
||||
`com.apple.developer.team-identifier` to a temporary copy of the specified entitlements file
|
||||
(with the default option `preAutoEntitlements`), distribution builds can no longer be run directly.
|
||||
|
||||
To run an app codesigned for distribution locally after codesigning, you may manually add
|
||||
`ElectronTeamID` in your `Info.plist` and `com.apple.security.application-groups` in the
|
||||
entitlements file, and set `preAutoEntitlements: false` for `@electron/osx-sign` to avoid
|
||||
this extra bit. Note that "certain features are only allowed across apps whose team-identifier value match"
|
||||
([Technical Note TN2415](https://developer.apple.com/library/content/technotes/tn2415/_index.html#//apple_ref/doc/uid/DTS40016427-CH1-ENTITLEMENTSLIST)).
|
||||
|
||||
Alternatively, set the app's `type` to `development` to codesign a development version of your app,
|
||||
which will allow it to be run on your development provisioned machine. Apps signed for development
|
||||
will not be eligible for submission via App Store Connect.
|
||||
|
||||
#### Signing with `--deep`
|
||||
|
||||
Some subresources that you may include in your Electron app may need to be signed with `--deep`.
|
||||
This is not typically safe to apply to the entire Electron app and therefore should be applied to _just_ your file.
|
||||
|
||||
```javascript
|
||||
signAsync({
|
||||
app: 'path/to/my.app',
|
||||
optionsForFile: (filePath) => {
|
||||
// For our one specific file we can pass extra options to be merged
|
||||
// with the default options
|
||||
if (path.basename(filePath) === 'myStrangeFile.jar') {
|
||||
return {
|
||||
additionalArguments: ['--deep'],
|
||||
};
|
||||
}
|
||||
|
||||
// Just use the default options for everything else
|
||||
return null;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Signing legacy versions of Electron
|
||||
|
||||
`@electron/osx-sign` maintains backwards compatibility with older versions of Electron, but
|
||||
generally assumes that you are on the latest stable version.
|
||||
|
||||
If you are running an older unsupported version of Electron, you should pass in the `version`
|
||||
option as such:
|
||||
|
||||
```javascript
|
||||
signAsync({
|
||||
app: 'path/to/my.app',
|
||||
version: '0.34.0',
|
||||
});
|
||||
```
|
||||
|
||||
## Flat installer packaging
|
||||
|
||||
This module also handles the creation of flat installer packages (`.pkg` installers).
|
||||
|
||||
> [!NOTE]
|
||||
> Modern `.pkg` installers are also named "flat" packages for historical purposes. Prior
|
||||
> to Mac OS X Leopard (10.5), installation packages were organized in hierarchical
|
||||
> directories. OS X Leopard introduced a new flat package format that is used for modern
|
||||
> `.pkg` installers.
|
||||
|
||||
### API usage
|
||||
|
||||
```javascript
|
||||
const { flatAsync } = require('@electron/osx-sign')
|
||||
flatAsync({
|
||||
app: 'path/to/my.app'
|
||||
})
|
||||
.then(function () {
|
||||
// Application flattened
|
||||
})
|
||||
.catch(function (err) {
|
||||
// Handle the error
|
||||
})
|
||||
```
|
||||
|
||||
The only mandatory option for `flatAsync` is a path to your `.app` package.
|
||||
For full configuration options, see the [API documentation].
|
||||
|
||||
## CLI
|
||||
|
||||
`@electron/osx-sign` also exposes a legacy command-line interface (CLI) for both signing
|
||||
and installer generation. However, we recommend using the JavaScript API as it has a more
|
||||
complete API surface (e.g. `optionsForFile` is only available via JS).
|
||||
|
||||
```sh
|
||||
# install the package locally into devDependencies
|
||||
npm install --save-dev @electron/osx-sign
|
||||
|
||||
# Sign a packaged .app bundle
|
||||
npx electron-osx-sign path/to/my.app [options ...]
|
||||
|
||||
# Create a .pkg installer from a packaged .app bundle
|
||||
npx electron-osx-flat path/to/my.app [options ...]
|
||||
```
|
||||
|
||||
For full options, use the `--help` flag for either command.
|
||||
|
||||
|
||||
## Debug
|
||||
|
||||
The [`debug`](https://www.npmjs.com/package/debug) module is used to display advanced logs and messages.
|
||||
If you are having problems with signing your app with `@electron/osx-sign`, run your signing scripts with
|
||||
the `DEBUG=electron-osx-sign*` environment variable.
|
||||
|
||||
## Test
|
||||
|
||||
The project's configured to run automated tests on CircleCI.
|
||||
|
||||
If you wish to manually test the module, first comment out `opts.identity` in `test/basic.js` to enable
|
||||
auto discovery. Then run the command `npm test` from the dev directory.
|
||||
|
||||
When this command is run for the first time: `@electron/get` will download macOS Electron releases defined
|
||||
in `test/config.json`, and save to `~/.electron/`, which might take up less than 1GB of disk space.
|
||||
|
||||
A successful testing should look something like:
|
||||
|
||||
```
|
||||
$ npm test
|
||||
|
||||
> electron-osx-sign@0.4.17 pretest electron-osx-sign
|
||||
> rimraf test/work
|
||||
|
||||
> electron-osx-sign@0.4.17 test electron-osx-sign
|
||||
> standard && tape test
|
||||
|
||||
Calling @electron/get before running tests...
|
||||
Running tests...
|
||||
TAP version 13
|
||||
# setup
|
||||
# defaults-test:v7.0.0-beta.3-darwin-x64
|
||||
ok 1 app signed
|
||||
# defaults-test:v7.0.0-beta.3-mas-x64
|
||||
ok 2 app signed
|
||||
# defaults-test:v6.0.3-darwin-x64
|
||||
ok 3 app signed
|
||||
# defaults-test:v6.0.3-mas-x64
|
||||
ok 4 app signed
|
||||
# defaults-test:v5.0.10-darwin-x64
|
||||
ok 5 app signed
|
||||
# defaults-test:v5.0.10-mas-x64
|
||||
ok 6 app signed
|
||||
# defaults-test:v4.2.9-darwin-x64
|
||||
ok 7 app signed
|
||||
# defaults-test:v4.2.9-mas-x64
|
||||
ok 8 app signed
|
||||
# defaults-test:v3.1.2-darwin-x64
|
||||
ok 9 app signed
|
||||
# defaults-test:v3.1.2-mas-x64
|
||||
ok 10 app signed
|
||||
# teardown
|
||||
|
||||
1..10
|
||||
# tests 10
|
||||
# pass 10
|
||||
|
||||
# ok
|
||||
```
|
||||
|
||||
[Electron]: https://github.com/electron/electron
|
||||
[electron-osx-sign]: https://github.com/electron/osx-sign
|
||||
[npm_img]: https://img.shields.io/npm/v/@electron/osx-sign.svg
|
||||
[npm_url]: https://npmjs.org/package/@electron/osx-sign
|
||||
[gha_img]: https://github.com/electron/osx-sign/actions/workflows/test.yml/badge.svg
|
||||
[gha_url]: https://github.com/electron/osx-sign/actions/workflows/test.yml
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
|
||||
NAME
|
||||
electron-osx-flat -- product building for Electron apps
|
||||
|
||||
SYNOPSIS
|
||||
electron-osx-flat app [options ...]
|
||||
|
||||
DESCRIPTION
|
||||
app
|
||||
Path to the application package.
|
||||
Needs file extension ``.app''.
|
||||
|
||||
--help
|
||||
Flag to display all commands.
|
||||
|
||||
--identity=identity
|
||||
Name of certificate to use when signing.
|
||||
Default to selected with respect to --platform from --keychain specified or keychain by system default.
|
||||
|
||||
--identityValidation, --no-identityValidation
|
||||
Flag to enable/disable validation for the signing identity.
|
||||
|
||||
--install=install-path
|
||||
Path to install the bundle.
|
||||
Default to ``/Applications''.
|
||||
|
||||
--keychain=keychain
|
||||
The keychain name.
|
||||
Default to system default keychain.
|
||||
|
||||
--platform=platform
|
||||
Build platform of Electron.
|
||||
Allowed values: ``darwin'', ``mas''.
|
||||
Default to auto detect from application bundle.
|
||||
|
||||
--pkg
|
||||
Path to the output the flattened package.
|
||||
Needs file extension ``.pkg''.
|
||||
|
||||
--scripts
|
||||
Path to a directory containing pre and/or post install scripts.
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const args = require('minimist')(process.argv.slice(2), {
|
||||
boolean: [
|
||||
'help'
|
||||
]
|
||||
});
|
||||
const usage = fs.readFileSync(path.join(__dirname, 'electron-osx-flat-usage.txt')).toString();
|
||||
const flat = require('../').flat;
|
||||
|
||||
args.app = args._.shift();
|
||||
|
||||
if (!args.app || args.help) {
|
||||
console.log(usage);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Remove excess arguments
|
||||
delete args._;
|
||||
delete args.help;
|
||||
|
||||
flat(args, function done (err) {
|
||||
if (err) {
|
||||
console.error('Flat failed:');
|
||||
if (err.message) console.error(err.message);
|
||||
else if (err.stack) console.error(err.stack);
|
||||
else console.log(err);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('Application flattened, saved to:', args.pkg);
|
||||
process.exit(0);
|
||||
});
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
|
||||
NAME
|
||||
electron-osx-sign -- code signing for Electron apps
|
||||
|
||||
SYNOPSIS
|
||||
electron-osx-sign app [embedded-binary ...] [options ...]
|
||||
|
||||
DESCRIPTION
|
||||
app
|
||||
Path to the application package.
|
||||
Needs file extension ``.app''.
|
||||
|
||||
embedded-binary ...
|
||||
Path to additional binaries that will be signed along with built-ins of Electron, spaced.
|
||||
|
||||
--help
|
||||
Flag to display all commands.
|
||||
|
||||
--identity=identity
|
||||
Name of certificate to use when signing.
|
||||
Default to selected with respect to --provisioning-profile and --platform from --keychain specified or keychain by system default.
|
||||
|
||||
--identityValidation, --no-identityValidation
|
||||
Flag to enable/disable validation for the signing identity.
|
||||
|
||||
--ignore=path
|
||||
Path to skip signing. The string will be treated as a regular expression when used to match the file paths.
|
||||
|
||||
--keychain=keychain
|
||||
The keychain name.
|
||||
Default to system default keychain.
|
||||
|
||||
--platform=platform
|
||||
Build platform of Electron.
|
||||
Allowed values: ``darwin'', ``mas''.
|
||||
Default to auto detect from application bundle.
|
||||
|
||||
--pre-auto-entitlements, --no-pre-auto-entitlements
|
||||
Flag to enable/disable automation of entitlements file and Info.plist.
|
||||
|
||||
--pre-embed-provisioning-profile, --no-pre-embed-provisioning-profile
|
||||
Flag to enable/disable embedding of provisioning profile.
|
||||
|
||||
--provisioning-profile=file
|
||||
Path to provisioning profile.
|
||||
|
||||
--strictVerify, --strictVerify=options, --no-strictVerify
|
||||
Flag to enable/disable ``--strict'' flag when verifying the signed application bundle.
|
||||
Each component should be separated in ``options'' with comma (``,'').
|
||||
Enabled by default.
|
||||
|
||||
--type=type
|
||||
Specify whether to sign app for development or for distribution.
|
||||
Allowed values: ``development'', ``distribution''.
|
||||
Default to ``distribution''.
|
||||
|
||||
--version=version
|
||||
Build version of Electron.
|
||||
Values may be: ``1.2.0''.
|
||||
Default to latest Electron version.
|
||||
Reference in New Issue
Block a user