UNPKG

4.78 kBJavaScriptView Raw
1/**
2 * @module flat
3 */
4
5'use strict'
6
7const path = require('path')
8
9const util = require('./util')
10const debuglog = util.debuglog
11const debugwarn = util.debugwarn
12const execFileAsync = util.execFileAsync
13const validateOptsAppAsync = util.validateOptsAppAsync
14const validateOptsPlatformAsync = util.validateOptsPlatformAsync
15const Identity = require('./util-identities').findIdentitiesAsync
16const findIdentitiesAsync = require('./util-identities').findIdentitiesAsync
17
18/**
19 * This function returns a promise validating all options passed in opts.
20 * @function
21 * @param {Object} opts - Options.
22 * @returns {Promise} Promise.
23 */
24function validateFlatOptsAsync (opts) {
25 if (opts.pkg) {
26 if (typeof opts.pkg !== 'string') return Promise.reject(new Error('`pkg` must be a string.'))
27 if (path.extname(opts.pkg) !== '.pkg') return Promise.reject(new Error('Extension of output package must be `.pkg`.'))
28 } else {
29 debugwarn('No `pkg` passed in arguments, will fallback to default inferred from the given application.')
30 opts.pkg = path.join(path.dirname(opts.app), path.basename(opts.app, '.app') + '.pkg')
31 }
32
33 if (opts.install) {
34 if (typeof opts.install !== 'string') return Promise.reject(new Error('`install` must be a string.'))
35 } else {
36 debugwarn('No `install` passed in arguments, will fallback to default `/Applications`.')
37 opts.install = '/Applications'
38 }
39
40 return Promise.all([
41 validateOptsAppAsync(opts),
42 validateOptsPlatformAsync(opts),
43 ])
44}
45
46/**
47 * This function returns a promise flattening the application.
48 * @function
49 * @param {Object} opts - Options.
50 * @returns {Promise} Promise.
51 */
52function flatApplicationAsync (opts) {
53 const args = [
54 '--component', opts.app, opts.install,
55 '--sign', opts.identity.name,
56 opts.pkg
57 ]
58 if (opts.keychain) {
59 args.unshift('--keychain', opts.keychain)
60 }
61 if (opts.scripts) {
62 args.unshift('--scripts', opts.scripts)
63 }
64
65 debuglog('Flattening... ' + opts.app)
66 return execFileAsync('productbuild', args)
67 .thenReturn(undefined)
68}
69
70/**
71 * This function is exported and returns a promise flattening the application.
72 * @function
73 * @param {Object} opts - Options.
74 * @returns {Promise} Promise.
75 */
76module.exports.flatAsync = function (opts) {
77 return validateFlatOptsAsync(opts)
78 .then(function () {
79 let promise
80 if (opts.identity) {
81 debuglog('`identity` passed in arguments.')
82 if (opts['identity-validation'] === false || opts.identity instanceof Identity) {
83 return Promise.resolve()
84 }
85 promise = findIdentitiesAsync(opts, opts.identity)
86 } else {
87 debugwarn('No `identity` passed in arguments...')
88 if (opts.platform === 'mas') {
89 debuglog('Finding `3rd Party Mac Developer Installer` certificate for flattening app distribution in the Mac App Store...')
90 promise = findIdentitiesAsync(opts, '3rd Party Mac Developer Installer:')
91 } else {
92 debuglog('Finding `Developer ID Application` certificate for distribution outside the Mac App Store...')
93 promise = findIdentitiesAsync(opts, 'Developer ID Installer:')
94 }
95 }
96 return promise
97 .then(function (identities) {
98 if (identities.length > 0) {
99 // Provisioning profile(s) found
100 if (identities.length > 1) {
101 debugwarn('Multiple identities found, will use the first discovered.')
102 } else {
103 debuglog('Found 1 identity.')
104 }
105 opts.identity = identities[0]
106 } else {
107 // No identity found
108 return Promise.reject(new Error('No identity found for signing.'))
109 }
110 })
111 })
112 .then(function () {
113 // Pre-flat operations
114 })
115 .then(function () {
116 debuglog('Flattening application...', '\n',
117 '> Application:', opts.app, '\n',
118 '> Package output:', opts.pkg, '\n',
119 '> Install path:', opts.install, '\n',
120 '> Identity:', opts.identity, '\n',
121 '> Scripts:', opts.scripts)
122 return flatApplicationAsync(opts)
123 })
124 .then(function () {
125 // Post-flat operations
126 debuglog('Application flattened.')
127 })
128}
129
130/**
131 * This function is exported with normal callback implementation.
132 * @function
133 * @param {Object} opts - Options.
134 * @param {RequestCallback} cb - Callback.
135 */
136module.exports.flat = function (opts, cb) {
137 module.exports.flatAsync(opts)
138 .then(function () {
139 debuglog('Application flattened, saved to: ' + opts.app)
140 if (cb) cb()
141 })
142 .catch(function (err) {
143 debuglog('Flat failed:')
144 if (err.message) debuglog(err.message)
145 else if (err.stack) debuglog(err.stack)
146 else debuglog(err)
147 if (cb) cb(err)
148 })
149}