Skip to content

Commit

Permalink
Require Node.js 14 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Jun 6, 2022
1 parent 6a2d954 commit 1f1b077
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 96 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ jobs:
fail-fast: false
matrix:
node-version:
- 18
- 16
- 14
- 12
- 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
24 changes: 11 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
'use strict';

const processFn = (fn, options, proxy, unwrapped) => function (...arguments_) {
const processFunction = (function_, options, proxy, unwrapped) => function (...arguments_) {
const P = options.promiseModule;

return new P((resolve, reject) => {
Expand Down Expand Up @@ -30,18 +28,18 @@ const processFn = (fn, options, proxy, unwrapped) => function (...arguments_) {
}

const self = this === proxy ? unwrapped : this;
Reflect.apply(fn, self, arguments_);
Reflect.apply(function_, self, arguments_);
});
};

const filterCache = new WeakMap();

module.exports = (input, options) => {
export default function pify(input, options) {
options = {
exclude: [/.+(?:Sync|Stream)$/],
errorFirst: true,
promiseModule: Promise,
...options
...options,
};

const objectType = typeof input;
Expand All @@ -62,9 +60,9 @@ module.exports = (input, options) => {
}

const match = pattern => (typeof pattern === 'string' || typeof key === 'symbol') ? key === pattern : pattern.test(key);
const desc = Reflect.getOwnPropertyDescriptor(target, key);
const writableOrConfigurableOwn = (desc === undefined || desc.writable || desc.configurable);
const included = options.include ? options.include.some(match) : !options.exclude.some(match);
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
const writableOrConfigurableOwn = (descriptor === undefined || descriptor.writable || descriptor.configurable);
const included = options.include ? options.include.some(element => match(element)) : !options.exclude.some(element => match(element));
const shouldFilter = included && writableOrConfigurableOwn;
cached[key] = shouldFilter;
return shouldFilter;
Expand All @@ -80,7 +78,7 @@ module.exports = (input, options) => {
return Reflect.apply(cached, thisArg, args);
}

const pified = options.excludeMain ? target : processFn(target, options, proxy, target);
const pified = options.excludeMain ? target : processFunction(target, options, proxy, target);
cache.set(target, pified);
return Reflect.apply(pified, thisArg, args);
},
Expand All @@ -100,14 +98,14 @@ module.exports = (input, options) => {
}

if (typeof property === 'function') {
const pified = processFn(property, options, proxy, target);
const pified = processFunction(property, options, proxy, target);
cache.set(property, pified);
return pified;
}

return property;
}
},
});

return proxy;
};
}
32 changes: 15 additions & 17 deletions optimization-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable no-fallthrough */
'use strict';
const assert = require('assert');
const v8 = require('v8-natives');
const pify = require('.');
import process from 'node:process';
import assert from 'node:assert';
import v8 from 'v8-natives';
import pify from './index.js';

function assertOptimized(fn, name) {
const status = v8.getOptimizationStatus(fn);
Expand All @@ -27,19 +27,17 @@ function assertOptimized(fn, name) {
}

const fn = pify({
unicorn: callback => {
unicorn(callback) {
callback(null, 'unicorn');
}
},
});

(async () => {
try {
await fn.unicorn();
v8.optimizeFunctionOnNextCall(fn.unicorn);
await fn.unicorn();
assertOptimized(fn.unicorn, 'unicorn');
} catch (error) {
console.error(error);
process.exit(1); // eslint-disable-line unicorn/no-process-exit
}
})();
try {
await fn.unicorn();
v8.optimizeFunctionOnNextCall(fn.unicorn);
await fn.unicorn();
assertOptimized(fn.unicorn, 'unicorn');
} catch (error) {
console.error(error);
process.exit(1); // eslint-disable-line unicorn/no-process-exit
}
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
"email": "[email protected]",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=10"
"node": ">=14.16"
},
"scripts": {
"test": "xo && ava",
Expand Down Expand Up @@ -41,9 +43,9 @@
"bluebird"
],
"devDependencies": {
"ava": "^2.4.0",
"pinkie-promise": "^2.0.0",
"v8-natives": "^1.1.0",
"xo": "^0.26.1"
"ava": "^4.3.0",
"pinkie-promise": "^2.0.1",
"v8-natives": "^1.2.5",
"xo": "^0.49.0"
}
}
56 changes: 25 additions & 31 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,25 @@
## Install

```
$ npm install pify
```sh
npm install pify
```

## Usage

```js
const fs = require('fs');
const pify = require('pify');

(async () => {
// Promisify a single function.
const data = await pify(fs.readFile)('package.json', 'utf8');
console.log(JSON.parse(data).name);
//=> 'pify'

// Promisify all methods in a module.
const data2 = await pify(fs).readFile('package.json', 'utf8');
console.log(JSON.parse(data2).name);
//=> 'pify'
})();
import fs from 'fs';
import pify from 'pify';

// Promisify a single function.
const data = await pify(fs.readFile)('package.json', 'utf8');
console.log(JSON.parse(data).name);
//=> 'pify'

// Promisify all methods in a module.
const data2 = await pify(fs).readFile('package.json', 'utf8');
console.log(JSON.parse(data2).name);
//=> 'pify'
```

## API
Expand All @@ -51,14 +49,12 @@ Default: `false`
By default, the promisified function will only return the second argument from the callback, which works fine for most APIs. This option can be useful for modules like `request` that return multiple arguments. Turning this on will make it return an array of all arguments from the callback, excluding the error argument, instead of just the second argument. This also applies to rejections, where it returns an array of all the callback arguments, including the error.

```js
const request = require('request');
const pify = require('pify');
import request from 'request';
import pify from 'pify';

const pRequest = pify(request, {multiArgs: true});

(async () => {
const [httpResponse, body] = await pRequest('https://sindresorhus.com');
})();
const [httpResponse, body] = await pRequest('https://sindresorhus.com');
```

##### include
Expand All @@ -82,7 +78,7 @@ Default: `false`
If the given module is a function itself, it will be promisified. Enable this option if you want to promisify only methods of the module.

```js
const pify = require('pify');
import pify from 'pify';

function fn() {
return true;
Expand All @@ -94,14 +90,12 @@ fn.method = (data, callback) => {
});
};

(async () => {
// Promisify methods but not `fn()`.
const promiseFn = pify(fn, {excludeMain: true});
// Promisify methods but not `fn()`.
const promiseFn = pify(fn, {excludeMain: true});

if (promiseFn()) {
console.log(await promiseFn.method('hi'));
}
})();
if (promiseFn()) {
console.log(await promiseFn.method('hi'));
}
```

##### errorFirst
Expand Down Expand Up @@ -132,8 +126,8 @@ Custom promise module to use instead of the native one.
Class methods are not bound, so when they're not called on the class itself, they don't have any context. You can either promisify the whole class or use `.bind()`.

```js
const pify = require('pify');
const SomeClass = require('./some-class');
import pify from 'pify';
import SomeClass from './some-class.js';

const someInstance = new SomeClass();

Expand Down
Loading

0 comments on commit 1f1b077

Please sign in to comment.