craft-native 0.0.37 → 0.0.50
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/dist/android/src/index.js +268 -0
- package/dist/android/src/index.js.map +10 -0
- package/dist/android/templates/AndroidManifest.xml.template +69 -0
- package/dist/android/templates/CraftBridge.kt.template +3748 -0
- package/dist/android/templates/CraftBridgeExtensions.kt.template +383 -0
- package/dist/android/templates/CraftWidgetProvider.kt.template +246 -0
- package/dist/android/templates/MainActivity.kt.template +109 -0
- package/dist/android/templates/build.gradle.kts.app.template +80 -0
- package/dist/android/templates/build.gradle.kts.project.template +5 -0
- package/dist/android/templates/fastlane/Appfile +25 -0
- package/dist/android/templates/fastlane/Fastfile +192 -0
- package/dist/android/templates/fastlane/Gemfile +7 -0
- package/dist/android/templates/github-workflow-android.yml +248 -0
- package/dist/android/templates/github-workflow-test.yml +329 -0
- package/dist/android/templates/settings.gradle.kts.template +18 -0
- package/dist/android/templates/test-bridges.html +1463 -0
- package/dist/api/window.d.ts +18 -0
- package/dist/api/window.d.ts.map +1 -1
- package/dist/assets/index.d.ts.map +1 -1
- package/dist/bridge/core.d.ts +2 -0
- package/dist/bridge/core.d.ts.map +1 -1
- package/dist/cli.js +4168 -0
- package/dist/components/sidebar.d.ts +5 -1
- package/dist/components/sidebar.d.ts.map +1 -1
- package/dist/dev/devtools.d.ts +1 -1
- package/dist/dev/devtools.d.ts.map +1 -1
- package/dist/dev/hot-reload.d.ts +12 -3
- package/dist/dev/hot-reload.d.ts.map +1 -1
- package/dist/index.cjs +575 -208
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +587 -216
- package/dist/index.js.map +45 -0
- package/dist/ios/src/index.js +186 -0
- package/dist/ios/src/index.js.map +10 -0
- package/dist/ios/templates/CraftApp.swift +4241 -0
- package/dist/ios/templates/CraftAppExtensions.swift +361 -0
- package/dist/ios/templates/CraftWidget.swift +247 -0
- package/dist/ios/templates/Info.plist.template +65 -0
- package/dist/ios/templates/fastlane/Appfile +45 -0
- package/dist/ios/templates/fastlane/Fastfile +189 -0
- package/dist/ios/templates/fastlane/Gemfile +7 -0
- package/dist/ios/templates/fastlane/Matchfile +58 -0
- package/dist/ios/templates/github-workflow-ios.yml +192 -0
- package/dist/ios/templates/github-workflow-release.yml +175 -0
- package/dist/ios/templates/github-workflow-test.yml +272 -0
- package/dist/ios/templates/project.yml.template +25 -0
- package/dist/ios/templates/test-bridges.html +1463 -0
- package/dist/package.d.ts +106 -2
- package/dist/package.d.ts.map +1 -1
- package/dist/package.test.d.ts +2 -0
- package/dist/package.test.d.ts.map +1 -0
- package/dist/styles/sidebar-templates.d.ts.map +1 -1
- package/dist/styles/sidebars.d.ts +12 -8
- package/dist/styles/sidebars.d.ts.map +1 -1
- package/dist/templates/projects/blank/craft.config.ts +19 -0
- package/dist/templates/projects/blank/index.html +27 -0
- package/dist/templates/projects/blank/package.json +19 -0
- package/dist/templates/projects/blank/src/main.ts +26 -0
- package/dist/templates/projects/dashboard/craft.config.ts +42 -0
- package/dist/templates/projects/dashboard/index.html +13 -0
- package/dist/templates/projects/dashboard/package.json +20 -0
- package/dist/templates/projects/dashboard/src/main.ts +163 -0
- package/dist/templates/projects/dashboard/src/styles.css +280 -0
- package/dist/templates/projects/drawer/craft.config.ts +47 -0
- package/dist/templates/projects/drawer/index.html +13 -0
- package/dist/templates/projects/drawer/package.json +21 -0
- package/dist/templates/projects/drawer/src/main.ts +406 -0
- package/dist/templates/projects/drawer/src/styles.css +468 -0
- package/dist/templates/projects/ecommerce/craft.config.ts +32 -0
- package/dist/templates/projects/ecommerce/index.html +13 -0
- package/dist/templates/projects/ecommerce/package.json +19 -0
- package/dist/templates/projects/ecommerce/src/main.ts +194 -0
- package/dist/templates/projects/ecommerce/src/styles.css +169 -0
- package/dist/templates/projects/social/craft.config.ts +32 -0
- package/dist/templates/projects/social/index.html +13 -0
- package/dist/templates/projects/social/package.json +19 -0
- package/dist/templates/projects/social/src/main.ts +270 -0
- package/dist/templates/projects/social/src/styles.css +216 -0
- package/dist/templates/projects/tabs/craft.config.ts +47 -0
- package/dist/templates/projects/tabs/index.html +13 -0
- package/dist/templates/projects/tabs/package.json +21 -0
- package/dist/templates/projects/tabs/src/main.ts +177 -0
- package/dist/templates/projects/tabs/src/styles.css +163 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/updater/index.d.ts +1 -0
- package/dist/updater/index.d.ts.map +1 -1
- package/package.json +5 -12
- package/bin/cli.ts +0 -937
package/dist/index.cjs
CHANGED
|
@@ -108,6 +108,7 @@ __export(exports_src, {
|
|
|
108
108
|
secureStorage: () => secureStorage,
|
|
109
109
|
secondaryTiles: () => secondaryTiles,
|
|
110
110
|
saveFile: () => saveFile,
|
|
111
|
+
resolveCraftBinary: () => resolveCraftBinary,
|
|
111
112
|
requireCraftRuntime: () => requireCraftRuntime,
|
|
112
113
|
renderTahoeSidebar: () => renderTahoeSidebar,
|
|
113
114
|
renderOrbStackSidebar: () => renderOrbStackSidebar,
|
|
@@ -177,7 +178,7 @@ __export(exports_src, {
|
|
|
177
178
|
focusFilters: () => focusFilters,
|
|
178
179
|
focus: () => focus,
|
|
179
180
|
exit: () => exit,
|
|
180
|
-
exec: () =>
|
|
181
|
+
exec: () => exec,
|
|
181
182
|
env: () => env,
|
|
182
183
|
dialog: () => dialog,
|
|
183
184
|
device: () => device,
|
|
@@ -202,6 +203,7 @@ __export(exports_src, {
|
|
|
202
203
|
createArcSidebar: () => createArcSidebar,
|
|
203
204
|
createApp: () => createApp,
|
|
204
205
|
craftUnavailableMessage: () => craftUnavailableMessage,
|
|
206
|
+
craftBinaryNotFoundMessage: () => craftBinaryNotFoundMessage,
|
|
205
207
|
copy: () => copy,
|
|
206
208
|
components: () => exports_components,
|
|
207
209
|
commonOptimizations: () => commonOptimizations,
|
|
@@ -290,16 +292,90 @@ function craftBinaryNotFoundMessage(triedPath) {
|
|
|
290
292
|
|
|
291
293
|
// src/package.ts
|
|
292
294
|
var import_child_process = require("child_process");
|
|
295
|
+
var import_crypto = require("crypto");
|
|
293
296
|
var import_fs = require("fs");
|
|
294
297
|
var import_os = require("os");
|
|
295
298
|
var import_path = require("path");
|
|
296
|
-
var
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
299
|
+
var import_zlib = require("zlib");
|
|
300
|
+
var CRC32_TABLE = (() => {
|
|
301
|
+
const table = new Uint32Array(256);
|
|
302
|
+
for (let n = 0;n < 256; n++) {
|
|
303
|
+
let c = n;
|
|
304
|
+
for (let k = 0;k < 8; k++)
|
|
305
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
306
|
+
table[n] = c >>> 0;
|
|
307
|
+
}
|
|
308
|
+
return table;
|
|
309
|
+
})();
|
|
310
|
+
function crc32(data) {
|
|
311
|
+
let c = 4294967295;
|
|
312
|
+
for (let i = 0;i < data.length; i++)
|
|
313
|
+
c = CRC32_TABLE[(c ^ data[i]) & 255] ^ c >>> 8;
|
|
314
|
+
return (c ^ 4294967295) >>> 0;
|
|
315
|
+
}
|
|
316
|
+
function dosDateTime(d) {
|
|
317
|
+
const time = d.getHours() << 11 | d.getMinutes() << 5 | d.getSeconds() >> 1;
|
|
318
|
+
const date = d.getFullYear() - 1980 << 9 | d.getMonth() + 1 << 5 | d.getDate();
|
|
319
|
+
return { time: time & 65535, date: date & 65535 };
|
|
320
|
+
}
|
|
321
|
+
function buildZip(entries) {
|
|
322
|
+
const { time, date } = dosDateTime(new Date);
|
|
323
|
+
const locals = [];
|
|
324
|
+
const central = [];
|
|
325
|
+
let offset = 0;
|
|
326
|
+
for (const entry of entries) {
|
|
327
|
+
const nameBytes = Buffer.from(entry.name, "utf8");
|
|
328
|
+
const compressed = import_zlib.deflateRawSync(entry.data, { level: 9 });
|
|
329
|
+
const crc = crc32(entry.data);
|
|
330
|
+
const lfh = Buffer.alloc(30);
|
|
331
|
+
lfh.writeUInt32LE(67324752, 0);
|
|
332
|
+
lfh.writeUInt16LE(20, 4);
|
|
333
|
+
lfh.writeUInt16LE(0, 6);
|
|
334
|
+
lfh.writeUInt16LE(8, 8);
|
|
335
|
+
lfh.writeUInt16LE(time, 10);
|
|
336
|
+
lfh.writeUInt16LE(date, 12);
|
|
337
|
+
lfh.writeUInt32LE(crc, 14);
|
|
338
|
+
lfh.writeUInt32LE(compressed.length, 18);
|
|
339
|
+
lfh.writeUInt32LE(entry.data.length, 22);
|
|
340
|
+
lfh.writeUInt16LE(nameBytes.length, 26);
|
|
341
|
+
lfh.writeUInt16LE(0, 28);
|
|
342
|
+
locals.push(lfh, nameBytes, compressed);
|
|
343
|
+
const cdh = Buffer.alloc(46);
|
|
344
|
+
cdh.writeUInt32LE(33639248, 0);
|
|
345
|
+
cdh.writeUInt16LE(20, 4);
|
|
346
|
+
cdh.writeUInt16LE(20, 6);
|
|
347
|
+
cdh.writeUInt16LE(0, 8);
|
|
348
|
+
cdh.writeUInt16LE(8, 10);
|
|
349
|
+
cdh.writeUInt16LE(time, 12);
|
|
350
|
+
cdh.writeUInt16LE(date, 14);
|
|
351
|
+
cdh.writeUInt32LE(crc, 16);
|
|
352
|
+
cdh.writeUInt32LE(compressed.length, 20);
|
|
353
|
+
cdh.writeUInt32LE(entry.data.length, 24);
|
|
354
|
+
cdh.writeUInt16LE(nameBytes.length, 28);
|
|
355
|
+
cdh.writeUInt16LE(0, 30);
|
|
356
|
+
cdh.writeUInt16LE(0, 32);
|
|
357
|
+
cdh.writeUInt16LE(0, 34);
|
|
358
|
+
cdh.writeUInt16LE(0, 36);
|
|
359
|
+
cdh.writeUInt32LE(0, 38);
|
|
360
|
+
cdh.writeUInt32LE(offset, 42);
|
|
361
|
+
central.push(cdh, nameBytes);
|
|
362
|
+
offset += lfh.length + nameBytes.length + compressed.length;
|
|
363
|
+
}
|
|
364
|
+
const centralBuf = Buffer.concat(central);
|
|
365
|
+
const eocd = Buffer.alloc(22);
|
|
366
|
+
eocd.writeUInt32LE(101010256, 0);
|
|
367
|
+
eocd.writeUInt16LE(0, 4);
|
|
368
|
+
eocd.writeUInt16LE(0, 6);
|
|
369
|
+
eocd.writeUInt16LE(entries.length, 8);
|
|
370
|
+
eocd.writeUInt16LE(entries.length, 10);
|
|
371
|
+
eocd.writeUInt32LE(centralBuf.length, 12);
|
|
372
|
+
eocd.writeUInt32LE(offset, 16);
|
|
373
|
+
eocd.writeUInt16LE(0, 20);
|
|
374
|
+
return Buffer.concat([...locals, centralBuf, eocd]);
|
|
375
|
+
}
|
|
376
|
+
function formatPackagingCommandError(tool, code, stdout, stderr) {
|
|
377
|
+
const detail = `${stdout}${stderr}`.trim();
|
|
378
|
+
return `${tool} exited with code ${code}${detail ? `: ${detail}` : ""}`;
|
|
303
379
|
}
|
|
304
380
|
async function packageApp(config) {
|
|
305
381
|
const results = [];
|
|
@@ -330,13 +406,20 @@ async function packageMacOS(config, outDir) {
|
|
|
330
406
|
const results = [];
|
|
331
407
|
const { name, version, bundleId = `com.myapp.${name.toLowerCase()}` } = config;
|
|
332
408
|
const opts = config.macos || {};
|
|
409
|
+
const hardenedRuntime = !opts.appStore;
|
|
333
410
|
const appBundlePath = import_path.join(outDir, `${name}.app`);
|
|
334
411
|
const appBundle = createMacOSAppBundle({
|
|
335
412
|
name,
|
|
336
413
|
version,
|
|
337
414
|
bundleId,
|
|
415
|
+
buildNumber: opts.buildNumber,
|
|
416
|
+
category: opts.category,
|
|
417
|
+
minimumSystemVersion: opts.minimumSystemVersion,
|
|
418
|
+
menuBarOnly: opts.menuBarOnly,
|
|
338
419
|
binaryPath: config.binaryPath,
|
|
339
420
|
iconPath: config.iconPath,
|
|
421
|
+
provisioningProfile: opts.provisioningProfile,
|
|
422
|
+
additionalExecutables: opts.additionalExecutables,
|
|
340
423
|
outputPath: appBundlePath
|
|
341
424
|
});
|
|
342
425
|
if (!appBundle.success) {
|
|
@@ -348,12 +431,30 @@ async function packageMacOS(config, outDir) {
|
|
|
348
431
|
});
|
|
349
432
|
return results;
|
|
350
433
|
}
|
|
351
|
-
if (opts.
|
|
352
|
-
const
|
|
353
|
-
appBundlePath,
|
|
354
|
-
|
|
355
|
-
|
|
434
|
+
if (opts.signIdentity) {
|
|
435
|
+
const signed = await runTool("codesign", codesignArguments({
|
|
436
|
+
path: appBundlePath,
|
|
437
|
+
identity: opts.signIdentity,
|
|
438
|
+
entitlements: opts.entitlements,
|
|
439
|
+
hardenedRuntime
|
|
440
|
+
}));
|
|
441
|
+
if (!signed.success) {
|
|
442
|
+
results.push({ success: false, platform: "macos", format: "app", error: signed.error });
|
|
443
|
+
return results;
|
|
444
|
+
}
|
|
445
|
+
} else if (opts.appStore) {
|
|
446
|
+
results.push({
|
|
447
|
+
success: false,
|
|
448
|
+
platform: "macos",
|
|
449
|
+
format: "pkg",
|
|
450
|
+
error: 'App Store packaging requires macos.signIdentity (a "3rd Party Mac Developer Application" identity)'
|
|
356
451
|
});
|
|
452
|
+
return results;
|
|
453
|
+
}
|
|
454
|
+
results.push({ success: true, platform: "macos", format: "app", outputPath: appBundlePath });
|
|
455
|
+
if (opts.dmg !== false) {
|
|
456
|
+
const outputPath = import_path.join(outDir, `${name}-${version}.dmg`);
|
|
457
|
+
const dmgResult = await createDMG({ appBundlePath, outputPath, volumeName: name });
|
|
357
458
|
results.push({
|
|
358
459
|
success: dmgResult.success,
|
|
359
460
|
platform: "macos",
|
|
@@ -361,24 +462,59 @@ async function packageMacOS(config, outDir) {
|
|
|
361
462
|
outputPath: dmgResult.outputPath,
|
|
362
463
|
error: dmgResult.error
|
|
363
464
|
});
|
|
465
|
+
if (dmgResult.success)
|
|
466
|
+
results.push(...await notarizeIfRequested(opts, outputPath, "dmg"));
|
|
364
467
|
}
|
|
365
|
-
if (opts.pkg) {
|
|
468
|
+
if (opts.pkg || opts.appStore) {
|
|
469
|
+
const outputPath = import_path.join(outDir, `${name}-${version}.pkg`);
|
|
366
470
|
const pkgResult = await createPKG({
|
|
367
471
|
appBundlePath,
|
|
368
|
-
outputPath
|
|
472
|
+
outputPath,
|
|
369
473
|
identifier: bundleId,
|
|
370
|
-
version
|
|
474
|
+
version,
|
|
475
|
+
appStore: opts.appStore === true,
|
|
476
|
+
installerIdentity: opts.installerIdentity
|
|
371
477
|
});
|
|
372
478
|
results.push({
|
|
373
479
|
success: pkgResult.success,
|
|
374
480
|
platform: "macos",
|
|
375
|
-
format: "pkg",
|
|
481
|
+
format: opts.appStore ? "pkg (app store)" : "pkg",
|
|
376
482
|
outputPath: pkgResult.outputPath,
|
|
377
483
|
error: pkgResult.error
|
|
378
484
|
});
|
|
485
|
+
if (pkgResult.success && !opts.appStore)
|
|
486
|
+
results.push(...await notarizeIfRequested(opts, outputPath, "pkg"));
|
|
379
487
|
}
|
|
380
488
|
return results;
|
|
381
489
|
}
|
|
490
|
+
async function notarizeIfRequested(opts, artifactPath, format) {
|
|
491
|
+
if (!opts.notarize)
|
|
492
|
+
return [];
|
|
493
|
+
if (!opts.appleId || !opts.applePassword || !opts.teamId) {
|
|
494
|
+
return [{
|
|
495
|
+
success: false,
|
|
496
|
+
platform: "macos",
|
|
497
|
+
format: `${format} (notarize)`,
|
|
498
|
+
error: "Notarization requires macos.appleId, macos.applePassword and macos.teamId"
|
|
499
|
+
}];
|
|
500
|
+
}
|
|
501
|
+
const submitted = await runTool("xcrun", notarytoolArguments({
|
|
502
|
+
artifactPath,
|
|
503
|
+
appleId: opts.appleId,
|
|
504
|
+
applePassword: opts.applePassword,
|
|
505
|
+
teamId: opts.teamId
|
|
506
|
+
}));
|
|
507
|
+
if (!submitted.success)
|
|
508
|
+
return [{ success: false, platform: "macos", format: `${format} (notarize)`, error: submitted.error }];
|
|
509
|
+
const stapled = await runTool("xcrun", ["stapler", "staple", artifactPath]);
|
|
510
|
+
return [{
|
|
511
|
+
success: stapled.success,
|
|
512
|
+
platform: "macos",
|
|
513
|
+
format: `${format} (notarize)`,
|
|
514
|
+
outputPath: stapled.success ? artifactPath : undefined,
|
|
515
|
+
error: stapled.success ? undefined : stapled.error
|
|
516
|
+
}];
|
|
517
|
+
}
|
|
382
518
|
async function packageWindows(config, outDir) {
|
|
383
519
|
const results = [];
|
|
384
520
|
const { name, version } = config;
|
|
@@ -389,7 +525,10 @@ async function packageWindows(config, outDir) {
|
|
|
389
525
|
version,
|
|
390
526
|
binaryPath: config.binaryPath,
|
|
391
527
|
outputPath: import_path.join(outDir, `${name}-${version}.msi`),
|
|
392
|
-
manufacturer: config.author || "Unknown"
|
|
528
|
+
manufacturer: config.author || "Unknown",
|
|
529
|
+
architecture: opts.architecture || windowsArchitecture(process.arch),
|
|
530
|
+
certificatePath: opts.certificatePath,
|
|
531
|
+
certificatePassword: opts.certificatePassword
|
|
393
532
|
});
|
|
394
533
|
results.push({
|
|
395
534
|
success: msiResult.success,
|
|
@@ -473,83 +612,200 @@ async function packageLinux(config, outDir) {
|
|
|
473
612
|
}
|
|
474
613
|
return results;
|
|
475
614
|
}
|
|
476
|
-
function
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
615
|
+
function macOSInfoPlist(metadata) {
|
|
616
|
+
const entries = [
|
|
617
|
+
["CFBundleExecutable", metadata.name],
|
|
618
|
+
["CFBundleIdentifier", metadata.bundleId],
|
|
619
|
+
["CFBundleName", metadata.name],
|
|
620
|
+
["CFBundleShortVersionString", metadata.version],
|
|
621
|
+
["CFBundleVersion", metadata.buildNumber || metadata.version],
|
|
622
|
+
["CFBundlePackageType", "APPL"],
|
|
623
|
+
["NSHighResolutionCapable", true]
|
|
624
|
+
];
|
|
625
|
+
if (metadata.iconName)
|
|
626
|
+
entries.push(["CFBundleIconFile", metadata.iconName]);
|
|
627
|
+
if (metadata.category)
|
|
628
|
+
entries.push(["LSApplicationCategoryType", metadata.category]);
|
|
629
|
+
if (metadata.minimumSystemVersion)
|
|
630
|
+
entries.push(["LSMinimumSystemVersion", metadata.minimumSystemVersion]);
|
|
631
|
+
if (metadata.menuBarOnly)
|
|
632
|
+
entries.push(["LSUIElement", true]);
|
|
633
|
+
const body = entries.map(([key, value]) => ` <key>${xml(key)}</key>
|
|
634
|
+
${value === true ? " <true/>" : ` <string>${xml(value)}</string>`}`).join(`
|
|
635
|
+
`);
|
|
636
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
484
637
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
485
638
|
<plist version="1.0">
|
|
486
639
|
<dict>
|
|
487
|
-
|
|
488
|
-
<string>${name}</string>
|
|
489
|
-
<key>CFBundleIdentifier</key>
|
|
490
|
-
<string>${bundleId}</string>
|
|
491
|
-
<key>CFBundleName</key>
|
|
492
|
-
<string>${name}</string>
|
|
493
|
-
<key>CFBundleShortVersionString</key>
|
|
494
|
-
<string>${version}</string>
|
|
495
|
-
<key>CFBundleVersion</key>
|
|
496
|
-
<string>${version}</string>
|
|
497
|
-
<key>CFBundlePackageType</key>
|
|
498
|
-
<string>APPL</string>
|
|
499
|
-
<key>NSHighResolutionCapable</key>
|
|
500
|
-
<true/>
|
|
640
|
+
${body}
|
|
501
641
|
</dict>
|
|
502
642
|
</plist>`;
|
|
503
|
-
|
|
643
|
+
}
|
|
644
|
+
function codesignArguments(opts) {
|
|
645
|
+
return [
|
|
646
|
+
"--force",
|
|
647
|
+
"--sign",
|
|
648
|
+
opts.identity,
|
|
649
|
+
"--timestamp",
|
|
650
|
+
...opts.hardenedRuntime ? ["--options", "runtime"] : [],
|
|
651
|
+
...opts.entitlements ? ["--entitlements", opts.entitlements] : [],
|
|
652
|
+
"--deep",
|
|
653
|
+
opts.path
|
|
654
|
+
];
|
|
655
|
+
}
|
|
656
|
+
function productbuildArguments(opts) {
|
|
657
|
+
return [
|
|
658
|
+
"--component",
|
|
659
|
+
opts.appBundlePath,
|
|
660
|
+
"/Applications",
|
|
661
|
+
"--sign",
|
|
662
|
+
opts.identity,
|
|
663
|
+
opts.outputPath
|
|
664
|
+
];
|
|
665
|
+
}
|
|
666
|
+
function notarytoolArguments(opts) {
|
|
667
|
+
return [
|
|
668
|
+
"notarytool",
|
|
669
|
+
"submit",
|
|
670
|
+
opts.artifactPath,
|
|
671
|
+
"--apple-id",
|
|
672
|
+
opts.appleId,
|
|
673
|
+
"--password",
|
|
674
|
+
opts.applePassword,
|
|
675
|
+
"--team-id",
|
|
676
|
+
opts.teamId,
|
|
677
|
+
"--wait"
|
|
678
|
+
];
|
|
679
|
+
}
|
|
680
|
+
function createMacOSAppBundle(opts) {
|
|
681
|
+
try {
|
|
682
|
+
const { name, binaryPath, iconPath, provisioningProfile, additionalExecutables, outputPath } = opts;
|
|
683
|
+
const contents = import_path.join(outputPath, "Contents");
|
|
684
|
+
const macOS = import_path.join(contents, "MacOS");
|
|
685
|
+
import_fs.mkdirSync(macOS, { recursive: true });
|
|
686
|
+
import_fs.mkdirSync(import_path.join(contents, "Resources"), { recursive: true });
|
|
687
|
+
import_fs.copyFileSync(binaryPath, import_path.join(macOS, name));
|
|
688
|
+
import_fs.chmodSync(import_path.join(macOS, name), 493);
|
|
689
|
+
for (const executable of additionalExecutables || []) {
|
|
690
|
+
if (!import_fs.existsSync(executable))
|
|
691
|
+
return { success: false, error: `Additional executable not found: ${executable}` };
|
|
692
|
+
const destination = import_path.join(macOS, import_path.basename(executable));
|
|
693
|
+
import_fs.copyFileSync(executable, destination);
|
|
694
|
+
import_fs.chmodSync(destination, 493);
|
|
695
|
+
}
|
|
696
|
+
let iconName;
|
|
697
|
+
if (iconPath) {
|
|
698
|
+
if (!import_fs.existsSync(iconPath))
|
|
699
|
+
return { success: false, error: `Icon not found: ${iconPath}` };
|
|
700
|
+
iconName = import_path.basename(iconPath).replace(/\.icns$/i, "");
|
|
701
|
+
import_fs.copyFileSync(iconPath, import_path.join(contents, "Resources", `${iconName}.icns`));
|
|
702
|
+
}
|
|
703
|
+
if (provisioningProfile) {
|
|
704
|
+
if (!import_fs.existsSync(provisioningProfile))
|
|
705
|
+
return { success: false, error: `Provisioning profile not found: ${provisioningProfile}` };
|
|
706
|
+
import_fs.copyFileSync(provisioningProfile, import_path.join(contents, "embedded.provisionprofile"));
|
|
707
|
+
}
|
|
708
|
+
import_fs.writeFileSync(import_path.join(contents, "Info.plist"), macOSInfoPlist({ ...opts, iconName }));
|
|
504
709
|
return { success: true };
|
|
505
710
|
} catch (error) {
|
|
506
711
|
return { success: false, error: error.message };
|
|
507
712
|
}
|
|
508
713
|
}
|
|
509
|
-
|
|
714
|
+
var MEBIBYTE = 1024 * 1024;
|
|
715
|
+
function pathContentBytes(path) {
|
|
716
|
+
const stat = import_fs.lstatSync(path);
|
|
717
|
+
if (!stat.isDirectory())
|
|
718
|
+
return stat.size;
|
|
719
|
+
return import_fs.readdirSync(path).reduce((total, entry) => total + pathContentBytes(import_path.join(path, entry)), 0);
|
|
720
|
+
}
|
|
721
|
+
function dmgCapacityMegabytes(contentBytes) {
|
|
722
|
+
if (!Number.isSafeInteger(contentBytes) || contentBytes < 0)
|
|
723
|
+
throw new Error(`DMG content size must be a non-negative safe integer: ${contentBytes}`);
|
|
724
|
+
const contentMegabytes = Math.ceil(contentBytes / MEBIBYTE);
|
|
725
|
+
return Math.max(64, Math.ceil(contentMegabytes * 1.25) + 32);
|
|
726
|
+
}
|
|
727
|
+
function dmgCreateArguments(opts, contentBytes) {
|
|
728
|
+
return [
|
|
729
|
+
"create",
|
|
730
|
+
"-volname",
|
|
731
|
+
opts.volumeName,
|
|
732
|
+
"-srcfolder",
|
|
733
|
+
opts.appBundlePath,
|
|
734
|
+
"-size",
|
|
735
|
+
`${dmgCapacityMegabytes(contentBytes)}m`,
|
|
736
|
+
"-ov",
|
|
737
|
+
"-format",
|
|
738
|
+
"UDZO",
|
|
739
|
+
opts.outputPath
|
|
740
|
+
];
|
|
741
|
+
}
|
|
742
|
+
var HDIUTIL_MAX_ATTEMPTS = 3;
|
|
743
|
+
function shouldRetryHdiutil(error, attempt, maxAttempts = HDIUTIL_MAX_ATTEMPTS) {
|
|
744
|
+
if (!Number.isInteger(attempt) || attempt < 1 || !Number.isInteger(maxAttempts) || maxAttempts < 1)
|
|
745
|
+
throw new Error("hdiutil retry attempts must be positive integers");
|
|
746
|
+
return attempt < maxAttempts && /(?:resource busy|resource temporarily unavailable)/i.test(error);
|
|
747
|
+
}
|
|
748
|
+
function runTool(tool, args) {
|
|
510
749
|
return new Promise((resolve) => {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
"create",
|
|
517
|
-
"-volname",
|
|
518
|
-
opts.volumeName,
|
|
519
|
-
"-srcfolder",
|
|
520
|
-
opts.appBundlePath,
|
|
521
|
-
"-ov",
|
|
522
|
-
"-format",
|
|
523
|
-
"UDZO",
|
|
524
|
-
opts.outputPath
|
|
525
|
-
]);
|
|
526
|
-
proc.on("close", (code) => {
|
|
527
|
-
if (code === 0) {
|
|
528
|
-
resolve({ success: true, outputPath: opts.outputPath });
|
|
529
|
-
} else {
|
|
530
|
-
resolve({ success: false, error: `hdiutil exited with code ${code}` });
|
|
531
|
-
}
|
|
750
|
+
const proc = import_child_process.spawn(tool, args);
|
|
751
|
+
let stdout = "";
|
|
752
|
+
let stderr = "";
|
|
753
|
+
proc.stdout?.on("data", (chunk) => {
|
|
754
|
+
stdout += chunk.toString();
|
|
532
755
|
});
|
|
533
|
-
proc.on("
|
|
534
|
-
|
|
756
|
+
proc.stderr?.on("data", (chunk) => {
|
|
757
|
+
stderr += chunk.toString();
|
|
535
758
|
});
|
|
759
|
+
proc.on("close", (code) => {
|
|
760
|
+
if (code === 0)
|
|
761
|
+
resolve({ success: true });
|
|
762
|
+
else
|
|
763
|
+
resolve({ success: false, error: formatPackagingCommandError(tool, code, stdout, stderr) });
|
|
764
|
+
});
|
|
765
|
+
proc.on("error", (err) => resolve({ success: false, error: err.message }));
|
|
536
766
|
});
|
|
537
767
|
}
|
|
768
|
+
var runHdiutil = (args) => runTool("hdiutil", args);
|
|
769
|
+
async function createDMG(opts) {
|
|
770
|
+
if (!/^[^/:\n]{1,27}$/.test(opts.volumeName))
|
|
771
|
+
return { success: false, error: `Invalid DMG volume name "${opts.volumeName}"; must be 1..27 chars without /, :, or newline` };
|
|
772
|
+
const args = dmgCreateArguments(opts, pathContentBytes(opts.appBundlePath));
|
|
773
|
+
const failures = [];
|
|
774
|
+
for (let attempt = 1;attempt <= HDIUTIL_MAX_ATTEMPTS; attempt++) {
|
|
775
|
+
const result = await runHdiutil(args);
|
|
776
|
+
if (result.success)
|
|
777
|
+
return { success: true, outputPath: opts.outputPath };
|
|
778
|
+
failures.push(`attempt ${attempt}: ${result.error}`);
|
|
779
|
+
if (!shouldRetryHdiutil(result.error, attempt))
|
|
780
|
+
return { success: false, error: failures.join(`
|
|
781
|
+
`) };
|
|
782
|
+
import_fs.rmSync(opts.outputPath, { force: true });
|
|
783
|
+
await new Promise((resolve) => setTimeout(resolve, attempt * 2000));
|
|
784
|
+
}
|
|
785
|
+
return { success: false, error: failures.join(`
|
|
786
|
+
`) };
|
|
787
|
+
}
|
|
538
788
|
async function createPKG(opts) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
789
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(opts.identifier) || !opts.identifier.includes("."))
|
|
790
|
+
return { success: false, error: `Invalid pkg identifier "${opts.identifier}"; expected reverse-DNS like com.example.app` };
|
|
791
|
+
if (!/^[A-Za-z0-9._+-]+$/.test(opts.version))
|
|
792
|
+
return { success: false, error: `Invalid pkg version "${opts.version}"` };
|
|
793
|
+
if (opts.appStore) {
|
|
794
|
+
if (!opts.installerIdentity)
|
|
795
|
+
return { success: false, error: 'App Store packaging requires macos.installerIdentity (a "3rd Party Mac Developer Installer" identity)' };
|
|
796
|
+
const built = await runTool("productbuild", productbuildArguments({
|
|
797
|
+
appBundlePath: opts.appBundlePath,
|
|
798
|
+
outputPath: opts.outputPath,
|
|
799
|
+
identity: opts.installerIdentity
|
|
800
|
+
}));
|
|
801
|
+
return built.success ? { success: true, outputPath: opts.outputPath } : { success: false, error: built.error };
|
|
802
|
+
}
|
|
803
|
+
const tempDir = import_fs.mkdtempSync(import_path.join(import_os.tmpdir(), "craft-pkg-"));
|
|
804
|
+
try {
|
|
549
805
|
const appsDir = import_path.join(tempDir, "Applications");
|
|
550
806
|
import_fs.mkdirSync(appsDir, { recursive: true });
|
|
551
807
|
import_fs.cpSync(opts.appBundlePath, import_path.join(appsDir, import_path.basename(opts.appBundlePath)), { recursive: true });
|
|
552
|
-
const
|
|
808
|
+
const built = await runTool("pkgbuild", [
|
|
553
809
|
"--root",
|
|
554
810
|
tempDir,
|
|
555
811
|
"--identifier",
|
|
@@ -558,64 +814,116 @@ async function createPKG(opts) {
|
|
|
558
814
|
opts.version,
|
|
559
815
|
"--install-location",
|
|
560
816
|
"/",
|
|
817
|
+
...opts.installerIdentity ? ["--sign", opts.installerIdentity] : [],
|
|
561
818
|
opts.outputPath
|
|
562
819
|
]);
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
820
|
+
return built.success ? { success: true, outputPath: opts.outputPath } : { success: false, error: built.error };
|
|
821
|
+
} finally {
|
|
822
|
+
import_fs.rmSync(tempDir, { recursive: true, force: true });
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
function xml(value) {
|
|
826
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll(`'`, "'");
|
|
827
|
+
}
|
|
828
|
+
function wixIdentifier(value) {
|
|
829
|
+
const sanitized = value.replace(/[^A-Za-z0-9_.]/g, "_");
|
|
830
|
+
return /^[A-Za-z_]/.test(sanitized) ? sanitized : `_${sanitized}`;
|
|
831
|
+
}
|
|
832
|
+
function deterministicGuid(value) {
|
|
833
|
+
const digest = import_crypto.createHash("sha256").update(value).digest("hex").slice(0, 32).split("");
|
|
834
|
+
digest[12] = "4";
|
|
835
|
+
digest[16] = (Number.parseInt(digest[16], 16) & 3 | 8).toString(16);
|
|
836
|
+
const hex = digest.join("").toUpperCase();
|
|
837
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
838
|
+
}
|
|
839
|
+
function windowsArchitecture(architecture) {
|
|
840
|
+
if (architecture === "ia32" || architecture === "x86")
|
|
841
|
+
return "x86";
|
|
842
|
+
if (architecture === "x64" || architecture === "arm64")
|
|
843
|
+
return architecture;
|
|
844
|
+
throw new Error(`Unsupported Windows package architecture: ${architecture}`);
|
|
845
|
+
}
|
|
846
|
+
function renderWixSource(opts, sourceName) {
|
|
847
|
+
if (!/^[0-9]+\.[0-9]+\.[0-9]+(?:\.[0-9]+)?$/.test(opts.version))
|
|
848
|
+
throw new Error(`MSI version must have 3 or 4 numeric parts: ${opts.version}`);
|
|
849
|
+
const id = wixIdentifier(opts.name);
|
|
850
|
+
const manufacturer = opts.manufacturer.trim() || "Unknown";
|
|
851
|
+
const upgradeCode = deterministicGuid(`${manufacturer}/${opts.name}`);
|
|
852
|
+
const programFilesFolder = opts.architecture === "x86" ? "ProgramFilesFolder" : "ProgramFiles64Folder";
|
|
853
|
+
const win64 = opts.architecture === "x86" ? "no" : "yes";
|
|
854
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
855
|
+
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
|
856
|
+
<Product Id="*" Name="${xml(opts.name)}" Language="1033" Version="${opts.version}" Manufacturer="${xml(manufacturer)}" UpgradeCode="${upgradeCode}">
|
|
857
|
+
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" Platform="${opts.architecture}" />
|
|
858
|
+
<MajorUpgrade AllowDowngrades="yes" />
|
|
859
|
+
<MediaTemplate EmbedCab="yes" />
|
|
860
|
+
<Directory Id="TARGETDIR" Name="SourceDir">
|
|
861
|
+
<Directory Id="${programFilesFolder}">
|
|
862
|
+
<Directory Id="INSTALLFOLDER" Name="${xml(opts.name)}">
|
|
863
|
+
<Component Id="${id}Executable" Guid="*" Win64="${win64}">
|
|
864
|
+
<File Id="${id}File" Source="${xml(sourceName)}" KeyPath="yes" />
|
|
865
|
+
</Component>
|
|
866
|
+
</Directory>
|
|
867
|
+
</Directory>
|
|
868
|
+
</Directory>
|
|
869
|
+
<Feature Id="ProductFeature" Title="${xml(opts.name)}" Level="1">
|
|
870
|
+
<ComponentRef Id="${id}Executable" />
|
|
871
|
+
</Feature>
|
|
872
|
+
</Product>
|
|
873
|
+
</Wix>
|
|
874
|
+
`;
|
|
576
875
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
});
|
|
876
|
+
function windowsExecutableName(name) {
|
|
877
|
+
if (name.length === 0 || name.trim() !== name || /[<>:"/\\|?*\u0000-\u001F]/.test(name) || /[. ]$/.test(name))
|
|
878
|
+
throw new Error(`Invalid Windows application name: ${JSON.stringify(name)}`);
|
|
879
|
+
if (/^(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)/i.test(name))
|
|
880
|
+
throw new Error(`Reserved Windows application name: ${JSON.stringify(name)}`);
|
|
881
|
+
return `${name}.exe`;
|
|
882
|
+
}
|
|
883
|
+
function runCommand(command, args, cwd) {
|
|
884
|
+
return new Promise((resolve, reject) => {
|
|
885
|
+
const child = import_child_process.spawn(command, args, { cwd, stdio: "inherit", windowsHide: true });
|
|
886
|
+
child.once("error", reject);
|
|
887
|
+
child.once("close", (code) => code === 0 ? resolve() : reject(new Error(`${command} exited with code ${code}`)));
|
|
592
888
|
});
|
|
593
889
|
}
|
|
890
|
+
async function createMSI(opts) {
|
|
891
|
+
const tempDir = import_fs.mkdtempSync(import_path.join(import_os.tmpdir(), "craft-msi-"));
|
|
892
|
+
try {
|
|
893
|
+
const binaryName = windowsExecutableName(opts.name);
|
|
894
|
+
const sourcePath = import_path.join(tempDir, binaryName);
|
|
895
|
+
const wxsPath = import_path.join(tempDir, "installer.wxs");
|
|
896
|
+
const wixobjPath = import_path.join(tempDir, "installer.wixobj");
|
|
897
|
+
import_fs.copyFileSync(opts.binaryPath, sourcePath);
|
|
898
|
+
import_fs.writeFileSync(wxsPath, renderWixSource(opts, binaryName));
|
|
899
|
+
await runCommand("candle.exe", ["-nologo", "-out", wixobjPath, wxsPath], tempDir);
|
|
900
|
+
await runCommand("light.exe", ["-nologo", "-sval", "-out", opts.outputPath, wixobjPath], tempDir);
|
|
901
|
+
if (opts.certificatePath) {
|
|
902
|
+
const signArgs = ["sign", "/fd", "sha256", "/tr", "https://timestamp.digicert.com", "/td", "sha256", "/f", opts.certificatePath];
|
|
903
|
+
if (opts.certificatePassword)
|
|
904
|
+
signArgs.push("/p", opts.certificatePassword);
|
|
905
|
+
signArgs.push(opts.outputPath);
|
|
906
|
+
await runCommand("signtool.exe", signArgs);
|
|
907
|
+
await runCommand("signtool.exe", ["verify", "/pa", "/all", opts.outputPath]);
|
|
908
|
+
}
|
|
909
|
+
return { success: true, outputPath: opts.outputPath };
|
|
910
|
+
} catch (error) {
|
|
911
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
912
|
+
const missingTool = /ENOENT|not found/i.test(message);
|
|
913
|
+
return { success: false, error: missingTool ? `WiX Toolset not found: ${message}` : message };
|
|
914
|
+
} finally {
|
|
915
|
+
import_fs.rmSync(tempDir, { recursive: true, force: true });
|
|
916
|
+
}
|
|
917
|
+
}
|
|
594
918
|
async function createZIP(opts) {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
settled = true;
|
|
604
|
-
resolve(r);
|
|
605
|
-
};
|
|
606
|
-
output.on("close", () => {
|
|
607
|
-
settle({ success: true, outputPath: opts.outputPath });
|
|
608
|
-
});
|
|
609
|
-
output.on("error", (err) => {
|
|
610
|
-
settle({ success: false, error: `Failed to write ZIP: ${err.message}` });
|
|
611
|
-
});
|
|
612
|
-
archive.on("error", (err) => {
|
|
613
|
-
settle({ success: false, error: err.message });
|
|
614
|
-
});
|
|
615
|
-
archive.pipe(output);
|
|
616
|
-
archive.file(opts.binaryPath, { name: `${opts.name}.exe` });
|
|
617
|
-
archive.finalize();
|
|
618
|
-
});
|
|
919
|
+
try {
|
|
920
|
+
const data = new Uint8Array(import_fs.readFileSync(opts.binaryPath));
|
|
921
|
+
const zip = buildZip([{ name: `${opts.name}.exe`, data }]);
|
|
922
|
+
import_fs.writeFileSync(opts.outputPath, zip);
|
|
923
|
+
return { success: true, outputPath: opts.outputPath };
|
|
924
|
+
} catch (err) {
|
|
925
|
+
return { success: false, error: `Failed to write ZIP: ${err.message}` };
|
|
926
|
+
}
|
|
619
927
|
}
|
|
620
928
|
async function createDEB(opts) {
|
|
621
929
|
return new Promise((resolve) => {
|
|
@@ -2082,6 +2390,9 @@ class Window {
|
|
|
2082
2390
|
async setPosition(x, y, animate) {
|
|
2083
2391
|
await this._call("setPosition", { x, y, animate });
|
|
2084
2392
|
}
|
|
2393
|
+
async moveBy(dx, dy) {
|
|
2394
|
+
await this._call("moveBy", { dx, dy });
|
|
2395
|
+
}
|
|
2085
2396
|
async getPosition() {
|
|
2086
2397
|
return this._call("getPosition");
|
|
2087
2398
|
}
|
|
@@ -2109,6 +2420,9 @@ class Window {
|
|
|
2109
2420
|
async setMovable(movable) {
|
|
2110
2421
|
await this._call("setMovable", { movable });
|
|
2111
2422
|
}
|
|
2423
|
+
async startDrag() {
|
|
2424
|
+
await this._call("startDrag");
|
|
2425
|
+
}
|
|
2112
2426
|
async isMovable() {
|
|
2113
2427
|
return this._call("isMovable");
|
|
2114
2428
|
}
|
|
@@ -2226,12 +2540,14 @@ class WindowManager {
|
|
|
2226
2540
|
setTitle = (title) => this.current.setTitle(title);
|
|
2227
2541
|
setSize = (width, height, animate) => this.current.setSize(width, height, animate);
|
|
2228
2542
|
setPosition = (x, y, animate) => this.current.setPosition(x, y, animate);
|
|
2543
|
+
moveBy = (dx, dy) => this.current.moveBy(dx, dy);
|
|
2229
2544
|
setBounds = (bounds, animate) => this.current.setBounds(bounds, animate);
|
|
2230
2545
|
setAlwaysOnTop = (alwaysOnTop) => this.current.setAlwaysOnTop(alwaysOnTop);
|
|
2231
2546
|
setOpacity = (opacity) => this.current.setOpacity(opacity);
|
|
2232
2547
|
setBackgroundColor = (color) => this.current.setBackgroundColor(color);
|
|
2233
2548
|
setVibrancy = (vibrancy) => this.current.setVibrancy(vibrancy);
|
|
2234
2549
|
setResizable = (resizable) => this.current.setResizable(resizable);
|
|
2550
|
+
startDrag = () => this.current.startDrag();
|
|
2235
2551
|
getState = () => this.current.getState();
|
|
2236
2552
|
on = (event, handler) => this.current.on(event, handler);
|
|
2237
2553
|
once = (event, handler) => this.current.once(event, handler);
|
|
@@ -3674,8 +3990,8 @@ var crypto = {
|
|
|
3674
3990
|
if (!hasNodeCrypto) {
|
|
3675
3991
|
throw new CraftCryptoError("MD5 is not available in this runtime — WebCrypto does not implement it. " + "Use sha256/sha512, or call this from Node.");
|
|
3676
3992
|
}
|
|
3677
|
-
const { createHash:
|
|
3678
|
-
return
|
|
3993
|
+
const { createHash: createHash3 } = await import("node:crypto");
|
|
3994
|
+
return createHash3("md5").update(data).digest("hex");
|
|
3679
3995
|
}
|
|
3680
3996
|
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
|
|
3681
3997
|
const encoder = new TextEncoder;
|
|
@@ -3683,8 +3999,8 @@ var crypto = {
|
|
|
3683
3999
|
const hashBuffer = await globalThis.crypto.subtle.digest(algorithm === "sha256" ? "SHA-256" : "SHA-512", dataBuffer);
|
|
3684
4000
|
return bufferToHex(hashBuffer);
|
|
3685
4001
|
}
|
|
3686
|
-
const { createHash } = await import("node:crypto");
|
|
3687
|
-
return
|
|
4002
|
+
const { createHash: createHash2 } = await import("node:crypto");
|
|
4003
|
+
return createHash2(algorithm).update(data).digest("hex");
|
|
3688
4004
|
},
|
|
3689
4005
|
async encrypt(data, key) {
|
|
3690
4006
|
if (typeof window !== "undefined" && window.craft?.crypto) {
|
|
@@ -3999,7 +4315,7 @@ async function getSystemInfo() {
|
|
|
3999
4315
|
uptime: 0
|
|
4000
4316
|
};
|
|
4001
4317
|
}
|
|
4002
|
-
async function
|
|
4318
|
+
async function exec(command, options) {
|
|
4003
4319
|
if (typeof window !== "undefined" && window.craft) {
|
|
4004
4320
|
return callBridge3("process.exec", { command, ...options });
|
|
4005
4321
|
}
|
|
@@ -4179,18 +4495,18 @@ async function open(target) {
|
|
|
4179
4495
|
const platform = getPlatform();
|
|
4180
4496
|
const { execFile } = await import("node:child_process");
|
|
4181
4497
|
const { promisify } = await import("node:util");
|
|
4182
|
-
const
|
|
4498
|
+
const exec2 = promisify(execFile);
|
|
4183
4499
|
switch (platform) {
|
|
4184
4500
|
case "darwin":
|
|
4185
4501
|
case "macos":
|
|
4186
|
-
await
|
|
4502
|
+
await exec2("open", [target]);
|
|
4187
4503
|
return;
|
|
4188
4504
|
case "win32":
|
|
4189
4505
|
case "windows":
|
|
4190
|
-
await
|
|
4506
|
+
await exec2("cmd.exe", ["/c", "start", '""', target]);
|
|
4191
4507
|
return;
|
|
4192
4508
|
case "linux":
|
|
4193
|
-
await
|
|
4509
|
+
await exec2("xdg-open", [target]);
|
|
4194
4510
|
return;
|
|
4195
4511
|
default:
|
|
4196
4512
|
throw new Error(`Unsupported platform: ${platform}`);
|
|
@@ -8169,9 +8485,9 @@ async function buildCSS(options) {
|
|
|
8169
8485
|
console.warn("buildCSS can only be run in Node.js environment");
|
|
8170
8486
|
return;
|
|
8171
8487
|
}
|
|
8172
|
-
const { exec:
|
|
8488
|
+
const { exec: exec2 } = await import("child_process");
|
|
8173
8489
|
const { promisify } = await import("util");
|
|
8174
|
-
const execAsync = promisify(
|
|
8490
|
+
const execAsync = promisify(exec2);
|
|
8175
8491
|
const args = [
|
|
8176
8492
|
"build",
|
|
8177
8493
|
"--content",
|
|
@@ -8192,109 +8508,123 @@ async function buildCSS(options) {
|
|
|
8192
8508
|
// src/styles/sidebars.ts
|
|
8193
8509
|
var tahoeStyles = {
|
|
8194
8510
|
sidebar: `
|
|
8195
|
-
w-
|
|
8196
|
-
bg-white/
|
|
8197
|
-
backdrop-blur-
|
|
8198
|
-
|
|
8511
|
+
w-[250px] h-full flex flex-col
|
|
8512
|
+
bg-white/55 dark:bg-[#1e1e23]/55
|
|
8513
|
+
backdrop-blur-[60px] backdrop-saturate-[1.8]
|
|
8514
|
+
text-black dark:text-white
|
|
8199
8515
|
select-none
|
|
8200
8516
|
`,
|
|
8201
8517
|
content: `
|
|
8202
8518
|
flex-1 overflow-y-auto overflow-x-hidden
|
|
8203
|
-
|
|
8204
|
-
scrollbar-thin scrollbar-thumb-black/10 dark:scrollbar-thumb-white/10
|
|
8519
|
+
px-[10px] pb-[10px]
|
|
8205
8520
|
`,
|
|
8206
8521
|
section: `
|
|
8207
|
-
|
|
8522
|
+
flex flex-col gap-[2px]
|
|
8208
8523
|
`,
|
|
8209
8524
|
sectionHeader: `
|
|
8210
|
-
|
|
8211
|
-
text-[11px] font-semibold
|
|
8212
|
-
text-
|
|
8525
|
+
pl-[8px] pr-[6px] pt-[16px] pb-[5px]
|
|
8526
|
+
text-[11px] font-semibold leading-[13px]
|
|
8527
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8213
8528
|
`,
|
|
8214
8529
|
sectionHeaderCollapsible: `
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
text-
|
|
8218
|
-
|
|
8219
|
-
|
|
8530
|
+
group flex items-center w-full
|
|
8531
|
+
pl-[8px] pr-[6px] pt-[16px] pb-[5px]
|
|
8532
|
+
text-[11px] font-semibold leading-[13px]
|
|
8533
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8534
|
+
cursor-default
|
|
8220
8535
|
`,
|
|
8221
8536
|
collapseChevron: `
|
|
8222
|
-
|
|
8537
|
+
ml-auto h-[11px] w-[11px]
|
|
8538
|
+
text-[#3c3c43]/45 dark:text-[#ebebf5]/45
|
|
8539
|
+
opacity-0 group-hover:opacity-100
|
|
8540
|
+
transition-all duration-200
|
|
8223
8541
|
`,
|
|
8224
8542
|
item: `
|
|
8225
|
-
flex items-center
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8543
|
+
flex w-full items-center
|
|
8544
|
+
h-[30px] rounded-[9px] pl-[4px] pr-[8px]
|
|
8545
|
+
text-[13px] leading-[16px] text-black dark:text-white
|
|
8546
|
+
cursor-default transition-colors duration-150 ease-out
|
|
8547
|
+
hover:bg-black/4 dark:hover:bg-white/6
|
|
8548
|
+
active:bg-black/10 dark:active:bg-white/18
|
|
8229
8549
|
`,
|
|
8230
8550
|
itemSelected: `
|
|
8231
|
-
flex items-center
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8551
|
+
flex w-full items-center
|
|
8552
|
+
h-[30px] rounded-[9px] pl-[4px] pr-[8px]
|
|
8553
|
+
text-[13px] leading-[16px] text-black dark:text-white
|
|
8554
|
+
cursor-default
|
|
8555
|
+
bg-black/8 dark:bg-white/14
|
|
8556
|
+
`,
|
|
8557
|
+
disclosure: `
|
|
8558
|
+
flex h-[16px] w-[18px] shrink-0 items-center justify-center
|
|
8559
|
+
`,
|
|
8560
|
+
disclosureChevron: `
|
|
8561
|
+
h-[11px] w-[11px]
|
|
8562
|
+
text-[#3c3c43]/55 dark:text-[#ebebf5]/55
|
|
8563
|
+
transition-transform duration-200 ease-out
|
|
8236
8564
|
`,
|
|
8237
8565
|
itemIcon: `
|
|
8238
|
-
|
|
8239
|
-
text-
|
|
8566
|
+
h-[17px] w-[17px] flex-shrink-0
|
|
8567
|
+
text-[#0088ff]
|
|
8240
8568
|
`,
|
|
8241
8569
|
itemIconSelected: `
|
|
8242
|
-
|
|
8243
|
-
text-
|
|
8570
|
+
h-[17px] w-[17px] flex-shrink-0
|
|
8571
|
+
text-[#0088ff]
|
|
8572
|
+
`,
|
|
8573
|
+
itemIconSlot: `
|
|
8574
|
+
flex h-[20px] w-[22px] shrink-0 items-center justify-center mr-[7px]
|
|
8244
8575
|
`,
|
|
8245
8576
|
itemLabel: `
|
|
8246
8577
|
flex-1 truncate
|
|
8247
8578
|
`,
|
|
8248
8579
|
itemBadge: `
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
text-
|
|
8580
|
+
ml-[8px] shrink-0 tabular-nums
|
|
8581
|
+
text-[13px] leading-[16px]
|
|
8582
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8252
8583
|
`,
|
|
8253
8584
|
itemBadgeSelected: `
|
|
8254
|
-
|
|
8255
|
-
|
|
8585
|
+
ml-[8px] shrink-0 tabular-nums
|
|
8586
|
+
text-[13px] leading-[16px]
|
|
8587
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8256
8588
|
`,
|
|
8257
8589
|
children: `
|
|
8258
|
-
ml-
|
|
8590
|
+
ml-[16px] mt-[2px] flex flex-col gap-[2px]
|
|
8259
8591
|
`,
|
|
8260
8592
|
dragIndicator: `
|
|
8261
|
-
absolute left-0 right-0 h-0.5 bg-
|
|
8593
|
+
absolute left-0 right-0 h-0.5 bg-[#0088ff]
|
|
8262
8594
|
pointer-events-none
|
|
8263
8595
|
`,
|
|
8264
8596
|
searchContainer: `
|
|
8265
|
-
px-
|
|
8597
|
+
px-[10px] pb-[6px]
|
|
8266
8598
|
`,
|
|
8267
8599
|
searchInput: `
|
|
8268
|
-
w-full
|
|
8269
|
-
text-[13px]
|
|
8270
|
-
|
|
8600
|
+
h-[28px] w-full rounded-[8px] px-[8px]
|
|
8601
|
+
text-[13px] text-black dark:text-white
|
|
8602
|
+
placeholder:text-[#3c3c43]/50 dark:placeholder:text-[#ebebf5]/50
|
|
8603
|
+
bg-black/5 dark:bg-white/10
|
|
8271
8604
|
border border-transparent
|
|
8272
|
-
focus:outline-none focus:
|
|
8605
|
+
focus:outline-none focus:ring-2 focus:ring-[#0088ff]/60
|
|
8273
8606
|
transition-all duration-150
|
|
8274
8607
|
`,
|
|
8275
8608
|
header: `
|
|
8276
|
-
|
|
8277
|
-
flex items-center gap-3
|
|
8609
|
+
h-[52px] px-[21px] flex items-center gap-3
|
|
8278
8610
|
`,
|
|
8279
8611
|
headerAvatar: `
|
|
8280
|
-
w-
|
|
8281
|
-
flex items-center justify-center text-
|
|
8612
|
+
w-[30px] h-[30px] rounded-full bg-black/10 dark:bg-white/15
|
|
8613
|
+
flex items-center justify-center text-[13px] font-semibold
|
|
8282
8614
|
`,
|
|
8283
8615
|
headerTitle: `
|
|
8284
|
-
text-[13px] font-medium text-
|
|
8616
|
+
text-[13px] font-medium text-black dark:text-white
|
|
8285
8617
|
`,
|
|
8286
8618
|
headerSubtitle: `
|
|
8287
|
-
text-[11px] text-
|
|
8619
|
+
text-[11px] text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8288
8620
|
`,
|
|
8289
8621
|
footer: `
|
|
8290
|
-
px-
|
|
8291
|
-
flex items-center gap-2
|
|
8622
|
+
px-[10px] pb-[8px] pt-[4px] flex items-center gap-2
|
|
8292
8623
|
`,
|
|
8293
8624
|
footerButton: `
|
|
8294
|
-
|
|
8295
|
-
text-
|
|
8296
|
-
hover:bg-black/5 dark:hover:bg-white/
|
|
8297
|
-
hover:text-neutral-700 dark:hover:text-neutral-200
|
|
8625
|
+
grid h-[28px] w-[28px] place-items-center rounded-[7px]
|
|
8626
|
+
text-[#3c3c43]/70 dark:text-[#ebebf5]/70
|
|
8627
|
+
hover:bg-black/5 dark:hover:bg-white/10
|
|
8298
8628
|
transition-colors duration-150
|
|
8299
8629
|
`
|
|
8300
8630
|
};
|
|
@@ -8713,19 +9043,21 @@ function renderTahoeSidebar(data) {
|
|
|
8713
9043
|
const itemClass = isSelected ? s.itemSelected : s.item;
|
|
8714
9044
|
const iconClass = isSelected ? s.itemIconSelected : s.itemIcon;
|
|
8715
9045
|
const badgeClass = isSelected ? s.itemBadgeSelected : s.itemBadge;
|
|
9046
|
+
const hasChildren = (item.children?.length ?? 0) > 0;
|
|
9047
|
+
const chevron = hasChildren ? `<span class='${s.disclosureChevron}${item.expanded ? " rotate-90" : ""}'>${icons.chevronRight}</span>` : "";
|
|
9048
|
+
const tint = item.color ? ` style='color: ${item.color}'` : "";
|
|
8716
9049
|
let html = `
|
|
8717
|
-
<div class='${itemClass}' data-id='${item.id}' style='padding-left: ${
|
|
8718
|
-
<span class='${
|
|
9050
|
+
<div class='${itemClass}' data-id='${item.id}'${depth > 0 ? ` style='padding-left: ${4 + depth * 16}px'` : ""}>
|
|
9051
|
+
<span class='${s.disclosure}'>${chevron}</span>
|
|
9052
|
+
<span class='${s.itemIconSlot}'><span class='${iconClass}'${tint}>${getIcon2(item.icon || "document")}</span></span>
|
|
8719
9053
|
<span class='${s.itemLabel}'>${item.label}</span>
|
|
8720
9054
|
${item.badge ? `<span class='${badgeClass}'>${item.badge}</span>` : ""}
|
|
8721
9055
|
</div>
|
|
8722
9056
|
`;
|
|
8723
9057
|
if (item.children && item.expanded) {
|
|
8724
|
-
html += `<div class='${s.children}'>`;
|
|
8725
9058
|
item.children.forEach((child) => {
|
|
8726
9059
|
html += renderItem(child, depth + 1);
|
|
8727
9060
|
});
|
|
8728
|
-
html += `</div>`;
|
|
8729
9061
|
}
|
|
8730
9062
|
return html;
|
|
8731
9063
|
};
|
|
@@ -8734,8 +9066,8 @@ function renderTahoeSidebar(data) {
|
|
|
8734
9066
|
<div class='${s.section}'>
|
|
8735
9067
|
${section.title ? `
|
|
8736
9068
|
<div class="${section.collapsible ? s.sectionHeaderCollapsible : s.sectionHeader}" data-section="${section.id}">
|
|
8737
|
-
|
|
8738
|
-
${section.
|
|
9069
|
+
<span class='truncate'>${section.title}</span>
|
|
9070
|
+
${section.collapsible ? `<span class='${s.collapseChevron}${section.collapsed ? " -rotate-90" : ""}'>${icons.chevronDown}</span>` : ""}
|
|
8739
9071
|
</div>
|
|
8740
9072
|
` : ""}
|
|
8741
9073
|
${!section.collapsed ? section.items.map((item) => renderItem(item)).join("") : ""}
|
|
@@ -9475,7 +9807,7 @@ __export(exports_updater, {
|
|
|
9475
9807
|
var import_fs3 = require("fs");
|
|
9476
9808
|
var import_path2 = require("path");
|
|
9477
9809
|
var import_child_process2 = require("child_process");
|
|
9478
|
-
var
|
|
9810
|
+
var import_crypto3 = require("crypto");
|
|
9479
9811
|
var import_events3 = require("events");
|
|
9480
9812
|
function findFirstByName(root, namePattern, kind) {
|
|
9481
9813
|
const out = import_child_process2.execFileSync("find", [root, "-name", namePattern, "-type", kind, "-print0"]);
|
|
@@ -9492,6 +9824,12 @@ class AutoUpdater extends import_events3.EventEmitter {
|
|
|
9492
9824
|
cachedEtag = null;
|
|
9493
9825
|
cachedLastModified = null;
|
|
9494
9826
|
cachedManifest = null;
|
|
9827
|
+
emitError(error) {
|
|
9828
|
+
if (this.listenerCount("error") > 0)
|
|
9829
|
+
this.emit("error", error);
|
|
9830
|
+
else
|
|
9831
|
+
console.error("[Updater]", error);
|
|
9832
|
+
}
|
|
9495
9833
|
constructor(config) {
|
|
9496
9834
|
super();
|
|
9497
9835
|
const url = config.updateUrl;
|
|
@@ -9565,7 +9903,7 @@ class AutoUpdater extends import_events3.EventEmitter {
|
|
|
9565
9903
|
return null;
|
|
9566
9904
|
}
|
|
9567
9905
|
} catch (error) {
|
|
9568
|
-
this.
|
|
9906
|
+
this.emitError(error);
|
|
9569
9907
|
return null;
|
|
9570
9908
|
}
|
|
9571
9909
|
}
|
|
@@ -9619,11 +9957,32 @@ class AutoUpdater extends import_events3.EventEmitter {
|
|
|
9619
9957
|
this.emit("download-progress", progress);
|
|
9620
9958
|
}
|
|
9621
9959
|
fileStream.end();
|
|
9960
|
+
await new Promise((resolve, reject) => {
|
|
9961
|
+
fileStream.once("finish", resolve);
|
|
9962
|
+
fileStream.once("error", reject);
|
|
9963
|
+
});
|
|
9622
9964
|
const hash = await this.computeFileHash(this.downloadPath);
|
|
9623
9965
|
if (hash !== expectedHash) {
|
|
9624
9966
|
import_fs3.unlinkSync(this.downloadPath);
|
|
9625
9967
|
throw new Error("Download verification failed: hash mismatch");
|
|
9626
9968
|
}
|
|
9969
|
+
if (deltaUpdate) {
|
|
9970
|
+
if (!import_fs3.statSync(this.config.appPath).isFile()) {
|
|
9971
|
+
throw new Error("Delta updates require appPath to point to the installed bundle file");
|
|
9972
|
+
}
|
|
9973
|
+
const patchPath = this.downloadPath;
|
|
9974
|
+
const reconstructedPath = import_path2.join(downloadDir, `reconstructed-${import_path2.basename(platformUpdate.url)}`);
|
|
9975
|
+
await DeltaGenerator.apply(this.config.appPath, patchPath, reconstructedPath);
|
|
9976
|
+
const reconstructedHash = await this.computeFileHash(reconstructedPath);
|
|
9977
|
+
if (reconstructedHash !== platformUpdate.sha256) {
|
|
9978
|
+
try {
|
|
9979
|
+
import_fs3.unlinkSync(reconstructedPath);
|
|
9980
|
+
} catch {}
|
|
9981
|
+
throw new Error("Delta reconstruction failed: full bundle hash mismatch");
|
|
9982
|
+
}
|
|
9983
|
+
import_fs3.unlinkSync(patchPath);
|
|
9984
|
+
this.downloadPath = reconstructedPath;
|
|
9985
|
+
}
|
|
9627
9986
|
if (this.config.publicKeyPem && !platformUpdate.signature) {
|
|
9628
9987
|
import_fs3.unlinkSync(this.downloadPath);
|
|
9629
9988
|
throw new Error("Updater: publicKeyPem is configured but the manifest entry has no signature. " + "Refusing to install unsigned update.");
|
|
@@ -9645,7 +10004,7 @@ class AutoUpdater extends import_events3.EventEmitter {
|
|
|
9645
10004
|
}
|
|
9646
10005
|
return this.downloadPath;
|
|
9647
10006
|
} catch (error) {
|
|
9648
|
-
this.
|
|
10007
|
+
this.emitError(error);
|
|
9649
10008
|
return null;
|
|
9650
10009
|
}
|
|
9651
10010
|
}
|
|
@@ -9705,7 +10064,8 @@ class AutoUpdater extends import_events3.EventEmitter {
|
|
|
9705
10064
|
}
|
|
9706
10065
|
} catch (error) {
|
|
9707
10066
|
progress.phase = "error";
|
|
9708
|
-
this.
|
|
10067
|
+
this.emitError(error);
|
|
10068
|
+
throw error;
|
|
9709
10069
|
}
|
|
9710
10070
|
}
|
|
9711
10071
|
async installMacOSUpdate() {
|
|
@@ -9824,7 +10184,7 @@ class AutoUpdater extends import_events3.EventEmitter {
|
|
|
9824
10184
|
}
|
|
9825
10185
|
async computeFileHash(filePath) {
|
|
9826
10186
|
return new Promise((resolve, reject) => {
|
|
9827
|
-
const hash =
|
|
10187
|
+
const hash = import_crypto3.createHash("sha256");
|
|
9828
10188
|
const stream = import_fs3.createReadStream(filePath);
|
|
9829
10189
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
9830
10190
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
@@ -9896,7 +10256,7 @@ class DeltaGenerator {
|
|
|
9896
10256
|
}
|
|
9897
10257
|
static async computeHash(filePath) {
|
|
9898
10258
|
return new Promise((resolve, reject) => {
|
|
9899
|
-
const hash =
|
|
10259
|
+
const hash = import_crypto3.createHash("sha256");
|
|
9900
10260
|
const stream = import_fs3.createReadStream(filePath);
|
|
9901
10261
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
9902
10262
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
@@ -9915,7 +10275,7 @@ function generateUpdateManifest(options) {
|
|
|
9915
10275
|
if (!info)
|
|
9916
10276
|
continue;
|
|
9917
10277
|
const bytes = import_fs3.readFileSync(info.path);
|
|
9918
|
-
const hash =
|
|
10278
|
+
const hash = import_crypto3.createHash("sha256").update(bytes).digest("hex");
|
|
9919
10279
|
manifest.platforms[platform] = {
|
|
9920
10280
|
url: info.url,
|
|
9921
10281
|
size: bytes.length,
|
|
@@ -9925,7 +10285,7 @@ function generateUpdateManifest(options) {
|
|
|
9925
10285
|
const platformDeltas = options.deltas?.filter((d) => d.platform === platform) || [];
|
|
9926
10286
|
for (const delta of platformDeltas) {
|
|
9927
10287
|
const deltaBytes = import_fs3.readFileSync(delta.path);
|
|
9928
|
-
const deltaHash =
|
|
10288
|
+
const deltaHash = import_crypto3.createHash("sha256").update(deltaBytes).digest("hex");
|
|
9929
10289
|
manifest.platforms[platform].delta.push({
|
|
9930
10290
|
fromVersion: delta.fromVersion,
|
|
9931
10291
|
url: delta.url,
|
|
@@ -10023,7 +10383,7 @@ var execFileAsync = import_node_util.promisify(import_node_child_process.execFil
|
|
|
10023
10383
|
var versionMismatchWarned = false;
|
|
10024
10384
|
function getSdkVersion() {
|
|
10025
10385
|
try {
|
|
10026
|
-
const pkgPath = import_node_path.join("/
|
|
10386
|
+
const pkgPath = import_node_path.join("/Users/chris/Code/Tools/craft/packages/typescript/src", "..", "package.json");
|
|
10027
10387
|
return JSON.parse(import_node_fs2.readFileSync(pkgPath, "utf-8")).version ?? "unknown";
|
|
10028
10388
|
} catch {
|
|
10029
10389
|
return "unknown";
|
|
@@ -10194,6 +10554,13 @@ class CraftApp {
|
|
|
10194
10554
|
args.push("--menubar-only");
|
|
10195
10555
|
if (window3?.titlebarHidden)
|
|
10196
10556
|
args.push("--titlebar-hidden");
|
|
10557
|
+
if (window3?.webSidebarMaterial) {
|
|
10558
|
+
args.push("--web-sidebar-material");
|
|
10559
|
+
if (window3?.webSidebarWidth)
|
|
10560
|
+
args.push("--web-sidebar-width", String(window3.webSidebarWidth));
|
|
10561
|
+
if (window3?.webSidebarMaterialOpacity !== undefined)
|
|
10562
|
+
args.push("--web-sidebar-material-opacity", String(window3.webSidebarMaterialOpacity));
|
|
10563
|
+
}
|
|
10197
10564
|
if (window3?.icon)
|
|
10198
10565
|
args.push("--icon", window3.icon);
|
|
10199
10566
|
if (window3?.nativeSidebar) {
|
|
@@ -10209,7 +10576,7 @@ class CraftApp {
|
|
|
10209
10576
|
} : undefined;
|
|
10210
10577
|
if (sidebarConfig?.variant === "desktop") {
|
|
10211
10578
|
sidebarConfig.material = sidebarConfig.material ?? "sidebar";
|
|
10212
|
-
sidebarConfig.backgroundEffect = sidebarConfig.backgroundEffect ?? "
|
|
10579
|
+
sidebarConfig.backgroundEffect = sidebarConfig.backgroundEffect ?? "vibrancy";
|
|
10213
10580
|
sidebarConfig.allowsVibrancy = sidebarConfig.allowsVibrancy ?? true;
|
|
10214
10581
|
}
|
|
10215
10582
|
if (sidebarConfig) {
|