Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit df9cf46

Browse files
committedNov 30, 2017
Initial commit
0 parents  commit df9cf46

12 files changed

+4887
-0
lines changed
 

‎.babelrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": [
3+
"flow",
4+
["env", { "targets": { "node": "current" } }]
5+
]
6+
}

‎.eslintignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/lib/*
2+
!/lib/bundle.js.flow
3+
/flow-typed/npm
4+
/coverage
5+
*.log
6+
*.log-*
7+
*.log_*
8+
*.log.*

‎.eslintrc.yml

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
extends:
2+
- airbnb-base
3+
- plugin:flowtype/recommended
4+
5+
plugins:
6+
- flowtype
7+
8+
env:
9+
node: true
10+
browser: false
11+
12+
rules:
13+
14+
no-multi-assign: off
15+
16+
no-return-assign:
17+
- error
18+
- except-parens
19+
20+
no-confusing-arrow: off
21+
22+
semi:
23+
- error
24+
- never
25+
26+
consistent-return: off
27+
28+
no-unused-expressions: off
29+
30+
object-curly-newline:
31+
- error
32+
- consistent: true
33+
34+
function-paren-newline:
35+
- error
36+
- consistent
37+
38+
import/prefer-default-export: off
39+
40+
41+
flowtype/boolean-style:
42+
- error
43+
- boolean
44+
45+
flowtype/define-flow-type: error
46+
47+
flowtype/delimiter-dangle:
48+
- error
49+
- always-multiline
50+
51+
flowtype/generic-spacing:
52+
- error
53+
- never
54+
55+
flowtype/no-dupe-keys: error
56+
57+
flowtype/no-primitive-constructor-types: error
58+
59+
flowtype/no-weak-types:
60+
- error
61+
- any: false
62+
Object: false
63+
Function: true
64+
65+
flowtype/object-type-delimiter:
66+
- error
67+
- comma
68+
69+
flowtype/require-valid-file-annotation:
70+
- error
71+
- never
72+
- annotationStyle: block
73+
74+
flowtype/semi:
75+
- error
76+
- never
77+
78+
flowtype/space-after-type-colon:
79+
- error
80+
- always
81+
- allowLineBreak: false
82+
83+
flowtype/space-before-generic-bracket:
84+
- error
85+
- never
86+
87+
flowtype/space-before-type-colon:
88+
- error
89+
- never
90+
91+
flowtype/type-id-match:
92+
- error
93+
- ^[A-Z]
94+
95+
flowtype/union-intersection-spacing:
96+
- error
97+
- always
98+
99+
flowtype/use-flow-type: error

‎.flowconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[ignore]
2+
3+
[include]
4+
5+
[libs]
6+
7+
[options]
8+
esproposal.export_star_as=enable
9+
10+
[lints]

‎.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/node_modules
2+
/lib/*
3+
!/lib/bundle.js.flow
4+
/coverage
5+
*.log
6+
*.log-*
7+
*.log.*
8+
*.log_*

‎LICENSE.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# The MIT License (MIT)
2+
3+
## Copyright © 2017 Pavel Tereschenko
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6+
associated documentation files (the "Software"), to deal in the Software without restriction,
7+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
8+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all copies or substantial
12+
portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
17+
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

‎README.md

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# typed-contracts
2+
3+
Validation with good type inference
4+
5+
## What is it
6+
7+
`Contract` is a function that receives an arbitrary value and validates it.
8+
`Сontract` returns this value if it passed the validation, or `ValidationError` instance if not.
9+
Contracts are a 100% guarantee that the data that passed validation matches your expeted type definitions.
10+
11+
## How it work
12+
13+
All contracts have this interface:
14+
15+
```js
16+
contract('my value', validValiue) // => validValiue
17+
contract('my value', invalidValue) // => ValidationError instance
18+
contract.maybe('my value', null) // => null
19+
contract.maybe('my value', undefined) // => undefined
20+
contract.maybe('my value', invalidValue) // => ValidationError instance
21+
contract.optional('my value', undefined) // => undefined
22+
contract.optional('my value', invalidValue) // => ValidationError instance
23+
24+
const namedContract = contract.bindName('my value')
25+
26+
namedContract(validValiue) // => validValiue
27+
namedContract(invalidValue) // => ValidationError instance
28+
namedContract.maybe(null) // => null
29+
namedContract.maybe(undefined) // => undefined
30+
namedContract.maybe(invalidValue) // => ValidationError instance
31+
namedContract.optional(undefined) // => undefined
32+
namedContract.optional(invalidValue) // => ValidationError instance
33+
```
34+
35+
## Contracts can be combined
36+
37+
```js
38+
type Person = {
39+
name: string,
40+
gender: 'm' | 'f',
41+
friends: Person[],
42+
email?: string,
43+
}
44+
45+
// isPerson returns Person-compatibile value or ValidationError
46+
const isPerson = isObject({
47+
name: isString,
48+
gender: isUnion( isLiteral('m'), isLiteral('f') ),
49+
friends: isArray((valueName, value) => isPerson(valueName, value)),
50+
email: isString.optional,
51+
})
52+
53+
// We need to control compatibility of the return value type with Person
54+
const userValidate =
55+
(value: mixed): Person | ValidationError =>
56+
isPerson('user', value)
57+
58+
const user = userValidate({ name: 'Vasya' })
59+
```
60+
61+
## Contracts API
62+
63+
### `isArray`
64+
65+
Creates a contract that expects an array of values that are validated by the initial contract.
66+
67+
```js
68+
(contract: (valueName: string, value: mixed) => (ValidationError | T)) => Contract
69+
```
70+
71+
### `isLiteral`
72+
73+
Creates a contract that expects a specific string or number value.
74+
75+
```js
76+
(expected: string | number) => Contract
77+
```
78+
79+
### `isNull`
80+
81+
Creates a contract that expects null.
82+
83+
### `isNumber`
84+
85+
Creates a contract that expects number.
86+
87+
### `isObject`
88+
89+
Creates a contract that expects an object whose properties are validated by the corresponding
90+
contracts in spec.
91+
92+
```js
93+
(spec: { [key: string] (valueName: string, value: mixed) => (ValidationError | T) }) => Contract
94+
```
95+
96+
### `isString`
97+
98+
Creates a contract that expects string.
99+
100+
### `isUnion`
101+
102+
Creates a contract that expects value, validating one of the initial contracts.
103+
104+
```js
105+
(...contracts: Array<(valueName: string, value: mixed) => (ValidationError | T)>) => Contract
106+
```
107+
108+
### `isVoid` or `isUndefined`
109+
110+
Creates a contract that expects undefined.

‎__tests__/.eslintrc.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
extends: ../.eslintrc.yml
2+
3+
env:
4+
jest: true

‎flow-typed/npm/jest_v21.x.x.js

+584
Large diffs are not rendered by default.

‎package.json

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"name": "typed-contracts",
3+
"version": "0.0.1",
4+
"description": "Validation with good type inference (Flow support)",
5+
"main": "lib/bundle.js",
6+
"engines": {
7+
"node": ">=6.0.0"
8+
},
9+
"files": [
10+
"README.md",
11+
"LICENSE.md",
12+
"lib",
13+
"src"
14+
],
15+
"scripts": {
16+
"lint": "eslint .",
17+
"flow": "flow",
18+
"test": "jest --env=node",
19+
"pretyped": "shx rm -rf flow-typed/npm",
20+
"typed": "flow-typed update",
21+
"posttyped": "flow-typed install",
22+
"build": "rollup -c",
23+
"precommit": "yarn lint && yarn flow && yarn test",
24+
"preversion": "git checkout master && yarn precommit",
25+
"postversion": "git push origin master --follow-tags"
26+
},
27+
"devDependencies": {
28+
"babel-core": "^6.26.0",
29+
"babel-eslint": "^8.0.2",
30+
"babel-jest": "^21.2.0",
31+
"babel-plugin-transform-class-properties": "^6.24.1",
32+
"babel-preset-env": "^1.6.1",
33+
"babel-preset-flow": "^6.23.0",
34+
"eslint": "^4.11.0",
35+
"eslint-config-airbnb-base": "^12.1.0",
36+
"eslint-plugin-flowtype": "^2.39.1",
37+
"eslint-plugin-import": "^2.8.0",
38+
"flow-bin": "^0.59.0",
39+
"flow-typed": "^2.2.3",
40+
"husky": "^0.14.3",
41+
"jest": "^21.2.1",
42+
"markdownlint": "^0.6.4",
43+
"rollup": "^0.52.0",
44+
"rollup-plugin-babel": "3.0.2",
45+
"rollup-plugin-commonjs": "<=8.2.3 || ^8.2.7",
46+
"rollup-plugin-node-resolve": "3.0.0",
47+
"shx": "^0.2.2"
48+
},
49+
"repository": {
50+
"type": "git",
51+
"url": "git+https://github.com/bigslycat/typed-contracts.git"
52+
},
53+
"keywords": [
54+
"flow",
55+
"flowtype",
56+
"contracts",
57+
"validation",
58+
"type inference"
59+
],
60+
"author": {
61+
"name": "Pavel Tereschenko",
62+
"email": "me@stupidcat.wtf",
63+
"url": "https://github.com/bigslycat"
64+
},
65+
"license": "MIT",
66+
"bugs": {
67+
"url": "https://github.com/bigslycat/typed-contracts/issues"
68+
},
69+
"homepage": "https://github.com/bigslycat/typed-contracts#readme"
70+
}

‎rollup.config.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import resolve from 'rollup-plugin-node-resolve'
2+
import commonjs from 'rollup-plugin-commonjs'
3+
import babel from 'rollup-plugin-babel'
4+
5+
import packageJson from './package.json'
6+
7+
const { dependencies } = packageJson
8+
9+
const deps = dependencies && Object.keys(dependencies).join('|')
10+
const reg = deps && new RegExp(`^(${deps})($|/)`)
11+
12+
const banner = `
13+
/**
14+
* ${packageJson.name} v${packageJson.version}
15+
* ${packageJson.description}
16+
*/
17+
`
18+
19+
export default {
20+
input: 'src/index.js',
21+
output: {
22+
file: 'lib/bundle.js',
23+
format: 'cjs',
24+
},
25+
plugins: [
26+
resolve(),
27+
commonjs(),
28+
babel({
29+
babelrc: false,
30+
exclude: 'node_modules/**',
31+
plugins: [
32+
'transform-class-properties',
33+
],
34+
presets: [
35+
'flow',
36+
['env', {
37+
targets: {
38+
node: 1,
39+
browsers: ['>= 1%'],
40+
},
41+
modules: false,
42+
}],
43+
],
44+
}),
45+
],
46+
external: id => !!reg && reg.test(id),
47+
banner,
48+
}

‎yarn.lock

+3,922
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.