-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
501 additions
and
741 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
language: node_js | ||
|
||
node_js: | ||
- "8" | ||
- "7" | ||
- "6.2" | ||
- "6.3" | ||
- "6.4" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,89 @@ | ||
# ts-library-starter | ||
[![NPM version](https://img.shields.io/npm/v/ts-library-starter.svg)](https://www.npmjs.com/package/ts-library-starter) | ||
[![Build Status](https://travis-ci.org/DxCx/ts-library-starter.svg?branch=master)](https://travis-ci.org/DxCx/ts-library-starter) | ||
[![Coverage Status](https://coveralls.io/repos/github/DxCx/ts-library-starter/badge.svg?branch=master)](https://coveralls.io/github/DxCx/ts-library-starter?branch=master) | ||
# ioo - Immutable Object Operators | ||
[![NPM version](https://img.shields.io/npm/v/ioo.svg)](https://www.npmjs.com/package/ioo) | ||
[![Build Status](https://travis-ci.org/this-dot/ioo.svg?branch=master)](https://travis-ci.org/this-dot/ioo) | ||
[![Coverage Status](https://coveralls.io/repos/github/this-dot/ioo/badge.svg?branch=master)](https://coveralls.io/github/this-dot/ioo?branch=master) | ||
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version) | ||
|
||
Example git project that is used for typescript libraries as a starter pack | ||
|
||
What does it include: | ||
---- | ||
1. exported class as example for an npm moudle | ||
2. packaging for npm modules (webpack + tslint + awesome-typescript-loader + dts-bundle) | ||
3. testings for npm modules (jest) | ||
4. code coverage (jest) when running tests | ||
5. Typescript => ES6 => ES5 (babel) | ||
6. Two versions embed in the package, one for node, one for browser (browserify) | ||
|
||
Notes | ||
---- | ||
Please note that you will need to rename the library name in some files: | ||
|
||
1. webpack.config.js (bundle_opts) | ||
2. package.json (ofcourse ;)) | ||
Also don't forget to reset package version ;) | ||
|
||
Useful commands: | ||
---- | ||
npm run prebuild - install NPM dependancies | ||
npm run build - build the library files | ||
npm run test - run the tests | ||
npm run test:watch - run the tests (watch-mode) | ||
npm run coverage - run the tests with coverage | ||
npm run coverage:watch - run the tests with coverage (watch-mode) | ||
npm run pack - build the library, make sure the tests passes, and then pack the library (creates .tgz) | ||
npm run release - prepare package for next release | ||
|
||
Files explained: | ||
---- | ||
1. src - directory is used for typescript code that is part of the project | ||
1a. src/Example.ts - Just an example exported library, used to should import in tests. | ||
1b. src/Example.spec.ts - tests for the example class | ||
1c. src/index.ts - index, which functionality is exported from the library | ||
1d. src/main.ts - just wrapper for index | ||
3. package.json - file is used to describe the library | ||
4. tsconfig.json - configuration file for the library compilation | ||
6. tslint.json - configuration file for the linter (both test and library) | ||
8. webpack.config.js - configuration file of the compilation automation process for the library | ||
|
||
Output files explained: | ||
---- | ||
1. node_modules - directory npm creates with all the dependencies of the module (result of npm install) | ||
2. dist - directory contains the compiled library (javascript + typings) | ||
3. <module_name>-<module_version>.tgz - final tgz file for publish. (result of npm run pack) | ||
4. coverage - code coverage report output made by istanbul | ||
# Installation | ||
|
||
```sh | ||
npm install --save ioo | ||
``` | ||
|
||
# Operations | ||
|
||
## mapObject(object, ( key: string, value: any ) => any): {} | ||
|
||
Iterate over keys of the object and invoke the callback for every key, passing the key and value on that key. The callback signature is meant to be similar to `Array.prototype.map`. Value returned from the callback will become the new value on that key. | ||
|
||
```ts | ||
mapObject({ firstName: 'peter', lastName: 'griffin' }, ( key, value ) => value.toUpperCase() ) | ||
// => { firstName: 'Peter', lastName: 'Griffin' } | ||
``` | ||
|
||
For more code examples, checkout [src/mapObject.test.ts](src/mapObject.test.ts) | ||
|
||
## reduceObject(object, ( result: any, key: string, value: any ) => any, initial: any ): any | ||
|
||
Reduce the object to a single value. The result can be another object. The callback signature is meant to be similar to `Array.prototype.reduce`. This operator will invoke the callback for each property. The callback will receive the result of previous operation or initial value, the key and value at that property. | ||
|
||
```ts | ||
reduceObject({ firstName: 'peter', lastName: 'griffin' }, ( result, key, value ) => { | ||
if (result) { | ||
return `${result} ${value}`; | ||
} else { | ||
return value; | ||
} | ||
}, null); | ||
// => peter griffin | ||
|
||
reduceObject({ firstName: 'peter', lastName: 'griffin' }, ( result, key, value ) => { | ||
return { | ||
...result, | ||
[key.toLowerCase()]: value | ||
}; | ||
}, {}); | ||
// => { firstname: 'peter', lastname: 'griffin' } | ||
``` | ||
|
||
For more code examples, checkout [src/reduceObject.test.ts](src/reduceObject.test.ts) | ||
|
||
## filterObject(object, ( key: string, value: any ) => {} ): {} | ||
|
||
Iterate the keys of the object and invoke the callback for each key and value pair. If the callback returns a truthy value then | ||
the key will be included in the output object. The callback signature is meant to be similar to `Array.prototype.filter`. | ||
|
||
```ts | ||
filterObject({ firstName: 'peter', lastName: 'griffin', age: 62 }, ( key, value ) => { | ||
return typeof value === 'string'; | ||
}); | ||
// => { firstName: 'peter', lastName: 'griffin' } | ||
``` | ||
|
||
For more code examples, checkout [src/filterObject.test.ts](src/filterObject.test.ts) | ||
|
||
## set(path: Array<string | number>, value: any, data: Array | {}): Array | {} | ||
|
||
`set` operator will create a new object with value replaced at given path. It uses lenses from [Ramda.js](http://ramdajs.com/docs/#set) to ensure that all objects that are parents to the object that received the value become new objects as well. This is particularly helpful in frameworks like React and Glimmer.js that compare state by reference. The path can mix objects and arrays. Use integer for array keys and strings for object keys. | ||
|
||
```ts | ||
set([ 'a', 0, 'b' ], 'e', { a: [ { b: 'c' }, { b: 'd' } ]}); | ||
//=> { a: [ { b: 'e' } , { b: 'd' } ] } | ||
``` | ||
|
||
For more code examples, checkout [src/set.test.ts](src/set.test.ts) | ||
|
||
## get(path: Array<string | number>, data: Array | {}): any | ||
|
||
`get` counterpart to `set`. It accepts a path array of strings or integers and returns value found that path. | ||
|
||
```ts | ||
set([ 'a', 0, 'b' ], { a: [ { b: 'c' }, { b: 'd' } ]}); | ||
//=> c | ||
``` | ||
|
||
For more code examples, checkout [src/get.test.ts](src/get.test.ts) | ||
|
||
# Credit | ||
|
||
Big thanks to [Charles Lowell](http://github.com/cowboyd) who wrote the map/reduceObject functions and showed me how to use lenses. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const { keys } = Object; | ||
/** | ||
* Invoke callback for each property and pass key and value to each property. | ||
* | ||
* eachProperty({ a: 'b', c: 'd'}, (key, value) => console.log(key, value)}) | ||
* // ab | ||
* // cd | ||
* | ||
* @param object {} | ||
* @param fn: (key: string, value: any) => any | ||
*/ | ||
export default function eachProperty( | ||
object: {}, | ||
fn: (key: string, value: any) => any | ||
): void { | ||
if (typeof object === 'object') { | ||
keys(object).forEach(function(key) { | ||
fn(key, object[key]); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
'use strict'; | ||
|
||
import 'jest'; | ||
require('babel-core/register'); | ||
require('babel-polyfill'); | ||
|
||
import eachProperty from './eachProperty'; | ||
|
||
describe('eachProperty', () => { | ||
let callback; | ||
beforeEach(() => { | ||
callback = jest.fn(); | ||
eachProperty({ a: 'b', c: 'd' }, callback); | ||
}); | ||
it('invokes callback for each property', () => { | ||
expect(callback.mock.calls.length).toEqual(2); | ||
}); | ||
it('passes key and value to callback', () => { | ||
expect(callback.mock.calls[0]).toEqual(['a', 'b']); | ||
expect(callback.mock.calls[1]).toEqual(['c', 'd']); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
'use strict'; | ||
|
||
import 'jest'; | ||
require('babel-core/register'); | ||
require('babel-polyfill'); | ||
|
||
import filterObject from './filterObject'; | ||
|
||
describe('filterObject', () => { | ||
let original = { small: 1, smallish: 2, big: 4 }; | ||
let callback, result; | ||
|
||
describe('callback use', () => { | ||
beforeEach(() => { | ||
callback = jest | ||
.fn() | ||
.mockReturnValueOnce(false) | ||
.mockReturnValueOnce(true) | ||
.mockReturnValueOnce(undefined); | ||
result = filterObject(original, callback); | ||
}); | ||
it('was called three times', () => { | ||
expect(callback.mock.calls.length).toEqual(3); | ||
}); | ||
it('removed items that returned false', () => { | ||
expect(result).toEqual({ smallish: 2 }); | ||
}); | ||
it('passed key and value', () => { | ||
expect(callback.mock.calls[0]).toEqual(['small', 1]); | ||
expect(callback.mock.calls[1]).toEqual(['smallish', 2]); | ||
expect(callback.mock.calls[2]).toEqual(['big', 4]); | ||
}); | ||
}); | ||
|
||
describe('result', () => { | ||
beforeEach(() => { | ||
result = filterObject( | ||
original, | ||
(key, value) => key.indexOf('small') === -1 | ||
); | ||
}); | ||
|
||
it('returns a new object', () => { | ||
expect(result).not.toEqual(original); | ||
}); | ||
|
||
it('returns filtered hash', () => { | ||
expect(result).toEqual({ big: 4 }); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import reduceObject from './reduceObject'; | ||
|
||
/** | ||
* Create a new hash with keys and their corresponding values | ||
* removed based on result of callback operation. E.g. | ||
* | ||
* filterObject({ small: 1, smallish: 2, big: 4}, (key, value) => value < 3 }) | ||
* | ||
* { small: 1, smallish: 2 } | ||
* | ||
* @param object | ||
* @param fn | ||
*/ | ||
export default function filterObject(object: {}, fn: (key, value) => boolean) { | ||
return reduceObject( | ||
object, | ||
(result, key, value) => { | ||
if (fn(key, value)) { | ||
return { | ||
...result, | ||
[key]: value | ||
}; | ||
} | ||
return result; | ||
}, | ||
{} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
'use strict'; | ||
|
||
import 'jest'; | ||
require('babel-core/register'); | ||
require('babel-polyfill'); | ||
|
||
import get from './get'; | ||
|
||
describe('get', () => { | ||
describe('array', () => { | ||
const original = [{ a: { b: { c: 'd' } } }, { e: 'f' }]; | ||
|
||
it('gets value from deeply nested path', () => { | ||
expect(get([0, 'a', 'b', 'c'], original)).toEqual('d'); | ||
}); | ||
}); | ||
|
||
describe('object', () => { | ||
const original = { a: { b: { c: 'd' } } }; | ||
it('gets value an object', () => { | ||
expect(get(['a', 'b', 'c'], original)).toEqual('d'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import * as lensPath from 'ramda/src/lensPath'; | ||
import * as view from 'ramda/src/view'; | ||
|
||
export default function get( | ||
path: Array<string | number>, | ||
data: {} | Array<any> | ||
) { | ||
let lens = lensPath(path); | ||
return view(lens, data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,8 @@ | ||
export { Example } from "./Example"; | ||
import get from './get'; | ||
import set from './set'; | ||
import reduceObject from './reduceObject'; | ||
import mapObject from './mapObject'; | ||
import filterObject from './filterObject'; | ||
import eachProperty from './eachProperty'; | ||
|
||
export { eachProperty, filterObject, mapObject, reduceObject, set, get }; |
Oops, something went wrong.