Skip to content

Commit

Permalink
Require Node.js 8, add TypeScript definition (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
BendingBender authored and sindresorhus committed Mar 12, 2019
1 parent d355a50 commit d93455e
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 77 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[{package.json,*.yml}]
[*.yml]
indent_style = space
indent_size = 2
3 changes: 1 addition & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* text=auto
*.js text eol=lf
* text=auto eol=lf
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
yarn.lock
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: node_js
node_js:
- '6'
- '4'
- '10'
- '8'
17 changes: 17 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Conditional promise chains. It's just a passthrough if `condition` is `false` and `doElse` is not provided.
*
* @param condition - Decides whether `doIf` or `doElse` is executed.
* @param doIf - Executed if `condition` is `true`. Expected to return a `Promise` or value.
* @param doElse - Executed if `condition` is `false`. Expected to return a `Promise` or value.
* @returns A [thunk](https://en.m.wikipedia.org/wiki/Thunk) that returns a `Promise`.
*/
export default function pIf<
ValueType,
DoIfReturnType,
DoElseReturnType = ValueType
>(
condition: boolean | ((value: ValueType) => boolean | PromiseLike<boolean>),
doIf: (value: ValueType) => DoIfReturnType | PromiseLike<DoIfReturnType>,
doElse?: (value: ValueType) => DoElseReturnType | PromiseLike<DoElseReturnType>
): (value: ValueType) => Promise<DoIfReturnType | DoElseReturnType>;
14 changes: 9 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
'use strict';

module.exports = (cond, doIf, doElse) => val => {
const chooseFn = bool => bool === true ? doIf(val) : (doElse ? doElse(val) : val);
const pIf = (condition, doIf, doElse) => async value => {
const chooseFn = bool =>
bool === true ? doIf(value) : doElse ? doElse(value) : value;

if (typeof cond === 'function') {
return Promise.resolve(cond(val)).then(chooseFn);
if (typeof condition === 'function') {
const conditionResult = await condition(value);
return chooseFn(conditionResult);
}

return chooseFn(cond);
return chooseFn(condition);
};

module.exports = pIf;
module.exports.default = pIf;
106 changes: 106 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {expectType} from 'tsd-check';
import pIf from '.';

expectType<Promise<number | string>>(
pIf<number, string>(true, value => {
expectType<number>(value);
return 'foo';
})(1)
);
expectType<Promise<number | string>>(
pIf<number, string>(
value => {
expectType<number>(value);
return true;
},
value => {
expectType<number>(value);
return 'foo';
}
)(1)
);
expectType<Promise<number | string>>(
pIf<number, string>(
value => {
expectType<number>(value);
return Promise.resolve(true);
},
value => {
expectType<number>(value);
return 'foo';
}
)(1)
);
expectType<Promise<number | string>>(
pIf<number, string>(
value => {
expectType<number>(value);
return Promise.resolve(true);
},
value => {
expectType<number>(value);
return Promise.resolve('foo');
}
)(1)
);
expectType<Promise<symbol | string>>(
pIf<number, string, symbol>(
true,
value => {
expectType<number>(value);
return 'foo';
},
value => {
expectType<number>(value);
return Symbol();
}
)(1)
);
expectType<Promise<symbol | string>>(
pIf<number, string, symbol>(
value => {
expectType<number>(value);
return true;
},
value => {
expectType<number>(value);
return 'foo';
},
value => {
expectType<number>(value);
return Symbol();
}
)(1)
);
expectType<Promise<number | string | symbol>>(
pIf<number, string, symbol>(
value => {
expectType<number>(value);
return Promise.resolve(true);
},
value => {
expectType<number>(value);
return 'foo';
},
value => {
expectType<number>(value);
return Symbol();
}
)(1)
);
expectType<Promise<symbol | string>>(
pIf<number, string, symbol>(
value => {
expectType<number>(value);
return Promise.resolve(true);
},
value => {
expectType<number>(value);
return Promise.resolve('foo');
},
value => {
expectType<number>(value);
return Promise.resolve(Symbol());
}
)(1)
);
83 changes: 41 additions & 42 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,43 @@
{
"name": "p-if",
"version": "1.1.0",
"description": "Conditional promise chains",
"license": "MIT",
"repository": "sindresorhus/p-if",
"author": {
"name": "Sindre Sorhus",
"email": "[email protected]",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=4"
},
"scripts": {
"test": "xo && ava"
},
"files": [
"index.js"
],
"keywords": [
"promise",
"if",
"else",
"conditional",
"cond",
"iff",
"chain",
"thunk",
"function",
"async",
"await",
"promises",
"combinator",
"bluebird"
],
"devDependencies": {
"ava": "*",
"xo": "*"
},
"xo": {
"esnext": true
}
"name": "p-if",
"version": "1.1.0",
"description": "Conditional promise chains",
"license": "MIT",
"repository": "sindresorhus/p-if",
"author": {
"name": "Sindre Sorhus",
"email": "[email protected]",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=8"
},
"scripts": {
"test": "xo && ava && tsd-check"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"promise",
"if",
"else",
"conditional",
"cond",
"iff",
"chain",
"thunk",
"function",
"async",
"await",
"promises",
"combinator",
"bluebird"
],
"devDependencies": {
"ava": "^1.3.1",
"tsd-check": "^0.3.0",
"xo": "^0.24.0"
}
}
50 changes: 25 additions & 25 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@
import test from 'ava';
import m from './';
import pIf from '.';

const fixture = Symbol('fixture');

test('if', async t => {
const val = await Promise.resolve(fixture)
.then(m(true, () => 'if', () => 'else'));
const value = await Promise.resolve(fixture)
.then(pIf(true, () => 'if', () => 'else'));

t.is(val, 'if');
t.is(value, 'if');
});

test('else', async t => {
const val = await Promise.resolve(fixture)
.then(m(false, () => 'if', () => 'else'));
const value = await Promise.resolve(fixture)
.then(pIf(false, () => 'if', () => 'else'));

t.is(val, 'else');
t.is(value, 'else');
});

test('passthrough', async t => {
const val = await Promise.resolve(fixture)
.then(m(false, () => 'if'));
const value = await Promise.resolve(fixture)
.then(pIf(false, () => 'if'));

t.is(val, fixture);
t.is(value, fixture);
});

test('composability', async t => {
const val = await Promise.resolve(fixture)
.then(m(true, m(false, () => 'if', () => 'else')));
const value = await Promise.resolve(fixture)
.then(pIf(true, pIf(false, () => 'if', () => 'else')));

t.is(val, 'else');
t.is(value, 'else');
});

test('condition can be a function', async t => {
const isEmpty = arr => arr.length === 0;

const valA = await Promise.resolve([])
.then(m(isEmpty, arr => arr.concat(42)));
const valueA = await Promise.resolve([])
.then(pIf(isEmpty, arr => arr.concat(42)));

const valB = await Promise.resolve([1])
.then(m(isEmpty, arr => arr.concat(42)));
const valueB = await Promise.resolve([1])
.then(pIf(isEmpty, arr => arr.concat(42)));

t.deepEqual(valA, [42]);
t.deepEqual(valB, [1]);
t.deepEqual(valueA, [42]);
t.deepEqual(valueB, [1]);
});

test('condition can be an async function', async t => {
const valA = await Promise.resolve([])
.then(m(async () => true, arr => arr.concat(42)));
const valueA = await Promise.resolve([])
.then(pIf(async () => true, arr => arr.concat(42)));

const valB = await Promise.resolve([1])
.then(m(async () => false, arr => arr.concat(42)));
const valueB = await Promise.resolve([1])
.then(pIf(async () => false, arr => arr.concat(42)));

t.deepEqual(valA, [42]);
t.deepEqual(valB, [1]);
t.deepEqual(valueA, [42]);
t.deepEqual(valueB, [1]);
});

0 comments on commit d93455e

Please sign in to comment.