pake-cli 3.2.0-beta15 → 3.2.12

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/cli.js CHANGED
@@ -4,11 +4,11 @@ import { InvalidArgumentError, program, Option } from 'commander';
4
4
  import log from 'loglevel';
5
5
  import path from 'path';
6
6
  import fsExtra from 'fs-extra';
7
+ import { fileURLToPath } from 'url';
7
8
  import prompts from 'prompts';
8
9
  import { execa, execaSync } from 'execa';
9
10
  import crypto from 'crypto';
10
11
  import ora from 'ora';
11
- import { fileURLToPath } from 'url';
12
12
  import dns from 'dns';
13
13
  import http from 'http';
14
14
  import { promisify } from 'util';
@@ -22,7 +22,7 @@ import sharp from 'sharp';
22
22
  import * as psl from 'psl';
23
23
 
24
24
  var name = "pake-cli";
25
- var version$1 = "3.2.0-beta15";
25
+ var version = "3.2.12";
26
26
  var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
27
27
  var engines = {
28
28
  node: ">=16.0.0"
@@ -56,15 +56,13 @@ var scripts = {
56
56
  build: "npm run tauri build --",
57
57
  "build:debug": "npm run tauri build -- --debug",
58
58
  "build:mac": "npm run tauri build -- --target universal-apple-darwin",
59
- "build:config": "chmod +x script/app_config.mjs && node script/app_config.mjs",
59
+ "build:config": "chmod +x scripts/configure-tauri.mjs && node scripts/configure-tauri.mjs",
60
60
  analyze: "cd src-tauri && cargo bloat --release --crates",
61
61
  tauri: "tauri",
62
- cli: "rollup -c rollup.config.js --watch",
63
- "cli:dev": "cross-env NODE_ENV=development rollup -c rollup.config.js -w",
64
- "cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
65
- test: "npm run cli:build && PAKE_CREATE_APP=1 node tests/index.js",
66
- format: "prettier --write . --ignore-unknown && cd src-tauri && cargo fmt --verbose",
67
- "hooks:setup": "bash .githooks/setup.sh",
62
+ cli: "cross-env NODE_ENV=development rollup -c -w",
63
+ "cli:build": "cross-env NODE_ENV=production rollup -c",
64
+ test: "npm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
65
+ format: "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
68
66
  prepublishOnly: "npm run cli:build"
69
67
  };
70
68
  var type = "module";
@@ -110,7 +108,7 @@ var devDependencies = {
110
108
  };
111
109
  var packageJson = {
112
110
  name: name,
113
- version: version$1,
111
+ version: version,
114
112
  description: description,
115
113
  engines: engines,
116
114
  bin: bin,
@@ -126,136 +124,19 @@ var packageJson = {
126
124
  devDependencies: devDependencies
127
125
  };
128
126
 
129
- var windows = [
130
- {
131
- url: "https://weekly.tw93.fun/",
132
- url_type: "web",
133
- hide_title_bar: true,
134
- fullscreen: false,
135
- width: 1200,
136
- height: 780,
137
- resizable: true,
138
- always_on_top: false,
139
- dark_mode: false,
140
- activation_shortcut: "",
141
- disabled_web_shortcuts: false,
142
- hide_on_close: true,
143
- incognito: false
144
- }
145
- ];
146
- var user_agent = {
147
- macos: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15",
148
- linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
149
- windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
150
- };
151
- var system_tray = {
152
- macos: false,
153
- linux: true,
154
- windows: true
155
- };
156
- var system_tray_path = "icons/icon.png";
157
- var inject = [
158
- ];
159
- var proxy_url = "";
160
- var pakeConf = {
161
- windows: windows,
162
- user_agent: user_agent,
163
- system_tray: system_tray,
164
- system_tray_path: system_tray_path,
165
- inject: inject,
166
- proxy_url: proxy_url
167
- };
168
-
169
- var productName$1 = "Weekly";
170
- var identifier = "com.pake.weekly";
171
- var version = "1.0.0";
172
- var app = {
173
- withGlobalTauri: true,
174
- trayIcon: {
175
- iconPath: "png/weekly_512.png",
176
- iconAsTemplate: false,
177
- id: "pake-tray"
178
- }
179
- };
180
- var build = {
181
- frontendDist: "../dist"
182
- };
183
- var CommonConf = {
184
- productName: productName$1,
185
- identifier: identifier,
186
- version: version,
187
- app: app,
188
- build: build
189
- };
190
-
191
- var bundle$2 = {
192
- icon: [
193
- "png/weekly_256.ico",
194
- "png/weekly_32.ico"
195
- ],
196
- active: true,
197
- resources: [
198
- "png/weekly_32.ico"
199
- ],
200
- targets: [
201
- "msi"
202
- ],
203
- windows: {
204
- digestAlgorithm: "sha256",
205
- wix: {
206
- language: [
207
- "en-US"
208
- ],
209
- template: "assets/main.wxs"
210
- }
211
- }
212
- };
213
- var WinConf = {
214
- bundle: bundle$2
215
- };
216
-
217
- var bundle$1 = {
218
- icon: [
219
- "icons/weekly.icns"
220
- ],
221
- active: true,
222
- macOS: {
223
- },
224
- targets: [
225
- "dmg"
226
- ]
227
- };
228
- var MacConf = {
229
- bundle: bundle$1
230
- };
231
-
232
- var productName = "weekly";
233
- var bundle = {
234
- icon: [
235
- "png/weekly_512.png"
236
- ],
237
- active: true,
238
- linux: {
239
- deb: {
240
- depends: [
241
- "curl",
242
- "wget"
243
- ],
244
- files: {
245
- "/usr/share/applications/com-pake-weekly.desktop": "assets/com-pake-weekly.desktop"
246
- }
247
- }
248
- },
249
- targets: [
250
- "deb",
251
- "appimage"
252
- ]
253
- };
254
- var LinuxConf = {
255
- productName: productName,
256
- bundle: bundle
257
- };
127
+ // Convert the current module URL to a file path
128
+ const currentModulePath = fileURLToPath(import.meta.url);
129
+ // Resolve the parent directory of the current module
130
+ const npmDirectory = path.join(path.dirname(currentModulePath), '..');
131
+ const tauriConfigDirectory = path.join(npmDirectory, 'src-tauri', '.pake');
258
132
 
133
+ // Load configs from npm package directory, not from project source
134
+ const tauriSrcDir = path.join(npmDirectory, 'src-tauri');
135
+ const pakeConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'pake.json'));
136
+ const CommonConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.conf.json'));
137
+ const WinConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.windows.conf.json'));
138
+ const MacConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.macos.conf.json'));
139
+ const LinuxConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.linux.conf.json'));
259
140
  const platformConfigs = {
260
141
  win32: WinConf,
261
142
  darwin: MacConf,
@@ -315,12 +196,6 @@ const IS_MAC = platform$1 === 'darwin';
315
196
  const IS_WIN = platform$1 === 'win32';
316
197
  const IS_LINUX = platform$1 === 'linux';
317
198
 
318
- // Convert the current module URL to a file path
319
- const currentModulePath = fileURLToPath(import.meta.url);
320
- // Resolve the parent directory of the current module
321
- const npmDirectory = path.join(path.dirname(currentModulePath), '..');
322
- const tauriConfigDirectory = path.join(npmDirectory, 'src-tauri', '.pake');
323
-
324
199
  async function shellExec(command, timeout = 300000, env) {
325
200
  try {
326
201
  const { exitCode } = await execa(command, {
@@ -532,7 +407,34 @@ async function mergeConfig(url, options, tauriConf) {
532
407
  tauriConf.pake.system_tray[currentPlatform] = showSystemTray;
533
408
  // Processing targets are currently only open to Linux.
534
409
  if (platform === 'linux') {
410
+ // Remove hardcoded desktop files and regenerate with correct app name
535
411
  delete tauriConf.bundle.linux.deb.files;
412
+ // Generate correct desktop file configuration
413
+ const appNameLower = name.toLowerCase();
414
+ const identifier = `com.pake.${appNameLower}`;
415
+ const desktopFileName = `${identifier}.desktop`;
416
+ // Create desktop file content
417
+ const desktopContent = `[Desktop Entry]
418
+ Version=1.0
419
+ Type=Application
420
+ Name=${name}
421
+ Comment=${name}
422
+ Exec=${appNameLower}
423
+ Icon=${appNameLower}
424
+ Categories=Network;WebBrowser;
425
+ MimeType=text/html;text/xml;application/xhtml_xml;
426
+ StartupNotify=true
427
+ `;
428
+ // Write desktop file to src-tauri/assets directory where Tauri expects it
429
+ const srcAssetsDir = path.join(npmDirectory, 'src-tauri/assets');
430
+ const srcDesktopFilePath = path.join(srcAssetsDir, desktopFileName);
431
+ await fsExtra.ensureDir(srcAssetsDir);
432
+ await fsExtra.writeFile(srcDesktopFilePath, desktopContent);
433
+ // Set up desktop file in bundle configuration
434
+ // Use absolute path from src-tauri directory to assets
435
+ tauriConf.bundle.linux.deb.files = {
436
+ [`/usr/share/applications/${desktopFileName}`]: `assets/${desktopFileName}`,
437
+ };
536
438
  const validTargets = ['deb', 'appimage', 'rpm'];
537
439
  if (validTargets.includes(options.targets)) {
538
440
  tauriConf.bundle.targets = [options.targets];
@@ -541,6 +443,13 @@ async function mergeConfig(url, options, tauriConf) {
541
443
  logger.warn(`✼ The target must be one of ${validTargets.join(', ')}, the default 'deb' will be used.`);
542
444
  }
543
445
  }
446
+ // Set macOS bundle targets (for app vs dmg)
447
+ if (platform === 'darwin') {
448
+ const validMacTargets = ['app', 'dmg'];
449
+ if (validMacTargets.includes(options.targets)) {
450
+ tauriConf.bundle.targets = [options.targets];
451
+ }
452
+ }
544
453
  // Set icon.
545
454
  const platformIconMap = {
546
455
  win32: {
@@ -563,7 +472,7 @@ async function mergeConfig(url, options, tauriConf) {
563
472
  },
564
473
  };
565
474
  const iconInfo = platformIconMap[platform];
566
- const exists = await fsExtra.pathExists(options.icon);
475
+ const exists = options.icon && (await fsExtra.pathExists(options.icon));
567
476
  if (exists) {
568
477
  let updateIconPath = true;
569
478
  let customIconExt = path.extname(options.icon).toLowerCase();
@@ -575,7 +484,12 @@ async function mergeConfig(url, options, tauriConf) {
575
484
  else {
576
485
  const iconPath = path.join(npmDirectory, 'src-tauri/', iconInfo.path);
577
486
  tauriConf.bundle.resources = [iconInfo.path];
578
- await fsExtra.copy(options.icon, iconPath);
487
+ // Avoid copying if source and destination are the same
488
+ const absoluteIconPath = path.resolve(options.icon);
489
+ const absoluteDestPath = path.resolve(iconPath);
490
+ if (absoluteIconPath !== absoluteDestPath) {
491
+ await fsExtra.copy(options.icon, iconPath);
492
+ }
579
493
  }
580
494
  if (updateIconPath) {
581
495
  tauriConf.bundle.icon = [options.icon];
@@ -651,17 +565,19 @@ class BaseBuilder {
651
565
  this.options = options;
652
566
  }
653
567
  getBuildEnvironment() {
654
- return IS_MAC ? {
655
- 'CFLAGS': '-fno-modules',
656
- 'CXXFLAGS': '-fno-modules',
657
- 'MACOSX_DEPLOYMENT_TARGET': '14.0'
658
- } : undefined;
568
+ return IS_MAC
569
+ ? {
570
+ CFLAGS: '-fno-modules',
571
+ CXXFLAGS: '-fno-modules',
572
+ MACOSX_DEPLOYMENT_TARGET: '14.0',
573
+ }
574
+ : undefined;
659
575
  }
660
576
  getInstallTimeout() {
661
577
  return process.platform === 'win32' ? 600000 : 300000;
662
578
  }
663
579
  getBuildTimeout() {
664
- return 300000; // 5 minutes for build process
580
+ return 900000; // 15 minutes for all builds
665
581
  }
666
582
  async prepare() {
667
583
  const tauriSrcPath = path.join(npmDirectory, 'src-tauri');
@@ -692,7 +608,9 @@ class BaseBuilder {
692
608
  await fsExtra.ensureDir(rustProjectDir);
693
609
  // 统一使用npm,简单可靠
694
610
  const packageManager = 'npm';
695
- const registryOption = isChina ? ' --registry=https://registry.npmmirror.com' : '';
611
+ const registryOption = isChina
612
+ ? ' --registry=https://registry.npmmirror.com'
613
+ : '';
696
614
  const legacyPeerDeps = ' --legacy-peer-deps'; // 解决dependency conflicts
697
615
  const timeout = this.getInstallTimeout();
698
616
  const buildEnv = this.getBuildEnvironment();
@@ -722,7 +640,7 @@ class BaseBuilder {
722
640
  // Build app
723
641
  const buildSpinner = getSpinner('Building app...');
724
642
  // Let spinner run for a moment so user can see it, then stop before npm command
725
- await new Promise(resolve => setTimeout(resolve, 500));
643
+ await new Promise((resolve) => setTimeout(resolve, 500));
726
644
  buildSpinner.stop();
727
645
  // Show static message to keep the status visible
728
646
  logger.warn('✸ Building app...');
@@ -752,13 +670,18 @@ class BaseBuilder {
752
670
  if (IS_MAC && this.options.targets === 'app') {
753
671
  fullCommand += ' --bundles app';
754
672
  }
673
+ // Add features
674
+ const features = ['cli-build'];
755
675
  // Add macos-proxy feature for modern macOS (Darwin 23+ = macOS 14+)
756
676
  if (IS_MAC) {
757
677
  const macOSVersion = this.getMacOSMajorVersion();
758
678
  if (macOSVersion >= 23) {
759
- fullCommand += ' --features macos-proxy';
679
+ features.push('macos-proxy');
760
680
  }
761
681
  }
682
+ if (features.length > 0) {
683
+ fullCommand += ` --features ${features.join(',')}`;
684
+ }
762
685
  return fullCommand;
763
686
  }
764
687
  getMacOSMajorVersion() {
@@ -812,9 +735,26 @@ class MacBuilder extends BaseBuilder {
812
735
  return `${name}_${tauriConfig.version}_${arch}`;
813
736
  }
814
737
  getBuildCommand() {
815
- return this.options.multiArch
816
- ? 'npm run build:mac'
817
- : super.getBuildCommand();
738
+ if (this.options.multiArch) {
739
+ const baseCommand = this.options.debug
740
+ ? 'npm run tauri build -- --debug'
741
+ : 'npm run tauri build --';
742
+ // Use temporary config directory to avoid modifying source files
743
+ const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
744
+ let fullCommand = `${baseCommand} --target universal-apple-darwin -c "${configPath}"`;
745
+ // Add features
746
+ const features = ['cli-build'];
747
+ // Add macos-proxy feature for modern macOS (Darwin 23+ = macOS 14+)
748
+ const macOSVersion = this.getMacOSMajorVersion();
749
+ if (macOSVersion >= 23) {
750
+ features.push('macos-proxy');
751
+ }
752
+ if (features.length > 0) {
753
+ fullCommand += ` --features ${features.join(',')}`;
754
+ }
755
+ return fullCommand;
756
+ }
757
+ return super.getBuildCommand();
818
758
  }
819
759
  getBasePath() {
820
760
  return this.options.multiArch
@@ -1000,7 +940,22 @@ async function convertIconFormat(inputPath, appName) {
1000
940
  async function handleIcon(options, url) {
1001
941
  if (options.icon) {
1002
942
  if (options.icon.startsWith('http')) {
1003
- return downloadIcon(options.icon);
943
+ const downloadedPath = await downloadIcon(options.icon);
944
+ if (downloadedPath && options.name) {
945
+ // Convert downloaded icon to platform-specific format
946
+ const convertedPath = await convertIconFormat(downloadedPath, options.name);
947
+ if (convertedPath) {
948
+ // For Windows, copy the converted ico to the expected location
949
+ if (IS_WIN && convertedPath.endsWith('.ico')) {
950
+ const finalIconPath = path.join(npmDirectory, `src-tauri/png/${options.name.toLowerCase()}_256.ico`);
951
+ await fsExtra.ensureDir(path.dirname(finalIconPath));
952
+ await fsExtra.copy(convertedPath, finalIconPath);
953
+ return finalIconPath;
954
+ }
955
+ return convertedPath;
956
+ }
957
+ }
958
+ return downloadedPath;
1004
959
  }
1005
960
  return path.resolve(options.icon);
1006
961
  }
@@ -1011,11 +966,43 @@ async function handleIcon(options, url) {
1011
966
  return faviconPath;
1012
967
  }
1013
968
  logger.info('✼ No icon provided, using default icon.');
1014
- const iconPath = IS_WIN
1015
- ? 'src-tauri/png/icon_256.ico'
1016
- : IS_LINUX
1017
- ? 'src-tauri/png/icon_512.png'
1018
- : 'src-tauri/icons/icon.icns';
969
+ // For Windows, ensure we have proper fallback handling
970
+ if (IS_WIN) {
971
+ const defaultIcoPath = path.join(npmDirectory, 'src-tauri/png/icon_256.ico');
972
+ const defaultPngPath = path.join(npmDirectory, 'src-tauri/png/icon_512.png');
973
+ // First try default ico
974
+ if (await fsExtra.pathExists(defaultIcoPath)) {
975
+ return defaultIcoPath;
976
+ }
977
+ // If ico doesn't exist, try to convert from png
978
+ if (await fsExtra.pathExists(defaultPngPath)) {
979
+ logger.info('✼ Default ico not found, converting from png...');
980
+ try {
981
+ const convertedPath = await convertIconFormat(defaultPngPath, 'icon');
982
+ if (convertedPath && (await fsExtra.pathExists(convertedPath))) {
983
+ // Copy converted icon to the expected location for Windows
984
+ const finalIconPath = path.join(npmDirectory, 'src-tauri/png/icon_256.ico');
985
+ await fsExtra.ensureDir(path.dirname(finalIconPath));
986
+ await fsExtra.copy(convertedPath, finalIconPath);
987
+ return finalIconPath;
988
+ }
989
+ }
990
+ catch (error) {
991
+ logger.warn(`Failed to convert default png to ico: ${error.message}`);
992
+ }
993
+ }
994
+ // Last resort: return png path if it exists (Windows can handle png in some cases)
995
+ if (await fsExtra.pathExists(defaultPngPath)) {
996
+ logger.warn('✼ Using png as fallback for Windows (may cause issues).');
997
+ return defaultPngPath;
998
+ }
999
+ // If nothing exists, return empty string to let merge.ts handle default icon
1000
+ logger.warn('✼ No default icon found, will use pake default.');
1001
+ return '';
1002
+ }
1003
+ const iconPath = IS_LINUX
1004
+ ? 'src-tauri/png/icon_512.png'
1005
+ : 'src-tauri/icons/icon.icns';
1019
1006
  return path.join(npmDirectory, iconPath);
1020
1007
  }
1021
1008
  /**
@@ -1024,10 +1011,10 @@ async function handleIcon(options, url) {
1024
1011
  function generateIconServiceUrls(domain) {
1025
1012
  const logoDevUrls = API_TOKENS.logoDev
1026
1013
  .sort(() => Math.random() - 0.5)
1027
- .map(token => `https://img.logo.dev/${domain}?token=${token}&format=png&size=256`);
1014
+ .map((token) => `https://img.logo.dev/${domain}?token=${token}&format=png&size=256`);
1028
1015
  const brandfetchUrls = API_TOKENS.brandfetch
1029
1016
  .sort(() => Math.random() - 0.5)
1030
- .map(key => `https://cdn.brandfetch.io/${domain}/w/400/h/400?c=${key}`);
1017
+ .map((key) => `https://cdn.brandfetch.io/${domain}/w/400/h/400?c=${key}`);
1031
1018
  return [
1032
1019
  ...logoDevUrls,
1033
1020
  ...brandfetchUrls,
@@ -1051,18 +1038,33 @@ async function tryGetFavicon(url, appName) {
1051
1038
  const domain = new URL(url).hostname;
1052
1039
  const spinner = getSpinner(`Fetching icon from ${domain}...`);
1053
1040
  const serviceUrls = generateIconServiceUrls(domain);
1041
+ // Use shorter timeout for CI environments
1042
+ const isCI = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
1043
+ const downloadTimeout = isCI ? 5000 : ICON_CONFIG.downloadTimeout;
1054
1044
  for (const serviceUrl of serviceUrls) {
1055
1045
  try {
1056
- const faviconPath = await downloadIcon(serviceUrl, false);
1046
+ const faviconPath = await downloadIcon(serviceUrl, false, downloadTimeout);
1057
1047
  if (!faviconPath)
1058
1048
  continue;
1059
1049
  const convertedPath = await convertIconFormat(faviconPath, appName);
1060
1050
  if (convertedPath) {
1051
+ // For Windows, copy the converted ico to the expected location
1052
+ if (IS_WIN && convertedPath.endsWith('.ico')) {
1053
+ const finalIconPath = path.join(npmDirectory, `src-tauri/png/${appName.toLowerCase()}_256.ico`);
1054
+ await fsExtra.ensureDir(path.dirname(finalIconPath));
1055
+ await fsExtra.copy(convertedPath, finalIconPath);
1056
+ spinner.succeed(chalk.green('Icon fetched and converted successfully!'));
1057
+ return finalIconPath;
1058
+ }
1061
1059
  spinner.succeed(chalk.green('Icon fetched and converted successfully!'));
1062
1060
  return convertedPath;
1063
1061
  }
1064
1062
  }
1065
- catch {
1063
+ catch (error) {
1064
+ // Log specific errors in CI for debugging
1065
+ if (isCI) {
1066
+ logger.debug(`Icon service ${serviceUrl} failed: ${error.message}`);
1067
+ }
1066
1068
  continue;
1067
1069
  }
1068
1070
  }
@@ -1077,17 +1079,18 @@ async function tryGetFavicon(url, appName) {
1077
1079
  /**
1078
1080
  * Downloads icon from URL
1079
1081
  */
1080
- async function downloadIcon(iconUrl, showSpinner = true) {
1082
+ async function downloadIcon(iconUrl, showSpinner = true, customTimeout) {
1081
1083
  try {
1082
1084
  const response = await axios.get(iconUrl, {
1083
1085
  responseType: 'arraybuffer',
1084
- timeout: ICON_CONFIG.downloadTimeout,
1086
+ timeout: customTimeout || ICON_CONFIG.downloadTimeout,
1085
1087
  });
1086
1088
  const iconData = response.data;
1087
1089
  if (!iconData || iconData.byteLength < ICON_CONFIG.minFileSize)
1088
1090
  return null;
1089
1091
  const fileDetails = await fileTypeFromBuffer(iconData);
1090
- if (!fileDetails || !ICON_CONFIG.supportedFormats.includes(fileDetails.ext)) {
1092
+ if (!fileDetails ||
1093
+ !ICON_CONFIG.supportedFormats.includes(fileDetails.ext)) {
1091
1094
  return null;
1092
1095
  }
1093
1096
  return await saveIconFile(iconData, fileDetails.ext);
@@ -1201,7 +1204,8 @@ async function handleOptions(options, url) {
1201
1204
  name,
1202
1205
  identifier: getIdentifier(url),
1203
1206
  };
1204
- appOptions.icon = await handleIcon(appOptions, url);
1207
+ const iconPath = await handleIcon(appOptions, url);
1208
+ appOptions.icon = iconPath || undefined;
1205
1209
  return appOptions;
1206
1210
  }
1207
1211