muon-ui 0.7.0 → 0.9.0
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/README.md +9 -12
- package/dist/cli.cjs +291 -126
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/native/linux-amd64/muon-bootstrap +0 -0
- package/dist/native/linux-amd64/muon-builder +0 -0
- package/dist/native/linux-arm64/muon-bootstrap +0 -0
- package/dist/native/linux-arm64/{muon-prepare → muon-builder} +0 -0
- package/dist/native/linux-armhf/muon-bootstrap +0 -0
- package/dist/native/linux-armhf/{muon-prepare → muon-builder} +0 -0
- package/dist/native/muon-256.png +0 -0
- package/dist/native/windows-amd64/muon-bootstrap.exe +0 -0
- package/dist/native/windows-amd64/muon-builder.exe +0 -0
- package/dist/native/windows-i686/muon-bootstrap.exe +0 -0
- package/dist/native/windows-i686/muon-builder.exe +0 -0
- package/dist/runtime/linux-amd64/CREDITS.md +24 -0
- package/dist/runtime/linux-amd64/libmuon-ui.so +0 -0
- package/dist/runtime/linux-amd64/muon-core +0 -0
- package/dist/runtime/linux-arm64/CREDITS.md +24 -0
- package/dist/runtime/linux-arm64/libmuon-ui.so +0 -0
- package/dist/runtime/linux-arm64/muon-core +0 -0
- package/dist/runtime/linux-armhf/CREDITS.md +24 -0
- package/dist/runtime/linux-armhf/libmuon-ui.so +0 -0
- package/dist/runtime/linux-armhf/muon-core +0 -0
- package/dist/runtime/windows-amd64/CREDITS.md +24 -0
- package/dist/runtime/windows-amd64/libcardio.dll +0 -0
- package/dist/runtime/windows-amd64/libmuon-ui.dll +0 -0
- package/dist/runtime/windows-amd64/muon-core.exe +0 -0
- package/dist/runtime/windows-i686/CREDITS.md +24 -0
- package/dist/runtime/windows-i686/libcardio.dll +0 -0
- package/dist/runtime/windows-i686/libmuon-ui.dll +0 -0
- package/dist/runtime/windows-i686/muon-core.exe +0 -0
- package/dist/{vite-options-FFh0NWUa.cjs → vite-internals-HXgH7b5M.cjs} +1460 -121
- package/dist/vite-internals-HXgH7b5M.cjs.map +1 -0
- package/dist/vite.cjs +452 -10
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +1552 -92
- package/dist/vite.mjs.map +1 -1
- package/muon.d.ts +141 -27
- package/package.json +14 -10
- package/vite.d.ts +276 -14
- package/dist/native/linux-amd64/muon-prepare +0 -0
- package/dist/native/windows-amd64/muon-prepare.exe +0 -0
- package/dist/native/windows-i686/muon-prepare.exe +0 -0
- package/dist/vite-options-FFh0NWUa.cjs.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: muon-ui
|
|
3
|
-
* version: 0.
|
|
3
|
+
* version: 0.9.0
|
|
4
4
|
* description: A multi-platform GUI application framework that uses CEF as its backend
|
|
5
5
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
6
6
|
* license: MIT
|
|
7
7
|
* repository.url: https://github.com/kekyo/muon-ui.git
|
|
8
|
-
* git.commit.hash:
|
|
8
|
+
* git.commit.hash: 3437b522a51d8772713b72722b109c5ff30fc711
|
|
9
9
|
*/
|
|
10
10
|
//#region \0rolldown/runtime.js
|
|
11
11
|
var __create = Object.create;
|
|
@@ -39,6 +39,8 @@ let node_crypto = require("node:crypto");
|
|
|
39
39
|
let node_os = require("node:os");
|
|
40
40
|
let adm_zip = require("adm-zip");
|
|
41
41
|
adm_zip = __toESM(adm_zip, 1);
|
|
42
|
+
let sharp = require("sharp");
|
|
43
|
+
sharp = __toESM(sharp, 1);
|
|
42
44
|
//#region src/targets.ts
|
|
43
45
|
/**
|
|
44
46
|
* Supported public Muon targets in deterministic build order.
|
|
@@ -56,7 +58,7 @@ var targetDescriptors = {
|
|
|
56
58
|
cefTarget: "linux64",
|
|
57
59
|
os: "linux",
|
|
58
60
|
arch: "amd64",
|
|
59
|
-
distributionDirectoryName: "dist-muon
|
|
61
|
+
distributionDirectoryName: "dist-muon/linux-amd64",
|
|
60
62
|
runtimeExecutableName: "muon-core",
|
|
61
63
|
bootstrapExecutableName: "muon-bootstrap",
|
|
62
64
|
launcherExtension: "",
|
|
@@ -71,7 +73,7 @@ var targetDescriptors = {
|
|
|
71
73
|
cefTarget: "linuxarm",
|
|
72
74
|
os: "linux",
|
|
73
75
|
arch: "armhf",
|
|
74
|
-
distributionDirectoryName: "dist-muon
|
|
76
|
+
distributionDirectoryName: "dist-muon/linux-armhf",
|
|
75
77
|
runtimeExecutableName: "muon-core",
|
|
76
78
|
bootstrapExecutableName: "muon-bootstrap",
|
|
77
79
|
launcherExtension: "",
|
|
@@ -86,7 +88,7 @@ var targetDescriptors = {
|
|
|
86
88
|
cefTarget: "linuxarm64",
|
|
87
89
|
os: "linux",
|
|
88
90
|
arch: "arm64",
|
|
89
|
-
distributionDirectoryName: "dist-muon
|
|
91
|
+
distributionDirectoryName: "dist-muon/linux-arm64",
|
|
90
92
|
runtimeExecutableName: "muon-core",
|
|
91
93
|
bootstrapExecutableName: "muon-bootstrap",
|
|
92
94
|
launcherExtension: "",
|
|
@@ -101,7 +103,7 @@ var targetDescriptors = {
|
|
|
101
103
|
cefTarget: "windows32",
|
|
102
104
|
os: "windows",
|
|
103
105
|
arch: "i686",
|
|
104
|
-
distributionDirectoryName: "dist-muon
|
|
106
|
+
distributionDirectoryName: "dist-muon/windows-i686",
|
|
105
107
|
runtimeExecutableName: "muon-core.exe",
|
|
106
108
|
bootstrapExecutableName: "muon-bootstrap.exe",
|
|
107
109
|
launcherExtension: ".exe",
|
|
@@ -121,7 +123,7 @@ var targetDescriptors = {
|
|
|
121
123
|
cefTarget: "windows64",
|
|
122
124
|
os: "windows",
|
|
123
125
|
arch: "amd64",
|
|
124
|
-
distributionDirectoryName: "dist-muon
|
|
126
|
+
distributionDirectoryName: "dist-muon/windows-amd64",
|
|
125
127
|
runtimeExecutableName: "muon-core.exe",
|
|
126
128
|
bootstrapExecutableName: "muon-bootstrap.exe",
|
|
127
129
|
launcherExtension: ".exe",
|
|
@@ -146,6 +148,20 @@ Object.fromEntries(allMuonTargets.map((target) => [targetDescriptors[target].cef
|
|
|
146
148
|
*/
|
|
147
149
|
var getMuonTargetDescriptor = (target) => targetDescriptors[target];
|
|
148
150
|
/**
|
|
151
|
+
* Returns the runtime app identifier embedded for one target distribution.
|
|
152
|
+
*
|
|
153
|
+
* @param appId Base sanitized application identifier.
|
|
154
|
+
* @param target Public Muon target.
|
|
155
|
+
* @returns Target runtime application identifier.
|
|
156
|
+
*
|
|
157
|
+
* @remarks Windows targets append their public architecture name so 32-bit and
|
|
158
|
+
* 64-bit packages do not share runtime state or installer identities.
|
|
159
|
+
*/
|
|
160
|
+
var getMuonTargetRuntimeAppId = (appId, target) => {
|
|
161
|
+
const descriptor = getMuonTargetDescriptor(target);
|
|
162
|
+
return descriptor.os === "windows" ? `${appId}.${descriptor.arch}` : appId;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
149
165
|
* Normalizes a user supplied public Muon target.
|
|
150
166
|
*
|
|
151
167
|
* @param target Target value supplied by the user.
|
|
@@ -192,8 +208,8 @@ var getDefaultMuonPrepareTarget = (platform, architecture) => {
|
|
|
192
208
|
throw new Error(`Unsupported Muon prepare target: platform=${platform}, arch=${architecture}`);
|
|
193
209
|
}
|
|
194
210
|
};
|
|
195
|
-
var
|
|
196
|
-
var moduleDirectory$
|
|
211
|
+
var getBuilderExecutableName = (platform) => platform === "win32" ? "muon-builder.exe" : "muon-builder";
|
|
212
|
+
var moduleDirectory$4 = typeof __dirname === "string" ? __dirname : (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
|
|
197
213
|
var canExecute = async (path) => {
|
|
198
214
|
try {
|
|
199
215
|
await (0, node_fs_promises.access)(path, node_fs.constants.X_OK);
|
|
@@ -202,12 +218,12 @@ var canExecute = async (path) => {
|
|
|
202
218
|
return false;
|
|
203
219
|
}
|
|
204
220
|
};
|
|
205
|
-
var
|
|
206
|
-
const explicit = options.prepareExecutablePath ?? options.environment.
|
|
221
|
+
var resolveMuonBuilderExecutable = async (options) => {
|
|
222
|
+
const explicit = options.prepareExecutablePath ?? options.environment.MUON_BUILDER_PATH;
|
|
207
223
|
if (explicit !== void 0 && explicit !== "") return explicit;
|
|
208
|
-
const executableName =
|
|
224
|
+
const executableName = getBuilderExecutableName(process.platform);
|
|
209
225
|
const target = getDefaultMuonPrepareTarget(process.platform, process.arch);
|
|
210
|
-
const candidates = [(0, node_path.join)(moduleDirectory$
|
|
226
|
+
const candidates = [(0, node_path.join)(moduleDirectory$4, "native", target, executableName), (0, node_path.join)(moduleDirectory$4, "..", "dist", "native", target, executableName)];
|
|
211
227
|
for (const candidate of candidates) if (await canExecute(candidate)) return candidate;
|
|
212
228
|
return candidates[0] ?? executableName;
|
|
213
229
|
};
|
|
@@ -226,14 +242,100 @@ var createMuonPrepareArguments = (options) => {
|
|
|
226
242
|
if (options.quiet) args.push("--quiet");
|
|
227
243
|
return args;
|
|
228
244
|
};
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
var
|
|
236
|
-
|
|
245
|
+
var spinnerFrames = [
|
|
246
|
+
"-",
|
|
247
|
+
"\\",
|
|
248
|
+
"|",
|
|
249
|
+
"/"
|
|
250
|
+
];
|
|
251
|
+
var spinnerIntervalMilliseconds = 100;
|
|
252
|
+
var terminalLineStart = "\r";
|
|
253
|
+
var terminalClearLine = "\x1B[K";
|
|
254
|
+
var isMuonPrepareStatusLine = (line) => {
|
|
255
|
+
const trimmed = line.trimEnd();
|
|
256
|
+
return trimmed.endsWith("...") || trimmed === "Failed to prepare CEF." || trimmed.startsWith("Downloading CEF binary:");
|
|
257
|
+
};
|
|
258
|
+
var shouldKeepMuonPrepareStatusAfterLine = (line) => line.startsWith("Muon files copied to staging:");
|
|
259
|
+
var createPlainStderrForwarder = () => ({
|
|
260
|
+
write: (chunk) => {
|
|
261
|
+
process.stderr.write(chunk);
|
|
262
|
+
},
|
|
263
|
+
flush: () => {}
|
|
264
|
+
});
|
|
265
|
+
var createSpinnerStderrForwarder = () => {
|
|
266
|
+
let pending = "";
|
|
267
|
+
let activeStatus = void 0;
|
|
268
|
+
let frameIndex = 0;
|
|
269
|
+
let timer = void 0;
|
|
270
|
+
const writeRaw = (chunk) => {
|
|
271
|
+
process.stderr.write(chunk);
|
|
272
|
+
};
|
|
273
|
+
const stopTimer = () => {
|
|
274
|
+
if (timer !== void 0) {
|
|
275
|
+
clearInterval(timer);
|
|
276
|
+
timer = void 0;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
const renderStatus = () => {
|
|
280
|
+
if (activeStatus === void 0) return;
|
|
281
|
+
writeRaw(`${terminalLineStart}${spinnerFrames[frameIndex] ?? spinnerFrames[0]} ${activeStatus}${terminalClearLine}`);
|
|
282
|
+
frameIndex = (frameIndex + 1) % spinnerFrames.length;
|
|
283
|
+
};
|
|
284
|
+
const ensureTimer = () => {
|
|
285
|
+
if (timer === void 0) timer = setInterval(renderStatus, spinnerIntervalMilliseconds);
|
|
286
|
+
};
|
|
287
|
+
const finishStatus = () => {
|
|
288
|
+
if (activeStatus === void 0) return;
|
|
289
|
+
const status = activeStatus;
|
|
290
|
+
activeStatus = void 0;
|
|
291
|
+
stopTimer();
|
|
292
|
+
frameIndex = 0;
|
|
293
|
+
writeRaw(`${terminalLineStart}${status}${terminalClearLine}\n`);
|
|
294
|
+
};
|
|
295
|
+
const startStatus = (status) => {
|
|
296
|
+
if (activeStatus !== void 0 && activeStatus !== status) finishStatus();
|
|
297
|
+
activeStatus = status;
|
|
298
|
+
renderStatus();
|
|
299
|
+
ensureTimer();
|
|
300
|
+
};
|
|
301
|
+
const writeLine = (line) => {
|
|
302
|
+
const text = line.replace(/\r?\n$/, "");
|
|
303
|
+
if (isMuonPrepareStatusLine(text)) {
|
|
304
|
+
startStatus(text.trimEnd());
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (activeStatus !== void 0 && shouldKeepMuonPrepareStatusAfterLine(text)) {
|
|
308
|
+
writeRaw(`${terminalLineStart}${terminalClearLine}${line.endsWith("\n") ? line : `${line}\n`}`);
|
|
309
|
+
renderStatus();
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
finishStatus();
|
|
313
|
+
writeRaw(line);
|
|
314
|
+
};
|
|
315
|
+
return {
|
|
316
|
+
write: (chunk) => {
|
|
317
|
+
pending += chunk;
|
|
318
|
+
for (;;) {
|
|
319
|
+
const newlineIndex = pending.indexOf("\n");
|
|
320
|
+
if (newlineIndex < 0) break;
|
|
321
|
+
const line = pending.slice(0, newlineIndex + 1);
|
|
322
|
+
pending = pending.slice(newlineIndex + 1);
|
|
323
|
+
writeLine(line);
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
flush: () => {
|
|
327
|
+
if (pending.length > 0) {
|
|
328
|
+
const line = pending;
|
|
329
|
+
pending = "";
|
|
330
|
+
writeLine(line);
|
|
331
|
+
}
|
|
332
|
+
finishStatus();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
};
|
|
336
|
+
var createMuonPrepareStderrForwarder = () => process.stderr.isTTY === true ? createSpinnerStderrForwarder() : createPlainStderrForwarder();
|
|
337
|
+
var runMuonPrepareCommand = async (options) => {
|
|
338
|
+
const child = (0, node_child_process.spawn)(await resolveMuonBuilderExecutable(options), [...options.args], {
|
|
237
339
|
cwd: options.cwd,
|
|
238
340
|
env: options.environment,
|
|
239
341
|
stdio: [
|
|
@@ -246,22 +348,46 @@ var runMuonPrepare = async (options) => {
|
|
|
246
348
|
let stderr = "";
|
|
247
349
|
child.stdout.setEncoding("utf8");
|
|
248
350
|
child.stderr.setEncoding("utf8");
|
|
351
|
+
const stderrForwarder = options.quiet ? void 0 : createMuonPrepareStderrForwarder();
|
|
249
352
|
child.stdout.on("data", (chunk) => {
|
|
250
353
|
stdout += chunk;
|
|
251
354
|
});
|
|
252
355
|
child.stderr.on("data", (chunk) => {
|
|
253
356
|
stderr += chunk;
|
|
254
|
-
|
|
357
|
+
stderrForwarder?.write(chunk);
|
|
255
358
|
});
|
|
256
|
-
const exitCode = await
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
359
|
+
const exitCode = await (async () => {
|
|
360
|
+
try {
|
|
361
|
+
return await new Promise((resolvePromise, reject) => {
|
|
362
|
+
child.on("error", reject);
|
|
363
|
+
child.on("close", (code) => {
|
|
364
|
+
resolvePromise(code ?? 1);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
} finally {
|
|
368
|
+
stderrForwarder?.flush();
|
|
369
|
+
}
|
|
370
|
+
})();
|
|
371
|
+
if (exitCode !== 0) throw new Error(`muon-builder failed with exit code ${exitCode}.\n${stderr.trim()}`);
|
|
372
|
+
return stdout;
|
|
373
|
+
};
|
|
374
|
+
/**
|
|
375
|
+
* Invokes the native muon-builder executable and returns the prepared runtime.
|
|
376
|
+
*
|
|
377
|
+
* @param options Native prepare invocation options.
|
|
378
|
+
* @returns Prepared runtime location.
|
|
379
|
+
*/
|
|
380
|
+
var runMuonPrepare = async (options) => {
|
|
381
|
+
const args = createMuonPrepareArguments(options);
|
|
382
|
+
const stdout = await runMuonPrepareCommand({
|
|
383
|
+
prepareExecutablePath: options.prepareExecutablePath,
|
|
384
|
+
environment: options.environment,
|
|
385
|
+
cwd: options.cwd,
|
|
386
|
+
quiet: options.quiet,
|
|
387
|
+
args
|
|
261
388
|
});
|
|
262
|
-
if (exitCode !== 0) throw new Error(`muon-prepare failed with exit code ${exitCode}.\n${stderr.trim()}`);
|
|
263
389
|
const result = JSON.parse(stdout);
|
|
264
|
-
if (result.stagePath !== void 0 && typeof result.stagePath !== "string" || typeof result.muonPath !== "string" || typeof result.cefPath !== "string" || typeof result.cacheHit !== "boolean") throw new Error(`muon-
|
|
390
|
+
if (result.stagePath !== void 0 && typeof result.stagePath !== "string" || typeof result.muonPath !== "string" || typeof result.cefPath !== "string" || typeof result.cacheHit !== "boolean") throw new Error(`muon-builder returned invalid JSON: ${stdout}`);
|
|
265
391
|
return {
|
|
266
392
|
...result.stagePath === void 0 ? {} : { stagePath: result.stagePath },
|
|
267
393
|
muonPath: result.muonPath,
|
|
@@ -269,11 +395,34 @@ var runMuonPrepare = async (options) => {
|
|
|
269
395
|
cacheHit: result.cacheHit
|
|
270
396
|
};
|
|
271
397
|
};
|
|
398
|
+
/**
|
|
399
|
+
* Invokes the native muon-builder executable to write Windows PE resources.
|
|
400
|
+
*
|
|
401
|
+
* @param options Resource update invocation options.
|
|
402
|
+
*/
|
|
403
|
+
var runMuonPrepareResourceUpdate = async (options) => {
|
|
404
|
+
await runMuonPrepareCommand({
|
|
405
|
+
prepareExecutablePath: options.prepareExecutablePath,
|
|
406
|
+
environment: options.environment,
|
|
407
|
+
cwd: options.cwd,
|
|
408
|
+
quiet: options.quiet,
|
|
409
|
+
args: [
|
|
410
|
+
"resource",
|
|
411
|
+
"--input",
|
|
412
|
+
options.inputPath,
|
|
413
|
+
"--updates-json",
|
|
414
|
+
options.updatesJsonPath,
|
|
415
|
+
"--output",
|
|
416
|
+
options.outputPath,
|
|
417
|
+
...options.quiet ? ["--quiet"] : []
|
|
418
|
+
]
|
|
419
|
+
});
|
|
420
|
+
};
|
|
272
421
|
//#endregion
|
|
273
422
|
//#region src/gitignore.ts
|
|
274
423
|
var muonGitignoreEntries = [
|
|
275
424
|
".muon/",
|
|
276
|
-
"dist-muon
|
|
425
|
+
"dist-muon/",
|
|
277
426
|
"artifacts/"
|
|
278
427
|
];
|
|
279
428
|
var muonGitignoreEntryAliases = {
|
|
@@ -283,11 +432,13 @@ var muonGitignoreEntryAliases = {
|
|
|
283
432
|
".muon",
|
|
284
433
|
"/.muon"
|
|
285
434
|
],
|
|
286
|
-
"dist-muon
|
|
287
|
-
"dist-muon
|
|
288
|
-
"/dist-muon
|
|
289
|
-
"dist-muon
|
|
290
|
-
"/dist-muon
|
|
435
|
+
"dist-muon/": [
|
|
436
|
+
"dist-muon/",
|
|
437
|
+
"/dist-muon/",
|
|
438
|
+
"dist-muon",
|
|
439
|
+
"/dist-muon",
|
|
440
|
+
"dist-muon/*",
|
|
441
|
+
"/dist-muon/*"
|
|
291
442
|
],
|
|
292
443
|
"artifacts/": [
|
|
293
444
|
"artifacts/",
|
|
@@ -1602,8 +1753,10 @@ var encodeTaggedBytes = (tag, bytes) => Buffer.concat([
|
|
|
1602
1753
|
encodeVarUint(BigInt(bytes.length)),
|
|
1603
1754
|
Buffer.from(bytes)
|
|
1604
1755
|
]);
|
|
1605
|
-
var isJsonObject$
|
|
1756
|
+
var isJsonObject$4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1606
1757
|
var isPath = (path, first, second) => path.length === 2 && path[0] === first && path[1] === second;
|
|
1758
|
+
var isPluginSignaturePath = (path) => path.length === 3 && path[0] === "plugin" && path[1] === "plugins" && path[2] === "signature";
|
|
1759
|
+
var isPluginSaltPath = (path) => path.length === 3 && path[0] === "plugin" && path[1] === "plugins" && path[2] === "salt";
|
|
1607
1760
|
var isHexString = (value) => value.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(value);
|
|
1608
1761
|
var decodeHexString = (value) => {
|
|
1609
1762
|
const bytes = Buffer.alloc(value.length / 2);
|
|
@@ -1613,6 +1766,8 @@ var decodeHexString = (value) => {
|
|
|
1613
1766
|
var encodeKnownBinaryString = (path, value) => {
|
|
1614
1767
|
if (isPath(path, "asset", "signature")) return value.length === 40 && isHexString(value) ? decodeHexString(value) : void 0;
|
|
1615
1768
|
if (isPath(path, "asset", "salt")) return isHexString(value) ? decodeHexString(value) : void 0;
|
|
1769
|
+
if (isPluginSignaturePath(path)) return value.length === 40 && isHexString(value) ? decodeHexString(value) : void 0;
|
|
1770
|
+
if (isPluginSaltPath(path)) return isHexString(value) ? decodeHexString(value) : void 0;
|
|
1616
1771
|
if (isPath(path, "browser", "backgroundColor")) {
|
|
1617
1772
|
const hex = value.startsWith("#") ? value.slice(1) : value;
|
|
1618
1773
|
return hex.length === 6 && isHexString(hex) ? decodeHexString(hex) : void 0;
|
|
@@ -1635,7 +1790,7 @@ var encodeTlvValue = (value, path) => {
|
|
|
1635
1790
|
encodeVarUint(BigInt(value.length)),
|
|
1636
1791
|
...value.map((entry) => encodeTlvValue(entry, path))
|
|
1637
1792
|
]);
|
|
1638
|
-
if (isJsonObject$
|
|
1793
|
+
if (isJsonObject$4(value)) {
|
|
1639
1794
|
const entries = Object.entries(value);
|
|
1640
1795
|
return Buffer.concat([
|
|
1641
1796
|
Buffer.from([tlvObjectTag]),
|
|
@@ -1660,8 +1815,8 @@ var encodeMuonConfigTlv = (config) => encodeTlvValue(config, []);
|
|
|
1660
1815
|
*/
|
|
1661
1816
|
var createMuonEmbeddedConfigSlot = (payload = void 0) => {
|
|
1662
1817
|
if (payload !== void 0 && payload.length > muonEmbeddedConfigPayloadCapacity) throw new Error(`Encoded muon config exceeds the embedded slot capacity: ${payload.length} > ${muonEmbeddedConfigPayloadCapacity}`);
|
|
1663
|
-
|
|
1664
|
-
|
|
1818
|
+
if (payload === void 0) return createEmptySlot();
|
|
1819
|
+
const slot = (0, node_crypto.randomBytes)(muonEmbeddedConfigSlotSize);
|
|
1665
1820
|
Buffer.from(payload).copy(slot, 0);
|
|
1666
1821
|
return slot;
|
|
1667
1822
|
};
|
|
@@ -1673,9 +1828,12 @@ var createMuonEmbeddedConfigSlot = (payload = void 0) => {
|
|
|
1673
1828
|
*/
|
|
1674
1829
|
var createMuonBootstrapEmbeddedConfigSlot = (payload = void 0) => {
|
|
1675
1830
|
if (payload !== void 0 && payload.length > muonBootstrapEmbeddedConfigPayloadCapacity) throw new Error(`Encoded muon config exceeds the embedded bootstrap slot capacity: ${payload.length} > ${muonBootstrapEmbeddedConfigPayloadCapacity}`);
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1831
|
+
if (payload === void 0) {
|
|
1832
|
+
const slot = Buffer.alloc(muonBootstrapEmbeddedConfigSlotSize, 0);
|
|
1833
|
+
muonBootstrapEmbeddedConfigEmptySlotMarker.copy(slot, 0);
|
|
1834
|
+
return slot;
|
|
1835
|
+
}
|
|
1836
|
+
const slot = (0, node_crypto.randomBytes)(muonBootstrapEmbeddedConfigSlotSize);
|
|
1679
1837
|
Buffer.from(payload).copy(slot, 0);
|
|
1680
1838
|
return slot;
|
|
1681
1839
|
};
|
|
@@ -1749,7 +1907,7 @@ var findMuonBootstrapEmbeddedConfigSlot = (content) => {
|
|
|
1749
1907
|
if (candidate === void 0) throw new Error("Embedded muon-bootstrap config slot was not found.");
|
|
1750
1908
|
return candidate;
|
|
1751
1909
|
};
|
|
1752
|
-
var fileExists$
|
|
1910
|
+
var fileExists$5 = async (path) => {
|
|
1753
1911
|
try {
|
|
1754
1912
|
return (await (0, node_fs_promises.stat)(path)).isFile();
|
|
1755
1913
|
} catch {
|
|
@@ -1765,10 +1923,10 @@ var resolveMuonConfigInputPath = async (configPath) => {
|
|
|
1765
1923
|
"muon.json"
|
|
1766
1924
|
]) {
|
|
1767
1925
|
const candidate = (0, node_path.join)(directory, fileName);
|
|
1768
|
-
if (await fileExists$
|
|
1926
|
+
if (await fileExists$5(candidate)) return candidate;
|
|
1769
1927
|
}
|
|
1770
1928
|
}
|
|
1771
|
-
if (!await fileExists$
|
|
1929
|
+
if (!await fileExists$5(configPath)) throw new Error(`muon config does not exist: ${configPath}`);
|
|
1772
1930
|
return configPath;
|
|
1773
1931
|
};
|
|
1774
1932
|
var readMuonConfigInput = async (configPath) => {
|
|
@@ -1864,6 +2022,831 @@ var embedMuonConfigInRuntime = async ({ runtimePath, configPath, outputRuntimePa
|
|
|
1864
2022
|
});
|
|
1865
2023
|
};
|
|
1866
2024
|
//#endregion
|
|
2025
|
+
//#region src/windows-icon.ts
|
|
2026
|
+
var sharp$1 = __resolveDefaultExport$1(sharp, true);
|
|
2027
|
+
globalThis.__screwUpIsInCJS_27e672935538 = true;
|
|
2028
|
+
function __resolveDefaultExport$1(module, isESM) {
|
|
2029
|
+
const __isInCJS = typeof globalThis !== "undefined" && globalThis.__screwUpIsInCJS_27e672935538 === true;
|
|
2030
|
+
const maybe = module;
|
|
2031
|
+
const hasDefault = !!(maybe && typeof maybe === "object" && "default" in maybe);
|
|
2032
|
+
const unwrapNamespaceDefault = (value) => {
|
|
2033
|
+
if (!value || typeof value !== "object") return value;
|
|
2034
|
+
const inner = value;
|
|
2035
|
+
if ((inner.__esModule === true || typeof Symbol !== "undefined" && inner[Symbol.toStringTag] === "Module") && "default" in inner) return inner.default;
|
|
2036
|
+
return value;
|
|
2037
|
+
};
|
|
2038
|
+
const resolvedDefault = hasDefault ? unwrapNamespaceDefault(maybe.default) : void 0;
|
|
2039
|
+
if (__isInCJS) return hasDefault ? resolvedDefault ?? module : module;
|
|
2040
|
+
if (isESM) {
|
|
2041
|
+
if (hasDefault) return resolvedDefault;
|
|
2042
|
+
throw new Error("Default export not found.");
|
|
2043
|
+
}
|
|
2044
|
+
return hasDefault ? resolvedDefault ?? module : module;
|
|
2045
|
+
}
|
|
2046
|
+
var normalizedIconSize = 256;
|
|
2047
|
+
var windowsIconDibSizes = [
|
|
2048
|
+
16,
|
|
2049
|
+
24,
|
|
2050
|
+
32,
|
|
2051
|
+
48,
|
|
2052
|
+
64,
|
|
2053
|
+
128
|
|
2054
|
+
];
|
|
2055
|
+
var pngSignature = Buffer.from([
|
|
2056
|
+
137,
|
|
2057
|
+
80,
|
|
2058
|
+
78,
|
|
2059
|
+
71,
|
|
2060
|
+
13,
|
|
2061
|
+
10,
|
|
2062
|
+
26,
|
|
2063
|
+
10
|
|
2064
|
+
]);
|
|
2065
|
+
/**
|
|
2066
|
+
* Creates a normalized square PNG icon image.
|
|
2067
|
+
*
|
|
2068
|
+
* @param pngData Source PNG bytes.
|
|
2069
|
+
* @param source Diagnostic source label used in errors.
|
|
2070
|
+
* @param label User-facing diagnostic label.
|
|
2071
|
+
* @returns PNG bytes normalized to the Muon base icon size.
|
|
2072
|
+
* @remarks Non-square images are fitted into transparent padding without
|
|
2073
|
+
* stretching. The normalized PNG is the source for all platform-specific icon
|
|
2074
|
+
* derivatives.
|
|
2075
|
+
*/
|
|
2076
|
+
var createNormalizedIconPngData = async (pngData, source, label) => {
|
|
2077
|
+
await assertPngData(pngData, source, label);
|
|
2078
|
+
try {
|
|
2079
|
+
return await sharp$1(pngData).resize(normalizedIconSize, normalizedIconSize, {
|
|
2080
|
+
fit: "contain",
|
|
2081
|
+
background: {
|
|
2082
|
+
r: 0,
|
|
2083
|
+
g: 0,
|
|
2084
|
+
b: 0,
|
|
2085
|
+
alpha: 0
|
|
2086
|
+
}
|
|
2087
|
+
}).ensureAlpha().png().toBuffer();
|
|
2088
|
+
} catch {
|
|
2089
|
+
throw new Error(`${label} must be a valid PNG: ${source}`);
|
|
2090
|
+
}
|
|
2091
|
+
};
|
|
2092
|
+
/**
|
|
2093
|
+
* Creates a normalized square PNG icon image for Windows resources.
|
|
2094
|
+
*
|
|
2095
|
+
* @param pngData Source PNG bytes.
|
|
2096
|
+
* @param source Diagnostic source label used in errors.
|
|
2097
|
+
* @returns PNG bytes normalized to the Muon base icon size.
|
|
2098
|
+
*/
|
|
2099
|
+
var createNormalizedMuonIconPngData = async (pngData, source) => await createNormalizedIconPngData(pngData, source, "Windows resource icon");
|
|
2100
|
+
/**
|
|
2101
|
+
* Creates a Windows ICO file from PNG bytes.
|
|
2102
|
+
*
|
|
2103
|
+
* @param pngData Source PNG bytes.
|
|
2104
|
+
* @param source Diagnostic source label used in errors.
|
|
2105
|
+
* @returns ICO file bytes containing 16, 24, 32, 48, 64, 128, and 256 pixel images.
|
|
2106
|
+
* @remarks The 256px entry is PNG-compressed. Smaller entries are 32-bit DIB
|
|
2107
|
+
* images, matching the common Windows ICO layout recommended by Microsoft.
|
|
2108
|
+
*/
|
|
2109
|
+
var createWindowsIconBufferFromPngData = async (pngData, source) => {
|
|
2110
|
+
const normalizedPng = await createNormalizedMuonIconPngData(pngData, source);
|
|
2111
|
+
const images = [];
|
|
2112
|
+
for (const size of windowsIconDibSizes) {
|
|
2113
|
+
const rawImage = await resizePngToRawRgba(normalizedPng, size, source);
|
|
2114
|
+
images.push({
|
|
2115
|
+
data: createDibIconImage(rawImage),
|
|
2116
|
+
size,
|
|
2117
|
+
bitCount: 32
|
|
2118
|
+
});
|
|
2119
|
+
}
|
|
2120
|
+
images.push({
|
|
2121
|
+
data: normalizedPng,
|
|
2122
|
+
size: normalizedIconSize,
|
|
2123
|
+
bitCount: 32
|
|
2124
|
+
});
|
|
2125
|
+
return createIco(images);
|
|
2126
|
+
};
|
|
2127
|
+
/**
|
|
2128
|
+
* Creates a Windows ICO file from a PNG file.
|
|
2129
|
+
*
|
|
2130
|
+
* @param sourcePath Source PNG file path.
|
|
2131
|
+
* @param outputPath Output ICO file path.
|
|
2132
|
+
* @returns Promise resolved when the ICO file has been written.
|
|
2133
|
+
*/
|
|
2134
|
+
var createWindowsIconFromPngFile = async (sourcePath, outputPath) => {
|
|
2135
|
+
const icon = await createWindowsIconBufferFromPngData(await (0, node_fs_promises.readFile)(sourcePath), sourcePath);
|
|
2136
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(outputPath), { recursive: true });
|
|
2137
|
+
await (0, node_fs_promises.writeFile)(outputPath, icon);
|
|
2138
|
+
};
|
|
2139
|
+
var assertPngData = async (data, source, label) => {
|
|
2140
|
+
if (data.length === 0) throw new Error(`${label} PNG must not be empty: ${source}`);
|
|
2141
|
+
if (!data.subarray(0, pngSignature.length).equals(pngSignature)) throw new Error(`${label} must be a valid PNG: ${source}`);
|
|
2142
|
+
try {
|
|
2143
|
+
if ((await sharp$1(data).metadata()).format !== "png") throw new Error();
|
|
2144
|
+
} catch {
|
|
2145
|
+
throw new Error(`${label} must be a valid PNG: ${source}`);
|
|
2146
|
+
}
|
|
2147
|
+
};
|
|
2148
|
+
var resizePngToRawRgba = async (pngData, size, source) => {
|
|
2149
|
+
try {
|
|
2150
|
+
const { data, info } = await sharp$1(pngData).resize(size, size, {
|
|
2151
|
+
fit: "fill",
|
|
2152
|
+
kernel: "lanczos3"
|
|
2153
|
+
}).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
2154
|
+
if (info.width !== size || info.height !== size || info.channels !== 4) throw new Error();
|
|
2155
|
+
return {
|
|
2156
|
+
data,
|
|
2157
|
+
width: info.width,
|
|
2158
|
+
height: info.height
|
|
2159
|
+
};
|
|
2160
|
+
} catch {
|
|
2161
|
+
throw new Error(`Failed to resize Windows resource icon PNG: ${source}`);
|
|
2162
|
+
}
|
|
2163
|
+
};
|
|
2164
|
+
var createDibIconImage = (image) => {
|
|
2165
|
+
const pixelBytes = image.width * image.height * 4;
|
|
2166
|
+
const maskBytes = Math.ceil(image.width / 32) * 4 * image.height;
|
|
2167
|
+
const output = Buffer.alloc(40 + pixelBytes + maskBytes);
|
|
2168
|
+
output.writeUInt32LE(40, 0);
|
|
2169
|
+
output.writeInt32LE(image.width, 4);
|
|
2170
|
+
output.writeInt32LE(image.height * 2, 8);
|
|
2171
|
+
output.writeUInt16LE(1, 12);
|
|
2172
|
+
output.writeUInt16LE(32, 14);
|
|
2173
|
+
output.writeUInt32LE(0, 16);
|
|
2174
|
+
output.writeUInt32LE(pixelBytes + maskBytes, 20);
|
|
2175
|
+
output.writeInt32LE(0, 24);
|
|
2176
|
+
output.writeInt32LE(0, 28);
|
|
2177
|
+
output.writeUInt32LE(0, 32);
|
|
2178
|
+
output.writeUInt32LE(0, 36);
|
|
2179
|
+
for (let y = 0; y < image.height; y += 1) {
|
|
2180
|
+
const sourceY = image.height - 1 - y;
|
|
2181
|
+
for (let x = 0; x < image.width; x += 1) {
|
|
2182
|
+
const sourceOffset = (sourceY * image.width + x) * 4;
|
|
2183
|
+
const outputOffset = 40 + (y * image.width + x) * 4;
|
|
2184
|
+
output[outputOffset] = image.data[sourceOffset + 2];
|
|
2185
|
+
output[outputOffset + 1] = image.data[sourceOffset + 1];
|
|
2186
|
+
output[outputOffset + 2] = image.data[sourceOffset];
|
|
2187
|
+
output[outputOffset + 3] = image.data[sourceOffset + 3];
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
return output;
|
|
2191
|
+
};
|
|
2192
|
+
var createIco = (images) => {
|
|
2193
|
+
const directorySize = 6 + images.length * 16;
|
|
2194
|
+
let imageOffset = directorySize;
|
|
2195
|
+
const header = Buffer.alloc(directorySize);
|
|
2196
|
+
header.writeUInt16LE(0, 0);
|
|
2197
|
+
header.writeUInt16LE(1, 2);
|
|
2198
|
+
header.writeUInt16LE(images.length, 4);
|
|
2199
|
+
const imageData = [];
|
|
2200
|
+
images.forEach((image, index) => {
|
|
2201
|
+
const entryOffset = 6 + index * 16;
|
|
2202
|
+
header[entryOffset] = image.size === 256 ? 0 : image.size;
|
|
2203
|
+
header[entryOffset + 1] = image.size === 256 ? 0 : image.size;
|
|
2204
|
+
header[entryOffset + 2] = 0;
|
|
2205
|
+
header[entryOffset + 3] = 0;
|
|
2206
|
+
header.writeUInt16LE(1, entryOffset + 4);
|
|
2207
|
+
header.writeUInt16LE(image.bitCount, entryOffset + 6);
|
|
2208
|
+
header.writeUInt32LE(image.data.length, entryOffset + 8);
|
|
2209
|
+
header.writeUInt32LE(imageOffset, entryOffset + 12);
|
|
2210
|
+
imageOffset += image.data.length;
|
|
2211
|
+
imageData.push(image.data);
|
|
2212
|
+
});
|
|
2213
|
+
return Buffer.concat([header, ...imageData]);
|
|
2214
|
+
};
|
|
2215
|
+
//#endregion
|
|
2216
|
+
//#region src/app-icon.ts
|
|
2217
|
+
/**
|
|
2218
|
+
* ZIP entry used for the generated static application icon asset.
|
|
2219
|
+
*/
|
|
2220
|
+
var appIconAssetEntryName = "main/.muon/app-icon.png";
|
|
2221
|
+
/**
|
|
2222
|
+
* Runtime asset URL injected as the generated initial title bar icon.
|
|
2223
|
+
*/
|
|
2224
|
+
var appIconAssetUrl = "asset://main/.muon/app-icon.png";
|
|
2225
|
+
/**
|
|
2226
|
+
* Creates a static application icon source from API or CLI options.
|
|
2227
|
+
*/
|
|
2228
|
+
var createAppIconOptionsSource = (iconPath, directory, label = "iconPath") => {
|
|
2229
|
+
if (iconPath === void 0) return;
|
|
2230
|
+
if (typeof iconPath !== "string") throw new Error(`${label} must be a string when present.`);
|
|
2231
|
+
if (iconPath.trim() === "") return;
|
|
2232
|
+
return {
|
|
2233
|
+
iconPath: iconPath.trim(),
|
|
2234
|
+
directory
|
|
2235
|
+
};
|
|
2236
|
+
};
|
|
2237
|
+
/**
|
|
2238
|
+
* Reads the top-level `iconPath` from a Muon config object.
|
|
2239
|
+
*/
|
|
2240
|
+
var readConfigAppIconSource = (config, directory, label) => {
|
|
2241
|
+
const value = config.iconPath;
|
|
2242
|
+
if (value === void 0) return;
|
|
2243
|
+
if (typeof value !== "string") throw new Error(`${label} iconPath must be a string when present.`);
|
|
2244
|
+
return createAppIconOptionsSource(value, directory);
|
|
2245
|
+
};
|
|
2246
|
+
/**
|
|
2247
|
+
* Reads the top-level `iconPath` from project metadata.
|
|
2248
|
+
*/
|
|
2249
|
+
var readProjectAppIconSource = (projectJson, directory) => {
|
|
2250
|
+
const value = projectJson.iconPath;
|
|
2251
|
+
return typeof value === "string" ? createAppIconOptionsSource(value, directory) : void 0;
|
|
2252
|
+
};
|
|
2253
|
+
/**
|
|
2254
|
+
* Resolves and validates the first available static application icon source.
|
|
2255
|
+
*/
|
|
2256
|
+
var resolveMuonAppIconPath = async (sources) => {
|
|
2257
|
+
for (const source of sources) {
|
|
2258
|
+
const iconPath = resolveResourcePath$2(source.directory, source.iconPath);
|
|
2259
|
+
await assertMuonAppIconPath(iconPath);
|
|
2260
|
+
return iconPath;
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
var assertMuonAppIconPath = async (iconPath) => {
|
|
2264
|
+
if ((0, node_path.extname)(iconPath).toLowerCase() !== ".png") throw new Error(`Muon app icon must be a .png file: ${iconPath}`);
|
|
2265
|
+
if (!await fileExists$4(iconPath)) throw new Error(`Muon app icon does not exist: ${iconPath}`);
|
|
2266
|
+
await createNormalizedIconPngData(await (0, node_fs_promises.readFile)(iconPath), iconPath, "Muon app icon");
|
|
2267
|
+
};
|
|
2268
|
+
var resolveResourcePath$2 = (directory, value) => (0, node_path.isAbsolute)(value) ? value : (0, node_path.resolve)(directory, value);
|
|
2269
|
+
var fileExists$4 = async (path) => {
|
|
2270
|
+
try {
|
|
2271
|
+
await (0, node_fs_promises.access)(path, node_fs.constants.F_OK);
|
|
2272
|
+
return true;
|
|
2273
|
+
} catch {
|
|
2274
|
+
return false;
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
//#endregion
|
|
2278
|
+
//#region src/windows-resource.ts
|
|
2279
|
+
var defaultConfigFileNames$1 = [
|
|
2280
|
+
"muon.json5",
|
|
2281
|
+
"muon.jsonc",
|
|
2282
|
+
"muon.json"
|
|
2283
|
+
];
|
|
2284
|
+
var defaultLanguage = 1033;
|
|
2285
|
+
var defaultCodePage = 1200;
|
|
2286
|
+
var moduleDirectory$3 = typeof __dirname === "string" ? __dirname : (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
|
|
2287
|
+
/**
|
|
2288
|
+
* Reads the Muon config file using the same default file names as muon build.
|
|
2289
|
+
*/
|
|
2290
|
+
var readMuonConfigForWindowsResource = async (root, configPath) => {
|
|
2291
|
+
const resolvedConfigPath = await resolveConfigPath$1(root, configPath);
|
|
2292
|
+
if (resolvedConfigPath === void 0) return {
|
|
2293
|
+
config: {},
|
|
2294
|
+
directory: root
|
|
2295
|
+
};
|
|
2296
|
+
return {
|
|
2297
|
+
config: await readJsonObjectFile$2(resolvedConfigPath, "Muon config file"),
|
|
2298
|
+
directory: (0, node_path.dirname)(resolvedConfigPath)
|
|
2299
|
+
};
|
|
2300
|
+
};
|
|
2301
|
+
/**
|
|
2302
|
+
* Merges Windows resource options while preserving field-level fallback.
|
|
2303
|
+
*/
|
|
2304
|
+
var mergeMuonWindowsResourceOptions = (primary, fallback) => {
|
|
2305
|
+
if (primary === void 0) return fallback;
|
|
2306
|
+
if (fallback === void 0) return primary;
|
|
2307
|
+
const merged = { ...fallback };
|
|
2308
|
+
if (primary.iconPath !== void 0) merged.iconPath = primary.iconPath;
|
|
2309
|
+
if (primary.productName !== void 0) merged.productName = primary.productName;
|
|
2310
|
+
if (primary.fileDescription !== void 0) merged.fileDescription = primary.fileDescription;
|
|
2311
|
+
if (primary.companyName !== void 0) merged.companyName = primary.companyName;
|
|
2312
|
+
if (primary.version !== void 0) merged.version = primary.version;
|
|
2313
|
+
if (primary.copyright !== void 0) merged.copyright = primary.copyright;
|
|
2314
|
+
if (primary.language !== void 0) merged.language = primary.language;
|
|
2315
|
+
if (primary.codePage !== void 0) merged.codePage = primary.codePage;
|
|
2316
|
+
return merged;
|
|
2317
|
+
};
|
|
2318
|
+
/**
|
|
2319
|
+
* Resolves Windows resource metadata from options, config files, and package metadata.
|
|
2320
|
+
*/
|
|
2321
|
+
var resolveMuonWindowsResource = async (input) => {
|
|
2322
|
+
const projectJson = await readProjectJson$1(input.root);
|
|
2323
|
+
const windowsSources = [
|
|
2324
|
+
createOptionsSource$1(input.options, input.root, "windowsResource"),
|
|
2325
|
+
readConfigWindowsResourceSource(input.muonConfig, input.muonConfigDirectory, "muon.json"),
|
|
2326
|
+
readConfigWindowsResourceSource(projectJson, input.root, "project.json")
|
|
2327
|
+
].filter((source) => source !== void 0);
|
|
2328
|
+
const sources = [
|
|
2329
|
+
...windowsSources,
|
|
2330
|
+
createProjectSource(projectJson, input.root),
|
|
2331
|
+
createPackageSource(input.packageJson, input.root)
|
|
2332
|
+
].filter((source) => source !== void 0);
|
|
2333
|
+
const appIconSources = [
|
|
2334
|
+
createAppIconOptionsSource(input.appIconPath, input.root),
|
|
2335
|
+
readConfigAppIconSource(input.muonConfig, input.muonConfigDirectory, "muon.json"),
|
|
2336
|
+
readProjectAppIconSource(projectJson, input.root)
|
|
2337
|
+
].filter((source) => source !== void 0);
|
|
2338
|
+
const productName = resolveStringField$1(sources, "productName", input.defaults.productName);
|
|
2339
|
+
const fileDescription = resolveStringField$1(sources, "fileDescription", input.defaults.fileDescription);
|
|
2340
|
+
const companyName = resolveStringField$1(sources, "companyName", input.defaults.companyName);
|
|
2341
|
+
const version = resolveStringField$1(sources, "version", input.defaults.version);
|
|
2342
|
+
const copyright = resolveOptionalStringField(sources, "copyright", input.defaults.copyright);
|
|
2343
|
+
const language = resolveNumericField(sources, "language", defaultLanguage);
|
|
2344
|
+
const codePage = resolveNumericField(sources, "codePage", defaultCodePage);
|
|
2345
|
+
const fixedVersion = normalizeWindowsVersion(version);
|
|
2346
|
+
return {
|
|
2347
|
+
iconPath: await resolveWindowsIconPath(windowsSources, appIconSources, await resolveDefaultWindowsIcon(input.packageDirectory)),
|
|
2348
|
+
productName,
|
|
2349
|
+
fileDescription,
|
|
2350
|
+
companyName,
|
|
2351
|
+
version,
|
|
2352
|
+
fixedVersion,
|
|
2353
|
+
copyright,
|
|
2354
|
+
language,
|
|
2355
|
+
codePage
|
|
2356
|
+
};
|
|
2357
|
+
};
|
|
2358
|
+
/**
|
|
2359
|
+
* Removes build-only Windows resource settings from runtime config.
|
|
2360
|
+
*/
|
|
2361
|
+
var stripBuildOnlyWindowsResourceConfig = (sourceConfig) => {
|
|
2362
|
+
const sourceWindows = sourceConfig.windows;
|
|
2363
|
+
if (!isJsonObject$3(sourceWindows)) return sourceConfig;
|
|
2364
|
+
const windowsConfig = {};
|
|
2365
|
+
for (const [key, value] of Object.entries(sourceWindows)) if (key !== "resource") windowsConfig[key] = value;
|
|
2366
|
+
const output = {};
|
|
2367
|
+
for (const [key, value] of Object.entries(sourceConfig)) if (key !== "windows") output[key] = value;
|
|
2368
|
+
if (Object.keys(windowsConfig).length > 0) output.windows = windowsConfig;
|
|
2369
|
+
return output;
|
|
2370
|
+
};
|
|
2371
|
+
/**
|
|
2372
|
+
* Returns true when the file has a Windows PE header.
|
|
2373
|
+
*/
|
|
2374
|
+
var isWindowsPeExecutable = async (path) => {
|
|
2375
|
+
const content = await (0, node_fs_promises.readFile)(path);
|
|
2376
|
+
if (content.length < 64 || content.toString("ascii", 0, 2) !== "MZ") return false;
|
|
2377
|
+
const peOffset = content.readUInt32LE(60);
|
|
2378
|
+
return peOffset + 4 <= content.length && content.toString("ascii", peOffset, peOffset + 4) === "PE\0\0";
|
|
2379
|
+
};
|
|
2380
|
+
/**
|
|
2381
|
+
* Applies resolved resource metadata to a Windows PE executable in place.
|
|
2382
|
+
*/
|
|
2383
|
+
var updateWindowsPeResources = async (input) => {
|
|
2384
|
+
return await updateWindowsPeResourceFile(input, createEngraverUpdate);
|
|
2385
|
+
};
|
|
2386
|
+
/**
|
|
2387
|
+
* Applies only resolved icon metadata to a Windows PE executable in place.
|
|
2388
|
+
*/
|
|
2389
|
+
var updateWindowsPeIconResource = async (input) => {
|
|
2390
|
+
return await updateWindowsPeResourceFile(input, createEngraverIconUpdate);
|
|
2391
|
+
};
|
|
2392
|
+
var updateWindowsPeResourceFile = async (input, createUpdate) => {
|
|
2393
|
+
if (!await isWindowsPeExecutable(input.executablePath)) return false;
|
|
2394
|
+
const mode = (await (0, node_fs_promises.stat)(input.executablePath)).mode & 511;
|
|
2395
|
+
const tempDirectory = await (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "muon-windows-resource-"));
|
|
2396
|
+
const updatesJsonPath = (0, node_path.join)(tempDirectory, "updates.json");
|
|
2397
|
+
const outputPath = (0, node_path.join)(tempDirectory, "output.exe");
|
|
2398
|
+
const iconPath = (0, node_path.join)(tempDirectory, "icon.ico");
|
|
2399
|
+
try {
|
|
2400
|
+
await createWindowsIconFromPngFile(input.resource.iconPath, iconPath);
|
|
2401
|
+
await (0, node_fs_promises.writeFile)(updatesJsonPath, `${JSON.stringify(createUpdate(input.resource, iconPath), null, 2)}\n`);
|
|
2402
|
+
await runMuonPrepareResourceUpdate({
|
|
2403
|
+
inputPath: input.executablePath,
|
|
2404
|
+
updatesJsonPath,
|
|
2405
|
+
outputPath,
|
|
2406
|
+
quiet: true,
|
|
2407
|
+
prepareExecutablePath: void 0,
|
|
2408
|
+
environment: input.environment,
|
|
2409
|
+
cwd: input.cwd
|
|
2410
|
+
});
|
|
2411
|
+
await (0, node_fs_promises.copyFile)(outputPath, input.executablePath);
|
|
2412
|
+
await (0, node_fs_promises.chmod)(input.executablePath, mode === 0 ? 493 : mode);
|
|
2413
|
+
return true;
|
|
2414
|
+
} finally {
|
|
2415
|
+
await (0, node_fs_promises.rm)(tempDirectory, {
|
|
2416
|
+
recursive: true,
|
|
2417
|
+
force: true
|
|
2418
|
+
});
|
|
2419
|
+
}
|
|
2420
|
+
};
|
|
2421
|
+
var createEngraverUpdate = (resource, iconPath) => {
|
|
2422
|
+
const strings = {
|
|
2423
|
+
CompanyName: resource.companyName,
|
|
2424
|
+
FileDescription: resource.fileDescription,
|
|
2425
|
+
FileVersion: resource.version,
|
|
2426
|
+
ProductName: resource.productName,
|
|
2427
|
+
ProductVersion: resource.version
|
|
2428
|
+
};
|
|
2429
|
+
if (resource.copyright !== void 0) strings.LegalCopyright = resource.copyright;
|
|
2430
|
+
return {
|
|
2431
|
+
version: {
|
|
2432
|
+
language: resource.language,
|
|
2433
|
+
codePage: resource.codePage,
|
|
2434
|
+
fixed: {
|
|
2435
|
+
fileVersion: resource.fixedVersion,
|
|
2436
|
+
productVersion: resource.fixedVersion,
|
|
2437
|
+
fileOS: "windows32",
|
|
2438
|
+
fileType: "app"
|
|
2439
|
+
},
|
|
2440
|
+
strings
|
|
2441
|
+
},
|
|
2442
|
+
icons: createEngraverIcons(resource, iconPath)
|
|
2443
|
+
};
|
|
2444
|
+
};
|
|
2445
|
+
var createEngraverIconUpdate = (resource, iconPath) => ({ icons: createEngraverIcons(resource, iconPath) });
|
|
2446
|
+
var createEngraverIcons = (resource, iconPath) => [{
|
|
2447
|
+
id: 1,
|
|
2448
|
+
language: resource.language,
|
|
2449
|
+
path: iconPath
|
|
2450
|
+
}];
|
|
2451
|
+
var resolveConfigPath$1 = async (root, configPath) => {
|
|
2452
|
+
if (configPath !== void 0) {
|
|
2453
|
+
const resolvedPath = (0, node_path.resolve)(root, configPath);
|
|
2454
|
+
if (await fileExists$3(resolvedPath)) return resolvedPath;
|
|
2455
|
+
throw new Error(`Muon config file does not exist: ${resolvedPath}`);
|
|
2456
|
+
}
|
|
2457
|
+
for (const fileName of defaultConfigFileNames$1) {
|
|
2458
|
+
const candidatePath = (0, node_path.join)(root, fileName);
|
|
2459
|
+
if (await fileExists$3(candidatePath)) return candidatePath;
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2462
|
+
var readProjectJson$1 = async (root) => {
|
|
2463
|
+
const projectJsonPath = (0, node_path.join)(root, "project.json");
|
|
2464
|
+
if (!await fileExists$3(projectJsonPath)) return {};
|
|
2465
|
+
return await readJsonObjectFile$2(projectJsonPath, "project.json");
|
|
2466
|
+
};
|
|
2467
|
+
var readJsonObjectFile$2 = async (filePath, label) => {
|
|
2468
|
+
const parsed = (0, import_dist.parse)(await (0, node_fs_promises.readFile)(filePath, "utf8"));
|
|
2469
|
+
if (!isJsonObject$3(parsed)) throw new Error(`${label} must contain a JSON object: ${filePath}`);
|
|
2470
|
+
return parsed;
|
|
2471
|
+
};
|
|
2472
|
+
var createOptionsSource$1 = (options, directory, label) => {
|
|
2473
|
+
if (options === void 0) return;
|
|
2474
|
+
return {
|
|
2475
|
+
options: validateWindowsResourceOptions(options, label),
|
|
2476
|
+
directory
|
|
2477
|
+
};
|
|
2478
|
+
};
|
|
2479
|
+
var readConfigWindowsResourceSource = (config, directory, label) => {
|
|
2480
|
+
const windows = config.windows;
|
|
2481
|
+
if (windows === void 0) return;
|
|
2482
|
+
if (!isJsonObject$3(windows)) throw new Error(`${label} windows must be an object when present.`);
|
|
2483
|
+
const resource = windows.resource;
|
|
2484
|
+
if (resource === void 0) return;
|
|
2485
|
+
return createOptionsSource$1(validateWindowsResourceOptions(resource, `${label} windows.resource`), directory, `${label} windows.resource`);
|
|
2486
|
+
};
|
|
2487
|
+
var createProjectSource = (projectJson, directory) => {
|
|
2488
|
+
const topLevel = {};
|
|
2489
|
+
copyStringField(projectJson, "productName", topLevel, "productName");
|
|
2490
|
+
copyStringField(projectJson, "name", topLevel, "productName");
|
|
2491
|
+
copyStringField(projectJson, "fileDescription", topLevel, "fileDescription");
|
|
2492
|
+
copyStringField(projectJson, "description", topLevel, "fileDescription");
|
|
2493
|
+
copyStringField(projectJson, "companyName", topLevel, "companyName");
|
|
2494
|
+
copyStringField(projectJson, "version", topLevel, "version");
|
|
2495
|
+
copyStringField(projectJson, "copyright", topLevel, "copyright");
|
|
2496
|
+
const author = stringifyAuthor(projectJson.author);
|
|
2497
|
+
if (author !== void 0 && topLevel.companyName === void 0) topLevel.companyName = author;
|
|
2498
|
+
const options = mergeMuonWindowsResourceOptions(readConfigWindowsResourceSource(projectJson, directory, "project.json")?.options, topLevel);
|
|
2499
|
+
if (options === void 0 || Object.keys(options).length === 0) return;
|
|
2500
|
+
return {
|
|
2501
|
+
options,
|
|
2502
|
+
directory
|
|
2503
|
+
};
|
|
2504
|
+
};
|
|
2505
|
+
var createPackageSource = (packageJson, directory) => {
|
|
2506
|
+
const options = {};
|
|
2507
|
+
copyStringField(packageJson, "name", options, "productName");
|
|
2508
|
+
copyStringField(packageJson, "description", options, "fileDescription");
|
|
2509
|
+
copyStringField(packageJson, "version", options, "version");
|
|
2510
|
+
copyStringField(packageJson, "copyright", options, "copyright");
|
|
2511
|
+
const author = stringifyAuthor(packageJson.author);
|
|
2512
|
+
if (author !== void 0) options.companyName = author;
|
|
2513
|
+
return Object.keys(options).length === 0 ? void 0 : {
|
|
2514
|
+
options,
|
|
2515
|
+
directory
|
|
2516
|
+
};
|
|
2517
|
+
};
|
|
2518
|
+
var copyStringField = (source, sourceKey, target, targetKey) => {
|
|
2519
|
+
const value = source[sourceKey];
|
|
2520
|
+
if (typeof value === "string" && value.trim() !== "") target[targetKey] = value.trim();
|
|
2521
|
+
};
|
|
2522
|
+
var validateWindowsResourceOptions = (value, label) => {
|
|
2523
|
+
if (!isJsonObject$3(value)) throw new Error(`${label} must be an object.`);
|
|
2524
|
+
const output = {};
|
|
2525
|
+
copyOptionalStringResourceField(value, "iconPath", output);
|
|
2526
|
+
copyOptionalStringResourceField(value, "productName", output);
|
|
2527
|
+
copyOptionalStringResourceField(value, "fileDescription", output);
|
|
2528
|
+
copyOptionalStringResourceField(value, "companyName", output);
|
|
2529
|
+
copyOptionalStringResourceField(value, "version", output);
|
|
2530
|
+
copyOptionalStringResourceField(value, "copyright", output);
|
|
2531
|
+
copyOptionalNumberResourceField(value, "language", output, label);
|
|
2532
|
+
copyOptionalNumberResourceField(value, "codePage", output, label);
|
|
2533
|
+
return output;
|
|
2534
|
+
};
|
|
2535
|
+
var copyOptionalStringResourceField = (source, key, target) => {
|
|
2536
|
+
const value = source[key];
|
|
2537
|
+
if (value === void 0) return;
|
|
2538
|
+
if (typeof value !== "string") throw new Error(`${key} must be a string when present.`);
|
|
2539
|
+
if (value.trim() !== "") target[key] = value.trim();
|
|
2540
|
+
};
|
|
2541
|
+
var copyOptionalNumberResourceField = (source, key, target, label) => {
|
|
2542
|
+
const value = source[key];
|
|
2543
|
+
if (value === void 0) return;
|
|
2544
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > 65535) throw new Error(`${label} ${key} must be an integer from 0 to 65535.`);
|
|
2545
|
+
target[key] = value;
|
|
2546
|
+
};
|
|
2547
|
+
var resolveStringField$1 = (sources, field, fallback) => {
|
|
2548
|
+
return resolveOptionalStringField(sources, field, fallback) ?? fallback;
|
|
2549
|
+
};
|
|
2550
|
+
var resolveOptionalStringField = (sources, field, fallback) => {
|
|
2551
|
+
for (const source of sources) {
|
|
2552
|
+
const value = source.options[field];
|
|
2553
|
+
if (value !== void 0 && value.trim() !== "") return value.trim();
|
|
2554
|
+
}
|
|
2555
|
+
return fallback;
|
|
2556
|
+
};
|
|
2557
|
+
var resolveNumericField = (sources, field, fallback) => {
|
|
2558
|
+
for (const source of sources) {
|
|
2559
|
+
const value = source.options[field];
|
|
2560
|
+
if (value !== void 0) return value;
|
|
2561
|
+
}
|
|
2562
|
+
return fallback;
|
|
2563
|
+
};
|
|
2564
|
+
var resolveWindowsIconPath = async (windowsSources, appIconSources, defaultIconPath) => {
|
|
2565
|
+
for (const source of windowsSources) {
|
|
2566
|
+
const value = source.options.iconPath;
|
|
2567
|
+
if (value !== void 0 && value.trim() !== "") {
|
|
2568
|
+
const iconPath = resolveResourcePath$1(source.directory, value);
|
|
2569
|
+
await assertIconPath$1(iconPath);
|
|
2570
|
+
return iconPath;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
const appIconPath = await resolveMuonAppIconPath(appIconSources);
|
|
2574
|
+
if (appIconPath !== void 0) return appIconPath;
|
|
2575
|
+
await assertIconPath$1(defaultIconPath);
|
|
2576
|
+
return defaultIconPath;
|
|
2577
|
+
};
|
|
2578
|
+
var assertIconPath$1 = async (iconPath) => {
|
|
2579
|
+
if ((0, node_path.extname)(iconPath).toLowerCase() !== ".png") throw new Error(`Windows resource icon must be a .png file: ${iconPath}`);
|
|
2580
|
+
if (!await fileExists$3(iconPath)) throw new Error(`Windows resource icon does not exist: ${iconPath}`);
|
|
2581
|
+
await createNormalizedMuonIconPngData(await (0, node_fs_promises.readFile)(iconPath), iconPath);
|
|
2582
|
+
};
|
|
2583
|
+
var resolveDefaultWindowsIcon = async (packageDirectory) => {
|
|
2584
|
+
const sourceIconPath = (0, node_path.join)(moduleDirectory$3, "..", "..", "images", "muon-256.png");
|
|
2585
|
+
const candidates = [
|
|
2586
|
+
(0, node_path.join)((0, node_path.resolve)(packageDirectory), "native", "muon-256.png"),
|
|
2587
|
+
(0, node_path.join)(moduleDirectory$3, "native", "muon-256.png"),
|
|
2588
|
+
(0, node_path.join)(moduleDirectory$3, "..", "dist", "native", "muon-256.png"),
|
|
2589
|
+
sourceIconPath
|
|
2590
|
+
];
|
|
2591
|
+
for (const candidate of candidates) if (await fileExists$3(candidate)) return candidate;
|
|
2592
|
+
return sourceIconPath;
|
|
2593
|
+
};
|
|
2594
|
+
var resolveResourcePath$1 = (directory, path) => {
|
|
2595
|
+
return (0, node_path.isAbsolute)(path) ? path : (0, node_path.resolve)(directory, path);
|
|
2596
|
+
};
|
|
2597
|
+
var normalizeWindowsVersion = (version) => {
|
|
2598
|
+
const normalized = version.trim();
|
|
2599
|
+
const match = /^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?(?:$|[-+])/.exec(normalized);
|
|
2600
|
+
if (match === null) throw new Error(`Windows resource version must start with numeric parts: ${version}`);
|
|
2601
|
+
const values = [
|
|
2602
|
+
match[1],
|
|
2603
|
+
match[2],
|
|
2604
|
+
match[3],
|
|
2605
|
+
match[4]
|
|
2606
|
+
].map((value) => value === void 0 ? 0 : Number.parseInt(value, 10));
|
|
2607
|
+
for (const value of values) if (!Number.isInteger(value) || value < 0 || value > 65535) throw new Error(`Windows resource version part must be from 0 to 65535: ${version}`);
|
|
2608
|
+
return values.join(".");
|
|
2609
|
+
};
|
|
2610
|
+
var stringifyAuthor = (value) => {
|
|
2611
|
+
if (typeof value === "string" && value.trim() !== "") return value.trim();
|
|
2612
|
+
if (!isJsonObject$3(value) || typeof value.name !== "string") return;
|
|
2613
|
+
const name = value.name.trim();
|
|
2614
|
+
if (name === "") return;
|
|
2615
|
+
return value.email === void 0 || typeof value.email !== "string" ? name : `${name} <${value.email}>`;
|
|
2616
|
+
};
|
|
2617
|
+
var fileExists$3 = async (path) => {
|
|
2618
|
+
try {
|
|
2619
|
+
await (0, node_fs_promises.access)(path, node_fs.constants.F_OK);
|
|
2620
|
+
return true;
|
|
2621
|
+
} catch {
|
|
2622
|
+
return false;
|
|
2623
|
+
}
|
|
2624
|
+
};
|
|
2625
|
+
var isJsonObject$3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2626
|
+
//#endregion
|
|
2627
|
+
//#region src/linux-desktop.ts
|
|
2628
|
+
var defaultIconFileName = "muon-desktop-icon.png";
|
|
2629
|
+
var defaultDesktopConfigFileName = "muon-desktop.json";
|
|
2630
|
+
var moduleDirectory$2 = typeof __dirname === "string" ? __dirname : (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
|
|
2631
|
+
/**
|
|
2632
|
+
* Merges Linux desktop options while preserving field-level fallback.
|
|
2633
|
+
*/
|
|
2634
|
+
var mergeMuonLinuxDesktopOptions = (primary, fallback) => {
|
|
2635
|
+
if (primary === void 0) return fallback;
|
|
2636
|
+
if (fallback === void 0) return primary;
|
|
2637
|
+
const merged = { ...fallback };
|
|
2638
|
+
if (primary.desktopId !== void 0) merged.desktopId = primary.desktopId;
|
|
2639
|
+
if (primary.name !== void 0) merged.name = primary.name;
|
|
2640
|
+
if (primary.comment !== void 0) merged.comment = primary.comment;
|
|
2641
|
+
if (primary.iconPath !== void 0) merged.iconPath = primary.iconPath;
|
|
2642
|
+
if (primary.categories !== void 0) merged.categories = primary.categories;
|
|
2643
|
+
if (primary.startupNotify !== void 0) merged.startupNotify = primary.startupNotify;
|
|
2644
|
+
return merged;
|
|
2645
|
+
};
|
|
2646
|
+
/**
|
|
2647
|
+
* Resolves Linux desktop integration metadata from options, config files, and
|
|
2648
|
+
* package metadata.
|
|
2649
|
+
*/
|
|
2650
|
+
var resolveMuonLinuxDesktop = async (input) => {
|
|
2651
|
+
const projectJson = await readProjectJson(input.root);
|
|
2652
|
+
const sources = [createOptionsSource(input.options, input.root, "linuxDesktop"), readConfigLinuxDesktopSource(input.muonConfig, input.muonConfigDirectory, "muon.json")].filter((source) => source !== void 0);
|
|
2653
|
+
const appIconSources = [
|
|
2654
|
+
createAppIconOptionsSource(input.appIconPath, input.root),
|
|
2655
|
+
readConfigAppIconSource(input.muonConfig, input.muonConfigDirectory, "muon.json"),
|
|
2656
|
+
readProjectAppIconSource(projectJson, input.root)
|
|
2657
|
+
].filter((source) => source !== void 0);
|
|
2658
|
+
return {
|
|
2659
|
+
desktopId: sanitizeDesktopId(resolveStringField(sources, "desktopId", input.defaults.desktopId)),
|
|
2660
|
+
name: resolveStringField(sources, "name", input.defaults.name),
|
|
2661
|
+
comment: resolveStringField(sources, "comment", input.defaults.comment),
|
|
2662
|
+
categories: resolveCategories(sources, input.defaults.categories),
|
|
2663
|
+
startupNotify: resolveBooleanField(sources, "startupNotify", input.defaults.startupNotify),
|
|
2664
|
+
iconPath: await resolveLinuxIconPath(sources, appIconSources, await resolveDefaultLinuxDesktopIcon(input.packageDirectory)),
|
|
2665
|
+
iconFileName: defaultIconFileName,
|
|
2666
|
+
configFileName: defaultDesktopConfigFileName
|
|
2667
|
+
};
|
|
2668
|
+
};
|
|
2669
|
+
/**
|
|
2670
|
+
* Removes build-only Linux desktop settings from runtime config.
|
|
2671
|
+
*/
|
|
2672
|
+
var stripBuildOnlyLinuxDesktopConfig = (sourceConfig) => {
|
|
2673
|
+
const sourceLinux = sourceConfig.linux;
|
|
2674
|
+
if (!isJsonObject$2(sourceLinux)) return sourceConfig;
|
|
2675
|
+
const linuxConfig = {};
|
|
2676
|
+
for (const [key, value] of Object.entries(sourceLinux)) if (key !== "desktop") linuxConfig[key] = value;
|
|
2677
|
+
const output = {};
|
|
2678
|
+
for (const [key, value] of Object.entries(sourceConfig)) if (key !== "linux") output[key] = value;
|
|
2679
|
+
if (Object.keys(linuxConfig).length > 0) output.linux = linuxConfig;
|
|
2680
|
+
return output;
|
|
2681
|
+
};
|
|
2682
|
+
/**
|
|
2683
|
+
* Writes normalized Linux desktop sidecar files into a target distribution.
|
|
2684
|
+
*/
|
|
2685
|
+
var writeLinuxDesktopDistributionFiles = async (outputPath, desktop) => {
|
|
2686
|
+
const iconData = await createNormalizedIconPngData(await (0, node_fs_promises.readFile)(desktop.iconPath), desktop.iconPath, "Linux desktop icon");
|
|
2687
|
+
await (0, node_fs_promises.writeFile)((0, node_path.join)(outputPath, desktop.iconFileName), iconData);
|
|
2688
|
+
await (0, node_fs_promises.writeFile)((0, node_path.join)(outputPath, desktop.configFileName), `${JSON.stringify({
|
|
2689
|
+
desktopId: desktop.desktopId,
|
|
2690
|
+
name: desktop.name,
|
|
2691
|
+
comment: desktop.comment,
|
|
2692
|
+
categories: desktop.categories,
|
|
2693
|
+
startupNotify: desktop.startupNotify,
|
|
2694
|
+
iconFileName: desktop.iconFileName
|
|
2695
|
+
}, void 0, 2)}\n`);
|
|
2696
|
+
};
|
|
2697
|
+
/**
|
|
2698
|
+
* Creates a Desktop Entry file.
|
|
2699
|
+
*/
|
|
2700
|
+
var createLinuxDesktopEntry = (input) => {
|
|
2701
|
+
const lines = [
|
|
2702
|
+
"[Desktop Entry]",
|
|
2703
|
+
"Type=Application",
|
|
2704
|
+
`Name=${escapeDesktopString(input.desktop.name)}`
|
|
2705
|
+
];
|
|
2706
|
+
if (input.desktop.comment.length > 0) lines.push(`Comment=${escapeDesktopString(input.desktop.comment)}`);
|
|
2707
|
+
lines.push(`Exec=${input.exec}`);
|
|
2708
|
+
lines.push(`TryExec=${input.tryExec}`);
|
|
2709
|
+
lines.push(`Icon=${escapeDesktopString(input.icon)}`);
|
|
2710
|
+
lines.push(`Terminal=false`);
|
|
2711
|
+
if (input.desktop.categories.length > 0) lines.push(`Categories=${input.desktop.categories.join(";")};`);
|
|
2712
|
+
lines.push(`StartupNotify=${input.desktop.startupNotify ? "true" : "false"}`);
|
|
2713
|
+
lines.push(`StartupWMClass=${escapeDesktopString(input.desktop.desktopId)}`);
|
|
2714
|
+
lines.push("X-Muon-Managed=true");
|
|
2715
|
+
lines.push("");
|
|
2716
|
+
return lines.join("\n");
|
|
2717
|
+
};
|
|
2718
|
+
/**
|
|
2719
|
+
* Quotes one Desktop Entry Exec argument.
|
|
2720
|
+
*/
|
|
2721
|
+
var quoteDesktopExecArgument = (value) => {
|
|
2722
|
+
let escaped = "\"";
|
|
2723
|
+
for (const character of value) {
|
|
2724
|
+
if (character === "\"" || character === "\\" || character === "$" || character === "`") escaped += "\\";
|
|
2725
|
+
escaped += character;
|
|
2726
|
+
}
|
|
2727
|
+
return `${escaped}"`;
|
|
2728
|
+
};
|
|
2729
|
+
var readJsonObjectFile$1 = async (filePath, label) => {
|
|
2730
|
+
const parsed = (0, import_dist.parse)(await (0, node_fs_promises.readFile)(filePath, "utf8"));
|
|
2731
|
+
if (!isJsonObject$2(parsed)) throw new Error(`${label} must contain a JSON object: ${filePath}`);
|
|
2732
|
+
return parsed;
|
|
2733
|
+
};
|
|
2734
|
+
var readProjectJson = async (root) => {
|
|
2735
|
+
const projectJsonPath = (0, node_path.join)(root, "project.json");
|
|
2736
|
+
if (!await fileExists$2(projectJsonPath)) return {};
|
|
2737
|
+
return await readJsonObjectFile$1(projectJsonPath, "project.json");
|
|
2738
|
+
};
|
|
2739
|
+
var createOptionsSource = (options, directory, label) => {
|
|
2740
|
+
if (options === void 0) return;
|
|
2741
|
+
return {
|
|
2742
|
+
options: validateLinuxDesktopOptions(options, label),
|
|
2743
|
+
directory
|
|
2744
|
+
};
|
|
2745
|
+
};
|
|
2746
|
+
var readConfigLinuxDesktopSource = (config, directory, label) => {
|
|
2747
|
+
const linux = config.linux;
|
|
2748
|
+
if (linux === void 0) return;
|
|
2749
|
+
if (!isJsonObject$2(linux)) throw new Error(`${label} linux must be an object when present.`);
|
|
2750
|
+
const desktop = linux.desktop;
|
|
2751
|
+
if (desktop === void 0) return;
|
|
2752
|
+
return createOptionsSource(validateLinuxDesktopOptions(desktop, `${label} linux.desktop`), directory, `${label} linux.desktop`);
|
|
2753
|
+
};
|
|
2754
|
+
var validateLinuxDesktopOptions = (value, label) => {
|
|
2755
|
+
if (!isJsonObject$2(value)) throw new Error(`${label} must be an object.`);
|
|
2756
|
+
const output = {};
|
|
2757
|
+
copyOptionalStringDesktopField(value, "desktopId", output);
|
|
2758
|
+
copyOptionalStringDesktopField(value, "name", output);
|
|
2759
|
+
copyOptionalStringDesktopField(value, "comment", output);
|
|
2760
|
+
copyOptionalStringDesktopField(value, "iconPath", output);
|
|
2761
|
+
copyOptionalCategoriesField(value, output, label);
|
|
2762
|
+
copyOptionalBooleanDesktopField(value, "startupNotify", output, label);
|
|
2763
|
+
return output;
|
|
2764
|
+
};
|
|
2765
|
+
var copyOptionalStringDesktopField = (source, key, target) => {
|
|
2766
|
+
const value = source[key];
|
|
2767
|
+
if (value === void 0) return;
|
|
2768
|
+
if (typeof value !== "string") throw new Error(`${key} must be a string when present.`);
|
|
2769
|
+
if (value.trim() !== "") target[key] = value.trim();
|
|
2770
|
+
};
|
|
2771
|
+
var copyOptionalCategoriesField = (source, target, label) => {
|
|
2772
|
+
const value = source.categories;
|
|
2773
|
+
if (value === void 0) return;
|
|
2774
|
+
if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string" && entry.trim() !== "" && !entry.includes(";") && !entry.includes("\n") && !entry.includes("\r"))) throw new Error(`${label} categories must be a string array without semicolons when present.`);
|
|
2775
|
+
target.categories = value.map((entry) => entry.trim());
|
|
2776
|
+
};
|
|
2777
|
+
var copyOptionalBooleanDesktopField = (source, key, target, label) => {
|
|
2778
|
+
const value = source[key];
|
|
2779
|
+
if (value === void 0) return;
|
|
2780
|
+
if (typeof value !== "boolean") throw new Error(`${label} ${key} must be a boolean when present.`);
|
|
2781
|
+
target[key] = value;
|
|
2782
|
+
};
|
|
2783
|
+
var resolveStringField = (sources, field, fallback) => {
|
|
2784
|
+
for (const source of sources) {
|
|
2785
|
+
const value = source.options[field];
|
|
2786
|
+
if (value !== void 0 && value.trim() !== "") return value.trim();
|
|
2787
|
+
}
|
|
2788
|
+
return fallback;
|
|
2789
|
+
};
|
|
2790
|
+
var resolveCategories = (sources, fallback) => {
|
|
2791
|
+
for (const source of sources) if (source.options.categories !== void 0) return source.options.categories;
|
|
2792
|
+
return fallback;
|
|
2793
|
+
};
|
|
2794
|
+
var resolveBooleanField = (sources, field, fallback) => {
|
|
2795
|
+
for (const source of sources) {
|
|
2796
|
+
const value = source.options[field];
|
|
2797
|
+
if (value !== void 0) return value;
|
|
2798
|
+
}
|
|
2799
|
+
return fallback;
|
|
2800
|
+
};
|
|
2801
|
+
var resolveLinuxIconPath = async (sources, appIconSources, defaultIconPath) => {
|
|
2802
|
+
for (const source of sources) {
|
|
2803
|
+
const value = source.options.iconPath;
|
|
2804
|
+
if (value !== void 0 && value.trim() !== "") {
|
|
2805
|
+
const iconPath = resolveResourcePath(source.directory, value);
|
|
2806
|
+
await assertIconPath(iconPath, true);
|
|
2807
|
+
return iconPath;
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
const appIconPath = await resolveMuonAppIconPath(appIconSources);
|
|
2811
|
+
if (appIconPath !== void 0) return appIconPath;
|
|
2812
|
+
if (defaultIconPath !== void 0 && await fileExists$2(defaultIconPath)) {
|
|
2813
|
+
await assertIconPath(defaultIconPath, false);
|
|
2814
|
+
return defaultIconPath;
|
|
2815
|
+
}
|
|
2816
|
+
throw new Error("Linux desktop icon does not exist.");
|
|
2817
|
+
};
|
|
2818
|
+
var assertIconPath = async (iconPath, required) => {
|
|
2819
|
+
if ((0, node_path.extname)(iconPath).toLowerCase() !== ".png") throw new Error(`Linux desktop icon must be a .png file: ${iconPath}`);
|
|
2820
|
+
if (required && !await fileExists$2(iconPath)) throw new Error(`Linux desktop icon does not exist: ${iconPath}`);
|
|
2821
|
+
if (await fileExists$2(iconPath)) await createNormalizedIconPngData(await (0, node_fs_promises.readFile)(iconPath), iconPath, "Linux desktop icon");
|
|
2822
|
+
};
|
|
2823
|
+
var resolveDefaultLinuxDesktopIcon = async (packageDirectory) => {
|
|
2824
|
+
const candidates = [
|
|
2825
|
+
(0, node_path.join)((0, node_path.resolve)(packageDirectory), "native", "muon-256.png"),
|
|
2826
|
+
(0, node_path.join)(moduleDirectory$2, "native", "muon-256.png"),
|
|
2827
|
+
(0, node_path.join)(moduleDirectory$2, "..", "dist", "native", "muon-256.png"),
|
|
2828
|
+
(0, node_path.join)(moduleDirectory$2, "..", "..", "images", "muon-256.png")
|
|
2829
|
+
];
|
|
2830
|
+
for (const candidate of candidates) if (await fileExists$2(candidate)) return candidate;
|
|
2831
|
+
};
|
|
2832
|
+
var sanitizeDesktopId = (value) => {
|
|
2833
|
+
const sanitized = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[.-]+/g, "").replace(/[.-]+$/g, "");
|
|
2834
|
+
return sanitized.length > 0 ? sanitized : "muon-app";
|
|
2835
|
+
};
|
|
2836
|
+
var escapeDesktopString = (value) => value.replaceAll("\\", "\\\\").replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll(" ", "\\t");
|
|
2837
|
+
var resolveResourcePath = (directory, path) => {
|
|
2838
|
+
return (0, node_path.isAbsolute)(path) ? path : (0, node_path.resolve)(directory, path);
|
|
2839
|
+
};
|
|
2840
|
+
var fileExists$2 = async (path) => {
|
|
2841
|
+
try {
|
|
2842
|
+
await (0, node_fs_promises.access)(path, node_fs.constants.F_OK);
|
|
2843
|
+
return true;
|
|
2844
|
+
} catch {
|
|
2845
|
+
return false;
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
var isJsonObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2849
|
+
//#endregion
|
|
1867
2850
|
//#region src/build.ts
|
|
1868
2851
|
var AdmZip = __resolveDefaultExport(adm_zip.default, false);
|
|
1869
2852
|
globalThis.__screwUpIsInCJS_f9d0012cc677 = true;
|
|
@@ -1922,18 +2905,58 @@ var buildMuonApp = async (options = {}) => {
|
|
|
1922
2905
|
const appName = resolveAppName(packageJson, options.appName);
|
|
1923
2906
|
const appId = resolveAppId(packageJson, options.appId);
|
|
1924
2907
|
const buildConfig = await readBuildConfig(root, options.configPath);
|
|
1925
|
-
const
|
|
2908
|
+
const sourceConfig = applyRuntimePluginConfig(buildConfig.config, options.runtimePluginConfig ?? { mode: "simple" });
|
|
2909
|
+
assertNoUserInitialTitleBarIcon(sourceConfig);
|
|
2910
|
+
const resolvedBuildConfig = {
|
|
2911
|
+
...buildConfig,
|
|
2912
|
+
config: sourceConfig
|
|
2913
|
+
};
|
|
2914
|
+
const assetInput = resolveAssetInput(root, options.assetSourcePath, options.assetPrefix, resolvedBuildConfig);
|
|
2915
|
+
const windowsResource = await resolveMuonWindowsResource({
|
|
2916
|
+
root,
|
|
2917
|
+
packageDirectory,
|
|
2918
|
+
packageJson,
|
|
2919
|
+
muonConfig: sourceConfig,
|
|
2920
|
+
muonConfigDirectory: buildConfig.directory,
|
|
2921
|
+
options: options.windowsResource,
|
|
2922
|
+
appIconPath: options.iconPath,
|
|
2923
|
+
defaults: {
|
|
2924
|
+
productName: appName,
|
|
2925
|
+
fileDescription: appName,
|
|
2926
|
+
companyName: "Unknown",
|
|
2927
|
+
version: "0.0.0",
|
|
2928
|
+
copyright: void 0
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2931
|
+
const linuxDesktop = await resolveMuonLinuxDesktop({
|
|
2932
|
+
root,
|
|
2933
|
+
packageDirectory,
|
|
2934
|
+
muonConfig: sourceConfig,
|
|
2935
|
+
muonConfigDirectory: buildConfig.directory,
|
|
2936
|
+
options: options.linuxDesktop,
|
|
2937
|
+
appIconPath: options.iconPath,
|
|
2938
|
+
defaults: {
|
|
2939
|
+
desktopId: appId,
|
|
2940
|
+
name: resolveLinuxDesktopDefaultName(packageJson, appName),
|
|
2941
|
+
comment: resolvePackageDescription(packageJson),
|
|
2942
|
+
categories: ["Utility"],
|
|
2943
|
+
startupNotify: true
|
|
2944
|
+
}
|
|
2945
|
+
});
|
|
1926
2946
|
const salt = Buffer.from(options.assetSalt ?? (0, node_crypto.randomBytes)(assetSaltByteLength));
|
|
1927
2947
|
const results = [];
|
|
1928
2948
|
for (const target of targets) {
|
|
1929
2949
|
const result = await buildMuonTarget({
|
|
1930
2950
|
packageDirectory,
|
|
2951
|
+
root,
|
|
1931
2952
|
outputRoot,
|
|
1932
2953
|
appName,
|
|
1933
2954
|
appId,
|
|
1934
2955
|
target,
|
|
1935
2956
|
assetInput,
|
|
1936
|
-
sourceConfig
|
|
2957
|
+
sourceConfig,
|
|
2958
|
+
windowsResource,
|
|
2959
|
+
linuxDesktop,
|
|
1937
2960
|
salt
|
|
1938
2961
|
});
|
|
1939
2962
|
results.push(result);
|
|
@@ -1991,6 +3014,8 @@ var sanitizeAppId = (value) => {
|
|
|
1991
3014
|
const sanitized = (value.startsWith("@") ? value.slice(1) : value).trim().toLowerCase().replace("/", ".").replace(/[^a-z0-9._-]+/g, ".").replace(/^[.]+/g, "").replace(/[.]+$/g, "");
|
|
1992
3015
|
return sanitized.length > 0 ? sanitized : defaultAppId;
|
|
1993
3016
|
};
|
|
3017
|
+
var resolveLinuxDesktopDefaultName = (packageJson, appName) => typeof packageJson.name === "string" && packageJson.name.trim() !== "" ? packageJson.name.trim() : appName;
|
|
3018
|
+
var resolvePackageDescription = (packageJson) => typeof packageJson.description === "string" ? packageJson.description.trim() : "";
|
|
1994
3019
|
var readBuildConfig = async (root, configPath) => {
|
|
1995
3020
|
const resolvedConfigPath = await resolveConfigPath(root, configPath);
|
|
1996
3021
|
if (resolvedConfigPath === void 0) return {
|
|
@@ -2002,6 +3027,19 @@ var readBuildConfig = async (root, configPath) => {
|
|
|
2002
3027
|
directory: (0, node_path.dirname)(resolvedConfigPath)
|
|
2003
3028
|
};
|
|
2004
3029
|
};
|
|
3030
|
+
var applyRuntimePluginConfig = (sourceConfig, runtimePluginConfig) => {
|
|
3031
|
+
if (runtimePluginConfig === void 0) return sourceConfig;
|
|
3032
|
+
const sourcePlugin = sourceConfig.plugin;
|
|
3033
|
+
if (sourcePlugin !== void 0 && !isJsonObject$1(sourcePlugin)) throw new Error("muon.json plugin must be an object when runtime plugin config is applied.");
|
|
3034
|
+
const plugin = sourcePlugin ?? {};
|
|
3035
|
+
return {
|
|
3036
|
+
...sourceConfig,
|
|
3037
|
+
plugin: {
|
|
3038
|
+
...plugin,
|
|
3039
|
+
...runtimePluginConfig
|
|
3040
|
+
}
|
|
3041
|
+
};
|
|
3042
|
+
};
|
|
2005
3043
|
var readConfigAssetSourcePath = (sourceConfig) => {
|
|
2006
3044
|
const sourceAsset = sourceConfig.asset;
|
|
2007
3045
|
if (sourceAsset === void 0) return;
|
|
@@ -2045,6 +3083,8 @@ var buildMuonTarget = async (input) => {
|
|
|
2045
3083
|
const outputPath = (0, node_path.join)(input.outputRoot, descriptor.distributionDirectoryName);
|
|
2046
3084
|
const launcherPath = (0, node_path.join)(outputPath, getLauncherFileName(input.appName, descriptor));
|
|
2047
3085
|
const assetZipPath = (0, node_path.join)(outputPath, "assets.zip");
|
|
3086
|
+
const runtimeAppId = getMuonTargetRuntimeAppId(input.appId, input.target);
|
|
3087
|
+
const appIconPath = descriptor.os === "windows" ? input.windowsResource.iconPath : input.linuxDesktop.iconPath;
|
|
2048
3088
|
await verifyTargetInputs({
|
|
2049
3089
|
sourceRuntimePath,
|
|
2050
3090
|
sourceBootstrapPath,
|
|
@@ -2063,8 +3103,11 @@ var buildMuonTarget = async (input) => {
|
|
|
2063
3103
|
await (0, node_fs_promises.chmod)((0, node_path.join)(outputPath, descriptor.runtimeExecutableName), executableMode);
|
|
2064
3104
|
await (0, node_fs_promises.copyFile)(sourceBootstrapPath, launcherPath);
|
|
2065
3105
|
await (0, node_fs_promises.chmod)(launcherPath, executableMode);
|
|
2066
|
-
const asset = await writeAssetArchive(input.assetInput, assetZipPath, input.salt
|
|
2067
|
-
|
|
3106
|
+
const asset = await writeAssetArchive(input.assetInput, assetZipPath, input.salt, [{
|
|
3107
|
+
name: appIconAssetEntryName,
|
|
3108
|
+
data: await (0, node_fs_promises.readFile)(appIconPath)
|
|
3109
|
+
}]);
|
|
3110
|
+
const embeddedConfig = createEmbeddedConfig(input.sourceConfig, asset, runtimeAppId, input.linuxDesktop.desktopId, appIconAssetUrl);
|
|
2068
3111
|
await withTemporaryConfig(embeddedConfig, async (configPath) => {
|
|
2069
3112
|
await embedMuonConfigInRuntime({
|
|
2070
3113
|
runtimePath: outputPath,
|
|
@@ -2077,13 +3120,29 @@ var buildMuonTarget = async (input) => {
|
|
|
2077
3120
|
outputPath: void 0
|
|
2078
3121
|
});
|
|
2079
3122
|
});
|
|
3123
|
+
if (descriptor.os === "windows") {
|
|
3124
|
+
await updateWindowsPeIconResource({
|
|
3125
|
+
executablePath: (0, node_path.join)(outputPath, descriptor.runtimeExecutableName),
|
|
3126
|
+
resource: input.windowsResource,
|
|
3127
|
+
environment: process.env,
|
|
3128
|
+
cwd: input.root
|
|
3129
|
+
});
|
|
3130
|
+
await updateWindowsPeResources({
|
|
3131
|
+
executablePath: launcherPath,
|
|
3132
|
+
resource: input.windowsResource,
|
|
3133
|
+
environment: process.env,
|
|
3134
|
+
cwd: input.root
|
|
3135
|
+
});
|
|
3136
|
+
} else if (descriptor.os === "linux") await writeLinuxDesktopDistributionFiles(outputPath, input.linuxDesktop);
|
|
2080
3137
|
return {
|
|
2081
3138
|
target: input.target,
|
|
2082
3139
|
distributionDirectoryName: descriptor.distributionDirectoryName,
|
|
2083
3140
|
outputPath,
|
|
2084
3141
|
launcherPath,
|
|
2085
3142
|
asset,
|
|
2086
|
-
|
|
3143
|
+
runtimeAppId,
|
|
3144
|
+
embeddedConfig,
|
|
3145
|
+
...descriptor.os === "linux" ? { linuxDesktop: input.linuxDesktop } : {}
|
|
2087
3146
|
};
|
|
2088
3147
|
};
|
|
2089
3148
|
var verifyTargetInputs = async (input) => {
|
|
@@ -2104,10 +3163,10 @@ var copyRuntimeFiles = async (sourceRuntimePath, outputPath, descriptor) => {
|
|
|
2104
3163
|
}
|
|
2105
3164
|
await (0, node_fs_promises.copyFile)((0, node_path.join)(sourceRuntimePath, muonLicenseFileName), (0, node_path.join)(outputPath, muonLicenseFileName));
|
|
2106
3165
|
};
|
|
2107
|
-
var writeAssetArchive = async (input, outputPath, salt) => {
|
|
3166
|
+
var writeAssetArchive = async (input, outputPath, salt, extraEntries) => {
|
|
2108
3167
|
const sourceStats = await statOrUndefined(input.sourcePath);
|
|
2109
3168
|
if (sourceStats === void 0) throw new Error(`Muon asset source does not exist: ${input.sourcePath}`);
|
|
2110
|
-
const archive = sourceStats.isDirectory() ? await createAssetArchiveFromDirectory(input) : sourceStats.isFile() ? await (
|
|
3169
|
+
const archive = sourceStats.isDirectory() ? await createAssetArchiveFromDirectory(input, extraEntries) : sourceStats.isFile() ? await createAssetArchiveFromZipFile(input.sourcePath, extraEntries) : void 0;
|
|
2111
3170
|
if (archive === void 0) throw new Error(`Muon asset source is not a directory or file: ${input.sourcePath}`);
|
|
2112
3171
|
await (0, node_fs_promises.writeFile)(outputPath, archive);
|
|
2113
3172
|
return {
|
|
@@ -2117,10 +3176,30 @@ var writeAssetArchive = async (input, outputPath, salt) => {
|
|
|
2117
3176
|
entryCount: sourceStats.isDirectory() ? readZipEntryCount(archive, outputPath) : readZipEntryCount(archive, input.sourcePath)
|
|
2118
3177
|
};
|
|
2119
3178
|
};
|
|
2120
|
-
var createAssetArchiveFromDirectory = async (input) => {
|
|
3179
|
+
var createAssetArchiveFromDirectory = async (input, extraEntries) => {
|
|
2121
3180
|
const entries = await collectZipEntries(input.sourcePath, input.prefix);
|
|
2122
3181
|
if (entries.length === 0) throw new Error(`Muon asset source has no files: ${input.sourcePath}`);
|
|
2123
|
-
return createZipArchive(entries);
|
|
3182
|
+
return createZipArchive(appendZipEntries(entries, extraEntries));
|
|
3183
|
+
};
|
|
3184
|
+
var createAssetArchiveFromZipFile = async (sourcePath, extraEntries) => {
|
|
3185
|
+
const zip = new AdmZip(await (0, node_fs_promises.readFile)(sourcePath));
|
|
3186
|
+
for (const entry of extraEntries) {
|
|
3187
|
+
assertSafeZipEntryName(entry.name);
|
|
3188
|
+
if (zip.getEntry(entry.name) !== null) throw new Error(`Muon app icon asset entry already exists: ${entry.name}`);
|
|
3189
|
+
zip.addFile(entry.name, entry.data);
|
|
3190
|
+
}
|
|
3191
|
+
return zip.toBuffer();
|
|
3192
|
+
};
|
|
3193
|
+
var appendZipEntries = (entries, extraEntries) => {
|
|
3194
|
+
const output = [...entries];
|
|
3195
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
3196
|
+
for (const entry of extraEntries) {
|
|
3197
|
+
assertSafeZipEntryName(entry.name);
|
|
3198
|
+
if (names.has(entry.name)) throw new Error(`Muon app icon asset entry already exists: ${entry.name}`);
|
|
3199
|
+
names.add(entry.name);
|
|
3200
|
+
output.push(entry);
|
|
3201
|
+
}
|
|
3202
|
+
return output;
|
|
2124
3203
|
};
|
|
2125
3204
|
var readZipEntryCount = (archive, sourcePath) => {
|
|
2126
3205
|
const endSignature = 101010256;
|
|
@@ -2158,13 +3237,20 @@ var createZipArchive = (entries) => {
|
|
|
2158
3237
|
for (const entry of entries) zip.addFile(entry.name, entry.data);
|
|
2159
3238
|
return zip.toBuffer();
|
|
2160
3239
|
};
|
|
2161
|
-
var createEmbeddedConfig = (sourceConfig, asset, appId) => {
|
|
3240
|
+
var createEmbeddedConfig = (sourceConfig, asset, appId, desktopId, initialTitleBarIcon) => {
|
|
2162
3241
|
const sourceAsset = sourceConfig.asset;
|
|
2163
3242
|
if (sourceAsset !== void 0 && !isJsonObject$1(sourceAsset)) throw new Error("muon.json asset must be an object when present.");
|
|
2164
3243
|
const sourceBootstrap = sourceConfig.bootstrap;
|
|
2165
3244
|
if (sourceBootstrap !== void 0 && !isJsonObject$1(sourceBootstrap)) throw new Error("muon.json bootstrap must be an object when present.");
|
|
3245
|
+
const runtimeConfig = stripBuildOnlyAppIconConfig(stripBuildOnlyLinuxDesktopConfig(stripBuildOnlyWindowsResourceConfig(sourceConfig)));
|
|
3246
|
+
const sourceBrowser = runtimeConfig.browser;
|
|
3247
|
+
if (sourceBrowser !== void 0 && !isJsonObject$1(sourceBrowser)) throw new Error("muon.json browser must be an object when present.");
|
|
2166
3248
|
return {
|
|
2167
|
-
...
|
|
3249
|
+
...runtimeConfig,
|
|
3250
|
+
browser: {
|
|
3251
|
+
...sourceBrowser ?? {},
|
|
3252
|
+
initialTitleBarIcon
|
|
3253
|
+
},
|
|
2168
3254
|
asset: {
|
|
2169
3255
|
...sourceAsset ?? {},
|
|
2170
3256
|
sourcePath: appConfigSourcePath,
|
|
@@ -2173,10 +3259,22 @@ var createEmbeddedConfig = (sourceConfig, asset, appId) => {
|
|
|
2173
3259
|
},
|
|
2174
3260
|
bootstrap: {
|
|
2175
3261
|
...sourceBootstrap ?? {},
|
|
2176
|
-
appId
|
|
3262
|
+
appId,
|
|
3263
|
+
desktopId
|
|
2177
3264
|
}
|
|
2178
3265
|
};
|
|
2179
3266
|
};
|
|
3267
|
+
var assertNoUserInitialTitleBarIcon = (sourceConfig) => {
|
|
3268
|
+
const sourceBrowser = sourceConfig.browser;
|
|
3269
|
+
if (sourceBrowser === void 0) return;
|
|
3270
|
+
if (!isJsonObject$1(sourceBrowser)) throw new Error("muon.json browser must be an object when present.");
|
|
3271
|
+
if (sourceBrowser.initialTitleBarIcon !== void 0) throw new Error("muon.json browser.initialTitleBarIcon is generated by muon build; use top-level iconPath instead.");
|
|
3272
|
+
};
|
|
3273
|
+
var stripBuildOnlyAppIconConfig = (sourceConfig) => {
|
|
3274
|
+
const output = {};
|
|
3275
|
+
for (const [key, value] of Object.entries(sourceConfig)) if (key !== "iconPath") output[key] = value;
|
|
3276
|
+
return output;
|
|
3277
|
+
};
|
|
2180
3278
|
var withTemporaryConfig = async (config, callback) => {
|
|
2181
3279
|
const tempDirectory = await (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "muon-build-config-"));
|
|
2182
3280
|
const configPath = (0, node_path.join)(tempDirectory, "muon.json");
|
|
@@ -2218,6 +3316,203 @@ var isJsonObject$1 = (value) => {
|
|
|
2218
3316
|
};
|
|
2219
3317
|
var getErrorMessage$1 = (error) => error instanceof Error ? error.message : String(error);
|
|
2220
3318
|
//#endregion
|
|
3319
|
+
//#region src/vite-options.ts
|
|
3320
|
+
/**
|
|
3321
|
+
* Metadata symbol used to recover `muon()` plugin options from `vite.config.*`.
|
|
3322
|
+
*/
|
|
3323
|
+
var muonVitePluginOptionsSymbol = Symbol.for("muon.vite.plugin.options");
|
|
3324
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3325
|
+
var isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
3326
|
+
var isWindowsResourceOptions = (value) => {
|
|
3327
|
+
if (!isRecord(value)) return false;
|
|
3328
|
+
return (value.iconPath === void 0 || typeof value.iconPath === "string") && (value.productName === void 0 || typeof value.productName === "string") && (value.fileDescription === void 0 || typeof value.fileDescription === "string") && (value.companyName === void 0 || typeof value.companyName === "string") && (value.version === void 0 || typeof value.version === "string") && (value.copyright === void 0 || typeof value.copyright === "string") && (value.language === void 0 || typeof value.language === "number" && Number.isInteger(value.language)) && (value.codePage === void 0 || typeof value.codePage === "number" && Number.isInteger(value.codePage));
|
|
3329
|
+
};
|
|
3330
|
+
var isLinuxDesktopOptions = (value) => {
|
|
3331
|
+
if (!isRecord(value)) return false;
|
|
3332
|
+
return (value.desktopId === void 0 || typeof value.desktopId === "string") && (value.name === void 0 || typeof value.name === "string") && (value.comment === void 0 || typeof value.comment === "string") && (value.iconPath === void 0 || typeof value.iconPath === "string") && (value.categories === void 0 || isStringArray(value.categories)) && (value.startupNotify === void 0 || typeof value.startupNotify === "boolean");
|
|
3333
|
+
};
|
|
3334
|
+
var isMuonViteBuildOptions = (value) => {
|
|
3335
|
+
if (!isRecord(value)) return false;
|
|
3336
|
+
return (value.targets === void 0 || isStringArray(value.targets)) && (value.allTargets === void 0 || typeof value.allTargets === "boolean") && (value.appName === void 0 || typeof value.appName === "string") && (value.appId === void 0 || typeof value.appId === "string") && (value.outputRoot === void 0 || typeof value.outputRoot === "string") && (value.configPath === void 0 || typeof value.configPath === "string") && (value.iconPath === void 0 || typeof value.iconPath === "string") && (value.windowsResource === void 0 || isWindowsResourceOptions(value.windowsResource)) && (value.linuxDesktop === void 0 || isLinuxDesktopOptions(value.linuxDesktop)) && (value.packageDirectory === void 0 || typeof value.packageDirectory === "string") && (value.assetSalt === void 0 || value.assetSalt instanceof Uint8Array);
|
|
3337
|
+
};
|
|
3338
|
+
var isMuonVitePluginAccessImportOptions = (value) => {
|
|
3339
|
+
if (!isRecord(value)) return false;
|
|
3340
|
+
return (value.sources === void 0 || isStringArray(value.sources)) && (value.packages === void 0 || isStringArray(value.packages)) && (value.allow === void 0 || isStringArray(value.allow));
|
|
3341
|
+
};
|
|
3342
|
+
var isMuonVitePluginAccessEntryOptions = (value) => {
|
|
3343
|
+
if (!isRecord(value)) return false;
|
|
3344
|
+
return typeof value.name === "string" && (value.signature === void 0 || typeof value.signature === "string") && (value.salt === void 0 || typeof value.salt === "string") && (value.allow === void 0 || isStringArray(value.allow)) && (value.imports === void 0 || Array.isArray(value.imports) && value.imports.every(isMuonVitePluginAccessImportOptions));
|
|
3345
|
+
};
|
|
3346
|
+
var isMuonVitePluginAccessOptions = (value) => {
|
|
3347
|
+
if (!isRecord(value)) return false;
|
|
3348
|
+
return (value.path === void 0 || typeof value.path === "string") && (value.mode === void 0 || value.mode === "simple" || value.mode === "validate") && (value.pages === void 0 || isStringArray(value.pages)) && (value.plugins === void 0 || Array.isArray(value.plugins) && value.plugins.every(isMuonVitePluginAccessEntryOptions));
|
|
3349
|
+
};
|
|
3350
|
+
var isMuonVitePluginOptions = (value) => {
|
|
3351
|
+
if (!isRecord(value)) return false;
|
|
3352
|
+
return (value.muonPath === void 0 || typeof value.muonPath === "string") && (value.cefPath === void 0 || typeof value.cefPath === "string") && (value.stagePath === void 0 || typeof value.stagePath === "string") && (value.open === void 0 || typeof value.open === "boolean") && (value.enableDebugger === void 0 || typeof value.enableDebugger === "boolean") && (value.pluginAccess === void 0 || value.pluginAccess === false || isMuonVitePluginAccessOptions(value.pluginAccess)) && (value.build === void 0 || typeof value.build === "boolean" || isMuonViteBuildOptions(value.build));
|
|
3353
|
+
};
|
|
3354
|
+
/**
|
|
3355
|
+
* Attaches raw Muon Vite plugin options to a plugin instance.
|
|
3356
|
+
*
|
|
3357
|
+
* @param plugin Plugin object.
|
|
3358
|
+
* @param options Raw plugin options.
|
|
3359
|
+
* @returns Plugin object with internal Muon metadata.
|
|
3360
|
+
*/
|
|
3361
|
+
var attachMuonVitePluginOptions = (plugin, options) => {
|
|
3362
|
+
Object.defineProperty(plugin, muonVitePluginOptionsSymbol, {
|
|
3363
|
+
configurable: false,
|
|
3364
|
+
enumerable: false,
|
|
3365
|
+
value: { ...options },
|
|
3366
|
+
writable: false
|
|
3367
|
+
});
|
|
3368
|
+
return plugin;
|
|
3369
|
+
};
|
|
3370
|
+
/**
|
|
3371
|
+
* Reads raw Muon Vite plugin options from a plugin instance.
|
|
3372
|
+
*
|
|
3373
|
+
* @param plugin Candidate plugin object.
|
|
3374
|
+
* @returns Attached Muon options, if present.
|
|
3375
|
+
*/
|
|
3376
|
+
var getMuonVitePluginOptions = (plugin) => {
|
|
3377
|
+
if (!isRecord(plugin)) return;
|
|
3378
|
+
const options = plugin[muonVitePluginOptionsSymbol];
|
|
3379
|
+
return isMuonVitePluginOptions(options) ? options : void 0;
|
|
3380
|
+
};
|
|
3381
|
+
/**
|
|
3382
|
+
* Resolves nested Vite plugin option values into a flat list.
|
|
3383
|
+
*
|
|
3384
|
+
* @param pluginOptions Raw `plugins` field from a Vite config.
|
|
3385
|
+
* @returns Flat plugin object list.
|
|
3386
|
+
*/
|
|
3387
|
+
var flattenVitePluginOptions = async (pluginOptions) => {
|
|
3388
|
+
const resolvedValue = await pluginOptions;
|
|
3389
|
+
if (resolvedValue === null || resolvedValue === void 0 || !resolvedValue) return [];
|
|
3390
|
+
if (Array.isArray(resolvedValue)) return (await Promise.all(resolvedValue.map((entry) => flattenVitePluginOptions(entry)))).flat();
|
|
3391
|
+
return [resolvedValue];
|
|
3392
|
+
};
|
|
3393
|
+
//#endregion
|
|
3394
|
+
//#region src/build-sequence.ts
|
|
3395
|
+
/**
|
|
3396
|
+
* Environment variable used to prevent the Vite plugin build hook from running
|
|
3397
|
+
* when a CLI command owns the Muon build sequence.
|
|
3398
|
+
*/
|
|
3399
|
+
var muonBuildSequenceSuppressViteBuildEnvironmentKey = "MUON_SUPPRESS_VITE_MUON_BUILD";
|
|
3400
|
+
var isMissingVitePackageError = (error) => {
|
|
3401
|
+
const candidate = error;
|
|
3402
|
+
return candidate.code === "ERR_MODULE_NOT_FOUND" && typeof candidate.message === "string" && candidate.message.includes("vite");
|
|
3403
|
+
};
|
|
3404
|
+
var resolveViteOutputDirectory = (config) => {
|
|
3405
|
+
return (0, node_path.isAbsolute)(config.build.outDir) ? config.build.outDir : (0, node_path.resolve)(config.root, config.build.outDir);
|
|
3406
|
+
};
|
|
3407
|
+
var findMuonVitePluginOptions = async (plugins) => {
|
|
3408
|
+
const muonPlugins = (await flattenVitePluginOptions(plugins)).map((plugin) => getMuonVitePluginOptions(plugin)).filter((pluginOptions) => pluginOptions !== void 0);
|
|
3409
|
+
if (muonPlugins.length > 1) throw new Error("Multiple muon() plugin definitions were found in vite.config.*.");
|
|
3410
|
+
return muonPlugins[0];
|
|
3411
|
+
};
|
|
3412
|
+
/**
|
|
3413
|
+
* Loads Vite configuration only far enough to discover whether a Muon plugin
|
|
3414
|
+
* controls the build sequence.
|
|
3415
|
+
*/
|
|
3416
|
+
var loadMuonBuildSequenceProject = async (cwd) => {
|
|
3417
|
+
const resolvedCwd = (0, node_path.resolve)(cwd);
|
|
3418
|
+
let vite;
|
|
3419
|
+
try {
|
|
3420
|
+
vite = await import("vite");
|
|
3421
|
+
} catch (error) {
|
|
3422
|
+
if (isMissingVitePackageError(error)) return {
|
|
3423
|
+
root: resolvedCwd,
|
|
3424
|
+
viteBuildRoot: resolvedCwd,
|
|
3425
|
+
viteOutputDirectory: void 0,
|
|
3426
|
+
pluginOptions: void 0
|
|
3427
|
+
};
|
|
3428
|
+
throw error;
|
|
3429
|
+
}
|
|
3430
|
+
const resolvedConfig = await vite.resolveConfig({
|
|
3431
|
+
root: resolvedCwd,
|
|
3432
|
+
logLevel: "silent"
|
|
3433
|
+
}, "build", "production", "production");
|
|
3434
|
+
const pluginOptions = await findMuonVitePluginOptions(resolvedConfig.plugins);
|
|
3435
|
+
if (pluginOptions === void 0) return {
|
|
3436
|
+
root: resolvedCwd,
|
|
3437
|
+
viteBuildRoot: resolvedCwd,
|
|
3438
|
+
viteOutputDirectory: void 0,
|
|
3439
|
+
pluginOptions: void 0
|
|
3440
|
+
};
|
|
3441
|
+
return {
|
|
3442
|
+
root: resolvedConfig.root,
|
|
3443
|
+
viteBuildRoot: resolvedCwd,
|
|
3444
|
+
viteOutputDirectory: resolveViteOutputDirectory(resolvedConfig),
|
|
3445
|
+
pluginOptions
|
|
3446
|
+
};
|
|
3447
|
+
};
|
|
3448
|
+
/**
|
|
3449
|
+
* Returns Muon build options from a Muon Vite plugin declaration.
|
|
3450
|
+
*/
|
|
3451
|
+
var resolveMuonViteBuildOptions = (pluginOptions) => {
|
|
3452
|
+
if (pluginOptions?.build === false) throw new Error("Muon build is disabled by muon({ build: false }).");
|
|
3453
|
+
return typeof pluginOptions?.build === "object" ? pluginOptions.build : {};
|
|
3454
|
+
};
|
|
3455
|
+
var runViteBuild = async (root) => {
|
|
3456
|
+
const vite = await import("vite");
|
|
3457
|
+
const previous = process.env[muonBuildSequenceSuppressViteBuildEnvironmentKey];
|
|
3458
|
+
process.env[muonBuildSequenceSuppressViteBuildEnvironmentKey] = "1";
|
|
3459
|
+
try {
|
|
3460
|
+
await vite.build({
|
|
3461
|
+
root,
|
|
3462
|
+
logLevel: "silent"
|
|
3463
|
+
});
|
|
3464
|
+
} finally {
|
|
3465
|
+
if (previous === void 0) delete process.env[muonBuildSequenceSuppressViteBuildEnvironmentKey];
|
|
3466
|
+
else process.env[muonBuildSequenceSuppressViteBuildEnvironmentKey] = previous;
|
|
3467
|
+
}
|
|
3468
|
+
};
|
|
3469
|
+
var hasExplicitTargets = (options) => options.targets !== void 0 && options.targets.length > 0;
|
|
3470
|
+
var copyDefinedBuildOptions = (output, input, usesViteAssets) => {
|
|
3471
|
+
if (input.assetSourcePath !== void 0) {
|
|
3472
|
+
if (usesViteAssets) throw new Error("--assets cannot be used when a muon() Vite plugin provides the build sequence.");
|
|
3473
|
+
output.assetSourcePath = input.assetSourcePath;
|
|
3474
|
+
}
|
|
3475
|
+
if (input.assetPrefix !== void 0) output.assetPrefix = input.assetPrefix;
|
|
3476
|
+
if (input.targets !== void 0 && input.targets.length > 0) {
|
|
3477
|
+
output.targets = input.targets;
|
|
3478
|
+
if (input.allTargets === void 0) output.allTargets = false;
|
|
3479
|
+
}
|
|
3480
|
+
if (input.allTargets !== void 0) output.allTargets = input.allTargets;
|
|
3481
|
+
if (input.appName !== void 0) output.appName = input.appName;
|
|
3482
|
+
if (input.appId !== void 0) output.appId = input.appId;
|
|
3483
|
+
if (input.outputRoot !== void 0) output.outputRoot = input.outputRoot;
|
|
3484
|
+
if (input.configPath !== void 0) output.configPath = input.configPath;
|
|
3485
|
+
if (input.iconPath !== void 0) output.iconPath = input.iconPath;
|
|
3486
|
+
if (input.windowsResource !== void 0) {
|
|
3487
|
+
const windowsResource = mergeMuonWindowsResourceOptions(input.windowsResource, output.windowsResource);
|
|
3488
|
+
if (windowsResource !== void 0) output.windowsResource = windowsResource;
|
|
3489
|
+
}
|
|
3490
|
+
if (input.linuxDesktop !== void 0) {
|
|
3491
|
+
const linuxDesktop = mergeMuonLinuxDesktopOptions(input.linuxDesktop, output.linuxDesktop);
|
|
3492
|
+
if (linuxDesktop !== void 0) output.linuxDesktop = linuxDesktop;
|
|
3493
|
+
}
|
|
3494
|
+
if (input.packageDirectory !== void 0) output.packageDirectory = input.packageDirectory;
|
|
3495
|
+
if (input.assetSalt !== void 0) output.assetSalt = input.assetSalt;
|
|
3496
|
+
};
|
|
3497
|
+
/**
|
|
3498
|
+
* Runs the project build sequence used by `muon build` and `muon pack`.
|
|
3499
|
+
*/
|
|
3500
|
+
var runMuonBuildSequence = async (options = {}, loadedProject) => {
|
|
3501
|
+
const project = loadedProject ?? await loadMuonBuildSequenceProject(options.root ?? process.cwd());
|
|
3502
|
+
const pluginBuildOptions = resolveMuonViteBuildOptions(project.pluginOptions);
|
|
3503
|
+
const usesViteAssets = project.pluginOptions !== void 0;
|
|
3504
|
+
const buildOptions = { root: project.root };
|
|
3505
|
+
if (usesViteAssets) {
|
|
3506
|
+
if (project.viteOutputDirectory === void 0) throw new Error("Vite output directory could not be resolved.");
|
|
3507
|
+
Object.assign(buildOptions, pluginBuildOptions);
|
|
3508
|
+
buildOptions.assetSourcePath = project.viteOutputDirectory;
|
|
3509
|
+
buildOptions.assetPrefix = "main";
|
|
3510
|
+
await runViteBuild(project.viteBuildRoot);
|
|
3511
|
+
} else if (options.defaultAllTargets !== void 0 && options.allTargets === void 0 && !hasExplicitTargets(options)) buildOptions.allTargets = options.defaultAllTargets;
|
|
3512
|
+
copyDefinedBuildOptions(buildOptions, options, usesViteAssets);
|
|
3513
|
+
return await buildMuonApp(buildOptions);
|
|
3514
|
+
};
|
|
3515
|
+
//#endregion
|
|
2221
3516
|
//#region src/vite-internals.ts
|
|
2222
3517
|
var resolveFromRoot = (root, path) => (0, node_path.isAbsolute)(path) ? path : (0, node_path.resolve)(root, path);
|
|
2223
3518
|
var moduleDirectory = typeof __dirname === "string" ? __dirname : (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
|
|
@@ -2323,7 +3618,7 @@ var getWebSocketOrigin = (startUrl) => {
|
|
|
2323
3618
|
else if (url.protocol === "http:") url.protocol = "ws:";
|
|
2324
3619
|
return url.origin;
|
|
2325
3620
|
};
|
|
2326
|
-
var createMuonOverrideConfig = (startUrl, enableDebugger) => {
|
|
3621
|
+
var createMuonOverrideConfig = (startUrl, enableDebugger, runtimePluginConfig) => {
|
|
2327
3622
|
const origin = new URL(startUrl).origin;
|
|
2328
3623
|
return {
|
|
2329
3624
|
...enableDebugger ? { cdp: { enable: true } } : {},
|
|
@@ -2332,19 +3627,22 @@ var createMuonOverrideConfig = (startUrl, enableDebugger) => {
|
|
|
2332
3627
|
...enableDebugger ? { keybind: {
|
|
2333
3628
|
devtools: "f12",
|
|
2334
3629
|
recycle: "ctrl+f12"
|
|
2335
|
-
} } : {}
|
|
2336
|
-
|
|
3630
|
+
} } : {}
|
|
3631
|
+
},
|
|
3632
|
+
plugin: {
|
|
3633
|
+
...runtimePluginConfig,
|
|
3634
|
+
pages: [`${origin}/**`]
|
|
2337
3635
|
},
|
|
2338
3636
|
network: { allow: [`${origin}/**`, `${getWebSocketOrigin(startUrl)}/**`] }
|
|
2339
3637
|
};
|
|
2340
3638
|
};
|
|
2341
|
-
var writeMuonOverrideConfig = (server, overrideConfigPath,
|
|
3639
|
+
var writeMuonOverrideConfig = (server, overrideConfigPath, pluginOptions, getRuntimePluginConfig) => {
|
|
2342
3640
|
const startUrl = getBaseUrl(server);
|
|
2343
3641
|
if (startUrl === void 0) {
|
|
2344
3642
|
server.config.logger.warn("Muon Vite plugin could not resolve a Vite URL.");
|
|
2345
3643
|
return false;
|
|
2346
3644
|
}
|
|
2347
|
-
(0, node_fs.writeFileSync)(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl, enableDebugger), null, 2)}\n`);
|
|
3645
|
+
(0, node_fs.writeFileSync)(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl, pluginOptions.enableDebugger !== false, getRuntimePluginConfig()), null, 2)}\n`);
|
|
2348
3646
|
return true;
|
|
2349
3647
|
};
|
|
2350
3648
|
var createRuntimePaths = async (server, stagePath, platform, projectConfigPath) => {
|
|
@@ -2407,7 +3705,7 @@ var launchMuon = (paths, platform, server) => {
|
|
|
2407
3705
|
});
|
|
2408
3706
|
child.unref();
|
|
2409
3707
|
};
|
|
2410
|
-
var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, architecture, environment }) => {
|
|
3708
|
+
var startMuonViteBrowserBridge = async ({ server, pluginOptions, getRuntimePluginConfig, platform, architecture, environment }) => {
|
|
2411
3709
|
await ensureMuonGitignoreEntry(server.config.root);
|
|
2412
3710
|
if (pluginOptions.open === false || server.httpServer === null) return;
|
|
2413
3711
|
const target = getDefaultMuonPrepareTarget(platform, architecture);
|
|
@@ -2427,7 +3725,7 @@ var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, archi
|
|
|
2427
3725
|
environment,
|
|
2428
3726
|
cwd: server.config.root
|
|
2429
3727
|
});
|
|
2430
|
-
if (preparedRuntime.stagePath === void 0) throw new Error("muon-
|
|
3728
|
+
if (preparedRuntime.stagePath === void 0) throw new Error("muon-builder did not return a staged runtime path.");
|
|
2431
3729
|
const paths = await createRuntimePaths(server, preparedRuntime.stagePath, platform, await resolveProjectConfigPath(server));
|
|
2432
3730
|
await writeLaunchScript(paths, platform);
|
|
2433
3731
|
let cleanupPromise = void 0;
|
|
@@ -2453,63 +3751,8 @@ var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, archi
|
|
|
2453
3751
|
cleanup();
|
|
2454
3752
|
});
|
|
2455
3753
|
server.httpServer.once("listening", () => {
|
|
2456
|
-
if (writeMuonOverrideConfig(server, paths.overrideConfigPath, pluginOptions
|
|
2457
|
-
});
|
|
2458
|
-
};
|
|
2459
|
-
//#endregion
|
|
2460
|
-
//#region src/vite-options.ts
|
|
2461
|
-
/**
|
|
2462
|
-
* Metadata symbol used to recover `muon()` plugin options from `vite.config.*`.
|
|
2463
|
-
*/
|
|
2464
|
-
var muonVitePluginOptionsSymbol = Symbol.for("muon.vite.plugin.options");
|
|
2465
|
-
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2466
|
-
var isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
2467
|
-
var isMuonViteBuildOptions = (value) => {
|
|
2468
|
-
if (!isRecord(value)) return false;
|
|
2469
|
-
return (value.targets === void 0 || isStringArray(value.targets)) && (value.allTargets === void 0 || typeof value.allTargets === "boolean") && (value.appName === void 0 || typeof value.appName === "string") && (value.appId === void 0 || typeof value.appId === "string") && (value.outputRoot === void 0 || typeof value.outputRoot === "string") && (value.configPath === void 0 || typeof value.configPath === "string") && (value.packageDirectory === void 0 || typeof value.packageDirectory === "string") && (value.assetSalt === void 0 || value.assetSalt instanceof Uint8Array);
|
|
2470
|
-
};
|
|
2471
|
-
var isMuonVitePluginOptions = (value) => {
|
|
2472
|
-
if (!isRecord(value)) return false;
|
|
2473
|
-
return (value.muonPath === void 0 || typeof value.muonPath === "string") && (value.cefPath === void 0 || typeof value.cefPath === "string") && (value.stagePath === void 0 || typeof value.stagePath === "string") && (value.open === void 0 || typeof value.open === "boolean") && (value.enableDebugger === void 0 || typeof value.enableDebugger === "boolean") && (value.build === void 0 || typeof value.build === "boolean" || isMuonViteBuildOptions(value.build));
|
|
2474
|
-
};
|
|
2475
|
-
/**
|
|
2476
|
-
* Attaches raw Muon Vite plugin options to a plugin instance.
|
|
2477
|
-
*
|
|
2478
|
-
* @param plugin Plugin object.
|
|
2479
|
-
* @param options Raw plugin options.
|
|
2480
|
-
* @returns Plugin object with internal Muon metadata.
|
|
2481
|
-
*/
|
|
2482
|
-
var attachMuonVitePluginOptions = (plugin, options) => {
|
|
2483
|
-
Object.defineProperty(plugin, muonVitePluginOptionsSymbol, {
|
|
2484
|
-
configurable: false,
|
|
2485
|
-
enumerable: false,
|
|
2486
|
-
value: { ...options },
|
|
2487
|
-
writable: false
|
|
3754
|
+
if (writeMuonOverrideConfig(server, paths.overrideConfigPath, pluginOptions, getRuntimePluginConfig)) launchMuon(paths, platform, server);
|
|
2488
3755
|
});
|
|
2489
|
-
return plugin;
|
|
2490
|
-
};
|
|
2491
|
-
/**
|
|
2492
|
-
* Reads raw Muon Vite plugin options from a plugin instance.
|
|
2493
|
-
*
|
|
2494
|
-
* @param plugin Candidate plugin object.
|
|
2495
|
-
* @returns Attached Muon options, if present.
|
|
2496
|
-
*/
|
|
2497
|
-
var getMuonVitePluginOptions = (plugin) => {
|
|
2498
|
-
if (!isRecord(plugin)) return;
|
|
2499
|
-
const options = plugin[muonVitePluginOptionsSymbol];
|
|
2500
|
-
return isMuonVitePluginOptions(options) ? options : void 0;
|
|
2501
|
-
};
|
|
2502
|
-
/**
|
|
2503
|
-
* Resolves nested Vite plugin option values into a flat list.
|
|
2504
|
-
*
|
|
2505
|
-
* @param pluginOptions Raw `plugins` field from a Vite config.
|
|
2506
|
-
* @returns Flat plugin object list.
|
|
2507
|
-
*/
|
|
2508
|
-
var flattenVitePluginOptions = async (pluginOptions) => {
|
|
2509
|
-
const resolvedValue = await pluginOptions;
|
|
2510
|
-
if (resolvedValue === null || resolvedValue === void 0 || !resolvedValue) return [];
|
|
2511
|
-
if (Array.isArray(resolvedValue)) return (await Promise.all(resolvedValue.map((entry) => flattenVitePluginOptions(entry)))).flat();
|
|
2512
|
-
return [resolvedValue];
|
|
2513
3756
|
};
|
|
2514
3757
|
//#endregion
|
|
2515
3758
|
Object.defineProperty(exports, "__toESM", {
|
|
@@ -2518,6 +3761,12 @@ Object.defineProperty(exports, "__toESM", {
|
|
|
2518
3761
|
return __toESM;
|
|
2519
3762
|
}
|
|
2520
3763
|
});
|
|
3764
|
+
Object.defineProperty(exports, "allMuonTargets", {
|
|
3765
|
+
enumerable: true,
|
|
3766
|
+
get: function() {
|
|
3767
|
+
return allMuonTargets;
|
|
3768
|
+
}
|
|
3769
|
+
});
|
|
2521
3770
|
Object.defineProperty(exports, "attachMuonVitePluginOptions", {
|
|
2522
3771
|
enumerable: true,
|
|
2523
3772
|
get: function() {
|
|
@@ -2530,6 +3779,18 @@ Object.defineProperty(exports, "buildMuonApp", {
|
|
|
2530
3779
|
return buildMuonApp;
|
|
2531
3780
|
}
|
|
2532
3781
|
});
|
|
3782
|
+
Object.defineProperty(exports, "createLinuxDesktopEntry", {
|
|
3783
|
+
enumerable: true,
|
|
3784
|
+
get: function() {
|
|
3785
|
+
return createLinuxDesktopEntry;
|
|
3786
|
+
}
|
|
3787
|
+
});
|
|
3788
|
+
Object.defineProperty(exports, "createWindowsIconFromPngFile", {
|
|
3789
|
+
enumerable: true,
|
|
3790
|
+
get: function() {
|
|
3791
|
+
return createWindowsIconFromPngFile;
|
|
3792
|
+
}
|
|
3793
|
+
});
|
|
2533
3794
|
Object.defineProperty(exports, "embedMuonConfigInBootstrapFile", {
|
|
2534
3795
|
enumerable: true,
|
|
2535
3796
|
get: function() {
|
|
@@ -2560,6 +3821,12 @@ Object.defineProperty(exports, "flattenVitePluginOptions", {
|
|
|
2560
3821
|
return flattenVitePluginOptions;
|
|
2561
3822
|
}
|
|
2562
3823
|
});
|
|
3824
|
+
Object.defineProperty(exports, "getDefaultMuonBuildTarget", {
|
|
3825
|
+
enumerable: true,
|
|
3826
|
+
get: function() {
|
|
3827
|
+
return getDefaultMuonBuildTarget;
|
|
3828
|
+
}
|
|
3829
|
+
});
|
|
2563
3830
|
Object.defineProperty(exports, "getDefaultMuonPrepareTarget", {
|
|
2564
3831
|
enumerable: true,
|
|
2565
3832
|
get: function() {
|
|
@@ -2584,6 +3851,48 @@ Object.defineProperty(exports, "getMuonVitePluginOptions", {
|
|
|
2584
3851
|
return getMuonVitePluginOptions;
|
|
2585
3852
|
}
|
|
2586
3853
|
});
|
|
3854
|
+
Object.defineProperty(exports, "loadMuonBuildSequenceProject", {
|
|
3855
|
+
enumerable: true,
|
|
3856
|
+
get: function() {
|
|
3857
|
+
return loadMuonBuildSequenceProject;
|
|
3858
|
+
}
|
|
3859
|
+
});
|
|
3860
|
+
Object.defineProperty(exports, "mergeMuonLinuxDesktopOptions", {
|
|
3861
|
+
enumerable: true,
|
|
3862
|
+
get: function() {
|
|
3863
|
+
return mergeMuonLinuxDesktopOptions;
|
|
3864
|
+
}
|
|
3865
|
+
});
|
|
3866
|
+
Object.defineProperty(exports, "mergeMuonWindowsResourceOptions", {
|
|
3867
|
+
enumerable: true,
|
|
3868
|
+
get: function() {
|
|
3869
|
+
return mergeMuonWindowsResourceOptions;
|
|
3870
|
+
}
|
|
3871
|
+
});
|
|
3872
|
+
Object.defineProperty(exports, "muonBuildSequenceSuppressViteBuildEnvironmentKey", {
|
|
3873
|
+
enumerable: true,
|
|
3874
|
+
get: function() {
|
|
3875
|
+
return muonBuildSequenceSuppressViteBuildEnvironmentKey;
|
|
3876
|
+
}
|
|
3877
|
+
});
|
|
3878
|
+
Object.defineProperty(exports, "normalizeMuonTarget", {
|
|
3879
|
+
enumerable: true,
|
|
3880
|
+
get: function() {
|
|
3881
|
+
return normalizeMuonTarget;
|
|
3882
|
+
}
|
|
3883
|
+
});
|
|
3884
|
+
Object.defineProperty(exports, "quoteDesktopExecArgument", {
|
|
3885
|
+
enumerable: true,
|
|
3886
|
+
get: function() {
|
|
3887
|
+
return quoteDesktopExecArgument;
|
|
3888
|
+
}
|
|
3889
|
+
});
|
|
3890
|
+
Object.defineProperty(exports, "readMuonConfigForWindowsResource", {
|
|
3891
|
+
enumerable: true,
|
|
3892
|
+
get: function() {
|
|
3893
|
+
return readMuonConfigForWindowsResource;
|
|
3894
|
+
}
|
|
3895
|
+
});
|
|
2587
3896
|
Object.defineProperty(exports, "require_dist", {
|
|
2588
3897
|
enumerable: true,
|
|
2589
3898
|
get: function() {
|
|
@@ -2596,6 +3905,24 @@ Object.defineProperty(exports, "resolveMuonRuntimePath", {
|
|
|
2596
3905
|
return resolveMuonRuntimePath;
|
|
2597
3906
|
}
|
|
2598
3907
|
});
|
|
3908
|
+
Object.defineProperty(exports, "resolveMuonViteBuildOptions", {
|
|
3909
|
+
enumerable: true,
|
|
3910
|
+
get: function() {
|
|
3911
|
+
return resolveMuonViteBuildOptions;
|
|
3912
|
+
}
|
|
3913
|
+
});
|
|
3914
|
+
Object.defineProperty(exports, "resolveMuonWindowsResource", {
|
|
3915
|
+
enumerable: true,
|
|
3916
|
+
get: function() {
|
|
3917
|
+
return resolveMuonWindowsResource;
|
|
3918
|
+
}
|
|
3919
|
+
});
|
|
3920
|
+
Object.defineProperty(exports, "runMuonBuildSequence", {
|
|
3921
|
+
enumerable: true,
|
|
3922
|
+
get: function() {
|
|
3923
|
+
return runMuonBuildSequence;
|
|
3924
|
+
}
|
|
3925
|
+
});
|
|
2599
3926
|
Object.defineProperty(exports, "runMuonPrepare", {
|
|
2600
3927
|
enumerable: true,
|
|
2601
3928
|
get: function() {
|
|
@@ -2608,5 +3935,17 @@ Object.defineProperty(exports, "startMuonViteBrowserBridge", {
|
|
|
2608
3935
|
return startMuonViteBrowserBridge;
|
|
2609
3936
|
}
|
|
2610
3937
|
});
|
|
3938
|
+
Object.defineProperty(exports, "updateWindowsPeIconResource", {
|
|
3939
|
+
enumerable: true,
|
|
3940
|
+
get: function() {
|
|
3941
|
+
return updateWindowsPeIconResource;
|
|
3942
|
+
}
|
|
3943
|
+
});
|
|
3944
|
+
Object.defineProperty(exports, "updateWindowsPeResources", {
|
|
3945
|
+
enumerable: true,
|
|
3946
|
+
get: function() {
|
|
3947
|
+
return updateWindowsPeResources;
|
|
3948
|
+
}
|
|
3949
|
+
});
|
|
2611
3950
|
|
|
2612
|
-
//# sourceMappingURL=vite-
|
|
3951
|
+
//# sourceMappingURL=vite-internals-HXgH7b5M.cjs.map
|