craft-native 0.0.37 → 0.0.49
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 +573 -208
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +585 -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.js
CHANGED
|
@@ -17,7 +17,7 @@ var __require = import.meta.require;
|
|
|
17
17
|
|
|
18
18
|
// src/index.ts
|
|
19
19
|
import { execFile, spawn as spawn4 } from "child_process";
|
|
20
|
-
import { mkdtempSync as mkdtempSync2, readFileSync as
|
|
20
|
+
import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
21
21
|
import { tmpdir as tmpdir2 } from "os";
|
|
22
22
|
import { join as join3 } from "path";
|
|
23
23
|
import { promisify } from "util";
|
|
@@ -58,27 +58,103 @@ function craftBinaryNotFoundMessage(triedPath) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// src/package.ts
|
|
61
|
-
import {
|
|
61
|
+
import { spawn } from "child_process";
|
|
62
|
+
import { createHash } from "crypto";
|
|
62
63
|
import {
|
|
63
64
|
chmodSync,
|
|
64
65
|
copyFileSync,
|
|
65
66
|
cpSync,
|
|
66
|
-
createWriteStream,
|
|
67
67
|
existsSync as existsSync2,
|
|
68
|
+
lstatSync,
|
|
68
69
|
mkdirSync,
|
|
69
70
|
mkdtempSync,
|
|
71
|
+
readFileSync,
|
|
72
|
+
readdirSync,
|
|
70
73
|
rmSync,
|
|
71
74
|
writeFileSync
|
|
72
75
|
} from "fs";
|
|
73
76
|
import { homedir, tmpdir } from "os";
|
|
74
77
|
import { basename, join } from "path";
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
import { deflateRawSync } from "zlib";
|
|
79
|
+
var CRC32_TABLE = (() => {
|
|
80
|
+
const table = new Uint32Array(256);
|
|
81
|
+
for (let n = 0;n < 256; n++) {
|
|
82
|
+
let c = n;
|
|
83
|
+
for (let k = 0;k < 8; k++)
|
|
84
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
85
|
+
table[n] = c >>> 0;
|
|
86
|
+
}
|
|
87
|
+
return table;
|
|
88
|
+
})();
|
|
89
|
+
function crc32(data) {
|
|
90
|
+
let c = 4294967295;
|
|
91
|
+
for (let i = 0;i < data.length; i++)
|
|
92
|
+
c = CRC32_TABLE[(c ^ data[i]) & 255] ^ c >>> 8;
|
|
93
|
+
return (c ^ 4294967295) >>> 0;
|
|
94
|
+
}
|
|
95
|
+
function dosDateTime(d) {
|
|
96
|
+
const time = d.getHours() << 11 | d.getMinutes() << 5 | d.getSeconds() >> 1;
|
|
97
|
+
const date = d.getFullYear() - 1980 << 9 | d.getMonth() + 1 << 5 | d.getDate();
|
|
98
|
+
return { time: time & 65535, date: date & 65535 };
|
|
99
|
+
}
|
|
100
|
+
function buildZip(entries) {
|
|
101
|
+
const { time, date } = dosDateTime(new Date);
|
|
102
|
+
const locals = [];
|
|
103
|
+
const central = [];
|
|
104
|
+
let offset = 0;
|
|
105
|
+
for (const entry of entries) {
|
|
106
|
+
const nameBytes = Buffer.from(entry.name, "utf8");
|
|
107
|
+
const compressed = deflateRawSync(entry.data, { level: 9 });
|
|
108
|
+
const crc = crc32(entry.data);
|
|
109
|
+
const lfh = Buffer.alloc(30);
|
|
110
|
+
lfh.writeUInt32LE(67324752, 0);
|
|
111
|
+
lfh.writeUInt16LE(20, 4);
|
|
112
|
+
lfh.writeUInt16LE(0, 6);
|
|
113
|
+
lfh.writeUInt16LE(8, 8);
|
|
114
|
+
lfh.writeUInt16LE(time, 10);
|
|
115
|
+
lfh.writeUInt16LE(date, 12);
|
|
116
|
+
lfh.writeUInt32LE(crc, 14);
|
|
117
|
+
lfh.writeUInt32LE(compressed.length, 18);
|
|
118
|
+
lfh.writeUInt32LE(entry.data.length, 22);
|
|
119
|
+
lfh.writeUInt16LE(nameBytes.length, 26);
|
|
120
|
+
lfh.writeUInt16LE(0, 28);
|
|
121
|
+
locals.push(lfh, nameBytes, compressed);
|
|
122
|
+
const cdh = Buffer.alloc(46);
|
|
123
|
+
cdh.writeUInt32LE(33639248, 0);
|
|
124
|
+
cdh.writeUInt16LE(20, 4);
|
|
125
|
+
cdh.writeUInt16LE(20, 6);
|
|
126
|
+
cdh.writeUInt16LE(0, 8);
|
|
127
|
+
cdh.writeUInt16LE(8, 10);
|
|
128
|
+
cdh.writeUInt16LE(time, 12);
|
|
129
|
+
cdh.writeUInt16LE(date, 14);
|
|
130
|
+
cdh.writeUInt32LE(crc, 16);
|
|
131
|
+
cdh.writeUInt32LE(compressed.length, 20);
|
|
132
|
+
cdh.writeUInt32LE(entry.data.length, 24);
|
|
133
|
+
cdh.writeUInt16LE(nameBytes.length, 28);
|
|
134
|
+
cdh.writeUInt16LE(0, 30);
|
|
135
|
+
cdh.writeUInt16LE(0, 32);
|
|
136
|
+
cdh.writeUInt16LE(0, 34);
|
|
137
|
+
cdh.writeUInt16LE(0, 36);
|
|
138
|
+
cdh.writeUInt32LE(0, 38);
|
|
139
|
+
cdh.writeUInt32LE(offset, 42);
|
|
140
|
+
central.push(cdh, nameBytes);
|
|
141
|
+
offset += lfh.length + nameBytes.length + compressed.length;
|
|
142
|
+
}
|
|
143
|
+
const centralBuf = Buffer.concat(central);
|
|
144
|
+
const eocd = Buffer.alloc(22);
|
|
145
|
+
eocd.writeUInt32LE(101010256, 0);
|
|
146
|
+
eocd.writeUInt16LE(0, 4);
|
|
147
|
+
eocd.writeUInt16LE(0, 6);
|
|
148
|
+
eocd.writeUInt16LE(entries.length, 8);
|
|
149
|
+
eocd.writeUInt16LE(entries.length, 10);
|
|
150
|
+
eocd.writeUInt32LE(centralBuf.length, 12);
|
|
151
|
+
eocd.writeUInt32LE(offset, 16);
|
|
152
|
+
eocd.writeUInt16LE(0, 20);
|
|
153
|
+
return Buffer.concat([...locals, centralBuf, eocd]);
|
|
154
|
+
}
|
|
155
|
+
function formatPackagingCommandError(tool, code, stdout, stderr) {
|
|
156
|
+
const detail = `${stdout}${stderr}`.trim();
|
|
157
|
+
return `${tool} exited with code ${code}${detail ? `: ${detail}` : ""}`;
|
|
82
158
|
}
|
|
83
159
|
async function packageApp(config) {
|
|
84
160
|
const results = [];
|
|
@@ -109,13 +185,20 @@ async function packageMacOS(config, outDir) {
|
|
|
109
185
|
const results = [];
|
|
110
186
|
const { name, version, bundleId = `com.myapp.${name.toLowerCase()}` } = config;
|
|
111
187
|
const opts = config.macos || {};
|
|
188
|
+
const hardenedRuntime = !opts.appStore;
|
|
112
189
|
const appBundlePath = join(outDir, `${name}.app`);
|
|
113
190
|
const appBundle = createMacOSAppBundle({
|
|
114
191
|
name,
|
|
115
192
|
version,
|
|
116
193
|
bundleId,
|
|
194
|
+
buildNumber: opts.buildNumber,
|
|
195
|
+
category: opts.category,
|
|
196
|
+
minimumSystemVersion: opts.minimumSystemVersion,
|
|
197
|
+
menuBarOnly: opts.menuBarOnly,
|
|
117
198
|
binaryPath: config.binaryPath,
|
|
118
199
|
iconPath: config.iconPath,
|
|
200
|
+
provisioningProfile: opts.provisioningProfile,
|
|
201
|
+
additionalExecutables: opts.additionalExecutables,
|
|
119
202
|
outputPath: appBundlePath
|
|
120
203
|
});
|
|
121
204
|
if (!appBundle.success) {
|
|
@@ -127,12 +210,30 @@ async function packageMacOS(config, outDir) {
|
|
|
127
210
|
});
|
|
128
211
|
return results;
|
|
129
212
|
}
|
|
130
|
-
if (opts.
|
|
131
|
-
const
|
|
132
|
-
appBundlePath,
|
|
133
|
-
|
|
134
|
-
|
|
213
|
+
if (opts.signIdentity) {
|
|
214
|
+
const signed = await runTool("codesign", codesignArguments({
|
|
215
|
+
path: appBundlePath,
|
|
216
|
+
identity: opts.signIdentity,
|
|
217
|
+
entitlements: opts.entitlements,
|
|
218
|
+
hardenedRuntime
|
|
219
|
+
}));
|
|
220
|
+
if (!signed.success) {
|
|
221
|
+
results.push({ success: false, platform: "macos", format: "app", error: signed.error });
|
|
222
|
+
return results;
|
|
223
|
+
}
|
|
224
|
+
} else if (opts.appStore) {
|
|
225
|
+
results.push({
|
|
226
|
+
success: false,
|
|
227
|
+
platform: "macos",
|
|
228
|
+
format: "pkg",
|
|
229
|
+
error: 'App Store packaging requires macos.signIdentity (a "3rd Party Mac Developer Application" identity)'
|
|
135
230
|
});
|
|
231
|
+
return results;
|
|
232
|
+
}
|
|
233
|
+
results.push({ success: true, platform: "macos", format: "app", outputPath: appBundlePath });
|
|
234
|
+
if (opts.dmg !== false) {
|
|
235
|
+
const outputPath = join(outDir, `${name}-${version}.dmg`);
|
|
236
|
+
const dmgResult = await createDMG({ appBundlePath, outputPath, volumeName: name });
|
|
136
237
|
results.push({
|
|
137
238
|
success: dmgResult.success,
|
|
138
239
|
platform: "macos",
|
|
@@ -140,24 +241,59 @@ async function packageMacOS(config, outDir) {
|
|
|
140
241
|
outputPath: dmgResult.outputPath,
|
|
141
242
|
error: dmgResult.error
|
|
142
243
|
});
|
|
244
|
+
if (dmgResult.success)
|
|
245
|
+
results.push(...await notarizeIfRequested(opts, outputPath, "dmg"));
|
|
143
246
|
}
|
|
144
|
-
if (opts.pkg) {
|
|
247
|
+
if (opts.pkg || opts.appStore) {
|
|
248
|
+
const outputPath = join(outDir, `${name}-${version}.pkg`);
|
|
145
249
|
const pkgResult = await createPKG({
|
|
146
250
|
appBundlePath,
|
|
147
|
-
outputPath
|
|
251
|
+
outputPath,
|
|
148
252
|
identifier: bundleId,
|
|
149
|
-
version
|
|
253
|
+
version,
|
|
254
|
+
appStore: opts.appStore === true,
|
|
255
|
+
installerIdentity: opts.installerIdentity
|
|
150
256
|
});
|
|
151
257
|
results.push({
|
|
152
258
|
success: pkgResult.success,
|
|
153
259
|
platform: "macos",
|
|
154
|
-
format: "pkg",
|
|
260
|
+
format: opts.appStore ? "pkg (app store)" : "pkg",
|
|
155
261
|
outputPath: pkgResult.outputPath,
|
|
156
262
|
error: pkgResult.error
|
|
157
263
|
});
|
|
264
|
+
if (pkgResult.success && !opts.appStore)
|
|
265
|
+
results.push(...await notarizeIfRequested(opts, outputPath, "pkg"));
|
|
158
266
|
}
|
|
159
267
|
return results;
|
|
160
268
|
}
|
|
269
|
+
async function notarizeIfRequested(opts, artifactPath, format) {
|
|
270
|
+
if (!opts.notarize)
|
|
271
|
+
return [];
|
|
272
|
+
if (!opts.appleId || !opts.applePassword || !opts.teamId) {
|
|
273
|
+
return [{
|
|
274
|
+
success: false,
|
|
275
|
+
platform: "macos",
|
|
276
|
+
format: `${format} (notarize)`,
|
|
277
|
+
error: "Notarization requires macos.appleId, macos.applePassword and macos.teamId"
|
|
278
|
+
}];
|
|
279
|
+
}
|
|
280
|
+
const submitted = await runTool("xcrun", notarytoolArguments({
|
|
281
|
+
artifactPath,
|
|
282
|
+
appleId: opts.appleId,
|
|
283
|
+
applePassword: opts.applePassword,
|
|
284
|
+
teamId: opts.teamId
|
|
285
|
+
}));
|
|
286
|
+
if (!submitted.success)
|
|
287
|
+
return [{ success: false, platform: "macos", format: `${format} (notarize)`, error: submitted.error }];
|
|
288
|
+
const stapled = await runTool("xcrun", ["stapler", "staple", artifactPath]);
|
|
289
|
+
return [{
|
|
290
|
+
success: stapled.success,
|
|
291
|
+
platform: "macos",
|
|
292
|
+
format: `${format} (notarize)`,
|
|
293
|
+
outputPath: stapled.success ? artifactPath : undefined,
|
|
294
|
+
error: stapled.success ? undefined : stapled.error
|
|
295
|
+
}];
|
|
296
|
+
}
|
|
161
297
|
async function packageWindows(config, outDir) {
|
|
162
298
|
const results = [];
|
|
163
299
|
const { name, version } = config;
|
|
@@ -168,7 +304,10 @@ async function packageWindows(config, outDir) {
|
|
|
168
304
|
version,
|
|
169
305
|
binaryPath: config.binaryPath,
|
|
170
306
|
outputPath: join(outDir, `${name}-${version}.msi`),
|
|
171
|
-
manufacturer: config.author || "Unknown"
|
|
307
|
+
manufacturer: config.author || "Unknown",
|
|
308
|
+
architecture: opts.architecture || windowsArchitecture(process.arch),
|
|
309
|
+
certificatePath: opts.certificatePath,
|
|
310
|
+
certificatePassword: opts.certificatePassword
|
|
172
311
|
});
|
|
173
312
|
results.push({
|
|
174
313
|
success: msiResult.success,
|
|
@@ -252,83 +391,200 @@ async function packageLinux(config, outDir) {
|
|
|
252
391
|
}
|
|
253
392
|
return results;
|
|
254
393
|
}
|
|
255
|
-
function
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
394
|
+
function macOSInfoPlist(metadata) {
|
|
395
|
+
const entries = [
|
|
396
|
+
["CFBundleExecutable", metadata.name],
|
|
397
|
+
["CFBundleIdentifier", metadata.bundleId],
|
|
398
|
+
["CFBundleName", metadata.name],
|
|
399
|
+
["CFBundleShortVersionString", metadata.version],
|
|
400
|
+
["CFBundleVersion", metadata.buildNumber || metadata.version],
|
|
401
|
+
["CFBundlePackageType", "APPL"],
|
|
402
|
+
["NSHighResolutionCapable", true]
|
|
403
|
+
];
|
|
404
|
+
if (metadata.iconName)
|
|
405
|
+
entries.push(["CFBundleIconFile", metadata.iconName]);
|
|
406
|
+
if (metadata.category)
|
|
407
|
+
entries.push(["LSApplicationCategoryType", metadata.category]);
|
|
408
|
+
if (metadata.minimumSystemVersion)
|
|
409
|
+
entries.push(["LSMinimumSystemVersion", metadata.minimumSystemVersion]);
|
|
410
|
+
if (metadata.menuBarOnly)
|
|
411
|
+
entries.push(["LSUIElement", true]);
|
|
412
|
+
const body = entries.map(([key, value]) => ` <key>${xml(key)}</key>
|
|
413
|
+
${value === true ? " <true/>" : ` <string>${xml(value)}</string>`}`).join(`
|
|
414
|
+
`);
|
|
415
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
263
416
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
264
417
|
<plist version="1.0">
|
|
265
418
|
<dict>
|
|
266
|
-
|
|
267
|
-
<string>${name}</string>
|
|
268
|
-
<key>CFBundleIdentifier</key>
|
|
269
|
-
<string>${bundleId}</string>
|
|
270
|
-
<key>CFBundleName</key>
|
|
271
|
-
<string>${name}</string>
|
|
272
|
-
<key>CFBundleShortVersionString</key>
|
|
273
|
-
<string>${version}</string>
|
|
274
|
-
<key>CFBundleVersion</key>
|
|
275
|
-
<string>${version}</string>
|
|
276
|
-
<key>CFBundlePackageType</key>
|
|
277
|
-
<string>APPL</string>
|
|
278
|
-
<key>NSHighResolutionCapable</key>
|
|
279
|
-
<true/>
|
|
419
|
+
${body}
|
|
280
420
|
</dict>
|
|
281
421
|
</plist>`;
|
|
282
|
-
|
|
422
|
+
}
|
|
423
|
+
function codesignArguments(opts) {
|
|
424
|
+
return [
|
|
425
|
+
"--force",
|
|
426
|
+
"--sign",
|
|
427
|
+
opts.identity,
|
|
428
|
+
"--timestamp",
|
|
429
|
+
...opts.hardenedRuntime ? ["--options", "runtime"] : [],
|
|
430
|
+
...opts.entitlements ? ["--entitlements", opts.entitlements] : [],
|
|
431
|
+
"--deep",
|
|
432
|
+
opts.path
|
|
433
|
+
];
|
|
434
|
+
}
|
|
435
|
+
function productbuildArguments(opts) {
|
|
436
|
+
return [
|
|
437
|
+
"--component",
|
|
438
|
+
opts.appBundlePath,
|
|
439
|
+
"/Applications",
|
|
440
|
+
"--sign",
|
|
441
|
+
opts.identity,
|
|
442
|
+
opts.outputPath
|
|
443
|
+
];
|
|
444
|
+
}
|
|
445
|
+
function notarytoolArguments(opts) {
|
|
446
|
+
return [
|
|
447
|
+
"notarytool",
|
|
448
|
+
"submit",
|
|
449
|
+
opts.artifactPath,
|
|
450
|
+
"--apple-id",
|
|
451
|
+
opts.appleId,
|
|
452
|
+
"--password",
|
|
453
|
+
opts.applePassword,
|
|
454
|
+
"--team-id",
|
|
455
|
+
opts.teamId,
|
|
456
|
+
"--wait"
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
function createMacOSAppBundle(opts) {
|
|
460
|
+
try {
|
|
461
|
+
const { name, binaryPath, iconPath, provisioningProfile, additionalExecutables, outputPath } = opts;
|
|
462
|
+
const contents = join(outputPath, "Contents");
|
|
463
|
+
const macOS = join(contents, "MacOS");
|
|
464
|
+
mkdirSync(macOS, { recursive: true });
|
|
465
|
+
mkdirSync(join(contents, "Resources"), { recursive: true });
|
|
466
|
+
copyFileSync(binaryPath, join(macOS, name));
|
|
467
|
+
chmodSync(join(macOS, name), 493);
|
|
468
|
+
for (const executable of additionalExecutables || []) {
|
|
469
|
+
if (!existsSync2(executable))
|
|
470
|
+
return { success: false, error: `Additional executable not found: ${executable}` };
|
|
471
|
+
const destination = join(macOS, basename(executable));
|
|
472
|
+
copyFileSync(executable, destination);
|
|
473
|
+
chmodSync(destination, 493);
|
|
474
|
+
}
|
|
475
|
+
let iconName;
|
|
476
|
+
if (iconPath) {
|
|
477
|
+
if (!existsSync2(iconPath))
|
|
478
|
+
return { success: false, error: `Icon not found: ${iconPath}` };
|
|
479
|
+
iconName = basename(iconPath).replace(/\.icns$/i, "");
|
|
480
|
+
copyFileSync(iconPath, join(contents, "Resources", `${iconName}.icns`));
|
|
481
|
+
}
|
|
482
|
+
if (provisioningProfile) {
|
|
483
|
+
if (!existsSync2(provisioningProfile))
|
|
484
|
+
return { success: false, error: `Provisioning profile not found: ${provisioningProfile}` };
|
|
485
|
+
copyFileSync(provisioningProfile, join(contents, "embedded.provisionprofile"));
|
|
486
|
+
}
|
|
487
|
+
writeFileSync(join(contents, "Info.plist"), macOSInfoPlist({ ...opts, iconName }));
|
|
283
488
|
return { success: true };
|
|
284
489
|
} catch (error) {
|
|
285
490
|
return { success: false, error: error.message };
|
|
286
491
|
}
|
|
287
492
|
}
|
|
288
|
-
|
|
493
|
+
var MEBIBYTE = 1024 * 1024;
|
|
494
|
+
function pathContentBytes(path) {
|
|
495
|
+
const stat = lstatSync(path);
|
|
496
|
+
if (!stat.isDirectory())
|
|
497
|
+
return stat.size;
|
|
498
|
+
return readdirSync(path).reduce((total, entry) => total + pathContentBytes(join(path, entry)), 0);
|
|
499
|
+
}
|
|
500
|
+
function dmgCapacityMegabytes(contentBytes) {
|
|
501
|
+
if (!Number.isSafeInteger(contentBytes) || contentBytes < 0)
|
|
502
|
+
throw new Error(`DMG content size must be a non-negative safe integer: ${contentBytes}`);
|
|
503
|
+
const contentMegabytes = Math.ceil(contentBytes / MEBIBYTE);
|
|
504
|
+
return Math.max(64, Math.ceil(contentMegabytes * 1.25) + 32);
|
|
505
|
+
}
|
|
506
|
+
function dmgCreateArguments(opts, contentBytes) {
|
|
507
|
+
return [
|
|
508
|
+
"create",
|
|
509
|
+
"-volname",
|
|
510
|
+
opts.volumeName,
|
|
511
|
+
"-srcfolder",
|
|
512
|
+
opts.appBundlePath,
|
|
513
|
+
"-size",
|
|
514
|
+
`${dmgCapacityMegabytes(contentBytes)}m`,
|
|
515
|
+
"-ov",
|
|
516
|
+
"-format",
|
|
517
|
+
"UDZO",
|
|
518
|
+
opts.outputPath
|
|
519
|
+
];
|
|
520
|
+
}
|
|
521
|
+
var HDIUTIL_MAX_ATTEMPTS = 3;
|
|
522
|
+
function shouldRetryHdiutil(error, attempt, maxAttempts = HDIUTIL_MAX_ATTEMPTS) {
|
|
523
|
+
if (!Number.isInteger(attempt) || attempt < 1 || !Number.isInteger(maxAttempts) || maxAttempts < 1)
|
|
524
|
+
throw new Error("hdiutil retry attempts must be positive integers");
|
|
525
|
+
return attempt < maxAttempts && /(?:resource busy|resource temporarily unavailable)/i.test(error);
|
|
526
|
+
}
|
|
527
|
+
function runTool(tool, args) {
|
|
289
528
|
return new Promise((resolve) => {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
"create",
|
|
296
|
-
"-volname",
|
|
297
|
-
opts.volumeName,
|
|
298
|
-
"-srcfolder",
|
|
299
|
-
opts.appBundlePath,
|
|
300
|
-
"-ov",
|
|
301
|
-
"-format",
|
|
302
|
-
"UDZO",
|
|
303
|
-
opts.outputPath
|
|
304
|
-
]);
|
|
305
|
-
proc.on("close", (code) => {
|
|
306
|
-
if (code === 0) {
|
|
307
|
-
resolve({ success: true, outputPath: opts.outputPath });
|
|
308
|
-
} else {
|
|
309
|
-
resolve({ success: false, error: `hdiutil exited with code ${code}` });
|
|
310
|
-
}
|
|
529
|
+
const proc = spawn(tool, args);
|
|
530
|
+
let stdout = "";
|
|
531
|
+
let stderr = "";
|
|
532
|
+
proc.stdout?.on("data", (chunk) => {
|
|
533
|
+
stdout += chunk.toString();
|
|
311
534
|
});
|
|
312
|
-
proc.on("
|
|
313
|
-
|
|
535
|
+
proc.stderr?.on("data", (chunk) => {
|
|
536
|
+
stderr += chunk.toString();
|
|
314
537
|
});
|
|
538
|
+
proc.on("close", (code) => {
|
|
539
|
+
if (code === 0)
|
|
540
|
+
resolve({ success: true });
|
|
541
|
+
else
|
|
542
|
+
resolve({ success: false, error: formatPackagingCommandError(tool, code, stdout, stderr) });
|
|
543
|
+
});
|
|
544
|
+
proc.on("error", (err) => resolve({ success: false, error: err.message }));
|
|
315
545
|
});
|
|
316
546
|
}
|
|
547
|
+
var runHdiutil = (args) => runTool("hdiutil", args);
|
|
548
|
+
async function createDMG(opts) {
|
|
549
|
+
if (!/^[^/:\n]{1,27}$/.test(opts.volumeName))
|
|
550
|
+
return { success: false, error: `Invalid DMG volume name "${opts.volumeName}"; must be 1..27 chars without /, :, or newline` };
|
|
551
|
+
const args = dmgCreateArguments(opts, pathContentBytes(opts.appBundlePath));
|
|
552
|
+
const failures = [];
|
|
553
|
+
for (let attempt = 1;attempt <= HDIUTIL_MAX_ATTEMPTS; attempt++) {
|
|
554
|
+
const result = await runHdiutil(args);
|
|
555
|
+
if (result.success)
|
|
556
|
+
return { success: true, outputPath: opts.outputPath };
|
|
557
|
+
failures.push(`attempt ${attempt}: ${result.error}`);
|
|
558
|
+
if (!shouldRetryHdiutil(result.error, attempt))
|
|
559
|
+
return { success: false, error: failures.join(`
|
|
560
|
+
`) };
|
|
561
|
+
rmSync(opts.outputPath, { force: true });
|
|
562
|
+
await new Promise((resolve) => setTimeout(resolve, attempt * 2000));
|
|
563
|
+
}
|
|
564
|
+
return { success: false, error: failures.join(`
|
|
565
|
+
`) };
|
|
566
|
+
}
|
|
317
567
|
async function createPKG(opts) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
568
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(opts.identifier) || !opts.identifier.includes("."))
|
|
569
|
+
return { success: false, error: `Invalid pkg identifier "${opts.identifier}"; expected reverse-DNS like com.example.app` };
|
|
570
|
+
if (!/^[A-Za-z0-9._+-]+$/.test(opts.version))
|
|
571
|
+
return { success: false, error: `Invalid pkg version "${opts.version}"` };
|
|
572
|
+
if (opts.appStore) {
|
|
573
|
+
if (!opts.installerIdentity)
|
|
574
|
+
return { success: false, error: 'App Store packaging requires macos.installerIdentity (a "3rd Party Mac Developer Installer" identity)' };
|
|
575
|
+
const built = await runTool("productbuild", productbuildArguments({
|
|
576
|
+
appBundlePath: opts.appBundlePath,
|
|
577
|
+
outputPath: opts.outputPath,
|
|
578
|
+
identity: opts.installerIdentity
|
|
579
|
+
}));
|
|
580
|
+
return built.success ? { success: true, outputPath: opts.outputPath } : { success: false, error: built.error };
|
|
581
|
+
}
|
|
582
|
+
const tempDir = mkdtempSync(join(tmpdir(), "craft-pkg-"));
|
|
583
|
+
try {
|
|
328
584
|
const appsDir = join(tempDir, "Applications");
|
|
329
585
|
mkdirSync(appsDir, { recursive: true });
|
|
330
586
|
cpSync(opts.appBundlePath, join(appsDir, basename(opts.appBundlePath)), { recursive: true });
|
|
331
|
-
const
|
|
587
|
+
const built = await runTool("pkgbuild", [
|
|
332
588
|
"--root",
|
|
333
589
|
tempDir,
|
|
334
590
|
"--identifier",
|
|
@@ -337,64 +593,116 @@ async function createPKG(opts) {
|
|
|
337
593
|
opts.version,
|
|
338
594
|
"--install-location",
|
|
339
595
|
"/",
|
|
596
|
+
...opts.installerIdentity ? ["--sign", opts.installerIdentity] : [],
|
|
340
597
|
opts.outputPath
|
|
341
598
|
]);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
599
|
+
return built.success ? { success: true, outputPath: opts.outputPath } : { success: false, error: built.error };
|
|
600
|
+
} finally {
|
|
601
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
function xml(value) {
|
|
605
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll(`'`, "'");
|
|
606
|
+
}
|
|
607
|
+
function wixIdentifier(value) {
|
|
608
|
+
const sanitized = value.replace(/[^A-Za-z0-9_.]/g, "_");
|
|
609
|
+
return /^[A-Za-z_]/.test(sanitized) ? sanitized : `_${sanitized}`;
|
|
610
|
+
}
|
|
611
|
+
function deterministicGuid(value) {
|
|
612
|
+
const digest = createHash("sha256").update(value).digest("hex").slice(0, 32).split("");
|
|
613
|
+
digest[12] = "4";
|
|
614
|
+
digest[16] = (Number.parseInt(digest[16], 16) & 3 | 8).toString(16);
|
|
615
|
+
const hex = digest.join("").toUpperCase();
|
|
616
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
617
|
+
}
|
|
618
|
+
function windowsArchitecture(architecture) {
|
|
619
|
+
if (architecture === "ia32" || architecture === "x86")
|
|
620
|
+
return "x86";
|
|
621
|
+
if (architecture === "x64" || architecture === "arm64")
|
|
622
|
+
return architecture;
|
|
623
|
+
throw new Error(`Unsupported Windows package architecture: ${architecture}`);
|
|
624
|
+
}
|
|
625
|
+
function renderWixSource(opts, sourceName) {
|
|
626
|
+
if (!/^[0-9]+\.[0-9]+\.[0-9]+(?:\.[0-9]+)?$/.test(opts.version))
|
|
627
|
+
throw new Error(`MSI version must have 3 or 4 numeric parts: ${opts.version}`);
|
|
628
|
+
const id = wixIdentifier(opts.name);
|
|
629
|
+
const manufacturer = opts.manufacturer.trim() || "Unknown";
|
|
630
|
+
const upgradeCode = deterministicGuid(`${manufacturer}/${opts.name}`);
|
|
631
|
+
const programFilesFolder = opts.architecture === "x86" ? "ProgramFilesFolder" : "ProgramFiles64Folder";
|
|
632
|
+
const win64 = opts.architecture === "x86" ? "no" : "yes";
|
|
633
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
634
|
+
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
|
635
|
+
<Product Id="*" Name="${xml(opts.name)}" Language="1033" Version="${opts.version}" Manufacturer="${xml(manufacturer)}" UpgradeCode="${upgradeCode}">
|
|
636
|
+
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" Platform="${opts.architecture}" />
|
|
637
|
+
<MajorUpgrade AllowDowngrades="yes" />
|
|
638
|
+
<MediaTemplate EmbedCab="yes" />
|
|
639
|
+
<Directory Id="TARGETDIR" Name="SourceDir">
|
|
640
|
+
<Directory Id="${programFilesFolder}">
|
|
641
|
+
<Directory Id="INSTALLFOLDER" Name="${xml(opts.name)}">
|
|
642
|
+
<Component Id="${id}Executable" Guid="*" Win64="${win64}">
|
|
643
|
+
<File Id="${id}File" Source="${xml(sourceName)}" KeyPath="yes" />
|
|
644
|
+
</Component>
|
|
645
|
+
</Directory>
|
|
646
|
+
</Directory>
|
|
647
|
+
</Directory>
|
|
648
|
+
<Feature Id="ProductFeature" Title="${xml(opts.name)}" Level="1">
|
|
649
|
+
<ComponentRef Id="${id}Executable" />
|
|
650
|
+
</Feature>
|
|
651
|
+
</Product>
|
|
652
|
+
</Wix>
|
|
653
|
+
`;
|
|
355
654
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
});
|
|
655
|
+
function windowsExecutableName(name) {
|
|
656
|
+
if (name.length === 0 || name.trim() !== name || /[<>:"/\\|?*\u0000-\u001F]/.test(name) || /[. ]$/.test(name))
|
|
657
|
+
throw new Error(`Invalid Windows application name: ${JSON.stringify(name)}`);
|
|
658
|
+
if (/^(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)/i.test(name))
|
|
659
|
+
throw new Error(`Reserved Windows application name: ${JSON.stringify(name)}`);
|
|
660
|
+
return `${name}.exe`;
|
|
661
|
+
}
|
|
662
|
+
function runCommand(command, args, cwd) {
|
|
663
|
+
return new Promise((resolve, reject) => {
|
|
664
|
+
const child = spawn(command, args, { cwd, stdio: "inherit", windowsHide: true });
|
|
665
|
+
child.once("error", reject);
|
|
666
|
+
child.once("close", (code) => code === 0 ? resolve() : reject(new Error(`${command} exited with code ${code}`)));
|
|
371
667
|
});
|
|
372
668
|
}
|
|
669
|
+
async function createMSI(opts) {
|
|
670
|
+
const tempDir = mkdtempSync(join(tmpdir(), "craft-msi-"));
|
|
671
|
+
try {
|
|
672
|
+
const binaryName = windowsExecutableName(opts.name);
|
|
673
|
+
const sourcePath = join(tempDir, binaryName);
|
|
674
|
+
const wxsPath = join(tempDir, "installer.wxs");
|
|
675
|
+
const wixobjPath = join(tempDir, "installer.wixobj");
|
|
676
|
+
copyFileSync(opts.binaryPath, sourcePath);
|
|
677
|
+
writeFileSync(wxsPath, renderWixSource(opts, binaryName));
|
|
678
|
+
await runCommand("candle.exe", ["-nologo", "-out", wixobjPath, wxsPath], tempDir);
|
|
679
|
+
await runCommand("light.exe", ["-nologo", "-sval", "-out", opts.outputPath, wixobjPath], tempDir);
|
|
680
|
+
if (opts.certificatePath) {
|
|
681
|
+
const signArgs = ["sign", "/fd", "sha256", "/tr", "https://timestamp.digicert.com", "/td", "sha256", "/f", opts.certificatePath];
|
|
682
|
+
if (opts.certificatePassword)
|
|
683
|
+
signArgs.push("/p", opts.certificatePassword);
|
|
684
|
+
signArgs.push(opts.outputPath);
|
|
685
|
+
await runCommand("signtool.exe", signArgs);
|
|
686
|
+
await runCommand("signtool.exe", ["verify", "/pa", "/all", opts.outputPath]);
|
|
687
|
+
}
|
|
688
|
+
return { success: true, outputPath: opts.outputPath };
|
|
689
|
+
} catch (error) {
|
|
690
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
691
|
+
const missingTool = /ENOENT|not found/i.test(message);
|
|
692
|
+
return { success: false, error: missingTool ? `WiX Toolset not found: ${message}` : message };
|
|
693
|
+
} finally {
|
|
694
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
695
|
+
}
|
|
696
|
+
}
|
|
373
697
|
async function createZIP(opts) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
settled = true;
|
|
383
|
-
resolve(r);
|
|
384
|
-
};
|
|
385
|
-
output.on("close", () => {
|
|
386
|
-
settle({ success: true, outputPath: opts.outputPath });
|
|
387
|
-
});
|
|
388
|
-
output.on("error", (err) => {
|
|
389
|
-
settle({ success: false, error: `Failed to write ZIP: ${err.message}` });
|
|
390
|
-
});
|
|
391
|
-
archive.on("error", (err) => {
|
|
392
|
-
settle({ success: false, error: err.message });
|
|
393
|
-
});
|
|
394
|
-
archive.pipe(output);
|
|
395
|
-
archive.file(opts.binaryPath, { name: `${opts.name}.exe` });
|
|
396
|
-
archive.finalize();
|
|
397
|
-
});
|
|
698
|
+
try {
|
|
699
|
+
const data = new Uint8Array(readFileSync(opts.binaryPath));
|
|
700
|
+
const zip = buildZip([{ name: `${opts.name}.exe`, data }]);
|
|
701
|
+
writeFileSync(opts.outputPath, zip);
|
|
702
|
+
return { success: true, outputPath: opts.outputPath };
|
|
703
|
+
} catch (err) {
|
|
704
|
+
return { success: false, error: `Failed to write ZIP: ${err.message}` };
|
|
705
|
+
}
|
|
398
706
|
}
|
|
399
707
|
async function createDEB(opts) {
|
|
400
708
|
return new Promise((resolve) => {
|
|
@@ -1861,6 +2169,9 @@ class Window {
|
|
|
1861
2169
|
async setPosition(x, y, animate) {
|
|
1862
2170
|
await this._call("setPosition", { x, y, animate });
|
|
1863
2171
|
}
|
|
2172
|
+
async moveBy(dx, dy) {
|
|
2173
|
+
await this._call("moveBy", { dx, dy });
|
|
2174
|
+
}
|
|
1864
2175
|
async getPosition() {
|
|
1865
2176
|
return this._call("getPosition");
|
|
1866
2177
|
}
|
|
@@ -1888,6 +2199,9 @@ class Window {
|
|
|
1888
2199
|
async setMovable(movable) {
|
|
1889
2200
|
await this._call("setMovable", { movable });
|
|
1890
2201
|
}
|
|
2202
|
+
async startDrag() {
|
|
2203
|
+
await this._call("startDrag");
|
|
2204
|
+
}
|
|
1891
2205
|
async isMovable() {
|
|
1892
2206
|
return this._call("isMovable");
|
|
1893
2207
|
}
|
|
@@ -2005,12 +2319,14 @@ class WindowManager {
|
|
|
2005
2319
|
setTitle = (title) => this.current.setTitle(title);
|
|
2006
2320
|
setSize = (width, height, animate) => this.current.setSize(width, height, animate);
|
|
2007
2321
|
setPosition = (x, y, animate) => this.current.setPosition(x, y, animate);
|
|
2322
|
+
moveBy = (dx, dy) => this.current.moveBy(dx, dy);
|
|
2008
2323
|
setBounds = (bounds, animate) => this.current.setBounds(bounds, animate);
|
|
2009
2324
|
setAlwaysOnTop = (alwaysOnTop) => this.current.setAlwaysOnTop(alwaysOnTop);
|
|
2010
2325
|
setOpacity = (opacity) => this.current.setOpacity(opacity);
|
|
2011
2326
|
setBackgroundColor = (color) => this.current.setBackgroundColor(color);
|
|
2012
2327
|
setVibrancy = (vibrancy) => this.current.setVibrancy(vibrancy);
|
|
2013
2328
|
setResizable = (resizable) => this.current.setResizable(resizable);
|
|
2329
|
+
startDrag = () => this.current.startDrag();
|
|
2014
2330
|
getState = () => this.current.getState();
|
|
2015
2331
|
on = (event, handler) => this.current.on(event, handler);
|
|
2016
2332
|
once = (event, handler) => this.current.once(event, handler);
|
|
@@ -3453,8 +3769,8 @@ var crypto = {
|
|
|
3453
3769
|
if (!hasNodeCrypto) {
|
|
3454
3770
|
throw new CraftCryptoError("MD5 is not available in this runtime \u2014 WebCrypto does not implement it. " + "Use sha256/sha512, or call this from Node.");
|
|
3455
3771
|
}
|
|
3456
|
-
const { createHash:
|
|
3457
|
-
return
|
|
3772
|
+
const { createHash: createHash3 } = await import("crypto");
|
|
3773
|
+
return createHash3("md5").update(data).digest("hex");
|
|
3458
3774
|
}
|
|
3459
3775
|
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
|
|
3460
3776
|
const encoder = new TextEncoder;
|
|
@@ -3462,8 +3778,8 @@ var crypto = {
|
|
|
3462
3778
|
const hashBuffer = await globalThis.crypto.subtle.digest(algorithm === "sha256" ? "SHA-256" : "SHA-512", dataBuffer);
|
|
3463
3779
|
return bufferToHex(hashBuffer);
|
|
3464
3780
|
}
|
|
3465
|
-
const { createHash } = await import("crypto");
|
|
3466
|
-
return
|
|
3781
|
+
const { createHash: createHash2 } = await import("crypto");
|
|
3782
|
+
return createHash2(algorithm).update(data).digest("hex");
|
|
3467
3783
|
},
|
|
3468
3784
|
async encrypt(data, key) {
|
|
3469
3785
|
if (typeof window !== "undefined" && window.craft?.crypto) {
|
|
@@ -3778,7 +4094,7 @@ async function getSystemInfo() {
|
|
|
3778
4094
|
uptime: 0
|
|
3779
4095
|
};
|
|
3780
4096
|
}
|
|
3781
|
-
async function
|
|
4097
|
+
async function exec(command, options) {
|
|
3782
4098
|
if (typeof window !== "undefined" && window.craft) {
|
|
3783
4099
|
return callBridge3("process.exec", { command, ...options });
|
|
3784
4100
|
}
|
|
@@ -3958,18 +4274,18 @@ async function open(target) {
|
|
|
3958
4274
|
const platform = getPlatform();
|
|
3959
4275
|
const { execFile } = await import("child_process");
|
|
3960
4276
|
const { promisify } = await import("util");
|
|
3961
|
-
const
|
|
4277
|
+
const exec2 = promisify(execFile);
|
|
3962
4278
|
switch (platform) {
|
|
3963
4279
|
case "darwin":
|
|
3964
4280
|
case "macos":
|
|
3965
|
-
await
|
|
4281
|
+
await exec2("open", [target]);
|
|
3966
4282
|
return;
|
|
3967
4283
|
case "win32":
|
|
3968
4284
|
case "windows":
|
|
3969
|
-
await
|
|
4285
|
+
await exec2("cmd.exe", ["/c", "start", '""', target]);
|
|
3970
4286
|
return;
|
|
3971
4287
|
case "linux":
|
|
3972
|
-
await
|
|
4288
|
+
await exec2("xdg-open", [target]);
|
|
3973
4289
|
return;
|
|
3974
4290
|
default:
|
|
3975
4291
|
throw new Error(`Unsupported platform: ${platform}`);
|
|
@@ -7948,9 +8264,9 @@ async function buildCSS(options) {
|
|
|
7948
8264
|
console.warn("buildCSS can only be run in Node.js environment");
|
|
7949
8265
|
return;
|
|
7950
8266
|
}
|
|
7951
|
-
const { exec:
|
|
8267
|
+
const { exec: exec2 } = await import("child_process");
|
|
7952
8268
|
const { promisify } = await import("util");
|
|
7953
|
-
const execAsync = promisify(
|
|
8269
|
+
const execAsync = promisify(exec2);
|
|
7954
8270
|
const args = [
|
|
7955
8271
|
"build",
|
|
7956
8272
|
"--content",
|
|
@@ -7971,109 +8287,123 @@ async function buildCSS(options) {
|
|
|
7971
8287
|
// src/styles/sidebars.ts
|
|
7972
8288
|
var tahoeStyles = {
|
|
7973
8289
|
sidebar: `
|
|
7974
|
-
w-
|
|
7975
|
-
bg-white/
|
|
7976
|
-
backdrop-blur-
|
|
7977
|
-
|
|
8290
|
+
w-[250px] h-full flex flex-col
|
|
8291
|
+
bg-white/55 dark:bg-[#1e1e23]/55
|
|
8292
|
+
backdrop-blur-[60px] backdrop-saturate-[1.8]
|
|
8293
|
+
text-black dark:text-white
|
|
7978
8294
|
select-none
|
|
7979
8295
|
`,
|
|
7980
8296
|
content: `
|
|
7981
8297
|
flex-1 overflow-y-auto overflow-x-hidden
|
|
7982
|
-
|
|
7983
|
-
scrollbar-thin scrollbar-thumb-black/10 dark:scrollbar-thumb-white/10
|
|
8298
|
+
px-[10px] pb-[10px]
|
|
7984
8299
|
`,
|
|
7985
8300
|
section: `
|
|
7986
|
-
|
|
8301
|
+
flex flex-col gap-[2px]
|
|
7987
8302
|
`,
|
|
7988
8303
|
sectionHeader: `
|
|
7989
|
-
|
|
7990
|
-
text-[11px] font-semibold
|
|
7991
|
-
text-
|
|
8304
|
+
pl-[8px] pr-[6px] pt-[16px] pb-[5px]
|
|
8305
|
+
text-[11px] font-semibold leading-[13px]
|
|
8306
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
7992
8307
|
`,
|
|
7993
8308
|
sectionHeaderCollapsible: `
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
text-
|
|
7997
|
-
|
|
7998
|
-
|
|
8309
|
+
group flex items-center w-full
|
|
8310
|
+
pl-[8px] pr-[6px] pt-[16px] pb-[5px]
|
|
8311
|
+
text-[11px] font-semibold leading-[13px]
|
|
8312
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8313
|
+
cursor-default
|
|
7999
8314
|
`,
|
|
8000
8315
|
collapseChevron: `
|
|
8001
|
-
|
|
8316
|
+
ml-auto h-[11px] w-[11px]
|
|
8317
|
+
text-[#3c3c43]/45 dark:text-[#ebebf5]/45
|
|
8318
|
+
opacity-0 group-hover:opacity-100
|
|
8319
|
+
transition-all duration-200
|
|
8002
8320
|
`,
|
|
8003
8321
|
item: `
|
|
8004
|
-
flex items-center
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8322
|
+
flex w-full items-center
|
|
8323
|
+
h-[30px] rounded-[9px] pl-[4px] pr-[8px]
|
|
8324
|
+
text-[13px] leading-[16px] text-black dark:text-white
|
|
8325
|
+
cursor-default transition-colors duration-150 ease-out
|
|
8326
|
+
hover:bg-black/4 dark:hover:bg-white/6
|
|
8327
|
+
active:bg-black/10 dark:active:bg-white/18
|
|
8008
8328
|
`,
|
|
8009
8329
|
itemSelected: `
|
|
8010
|
-
flex items-center
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8330
|
+
flex w-full items-center
|
|
8331
|
+
h-[30px] rounded-[9px] pl-[4px] pr-[8px]
|
|
8332
|
+
text-[13px] leading-[16px] text-black dark:text-white
|
|
8333
|
+
cursor-default
|
|
8334
|
+
bg-black/8 dark:bg-white/14
|
|
8335
|
+
`,
|
|
8336
|
+
disclosure: `
|
|
8337
|
+
flex h-[16px] w-[18px] shrink-0 items-center justify-center
|
|
8338
|
+
`,
|
|
8339
|
+
disclosureChevron: `
|
|
8340
|
+
h-[11px] w-[11px]
|
|
8341
|
+
text-[#3c3c43]/55 dark:text-[#ebebf5]/55
|
|
8342
|
+
transition-transform duration-200 ease-out
|
|
8015
8343
|
`,
|
|
8016
8344
|
itemIcon: `
|
|
8017
|
-
|
|
8018
|
-
text-
|
|
8345
|
+
h-[17px] w-[17px] flex-shrink-0
|
|
8346
|
+
text-[#0088ff]
|
|
8019
8347
|
`,
|
|
8020
8348
|
itemIconSelected: `
|
|
8021
|
-
|
|
8022
|
-
text-
|
|
8349
|
+
h-[17px] w-[17px] flex-shrink-0
|
|
8350
|
+
text-[#0088ff]
|
|
8351
|
+
`,
|
|
8352
|
+
itemIconSlot: `
|
|
8353
|
+
flex h-[20px] w-[22px] shrink-0 items-center justify-center mr-[7px]
|
|
8023
8354
|
`,
|
|
8024
8355
|
itemLabel: `
|
|
8025
8356
|
flex-1 truncate
|
|
8026
8357
|
`,
|
|
8027
8358
|
itemBadge: `
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
text-
|
|
8359
|
+
ml-[8px] shrink-0 tabular-nums
|
|
8360
|
+
text-[13px] leading-[16px]
|
|
8361
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8031
8362
|
`,
|
|
8032
8363
|
itemBadgeSelected: `
|
|
8033
|
-
|
|
8034
|
-
|
|
8364
|
+
ml-[8px] shrink-0 tabular-nums
|
|
8365
|
+
text-[13px] leading-[16px]
|
|
8366
|
+
text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8035
8367
|
`,
|
|
8036
8368
|
children: `
|
|
8037
|
-
ml-
|
|
8369
|
+
ml-[16px] mt-[2px] flex flex-col gap-[2px]
|
|
8038
8370
|
`,
|
|
8039
8371
|
dragIndicator: `
|
|
8040
|
-
absolute left-0 right-0 h-0.5 bg-
|
|
8372
|
+
absolute left-0 right-0 h-0.5 bg-[#0088ff]
|
|
8041
8373
|
pointer-events-none
|
|
8042
8374
|
`,
|
|
8043
8375
|
searchContainer: `
|
|
8044
|
-
px-
|
|
8376
|
+
px-[10px] pb-[6px]
|
|
8045
8377
|
`,
|
|
8046
8378
|
searchInput: `
|
|
8047
|
-
w-full
|
|
8048
|
-
text-[13px]
|
|
8049
|
-
|
|
8379
|
+
h-[28px] w-full rounded-[8px] px-[8px]
|
|
8380
|
+
text-[13px] text-black dark:text-white
|
|
8381
|
+
placeholder:text-[#3c3c43]/50 dark:placeholder:text-[#ebebf5]/50
|
|
8382
|
+
bg-black/5 dark:bg-white/10
|
|
8050
8383
|
border border-transparent
|
|
8051
|
-
focus:outline-none focus:
|
|
8384
|
+
focus:outline-none focus:ring-2 focus:ring-[#0088ff]/60
|
|
8052
8385
|
transition-all duration-150
|
|
8053
8386
|
`,
|
|
8054
8387
|
header: `
|
|
8055
|
-
|
|
8056
|
-
flex items-center gap-3
|
|
8388
|
+
h-[52px] px-[21px] flex items-center gap-3
|
|
8057
8389
|
`,
|
|
8058
8390
|
headerAvatar: `
|
|
8059
|
-
w-
|
|
8060
|
-
flex items-center justify-center text-
|
|
8391
|
+
w-[30px] h-[30px] rounded-full bg-black/10 dark:bg-white/15
|
|
8392
|
+
flex items-center justify-center text-[13px] font-semibold
|
|
8061
8393
|
`,
|
|
8062
8394
|
headerTitle: `
|
|
8063
|
-
text-[13px] font-medium text-
|
|
8395
|
+
text-[13px] font-medium text-black dark:text-white
|
|
8064
8396
|
`,
|
|
8065
8397
|
headerSubtitle: `
|
|
8066
|
-
text-[11px] text-
|
|
8398
|
+
text-[11px] text-[#3c3c43]/60 dark:text-[#ebebf5]/60
|
|
8067
8399
|
`,
|
|
8068
8400
|
footer: `
|
|
8069
|
-
px-
|
|
8070
|
-
flex items-center gap-2
|
|
8401
|
+
px-[10px] pb-[8px] pt-[4px] flex items-center gap-2
|
|
8071
8402
|
`,
|
|
8072
8403
|
footerButton: `
|
|
8073
|
-
|
|
8074
|
-
text-
|
|
8075
|
-
hover:bg-black/5 dark:hover:bg-white/
|
|
8076
|
-
hover:text-neutral-700 dark:hover:text-neutral-200
|
|
8404
|
+
grid h-[28px] w-[28px] place-items-center rounded-[7px]
|
|
8405
|
+
text-[#3c3c43]/70 dark:text-[#ebebf5]/70
|
|
8406
|
+
hover:bg-black/5 dark:hover:bg-white/10
|
|
8077
8407
|
transition-colors duration-150
|
|
8078
8408
|
`
|
|
8079
8409
|
};
|
|
@@ -8492,19 +8822,21 @@ function renderTahoeSidebar(data) {
|
|
|
8492
8822
|
const itemClass = isSelected ? s.itemSelected : s.item;
|
|
8493
8823
|
const iconClass = isSelected ? s.itemIconSelected : s.itemIcon;
|
|
8494
8824
|
const badgeClass = isSelected ? s.itemBadgeSelected : s.itemBadge;
|
|
8825
|
+
const hasChildren = (item.children?.length ?? 0) > 0;
|
|
8826
|
+
const chevron = hasChildren ? `<span class='${s.disclosureChevron}${item.expanded ? " rotate-90" : ""}'>${icons.chevronRight}</span>` : "";
|
|
8827
|
+
const tint = item.color ? ` style='color: ${item.color}'` : "";
|
|
8495
8828
|
let html = `
|
|
8496
|
-
<div class='${itemClass}' data-id='${item.id}' style='padding-left: ${
|
|
8497
|
-
<span class='${
|
|
8829
|
+
<div class='${itemClass}' data-id='${item.id}'${depth > 0 ? ` style='padding-left: ${4 + depth * 16}px'` : ""}>
|
|
8830
|
+
<span class='${s.disclosure}'>${chevron}</span>
|
|
8831
|
+
<span class='${s.itemIconSlot}'><span class='${iconClass}'${tint}>${getIcon2(item.icon || "document")}</span></span>
|
|
8498
8832
|
<span class='${s.itemLabel}'>${item.label}</span>
|
|
8499
8833
|
${item.badge ? `<span class='${badgeClass}'>${item.badge}</span>` : ""}
|
|
8500
8834
|
</div>
|
|
8501
8835
|
`;
|
|
8502
8836
|
if (item.children && item.expanded) {
|
|
8503
|
-
html += `<div class='${s.children}'>`;
|
|
8504
8837
|
item.children.forEach((child) => {
|
|
8505
8838
|
html += renderItem(child, depth + 1);
|
|
8506
8839
|
});
|
|
8507
|
-
html += `</div>`;
|
|
8508
8840
|
}
|
|
8509
8841
|
return html;
|
|
8510
8842
|
};
|
|
@@ -8513,8 +8845,8 @@ function renderTahoeSidebar(data) {
|
|
|
8513
8845
|
<div class='${s.section}'>
|
|
8514
8846
|
${section.title ? `
|
|
8515
8847
|
<div class="${section.collapsible ? s.sectionHeaderCollapsible : s.sectionHeader}" data-section="${section.id}">
|
|
8516
|
-
|
|
8517
|
-
${section.
|
|
8848
|
+
<span class='truncate'>${section.title}</span>
|
|
8849
|
+
${section.collapsible ? `<span class='${s.collapseChevron}${section.collapsed ? " -rotate-90" : ""}'>${icons.chevronDown}</span>` : ""}
|
|
8518
8850
|
</div>
|
|
8519
8851
|
` : ""}
|
|
8520
8852
|
${!section.collapsed ? section.items.map((item) => renderItem(item)).join("") : ""}
|
|
@@ -9251,10 +9583,10 @@ __export(exports_updater, {
|
|
|
9251
9583
|
DeltaGenerator: () => DeltaGenerator,
|
|
9252
9584
|
AutoUpdater: () => AutoUpdater
|
|
9253
9585
|
});
|
|
9254
|
-
import { createReadStream, createWriteStream
|
|
9586
|
+
import { createReadStream, createWriteStream, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
9255
9587
|
import { join as join2, basename as basename2, dirname } from "path";
|
|
9256
9588
|
import { execFileSync, spawn as spawn3 } from "child_process";
|
|
9257
|
-
import { createHash } from "crypto";
|
|
9589
|
+
import { createHash as createHash2 } from "crypto";
|
|
9258
9590
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
9259
9591
|
function findFirstByName(root, namePattern, kind) {
|
|
9260
9592
|
const out = execFileSync("find", [root, "-name", namePattern, "-type", kind, "-print0"]);
|
|
@@ -9271,6 +9603,12 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9271
9603
|
cachedEtag = null;
|
|
9272
9604
|
cachedLastModified = null;
|
|
9273
9605
|
cachedManifest = null;
|
|
9606
|
+
emitError(error) {
|
|
9607
|
+
if (this.listenerCount("error") > 0)
|
|
9608
|
+
this.emit("error", error);
|
|
9609
|
+
else
|
|
9610
|
+
console.error("[Updater]", error);
|
|
9611
|
+
}
|
|
9274
9612
|
constructor(config) {
|
|
9275
9613
|
super();
|
|
9276
9614
|
const url = config.updateUrl;
|
|
@@ -9344,7 +9682,7 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9344
9682
|
return null;
|
|
9345
9683
|
}
|
|
9346
9684
|
} catch (error) {
|
|
9347
|
-
this.
|
|
9685
|
+
this.emitError(error);
|
|
9348
9686
|
return null;
|
|
9349
9687
|
}
|
|
9350
9688
|
}
|
|
@@ -9375,7 +9713,7 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9375
9713
|
const total = contentLength || expectedSize;
|
|
9376
9714
|
let downloaded = 0;
|
|
9377
9715
|
const startTime = Date.now();
|
|
9378
|
-
const fileStream =
|
|
9716
|
+
const fileStream = createWriteStream(this.downloadPath);
|
|
9379
9717
|
const reader = response.body?.getReader();
|
|
9380
9718
|
if (!reader) {
|
|
9381
9719
|
throw new Error("Failed to get response reader");
|
|
@@ -9398,11 +9736,32 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9398
9736
|
this.emit("download-progress", progress);
|
|
9399
9737
|
}
|
|
9400
9738
|
fileStream.end();
|
|
9739
|
+
await new Promise((resolve, reject) => {
|
|
9740
|
+
fileStream.once("finish", resolve);
|
|
9741
|
+
fileStream.once("error", reject);
|
|
9742
|
+
});
|
|
9401
9743
|
const hash = await this.computeFileHash(this.downloadPath);
|
|
9402
9744
|
if (hash !== expectedHash) {
|
|
9403
9745
|
unlinkSync(this.downloadPath);
|
|
9404
9746
|
throw new Error("Download verification failed: hash mismatch");
|
|
9405
9747
|
}
|
|
9748
|
+
if (deltaUpdate) {
|
|
9749
|
+
if (!statSync(this.config.appPath).isFile()) {
|
|
9750
|
+
throw new Error("Delta updates require appPath to point to the installed bundle file");
|
|
9751
|
+
}
|
|
9752
|
+
const patchPath = this.downloadPath;
|
|
9753
|
+
const reconstructedPath = join2(downloadDir, `reconstructed-${basename2(platformUpdate.url)}`);
|
|
9754
|
+
await DeltaGenerator.apply(this.config.appPath, patchPath, reconstructedPath);
|
|
9755
|
+
const reconstructedHash = await this.computeFileHash(reconstructedPath);
|
|
9756
|
+
if (reconstructedHash !== platformUpdate.sha256) {
|
|
9757
|
+
try {
|
|
9758
|
+
unlinkSync(reconstructedPath);
|
|
9759
|
+
} catch {}
|
|
9760
|
+
throw new Error("Delta reconstruction failed: full bundle hash mismatch");
|
|
9761
|
+
}
|
|
9762
|
+
unlinkSync(patchPath);
|
|
9763
|
+
this.downloadPath = reconstructedPath;
|
|
9764
|
+
}
|
|
9406
9765
|
if (this.config.publicKeyPem && !platformUpdate.signature) {
|
|
9407
9766
|
unlinkSync(this.downloadPath);
|
|
9408
9767
|
throw new Error("Updater: publicKeyPem is configured but the manifest entry has no signature. " + "Refusing to install unsigned update.");
|
|
@@ -9424,7 +9783,7 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9424
9783
|
}
|
|
9425
9784
|
return this.downloadPath;
|
|
9426
9785
|
} catch (error) {
|
|
9427
|
-
this.
|
|
9786
|
+
this.emitError(error);
|
|
9428
9787
|
return null;
|
|
9429
9788
|
}
|
|
9430
9789
|
}
|
|
@@ -9484,7 +9843,8 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9484
9843
|
}
|
|
9485
9844
|
} catch (error) {
|
|
9486
9845
|
progress.phase = "error";
|
|
9487
|
-
this.
|
|
9846
|
+
this.emitError(error);
|
|
9847
|
+
throw error;
|
|
9488
9848
|
}
|
|
9489
9849
|
}
|
|
9490
9850
|
async installMacOSUpdate() {
|
|
@@ -9603,7 +9963,7 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9603
9963
|
}
|
|
9604
9964
|
async computeFileHash(filePath) {
|
|
9605
9965
|
return new Promise((resolve, reject) => {
|
|
9606
|
-
const hash =
|
|
9966
|
+
const hash = createHash2("sha256");
|
|
9607
9967
|
const stream = createReadStream(filePath);
|
|
9608
9968
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
9609
9969
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
@@ -9629,7 +9989,7 @@ class AutoUpdater extends EventEmitter3 {
|
|
|
9629
9989
|
} catch {
|
|
9630
9990
|
return false;
|
|
9631
9991
|
}
|
|
9632
|
-
const data =
|
|
9992
|
+
const data = readFileSync2(filePath);
|
|
9633
9993
|
if (algo === "ed25519") {
|
|
9634
9994
|
return verify(null, data, publicKey, sigBytes);
|
|
9635
9995
|
}
|
|
@@ -9675,7 +10035,7 @@ class DeltaGenerator {
|
|
|
9675
10035
|
}
|
|
9676
10036
|
static async computeHash(filePath) {
|
|
9677
10037
|
return new Promise((resolve, reject) => {
|
|
9678
|
-
const hash =
|
|
10038
|
+
const hash = createHash2("sha256");
|
|
9679
10039
|
const stream = createReadStream(filePath);
|
|
9680
10040
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
9681
10041
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
@@ -9693,8 +10053,8 @@ function generateUpdateManifest(options) {
|
|
|
9693
10053
|
for (const [platform, info] of Object.entries(options.platforms)) {
|
|
9694
10054
|
if (!info)
|
|
9695
10055
|
continue;
|
|
9696
|
-
const bytes =
|
|
9697
|
-
const hash =
|
|
10056
|
+
const bytes = readFileSync2(info.path);
|
|
10057
|
+
const hash = createHash2("sha256").update(bytes).digest("hex");
|
|
9698
10058
|
manifest.platforms[platform] = {
|
|
9699
10059
|
url: info.url,
|
|
9700
10060
|
size: bytes.length,
|
|
@@ -9703,8 +10063,8 @@ function generateUpdateManifest(options) {
|
|
|
9703
10063
|
};
|
|
9704
10064
|
const platformDeltas = options.deltas?.filter((d) => d.platform === platform) || [];
|
|
9705
10065
|
for (const delta of platformDeltas) {
|
|
9706
|
-
const deltaBytes =
|
|
9707
|
-
const deltaHash =
|
|
10066
|
+
const deltaBytes = readFileSync2(delta.path);
|
|
10067
|
+
const deltaHash = createHash2("sha256").update(deltaBytes).digest("hex");
|
|
9708
10068
|
manifest.platforms[platform].delta.push({
|
|
9709
10069
|
fromVersion: delta.fromVersion,
|
|
9710
10070
|
url: delta.url,
|
|
@@ -9803,7 +10163,7 @@ var versionMismatchWarned = false;
|
|
|
9803
10163
|
function getSdkVersion() {
|
|
9804
10164
|
try {
|
|
9805
10165
|
const pkgPath = join3(import.meta.dir, "..", "package.json");
|
|
9806
|
-
return JSON.parse(
|
|
10166
|
+
return JSON.parse(readFileSync3(pkgPath, "utf-8")).version ?? "unknown";
|
|
9807
10167
|
} catch {
|
|
9808
10168
|
return "unknown";
|
|
9809
10169
|
}
|
|
@@ -9973,6 +10333,13 @@ class CraftApp {
|
|
|
9973
10333
|
args.push("--menubar-only");
|
|
9974
10334
|
if (window3?.titlebarHidden)
|
|
9975
10335
|
args.push("--titlebar-hidden");
|
|
10336
|
+
if (window3?.webSidebarMaterial) {
|
|
10337
|
+
args.push("--web-sidebar-material");
|
|
10338
|
+
if (window3?.webSidebarWidth)
|
|
10339
|
+
args.push("--web-sidebar-width", String(window3.webSidebarWidth));
|
|
10340
|
+
if (window3?.webSidebarMaterialOpacity !== undefined)
|
|
10341
|
+
args.push("--web-sidebar-material-opacity", String(window3.webSidebarMaterialOpacity));
|
|
10342
|
+
}
|
|
9976
10343
|
if (window3?.icon)
|
|
9977
10344
|
args.push("--icon", window3.icon);
|
|
9978
10345
|
if (window3?.nativeSidebar) {
|
|
@@ -9988,7 +10355,7 @@ class CraftApp {
|
|
|
9988
10355
|
} : undefined;
|
|
9989
10356
|
if (sidebarConfig?.variant === "desktop") {
|
|
9990
10357
|
sidebarConfig.material = sidebarConfig.material ?? "sidebar";
|
|
9991
|
-
sidebarConfig.backgroundEffect = sidebarConfig.backgroundEffect ?? "
|
|
10358
|
+
sidebarConfig.backgroundEffect = sidebarConfig.backgroundEffect ?? "vibrancy";
|
|
9992
10359
|
sidebarConfig.allowsVibrancy = sidebarConfig.allowsVibrancy ?? true;
|
|
9993
10360
|
}
|
|
9994
10361
|
if (sidebarConfig) {
|
|
@@ -10169,7 +10536,7 @@ export {
|
|
|
10169
10536
|
focusFilters,
|
|
10170
10537
|
focus,
|
|
10171
10538
|
exit,
|
|
10172
|
-
|
|
10539
|
+
exec,
|
|
10173
10540
|
env,
|
|
10174
10541
|
dialog,
|
|
10175
10542
|
device,
|
|
@@ -10238,3 +10605,5 @@ export {
|
|
|
10238
10605
|
AudioManager,
|
|
10239
10606
|
Animated
|
|
10240
10607
|
};
|
|
10608
|
+
|
|
10609
|
+
//# debugId=141B94C437209F2B64756E2164756E21
|