unfix: add some bugs
呃这个可能有点炸了
This commit is contained in:
143
WordDictationStudentApp/node_modules/electron-packager/src/cli.js
generated
vendored
Normal file
143
WordDictationStudentApp/node_modules/electron-packager/src/cli.js
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
'use strict'
|
||||
|
||||
const { info, hostInfo, warning } = require('./common')
|
||||
const fs = require('fs-extra')
|
||||
const { initializeProxy } = require('@electron/get')
|
||||
const packager = require('..')
|
||||
const path = require('path')
|
||||
const yargs = require('yargs-parser')
|
||||
|
||||
/* istanbul ignore next */
|
||||
async function printUsageAndExit (isError) {
|
||||
const usage = (await fs.readFile(path.resolve(__dirname, '..', 'usage.txt'))).toString()
|
||||
const print = isError ? console.error : console.log
|
||||
print(usage)
|
||||
process.exit(isError ? 1 : 0)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseArgs: function parseArgs (argv) {
|
||||
const args = yargs(argv, {
|
||||
boolean: [
|
||||
'all',
|
||||
'deref-symlinks',
|
||||
'download.rejectUnauthorized',
|
||||
'junk',
|
||||
'overwrite',
|
||||
'prune',
|
||||
'quiet'
|
||||
],
|
||||
default: {
|
||||
'deref-symlinks': true,
|
||||
'download.rejectUnauthorized': true,
|
||||
junk: true,
|
||||
prune: true
|
||||
},
|
||||
string: [
|
||||
'electron-version',
|
||||
'out'
|
||||
]
|
||||
})
|
||||
|
||||
args.dir = args._[0]
|
||||
args.name = args._[1]
|
||||
|
||||
const protocolSchemes = [].concat(args.protocol || [])
|
||||
const protocolNames = [].concat(args.protocolName || [])
|
||||
|
||||
if (protocolSchemes && protocolNames && protocolNames.length === protocolSchemes.length) {
|
||||
args.protocols = protocolSchemes.map(function (scheme, i) {
|
||||
return { schemes: [scheme], name: protocolNames[i] }
|
||||
})
|
||||
}
|
||||
|
||||
if (args.out === '') {
|
||||
warning('Specifying --out= without a value is the same as the default value', args.quiet)
|
||||
args.out = null
|
||||
}
|
||||
|
||||
// Overrides for multi-typed arguments, because minimist doesn't support it
|
||||
|
||||
// asar: `Object` or `true`
|
||||
if (args.asar === 'true' || args.asar instanceof Array) {
|
||||
warning('--asar does not take any arguments, it only has sub-properties (see --help)', args.quiet)
|
||||
args.asar = true
|
||||
}
|
||||
|
||||
// osx-sign: `Object` or `true`
|
||||
if (args.osxSign === 'true') {
|
||||
warning('--osx-sign does not take any arguments, it only has sub-properties (see --help)', args.quiet)
|
||||
args.osxSign = true
|
||||
} else if (typeof args['osx-sign'] === 'object') {
|
||||
if (Array.isArray(args['osx-sign'])) {
|
||||
warning('Remove --osx-sign (the bare flag) from the command line, only specify sub-properties (see --help)', args.quiet)
|
||||
} else {
|
||||
// Keep kebab case of sub properties
|
||||
args.osxSign = args['osx-sign']
|
||||
}
|
||||
}
|
||||
|
||||
if (args.osxNotarize) {
|
||||
let notarize = true
|
||||
if (typeof args.osxNotarize !== 'object' || Array.isArray(args.osxNotarize)) {
|
||||
warning('--osx-notarize does not take any arguments, it only has sub-properties (see --help)', args.quiet)
|
||||
notarize = false
|
||||
} else if (!args.osxSign) {
|
||||
warning('Notarization was enabled but macOS code signing was not, code signing is a requirement for notarization, notarize will not run', args.quiet)
|
||||
notarize = false
|
||||
}
|
||||
|
||||
if (!notarize) {
|
||||
args.osxNotarize = null
|
||||
}
|
||||
}
|
||||
|
||||
// tmpdir: `String` or `false`
|
||||
if (args.tmpdir === 'false') {
|
||||
warning('--tmpdir=false is deprecated, use --no-tmpdir instead', args.quiet)
|
||||
args.tmpdir = false
|
||||
}
|
||||
|
||||
return args
|
||||
},
|
||||
run: /* istanbul ignore next */ async function run (argv) {
|
||||
const args = module.exports.parseArgs(argv)
|
||||
|
||||
// temporary fix for https://github.com/nodejs/node/issues/6456
|
||||
for (const stdioWriter of [process.stdout, process.stderr]) {
|
||||
if (stdioWriter._handle && stdioWriter._handle.setBlocking) {
|
||||
stdioWriter._handle.setBlocking(true)
|
||||
}
|
||||
}
|
||||
|
||||
if (args.help) {
|
||||
await printUsageAndExit(false)
|
||||
} else if (args.version) {
|
||||
if (typeof args.version !== 'boolean') {
|
||||
console.error('--version does not take an argument. Perhaps you meant --app-version or --electron-version?\n')
|
||||
}
|
||||
console.log(hostInfo())
|
||||
process.exit(0)
|
||||
} else if (!args.dir) {
|
||||
await printUsageAndExit(true)
|
||||
}
|
||||
|
||||
initializeProxy()
|
||||
|
||||
try {
|
||||
const appPaths = await packager(args)
|
||||
if (appPaths.length > 1) {
|
||||
info(`Wrote new apps to:\n${appPaths.join('\n')}`, args.quiet)
|
||||
} else if (appPaths.length === 1) {
|
||||
info(`Wrote new app to: ${appPaths[0]}`, args.quiet)
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message) {
|
||||
console.error(err.message)
|
||||
} else {
|
||||
console.error(err, err.stack)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
128
WordDictationStudentApp/node_modules/electron-packager/src/common.js
generated
vendored
Normal file
128
WordDictationStudentApp/node_modules/electron-packager/src/common.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('electron-packager')
|
||||
const filenamify = require('filenamify')
|
||||
const fs = require('fs-extra')
|
||||
const metadata = require('../package.json')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
|
||||
function sanitizeAppName (name) {
|
||||
return filenamify(name, { replacement: '-' })
|
||||
}
|
||||
|
||||
function generateFinalBasename (opts) {
|
||||
return `${sanitizeAppName(opts.name)}-${opts.platform}-${opts.arch}`
|
||||
}
|
||||
|
||||
function generateFinalPath (opts) {
|
||||
return path.join(opts.out || process.cwd(), generateFinalBasename(opts))
|
||||
}
|
||||
|
||||
function info (message, quiet) {
|
||||
if (!quiet) {
|
||||
console.error(message)
|
||||
}
|
||||
}
|
||||
|
||||
function warning (message, quiet) {
|
||||
if (!quiet) {
|
||||
console.warn(`WARNING: ${message}`)
|
||||
}
|
||||
}
|
||||
|
||||
function subOptionWarning (properties, optionName, parameter, value, quiet) {
|
||||
if (Object.prototype.hasOwnProperty.call(properties, parameter)) {
|
||||
warning(`${optionName}.${parameter} will be inferred from the main options`, quiet)
|
||||
}
|
||||
properties[parameter] = value
|
||||
}
|
||||
|
||||
function createAsarOpts (opts) {
|
||||
let asarOptions
|
||||
if (opts.asar === true) {
|
||||
asarOptions = {}
|
||||
} else if (typeof opts.asar === 'object') {
|
||||
asarOptions = opts.asar
|
||||
} else if (opts.asar === false || opts.asar === undefined) {
|
||||
return false
|
||||
} else {
|
||||
warning(`asar parameter set to an invalid value (${opts.asar}), ignoring and disabling asar`, opts.quiet)
|
||||
return false
|
||||
}
|
||||
|
||||
return asarOptions
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ensureArray: function ensureArray (value) {
|
||||
return Array.isArray(value) ? value : [value]
|
||||
},
|
||||
isPlatformMac: function isPlatformMac (platform) {
|
||||
return platform === 'darwin' || platform === 'mas'
|
||||
},
|
||||
|
||||
createAsarOpts: createAsarOpts,
|
||||
|
||||
deprecatedParameter: function deprecatedParameter (properties, oldName, newName, newCLIName, quiet) {
|
||||
if (Object.prototype.hasOwnProperty.call(properties, oldName)) {
|
||||
warning(`The ${oldName} parameter is deprecated, use ${newName} (or --${newCLIName} in the CLI) instead`, quiet)
|
||||
if (!Object.prototype.hasOwnProperty.call(properties, newName)) {
|
||||
properties[newName] = properties[oldName]
|
||||
}
|
||||
delete properties[oldName]
|
||||
}
|
||||
},
|
||||
subOptionWarning: subOptionWarning,
|
||||
|
||||
baseTempDir: function baseTempDir (opts) {
|
||||
return path.join(opts.tmpdir || os.tmpdir(), 'electron-packager')
|
||||
},
|
||||
generateFinalBasename: generateFinalBasename,
|
||||
generateFinalPath: generateFinalPath,
|
||||
sanitizeAppName,
|
||||
/**
|
||||
* Convert slashes to UNIX-format separators.
|
||||
*/
|
||||
normalizePath: function normalizePath (pathToNormalize) {
|
||||
return pathToNormalize.replace(/\\/g, '/')
|
||||
},
|
||||
/**
|
||||
* Validates that the application directory contains a package.json file, and that there exists an
|
||||
* appropriate main entry point file, per the rules of the "main" field in package.json.
|
||||
*
|
||||
* See: https://docs.npmjs.com/cli/v6/configuring-npm/package-json#main
|
||||
*
|
||||
* @param appDir - the directory specified by the user
|
||||
* @param bundledAppDir - the directory where the appDir is copied to in the bundled Electron app
|
||||
*/
|
||||
validateElectronApp: async function validateElectronApp (appDir, bundledAppDir) {
|
||||
debug('Validating bundled Electron app')
|
||||
debug('Checking for a package.json file')
|
||||
|
||||
const bundledPackageJSONPath = path.join(bundledAppDir, 'package.json')
|
||||
if (!(await fs.pathExists(bundledPackageJSONPath))) {
|
||||
const originalPackageJSONPath = path.join(appDir, 'package.json')
|
||||
throw new Error(`Application manifest was not found. Make sure "${originalPackageJSONPath}" exists and does not get ignored by your ignore option`)
|
||||
}
|
||||
|
||||
debug('Checking for the main entry point file')
|
||||
const packageJSON = await fs.readJson(bundledPackageJSONPath)
|
||||
const mainScriptBasename = packageJSON.main || 'index.js'
|
||||
const mainScript = path.resolve(bundledAppDir, mainScriptBasename)
|
||||
if (!(await fs.pathExists(mainScript))) {
|
||||
const originalMainScript = path.join(appDir, mainScriptBasename)
|
||||
throw new Error(`The main entry point to your app was not found. Make sure "${originalMainScript}" exists and does not get ignored by your ignore option`)
|
||||
}
|
||||
|
||||
debug('Validation complete')
|
||||
},
|
||||
|
||||
hostInfo: function hostInfo () {
|
||||
return `Electron Packager ${metadata.version}\n` +
|
||||
`Node ${process.version}\n` +
|
||||
`Host Operating system: ${process.platform} ${os.release()} (${process.arch})`
|
||||
},
|
||||
info: info,
|
||||
warning: warning
|
||||
}
|
||||
110
WordDictationStudentApp/node_modules/electron-packager/src/copy-filter.js
generated
vendored
Normal file
110
WordDictationStudentApp/node_modules/electron-packager/src/copy-filter.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('./common')
|
||||
const debug = require('debug')('electron-packager')
|
||||
const junk = require('junk')
|
||||
const path = require('path')
|
||||
const prune = require('./prune')
|
||||
const targets = require('./targets')
|
||||
|
||||
const DEFAULT_IGNORES = [
|
||||
'/package-lock\\.json$',
|
||||
'/yarn\\.lock$',
|
||||
'/\\.git($|/)',
|
||||
'/node_modules/\\.bin($|/)',
|
||||
'\\.o(bj)?$',
|
||||
'/node_gyp_bins($|/)'
|
||||
]
|
||||
|
||||
function populateIgnoredPaths (opts) {
|
||||
opts.originalIgnore = opts.ignore
|
||||
if (typeof (opts.ignore) !== 'function') {
|
||||
if (opts.ignore) {
|
||||
opts.ignore = common.ensureArray(opts.ignore).concat(DEFAULT_IGNORES)
|
||||
} else {
|
||||
opts.ignore = [].concat(DEFAULT_IGNORES)
|
||||
}
|
||||
if (process.platform === 'linux') {
|
||||
opts.ignore.push(common.baseTempDir(opts))
|
||||
}
|
||||
|
||||
debug('Ignored path regular expressions:', opts.ignore)
|
||||
}
|
||||
}
|
||||
|
||||
function generateIgnoredOutDirs (opts) {
|
||||
const normalizedOut = opts.out ? path.resolve(opts.out) : null
|
||||
const ignoredOutDirs = []
|
||||
if (normalizedOut === null || normalizedOut === process.cwd()) {
|
||||
for (const [platform, archs] of Object.entries(targets.officialPlatformArchCombos)) {
|
||||
for (const arch of archs) {
|
||||
const basenameOpts = {
|
||||
arch: arch,
|
||||
name: opts.name,
|
||||
platform: platform
|
||||
}
|
||||
ignoredOutDirs.push(path.join(process.cwd(), common.generateFinalBasename(basenameOpts)))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ignoredOutDirs.push(normalizedOut)
|
||||
}
|
||||
|
||||
debug('Ignored paths based on the out param:', ignoredOutDirs)
|
||||
|
||||
return ignoredOutDirs
|
||||
}
|
||||
|
||||
function generateFilterFunction (ignore) {
|
||||
if (typeof (ignore) === 'function') {
|
||||
return file => !ignore(file)
|
||||
} else {
|
||||
const ignoredRegexes = common.ensureArray(ignore)
|
||||
|
||||
return function filterByRegexes (file) {
|
||||
return !ignoredRegexes.some(regex => file.match(regex))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function userPathFilter (opts) {
|
||||
const filterFunc = generateFilterFunction(opts.ignore || [])
|
||||
const ignoredOutDirs = generateIgnoredOutDirs(opts)
|
||||
const pruner = opts.prune ? new prune.Pruner(opts.dir, opts.quiet) : null
|
||||
|
||||
return async function filter (file) {
|
||||
const fullPath = path.resolve(file)
|
||||
|
||||
if (ignoredOutDirs.includes(fullPath)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (opts.junk !== false) { // defaults to true
|
||||
if (junk.is(path.basename(fullPath))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let name = fullPath.split(path.resolve(opts.dir))[1]
|
||||
|
||||
if (path.sep === '\\') {
|
||||
name = common.normalizePath(name)
|
||||
}
|
||||
|
||||
if (pruner && name.startsWith('/node_modules/')) {
|
||||
if (await prune.isModule(file)) {
|
||||
return pruner.pruneModule(name)
|
||||
} else {
|
||||
return filterFunc(name)
|
||||
}
|
||||
}
|
||||
|
||||
return filterFunc(name)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
populateIgnoredPaths,
|
||||
generateIgnoredOutDirs,
|
||||
userPathFilter
|
||||
}
|
||||
37
WordDictationStudentApp/node_modules/electron-packager/src/download.js
generated
vendored
Normal file
37
WordDictationStudentApp/node_modules/electron-packager/src/download.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('./common')
|
||||
const debug = require('debug')('electron-packager')
|
||||
const { downloadArtifact } = require('@electron/get')
|
||||
const semver = require('semver')
|
||||
const targets = require('./targets')
|
||||
|
||||
function createDownloadOpts (opts, platform, arch) {
|
||||
const downloadOpts = { ...opts.download }
|
||||
|
||||
common.subOptionWarning(downloadOpts, 'download', 'platform', platform, opts.quiet)
|
||||
common.subOptionWarning(downloadOpts, 'download', 'arch', arch, opts.quiet)
|
||||
common.subOptionWarning(downloadOpts, 'download', 'version', opts.electronVersion, opts.quiet)
|
||||
common.subOptionWarning(downloadOpts, 'download', 'artifactName', 'electron', opts.quiet)
|
||||
|
||||
return downloadOpts
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createDownloadCombos: function createDownloadCombos (opts, selectedPlatforms, selectedArchs, ignoreFunc) {
|
||||
return targets.createPlatformArchPairs(opts, selectedPlatforms, selectedArchs, ignoreFunc).map(([platform, arch]) => {
|
||||
return createDownloadOpts(opts, platform, arch)
|
||||
})
|
||||
},
|
||||
createDownloadOpts: createDownloadOpts,
|
||||
downloadElectronZip: async function downloadElectronZip (downloadOpts) {
|
||||
// armv7l builds have only been backfilled for Electron >= 1.0.0.
|
||||
// See: https://github.com/electron/electron/pull/6986
|
||||
/* istanbul ignore if */
|
||||
if (downloadOpts.arch === 'armv7l' && semver.lt(downloadOpts.version, '1.0.0')) {
|
||||
downloadOpts.arch = 'arm'
|
||||
}
|
||||
debug(`Downloading Electron with options ${JSON.stringify(downloadOpts)}`)
|
||||
return downloadArtifact(downloadOpts)
|
||||
}
|
||||
}
|
||||
24
WordDictationStudentApp/node_modules/electron-packager/src/hooks.js
generated
vendored
Normal file
24
WordDictationStudentApp/node_modules/electron-packager/src/hooks.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const { promisify } = require('util')
|
||||
|
||||
module.exports = {
|
||||
promisifyHooks: async function promisifyHooks (hooks, args) {
|
||||
if (!hooks || !Array.isArray(hooks)) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
await Promise.all(hooks.map(hookFn => promisify(hookFn).apply(this, args)))
|
||||
},
|
||||
serialHooks: function serialHooks (hooks) {
|
||||
return async function () {
|
||||
const args = Array.prototype.splice.call(arguments, 0, arguments.length - 1)
|
||||
const done = arguments[arguments.length - 1]
|
||||
for (const hook of hooks) {
|
||||
await hook.apply(this, args)
|
||||
}
|
||||
|
||||
return done() // eslint-disable-line promise/no-callback-in-promise
|
||||
}
|
||||
}
|
||||
}
|
||||
607
WordDictationStudentApp/node_modules/electron-packager/src/index.d.ts
generated
vendored
Normal file
607
WordDictationStudentApp/node_modules/electron-packager/src/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,607 @@
|
||||
// Originally based on the type definitions for electron-packager 14.0
|
||||
// Project: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/electron-packager
|
||||
// Original Authors:
|
||||
// * Maxime LUCE <https://github.com/SomaticIT>
|
||||
// * Juan Jimenez-Anca <https://github.com/cortopy>
|
||||
// * John Kleinschmidt <https://github.com/jkleinsc>
|
||||
// * Brendan Forster <https://github.com/shiftkey>
|
||||
// * Mark Lee <https://github.com/malept>
|
||||
// * Florian Keller <https://github.com/ffflorian>
|
||||
|
||||
import { CreateOptions as AsarOptions } from '@electron/asar';
|
||||
import { ElectronDownloadRequestOptions as ElectronDownloadOptions } from '@electron/get';
|
||||
import {
|
||||
LegacyNotarizeCredentials,
|
||||
NotaryToolCredentials,
|
||||
TransporterOptions
|
||||
} from '@electron/notarize/lib/types';
|
||||
import { SignOptions } from '@electron/osx-sign/dist/esm/types';
|
||||
import type { makeUniversalApp } from '@electron/universal';
|
||||
|
||||
type MakeUniversalOpts = Parameters<typeof makeUniversalApp>[0]
|
||||
|
||||
type NotarizeLegacyOptions = LegacyNotarizeCredentials & TransporterOptions;
|
||||
|
||||
/**
|
||||
* Bundles Electron-based application source code with a renamed/customized Electron executable and
|
||||
* its supporting files into folders ready for distribution.
|
||||
*
|
||||
* Briefly, this function:
|
||||
* - finds or downloads the correct release of Electron
|
||||
* - uses that version of Electron to create a app in `<out>/<appname>-<platform>-<arch>`
|
||||
*
|
||||
* Short example:
|
||||
*
|
||||
* ```javascript
|
||||
* const packager = require('electron-packager')
|
||||
*
|
||||
* async function bundleElectronApp(options) {
|
||||
* const appPaths = await packager(options)
|
||||
* console.log(`Electron app bundles created:\n${appPaths.join("\n")}`)
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param opts - Options to configure packaging.
|
||||
*
|
||||
* @returns A Promise containing the paths to the newly created application bundles.
|
||||
*/
|
||||
declare function electronPackager(opts: electronPackager.Options): Promise<string[]>;
|
||||
|
||||
declare namespace electronPackager {
|
||||
/**
|
||||
* Architectures that have been supported by the official Electron prebuilt binaries, past
|
||||
* and present.
|
||||
*/
|
||||
type OfficialArch = 'ia32' | 'x64' | 'armv7l' | 'arm64' | 'mips64el' | 'universal';
|
||||
/**
|
||||
* Platforms that have been supported by the official Electron prebuilt binaries, past and present.
|
||||
*/
|
||||
type OfficialPlatform = 'linux' | 'win32' | 'darwin' | 'mas';
|
||||
type TargetArch = OfficialArch | string;
|
||||
type TargetPlatform = OfficialPlatform | string;
|
||||
type ArchOption = TargetArch | 'all';
|
||||
type PlatformOption = TargetPlatform | 'all';
|
||||
|
||||
/**
|
||||
* A predicate function that, given an absolute file `path`, returns `true` if the file should be
|
||||
* ignored, or `false` if the file should be kept. *This does not use any of the default ignored
|
||||
* files/directories listed for the {@link ignore} option.*
|
||||
*/
|
||||
type IgnoreFunction = (path: string) => boolean;
|
||||
/**
|
||||
* A function that is called on the completion of a packaging stage.
|
||||
*
|
||||
* By default, the functions are called in parallel (via
|
||||
* [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)).
|
||||
* If you need the functions called serially, there is a utility function provided. Please note that
|
||||
* **callback-style functions are not supported by `serialHooks`.** For example:
|
||||
*
|
||||
* ```javascript
|
||||
* const packager = require('electron-packager')
|
||||
* const { serialHooks } = require('electron-packager/src/hooks')
|
||||
*
|
||||
* packager({
|
||||
* // ...
|
||||
* afterCopy: [serialHooks([
|
||||
* (buildPath, electronVersion, platform, arch) => {
|
||||
* return new Promise((resolve, reject) => {
|
||||
* setTimeout(() => {
|
||||
* console.log('first function')
|
||||
* resolve()
|
||||
* }, 1000)
|
||||
* })
|
||||
* },
|
||||
* (buildPath, electronVersion, platform, arch) => {
|
||||
* console.log('second function')
|
||||
* }
|
||||
* ])],
|
||||
* // ...
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* For real-world examples of `HookFunction`s, see the [list of related
|
||||
* plugins](https://github.com/electron/electron-packager#plugins).
|
||||
*/
|
||||
type HookFunction =
|
||||
/**
|
||||
* @param buildPath - For {@link afterExtract}, the path to the temporary folder where the prebuilt
|
||||
* Electron binary has been extracted to. For {@link afterCopy} and {@link afterPrune}, the path to the
|
||||
* folder where the Electron app has been copied to. For {@link afterComplete}, the final directory
|
||||
* of the packaged application.
|
||||
* @param electronVersion - the version of Electron that is being bundled with the application.
|
||||
* @param platform - The target platform you are packaging for.
|
||||
* @param arch - The target architecture you are packaging for.
|
||||
* @param callback - Must be called once you have completed your actions.
|
||||
*/
|
||||
(
|
||||
buildPath: string,
|
||||
electronVersion: string,
|
||||
platform: TargetArch,
|
||||
arch: TargetArch,
|
||||
callback: (err?: Error | null) => void
|
||||
) => void;
|
||||
|
||||
type TargetDefinition = {
|
||||
arch: TargetArch;
|
||||
platform: TargetPlatform;
|
||||
}
|
||||
type FinalizePackageTargetsHookFunction = (targets: TargetDefinition[], callback: (err?: Error | null) => void) => void;
|
||||
|
||||
/** See the documentation for [`@electron/osx-sign`](https://npm.im/@electron/osx-sign#opts) for details. */
|
||||
type OsxSignOptions = Omit<SignOptions, 'app' | 'binaries' | 'platform' | 'version'>;
|
||||
|
||||
/**
|
||||
* See the documentation for [`@electron/notarize`](https://npm.im/@electron/notarize#method-notarizeopts-promisevoid)
|
||||
* for details.
|
||||
*/
|
||||
type OsxNotarizeOptions =
|
||||
| ({ tool?: 'legacy' } & NotarizeLegacyOptions)
|
||||
| ({ tool: 'notarytool' } & NotaryToolCredentials);
|
||||
|
||||
/**
|
||||
* See the documentation for [`@electron/universal`](https://github.com/electron/universal)
|
||||
* for details.
|
||||
*/
|
||||
type OsxUniversalOptions = Omit<MakeUniversalOpts, 'x64AppPath' | 'arm64AppPath' | 'outAppPath' | 'force'>
|
||||
|
||||
/**
|
||||
* Defines URL protocol schemes to be used on macOS.
|
||||
*/
|
||||
interface MacOSProtocol {
|
||||
/**
|
||||
* The descriptive name. Maps to the `CFBundleURLName` metadata property.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* One or more protocol schemes associated with the app. For example, specifying `myapp`
|
||||
* would cause URLs such as `myapp://path` to be opened with the app. Maps to the
|
||||
* `CFBundleURLSchemes` metadata property.
|
||||
*/
|
||||
schemes: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of application metadata to embed into the Windows executable.
|
||||
*
|
||||
* For more information, read the [`rcedit` Node module documentation](https://github.com/electron/node-rcedit#docs).
|
||||
*/
|
||||
interface Win32MetadataOptions {
|
||||
/** Defaults to the `author` name from the nearest `package.json`. */
|
||||
CompanyName?: string;
|
||||
/** Defaults to either `productName` or `name` from the nearest `package.json`. */
|
||||
FileDescription?: string;
|
||||
/** Defaults to the renamed Electron `.exe` file. */
|
||||
OriginalFilename?: string;
|
||||
/** Defaults to either `productName` or `name` from the nearest `package.json`. */
|
||||
ProductName?: string;
|
||||
/** Defaults to either `productName` or `name` from the nearest `package.json`. */
|
||||
InternalName?: string;
|
||||
/** See [MSDN](https://msdn.microsoft.com/en-us/library/6ad1fshk.aspx#Anchor_9) for details. */
|
||||
'requested-execution-level'?: 'asInvoker' | 'highestAvailable' | 'requireAdministrator';
|
||||
/**
|
||||
* Path to a local manifest file.
|
||||
*
|
||||
* See [MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374191.aspx) for more details.
|
||||
*/
|
||||
'application-manifest'?: string;
|
||||
}
|
||||
|
||||
/** Options passed to the `packager()` function. */
|
||||
interface Options {
|
||||
/** The source directory. */
|
||||
dir: string;
|
||||
/**
|
||||
* Functions to be called after your app directory has been packaged into an .asar file.
|
||||
*
|
||||
* **Note**: `afterAsar` will only be called if the {@link asar} option is set.
|
||||
*/
|
||||
afterAsar?: HookFunction[];
|
||||
/** Functions to be called after the packaged application has been moved to the final directory. */
|
||||
afterComplete?: HookFunction[];
|
||||
/**
|
||||
* Functions to be called after your app directory has been copied to a temporary directory.
|
||||
*
|
||||
* **Note**: `afterCopy` will not be called if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
afterCopy?: HookFunction[];
|
||||
/**
|
||||
* Functions to be called after the files specified in the {@link extraResource} option have been copied.
|
||||
**/
|
||||
afterCopyExtraResources?: HookFunction[];
|
||||
/** Functions to be called after the prebuilt Electron binary has been extracted to a temporary directory. */
|
||||
afterExtract?: HookFunction[];
|
||||
/**
|
||||
* Functions to be called after the final matrix of platform/arch combination is determined. Use this to
|
||||
* learn what archs/platforms packager is targetting when you pass "all" as a value.
|
||||
*/
|
||||
afterFinalizePackageTargets?: FinalizePackageTargetsHookFunction[];
|
||||
/**
|
||||
* Functions to be called after Node module pruning has been applied to the application.
|
||||
*
|
||||
* **Note**: None of these functions will be called if the {@link prune} option is `false` or
|
||||
* the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
afterPrune?: HookFunction[];
|
||||
|
||||
/** When `true`, sets both {@link arch} and {@link platform} to `all`. */
|
||||
all?: boolean;
|
||||
/*
|
||||
* The bundle identifier to use in the application's `Info.plist`.
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
appBundleId?: string;
|
||||
/**
|
||||
* The application category type, as shown in the Finder via *View → Arrange by Application
|
||||
* Category* when viewing the Applications directory.
|
||||
*
|
||||
* For example, `app-category-type=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).
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
appCategoryType?: string;
|
||||
/**
|
||||
* The human-readable copyright line for the app. Maps to the `LegalCopyright` metadata
|
||||
* property on Windows, and `NSHumanReadableCopyright` on macOS.
|
||||
*/
|
||||
appCopyright?: string;
|
||||
/**
|
||||
* The release version of the application.
|
||||
*
|
||||
* By default the `version` property in the `package.json` is used, but it can be overridden
|
||||
* with this argument. If neither are provided, the version of Electron will be used. Maps
|
||||
* to the `ProductVersion` metadata property on Windows, and `CFBundleShortVersionString`
|
||||
* on macOS.
|
||||
*/
|
||||
appVersion?: string;
|
||||
/**
|
||||
* The target system architecture(s) to build for.
|
||||
*
|
||||
* Not required if the {@link all} option is set. If `arch` is set to `all`, all supported
|
||||
* architectures for the target platforms specified by {@link platform} will be built.
|
||||
* Arbitrary combinations of individual architectures are also supported via a comma-delimited
|
||||
* string or array of strings. The non-`all` values correspond to the architecture names used
|
||||
* by [Electron releases](https://github.com/electron/electron/releases). This value
|
||||
* is not restricted to the official set if [[download|`download.mirrorOptions`]] is set.
|
||||
*
|
||||
* Defaults to the arch of the host computer running Electron Packager.
|
||||
*
|
||||
* Arch values for the official prebuilt Electron binaries:
|
||||
* - `ia32`
|
||||
* - `x64`
|
||||
* - `armv7l`
|
||||
* - `arm64` _(Linux: Electron 1.8.0 and above; Windows: 6.0.8 and above; macOS: 11.0.0-beta.1 and above)_
|
||||
* - `mips64el` _(Electron 1.8.2-beta.5 to 1.8.8)_
|
||||
*/
|
||||
arch?: ArchOption | ArchOption[];
|
||||
/**
|
||||
* Whether to package the application's source code into an archive, using [Electron's
|
||||
* archive format](https://github.com/electron/asar). Reasons why you may want to enable
|
||||
* this feature include mitigating issues around long path names on Windows, slightly speeding
|
||||
* up `require`, and concealing your source code from cursory inspection. When the value
|
||||
* is `true`, it passes the default configuration to the `asar` module. The configuration
|
||||
* values can be customized when the value is an `Object`. Supported sub-options include, but
|
||||
* are not limited to:
|
||||
* - `ordering` (*string*): A path to an ordering file for packing files. An explanation can be
|
||||
* found on the [Atom issue tracker](https://github.com/atom/atom/issues/10163).
|
||||
* - `unpack` (*string*): A [glob expression](https://github.com/isaacs/minimatch#features),
|
||||
* when specified, unpacks the file with matching names to the `app.asar.unpacked` directory.
|
||||
* - `unpackDir` (*string*): Unpacks the dir to the `app.asar.unpacked` directory whose names
|
||||
* exactly or pattern match this string. The `asar.unpackDir` is relative to {@link dir}.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*
|
||||
* Some examples:
|
||||
*
|
||||
* - `asar.unpackDir = 'sub_dir'` will unpack the directory `/<dir>/sub_dir`
|
||||
* - `asar.unpackDir = path.join('**', '{sub_dir1/sub_sub_dir,sub_dir2}', '*')` will unpack the directories `/<dir>/sub_dir1/sub_sub_dir` and `/<dir>/sub_dir2`, but it will not include their subdirectories.
|
||||
* - `asar.unpackDir = path.join('**', '{sub_dir1/sub_sub_dir,sub_dir2}', '**')` will unpack the subdirectories of the directories `/<dir>/sub_dir1/sub_sub_dir` and `/<dir>/sub_dir2`.
|
||||
* - `asar.unpackDir = path.join('**', '{sub_dir1/sub_sub_dir,sub_dir2}', '**', '*')` will unpack the directories `/<dir>/sub_dir1/sub_sub_dir` and `/<dir>/sub_dir2` and their subdirectories.
|
||||
*
|
||||
* **Note:** `asar` will have no effect if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
asar?: boolean | AsarOptions;
|
||||
/**
|
||||
* Functions to be called before your app directory is packaged into an .asar file.
|
||||
*
|
||||
* **Note**: `beforeAsar` will only be called if the {@link asar} option is set.
|
||||
*/
|
||||
beforeAsar?: HookFunction[];
|
||||
/**
|
||||
* Functions to be called before your app directory is copied to a temporary directory.
|
||||
*
|
||||
* **Note**: `beforeCopy` will not be called if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
beforeCopy?: HookFunction[];
|
||||
/**
|
||||
* Functions to be called before the files specified in the {@link extraResource} option are copied.
|
||||
**/
|
||||
beforeCopyExtraResources?: HookFunction[];
|
||||
/**
|
||||
* The build version of the application. Defaults to the value of the {@link appVersion} option.
|
||||
* Maps to the `FileVersion` metadata property on Windows, and `CFBundleVersion` on macOS.
|
||||
*/
|
||||
buildVersion?: string;
|
||||
/**
|
||||
* Forces support for Mojave (macOS 10.14) dark mode in your packaged app. This sets the
|
||||
* `NSRequiresAquaSystemAppearance` key to `false` in your app's `Info.plist`. For more information,
|
||||
* see the [Electron documentation](https://www.electronjs.org/docs/tutorial/mojave-dark-mode-guide)
|
||||
* and the [Apple developer documentation](https://developer.apple.com/documentation/appkit/nsappearancecustomization/choosing_a_specific_appearance_for_your_app).
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
darwinDarkModeSupport?: boolean;
|
||||
/**
|
||||
* Whether symlinks should be dereferenced during the copying of the application source.
|
||||
* Defaults to `true`.
|
||||
*
|
||||
* **Note:** `derefSymlinks` will have no effect if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
derefSymlinks?: boolean;
|
||||
/**
|
||||
* If present, passes custom options to [`@electron/get`](https://npm.im/@electron/get). See
|
||||
* the module for option descriptions, proxy support, and defaults. Supported parameters
|
||||
* include, but are not limited to:
|
||||
* - `cacheRoot` (*string*): The directory where prebuilt, pre-packaged Electron downloads are cached.
|
||||
* - `mirrorOptions` (*Object*): Options to override the default Electron download location.
|
||||
* - `rejectUnauthorized` (*boolean* - default: `true`): Whether SSL certificates are required to be
|
||||
* valid when downloading Electron.
|
||||
*
|
||||
* **Note:** `download` sub-options will have no effect if the {@link electronZipDir} option is set.
|
||||
*/
|
||||
download?: ElectronDownloadOptions;
|
||||
/**
|
||||
* The Electron version with which the app is built (without the leading 'v') - for example,
|
||||
* [`1.4.13`](https://github.com/electron/electron/releases/tag/v1.4.13). See [Electron
|
||||
* releases](https://github.com/electron/electron/releases) for valid versions. If omitted, it
|
||||
* will use the version of the nearest local installation of `electron`,
|
||||
* `electron-prebuilt-compile`, or `electron-prebuilt`, defined in `package.json` in either
|
||||
* `devDependencies` or `dependencies`.
|
||||
*/
|
||||
electronVersion?: string;
|
||||
/**
|
||||
* The local path to a directory containing Electron ZIP files for Electron Packager to unzip, instead
|
||||
* of downloading them. The ZIP filenames should be in the same format as the ones downloaded from the
|
||||
* [Electron releases](https://github.com/electron/electron/releases) site.
|
||||
*
|
||||
* **Note:** Setting this option prevents the {@link download} sub-options from being used, as
|
||||
* the functionality gets skipped over.
|
||||
*/
|
||||
electronZipDir?: string;
|
||||
/**
|
||||
* The name of the executable file, sans file extension. Defaults to the value for the {@link name}
|
||||
* option. For `darwin` or `mas` target platforms, this does not affect the name of the
|
||||
* `.app` folder - this will use the {@link name} option instead.
|
||||
*/
|
||||
executableName?: string;
|
||||
/**
|
||||
* When the value is a string, specifies the filename of a `plist` file. Its contents are merged
|
||||
* into the app's `Info.plist`.
|
||||
* When the value is an `Object`, it specifies an already-parsed `plist` data structure that is
|
||||
* merged into the app's `Info.plist`.
|
||||
*
|
||||
* Entries from `extendInfo` override entries in the base `Info.plist` file supplied by
|
||||
* `electron`, `electron-prebuilt-compile`, or `electron-prebuilt`, but are overridden by other
|
||||
* options such as {@link appVersion} or {@link appBundleId}.
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
extendInfo?: string | { [property: string]: any }; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
/**
|
||||
* When the value is a string, specifies the filename of a `plist` file. Its contents are merged
|
||||
* into all the Helper apps' `Info.plist` files.
|
||||
* When the value is an `Object`, it specifies an already-parsed `plist` data structure that is
|
||||
* merged into all the Helper apps' `Info.plist` files.
|
||||
*
|
||||
* Entries from `extendHelperInfo` override entries in the helper apps' `Info.plist` file supplied by
|
||||
* `electron`, `electron-prebuilt-compile`, or `electron-prebuilt`, but are overridden by other
|
||||
* options such as {@link appVersion} or {@link appBundleId}.
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
extendHelperInfo?: string | { [property: string]: any }; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
/**
|
||||
* One or more files to be copied directly into the app's `Contents/Resources` directory for
|
||||
* macOS target platforms, and the `resources` directory for other target platforms. The
|
||||
* resources directory can be referenced in the packaged app via the
|
||||
* [`process.resourcesPath`](https://www.electronjs.org/docs/api/process#processresourcespath-readonly) value.
|
||||
*/
|
||||
extraResource?: string | string[];
|
||||
/**
|
||||
* The bundle identifier to use in the application helper's `Info.plist`.
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
helperBundleId?: string;
|
||||
/**
|
||||
* The local path to the icon file, if the target platform supports setting embedding an icon.
|
||||
*
|
||||
* Currently you must look for conversion tools in order to supply an icon in the format required by the platform:
|
||||
*
|
||||
* - macOS: `.icns`
|
||||
* - Windows: `.ico` ([See the readme](https://github.com/electron/electron-packager#building-windows-apps-from-non-windows-platforms) for details on non-Windows platforms)
|
||||
* - Linux: this option is not supported, as the dock/window list icon is set via
|
||||
* [the `icon` option in the `BrowserWindow` constructor](https://electronjs.org/docs/api/browser-window/#new-browserwindowoptions).
|
||||
* *Please note that you need to use a PNG, and not the macOS or Windows icon formats, in order for it
|
||||
* to show up in the dock/window list.* Setting the icon in the file manager is not currently supported.
|
||||
*
|
||||
* If the file extension is omitted, it is auto-completed to the correct extension based on the
|
||||
* platform, including when [[platform|`platform: 'all'`]] is in effect.
|
||||
*/
|
||||
icon?: string;
|
||||
/**
|
||||
* One or more additional [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)
|
||||
* patterns which specify which files to ignore when copying files to create the app bundle(s). The
|
||||
* regular expressions are matched against the absolute path of a given file/directory to be copied.
|
||||
*
|
||||
* **Please note that [glob patterns](https://en.wikipedia.org/wiki/Glob_%28programming%29) will not work.**
|
||||
*
|
||||
* The following paths are always ignored (*when you aren't using an {@link IgnoreFunction}*):
|
||||
*
|
||||
* - the directory specified by the {@link out} option
|
||||
* - the temporary directory used to build the Electron app
|
||||
* - `node_modules/.bin`
|
||||
* - `node_modules/electron`
|
||||
* - `node_modules/electron-prebuilt`
|
||||
* - `node_modules/electron-prebuilt-compile`
|
||||
* - `.git`
|
||||
* - files and folders ending in `.o` and `.obj`
|
||||
*
|
||||
* **Note**: Node modules specified in `devDependencies` are ignored by default, via the
|
||||
* {@link prune} option.
|
||||
*
|
||||
* **Note:** `ignore` will have no effect if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
ignore?: RegExp | RegExp[] | IgnoreFunction;
|
||||
/**
|
||||
* Ignores [system junk files](https://github.com/sindresorhus/junk) when copying the Electron app,
|
||||
* regardless of the {@link ignore} option.
|
||||
*
|
||||
* **Note:** `junk` will have no effect if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
junk?: boolean;
|
||||
/**
|
||||
* The application name. If omitted, it will use the `productName` or `name` value from the
|
||||
* nearest `package.json`.
|
||||
*
|
||||
* **Regardless of source, characters in the Electron app name which are not allowed in all target
|
||||
* platforms' filenames (e.g., `/`), will be replaced by hyphens (`-`).**
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* If present, notarizes macOS target apps when the host platform is macOS and Xcode is installed.
|
||||
* See [`@electron/notarize`](https://github.com/electron/notarize#method-notarizeopts-promisevoid)
|
||||
* for option descriptions, such as how to use `appleIdPassword` safely or obtain an API key.
|
||||
*
|
||||
* **Requires the {@link osxSign} option to be set.**
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
osxNotarize?: OsxNotarizeOptions;
|
||||
/**
|
||||
* If present, signs macOS target apps when the host platform is macOS and Xcode is installed.
|
||||
* When the value is `true`, pass default configuration to the signing module. See
|
||||
* [@electron/osx-sign](https://npm.im/@electron/osx-sign#opts---options) for sub-option descriptions and
|
||||
* their defaults. Options include, but are not limited to:
|
||||
* - `identity` (*string*): The identity used when signing the package via `codesign`.
|
||||
* - `binaries` (*array<string>*): Path to additional binaries that will be signed along with built-ins of Electron/
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
osxSign?: true | OsxSignOptions;
|
||||
/**
|
||||
* Used to provide custom options to the internal call to `@electron/universal` when building a macOS
|
||||
* app with the target architecture of "universal". Unused otherwise, providing a value does not imply
|
||||
* a universal app is built.
|
||||
*/
|
||||
osxUniversal?: OsxUniversalOptions;
|
||||
/**
|
||||
* The base directory where the finished package(s) are created.
|
||||
*
|
||||
* Defaults to the current working directory.
|
||||
*/
|
||||
out?: string;
|
||||
/**
|
||||
* Whether to replace an already existing output directory for a given platform (`true`) or
|
||||
* skip recreating it (`false`). Defaults to `false`.
|
||||
*/
|
||||
overwrite?: boolean;
|
||||
/**
|
||||
* The target platform(s) to build for.
|
||||
*
|
||||
* Not required if the {@link all} option is set. If `platform` is set to `all`, all officially
|
||||
* supported target platforms for the target architectures specified by the {@link arch} option
|
||||
* will be built. Arbitrary combinations of individual platforms are also supported via a
|
||||
* comma-delimited string or array of strings.
|
||||
*
|
||||
* The official non-`all` values correspond to the platform names used by [Electron
|
||||
* releases](https://github.com/electron/electron/releases). This value is not restricted to
|
||||
* the official set if [[download|`download.mirrorOptions]] is set.
|
||||
*
|
||||
* Defaults to the platform of the host computer running Electron Packager.
|
||||
*
|
||||
* Platform values for the official prebuilt Electron binaries:
|
||||
* - `darwin` (macOS)
|
||||
* - `linux`
|
||||
* - `mas` (macOS, specifically for submitting to the Mac App Store)
|
||||
* - `win32`
|
||||
*/
|
||||
platform?: PlatformOption | PlatformOption[];
|
||||
/**
|
||||
* The path to a prebuilt ASAR file.
|
||||
*
|
||||
* **Note:** Setting this option prevents the following options from being used, as the functionality
|
||||
* gets skipped over:
|
||||
*
|
||||
* - {@link asar}
|
||||
* - {@link afterCopy}
|
||||
* - {@link afterPrune}
|
||||
* - {@link derefSymlinks}
|
||||
* - {@link ignore}
|
||||
* - {@link junk}
|
||||
* - {@link prune}
|
||||
*/
|
||||
prebuiltAsar?: string;
|
||||
/**
|
||||
* The URL protocol schemes associated with the Electron app.
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
protocols?: MacOSProtocol[];
|
||||
/**
|
||||
* Walks the `node_modules` dependency tree to remove all of the packages specified in the
|
||||
* `devDependencies` section of `package.json` from the outputted Electron app.
|
||||
*
|
||||
* Defaults to `true`.
|
||||
*
|
||||
* **Note:** `prune` will have no effect if the {@link prebuiltAsar} option is set.
|
||||
*/
|
||||
prune?: boolean;
|
||||
/**
|
||||
* If `true`, disables printing informational and warning messages to the console when
|
||||
* packaging the application. This does not disable errors.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
quiet?: boolean;
|
||||
/**
|
||||
* The base directory to use as a temporary directory. Set to `false` to disable use of a
|
||||
* temporary directory. Defaults to the system's temporary directory.
|
||||
*/
|
||||
tmpdir?: string | false;
|
||||
/**
|
||||
* Human-readable descriptions of how the Electron app uses certain macOS features. These are displayed
|
||||
* in the App Store. A non-exhaustive list of available properties:
|
||||
*
|
||||
* * `Camera` - required for media access API usage in macOS Catalina
|
||||
* * `Microphone` - required for media access API usage in macOS Catalina
|
||||
*
|
||||
* Valid properties are the [Cocoa keys for MacOS](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html)
|
||||
* of the pattern `NS(.*)UsageDescription`, where the captured group is the key to use.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```javascript
|
||||
* {
|
||||
* usageDescription: {
|
||||
* Camera: 'Needed for video calls',
|
||||
* Microphone: 'Needed for voice calls'
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @category macOS
|
||||
*/
|
||||
usageDescription?: { [property: string]: string };
|
||||
/**
|
||||
* Application metadata to embed into the Windows executable.
|
||||
* @category Windows
|
||||
*/
|
||||
win32metadata?: Win32MetadataOptions;
|
||||
}
|
||||
}
|
||||
|
||||
export = electronPackager;
|
||||
207
WordDictationStudentApp/node_modules/electron-packager/src/index.js
generated
vendored
Normal file
207
WordDictationStudentApp/node_modules/electron-packager/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('./common')
|
||||
const copyFilter = require('./copy-filter')
|
||||
const debug = require('debug')('electron-packager')
|
||||
const download = require('./download')
|
||||
const fs = require('fs-extra')
|
||||
const getMetadataFromPackageJSON = require('./infer')
|
||||
const hooks = require('./hooks')
|
||||
const path = require('path')
|
||||
const targets = require('./targets')
|
||||
const unzip = require('./unzip')
|
||||
const { packageUniversalMac } = require('./universal')
|
||||
|
||||
function debugHostInfo () {
|
||||
debug(common.hostInfo())
|
||||
}
|
||||
|
||||
class Packager {
|
||||
constructor (opts) {
|
||||
this.opts = opts
|
||||
this.tempBase = common.baseTempDir(opts)
|
||||
this.useTempDir = opts.tmpdir !== false
|
||||
this.canCreateSymlinks = undefined
|
||||
}
|
||||
|
||||
async ensureTempDir () {
|
||||
if (this.useTempDir) {
|
||||
await fs.remove(this.tempBase)
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
async testSymlink (comboOpts, zipPath) {
|
||||
await fs.mkdirp(this.tempBase)
|
||||
const testPath = await fs.mkdtemp(path.join(this.tempBase, `symlink-test-${comboOpts.platform}-${comboOpts.arch}-`))
|
||||
const testFile = path.join(testPath, 'test')
|
||||
const testLink = path.join(testPath, 'testlink')
|
||||
|
||||
try {
|
||||
await fs.outputFile(testFile, '')
|
||||
await fs.symlink(testFile, testLink)
|
||||
this.canCreateSymlinks = true
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
this.canCreateSymlinks = false
|
||||
} finally {
|
||||
await fs.remove(testPath)
|
||||
}
|
||||
|
||||
if (this.canCreateSymlinks) {
|
||||
return this.checkOverwrite(comboOpts, zipPath)
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
return this.skipHostPlatformSansSymlinkSupport(comboOpts)
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
skipHostPlatformSansSymlinkSupport (comboOpts) {
|
||||
common.info(`Cannot create symlinks (on Windows hosts, it requires admin privileges); skipping ${comboOpts.platform} platform`, this.opts.quiet)
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
async overwriteAndCreateApp (outDir, comboOpts, zipPath) {
|
||||
debug(`Removing ${outDir} due to setting overwrite: true`)
|
||||
await fs.remove(outDir)
|
||||
return this.createApp(comboOpts, zipPath)
|
||||
}
|
||||
|
||||
async extractElectronZip (comboOpts, zipPath, buildDir) {
|
||||
debug(`Extracting ${zipPath} to ${buildDir}`)
|
||||
await unzip(zipPath, buildDir)
|
||||
await hooks.promisifyHooks(this.opts.afterExtract, [buildDir, comboOpts.electronVersion, comboOpts.platform, comboOpts.arch])
|
||||
}
|
||||
|
||||
async buildDir (platform, arch) {
|
||||
let buildParentDir
|
||||
if (this.useTempDir) {
|
||||
buildParentDir = this.tempBase
|
||||
} else {
|
||||
buildParentDir = this.opts.out || process.cwd()
|
||||
}
|
||||
await fs.mkdirp(buildParentDir)
|
||||
return await fs.mkdtemp(path.resolve(buildParentDir, `${platform}-${arch}-template-`))
|
||||
}
|
||||
|
||||
async createApp (comboOpts, zipPath) {
|
||||
const buildDir = await this.buildDir(comboOpts.platform, comboOpts.arch)
|
||||
common.info(`Packaging app for platform ${comboOpts.platform} ${comboOpts.arch} using electron v${comboOpts.electronVersion}`, this.opts.quiet)
|
||||
|
||||
debug(`Creating ${buildDir}`)
|
||||
await fs.ensureDir(buildDir)
|
||||
await this.extractElectronZip(comboOpts, zipPath, buildDir)
|
||||
const os = require(targets.osModules[comboOpts.platform])
|
||||
const app = new os.App(comboOpts, buildDir)
|
||||
return app.create()
|
||||
}
|
||||
|
||||
async checkOverwrite (comboOpts, zipPath) {
|
||||
const finalPath = common.generateFinalPath(comboOpts)
|
||||
if (await fs.pathExists(finalPath)) {
|
||||
if (this.opts.overwrite) {
|
||||
return this.overwriteAndCreateApp(finalPath, comboOpts, zipPath)
|
||||
} else {
|
||||
common.info(`Skipping ${comboOpts.platform} ${comboOpts.arch} (output dir already exists, use --overwrite to force)`, this.opts.quiet)
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return this.createApp(comboOpts, zipPath)
|
||||
}
|
||||
}
|
||||
|
||||
async getElectronZipPath (downloadOpts) {
|
||||
if (this.opts.electronZipDir) {
|
||||
if (await fs.pathExists(this.opts.electronZipDir)) {
|
||||
const zipPath = path.resolve(
|
||||
this.opts.electronZipDir,
|
||||
`electron-v${downloadOpts.version}-${downloadOpts.platform}-${downloadOpts.arch}.zip`
|
||||
)
|
||||
if (!await fs.pathExists(zipPath)) {
|
||||
throw new Error(`The specified Electron ZIP file does not exist: ${zipPath}`)
|
||||
}
|
||||
|
||||
return zipPath
|
||||
}
|
||||
|
||||
throw new Error(`The specified Electron ZIP directory does not exist: ${this.opts.electronZipDir}`)
|
||||
} else {
|
||||
return download.downloadElectronZip(downloadOpts)
|
||||
}
|
||||
}
|
||||
|
||||
async packageForPlatformAndArchWithOpts (comboOpts, downloadOpts) {
|
||||
const zipPath = await this.getElectronZipPath(downloadOpts)
|
||||
|
||||
if (!this.useTempDir) {
|
||||
return this.createApp(comboOpts, zipPath)
|
||||
}
|
||||
|
||||
if (common.isPlatformMac(comboOpts.platform)) {
|
||||
/* istanbul ignore else */
|
||||
if (this.canCreateSymlinks === undefined) {
|
||||
return this.testSymlink(comboOpts, zipPath)
|
||||
} else if (!this.canCreateSymlinks) {
|
||||
return this.skipHostPlatformSansSymlinkSupport(comboOpts)
|
||||
}
|
||||
}
|
||||
|
||||
return this.checkOverwrite(comboOpts, zipPath)
|
||||
}
|
||||
|
||||
async packageForPlatformAndArch (downloadOpts) {
|
||||
// Create delegated options object with specific platform and arch, for output directory naming
|
||||
const comboOpts = {
|
||||
...this.opts,
|
||||
arch: downloadOpts.arch,
|
||||
platform: downloadOpts.platform,
|
||||
electronVersion: downloadOpts.version
|
||||
}
|
||||
|
||||
if (common.isPlatformMac(comboOpts.platform) && comboOpts.arch === 'universal') {
|
||||
return packageUniversalMac(this.packageForPlatformAndArchWithOpts.bind(this), await this.buildDir(comboOpts.platform, comboOpts.arch), comboOpts, downloadOpts, this.tempBase)
|
||||
}
|
||||
|
||||
return this.packageForPlatformAndArchWithOpts(comboOpts, downloadOpts)
|
||||
}
|
||||
}
|
||||
|
||||
async function packageAllSpecifiedCombos (opts, archs, platforms) {
|
||||
const packager = new Packager(opts)
|
||||
await packager.ensureTempDir()
|
||||
return Promise.all(download.createDownloadCombos(opts, platforms, archs).map(
|
||||
downloadOpts => packager.packageForPlatformAndArch(downloadOpts)
|
||||
))
|
||||
}
|
||||
|
||||
module.exports = async function packager (opts) {
|
||||
debugHostInfo()
|
||||
if (debug.enabled) debug(`Packager Options: ${JSON.stringify(opts)}`)
|
||||
|
||||
const archs = targets.validateListFromOptions(opts, 'arch')
|
||||
const platforms = targets.validateListFromOptions(opts, 'platform')
|
||||
if (!Array.isArray(archs)) return Promise.reject(archs)
|
||||
if (!Array.isArray(platforms)) return Promise.reject(platforms)
|
||||
|
||||
debug(`Target Platforms: ${platforms.join(', ')}`)
|
||||
debug(`Target Architectures: ${archs.join(', ')}`)
|
||||
|
||||
const packageJSONDir = path.resolve(process.cwd(), opts.dir) || process.cwd()
|
||||
|
||||
await getMetadataFromPackageJSON(platforms, opts, packageJSONDir)
|
||||
if (opts.name.endsWith(' Helper')) {
|
||||
throw new Error('Application names cannot end in " Helper" due to limitations on macOS')
|
||||
}
|
||||
|
||||
debug(`Application name: ${opts.name}`)
|
||||
debug(`Target Electron version: ${opts.electronVersion}`)
|
||||
|
||||
copyFilter.populateIgnoredPaths(opts)
|
||||
|
||||
await hooks.promisifyHooks(opts.afterFinalizePackageTargets, [targets.createPlatformArchPairs(opts, platforms, archs).map(([platform, arch]) => ({ platform, arch }))])
|
||||
const appPaths = await packageAllSpecifiedCombos(opts, archs, platforms)
|
||||
// Remove falsy entries (e.g. skipped platforms)
|
||||
return appPaths.filter(appPath => appPath)
|
||||
}
|
||||
178
WordDictationStudentApp/node_modules/electron-packager/src/infer.js
generated
vendored
Normal file
178
WordDictationStudentApp/node_modules/electron-packager/src/infer.js
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('electron-packager')
|
||||
const getPackageInfo = require('get-package-info')
|
||||
const parseAuthor = require('parse-author')
|
||||
const path = require('path')
|
||||
const resolve = require('resolve')
|
||||
const semver = require('semver')
|
||||
|
||||
function isMissingRequiredProperty (props) {
|
||||
return props.some(prop => prop === 'productName' || prop === 'dependencies.electron')
|
||||
}
|
||||
|
||||
function errorMessageForProperty (prop) {
|
||||
let hash, propDescription
|
||||
switch (prop) {
|
||||
case 'productName':
|
||||
hash = 'name'
|
||||
propDescription = 'application name'
|
||||
break
|
||||
case 'dependencies.electron':
|
||||
hash = 'electronversion'
|
||||
propDescription = 'Electron version'
|
||||
break
|
||||
case 'version':
|
||||
hash = 'appversion'
|
||||
propDescription = 'application version'
|
||||
break
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
hash = ''
|
||||
propDescription = `[Unknown Property (${prop})]`
|
||||
}
|
||||
|
||||
return `Unable to determine ${propDescription}. Please specify an ${propDescription}\n\n` +
|
||||
'For more information, please see\n' +
|
||||
`https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html#${hash}\n`
|
||||
}
|
||||
|
||||
function resolvePromise (id, options) {
|
||||
// eslint-disable-next-line promise/param-names
|
||||
return new Promise((accept, reject) => {
|
||||
resolve(id, options, (err, mainPath, pkg) => {
|
||||
if (err) {
|
||||
/* istanbul ignore next */
|
||||
reject(err)
|
||||
} else {
|
||||
accept([mainPath, pkg])
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function rangeFromElectronVersion (electronVersion) {
|
||||
try {
|
||||
return new semver.Range(electronVersion)
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function getVersion (opts, electronProp) {
|
||||
const [depType, packageName] = electronProp.prop.split('.')
|
||||
const src = electronProp.src
|
||||
if (packageName === 'electron-prebuilt-compile') {
|
||||
const electronVersion = electronProp.pkg[depType][packageName]
|
||||
const versionRange = rangeFromElectronVersion(electronVersion)
|
||||
if (versionRange !== null && versionRange.intersects(new semver.Range('< 1.6.5'))) {
|
||||
if (!/^\d+\.\d+\.\d+/.test(electronVersion)) {
|
||||
// electron-prebuilt-compile cannot be resolved because `main` does not point
|
||||
// to a valid JS file.
|
||||
throw new Error('Using electron-prebuilt-compile with Electron Packager requires specifying an exact Electron version')
|
||||
}
|
||||
|
||||
opts.electronVersion = electronVersion
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
const pkg = (await resolvePromise(packageName, { basedir: path.dirname(src) }))[1]
|
||||
debug(`Inferring target Electron version from ${packageName} in ${src}`)
|
||||
opts.electronVersion = pkg.version
|
||||
return null
|
||||
}
|
||||
|
||||
async function handleMetadata (opts, result) {
|
||||
if (result.values.productName) {
|
||||
debug(`Inferring application name from ${result.source.productName.prop} in ${result.source.productName.src}`)
|
||||
opts.name = result.values.productName
|
||||
}
|
||||
|
||||
if (result.values.version) {
|
||||
debug(`Inferring appVersion from version in ${result.source.version.src}`)
|
||||
opts.appVersion = result.values.version
|
||||
}
|
||||
|
||||
if (result.values.author && !opts.win32metadata) {
|
||||
opts.win32metadata = {}
|
||||
}
|
||||
|
||||
if (result.values.author) {
|
||||
debug(`Inferring win32metadata.CompanyName from author in ${result.source.author.src}`)
|
||||
if (typeof result.values.author === 'string') {
|
||||
opts.win32metadata.CompanyName = parseAuthor(result.values.author).name
|
||||
} else if (result.values.author.name) {
|
||||
opts.win32metadata.CompanyName = result.values.author.name
|
||||
} else {
|
||||
debug('Cannot infer win32metadata.CompanyName from author, no name found')
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (result.values.hasOwnProperty('dependencies.electron')) {
|
||||
return getVersion(opts, result.source['dependencies.electron'])
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
function handleMissingProperties (opts, err) {
|
||||
const missingProps = err.missingProps.map(prop => {
|
||||
return Array.isArray(prop) ? prop[0] : prop
|
||||
})
|
||||
|
||||
if (isMissingRequiredProperty(missingProps)) {
|
||||
const messages = missingProps.map(errorMessageForProperty)
|
||||
|
||||
debug(err.message)
|
||||
err.message = messages.join('\n') + '\n'
|
||||
throw err
|
||||
} else {
|
||||
// Missing props not required, can continue w/ partial result
|
||||
return handleMetadata(opts, err.result)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async function getMetadataFromPackageJSON (platforms, opts, dir) {
|
||||
const props = []
|
||||
if (!opts.name) props.push(['productName', 'name'])
|
||||
if (!opts.appVersion) props.push('version')
|
||||
if (!opts.electronVersion) {
|
||||
props.push([
|
||||
'dependencies.electron',
|
||||
'devDependencies.electron',
|
||||
'dependencies.electron-nightly',
|
||||
'devDependencies.electron-nightly',
|
||||
'dependencies.electron-prebuilt-compile',
|
||||
'devDependencies.electron-prebuilt-compile',
|
||||
'dependencies.electron-prebuilt',
|
||||
'devDependencies.electron-prebuilt'
|
||||
])
|
||||
}
|
||||
|
||||
if (platforms.includes('win32') && !(opts.win32metadata && opts.win32metadata.CompanyName)) {
|
||||
debug('Requiring author in package.json, as CompanyName was not specified for win32metadata')
|
||||
props.push('author')
|
||||
}
|
||||
|
||||
// Name and version provided, no need to infer
|
||||
if (props.length === 0) return Promise.resolve()
|
||||
|
||||
// Search package.json files to infer name and version from
|
||||
try {
|
||||
const result = await getPackageInfo(props, dir)
|
||||
return handleMetadata(opts, result)
|
||||
} catch (err) {
|
||||
if (err.missingProps) {
|
||||
if (err.missingProps.length === props.length) {
|
||||
debug(err.message)
|
||||
err.message = `Could not locate a package.json file in "${path.resolve(opts.dir)}" or its parent directories for an Electron app with the following fields: ${err.missingProps.join(', ')}`
|
||||
} else {
|
||||
return handleMissingProperties(opts, err)
|
||||
}
|
||||
}
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
25
WordDictationStudentApp/node_modules/electron-packager/src/linux.js
generated
vendored
Normal file
25
WordDictationStudentApp/node_modules/electron-packager/src/linux.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict'
|
||||
|
||||
const App = require('./platform')
|
||||
const common = require('./common')
|
||||
|
||||
class LinuxApp extends App {
|
||||
get originalElectronName () {
|
||||
return 'electron'
|
||||
}
|
||||
|
||||
get newElectronName () {
|
||||
return common.sanitizeAppName(this.executableName)
|
||||
}
|
||||
|
||||
async create () {
|
||||
await this.initialize()
|
||||
await this.renameElectron()
|
||||
await this.copyExtraResources()
|
||||
return this.move()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
App: LinuxApp
|
||||
}
|
||||
440
WordDictationStudentApp/node_modules/electron-packager/src/mac.js
generated
vendored
Normal file
440
WordDictationStudentApp/node_modules/electron-packager/src/mac.js
generated
vendored
Normal file
@@ -0,0 +1,440 @@
|
||||
'use strict'
|
||||
|
||||
const App = require('./platform')
|
||||
const common = require('./common')
|
||||
const debug = require('debug')('electron-packager')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const plist = require('plist')
|
||||
const { notarize } = require('@electron/notarize')
|
||||
const { signApp } = require('@electron/osx-sign')
|
||||
|
||||
class MacApp extends App {
|
||||
constructor (opts, templatePath) {
|
||||
super(opts, templatePath)
|
||||
|
||||
this.appName = opts.name
|
||||
}
|
||||
|
||||
get appCategoryType () {
|
||||
return this.opts.appCategoryType
|
||||
}
|
||||
|
||||
get appCopyright () {
|
||||
return this.opts.appCopyright
|
||||
}
|
||||
|
||||
get appVersion () {
|
||||
return this.opts.appVersion
|
||||
}
|
||||
|
||||
get buildVersion () {
|
||||
return this.opts.buildVersion
|
||||
}
|
||||
|
||||
get enableDarkMode () {
|
||||
return this.opts.darwinDarkModeSupport
|
||||
}
|
||||
|
||||
get usageDescription () {
|
||||
return this.opts.usageDescription
|
||||
}
|
||||
|
||||
get protocols () {
|
||||
return this.opts.protocols.map((protocol) => {
|
||||
return {
|
||||
CFBundleURLName: protocol.name,
|
||||
CFBundleURLSchemes: [].concat(protocol.schemes)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get dotAppName () {
|
||||
return `${common.sanitizeAppName(this.appName)}.app`
|
||||
}
|
||||
|
||||
get defaultBundleName () {
|
||||
return `com.electron.${common.sanitizeAppName(this.appName).toLowerCase()}`
|
||||
}
|
||||
|
||||
get bundleName () {
|
||||
return filterCFBundleIdentifier(this.opts.appBundleId || this.defaultBundleName)
|
||||
}
|
||||
|
||||
get originalResourcesDir () {
|
||||
return path.join(this.contentsPath, 'Resources')
|
||||
}
|
||||
|
||||
get resourcesDir () {
|
||||
return path.join(this.dotAppName, 'Contents', 'Resources')
|
||||
}
|
||||
|
||||
get electronBinaryDir () {
|
||||
return path.join(this.contentsPath, 'MacOS')
|
||||
}
|
||||
|
||||
get originalElectronName () {
|
||||
return 'Electron'
|
||||
}
|
||||
|
||||
get newElectronName () {
|
||||
return this.appPlist.CFBundleExecutable
|
||||
}
|
||||
|
||||
get renamedAppPath () {
|
||||
return path.join(this.stagingPath, this.dotAppName)
|
||||
}
|
||||
|
||||
get electronAppPath () {
|
||||
return path.join(this.stagingPath, `${this.originalElectronName}.app`)
|
||||
}
|
||||
|
||||
get contentsPath () {
|
||||
return path.join(this.electronAppPath, 'Contents')
|
||||
}
|
||||
|
||||
get frameworksPath () {
|
||||
return path.join(this.contentsPath, 'Frameworks')
|
||||
}
|
||||
|
||||
get loginItemsPath () {
|
||||
return path.join(this.contentsPath, 'Library', 'LoginItems')
|
||||
}
|
||||
|
||||
get loginHelperPath () {
|
||||
return path.join(this.loginItemsPath, 'Electron Login Helper.app')
|
||||
}
|
||||
|
||||
updatePlist (basePlist, displayName, identifier, name) {
|
||||
return Object.assign(basePlist, {
|
||||
CFBundleDisplayName: displayName,
|
||||
CFBundleExecutable: common.sanitizeAppName(displayName),
|
||||
CFBundleIdentifier: identifier,
|
||||
CFBundleName: common.sanitizeAppName(name)
|
||||
})
|
||||
}
|
||||
|
||||
updateHelperPlist (basePlist, suffix, identifierIgnoresSuffix) {
|
||||
let helperSuffix, identifier, name
|
||||
if (suffix) {
|
||||
helperSuffix = `Helper ${suffix}`
|
||||
if (identifierIgnoresSuffix) {
|
||||
identifier = this.helperBundleIdentifier
|
||||
} else {
|
||||
identifier = `${this.helperBundleIdentifier}.${suffix}`
|
||||
}
|
||||
name = `${this.appName} ${helperSuffix}`
|
||||
} else {
|
||||
helperSuffix = 'Helper'
|
||||
identifier = this.helperBundleIdentifier
|
||||
name = this.appName
|
||||
}
|
||||
return this.updatePlist(basePlist, `${this.appName} ${helperSuffix}`, identifier, name)
|
||||
}
|
||||
|
||||
async extendPlist (basePlist, propsOrFilename) {
|
||||
if (!propsOrFilename) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
if (typeof propsOrFilename === 'string') {
|
||||
const plist = await this.loadPlist(propsOrFilename)
|
||||
return Object.assign(basePlist, plist)
|
||||
} else {
|
||||
return Object.assign(basePlist, propsOrFilename)
|
||||
}
|
||||
}
|
||||
|
||||
async loadPlist (filename, propName) {
|
||||
const loadedPlist = plist.parse((await fs.readFile(filename)).toString())
|
||||
if (propName) {
|
||||
this[propName] = loadedPlist
|
||||
}
|
||||
return loadedPlist
|
||||
}
|
||||
|
||||
ehPlistFilename (helper) {
|
||||
return this.helperPlistFilename(path.join(this.frameworksPath, helper))
|
||||
}
|
||||
|
||||
helperPlistFilename (helperApp) {
|
||||
return path.join(helperApp, 'Contents', 'Info.plist')
|
||||
}
|
||||
|
||||
async determinePlistFilesToUpdate () {
|
||||
const appPlistFilename = path.join(this.contentsPath, 'Info.plist')
|
||||
|
||||
const plists = [
|
||||
[appPlistFilename, 'appPlist'],
|
||||
[this.ehPlistFilename('Electron Helper.app'), 'helperPlist']
|
||||
]
|
||||
|
||||
const possiblePlists = [
|
||||
[this.ehPlistFilename('Electron Helper (Renderer).app'), 'helperRendererPlist'],
|
||||
[this.ehPlistFilename('Electron Helper (Plugin).app'), 'helperPluginPlist'],
|
||||
[this.ehPlistFilename('Electron Helper (GPU).app'), 'helperGPUPlist'],
|
||||
[this.ehPlistFilename('Electron Helper EH.app'), 'helperEHPlist'],
|
||||
[this.ehPlistFilename('Electron Helper NP.app'), 'helperNPPlist'],
|
||||
[this.helperPlistFilename(this.loginHelperPath), 'loginHelperPlist']
|
||||
]
|
||||
|
||||
const optional = await Promise.all(possiblePlists.map(async item =>
|
||||
(await fs.pathExists(item[0])) ? item : null))
|
||||
return plists.concat(optional.filter(item => item))
|
||||
}
|
||||
|
||||
appRelativePath (p) {
|
||||
return path.relative(this.contentsPath, p)
|
||||
}
|
||||
|
||||
async updatePlistFiles () {
|
||||
const appBundleIdentifier = this.bundleName
|
||||
this.helperBundleIdentifier = filterCFBundleIdentifier(this.opts.helperBundleId || `${appBundleIdentifier}.helper`)
|
||||
|
||||
const plists = await this.determinePlistFilesToUpdate()
|
||||
await Promise.all(plists.map(plistArgs => this.loadPlist(...plistArgs)))
|
||||
await this.extendPlist(this.appPlist, this.opts.extendInfo)
|
||||
if (this.asarIntegrity) {
|
||||
await this.extendPlist(this.appPlist, {
|
||||
ElectronAsarIntegrity: this.asarIntegrity
|
||||
})
|
||||
} else {
|
||||
delete this.appPlist.ElectronAsarIntegrity
|
||||
}
|
||||
this.appPlist = this.updatePlist(this.appPlist, this.executableName, appBundleIdentifier, this.appName)
|
||||
|
||||
const updateIfExists = [
|
||||
['helperRendererPlist', '(Renderer)', true],
|
||||
['helperPluginPlist', '(Plugin)', true],
|
||||
['helperGPUPlist', '(GPU)', true],
|
||||
['helperEHPlist', 'EH'],
|
||||
['helperNPPlist', 'NP']
|
||||
]
|
||||
|
||||
for (const [plistKey] of [...updateIfExists, ['helperPlist']]) {
|
||||
if (!this[plistKey]) continue
|
||||
await this.extendPlist(this[plistKey], this.opts.extendHelperInfo)
|
||||
}
|
||||
|
||||
this.helperPlist = this.updateHelperPlist(this.helperPlist)
|
||||
for (const [plistKey, ...suffixArgs] of updateIfExists) {
|
||||
if (!this[plistKey]) continue
|
||||
this[plistKey] = this.updateHelperPlist(this[plistKey], ...suffixArgs)
|
||||
}
|
||||
|
||||
// Some properties need to go on all helpers as well, version, usage info, etc.
|
||||
const plistsToUpdate = updateIfExists
|
||||
.filter(([key]) => !!this[key])
|
||||
.map(([key]) => key)
|
||||
.concat(['appPlist', 'helperPlist'])
|
||||
|
||||
if (this.loginHelperPlist) {
|
||||
const loginHelperName = common.sanitizeAppName(`${this.appName} Login Helper`)
|
||||
this.loginHelperPlist.CFBundleExecutable = loginHelperName
|
||||
this.loginHelperPlist.CFBundleIdentifier = `${appBundleIdentifier}.loginhelper`
|
||||
this.loginHelperPlist.CFBundleName = loginHelperName
|
||||
}
|
||||
|
||||
if (this.appVersion) {
|
||||
const appVersionString = '' + this.appVersion
|
||||
for (const plistKey of plistsToUpdate) {
|
||||
this[plistKey].CFBundleShortVersionString = this[plistKey].CFBundleVersion = appVersionString
|
||||
}
|
||||
}
|
||||
|
||||
if (this.buildVersion) {
|
||||
const buildVersionString = '' + this.buildVersion
|
||||
for (const plistKey of plistsToUpdate) {
|
||||
this[plistKey].CFBundleVersion = buildVersionString
|
||||
}
|
||||
}
|
||||
|
||||
if (this.opts.protocols && this.opts.protocols.length) {
|
||||
this.appPlist.CFBundleURLTypes = this.protocols
|
||||
}
|
||||
|
||||
if (this.appCategoryType) {
|
||||
this.appPlist.LSApplicationCategoryType = this.appCategoryType
|
||||
}
|
||||
|
||||
if (this.appCopyright) {
|
||||
this.appPlist.NSHumanReadableCopyright = this.appCopyright
|
||||
}
|
||||
|
||||
if (this.enableDarkMode) {
|
||||
this.appPlist.NSRequiresAquaSystemAppearance = false
|
||||
}
|
||||
|
||||
if (this.usageDescription) {
|
||||
for (const [type, description] of Object.entries(this.usageDescription)) {
|
||||
const usageTypeKey = `NS${type}UsageDescription`
|
||||
for (const plistKey of plistsToUpdate) {
|
||||
this[plistKey][usageTypeKey] = description
|
||||
}
|
||||
this.appPlist[usageTypeKey] = description
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(plists.map(([filename, varName]) =>
|
||||
fs.writeFile(filename, plist.build(this[varName]))))
|
||||
}
|
||||
|
||||
async moveHelpers () {
|
||||
const helpers = [' Helper', ' Helper EH', ' Helper NP', ' Helper (Renderer)', ' Helper (Plugin)', ' Helper (GPU)']
|
||||
await Promise.all(helpers.map(suffix => this.moveHelper(this.frameworksPath, suffix)))
|
||||
if (await fs.pathExists(this.loginItemsPath)) {
|
||||
await this.moveHelper(this.loginItemsPath, ' Login Helper')
|
||||
}
|
||||
}
|
||||
|
||||
async moveHelper (helperDirectory, suffix) {
|
||||
const originalBasename = `Electron${suffix}`
|
||||
|
||||
if (await fs.pathExists(path.join(helperDirectory, `${originalBasename}.app`))) {
|
||||
return this.renameHelperAndExecutable(
|
||||
helperDirectory,
|
||||
originalBasename,
|
||||
`${common.sanitizeAppName(this.appName)}${suffix}`
|
||||
)
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
async renameHelperAndExecutable (helperDirectory, originalBasename, newBasename) {
|
||||
const originalAppname = `${originalBasename}.app`
|
||||
const executableBasePath = path.join(helperDirectory, originalAppname, 'Contents', 'MacOS')
|
||||
await this.relativeRename(executableBasePath, originalBasename, newBasename)
|
||||
await this.relativeRename(helperDirectory, originalAppname, `${newBasename}.app`)
|
||||
}
|
||||
|
||||
async copyIcon () {
|
||||
if (!this.opts.icon) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
let icon
|
||||
|
||||
try {
|
||||
icon = await this.normalizeIconExtension('.icns')
|
||||
} catch {
|
||||
// Ignore error if icon doesn't exist, in case it's only available for other OSes
|
||||
/* istanbul ignore next */
|
||||
return Promise.resolve()
|
||||
}
|
||||
if (icon) {
|
||||
debug(`Copying icon "${icon}" to app's Resources as "${this.appPlist.CFBundleIconFile}"`)
|
||||
await fs.copy(icon, path.join(this.originalResourcesDir, this.appPlist.CFBundleIconFile))
|
||||
}
|
||||
}
|
||||
|
||||
async renameAppAndHelpers () {
|
||||
await this.moveHelpers()
|
||||
await fs.rename(this.electronAppPath, this.renamedAppPath)
|
||||
}
|
||||
|
||||
async signAppIfSpecified () {
|
||||
const osxSignOpt = this.opts.osxSign
|
||||
const platform = this.opts.platform
|
||||
const version = this.opts.electronVersion
|
||||
|
||||
if ((platform === 'all' || platform === 'mas') &&
|
||||
osxSignOpt === undefined) {
|
||||
common.warning('signing is required for mas builds. Provide the osx-sign option, ' +
|
||||
'or manually sign the app later.', this.opts.quiet)
|
||||
}
|
||||
|
||||
if (osxSignOpt) {
|
||||
const signOpts = createSignOpts(osxSignOpt, platform, this.renamedAppPath, version, this.opts.quiet)
|
||||
debug(`Running @electron/osx-sign with the options ${JSON.stringify(signOpts)}`)
|
||||
try {
|
||||
await signApp(signOpts)
|
||||
} catch (err) {
|
||||
// Although not signed successfully, the application is packed.
|
||||
common.warning(`Code sign failed; please retry manually. ${err}`, this.opts.quiet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async notarizeAppIfSpecified () {
|
||||
const osxNotarizeOpt = this.opts.osxNotarize
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (osxNotarizeOpt) {
|
||||
const notarizeOpts = createNotarizeOpts(
|
||||
osxNotarizeOpt,
|
||||
this.bundleName,
|
||||
this.renamedAppPath,
|
||||
this.opts.quiet
|
||||
)
|
||||
if (notarizeOpts) {
|
||||
return notarize(notarizeOpts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async create () {
|
||||
await this.initialize()
|
||||
await this.updatePlistFiles()
|
||||
await this.copyIcon()
|
||||
await this.renameElectron()
|
||||
await this.renameAppAndHelpers()
|
||||
await this.copyExtraResources()
|
||||
await this.signAppIfSpecified()
|
||||
await this.notarizeAppIfSpecified()
|
||||
return this.move()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function filterCFBundleIdentifier (identifier) {
|
||||
return identifier.replace(/ /g, '-').replace(/[^a-zA-Z0-9.-]/g, '')
|
||||
}
|
||||
|
||||
function createSignOpts (properties, platform, app, version, quiet) {
|
||||
// use default sign opts if osx-sign is true, otherwise clone osx-sign object
|
||||
const signOpts = properties === true ? { identity: null } : { ...properties }
|
||||
|
||||
// osx-sign options are handed off to sign module, but
|
||||
// with a few additions from the main options
|
||||
// user may think they can pass platform, app, or version, but they will be ignored
|
||||
common.subOptionWarning(signOpts, 'osx-sign', 'platform', platform, quiet)
|
||||
common.subOptionWarning(signOpts, 'osx-sign', 'app', app, quiet)
|
||||
common.subOptionWarning(signOpts, 'osx-sign', 'version', version, quiet)
|
||||
|
||||
if (signOpts.binaries) {
|
||||
common.warning('osx-sign.binaries is not an allowed sub-option. Not passing to @electron/osx-sign.', quiet)
|
||||
delete signOpts.binaries
|
||||
}
|
||||
|
||||
// Take argument osx-sign as signing identity:
|
||||
// if opts.osxSign is true (bool), fallback to identity=null for
|
||||
// autodiscovery. Otherwise, provide signing certificate info.
|
||||
if (signOpts.identity === true) {
|
||||
signOpts.identity = null
|
||||
}
|
||||
|
||||
return signOpts
|
||||
}
|
||||
|
||||
function createNotarizeOpts (properties, appBundleId, appPath, quiet) {
|
||||
// osxNotarize options are handed off to the @electron/notarize module, but with a few
|
||||
// additions from the main options. The user may think they can pass bundle ID or appPath,
|
||||
// but they will be ignored.
|
||||
if (properties.tool !== 'notarytool') {
|
||||
common.subOptionWarning(properties, 'osxNotarize', 'appBundleId', appBundleId, quiet)
|
||||
}
|
||||
common.subOptionWarning(properties, 'osxNotarize', 'appPath', appPath, quiet)
|
||||
return properties
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
App: MacApp,
|
||||
createNotarizeOpts: createNotarizeOpts,
|
||||
createSignOpts: createSignOpts,
|
||||
filterCFBundleIdentifier: filterCFBundleIdentifier
|
||||
}
|
||||
277
WordDictationStudentApp/node_modules/electron-packager/src/platform.js
generated
vendored
Normal file
277
WordDictationStudentApp/node_modules/electron-packager/src/platform.js
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
'use strict'
|
||||
|
||||
const asar = require('@electron/asar')
|
||||
const crypto = require('crypto')
|
||||
const debug = require('debug')('electron-packager')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
const common = require('./common')
|
||||
const copyFilter = require('./copy-filter')
|
||||
const hooks = require('./hooks')
|
||||
|
||||
class App {
|
||||
constructor (opts, templatePath) {
|
||||
this.opts = opts
|
||||
this.templatePath = templatePath
|
||||
this.asarOptions = common.createAsarOpts(opts)
|
||||
|
||||
if (this.opts.prune === undefined) {
|
||||
this.opts.prune = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource directory path before renaming.
|
||||
*/
|
||||
get originalResourcesDir () {
|
||||
return this.resourcesDir
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource directory path after renaming.
|
||||
*/
|
||||
get resourcesDir () {
|
||||
return path.join(this.stagingPath, 'resources')
|
||||
}
|
||||
|
||||
get originalResourcesAppDir () {
|
||||
return path.join(this.originalResourcesDir, 'app')
|
||||
}
|
||||
|
||||
get electronBinaryDir () {
|
||||
return this.stagingPath
|
||||
}
|
||||
|
||||
get originalElectronName () {
|
||||
/* istanbul ignore next */
|
||||
throw new Error('Child classes must implement this')
|
||||
}
|
||||
|
||||
get newElectronName () {
|
||||
/* istanbul ignore next */
|
||||
throw new Error('Child classes must implement this')
|
||||
}
|
||||
|
||||
get executableName () {
|
||||
return this.opts.executableName || this.opts.name
|
||||
}
|
||||
|
||||
get stagingPath () {
|
||||
if (this.opts.tmpdir === false) {
|
||||
return common.generateFinalPath(this.opts)
|
||||
} else {
|
||||
if (!this.cachedStagingPath) {
|
||||
const parentDir = path.join(
|
||||
common.baseTempDir(this.opts),
|
||||
`${this.opts.platform}-${this.opts.arch}`
|
||||
)
|
||||
fs.mkdirpSync(parentDir)
|
||||
this.cachedStagingPath = fs.mkdtempSync(path.join(parentDir, `${common.generateFinalBasename(this.opts)}-`))
|
||||
}
|
||||
return this.cachedStagingPath
|
||||
}
|
||||
}
|
||||
|
||||
get appAsarPath () {
|
||||
return path.join(this.originalResourcesDir, 'app.asar')
|
||||
}
|
||||
|
||||
get commonHookArgs () {
|
||||
return [
|
||||
this.opts.electronVersion,
|
||||
this.opts.platform,
|
||||
this.opts.arch
|
||||
]
|
||||
}
|
||||
|
||||
get hookArgsWithOriginalResourcesAppDir () {
|
||||
return [
|
||||
this.originalResourcesAppDir,
|
||||
...this.commonHookArgs
|
||||
]
|
||||
}
|
||||
|
||||
async relativeRename (basePath, oldName, newName) {
|
||||
debug(`Renaming ${oldName} to ${newName} in ${basePath}`)
|
||||
await fs.rename(path.join(basePath, oldName), path.join(basePath, newName))
|
||||
}
|
||||
|
||||
async renameElectron () {
|
||||
return this.relativeRename(this.electronBinaryDir, this.originalElectronName, this.newElectronName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the following initial operations for an app:
|
||||
* * Creates temporary directory
|
||||
* * Remove default_app (which is either a folder or an asar file)
|
||||
* * If a prebuilt asar is specified:
|
||||
* * Copies asar into temporary directory as app.asar
|
||||
* * Otherwise:
|
||||
* * Copies template into temporary directory
|
||||
* * Copies user's app into temporary directory
|
||||
* * Prunes non-production node_modules (if opts.prune is either truthy or undefined)
|
||||
* * Creates an asar (if opts.asar is set)
|
||||
*
|
||||
* Prune and asar are performed before platform-specific logic, primarily so that
|
||||
* this.originalResourcesAppDir is predictable (e.g. before .app is renamed for Mac)
|
||||
*/
|
||||
async initialize () {
|
||||
debug(`Initializing app in ${this.stagingPath} from ${this.templatePath} template`)
|
||||
|
||||
await fs.move(this.templatePath, this.stagingPath, { clobber: true })
|
||||
await this.removeDefaultApp()
|
||||
if (this.opts.prebuiltAsar) {
|
||||
await this.copyPrebuiltAsar()
|
||||
} else {
|
||||
await this.buildApp()
|
||||
}
|
||||
|
||||
await hooks.promisifyHooks(this.opts.afterInitialize, this.hookArgsWithOriginalResourcesAppDir)
|
||||
}
|
||||
|
||||
async buildApp () {
|
||||
await this.copyTemplate()
|
||||
await common.validateElectronApp(this.opts.dir, this.originalResourcesAppDir)
|
||||
await this.asarApp()
|
||||
}
|
||||
|
||||
async copyTemplate () {
|
||||
await hooks.promisifyHooks(this.opts.beforeCopy, this.hookArgsWithOriginalResourcesAppDir)
|
||||
|
||||
await fs.copy(this.opts.dir, this.originalResourcesAppDir, {
|
||||
filter: copyFilter.userPathFilter(this.opts),
|
||||
dereference: this.opts.derefSymlinks
|
||||
})
|
||||
await hooks.promisifyHooks(this.opts.afterCopy, this.hookArgsWithOriginalResourcesAppDir)
|
||||
if (this.opts.prune) {
|
||||
await hooks.promisifyHooks(this.opts.afterPrune, this.hookArgsWithOriginalResourcesAppDir)
|
||||
}
|
||||
}
|
||||
|
||||
async removeDefaultApp () {
|
||||
await Promise.all(['default_app', 'default_app.asar'].map(async basename => fs.remove(path.join(this.originalResourcesDir, basename))))
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces an icon filename to a given extension and returns the normalized filename,
|
||||
* if it exists. Otherwise, returns null.
|
||||
*
|
||||
* This error path is used by win32 if no icon is specified.
|
||||
*/
|
||||
async normalizeIconExtension (targetExt) {
|
||||
if (!this.opts.icon) throw new Error('No filename specified to normalizeIconExtension')
|
||||
|
||||
let iconFilename = this.opts.icon
|
||||
const ext = path.extname(iconFilename)
|
||||
if (ext !== targetExt) {
|
||||
iconFilename = path.join(path.dirname(iconFilename), path.basename(iconFilename, ext) + targetExt)
|
||||
}
|
||||
|
||||
if (await fs.pathExists(iconFilename)) {
|
||||
return iconFilename
|
||||
} else {
|
||||
/* istanbul ignore next */
|
||||
common.warning(`Could not find icon "${iconFilename}", not updating app icon`, this.opts.quiet)
|
||||
}
|
||||
}
|
||||
|
||||
prebuiltAsarWarning (option, triggerWarning) {
|
||||
if (triggerWarning) {
|
||||
common.warning(`prebuiltAsar and ${option} are incompatible, ignoring the ${option} option`, this.opts.quiet)
|
||||
}
|
||||
}
|
||||
|
||||
async copyPrebuiltAsar () {
|
||||
if (this.asarOptions) {
|
||||
common.warning('prebuiltAsar has been specified, all asar options will be ignored', this.opts.quiet)
|
||||
}
|
||||
|
||||
for (const hookName of ['beforeCopy', 'afterCopy', 'afterPrune']) {
|
||||
if (this.opts[hookName]) {
|
||||
throw new Error(`${hookName} is incompatible with prebuiltAsar`)
|
||||
}
|
||||
}
|
||||
|
||||
this.prebuiltAsarWarning('ignore', this.opts.originalIgnore)
|
||||
this.prebuiltAsarWarning('prune', !this.opts.prune)
|
||||
this.prebuiltAsarWarning('derefSymlinks', this.opts.derefSymlinks !== undefined)
|
||||
|
||||
const src = path.resolve(this.opts.prebuiltAsar)
|
||||
|
||||
const stat = await fs.stat(src)
|
||||
if (!stat.isFile()) {
|
||||
throw new Error(`${src} specified in prebuiltAsar must be an asar file.`)
|
||||
}
|
||||
|
||||
debug(`Copying asar: ${src} to ${this.appAsarPath}`)
|
||||
await fs.copy(src, this.appAsarPath, { overwrite: false, errorOnExist: true })
|
||||
}
|
||||
|
||||
appRelativePath (p) {
|
||||
return path.relative(this.stagingPath, p)
|
||||
}
|
||||
|
||||
async asarApp () {
|
||||
if (!this.asarOptions) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
debug(`Running asar with the options ${JSON.stringify(this.asarOptions)}`)
|
||||
|
||||
await hooks.promisifyHooks(this.opts.beforeAsar, this.hookArgsWithOriginalResourcesAppDir)
|
||||
|
||||
await asar.createPackageWithOptions(this.originalResourcesAppDir, this.appAsarPath, this.asarOptions)
|
||||
const { headerString } = asar.getRawHeader(this.appAsarPath)
|
||||
this.asarIntegrity = {
|
||||
[this.appRelativePath(this.appAsarPath)]: {
|
||||
algorithm: 'SHA256',
|
||||
hash: crypto.createHash('SHA256').update(headerString).digest('hex')
|
||||
}
|
||||
}
|
||||
await fs.remove(this.originalResourcesAppDir)
|
||||
|
||||
await hooks.promisifyHooks(this.opts.afterAsar, this.hookArgsWithOriginalResourcesAppDir)
|
||||
}
|
||||
|
||||
async copyExtraResources () {
|
||||
if (!this.opts.extraResource) return Promise.resolve()
|
||||
|
||||
const extraResources = common.ensureArray(this.opts.extraResource)
|
||||
|
||||
const hookArgs = [
|
||||
this.stagingPath,
|
||||
...this.commonHookArgs
|
||||
]
|
||||
|
||||
await hooks.promisifyHooks(this.opts.beforeCopyExtraResources, hookArgs)
|
||||
|
||||
await Promise.all(extraResources.map(
|
||||
resource => fs.copy(resource, path.resolve(this.stagingPath, this.resourcesDir, path.basename(resource)))
|
||||
))
|
||||
|
||||
await hooks.promisifyHooks(this.opts.afterCopyExtraResources, hookArgs)
|
||||
}
|
||||
|
||||
async move () {
|
||||
const finalPath = common.generateFinalPath(this.opts)
|
||||
|
||||
if (this.opts.tmpdir !== false) {
|
||||
debug(`Moving ${this.stagingPath} to ${finalPath}`)
|
||||
await fs.move(this.stagingPath, finalPath)
|
||||
}
|
||||
|
||||
if (this.opts.afterComplete) {
|
||||
const hookArgs = [
|
||||
finalPath,
|
||||
...this.commonHookArgs
|
||||
]
|
||||
|
||||
await hooks.promisifyHooks(this.opts.afterComplete, hookArgs)
|
||||
}
|
||||
|
||||
return finalPath
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = App
|
||||
70
WordDictationStudentApp/node_modules/electron-packager/src/prune.js
generated
vendored
Normal file
70
WordDictationStudentApp/node_modules/electron-packager/src/prune.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('./common')
|
||||
const galactus = require('galactus')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
const ELECTRON_MODULES = [
|
||||
'electron',
|
||||
'electron-nightly',
|
||||
'electron-prebuilt',
|
||||
'electron-prebuilt-compile'
|
||||
]
|
||||
|
||||
class Pruner {
|
||||
constructor (dir, quiet) {
|
||||
this.baseDir = common.normalizePath(dir)
|
||||
this.quiet = quiet
|
||||
this.galactus = new galactus.DestroyerOfModules({
|
||||
rootDirectory: dir,
|
||||
shouldKeepModuleTest: (module, isDevDep) => this.shouldKeepModule(module, isDevDep)
|
||||
})
|
||||
this.walkedTree = false
|
||||
}
|
||||
|
||||
setModules (moduleMap) {
|
||||
const modulePaths = Array.from(moduleMap.keys()).map(modulePath => `/${common.normalizePath(modulePath)}`)
|
||||
this.modules = new Set(modulePaths)
|
||||
this.walkedTree = true
|
||||
}
|
||||
|
||||
async pruneModule (name) {
|
||||
if (this.walkedTree) {
|
||||
return this.isProductionModule(name)
|
||||
} else {
|
||||
const moduleMap = await this.galactus.collectKeptModules({ relativePaths: true })
|
||||
this.setModules(moduleMap)
|
||||
return this.isProductionModule(name)
|
||||
}
|
||||
}
|
||||
|
||||
shouldKeepModule (module, isDevDep) {
|
||||
if (isDevDep || module.depType === galactus.DepType.ROOT) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (ELECTRON_MODULES.includes(module.name)) {
|
||||
common.warning(`Found '${module.name}' but not as a devDependency, pruning anyway`, this.quiet)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
isProductionModule (name) {
|
||||
return this.modules.has(name)
|
||||
}
|
||||
}
|
||||
|
||||
function isNodeModuleFolder (pathToCheck) {
|
||||
return path.basename(path.dirname(pathToCheck)) === 'node_modules' ||
|
||||
(path.basename(path.dirname(pathToCheck)).startsWith('@') && path.basename(path.resolve(pathToCheck, `..${path.sep}..`)) === 'node_modules')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isModule: async function isModule (pathToCheck) {
|
||||
return (await fs.pathExists(path.join(pathToCheck, 'package.json'))) && isNodeModuleFolder(pathToCheck)
|
||||
},
|
||||
Pruner: Pruner
|
||||
}
|
||||
149
WordDictationStudentApp/node_modules/electron-packager/src/targets.js
generated
vendored
Normal file
149
WordDictationStudentApp/node_modules/electron-packager/src/targets.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('./common')
|
||||
const { getHostArch } = require('@electron/get')
|
||||
const semver = require('semver')
|
||||
|
||||
const officialArchs = ['ia32', 'x64', 'armv7l', 'arm64', 'mips64el', 'universal']
|
||||
const officialPlatforms = ['darwin', 'linux', 'mas', 'win32']
|
||||
const officialPlatformArchCombos = {
|
||||
darwin: ['x64', 'arm64', 'universal'],
|
||||
linux: ['ia32', 'x64', 'armv7l', 'arm64', 'mips64el'],
|
||||
mas: ['x64', 'arm64', 'universal'],
|
||||
win32: ['ia32', 'x64', 'arm64']
|
||||
}
|
||||
|
||||
const buildVersions = {
|
||||
darwin: {
|
||||
arm64: '>= 11.0.0-beta.1',
|
||||
universal: '>= 11.0.0-beta.1'
|
||||
},
|
||||
linux: {
|
||||
arm64: '>= 1.8.0',
|
||||
ia32: '<19.0.0-beta.1',
|
||||
mips64el: '^1.8.2-beta.5'
|
||||
},
|
||||
mas: {
|
||||
arm64: '>= 11.0.0-beta.1',
|
||||
universal: '>= 11.0.0-beta.1'
|
||||
},
|
||||
win32: {
|
||||
arm64: '>= 6.0.8'
|
||||
}
|
||||
}
|
||||
|
||||
// Maps to module filename for each platform (lazy-required if used)
|
||||
const osModules = {
|
||||
darwin: './mac',
|
||||
linux: './linux',
|
||||
mas: './mac', // map to darwin
|
||||
win32: './win32'
|
||||
}
|
||||
|
||||
const supported = {
|
||||
arch: new Set(officialArchs),
|
||||
platform: new Set(officialPlatforms)
|
||||
}
|
||||
|
||||
function createPlatformArchPairs (opts, selectedPlatforms, selectedArchs, ignoreFunc) {
|
||||
const combinations = []
|
||||
for (const arch of selectedArchs) {
|
||||
for (const platform of selectedPlatforms) {
|
||||
if (usingOfficialElectronPackages(opts)) {
|
||||
if (!validOfficialPlatformArch(opts, platform, arch)) {
|
||||
warnIfAllNotSpecified(opts, `The platform/arch combination ${platform}/${arch} is not currently supported by Electron Packager`)
|
||||
continue
|
||||
} else if (buildVersions[platform] && buildVersions[platform][arch]) {
|
||||
const buildVersion = buildVersions[platform][arch]
|
||||
if (buildVersion && !officialBuildExists(opts, buildVersion)) {
|
||||
warnIfAllNotSpecified(opts, `Official ${platform}/${arch} support only exists in Electron ${buildVersion}`)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (typeof ignoreFunc === 'function' && ignoreFunc(platform, arch)) continue
|
||||
}
|
||||
combinations.push([platform, arch])
|
||||
}
|
||||
}
|
||||
|
||||
return combinations
|
||||
}
|
||||
|
||||
function unsupportedListOption (name, value, supported) {
|
||||
return new Error(`Unsupported ${name}=${value} (${typeof value}); must be a string matching: ${Array.from(supported.values()).join(', ')}`)
|
||||
}
|
||||
|
||||
function usingOfficialElectronPackages (opts) {
|
||||
return !opts.download || !Object.prototype.hasOwnProperty.call(opts.download, 'mirrorOptions')
|
||||
}
|
||||
|
||||
function validOfficialPlatformArch (opts, platform, arch) {
|
||||
return officialPlatformArchCombos[platform] && officialPlatformArchCombos[platform].includes(arch)
|
||||
}
|
||||
|
||||
function officialBuildExists (opts, buildVersion) {
|
||||
return semver.satisfies(opts.electronVersion, buildVersion, { includePrerelease: true })
|
||||
}
|
||||
|
||||
function allPlatformsOrArchsSpecified (opts) {
|
||||
return opts.all || opts.arch === 'all' || opts.platform === 'all'
|
||||
}
|
||||
|
||||
function warnIfAllNotSpecified (opts, message) {
|
||||
if (!allPlatformsOrArchsSpecified(opts)) {
|
||||
common.warning(message, opts.quiet)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
allOfficialArchsForPlatformAndVersion: function allOfficialArchsForPlatformAndVersion (platform, electronVersion) {
|
||||
const archs = officialPlatformArchCombos[platform]
|
||||
if (buildVersions[platform]) {
|
||||
const excludedArchs = Object.keys(buildVersions[platform])
|
||||
.filter(arch => !officialBuildExists({ electronVersion: electronVersion }, buildVersions[platform][arch]))
|
||||
return archs.filter(arch => !excludedArchs.includes(arch))
|
||||
}
|
||||
|
||||
return archs
|
||||
},
|
||||
createPlatformArchPairs,
|
||||
officialArchs,
|
||||
officialPlatformArchCombos,
|
||||
officialPlatforms,
|
||||
osModules,
|
||||
supported,
|
||||
// Validates list of architectures or platforms.
|
||||
// Returns a normalized array if successful, or throws an Error.
|
||||
validateListFromOptions: function validateListFromOptions (opts, name) {
|
||||
if (opts.all) return Array.from(supported[name].values())
|
||||
|
||||
let list = opts[name]
|
||||
if (!list) {
|
||||
if (name === 'arch') {
|
||||
list = getHostArch()
|
||||
} else {
|
||||
list = process[name]
|
||||
}
|
||||
} else if (list === 'all') {
|
||||
return Array.from(supported[name].values())
|
||||
}
|
||||
|
||||
if (!Array.isArray(list)) {
|
||||
if (typeof list === 'string') {
|
||||
list = list.split(/,\s*/)
|
||||
} else {
|
||||
return unsupportedListOption(name, list, supported[name])
|
||||
}
|
||||
}
|
||||
|
||||
const officialElectronPackages = usingOfficialElectronPackages(opts)
|
||||
|
||||
for (const value of list) {
|
||||
if (officialElectronPackages && !supported[name].has(value)) {
|
||||
return unsupportedListOption(name, value, supported[name])
|
||||
}
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
}
|
||||
80
WordDictationStudentApp/node_modules/electron-packager/src/universal.js
generated
vendored
Normal file
80
WordDictationStudentApp/node_modules/electron-packager/src/universal.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict'
|
||||
|
||||
const universal = require('@electron/universal')
|
||||
const common = require('./common')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
async function packageUniversalMac (packageForPlatformAndArchWithOpts, buildDir, comboOpts, downloadOpts, tempBase) {
|
||||
// In order to generate a universal macOS build we actually need to build the x64 and the arm64 app
|
||||
// and then glue them together
|
||||
common.info(`Packaging app for platform ${comboOpts.platform} universal using electron v${comboOpts.electronVersion} - Building x64 and arm64 slices now`, comboOpts.quiet)
|
||||
await fs.mkdirp(tempBase)
|
||||
const tempDir = await fs.mkdtemp(path.resolve(tempBase, 'electron-packager-universal-'))
|
||||
|
||||
const { App } = require('./mac')
|
||||
const app = new App(comboOpts, buildDir)
|
||||
const universalStagingPath = app.stagingPath
|
||||
const finalUniversalPath = common.generateFinalPath(app.opts)
|
||||
|
||||
if (await fs.pathExists(finalUniversalPath)) {
|
||||
if (comboOpts.overwrite) {
|
||||
await fs.remove(finalUniversalPath)
|
||||
} else {
|
||||
common.info(`Skipping ${comboOpts.platform} ${comboOpts.arch} (output dir already exists, use --overwrite to force)`, comboOpts.quiet)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const tempPackages = {}
|
||||
|
||||
for (const tempArch of ['x64', 'arm64']) {
|
||||
const tempOpts = {
|
||||
...comboOpts,
|
||||
arch: tempArch,
|
||||
out: tempDir
|
||||
}
|
||||
const tempDownloadOpts = {
|
||||
...downloadOpts,
|
||||
arch: tempArch
|
||||
}
|
||||
// Do not sign or notarize the individual slices, we sign and notarize the merged app later
|
||||
delete tempOpts.osxSign
|
||||
delete tempOpts.osxNotarize
|
||||
|
||||
tempPackages[tempArch] = await packageForPlatformAndArchWithOpts(tempOpts, tempDownloadOpts)
|
||||
}
|
||||
|
||||
const x64AppPath = tempPackages.x64
|
||||
const arm64AppPath = tempPackages.arm64
|
||||
|
||||
common.info(`Stitching universal app for platform ${comboOpts.platform}`, comboOpts.quiet)
|
||||
|
||||
const generatedFiles = await fs.readdir(x64AppPath)
|
||||
const appName = generatedFiles.filter(file => path.extname(file) === '.app')[0]
|
||||
|
||||
await universal.makeUniversalApp({
|
||||
...comboOpts.osxUniversal,
|
||||
x64AppPath: path.resolve(x64AppPath, appName),
|
||||
arm64AppPath: path.resolve(arm64AppPath, appName),
|
||||
outAppPath: path.resolve(universalStagingPath, appName)
|
||||
})
|
||||
|
||||
await app.signAppIfSpecified()
|
||||
await app.notarizeAppIfSpecified()
|
||||
await app.move()
|
||||
|
||||
for (const generatedFile of generatedFiles) {
|
||||
if (path.extname(generatedFile) === '.app') continue
|
||||
|
||||
await fs.copy(path.resolve(x64AppPath, generatedFile), path.resolve(finalUniversalPath, generatedFile))
|
||||
}
|
||||
|
||||
await fs.remove(tempDir)
|
||||
|
||||
return finalUniversalPath
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
packageUniversalMac
|
||||
}
|
||||
7
WordDictationStudentApp/node_modules/electron-packager/src/unzip.js
generated
vendored
Normal file
7
WordDictationStudentApp/node_modules/electron-packager/src/unzip.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict'
|
||||
|
||||
const extractZip = require('extract-zip')
|
||||
|
||||
module.exports = async function extractElectronZip (zipPath, targetDir) {
|
||||
await extractZip(zipPath, { dir: targetDir })
|
||||
}
|
||||
113
WordDictationStudentApp/node_modules/electron-packager/src/win32.js
generated
vendored
Normal file
113
WordDictationStudentApp/node_modules/electron-packager/src/win32.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('electron-packager')
|
||||
const path = require('path')
|
||||
const { WrapperError } = require('cross-spawn-windows-exe')
|
||||
|
||||
const App = require('./platform')
|
||||
const common = require('./common')
|
||||
|
||||
function updateWineMissingException (err) {
|
||||
if (err instanceof WrapperError) {
|
||||
err.message += '\n\n' +
|
||||
'Wine is required to use the appCopyright, appVersion, buildVersion, icon, and \n' +
|
||||
'win32metadata parameters for Windows targets.\n\n' +
|
||||
'See https://github.com/electron/electron-packager#building-windows-apps-from-non-windows-platforms for details.'
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
class WindowsApp extends App {
|
||||
get originalElectronName () {
|
||||
return 'electron.exe'
|
||||
}
|
||||
|
||||
get newElectronName () {
|
||||
return `${common.sanitizeAppName(this.executableName)}.exe`
|
||||
}
|
||||
|
||||
get electronBinaryPath () {
|
||||
return path.join(this.stagingPath, this.newElectronName)
|
||||
}
|
||||
|
||||
generateRceditOptionsSansIcon () {
|
||||
const win32metadata = {
|
||||
FileDescription: this.opts.name,
|
||||
InternalName: this.opts.name,
|
||||
OriginalFilename: this.newElectronName,
|
||||
ProductName: this.opts.name,
|
||||
...this.opts.win32metadata
|
||||
}
|
||||
|
||||
const rcOpts = { 'version-string': win32metadata }
|
||||
|
||||
if (this.opts.appVersion) {
|
||||
rcOpts['product-version'] = rcOpts['file-version'] = this.opts.appVersion
|
||||
}
|
||||
|
||||
if (this.opts.buildVersion) {
|
||||
rcOpts['file-version'] = this.opts.buildVersion
|
||||
}
|
||||
|
||||
if (this.opts.appCopyright) {
|
||||
rcOpts['version-string'].LegalCopyright = this.opts.appCopyright
|
||||
}
|
||||
|
||||
const manifestProperties = ['application-manifest', 'requested-execution-level']
|
||||
for (const manifestProperty of manifestProperties) {
|
||||
if (win32metadata[manifestProperty]) {
|
||||
rcOpts[manifestProperty] = win32metadata[manifestProperty]
|
||||
}
|
||||
}
|
||||
|
||||
return rcOpts
|
||||
}
|
||||
|
||||
async getIconPath () {
|
||||
if (!this.opts.icon) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return this.normalizeIconExtension('.ico')
|
||||
}
|
||||
|
||||
needsRcedit () {
|
||||
return this.opts.icon || this.opts.win32metadata || this.opts.appCopyright || this.opts.appVersion || this.opts.buildVersion
|
||||
}
|
||||
|
||||
async runRcedit () {
|
||||
/* istanbul ignore if */
|
||||
if (!this.needsRcedit()) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const rcOpts = this.generateRceditOptionsSansIcon()
|
||||
|
||||
// Icon might be omitted or only exist in one OS's format, so skip it if normalizeExt reports an error
|
||||
const icon = await this.getIconPath()
|
||||
if (icon) {
|
||||
rcOpts.icon = icon
|
||||
}
|
||||
|
||||
debug(`Running rcedit with the options ${JSON.stringify(rcOpts)}`)
|
||||
try {
|
||||
await require('rcedit')(this.electronBinaryPath, rcOpts)
|
||||
} catch (err) {
|
||||
throw updateWineMissingException(err)
|
||||
}
|
||||
}
|
||||
|
||||
async create () {
|
||||
await this.initialize()
|
||||
await this.renameElectron()
|
||||
await this.copyExtraResources()
|
||||
await this.runRcedit()
|
||||
return this.move()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
App: WindowsApp,
|
||||
updateWineMissingException: updateWineMissingException
|
||||
}
|
||||
Reference in New Issue
Block a user