diff --git a/.circleci/config.yml b/.circleci/config.yml index 273c6b3..7739105 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,6 +20,12 @@ jobs: type: string steps: - node/test: + override-ci-command: | + if [ << parameters.node-version >> = '14.21' ]; then + yarn install --frozen-lockfile --ignore-engines + else + yarn install --frozen-lockfile + fi checkout-steps: - when: condition: diff --git a/.gitignore b/.gitignore index 3c5c090..6331af4 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ spec/fixtures/app/Update.exe vendor/7z.dll vendor/7z.exe hook.log +docs diff --git a/README.md b/README.md index 34862a4..aaece6a 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,6 @@ const electronInstaller = require('electron-winstaller'); Then do a build like so.. ```javascript -// NB: Use this syntax within an async function, Node does not have support for -// top-level await as of Node 12. try { await electronInstaller.createWindowsInstaller({ appDirectory: '/tmp/build/my-app-64', diff --git a/package.json b/package.json index d1438bc..d7cbe94 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "scripts": { "install": "node ./script/select-7z-arch.js", "build": "tsc", + "docs": "npx typedoc", "prepublish": "npm run build", "lint": "eslint --ext .ts src spec", "ava": "ava --timeout=60s", @@ -45,6 +46,7 @@ "eslint": "^8.49.0", "eslint-plugin-ava": "^14.0.0", "ts-node": "^10.9.1", + "typedoc": "0.25.13", "typescript": "^4.9.3" }, "optionalDependencies": { diff --git a/src/index.ts b/src/index.ts index a38c734..17c4180 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,14 @@ export { SquirrelWindowsOptions as Options} from './options'; const log = require('debug')('electron-windows-installer:main'); +/** + * A utility function to convert SemVer version strings into NuGet-compatible + * version strings. + * @param version A SemVer version string + * @returns A NuGet-compatible version string + * @see {@link https://semver.org/ | Semantic Versioning specification} + * @see {@link https://learn.microsoft.com/en-us/nuget/concepts/package-versioning?tabs=semver20sort | NuGet versioning specification} + */ export function convertVersion(version: string): string { const parts = version.split('+')[0].split('-'); const mainVersion = parts.shift(); @@ -34,7 +42,13 @@ function checkIfCommandExists(command: string): Promise { }); } - +/** + * This package's main function, which creates a Squirrel.Windows executable + * installer and optionally code-signs the output. + * + * @param options Options for installer generation and signing + * @see {@link https://github.com/Squirrel/Squirrel.Windows | Squirrel.Windows} + */ export async function createWindowsInstaller(options: SquirrelWindowsOptions): Promise { let useMono = false; diff --git a/src/options.ts b/src/options.ts index dd8b7dd..d92c41c 100644 --- a/src/options.ts +++ b/src/options.ts @@ -12,65 +12,82 @@ export interface SquirrelWindowsOptions { /** * The folder path to create the .exe installer in. * - * Defaults to the installer folder at the project root. + * @defaultValue an `installer` folder at the project root. */ outputDirectory?: string; /** * The path to the .nuspectemplate file used by Squirrel.exe. * - * Defaults to the bundled template.nuspectemplate. + * @defaultValue the bundled {@link https://github.com/electron/windows-installer/blob/main/template.nuspectemplate | template.nuspectemplate}. */ nuspecTemplate?: string; /** * The local path to a `.gif` file to display during install. + * + * @defaultValue the bundled {@link https://github.com/electron/windows-installer/blob/main/resources/install-spinner.gif | install-spinner.gif} */ loadingGif?: string; /** - * The authors value for the nuget package metadata. + * The `authors` value for the NuGet package metadata. * - * Defaults to the `author` field from your app's package.json file when unspecified. + * @defaultValue the `author` field from your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. + * @see {@link https://learn.microsoft.com/en-us/nuget/reference/nuspec | the Microsoft .nuspec reference}. */ authors?: string; /** - * The owners value for the nuget package metadata. + * The `owners` value for the NuGet package metadata. * - * Defaults to the `authors` field when unspecified. + * @defaultValue the `authors` field from your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. + * @see {@link https://learn.microsoft.com/en-us/nuget/reference/nuspec | the Microsoft .nuspec reference}. */ owners?: string; /** - * The copyright value for the nuget package metadata. + * The `copyright` value for the NuGet package metadata. * - * Defaults to a generated copyright with `authors` or `owners`. + * @defaultValue a generated copyright with {@link SquirrelWindowsOptions.authors | authors} + * or {@link SquirrelWindowsOptions.owners | owners}. + * @see {@link https://learn.microsoft.com/en-us/nuget/reference/nuspec | the Microsoft .nuspec reference}. */ copyright?: string; /** * The name of your app's main `.exe` file. * - * This uses the `name` field in your app's package.json file with an added `.exe` extension when unspecified. + * @defaultValue the `name` field in your app's package.json file with an added `.exe` extension + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. */ exe?: string; /** - * The description value for the nuget package metadata. + * The `description` value for the NuGet package metadata. * - * Defaults to the `description` field from your app's package.json file when unspecified. + * @defaultValue the `description` field from your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. + * @see {@link https://learn.microsoft.com/en-us/nuget/reference/nuspec | the Microsoft .nuspec reference}. */ description?: string; /** - * The version value for the nuget package metadata. + * The `version` value for the Nuget package metadata. * - * Defaults to the `version` field from your app's package.json file when unspecified. + * @defaultValue the `version` field from your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. + * @see {@link https://learn.microsoft.com/en-us/nuget/reference/nuspec | the Microsoft .nuspec reference}. */ version?: string; /** - * The title value for the nuget package metadata. + * The `title` value for the nuget package metadata. * - * Defaults to the `productName` field and then the `name` field from your app's package.json file when unspecified. + * @defaultValue the `productName` field and then the `name` field from your app's package.json + * file unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. + * @see {@link https://learn.microsoft.com/en-us/nuget/reference/nuspec | the Microsoft .nuspec reference}. */ title?: string; /** * Windows Application Model ID (appId). * - * Defaults to the name field in your app's package.json file. + * @defaultValue the `name` field in your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. + * @see {@link https://learn.microsoft.com/en-us/windows/win32/shell/appids | Microsoft's Application User Model IDs documentation}. */ name?: string; /** @@ -78,7 +95,8 @@ export interface SquirrelWindowsOptions { * * This is a legacy parameter provided for backwards compatibility. * For more comprehensive support of various codesigning scenarios - * like EV certificates, see the "windowsSign" parameter. + * like EV certificates, see the + * {@link SquirrelWindowsOptions.windowsSign | windowsSign} parameter. */ certificateFile?: string; /** @@ -86,17 +104,20 @@ export interface SquirrelWindowsOptions { * * This is a legacy parameter provided for backwards compatibility. * For more comprehensive support of various codesigning scenarios - * like EV certificates, see the "windowsSign" parameter. + * like EV certificates, see the + * {@link SquirrelWindowsOptions.windowsSign | windowsSign} parameter. */ certificatePassword?: string; /** * Params to pass to signtool. * - * Overrides `certificateFile` and `certificatePassword`. + * Overrides {@link SquirrelWindowsOptions.certificateFile | certificateFile} + * and {@link SquirrelWindowsOptions.certificatePassword | certificatePassword}`. * * This is a legacy parameter provided for backwards compatibility. * For more comprehensive support of various codesigning scenarios - * like EV certificates, see the "windowsSign" parameter. + * like EV certificates, see the + * {@link SquirrelWindowsOptions.windowsSign | windowsSign} parameter. */ signWithParams?: string; /** @@ -106,7 +127,7 @@ export interface SquirrelWindowsOptions { * * Does not accept `file:` URLs. * - * Defaults to the Electron icon. + * @defaultValue the Electron icon. */ iconUrl?: string; /** @@ -115,48 +136,65 @@ export interface SquirrelWindowsOptions { setupIcon?: string; /** * The name to use for the generated Setup.exe file + * @defaultValue the `productName` field from your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. */ setupExe?: string; /** * The name to use for the generated Setup.msi file + * @defaultValue the `productName` field from your app's package.json file + * unless {@link SquirrelWindowsOptions.usePackageJson | usePackageJson} is false. */ setupMsi?: string; /** - * Should Squirrel.Windows create an MSI installer? + * Enable this flag to prevent Squirrel.Windows from creating an MSI installer. + * @defaultValue false */ noMsi?: boolean; /** - * Should Squirrel.Windows delta packages? (disable only if necessary, they are a Good Thing) + * Enable this flag to prevent Squirrel.Windows from creating delta packages (disable only if necessary, they are a Good Thing). + * @defaultValue false */ noDelta?: boolean; /** - * A URL to your existing updates. If given, these will be downloaded to create delta updates + * A URL to your existing updates. If given, these will be downloaded to create delta updates. */ remoteReleases?: string; /** - * Authentication token for remote updates + * Authentication token for remote updates using {@link SquirrelWindowsOptions.remoteReleases | remoteReleases} */ remoteToken?: string; - + /** + * Whether or not to infer metadata options from your app's package.json file. + * @defaultValue true + */ usePackageJson?: boolean; - + /** + * Set the required .NET framework version (e.g. `net461`). + */ frameworkVersion?: string; - + /** + * Attempt to create more descriptive installer names using metadata parameters. + * @defaultValue false + */ fixUpPaths?: boolean; - + /** + * Enable this flag to skip setting a custom icon for `Update.exe` + * @defaultValue false + */ skipUpdateIcon?: boolean; /** * Requires Node.js 18 or newer. * - * Sign your app with @electron/windows-sign, allowing for full customization + * Sign your app with `@electron/windows-sign`, allowing for full customization * of the code-signing process - and supports more complicated scenarios like * cloud-hosted EV certificates, custom sign pipelines, and per-file overrides. * It also supports all existing "simple" codesigning scenarios, including * just passing a certificate file and password. * - * Please see https://github.com/@electron/windows-sign for all possible - * configuration options. + * @see {@link https://github.com/electron/windows-sign | @electron/windows-sign documentation} + * for all possible configuration options. */ windowsSign?: SignToolOptions; } diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..883263c --- /dev/null +++ b/typedoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["./src/index.ts"] +} diff --git a/yarn.lock b/yarn.lock index fbdc05b..1624877 100644 --- a/yarn.lock +++ b/yarn.lock @@ -327,6 +327,11 @@ ansi-regex@^6.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== +ansi-sequence-parser@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" + integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== + ansi-styles@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.0.0.tgz" @@ -463,6 +468,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -1257,6 +1269,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +jsonc-parser@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4" + integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" @@ -1324,6 +1341,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + make-error@^1.1.1: version "1.3.5" resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz" @@ -1336,6 +1358,11 @@ map-age-cleaner@^0.1.3: dependencies: p-defer "^1.0.0" +marked@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" + integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== + matcher@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz" @@ -1388,6 +1415,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.3: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -1673,6 +1707,16 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shiki@^0.14.7: + version "0.14.7" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.7.tgz#c3c9e1853e9737845f1d2ef81b31bcfb07056d4e" + integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== + dependencies: + ansi-sequence-parser "^1.1.0" + jsonc-parser "^3.2.0" + vscode-oniguruma "^1.7.0" + vscode-textmate "^8.0.0" + signal-exit@^4.0.1: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" @@ -1839,6 +1883,16 @@ type-fest@^0.20.2: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +typedoc@0.25.13: + version "0.25.13" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.13.tgz#9a98819e3b2d155a6d78589b46fa4c03768f0922" + integrity sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ== + dependencies: + lunr "^2.3.9" + marked "^4.3.0" + minimatch "^9.0.3" + shiki "^0.14.7" + typescript@^4.9.3: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" @@ -1866,6 +1920,16 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== +vscode-oniguruma@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" + integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== + +vscode-textmate@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" + integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== + well-known-symbols@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz"