Repository: jiahaog/nativefier
File: src/build/buildNativefierApp.ts (TypeScript)

Code before:
    }
  }
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export async function buildNativefierApp(
  rawOptions: NativefierOptions,
): Promise<string[]> {
  log.info('Processing options...');
  const options = await getOptions(rawOptions);

  if (options.packager.platform === 'darwin' && isWindows()) {
    // electron-packager has to extract the desired electron package for the target platform.
    // For a target platform of Mac, this zip file contains symlinks. And on Windows, extracting
    // files that are symlinks need Admin permissions. So we'll check if the user is an admin, and
    // fail early if not.
    // For reference
    // https://github.com/electron/electron-packager/issues/933
    // https://github.com/electron/electron-packager/issues/1194
    // https://github.com/electron/electron/issues/11094
    const admin = await isAdmin();
    if (!admin) {
      throw new Error(
        'Building an app with a target platform of Mac on a Windows machine requires admin priveleges to perform. Please rerun this command in an admin command prompt.',
      );
    }
  }

  log.info('\nPreparing Electron app...');
  const tmpPath = getTempDir('app', 0o755);
  await prepareElectronApp(options.packager.dir, tmpPath, options);

  log.info('\nConverting icons...');
  options.packager.dir = tmpPath; // const optionsWithTmpPath = { ...options, dir: tmpPath };
  convertIconIfNecessary(options);
  await copyIconsIfNecessary(options, tmpPath);

  log.info(
    "\nPackaging... This will take a few seconds, maybe minutes if the requested Electron isn't cached yet...",
  );
  trimUnprocessableOptions(options);
  electronGet.initializeProxy(); // https://github.com/electron/get#proxies
  const appPathArray = await electronPackager(options.packager);

  log.info('\nFinalizing build...');
  const appPaths =
    options.packager.arch === 'all' ? appPathArray : [getAppPath(appPathArray)];

  if (appPaths) {
    let osRunHelp = '';
    if (options.packager.platform === 'win32') {

Review comment (bug):
Neat. One gripe: I strive to limit the amount of dependencies, for maintainability and security.

In this case, I don't think the extra `is-admin` dep costs exceed the rare benefits of the early exit (macOS builds on Windows must not be super frequent). Please either:

- A. Show a pre-build warning that admin rights are required (which may be incorrect if user is already running as admin).
- B. Add extra error handling when we fail during a macOS build under Windows, warning that it might be due to be admin (which may also be incorrect as above, and secondly incorrect if the crash was due to something else).
- C. Steal from `is-admin` into a util function, which cite their sources https://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights or https://stackoverflow.com/questions/57009374/check-admin-or-non-admin-users-in-nodejs-or-javascript . Looking at the alternatives, I'd go for the `fltmc` one, it doesn't require shell features and can be done in a simple `require('child_process').spawn(`

I'd be happy with any of the three.

Code after:
      'Wine is required when packaging a Windows app under on non-Windows platforms.',
      'Also, note that Windows apps built under non-Windows platforms without Wine *will lack* certain',
      'features, like a correct icon and process name. Do yourself a favor and install Wine, please.',
    );
    for (const keyToUnset of optionsPresent) {
      options[keyToUnset] = null;
    }
  }
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export async function buildNativefierApp(
  rawOptions: NativefierOptions,
): Promise<string> {
  log.info('Processing options...');
  const options = await getOptions(rawOptions);

  if (options.packager.platform === 'darwin' && isWindows()) {
    // electron-packager has to extract the desired electron package for the target platform.
    // For a target platform of Mac, this zip file contains symlinks. And on Windows, extracting
    // files that are symlinks need Admin permissions. So we'll check if the user is an admin, and
    // fail early if not.
    // For reference
    // https://github.com/electron/electron-packager/issues/933
    // https://github.com/electron/electron-packager/issues/1194
    // https://github.com/electron/electron/issues/11094
    if (!isWindowsAdmin()) {
      throw new Error(
        'Building an app with a target platform of Mac on a Windows machine requires admin priveleges to perform. Please rerun this command in an admin command prompt.',
      );
    }
  }

  log.info('\nPreparing Electron app...');
  const tmpPath = getTempDir('app', 0o755);
  await prepareElectronApp(options.packager.dir, tmpPath, options);

  log.info('\nConverting icons...');
  options.packager.dir = tmpPath; // const optionsWithTmpPath = { ...options, dir: tmpPath };
  convertIconIfNecessary(options);
  await copyIconsIfNecessary(options, tmpPath);

  log.info(
    "\nPackaging... This will take a few seconds, maybe minutes if the requested Electron isn't cached yet...",
  );
  trimUnprocessableOptions(options);
  electronGet.initializeProxy(); // https://github.com/electron/get#proxies
  const appPathArray = await electronPackager(options.packager);

  log.info('\nFinalizing build...');
  const appPath = getAppPath(appPathArray);