graphql-query-builder-v2
Advanced tools
+82
-66
@@ -8,16 +8,16 @@ "use strict"; | ||
| function parceFind(_levelA) { | ||
| //+++++++++++++++++++++++++++++++++++ work over Array | ||
| //++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
| let propsA = _levelA.map(function(currentValue, index) { | ||
| let itemX = _levelA[index]; | ||
| if( itemX instanceof Query){ | ||
| if (itemX instanceof Query) { | ||
| return itemX.toString(); | ||
| } else if ( ! Array.isArray(itemX) && "object" === typeof itemX ) { | ||
| } else if (!Array.isArray(itemX) && "object" === typeof itemX) { | ||
| let propsA = Object.keys(itemX); | ||
| if ( 1 !== propsA.length) { | ||
| throw new RangeError("Alias objects should only have one value. was passed: "+JSON.stringify(itemX)); | ||
| if (1 !== propsA.length) { | ||
| throw new RangeError("Alias objects should only have one value. was passed: " + JSON.stringify(itemX)); | ||
| } | ||
@@ -28,12 +28,12 @@ let propS = propsA[0]; | ||
| if (Array.isArray(item)) { | ||
| return new Query(propS).find(item) | ||
| return new Query(propS).find(item) | ||
| } | ||
| return `${propS} : ${item} `; | ||
| } else if ( "string" === typeof itemX ) { | ||
| } else if ("string" === typeof itemX) { | ||
| return itemX; | ||
| } else { | ||
| throw new RangeError("cannot handle Find value of "+itemX); | ||
| throw new RangeError("cannot handle Find value of " + itemX); | ||
| } | ||
| }); | ||
| return propsA.join(","); | ||
@@ -47,39 +47,40 @@ } | ||
| function getGraphQLValue(value) { | ||
| if ("string" === typeof value || value === null || value === undefined) { | ||
| if ("string" === typeof value || value === null || value === undefined) { | ||
| value = JSON.stringify(value); | ||
| } else if (Array.isArray(value)) { | ||
| } else if (Array.isArray(value)) { | ||
| value = value.map(item => { | ||
| return getGraphQLValue(item); | ||
| }).join(); | ||
| }).join(); | ||
| value = `[${value}]`; | ||
| } else if ("object" === typeof value) { | ||
| /*if (value.toSource) | ||
| value = value.toSource().slice(2,-2); | ||
| else*/ | ||
| value = objectToString(value); | ||
| //console.error("No toSource!!",value); | ||
| } | ||
| return value; | ||
| } else if ("object" === typeof value) { | ||
| /*if (value.toSource) | ||
| value = value.toSource().slice(2,-2); | ||
| else*/ | ||
| value = objectToString(value); | ||
| //console.error("No toSource!!",value); | ||
| } | ||
| return value; | ||
| } | ||
| function objectToString(obj) { | ||
| let sourceA = []; | ||
| for(let prop in obj){ | ||
| if ("function" === typeof obj[prop]) { | ||
| continue; | ||
| if (obj instanceof Query.EnumValue) { | ||
| return obj.value; | ||
| } | ||
| // if ("object" === typeof obj[prop]) { | ||
| let sourceA = []; | ||
| for (let prop in obj) { | ||
| if ("function" === typeof obj[prop]) { | ||
| continue; | ||
| } | ||
| // if ("object" === typeof obj[prop]) { | ||
| sourceA.push(`${prop}:${getGraphQLValue(obj[prop])}`); | ||
| // } else { | ||
| // sourceA.push(`${prop}:${obj[prop]}`); | ||
| // } | ||
| } | ||
| return `{${sourceA.join()}}`; | ||
| // } else { | ||
| // sourceA.push(`${prop}:${obj[prop]}`); | ||
| // } | ||
| } | ||
| return `{${sourceA.join()}}`; | ||
| } | ||
| //===================================================== | ||
@@ -89,12 +90,11 @@ //========================================= Query Class | ||
| function Query(_fnNameS, _aliasS_OR_Filter){ | ||
| function Query(_fnNameS, _aliasS_OR_Filter) { | ||
| this.fnNameS = _fnNameS; | ||
| this.headA = []; | ||
| this.filter = (filtersO) => { | ||
| for(let propS in filtersO){ | ||
| for (let propS in filtersO) { | ||
| if ("function" === typeof filtersO[propS]) { | ||
| continue; | ||
| continue; | ||
| } | ||
@@ -104,26 +104,26 @@ let val = getGraphQLValue(filtersO[propS]); | ||
| if ("{}" === val) { | ||
| continue; | ||
| continue; | ||
| } | ||
| this.headA.push( `${propS}:${val}` ); | ||
| } | ||
| this.headA.push(`${propS}:${val}`); | ||
| } | ||
| return this; | ||
| }; | ||
| if ("string" === typeof _aliasS_OR_Filter) { | ||
| this.aliasS = _aliasS_OR_Filter; | ||
| this.aliasS = _aliasS_OR_Filter; | ||
| } else if ("object" === typeof _aliasS_OR_Filter) { | ||
| this.filter(_aliasS_OR_Filter); | ||
| } else if (undefined === _aliasS_OR_Filter && 2 === arguments.length){ | ||
| } else if (undefined === _aliasS_OR_Filter && 2 === arguments.length) { | ||
| throw new TypeError("You have passed undefined as Second argument to 'Query'"); | ||
| } else if (undefined !== _aliasS_OR_Filter){ | ||
| throw new TypeError("Second argument to 'Query' should be an alias name(String) or filter arguments(Object). was passed "+_aliasS_OR_Filter); | ||
| } else if (undefined !== _aliasS_OR_Filter) { | ||
| throw new TypeError("Second argument to 'Query' should be an alias name(String) or filter arguments(Object). was passed " + _aliasS_OR_Filter); | ||
| } | ||
| this.setAlias = (_aliasS) =>{ | ||
| this.aliasS = _aliasS; | ||
| this.setAlias = (_aliasS) => { | ||
| this.aliasS = _aliasS; | ||
| return this; | ||
| }; | ||
| this.find = function(findA) { // THIS NEED TO BE A "FUNCTION" to scope 'arguments' | ||
| if( ! findA){ | ||
| if (!findA) { | ||
| throw new TypeError("find value can not be >>falsy<<"); | ||
@@ -143,4 +143,4 @@ } | ||
| Query.prototype = { | ||
| toString : function(){ | ||
| toString: function() { | ||
| // if (undefined === this.bodyS) { | ||
@@ -150,19 +150,19 @@ // throw new ReferenceError("return properties are not defined. use the 'find' function to defined them"); | ||
| let alias = | ||
| (this.aliasS) | ||
| ? (this.aliasS + ":") | ||
| let alias = | ||
| (this.aliasS) | ||
| ? (this.aliasS + ":") | ||
| : "" | ||
| let fnNameS = | ||
| let fnNameS = | ||
| this.fnNameS | ||
| let part2 = | ||
| let part2 = | ||
| (0 < this.headA.length) | ||
| ? `( ${this.headA.join(",")} )` | ||
| : "" | ||
| : "" | ||
| // console.log(this.headA) | ||
| // console.log(this.bodyS) | ||
| let part3 = | ||
| this.bodyS | ||
| ? `{ ${ this.bodyS } }` | ||
| let part3 = | ||
| this.bodyS | ||
| ? `{ ${this.bodyS} }` | ||
| : "" | ||
| return `${alias} ${fnNameS} ${part2} ${part3}`; | ||
@@ -173,2 +173,18 @@ // return `${ (this.aliasS) ? (this.aliasS + ":") : "" } ${this.fnNameS } ${ (0 < this.headA.length)?"("+this.headA.join(",")+")":"" } { ${ this.bodyS } }`; | ||
| //===================================================== | ||
| //========================================= Enum Class | ||
| //===================================================== | ||
| Query.EnumValue = function EnumValue(value) { | ||
| if (!value) { | ||
| throw new TypeError("enum value can not be >>falsy<<") | ||
| } | ||
| this.value = value; | ||
| }; | ||
| Query.Enum = function Enum(value) { | ||
| return new Query.EnumValue(value); | ||
| }; | ||
| module.exports = Query; |
+1
-1
| { | ||
| "name": "graphql-query-builder-v2", | ||
| "version": "2.0.3", | ||
| "version": "2.0.4", | ||
| "description": "a simple but powerful graphQL query builder", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
+18
-0
@@ -47,2 +47,20 @@ # graphql-query-builder-v2 | ||
| #### With enums | ||
| ```javascript | ||
| let query = | ||
| new QueryBuilder( | ||
| "functionName", | ||
| { | ||
| status: QueryBuilder.Enum('draft') | ||
| } | ||
| ) | ||
| ``` | ||
| **Output** | ||
| ```javascript | ||
| functionName( status: draft ) | ||
| ``` | ||
| # Install | ||
@@ -49,0 +67,0 @@ |
+218
-188
| "use strict"; | ||
| var expect = require('chai').expect; | ||
| var Query = require('./index'); | ||
| var expect = require("chai").expect; | ||
| var Query = require("./index"); | ||
| function removeSpaces(textS) { | ||
| return `${textS}`.replace(/\s+/g, ''); | ||
| return `${textS}`.replace(/\s+/g, ""); | ||
| } | ||
| describe("graphql query builder", function() { //log the function | ||
| it('should accept no find value', function(){ | ||
| let expeted = `user`; | ||
| let user = new Query("user"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| it("should accept no find value", function() { | ||
| let expected = `user`; | ||
| let user = new Query("user"); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should accept a null argument value', function(){ | ||
| let expeted = `user (id: null)`; | ||
| it("should accept a null argument value", function() { | ||
| let expected = `user (id: null)`; | ||
| let user = new Query("user", { id: null }); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should accept a single find value', function(){ | ||
| let expeted = `user{age}`; | ||
| let user = new Query("user").find("age"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should create a Query with function name & alia', function(){ | ||
| let expeted = `sam : user{name}`; | ||
| let user = new Query("user","sam").find("name"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should create a Query with function name & input', function(){ | ||
| let expeted = `user(id:12345){name}`; | ||
| let user = new Query("user",{id : 12345}).find("name"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should create a Query with function name & input(s)', function(){ | ||
| let expeted = `user(id:12345, age:34){name}`; | ||
| let user = new Query("user",{id : 12345, age:34}).find("name"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should accept a single find value with alia', function(){ | ||
| let expeted = `user{nickname:name}`; | ||
| let user = new Query("user").find({nickname:"name"}); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should accept a multiple find values', function(){ | ||
| let expeted = `user{firstname, lastname}`; | ||
| let user = new Query("user").find("firstname","lastname") | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should accept an array find values', function(){ | ||
| let expeted = `user{firstname, lastname}`; | ||
| let user = new Query("user").find(["firstname","lastname"]); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should work with nesting Querys', function(){ | ||
| let expeted = `user( id:12345 ) { | ||
| it("should accept a single find value", function() { | ||
| let expected = `user{age}`; | ||
| let user = new Query("user").find("age"); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should create a Query with function name & alia", function() { | ||
| let expected = `sam : user{name}`; | ||
| let user = new Query("user", "sam").find("name"); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should create a Query with function name & input", function() { | ||
| let expected = `user(id:12345){name}`; | ||
| let user = new Query("user", { id: 12345 }).find("name"); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should create a Query with function name & input(s)", function() { | ||
| let expected = `user(id:12345, age:34){name}`; | ||
| let user = new Query("user", { id: 12345, age: 34 }).find("name"); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should accept a single find value with alia", function() { | ||
| let expected = `user{nickname:name}`; | ||
| let user = new Query("user").find({ nickname: "name" }); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should accept a multiple find values", function() { | ||
| let expected = `user{firstname, lastname}`; | ||
| let user = new Query("user").find("firstname", "lastname") | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should accept an array find values", function() { | ||
| let expected = `user{firstname, lastname}`; | ||
| let user = new Query("user").find(["firstname", "lastname"]); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should work with nesting Querys", function() { | ||
| let expected = `user( id:12345 ) { | ||
| id, nickname : name, isViewerFriend, | ||
| image : profilePicture( size:50 ) { | ||
| uri, width, height } }`; | ||
| let profilePicture = new Query("profilePicture",{size : 50}); | ||
| profilePicture.find( "uri", "width", "height"); | ||
| let user = new Query("user",{id : 12345}); | ||
| user.find(["id", {"nickname":"name"}, "isViewerFriend", {"image":profilePicture}]); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should work with simple nesting Querys', function(){ | ||
| let profilePicture = new Query("profilePicture", { size: 50 }); | ||
| profilePicture.find("uri", "width", "height"); | ||
| let expeted = `user { profilePicture { uri, width, height } }` | ||
| let user = new Query("user", { id: 12345 }); | ||
| user.find(["id", { "nickname": "name" }, "isViewerFriend", { "image": profilePicture }]); | ||
| let user = new Query("user"); | ||
| user.find({"profilePicture": ['uri', 'width', 'height']}); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it('should be able to group Querys', function(){ | ||
| let expeted = `FetchLeeAndSam { lee: user(id: "1") { name }, | ||
| it("should work with simple nesting Querys", function() { | ||
| let expected = `user { profilePicture { uri, width, height } }` | ||
| let user = new Query("user"); | ||
| user.find({ "profilePicture": ["uri", "width", "height"] }); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(user)); | ||
| }); | ||
| it("should be able to group Querys", function() { | ||
| let expected = `FetchLeeAndSam { lee: user(id: "1") { name }, | ||
| sam: user(id: "2") { name } }`; | ||
| let FetchLeeAndSam = new Query("FetchLeeAndSam"); | ||
| let lee = new Query("user",{id : '1'}); | ||
| lee.setAlias('lee'); | ||
| lee.find(["name"]); | ||
| let sam = new Query("user","sam"); | ||
| sam.filter({id : '2'}); | ||
| sam.find("name"); | ||
| FetchLeeAndSam.find(lee,sam); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(FetchLeeAndSam)); | ||
| }); | ||
| it('should work with nasted objects and lists', function(){ | ||
| let expeted =`myPost:Message(type:"chat",message:"yoyo", | ||
| let FetchLeeAndSam = new Query("FetchLeeAndSam"); | ||
| let lee = new Query("user", { id: "1" }); | ||
| lee.setAlias("lee"); | ||
| lee.find(["name"]); | ||
| let sam = new Query("user", "sam"); | ||
| sam.filter({ id: "2" }); | ||
| sam.find("name"); | ||
| FetchLeeAndSam.find(lee, sam); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(FetchLeeAndSam)); | ||
| }); | ||
| it("should work with nasted objects and lists", function() { | ||
| let expected = `myPost:Message(type:"chat",message:"yoyo", | ||
| user:{name:"bob",screen:{height:1080,width:1920}}, | ||
| friends:[{id:1,name:"ann"},{id:2,name:"tom"}]) { | ||
| messageId : id, postedTime : createTime }`; | ||
| let MessageRequest = { type:"chat", | ||
| message:"yoyo", | ||
| user:{ name:"bob", | ||
| screen:{ height:1080, width:1920 } }, | ||
| friends:[ {id:1,name:"ann"}, {id:2,name:"tom"} ] | ||
| }; | ||
| let MessageQuery = new Query("Message","myPost"); | ||
| let MessageRequest = { | ||
| type: "chat", | ||
| message: "yoyo", | ||
| user: { | ||
| name: "bob", | ||
| screen: { height: 1080, width: 1920 } | ||
| }, | ||
| friends: [{ id: 1, name: "ann" }, { id: 2, name: "tom" }] | ||
| }; | ||
| let MessageQuery = new Query("Message", "myPost"); | ||
| MessageQuery.filter(MessageRequest); | ||
| MessageQuery.find({ messageId : "id"}, {postedTime : "createTime" }); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(MessageQuery)); | ||
| }); | ||
| it('should work with objects that have help functions(will skip function name)', function(){ | ||
| let expeted ='inventory(toy:"jack in the box") { id }'; | ||
| let ChildsToy = { toy:"jack in the box", getState:function(){ } }; | ||
| ChildsToy.getState();//for istanbul(coverage) to say all fn was called | ||
| let ItemQuery = new Query("inventory",ChildsToy); | ||
| MessageQuery.find({ messageId: "id" }, { postedTime: "createTime" }); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(MessageQuery)); | ||
| }); | ||
| it("should work with objects that have help functions(will skip function name)", function() { | ||
| let expected = "inventory(toy:\"jack in the box\") { id }"; | ||
| let ChildsToy = { | ||
| toy: "jack in the box", getState: function() { | ||
| } | ||
| }; | ||
| ChildsToy.getState();//for istanbul(coverage) to say all fn was called | ||
| let ItemQuery = new Query("inventory", ChildsToy); | ||
| ItemQuery.find("id"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it('should work with nasted objects that have help functions(will skip function name)', function(){ | ||
| let expeted ='inventory(toy:"jack in the box") { id }'; | ||
| let ChildsToy = { toy:"jack in the box", utils: { getState:function(){ } } }; | ||
| ChildsToy.utils.getState();//for istanbul(coverage) to say all fn was called | ||
| let ItemQuery = new Query("inventory",ChildsToy); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it("should work with nasted objects that have help functions(will skip function name)", function() { | ||
| let expeсted = "inventory(toy:\"jack in the box\") { id }"; | ||
| let ChildsToy = { | ||
| toy: "jack in the box", utils: { | ||
| getState: function() { | ||
| } | ||
| } | ||
| }; | ||
| ChildsToy.utils.getState();//for istanbul(coverage) to say all fn was called | ||
| let ItemQuery = new Query("inventory", ChildsToy); | ||
| ItemQuery.find("id"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it('should skip empty objects in filter/args', function(){ | ||
| let expeted ='inventory(toy:"jack in the box") { id }'; | ||
| let ChildsToy = { toy:"jack in the box", utils: { } }; | ||
| let ItemQuery = new Query("inventory",ChildsToy); | ||
| expect(removeSpaces(expeсted)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it("should skip empty objects in filter/args", function() { | ||
| let expeсted = "inventory(toy:\"jack in the box\") { id }"; | ||
| let ChildsToy = { toy: "jack in the box", utils: {} }; | ||
| let ItemQuery = new Query("inventory", ChildsToy); | ||
| ItemQuery.find("id"); | ||
| expect(removeSpaces(expeted)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it('should throw Error if find input items have zero props', function(){ | ||
| expect(() => new Query("x").find({})).to.throw(Error); | ||
| }); | ||
| it('should throw Error if find input items have multiple props', function(){ | ||
| expect(() => new Query("x").find({a:"z",b:"y"})).to.throw(Error); | ||
| }); | ||
| it('should throw Error if find is undefined', function(){ | ||
| expect(() => new Query("x").find()).to.throw(Error); | ||
| }); | ||
| it('should not throw Error if no find values have been set', function(){ | ||
| expect(() => `${new Query("x")}`).not.to.throw(Error); | ||
| }); | ||
| it('should throw Error if find is not valid', function(){ | ||
| expect(() => new Query("x").find(123)).to.throw(Error); | ||
| }); | ||
| it('should throw Error if you accidentally pass an undefined', function(){ | ||
| expect(() => new Query("x",undefined)).to.throw(Error); | ||
| }); | ||
| it('should throw Error it is not an input object for alias', function(){ | ||
| expect(() => new Query("x",true)).to.throw(Error); | ||
| }); | ||
| }); | ||
| expect(removeSpaces(expeсted)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it("should work with enums", function() { | ||
| let expected = "inventory(type:missing) { id }"; | ||
| let ChildsToy = { type: Query.Enum("missing"), utils: {} }; | ||
| let ItemQuery = new Query("inventory", ChildsToy); | ||
| ItemQuery.find("id"); | ||
| expect(removeSpaces(expected)).to.equal(removeSpaces(ItemQuery)); | ||
| }); | ||
| it("should throw Error it is not an input object for alias", function() { | ||
| expect(() => new Query("x", true)).to.throw(Error); | ||
| }); | ||
| it("should throw Error if find input items have zero props", function() { | ||
| expect(() => new Query("x").find({})).to.throw(Error); | ||
| }); | ||
| it("should throw Error if find input items have multiple props", function() { | ||
| expect(() => new Query("x").find({ a: "z", b: "y" })).to.throw(Error); | ||
| }); | ||
| it("should throw Error if find is undefined", function() { | ||
| expect(() => new Query("x").find()).to.throw(Error); | ||
| }); | ||
| it("should not throw Error if no find values have been set", function() { | ||
| expect(() => `${new Query("x")}`).not.to.throw(Error); | ||
| }); | ||
| it("should throw Error if find is not valid", function() { | ||
| expect(() => new Query("x").find(123)).to.throw(Error); | ||
| }); | ||
| it("should throw Error if you accidentally pass an undefined", function() { | ||
| expect(() => new Query("x", undefined)).to.throw(Error); | ||
| }); | ||
| it("should throw Error it is not an input object for alias", function() { | ||
| expect(() => new Query("x", true)).to.throw(Error); | ||
| }); | ||
| it("should throw Error if Enum not received value", function() { | ||
| expect(() => new Query.Enum()).to.throw(Error); | ||
| }); | ||
| }); |
23620
8.22%358
12.58%271
7.11%