├── .eslintrc ├── .github ├── FUNDING.yml └── workflows │ ├── node-aught.yml │ ├── node-noproto.yml │ ├── node-pretest.yml │ ├── node-tens.yml │ ├── node-twenties.yml │ ├── rebase.yml │ └── require-allow-edits.yml ├── .gitignore ├── .npmrc ├── .nycrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── auto.js ├── implementation.js ├── index.js ├── package.json ├── polyfill.js ├── shim.js └── test ├── implementation.js ├── index.js ├── shimmed.js └── tests.js /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | 4 | "extends": "@ljharb", 5 | 6 | "rules": { 7 | "id-length": [2, { "min": 1, "max": 30 }], 8 | "max-lines-per-function": 0, 9 | "multiline-comment-style": 0, 10 | "new-cap": [2, { 11 | "capIsNewExceptions": [ 12 | "GetIntrinsic", 13 | ], 14 | }], 15 | "no-magic-numbers": 0, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ljharb] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: npm/util.promisify 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/node-aught.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js < 10' 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | tests: 7 | uses: ljharb/actions/.github/workflows/node.yml@main 8 | with: 9 | range: '< 10' 10 | type: minors 11 | command: npm run tests-only 12 | 13 | node: 14 | name: 'node < 10' 15 | needs: [tests] 16 | runs-on: ubuntu-latest 17 | steps: 18 | - run: 'echo tests completed' 19 | -------------------------------------------------------------------------------- /.github/workflows/node-noproto.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node --disable-proto=throw' 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | throw: 7 | uses: ljharb/actions/.github/workflows/node.yml@main 8 | with: 9 | range: '>= 12.17' 10 | type: minors 11 | command: "NODE_OPTIONS='--disable-proto=throw' npx tape 'tests/**/*.js'" 12 | 13 | delete: 14 | uses: ljharb/actions/.github/workflows/node.yml@main 15 | with: 16 | range: '>= 12.17' 17 | type: minors 18 | command: "NODE_OPTIONS='--disable-proto=delete' npx tape 'tests/**/*.js'" 19 | 20 | node: 21 | name: 'node --disable-proto' 22 | needs: [throw, delete] 23 | runs-on: ubuntu-latest 24 | steps: 25 | - run: true 26 | -------------------------------------------------------------------------------- /.github/workflows/node-pretest.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: pretest/posttest' 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | tests: 7 | uses: ljharb/actions/.github/workflows/pretest.yml@main 8 | -------------------------------------------------------------------------------- /.github/workflows/node-tens.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js 10 - 20' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/node.yml@main 11 | with: 12 | range: '>= 10 < 20' 13 | type: minors 14 | command: npm run tests-only 15 | 16 | node: 17 | name: 'node 10 - 20' 18 | needs: [tests] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - run: true 22 | -------------------------------------------------------------------------------- /.github/workflows/node-twenties.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js >= 20' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/node.yml@main 11 | with: 12 | range: '>= 20' 13 | type: minors 14 | command: npm run tests-only 15 | 16 | node: 17 | name: 'node >= 20' 18 | needs: [tests] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - run: true 22 | -------------------------------------------------------------------------------- /.github/workflows/rebase.yml: -------------------------------------------------------------------------------- 1 | name: Automatic Rebase 2 | 3 | on: [pull_request_target] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | _: 10 | permissions: 11 | contents: write # for ljharb/rebase to push code to rebase 12 | pull-requests: read # for ljharb/rebase to get info about PR 13 | 14 | name: "Automatic Rebase" 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - uses: ljharb/rebase@master 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/require-allow-edits.yml: -------------------------------------------------------------------------------- 1 | name: Require “Allow Edits” 2 | 3 | on: [pull_request_target] 4 | 5 | jobs: 6 | _: 7 | name: "Require “Allow Edits”" 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: ljharb/require-allow-edits@main 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # Only apps should have lockfiles 61 | npm-shrinkwrap.json 62 | package-lock.json 63 | yarn.lock 64 | 65 | .npmignore 66 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | allow-same-version=true 3 | message=v%s 4 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "all": true, 3 | "check-coverage": false, 4 | "reporter": ["text-summary", "text", "html", "json"], 5 | "lines": 86, 6 | "statements": 85.93, 7 | "functions": 82.43, 8 | "branches": 76.06, 9 | "exclude": [ 10 | "coverage", 11 | "test" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [v1.1.3](https://github.com/ljharb/util.promisify/compare/v1.1.2...v1.1.3) - 2024-12-18 9 | 10 | ### Commits 11 | 12 | - [Robustness]: use `call-bind`, `define-data-property`, `es-errors`, `es-object-atoms`, `get-intrinsic` [`f3b4baa`](https://github.com/ljharb/util.promisify/commit/f3b4baaebf234621f88af5dd4b5513b4be540d97) 13 | - [actions] split out node 10-20, and 20+ [`fda95ae`](https://github.com/ljharb/util.promisify/commit/fda95ae91df65fef2c4909a54a2cf26ddb3bdf5d) 14 | - [Tests] test with both disable-proto options [`509cfcb`](https://github.com/ljharb/util.promisify/commit/509cfcbe5d869e0b1a867ebd78acb86138e156ad) 15 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config`, `auto-changelog`, `npmignore`, `tape` [`3712bb5`](https://github.com/ljharb/util.promisify/commit/3712bb5ae38f0dc86a198d7fb61a0c225c1bce20) 16 | - [Deps] update `call-bind`, `has-proto`, `has-symbols`, `object.getownpropertydescriptors`, `safe-array-concat` [`4d1441e`](https://github.com/ljharb/util.promisify/commit/4d1441e0d9cd3ecd92954d8d6bf9ed2a6989f594) 17 | - [Deps] update `define-properties`, `object.getownpropertydescriptors`, `safe-array-concat` [`47a969e`](https://github.com/ljharb/util.promisify/commit/47a969e5e202be2f0978cc21028831bc34151d52) 18 | - [Refactor] use `call-bound` directly [`48dba6c`](https://github.com/ljharb/util.promisify/commit/48dba6c1dbe3edb7c8b03515836711924b68f5e8) 19 | - [Dev Deps] update `aud`, `tape` [`7aa0c21`](https://github.com/ljharb/util.promisify/commit/7aa0c21777de3e0eb72db07cbb599239fdf9699e) 20 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config` [`0817cfd`](https://github.com/ljharb/util.promisify/commit/0817cfde128e90a8722533118e2adee28aac87fd) 21 | - [meta] add missing `engines.node` [`9d08241`](https://github.com/ljharb/util.promisify/commit/9d082412e7063c22d98504d73028782a3b67ca73) 22 | - [Tests] replace `aud` with `npm audit` [`cf287ac`](https://github.com/ljharb/util.promisify/commit/cf287aca6a4b33d629254173b7d9f2c6ad3e9eed) 23 | - [Dev Deps] add missing peer dep [`fb9e435`](https://github.com/ljharb/util.promisify/commit/fb9e435973d1d773c59c3b3f906ca80d7ceda894) 24 | 25 | ## [v1.1.2](https://github.com/ljharb/util.promisify/compare/v1.1.1...v1.1.2) - 2023-04-20 26 | 27 | ### Fixed 28 | 29 | - [Fix] avoid crashing with `--disable-proto=throw` [`#26`](https://github.com/ljharb/util.promisify/issues/26) 30 | 31 | ### Commits 32 | 33 | - [actions] reuse common workflows [`2736cb6`](https://github.com/ljharb/util.promisify/commit/2736cb6c8ea7c1cfeca6ddc3c9cf1615aab9a1a8) 34 | - [meta] use `npmignore` to autogenerate an npmignore file [`0eb5abb`](https://github.com/ljharb/util.promisify/commit/0eb5abbe3d3e78fccd20c9f6cac665a7687b54b8) 35 | - [meta] reorganize package.json [`e610642`](https://github.com/ljharb/util.promisify/commit/e610642b27f1498a2114d970ce327b29cfd3bde6) 36 | - [Fix] proper error name [`727c30c`](https://github.com/ljharb/util.promisify/commit/727c30c330b829ee5946226f69b114fae9c761cf) 37 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `@es-shims/api`, `aud`, `auto-changelog`, `safe-publish-latest`, `tape` [`ecc9281`](https://github.com/ljharb/util.promisify/commit/ecc9281821e111f04c3f57e5f28e01386721da30) 38 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`91c385d`](https://github.com/ljharb/util.promisify/commit/91c385d7c500678ae87c9b022cc5003815b2bf89) 39 | - [actions] update rebase action [`c62f4bf`](https://github.com/ljharb/util.promisify/commit/c62f4bfac476b1cdf4836d2e554dca712e2552b8) 40 | - [Refactor] use `has-proto` [`e423ed0`](https://github.com/ljharb/util.promisify/commit/e423ed024de422aa75264f2cfd13a16455da2fc4) 41 | - [Dev Deps] update `@es-shims/api`, `ljharb/eslint-config`,` aud`, `tape` [`62717c1`](https://github.com/ljharb/util.promisify/commit/62717c13f97227771f0b72c3d0638976d04e472a) 42 | - [Refactor] use `safe-array-concat` [`d068529`](https://github.com/ljharb/util.promisify/commit/d068529b46fbff46960111dfe857d43734f3a0f1) 43 | - [Deps] update `define-properties`, `has-symbols`, `object.getownpropertydescriptors` [`bd8a7be`](https://github.com/ljharb/util.promisify/commit/bd8a7be795d349176a667a69755a6472facbb2af) 44 | - [Deps] update `call-bind`, `has-symbols`, `object.getownpropertydescriptors` [`7473409`](https://github.com/ljharb/util.promisify/commit/7473409dbc10974549a869c8bed8172342a40728) 45 | - [Deps] update `define-properties`, `object.getownpropertydescriptors` [`4f244be`](https://github.com/ljharb/util.promisify/commit/4f244beb8e8f51011f265bef0bb87e2a8972f320) 46 | 47 | ## [v1.1.1](https://github.com/ljharb/util.promisify/compare/v1.1.0...v1.1.1) - 2021-01-08 48 | 49 | ### Commits 50 | 51 | - [Fix] add missing runtime dependency `has-symbols` [`9b45a3b`](https://github.com/ljharb/util.promisify/commit/9b45a3bfbc0bcf5e474e1d045aacca3dc9609e54) 52 | 53 | ## [v1.1.0](https://github.com/ljharb/util.promisify/compare/v1.0.1...v1.1.0) - 2021-01-06 54 | 55 | ### Commits 56 | 57 | - [Tests] migrate tests to Github Actions [`a09e2f5`](https://github.com/ljharb/util.promisify/commit/a09e2f5cc3590c3098681c98b08dcb15b5c0877b) 58 | - [Tests] add tests [`5162b64`](https://github.com/ljharb/util.promisify/commit/5162b642805030b7d83e978e73392213d0b2431a) 59 | - [meta] do not publish github action workflow files [`4b5a39e`](https://github.com/ljharb/util.promisify/commit/4b5a39ed1df1c6ce86fb687f7494882fd29099ba) 60 | - [Fix] handle nonconfigurable own function properties, in older engines [`07693ae`](https://github.com/ljharb/util.promisify/commit/07693ae63cdc71d88c2203d62aca53623fba4815) 61 | - [New] use a global symbol for `util.promisify.custom` [`8f8631b`](https://github.com/ljharb/util.promisify/commit/8f8631b04c3f2cf1bd082837c8d73431e356eb2f) 62 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog` [`83e7267`](https://github.com/ljharb/util.promisify/commit/83e7267f27e38a9abcba6803f945c71a68255ff9) 63 | - [actions] add "Allow Edits" workflow [`e2a92ae`](https://github.com/ljharb/util.promisify/commit/e2a92ae988554713f89e62fcbf0ac602f76976f6) 64 | - [Tests] move `es-shim-api` to `postlint` [`7b93efa`](https://github.com/ljharb/util.promisify/commit/7b93efacd4c978b76d02be9b33b94b61ee366e65) 65 | - [Deps] use `call-bind` instead of `es-abstract` [`e68f500`](https://github.com/ljharb/util.promisify/commit/e68f500d9dd0cdd0563d72b758e34bdf1bed0d6c) 66 | - [actions] switch Automatic Rebase workflow to `pull_request_target` event [`7da936c`](https://github.com/ljharb/util.promisify/commit/7da936c0681062c5eb812185ebc9ccf4d86851c5) 67 | - [Dev Deps] update `aud`, `auto-changelog` [`88465d4`](https://github.com/ljharb/util.promisify/commit/88465d4202969895123e3113db3e8b45972ca2f6) 68 | - [Tests] only audit prod deps [`8a13dc5`](https://github.com/ljharb/util.promisify/commit/8a13dc5192ab899034e1f78151324ea06fb381b1) 69 | - [Deps] update `object.getownpropertydescriptors` [`899d30b`](https://github.com/ljharb/util.promisify/commit/899d30b3389b033b3964dd0e7faa0469db8b3ba4) 70 | - [Deps] update `es-abstract` [`552d18b`](https://github.com/ljharb/util.promisify/commit/552d18b34ebc0eda0d0bc33a84ca1827aa86aaf9) 71 | - [Dev Deps] update `auto-changelog` [`dd61917`](https://github.com/ljharb/util.promisify/commit/dd61917fabad7c8c4c52807ca4b5b40611a14e62) 72 | - [Deps] update `es-abstract` [`40a839a`](https://github.com/ljharb/util.promisify/commit/40a839a8db3d79699688d27f6613a827056428c8) 73 | - [Dev Deps] update `@ljharb/eslint-config` [`07c3b39`](https://github.com/ljharb/util.promisify/commit/07c3b3952682e9c4d58b6bfb9404049827b5c523) 74 | 75 | ## [v1.0.1](https://github.com/ljharb/util.promisify/compare/v1.0.0...v1.0.1) - 2020-01-16 76 | 77 | ### Fixed 78 | 79 | - [Refactor] remove unnecessary duplication. Fixes #3. [`#3`](https://github.com/ljharb/util.promisify/issues/3) 80 | 81 | ### Commits 82 | 83 | - [Tests] use shared travis-ci configs [`f1b5e43`](https://github.com/ljharb/util.promisify/commit/f1b5e43359e74a30f35bd10a33be765de73917c6) 84 | - [Tests] up to `node` `v10.0`, `v9.11`, `v8.11`, `v6.14`, `4.9`; use `nvm install-latest-npm`; pin included builds to LTS [`e89390f`](https://github.com/ljharb/util.promisify/commit/e89390f498f7eb5111188fff5260cbb9f5216cd3) 85 | - [meta] add `auto-changelog` [`fe8e751`](https://github.com/ljharb/util.promisify/commit/fe8e751819a1318d3c929b086c70308aed50715d) 86 | - [Tests] up to `node` `v11.0`, `v10.12`, `v8.12` [`e09b894`](https://github.com/ljharb/util.promisify/commit/e09b894291aef2991e5c553f0b64968e03b58262) 87 | - [Refactor] use `callBound` helper from `es-abstract` for robustness [`baa0cf6`](https://github.com/ljharb/util.promisify/commit/baa0cf697068573cbe650e01aa6774154dd3f454) 88 | - [actions] add automatic rebasing / merge commit blocking [`24912f4`](https://github.com/ljharb/util.promisify/commit/24912f41b30d88b8984fb07307f737de6f576873) 89 | - [Docs] Add usage information for the shim/monkey-patch [`38b1ee5`](https://github.com/ljharb/util.promisify/commit/38b1ee56b558019213a6fdc2553796e8cdaf773e) 90 | - [Refactor] use `__proto__` instead of ES6’s `Object.setPrototypeOf` [`02ec7e2`](https://github.com/ljharb/util.promisify/commit/02ec7e241caf8848c1e141c801f98ed31325b59a) 91 | - [meta] create FUNDING.yml [`076b8b5`](https://github.com/ljharb/util.promisify/commit/076b8b5d19783a0e4c932e41782846e431deeb7d) 92 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest` [`4cedaa9`](https://github.com/ljharb/util.promisify/commit/4cedaa9c6b0a77a0416b69d480b3b806c00dec6e) 93 | - Adds usage information to the README [`ddb4556`](https://github.com/ljharb/util.promisify/commit/ddb45562320ab8aea93dc0364640ea21ab68bfbb) 94 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest` [`95362c0`](https://github.com/ljharb/util.promisify/commit/95362c0e93186a30ede6333430ddfa0606a769b4) 95 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config`, `eslint` [`fd79a58`](https://github.com/ljharb/util.promisify/commit/fd79a58573186c83d81777fa0b1ad293b2f475e3) 96 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config` [`2cf792b`](https://github.com/ljharb/util.promisify/commit/2cf792b9dcaab24b642ef1de8239ceb089fc5d38) 97 | - [Docs] Link to util.promisify-all [`032ff5c`](https://github.com/ljharb/util.promisify/commit/032ff5c6ee2958a02f56c770337441c3a587b88c) 98 | - [Tests] allow node 0.10 and 0.8 to fail again [`c2f8418`](https://github.com/ljharb/util.promisify/commit/c2f8418dfc36b83cd8a18b86a735c2936c6f5f9e) 99 | - [Tests] remove mistakenly added travis jobs [`13a242f`](https://github.com/ljharb/util.promisify/commit/13a242fb33dcbd4e2872436f2e430e62526fb147) 100 | - [Tests] on `node` `v10.1` [`8244578`](https://github.com/ljharb/util.promisify/commit/82445786197fd3e54aeffaa2fe0f1da38bcafec4) 101 | - [meta] add `funding` field [`e1645ca`](https://github.com/ljharb/util.promisify/commit/e1645ca10648d1ae917e3f5ae954b37de338dc20) 102 | - [New] add `auto` entry point [`2c48047`](https://github.com/ljharb/util.promisify/commit/2c480479d67646fb2bfb92a4e5d50ff14bcdca3c) 103 | - [Fix] use `has-symbols` package to ensure we support Symbol shams too. [`75135c8`](https://github.com/ljharb/util.promisify/commit/75135c8a48ea4e1be1cfe7a95af11905818303e7) 104 | - [Deps] update `es-abstract` [`32aa5cc`](https://github.com/ljharb/util.promisify/commit/32aa5ccd3ee7513edef99ed7d516d6c0f4901883) 105 | - [Dev Deps] update `eslint` [`c3043e6`](https://github.com/ljharb/util.promisify/commit/c3043e6e562847102e9136479268777bc07e9b26) 106 | - [Deps] update `object.getownpropertydescriptors` [`521ed25`](https://github.com/ljharb/util.promisify/commit/521ed25d40dc230b38ac3755036219fbaf94694c) 107 | - [Deps] update `has-symbol` [`16d91ec`](https://github.com/ljharb/util.promisify/commit/16d91ecc0016c31e49b7c3da938c19132c243732) 108 | - [Deps] update `define-properties` [`532915e`](https://github.com/ljharb/util.promisify/commit/532915ed58fe6f0edc3670837b510e09fb39b99a) 109 | - [Tests] `npm` v5+ breaks on node < v4 [`0647c63`](https://github.com/ljharb/util.promisify/commit/0647c63d932451c043c3e8f3b003c636057f035a) 110 | 111 | ## v1.0.0 - 2017-05-30 112 | 113 | ### Commits 114 | 115 | - Dotfiles. [`02c20cb`](https://github.com/ljharb/util.promisify/commit/02c20cb4eb01cf656102f57f71635785114f1d09) 116 | - Initial implementation. [`05ff048`](https://github.com/ljharb/util.promisify/commit/05ff0480448f019a85675ce81ecc4e9bdc099286) 117 | - Initial commit [`9472155`](https://github.com/ljharb/util.promisify/commit/947215502491bb1b3238aa0ac5c67258e41db3a8) 118 | - package.json [`e0302c0`](https://github.com/ljharb/util.promisify/commit/e0302c01e5e3b1dd78647303f9a4337b5bb63196) 119 | - Initial readme. [`5df78e1`](https://github.com/ljharb/util.promisify/commit/5df78e16e89e8328c61d6bbac85409a36560fe3b) 120 | - [Dev Deps] add `safe-publish-latest` [`596b6b4`](https://github.com/ljharb/util.promisify/commit/596b6b4fbce79dbaf5fff366454ab5b31d2eb993) 121 | - [Tests] add `npm run lint` [`54c2ccb`](https://github.com/ljharb/util.promisify/commit/54c2ccb85db682fc293b30a0bfece76d0a5c7c60) 122 | - [Dev Deps] add `@es-shims/api` [`d9014f1`](https://github.com/ljharb/util.promisify/commit/d9014f12add2fb3fe743647df614c69ed305a824) 123 | - [Tests] allow 0.10 and 0.8 to fail, for now. [`c5c7b61`](https://github.com/ljharb/util.promisify/commit/c5c7b619b88878fc715d1768b48bd45378c9f807) 124 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jordan Harband 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # util.promisify 2 | Polyfill for util.promisify in node versions < v8 3 | 4 | node v8.0.0 added support for a built-in `util.promisify`: https://github.com/nodejs/node/pull/12442/ 5 | 6 | This package provides the built-in `util.promisify` in node v8.0.0 and later, and a replacement in other environments. 7 | 8 | ## Usage 9 | 10 | **Direct** 11 | ```js 12 | const promisify = require('util.promisify'); 13 | // Use `promisify` just like the built-in method on `util` 14 | ``` 15 | 16 | **Shim** 17 | ```js 18 | require('util.promisify/shim')(); 19 | // `util.promisify` is now defined 20 | const util = require('util'); 21 | // Use `util.promisify` 22 | ``` 23 | 24 | Note: this package requires a native ES5 environment, and for `Promise` to be globally available. It will throw upon requiring it if these are not present. 25 | 26 | ## Promisifying modules 27 | 28 | If you want to promisify a whole module, like the `fs` module, you can use [`util.promisify-all`](https://www.npmjs.com/package/util.promisify-all). 29 | -------------------------------------------------------------------------------- /auto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('./shim')(); 4 | -------------------------------------------------------------------------------- /implementation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var forEach = require('for-each'); 4 | 5 | var $Object = require('es-object-atoms'); 6 | 7 | var isES5 = typeof $Object.defineProperty === 'function'; 8 | 9 | var gPO = $Object.getPrototypeOf; 10 | var sPO = $Object.setPrototypeOf; 11 | // eslint-disable-next-line global-require 12 | var hasProto = require('has-proto')() || (typeof gPO === 'function' && gPO([]) === Array.prototype); 13 | 14 | if (!isES5 || !hasProto) { 15 | throw new TypeError('util.promisify requires a true ES5+ environment, that also supports `__proto__` and/or `Object.getPrototypeOf`'); 16 | } 17 | 18 | var getOwnPropertyDescriptors = require('object.getownpropertydescriptors'); 19 | 20 | if (typeof Promise !== 'function') { 21 | throw new TypeError('`Promise` must be globally available for util.promisify to work.'); 22 | } 23 | 24 | var GetIntrinsic = require('get-intrinsic'); 25 | 26 | var oDP = $Object.defineProperty; 27 | var $Promise = GetIntrinsic('%Promise%'); 28 | var $TypeError = TypeError; 29 | 30 | var safeConcat = require('safe-array-concat'); 31 | var callBind = require('call-bind'); 32 | var callBound = require('call-bound'); 33 | var defineDataProperty = require('define-data-property'); 34 | 35 | var $slice = callBound('Array.prototype.slice'); 36 | 37 | var hasSymbols = require('has-symbols/shams')(); 38 | 39 | // eslint-disable-next-line no-restricted-properties 40 | var kCustomPromisifiedSymbol = hasSymbols ? Symbol['for']('nodejs.util.promisify.custom') : null; 41 | var kCustomPromisifyArgsSymbol = hasSymbols ? Symbol('customPromisifyArgs') : null; 42 | 43 | module.exports = function promisify(orig) { 44 | if (typeof orig !== 'function') { 45 | var error = new $TypeError('The "original" argument must be of type function'); 46 | error.code = 'ERR_INVALID_ARG_TYPE'; 47 | error.toString = function value() { 48 | return this.name + '[' + this.code + ']: ' + this.message; 49 | }; 50 | throw error; 51 | } 52 | 53 | if (hasSymbols && orig[kCustomPromisifiedSymbol]) { 54 | var customFunction = orig[kCustomPromisifiedSymbol]; 55 | if (typeof customFunction !== 'function') { 56 | var customError = $TypeError('The [util.promisify.custom] property must be of type function.'); 57 | customError.code = 'ERR_INVALID_ARG_TYPE'; 58 | customError.toString = function value() { 59 | return this.name + '[' + this.code + ']: ' + this.message; 60 | }; 61 | throw customError; 62 | } 63 | defineDataProperty( 64 | customFunction, 65 | kCustomPromisifiedSymbol, 66 | customFunction, 67 | true, 68 | true, 69 | null, 70 | true 71 | ); 72 | return customFunction; 73 | } 74 | 75 | // Names to create an object from in case the callback receives multiple 76 | // arguments, e.g. ['stdout', 'stderr'] for child_process.exec. 77 | var argumentNames = orig[kCustomPromisifyArgsSymbol]; 78 | 79 | var origApply = callBind.apply(orig); 80 | 81 | var promisified = function fn() { 82 | var args = $slice(arguments); 83 | var self = this; // eslint-disable-line no-invalid-this 84 | return new $Promise(function (resolve, reject) { 85 | origApply(self, safeConcat(args, function (err) { 86 | var values = arguments.length > 1 ? $slice(arguments, 1) : []; 87 | if (err) { 88 | reject(err); 89 | } else if (typeof argumentNames !== 'undefined' && values.length > 1) { 90 | var obj = {}; 91 | forEach(argumentNames, function (name, index) { 92 | obj[name] = values[index]; 93 | }); 94 | resolve(obj); 95 | } else { 96 | resolve(values[0]); 97 | } 98 | })); 99 | }); 100 | }; 101 | 102 | if (typeof sPO === 'function' && typeof gPO === 'function') { 103 | sPO(promisified, gPO(orig)); 104 | } else { 105 | promisified.__proto__ = orig.__proto__; // eslint-disable-line no-proto 106 | } 107 | 108 | defineDataProperty(promisified, kCustomPromisifiedSymbol, promisified, true, true, null, true); 109 | 110 | var descriptors = getOwnPropertyDescriptors(orig); 111 | forEach(descriptors, function (k, v) { 112 | try { 113 | oDP(promisified, k, v); 114 | } catch (e) { 115 | // handle nonconfigurable function properties 116 | } 117 | }); 118 | return promisified; 119 | }; 120 | 121 | module.exports.custom = kCustomPromisifiedSymbol; 122 | module.exports.customPromisifyArgs = kCustomPromisifyArgsSymbol; 123 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var define = require('define-properties'); 4 | var util = require('util'); 5 | 6 | var implementation = require('./implementation'); 7 | var getPolyfill = require('./polyfill'); 8 | var polyfill = getPolyfill(); 9 | var shim = require('./shim'); 10 | 11 | /* eslint-disable no-unused-vars */ 12 | var boundPromisify = function promisify(orig) { 13 | /* eslint-enable no-unused-vars */ 14 | return polyfill.apply(util, arguments); 15 | }; 16 | define(boundPromisify, { 17 | custom: polyfill.custom, 18 | customPromisifyArgs: polyfill.customPromisifyArgs, 19 | getPolyfill: getPolyfill, 20 | implementation: implementation, 21 | shim: shim 22 | }); 23 | 24 | module.exports = boundPromisify; 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "util.promisify", 3 | "version": "1.1.3", 4 | "description": "Polyfill/shim for util.promisify in node versions < v8", 5 | "main": "index.js", 6 | "scripts": { 7 | "prepack": "npmignore --auto --commentLines=autogenerated", 8 | "prepublishOnly": "safe-publish-latest", 9 | "prepublish": "not-in-publish || npm run prepublishOnly", 10 | "lint": "eslint --ext=js,mjs.", 11 | "postlint": "es-shim-api --bound", 12 | "pretest": "npm run lint", 13 | "tests-only": "nyc tape 'test/**/*.js'", 14 | "test": "npm run tests-only", 15 | "posttest": "npx npm@'>= 10.2' audit --production", 16 | "version": "auto-changelog && git add CHANGELOG.md", 17 | "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/ljharb/util.promisify.git" 22 | }, 23 | "keywords": [ 24 | "promisify", 25 | "promise", 26 | "util", 27 | "polyfill", 28 | "shim", 29 | "util.promisify" 30 | ], 31 | "author": "Jordan Harband ", 32 | "funding": { 33 | "url": "https://github.com/sponsors/ljharb" 34 | }, 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/ljharb/util.promisify/issues" 38 | }, 39 | "homepage": "https://github.com/ljharb/util.promisify#readme", 40 | "dependencies": { 41 | "call-bind": "^1.0.8", 42 | "call-bound": "^1.0.3", 43 | "define-data-property": "^1.1.4", 44 | "define-properties": "^1.2.1", 45 | "es-errors": "^1.3.0", 46 | "es-object-atoms": "^1.0.0", 47 | "for-each": "^0.3.3", 48 | "get-intrinsic": "^1.2.6", 49 | "has-proto": "^1.2.0", 50 | "has-symbols": "^1.1.0", 51 | "object.getownpropertydescriptors": "^2.1.8", 52 | "safe-array-concat": "^1.1.3" 53 | }, 54 | "devDependencies": { 55 | "@es-shims/api": "^2.5.1", 56 | "@ljharb/eslint-config": "^21.1.1", 57 | "auto-changelog": "^2.5.0", 58 | "encoding": "^0.1.13", 59 | "eslint": "=8.8.0", 60 | "in-publish": "^2.0.1", 61 | "npmignore": "^0.3.1", 62 | "nyc": "^10.3.2", 63 | "safe-publish-latest": "^2.0.0", 64 | "tape": "^5.9.0" 65 | }, 66 | "auto-changelog": { 67 | "output": "CHANGELOG.md", 68 | "template": "keepachangelog", 69 | "unreleased": false, 70 | "commitLimit": false, 71 | "backfillLimit": false, 72 | "hideCredit": true 73 | }, 74 | "publishConfig": { 75 | "ignore": [ 76 | ".github/workflows" 77 | ] 78 | }, 79 | "engines": { 80 | "node": ">= 0.8" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /polyfill.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var implementation = require('./implementation'); 5 | 6 | module.exports = function getPolyfill() { 7 | if (typeof util.promisify === 'function' && util.promisify.custom === implementation.custom) { 8 | return util.promisify; 9 | } 10 | return implementation; 11 | }; 12 | -------------------------------------------------------------------------------- /shim.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var getPolyfill = require('./polyfill'); 5 | 6 | module.exports = function shimUtilPromisify() { 7 | var polyfill = getPolyfill(); 8 | if (polyfill !== util.promisify) { 9 | Object.defineProperty(util, 'promisify', { 10 | configurable: true, 11 | enumerable: true, 12 | value: polyfill, 13 | writable: true 14 | }); 15 | } 16 | return polyfill; 17 | }; 18 | -------------------------------------------------------------------------------- /test/implementation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var test = require('tape'); 4 | 5 | var runTests = require('./tests'); 6 | 7 | test('implementation', function (t) { 8 | /* eslint global-require: 1 */ 9 | if (typeof Promise === 'function') { 10 | var promisify = require('../implementation'); 11 | runTests(promisify, t); 12 | } else { 13 | t['throws']( 14 | function () { require('../implementation'); }, 15 | TypeError, 16 | 'throws when no Promise available' 17 | ); 18 | } 19 | 20 | t.end(); 21 | }); 22 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var test = require('tape'); 4 | 5 | var runTests = require('./tests'); 6 | 7 | test('as a function', function (t) { 8 | /* eslint global-require: 1 */ 9 | if (typeof Promise === 'function') { 10 | var promisify = require('../'); 11 | runTests(promisify, t); 12 | } else { 13 | t['throws']( 14 | function () { require('../'); }, 15 | TypeError, 16 | 'throws when no Promise available' 17 | ); 18 | } 19 | 20 | t.end(); 21 | }); 22 | -------------------------------------------------------------------------------- /test/shimmed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var test = require('tape'); 4 | var util = require('util'); 5 | 6 | var runTests = require('./tests'); 7 | 8 | test('shimmed', { skip: typeof Promise !== 'function' }, function (t) { 9 | require('../auto'); // eslint-disable-line global-require 10 | 11 | runTests(util.promisify, t); 12 | 13 | t.end(); 14 | }); 15 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var hasSymbols = require('has-symbols')(); 4 | 5 | module.exports = function runTests(promisify, t) { 6 | t.equal(typeof promisify, 'function', 'promisify is a function'); 7 | 8 | t['throws']( 9 | function () { promisify(null); }, 10 | TypeError, 11 | 'throws on non-functions' 12 | ); 13 | 14 | var yes = function () { 15 | var cb = arguments[arguments.length - 1]; 16 | cb(null, Array.prototype.slice.call(arguments, 0, -1)); 17 | }; 18 | var no = function () { 19 | var cb = arguments[arguments.length - 1]; 20 | cb(Array.prototype.slice.call(arguments, 0, -1)); 21 | }; 22 | 23 | var pYes = promisify(yes); 24 | var pNo = promisify(no); 25 | 26 | t.equal(typeof pYes, 'function', 'pYes is a function'); 27 | t.equal(typeof pNo, 'function', 'pNo is a function'); 28 | 29 | t.test('pYes is properly promisified', { skip: typeof Promise !== 'function' }, function (st) { 30 | st.plan(1); 31 | 32 | var p = pYes(1, 2, 3); 33 | return p.then(function (result) { 34 | st.deepEqual(result, [1, 2, 3], 'fulfillment: arguments are preserved'); 35 | }); 36 | }); 37 | 38 | t.test('pNo is properly promisified', { skip: typeof Promise !== 'function' }, function (st) { 39 | st.plan(1); 40 | 41 | var p = pNo(1, 2, 3); 42 | return p.then(null, function (args) { 43 | st.deepEqual(args, [1, 2, 3], 'rejection: arguments are preserved'); 44 | }); 45 | }); 46 | 47 | t.test('custom symbol', { skip: !hasSymbols }, function (st) { 48 | st.equal(Symbol.keyFor(promisify.custom), 'nodejs.util.promisify.custom', 'is a global symbol with the right key'); 49 | // eslint-disable-next-line no-restricted-properties 50 | st.equal(Symbol['for']('nodejs.util.promisify.custom'), promisify.custom, 'is the global symbol'); 51 | 52 | st.end(); 53 | }); 54 | }; 55 | --------------------------------------------------------------------------------