reset-framework-cli 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/README.md +19 -19
- package/package.json +8 -6
- package/src/commands/build.js +91 -73
- package/src/commands/dev.js +143 -122
- package/src/commands/doctor.js +61 -54
- package/src/commands/init.js +946 -866
- package/src/commands/package.js +68 -68
- package/src/index.js +195 -195
- package/src/lib/backend.js +123 -0
- package/src/lib/context.js +66 -66
- package/src/lib/framework.js +57 -57
- package/src/lib/logger.js +11 -11
- package/src/lib/output.js +251 -236
- package/src/lib/process.js +303 -303
- package/src/lib/project.js +531 -494
- package/src/lib/toolchain.js +62 -62
- package/src/lib/ui.js +244 -244
- package/templates/basic/README.md +15 -15
- package/templates/basic/frontend/README.md +73 -73
- package/templates/basic/frontend/eslint.config.js +23 -23
- package/templates/basic/frontend/index.html +13 -13
- package/templates/basic/frontend/package.json +31 -31
- package/templates/basic/frontend/public/icons.svg +24 -24
- package/templates/basic/frontend/src/App.css +216 -216
- package/templates/basic/frontend/src/App.tsx +77 -77
- package/templates/basic/frontend/src/assets/vite.svg +1 -1
- package/templates/basic/frontend/src/index.css +111 -111
- package/templates/basic/frontend/src/lib/reset.ts +1 -1
- package/templates/basic/frontend/src/main.tsx +10 -10
- package/templates/basic/frontend/tsconfig.app.json +28 -28
- package/templates/basic/frontend/tsconfig.json +7 -7
- package/templates/basic/frontend/tsconfig.node.json +26 -26
- package/templates/basic/frontend/vite.config.ts +16 -16
- package/templates/basic/reset.config.json +58 -58
package/src/lib/output.js
CHANGED
|
@@ -1,124 +1,125 @@
|
|
|
1
|
-
import path from "node:path"
|
|
2
|
-
import { cp, mkdir, readdir, rm, writeFile } from "node:fs/promises"
|
|
3
|
-
import { existsSync } from "node:fs"
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.replaceAll("
|
|
16
|
-
.replaceAll("
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
".
|
|
107
|
-
".
|
|
108
|
-
".
|
|
109
|
-
".
|
|
110
|
-
".
|
|
111
|
-
".
|
|
112
|
-
".
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { cp, mkdir, readdir, rm, writeFile } from "node:fs/promises"
|
|
3
|
+
import { existsSync } from "node:fs"
|
|
4
|
+
|
|
5
|
+
import { stageAppBackend } from "./backend.js"
|
|
6
|
+
import { logger } from "./logger.js"
|
|
7
|
+
import { runCommand } from "./process.js"
|
|
8
|
+
import {
|
|
9
|
+
resolveFrameworkRuntimeBinary,
|
|
10
|
+
resolveFrameworkRuntimeOutputDir
|
|
11
|
+
} from "./project.js"
|
|
12
|
+
|
|
13
|
+
function escapePlistString(value) {
|
|
14
|
+
return value
|
|
15
|
+
.replaceAll("&", "&")
|
|
16
|
+
.replaceAll("<", "<")
|
|
17
|
+
.replaceAll(">", ">")
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function serializePlistValue(value, indentLevel = 1) {
|
|
21
|
+
const indent = " ".repeat(indentLevel)
|
|
22
|
+
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
if (value.length === 0) {
|
|
25
|
+
return `${indent}<array/>\n`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
`${indent}<array>\n` +
|
|
30
|
+
value.map((entry) => serializePlistValue(entry, indentLevel + 1)).join("") +
|
|
31
|
+
`${indent}</array>\n`
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (typeof value === "object" && value !== null) {
|
|
36
|
+
const entries = Object.entries(value)
|
|
37
|
+
if (entries.length === 0) {
|
|
38
|
+
return `${indent}<dict/>\n`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
`${indent}<dict>\n` +
|
|
43
|
+
entries
|
|
44
|
+
.map(
|
|
45
|
+
([key, entryValue]) =>
|
|
46
|
+
`${" ".repeat(indentLevel + 1)}<key>${escapePlistString(key)}</key>\n${serializePlistValue(entryValue, indentLevel + 1)}`
|
|
47
|
+
)
|
|
48
|
+
.join("") +
|
|
49
|
+
`${indent}</dict>\n`
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (typeof value === "boolean") {
|
|
54
|
+
return `${indent}<${value ? "true" : "false"}/>\n`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (typeof value === "number") {
|
|
58
|
+
return `${indent}<integer>${value}</integer>\n`
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return `${indent}<string>${escapePlistString(String(value))}</string>\n`
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function buildMacOSInfoPlist(config) {
|
|
65
|
+
const urlTypes = Array.isArray(config.protocols?.schemes)
|
|
66
|
+
? config.protocols.schemes.map((schemeConfig) => ({
|
|
67
|
+
CFBundleTypeRole: schemeConfig.role ?? "Viewer",
|
|
68
|
+
CFBundleURLName:
|
|
69
|
+
typeof schemeConfig.name === "string" && schemeConfig.name.trim() !== ""
|
|
70
|
+
? schemeConfig.name
|
|
71
|
+
: `${config.appId}.${schemeConfig.scheme}`,
|
|
72
|
+
CFBundleURLSchemes: [schemeConfig.scheme]
|
|
73
|
+
}))
|
|
74
|
+
: []
|
|
75
|
+
|
|
76
|
+
const plist = {
|
|
77
|
+
CFBundleDevelopmentRegion: "English",
|
|
78
|
+
CFBundleDisplayName: config.productName,
|
|
79
|
+
CFBundleExecutable: "reset-framework",
|
|
80
|
+
CFBundleIdentifier: config.appId,
|
|
81
|
+
CFBundleInfoDictionaryVersion: "6.0",
|
|
82
|
+
CFBundleName: config.productName,
|
|
83
|
+
CFBundlePackageType: "APPL",
|
|
84
|
+
CFBundleShortVersionString: config.version,
|
|
85
|
+
CFBundleVersion: config.version,
|
|
86
|
+
CSResourcesFileMapped: true
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (urlTypes.length > 0) {
|
|
90
|
+
plist.CFBundleURLTypes = urlTypes
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
`<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
95
|
+
`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n` +
|
|
96
|
+
`<plist version="1.0">\n` +
|
|
97
|
+
serializePlistValue(plist, 0) +
|
|
98
|
+
`</plist>\n`
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function shouldCopyWindowsRuntimeArtifact(entryName) {
|
|
103
|
+
const extension = path.extname(entryName).toLowerCase()
|
|
104
|
+
|
|
105
|
+
return [
|
|
106
|
+
".bin",
|
|
107
|
+
".dat",
|
|
108
|
+
".dll",
|
|
109
|
+
".exe",
|
|
110
|
+
".json",
|
|
111
|
+
".manifest",
|
|
112
|
+
".pak",
|
|
113
|
+
".pri"
|
|
114
|
+
].includes(extension)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function escapePowerShellLiteral(value) {
|
|
118
|
+
return String(value).replaceAll("'", "''")
|
|
119
|
+
}
|
|
120
|
+
|
|
120
121
|
export async function stageMacOSAppBundle(frameworkPaths, frameworkBuildPaths, config, options = {}) {
|
|
121
|
-
const { dryRun = false, outputPaths, configPath, preferSource = false } = options
|
|
122
|
+
const { dryRun = false, outputPaths, configPath, preferSource = false, backendArtifact = null } = options
|
|
122
123
|
const runtimeSourceBundle = resolveFrameworkRuntimeOutputDir(frameworkPaths, frameworkBuildPaths, "release", {
|
|
123
124
|
mustExist: !dryRun,
|
|
124
125
|
preferSource
|
|
@@ -131,37 +132,44 @@ export async function stageMacOSAppBundle(frameworkPaths, frameworkBuildPaths, c
|
|
|
131
132
|
if (!existsSync(outputPaths.frontendEntryFile) && !dryRun) {
|
|
132
133
|
throw new Error(
|
|
133
134
|
`Missing frontend build output at ${outputPaths.frontendEntryFile}. Run the frontend build first.`
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
137
138
|
logger.info(`Staging app bundle into ${outputPaths.appBundlePath}`)
|
|
138
139
|
|
|
139
140
|
if (dryRun) {
|
|
140
141
|
logger.info(`- copy ${runtimeSourceBundle} -> ${outputPaths.appBundlePath}`)
|
|
141
142
|
logger.info(`- copy ${configPath} -> ${outputPaths.bundledConfigPath}`)
|
|
142
143
|
logger.info(`- copy ${outputPaths.frontendDistDir} -> ${outputPaths.bundledFrontendDir}`)
|
|
144
|
+
if (backendArtifact) {
|
|
145
|
+
logger.info(`- copy ${backendArtifact.bundleEntryPath} -> ${outputPaths.bundledBackendEntryPath}`)
|
|
146
|
+
logger.info(`- copy ${backendArtifact.runnerPath} -> ${outputPaths.bundledBackendRunnerPath}`)
|
|
147
|
+
logger.info(`- copy ${backendArtifact.supportModulePath} -> ${outputPaths.bundledBackendSupportModulePath}`)
|
|
148
|
+
logger.info(`- copy ${backendArtifact.runtimeExecutablePath} -> ${outputPaths.bundledBackendRuntimePath}`)
|
|
149
|
+
}
|
|
143
150
|
return outputPaths
|
|
144
|
-
}
|
|
145
|
-
|
|
151
|
+
}
|
|
152
|
+
|
|
146
153
|
await mkdir(outputPaths.macosDir, { recursive: true })
|
|
147
154
|
await rm(outputPaths.appBundlePath, { recursive: true, force: true })
|
|
148
155
|
await cp(runtimeSourceBundle, outputPaths.appBundlePath, { recursive: true })
|
|
149
|
-
|
|
150
|
-
await mkdir(outputPaths.resourcesDir, { recursive: true })
|
|
151
|
-
await cp(configPath, outputPaths.bundledConfigPath, { force: true })
|
|
152
|
-
await rm(outputPaths.bundledFrontendDir, { recursive: true, force: true })
|
|
153
|
-
await cp(outputPaths.frontendDistDir, outputPaths.bundledFrontendDir, { recursive: true })
|
|
154
|
-
await
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
|
|
157
|
+
await mkdir(outputPaths.resourcesDir, { recursive: true })
|
|
158
|
+
await cp(configPath, outputPaths.bundledConfigPath, { force: true })
|
|
159
|
+
await rm(outputPaths.bundledFrontendDir, { recursive: true, force: true })
|
|
160
|
+
await cp(outputPaths.frontendDistDir, outputPaths.bundledFrontendDir, { recursive: true })
|
|
161
|
+
await stageAppBackend(backendArtifact, outputPaths)
|
|
162
|
+
await writeFile(
|
|
163
|
+
path.join(outputPaths.appBundlePath, "Contents", "Info.plist"),
|
|
164
|
+
buildMacOSInfoPlist(config),
|
|
165
|
+
"utf8"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
return outputPaths
|
|
169
|
+
}
|
|
170
|
+
|
|
163
171
|
export async function stageWindowsAppBundle(frameworkPaths, frameworkBuildPaths, config, options = {}) {
|
|
164
|
-
const { dryRun = false, outputPaths, configPath, preferSource = false } = options
|
|
172
|
+
const { dryRun = false, outputPaths, configPath, preferSource = false, backendArtifact = null } = options
|
|
165
173
|
const runtimeSourceBinary = resolveFrameworkRuntimeBinary(frameworkPaths, frameworkBuildPaths, "release", {
|
|
166
174
|
mustExist: !dryRun,
|
|
167
175
|
preferSource
|
|
@@ -170,99 +178,106 @@ export async function stageWindowsAppBundle(frameworkPaths, frameworkBuildPaths,
|
|
|
170
178
|
mustExist: !dryRun,
|
|
171
179
|
preferSource
|
|
172
180
|
})
|
|
173
|
-
|
|
174
|
-
if (!outputPaths) {
|
|
175
|
-
throw new Error("stageWindowsAppBundle requires resolved output paths")
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (!existsSync(outputPaths.frontendEntryFile) && !dryRun) {
|
|
179
|
-
throw new Error(
|
|
180
|
-
`Missing frontend build output at ${outputPaths.frontendEntryFile}. Run the frontend build first.`
|
|
181
|
-
)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
logger.info(`Staging Windows app into ${outputPaths.appBundlePath}`)
|
|
185
|
-
|
|
186
|
-
if (dryRun) {
|
|
187
|
-
logger.info(`- copy ${runtimeSourceDir} -> ${outputPaths.appBundlePath}`)
|
|
188
|
-
logger.info(`- rename ${runtimeSourceBinary} -> ${outputPaths.appExecutablePath}`)
|
|
189
|
-
logger.info(`- copy ${configPath} -> ${outputPaths.bundledConfigPath}`)
|
|
190
|
-
logger.info(`- copy ${outputPaths.frontendDistDir} -> ${outputPaths.bundledFrontendDir}`)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
181
|
+
|
|
182
|
+
if (!outputPaths) {
|
|
183
|
+
throw new Error("stageWindowsAppBundle requires resolved output paths")
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!existsSync(outputPaths.frontendEntryFile) && !dryRun) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Missing frontend build output at ${outputPaths.frontendEntryFile}. Run the frontend build first.`
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
logger.info(`Staging Windows app into ${outputPaths.appBundlePath}`)
|
|
193
|
+
|
|
194
|
+
if (dryRun) {
|
|
195
|
+
logger.info(`- copy ${runtimeSourceDir} -> ${outputPaths.appBundlePath}`)
|
|
196
|
+
logger.info(`- rename ${runtimeSourceBinary} -> ${outputPaths.appExecutablePath}`)
|
|
197
|
+
logger.info(`- copy ${configPath} -> ${outputPaths.bundledConfigPath}`)
|
|
198
|
+
logger.info(`- copy ${outputPaths.frontendDistDir} -> ${outputPaths.bundledFrontendDir}`)
|
|
199
|
+
if (backendArtifact) {
|
|
200
|
+
logger.info(`- copy ${backendArtifact.bundleEntryPath} -> ${outputPaths.bundledBackendEntryPath}`)
|
|
201
|
+
logger.info(`- copy ${backendArtifact.runnerPath} -> ${outputPaths.bundledBackendRunnerPath}`)
|
|
202
|
+
logger.info(`- copy ${backendArtifact.supportModulePath} -> ${outputPaths.bundledBackendSupportModulePath}`)
|
|
203
|
+
logger.info(`- copy ${backendArtifact.runtimeExecutablePath} -> ${outputPaths.bundledBackendRuntimePath}`)
|
|
204
|
+
}
|
|
205
|
+
return outputPaths
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
await mkdir(outputPaths.windowsDir, { recursive: true })
|
|
209
|
+
await rm(outputPaths.appBundlePath, { recursive: true, force: true })
|
|
210
|
+
await mkdir(outputPaths.appBundlePath, { recursive: true })
|
|
211
|
+
const runtimeEntries = await readdir(runtimeSourceDir, { withFileTypes: true })
|
|
212
|
+
const runtimeBinaryName = path.basename(runtimeSourceBinary)
|
|
213
|
+
|
|
214
|
+
for (const entry of runtimeEntries) {
|
|
215
|
+
if (!entry.isDirectory() && !shouldCopyWindowsRuntimeArtifact(entry.name)) {
|
|
216
|
+
continue
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const sourcePath = path.join(runtimeSourceDir, entry.name)
|
|
220
|
+
const targetPath =
|
|
221
|
+
entry.name.toLowerCase() === runtimeBinaryName.toLowerCase()
|
|
222
|
+
? outputPaths.appExecutablePath
|
|
223
|
+
: path.join(outputPaths.appBundlePath, entry.name)
|
|
224
|
+
|
|
225
|
+
await cp(sourcePath, targetPath, { recursive: true, force: true })
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
await mkdir(outputPaths.resourcesDir, { recursive: true })
|
|
229
|
+
await cp(configPath, outputPaths.bundledConfigPath, { force: true })
|
|
230
|
+
await rm(outputPaths.bundledFrontendDir, { recursive: true, force: true })
|
|
231
|
+
await cp(outputPaths.frontendDistDir, outputPaths.bundledFrontendDir, { recursive: true })
|
|
232
|
+
await stageAppBackend(backendArtifact, outputPaths)
|
|
233
|
+
|
|
234
|
+
return outputPaths
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export async function createMacOSZipArchive(outputPaths, options = {}) {
|
|
238
|
+
const { dryRun = false } = options
|
|
239
|
+
|
|
240
|
+
logger.info(`Packaging ${outputPaths.appBundlePath} -> ${outputPaths.zipPath}`)
|
|
241
|
+
|
|
242
|
+
if (process.platform !== "darwin") {
|
|
243
|
+
throw new Error("Packaging is only implemented for macOS right now")
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (!dryRun) {
|
|
247
|
+
await mkdir(outputPaths.packagesDir, { recursive: true })
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
await runCommand(
|
|
251
|
+
"ditto",
|
|
252
|
+
["-c", "-k", "--sequesterRsrc", "--keepParent", outputPaths.appBundlePath, outputPaths.zipPath],
|
|
253
|
+
{ dryRun }
|
|
254
|
+
)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export async function createWindowsZipArchive(outputPaths, options = {}) {
|
|
258
|
+
const { dryRun = false } = options
|
|
259
|
+
|
|
260
|
+
logger.info(`Packaging ${outputPaths.appBundlePath} -> ${outputPaths.zipPath}`)
|
|
261
|
+
|
|
262
|
+
if (process.platform !== "win32") {
|
|
263
|
+
throw new Error("Packaging is only implemented for Windows and macOS right now")
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!dryRun) {
|
|
267
|
+
await mkdir(outputPaths.packagesDir, { recursive: true })
|
|
268
|
+
await rm(outputPaths.zipPath, { force: true })
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const literalSourcePath = escapePowerShellLiteral(outputPaths.appBundlePath)
|
|
272
|
+
const literalDestinationPath = escapePowerShellLiteral(outputPaths.zipPath)
|
|
273
|
+
const archiveCommand = [
|
|
274
|
+
"$ErrorActionPreference = 'Stop'",
|
|
275
|
+
`Compress-Archive -LiteralPath '${literalSourcePath}' -DestinationPath '${literalDestinationPath}' -CompressionLevel Optimal`
|
|
276
|
+
].join("; ")
|
|
277
|
+
|
|
278
|
+
await runCommand(
|
|
279
|
+
"powershell.exe",
|
|
280
|
+
["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", archiveCommand],
|
|
281
|
+
{ dryRun }
|
|
282
|
+
)
|
|
283
|
+
}
|