@nwutils/packager 0.4.0 → 0.6.0
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/README.md +130 -35
- package/package.json +15 -4
- package/src/appImage.js +307 -10
- package/src/index.js +13 -6
- package/src/nsis.js +563 -0
- package/src/util.js +202 -2
- package/types/appImage.d.ts +85 -14
- package/types/index.d.ts +21 -5
- package/types/nsis.d.ts +140 -0
- package/types/util.d.ts +102 -7
package/src/util.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -71,16 +72,215 @@ function parseDesktopEntry(contents) {
|
|
|
71
72
|
function stringifyDesktopEntry(entries) {
|
|
72
73
|
let fileContent = "[Desktop Entry]\n";
|
|
73
74
|
for (const key of Object.keys(entries)) {
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
const value = entries[key];
|
|
76
|
+
if (value !== undefined) {
|
|
77
|
+
/* A line break would let the key or value inject further entries, eg. a second `Exec`. */
|
|
78
|
+
if (/[\r\n]/.test(key) || /[\r\n]/.test(value)) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Desktop entry keys and values must not contain line breaks. Received: ${JSON.stringify(`${key}=${value}`)}`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
fileContent += `${key}=${value}\n`;
|
|
76
84
|
}
|
|
77
85
|
}
|
|
78
86
|
return fileContent;
|
|
79
87
|
}
|
|
80
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Quote `value` as a single POSIX shell word. Inside single quotes nothing is
|
|
91
|
+
* expanded, so only single quotes themselves need escaping.
|
|
92
|
+
* @param {string} value
|
|
93
|
+
* @returns {string}
|
|
94
|
+
*/
|
|
95
|
+
function shellQuote(value) {
|
|
96
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Quote `value` as a single argument of a desktop entry's `Exec` key, per the
|
|
101
|
+
* Desktop Entry Specification: `%` is doubled so it isn't read as a field
|
|
102
|
+
* code, an argument with reserved characters is double quoted with `"`, `` ` ``,
|
|
103
|
+
* `$` and `\` backslash-escaped, and finally backslashes are escaped again as
|
|
104
|
+
* required for every string value.
|
|
105
|
+
* @param {string} value
|
|
106
|
+
* @returns {string}
|
|
107
|
+
*/
|
|
108
|
+
function desktopExecArg(value) {
|
|
109
|
+
let arg = value.replaceAll("%", "%%");
|
|
110
|
+
if (/[\s"'\\><~|&;$*?#()`]/.test(arg)) {
|
|
111
|
+
arg = `"${arg.replace(/["`$\\]/g, "\\$&")}"`;
|
|
112
|
+
}
|
|
113
|
+
return arg.replaceAll("\\", "\\\\");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Name of the update info file `@nwutils/updater` downloads to find the
|
|
118
|
+
* latest release, following electron-builder's naming: `x64` gets the bare
|
|
119
|
+
* `latest-linux.yml`, every other architecture gets an `-<arch>` suffix.
|
|
120
|
+
* @param {"ia32" | "x64" | "arm64"} arch
|
|
121
|
+
* @returns {string}
|
|
122
|
+
*/
|
|
123
|
+
function updateInfoFileName(arch) {
|
|
124
|
+
return arch === "x64" ? "latest-linux.yml" : `latest-linux-${arch}.yml`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Serialise `value` as a YAML scalar. Strings are written double-quoted via
|
|
129
|
+
* `JSON.stringify` - a JSON string literal is also a valid YAML double-quoted
|
|
130
|
+
* scalar, so this never needs YAML-specific escaping rules.
|
|
131
|
+
* @param {string | number | boolean} value
|
|
132
|
+
* @returns {string}
|
|
133
|
+
*/
|
|
134
|
+
function stringifyYamlScalar(value) {
|
|
135
|
+
return typeof value === "string" ? JSON.stringify(value) : String(value);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Serialise a map of scalars, and lists of maps of scalars, as YAML. This is
|
|
140
|
+
* the only shape the update info and `app-update.yml` files use, so it avoids
|
|
141
|
+
* pulling in a YAML library for a handful of lines.
|
|
142
|
+
* @param {Record<string, string | number | boolean | Record<string, string | number | boolean>[] | undefined>} entries
|
|
143
|
+
* @returns {string}
|
|
144
|
+
*/
|
|
145
|
+
function stringifyYaml(entries) {
|
|
146
|
+
let fileContent = "";
|
|
147
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
148
|
+
if (value === undefined) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (Array.isArray(value)) {
|
|
152
|
+
fileContent += `${key}:\n`;
|
|
153
|
+
for (const item of value) {
|
|
154
|
+
let prefix = " - ";
|
|
155
|
+
for (const [itemKey, itemValue] of Object.entries(item)) {
|
|
156
|
+
fileContent += `${prefix}${itemKey}: ${stringifyYamlScalar(itemValue)}\n`;
|
|
157
|
+
prefix = " ";
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
fileContent += `${key}: ${stringifyYamlScalar(value)}\n`;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return fileContent;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Compute the base64 encoded SHA-512 digest of the file at `filePath`, the
|
|
169
|
+
* same encoding electron-builder writes into its update info files.
|
|
170
|
+
* @async
|
|
171
|
+
* @function
|
|
172
|
+
* @param {string} filePath
|
|
173
|
+
* @returns {Promise<string>}
|
|
174
|
+
*/
|
|
175
|
+
async function sha512(filePath) {
|
|
176
|
+
const hash = crypto.createHash("sha512");
|
|
177
|
+
for await (const chunk of fs.createReadStream(filePath)) {
|
|
178
|
+
hash.update(chunk);
|
|
179
|
+
}
|
|
180
|
+
return hash.digest("base64");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Escape `value` for use inside a double quoted NSIS string. NSIS expands `$`
|
|
185
|
+
* variables and `$\` escapes there, so `$` is doubled and `"` is escaped.
|
|
186
|
+
* Line breaks are rejected rather than escaped: a raw one would end the
|
|
187
|
+
* command and let the value inject further script lines. The result is not
|
|
188
|
+
* quoted, so it can be joined with NSIS variables, eg. `"$INSTDIR\<value>"`.
|
|
189
|
+
* @param {string} value
|
|
190
|
+
* @returns {string}
|
|
191
|
+
*/
|
|
192
|
+
function nsisEscape(value) {
|
|
193
|
+
if (/[\r\n]/.test(value)) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`NSIS strings must not contain line breaks. Received: ${JSON.stringify(value)}`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
/* In a replacement string `$$` is a literal `$`, so "$$$$" writes "$$". */
|
|
199
|
+
return value.replaceAll("$", "$$$$").replaceAll('"', '$\\"');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Check a path on the host for use inside a double quoted NSIS string that
|
|
204
|
+
* `makensis` reads at compile time, eg. a `File` source or `OutFile`. Unlike
|
|
205
|
+
* runtime strings, those keep `$` literally, so nothing is escaped. Instead,
|
|
206
|
+
* the sequences `makensis` would still interpret are rejected: `${define}`
|
|
207
|
+
* expansions and `$\` escapes, and `"` - an escaped `$\"` doesn't survive
|
|
208
|
+
* being passed through a `!define`, as the icon and license paths are.
|
|
209
|
+
* @param {string} value
|
|
210
|
+
* @returns {string} `value`, unchanged.
|
|
211
|
+
*/
|
|
212
|
+
function nsisPath(value) {
|
|
213
|
+
if (/[\r\n"]/.test(value) || value.includes("${") || value.includes("$\\")) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`Paths passed to NSIS must not contain line breaks, '"', "\${" or "$\\". Received: ${JSON.stringify(value)}`,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Names Windows reserves for devices, with or without an extension.
|
|
223
|
+
* @type {RegExp}
|
|
224
|
+
*/
|
|
225
|
+
const WINDOWS_RESERVED_NAME = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Check that `value` can be used as a single Windows file name: no path
|
|
229
|
+
* separators, characters Windows forbids in file names, control characters,
|
|
230
|
+
* trailing dots or spaces, or reserved device names.
|
|
231
|
+
* @param {string} value
|
|
232
|
+
* @returns {boolean}
|
|
233
|
+
*/
|
|
234
|
+
function isWindowsFileName(value) {
|
|
235
|
+
const hasControlCharacter = [...value].some((character) => {
|
|
236
|
+
const code = character.charCodeAt(0);
|
|
237
|
+
return code < 0x20 || code === 0x7f;
|
|
238
|
+
});
|
|
239
|
+
return (
|
|
240
|
+
value !== "" &&
|
|
241
|
+
/[<>:"/\\|?*]/.test(value) === false &&
|
|
242
|
+
hasControlCharacter === false &&
|
|
243
|
+
/[. ]$/.test(value) === false &&
|
|
244
|
+
WINDOWS_RESERVED_NAME.test(value) === false
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Convert a version such as `"1.2.3"` or `"1.2.3-beta.1"` into the
|
|
250
|
+
* `X.X.X.X` form Windows version resources (and NSIS' `VIProductVersion`)
|
|
251
|
+
* require. Up to four leading numeric parts are kept, missing ones are
|
|
252
|
+
* filled with `0`, and any prerelease or build suffix is dropped.
|
|
253
|
+
* @param {string} version
|
|
254
|
+
* @returns {string}
|
|
255
|
+
*/
|
|
256
|
+
function windowsVersion(version) {
|
|
257
|
+
const match = version.match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?/);
|
|
258
|
+
if (match === null) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`Expected a version starting with a number, eg. "1.2.3". Received: ${JSON.stringify(version)}`,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
const parts = match.slice(1).map((part) => Number(part ?? 0));
|
|
264
|
+
if (parts.some((part) => part > 65535)) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
`Expected each part of the version to be at most 65535. Received: ${JSON.stringify(version)}`,
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
return parts.join(".");
|
|
270
|
+
}
|
|
271
|
+
|
|
81
272
|
export default {
|
|
82
273
|
APPIMAGE_ARCH_KV,
|
|
274
|
+
desktopExecArg,
|
|
83
275
|
fileExists,
|
|
276
|
+
isWindowsFileName,
|
|
277
|
+
nsisEscape,
|
|
278
|
+
nsisPath,
|
|
84
279
|
parseDesktopEntry,
|
|
280
|
+
sha512,
|
|
281
|
+
shellQuote,
|
|
85
282
|
stringifyDesktopEntry,
|
|
283
|
+
stringifyYaml,
|
|
284
|
+
updateInfoFileName,
|
|
285
|
+
windowsVersion,
|
|
86
286
|
};
|
package/types/appImage.d.ts
CHANGED
|
@@ -1,47 +1,120 @@
|
|
|
1
|
+
export default appImage;
|
|
1
2
|
export type AppImageOptions = {
|
|
2
3
|
/**
|
|
3
4
|
* Path to a built NW.js Linux application, ie. the `outDir` produced by `@nwutils/builder` for `platform: "linux"`.
|
|
4
5
|
*/
|
|
5
6
|
appDir: string;
|
|
6
7
|
/**
|
|
7
|
-
* Name of the application. Must match the `app.name` value used to build `appDir` - the executable and desktop entry are expected at `<appDir>/<appName>` and `<appDir>/<appName>.desktop`.
|
|
8
|
+
* Name of the application. Must match the `app.name` value used to build `appDir` - the executable and desktop entry are expected at `<appDir>/<appName>` and `<appDir>/<appName>.desktop`. Must not contain `/` or control characters.
|
|
8
9
|
*/
|
|
9
10
|
appName: string;
|
|
10
11
|
/**
|
|
11
12
|
* Path to a `.png` or `.svg` icon. Defaults to the `Icon` value read from `<appDir>/<appName>.desktop`.
|
|
12
13
|
*/
|
|
13
|
-
icon?: string;
|
|
14
|
+
icon?: string | undefined;
|
|
14
15
|
/**
|
|
15
16
|
* Target architecture. Defaults to the host architecture. `appimagetool` runs as a native binary, so this must match the host unless the host has emulation (eg. QEMU/binfmt) configured for the target architecture.
|
|
16
17
|
*/
|
|
17
|
-
arch?: "ia32" | "x64" | "arm64";
|
|
18
|
+
arch?: "ia32" | "x64" | "arm64" | undefined;
|
|
18
19
|
/**
|
|
19
20
|
* Directory the resulting `.AppImage` file is written to. Defaults to the parent directory of `appDir`.
|
|
20
21
|
*/
|
|
21
|
-
outDir?: string;
|
|
22
|
+
outDir?: string | undefined;
|
|
22
23
|
/**
|
|
23
24
|
* Directory used to cache the downloaded `appimagetool` binary.
|
|
24
25
|
*/
|
|
25
|
-
cacheDir?: string;
|
|
26
|
+
cacheDir?: string | undefined;
|
|
26
27
|
/**
|
|
27
28
|
* If true, reuse a cached `appimagetool` binary. Otherwise redownload it.
|
|
28
29
|
*/
|
|
29
|
-
cache?: boolean;
|
|
30
|
+
cache?: boolean | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Base URL `appimagetool-<arch>.AppImage` is downloaded from. Defaults to the `AppImage/appimagetool` "continuous" GitHub release. Must be https, except for localhost.
|
|
33
|
+
*/
|
|
34
|
+
appImageToolUrl?: string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* If true, embed a GPG signature in the AppImage. Requires `gpg` and a usable secret key on the host. A passphrase-protected key reads its passphrase from the `APPIMAGETOOL_SIGN_PASSPHRASE` environment variable.
|
|
37
|
+
*/
|
|
38
|
+
sign?: boolean | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* ID of the GPG key to sign with. Defaults to `gpg`'s default secret key. Requires `sign` to be true.
|
|
41
|
+
*/
|
|
42
|
+
signKey?: string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Version of the application, eg. `"1.2.0"`. Required when `publish` is set: it is written to the update info file `@nwutils/updater` compares against.
|
|
45
|
+
*/
|
|
46
|
+
version?: string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Where releases are published. When set, an `app-update.yml` pointing at it is embedded in the AppImage and a `latest-linux[-<arch>].yml` update info file is written next to it, for `@nwutils/updater` to self update from.
|
|
49
|
+
*/
|
|
50
|
+
publish?: PublishOptions | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* AppImage update information for zsync based updaters (eg. AppImageUpdate, `appimageupdatetool`, AppImage managers). `true` derives it from `publish`. A string is embedded as-is, eg. `"gh-releases-zsync|owner|repo|latest|Demo-x86_64.AppImage.zsync"`. Requires `zsyncmake` on the host to produce the `.zsync` file.
|
|
53
|
+
*/
|
|
54
|
+
updateInformation?: string | boolean | undefined;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Publish to a GitHub repository's releases. The AppImage and update info
|
|
58
|
+
* file must be uploaded as assets of the latest (non draft, non prerelease)
|
|
59
|
+
* release.
|
|
60
|
+
*/
|
|
61
|
+
export type GitHubPublishOptions = {
|
|
62
|
+
provider: "github";
|
|
63
|
+
/**
|
|
64
|
+
* Owner of the GitHub repository.
|
|
65
|
+
*/
|
|
66
|
+
owner: string;
|
|
67
|
+
/**
|
|
68
|
+
* Name of the GitHub repository.
|
|
69
|
+
*/
|
|
70
|
+
repo: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Publish to any static file server. The AppImage and update info file must
|
|
74
|
+
* be served from `url`.
|
|
75
|
+
*/
|
|
76
|
+
export type GenericPublishOptions = {
|
|
77
|
+
provider: "generic";
|
|
30
78
|
/**
|
|
31
|
-
* Base URL
|
|
79
|
+
* Base URL the latest release's files are served from.
|
|
32
80
|
*/
|
|
33
|
-
|
|
81
|
+
url: string;
|
|
34
82
|
};
|
|
83
|
+
export type PublishOptions = GitHubPublishOptions | GenericPublishOptions;
|
|
35
84
|
/**
|
|
36
85
|
* @typedef {object} AppImageOptions
|
|
37
86
|
* @property {string} appDir Path to a built NW.js Linux application, ie. the `outDir` produced by `@nwutils/builder` for `platform: "linux"`.
|
|
38
|
-
* @property {string} appName Name of the application. Must match the `app.name` value used to build `appDir` - the executable and desktop entry are expected at `<appDir>/<appName>` and `<appDir>/<appName>.desktop`.
|
|
87
|
+
* @property {string} appName Name of the application. Must match the `app.name` value used to build `appDir` - the executable and desktop entry are expected at `<appDir>/<appName>` and `<appDir>/<appName>.desktop`. Must not contain `/` or control characters.
|
|
39
88
|
* @property {string} [icon] Path to a `.png` or `.svg` icon. Defaults to the `Icon` value read from `<appDir>/<appName>.desktop`.
|
|
40
89
|
* @property {"ia32" | "x64" | "arm64"} [arch] Target architecture. Defaults to the host architecture. `appimagetool` runs as a native binary, so this must match the host unless the host has emulation (eg. QEMU/binfmt) configured for the target architecture.
|
|
41
90
|
* @property {string} [outDir] Directory the resulting `.AppImage` file is written to. Defaults to the parent directory of `appDir`.
|
|
42
91
|
* @property {string} [cacheDir="./cache"] Directory used to cache the downloaded `appimagetool` binary.
|
|
43
92
|
* @property {boolean} [cache=true] If true, reuse a cached `appimagetool` binary. Otherwise redownload it.
|
|
44
|
-
* @property {string} [appImageToolUrl] Base URL `appimagetool-<arch>.AppImage` is downloaded from. Defaults to the `AppImage/appimagetool` "continuous" GitHub release.
|
|
93
|
+
* @property {string} [appImageToolUrl] Base URL `appimagetool-<arch>.AppImage` is downloaded from. Defaults to the `AppImage/appimagetool` "continuous" GitHub release. Must be https, except for localhost.
|
|
94
|
+
* @property {boolean} [sign=false] If true, embed a GPG signature in the AppImage. Requires `gpg` and a usable secret key on the host. A passphrase-protected key reads its passphrase from the `APPIMAGETOOL_SIGN_PASSPHRASE` environment variable.
|
|
95
|
+
* @property {string} [signKey] ID of the GPG key to sign with. Defaults to `gpg`'s default secret key. Requires `sign` to be true.
|
|
96
|
+
* @property {string} [version] Version of the application, eg. `"1.2.0"`. Required when `publish` is set: it is written to the update info file `@nwutils/updater` compares against.
|
|
97
|
+
* @property {PublishOptions} [publish] Where releases are published. When set, an `app-update.yml` pointing at it is embedded in the AppImage and a `latest-linux[-<arch>].yml` update info file is written next to it, for `@nwutils/updater` to self update from.
|
|
98
|
+
* @property {string | boolean} [updateInformation] AppImage update information for zsync based updaters (eg. AppImageUpdate, `appimageupdatetool`, AppImage managers). `true` derives it from `publish`. A string is embedded as-is, eg. `"gh-releases-zsync|owner|repo|latest|Demo-x86_64.AppImage.zsync"`. Requires `zsyncmake` on the host to produce the `.zsync` file.
|
|
99
|
+
*/
|
|
100
|
+
/**
|
|
101
|
+
* Publish to a GitHub repository's releases. The AppImage and update info
|
|
102
|
+
* file must be uploaded as assets of the latest (non draft, non prerelease)
|
|
103
|
+
* release.
|
|
104
|
+
* @typedef {object} GitHubPublishOptions
|
|
105
|
+
* @property {"github"} provider
|
|
106
|
+
* @property {string} owner Owner of the GitHub repository.
|
|
107
|
+
* @property {string} repo Name of the GitHub repository.
|
|
108
|
+
*/
|
|
109
|
+
/**
|
|
110
|
+
* Publish to any static file server. The AppImage and update info file must
|
|
111
|
+
* be served from `url`.
|
|
112
|
+
* @typedef {object} GenericPublishOptions
|
|
113
|
+
* @property {"generic"} provider
|
|
114
|
+
* @property {string} url Base URL the latest release's files are served from.
|
|
115
|
+
*/
|
|
116
|
+
/**
|
|
117
|
+
* @typedef {GitHubPublishOptions | GenericPublishOptions} PublishOptions
|
|
45
118
|
*/
|
|
46
119
|
/**
|
|
47
120
|
* Package a built NW.js Linux application as an AppImage.
|
|
@@ -53,7 +126,7 @@ export type AppImageOptions = {
|
|
|
53
126
|
* @param {AppImageOptions} options
|
|
54
127
|
* @returns {Promise<string>} Path to the resulting `.AppImage` file.
|
|
55
128
|
*/
|
|
56
|
-
declare function appImage({ appDir, appName, icon, arch, outDir, cacheDir, cache, appImageToolUrl, }: AppImageOptions): Promise<string>;
|
|
129
|
+
declare function appImage({ appDir, appName, icon, arch, outDir, cacheDir, cache, appImageToolUrl, sign, signKey, version, publish, updateInformation, }: AppImageOptions): Promise<string>;
|
|
57
130
|
/**
|
|
58
131
|
* Download (or reuse a cached) `appimagetool` binary for `appImageToolArch`.
|
|
59
132
|
* @async
|
|
@@ -65,11 +138,9 @@ declare function appImage({ appDir, appName, icon, arch, outDir, cacheDir, cache
|
|
|
65
138
|
* @param {boolean} options.cache If true, reuse a cached binary. Otherwise redownload it.
|
|
66
139
|
* @returns {Promise<string>} Path to an executable `appimagetool` binary.
|
|
67
140
|
*/
|
|
68
|
-
|
|
141
|
+
export function getAppImageTool({ appImageToolArch, appImageToolUrl, cacheDir, cache, }: {
|
|
69
142
|
appImageToolArch: string;
|
|
70
143
|
appImageToolUrl: string;
|
|
71
144
|
cacheDir: string;
|
|
72
145
|
cache: boolean;
|
|
73
146
|
}): Promise<string>;
|
|
74
|
-
export default appImage;
|
|
75
|
-
export { getAppImageTool };
|
package/types/index.d.ts
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
|
+
export default packager;
|
|
2
|
+
/**
|
|
3
|
+
* Supported packaged output formats.
|
|
4
|
+
*
|
|
5
|
+
* `AppImage`, `deb` and `rpm` package a Linux build. `MSIX` and `NSIS`
|
|
6
|
+
* package a Windows build. `"AppImage"` and `"nsis"` are implemented today -
|
|
7
|
+
* the others are reserved so this option doesn't need to change shape once
|
|
8
|
+
* they land.
|
|
9
|
+
*/
|
|
1
10
|
export type PackageFormat = "AppImage" | "deb" | "rpm" | "msix" | "nsis" | "dmg";
|
|
11
|
+
/**
|
|
12
|
+
* Where releases are published, for packagers that support self updating.
|
|
13
|
+
*/
|
|
14
|
+
export type PublishOptions = import("./appImage.js").PublishOptions;
|
|
2
15
|
/**
|
|
3
16
|
* Supported packaged output formats.
|
|
4
17
|
*
|
|
5
18
|
* `AppImage`, `deb` and `rpm` package a Linux build. `MSIX` and `NSIS`
|
|
6
|
-
* package a Windows build.
|
|
7
|
-
* others are reserved so this option doesn't need to change shape once
|
|
8
|
-
* land.
|
|
19
|
+
* package a Windows build. `"AppImage"` and `"nsis"` are implemented today -
|
|
20
|
+
* the others are reserved so this option doesn't need to change shape once
|
|
21
|
+
* they land.
|
|
9
22
|
* @typedef {"AppImage" | "deb" | "rpm" | "msix" | "nsis" | "dmg"} PackageFormat
|
|
10
23
|
*/
|
|
24
|
+
/**
|
|
25
|
+
* Where releases are published, for packagers that support self updating.
|
|
26
|
+
* @typedef {import("./appImage.js").PublishOptions} PublishOptions
|
|
27
|
+
*/
|
|
11
28
|
/**
|
|
12
29
|
* Package a built NW.js application.
|
|
13
30
|
* @async
|
|
14
31
|
* @function
|
|
15
|
-
* @param {{format: PackageFormat} & Record<string, any>} options `format`, plus the options the matching packager (eg. `appImage`) expects.
|
|
32
|
+
* @param {{format: PackageFormat} & Record<string, any>} options `format`, plus the options the matching packager (eg. `appImage` or `nsis`) expects.
|
|
16
33
|
* @returns {Promise<string>} Path to the resulting packaged artifact.
|
|
17
34
|
*/
|
|
18
35
|
declare function packager({ format, ...options }: {
|
|
19
36
|
format: PackageFormat;
|
|
20
37
|
} & Record<string, any>): Promise<string>;
|
|
21
|
-
export default packager;
|
package/types/nsis.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export default nsis;
|
|
2
|
+
export type NsisOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* Path to a built NW.js Windows application, ie. the `outDir` produced by `@nwutils/builder` for `platform: "win"`.
|
|
5
|
+
*/
|
|
6
|
+
appDir: string;
|
|
7
|
+
/**
|
|
8
|
+
* Name of the application. Must match the `app.name` value used to build `appDir` - the executable is expected at `<appDir>/<appName>.exe`. Must be a valid Windows file name.
|
|
9
|
+
*/
|
|
10
|
+
appName: string;
|
|
11
|
+
/**
|
|
12
|
+
* Version of the application, eg. `"1.2.0"`. Shown in Windows' installed apps list, and converted to `X.X.X.X` for the installer's own version resource.
|
|
13
|
+
*/
|
|
14
|
+
version: string;
|
|
15
|
+
/**
|
|
16
|
+
* Architecture `appDir` was built for. Defaults to the host architecture. The installer refuses to run on Windows machines that can't run that architecture.
|
|
17
|
+
*/
|
|
18
|
+
arch?: "ia32" | "x64" | "arm64" | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Directory the resulting `<appName>-<arch>-Setup.exe` file is written to. Defaults to the parent directory of `appDir`.
|
|
21
|
+
*/
|
|
22
|
+
outDir?: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Path to a `.ico` icon for the installer and uninstaller. Defaults to NSIS' own icon.
|
|
25
|
+
*/
|
|
26
|
+
icon?: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Name of the registry key the installation is recorded under. Defaults to `appName`. Keep it the same across releases, so installing a new version replaces the previous one.
|
|
29
|
+
*/
|
|
30
|
+
appId?: string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Publisher shown in Windows' installed apps list.
|
|
33
|
+
*/
|
|
34
|
+
publisher?: string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Copyright notice written into the installer's version information.
|
|
37
|
+
*/
|
|
38
|
+
copyright?: string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Path to a `.txt` or `.rtf` license file. When set, the installer shows it on a page the user has to accept.
|
|
41
|
+
*/
|
|
42
|
+
license?: string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* If true, create a desktop shortcut.
|
|
45
|
+
*/
|
|
46
|
+
desktopShortcut?: boolean | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* If true, create a Start Menu shortcut.
|
|
49
|
+
*/
|
|
50
|
+
startMenuShortcut?: boolean | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Path to the NSIS compiler. Defaults to `makensis` on the `PATH`.
|
|
53
|
+
*/
|
|
54
|
+
makensisPath?: string | undefined;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The files and directories of a built application, relative to its root.
|
|
58
|
+
*/
|
|
59
|
+
export type AppFiles = {
|
|
60
|
+
/**
|
|
61
|
+
* Relative file paths, using the host's path separator.
|
|
62
|
+
*/
|
|
63
|
+
files: string[];
|
|
64
|
+
/**
|
|
65
|
+
* Relative directory paths, parents before children.
|
|
66
|
+
*/
|
|
67
|
+
dirs: string[];
|
|
68
|
+
/**
|
|
69
|
+
* Total size of `files` in bytes.
|
|
70
|
+
*/
|
|
71
|
+
size: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Package a built NW.js Windows application as an NSIS installer.
|
|
75
|
+
*
|
|
76
|
+
* The installer installs for the current user only, into
|
|
77
|
+
* `%LOCALAPPDATA%\Programs\<appName>`, so it never asks for administrator
|
|
78
|
+
* rights. It registers an uninstaller in Windows' installed apps list, and
|
|
79
|
+
* installing a new version first uninstalls the previous one. Both wait for
|
|
80
|
+
* the application to be closed before touching its files.
|
|
81
|
+
*
|
|
82
|
+
* This composes with `@nwutils/builder`: run it against the `outDir` (and
|
|
83
|
+
* `app.name`) that `@nwutils/builder` produced for `platform: "win"`.
|
|
84
|
+
* `makensis` runs on Linux and macOS too, so the installer can be built on
|
|
85
|
+
* any host.
|
|
86
|
+
* @async
|
|
87
|
+
* @function
|
|
88
|
+
* @param {NsisOptions} options
|
|
89
|
+
* @returns {Promise<string>} Path to the resulting installer `.exe` file.
|
|
90
|
+
*/
|
|
91
|
+
declare function nsis({ appDir, appName, version, arch, outDir, icon, appId, publisher, copyright, license, desktopShortcut, startMenuShortcut, makensisPath, }: NsisOptions): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* List the files and directories under `appDir`. Symbolic links are followed,
|
|
94
|
+
* since NSIS copies what they point at.
|
|
95
|
+
* @async
|
|
96
|
+
* @function
|
|
97
|
+
* @param {string} appDir Absolute path to the built application.
|
|
98
|
+
* @returns {Promise<AppFiles>}
|
|
99
|
+
*/
|
|
100
|
+
export function listAppFiles(appDir: string): Promise<AppFiles>;
|
|
101
|
+
/**
|
|
102
|
+
* Generate the NSIS script for an installer.
|
|
103
|
+
*
|
|
104
|
+
* Every file is listed explicitly rather than copied with `File /r`, so the
|
|
105
|
+
* uninstaller deletes exactly the files that were installed. The user can
|
|
106
|
+
* choose any install directory - including one such as `C:\` that holds
|
|
107
|
+
* other files - so the uninstaller never deletes directories recursively.
|
|
108
|
+
* @param {object} options
|
|
109
|
+
* @param {string} options.appDir Absolute path to the built application.
|
|
110
|
+
* @param {AppFiles} options.appFiles Files and directories under `appDir`.
|
|
111
|
+
* @param {string} options.appName
|
|
112
|
+
* @param {string} options.appId
|
|
113
|
+
* @param {string} options.version
|
|
114
|
+
* @param {string} options.fileVersion `version` in `X.X.X.X` form.
|
|
115
|
+
* @param {"ia32" | "x64" | "arm64"} options.arch
|
|
116
|
+
* @param {string} options.installerPath Absolute path the installer is written to.
|
|
117
|
+
* @param {string} [options.iconPath] Absolute path to a `.ico` file.
|
|
118
|
+
* @param {string} [options.licensePath] Absolute path to a `.txt` or `.rtf` file.
|
|
119
|
+
* @param {string} [options.publisher]
|
|
120
|
+
* @param {string} options.copyright
|
|
121
|
+
* @param {boolean} options.desktopShortcut
|
|
122
|
+
* @param {boolean} options.startMenuShortcut
|
|
123
|
+
* @returns {string}
|
|
124
|
+
*/
|
|
125
|
+
export function nsisScript({ appDir, appFiles, appName, appId, version, fileVersion, arch, installerPath, iconPath, licensePath, publisher, copyright, desktopShortcut, startMenuShortcut, }: {
|
|
126
|
+
appDir: string;
|
|
127
|
+
appFiles: AppFiles;
|
|
128
|
+
appName: string;
|
|
129
|
+
appId: string;
|
|
130
|
+
version: string;
|
|
131
|
+
fileVersion: string;
|
|
132
|
+
arch: "ia32" | "x64" | "arm64";
|
|
133
|
+
installerPath: string;
|
|
134
|
+
iconPath?: string | undefined;
|
|
135
|
+
licensePath?: string | undefined;
|
|
136
|
+
publisher?: string | undefined;
|
|
137
|
+
copyright: string;
|
|
138
|
+
desktopShortcut: boolean;
|
|
139
|
+
startMenuShortcut: boolean;
|
|
140
|
+
}): string;
|