├── .gitignore ├── .travis.yml ├── .editorconfig ├── main.mjs ├── main.d.ts ├── test.mjs ├── license.md ├── readme.md ├── package.json └── changelog.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - 14 5 | 6 | script: 7 | - npm run test:ci 8 | 9 | branches: 10 | only: 11 | - master 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org/ 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /main.mjs: -------------------------------------------------------------------------------- 1 | export function promiseAllProps (object) { 2 | return Promise.all(Object.values(object)).then((results) => ( 3 | Object.keys(object).reduce((fulfilledObject, key, index) => { 4 | fulfilledObject[key] = results[index]; 5 | return fulfilledObject; 6 | }, {}) 7 | )); 8 | } 9 | -------------------------------------------------------------------------------- /main.d.ts: -------------------------------------------------------------------------------- 1 | export function promiseAllProps< 2 | PromisesObject extends Record>, 3 | >( 4 | objectWithPromises: PromisesObject, 5 | ): { 6 | [Key in keyof PromisesObject]: PromisesObject[Key] extends Promise< 7 | infer Result 8 | > 9 | ? Result 10 | : never; 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /test.mjs: -------------------------------------------------------------------------------- 1 | import test from 'tape' 2 | import { promiseAllProps } from './main.mjs'; 3 | 4 | test('wait for fulfilled object properties', function (t) { 5 | t.plan(1); 6 | 7 | promiseAllProps({ 8 | foo: Promise.resolve('foo'), 9 | bar: Promise.resolve('bar') 10 | }).then(function (result) { 11 | t.deepEqual(result, { foo:'foo', bar:'bar' }); 12 | }); 13 | }); 14 | 15 | test('reject promise on rejected object properties', function (t) { 16 | t.plan(1); 17 | 18 | promiseAllProps({ 19 | foo: Promise.resolve('foo'), 20 | bar: Promise.reject('bar') 21 | }).catch(function (error) { 22 | t.equal(error, 'bar'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # promise-all-props 2 | [![npm][npm-badge]][npm] 3 | [![bundlephobia][bundlephobia-badge]][bundlephobia] 4 | 5 | Inspired by [bluebird's `Promise.props`](http://bluebirdjs.com/docs/api/promise.props.html). 6 | 7 | Like `Promise.all` but for object properties instead of iterated values. Returns a promise that is fulfilled when all the properties of the object are fulfilled. The promise's fulfillment value is an object with fulfilled values at respective keys to the original object. If any promise in the object rejects, the returned promise is rejected. 8 | 9 | ## Install 10 | Node.js: 11 | `npm install promise-all-props` 12 | 13 | Deno: 14 | `https://deno.land/x/promise_all_props` 15 | 16 | ## Usage example 17 | ```js 18 | import { promiseAllProps } from 'promise-all-props'; 19 | 20 | promiseAllProps({ 21 | foo: Promise.resolve('foo'), 22 | bar: Promise.resolve('bar') 23 | }).then((result) => { 24 | console.log(result.foo, result.bar); 25 | }); 26 | ``` 27 | 28 | [npm]: https://npmjs.com/package/promise-all-props 29 | [npm-badge]: https://tinyshields.dev/npm/promise-all-props.svg 30 | [bundlephobia]: https://bundlephobia.com/package/promise-all-props 31 | [bundlephobia-badge]: https://tinyshields.dev/bundlephobia/size/promise-all-props.svg 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "promise-all-props", 3 | "version": "3.0.0", 4 | "description": "Like `Promise.all` but for object properties.", 5 | "type": "module", 6 | "exports": { 7 | "types": "./main.d.ts", 8 | "import": "./main.mjs" 9 | }, 10 | "files": [ 11 | "main.mjs", 12 | "main.d.ts" 13 | ], 14 | "scripts": { 15 | "test": "node test.mjs", 16 | "test:ci": "npm test && npm run lint -- --max-warnings 0", 17 | "lint": "eslint *.mjs", 18 | "preversion": "npm test", 19 | "postversion": "git push --follow-tags" 20 | }, 21 | "devDependencies": { 22 | "eslint": "^8.6.0", 23 | "tape": "^5.4.0" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0" 27 | }, 28 | "eslintConfig": { 29 | "env": { 30 | "es2021": true, 31 | "node": true 32 | }, 33 | "parserOptions": { 34 | "ecmaVersion": 12, 35 | "sourceType": "module" 36 | }, 37 | "extends": "eslint:recommended" 38 | }, 39 | "repository": { 40 | "type": "git", 41 | "url": "https://github.com/Siilwyn/promise-all-props.git" 42 | }, 43 | "author": "Selwyn (https://selwyn.cc/)", 44 | "license": "ISC", 45 | "keywords": [ 46 | "promise", 47 | "all", 48 | "props", 49 | "properties", 50 | "object", 51 | "bluebird" 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and follows [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 4 | 5 | ## [3.0.0] - 2023-08-28 6 | ### Changed 7 | - Drop support for Node.js 14. 8 | - Function is exported as a named function so importing needs a destructure: 9 | ```js 10 | import { promiseAllProps } from 'promise-all-props'; 11 | ``` 12 | 13 | ### Added 14 | - TypeScript types, thanks to @karlhorky! 15 | 16 | ## [2.1.1] - 2021-07-13 17 | ### Fixed 18 | - The too strict Node.js engine semver range, support from 14 and up. 19 | 20 | ## [2.1.0] - 2021-03-09 21 | ### Added 22 | - Deno export to https://deno.land. 23 | 24 | ## [2.0.0] - 2021-03-08 25 | ### Changed 26 | - Drop support for older JS runtimes and Node.js versions under version 14. 27 | - Replace CommonJS entrypoints with ECMAScript modules. 28 | 29 | ## [1.0.1] - 2017-04-05 30 | ### Changed 31 | - Removed ES6 usage so code works out of the box in older JS runtimes 32 | 33 | [3.0.0]: https://github.com/Siilwyn/promise-all-props/compare/v2.1.1...v3.0.0 34 | [2.1.1]: https://github.com/Siilwyn/promise-all-props/compare/v2.1.0...v2.1.1 35 | [2.1.0]: https://github.com/Siilwyn/promise-all-props/compare/v2.0.0...v2.1.0 36 | [2.0.0]: https://github.com/Siilwyn/promise-all-props/compare/v1.0.1...v2.0.0 37 | [1.0.1]: https://github.com/Siilwyn/promise-all-props/compare/241fedc...v1.0.1 38 | --------------------------------------------------------------------------------