Skip to content

Commit

Permalink
Merge pull request #3 from chuvikovd/typescript
Browse files Browse the repository at this point in the history
Typescript
  • Loading branch information
chuvikovd authored Mar 27, 2020
2 parents 7e192ac + 55022b0 commit a5a8a5b
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 771 deletions.
9 changes: 5 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2.1
orbs:
node: circleci/[email protected]
jobs:
build-and-test:
test-and-build:
executor:
name: node/default
steps:
Expand All @@ -11,7 +11,8 @@ jobs:
steps:
- run: yarn
- run: yarn test
- run: yarn build
workflows:
build-and-test:
jobs:
- build-and-test
test-and-build:
jobs:
- test-and-build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
coverage
dist
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!dist/*
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## 2.0.0 (March 27, 2020)

* Rewritten with typescript

### Breaking changes

* Syntax for sort array changed from `['column-order']` to `[['column', 'order']]`. `order` now must be uppercased.

7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Tiny, zero-dependency multi column sorting helper.

[![npm](https://img.shields.io/npm/v/multi-column-sort?style=flat-square)](https://www.npmjs.com/package/multi-column-sort)
[![CircleCI](https://img.shields.io/circleci/build/github/chuvikovd/multi-column-sort?style=flat-square)](https://circleci.com/gh/chuvikovd/multi-column-sort)
[![GitHub file size in bytes](https://img.shields.io/github/size/chuvikovd/multi-column-sort/index.js?style=flat-square)](https://github.com/chuvikovd/multi-column-sort/blob/master/index.js)
[![GitHub](https://img.shields.io/github/license/chuvikovd/multi-column-sort?style=flat-square)](https://github.com/chuvikovd/multi-column-sort/blob/master/LICENSE)

## Installation
Expand All @@ -23,7 +22,7 @@ $ yarn add multi-column-sort

## Usage

```javascript
```typescript
import multiColumnSort from 'multi-column-sort'

const data = [
Expand All @@ -45,7 +44,7 @@ const getColumnValue = (column, value) => {

const sorted = multiColumnSort(
data,
['firstName-asc', 'balance-desc'],
[['firstName', 'ASC'], ['balance', 'DESC']],
getColumnValue
)

Expand All @@ -67,5 +66,5 @@ multiColumnSort(array, sortArray, getColumnValue)
**Parameters**

- `array` **array** Array of objects to be sorted.
- `sortArray` **array** Array of strings defining columns to be sorted by, order and direction e.g. `['name-asc', 'city-desc']`.
- `sortArray` **array** Array of tuples defining columns to be sorted by, order and direction e.g. `[['name', 'ASC'], ['city', 'DESC']]`.
- `getColumnValue` **function** Optional, by default all values are cast to string. Takes `column` and `value` arguments, must return value for comparison.
3 changes: 0 additions & 3 deletions babel.config.js

This file was deleted.

23 changes: 0 additions & 23 deletions index.js

This file was deleted.

34 changes: 34 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
type SortArray<T> = [keyof T, 'ASC' | 'DESC'][]
type GetColumnValue<T> = (column: keyof T, value: T[keyof T]) => any

const sort = <T>(
a: T,
b: T,
columns: SortArray<T>,
getColumnValue?: GetColumnValue<T>
): -1 | 0 | 1 => {
const [item, ...others] = columns
const [column, orderBy] = item
const valueA = getColumnValue ? getColumnValue(column, a[column]) : a[column]
const valueB = getColumnValue ? getColumnValue(column, b[column]) : b[column]

if (orderBy === 'ASC') {
if (valueA > valueB) return 1
if (valueA < valueB) return -1
if (others.length) return sort(a, b, others, getColumnValue)
return 0
} else {
if (valueB > valueA) return 1
if (valueB < valueA) return -1
if (others.length) return sort(a, b, others, getColumnValue)
return 0
}
}

const multiColumnSort = <T>(
arr: T[],
sortArr: [keyof T, 'ASC' | 'DESC'][],
getColumnValue?: GetColumnValue<T>
): T[] => [...arr].sort((a, b) => sort(a, b, sortArr, getColumnValue))

export default multiColumnSort
5 changes: 2 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module.exports = {
transform: {
'^.+\\.js$': 'babel-jest'
}
preset: 'ts-jest',
testEnvironment: 'node'
}
23 changes: 13 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,29 @@
"keywords": [
"multi-column-sorting",
"sorting",
"util"
],
"main": "index.js",
"files": [
"index.js"
"util",
"typescript"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
"scripts": {
"build": "tsc",
"format": "prettier-standard --format",
"lint": "prettier-standard --lint",
"test": "jest"
"test": "jest",
"prepublish": "yarn rimraf dist && yarn test && yarn build"
},
"devDependencies": {
"@babel/preset-env": "^7.8.7",
"babel-jest": "^25.1.0",
"@types/jest": "^25.1.4",
"husky": "^4.2.3",
"jest": "^25.1.0",
"prettier-config-standard": "^1.0.1",
"prettier-standard": "^16.2.1",
"standard": "^14.3.3"
"rimraf": "^3.0.2",
"standard": "^14.3.3",
"ts-jest": "^25.2.1",
"typescript": "^3.8.3"
},
"resolutions": {
"minimist": "^1.2.2"
Expand All @@ -38,7 +41,7 @@
}
},
"lint-staged": {
"*.{js,json}": [
"*.{js,ts,json}": [
"prettier-standard --format -- lint",
"git add"
]
Expand Down
36 changes: 24 additions & 12 deletions test.js → test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import multiColumnSort from './index.js'
import multiColumnSort from './index'
import unsorted from './data/unsorted.json'
import firstNameASCSorted from './data/firstNameASCSorted.json'
import firstNameDESCSorted from './data/firstNameDESCSorted.json'
import firstNameASCBalanceDESCSorted from './data/firstNameASCBalanceDESCSorted.json'
import firstNameDESCBalanceASCSorted from './data/firstNameDESCBalanceASCSorted.json'

interface Data {
firstName: string
lastName: string
balance: string
}

describe('multiColumnSort', () => {
const mapValues = arr => arr.map(({ firstName }) => ({ firstName }))
const mapValues = (arr: Data[]) => arr.map(({ firstName }) => ({ firstName }))

it('sorts by one column ASC', () => {
expect(mapValues(multiColumnSort(unsorted, ['firstName-asc']))).toEqual(
mapValues(firstNameASCSorted)
)
expect(
mapValues(multiColumnSort(unsorted, [['firstName', 'ASC']]))
).toEqual(mapValues(firstNameASCSorted))
})

it('sorts by one column DESC', () => {
expect(mapValues(multiColumnSort(unsorted, ['firstName-desc']))).toEqual(
mapValues(firstNameDESCSorted)
)
expect(
mapValues(multiColumnSort(unsorted, [['firstName', 'DESC']]))
).toEqual(mapValues(firstNameDESCSorted))
})

describe('with getColumnValue', () => {
const mapValues = arr =>
const mapValues = (arr: Data[]) =>
arr.map(({ firstName, balance }) => ({ firstName, balance }))

const getColumnValue = (column, value) => {
const getColumnValue = (column: keyof Data, value: Data[keyof Data]) => {
switch (column) {
case 'balance':
return parseFloat(value.replace(/\,|\$/g, ''))
Expand All @@ -38,7 +44,10 @@ describe('multiColumnSort', () => {
mapValues(
multiColumnSort(
unsorted,
['firstName-desc', 'balance-asc'],
[
['firstName', 'DESC'],
['balance', 'ASC']
],
getColumnValue
)
)
Expand All @@ -48,7 +57,10 @@ describe('multiColumnSort', () => {
mapValues(
multiColumnSort(
unsorted,
['firstName-asc', 'balance-desc'],
[
['firstName', 'ASC'],
['balance', 'DESC']
],
getColumnValue
)
)
Expand Down
12 changes: 12 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "dist",
"declaration": true,
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": ["index.ts"]
}
Loading

0 comments on commit a5a8a5b

Please sign in to comment.