New Upstream Release - node-exit-hook

Ready changes

Summary

Merged new upstream version: 3.2.0 (was: 3.1.2).

Resulting package

Built on 2023-07-28T03:29 (took 5m35s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases node-exit-hook

Lintian Result

Diff

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..6313b56
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text=auto eol=lf
diff --git a/.github/funding.yml b/.github/funding.yml
new file mode 100644
index 0000000..797757b
--- /dev/null
+++ b/.github/funding.yml
@@ -0,0 +1,4 @@
+github: sindresorhus
+open_collective: sindresorhus
+tidelift: npm/exit-hook
+custom: https://sindresorhus.com/donate
diff --git a/.github/security.md b/.github/security.md
new file mode 100644
index 0000000..5358dc5
--- /dev/null
+++ b/.github/security.md
@@ -0,0 +1,3 @@
+# Security Policy
+
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..6a82b18
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,21 @@
+name: CI
+on:
+  - push
+  - pull_request
+jobs:
+  test:
+    name: Node.js ${{ matrix.node-version }}
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        node-version:
+          - 18
+          - 16
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-node@v3
+        with:
+          node-version: ${{ matrix.node-version }}
+      - run: npm install
+      - run: npm test
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..239ecff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+yarn.lock
diff --git a/debian/changelog b/debian/changelog
index 9b8987f..4083dc9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+node-exit-hook (3.2.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Fri, 28 Jul 2023 03:24:36 -0000
+
 node-exit-hook (3.1.2-1) unstable; urgency=medium
 
   * Team upload
diff --git a/debian/patches/replace-ava-by-tape.patch b/debian/patches/replace-ava-by-tape.patch
index 33954ab..80e0279 100644
--- a/debian/patches/replace-ava-by-tape.patch
+++ b/debian/patches/replace-ava-by-tape.patch
@@ -3,8 +3,10 @@ Author: Yadd <yadd@debian.org>
 Forwarded: not-needed
 Last-Update: 2022-11-26
 
---- a/test.js
-+++ b/test.js
+Index: node-exit-hook.git/test.js
+===================================================================
+--- node-exit-hook.git.orig/test.js
++++ node-exit-hook.git/test.js
 @@ -1,6 +1,6 @@
  import process from 'node:process';
 -import test from 'ava';
@@ -14,7 +16,7 @@ Last-Update: 2022-11-26
  import exitHook, {asyncExitHook} from './index.js';
  
  test('main', async t => {
-@@ -8,12 +8,14 @@
+@@ -8,12 +8,14 @@ test('main', async t => {
  	t.is(stdout, 'foo\nbar');
  	t.is(stderr, '');
  	t.is(exitCode, 0);
@@ -29,7 +31,7 @@ Last-Update: 2022-11-26
  });
  
  test('main-async', async t => {
-@@ -21,6 +23,7 @@
+@@ -21,6 +23,7 @@ test('main-async', async t => {
  	t.is(stdout, 'foo\nbar\nquux');
  	t.is(stderr, '');
  	t.is(exitCode, 0);
@@ -37,7 +39,7 @@ Last-Update: 2022-11-26
  });
  
  test('main-async-notice', async t => {
-@@ -30,61 +33,32 @@
+@@ -30,63 +33,34 @@ test('main-async-notice', async t => {
  		},
  	});
  	t.is(stdout, 'foo\nbar');
@@ -104,3 +106,5 @@ Last-Update: 2022-11-26
  	});
 +	t.end();
  });
+ 
+ const signalTests = [
diff --git a/fixtures/signal.js b/fixtures/signal.js
new file mode 100644
index 0000000..174f9fa
--- /dev/null
+++ b/fixtures/signal.js
@@ -0,0 +1,13 @@
+import exitHook, {asyncExitHook} from '../index.js';
+
+exitHook(signal => {
+	console.log(signal);
+});
+
+asyncExitHook(async signal => {
+	console.log(signal);
+}, {
+	minimumWait: 200,
+});
+
+setInterval(() => {}, 1 << 30);
diff --git a/index.d.ts b/index.d.ts
index e104688..0405103 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -1,3 +1,8 @@
+/**
+@callback onExit
+@param {number} signal - The exit code.
+*/
+
 /**
 Run some code when the process exits.
 
@@ -5,15 +10,15 @@ The `process.on('exit')` event doesn't catch all the ways a process can exit.
 
 This is useful for cleaning synchronously before exiting.
 
-@param onExit - The callback function to execute when the process exits.
+@param {onExit} onExit - The callback function to execute when the process exits.
 @returns A function that removes the hook when called.
 
 @example
 ```
 import exitHook from 'exit-hook';
 
-exitHook(() => {
-	console.log('Exiting');
+exitHook(signal => {
+	console.log(`Exiting with signal: ${signal}`);
 });
 
 // You can add multiple hooks, even across files
@@ -32,13 +37,13 @@ const unsubscribe = exitHook(() => {});
 unsubscribe();
 ```
 */
-export default function exitHook(onExit: () => void): () => void;
+export default function exitHook(onExit: (signal: number) => void): () => void;
 
 /**
 Run code asynchronously when the process exits.
 
 @see https://github.com/sindresorhus/exit-hook/blob/main/readme.md#asynchronous-exit-notes
-@param onExit - The callback function to execute when the process exits via `gracefulExit`, and will be wrapped in `Promise.resolve`.
+@param {onExit} onExit - The callback function to execute when the process exits via `gracefulExit`, and will be wrapped in `Promise.resolve`.
 @returns A function that removes the hook when called.
 
 @example
@@ -56,12 +61,12 @@ throw new Error('🦄');
 //=> 'Exiting'
 
 // Removing an exit hook:
-const unsubscribe = asyncExitHook(() => {}, {});
+const unsubscribe = asyncExitHook(() => {}, {minimumWait: 500});
 
 unsubscribe();
 ```
 */
-export function asyncExitHook(onExit: () => (void | Promise<void>), options: Options): () => void;
+export function asyncExitHook(onExit: (signal: number) => (void | Promise<void>), options: Options): () => void;
 
 /**
 Exit the process and make a best-effort to complete all asynchronous hooks.
@@ -77,7 +82,9 @@ import {asyncExitHook, gracefulExit} from 'exit-hook';
 
 asyncExitHook(() => {
 	console.log('Exiting');
-}, 500);
+}, {
+	minimumWait: 500
+});
 
 // Instead of `process.exit()`
 gracefulExit();
diff --git a/index.js b/index.js
index e880ba6..1f0f8f2 100644
--- a/index.js
+++ b/index.js
@@ -23,14 +23,16 @@ async function exit(shouldManuallyExit, isSynchronous, signal) {
 		].join(' '));
 	}
 
+	const exitCode = 128 + signal;
+
 	const done = (force = false) => {
 		if (force === true || shouldManuallyExit === true) {
-			process.exit(128 + signal); // eslint-disable-line unicorn/no-process-exit
+			process.exit(exitCode); // eslint-disable-line unicorn/no-process-exit
 		}
 	};
 
 	for (const callback of callbacks) {
-		callback();
+		callback(exitCode);
 	}
 
 	if (isSynchronous) {
@@ -42,7 +44,7 @@ async function exit(shouldManuallyExit, isSynchronous, signal) {
 	let forceAfter = 0;
 	for (const [callback, wait] of asyncCallbacks) {
 		forceAfter = Math.max(forceAfter, wait);
-		promises.push(Promise.resolve(callback()));
+		promises.push(Promise.resolve(callback(exitCode)));
 	}
 
 	// Force exit if we exceeded our wait value
@@ -109,12 +111,12 @@ export default function exitHook(onExit) {
 	});
 }
 
-export function asyncExitHook(onExit, options) {
+export function asyncExitHook(onExit, options = {}) {
 	if (typeof onExit !== 'function') {
 		throw new TypeError('onExit must be a function');
 	}
 
-	if (typeof options?.minimumWait !== 'number' || options.minimumWait <= 0) {
+	if (!(typeof options.minimumWait === 'number' && options.minimumWait > 0)) {
 		throw new TypeError('minimumWait must be set to a positive numeric value');
 	}
 
diff --git a/package.json b/package.json
index 5e284bb..05218c6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "exit-hook",
-	"version": "3.1.2",
+	"version": "3.2.0",
 	"description": "Run some code when the process exits",
 	"license": "MIT",
 	"repository": "sindresorhus/exit-hook",
diff --git a/readme.md b/readme.md
index f54fdf1..2f3c5ea 100644
--- a/readme.md
+++ b/readme.md
@@ -17,8 +17,8 @@ npm install exit-hook
 ```js
 import exitHook from 'exit-hook';
 
-exitHook(() => {
-	console.log('Exiting');
+exitHook(signal => {
+	console.log(`Exiting with signal: ${signal}`);
 });
 
 // You can add multiple hooks, even across files
@@ -52,11 +52,11 @@ Returns a function that removes the hook when called.
 
 #### onExit
 
-Type: `function(): void`
+Type: `(signal: number) => void`
 
 The callback function to execute when the process exits.
 
-### asyncExitHook(onExit, minimumWait)
+### asyncExitHook(onExit, options)
 
 Register a function to run during `gracefulExit`.
 
@@ -64,12 +64,30 @@ Returns a function that removes the hook when called.
 
 Please see [Async Notes](#asynchronous-exit-notes) for considerations when using the asynchronous API.
 
+#### onExit
+
+Type: `(signal: number) => (void | Promise<void>)`
+
+The callback function to execute when the process exits via `gracefulExit`, and will be wrapped in `Promise.resolve`.
+
+#### options
+
+Type: `object`
+
+##### minimumWait
+
+Type: `number`
+
+The amount of time in milliseconds that the `onExit` function is expected to take.
+
 ```js
 import {asyncExitHook} from 'exit-hook';
 
 asyncExitHook(async () => {
 	console.log('Exiting');
-}, 300);
+}, {
+	minimumWait: 300
+});
 
 throw new Error('🦄');
 
@@ -90,20 +108,6 @@ const unsubscribe = asyncExitHook(async () => {
 unsubscribe();
 ```
 
-#### onExit
-
-Type: `function(): void | Promise<void>`
-
-The callback function to execute when the process exits via `gracefulExit`, and will be wrapped in `Promise.resolve`.
-
-#### options
-
-##### minimumWait
-
-Type: `number`
-
-The amount of time in milliseconds that the `onExit` function is expected to take.
-
 ### gracefulExit(signal?: number): void
 
 Exit the process and make a best-effort to complete all asynchronous hooks.
diff --git a/test.js b/test.js
index 5f2d8dc..9094fe9 100644
--- a/test.js
+++ b/test.js
@@ -88,3 +88,26 @@ test('type enforcing', t => {
 		asyncExitHook(async () => true, {});
 	});
 });
+
+const signalTests = [
+	['SIGINT', 130],
+	['SIGTERM', 143],
+];
+
+for (const [signal, exitCode] of signalTests) {
+	test(signal, async t => {
+		const subprocess = execa(process.execPath, ['./fixtures/signal.js']);
+
+		setTimeout(() => {
+			subprocess.kill(signal);
+		}, 1000);
+
+		try {
+			await subprocess;
+		} catch (error) {
+			t.is(error.exitCode, exitCode);
+			t.is(error.stderr, '');
+			t.is(error.stdout, `${exitCode}\n${exitCode}`);
+		}
+	});
+}

Debdiff

File lists identical (after any substitutions)

No differences were encountered in the control files

More details

Full run details