Skip to content

Commit 4ce0e4e

Browse files
authored
Merge pull request #6 from okgrow/feat/add-negative-number-scalars
Added NegativeInt and NegativeFloat scalars
2 parents 829b6a5 + b508663 commit 4ce0e4e

21 files changed

+1291
-76
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [0.2.0] - 2018-01-16
8+
### Changed
9+
- Implemented more strict numeric type checking
10+
- Some type exception messages changed slightly
11+
- Changed `graphql` from a dependency to a _peer_ dependency
12+
13+
### Added
14+
- NegativeInt
15+
- NegativeFloat
16+
- NonPositiveInt
17+
- NonPositiveFloat
18+
- more tests
19+
720
## [0.1.0] - 2017-07-14
821
### Added
922
- Initial Release - released as [`@okgrow/graphql-scalars`](https://www.npmjs.com/package/@okgrow/graphql-scalars) on npm.

README.md

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@ In your schema:
1818
```graphql
1919
scalar DateTime
2020

21+
scalar NonPositiveInt
2122
scalar PositiveInt
2223
scalar NonNegativeInt
24+
scalar NegativeInt
25+
26+
scalar NonPositiveFloat
2327
scalar PositiveFloat
2428
scalar NonNegativeFloat
29+
scalar NegativeFloat
2530

2631
scalar EmailAddress
2732
scalar URL
@@ -31,9 +36,17 @@ In your resolver map, first import them:
3136
```js
3237
import {
3338
DateTime,
39+
40+
NonPositiveInt,
3441
PositiveInt,
42+
NonNegativeInt,
43+
NegativeInt,
44+
45+
NonPositiveFloat,
3546
PositiveFloat,
3647
NonNegativeFloat,
48+
NegativeFloat,
49+
3750
EmailAddress,
3851
URL,
3952
} from '@okgrow/graphql-scalars';
@@ -45,10 +58,15 @@ Then make sure they're in the root resolver map like this:
4558
const myResolverMap = {
4659
DateTime,
4760

61+
NonPositiveInt,
4862
PositiveInt,
4963
NonNegativeInt,
64+
NegativeInt,
65+
66+
NonPositiveFloat,
5067
PositiveFloat,
5168
NonNegativeFloat,
69+
NegativeFloat,
5270

5371
EmailAddress,
5472
URL,
@@ -134,15 +152,27 @@ inevitable parsing or conversion themselves.
134152
### NonNegativeInt
135153
Integers that will have a value of 0 or more. Uses [`parseInt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt).
136154

155+
### NonPositiveInt
156+
Integers that will have a value of 0 or less. Uses [`parseInt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt).
157+
137158
### PositiveInt
138159
Integers that will have a value greater than 0. Uses [`parseInt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt).
139160

161+
### NegativeInt
162+
Integers that will have a value less than 0. Uses [`parseInt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt).
163+
140164
### NonNegativeFloat
141165
Floats that will have a value of 0 or more. Uses [`parseFloat()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat).
142166

167+
### NonPositiveFloat
168+
Floats that will have a value of 0 or less. Uses [`parseFloat()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat).
169+
143170
### PositiveFloat
144171
Floats that will have a value greater than 0. Uses [`parseFloat()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat).
145172

173+
### NegativeFloat
174+
Floats that will have a value less than 0. Uses [`parseFloat()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat).
175+
146176
### EmailAddress
147177
A field whose value conforms to the standard internet email address format as specified in
148178
[RFC822](https://www.w3.org/Protocols/rfc822/).
@@ -157,15 +187,11 @@ We'd like to keep growing this package, within reason, to include the scalar typ
157187
required when defining GraphQL schemas. We welcome both suggestions and pull requests. A couple of
158188
ideas we're considering are:
159189

160-
- NegativeInt
161-
- NegativeFloat
162-
163-
These are easy to add, we just haven't run into cases for them yet.
164-
165190
- PhoneNumber
166191
- PostalCode
192+
- BLOB
167193

168-
These both have challenges in terms of making them globally useful so they need a bit of thought.
194+
These all have challenges in terms of making them globally useful so they need a bit of thought.
169195

170196
For `PhoneNumber` we can probably just use the [E.164 specification](https://en.wikipedia.org/wiki/E.164)
171197
which is simply `+17895551234`. The very powerful
@@ -176,6 +202,8 @@ parse user input and _get_ the E.164 format to pass _into_ a schema.
176202
Postal codes are [a bit more involved](https://en.wikipedia.org/wiki/List_of_postal_codes). But,
177203
again, it's probably just a really long regex.
178204

205+
BLOBs could be a base64-encoded object of some kind.
206+
179207
## What's this all about?
180208
GraphQL is a wonderful new approach to application data and API layers that's gaining momentum. If
181209
you have not heard of it, start [here](http://graphql.org/learn/) and check out

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@okgrow/graphql-scalars",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "A collection of scalar types not included in base GraphQL.",
55
"repository": {
66
"type": "git",
@@ -31,10 +31,11 @@
3131
"eslint-plugin-import": "^2.2.0",
3232
"eslint-plugin-jsx-a11y": "^3.0.0",
3333
"eslint-plugin-react": "^6.10.3",
34+
"graphql": "^0.10.1",
3435
"jest": "^20.0.4",
3536
"nodemon": "1.11.x"
3637
},
37-
"dependencies": {
38+
"peerDependencies": {
3839
"graphql": "^0.10.1"
3940
}
4041
}

src/NegativeFloat.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { GraphQLScalarType } from 'graphql';
2+
import { GraphQLError } from 'graphql/error';
3+
import { Kind } from 'graphql/language';
4+
5+
import { processValue, VALIDATIONS } from './utilities';
6+
7+
export default new GraphQLScalarType({
8+
name: 'NegativeFloat',
9+
10+
description: 'Floats that will have a value less than 0.',
11+
12+
serialize(value) {
13+
return processValue(value, VALIDATIONS.NegativeFloat);
14+
},
15+
16+
parseValue(value) {
17+
return processValue(value, VALIDATIONS.NegativeFloat);
18+
},
19+
20+
parseLiteral(ast) {
21+
if (ast.kind !== Kind.FLOAT) {
22+
throw new GraphQLError(`Can only validate floating point numbers as negative floating point numbers but got a: ${ast.kind}`); // eslint-disable-line max-len
23+
}
24+
25+
return processValue(ast.value, VALIDATIONS.NegativeFloat);
26+
},
27+
});

src/NegativeInt.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { GraphQLScalarType } from 'graphql';
2+
import { GraphQLError } from 'graphql/error';
3+
import { Kind } from 'graphql/language';
4+
5+
import { processValue, VALIDATIONS } from './utilities';
6+
7+
export default new GraphQLScalarType({
8+
name: 'NegativeInt',
9+
10+
description: 'Integers that will have a value less than 0.',
11+
12+
serialize(value) {
13+
return processValue(value, VALIDATIONS.NegativeInt);
14+
},
15+
16+
parseValue(value) {
17+
return processValue(value, VALIDATIONS.NegativeInt);
18+
},
19+
20+
parseLiteral(ast) {
21+
if (ast.kind !== Kind.INT) {
22+
throw new GraphQLError(`Can only validate integers as negative integers but got a: ${ast.kind}`); // eslint-disable-line max-len
23+
}
24+
25+
return processValue(ast.value, VALIDATIONS.NegativeInt);
26+
},
27+
});

src/NonNegativeFloat.js

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,26 @@ import { GraphQLScalarType } from 'graphql';
22
import { GraphQLError } from 'graphql/error';
33
import { Kind } from 'graphql/language';
44

5-
function processValue(value) {
6-
if (isNaN(value)) {
7-
throw new TypeError(`Value is not a number: ${value}`);
8-
}
9-
10-
if (value < 0) {
11-
throw new TypeError(`Value is a negative number: ${value}`);
12-
}
13-
14-
return parseFloat(value);
15-
}
5+
import { processValue, VALIDATIONS } from './utilities';
166

177
export default new GraphQLScalarType({
188
name: 'NonNegativeFloat',
199

2010
description: 'Floats that will have a value of 0 or more.',
2111

2212
serialize(value) {
23-
return processValue(value);
13+
return processValue(value, VALIDATIONS.NonNegativeFloat);
2414
},
2515

2616
parseValue(value) {
27-
return processValue(value);
17+
return processValue(value, VALIDATIONS.NonNegativeFloat);
2818
},
2919

3020
parseLiteral(ast) {
3121
if (ast.kind !== Kind.FLOAT) {
3222
throw new GraphQLError(`Can only validate floating point numbers as non-negative floating point numbers but got a: ${ast.kind}`); // eslint-disable-line max-len
3323
}
3424

35-
return processValue(ast.value);
25+
return processValue(ast.value, VALIDATIONS.NonNegativeFloat);
3626
},
3727
});

src/NonNegativeInt.js

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,26 @@ import { GraphQLScalarType } from 'graphql';
22
import { GraphQLError } from 'graphql/error';
33
import { Kind } from 'graphql/language';
44

5-
function processValue(value) {
6-
if (isNaN(value)) {
7-
throw new TypeError(`Value is not a number: ${value}`);
8-
}
9-
10-
if (value < 0) {
11-
throw new TypeError(`Value is a negative number: ${value}`);
12-
}
13-
14-
return parseInt(value, 10);
15-
}
5+
import { processValue, VALIDATIONS } from './utilities';
166

177
export default new GraphQLScalarType({
188
name: 'NonNegativeInt',
199

2010
description: 'Integers that will have a value of 0 or more.',
2111

2212
serialize(value) {
23-
return processValue(value);
13+
return processValue(value, VALIDATIONS.NonNegativeInt);
2414
},
2515

2616
parseValue(value) {
27-
return processValue(value);
17+
return processValue(value, VALIDATIONS.NonNegativeInt);
2818
},
2919

3020
parseLiteral(ast) {
3121
if (ast.kind !== Kind.INT) {
3222
throw new GraphQLError(`Can only validate integers as non-negative integers but got a: ${ast.kind}`); // eslint-disable-line max-len
3323
}
3424

35-
return processValue(ast.value);
25+
return processValue(ast.value, VALIDATIONS.NonNegativeInt);
3626
},
3727
});

src/NonPositiveFloat.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { GraphQLScalarType } from 'graphql';
2+
import { GraphQLError } from 'graphql/error';
3+
import { Kind } from 'graphql/language';
4+
5+
import { processValue, VALIDATIONS } from './utilities';
6+
7+
export default new GraphQLScalarType({
8+
name: 'NonPositiveFloat',
9+
10+
description: 'Floats that will have a value of 0 or less.',
11+
12+
serialize(value) {
13+
return processValue(value, VALIDATIONS.NonPositiveFloat);
14+
},
15+
16+
parseValue(value) {
17+
return processValue(value, VALIDATIONS.NonPositiveFloat);
18+
},
19+
20+
parseLiteral(ast) {
21+
if (ast.kind !== Kind.FLOAT) {
22+
throw new GraphQLError(`Can only validate floating point numbers as non-positive floating point numbers but got a: ${ast.kind}`); // eslint-disable-line max-len
23+
}
24+
25+
return processValue(ast.value, VALIDATIONS.NonPositiveFloat);
26+
},
27+
});

src/NonPositiveInt.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { GraphQLScalarType } from 'graphql';
2+
import { GraphQLError } from 'graphql/error';
3+
import { Kind } from 'graphql/language';
4+
5+
import { processValue, VALIDATIONS } from './utilities';
6+
7+
export default new GraphQLScalarType({
8+
name: 'NonPositiveInt',
9+
10+
description: 'Integers that will have a value of 0 or less.',
11+
12+
serialize(value) {
13+
return processValue(value, VALIDATIONS.NonPositiveInt);
14+
},
15+
16+
parseValue(value) {
17+
return processValue(value, VALIDATIONS.NonPositiveInt);
18+
},
19+
20+
parseLiteral(ast) {
21+
if (ast.kind !== Kind.INT) {
22+
throw new GraphQLError(`Can only validate integers as non-positive integers but got a: ${ast.kind}`); // eslint-disable-line max-len
23+
}
24+
25+
return processValue(ast.value, VALIDATIONS.NonPositiveInt);
26+
},
27+
});

src/PositiveFloat.js

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,26 @@ import { GraphQLScalarType } from 'graphql';
22
import { GraphQLError } from 'graphql/error';
33
import { Kind } from 'graphql/language';
44

5-
function processValue(value) {
6-
if (isNaN(value)) {
7-
throw new TypeError(`Value is not a number: ${value}`);
8-
}
9-
10-
if (!(value > 0)) {
11-
throw new TypeError(`Value is not a positive number: ${value}`);
12-
}
13-
14-
return parseFloat(value);
15-
}
5+
import { processValue, VALIDATIONS } from './utilities';
166

177
export default new GraphQLScalarType({
188
name: 'PositiveFloat',
199

2010
description: 'Floats that will have a value greater than 0.',
2111

2212
serialize(value) {
23-
return processValue(value);
13+
return processValue(value, VALIDATIONS.PositiveFloat);
2414
},
2515

2616
parseValue(value) {
27-
return processValue(value);
17+
return processValue(value, VALIDATIONS.PositiveFloat);
2818
},
2919

3020
parseLiteral(ast) {
3121
if (ast.kind !== Kind.FLOAT) {
3222
throw new GraphQLError(`Can only validate floating point numbers as positive floating point numbers but got a: ${ast.kind}`); // eslint-disable-line max-len
3323
}
3424

35-
return processValue(ast.value);
25+
return processValue(ast.value, VALIDATIONS.PositiveFloat);
3626
},
3727
});

0 commit comments

Comments
 (0)