├── .gitignore ├── LICENSE ├── README.md ├── example ├── index.js └── schema.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Xpepermint (Kristijan Sedlak) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [graphql](http://graphql.org/)-type-factory 2 | 3 | > Additional GraphQL types 4 | 5 | ## Setup 6 | 7 | Install the package. 8 | 9 | ``` 10 | npm i --save graphql-type-factory 11 | ``` 12 | 13 | Use new types as you would use the default GraphQL types. 14 | 15 | ```js 16 | import { ... } from 'graphql-type-factory'; // ES6 17 | var GraphQLTypeFactory = require('graphql-type-factory'); // CommonJS 18 | ``` 19 | 20 | ## Types 21 | 22 | #### ::: String Factory 23 | 24 | ``` 25 | GraphQLStringFactory({ 26 | name: ... Type name. 27 | min: ... Minimum string length. 28 | max: ... Maximum string length. 29 | regex: ... Regular expression pattern. 30 | fn: ... Method which returns `true` when input is valid. 31 | }); 32 | ``` 33 | 34 | Example: 35 | 36 | ```js 37 | var NameType = GraphQLStringFactory({ 38 | name: 'Name', 39 | fn: function(ast) {return ast.value.length > 5} 40 | }); 41 | ``` 42 | 43 | #### ::: Email 44 | 45 | ``` 46 | GraphQLEmailType 47 | ``` 48 | 49 | #### ::: URL 50 | 51 | ``` 52 | GraphQLURLType 53 | ``` 54 | 55 | ## Example 56 | 57 | How to run the example: 58 | 59 | * Clone this repository. 60 | * Run `npm install` to install the required modules. 61 | * Run `npm run example` to start the GraphQL server. 62 | * Create a new user. 63 | ``` 64 | curl -XPOST -H 'Content-Type:application/graphql' -d 'mutation RootMutation { addUser(id: "1", name: "John", email: "me@domain.com", website: "http://domain.com")}' http://localhost:4444 65 | ``` 66 | * Retrieve created users. 67 | ``` 68 | curl -XPOST -H 'Content-Type:application/graphql' -d '{users{id, email}}' http://localhost:4444 69 | ``` 70 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var graphQLHTTP = require('express-graphql'); 3 | var schema = require('./schema'); 4 | 5 | var app = express(); 6 | app.use(graphQLHTTP({schema, pretty: true})); 7 | app.listen(4444); 8 | -------------------------------------------------------------------------------- /example/schema.js: -------------------------------------------------------------------------------- 1 | var gt = require('graphql/type'); 2 | var gtf = require('..'); 3 | 4 | var users = []; // this will be our database 5 | 6 | var GraphQLNameType = gtf.GraphQLStringFactory({name: 'Name', min: 1, max: 250}); // how can we create a custom string type 7 | 8 | var UserType = new gt.GraphQLObjectType({ 9 | name: 'User', 10 | fields: { 11 | id: {type: gt.GraphQLInt}, 12 | name: {type: GraphQLNameType}, 13 | email: {type: gtf.GraphQLEmailType}, 14 | website: {type: gtf.GraphQLURLType} 15 | } 16 | }); 17 | 18 | var RootQueryType = new gt.GraphQLObjectType({ 19 | name: 'RootQuery', 20 | fields: { 21 | users: { 22 | type: new gt.GraphQLList(UserType), 23 | resolve() { 24 | return users; 25 | } 26 | } 27 | } 28 | }); 29 | 30 | var RootMutationType = new gt.GraphQLObjectType({ 31 | name: 'RootMutation', 32 | fields: { 33 | addUser: { 34 | type: UserType, 35 | args: { 36 | id: {type: gt.GraphQLString}, 37 | name: {type: GraphQLNameType}, 38 | email: {type: gtf.GraphQLEmailType}, 39 | website: {type: gtf.GraphQLURLType} 40 | }, 41 | resolve: (root, args) => { 42 | var user = {id: args.id, name: args.name, email: args.email, website: args.website}; 43 | users.push(user); 44 | return user; 45 | } 46 | } 47 | } 48 | }) 49 | var schema = new gt.GraphQLSchema({ 50 | query: RootQueryType, 51 | mutation: RootMutationType 52 | }); 53 | 54 | module.exports = schema; 55 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var GraphQLScalarType = require('graphql').GraphQLScalarType; 2 | var GraphQLError = require('graphql/error').GraphQLError; 3 | var Kind = require('graphql/language').Kind; 4 | 5 | var GraphQLStringFactory = function(attrs) { 6 | return new GraphQLScalarType({ 7 | name: attrs.name, 8 | description: attrs.description, 9 | serialize: function(value) { 10 | return value; 11 | }, 12 | parseValue: function(value) { 13 | return value; 14 | }, 15 | parseLiteral: function(ast) { 16 | if (ast.kind !== Kind.STRING) { 17 | throw new GraphQLError('Expecting "' + attrs.name + '" to be string value.', [ast]); 18 | } 19 | if (ast.value.length <= attrs.min) { 20 | throw new GraphQLError('Minimum length for "' + attrs.name + '" is ' + attrs.min + '.', [ast]); 21 | } 22 | if (ast.value.length >= attrs.max){ 23 | throw new GraphQLError('Maximum length for "' + attrs.name + '" is ' + attrs.max + '.', [ast]); 24 | } 25 | if(attrs.regex && !attrs.regex.test(ast.value)) { 26 | throw new GraphQLError('"' + attrs.name + '" is invalid.', [ast]); 27 | } 28 | if(attrs.fn && !attrs.fn(ast)) { 29 | throw new GraphQLError('"' + attrs.name + '" is invalid.', [ast]); 30 | } 31 | return ast.value; 32 | } 33 | }); 34 | }; 35 | 36 | var GraphQLEmailType = GraphQLStringFactory({ 37 | name: 'Email', 38 | min: 4, 39 | max: 254, 40 | regex: /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i, 41 | fn: function(ast) {return true} 42 | }); 43 | 44 | var GraphQLURLType = GraphQLStringFactory({ 45 | name: 'URL', 46 | max: 2083, 47 | regex: /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i 48 | }); 49 | 50 | module.exports = { 51 | GraphQLStringFactory: GraphQLStringFactory, 52 | GraphQLEmailType: GraphQLEmailType, 53 | GraphQLURLType: GraphQLURLType 54 | }; 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graphql-type-factory", 3 | "version": "0.1.0", 4 | "description": "Additional GraphQL types", 5 | "main": "index.js", 6 | "scripts": { 7 | "example": "node ./example/index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/xpepermint/graphql-type-factory.git" 13 | }, 14 | "keywords": [ 15 | "graphql", 16 | "type", 17 | "types", 18 | "scalar", 19 | "validate", 20 | "validation", 21 | "custom" 22 | ], 23 | "author": "Xpepermint", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/xpepermint/graphql-type-factory/issues" 27 | }, 28 | "homepage": "https://github.com/xpepermint/graphql-type-factory#readme", 29 | "devDependencies": { 30 | "express-graphql": "^0.4.0", 31 | "graphql": "^0.4.5" 32 | } 33 | } 34 | --------------------------------------------------------------------------------