From ceccc550eea014d73407b693f05c367dc5331835 Mon Sep 17 00:00:00 2001
From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com>
Date: Sun, 10 May 2026 14:19:53 +0530
Subject: [PATCH 1/4] chore(docs): update docs
---
README.md | 108 ++++++++++++-------------------------------------
src/main.js | 49 +++++++++++++++++++++-
src/updater.js | 1 +
3 files changed, 75 insertions(+), 83 deletions(-)
diff --git a/README.md b/README.md
index 72ada51..2b4db2b 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ const updater = new Updater(nw.App.manifest);
let updateStatus = "";
let newManifest = "";
+let downloadedFilePath = "";
updater.checkNewVersion((err, newerVersionExists, remoteManifest) => {
if (err) {
updateStatus = `Error checking for updates: ${err.message}`;
@@ -40,84 +41,22 @@ updater.download((err, filePath) => {
return;
}
downloadStatus = "Update downloaded successfully at " + filePath;
+ downloadedFilePath = filePath;
}, newManifest);
-```
-
-It gives you low-level API to:
-1. Check the manifest for version (from your running "old" app).
-2. If the version is different from the running one, download new package to a temp directory.
-3. Unpack the package in temp.
-4. Run new app from temp and kill the old one (i.e. still all from the running app).
-5. The new app (in temp) will copy itself to the original folder, overwriting the old app.
-6. The new app will run itself from original folder and exit the process.
+updater.download();
+```
## API
-
-
-#### new updater(manifest, options)
-
-Creates new instance of updater. Manifest could be a `package.json` of project.
-
-Note that compressed apps are assumed to be downloaded in the format produced by [nw-builder](https://github.com/nwutils/nw-builder) (or [grunt-nw-builder](https://github.com/nwjs/grunt-nw-builder)).
-
-**Params**
-
-- manifest `object` - See the [manifest schema](#manifest-schema) below.
-- options `object` - Optional
-
-
-
-#### updater.checkNewVersion(cb)
-
-Will check the latest available version of the application by requesting the manifest specified in `manifestUrl`.
-
-The callback will always be called; the second parameter indicates whether or not there's a newer version.
-This function assumes you use [Semantic Versioning](http://semver.org) and enforces it; if your local version is `0.2.0` and the remote one is `0.1.23456` then the callback will be called with `false` as the second paramter. If on the off chance you don't use semantic versioning, you could manually download the remote manifest and call `download` if you're happy that the remote version is newer.
-
-**Params**
-
-- cb `function` - Callback arguments: error, newerVersionExists (`Boolean`), remoteManifest
-
-
-
-#### updater.download(cb, newManifest)
-
-Downloads the new app to a temporary folder.
-
-**Params**
-
-- cb `function` - called when download completes. Callback arguments: error, downloaded filepath
-- newManifest `Object` - see [manifest schema](#manifest-schema) below
-
-**Returns**: `Request` - Request - stream, the stream contains `manifest` property with new manifest and 'content-length' property with the size of package.
-
-
-#### updater.getAppPath()
-
-Returns executed application path
-
-**Returns**: `string`
-
-
-#### updater.getAppExec()
-
-Returns current application executable
-
-**Returns**: `string`
-
-
-#### updater.unpack(filename, cb, manifest)
-
-Will unpack the `filename` in temporary folder.
-For Windows, [unzip](https://www.mkssoftware.com/docs/man1/unzip.1.asp) is used (which is [not signed](https://github.com/edjafarov/node-webkit-updater/issues/68)).
-
-**Params**
-
-- filename `string`
-- cb `function` - Callback arguments: error, unpacked directory
-- manifest `object`
+| Method | Arguments | Return Type | Description |
+| ------ | --------- | ----------- | ----------- |
+| new Updater | `manifest: object, options: object \| undefined` | `void` | Creates a new instance of Updater. See the [manifest schema](#manifest-schema) below. |
+| checkNewVersion | `cb: (error: Error, newerVersionExists: boolean, remoteManifest: object) => void` | `void` | Checks the latest version of the application by requesting manifest at `manifestUrl`. Semantic versioning is used when comparing versions. |
+| download | `cb: (error: Error, filepath: string) => void, newManifest: object` | `void` | Checks the latest version of the application by requesting manifest at `manifestUrl`. Downloads the new app to a temporary folder. |
+| getAppPath | | `string` | Returns the executed application path. |
+| getAppExec | | `string` | Returns the current application path. |
+| unpack | `filename: string, cb: (error: Error, unpackedDir: string) => void, manifest: object` | `string` | Returns the executed application path. |
@@ -211,18 +150,23 @@ It's assumed your app is stored at the root of your package, use this to overrid
This can also be used to override `manifest.name`; e.g. if your `manifest.name` is `helloWorld` (therefore `helloWorld.app` on Mac) but your Windows executable is named `nw.exe`. Then you'd set `execPath` to `nw.exe`
----
-
-## Troubleshooting
+## Roadmap
-### Mac
+1. Check the manifest for version (from your running "old" app).
+2. If the version is different from the running one, download new package to a temp directory.
+3. Unpack the package in temp.
+4. Run new app from temp and kill the old one (i.e. still all from the running app).
+5. The new app (in temp) will copy itself to the original folder, overwriting the old app.
+6. The new app will run itself from original folder and exit the process.
-If you get an error on Mac about too many files being open, run `ulimit -n 10240`
+## Contributing
-### Windows
+### External contributor
-On Windows, there is no "unzip" command built in by default. As a result, this project uses a third party "unzip.exe" in order to extract the downloaded update. On the NWJS site, in the "How to package and distribute your apps" file, one of the recommended methods of distribution is using EnigmaVirtualBox to package the app, nw.exe, and required DLLs into a single EXE file. This method works great for distribution, but unfortunately breaks node-webkit-updater, because it wraps the required unzip.exe file inside of the created EnigmaVirtualBox EXE. As a result, *it is not possible to use EnigmaVirtualBox to distribute your app if you plan on using node-webkit-updater*. Try using InnoSetup instead.
+- Use Node.js standard libraries whenever possible.
+- Prefer to use syncronous APIs over modern APIs which have been introduced in later versions.
-## Contributing
+### Maintainer
-See [CONTRIBUTING.md](CONTRIBUTING.md)
+- npm trusted publishing is used for releases
+- a package is released when a maintainer creates a release note for a specific version
diff --git a/src/main.js b/src/main.js
index 749691c..4f97e22 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,6 +1,7 @@
const fs = await import('node:fs');
const os = await import('node:os');
const path = await import('node:path');
+const process = await import('node:process');
const stream = await import('node:stream');
function semverGt(v1, v2) {
@@ -25,7 +26,7 @@ function semverGt(v1, v2) {
/**
* @typedef {object} Packages
* @property {Platform} win - The Windows package
- * @property {Platform} mac - The macOS package
+ * @property {Platform} osx - The macOS package
* @property {Platform} linux32 - The Linux 32-bit package
* @property {Platform} linux64 - The Linux 64-bit package
*/
@@ -160,6 +161,52 @@ class Updater {
cb(err, null);
});
}
+
+ /**
+ * Returns executed application path.
+ *
+ * @returns {string}
+ */
+ getAppPath() {
+ /**
+ * @type {Object.}
+ */
+ let appPath = {
+ osx: path.join(process.cwd(), '../../..'),
+ win: path.dirname(process.execPath)
+ };
+ appPath.linux32 = appPath.win;
+ appPath.linux64 = appPath.win;
+ return appPath[getHost()];
+ }
+
+ /**
+ * Returns current application executable.
+ *
+ * @returns {string}
+ */
+ getAppExec() {
+ let execFolder = this.getAppPath();
+ let exec = {
+ osx: '',
+ win: path.basename(process.execPath),
+ linux32: path.basename(process.execPath),
+ linux64: path.basename(process.execPath)
+ };
+ return path.join(execFolder, exec[platform]);
+ }
+
+ /**
+ * Unpack the `filename` in temporary folder.
+ * For Windows, [unzip](https://www.mkssoftware.com/docs/man1/unzip.1.asp) is used (which is [not signed](https://github.com/nwutils/updater/issues/68)).
+ *
+ * @param {string} filename
+ * @param {function} cb - Callback arguments: error, unpacked directory
+ * @param {object} manifest
+ */
+ unpack(filename, cb, manifest) {
+ pUnpack[platform](filename, cb, manifest, this.options.temporaryDirectory);
+ }
}
export default Updater;
diff --git a/src/updater.js b/src/updater.js
index e345a30..0b9ef1a 100644
--- a/src/updater.js
+++ b/src/updater.js
@@ -156,6 +156,7 @@ class Updater {
unpack(filename, cb, manifest) {
pUnpack[platform](filename, cb, manifest, this.options.temporaryDirectory);
}
+
/**
* Runs installer
* @param {string} appPath
From f0d6957143257690148be5280bb2f98fc2ba002b Mon Sep 17 00:00:00 2001
From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com>
Date: Sun, 10 May 2026 14:36:15 +0530
Subject: [PATCH 2/4] chore(docs): update manifest schema
---
README.md | 49 +++++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
index 2b4db2b..a13929b 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,8 @@ const updater = new Updater(nw.App.manifest);
let updateStatus = "";
let newManifest = "";
let downloadedFilePath = "";
+
+// Check for new version via current running application.
updater.checkNewVersion((err, newerVersionExists, remoteManifest) => {
if (err) {
updateStatus = `Error checking for updates: ${err.message}`;
@@ -34,6 +36,7 @@ updater.checkNewVersion((err, newerVersionExists, remoteManifest) => {
}
});
+// Download to temporary directory if new version is available.
let downloadStatus = "";
updater.download((err, filePath) => {
if (err) {
@@ -44,10 +47,17 @@ updater.download((err, filePath) => {
downloadedFilePath = filePath;
}, newManifest);
-updater.download();
+// Unpack the application in the temporary directory
+updater.unpack();
+
+// Run the new application from the temporary directory and kill the old one
+
+// The new application will copy itself from the temporary directory to the directory where the previous application was running.
+
+// The new application will run itself from the original directory and exit the process.
```
-## API
+## API Schema
| Method | Arguments | Return Type | Description |
| ------ | --------- | ----------- | ----------- |
@@ -100,29 +110,29 @@ Note: if this doesn't work, try `gui.Shell.openItem(execPath)` (see [node-webkit
## Manifest Schema
-An example manifest:
+Example usage:
```json
{
- "name": "updapp",
- "version": "0.0.2",
- "author": "Eldar Djafarov ",
- "manifestUrl": "http://localhost:3000/package.json",
+ "name": "demo",
+ "version": "0.0.1",
+ "author": "NW.js Utils ",
+ "manifestUrl": "http://localhost:3000/manifest.json",
"packages": {
- "mac": {
- "url": "http://localhost:3000/releases/updapp/mac/updapp.zip"
+ "linux-x64": {
+ "url": "http://localhost:3000/demo-0.0.1-linux-x64.zip"
},
- "win": {
- "url": "http://localhost:3000/releases/updapp/win/updapp.zip"
+ "osx-arm64": {
+ "url": "http://localhost:3000/demo-0.0.1-osx-arm64.zip"
+ },
+ "win-x64": {
+ "url": "http://localhost:3000/demo-0.0.1-win-x64.zip"
},
- "linux32": {
- "url": "http://localhost:3000/releases/updapp/linux32/updapp.tar.gz"
- }
}
}
```
-The manifest could be a `package.json` of project, but doesn't have to be.
+> Note: The manifest could be a `package.json` of project, but doesn't have to be.
### manifest.name
@@ -150,15 +160,6 @@ It's assumed your app is stored at the root of your package, use this to overrid
This can also be used to override `manifest.name`; e.g. if your `manifest.name` is `helloWorld` (therefore `helloWorld.app` on Mac) but your Windows executable is named `nw.exe`. Then you'd set `execPath` to `nw.exe`
-## Roadmap
-
-1. Check the manifest for version (from your running "old" app).
-2. If the version is different from the running one, download new package to a temp directory.
-3. Unpack the package in temp.
-4. Run new app from temp and kill the old one (i.e. still all from the running app).
-5. The new app (in temp) will copy itself to the original folder, overwriting the old app.
-6. The new app will run itself from original folder and exit the process.
-
## Contributing
### External contributor
From 0159966edb8f5d7e109d95ec4786d2c8f110c8f4 Mon Sep 17 00:00:00 2001
From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com>
Date: Sun, 10 May 2026 14:37:28 +0530
Subject: [PATCH 3/4] chore(deps): install @types/chrome
---
package-lock.json | 36 ++++++++++++++++++++++++++++++++++++
package.json | 1 +
2 files changed, 37 insertions(+)
diff --git a/package-lock.json b/package-lock.json
index 7606aa8..caba6de 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"semver": "^7.6.2"
},
"devDependencies": {
+ "@types/chrome": "^0.1.42",
"@types/del": "^3.0.1",
"@types/ncp": "^2.0.8",
"@types/node": "^25.6.2",
@@ -565,6 +566,17 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/chrome": {
+ "version": "0.1.42",
+ "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.42.tgz",
+ "integrity": "sha512-tdT2roFqGecZZDjA9fUEAINb2STxSPifHMDvY6EfRjNRCjdrs/0FwKt5RCIA9MKMd1arAYZZL3nwEkp6ZLZu2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/filesystem": "*",
+ "@types/har-format": "*"
+ }
+ },
"node_modules/@types/del": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/del/-/del-3.0.1.tgz",
@@ -575,6 +587,23 @@
"@types/glob": "*"
}
},
+ "node_modules/@types/filesystem": {
+ "version": "0.0.36",
+ "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz",
+ "integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/filewriter": "*"
+ }
+ },
+ "node_modules/@types/filewriter": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz",
+ "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz",
@@ -586,6 +615,13 @@
"@types/node": "*"
}
},
+ "node_modules/@types/har-format": {
+ "version": "1.2.16",
+ "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz",
+ "integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/minimatch": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
diff --git a/package.json b/package.json
index 010a09b..2211d92 100644
--- a/package.json
+++ b/package.json
@@ -53,6 +53,7 @@
"semver": "^7.6.2"
},
"devDependencies": {
+ "@types/chrome": "^0.1.42",
"@types/del": "^3.0.1",
"@types/ncp": "^2.0.8",
"@types/node": "^25.6.2",
From ce0220af794c44d84bb690a0ae41585240f6937c Mon Sep 17 00:00:00 2001
From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com>
Date: Sat, 16 May 2026 01:36:43 +0530
Subject: [PATCH 4/4] fix: use tar and yauzl-promise packages to unpack
---
package-lock.json | 11 +++++
package.json | 1 +
src/main.js | 35 +++++++++++++--
src/util.js | 107 ++++++++++++++++++++++++++++++++++++++++++++
tsconfig.json | 5 +--
types/src/main.d.ts | 23 +++++++++-
6 files changed, 174 insertions(+), 8 deletions(-)
create mode 100644 src/util.js
diff --git a/package-lock.json b/package-lock.json
index caba6de..3ee9c24 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"@types/node": "^25.6.2",
"@types/nw.js": "^0.92.0",
"@types/semver": "^7.7.1",
+ "@types/yauzl-promise": "^4.0.1",
"express": "^5.2.1",
"get-port": "^7.2.0",
"nw-builder": "^4.17.10",
@@ -666,6 +667,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/yauzl-promise": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@types/yauzl-promise/-/yauzl-promise-4.0.1.tgz",
+ "integrity": "sha512-qYEC3rJwqiJpdQ9b+bPNeuSY0c3JUM8vIuDy08qfuVN7xHm3ZDsHn2kGphUIB0ruEXrPGNXZ64nMUcu4fDjViQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@xmldom/xmldom": {
"version": "0.9.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz",
diff --git a/package.json b/package.json
index 2211d92..f935022 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,7 @@
"@types/node": "^25.6.2",
"@types/nw.js": "^0.92.0",
"@types/semver": "^7.7.1",
+ "@types/yauzl-promise": "^4.0.1",
"express": "^5.2.1",
"get-port": "^7.2.0",
"nw-builder": "^4.17.10",
diff --git a/src/main.js b/src/main.js
index 4f97e22..feae0d4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -4,6 +4,8 @@ const path = await import('node:path');
const process = await import('node:process');
const stream = await import('node:stream');
+import util from './util';
+
function semverGt(v1, v2) {
const [major1, minor1, patch1] = v1.replace(/^v/i, '').split('.').map(Number);
const [major2, minor2, patch2] = v2.replace(/^v/i, '').split('.').map(Number);
@@ -196,16 +198,41 @@ class Updater {
return path.join(execFolder, exec[platform]);
}
+ /**
+ * @private
+ * @param {Manifest} manifest
+ * @return {string}
+ */
+ getExecPathRelativeToPackage(manifest) {
+ const execPath = manifest.packages[platform] && manifest.packages[platform].execPath;
+
+ if (execPath) {
+ return execPath;
+ }
+ else {
+ const suffix = {
+ win: '.exe',
+ mac: '.app'
+ };
+ return manifest.name + (suffix[platform] || '');
+ }
+ };
+
/**
* Unpack the `filename` in temporary folder.
- * For Windows, [unzip](https://www.mkssoftware.com/docs/man1/unzip.1.asp) is used (which is [not signed](https://github.com/nwutils/updater/issues/68)).
- *
+ *
* @param {string} filename
* @param {function} cb - Callback arguments: error, unpacked directory
- * @param {object} manifest
+ * @param {Manifest} manifest
*/
unpack(filename, cb, manifest) {
- pUnpack[platform](filename, cb, manifest, this.options.temporaryDirectory);
+ util.decompress(filename, this.options.temporaryDirectory)
+ .then(() => {
+ cb(null, path.join(this.options.temporaryDirectory, this.getExecPathRelativeToPackage(manifest)));
+ })
+ .catch((err) => {
+ cb(err, null);
+ });
}
}
diff --git a/src/util.js b/src/util.js
new file mode 100644
index 0000000..dfd1d36
--- /dev/null
+++ b/src/util.js
@@ -0,0 +1,107 @@
+
+import fs from 'node:fs';
+import path from 'node:path';
+import stream from 'node:stream';
+
+import * as tar from 'tar';
+import yauzl from 'yauzl-promise';
+
+/**
+ * Decompresses a file at `filePath` to `cacheDir` directory.
+ * @async
+ * @function
+ * @param {string} filePath - file path to compressed binary
+ * @param {string} cacheDir - directory to decompress into
+ * @throws {Error}
+ * @returns {Promise}
+ */
+async function decompress(filePath, cacheDir) {
+ if (filePath.endsWith('.zip')) {
+ await unzip(filePath, cacheDir);
+ } else {
+ await tar.extract({
+ file: filePath,
+ C: cacheDir
+ });
+ }
+}
+
+/**
+ * Get file mode from entry. Reference implementation is [here](https://github.com/fpsqdb/zip-lib/blob/ac447d269218d396e05cd7072d0e9cd82b5ec52c/src/unzip.ts#L380).
+ * @async
+ * @function
+ * @param {yauzl.Entry} entry - Yauzl entry
+ * @returns {number} - entry's file mode
+ */
+function modeFromEntry(entry) {
+ const attr = entry.externalFileAttributes >> 16 || 33188;
+
+ return [448 /* S_IRWXU */, 56 /* S_IRWXG */, 7 /* S_IRWXO */]
+ .map(mask => attr & mask)
+ .reduce((a, b) => a + b, attr & 61440 /* S_IFMT */);
+}
+
+/**
+ * Unzip `zippedFile` to `cacheDir`.
+ * @async
+ * @function
+ * @param {string} zippedFile - file path to .zip file
+ * @param {string} cacheDir - directory to unzip in
+ * @throws {Error}
+ * @returns {Promise}
+ */
+async function unzip(zippedFile, cacheDir) {
+ const zip = await yauzl.open(zippedFile);
+ let entry = await zip.readEntry();
+ /* Array to hold symbolic link entries */
+ const symlinks = [];
+
+ while (entry !== null) {
+ let entryPathAbs = path.join(cacheDir, entry.filename);
+ /* Check if entry is a symbolic link */
+ const isSymlink = ((modeFromEntry(entry) & 0o170000) === 0o120000);
+
+ if (isSymlink) {
+ /* Store symlink entries to process later */
+ symlinks.push(entry);
+ } else {
+ /* Handle regular files and directories */
+ await fs.promises.mkdir(path.dirname(entryPathAbs), { recursive: true });
+ /* Skip directories */
+ if (!entry.filename.endsWith('/')) {
+ const readStream = await entry.openReadStream();
+ const writeStream = fs.createWriteStream(entryPathAbs);
+ await stream.promises.pipeline(readStream, writeStream);
+
+ /* Set file permissions after the file has been written */
+ const mode = modeFromEntry(entry);
+ await fs.promises.chmod(entryPathAbs, mode);
+ }
+ }
+
+ /* Read next entry */
+ entry = await zip.readEntry();
+ }
+
+ /* Process symbolic links after all other files have been extracted */
+ for (const symlinkEntry of symlinks) {
+ let entryPathAbs = path.join(cacheDir, symlinkEntry.filename);
+ const readStream = await symlinkEntry.openReadStream();
+ /** @type {Buffer[]} */
+ const chunks = [];
+ readStream.on('data', (chunk) => chunks.push(chunk));
+ await new Promise(resolve => readStream.on('end', resolve));
+ const linkTarget = Buffer.concat(chunks).toString('utf8').trim();
+
+ /* Check if the symlink or a file/directory already exists at the destination */
+ if (fs.existsSync(entryPathAbs)) {
+ /* skip */
+ } else {
+ /* Create symbolic link */
+ await fs.promises.symlink(linkTarget, entryPathAbs);
+ }
+ }
+ await zip.close();
+}
+
+export default { decompress };
diff --git a/tsconfig.json b/tsconfig.json
index 85f1271..802e020 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,12 +7,11 @@
"rootDir": ".",
"outDir": "types",
"strict": true,
- "target": "ES2020",
+ "target": "esnext",
"lib": [
- "ES2020"
+ "ESNext"
],
"module": "ESNext",
- // "moduleResolution": "node",
"types": [
"node"
],
diff --git a/types/src/main.d.ts b/types/src/main.d.ts
index 140325a..5a33a31 100644
--- a/types/src/main.d.ts
+++ b/types/src/main.d.ts
@@ -17,7 +17,7 @@ export type Packages = {
/**
* - The macOS package
*/
- mac: Platform;
+ osx: Platform;
/**
* - The Linux 32-bit package
*/
@@ -83,4 +83,25 @@ declare class Updater {
* @returns {void}
*/
download(cb: (error: Error | null, filepath: string | null) => void, newManifest: Manifest): void;
+ /**
+ * Returns executed application path.
+ *
+ * @returns {string}
+ */
+ getAppPath(): string;
+ /**
+ * Returns current application executable.
+ *
+ * @returns {string}
+ */
+ getAppExec(): string;
+ /**
+ * Unpack the `filename` in temporary folder.
+ * For Windows, [unzip](https://www.mkssoftware.com/docs/man1/unzip.1.asp) is used (which is [not signed](https://github.com/nwutils/updater/issues/68)).
+ *
+ * @param {string} filename
+ * @param {function} cb - Callback arguments: error, unpacked directory
+ * @param {object} manifest
+ */
+ unpack(filename: string, cb: Function, manifest: object): void;
}