Update gitignore (sorry)

This commit is contained in:
olcxja 2026-05-10 14:02:17 +02:00
commit cca8b02fea
6604 changed files with 1219661 additions and 4 deletions

View file

@ -0,0 +1,36 @@
import { FileTransformer } from "builder-util/out/fs";
import { AsarIntegrity } from "./asar/integrity";
import { Platform, PlatformPackager, ElectronPlatformName, AfterPackContext } from "./index";
export interface Framework {
readonly name: string;
readonly version: string;
readonly distMacOsAppName: string;
readonly macOsDefaultTargets: Array<string>;
readonly defaultAppIdPrefix: string;
readonly isNpmRebuildRequired: boolean;
readonly isCopyElevateHelper: boolean;
getDefaultIcon?(platform: Platform): string | null;
getMainFile?(platform: Platform): string | null;
getExcludedDependencies?(platform: Platform): Array<string> | null;
prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions): Promise<any>;
beforeCopyExtraFiles?(options: BeforeCopyExtraFilesOptions): Promise<any>;
afterPack?(context: AfterPackContext): Promise<any>;
createTransformer?(): FileTransformer | null;
}
export interface BeforeCopyExtraFilesOptions {
packager: PlatformPackager<any>;
appOutDir: string;
asarIntegrity: AsarIntegrity | null;
platformName: string;
}
export interface PrepareApplicationStageDirectoryOptions {
readonly packager: PlatformPackager<any>;
/**
* Platform doesn't process application output directory in any way. Unpack implementation must create or empty dir if need.
*/
readonly appOutDir: string;
readonly platformName: ElectronPlatformName;
readonly arch: string;
readonly version: string;
}
export declare function isElectronBased(framework: Framework): boolean;

View file

@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isElectronBased = void 0;
function isElectronBased(framework) {
return framework.name === "electron";
}
exports.isElectronBased = isElectronBased;
//# sourceMappingURL=Framework.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"Framework.js","sourceRoot":"","sources":["../src/Framework.ts"],"names":[],"mappings":";;;AAmDA,SAAgB,eAAe,CAAC,SAAoB;IAClD,OAAO,SAAS,CAAC,IAAI,KAAK,UAAU,CAAA;AACtC,CAAC;AAFD,0CAEC","sourcesContent":["import { FileTransformer } from \"builder-util/out/fs\"\nimport { AsarIntegrity } from \"./asar/integrity\"\nimport { Platform, PlatformPackager, ElectronPlatformName, AfterPackContext } from \"./index\"\n\nexport interface Framework {\n readonly name: string\n readonly version: string\n readonly distMacOsAppName: string\n readonly macOsDefaultTargets: Array<string>\n readonly defaultAppIdPrefix: string\n\n readonly isNpmRebuildRequired: boolean\n\n readonly isCopyElevateHelper: boolean\n\n getDefaultIcon?(platform: Platform): string | null\n\n getMainFile?(platform: Platform): string | null\n\n getExcludedDependencies?(platform: Platform): Array<string> | null\n\n prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions): Promise<any>\n\n beforeCopyExtraFiles?(options: BeforeCopyExtraFilesOptions): Promise<any>\n\n afterPack?(context: AfterPackContext): Promise<any>\n\n createTransformer?(): FileTransformer | null\n}\n\nexport interface BeforeCopyExtraFilesOptions {\n packager: PlatformPackager<any>\n appOutDir: string\n\n asarIntegrity: AsarIntegrity | null\n\n // ElectronPlatformName\n platformName: string\n}\n\nexport interface PrepareApplicationStageDirectoryOptions {\n readonly packager: PlatformPackager<any>\n /**\n * Platform doesn't process application output directory in any way. Unpack implementation must create or empty dir if need.\n */\n readonly appOutDir: string\n readonly platformName: ElectronPlatformName\n readonly arch: string\n readonly version: string\n}\n\nexport function isElectronBased(framework: Framework): boolean {\n return framework.name === \"electron\"\n}\n"]}

View file

@ -0,0 +1,10 @@
import { FileTransformer } from "builder-util/out/fs";
import { Platform } from "./core";
import { LibUiFramework } from "./frameworks/LibUiFramework";
export declare class ProtonFramework extends LibUiFramework {
readonly name = "proton";
readonly defaultAppIdPrefix = "com.proton-native.";
constructor(version: string, distMacOsAppName: string, isUseLaunchUi: boolean);
getDefaultIcon(platform: Platform): string;
createTransformer(): FileTransformer | null;
}

View file

@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProtonFramework = void 0;
const builder_util_1 = require("builder-util");
const builder_util_runtime_1 = require("builder-util-runtime");
const core_1 = require("./core");
const fileTransformer_1 = require("./fileTransformer");
const LibUiFramework_1 = require("./frameworks/LibUiFramework");
const pathManager_1 = require("./util/pathManager");
class ProtonFramework extends LibUiFramework_1.LibUiFramework {
constructor(version, distMacOsAppName, isUseLaunchUi) {
super(version, distMacOsAppName, isUseLaunchUi);
this.name = "proton";
// noinspection JSUnusedGlobalSymbols
this.defaultAppIdPrefix = "com.proton-native.";
}
getDefaultIcon(platform) {
if (platform === core_1.Platform.WINDOWS) {
return pathManager_1.getTemplatePath("icons/proton-native/proton-native.ico");
}
else if (platform === core_1.Platform.LINUX) {
return pathManager_1.getTemplatePath("icons/proton-native/linux");
}
else {
return pathManager_1.getTemplatePath("icons/proton-native/proton-native.icns");
}
}
createTransformer() {
let babel;
const babelOptions = { ast: false, sourceMaps: "inline" };
if (process.env.TEST_SET_BABEL_PRESET === "true") {
babel = require("@babel/core");
// eslint-disable-next-line @typescript-eslint/no-use-before-define
babel = testOnlyBabel(babel, babelOptions, this.version);
}
else {
try {
babel = require("babel-core");
}
catch (e) {
// babel isn't installed
builder_util_1.log.debug(null, "don't transpile source code using Babel");
return null;
}
}
builder_util_1.log.info({
options: builder_util_runtime_1.safeStringifyJson(babelOptions, new Set(["presets"])),
}, "transpile source code using Babel");
return (file) => {
if (!(file.endsWith(".js") || file.endsWith(".jsx")) || file.includes(fileTransformer_1.NODE_MODULES_PATTERN)) {
return null;
}
return new Promise((resolve, reject) => {
return babel.transformFile(file, babelOptions, (error, result) => {
if (error == null) {
resolve(result.code);
}
else {
reject(error);
}
});
});
};
}
}
exports.ProtonFramework = ProtonFramework;
function testOnlyBabel(babel, babelOptions, nodeVersion) {
// out test dir can be located outside of electron-builder node_modules and babel cannot resolve string names of preset
babelOptions.presets = [[require("@babel/preset-env").default, { targets: { node: nodeVersion } }], require("@babel/preset-react")];
babelOptions.plugins = [
// stage 0
require("@babel/plugin-proposal-function-bind").default,
// stage 1
require("@babel/plugin-proposal-export-default-from").default,
require("@babel/plugin-proposal-logical-assignment-operators").default,
[require("@babel/plugin-proposal-optional-chaining").default, { loose: false }],
[require("@babel/plugin-proposal-pipeline-operator").default, { proposal: "minimal" }],
[require("@babel/plugin-proposal-nullish-coalescing-operator").default, { loose: false }],
require("@babel/plugin-proposal-do-expressions").default,
// stage 2
[require("@babel/plugin-proposal-decorators").default, { legacy: true }],
require("@babel/plugin-proposal-function-sent").default,
require("@babel/plugin-proposal-export-namespace-from").default,
require("@babel/plugin-proposal-numeric-separator").default,
require("@babel/plugin-proposal-throw-expressions").default,
// stage 3
require("@babel/plugin-syntax-dynamic-import").default,
require("@babel/plugin-syntax-import-meta").default,
[require("@babel/plugin-proposal-class-properties").default, { loose: false }],
require("@babel/plugin-proposal-json-strings").default,
];
babelOptions.babelrc = false;
return babel;
}
//# sourceMappingURL=ProtonFramework.js.map

File diff suppressed because one or more lines are too long

29
electron/node_modules/app-builder-lib/out/appInfo.d.ts generated vendored Normal file
View file

@ -0,0 +1,29 @@
import { PlatformSpecificBuildOptions } from "./options/PlatformSpecificBuildOptions";
import { Packager } from "./packager";
export declare function smarten(s: string): string;
export declare class AppInfo {
private readonly info;
private readonly platformSpecificOptions;
readonly description: string;
readonly version: string;
readonly shortVersion: string | undefined;
readonly shortVersionWindows: string | undefined;
readonly buildNumber: string | undefined;
readonly buildVersion: string;
readonly productName: string;
readonly sanitizedProductName: string;
readonly productFilename: string;
constructor(info: Packager, buildVersion: string | null | undefined, platformSpecificOptions?: PlatformSpecificBuildOptions | null);
get channel(): string | null;
getVersionInWeirdWindowsForm(isSetBuildNumber?: boolean): string;
private get notNullDevMetadata();
get companyName(): string | null;
get id(): string;
get macBundleIdentifier(): string;
get name(): string;
get linuxPackageName(): string;
get sanitizedName(): string;
get updaterCacheDirName(): string;
get copyright(): string;
computePackageUrl(): Promise<string | null>;
}

137
electron/node_modules/app-builder-lib/out/appInfo.js generated vendored Normal file
View file

@ -0,0 +1,137 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.filterCFBundleIdentifier = exports.AppInfo = exports.smarten = void 0;
const builder_util_1 = require("builder-util");
const semver_1 = require("semver");
const macroExpander_1 = require("./util/macroExpander");
const filename_1 = require("./util/filename");
// fpm bug - rpm build --description is not escaped, well... decided to replace quite to smart quote
// http://leancrew.com/all-this/2010/11/smart-quotes-in-javascript/
function smarten(s) {
// opening singles
s = s.replace(/(^|[-\u2014\s(["])'/g, "$1\u2018");
// closing singles & apostrophes
s = s.replace(/'/g, "\u2019");
// opening doubles
s = s.replace(/(^|[-\u2014/[(\u2018\s])"/g, "$1\u201c");
// closing doubles
s = s.replace(/"/g, "\u201d");
return s;
}
exports.smarten = smarten;
class AppInfo {
constructor(info, buildVersion, platformSpecificOptions = null) {
this.info = info;
this.platformSpecificOptions = platformSpecificOptions;
this.description = smarten(this.info.metadata.description || "");
this.version = info.metadata.version;
if (buildVersion == null) {
buildVersion = info.config.buildVersion;
}
const buildNumberEnvs = process.env.BUILD_NUMBER ||
process.env.TRAVIS_BUILD_NUMBER ||
process.env.APPVEYOR_BUILD_NUMBER ||
process.env.CIRCLE_BUILD_NUM ||
process.env.BUILD_BUILDNUMBER ||
process.env.CI_PIPELINE_IID;
this.buildNumber = info.config.buildNumber || buildNumberEnvs;
if (buildVersion == null) {
buildVersion = this.version;
if (!builder_util_1.isEmptyOrSpaces(this.buildNumber)) {
buildVersion += `.${this.buildNumber}`;
}
}
this.buildVersion = buildVersion;
if (info.metadata.shortVersion) {
this.shortVersion = info.metadata.shortVersion;
}
if (info.metadata.shortVersionWindows) {
this.shortVersionWindows = info.metadata.shortVersionWindows;
}
this.productName = info.config.productName || info.metadata.productName || info.metadata.name;
this.sanitizedProductName = filename_1.sanitizeFileName(this.productName);
this.productFilename = (platformSpecificOptions === null || platformSpecificOptions === void 0 ? void 0 : platformSpecificOptions.executableName) != null ? filename_1.sanitizeFileName(platformSpecificOptions.executableName) : this.sanitizedProductName;
}
get channel() {
const prereleaseInfo = semver_1.prerelease(this.version);
if (prereleaseInfo != null && prereleaseInfo.length > 0) {
return prereleaseInfo[0];
}
return null;
}
getVersionInWeirdWindowsForm(isSetBuildNumber = true) {
const parsedVersion = new semver_1.SemVer(this.version);
// https://github.com/electron-userland/electron-builder/issues/2635#issuecomment-371792272
let buildNumber = isSetBuildNumber ? this.buildNumber : null;
if (buildNumber == null || !/^\d+$/.test(buildNumber)) {
buildNumber = "0";
}
return `${parsedVersion.major}.${parsedVersion.minor}.${parsedVersion.patch}.${buildNumber}`;
}
get notNullDevMetadata() {
return this.info.devMetadata || {};
}
get companyName() {
const author = this.info.metadata.author || this.notNullDevMetadata.author;
return author == null ? null : author.name;
}
get id() {
let appId = null;
for (const options of [this.platformSpecificOptions, this.info.config]) {
if (options != null && appId == null) {
appId = options.appId;
}
}
const generateDefaultAppId = () => {
const info = this.info;
return `${info.framework.defaultAppIdPrefix}${info.metadata.name.toLowerCase()}`;
};
if (appId != null && (appId === "your.id" || builder_util_1.isEmptyOrSpaces(appId))) {
const incorrectAppId = appId;
appId = generateDefaultAppId();
builder_util_1.log.warn(`do not use "${incorrectAppId}" as appId, "${appId}" will be used instead`);
}
return appId == null ? generateDefaultAppId() : appId;
}
get macBundleIdentifier() {
return filterCFBundleIdentifier(this.id);
}
get name() {
return this.info.metadata.name;
}
get linuxPackageName() {
const name = this.name;
// https://github.com/electron-userland/electron-builder/issues/2963
return name.startsWith("@") ? this.sanitizedProductName : name;
}
get sanitizedName() {
return filename_1.sanitizeFileName(this.name);
}
get updaterCacheDirName() {
return this.sanitizedName.toLowerCase() + "-updater";
}
get copyright() {
const copyright = this.info.config.copyright;
if (copyright != null) {
return macroExpander_1.expandMacro(copyright, null, this);
}
return `Copyright © ${new Date().getFullYear()} ${this.companyName || this.productName}`;
}
async computePackageUrl() {
const url = this.info.metadata.homepage || this.notNullDevMetadata.homepage;
if (url != null) {
return url;
}
const info = await this.info.repositoryInfo;
return info == null || info.type !== "github" ? null : `https://${info.domain}/${info.user}/${info.project}`;
}
}
exports.AppInfo = AppInfo;
/** @internal */
function filterCFBundleIdentifier(identifier) {
// Remove special characters and allow only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.)
// Apple documentation: https://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070
return identifier.replace(/ /g, "-").replace(/[^a-zA-Z0-9.-]/g, "");
}
exports.filterCFBundleIdentifier = filterCFBundleIdentifier;
//# sourceMappingURL=appInfo.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,29 @@
/// <reference types="node" />
import { Stats } from "fs-extra";
export interface ReadAsarHeader {
readonly header: string;
readonly size: number;
}
export interface NodeIntegrity {
algorithm: "SHA256";
hash: string;
blockSize: number;
blocks: Array<string>;
}
export declare class AsarFilesystem {
readonly src: string;
readonly header: Node;
readonly headerSize: number;
private offset;
constructor(src: string, header?: Node, headerSize?: number);
searchNodeFromDirectory(p: string, isCreate: boolean): Node | null;
getOrCreateNode(p: string): Node;
addFileNode(file: string, dirNode: Node, size: number, unpacked: boolean, stat: Stats, integrity?: NodeIntegrity): Node;
getNode(p: string): Node | null;
getFile(p: string, followLinks?: boolean): Node;
readJson(file: string): Promise<any>;
readFile(file: string): Promise<Buffer>;
}
export declare function readAsarHeader(archive: string): Promise<ReadAsarHeader>;
export declare function readAsar(archive: string): Promise<AsarFilesystem>;
export declare function readAsarJson(archive: string, file: string): Promise<any>;

152
electron/node_modules/app-builder-lib/out/asar/asar.js generated vendored Normal file
View file

@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readAsarJson = exports.readAsar = exports.readAsarHeader = exports.AsarFilesystem = exports.Node = void 0;
const chromium_pickle_js_1 = require("chromium-pickle-js");
const fs_extra_1 = require("fs-extra");
const path = require("path");
/** @internal */
class Node {
}
exports.Node = Node;
class AsarFilesystem {
constructor(src, header = new Node(), headerSize = -1) {
this.src = src;
this.header = header;
this.headerSize = headerSize;
this.offset = 0;
if (this.header.files == null) {
this.header.files = {};
}
}
searchNodeFromDirectory(p, isCreate) {
let node = this.header;
for (const dir of p.split(path.sep)) {
if (dir !== ".") {
let child = node.files[dir];
if (child == null) {
if (!isCreate) {
return null;
}
child = new Node();
child.files = {};
node.files[dir] = child;
}
node = child;
}
}
return node;
}
getOrCreateNode(p) {
if (p == null || p.length === 0) {
return this.header;
}
const name = path.basename(p);
const dirNode = this.searchNodeFromDirectory(path.dirname(p), true);
if (dirNode.files == null) {
dirNode.files = {};
}
let result = dirNode.files[name];
if (result == null) {
result = new Node();
dirNode.files[name] = result;
}
return result;
}
addFileNode(file, dirNode, size, unpacked, stat, integrity) {
if (size > 4294967295) {
throw new Error(`${file}: file size cannot be larger than 4.2GB`);
}
const node = new Node();
node.size = size;
if (integrity) {
node.integrity = integrity;
}
if (unpacked) {
node.unpacked = true;
}
else {
// electron expects string
node.offset = this.offset.toString();
if (process.platform !== "win32" && stat.mode & 0o100) {
node.executable = true;
}
this.offset += node.size;
}
let children = dirNode.files;
if (children == null) {
children = {};
dirNode.files = children;
}
children[path.basename(file)] = node;
return node;
}
getNode(p) {
const node = this.searchNodeFromDirectory(path.dirname(p), false);
return node.files[path.basename(p)];
}
getFile(p, followLinks = true) {
const info = this.getNode(p);
// if followLinks is false we don't resolve symlinks
return followLinks && info.link != null ? this.getFile(info.link) : info;
}
async readJson(file) {
return JSON.parse((await this.readFile(file)).toString());
}
readFile(file) {
return readFileFromAsar(this, file, this.getFile(file));
}
}
exports.AsarFilesystem = AsarFilesystem;
async function readAsarHeader(archive) {
const fd = await fs_extra_1.open(archive, "r");
let size;
let headerBuf;
try {
const sizeBuf = Buffer.allocUnsafe(8);
if ((await fs_extra_1.read(fd, sizeBuf, 0, 8, null)).bytesRead !== 8) {
throw new Error("Unable to read header size");
}
const sizePickle = chromium_pickle_js_1.createFromBuffer(sizeBuf);
size = sizePickle.createIterator().readUInt32();
headerBuf = Buffer.allocUnsafe(size);
if ((await fs_extra_1.read(fd, headerBuf, 0, size, null)).bytesRead !== size) {
throw new Error("Unable to read header");
}
}
finally {
await fs_extra_1.close(fd);
}
const headerPickle = chromium_pickle_js_1.createFromBuffer(headerBuf);
return { header: headerPickle.createIterator().readString(), size };
}
exports.readAsarHeader = readAsarHeader;
async function readAsar(archive) {
const { header, size } = await readAsarHeader(archive);
return new AsarFilesystem(archive, JSON.parse(header), size);
}
exports.readAsar = readAsar;
async function readAsarJson(archive, file) {
const fs = await readAsar(archive);
return await fs.readJson(file);
}
exports.readAsarJson = readAsarJson;
async function readFileFromAsar(filesystem, filename, info) {
const size = info.size;
const buffer = Buffer.allocUnsafe(size);
if (size <= 0) {
return buffer;
}
if (info.unpacked) {
return await fs_extra_1.readFile(path.join(`${filesystem.src}.unpacked`, filename));
}
const fd = await fs_extra_1.open(filesystem.src, "r");
try {
const offset = 8 + filesystem.headerSize + parseInt(info.offset, 10);
await fs_extra_1.read(fd, buffer, 0, size, offset);
}
finally {
await fs_extra_1.close(fd);
}
return buffer;
}
//# sourceMappingURL=asar.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkFileInArchive = void 0;
const fs_1 = require("builder-util/out/fs");
const asar_1 = require("./asar");
/** @internal */
async function checkFileInArchive(asarFile, relativeFile, messagePrefix) {
function error(text) {
return new Error(`${messagePrefix} "${relativeFile}" in the "${asarFile}" ${text}`);
}
let fs;
try {
fs = await asar_1.readAsar(asarFile);
}
catch (e) {
throw error(`is corrupted: ${e}`);
}
let stat;
try {
stat = fs.getFile(relativeFile);
}
catch (e) {
const fileStat = await fs_1.statOrNull(asarFile);
if (fileStat == null) {
throw error(`does not exist. Seems like a wrong configuration.`);
}
// asar throws error on access to undefined object (info.link)
stat = null;
}
if (stat == null) {
throw error(`does not exist. Seems like a wrong configuration.`);
}
if (stat.size === 0) {
throw error(`is corrupted: size 0`);
}
}
exports.checkFileInArchive = checkFileInArchive;
//# sourceMappingURL=asarFileChecker.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"asarFileChecker.js","sourceRoot":"","sources":["../../src/asar/asarFileChecker.ts"],"names":[],"mappings":";;;AAAA,4CAAgD;AAChD,iCAAuC;AAEvC,gBAAgB;AACT,KAAK,UAAU,kBAAkB,CAAC,QAAgB,EAAE,YAAoB,EAAE,aAAqB;IACpG,SAAS,KAAK,CAAC,IAAY;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,aAAa,KAAK,YAAY,aAAa,QAAQ,KAAK,IAAI,EAAE,CAAC,CAAA;IACrF,CAAC;IAED,IAAI,EAAE,CAAA;IACN,IAAI;QACF,EAAE,GAAG,MAAM,eAAQ,CAAC,QAAQ,CAAC,CAAA;KAC9B;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAA;KAClC;IAED,IAAI,IAAiB,CAAA;IACrB,IAAI;QACF,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;KAChC;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,QAAQ,GAAG,MAAM,eAAU,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,QAAQ,IAAI,IAAI,EAAE;YACpB,MAAM,KAAK,CAAC,mDAAmD,CAAC,CAAA;SACjE;QAED,8DAA8D;QAC9D,IAAI,GAAG,IAAI,CAAA;KACZ;IAED,IAAI,IAAI,IAAI,IAAI,EAAE;QAChB,MAAM,KAAK,CAAC,mDAAmD,CAAC,CAAA;KACjE;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;QACnB,MAAM,KAAK,CAAC,sBAAsB,CAAC,CAAA;KACpC;AACH,CAAC;AA/BD,gDA+BC","sourcesContent":["import { statOrNull } from \"builder-util/out/fs\"\nimport { Node, readAsar } from \"./asar\"\n\n/** @internal */\nexport async function checkFileInArchive(asarFile: string, relativeFile: string, messagePrefix: string) {\n function error(text: string) {\n return new Error(`${messagePrefix} \"${relativeFile}\" in the \"${asarFile}\" ${text}`)\n }\n\n let fs\n try {\n fs = await readAsar(asarFile)\n } catch (e) {\n throw error(`is corrupted: ${e}`)\n }\n\n let stat: Node | null\n try {\n stat = fs.getFile(relativeFile)\n } catch (e) {\n const fileStat = await statOrNull(asarFile)\n if (fileStat == null) {\n throw error(`does not exist. Seems like a wrong configuration.`)\n }\n\n // asar throws error on access to undefined object (info.link)\n stat = null\n }\n\n if (stat == null) {\n throw error(`does not exist. Seems like a wrong configuration.`)\n }\n if (stat.size === 0) {\n throw error(`is corrupted: size 0`)\n }\n}\n"]}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,241 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsarPackager = void 0;
const builder_util_1 = require("builder-util");
const fs_1 = require("builder-util/out/fs");
const fs_2 = require("fs");
const promises_1 = require("fs/promises");
const path = require("path");
const appFileCopier_1 = require("../util/appFileCopier");
const asar_1 = require("./asar");
const integrity_1 = require("./integrity");
const unpackDetector_1 = require("./unpackDetector");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const pickle = require("chromium-pickle-js");
/** @internal */
class AsarPackager {
constructor(src, destination, options, unpackPattern) {
this.src = src;
this.destination = destination;
this.options = options;
this.unpackPattern = unpackPattern;
this.fs = new asar_1.AsarFilesystem(this.src);
this.outFile = path.join(destination, "app.asar");
this.unpackedDest = `${this.outFile}.unpacked`;
}
// sort files to minimize file change (i.e. asar file is not changed dramatically on small change)
async pack(fileSets, packager) {
if (this.options.ordering != null) {
// ordering doesn't support transformed files, but ordering is not used functionality - wait user report to fix it
await order(fileSets[0].files, this.options.ordering, fileSets[0].src);
}
await promises_1.mkdir(path.dirname(this.outFile), { recursive: true });
const unpackedFileIndexMap = new Map();
for (const fileSet of fileSets) {
unpackedFileIndexMap.set(fileSet, await this.createPackageFromFiles(fileSet, packager.info));
}
await this.writeAsarFile(fileSets, unpackedFileIndexMap);
}
async createPackageFromFiles(fileSet, packager) {
const metadata = fileSet.metadata;
// search auto unpacked dir
const unpackedDirs = new Set();
const rootForAppFilesWithoutAsar = path.join(this.destination, "app");
if (this.options.smartUnpack !== false) {
await unpackDetector_1.detectUnpackedDirs(fileSet, unpackedDirs, this.unpackedDest, rootForAppFilesWithoutAsar);
}
const dirToCreateForUnpackedFiles = new Set(unpackedDirs);
const correctDirNodeUnpackedFlag = async (filePathInArchive, dirNode) => {
for (const dir of unpackedDirs) {
if (filePathInArchive.length > dir.length + 2 && filePathInArchive[dir.length] === path.sep && filePathInArchive.startsWith(dir)) {
dirNode.unpacked = true;
unpackedDirs.add(filePathInArchive);
// not all dirs marked as unpacked after first iteration - because node module dir can be marked as unpacked after processing node module dir content
// e.g. node-notifier/example/advanced.js processed, but only on process vendor/terminal-notifier.app module will be marked as unpacked
await promises_1.mkdir(path.join(this.unpackedDest, filePathInArchive), { recursive: true });
break;
}
}
};
const transformedFiles = fileSet.transformedFiles;
const taskManager = new builder_util_1.AsyncTaskManager(packager.cancellationToken);
const fileCopier = new fs_1.FileCopier();
let currentDirNode = null;
let currentDirPath = null;
const unpackedFileIndexSet = new Set();
for (let i = 0, n = fileSet.files.length; i < n; i++) {
const file = fileSet.files[i];
const stat = metadata.get(file);
if (stat == null) {
continue;
}
const pathInArchive = path.relative(rootForAppFilesWithoutAsar, appFileCopier_1.getDestinationPath(file, fileSet));
if (stat.isSymbolicLink()) {
const s = stat;
this.fs.getOrCreateNode(pathInArchive).link = s.relativeLink;
s.pathInArchive = pathInArchive;
unpackedFileIndexSet.add(i);
continue;
}
let fileParent = path.dirname(pathInArchive);
if (fileParent === ".") {
fileParent = "";
}
if (currentDirPath !== fileParent) {
if (fileParent.startsWith("..")) {
throw new Error(`Internal error: path must not start with "..": ${fileParent}`);
}
currentDirPath = fileParent;
currentDirNode = this.fs.getOrCreateNode(fileParent);
// do not check for root
if (fileParent !== "" && !currentDirNode.unpacked) {
if (unpackedDirs.has(fileParent)) {
currentDirNode.unpacked = true;
}
else {
await correctDirNodeUnpackedFlag(fileParent, currentDirNode);
}
}
}
const dirNode = currentDirNode;
const newData = transformedFiles == null ? undefined : transformedFiles.get(i);
const isUnpacked = dirNode.unpacked || (this.unpackPattern != null && this.unpackPattern(file, stat));
const integrity = newData === undefined ? await integrity_1.hashFile(file) : integrity_1.hashFileContents(newData);
this.fs.addFileNode(file, dirNode, newData == undefined ? stat.size : Buffer.byteLength(newData), isUnpacked, stat, integrity);
if (isUnpacked) {
if (!dirNode.unpacked && !dirToCreateForUnpackedFiles.has(fileParent)) {
dirToCreateForUnpackedFiles.add(fileParent);
await promises_1.mkdir(path.join(this.unpackedDest, fileParent), { recursive: true });
}
const unpackedFile = path.join(this.unpackedDest, pathInArchive);
taskManager.addTask(copyFileOrData(fileCopier, newData, file, unpackedFile, stat));
if (taskManager.tasks.length > fs_1.MAX_FILE_REQUESTS) {
await taskManager.awaitTasks();
}
unpackedFileIndexSet.add(i);
}
}
if (taskManager.tasks.length > 0) {
await taskManager.awaitTasks();
}
return unpackedFileIndexSet;
}
writeAsarFile(fileSets, unpackedFileIndexMap) {
return new Promise((resolve, reject) => {
const headerPickle = pickle.createEmpty();
headerPickle.writeString(JSON.stringify(this.fs.header));
const headerBuf = headerPickle.toBuffer();
const sizePickle = pickle.createEmpty();
sizePickle.writeUInt32(headerBuf.length);
const sizeBuf = sizePickle.toBuffer();
const writeStream = fs_2.createWriteStream(this.outFile);
writeStream.on("error", reject);
writeStream.on("close", resolve);
writeStream.write(sizeBuf);
let fileSetIndex = 0;
let files = fileSets[0].files;
let metadata = fileSets[0].metadata;
let transformedFiles = fileSets[0].transformedFiles;
let unpackedFileIndexSet = unpackedFileIndexMap.get(fileSets[0]);
const w = (index) => {
while (true) {
if (index >= files.length) {
if (++fileSetIndex >= fileSets.length) {
writeStream.end();
return;
}
else {
files = fileSets[fileSetIndex].files;
metadata = fileSets[fileSetIndex].metadata;
transformedFiles = fileSets[fileSetIndex].transformedFiles;
unpackedFileIndexSet = unpackedFileIndexMap.get(fileSets[fileSetIndex]);
index = 0;
}
}
if (!unpackedFileIndexSet.has(index)) {
break;
}
else {
const stat = metadata.get(files[index]);
if (stat != null && stat.isSymbolicLink()) {
fs_2.symlink(stat.linkRelativeToFile, path.join(this.unpackedDest, stat.pathInArchive), () => w(index + 1));
return;
}
}
index++;
}
const data = transformedFiles == null ? null : transformedFiles.get(index);
const file = files[index];
if (data !== null && data !== undefined) {
writeStream.write(data, () => w(index + 1));
return;
}
// https://github.com/yarnpkg/yarn/pull/3539
const stat = metadata.get(file);
if (stat != null && stat.size < 2 * 1024 * 1024) {
promises_1.readFile(file)
.then(it => {
writeStream.write(it, () => w(index + 1));
})
.catch(e => reject(`Cannot read file ${file}: ${e.stack || e}`));
}
else {
const readStream = fs_2.createReadStream(file);
readStream.on("error", reject);
readStream.once("end", () => w(index + 1));
readStream.on("open", () => {
readStream.pipe(writeStream, {
end: false,
});
});
}
};
writeStream.write(headerBuf, () => w(0));
});
}
}
exports.AsarPackager = AsarPackager;
async function order(filenames, orderingFile, src) {
const orderingFiles = (await promises_1.readFile(orderingFile, "utf8")).split("\n").map(line => {
if (line.indexOf(":") !== -1) {
line = line.split(":").pop();
}
line = line.trim();
if (line[0] === "/") {
line = line.slice(1);
}
return line;
});
const ordering = [];
for (const file of orderingFiles) {
const pathComponents = file.split(path.sep);
for (const pathComponent of pathComponents) {
ordering.push(path.join(src, pathComponent));
}
}
const sortedFiles = [];
let missing = 0;
const total = filenames.length;
for (const file of ordering) {
if (!sortedFiles.includes(file) && filenames.includes(file)) {
sortedFiles.push(file);
}
}
for (const file of filenames) {
if (!sortedFiles.includes(file)) {
sortedFiles.push(file);
missing += 1;
}
}
builder_util_1.log.info({ coverage: ((total - missing) / total) * 100 }, "ordering files in ASAR archive");
return sortedFiles;
}
function copyFileOrData(fileCopier, data, source, destination, stats) {
if (data == null) {
return fileCopier.copy(source, destination, stats);
}
else {
return promises_1.writeFile(destination, data);
}
}
//# sourceMappingURL=asarUtil.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
/// <reference types="node" />
import { NodeIntegrity } from "./asar";
export interface AsarIntegrityOptions {
readonly resourcesPath: string;
readonly resourcesRelativePath: string;
}
export interface HeaderHash {
algorithm: "SHA256";
hash: string;
}
export interface AsarIntegrity {
[key: string]: HeaderHash;
}
export declare function computeData({ resourcesPath, resourcesRelativePath }: AsarIntegrityOptions): Promise<AsarIntegrity>;
export declare function hashFile(file: string, blockSize?: number): Promise<NodeIntegrity>;
export declare function hashFileContents(contents: Buffer | string, blockSize?: number): NodeIntegrity;

View file

@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hashFileContents = exports.hashFile = exports.computeData = void 0;
const bluebird_lst_1 = require("bluebird-lst");
const crypto_1 = require("crypto");
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const path = require("path");
const asar_1 = require("./asar");
async function computeData({ resourcesPath, resourcesRelativePath }) {
// sort to produce constant result
const names = (await promises_1.readdir(resourcesPath)).filter(it => it.endsWith(".asar")).sort();
const checksums = await bluebird_lst_1.default.map(names, it => hashHeader(path.join(resourcesPath, it)));
const result = {};
for (let i = 0; i < names.length; i++) {
result[path.join(resourcesRelativePath, names[i])] = checksums[i];
}
return result;
}
exports.computeData = computeData;
async function hashHeader(file) {
const hash = crypto_1.createHash("sha256");
const { header } = await asar_1.readAsarHeader(file);
hash.update(header);
return {
algorithm: "SHA256",
hash: hash.digest("hex"),
};
}
function hashFile(file, blockSize = 4 * 1024 * 1024) {
return new Promise((resolve, reject) => {
const hash = crypto_1.createHash("sha256");
const blocks = new Array();
let blockBytes = 0;
let blockHash = crypto_1.createHash("sha256");
function updateBlockHash(chunk) {
let off = 0;
while (off < chunk.length) {
const toHash = Math.min(blockSize - blockBytes, chunk.length - off);
blockHash.update(chunk.slice(off, off + toHash));
off += toHash;
blockBytes += toHash;
if (blockBytes === blockSize) {
blocks.push(blockHash.digest("hex"));
blockHash = crypto_1.createHash("sha256");
blockBytes = 0;
}
}
}
fs_1.createReadStream(file)
.on("data", it => {
// Note that `it` is a Buffer anyway so this cast is a no-op
updateBlockHash(Buffer.from(it));
hash.update(it);
})
.on("error", reject)
.on("end", () => {
if (blockBytes !== 0) {
blocks.push(blockHash.digest("hex"));
}
resolve({
algorithm: "SHA256",
hash: hash.digest("hex"),
blockSize,
blocks,
});
});
});
}
exports.hashFile = hashFile;
function hashFileContents(contents, blockSize = 4 * 1024 * 1024) {
const buffer = Buffer.from(contents);
const hash = crypto_1.createHash("sha256");
hash.update(buffer);
const blocks = new Array();
for (let off = 0; off < buffer.length; off += blockSize) {
const blockHash = crypto_1.createHash("sha256");
blockHash.update(buffer.slice(off, off + blockSize));
blocks.push(blockHash.digest("hex"));
}
return {
algorithm: "SHA256",
hash: hash.digest("hex"),
blockSize,
blocks,
};
}
exports.hashFileContents = hashFileContents;
//# sourceMappingURL=integrity.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
export declare function isLibOrExe(file: string): boolean;

View file

@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.detectUnpackedDirs = exports.isLibOrExe = void 0;
const bluebird_lst_1 = require("bluebird-lst");
const builder_util_1 = require("builder-util");
const fs_1 = require("builder-util/out/fs");
const fs_extra_1 = require("fs-extra");
const isbinaryfile_1 = require("isbinaryfile");
const path = require("path");
const fileTransformer_1 = require("../fileTransformer");
const appFileCopier_1 = require("../util/appFileCopier");
function addValue(map, key, value) {
let list = map.get(key);
if (list == null) {
list = [value];
map.set(key, list);
}
else {
list.push(value);
}
}
function isLibOrExe(file) {
return file.endsWith(".dll") || file.endsWith(".exe") || file.endsWith(".dylib") || file.endsWith(".so");
}
exports.isLibOrExe = isLibOrExe;
/** @internal */
async function detectUnpackedDirs(fileSet, autoUnpackDirs, unpackedDest, rootForAppFilesWithoutAsar) {
const dirToCreate = new Map();
const metadata = fileSet.metadata;
function addParents(child, root) {
child = path.dirname(child);
if (autoUnpackDirs.has(child)) {
return;
}
do {
autoUnpackDirs.add(child);
const p = path.dirname(child);
// create parent dir to be able to copy file later without directory existence check
addValue(dirToCreate, p, path.basename(child));
if (child === root || p === root || autoUnpackDirs.has(p)) {
break;
}
child = p;
} while (true);
autoUnpackDirs.add(root);
}
for (let i = 0, n = fileSet.files.length; i < n; i++) {
const file = fileSet.files[i];
const index = file.lastIndexOf(fileTransformer_1.NODE_MODULES_PATTERN);
if (index < 0) {
continue;
}
let nextSlashIndex = file.indexOf(path.sep, index + fileTransformer_1.NODE_MODULES_PATTERN.length + 1);
if (nextSlashIndex < 0) {
continue;
}
if (file[index + fileTransformer_1.NODE_MODULES_PATTERN.length] === "@") {
nextSlashIndex = file.indexOf(path.sep, nextSlashIndex + 1);
}
if (!metadata.get(file).isFile()) {
continue;
}
const packageDir = file.substring(0, nextSlashIndex);
const packageDirPathInArchive = path.relative(rootForAppFilesWithoutAsar, appFileCopier_1.getDestinationPath(packageDir, fileSet));
const pathInArchive = path.relative(rootForAppFilesWithoutAsar, appFileCopier_1.getDestinationPath(file, fileSet));
if (autoUnpackDirs.has(packageDirPathInArchive)) {
// if package dir is unpacked, any file also unpacked
addParents(pathInArchive, packageDirPathInArchive);
continue;
}
// https://github.com/electron-userland/electron-builder/issues/2679
let shouldUnpack = false;
// ffprobe-static and ffmpeg-static are known packages to always unpack
const moduleName = path.basename(packageDir);
if (moduleName === "ffprobe-static" || moduleName === "ffmpeg-static" || isLibOrExe(file)) {
shouldUnpack = true;
}
else if (!file.includes(".", nextSlashIndex)) {
shouldUnpack = !!isbinaryfile_1.isBinaryFileSync(file);
}
if (!shouldUnpack) {
continue;
}
if (builder_util_1.log.isDebugEnabled) {
builder_util_1.log.debug({ file: pathInArchive, reason: "contains executable code" }, "not packed into asar archive");
}
addParents(pathInArchive, packageDirPathInArchive);
}
if (dirToCreate.size > 0) {
await fs_extra_1.mkdir(`${unpackedDest + path.sep}node_modules`, { recursive: true });
// child directories should be not created asynchronously - parent directories should be created first
await bluebird_lst_1.default.map(dirToCreate.keys(), async (parentDir) => {
const base = unpackedDest + path.sep + parentDir;
await fs_extra_1.mkdir(base, { recursive: true });
await bluebird_lst_1.default.each(dirToCreate.get(parentDir), (it) => {
if (dirToCreate.has(parentDir + path.sep + it)) {
// already created
return null;
}
else {
return fs_extra_1.mkdir(base + path.sep + it, { recursive: true });
}
});
}, fs_1.CONCURRENCY);
}
}
exports.detectUnpackedDirs = detectUnpackedDirs;
//# sourceMappingURL=unpackDetector.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,4 @@
export declare function download(url: string, output: string, checksum?: string | null): Promise<void>;
export declare function getBinFromCustomLoc(name: string, version: string, binariesLocUrl: string, checksum: string): Promise<string>;
export declare function getBinFromUrl(name: string, version: string, checksum: string): Promise<string>;
export declare function getBin(name: string, url?: string | null, checksum?: string | null): Promise<string>;

View file

@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBin = exports.getBinFromUrl = exports.getBinFromCustomLoc = exports.download = void 0;
const builder_util_1 = require("builder-util");
const versionToPromise = new Map();
function download(url, output, checksum) {
const args = ["download", "--url", url, "--output", output];
if (checksum != null) {
args.push("--sha512", checksum);
}
return builder_util_1.executeAppBuilder(args);
}
exports.download = download;
function getBinFromCustomLoc(name, version, binariesLocUrl, checksum) {
const dirName = `${name}-${version}`;
return getBin(dirName, binariesLocUrl, checksum);
}
exports.getBinFromCustomLoc = getBinFromCustomLoc;
function getBinFromUrl(name, version, checksum) {
const dirName = `${name}-${version}`;
let url;
if (process.env.ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL) {
url = process.env.ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL + "/" + dirName + ".7z";
}
else {
const baseUrl = process.env.NPM_CONFIG_ELECTRON_BUILDER_BINARIES_MIRROR ||
process.env.npm_config_electron_builder_binaries_mirror ||
process.env.npm_package_config_electron_builder_binaries_mirror ||
process.env.ELECTRON_BUILDER_BINARIES_MIRROR ||
"https://github.com/electron-userland/electron-builder-binaries/releases/download/";
const middleUrl = process.env.NPM_CONFIG_ELECTRON_BUILDER_BINARIES_CUSTOM_DIR ||
process.env.npm_config_electron_builder_binaries_custom_dir ||
process.env.npm_package_config_electron_builder_binaries_custom_dir ||
process.env.ELECTRON_BUILDER_BINARIES_CUSTOM_DIR ||
dirName;
const urlSuffix = dirName + ".7z";
url = `${baseUrl}${middleUrl}/${urlSuffix}`;
}
return getBin(dirName, url, checksum);
}
exports.getBinFromUrl = getBinFromUrl;
function getBin(name, url, checksum) {
// Old cache is ignored if cache environment variable changes
const cacheName = `${process.env.ELECTRON_BUILDER_CACHE}${name}`;
let promise = versionToPromise.get(cacheName); // if rejected, we will try to download again
if (promise != null) {
return promise;
}
promise = doGetBin(name, url, checksum);
versionToPromise.set(cacheName, promise);
return promise;
}
exports.getBin = getBin;
function doGetBin(name, url, checksum) {
const args = ["download-artifact", "--name", name];
if (url != null) {
args.push("--url", url);
}
if (checksum != null) {
args.push("--sha512", checksum);
}
return builder_util_1.executeAppBuilder(args);
}
//# sourceMappingURL=binDownload.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"binDownload.js","sourceRoot":"","sources":["../src/binDownload.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAEhD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA2B,CAAA;AAE3D,SAAgB,QAAQ,CAAC,GAAW,EAAE,MAAc,EAAE,QAAwB;IAC5E,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IAC3D,IAAI,QAAQ,IAAI,IAAI,EAAE;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;KAChC;IACD,OAAO,gCAAiB,CAAC,IAAI,CAAiB,CAAA;AAChD,CAAC;AAND,4BAMC;AAED,SAAgB,mBAAmB,CAAC,IAAY,EAAE,OAAe,EAAE,cAAsB,EAAE,QAAgB;IACzG,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,OAAO,EAAE,CAAA;IACpC,OAAO,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAA;AAClD,CAAC;AAHD,kDAGC;AAED,SAAgB,aAAa,CAAC,IAAY,EAAE,OAAe,EAAE,QAAgB;IAC3E,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,OAAO,EAAE,CAAA;IACpC,IAAI,GAAW,CAAA;IACf,IAAI,OAAO,CAAC,GAAG,CAAC,+CAA+C,EAAE;QAC/D,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,+CAA+C,GAAG,GAAG,GAAG,OAAO,GAAG,KAAK,CAAA;KAC1F;SAAM;QACL,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,2CAA2C;YACvD,OAAO,CAAC,GAAG,CAAC,2CAA2C;YACvD,OAAO,CAAC,GAAG,CAAC,mDAAmD;YAC/D,OAAO,CAAC,GAAG,CAAC,gCAAgC;YAC5C,mFAAmF,CAAA;QACrF,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,+CAA+C;YAC3D,OAAO,CAAC,GAAG,CAAC,+CAA+C;YAC3D,OAAO,CAAC,GAAG,CAAC,uDAAuD;YACnE,OAAO,CAAC,GAAG,CAAC,oCAAoC;YAChD,OAAO,CAAA;QACT,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,CAAA;QACjC,GAAG,GAAG,GAAG,OAAO,GAAG,SAAS,IAAI,SAAS,EAAE,CAAA;KAC5C;IAED,OAAO,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;AACvC,CAAC;AAvBD,sCAuBC;AAED,SAAgB,MAAM,CAAC,IAAY,EAAE,GAAmB,EAAE,QAAwB;IAChF,6DAA6D;IAC7D,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,IAAI,EAAE,CAAA;IAChE,IAAI,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA,CAAC,6CAA6C;IAE3F,IAAI,OAAO,IAAI,IAAI,EAAE;QACnB,OAAO,OAAO,CAAA;KACf;IAED,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;IACvC,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACxC,OAAO,OAAO,CAAA;AAChB,CAAC;AAZD,wBAYC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,GAA8B,EAAE,QAAmC;IACjG,MAAM,IAAI,GAAG,CAAC,mBAAmB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IAClD,IAAI,GAAG,IAAI,IAAI,EAAE;QACf,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;KACxB;IACD,IAAI,QAAQ,IAAI,IAAI,EAAE;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;KAChC;IACD,OAAO,gCAAiB,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC","sourcesContent":["import { executeAppBuilder } from \"builder-util\"\n\nconst versionToPromise = new Map<string, Promise<string>>()\n\nexport function download(url: string, output: string, checksum?: string | null): Promise<void> {\n const args = [\"download\", \"--url\", url, \"--output\", output]\n if (checksum != null) {\n args.push(\"--sha512\", checksum)\n }\n return executeAppBuilder(args) as Promise<any>\n}\n\nexport function getBinFromCustomLoc(name: string, version: string, binariesLocUrl: string, checksum: string): Promise<string> {\n const dirName = `${name}-${version}`\n return getBin(dirName, binariesLocUrl, checksum)\n}\n\nexport function getBinFromUrl(name: string, version: string, checksum: string): Promise<string> {\n const dirName = `${name}-${version}`\n let url: string\n if (process.env.ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL) {\n url = process.env.ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL + \"/\" + dirName + \".7z\"\n } else {\n const baseUrl =\n process.env.NPM_CONFIG_ELECTRON_BUILDER_BINARIES_MIRROR ||\n process.env.npm_config_electron_builder_binaries_mirror ||\n process.env.npm_package_config_electron_builder_binaries_mirror ||\n process.env.ELECTRON_BUILDER_BINARIES_MIRROR ||\n \"https://github.com/electron-userland/electron-builder-binaries/releases/download/\"\n const middleUrl =\n process.env.NPM_CONFIG_ELECTRON_BUILDER_BINARIES_CUSTOM_DIR ||\n process.env.npm_config_electron_builder_binaries_custom_dir ||\n process.env.npm_package_config_electron_builder_binaries_custom_dir ||\n process.env.ELECTRON_BUILDER_BINARIES_CUSTOM_DIR ||\n dirName\n const urlSuffix = dirName + \".7z\"\n url = `${baseUrl}${middleUrl}/${urlSuffix}`\n }\n\n return getBin(dirName, url, checksum)\n}\n\nexport function getBin(name: string, url?: string | null, checksum?: string | null): Promise<string> {\n // Old cache is ignored if cache environment variable changes\n const cacheName = `${process.env.ELECTRON_BUILDER_CACHE}${name}`\n let promise = versionToPromise.get(cacheName) // if rejected, we will try to download again\n\n if (promise != null) {\n return promise\n }\n\n promise = doGetBin(name, url, checksum)\n versionToPromise.set(cacheName, promise)\n return promise\n}\n\nfunction doGetBin(name: string, url: string | undefined | null, checksum: string | null | undefined): Promise<string> {\n const args = [\"download-artifact\", \"--name\", name]\n if (url != null) {\n args.push(\"--url\", url)\n }\n if (checksum != null) {\n args.push(\"--sha512\", checksum)\n }\n return executeAppBuilder(args)\n}\n"]}

View file

@ -0,0 +1,3 @@
import { TmpDir } from "temp-file";
/** @private */
export declare function importCertificate(cscLink: string, tmpDir: TmpDir, currentDir: string): Promise<string>;

View file

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.importCertificate = void 0;
const fs_extra_1 = require("fs-extra");
const os_1 = require("os");
const path = require("path");
const builder_util_1 = require("builder-util");
const fs_1 = require("builder-util/out/fs");
const binDownload_1 = require("../binDownload");
/** @private */
async function importCertificate(cscLink, tmpDir, currentDir) {
var _a, _b;
cscLink = cscLink.trim();
let file = null;
if ((cscLink.length > 3 && cscLink[1] === ":") || cscLink.startsWith("/") || cscLink.startsWith(".")) {
file = cscLink;
}
else if (cscLink.startsWith("file://")) {
file = cscLink.substring("file://".length);
}
else if (cscLink.startsWith("~/")) {
file = path.join(os_1.homedir(), cscLink.substring("~/".length));
}
else if (cscLink.startsWith("https://")) {
const tempFile = await tmpDir.getTempFile({ suffix: ".p12" });
await binDownload_1.download(cscLink, tempFile);
return tempFile;
}
else {
const mimeType = (_a = /data:.*;base64,/.exec(cscLink)) === null || _a === void 0 ? void 0 : _a[0];
if (mimeType || cscLink.length > 2048 || cscLink.endsWith("=")) {
const tempFile = await tmpDir.getTempFile({ suffix: ".p12" });
await fs_extra_1.outputFile(tempFile, Buffer.from(cscLink.substring((_b = mimeType === null || mimeType === void 0 ? void 0 : mimeType.length) !== null && _b !== void 0 ? _b : 0), "base64"));
return tempFile;
}
file = cscLink;
}
file = path.resolve(currentDir, file);
const stat = await fs_1.statOrNull(file);
if (stat == null) {
throw new builder_util_1.InvalidConfigurationError(`${file} doesn't exist`);
}
else if (!stat.isFile()) {
throw new builder_util_1.InvalidConfigurationError(`${file} not a file`);
}
else {
return file;
}
}
exports.importCertificate = importCertificate;
//# sourceMappingURL=codesign.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"codesign.js","sourceRoot":"","sources":["../../src/codeSign/codesign.ts"],"names":[],"mappings":";;;AAAA,uCAAqC;AACrC,2BAA4B;AAC5B,6BAA4B;AAE5B,+CAAwD;AACxD,4CAAgD;AAChD,gDAAyC;AAEzC,eAAe;AACR,KAAK,UAAU,iBAAiB,CAAC,OAAe,EAAE,MAAc,EAAE,UAAkB;;IACzF,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;IAExB,IAAI,IAAI,GAAkB,IAAI,CAAA;IAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QACpG,IAAI,GAAG,OAAO,CAAA;KACf;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QACxC,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;KAC3C;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACnC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAO,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;KAC5D;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;QACzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7D,MAAM,sBAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QACjC,OAAO,QAAQ,CAAA;KAChB;SAAM;QACL,MAAM,QAAQ,GAAG,MAAA,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,0CAAG,CAAC,CAAC,CAAA;QACrD,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YAC9D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;YAC7D,MAAM,qBAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,mCAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;YAC3F,OAAO,QAAQ,CAAA;SAChB;QACD,IAAI,GAAG,OAAO,CAAA;KACf;IAED,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IACrC,MAAM,IAAI,GAAG,MAAM,eAAU,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,IAAI,IAAI,IAAI,EAAE;QAChB,MAAM,IAAI,wCAAyB,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAA;KAC7D;SAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE;QACzB,MAAM,IAAI,wCAAyB,CAAC,GAAG,IAAI,aAAa,CAAC,CAAA;KAC1D;SAAM;QACL,OAAO,IAAI,CAAA;KACZ;AACH,CAAC;AAjCD,8CAiCC","sourcesContent":["import { outputFile } from \"fs-extra\"\nimport { homedir } from \"os\"\nimport * as path from \"path\"\nimport { TmpDir } from \"temp-file\"\nimport { InvalidConfigurationError } from \"builder-util\"\nimport { statOrNull } from \"builder-util/out/fs\"\nimport { download } from \"../binDownload\"\n\n/** @private */\nexport async function importCertificate(cscLink: string, tmpDir: TmpDir, currentDir: string): Promise<string> {\n cscLink = cscLink.trim()\n\n let file: string | null = null\n if ((cscLink.length > 3 && cscLink[1] === \":\") || cscLink.startsWith(\"/\") || cscLink.startsWith(\".\")) {\n file = cscLink\n } else if (cscLink.startsWith(\"file://\")) {\n file = cscLink.substring(\"file://\".length)\n } else if (cscLink.startsWith(\"~/\")) {\n file = path.join(homedir(), cscLink.substring(\"~/\".length))\n } else if (cscLink.startsWith(\"https://\")) {\n const tempFile = await tmpDir.getTempFile({ suffix: \".p12\" })\n await download(cscLink, tempFile)\n return tempFile\n } else {\n const mimeType = /data:.*;base64,/.exec(cscLink)?.[0]\n if (mimeType || cscLink.length > 2048 || cscLink.endsWith(\"=\")) {\n const tempFile = await tmpDir.getTempFile({ suffix: \".p12\" })\n await outputFile(tempFile, Buffer.from(cscLink.substring(mimeType?.length ?? 0), \"base64\"))\n return tempFile\n }\n file = cscLink\n }\n\n file = path.resolve(currentDir, file)\n const stat = await statOrNull(file)\n if (stat == null) {\n throw new InvalidConfigurationError(`${file} doesn't exist`)\n } else if (!stat.isFile()) {\n throw new InvalidConfigurationError(`${file} not a file`)\n } else {\n return file\n }\n}\n"]}

View file

@ -0,0 +1,27 @@
import { TmpDir } from "builder-util/out/util";
export declare const appleCertificatePrefixes: string[];
export declare type CertType = "Developer ID Application" | "Developer ID Installer" | "3rd Party Mac Developer Application" | "3rd Party Mac Developer Installer" | "Mac Developer" | "Apple Development" | "Apple Distribution";
export interface CodeSigningInfo {
keychainFile?: string | null;
}
export declare function isSignAllowed(isPrintWarn?: boolean): boolean;
export declare function reportError(isMas: boolean, certificateTypes: CertType[], qualifier: string | null | undefined, keychainFile: string | null | undefined, isForceCodeSigning: boolean): Promise<void>;
export interface CreateKeychainOptions {
tmpDir: TmpDir;
cscLink: string;
cscKeyPassword: string;
cscILink?: string | null;
cscIKeyPassword?: string | null;
currentDir: string;
}
export declare function removeKeychain(keychainFile: string, printWarn?: boolean): Promise<any>;
export declare function createKeychain({ tmpDir, cscLink, cscKeyPassword, cscILink, cscIKeyPassword, currentDir }: CreateKeychainOptions): Promise<CodeSigningInfo>;
/** @private */
export declare function sign(path: string, name: string, keychain: string): Promise<any>;
export declare let findIdentityRawResult: Promise<Array<string>> | null;
export declare class Identity {
readonly name: string;
readonly hash: string;
constructor(name: string, hash: string);
}
export declare function findIdentity(certType: CertType, qualifier?: string | null, keychain?: string | null): Promise<Identity | null>;

View file

@ -0,0 +1,280 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findIdentity = exports.findIdentityRawResult = exports.sign = exports.createKeychain = exports.removeKeychain = exports.reportError = exports.isSignAllowed = exports.appleCertificatePrefixes = void 0;
const bluebird_lst_1 = require("bluebird-lst");
const util_1 = require("builder-util/out/util");
const fs_1 = require("builder-util/out/fs");
const log_1 = require("builder-util/out/log");
const crypto_1 = require("crypto");
const promises_1 = require("fs/promises");
const lazy_val_1 = require("lazy-val");
const os_1 = require("os");
const path = require("path");
const temp_file_1 = require("temp-file");
const flags_1 = require("../util/flags");
const codesign_1 = require("./codesign");
exports.appleCertificatePrefixes = ["Developer ID Application:", "Developer ID Installer:", "3rd Party Mac Developer Application:", "3rd Party Mac Developer Installer:"];
function isSignAllowed(isPrintWarn = true) {
if (process.platform !== "darwin") {
if (isPrintWarn) {
util_1.log.warn({ reason: "supported only on macOS" }, "skipped macOS application code signing");
}
return false;
}
const buildForPrWarning = "There are serious security concerns with CSC_FOR_PULL_REQUEST=true (see the CircleCI documentation (https://circleci.com/docs/1.0/fork-pr-builds/) for details)" +
"\nIf you have SSH keys, sensitive env vars or AWS credentials stored in your project settings and untrusted forks can make pull requests against your repo, then this option isn't for you.";
if (util_1.isPullRequest()) {
if (util_1.isEnvTrue(process.env.CSC_FOR_PULL_REQUEST)) {
if (isPrintWarn) {
util_1.log.warn(buildForPrWarning);
}
}
else {
if (isPrintWarn) {
// https://github.com/electron-userland/electron-builder/issues/1524
util_1.log.warn("Current build is a part of pull request, code signing will be skipped." + "\nSet env CSC_FOR_PULL_REQUEST to true to force code signing." + `\n${buildForPrWarning}`);
}
return false;
}
}
return true;
}
exports.isSignAllowed = isSignAllowed;
async function reportError(isMas, certificateTypes, qualifier, keychainFile, isForceCodeSigning) {
const logFields = {};
if (qualifier == null) {
logFields.reason = "";
if (flags_1.isAutoDiscoveryCodeSignIdentity()) {
logFields.reason += `cannot find valid "${certificateTypes.join(", ")}" identity${isMas ? "" : ` or custom non-Apple code signing certificate, it could cause some undefined behaviour, e.g. macOS localized description not visible`}`;
}
logFields.reason += ", see https://electron.build/code-signing";
if (!flags_1.isAutoDiscoveryCodeSignIdentity()) {
logFields.CSC_IDENTITY_AUTO_DISCOVERY = false;
}
}
else {
logFields.reason = "Identity name is specified, but no valid identity with this name in the keychain";
logFields.identity = qualifier;
}
const args = ["find-identity"];
if (keychainFile != null) {
args.push(keychainFile);
}
if (qualifier != null || flags_1.isAutoDiscoveryCodeSignIdentity()) {
logFields.allIdentities = (await util_1.exec("security", args))
.trim()
.split("\n")
.filter(it => !(it.includes("Policy: X.509 Basic") || it.includes("Matching identities")))
.join("\n");
}
if (isMas || isForceCodeSigning) {
throw new Error(log_1.Logger.createMessage("skipped macOS application code signing", logFields, "error", it => it));
}
else {
util_1.log.warn(logFields, "skipped macOS application code signing");
}
}
exports.reportError = reportError;
// "Note that filename will not be searched to resolve the signing identity's certificate chain unless it is also on the user's keychain search list."
// but "security list-keychains" doesn't support add - we should 1) get current list 2) set new list - it is very bad http://stackoverflow.com/questions/10538942/add-a-keychain-to-search-list
// "overly complicated and introduces a race condition."
// https://github.com/electron-userland/electron-builder/issues/398
const bundledCertKeychainAdded = new lazy_val_1.Lazy(async () => {
// copy to temp and then atomic rename to final path
const cacheDir = getCacheDirectory();
const tmpKeychainPath = path.join(cacheDir, temp_file_1.getTempName("electron-builder-root-certs"));
const keychainPath = path.join(cacheDir, "electron-builder-root-certs.keychain");
const results = await Promise.all([
listUserKeychains(),
fs_1.copyFile(path.join(__dirname, "..", "..", "certs", "root_certs.keychain"), tmpKeychainPath).then(() => promises_1.rename(tmpKeychainPath, keychainPath)),
]);
const list = results[0];
if (!list.includes(keychainPath)) {
await util_1.exec("security", ["list-keychains", "-d", "user", "-s", keychainPath].concat(list));
}
});
function getCacheDirectory() {
const env = process.env.ELECTRON_BUILDER_CACHE;
return util_1.isEmptyOrSpaces(env) ? path.join(os_1.homedir(), "Library", "Caches", "electron-builder") : path.resolve(env);
}
function listUserKeychains() {
return util_1.exec("security", ["list-keychains", "-d", "user"]).then(it => it
.split("\n")
.map(it => {
const r = it.trim();
return r.substring(1, r.length - 1);
})
.filter(it => it.length > 0));
}
function removeKeychain(keychainFile, printWarn = true) {
return util_1.exec("security", ["delete-keychain", keychainFile]).catch(e => {
if (printWarn) {
util_1.log.warn({ file: keychainFile, error: e.stack || e }, "cannot delete keychain");
}
return fs_1.unlinkIfExists(keychainFile);
});
}
exports.removeKeychain = removeKeychain;
async function createKeychain({ tmpDir, cscLink, cscKeyPassword, cscILink, cscIKeyPassword, currentDir }) {
// travis has correct AppleWWDRCA cert
if (process.env.TRAVIS !== "true") {
await bundledCertKeychainAdded.value;
}
// https://github.com/electron-userland/electron-builder/issues/3685
// use constant file
const keychainFile = path.join(process.env.APP_BUILDER_TMP_DIR || os_1.tmpdir(), `${crypto_1.createHash("sha256").update(currentDir).update("app-builder").digest("hex")}.keychain`);
// noinspection JSUnusedLocalSymbols
// eslint-disable-next-line @typescript-eslint/no-unused-vars
await removeKeychain(keychainFile, false).catch(_ => {
/* ignore*/
});
const certLinks = [cscLink];
if (cscILink != null) {
certLinks.push(cscILink);
}
const certPaths = new Array(certLinks.length);
const keychainPassword = crypto_1.randomBytes(32).toString("base64");
const securityCommands = [
["create-keychain", "-p", keychainPassword, keychainFile],
["unlock-keychain", "-p", keychainPassword, keychainFile],
["set-keychain-settings", keychainFile],
];
// https://stackoverflow.com/questions/42484678/codesign-keychain-gets-ignored
// https://github.com/electron-userland/electron-builder/issues/1457
const list = await listUserKeychains();
if (!list.includes(keychainFile)) {
securityCommands.push(["list-keychains", "-d", "user", "-s", keychainFile].concat(list));
}
await Promise.all([
// we do not clear downloaded files - will be removed on tmpDir cleanup automatically. not a security issue since in any case data is available as env variables and protected by password.
bluebird_lst_1.default.map(certLinks, (link, i) => codesign_1.importCertificate(link, tmpDir, currentDir).then(it => (certPaths[i] = it))),
bluebird_lst_1.default.mapSeries(securityCommands, it => util_1.exec("security", it)),
]);
return await importCerts(keychainFile, certPaths, [cscKeyPassword, cscIKeyPassword].filter(it => it != null));
}
exports.createKeychain = createKeychain;
async function importCerts(keychainFile, paths, keyPasswords) {
for (let i = 0; i < paths.length; i++) {
const password = keyPasswords[i];
await util_1.exec("security", ["import", paths[i], "-k", keychainFile, "-T", "/usr/bin/codesign", "-T", "/usr/bin/productbuild", "-P", password]);
// https://stackoverflow.com/questions/39868578/security-codesign-in-sierra-keychain-ignores-access-control-settings-and-ui-p
// https://github.com/electron-userland/electron-packager/issues/701#issuecomment-322315996
await util_1.exec("security", ["set-key-partition-list", "-S", "apple-tool:,apple:", "-s", "-k", password, keychainFile]);
}
return {
keychainFile,
};
}
/** @private */
function sign(path, name, keychain) {
const args = ["--deep", "--force", "--sign", name, path];
if (keychain != null) {
args.push("--keychain", keychain);
}
return util_1.exec("codesign", args);
}
exports.sign = sign;
exports.findIdentityRawResult = null;
async function getValidIdentities(keychain) {
function addKeychain(args) {
if (keychain != null) {
args.push(keychain);
}
return args;
}
let result = exports.findIdentityRawResult;
if (result == null || keychain != null) {
// https://github.com/electron-userland/electron-builder/issues/481
// https://github.com/electron-userland/electron-builder/issues/535
result = Promise.all([
util_1.exec("security", addKeychain(["find-identity", "-v"])).then(it => it
.trim()
.split("\n")
.filter(it => {
for (const prefix of exports.appleCertificatePrefixes) {
if (it.includes(prefix)) {
return true;
}
}
return false;
})),
util_1.exec("security", addKeychain(["find-identity", "-v", "-p", "codesigning"])).then(it => it.trim().split("\n")),
]).then(it => {
const array = it[0]
.concat(it[1])
.filter(it => !it.includes("(Missing required extension)") && !it.includes("valid identities found") && !it.includes("iPhone ") && !it.includes("com.apple.idms.appleid.prd."))
// remove 1)
.map(it => it.substring(it.indexOf(")") + 1).trim());
return Array.from(new Set(array));
});
if (keychain == null) {
exports.findIdentityRawResult = result;
}
}
return result;
}
async function _findIdentity(type, qualifier, keychain) {
// https://github.com/electron-userland/electron-builder/issues/484
//noinspection SpellCheckingInspection
const lines = await getValidIdentities(keychain);
const namePrefix = `${type}:`;
for (const line of lines) {
if (qualifier != null && !line.includes(qualifier)) {
continue;
}
if (line.includes(namePrefix)) {
return parseIdentity(line);
}
}
if (type === "Developer ID Application") {
// find non-Apple certificate
// https://github.com/electron-userland/electron-builder/issues/458
l: for (const line of lines) {
if (qualifier != null && !line.includes(qualifier)) {
continue;
}
if (line.includes("Mac Developer:")) {
continue;
}
for (const prefix of exports.appleCertificatePrefixes) {
if (line.includes(prefix)) {
continue l;
}
}
return parseIdentity(line);
}
}
return null;
}
const _Identity = require("electron-osx-sign/util-identities").Identity;
function parseIdentity(line) {
const firstQuoteIndex = line.indexOf('"');
const name = line.substring(firstQuoteIndex + 1, line.lastIndexOf('"'));
const hash = line.substring(0, firstQuoteIndex - 1);
return new _Identity(name, hash);
}
function findIdentity(certType, qualifier, keychain) {
let identity = qualifier || process.env.CSC_NAME;
if (util_1.isEmptyOrSpaces(identity)) {
if (flags_1.isAutoDiscoveryCodeSignIdentity()) {
return _findIdentity(certType, null, keychain);
}
else {
return Promise.resolve(null);
}
}
else {
identity = identity.trim();
for (const prefix of exports.appleCertificatePrefixes) {
checkPrefix(identity, prefix);
}
return _findIdentity(certType, identity, keychain);
}
}
exports.findIdentity = findIdentity;
function checkPrefix(name, prefix) {
if (name.startsWith(prefix)) {
throw new util_1.InvalidConfigurationError(`Please remove prefix "${prefix}" from the specified name — appropriate certificate will be chosen automatically`);
}
}
//# sourceMappingURL=macCodeSign.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,38 @@
import { WindowsConfiguration } from "../options/winOptions";
import { VmManager } from "../vm/vm";
import { WinPackager } from "../winPackager";
export declare function getSignVendorPath(): Promise<string>;
export declare type CustomWindowsSign = (configuration: CustomWindowsSignTaskConfiguration, packager?: WinPackager) => Promise<any>;
export interface WindowsSignOptions {
readonly path: string;
readonly name?: string | null;
readonly cscInfo?: FileCodeSigningInfo | CertificateFromStoreInfo | null;
readonly site?: string | null;
readonly options: WindowsConfiguration;
}
export interface WindowsSignTaskConfiguration extends WindowsSignOptions {
resultOutputPath?: string;
hash: string;
isNest: boolean;
}
export interface CustomWindowsSignTaskConfiguration extends WindowsSignTaskConfiguration {
computeSignToolArgs(isWin: boolean): Array<string>;
}
export declare function sign(options: WindowsSignOptions, packager: WinPackager): Promise<void>;
export interface FileCodeSigningInfo {
readonly file: string;
readonly password: string | null;
}
export declare function getCertInfo(file: string, password: string): Promise<CertificateInfo>;
export interface CertificateInfo {
readonly commonName: string;
readonly bloodyMicrosoftSubjectDn: string;
}
export interface CertificateFromStoreInfo {
thumbprint: string;
subject: string;
store: string;
isLocalMachineStore: boolean;
}
export declare function getCertificateFromStoreInfo(options: WindowsConfiguration, vm: VmManager): Promise<CertificateFromStoreInfo>;
export declare function doSign(configuration: CustomWindowsSignTaskConfiguration, packager: WinPackager): Promise<void>;

View file

@ -0,0 +1,251 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isOldWin6 = exports.doSign = exports.getCertificateFromStoreInfo = exports.getCertInfo = exports.sign = exports.getSignVendorPath = void 0;
const util_1 = require("builder-util/out/util");
const binDownload_1 = require("../binDownload");
const appBuilder_1 = require("../util/appBuilder");
const bundledTool_1 = require("../util/bundledTool");
const fs_extra_1 = require("fs-extra");
const os = require("os");
const path = require("path");
const platformPackager_1 = require("../platformPackager");
const flags_1 = require("../util/flags");
const vm_1 = require("../vm/vm");
function getSignVendorPath() {
return binDownload_1.getBin("winCodeSign");
}
exports.getSignVendorPath = getSignVendorPath;
async function sign(options, packager) {
let hashes = options.options.signingHashAlgorithms;
// msi does not support dual-signing
if (options.path.endsWith(".msi")) {
hashes = [hashes != null && !hashes.includes("sha1") ? "sha256" : "sha1"];
}
else if (options.path.endsWith(".appx")) {
hashes = ["sha256"];
}
else if (hashes == null) {
hashes = ["sha1", "sha256"];
}
else {
hashes = Array.isArray(hashes) ? hashes : [hashes];
}
const executor = platformPackager_1.resolveFunction(options.options.sign, "sign") || doSign;
let isNest = false;
for (const hash of hashes) {
const taskConfiguration = { ...options, hash, isNest };
await Promise.resolve(executor({
...taskConfiguration,
computeSignToolArgs: isWin => computeSignToolArgs(taskConfiguration, isWin),
}, packager));
isNest = true;
if (taskConfiguration.resultOutputPath != null) {
await fs_extra_1.rename(taskConfiguration.resultOutputPath, options.path);
}
}
}
exports.sign = sign;
async function getCertInfo(file, password) {
let result = null;
const errorMessagePrefix = "Cannot extract publisher name from code signing certificate. As workaround, set win.publisherName. Error: ";
try {
result = await appBuilder_1.executeAppBuilderAsJson(["certificate-info", "--input", file, "--password", password]);
}
catch (e) {
throw new Error(`${errorMessagePrefix}${e.stack || e}`);
}
if (result.error != null) {
// noinspection ExceptionCaughtLocallyJS
throw new util_1.InvalidConfigurationError(`${errorMessagePrefix}${result.error}`);
}
return result;
}
exports.getCertInfo = getCertInfo;
async function getCertificateFromStoreInfo(options, vm) {
const certificateSubjectName = options.certificateSubjectName;
const certificateSha1 = options.certificateSha1 ? options.certificateSha1.toUpperCase() : options.certificateSha1;
// ExcludeProperty doesn't work, so, we cannot exclude RawData, it is ok
// powershell can return object if the only item
const rawResult = await vm.exec("powershell.exe", [
"-NoProfile",
"-NonInteractive",
"-Command",
"Get-ChildItem -Recurse Cert: -CodeSigningCert | Select-Object -Property Subject,PSParentPath,Thumbprint | ConvertTo-Json -Compress",
]);
const certList = rawResult.length === 0 ? [] : util_1.asArray(JSON.parse(rawResult));
for (const certInfo of certList) {
if ((certificateSubjectName != null && !certInfo.Subject.includes(certificateSubjectName)) ||
(certificateSha1 != null && certInfo.Thumbprint.toUpperCase() !== certificateSha1)) {
continue;
}
const parentPath = certInfo.PSParentPath;
const store = parentPath.substring(parentPath.lastIndexOf("\\") + 1);
util_1.log.debug({ store, PSParentPath: parentPath }, "auto-detect certificate store");
// https://github.com/electron-userland/electron-builder/issues/1717
const isLocalMachineStore = parentPath.includes("Certificate::LocalMachine");
util_1.log.debug(null, "auto-detect using of LocalMachine store");
return {
thumbprint: certInfo.Thumbprint,
subject: certInfo.Subject,
store,
isLocalMachineStore,
};
}
throw new Error(`Cannot find certificate ${certificateSubjectName || certificateSha1}, all certs: ${rawResult}`);
}
exports.getCertificateFromStoreInfo = getCertificateFromStoreInfo;
async function doSign(configuration, packager) {
// https://github.com/electron-userland/electron-builder/pull/1944
const timeout = parseInt(process.env.SIGNTOOL_TIMEOUT, 10) || 10 * 60 * 1000;
// unify logic of signtool path location
const toolInfo = await getToolPath();
const tool = toolInfo.path;
// decide runtime argument by cases
let args;
let env = process.env;
let vm;
if (configuration.path.endsWith(".appx") || !("file" in configuration.cscInfo) /* certificateSubjectName and other such options */) {
vm = await packager.vm.value;
args = computeSignToolArgs(configuration, true, vm);
}
else {
vm = new vm_1.VmManager();
args = configuration.computeSignToolArgs(process.platform === "win32");
if (toolInfo.env != null) {
env = toolInfo.env;
}
}
try {
await vm.exec(tool, args, { timeout, env });
}
catch (e) {
if (e.message.includes("The file is being used by another process") || e.message.includes("The specified timestamp server either could not be reached")) {
util_1.log.warn(`First attempt to code sign failed, another attempt will be made in 15 seconds: ${e.message}`);
await new Promise((resolve, reject) => {
setTimeout(() => {
vm.exec(tool, args, { timeout, env }).then(resolve).catch(reject);
}, 15000);
});
}
throw e;
}
}
exports.doSign = doSign;
// on windows be aware of http://stackoverflow.com/a/32640183/1910191
function computeSignToolArgs(options, isWin, vm = new vm_1.VmManager()) {
const inputFile = vm.toVmFile(options.path);
const outputPath = isWin ? inputFile : getOutputPath(inputFile, options.hash);
if (!isWin) {
options.resultOutputPath = outputPath;
}
const args = isWin ? ["sign"] : ["-in", inputFile, "-out", outputPath];
if (process.env.ELECTRON_BUILDER_OFFLINE !== "true") {
const timestampingServiceUrl = options.options.timeStampServer || "http://timestamp.digicert.com";
if (isWin) {
args.push(options.isNest || options.hash === "sha256" ? "/tr" : "/t", options.isNest || options.hash === "sha256" ? options.options.rfc3161TimeStampServer || "http://timestamp.digicert.com" : timestampingServiceUrl);
}
else {
args.push("-t", timestampingServiceUrl);
}
}
const certificateFile = options.cscInfo.file;
if (certificateFile == null) {
const cscInfo = options.cscInfo;
const subjectName = cscInfo.thumbprint;
if (!isWin) {
throw new Error(`${subjectName == null ? "certificateSha1" : "certificateSubjectName"} supported only on Windows`);
}
args.push("/sha1", cscInfo.thumbprint);
args.push("/s", cscInfo.store);
if (cscInfo.isLocalMachineStore) {
args.push("/sm");
}
}
else {
const certExtension = path.extname(certificateFile);
if (certExtension === ".p12" || certExtension === ".pfx") {
args.push(isWin ? "/f" : "-pkcs12", vm.toVmFile(certificateFile));
}
else {
throw new Error(`Please specify pkcs12 (.p12/.pfx) file, ${certificateFile} is not correct`);
}
}
if (!isWin || options.hash !== "sha1") {
args.push(isWin ? "/fd" : "-h", options.hash);
if (isWin && process.env.ELECTRON_BUILDER_OFFLINE !== "true") {
args.push("/td", "sha256");
}
}
if (options.name) {
args.push(isWin ? "/d" : "-n", options.name);
}
if (options.site) {
args.push(isWin ? "/du" : "-i", options.site);
}
// msi does not support dual-signing
if (options.isNest) {
args.push(isWin ? "/as" : "-nest");
}
const password = options.cscInfo == null ? null : options.cscInfo.password;
if (password) {
args.push(isWin ? "/p" : "-pass", password);
}
if (options.options.additionalCertificateFile) {
args.push(isWin ? "/ac" : "-ac", vm.toVmFile(options.options.additionalCertificateFile));
}
const httpsProxyFromEnv = process.env.HTTPS_PROXY;
if (!isWin && httpsProxyFromEnv != null && httpsProxyFromEnv.length) {
args.push("-p", httpsProxyFromEnv);
}
if (isWin) {
// https://github.com/electron-userland/electron-builder/issues/2875#issuecomment-387233610
args.push("/debug");
// must be last argument
args.push(inputFile);
}
return args;
}
function getOutputPath(inputPath, hash) {
const extension = path.extname(inputPath);
return path.join(path.dirname(inputPath), `${path.basename(inputPath, extension)}-signed-${hash}${extension}`);
}
/** @internal */
function isOldWin6() {
const winVersion = os.release();
return winVersion.startsWith("6.") && !winVersion.startsWith("6.3");
}
exports.isOldWin6 = isOldWin6;
function getWinSignTool(vendorPath) {
// use modern signtool on Windows Server 2012 R2 to be able to sign AppX
if (isOldWin6()) {
return path.join(vendorPath, "windows-6", "signtool.exe");
}
else {
return path.join(vendorPath, "windows-10", process.arch, "signtool.exe");
}
}
async function getToolPath() {
if (flags_1.isUseSystemSigncode()) {
return { path: "osslsigncode" };
}
const result = process.env.SIGNTOOL_PATH;
if (result) {
return { path: result };
}
const vendorPath = await getSignVendorPath();
if (process.platform === "win32") {
// use modern signtool on Windows Server 2012 R2 to be able to sign AppX
return { path: getWinSignTool(vendorPath) };
}
else if (process.platform === "darwin") {
const toolDirPath = path.join(vendorPath, process.platform, "10.12");
return {
path: path.join(toolDirPath, "osslsigncode"),
env: bundledTool_1.computeToolEnv([path.join(toolDirPath, "lib")]),
};
}
else {
return { path: path.join(vendorPath, process.platform, "osslsigncode") };
}
}
//# sourceMappingURL=windowsCodeSign.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,274 @@
import { Arch } from "builder-util";
import { BeforeBuildContext, Target } from "./core";
import { ElectronBrandingOptions, ElectronDownloadOptions } from "./electron/ElectronFramework";
import { PrepareApplicationStageDirectoryOptions } from "./Framework";
import { AppXOptions } from "./options/AppXOptions";
import { AppImageOptions, DebOptions, FlatpakOptions, LinuxConfiguration, LinuxTargetSpecificOptions } from "./options/linuxOptions";
import { DmgOptions, MacConfiguration, MasConfiguration } from "./options/macOptions";
import { MsiOptions } from "./options/MsiOptions";
import { PkgOptions } from "./options/pkgOptions";
import { PlatformSpecificBuildOptions } from "./options/PlatformSpecificBuildOptions";
import { SnapOptions } from "./options/SnapOptions";
import { SquirrelWindowsOptions } from "./options/SquirrelWindowsOptions";
import { WindowsConfiguration } from "./options/winOptions";
import { BuildResult } from "./packager";
import { ArtifactBuildStarted, ArtifactCreated } from "./packagerApi";
import { PlatformPackager } from "./platformPackager";
import { NsisOptions, NsisWebOptions, PortableOptions } from "./targets/nsis/nsisOptions";
/**
* Configuration Options
*/
export interface Configuration extends PlatformSpecificBuildOptions {
/**
* The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as
* [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported). It is strongly recommended that an explicit ID is set.
* @default com.electron.${name}
*/
readonly appId?: string | null;
/**
* As [name](#Metadata-name), but allows you to specify a product name for your executable which contains spaces and other special characters not allowed in the [name property](https://docs.npmjs.com/files/package.json#name).
* If not specified inside of the `build` configuration, `productName` property defined at the top level of `package.json` is used. If not specified at the top level of `package.json`, [name property](https://docs.npmjs.com/files/package.json#name) is used.
*/
readonly productName?: string | null;
/**
* The human-readable copyright line for the app.
* @default Copyright © year ${author}
*/
readonly copyright?: string | null;
readonly directories?: MetadataDirectories | null;
/**
* Options related to how build macOS targets.
*/
readonly mac?: MacConfiguration | null;
/**
* MAS (Mac Application Store) options.
*/
readonly mas?: MasConfiguration | null;
/**
* MAS (Mac Application Store) development options (`mas-dev` target).
*/
readonly masDev?: MasConfiguration | null;
/**
* macOS DMG options.
*/
readonly dmg?: DmgOptions | null;
/**
* macOS PKG options.
*/
readonly pkg?: PkgOptions | null;
/**
* Options related to how build Windows targets.
*/
readonly win?: WindowsConfiguration | null;
readonly nsis?: NsisOptions | null;
readonly nsisWeb?: NsisWebOptions | null;
readonly portable?: PortableOptions | null;
readonly appx?: AppXOptions | null;
/** @private */
readonly msi?: MsiOptions | null;
readonly squirrelWindows?: SquirrelWindowsOptions | null;
/**
* Options related to how build Linux targets.
*/
readonly linux?: LinuxConfiguration | null;
/**
* Debian package options.
*/
readonly deb?: DebOptions | null;
/**
* Snap options.
*/
readonly snap?: SnapOptions | null;
/**
* AppImage options.
*/
readonly appImage?: AppImageOptions | null;
/**
* Flatpak options.
*/
readonly flatpak?: FlatpakOptions | null;
readonly pacman?: LinuxTargetSpecificOptions | null;
readonly rpm?: LinuxTargetSpecificOptions | null;
readonly freebsd?: LinuxTargetSpecificOptions | null;
readonly p5p?: LinuxTargetSpecificOptions | null;
readonly apk?: LinuxTargetSpecificOptions | null;
/**
* Whether to include *all* of the submodules node_modules directories
* @default false
*/
includeSubNodeModules?: boolean;
/**
* Whether to build the application native dependencies from source.
* @default false
*/
buildDependenciesFromSource?: boolean;
/**
* Whether to execute `node-gyp rebuild` before starting to package the app.
*
* Don't [use](https://github.com/electron-userland/electron-builder/issues/683#issuecomment-241214075) [npm](http://electron.atom.io/docs/tutorial/using-native-node-modules/#using-npm) (neither `.npmrc`) for configuring electron headers. Use `electron-builder node-gyp-rebuild` instead.
* @default false
*/
readonly nodeGypRebuild?: boolean;
/**
* Additional command line arguments to use when installing app native deps.
*/
readonly npmArgs?: Array<string> | string | null;
/**
* Whether to [rebuild](https://docs.npmjs.com/cli/rebuild) native dependencies before starting to package the app.
* @default true
*/
readonly npmRebuild?: boolean;
/**
* The build number. Maps to the `--iteration` flag for builds using FPM on Linux.
* If not defined, then it will fallback to `BUILD_NUMBER` or `TRAVIS_BUILD_NUMBER` or `APPVEYOR_BUILD_NUMBER` or `CIRCLE_BUILD_NUM` or `BUILD_BUILDNUMBER` or `CI_PIPELINE_IID` env.
*/
readonly buildNumber?: string | null;
/**
* The build version. Maps to the `CFBundleVersion` on macOS, and `FileVersion` metadata property on Windows. Defaults to the `version`.
* If `buildVersion` is not defined and `buildNumber` (or one of the `buildNumber` envs) is defined, it will be used as a build version (`version.buildNumber`).
*/
readonly buildVersion?: string | null;
/**
* Whether to use [electron-compile](http://github.com/electron/electron-compile) to compile app. Defaults to `true` if `electron-compile` in the dependencies. And `false` if in the `devDependencies` or doesn't specified.
*/
readonly electronCompile?: boolean;
/**
* Returns the path to custom Electron build (e.g. `~/electron/out/R`). Zip files must follow the pattern `electron-v${version}-${platformName}-${arch}.zip`, otherwise it will be assumed to be an unpacked Electron app directory
*/
readonly electronDist?: string | ((options: PrepareApplicationStageDirectoryOptions) => string);
/**
* The [electron-download](https://github.com/electron-userland/electron-download#usage) options.
*/
readonly electronDownload?: ElectronDownloadOptions;
/**
* The branding used by Electron's distributables. This is needed if a fork has modified Electron's BRANDING.json file.
*/
readonly electronBranding?: ElectronBrandingOptions;
/**
* The version of electron you are packaging for. Defaults to version of `electron`, `electron-prebuilt` or `electron-prebuilt-compile` dependency.
*/
electronVersion?: string | null;
/**
* The name of a built-in configuration preset (currently, only `react-cra` is supported) or any number of paths to config files (relative to project dir).
*
* The latter allows to mixin a config from multiple other configs, as if you `Object.assign` them, but properly combine `files` glob patterns.
*
* If `react-scripts` in the app dependencies, `react-cra` will be set automatically. Set to `null` to disable automatic detection.
*/
extends?: Array<string> | string | null;
/**
* Inject properties to `package.json`.
*/
readonly extraMetadata?: any;
/**
* Whether to fail if the application is not signed (to prevent unsigned app if code signing configuration is not correct).
* @default false
*/
readonly forceCodeSigning?: boolean;
/**
* *libui-based frameworks only* The version of NodeJS you are packaging for.
* You can set it to `current` to set the Node.js version that you use to run.
*/
readonly nodeVersion?: string | null;
/**
* *libui-based frameworks only* The version of LaunchUI you are packaging for. Applicable for Windows only. Defaults to version suitable for used framework version.
*/
readonly launchUiVersion?: boolean | string | null;
/**
* The framework name. One of `electron`, `proton`, `libui`. Defaults to `electron`.
*/
readonly framework?: string | null;
/**
* The function (or path to file or module id) to be [run before pack](#beforepack)
*/
readonly beforePack?: ((context: BeforePackContext) => Promise<any> | any) | string | null;
/**
* The function (or path to file or module id) to be [run after pack](#afterpack) (but before pack into distributable format and sign).
*/
readonly afterPack?: ((context: AfterPackContext) => Promise<any> | any) | string | null;
/**
* The function (or path to file or module id) to be [run after pack and sign](#aftersign) (but before pack into distributable format).
*/
readonly afterSign?: ((context: AfterPackContext) => Promise<any> | any) | string | null;
/**
* The function (or path to file or module id) to be run on artifact build start.
*/
readonly artifactBuildStarted?: ((context: ArtifactBuildStarted) => Promise<any> | any) | string | null;
/**
* The function (or path to file or module id) to be run on artifact build completed.
*/
readonly artifactBuildCompleted?: ((context: ArtifactCreated) => Promise<any> | any) | string | null;
/**
* The function (or path to file or module id) to be [run after all artifacts are build](#afterAllArtifactBuild).
*/
readonly afterAllArtifactBuild?: ((context: BuildResult) => Promise<Array<string>> | Array<string>) | string | null;
/**
* MSI project created on disk - not packed into .msi package yet.
*/
readonly msiProjectCreated?: ((path: string) => Promise<any> | any) | string | null;
/**
* Appx manifest created on disk - not packed into .appx package yet.
*/
readonly appxManifestCreated?: ((path: string) => Promise<any> | any) | string | null;
/**
* The function (or path to file or module id) to be [run on each node module](#onnodemodulefile) file.
*/
readonly onNodeModuleFile?: ((file: string) => void) | string | null;
/**
* The function (or path to file or module id) to be run before dependencies are installed or rebuilt. Works when `npmRebuild` is set to `true`. Resolving to `false` will skip dependencies install or rebuild.
*
* If provided and `node_modules` are missing, it will not invoke production dependencies check.
*/
readonly beforeBuild?: ((context: BeforeBuildContext) => Promise<any>) | string | null;
/**
* Whether to build using Electron Build Service if target not supported on current OS.
* @default true
*/
readonly remoteBuild?: boolean;
/**
* Whether to include PDB files.
* @default false
*/
readonly includePdb?: boolean;
/**
* Whether to remove `scripts` field from `package.json` files.
*
* @default true
*/
readonly removePackageScripts?: boolean;
/**
* Whether to remove `keywords` field from `package.json` files.
*
* @default true
*/
readonly removePackageKeywords?: boolean;
}
interface PackContext {
readonly outDir: string;
readonly appOutDir: string;
readonly packager: PlatformPackager<any>;
readonly electronPlatformName: string;
readonly arch: Arch;
readonly targets: Array<Target>;
}
export declare type AfterPackContext = PackContext;
export declare type BeforePackContext = PackContext;
export interface MetadataDirectories {
/**
* The path to build resources.
*
* Please note build resources are not packed into the app. If you need to use some files, e.g. as tray icon, please include required files explicitly: `"files": ["**\/*", "build/icon.*"]`
* @default build
*/
readonly buildResources?: string | null;
/**
* The output directory. [File macros](/file-patterns#file-macros) are supported.
* @default dist
*/
readonly output?: string | null;
/**
* The application directory (containing the application package.json), defaults to `app`, `www` or working directory.
*/
readonly app?: string | null;
}
export {};

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=configuration.js.map

File diff suppressed because one or more lines are too long

60
electron/node_modules/app-builder-lib/out/core.d.ts generated vendored Normal file
View file

@ -0,0 +1,60 @@
/// <reference types="node" />
import { Arch, ArchType } from "builder-util";
import { AllPublishOptions } from "builder-util-runtime";
export declare type Publish = AllPublishOptions | Array<AllPublishOptions> | null;
export declare type TargetConfigType = Array<string | TargetConfiguration> | string | TargetConfiguration | null;
export interface TargetConfiguration {
/**
* The target name. e.g. `snap`.
*/
readonly target: string;
/**
* The arch or list of archs.
*/
readonly arch?: Array<ArchType> | ArchType;
}
export declare class Platform {
name: string;
buildConfigurationKey: string;
nodeName: NodeJS.Platform;
static MAC: Platform;
static LINUX: Platform;
static WINDOWS: Platform;
constructor(name: string, buildConfigurationKey: string, nodeName: NodeJS.Platform);
toString(): string;
createTarget(type?: string | Array<string> | null, ...archs: Array<Arch>): Map<Platform, Map<Arch, Array<string>>>;
static current(): Platform;
static fromString(name: string): Platform;
}
export declare abstract class Target {
readonly name: string;
readonly isAsyncSupported: boolean;
abstract readonly outDir: string;
abstract readonly options: TargetSpecificOptions | null | undefined;
protected constructor(name: string, isAsyncSupported?: boolean);
checkOptions(): Promise<any>;
abstract build(appOutDir: string, arch: Arch): Promise<any>;
finishBuild(): Promise<any>;
}
export interface TargetSpecificOptions {
/**
The [artifact file name template](/configuration/configuration#artifact-file-name-template).
*/
readonly artifactName?: string | null;
publish?: Publish;
}
export declare const DEFAULT_TARGET = "default";
export declare const DIR_TARGET = "dir";
export declare type CompressionLevel = "store" | "normal" | "maximum";
export interface BeforeBuildContext {
readonly appDir: string;
readonly electronVersion: string;
readonly platform: Platform;
readonly arch: string;
}
export interface SourceRepositoryInfo {
type?: string;
domain?: string;
user: string;
project: string;
}

63
electron/node_modules/app-builder-lib/out/core.js generated vendored Normal file
View file

@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DIR_TARGET = exports.DEFAULT_TARGET = exports.Target = exports.Platform = void 0;
const builder_util_1 = require("builder-util");
class Platform {
constructor(name, buildConfigurationKey, nodeName) {
this.name = name;
this.buildConfigurationKey = buildConfigurationKey;
this.nodeName = nodeName;
}
toString() {
return this.name;
}
createTarget(type, ...archs) {
if (type == null && (archs == null || archs.length === 0)) {
return new Map([[this, new Map()]]);
}
const archToType = new Map();
for (const arch of archs == null || archs.length === 0 ? [builder_util_1.archFromString(process.arch)] : archs) {
archToType.set(arch, type == null ? [] : Array.isArray(type) ? type : [type]);
}
return new Map([[this, archToType]]);
}
static current() {
return Platform.fromString(process.platform);
}
static fromString(name) {
name = name.toLowerCase();
switch (name) {
case Platform.MAC.nodeName:
case Platform.MAC.name:
return Platform.MAC;
case Platform.WINDOWS.nodeName:
case Platform.WINDOWS.name:
case Platform.WINDOWS.buildConfigurationKey:
return Platform.WINDOWS;
case Platform.LINUX.nodeName:
return Platform.LINUX;
default:
throw new Error(`Unknown platform: ${name}`);
}
}
}
exports.Platform = Platform;
Platform.MAC = new Platform("mac", "mac", "darwin");
Platform.LINUX = new Platform("linux", "linux", "linux");
Platform.WINDOWS = new Platform("windows", "win", "win32");
class Target {
constructor(name, isAsyncSupported = true) {
this.name = name;
this.isAsyncSupported = isAsyncSupported;
}
async checkOptions() {
// ignore
}
finishBuild() {
return Promise.resolve();
}
}
exports.Target = Target;
exports.DEFAULT_TARGET = "default";
exports.DIR_TARGET = "dir";
//# sourceMappingURL=core.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,33 @@
import { Configuration } from "../configuration";
import { Framework } from "../Framework";
import { Packager } from "../index";
export declare type ElectronPlatformName = "darwin" | "linux" | "win32" | "mas";
/**
* Electron distributables branding options.
* @see [Electron BRANDING.json](https://github.com/electron/electron/blob/master/shell/app/BRANDING.json).
*/
export interface ElectronBrandingOptions {
projectName?: string;
productName?: string;
}
export declare function createBrandingOpts(opts: Configuration): Required<ElectronBrandingOptions>;
export interface ElectronDownloadOptions {
version?: string;
/**
* The [cache location](https://github.com/electron-userland/electron-download#cache-location).
*/
cache?: string | null;
/**
* The mirror.
*/
mirror?: string | null;
/** @private */
customDir?: string | null;
/** @private */
customFilename?: string | null;
strictSSL?: boolean;
isVerifyChecksum?: boolean;
platform?: ElectronPlatformName;
arch?: string;
}
export declare function createElectronFrameworkSupport(configuration: Configuration, packager: Packager): Promise<Framework>;

View file

@ -0,0 +1,163 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createElectronFrameworkSupport = exports.createBrandingOpts = void 0;
const bluebird_lst_1 = require("bluebird-lst");
const builder_util_1 = require("builder-util");
const fs_1 = require("builder-util/out/fs");
const fs_extra_1 = require("fs-extra");
const lazy_val_1 = require("lazy-val");
const path = require("path");
const index_1 = require("../index");
const platformPackager_1 = require("../platformPackager");
const pathManager_1 = require("../util/pathManager");
const electronMac_1 = require("./electronMac");
const electronVersion_1 = require("./electronVersion");
const fs = require("fs/promises");
function createBrandingOpts(opts) {
var _a, _b;
return {
projectName: ((_a = opts.electronBranding) === null || _a === void 0 ? void 0 : _a.projectName) || "electron",
productName: ((_b = opts.electronBranding) === null || _b === void 0 ? void 0 : _b.productName) || "Electron",
};
}
exports.createBrandingOpts = createBrandingOpts;
function createDownloadOpts(opts, platform, arch, electronVersion) {
return {
platform,
arch,
version: electronVersion,
...opts.electronDownload,
};
}
async function beforeCopyExtraFiles(options) {
const packager = options.packager;
const appOutDir = options.appOutDir;
const electronBranding = createBrandingOpts(packager.config);
if (packager.platform === index_1.Platform.LINUX) {
if (!platformPackager_1.isSafeToUnpackElectronOnRemoteBuildServer(packager)) {
const linuxPackager = packager;
const executable = path.join(appOutDir, linuxPackager.executableName);
await fs_extra_1.rename(path.join(appOutDir, electronBranding.projectName), executable);
}
}
else if (packager.platform === index_1.Platform.WINDOWS) {
const executable = path.join(appOutDir, `${packager.appInfo.productFilename}.exe`);
await fs_extra_1.rename(path.join(appOutDir, `${electronBranding.projectName}.exe`), executable);
}
else {
await electronMac_1.createMacApp(packager, appOutDir, options.asarIntegrity, options.platformName === "mas");
const wantedLanguages = builder_util_1.asArray(packager.platformSpecificBuildOptions.electronLanguages);
if (wantedLanguages.length === 0) {
return;
}
// noinspection SpellCheckingInspection
const langFileExt = ".lproj";
const resourcesDir = packager.getResourcesDir(appOutDir);
await bluebird_lst_1.default.map(fs_extra_1.readdir(resourcesDir), file => {
if (!file.endsWith(langFileExt)) {
return;
}
const language = file.substring(0, file.length - langFileExt.length);
if (!wantedLanguages.includes(language)) {
return fs.rm(path.join(resourcesDir, file), { recursive: true, force: true });
}
return;
}, fs_1.CONCURRENCY);
}
}
class ElectronFramework {
constructor(name, version, distMacOsAppName) {
this.name = name;
this.version = version;
this.distMacOsAppName = distMacOsAppName;
// noinspection JSUnusedGlobalSymbols
this.macOsDefaultTargets = ["zip", "dmg"];
// noinspection JSUnusedGlobalSymbols
this.defaultAppIdPrefix = "com.electron.";
// noinspection JSUnusedGlobalSymbols
this.isCopyElevateHelper = true;
// noinspection JSUnusedGlobalSymbols
this.isNpmRebuildRequired = true;
}
getDefaultIcon(platform) {
if (platform === index_1.Platform.LINUX) {
return path.join(pathManager_1.getTemplatePath("icons"), "electron-linux");
}
else {
// default icon is embedded into app skeleton
return null;
}
}
prepareApplicationStageDirectory(options) {
return unpack(options, createDownloadOpts(options.packager.config, options.platformName, options.arch, this.version), this.distMacOsAppName);
}
beforeCopyExtraFiles(options) {
return beforeCopyExtraFiles(options);
}
}
async function createElectronFrameworkSupport(configuration, packager) {
let version = configuration.electronVersion;
if (version == null) {
// for prepacked app asar no dev deps in the app.asar
if (packager.isPrepackedAppAsar) {
version = await electronVersion_1.getElectronVersionFromInstalled(packager.projectDir);
if (version == null) {
throw new Error(`Cannot compute electron version for prepacked asar`);
}
}
else {
version = await electronVersion_1.computeElectronVersion(packager.projectDir, new lazy_val_1.Lazy(() => Promise.resolve(packager.metadata)));
}
configuration.electronVersion = version;
}
const branding = createBrandingOpts(configuration);
return new ElectronFramework(branding.projectName, version, `${branding.productName}.app`);
}
exports.createElectronFrameworkSupport = createElectronFrameworkSupport;
async function unpack(prepareOptions, options, distMacOsAppName) {
const { packager, appOutDir, platformName } = prepareOptions;
const electronDist = packager.config.electronDist;
let dist = typeof electronDist === "function" ? electronDist(prepareOptions) : electronDist;
if (dist != null) {
const zipFile = `electron-v${options.version}-${platformName}-${options.arch}.zip`;
const resolvedDist = path.isAbsolute(dist) ? dist : path.resolve(packager.projectDir, dist);
if ((await fs_1.statOrNull(path.join(resolvedDist, zipFile))) != null) {
builder_util_1.log.info({ resolvedDist, zipFile }, "Resolved electronDist");
options.cache = resolvedDist;
dist = null;
}
}
let isFullCleanup = false;
if (dist == null) {
if (platformPackager_1.isSafeToUnpackElectronOnRemoteBuildServer(packager)) {
return;
}
await builder_util_1.executeAppBuilder(["unpack-electron", "--configuration", JSON.stringify([options]), "--output", appOutDir, "--distMacOsAppName", distMacOsAppName]);
}
else {
isFullCleanup = true;
const source = packager.getElectronSrcDir(dist);
const destination = packager.getElectronDestinationDir(appOutDir);
builder_util_1.log.info({ source, destination }, "copying Electron");
await fs_extra_1.emptyDir(appOutDir);
await fs_1.copyDir(source, destination, {
isUseHardLink: fs_1.DO_NOT_USE_HARD_LINKS,
});
}
await cleanupAfterUnpack(prepareOptions, distMacOsAppName, isFullCleanup);
}
function cleanupAfterUnpack(prepareOptions, distMacOsAppName, isFullCleanup) {
const out = prepareOptions.appOutDir;
const isMac = prepareOptions.packager.platform === index_1.Platform.MAC;
const resourcesPath = isMac ? path.join(out, distMacOsAppName, "Contents", "Resources") : path.join(out, "resources");
return Promise.all([
isFullCleanup ? fs_1.unlinkIfExists(path.join(resourcesPath, "default_app.asar")) : Promise.resolve(),
isFullCleanup ? fs_1.unlinkIfExists(path.join(out, "version")) : Promise.resolve(),
isMac
? Promise.resolve()
: fs_extra_1.rename(path.join(out, "LICENSE"), path.join(out, "LICENSE.electron.txt")).catch(() => {
/* ignore */
}),
]);
}
//# sourceMappingURL=ElectronFramework.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,259 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMacApp = void 0;
const bluebird_lst_1 = require("bluebird-lst");
const builder_util_1 = require("builder-util");
const fs_1 = require("builder-util/out/fs");
const promises_1 = require("fs/promises");
const path = require("path");
const appInfo_1 = require("../appInfo");
const platformPackager_1 = require("../platformPackager");
const appBuilder_1 = require("../util/appBuilder");
const ElectronFramework_1 = require("./ElectronFramework");
function doRename(basePath, oldName, newName) {
return promises_1.rename(path.join(basePath, oldName), path.join(basePath, newName));
}
function moveHelpers(helperSuffixes, frameworksPath, appName, prefix) {
return bluebird_lst_1.default.map(helperSuffixes, suffix => {
const executableBasePath = path.join(frameworksPath, `${prefix}${suffix}.app`, "Contents", "MacOS");
return doRename(executableBasePath, `${prefix}${suffix}`, appName + suffix).then(() => doRename(frameworksPath, `${prefix}${suffix}.app`, `${appName}${suffix}.app`));
});
}
function getAvailableHelperSuffixes(helperEHPlist, helperNPPlist, helperRendererPlist, helperPluginPlist, helperGPUPlist) {
const result = [" Helper"];
if (helperEHPlist != null) {
result.push(" Helper EH");
}
if (helperNPPlist != null) {
result.push(" Helper NP");
}
if (helperRendererPlist != null) {
result.push(" Helper (Renderer)");
}
if (helperPluginPlist != null) {
result.push(" Helper (Plugin)");
}
if (helperGPUPlist != null) {
result.push(" Helper (GPU)");
}
return result;
}
/** @internal */
async function createMacApp(packager, appOutDir, asarIntegrity, isMas) {
const appInfo = packager.appInfo;
const appFilename = appInfo.productFilename;
const electronBranding = ElectronFramework_1.createBrandingOpts(packager.config);
const contentsPath = path.join(appOutDir, packager.info.framework.distMacOsAppName, "Contents");
const frameworksPath = path.join(contentsPath, "Frameworks");
const loginItemPath = path.join(contentsPath, "Library", "LoginItems");
const appPlistFilename = path.join(contentsPath, "Info.plist");
const helperPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper.app`, "Contents", "Info.plist");
const helperEHPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper EH.app`, "Contents", "Info.plist");
const helperNPPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper NP.app`, "Contents", "Info.plist");
const helperRendererPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (Renderer).app`, "Contents", "Info.plist");
const helperPluginPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (Plugin).app`, "Contents", "Info.plist");
const helperGPUPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (GPU).app`, "Contents", "Info.plist");
const helperLoginPlistFilename = path.join(loginItemPath, `${electronBranding.productName} Login Helper.app`, "Contents", "Info.plist");
const plistContent = await appBuilder_1.executeAppBuilderAsJson([
"decode-plist",
"-f",
appPlistFilename,
"-f",
helperPlistFilename,
"-f",
helperEHPlistFilename,
"-f",
helperNPPlistFilename,
"-f",
helperRendererPlistFilename,
"-f",
helperPluginPlistFilename,
"-f",
helperGPUPlistFilename,
"-f",
helperLoginPlistFilename,
]);
if (plistContent[0] == null) {
throw new Error("corrupted Electron dist");
}
const appPlist = plistContent[0];
const helperPlist = plistContent[1];
const helperEHPlist = plistContent[2];
const helperNPPlist = plistContent[3];
const helperRendererPlist = plistContent[4];
const helperPluginPlist = plistContent[5];
const helperGPUPlist = plistContent[6];
const helperLoginPlist = plistContent[7];
// if an extend-info file was supplied, copy its contents in first
if (plistContent[8] != null) {
Object.assign(appPlist, plistContent[8]);
}
const buildMetadata = packager.config;
/**
* Configure bundleIdentifier for the generic Electron Helper process
*
* This was the only Helper in Electron 5 and before. Allow users to configure
* the bundleIdentifier for continuity.
*/
const oldHelperBundleId = buildMetadata["helper-bundle-id"];
if (oldHelperBundleId != null) {
builder_util_1.log.warn("build.helper-bundle-id is deprecated, please set as build.mac.helperBundleId");
}
const helperBundleIdentifier = appInfo_1.filterCFBundleIdentifier(packager.platformSpecificBuildOptions.helperBundleId || oldHelperBundleId || `${appInfo.macBundleIdentifier}.helper`);
await packager.applyCommonInfo(appPlist, contentsPath);
// required for electron-updater proxy
if (!isMas) {
configureLocalhostAts(appPlist);
}
helperPlist.CFBundleExecutable = `${appFilename} Helper`;
helperPlist.CFBundleDisplayName = `${appInfo.productName} Helper`;
helperPlist.CFBundleIdentifier = helperBundleIdentifier;
helperPlist.CFBundleVersion = appPlist.CFBundleVersion;
/**
* Configure bundleIdentifier for Electron 5+ Helper processes
*
* In Electron 6, parts of the generic Electron Helper process were split into
* individual helper processes. Allow users to configure the bundleIdentifiers
* for continuity, specifically because macOS keychain access relies on
* bundleIdentifiers not changing (i.e. across versions of Electron).
*/
function configureHelper(helper, postfix, userProvidedBundleIdentifier) {
helper.CFBundleExecutable = `${appFilename} Helper ${postfix}`;
helper.CFBundleDisplayName = `${appInfo.productName} Helper ${postfix}`;
helper.CFBundleIdentifier = userProvidedBundleIdentifier
? appInfo_1.filterCFBundleIdentifier(userProvidedBundleIdentifier)
: appInfo_1.filterCFBundleIdentifier(`${helperBundleIdentifier}.${postfix}`);
helper.CFBundleVersion = appPlist.CFBundleVersion;
}
if (helperRendererPlist != null) {
configureHelper(helperRendererPlist, "(Renderer)", packager.platformSpecificBuildOptions.helperRendererBundleId);
}
if (helperPluginPlist != null) {
configureHelper(helperPluginPlist, "(Plugin)", packager.platformSpecificBuildOptions.helperPluginBundleId);
}
if (helperGPUPlist != null) {
configureHelper(helperGPUPlist, "(GPU)", packager.platformSpecificBuildOptions.helperGPUBundleId);
}
if (helperEHPlist != null) {
configureHelper(helperEHPlist, "EH", packager.platformSpecificBuildOptions.helperEHBundleId);
}
if (helperNPPlist != null) {
configureHelper(helperNPPlist, "NP", packager.platformSpecificBuildOptions.helperNPBundleId);
}
if (helperLoginPlist != null) {
helperLoginPlist.CFBundleExecutable = `${appFilename} Login Helper`;
helperLoginPlist.CFBundleDisplayName = `${appInfo.productName} Login Helper`;
// noinspection SpellCheckingInspection
helperLoginPlist.CFBundleIdentifier = `${appInfo.macBundleIdentifier}.loginhelper`;
helperLoginPlist.CFBundleVersion = appPlist.CFBundleVersion;
}
const protocols = builder_util_1.asArray(buildMetadata.protocols).concat(builder_util_1.asArray(packager.platformSpecificBuildOptions.protocols));
if (protocols.length > 0) {
appPlist.CFBundleURLTypes = protocols.map(protocol => {
const schemes = builder_util_1.asArray(protocol.schemes);
if (schemes.length === 0) {
throw new builder_util_1.InvalidConfigurationError(`Protocol "${protocol.name}": must be at least one scheme specified`);
}
return {
CFBundleURLName: protocol.name,
CFBundleTypeRole: protocol.role || "Editor",
CFBundleURLSchemes: schemes.slice(),
};
});
}
const fileAssociations = packager.fileAssociations;
if (fileAssociations.length > 0) {
appPlist.CFBundleDocumentTypes = await bluebird_lst_1.default.map(fileAssociations, async (fileAssociation) => {
const extensions = builder_util_1.asArray(fileAssociation.ext).map(platformPackager_1.normalizeExt);
const customIcon = await packager.getResource(builder_util_1.getPlatformIconFileName(fileAssociation.icon, true), `${extensions[0]}.icns`);
let iconFile = appPlist.CFBundleIconFile;
if (customIcon != null) {
iconFile = path.basename(customIcon);
await fs_1.copyOrLinkFile(customIcon, path.join(path.join(contentsPath, "Resources"), iconFile));
}
const result = {
CFBundleTypeExtensions: extensions,
CFBundleTypeName: fileAssociation.name || extensions[0],
CFBundleTypeRole: fileAssociation.role || "Editor",
LSHandlerRank: fileAssociation.rank || "Default",
CFBundleTypeIconFile: iconFile,
};
if (fileAssociation.isPackage) {
result.LSTypeIsPackage = true;
}
return result;
});
}
if (asarIntegrity != null) {
appPlist.ElectronAsarIntegrity = asarIntegrity;
}
const plistDataToWrite = {
[appPlistFilename]: appPlist,
[helperPlistFilename]: helperPlist,
};
if (helperEHPlist != null) {
plistDataToWrite[helperEHPlistFilename] = helperEHPlist;
}
if (helperNPPlist != null) {
plistDataToWrite[helperNPPlistFilename] = helperNPPlist;
}
if (helperRendererPlist != null) {
plistDataToWrite[helperRendererPlistFilename] = helperRendererPlist;
}
if (helperPluginPlist != null) {
plistDataToWrite[helperPluginPlistFilename] = helperPluginPlist;
}
if (helperGPUPlist != null) {
plistDataToWrite[helperGPUPlistFilename] = helperGPUPlist;
}
if (helperLoginPlist != null) {
plistDataToWrite[helperLoginPlistFilename] = helperLoginPlist;
}
await Promise.all([
appBuilder_1.executeAppBuilderAndWriteJson(["encode-plist"], plistDataToWrite),
doRename(path.join(contentsPath, "MacOS"), electronBranding.productName, appPlist.CFBundleExecutable),
fs_1.unlinkIfExists(path.join(appOutDir, "LICENSE")),
fs_1.unlinkIfExists(path.join(appOutDir, "LICENSES.chromium.html")),
]);
await moveHelpers(getAvailableHelperSuffixes(helperEHPlist, helperNPPlist, helperRendererPlist, helperPluginPlist, helperGPUPlist), frameworksPath, appFilename, electronBranding.productName);
if (helperLoginPlist != null) {
const prefix = electronBranding.productName;
const suffix = " Login Helper";
const executableBasePath = path.join(loginItemPath, `${prefix}${suffix}.app`, "Contents", "MacOS");
await doRename(executableBasePath, `${prefix}${suffix}`, appFilename + suffix).then(() => doRename(loginItemPath, `${prefix}${suffix}.app`, `${appFilename}${suffix}.app`));
}
const appPath = path.join(appOutDir, `${appFilename}.app`);
await promises_1.rename(path.dirname(contentsPath), appPath);
// https://github.com/electron-userland/electron-builder/issues/840
const now = Date.now() / 1000;
await promises_1.utimes(appPath, now, now);
}
exports.createMacApp = createMacApp;
function configureLocalhostAts(appPlist) {
// https://bencoding.com/2015/07/20/app-transport-security-and-localhost/
let ats = appPlist.NSAppTransportSecurity;
if (ats == null) {
ats = {};
appPlist.NSAppTransportSecurity = ats;
}
ats.NSAllowsLocalNetworking = true;
// https://github.com/electron-userland/electron-builder/issues/3377#issuecomment-446035814
ats.NSAllowsArbitraryLoads = true;
let exceptionDomains = ats.NSExceptionDomains;
if (exceptionDomains == null) {
exceptionDomains = {};
ats.NSExceptionDomains = exceptionDomains;
}
if (exceptionDomains.localhost == null) {
const allowHttp = {
NSTemporaryExceptionAllowsInsecureHTTPSLoads: false,
NSIncludesSubdomains: false,
NSTemporaryExceptionAllowsInsecureHTTPLoads: true,
NSTemporaryExceptionMinimumTLSVersion: "1.0",
NSTemporaryExceptionRequiresForwardSecrecy: false,
};
exceptionDomains.localhost = allowHttp;
exceptionDomains["127.0.0.1"] = allowHttp;
}
}
//# sourceMappingURL=electronMac.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,8 @@
import { Lazy } from "lazy-val";
import { Configuration } from "../configuration";
export declare type MetadataValue = Lazy<{
[key: string]: any;
} | null>;
export declare function getElectronVersion(projectDir: string, config?: Configuration, projectMetadata?: MetadataValue): Promise<string>;
export declare function getElectronVersionFromInstalled(projectDir: string): Promise<any>;
export declare function getElectronPackage(projectDir: string): Promise<any>;

View file

@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeElectronVersion = exports.getElectronPackage = exports.getElectronVersionFromInstalled = exports.getElectronVersion = void 0;
const builder_util_1 = require("builder-util");
const builder_util_runtime_1 = require("builder-util-runtime");
const nodeHttpExecutor_1 = require("builder-util/out/nodeHttpExecutor");
const fs_extra_1 = require("fs-extra");
const lazy_val_1 = require("lazy-val");
const path = require("path");
const read_config_file_1 = require("read-config-file");
const semver = require("semver");
const config_1 = require("../util/config");
const electronPackages = ["electron", "electron-prebuilt", "electron-prebuilt-compile", "electron-nightly"];
async function getElectronVersion(projectDir, config, projectMetadata = new lazy_val_1.Lazy(() => read_config_file_1.orNullIfFileNotExist(fs_extra_1.readJson(path.join(projectDir, "package.json"))))) {
if (config == null) {
config = await config_1.getConfig(projectDir, null, null);
}
if (config.electronVersion != null) {
return config.electronVersion;
}
return await computeElectronVersion(projectDir, projectMetadata);
}
exports.getElectronVersion = getElectronVersion;
async function getElectronVersionFromInstalled(projectDir) {
for (const name of electronPackages) {
try {
return (await fs_extra_1.readJson(path.join(projectDir, "node_modules", name, "package.json"))).version;
}
catch (e) {
if (e.code !== "ENOENT") {
builder_util_1.log.warn({ name, error: e }, `cannot read electron version package.json`);
}
}
}
return null;
}
exports.getElectronVersionFromInstalled = getElectronVersionFromInstalled;
async function getElectronPackage(projectDir) {
for (const name of electronPackages) {
try {
return await fs_extra_1.readJson(path.join(projectDir, "node_modules", name, "package.json"));
}
catch (e) {
if (e.code !== "ENOENT") {
builder_util_1.log.warn({ name, error: e }, `cannot find electron in package.json`);
}
}
}
return null;
}
exports.getElectronPackage = getElectronPackage;
/** @internal */
async function computeElectronVersion(projectDir, projectMetadata) {
const result = await getElectronVersionFromInstalled(projectDir);
if (result != null) {
return result;
}
const dependency = findFromPackageMetadata(await projectMetadata.value);
if ((dependency === null || dependency === void 0 ? void 0 : dependency.name) === "electron-nightly") {
builder_util_1.log.info("You are using a nightly version of electron, be warned that those builds are highly unstable.");
const feedXml = await nodeHttpExecutor_1.httpExecutor.request({
hostname: "github.com",
path: `/electron/nightlies/releases.atom`,
headers: {
accept: "application/xml, application/atom+xml, text/xml, */*",
},
});
const feed = builder_util_runtime_1.parseXml(feedXml);
const latestRelease = feed.element("entry", false, `No published versions on GitHub`);
const v = /\/tag\/v?([^/]+)$/.exec(latestRelease.element("link").attribute("href"))[1];
return v.startsWith("v") ? v.substring(1) : v;
}
else if ((dependency === null || dependency === void 0 ? void 0 : dependency.version) === "latest") {
builder_util_1.log.warn('Electron version is set to "latest", but it is recommended to set it to some more restricted version range.');
try {
const releaseInfo = JSON.parse((await nodeHttpExecutor_1.httpExecutor.request({
hostname: "github.com",
path: `/electron/${dependency.name === "electron-nightly" ? "nightlies" : "electron"}/releases/latest`,
headers: {
accept: "application/json",
},
})));
const version = releaseInfo.tag_name.startsWith("v") ? releaseInfo.tag_name.substring(1) : releaseInfo.tag_name;
builder_util_1.log.info({ version }, `resolve ${dependency.name}@${dependency.version}`);
return version;
}
catch (e) {
builder_util_1.log.warn(e);
}
throw new builder_util_1.InvalidConfigurationError(`Cannot find electron dependency to get electron version in the '${path.join(projectDir, "package.json")}'`);
}
const version = dependency === null || dependency === void 0 ? void 0 : dependency.version;
if (version == null || !/^\d/.test(version)) {
const versionMessage = version == null ? "" : ` and version ("${version}") is not fixed in project`;
throw new builder_util_1.InvalidConfigurationError(`Cannot compute electron version from installed node modules - none of the possible electron modules are installed${versionMessage}.\nSee https://github.com/electron-userland/electron-builder/issues/3984#issuecomment-504968246`);
}
return semver.coerce(version).toString();
}
exports.computeElectronVersion = computeElectronVersion;
function findFromPackageMetadata(packageData) {
for (const name of electronPackages) {
const devDependencies = packageData.devDependencies;
let dep = devDependencies == null ? null : devDependencies[name];
if (dep == null) {
const dependencies = packageData.dependencies;
dep = dependencies == null ? null : dependencies[name];
}
if (dep != null) {
return { name, version: dep };
}
}
return null;
}
//# sourceMappingURL=electronVersion.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
export declare const authorEmailIsMissed = "Please specify author 'email' in the application package.json\n\nSee https://docs.npmjs.com/files/package.json#people-fields-author-contributors\n\nIt is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options.\n(see https://www.electron.build/configuration/linux).\n";

View file

@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.authorEmailIsMissed = void 0;
exports.authorEmailIsMissed = `Please specify author 'email' in the application package.json
See https://docs.npmjs.com/files/package.json#people-fields-author-contributors
It is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options.
(see https://www.electron.build/configuration/linux).
`;
//# sourceMappingURL=errorMessages.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"errorMessages.js","sourceRoot":"","sources":["../src/errorMessages.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG;;;;;;CAMlC,CAAA","sourcesContent":["export const authorEmailIsMissed = `Please specify author 'email' in the application package.json\n\nSee https://docs.npmjs.com/files/package.json#people-fields-author-contributors\n\nIt is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options.\n(see https://www.electron.build/configuration/linux).\n`\n"]}

View file

@ -0,0 +1,9 @@
import { PlatformSpecificBuildOptions } from "./index";
export declare const excludedNames: string;
export declare const excludedExts = "iml,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,suo,xproj,cc,d.ts";
export interface GetFileMatchersOptions {
readonly macroExpander: (pattern: string) => string;
readonly customBuildOptions: PlatformSpecificBuildOptions;
readonly globalOutDir: string;
readonly defaultSrc: string;
}

View file

@ -0,0 +1,282 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.copyFiles = exports.getFileMatchers = exports.getNodeModuleFileMatcher = exports.getMainFileMatchers = exports.FileMatcher = exports.excludedExts = exports.excludedNames = void 0;
const bluebird_lst_1 = require("bluebird-lst");
const builder_util_1 = require("builder-util");
const fs_1 = require("builder-util/out/fs");
const promises_1 = require("fs/promises");
const minimatch_1 = require("minimatch");
const path = require("path");
const filter_1 = require("./util/filter");
// https://github.com/electron-userland/electron-builder/issues/733
const minimatchOptions = { dot: true };
// noinspection SpellCheckingInspection
exports.excludedNames = ".git,.hg,.svn,CVS,RCS,SCCS," +
"__pycache__,.DS_Store,thumbs.db,.gitignore,.gitkeep,.gitattributes,.npmignore," +
".idea,.vs,.flowconfig,.jshintrc,.eslintrc,.circleci," +
".yarn-integrity,.yarn-metadata.json,yarn-error.log,yarn.lock,package-lock.json,npm-debug.log," +
"appveyor.yml,.travis.yml,circle.yml,.nyc_output";
exports.excludedExts = "iml,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,suo,xproj,cc,d.ts";
function ensureNoEndSlash(file) {
if (path.sep !== "/") {
file = file.replace(/\//g, path.sep);
}
if (path.sep !== "\\") {
file = file.replace(/\\/g, path.sep);
}
if (file.endsWith(path.sep)) {
return file.substring(0, file.length - 1);
}
else {
return file;
}
}
/** @internal */
class FileMatcher {
constructor(from, to, macroExpander, patterns) {
this.macroExpander = macroExpander;
this.excludePatterns = null;
this.from = ensureNoEndSlash(macroExpander(from));
this.to = ensureNoEndSlash(macroExpander(to));
this.patterns = builder_util_1.asArray(patterns).map(it => this.normalizePattern(it));
this.isSpecifiedAsEmptyArray = Array.isArray(patterns) && patterns.length === 0;
}
normalizePattern(pattern) {
if (pattern.startsWith("./")) {
pattern = pattern.substring("./".length);
}
return path.posix.normalize(this.macroExpander(pattern.replace(/\\/g, "/")));
}
addPattern(pattern) {
this.patterns.push(this.normalizePattern(pattern));
}
prependPattern(pattern) {
this.patterns.unshift(this.normalizePattern(pattern));
}
isEmpty() {
return this.patterns.length === 0;
}
containsOnlyIgnore() {
return !this.isEmpty() && this.patterns.find(it => !it.startsWith("!")) == null;
}
computeParsedPatterns(result, fromDir) {
const relativeFrom = fromDir == null ? null : path.relative(fromDir, this.from);
if (this.patterns.length === 0 && relativeFrom != null) {
// file mappings, from here is a file
result.push(new minimatch_1.Minimatch(relativeFrom, minimatchOptions));
return;
}
for (let pattern of this.patterns) {
if (relativeFrom != null) {
pattern = path.join(relativeFrom, pattern);
}
const parsedPattern = new minimatch_1.Minimatch(pattern, minimatchOptions);
result.push(parsedPattern);
// do not add if contains dot (possibly file if has extension)
if (!pattern.includes(".") && !filter_1.hasMagic(parsedPattern)) {
// https://github.com/electron-userland/electron-builder/issues/545
// add **/*
result.push(new minimatch_1.Minimatch(`${pattern}/**/*`, minimatchOptions));
}
}
}
createFilter() {
const parsedPatterns = [];
this.computeParsedPatterns(parsedPatterns);
return filter_1.createFilter(this.from, parsedPatterns, this.excludePatterns);
}
toString() {
return `from: ${this.from}, to: ${this.to}, patterns: ${this.patterns.join(", ")}`;
}
}
exports.FileMatcher = FileMatcher;
/** @internal */
function getMainFileMatchers(appDir, destination, macroExpander, platformSpecificBuildOptions, platformPackager, outDir, isElectronCompile) {
const packager = platformPackager.info;
const buildResourceDir = path.resolve(packager.projectDir, packager.buildResourcesDir);
let matchers = packager.isPrepackedAppAsar
? null
: getFileMatchers(packager.config, "files", destination, {
macroExpander,
customBuildOptions: platformSpecificBuildOptions,
globalOutDir: outDir,
defaultSrc: appDir,
});
if (matchers == null) {
matchers = [new FileMatcher(appDir, destination, macroExpander)];
}
const matcher = matchers[0];
// add default patterns, but only if from equals to app dir
if (matcher.from !== appDir) {
return matchers;
}
// https://github.com/electron-userland/electron-builder/issues/1741#issuecomment-311111418 so, do not use inclusive patterns
const patterns = matcher.patterns;
const customFirstPatterns = [];
// electron-webpack - we need to copy only package.json and node_modules from root dir (and these files are added by default), so, explicit empty array is specified
if (!matcher.isSpecifiedAsEmptyArray && (matcher.isEmpty() || matcher.containsOnlyIgnore())) {
customFirstPatterns.push("**/*");
}
else if (!patterns.includes("package.json")) {
patterns.push("package.json");
}
customFirstPatterns.push("!**/node_modules");
// https://github.com/electron-userland/electron-builder/issues/1482
const relativeBuildResourceDir = path.relative(matcher.from, buildResourceDir);
if (relativeBuildResourceDir.length !== 0 && !relativeBuildResourceDir.startsWith(".")) {
customFirstPatterns.push(`!${relativeBuildResourceDir}{,/**/*}`);
}
const relativeOutDir = matcher.normalizePattern(path.relative(packager.projectDir, outDir));
if (!relativeOutDir.startsWith(".")) {
customFirstPatterns.push(`!${relativeOutDir}{,/**/*}`);
}
// add our default exclusions after last user possibly defined "all"/permissive pattern
let insertIndex = 0;
for (let i = patterns.length - 1; i >= 0; i--) {
if (patterns[i].startsWith("**/")) {
insertIndex = i + 1;
break;
}
}
patterns.splice(insertIndex, 0, ...customFirstPatterns);
patterns.push(`!**/*.{${exports.excludedExts}${packager.config.includePdb === true ? "" : ",pdb"}}`);
patterns.push("!**/._*");
patterns.push("!**/electron-builder.{yaml,yml,json,json5,toml}");
patterns.push(`!**/{${exports.excludedNames}}`);
if (isElectronCompile) {
patterns.push("!.cache{,/**/*}");
}
patterns.push("!.yarn{,/**/*}");
// https://github.com/electron-userland/electron-builder/issues/1969
// exclude ony for app root, use .yarnclean to clean node_modules
patterns.push("!.editorconfig");
patterns.push("!.yarnrc.yml");
const debugLogger = packager.debugLogger;
if (debugLogger.isEnabled) {
//tslint:disable-next-line:no-invalid-template-strings
debugLogger.add(`${macroExpander("${arch}")}.firstOrDefaultFilePatterns`, patterns);
}
return matchers;
}
exports.getMainFileMatchers = getMainFileMatchers;
/** @internal */
function getNodeModuleFileMatcher(appDir, destination, macroExpander, platformSpecificBuildOptions, packager) {
// https://github.com/electron-userland/electron-builder/pull/2948#issuecomment-392241632
// grab only excludes
const matcher = new FileMatcher(appDir, destination, macroExpander);
function addPatterns(patterns) {
if (patterns == null) {
return;
}
else if (!Array.isArray(patterns)) {
if (typeof patterns === "string" && patterns.startsWith("!")) {
matcher.addPattern(patterns);
return;
}
// ignore object form
return;
}
for (const pattern of patterns) {
if (typeof pattern === "string") {
if (pattern.startsWith("!")) {
matcher.addPattern(pattern);
}
}
else {
const fileSet = pattern;
if (fileSet.from == null || fileSet.from === ".") {
for (const p of builder_util_1.asArray(fileSet.filter)) {
matcher.addPattern(p);
}
}
}
}
}
addPatterns(packager.config.files);
addPatterns(platformSpecificBuildOptions.files);
if (!matcher.isEmpty()) {
matcher.prependPattern("**/*");
}
const debugLogger = packager.debugLogger;
if (debugLogger.isEnabled) {
//tslint:disable-next-line:no-invalid-template-strings
debugLogger.add(`${macroExpander("${arch}")}.nodeModuleFilePatterns`, matcher.patterns);
}
return matcher;
}
exports.getNodeModuleFileMatcher = getNodeModuleFileMatcher;
/** @internal */
function getFileMatchers(config, name, defaultDestination, options) {
const defaultMatcher = new FileMatcher(options.defaultSrc, defaultDestination, options.macroExpander);
const fileMatchers = [];
function addPatterns(patterns) {
if (patterns == null) {
return;
}
else if (!Array.isArray(patterns)) {
if (typeof patterns === "string") {
defaultMatcher.addPattern(patterns);
return;
}
patterns = [patterns];
}
for (const pattern of patterns) {
if (typeof pattern === "string") {
// use normalize to transform ./foo to foo
defaultMatcher.addPattern(pattern);
}
else if (name === "asarUnpack") {
throw new Error(`Advanced file copying not supported for "${name}"`);
}
else {
const from = pattern.from == null ? options.defaultSrc : path.resolve(options.defaultSrc, pattern.from);
const to = pattern.to == null ? defaultDestination : path.resolve(defaultDestination, pattern.to);
fileMatchers.push(new FileMatcher(from, to, options.macroExpander, pattern.filter));
}
}
}
if (name !== "extraDistFiles") {
addPatterns(config[name]);
}
addPatterns(options.customBuildOptions[name]);
if (!defaultMatcher.isEmpty()) {
// default matcher should be first in the array
fileMatchers.unshift(defaultMatcher);
}
// we cannot exclude the whole out dir, because sometimes users want to use some file in the out dir in the patterns
const relativeOutDir = defaultMatcher.normalizePattern(path.relative(options.defaultSrc, options.globalOutDir));
if (!relativeOutDir.startsWith(".")) {
defaultMatcher.addPattern(`!${relativeOutDir}/*-unpacked{,/**/*}`);
}
return fileMatchers.length === 0 ? null : fileMatchers;
}
exports.getFileMatchers = getFileMatchers;
/** @internal */
function copyFiles(matchers, transformer, isUseHardLink) {
if (matchers == null || matchers.length === 0) {
return Promise.resolve();
}
return bluebird_lst_1.default.map(matchers, async (matcher) => {
const fromStat = await fs_1.statOrNull(matcher.from);
if (fromStat == null) {
builder_util_1.log.warn({ from: matcher.from }, `file source doesn't exist`);
return;
}
if (fromStat.isFile()) {
const toStat = await fs_1.statOrNull(matcher.to);
// https://github.com/electron-userland/electron-builder/issues/1245
if (toStat != null && toStat.isDirectory()) {
return await fs_1.copyOrLinkFile(matcher.from, path.join(matcher.to, path.basename(matcher.from)), fromStat, isUseHardLink);
}
await promises_1.mkdir(path.dirname(matcher.to), { recursive: true });
return await fs_1.copyOrLinkFile(matcher.from, matcher.to, fromStat);
}
if (matcher.isEmpty() || matcher.containsOnlyIgnore()) {
matcher.prependPattern("**/*");
}
builder_util_1.log.debug({ matcher }, "copying files using pattern");
return await fs_1.copyDir(matcher.from, matcher.to, { filter: matcher.createFilter(), transformer, isUseHardLink: isUseHardLink ? fs_1.USE_HARD_LINKS : null });
});
}
exports.copyFiles = copyFiles;
//# sourceMappingURL=fileMatcher.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createElectronCompilerHost = exports.createTransformer = exports.hasDep = exports.isElectronCompileUsed = exports.NODE_MODULES_PATTERN = void 0;
const builder_util_1 = require("builder-util");
const promises_1 = require("fs/promises");
const path = require("path");
/** @internal */
exports.NODE_MODULES_PATTERN = `${path.sep}node_modules${path.sep}`;
/** @internal */
function isElectronCompileUsed(info) {
if (info.config.electronCompile != null) {
return info.config.electronCompile;
}
// if in devDependencies - it means that babel is used for precompilation or for some reason user decided to not use electron-compile for production
return hasDep("electron-compile", info);
}
exports.isElectronCompileUsed = isElectronCompileUsed;
/** @internal */
function hasDep(name, info) {
const deps = info.metadata.dependencies;
return deps != null && name in deps;
}
exports.hasDep = hasDep;
/** @internal */
function createTransformer(srcDir, configuration, extraMetadata, extraTransformer) {
const mainPackageJson = path.join(srcDir, "package.json");
const isRemovePackageScripts = configuration.removePackageScripts !== false;
const isRemovePackageKeywords = configuration.removePackageKeywords !== false;
const packageJson = path.sep + "package.json";
return file => {
if (file === mainPackageJson) {
return modifyMainPackageJson(file, extraMetadata, isRemovePackageScripts, isRemovePackageKeywords);
}
if (file.endsWith(packageJson) && file.includes(exports.NODE_MODULES_PATTERN)) {
return promises_1.readFile(file, "utf-8")
.then(it => cleanupPackageJson(JSON.parse(it), {
isMain: false,
isRemovePackageScripts,
isRemovePackageKeywords,
}))
.catch(e => builder_util_1.log.warn(e));
}
else if (extraTransformer != null) {
return extraTransformer(file);
}
else {
return null;
}
};
}
exports.createTransformer = createTransformer;
/** @internal */
function createElectronCompilerHost(projectDir, cacheDir) {
const electronCompilePath = path.join(projectDir, "node_modules", "electron-compile", "lib");
return require(path.join(electronCompilePath, "config-parser")).createCompilerHostFromProjectRoot(projectDir, cacheDir);
}
exports.createElectronCompilerHost = createElectronCompilerHost;
const ignoredPackageMetadataProperties = new Set(["dist", "gitHead", "build", "jspm", "ava", "xo", "nyc", "eslintConfig", "contributors", "bundleDependencies", "tags"]);
function cleanupPackageJson(data, options) {
const deps = data.dependencies;
// https://github.com/electron-userland/electron-builder/issues/507#issuecomment-312772099
const isRemoveBabel = deps != null && typeof deps === "object" && !Object.getOwnPropertyNames(deps).some(it => it.startsWith("babel"));
try {
let changed = false;
for (const prop of Object.getOwnPropertyNames(data)) {
// removing devDependencies from package.json breaks levelup in electron, so, remove it only from main package.json
if (prop[0] === "_" ||
ignoredPackageMetadataProperties.has(prop) ||
(options.isRemovePackageScripts && prop === "scripts") ||
(options.isRemovePackageKeywords && prop === "keywords") ||
(options.isMain && prop === "devDependencies") ||
(!options.isMain && prop === "bugs") ||
(isRemoveBabel && prop === "babel")) {
delete data[prop];
changed = true;
}
}
if (changed) {
return JSON.stringify(data, null, 2);
}
}
catch (e) {
builder_util_1.debug(e);
}
return null;
}
async function modifyMainPackageJson(file, extraMetadata, isRemovePackageScripts, isRemovePackageKeywords) {
const mainPackageData = JSON.parse(await promises_1.readFile(file, "utf-8"));
if (extraMetadata != null) {
builder_util_1.deepAssign(mainPackageData, extraMetadata);
}
// https://github.com/electron-userland/electron-builder/issues/1212
const serializedDataIfChanged = cleanupPackageJson(mainPackageData, {
isMain: true,
isRemovePackageScripts,
isRemovePackageKeywords,
});
if (serializedDataIfChanged != null) {
return serializedDataIfChanged;
}
else if (extraMetadata != null) {
return JSON.stringify(mainPackageData, null, 2);
}
return null;
}
//# sourceMappingURL=fileTransformer.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,5 @@
import { PackagerOptions } from "./packagerApi";
export interface ForgeOptions {
readonly dir: string;
}
export declare function buildForge(forgeOptions: ForgeOptions, options: PackagerOptions): Promise<string[]>;

View file

@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildForge = void 0;
const path = require("path");
const index_1 = require("./index");
function buildForge(forgeOptions, options) {
const appDir = forgeOptions.dir;
return index_1.build({
prepackaged: appDir,
config: {
directories: {
// https://github.com/electron-userland/electron-forge/blob/master/src/makers/generic/zip.js
output: path.resolve(appDir, "..", "make"),
},
},
...options,
});
}
exports.buildForge = buildForge;
//# sourceMappingURL=forge-maker.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"forge-maker.js","sourceRoot":"","sources":["../src/forge-maker.ts"],"names":[],"mappings":";;;AAAA,6BAA4B;AAC5B,mCAA+B;AAO/B,SAAgB,UAAU,CAAC,YAA0B,EAAE,OAAwB;IAC7E,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAA;IAC/B,OAAO,aAAK,CAAC;QACX,WAAW,EAAE,MAAM;QACnB,MAAM,EAAE;YACN,WAAW,EAAE;gBACX,4FAA4F;gBAC5F,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;aAC3C;SACF;QACD,GAAG,OAAO;KACX,CAAC,CAAA;AACJ,CAAC;AAZD,gCAYC","sourcesContent":["import * as path from \"path\"\nimport { build } from \"./index\"\nimport { PackagerOptions } from \"./packagerApi\"\n\nexport interface ForgeOptions {\n readonly dir: string\n}\n\nexport function buildForge(forgeOptions: ForgeOptions, options: PackagerOptions) {\n const appDir = forgeOptions.dir\n return build({\n prepackaged: appDir,\n config: {\n directories: {\n // https://github.com/electron-userland/electron-forge/blob/master/src/makers/generic/zip.js\n output: path.resolve(appDir, \"..\", \"make\"),\n },\n },\n ...options,\n })\n}\n"]}

View file

@ -0,0 +1,21 @@
import { AfterPackContext } from "../configuration";
import { Platform } from "../core";
import { Framework, PrepareApplicationStageDirectoryOptions } from "../Framework";
export declare class LibUiFramework implements Framework {
readonly version: string;
readonly distMacOsAppName: string;
protected readonly isUseLaunchUi: boolean;
readonly name: string;
readonly macOsDefaultTargets: string[];
readonly defaultAppIdPrefix: string;
readonly isCopyElevateHelper = false;
readonly isNpmRebuildRequired = false;
constructor(version: string, distMacOsAppName: string, isUseLaunchUi: boolean);
prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions): Promise<void>;
private prepareMacosApplicationStageDirectory;
private prepareLinuxApplicationStageDirectory;
afterPack(context: AfterPackContext): Promise<void>;
getMainFile(platform: Platform): string | null;
private isUseLaunchUiForPlatform;
getExcludedDependencies(platform: Platform): Array<string> | null;
}

View file

@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LibUiFramework = void 0;
const fs_extra_1 = require("fs-extra");
const promises_1 = require("fs/promises");
const path = require("path");
const builder_util_1 = require("builder-util");
const core_1 = require("../core");
const appBuilder_1 = require("../util/appBuilder");
class LibUiFramework {
constructor(version, distMacOsAppName, isUseLaunchUi) {
this.version = version;
this.distMacOsAppName = distMacOsAppName;
this.isUseLaunchUi = isUseLaunchUi;
this.name = "libui";
// noinspection JSUnusedGlobalSymbols
this.macOsDefaultTargets = ["dmg"];
this.defaultAppIdPrefix = "com.libui.";
// noinspection JSUnusedGlobalSymbols
this.isCopyElevateHelper = false;
// noinspection JSUnusedGlobalSymbols
this.isNpmRebuildRequired = false;
}
async prepareApplicationStageDirectory(options) {
await fs_extra_1.emptyDir(options.appOutDir);
const packager = options.packager;
const platform = packager.platform;
if (this.isUseLaunchUiForPlatform(platform)) {
const appOutDir = options.appOutDir;
await builder_util_1.executeAppBuilder([
"proton-native",
"--node-version",
this.version,
"--use-launch-ui",
"--platform",
platform.nodeName,
"--arch",
options.arch,
"--stage",
appOutDir,
"--executable",
`${packager.appInfo.productFilename}${platform === core_1.Platform.WINDOWS ? ".exe" : ""}`,
]);
return;
}
if (platform === core_1.Platform.MAC) {
await this.prepareMacosApplicationStageDirectory(packager, options);
}
else if (platform === core_1.Platform.LINUX) {
await this.prepareLinuxApplicationStageDirectory(options);
}
}
async prepareMacosApplicationStageDirectory(packager, options) {
const appContentsDir = path.join(options.appOutDir, this.distMacOsAppName, "Contents");
await promises_1.mkdir(path.join(appContentsDir, "Resources"), { recursive: true });
await promises_1.mkdir(path.join(appContentsDir, "MacOS"), { recursive: true });
await builder_util_1.executeAppBuilder(["proton-native", "--node-version", this.version, "--platform", "darwin", "--stage", path.join(appContentsDir, "MacOS")]);
const appPlist = {
// https://github.com/albe-rosado/create-proton-app/issues/13
NSHighResolutionCapable: true,
};
await packager.applyCommonInfo(appPlist, appContentsDir);
await Promise.all([
appBuilder_1.executeAppBuilderAndWriteJson(["encode-plist"], { [path.join(appContentsDir, "Info.plist")]: appPlist }),
writeExecutableMain(path.join(appContentsDir, "MacOS", appPlist.CFBundleExecutable), `#!/bin/sh
DIR=$(dirname "$0")
"$DIR/node" "$DIR/../Resources/app/${options.packager.info.metadata.main || "index.js"}"
`),
]);
}
async prepareLinuxApplicationStageDirectory(options) {
const appOutDir = options.appOutDir;
await builder_util_1.executeAppBuilder(["proton-native", "--node-version", this.version, "--platform", "linux", "--arch", options.arch, "--stage", appOutDir]);
const mainPath = path.join(appOutDir, options.packager.executableName);
await writeExecutableMain(mainPath, `#!/bin/sh
DIR=$(dirname "$0")
"$DIR/node" "$DIR/app/${options.packager.info.metadata.main || "index.js"}"
`);
}
async afterPack(context) {
const packager = context.packager;
if (!this.isUseLaunchUiForPlatform(packager.platform)) {
return;
}
// LaunchUI requires main.js, rename if need
const userMain = packager.info.metadata.main || "index.js";
if (userMain === "main.js") {
return;
}
await promises_1.rename(path.join(context.appOutDir, "app", userMain), path.join(context.appOutDir, "app", "main.js"));
}
getMainFile(platform) {
return this.isUseLaunchUiForPlatform(platform) ? "main.js" : null;
}
isUseLaunchUiForPlatform(platform) {
return platform === core_1.Platform.WINDOWS || (this.isUseLaunchUi && platform === core_1.Platform.LINUX);
}
getExcludedDependencies(platform) {
// part of launchui
return this.isUseLaunchUiForPlatform(platform) ? ["libui-node"] : null;
}
}
exports.LibUiFramework = LibUiFramework;
async function writeExecutableMain(file, content) {
await promises_1.writeFile(file, content, { mode: 0o755 });
await promises_1.chmod(file, 0o755);
}
//# sourceMappingURL=LibUiFramework.js.map

File diff suppressed because one or more lines are too long

32
electron/node_modules/app-builder-lib/out/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,32 @@
import { PublishOptions } from "electron-publish/out/publisher";
import { Packager } from "./packager";
import { PackagerOptions } from "./packagerApi";
export { Packager, BuildResult } from "./packager";
export { PackagerOptions, ArtifactCreated, ArtifactBuildStarted } from "./packagerApi";
export { TargetConfiguration, Platform, Target, DIR_TARGET, BeforeBuildContext, SourceRepositoryInfo, TargetSpecificOptions, TargetConfigType, DEFAULT_TARGET, CompressionLevel, } from "./core";
export { getArchSuffix, Arch, archFromString } from "builder-util";
export { Configuration, AfterPackContext, MetadataDirectories } from "./configuration";
export { ElectronBrandingOptions, ElectronDownloadOptions, ElectronPlatformName } from "./electron/ElectronFramework";
export { PlatformSpecificBuildOptions, AsarOptions, FileSet, Protocol, ReleaseInfo } from "./options/PlatformSpecificBuildOptions";
export { FileAssociation } from "./options/FileAssociation";
export { MacConfiguration, DmgOptions, MasConfiguration, MacOsTargetName, DmgContent, DmgWindow } from "./options/macOptions";
export { PkgOptions, PkgBackgroundOptions, BackgroundAlignment, BackgroundScaling } from "./options/pkgOptions";
export { WindowsConfiguration } from "./options/winOptions";
export { AppXOptions } from "./options/AppXOptions";
export { MsiOptions } from "./options/MsiOptions";
export { CommonWindowsInstallerConfiguration } from "./options/CommonWindowsInstallerConfiguration";
export { NsisOptions, NsisWebOptions, PortableOptions, CommonNsisOptions } from "./targets/nsis/nsisOptions";
export { LinuxConfiguration, DebOptions, CommonLinuxOptions, LinuxTargetSpecificOptions, AppImageOptions, FlatpakOptions } from "./options/linuxOptions";
export { SnapOptions } from "./options/SnapOptions";
export { Metadata, AuthorMetadata, RepositoryInfo } from "./options/metadata";
export { AppInfo } from "./appInfo";
export { SquirrelWindowsOptions } from "./options/SquirrelWindowsOptions";
export { WindowsSignOptions, CustomWindowsSignTaskConfiguration, WindowsSignTaskConfiguration, CustomWindowsSign, FileCodeSigningInfo, CertificateFromStoreInfo, } from "./codeSign/windowsCodeSign";
export { CancellationToken, ProgressInfo } from "builder-util-runtime";
export { PublishOptions, UploadTask } from "electron-publish";
export { PublishManager } from "./publish/PublishManager";
export { PlatformPackager } from "./platformPackager";
export { Framework, PrepareApplicationStageDirectoryOptions } from "./Framework";
export { buildForge, ForgeOptions } from "./forge-maker";
export declare function checkBuildRequestOptions(options: PackagerOptions & PublishOptions): void;
export declare function build(options: PackagerOptions & PublishOptions, packager?: Packager): Promise<Array<string>>;

85
electron/node_modules/app-builder-lib/out/index.js generated vendored Normal file
View file

@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.build = exports.checkBuildRequestOptions = exports.buildForge = exports.PlatformPackager = exports.PublishManager = exports.CancellationToken = exports.AppInfo = exports.archFromString = exports.Arch = exports.getArchSuffix = exports.DEFAULT_TARGET = exports.DIR_TARGET = exports.Target = exports.Platform = exports.Packager = void 0;
const promise_1 = require("builder-util/out/promise");
const builder_util_1 = require("builder-util");
const builder_util_runtime_1 = require("builder-util-runtime");
const packager_1 = require("./packager");
const platformPackager_1 = require("./platformPackager");
const PublishManager_1 = require("./publish/PublishManager");
var packager_2 = require("./packager");
Object.defineProperty(exports, "Packager", { enumerable: true, get: function () { return packager_2.Packager; } });
var core_1 = require("./core");
Object.defineProperty(exports, "Platform", { enumerable: true, get: function () { return core_1.Platform; } });
Object.defineProperty(exports, "Target", { enumerable: true, get: function () { return core_1.Target; } });
Object.defineProperty(exports, "DIR_TARGET", { enumerable: true, get: function () { return core_1.DIR_TARGET; } });
Object.defineProperty(exports, "DEFAULT_TARGET", { enumerable: true, get: function () { return core_1.DEFAULT_TARGET; } });
var builder_util_2 = require("builder-util");
Object.defineProperty(exports, "getArchSuffix", { enumerable: true, get: function () { return builder_util_2.getArchSuffix; } });
Object.defineProperty(exports, "Arch", { enumerable: true, get: function () { return builder_util_2.Arch; } });
Object.defineProperty(exports, "archFromString", { enumerable: true, get: function () { return builder_util_2.archFromString; } });
var appInfo_1 = require("./appInfo");
Object.defineProperty(exports, "AppInfo", { enumerable: true, get: function () { return appInfo_1.AppInfo; } });
var builder_util_runtime_2 = require("builder-util-runtime");
Object.defineProperty(exports, "CancellationToken", { enumerable: true, get: function () { return builder_util_runtime_2.CancellationToken; } });
var PublishManager_2 = require("./publish/PublishManager");
Object.defineProperty(exports, "PublishManager", { enumerable: true, get: function () { return PublishManager_2.PublishManager; } });
var platformPackager_2 = require("./platformPackager");
Object.defineProperty(exports, "PlatformPackager", { enumerable: true, get: function () { return platformPackager_2.PlatformPackager; } });
var forge_maker_1 = require("./forge-maker");
Object.defineProperty(exports, "buildForge", { enumerable: true, get: function () { return forge_maker_1.buildForge; } });
const expectedOptions = new Set(["publish", "targets", "mac", "win", "linux", "projectDir", "platformPackagerFactory", "config", "effectiveOptionComputed", "prepackaged"]);
function checkBuildRequestOptions(options) {
for (const optionName of Object.keys(options)) {
if (!expectedOptions.has(optionName) && options[optionName] !== undefined) {
throw new builder_util_1.InvalidConfigurationError(`Unknown option "${optionName}"`);
}
}
}
exports.checkBuildRequestOptions = checkBuildRequestOptions;
function build(options, packager = new packager_1.Packager(options)) {
checkBuildRequestOptions(options);
const publishManager = new PublishManager_1.PublishManager(packager, options);
const sigIntHandler = () => {
builder_util_1.log.warn("cancelled by SIGINT");
packager.cancellationToken.cancel();
publishManager.cancelTasks();
};
process.once("SIGINT", sigIntHandler);
const promise = packager.build().then(async (buildResult) => {
const afterAllArtifactBuild = platformPackager_1.resolveFunction(buildResult.configuration.afterAllArtifactBuild, "afterAllArtifactBuild");
if (afterAllArtifactBuild != null) {
const newArtifacts = builder_util_runtime_1.asArray(await Promise.resolve(afterAllArtifactBuild(buildResult)));
if (newArtifacts.length === 0 || !publishManager.isPublish) {
return buildResult.artifactPaths;
}
const publishConfigurations = await publishManager.getGlobalPublishConfigurations();
if (publishConfigurations == null || publishConfigurations.length === 0) {
return buildResult.artifactPaths;
}
for (const newArtifact of newArtifacts) {
buildResult.artifactPaths.push(newArtifact);
for (const publishConfiguration of publishConfigurations) {
publishManager.scheduleUpload(publishConfiguration, {
file: newArtifact,
arch: null,
}, packager.appInfo);
}
}
}
return buildResult.artifactPaths;
});
return promise_1.executeFinally(promise, isErrorOccurred => {
let promise;
if (isErrorOccurred) {
publishManager.cancelTasks();
promise = Promise.resolve(null);
}
else {
promise = publishManager.awaitTasks();
}
return promise.then(() => process.removeListener("SIGINT", sigIntHandler));
});
}
exports.build = build;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,12 @@
import { Arch } from "builder-util";
import { Target } from "./core";
import { LinuxConfiguration } from "./options/linuxOptions";
import { Packager } from "./packager";
import { PlatformPackager } from "./platformPackager";
export declare class LinuxPackager extends PlatformPackager<LinuxConfiguration> {
readonly executableName: string;
constructor(info: Packager);
get defaultTarget(): Array<string>;
createTargets(targets: Array<string>, mapper: (name: string, factory: (outDir: string) => Target) => void): void;
}
export declare function toAppImageOrSnapArch(arch: Arch): string;

View file

@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toAppImageOrSnapArch = exports.LinuxPackager = void 0;
const builder_util_1 = require("builder-util");
const core_1 = require("./core");
const platformPackager_1 = require("./platformPackager");
const RemoteBuilder_1 = require("./remoteBuilder/RemoteBuilder");
const LinuxTargetHelper_1 = require("./targets/LinuxTargetHelper");
const targetFactory_1 = require("./targets/targetFactory");
const filename_1 = require("./util/filename");
class LinuxPackager extends platformPackager_1.PlatformPackager {
constructor(info) {
super(info, core_1.Platform.LINUX);
const executableName = this.platformSpecificBuildOptions.executableName;
this.executableName = executableName == null ? this.appInfo.sanitizedName.toLowerCase() : filename_1.sanitizeFileName(executableName);
}
get defaultTarget() {
return ["snap", "appimage"];
}
createTargets(targets, mapper) {
let helper;
const getHelper = () => {
if (helper == null) {
helper = new LinuxTargetHelper_1.LinuxTargetHelper(this);
}
return helper;
};
let remoteBuilder = null;
for (const name of targets) {
if (name === core_1.DIR_TARGET) {
continue;
}
const targetClass = (() => {
switch (name) {
case "appimage":
return require("./targets/AppImageTarget").default;
case "snap":
return require("./targets/snap").default;
case "flatpak":
return require("./targets/FlatpakTarget").default;
case "deb":
case "rpm":
case "sh":
case "freebsd":
case "pacman":
case "apk":
case "p5p":
return require("./targets/fpm").default;
default:
return null;
}
})();
mapper(name, outDir => {
if (targetClass === null) {
return targetFactory_1.createCommonTarget(name, outDir, this);
}
const target = new targetClass(name, this, getHelper(), outDir);
if (process.platform === "win32" || process.env._REMOTE_BUILD) {
if (remoteBuilder == null) {
remoteBuilder = new RemoteBuilder_1.RemoteBuilder(this);
}
// return remoteBuilder.buildTarget(this, arch, appOutDir, this.packager)
return new RemoteTarget(target, remoteBuilder);
}
return target;
});
}
}
}
exports.LinuxPackager = LinuxPackager;
class RemoteTarget extends core_1.Target {
constructor(target, remoteBuilder) {
super(target.name, true /* all must be scheduled in time (so, on finishBuild RemoteBuilder will have all targets added - so, we must set isAsyncSupported to true (resolved promise is returned)) */);
this.target = target;
this.remoteBuilder = remoteBuilder;
this.buildTaskManager = new builder_util_1.AsyncTaskManager(this.remoteBuilder.packager.info.cancellationToken);
}
get options() {
return this.target.options;
}
get outDir() {
return this.target.outDir;
}
async finishBuild() {
await this.buildTaskManager.awaitTasks();
await this.remoteBuilder.build();
}
build(appOutDir, arch) {
const promise = this.doBuild(appOutDir, arch);
this.buildTaskManager.addTask(promise);
return promise;
}
async doBuild(appOutDir, arch) {
builder_util_1.log.info({ target: this.target.name, arch: builder_util_1.Arch[arch] }, "scheduling remote build");
await this.target.checkOptions();
this.remoteBuilder.scheduleBuild(this.target, arch, appOutDir);
}
}
function toAppImageOrSnapArch(arch) {
switch (arch) {
case builder_util_1.Arch.x64:
return "x86_64";
case builder_util_1.Arch.ia32:
return "i386";
case builder_util_1.Arch.armv7l:
return "arm";
case builder_util_1.Arch.arm64:
return "arm_aarch64";
default:
throw new Error(`Unsupported arch ${arch}`);
}
}
exports.toAppImageOrSnapArch = toAppImageOrSnapArch;
//# sourceMappingURL=linuxPackager.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,29 @@
import { Arch, AsyncTaskManager } from "builder-util";
import { SignOptions } from "electron-osx-sign";
import { Lazy } from "lazy-val";
import { AppInfo } from "./appInfo";
import { CodeSigningInfo, Identity } from "./codeSign/macCodeSign";
import { Target } from "./core";
import { AfterPackContext, ElectronPlatformName } from "./index";
import { MacConfiguration } from "./options/macOptions";
import { Packager } from "./packager";
import { PlatformPackager } from "./platformPackager";
export default class MacPackager extends PlatformPackager<MacConfiguration> {
readonly codeSigningInfo: Lazy<CodeSigningInfo>;
private _iconPath;
constructor(info: Packager);
get defaultTarget(): Array<string>;
protected prepareAppInfo(appInfo: AppInfo): AppInfo;
getIconPath(): Promise<string | null>;
createTargets(targets: Array<string>, mapper: (name: string, factory: (outDir: string) => Target) => void): void;
protected doPack(outDir: string, appOutDir: string, platformName: ElectronPlatformName, arch: Arch, platformSpecificBuildOptions: MacConfiguration, targets: Array<Target>): Promise<any>;
pack(outDir: string, arch: Arch, targets: Array<Target>, taskManager: AsyncTaskManager): Promise<any>;
private sign;
private adjustSignOptions;
protected doSign(opts: SignOptions): Promise<any>;
protected doFlat(appPath: string, outFile: string, identity: Identity, keychain: string | null | undefined): Promise<any>;
getElectronSrcDir(dist: string): string;
getElectronDestinationDir(appOutDir: string): string;
applyCommonInfo(appPlist: any, contentsPath: string): Promise<void>;
protected signApp(packContext: AfterPackContext, isAsar: boolean): Promise<any>;
}

View file

@ -0,0 +1,399 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const bluebird_lst_1 = require("bluebird-lst");
const builder_util_1 = require("builder-util");
const electron_osx_sign_1 = require("electron-osx-sign");
const promises_1 = require("fs/promises");
const lazy_val_1 = require("lazy-val");
const path = require("path");
const fs_1 = require("builder-util/out/fs");
const promise_1 = require("builder-util/out/promise");
const appInfo_1 = require("./appInfo");
const macCodeSign_1 = require("./codeSign/macCodeSign");
const core_1 = require("./core");
const platformPackager_1 = require("./platformPackager");
const ArchiveTarget_1 = require("./targets/ArchiveTarget");
const pkg_1 = require("./targets/pkg");
const targetFactory_1 = require("./targets/targetFactory");
const macosVersion_1 = require("./util/macosVersion");
const pathManager_1 = require("./util/pathManager");
const fs = require("fs/promises");
class MacPackager extends platformPackager_1.PlatformPackager {
constructor(info) {
super(info, core_1.Platform.MAC);
this.codeSigningInfo = new lazy_val_1.Lazy(() => {
const cscLink = this.getCscLink();
if (cscLink == null || process.platform !== "darwin") {
return Promise.resolve({ keychainFile: process.env.CSC_KEYCHAIN || null });
}
return macCodeSign_1.createKeychain({
tmpDir: this.info.tempDirManager,
cscLink,
cscKeyPassword: this.getCscPassword(),
cscILink: platformPackager_1.chooseNotNull(this.platformSpecificBuildOptions.cscInstallerLink, process.env.CSC_INSTALLER_LINK),
cscIKeyPassword: platformPackager_1.chooseNotNull(this.platformSpecificBuildOptions.cscInstallerKeyPassword, process.env.CSC_INSTALLER_KEY_PASSWORD),
currentDir: this.projectDir,
}).then(result => {
const keychainFile = result.keychainFile;
if (keychainFile != null) {
this.info.disposeOnBuildFinish(() => macCodeSign_1.removeKeychain(keychainFile));
}
return result;
});
});
this._iconPath = new lazy_val_1.Lazy(() => this.getOrConvertIcon("icns"));
}
get defaultTarget() {
return this.info.framework.macOsDefaultTargets;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
prepareAppInfo(appInfo) {
return new appInfo_1.AppInfo(this.info, this.platformSpecificBuildOptions.bundleVersion, this.platformSpecificBuildOptions);
}
async getIconPath() {
return this._iconPath.value;
}
createTargets(targets, mapper) {
for (const name of targets) {
switch (name) {
case core_1.DIR_TARGET:
break;
case "dmg": {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { DmgTarget } = require("dmg-builder");
mapper(name, outDir => new DmgTarget(this, outDir));
break;
}
case "zip":
// https://github.com/electron-userland/electron-builder/issues/2313
mapper(name, outDir => new ArchiveTarget_1.ArchiveTarget(name, outDir, this, true));
break;
case "pkg":
mapper(name, outDir => new pkg_1.PkgTarget(this, outDir));
break;
default:
mapper(name, outDir => (name === "mas" || name === "mas-dev" ? new targetFactory_1.NoOpTarget(name) : targetFactory_1.createCommonTarget(name, outDir, this)));
break;
}
}
}
async doPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets) {
var _a;
switch (arch) {
default: {
return super.doPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets);
}
case builder_util_1.Arch.universal: {
const x64Arch = builder_util_1.Arch.x64;
const x64AppOutDir = appOutDir + "--" + builder_util_1.Arch[x64Arch];
await super.doPack(outDir, x64AppOutDir, platformName, x64Arch, platformSpecificBuildOptions, targets, false, true);
const arm64Arch = builder_util_1.Arch.arm64;
const arm64AppOutPath = appOutDir + "--" + builder_util_1.Arch[arm64Arch];
await super.doPack(outDir, arm64AppOutPath, platformName, arm64Arch, platformSpecificBuildOptions, targets, false, true);
const framework = this.info.framework;
builder_util_1.log.info({
platform: platformName,
arch: builder_util_1.Arch[arch],
[`${framework.name}`]: framework.version,
appOutDir: builder_util_1.log.filePath(appOutDir),
}, `packaging`);
const appFile = `${this.appInfo.productFilename}.app`;
const { makeUniversalApp } = require("@electron/universal");
await makeUniversalApp({
x64AppPath: path.join(x64AppOutDir, appFile),
arm64AppPath: path.join(arm64AppOutPath, appFile),
outAppPath: path.join(appOutDir, appFile),
force: true,
mergeASARs: (_a = platformSpecificBuildOptions.mergeASARs) !== null && _a !== void 0 ? _a : true,
singleArchFiles: platformSpecificBuildOptions.singleArchFiles,
x64ArchFiles: platformSpecificBuildOptions.x64ArchFiles,
});
await fs.rm(x64AppOutDir, { recursive: true, force: true });
await fs.rm(arm64AppOutPath, { recursive: true, force: true });
// Give users a final opportunity to perform things on the combined universal package before signing
const packContext = {
appOutDir,
outDir,
arch,
targets,
packager: this,
electronPlatformName: platformName,
};
await this.info.afterPack(packContext);
await this.doSignAfterPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets);
break;
}
}
}
async pack(outDir, arch, targets, taskManager) {
let nonMasPromise = null;
const hasMas = targets.length !== 0 && targets.some(it => it.name === "mas" || it.name === "mas-dev");
const prepackaged = this.packagerOptions.prepackaged;
if (!hasMas || targets.length > 1) {
const appPath = prepackaged == null ? path.join(this.computeAppOutDir(outDir, arch), `${this.appInfo.productFilename}.app`) : prepackaged;
nonMasPromise = (prepackaged
? Promise.resolve()
: this.doPack(outDir, path.dirname(appPath), this.platform.nodeName, arch, this.platformSpecificBuildOptions, targets)).then(() => this.packageInDistributableFormat(appPath, arch, targets, taskManager));
}
for (const target of targets) {
const targetName = target.name;
if (!(targetName === "mas" || targetName === "mas-dev")) {
continue;
}
const masBuildOptions = builder_util_1.deepAssign({}, this.platformSpecificBuildOptions, this.config.mas);
if (targetName === "mas-dev") {
builder_util_1.deepAssign(masBuildOptions, this.config.masDev, {
type: "development",
});
}
const targetOutDir = path.join(outDir, `${targetName}${builder_util_1.getArchSuffix(arch)}`);
if (prepackaged == null) {
await this.doPack(outDir, targetOutDir, "mas", arch, masBuildOptions, [target]);
await this.sign(path.join(targetOutDir, `${this.appInfo.productFilename}.app`), targetOutDir, masBuildOptions, arch);
}
else {
await this.sign(prepackaged, targetOutDir, masBuildOptions, arch);
}
}
if (nonMasPromise != null) {
await nonMasPromise;
}
}
async sign(appPath, outDir, masOptions, arch) {
if (!macCodeSign_1.isSignAllowed()) {
return;
}
const isMas = masOptions != null;
const options = masOptions == null ? this.platformSpecificBuildOptions : masOptions;
const qualifier = options.identity;
if (!isMas && qualifier === null) {
if (this.forceCodeSigning) {
throw new builder_util_1.InvalidConfigurationError("identity explicitly is set to null, but forceCodeSigning is set to true");
}
builder_util_1.log.info({ reason: "identity explicitly is set to null" }, "skipped macOS code signing");
return;
}
const keychainFile = (await this.codeSigningInfo.value).keychainFile;
const explicitType = options.type;
const type = explicitType || "distribution";
const isDevelopment = type === "development";
const certificateTypes = getCertificateTypes(isMas, isDevelopment);
let identity = null;
for (const certificateType of certificateTypes) {
identity = await macCodeSign_1.findIdentity(certificateType, qualifier, keychainFile);
if (identity != null) {
break;
}
}
if (identity == null) {
if (!isMas && !isDevelopment && explicitType !== "distribution") {
identity = await macCodeSign_1.findIdentity("Mac Developer", qualifier, keychainFile);
if (identity != null) {
builder_util_1.log.warn("Mac Developer is used to sign app — it is only for development and testing, not for production");
}
}
if (identity == null) {
await macCodeSign_1.reportError(isMas, certificateTypes, qualifier, keychainFile, this.forceCodeSigning);
return;
}
}
if (!macosVersion_1.isMacOsHighSierra()) {
throw new builder_util_1.InvalidConfigurationError("macOS High Sierra 10.13.6 is required to sign");
}
let filter = options.signIgnore;
if (Array.isArray(filter)) {
if (filter.length == 0) {
filter = null;
}
}
else if (filter != null) {
filter = filter.length === 0 ? null : [filter];
}
const filterRe = filter == null ? null : filter.map(it => new RegExp(it));
let binaries = options.binaries || undefined;
if (binaries) {
// Accept absolute paths for external binaries, else resolve relative paths from the artifact's app Contents path.
binaries = await Promise.all(binaries.map(async (destination) => {
if (await fs_1.statOrNull(destination)) {
return destination;
}
return path.resolve(appPath, destination);
}));
builder_util_1.log.info("Signing addtional user-defined binaries: " + JSON.stringify(binaries, null, 1));
}
const signOptions = {
"identity-validation": false,
// https://github.com/electron-userland/electron-builder/issues/1699
// kext are signed by the chipset manufacturers. You need a special certificate (only available on request) from Apple to be able to sign kext.
ignore: (file) => {
if (filterRe != null) {
for (const regExp of filterRe) {
if (regExp.test(file)) {
return true;
}
}
}
return (file.endsWith(".kext") ||
file.startsWith("/Contents/PlugIns", appPath.length) ||
file.includes("/node_modules/puppeteer/.local-chromium") ||
file.includes("/node_modules/playwright-firefox/.local-browsers") ||
file.includes("/node_modules/playwright/.local-browsers"));
/* Those are browser automating modules, browser (chromium, nightly) cannot be signed
https://github.com/electron-userland/electron-builder/issues/2010
https://github.com/electron-userland/electron-builder/issues/5383
*/
},
identity: identity,
type,
platform: isMas ? "mas" : "darwin",
version: this.config.electronVersion,
app: appPath,
keychain: keychainFile || undefined,
binaries,
timestamp: isMas ? masOptions === null || masOptions === void 0 ? void 0 : masOptions.timestamp : options.timestamp,
requirements: isMas || this.platformSpecificBuildOptions.requirements == null ? undefined : await this.getResource(this.platformSpecificBuildOptions.requirements),
// https://github.com/electron-userland/electron-osx-sign/issues/196
// will fail on 10.14.5+ because a signed but unnotarized app is also rejected.
"gatekeeper-assess": options.gatekeeperAssess === true,
// https://github.com/electron-userland/electron-builder/issues/1480
"strict-verify": options.strictVerify,
hardenedRuntime: isMas ? masOptions && masOptions.hardenedRuntime === true : options.hardenedRuntime !== false,
};
await this.adjustSignOptions(signOptions, masOptions);
builder_util_1.log.info({
file: builder_util_1.log.filePath(appPath),
identityName: identity.name,
identityHash: identity.hash,
provisioningProfile: signOptions["provisioning-profile"] || "none",
}, "signing");
await this.doSign(signOptions);
// https://github.com/electron-userland/electron-builder/issues/1196#issuecomment-312310209
if (masOptions != null && !isDevelopment) {
const certType = isDevelopment ? "Mac Developer" : "3rd Party Mac Developer Installer";
const masInstallerIdentity = await macCodeSign_1.findIdentity(certType, masOptions.identity, keychainFile);
if (masInstallerIdentity == null) {
throw new builder_util_1.InvalidConfigurationError(`Cannot find valid "${certType}" identity to sign MAS installer, please see https://electron.build/code-signing`);
}
// mas uploaded to AppStore, so, use "-" instead of space for name
const artifactName = this.expandArtifactNamePattern(masOptions, "pkg", arch);
const artifactPath = path.join(outDir, artifactName);
await this.doFlat(appPath, artifactPath, masInstallerIdentity, keychainFile);
await this.dispatchArtifactCreated(artifactPath, null, builder_util_1.Arch.x64, this.computeSafeArtifactName(artifactName, "pkg", arch, true, this.platformSpecificBuildOptions.defaultArch));
}
}
async adjustSignOptions(signOptions, masOptions) {
const resourceList = await this.resourceList;
const customSignOptions = masOptions || this.platformSpecificBuildOptions;
const entitlementsSuffix = masOptions == null ? "mac" : "mas";
let entitlements = customSignOptions.entitlements;
if (entitlements == null) {
const p = `entitlements.${entitlementsSuffix}.plist`;
if (resourceList.includes(p)) {
entitlements = path.join(this.info.buildResourcesDir, p);
}
else {
entitlements = pathManager_1.getTemplatePath("entitlements.mac.plist");
}
}
signOptions.entitlements = entitlements;
let entitlementsInherit = customSignOptions.entitlementsInherit;
if (entitlementsInherit == null) {
const p = `entitlements.${entitlementsSuffix}.inherit.plist`;
if (resourceList.includes(p)) {
entitlementsInherit = path.join(this.info.buildResourcesDir, p);
}
else {
entitlementsInherit = pathManager_1.getTemplatePath("entitlements.mac.plist");
}
}
signOptions["entitlements-inherit"] = entitlementsInherit;
if (customSignOptions.provisioningProfile != null) {
signOptions["provisioning-profile"] = customSignOptions.provisioningProfile;
}
signOptions["entitlements-loginhelper"] = customSignOptions.entitlementsLoginHelper;
}
//noinspection JSMethodCanBeStatic
async doSign(opts) {
return electron_osx_sign_1.signAsync(opts);
}
//noinspection JSMethodCanBeStatic
async doFlat(appPath, outFile, identity, keychain) {
// productbuild doesn't created directory for out file
await promises_1.mkdir(path.dirname(outFile), { recursive: true });
const args = pkg_1.prepareProductBuildArgs(identity, keychain);
args.push("--component", appPath, "/Applications");
args.push(outFile);
return await builder_util_1.exec("productbuild", args);
}
getElectronSrcDir(dist) {
return path.resolve(this.projectDir, dist, this.info.framework.distMacOsAppName);
}
getElectronDestinationDir(appOutDir) {
return path.join(appOutDir, this.info.framework.distMacOsAppName);
}
// todo fileAssociations
async applyCommonInfo(appPlist, contentsPath) {
const appInfo = this.appInfo;
const appFilename = appInfo.productFilename;
// https://github.com/electron-userland/electron-builder/issues/1278
appPlist.CFBundleExecutable = appFilename.endsWith(" Helper") ? appFilename.substring(0, appFilename.length - " Helper".length) : appFilename;
const icon = await this.getIconPath();
if (icon != null) {
const oldIcon = appPlist.CFBundleIconFile;
const resourcesPath = path.join(contentsPath, "Resources");
if (oldIcon != null) {
await fs_1.unlinkIfExists(path.join(resourcesPath, oldIcon));
}
const iconFileName = "icon.icns";
appPlist.CFBundleIconFile = iconFileName;
await fs_1.copyFile(icon, path.join(resourcesPath, iconFileName));
}
appPlist.CFBundleName = appInfo.productName;
appPlist.CFBundleDisplayName = appInfo.productName;
const minimumSystemVersion = this.platformSpecificBuildOptions.minimumSystemVersion;
if (minimumSystemVersion != null) {
appPlist.LSMinimumSystemVersion = minimumSystemVersion;
}
appPlist.CFBundleIdentifier = appInfo.macBundleIdentifier;
appPlist.CFBundleShortVersionString = this.platformSpecificBuildOptions.bundleShortVersion || appInfo.version;
appPlist.CFBundleVersion = appInfo.buildVersion;
builder_util_1.use(this.platformSpecificBuildOptions.category || this.config.category, it => (appPlist.LSApplicationCategoryType = it));
appPlist.NSHumanReadableCopyright = appInfo.copyright;
if (this.platformSpecificBuildOptions.darkModeSupport) {
appPlist.NSRequiresAquaSystemAppearance = false;
}
const extendInfo = this.platformSpecificBuildOptions.extendInfo;
if (extendInfo != null) {
Object.assign(appPlist, extendInfo);
}
}
async signApp(packContext, isAsar) {
const appFileName = `${this.appInfo.productFilename}.app`;
await bluebird_lst_1.default.map(promises_1.readdir(packContext.appOutDir), (file) => {
if (file === appFileName) {
return this.sign(path.join(packContext.appOutDir, file), null, null, null);
}
return null;
});
if (!isAsar) {
return;
}
const outResourcesDir = path.join(packContext.appOutDir, "resources", "app.asar.unpacked");
await bluebird_lst_1.default.map(promise_1.orIfFileNotExist(promises_1.readdir(outResourcesDir), []), (file) => {
if (file.endsWith(".app")) {
return this.sign(path.join(outResourcesDir, file), null, null, null);
}
else {
return null;
}
});
}
}
exports.default = MacPackager;
function getCertificateTypes(isMas, isDevelopment) {
if (isDevelopment) {
return isMas ? ["Mac Developer", "Apple Development"] : ["Mac Developer", "Developer ID Application"];
}
return isMas ? ["Apple Distribution", "3rd Party Mac Developer Application"] : ["Developer ID Application"];
}
//# sourceMappingURL=macPackager.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,61 @@
import { TargetSpecificOptions } from "../core";
export interface AppXOptions extends TargetSpecificOptions {
/**
* The application id. Defaults to `identityName`. Cant start with numbers.
*/
readonly applicationId?: string;
/**
* The background color of the app tile. See [Visual Elements](https://msdn.microsoft.com/en-us/library/windows/apps/br211471.aspx).
* @default #464646
*/
readonly backgroundColor?: string | null;
/**
* A friendly name that can be displayed to users. Corresponds to [Properties.DisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211432.aspx).
* Defaults to the application product name.
*/
readonly displayName?: string | null;
/**
* The name. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). Defaults to the [application name](/configuration/configuration#Metadata-name).
*/
readonly identityName?: string | null;
/**
* The Windows Store publisher. Not used if AppX is build for testing. See [AppX Package Code Signing](#appx-package-code-signing) below.
*/
readonly publisher?: string | null;
/**
* A friendly name for the publisher that can be displayed to users. Corresponds to [Properties.PublisherDisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211460.aspx).
* Defaults to company name from the application metadata.
*/
readonly publisherDisplayName?: string | null;
/**
* The list of [supported languages](https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest) that will be listed in the Windows Store.
* The first entry (index 0) will be the default language.
* Defaults to en-US if omitted.
*/
readonly languages?: Array<string> | string | null;
/**
* Whether to add auto launch extension. Defaults to `true` if [electron-winstore-auto-launch](https://github.com/felixrieseberg/electron-winstore-auto-launch) in the dependencies.
*/
readonly addAutoLaunchExtension?: boolean;
/**
* Relative path to custom extensions xml to be included in an `appmanifest.xml`.
*/
readonly customExtensionsPath?: string;
/**
* Whether to overlay the app's name on top of tile images on the Start screen. Defaults to `false`. (https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-shownameontiles) in the dependencies.
* @default false
*/
readonly showNameOnTiles?: boolean;
/**
* @private
* @default false
*/
readonly electronUpdaterAware?: boolean;
/**
* Whether to set build number. See https://github.com/electron-userland/electron-builder/issues/3875
* @default false
*/
readonly setBuildNumber?: boolean;
/** @private */
readonly makeappxArgs?: Array<string> | null;
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=AppXOptions.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"AppXOptions.js","sourceRoot":"","sources":["../../src/options/AppXOptions.ts"],"names":[],"mappings":"","sourcesContent":["import { TargetSpecificOptions } from \"../core\"\n\nexport interface AppXOptions extends TargetSpecificOptions {\n /**\n * The application id. Defaults to `identityName`. Cant start with numbers.\n */\n readonly applicationId?: string\n\n /**\n * The background color of the app tile. See [Visual Elements](https://msdn.microsoft.com/en-us/library/windows/apps/br211471.aspx).\n * @default #464646\n */\n readonly backgroundColor?: string | null\n\n /**\n * A friendly name that can be displayed to users. Corresponds to [Properties.DisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211432.aspx).\n * Defaults to the application product name.\n */\n readonly displayName?: string | null\n\n /**\n * The name. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). Defaults to the [application name](/configuration/configuration#Metadata-name).\n */\n readonly identityName?: string | null\n\n /**\n * The Windows Store publisher. Not used if AppX is build for testing. See [AppX Package Code Signing](#appx-package-code-signing) below.\n */\n readonly publisher?: string | null\n\n /**\n * A friendly name for the publisher that can be displayed to users. Corresponds to [Properties.PublisherDisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211460.aspx).\n * Defaults to company name from the application metadata.\n */\n readonly publisherDisplayName?: string | null\n\n /**\n * The list of [supported languages](https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest) that will be listed in the Windows Store.\n * The first entry (index 0) will be the default language.\n * Defaults to en-US if omitted.\n */\n readonly languages?: Array<string> | string | null\n\n /**\n * Whether to add auto launch extension. Defaults to `true` if [electron-winstore-auto-launch](https://github.com/felixrieseberg/electron-winstore-auto-launch) in the dependencies.\n */\n readonly addAutoLaunchExtension?: boolean\n\n /**\n * Relative path to custom extensions xml to be included in an `appmanifest.xml`.\n */\n readonly customExtensionsPath?: string\n\n /**\n * Whether to overlay the app's name on top of tile images on the Start screen. Defaults to `false`. (https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-shownameontiles) in the dependencies.\n * @default false\n */\n readonly showNameOnTiles?: boolean\n\n /**\n * @private\n * @default false\n */\n readonly electronUpdaterAware?: boolean\n\n /**\n * Whether to set build number. See https://github.com/electron-userland/electron-builder/issues/3875\n * @default false\n */\n readonly setBuildNumber?: boolean\n\n /** @private */\n readonly makeappxArgs?: Array<string> | null\n}\n"]}

View file

@ -0,0 +1,47 @@
import { WinPackager } from "../winPackager";
export interface CommonWindowsInstallerConfiguration {
readonly oneClick?: boolean;
/**
* Whether to install per all users (per-machine).
* @default false
*/
readonly perMachine?: boolean;
/**
* Whether to run the installed application after finish. For assisted installer corresponding checkbox will be removed.
* @default true
*/
readonly runAfterFinish?: boolean;
/**
* Whether to create desktop shortcut. Set to `always` if to recreate also on reinstall (even if removed by user).
* @default true
*/
readonly createDesktopShortcut?: boolean | "always";
/**
* Whether to create start menu shortcut.
* @default true
*/
readonly createStartMenuShortcut?: boolean;
/**
* Whether to create submenu for start menu shortcut and program files directory. If `true`, company name will be used. Or string value.
* @default false
*/
readonly menuCategory?: boolean | string;
/**
* The name that will be used for all shortcuts. Defaults to the application name.
*/
readonly shortcutName?: string | null;
}
export interface FinalCommonWindowsInstallerOptions {
isAssisted: boolean;
isPerMachine: boolean;
shortcutName: string;
menuCategory: string | null;
isCreateDesktopShortcut: DesktopShortcutCreationPolicy;
isCreateStartMenuShortcut: boolean;
}
export declare function getEffectiveOptions(options: CommonWindowsInstallerConfiguration, packager: WinPackager): FinalCommonWindowsInstallerOptions;
export declare enum DesktopShortcutCreationPolicy {
FRESH_INSTALL = 0,
ALWAYS = 1,
NEVER = 2
}

View file

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DesktopShortcutCreationPolicy = exports.getEffectiveOptions = void 0;
const builder_util_1 = require("builder-util");
const filename_1 = require("../util/filename");
function getEffectiveOptions(options, packager) {
const appInfo = packager.appInfo;
let menuCategory = null;
if (options.menuCategory != null && options.menuCategory !== false) {
if (options.menuCategory === true) {
const companyName = packager.appInfo.companyName;
if (companyName == null) {
throw new builder_util_1.InvalidConfigurationError(`Please specify "author" in the application package.json — it is required because "menuCategory" is set to true.`);
}
menuCategory = filename_1.sanitizeFileName(companyName);
}
else {
menuCategory = options.menuCategory
.split(/[/\\]/)
.map(it => filename_1.sanitizeFileName(it))
.join("\\");
}
}
return {
isPerMachine: options.perMachine === true,
isAssisted: options.oneClick === false,
shortcutName: builder_util_1.isEmptyOrSpaces(options.shortcutName) ? appInfo.sanitizedProductName : packager.expandMacro(options.shortcutName),
isCreateDesktopShortcut: convertToDesktopShortcutCreationPolicy(options.createDesktopShortcut),
isCreateStartMenuShortcut: options.createStartMenuShortcut !== false,
menuCategory,
};
}
exports.getEffectiveOptions = getEffectiveOptions;
function convertToDesktopShortcutCreationPolicy(value) {
if (value === false) {
return DesktopShortcutCreationPolicy.NEVER;
}
else if (value === "always") {
return DesktopShortcutCreationPolicy.ALWAYS;
}
else {
return DesktopShortcutCreationPolicy.FRESH_INSTALL;
}
}
var DesktopShortcutCreationPolicy;
(function (DesktopShortcutCreationPolicy) {
DesktopShortcutCreationPolicy[DesktopShortcutCreationPolicy["FRESH_INSTALL"] = 0] = "FRESH_INSTALL";
DesktopShortcutCreationPolicy[DesktopShortcutCreationPolicy["ALWAYS"] = 1] = "ALWAYS";
DesktopShortcutCreationPolicy[DesktopShortcutCreationPolicy["NEVER"] = 2] = "NEVER";
})(DesktopShortcutCreationPolicy = exports.DesktopShortcutCreationPolicy || (exports.DesktopShortcutCreationPolicy = {}));
//# sourceMappingURL=CommonWindowsInstallerConfiguration.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"CommonWindowsInstallerConfiguration.js","sourceRoot":"","sources":["../../src/options/CommonWindowsInstallerConfiguration.ts"],"names":[],"mappings":";;;AAAA,+CAAyE;AACzE,+CAAmD;AAqDnD,SAAgB,mBAAmB,CAAC,OAA4C,EAAE,QAAqB;IACrG,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;IAEhC,IAAI,YAAY,GAAkB,IAAI,CAAA;IACtC,IAAI,OAAO,CAAC,YAAY,IAAI,IAAI,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,EAAE;QAClE,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EAAE;YACjC,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAA;YAChD,IAAI,WAAW,IAAI,IAAI,EAAE;gBACvB,MAAM,IAAI,wCAAyB,CAAC,iHAAiH,CAAC,CAAA;aACvJ;YACD,YAAY,GAAG,2BAAgB,CAAC,WAAW,CAAC,CAAA;SAC7C;aAAM;YACL,YAAY,GAAG,OAAO,CAAC,YAAY;iBAChC,KAAK,CAAC,OAAO,CAAC;iBACd,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,2BAAgB,CAAC,EAAE,CAAC,CAAC;iBAC/B,IAAI,CAAC,IAAI,CAAC,CAAA;SACd;KACF;IAED,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,UAAU,KAAK,IAAI;QACzC,UAAU,EAAE,OAAO,CAAC,QAAQ,KAAK,KAAK;QAEtC,YAAY,EAAE,8BAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC;QAC/H,uBAAuB,EAAE,sCAAsC,CAAC,OAAO,CAAC,qBAAqB,CAAC;QAC9F,yBAAyB,EAAE,OAAO,CAAC,uBAAuB,KAAK,KAAK;QACpE,YAAY;KACb,CAAA;AACH,CAAC;AA5BD,kDA4BC;AAED,SAAS,sCAAsC,CAAC,KAAmC;IACjF,IAAI,KAAK,KAAK,KAAK,EAAE;QACnB,OAAO,6BAA6B,CAAC,KAAK,CAAA;KAC3C;SAAM,IAAI,KAAK,KAAK,QAAQ,EAAE;QAC7B,OAAO,6BAA6B,CAAC,MAAM,CAAA;KAC5C;SAAM;QACL,OAAO,6BAA6B,CAAC,aAAa,CAAA;KACnD;AACH,CAAC;AAED,IAAY,6BAIX;AAJD,WAAY,6BAA6B;IACvC,mGAAa,CAAA;IACb,qFAAM,CAAA;IACN,mFAAK,CAAA;AACP,CAAC,EAJW,6BAA6B,GAA7B,qCAA6B,KAA7B,qCAA6B,QAIxC","sourcesContent":["import { InvalidConfigurationError, isEmptyOrSpaces } from \"builder-util\"\nimport { sanitizeFileName } from \"../util/filename\"\nimport { WinPackager } from \"../winPackager\"\n\nexport interface CommonWindowsInstallerConfiguration {\n readonly oneClick?: boolean\n\n /**\n * Whether to install per all users (per-machine).\n * @default false\n */\n readonly perMachine?: boolean\n\n /**\n * Whether to run the installed application after finish. For assisted installer corresponding checkbox will be removed.\n * @default true\n */\n readonly runAfterFinish?: boolean\n\n /**\n * Whether to create desktop shortcut. Set to `always` if to recreate also on reinstall (even if removed by user).\n * @default true\n */\n readonly createDesktopShortcut?: boolean | \"always\"\n\n /**\n * Whether to create start menu shortcut.\n * @default true\n */\n readonly createStartMenuShortcut?: boolean\n\n /**\n * Whether to create submenu for start menu shortcut and program files directory. If `true`, company name will be used. Or string value.\n * @default false\n */\n readonly menuCategory?: boolean | string\n\n /**\n * The name that will be used for all shortcuts. Defaults to the application name.\n */\n readonly shortcutName?: string | null\n}\n\nexport interface FinalCommonWindowsInstallerOptions {\n isAssisted: boolean\n isPerMachine: boolean\n\n shortcutName: string\n menuCategory: string | null\n\n isCreateDesktopShortcut: DesktopShortcutCreationPolicy\n isCreateStartMenuShortcut: boolean\n}\n\nexport function getEffectiveOptions(options: CommonWindowsInstallerConfiguration, packager: WinPackager): FinalCommonWindowsInstallerOptions {\n const appInfo = packager.appInfo\n\n let menuCategory: string | null = null\n if (options.menuCategory != null && options.menuCategory !== false) {\n if (options.menuCategory === true) {\n const companyName = packager.appInfo.companyName\n if (companyName == null) {\n throw new InvalidConfigurationError(`Please specify \"author\" in the application package.json — it is required because \"menuCategory\" is set to true.`)\n }\n menuCategory = sanitizeFileName(companyName)\n } else {\n menuCategory = options.menuCategory\n .split(/[/\\\\]/)\n .map(it => sanitizeFileName(it))\n .join(\"\\\\\")\n }\n }\n\n return {\n isPerMachine: options.perMachine === true,\n isAssisted: options.oneClick === false,\n\n shortcutName: isEmptyOrSpaces(options.shortcutName) ? appInfo.sanitizedProductName : packager.expandMacro(options.shortcutName),\n isCreateDesktopShortcut: convertToDesktopShortcutCreationPolicy(options.createDesktopShortcut),\n isCreateStartMenuShortcut: options.createStartMenuShortcut !== false,\n menuCategory,\n }\n}\n\nfunction convertToDesktopShortcutCreationPolicy(value: boolean | undefined | string): DesktopShortcutCreationPolicy {\n if (value === false) {\n return DesktopShortcutCreationPolicy.NEVER\n } else if (value === \"always\") {\n return DesktopShortcutCreationPolicy.ALWAYS\n } else {\n return DesktopShortcutCreationPolicy.FRESH_INSTALL\n }\n}\n\nexport enum DesktopShortcutCreationPolicy {\n FRESH_INSTALL,\n ALWAYS,\n NEVER,\n}\n"]}

View file

@ -0,0 +1,45 @@
/**
* File associations.
*
* macOS (corresponds to [CFBundleDocumentTypes](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-101685)), NSIS, and MSI only.
*
* On Windows (NSIS) works only if [nsis.perMachine](https://electron.build/configuration/configuration#NsisOptions-perMachine) is set to `true`.
*/
export interface FileAssociation {
/**
* The extension (minus the leading period). e.g. `png`.
*/
readonly ext: string | Array<string>;
/**
* The name. e.g. `PNG`. Defaults to `ext`.
*/
readonly name?: string | null;
/**
* *windows-only.* The description.
*/
readonly description?: string | null;
/**
* *linux-only.* The mime-type.
*/
readonly mimeType?: string | null;
/**
* The path to icon (`.icns` for MacOS and `.ico` for Windows), relative to `build` (build resources directory). Defaults to `${firstExt}.icns`/`${firstExt}.ico` (if several extensions specified, first is used) or to application icon.
*
* Not supported on Linux, file issue if need (default icon will be `x-office-document`). Not supported on MSI.
*/
readonly icon?: string | null;
/**
* *macOS-only* The apps role with respect to the type. The value can be `Editor`, `Viewer`, `Shell`, or `None`. Corresponds to `CFBundleTypeRole`.
* @default Editor
*/
readonly role?: string;
/**
* *macOS-only* Whether the document is distributed as a bundle. If set to true, the bundle directory is treated as a file. Corresponds to `LSTypeIsPackage`.
*/
readonly isPackage?: boolean;
/**
* *macOS-only* The apps rank with respect to the type. The value can be `Owner`, `Default`, `Alternate`, or `None`. Corresponds to `LSHandlerRank`.
* @default Default
*/
readonly rank?: string;
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=FileAssociation.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"FileAssociation.js","sourceRoot":"","sources":["../../src/options/FileAssociation.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * File associations.\n *\n * macOS (corresponds to [CFBundleDocumentTypes](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-101685)), NSIS, and MSI only.\n *\n * On Windows (NSIS) works only if [nsis.perMachine](https://electron.build/configuration/configuration#NsisOptions-perMachine) is set to `true`.\n */\nexport interface FileAssociation {\n /**\n * The extension (minus the leading period). e.g. `png`.\n */\n readonly ext: string | Array<string>\n\n /**\n * The name. e.g. `PNG`. Defaults to `ext`.\n */\n readonly name?: string | null\n\n /**\n * *windows-only.* The description.\n */\n readonly description?: string | null\n\n /**\n * *linux-only.* The mime-type.\n */\n readonly mimeType?: string | null\n\n /**\n * The path to icon (`.icns` for MacOS and `.ico` for Windows), relative to `build` (build resources directory). Defaults to `${firstExt}.icns`/`${firstExt}.ico` (if several extensions specified, first is used) or to application icon.\n *\n * Not supported on Linux, file issue if need (default icon will be `x-office-document`). Not supported on MSI.\n */\n readonly icon?: string | null\n\n /**\n * *macOS-only* The apps role with respect to the type. The value can be `Editor`, `Viewer`, `Shell`, or `None`. Corresponds to `CFBundleTypeRole`.\n * @default Editor\n */\n readonly role?: string\n\n /**\n * *macOS-only* Whether the document is distributed as a bundle. If set to true, the bundle directory is treated as a file. Corresponds to `LSTypeIsPackage`.\n */\n readonly isPackage?: boolean\n\n /**\n * *macOS-only* The apps rank with respect to the type. The value can be `Owner`, `Default`, `Alternate`, or `None`. Corresponds to `LSHandlerRank`.\n * @default Default\n */\n readonly rank?: string\n}\n"]}

View file

@ -0,0 +1,22 @@
import { TargetSpecificOptions } from "../core";
import { CommonWindowsInstallerConfiguration } from "./CommonWindowsInstallerConfiguration";
export interface MsiOptions extends CommonWindowsInstallerConfiguration, TargetSpecificOptions {
/**
* One-click installation.
* @default true
*/
readonly oneClick?: boolean;
/**
* The [upgrade code](https://msdn.microsoft.com/en-us/library/windows/desktop/aa372375(v=vs.85).aspx). Optional, by default generated using app id.
*/
readonly upgradeCode?: string | null;
/**
* If `warningsAsErrors` is `true` (default): treat warnings as errors. If `warningsAsErrors` is `false`: allow warnings.
* @default true
*/
readonly warningsAsErrors?: boolean;
/**
* Any additional arguments to be passed to the WiX installer compiler, such as `["-ext", "WixUtilExtension"]`
*/
readonly additionalWixArgs?: Array<string> | null;
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=MsiOptions.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"MsiOptions.js","sourceRoot":"","sources":["../../src/options/MsiOptions.ts"],"names":[],"mappings":"","sourcesContent":["import { TargetSpecificOptions } from \"../core\"\nimport { CommonWindowsInstallerConfiguration } from \"./CommonWindowsInstallerConfiguration\"\n\nexport interface MsiOptions extends CommonWindowsInstallerConfiguration, TargetSpecificOptions {\n /**\n * One-click installation.\n * @default true\n */\n readonly oneClick?: boolean\n\n /**\n * The [upgrade code](https://msdn.microsoft.com/en-us/library/windows/desktop/aa372375(v=vs.85).aspx). Optional, by default generated using app id.\n */\n readonly upgradeCode?: string | null\n\n /**\n * If `warningsAsErrors` is `true` (default): treat warnings as errors. If `warningsAsErrors` is `false`: allow warnings.\n * @default true\n */\n readonly warningsAsErrors?: boolean\n\n /**\n * Any additional arguments to be passed to the WiX installer compiler, such as `[\"-ext\", \"WixUtilExtension\"]`\n */\n readonly additionalWixArgs?: Array<string> | null\n}\n"]}

View file

@ -0,0 +1,140 @@
import { CompressionLevel, Publish, TargetConfiguration, TargetSpecificOptions } from "../core";
import { FileAssociation } from "./FileAssociation";
export interface FileSet {
/**
* The source path relative to the project directory.
*/
from?: string;
/**
* The destination path relative to the app's content directory for `extraFiles` and the app's resource directory for `extraResources`.
*/
to?: string;
/**
* The [glob patterns](/file-patterns).
*/
filter?: Array<string> | string;
}
export interface AsarOptions {
/**
* Whether to automatically unpack executables files.
* @default true
*/
smartUnpack?: boolean;
ordering?: string | null;
}
export interface PlatformSpecificBuildOptions extends TargetSpecificOptions {
/**
* The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as
* [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported). It is strongly recommended that an explicit ID is set.
* @default com.electron.${name}
*/
readonly appId?: string | null;
/**
* The [artifact file name template](/configuration/configuration#artifact-file-name-template). Defaults to `${productName}-${version}.${ext}` (some target can have other defaults, see corresponding options).
*/
readonly artifactName?: string | null;
/**
* The executable name. Defaults to `productName`.
*/
readonly executableName?: string | null;
/**
* The compression level. If you want to rapidly test build, `store` can reduce build time significantly. `maximum` doesn't lead to noticeable size difference, but increase build time.
* @default normal
*/
readonly compression?: CompressionLevel | null;
files?: Array<FileSet | string> | FileSet | string | null;
extraResources?: Array<FileSet | string> | FileSet | string | null;
extraFiles?: Array<FileSet | string> | FileSet | string | null;
/**
* Whether to package the application's source code into an archive, using [Electron's archive format](http://electron.atom.io/docs/tutorial/application-packaging/).
*
* Node modules, that must be unpacked, will be detected automatically, you don't need to explicitly set [asarUnpack](#configuration-asarUnpack) - please file an issue if this doesn't work.
* @default true
*/
readonly asar?: AsarOptions | boolean | null;
/**
* A [glob patterns](/file-patterns) relative to the [app directory](#MetadataDirectories-app), which specifies which files to unpack when creating the [asar](http://electron.atom.io/docs/tutorial/application-packaging/) archive.
*/
readonly asarUnpack?: Array<string> | string | null;
/** @private */
readonly icon?: string | null;
/**
* The file associations.
*/
readonly fileAssociations?: Array<FileAssociation> | FileAssociation;
/**
* The URL protocol schemes.
*/
readonly protocols?: Array<Protocol> | Protocol;
/**
* Whether to fail if app will be not code signed.
*/
readonly forceCodeSigning?: boolean;
/**
* The [electron-updater compatibility](/auto-update#compatibility) semver range.
*/
readonly electronUpdaterCompatibility?: string | null;
publish?: Publish;
/**
* Whether to infer update channel from application version pre-release components. e.g. if version `0.12.1-alpha.1`, channel will be set to `alpha`. Otherwise to `latest`.
* @default true
*/
readonly detectUpdateChannel?: boolean;
/**
* Please see [Building and Releasing using Channels](https://github.com/electron-userland/electron-builder/issues/1182#issuecomment-324947139).
* @default false
*/
readonly generateUpdatesFilesForAllChannels?: boolean;
/**
* The release info. Intended for command line usage:
*
* ```
* -c.releaseInfo.releaseNotes="new features"
* ```
*/
readonly releaseInfo?: ReleaseInfo;
readonly target?: Array<string | TargetConfiguration> | string | TargetConfiguration | null;
/** @private */
cscLink?: string | null;
/** @private */
cscKeyPassword?: string | null;
readonly defaultArch?: string;
}
export interface ReleaseInfo {
/**
* The release name.
*/
releaseName?: string | null;
/**
* The release notes.
*/
releaseNotes?: string | null;
/**
* The path to release notes file. Defaults to `release-notes-${platform}.md` (where `platform` it is current platform `mac`, `linux` or `windows`) or `release-notes.md` in the [build resources](#MetadataDirectories-buildResources).
*/
releaseNotesFile?: string | null;
/**
* The release date.
*/
releaseDate?: string;
}
/**
* URL Protocol Schemes. Protocols to associate the app with. macOS only.
*
* Please note on macOS [you need to register an `open-url` event handler](http://electron.atom.io/docs/api/app/#event-open-url-macos).
*/
export interface Protocol {
/**
* The name. e.g. `IRC server URL`.
*/
readonly name: string;
/**
* The schemes. e.g. `["irc", "ircs"]`.
*/
readonly schemes: Array<string>;
/**
* *macOS-only* The apps role with respect to the type.
* @default Editor
*/
readonly role?: "Editor" | "Viewer" | "Shell" | "None";
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=PlatformSpecificBuildOptions.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,137 @@
import { TargetSpecificOptions } from "../core";
import { CommonLinuxOptions } from "./linuxOptions";
export interface SnapOptions extends CommonLinuxOptions, TargetSpecificOptions {
/**
* The type of [confinement](https://snapcraft.io/docs/reference/confinement) supported by the snap.
* @default strict
*/
readonly confinement?: "devmode" | "strict" | "classic" | null;
/**
* The custom environment. Defaults to `{"TMPDIR: "$XDG_RUNTIME_DIR"}`. If you set custom, it will be merged with default.
*/
readonly environment?: {
[key: string]: string;
} | null;
/**
* The 78 character long summary. Defaults to [productName](/configuration/configuration#Configuration-productName).
*/
readonly summary?: string | null;
/**
* The quality grade of the snap. It can be either `devel` (i.e. a development version of the snap, so not to be published to the stable or candidate channels) or stable (i.e. a stable release or release candidate, which can be released to all channels).
* @default stable
*/
readonly grade?: "devel" | "stable" | null;
/**
* The list of features that must be supported by the core in order for this snap to install.
*/
readonly assumes?: Array<string> | string | null;
/**
* The list of debian packages needs to be installed for building this snap.
*/
readonly buildPackages?: Array<string> | null;
/**
* The list of Ubuntu packages to use that are needed to support the `app` part creation. Like `depends` for `deb`.
* Defaults to `["libnspr4", "libnss3", "libxss1", "libappindicator3-1", "libsecret-1-0"]`.
*
* If list contains `default`, it will be replaced to default list, so, `["default", "foo"]` can be used to add custom package `foo` in addition to defaults.
*/
readonly stagePackages?: Array<string> | null;
/**
* The [hooks](https://docs.snapcraft.io/build-snaps/hooks) directory, relative to `build` (build resources directory).
* @default build/snap-hooks
*/
readonly hooks?: string | null;
/**
* The list of [plugs](https://snapcraft.io/docs/reference/interfaces).
* Defaults to `["desktop", "desktop-legacy", "home", "x11", "wayland", "unity7", "browser-support", "network", "gsettings", "audio-playback", "pulseaudio", "opengl"]`.
*
* If list contains `default`, it will be replaced to default list, so, `["default", "foo"]` can be used to add custom plug `foo` in addition to defaults.
*
* Additional attributes can be specified using object instead of just name of plug:
* ```
*[
* {
* "browser-sandbox": {
* "interface": "browser-support",
* "allow-sandbox": true
* },
* },
* "another-simple-plug-name"
*]
* ```
*/
readonly plugs?: Array<string | PlugDescriptor> | PlugDescriptor | null;
/**
* The list of [slots](https://snapcraft.io/docs/reference/interfaces).
*
* Additional attributes can be specified using object instead of just name of slot:
* ```
*[
* {
* "mpris": {
* "name": "chromium"
* },
* }
*]
*
* In case you want your application to be a compliant MPris player, you will need to definie
* The mpris slot with "chromium" name.
* This electron has it [hardcoded](https://source.chromium.org/chromium/chromium/src/+/master:components/system_media_controls/linux/system_media_controls_linux.cc;l=51;bpv=0;bpt=1),
* and we need to pass this name so snap [will allow it](https://forum.snapcraft.io/t/unable-to-use-mpris-interface/15360/7) in strict confinement.
*
*/
readonly slots?: Array<string | SlotDescriptor> | PlugDescriptor | null;
/**
* Specifies any [parts](https://snapcraft.io/docs/reference/parts) that should be built before this part.
* Defaults to `["desktop-gtk2""]`.
*
* If list contains `default`, it will be replaced to default list, so, `["default", "foo"]` can be used to add custom parts `foo` in addition to defaults.
*/
readonly after?: Array<string> | null;
/**
* Whether to use template snap. Defaults to `true` if `stagePackages` not specified.
*/
readonly useTemplateApp?: boolean;
/**
* Whether or not the snap should automatically start on login.
* @default false
*/
readonly autoStart?: boolean;
/**
* Specifies any files to make accessible from locations such as `/usr`, `/var`, and `/etc`. See [snap layouts](https://snapcraft.io/docs/snap-layouts) to learn more.
*/
readonly layout?: {
[key: string]: {
[key: string]: string;
};
} | null;
/**
* Specifies which files from the app part to stage and which to exclude. Individual files, directories, wildcards, globstars, and exclusions are accepted. See [Snapcraft filesets](https://snapcraft.io/docs/snapcraft-filesets) to learn more about the format.
*
* The defaults can be found in [snap.ts](https://github.com/electron-userland/electron-builder/blob/master/packages/app-builder-lib/templates/snap/snapcraft.yaml#L29).
*/
readonly appPartStage?: Array<string> | null;
/**
* An optional title for the snap, may contain uppercase letters and spaces. Defaults to `productName`. See [snap format documentation](https://snapcraft.io/docs/snap-format).
*/
readonly title?: string | null;
/**
* Sets the compression type for the snap. Can be xz, lzo, or null.
*/
readonly compression?: "xz" | "lzo" | null;
/**
* Allow running the program with native wayland support with --ozone-platform=wayland.
* Disabled by default because of this issue in older Electron/Snap versions: https://github.com/electron-userland/electron-builder/issues/4007
*/
readonly allowNativeWayland?: boolean | null;
}
export interface PlugDescriptor {
[key: string]: {
[key: string]: any;
} | null;
}
export interface SlotDescriptor {
[key: string]: {
[key: string]: any;
} | null;
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=SnapOptions.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,41 @@
/**
* Squirrel.Windows options.
*/
import { TargetSpecificOptions } from "../core";
export interface SquirrelWindowsOptions extends TargetSpecificOptions {
/**
* A URL to an ICO file to use as the application icon (displayed in Control Panel > Programs and Features). Defaults to the Electron icon.
*
* Please note [local icon file url is not accepted](https://github.com/atom/grunt-electron-installer/issues/73), must be https/http.
*
* If you don't plan to build windows installer, you can omit it.
* If your project repository is public on GitHub, it will be `https://github.com/${u}/${p}/blob/master/build/icon.ico?raw=true` by default.
*/
readonly iconUrl?: string | null;
/**
* The path to a .gif file to display during install. `build/install-spinner.gif` will be used if exists (it is a recommended way to set)
* (otherwise [default](https://github.com/electron/windows-installer/blob/master/resources/install-spinner.gif)).
*/
readonly loadingGif?: string | null;
/**
* Whether to create an MSI installer. Defaults to `false` (MSI is not created).
*/
readonly msi?: boolean;
/**
* A URL to your existing updates. Or `true` to automatically set to your GitHub repository. If given, these will be downloaded to create delta updates.
*/
readonly remoteReleases?: string | boolean | null;
/**
* Authentication token for remote updates
*/
readonly remoteToken?: string | null;
/**
* Use `appId` to identify package instead of `name`.
*/
readonly useAppIdAsId?: boolean;
/**
* https://github.com/electron-userland/electron-builder/issues/1743
* @private
*/
readonly name?: string;
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=SquirrelWindowsOptions.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"SquirrelWindowsOptions.js","sourceRoot":"","sources":["../../src/options/SquirrelWindowsOptions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Squirrel.Windows options.\n */\nimport { TargetSpecificOptions } from \"../core\"\n\nexport interface SquirrelWindowsOptions extends TargetSpecificOptions {\n /**\n * A URL to an ICO file to use as the application icon (displayed in Control Panel > Programs and Features). Defaults to the Electron icon.\n *\n * Please note — [local icon file url is not accepted](https://github.com/atom/grunt-electron-installer/issues/73), must be https/http.\n *\n * If you don't plan to build windows installer, you can omit it.\n * If your project repository is public on GitHub, it will be `https://github.com/${u}/${p}/blob/master/build/icon.ico?raw=true` by default.\n */\n readonly iconUrl?: string | null\n\n /**\n * The path to a .gif file to display during install. `build/install-spinner.gif` will be used if exists (it is a recommended way to set)\n * (otherwise [default](https://github.com/electron/windows-installer/blob/master/resources/install-spinner.gif)).\n */\n readonly loadingGif?: string | null\n\n /**\n * Whether to create an MSI installer. Defaults to `false` (MSI is not created).\n */\n readonly msi?: boolean\n\n /**\n * A URL to your existing updates. Or `true` to automatically set to your GitHub repository. If given, these will be downloaded to create delta updates.\n */\n readonly remoteReleases?: string | boolean | null\n\n /**\n * Authentication token for remote updates\n */\n readonly remoteToken?: string | null\n\n /**\n * Use `appId` to identify package instead of `name`.\n */\n readonly useAppIdAsId?: boolean\n\n /**\n * https://github.com/electron-userland/electron-builder/issues/1743\n * @private\n */\n readonly name?: string\n}\n"]}

View file

@ -0,0 +1,197 @@
import { PlatformSpecificBuildOptions, TargetConfigType, TargetSpecificOptions } from "../index";
export interface LinuxConfiguration extends CommonLinuxOptions, PlatformSpecificBuildOptions {
/**
* Target package type: list of `AppImage`, `flatpak`, `snap`, `deb`, `rpm`, `freebsd`, `pacman`, `p5p`, `apk`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`.
*
* electron-builder [docker image](/multi-platform-build#docker) can be used to build Linux targets on any platform.
*
* Please [do not put an AppImage into another archive](https://github.com/probonopd/AppImageKit/wiki/Creating-AppImages#common-mistake) like a .zip or .tar.gz.
* @default AppImage
*/
readonly target?: TargetConfigType;
/**
* The maintainer. Defaults to [author](/configuration/configuration#Metadata-author).
*/
readonly maintainer?: string | null;
/**
* The vendor. Defaults to [author](/configuration/configuration#Metadata-author).
*/
readonly vendor?: string | null;
/**
* The path to icon set directory or one png file, relative to the [build resources](/configuration/configuration#MetadataDirectories-buildResources) or to the project directory. The icon filename must contain the size (e.g. 32x32.png) of the icon.
* By default will be generated automatically based on the macOS icns file.
*/
readonly icon?: string;
/**
* backward compatibility + to allow specify fpm-only category for all possible fpm targets in one place
* @private
*/
readonly packageCategory?: string | null;
}
export interface CommonLinuxOptions {
/**
* The [short description](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Description).
*/
readonly synopsis?: string | null;
/**
* As [description](/configuration/configuration#Metadata-description) from application package.json, but allows you to specify different for Linux.
*/
readonly description?: string | null;
/**
* The [application category](https://specifications.freedesktop.org/menu-spec/latest/apa.html#main-category-registry).
*/
readonly category?: string | null;
/**
* The mime types in addition to specified in the file associations. Use it if you don't want to register a new mime type, but reuse existing.
*/
readonly mimeTypes?: Array<string> | null;
/**
* The [Desktop file](https://developer.gnome.org/documentation/guidelines/maintainer/integrating.html#desktop-files) entries (name to value).
*/
readonly desktop?: any | null;
/**
* The executable parameters. Pass to executableName
*/
readonly executableArgs?: Array<string> | null;
}
export interface LinuxTargetSpecificOptions extends CommonLinuxOptions, TargetSpecificOptions {
/**
* Package dependencies.
*/
readonly depends?: Array<string> | null;
/**
* The compression type.
* @default xz
*/
readonly compression?: "gz" | "bzip2" | "xz" | "lzo" | null;
readonly icon?: string;
/**
* The package category.
*/
readonly packageCategory?: string | null;
/**
* The name of the package.
*/
readonly packageName?: string | null;
readonly vendor?: string | null;
readonly maintainer?: string | null;
readonly afterInstall?: string | null;
readonly afterRemove?: string | null;
/**
* *Advanced only* The [fpm](https://github.com/jordansissel/fpm/wiki#usage) options.
*
* Example: `["--before-install=build/deb-preinstall.sh", "--after-upgrade=build/deb-postinstall.sh"]`
*/
readonly fpm?: Array<string> | null;
}
export interface DebOptions extends LinuxTargetSpecificOptions {
/**
* Package dependencies. Defaults to `["gconf2", "gconf-service", "libnotify4", "libappindicator1", "libxtst6", "libnss3"]`.
* If need to support Debian, `libappindicator1` should be removed, it is [deprecated in Debian](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=895037).
* If need to support KDE, `gconf2` and `gconf-service` should be removed as it's no longer used by GNOME](https://packages.debian.org/bullseye/gconf2).
*/
readonly depends?: Array<string> | null;
/**
* The [package category](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Section).
*/
readonly packageCategory?: string | null;
/**
* The [Priority](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Priority) attribute.
*/
readonly priority?: string | null;
}
export interface AppImageOptions extends CommonLinuxOptions, TargetSpecificOptions {
/**
* The path to EULA license file. Defaults to `license.txt` or `eula.txt` (or uppercase variants). Only plain text is supported.
*/
readonly license?: string | null;
}
export interface FlatpakOptions extends CommonLinuxOptions, TargetSpecificOptions {
/**
* The path to EULA license file. Defaults to `license.txt` or `eula.txt` (or uppercase variants). Only plain text is supported.
*/
readonly license?: string | null;
/**
* The name of the runtime that the application uses. Defaults to `org.freedesktop.Platform`.
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly runtime?: string;
/**
* The version of the runtime that the application uses. Defaults to `20.08`.
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly runtimeVersion?: string;
/**
* The name of the development runtime that the application builds with. Defaults to `org.freedesktop.Sdk`.
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly sdk?: string;
/**
* Start with the files from the specified application. This can be used to create applications that extend another application.
* Defaults to [org.electronjs.Electron2.BaseApp](https://github.com/flathub/org.electronjs.Electron2.BaseApp).
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly base?: string;
/**
* Use this specific version of the application specified in base. Defaults to `20.08`.
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly baseVersion?: string;
/**
* The branch to use when exporting the application. Defaults to `master`.
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly branch?: string;
/**
* An array of arguments passed to the flatpak build-finish command. Defaults to:
* ```json
* [
* // Wayland/X11 Rendering
* "--socket=wayland",
* "--socket=x11",
* "--share=ipc",
* // Open GL
* "--device=dri",
* // Audio output
* "--socket=pulseaudio",
* // Read/write home directory access
* "--filesystem=home",
* // Allow communication with network
* "--share=network",
* // System notifications with libnotify
* "--talk-name=org.freedesktop.Notifications",
* ]
* ```
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly finishArgs?: string[];
/**
* An array of objects specifying the modules to be built in order.
*
* See [flatpak manifest documentation](https://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html#flatpak-manifest).
*/
readonly modules?: (string | any)[];
/**
* Files to copy directly into the app. Should be a list of [source, dest] tuples. Source should be a relative/absolute path to a file/directory to copy into the flatpak, and dest should be the path inside the app install prefix (e.g. /share/applications/).
*
* See [@malept/flatpak-bundler documentation](https://github.com/malept/flatpak-bundler#build-options).
*/
readonly files?: [string, string][];
/**
* Symlinks to create in the app files. Should be a list of [target, location] symlink tuples. Target can be either a relative or absolute path inside the app install prefix, and location should be a absolute path inside the prefix to create the symlink at.
*
* See [@malept/flatpak-bundler documentation](https://github.com/malept/flatpak-bundler#build-options).
*/
readonly symlinks?: [string, string][];
/**
* Whether to enable the Wayland specific flags (`--enable-features=UseOzonePlatform --ozone-platform=wayland`) in the wrapper script. These flags are only available starting with Electron version 12. Defaults to `false`.
*/
readonly useWaylandFlags?: boolean;
}

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=linuxOptions.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,295 @@
import { PlatformSpecificBuildOptions, TargetConfiguration, TargetSpecificOptions } from "../index";
export declare type MacOsTargetName = "default" | "dmg" | "mas" | "mas-dev" | "pkg" | "7z" | "zip" | "tar.xz" | "tar.lz" | "tar.gz" | "tar.bz2" | "dir";
export interface MacConfiguration extends PlatformSpecificBuildOptions {
/**
* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
*
* For example, `"category": "public.app-category.developer-tools"` will set the application category to *Developer Tools*.
*
* Valid values are listed in [Apple's documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).
*/
readonly category?: string | null;
/**
* The target package type: list of `default`, `dmg`, `mas`, `mas-dev`, `pkg`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `default` (dmg and zip for Squirrel.Mac).
*/
readonly target?: Array<MacOsTargetName | TargetConfiguration> | MacOsTargetName | TargetConfiguration | null;
/**
* The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](/code-signing) instead of specifying this option.
* MAS installer identity is specified in the [mas](/configuration/mas).
*/
readonly identity?: string | null;
/**
* The path to application icon.
* @default build/icon.icns
*/
readonly icon?: string | null;
/**
* The path to entitlements file for signing the app. `build/entitlements.mac.plist` will be used if exists (it is a recommended way to set).
* MAS entitlements is specified in the [mas](/configuration/mas).
* See [this folder in osx-sign's repository](https://github.com/electron/osx-sign/tree/main/entitlements) for examples.
* Be aware that your app may crash if the right entitlements are not set like `com.apple.security.cs.allow-jit` for example on arm64 builds with Electron 20+.
* See [Signing and Notarizing macOS Builds from the Electron documentation](https://www.electronjs.org/docs/latest/tutorial/code-signing#signing--notarizing-macos-builds) for more information.
*/
readonly entitlements?: string | null;
/**
* The path to child entitlements which inherit the security settings for signing frameworks and bundles of a distribution. `build/entitlements.mac.inherit.plist` will be used if exists (it is a recommended way to set).
* See [this folder in osx-sign's repository](https://github.com/electron/osx-sign/tree/main/entitlements) for examples.
*
* This option only applies when signing with `entitlements` provided.
*/
readonly entitlementsInherit?: string | null;
/**
* Path to login helper entitlement file.
* When using App Sandbox, the the `com.apple.security.inherit` key that is normally in the inherited entitlements cannot be inherited since the login helper is a standalone executable.
* Defaults to the value provided for `entitlements`. This option only applies when signing with `entitlements` provided.
*/
readonly entitlementsLoginHelper?: string | null;
/**
* The path to the provisioning profile to use when signing, absolute or relative to the app root.
*/
readonly provisioningProfile?: string | null;
/**
* The `CFBundleVersion`. Do not use it unless [you need to](https://github.com/electron-userland/electron-builder/issues/565#issuecomment-230678643).
*/
readonly bundleVersion?: string | null;
/**
* The `CFBundleShortVersionString`. Do not use it unless you need to.
*/
readonly bundleShortVersion?: string | null;
/**
* Whether a dark mode is supported. If your app does have a dark mode, you can make your app follow the system-wide dark mode setting.
* @default false
*/
readonly darkModeSupport?: boolean;
/**
* The bundle identifier to use in the application helper's plist.
* @default ${appBundleIdentifier}.helper
*/
readonly helperBundleId?: string | null;
/**
* The bundle identifier to use in the Renderer helper's plist.
* @default ${appBundleIdentifier}.helper.Renderer
*/
readonly helperRendererBundleId?: string | null;
/**
* The bundle identifier to use in the Plugin helper's plist.
* @default ${appBundleIdentifier}.helper.Plugin
*/
readonly helperPluginBundleId?: string | null;
/**
* The bundle identifier to use in the GPU helper's plist.
* @default ${appBundleIdentifier}.helper.GPU
*/
readonly helperGPUBundleId?: string | null;
/**
* The bundle identifier to use in the EH helper's plist.
* @default ${appBundleIdentifier}.helper.EH
*/
readonly helperEHBundleId?: string | null;
/**
* The bundle identifier to use in the NP helper's plist.
* @default ${appBundleIdentifier}.helper.NP
*/
readonly helperNPBundleId?: string | null;
/**
* Whether to sign app for development or for distribution.
* @default distribution
*/
readonly type?: "distribution" | "development" | null;
/**
* The extra entries for `Info.plist`.
*/
readonly extendInfo?: any;
/**
* Paths of any extra binaries that need to be signed.
*/
readonly binaries?: Array<string> | null;
/**
* The minimum version of macOS required for the app to run. Corresponds to `LSMinimumSystemVersion`.
*/
readonly minimumSystemVersion?: string | null;
/**
* Path of [requirements file](https://developer.apple.com/library/mac/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html) used in signing. Not applicable for MAS.
*/
readonly requirements?: string | null;
/**
* The electron locales. By default Electron locales used as is.
*/
readonly electronLanguages?: Array<string> | string;
/** @private */
readonly cscInstallerLink?: string | null;
/** @private */
readonly cscInstallerKeyPassword?: string | null;
/**
* Extra files to put in archive. Not applicable for `tar.*`.
*/
readonly extraDistFiles?: Array<string> | string | null;
/**
* Whether your app has to be signed with hardened runtime.
* @default true
*/
readonly hardenedRuntime?: boolean;
/**
* Whether to let electron-osx-sign validate the signing or not.
* @default false
*/
readonly gatekeeperAssess?: boolean;
/**
* Whether to let electron-osx-sign verify the contents or not.
* @default true
*/
readonly strictVerify?: Array<string> | string | boolean;
/**
* Regex or an array of regex's that signal skipping signing a file.
*/
readonly signIgnore?: Array<string> | string | null;
/**
* Specify the URL of the timestamp authority server
*/
readonly timestamp?: string | null;
/**
* Whether to merge ASAR files for different architectures or not.
*
* This option has no effect unless building for "universal" arch.
* @default true
*/
readonly mergeASARs?: boolean;
/**
* Minimatch pattern of paths that are allowed to be present in one of the
* ASAR files, but not in the other.
*
* This option has no effect unless building for "universal" arch and applies
* only if `mergeASARs` is `true`.
*/
readonly singleArchFiles?: string;
/**
* Minimatch pattern of paths that are allowed to be x64 binaries in both
* ASAR files
*
* This option has no effect unless building for "universal" arch and applies
* only if `mergeASARs` is `true`.
*/
readonly x64ArchFiles?: string;
}
export interface DmgOptions extends TargetSpecificOptions {
/**
* The path to background image (default: `build/background.tiff` or `build/background.png` if exists). The resolution of this file determines the resolution of the installer window.
* If background is not specified, use `window.size`. Default locations expected background size to be 540x380.
* @see [DMG with Retina background support](http://stackoverflow.com/a/11204769/1910191).
*/
background?: string | null;
/**
* The background color (accepts css colors). Defaults to `#ffffff` (white) if no background image.
*/
backgroundColor?: string | null;
/**
* The path to DMG icon (volume icon), which will be shown when mounted, relative to the [build resources](/configuration/configuration#MetadataDirectories-buildResources) or to the project directory.
* Defaults to the application icon (`build/icon.icns`).
*/
icon?: string | null;
/**
* The size of all the icons inside the DMG.
* @default 80
*/
readonly iconSize?: number | null;
/**
* The size of all the icon texts inside the DMG.
* @default 12
*/
readonly iconTextSize?: number | null;
/**
* The title of the produced DMG, which will be shown when mounted (volume name).
*
* Macro `${productName}`, `${version}` and `${name}` are supported.
* @default ${productName} ${version}
*/
readonly title?: string | null;
/**
* The content to customize icon locations. The x and y coordinates refer to the position of the **center** of the icon (at 1x scale), and do not take the label into account.
*/
contents?: Array<DmgContent>;
/**
* The disk image format. `ULFO` (lzfse-compressed image (OS X 10.11+ only)).
* @default UDZO
*/
format?: "UDRW" | "UDRO" | "UDCO" | "UDZO" | "UDBZ" | "ULFO";
/**
* The DMG window position and size. With y co-ordinates running from bottom to top.
*
* The Finder makes sure that the window will be on the users display, so if you want your window at the top left of the display you could use `"x": 0, "y": 100000` as the x, y co-ordinates.
* It is not to be possible to position the window relative to the [top left](https://github.com/electron-userland/electron-builder/issues/3990#issuecomment-512960957) or relative to the center of the users screen.
*/
window?: DmgWindow;
/**
* Whether to create internet-enabled disk image (when it is downloaded using a browser it will automatically decompress the image, put the application on the desktop, unmount and remove the disk image file).
* @default false
*/
readonly internetEnabled?: boolean;
/**
* Whether to sign the DMG or not. Signing is not required and will lead to unwanted errors in combination with notarization requirements.
* @default false
*/
readonly sign?: boolean;
/**
* @private
* @default true
*/
writeUpdateInfo?: boolean;
}
export interface DmgWindow {
/**
* The X position relative to left of the screen.
* @default 400
*/
x?: number;
/**
* The Y position relative to bottom of the screen.
* @default 100
*/
y?: number;
/**
* The width. Defaults to background image width or 540.
*/
width?: number;
/**
* The height. Defaults to background image height or 380.
*/
height?: number;
}
export interface DmgContent {
/**
* The device-independent pixel offset from the left of the window to the **center** of the icon.
*/
x: number;
/**
* The device-independent pixel offset from the top of the window to the **center** of the icon.
*/
y: number;
type?: "link" | "file" | "dir";
/**
* The name of the file within the DMG. Defaults to basename of `path`.
*/
name?: string;
/**
* The path of the file within the DMG.
*/
path?: string;
}
export interface MasConfiguration extends MacConfiguration {
/**
* The path to entitlements file for signing the app. `build/entitlements.mas.plist` will be used if exists (it is a recommended way to set).
* See [this folder in osx-sign's repository](https://github.com/electron/osx-sign/tree/main/entitlements) for examples.
* Be aware that your app may crash if the right entitlements are not set like `com.apple.security.cs.allow-jit` for example on arm64 builds with Electron 20+.
* See [Signing and Notarizing macOS Builds from the Electron documentation](https://www.electronjs.org/docs/latest/tutorial/code-signing#signing--notarizing-macos-builds) for more information.
*/
readonly entitlements?: string | null;
/**
* The path to child entitlements which inherit the security settings for signing frameworks and bundles of a distribution. `build/entitlements.mas.inherit.plist` will be used if exists (it is a recommended way to set).
* See [this folder in osx-sign's repository](https://github.com/electron/osx-sign/tree/main/entitlements) for examples.
*/
readonly entitlementsInherit?: string | null;
/**
* Paths of any extra binaries that need to be signed.
*/
readonly binaries?: Array<string> | null;
}

Some files were not shown because too many files have changed in this diff Show more