Skip to content

Commit

Permalink
remove argName; typeName => name; error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
joonhocho committed Jun 10, 2016
1 parent f25e413 commit 63116e6
Show file tree
Hide file tree
Showing 5 changed files with 517 additions and 59 deletions.
124 changes: 124 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,127 @@


A configurable custom input string type for GraphQL with sanitization and validation.


### Install
```
npm install --save graphql-input-string
```


### Usage
```javascript
import GraphQLInputString from 'graphql-input-string';

const argType = GraphQLInputString({
name: 'TrimmedString',
trim: true,
});

new GraphQLObjectType({
name: 'Query',
fields: {
input: {
type: GraphQLString,
args: {
name: {
type: argType,
},
},
resolve: (_, {name}) => {

'name' IS NOW A TRIMMED STRING

};
},
},
});
```

### Options
```javascript
GraphQLInputString({
// Type name.
// [REQUIRED]
name: string = null,

// Whether to trim strings.
trim: boolean = false,

// Whether to trimLeft strings.
trimLeft: boolean = false,

// Whether to trimRight strings.
trimRight: boolean = false,

// If specified, truncate strings to the specified length.
truncate: number = null,

// Sanitize function that is called at the end of sanitzation phase and before
// validation phase.
sanitize: ((string) => string) = null,

// Whether to allow empty strings.
empty: boolean = false,

// Minimum length allowed (inclusive).
min: number = null,

// Maximum length allowed (inclusive).
max: number = null,

// Allowed pattern definition.
pattern: (string | RegExp) = null,

// Test function that is called at the end of validation phase.
test: ((string) => boolean) = null,

// Custom error handler.
// May throw an error or return a value.
// If a value is returned, it will become the final value.
error: ErrorHandler = () => throw GraphQLError,

// Parse function that is called after validation phase before returning a
// value.
// May throw an error or return a value.
parse: ((string) => any) = null,
});


type ErrorInfo = {
type: string,
value: string,
message: ?string,
ast: ?Ast,
...args,
};


type ErrorHandler = (ErrorInfo) => any;
```
### License
```
The MIT License (MIT)

Copyright (c) 2016 Joon Ho Cho

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "graphql-input-string",
"version": "0.0.6",
"version": "0.0.7",
"description": "A configurable custom input string type for GraphQL with sanitization and validation.",
"main": "lib/index.js",
"directories": {
Expand Down
75 changes: 57 additions & 18 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ function coerceString(value) {
}

export default ({
argName,
empty,
error,
max,
min,
name,
parse,
pattern,
sanitize,
Expand All @@ -27,30 +28,34 @@ export default ({
trimLeft,
trimRight,
truncate,
typeName,
}) => {
if (!typeName) {
throw new Error('"typeName" is required');
}

if (!argName) {
throw new Error('"argName" is required');
if (!name) {
throw new Error('"name" is required');
}

if (typeof pattern === 'string') {
pattern = new RegExp(pattern);
}

const error = (value, ast, message) => {
throw new GraphQLError(`Argument "${argName}" has invalid value ${JSON.stringify(value)}.${message ? ` ${message}` : ''}.`, ast ? [ast] : []);
};
if (typeof error !== 'function') {
error = ({value, ast, message}) => {
const more = message ? ` ${message}.` : '';
throw new GraphQLError(
`Invalid value ${JSON.stringify(value)}.${more}`,
ast ? [ast] : []
);
};
}

const parseValue = (value, ast) => {
value = coerceString(value);
if (value == null) {
return null;
}


// Sanitization Phase

if (trim) {
value = value.trim();
} else {
Expand All @@ -62,7 +67,7 @@ export default ({
}
}

if (truncate != null) {
if (truncate != null && value.length > truncate) {
value = value.substring(0, truncate);
}

Expand All @@ -73,26 +78,60 @@ export default ({
}
}


// Validation Phase

if (!empty && !value) {
error(value, ast, 'Expected non-empty string');
return error({
type: 'empty',
value,
message: 'Expected non-empty string',
ast,
});
}

if (min != null && value.length < min) {
error(value, ast, `Expected minimum length "${min}"`);
return error({
type: 'min',
value,
min,
message: `Expected minimum length "${min}"`,
ast,
});
}

if (max != null && value.length > max) {
error(value, ast, `Expected maximum length "${max}"`);
return error({
type: 'max',
value,
max,
message: `Expected maximum length "${max}"`,
ast,
});
}

if (pattern != null && !pattern.test(value)) {
error(value, ast, 'Unexpected pattern');
return error({
type: 'pattern',
value,
pattern,
message: 'Unexpected pattern',
ast,
});
}

if (test && !test(value)) {
error(value, ast);
return error({
type: 'test',
value,
test,
ast,
});
}


// Parse Phase

if (parse) {
return parse(value);
}
Expand All @@ -101,7 +140,7 @@ export default ({
};

return new GraphQLScalarType({
name: typeName,
name,
serialize: coerceString,
parseValue,
parseLiteral(ast) {
Expand Down
Loading

0 comments on commit 63116e6

Please sign in to comment.