diff --git a/README.md b/README.md index aca13c7..d890886 100644 --- a/README.md +++ b/README.md @@ -13,42 +13,54 @@ jraph is written in typescript, but can be used in both a VanillaJS and a TypeSc #### Queries ```js - import {jraph, JraphQuery} from 'jraph'; + import {jraph} from 'jraph'; async function getItems(){ - const JraphConfig = new JraphQuery({ - url: "https://csb-xpwq1o2824-alczxhlphl.now.sh/", - options: { + const jql = jraph( + "https://csb-xpwq1o2824-alczxhlphl.now.sh/", + { method: "POST" - }, - query:`{ + } + }); + return ( + jql`{ items{ title info } }` - }); - return jraph(JraphConfig); + ); + } + + async function showStuff(){ + console.log(await getItems()) } ``` #### Mutations ```js - import {jraph, JraphMutation} from 'jraph'; + import {jraph} from 'jraph'; - async function addItems(){ - const JraphConfig = new JraphMutation({ - url: "https://csb-xpwq1o2824-alczxhlphl.now.sh/", - options: { + async function addItem(){ + const jql = jraph( + "https://csb-xpwq1o2824-alczxhlphl.now.sh/", + { method: "POST" - }, - mutation:`{ - addItem(title: "Eggs", info: "Cumberbatch"){ - content - } - }`; + } }); - return jraph(JraphConfig); + return ( + jql` + mutation{ + addItem(title: "egg", info: "salad"){ + title + info + } + }` + ); + } + + async function showStuff(){ + console.log(await addItem()) } ``` diff --git a/index.ts b/index.ts index ca5a6f5..f6cb8c5 100644 --- a/index.ts +++ b/index.ts @@ -1,48 +1,65 @@ -import es6 from 'es6-promise'; -es6.polyfill(); -import 'isomorphic-fetch'; - -interface JraphBasic{ - url: string | Request; - options: any; -} -abstract class JraphQuery implements JraphBasic{ - url: string = ""; - options: any = {}; - query: string = ""; - constructor(args: any){ - Object.assign(this, args); +if(typeof global !== 'undefined'){ + const realFetch = require('node-fetch'); + let fetch = function(url:any, options:any) { + if (/^\/\//.test(url)) { + url = 'https:' + url; + } + // @ts-ignore + return realFetch.call(this, url, options); + }; + // @ts-ignore + if (!global.fetch) { + // @ts-ignore + global.fetch = fetch; + // @ts-ignore + global.Response = realFetch.Response; + // @ts-ignore + global.Headers = realFetch.Headers; + // @ts-ignore + global.Request = realFetch.Request; } } -abstract class JraphMutation implements JraphBasic{ - url: string = ""; - options: any = {}; - mutation: string = ""; - constructor(args: any){ - Object.assign(this, args); - } + +function cleanQueryString(string: string):string{ + //This removes whitespaces and slashes and '\n's + return string.replace(/([\\][n])?([\s])+/g, " "); } -type JraphOptions = JraphQuery | JraphMutation; +function prepareFetchBody(queryString: string):string{ + return JSON.stringify({ query: queryString }); +} -async function jraph(argv: JraphOptions){ - const url : string | Request = argv.url; +function jraph(uri: string, args: object): any{ const headers = { 'Content-Type': 'application/json' }; - const body = JSON.stringify( { query: ( (argv instanceof JraphQuery) ? argv.query : `mutation ${argv.mutation}`).replace(/([\\][n])?([\s])+/g, " ") } ); - //(argv instanceof JraphQuery) ? {query: argv.query} : { query: `mutation ${argv.mutation.replace(/([\\][n])?([\s])+/g, " ")}`} ); - const fetch_options = { + let fetch_options = { + method: "POST", + body: "", + ...args, headers, - body: body, - ...argv.options }; - console.log(body); - const request = await fetch(url, fetch_options).then(res=>res.json()); - return request; + return async (args: string[], ...values:any)=>{ + let queryString = ""; + args.forEach( (string, i) => { + queryString += string + (values[i] || ''); + }); + queryString = cleanQueryString(queryString); + let url = new URL(uri); + if(fetch_options.method && (fetch_options.method == "GET" || fetch_options.method == "get")) { + let searchParams = url.searchParams; + searchParams.append("query", queryString); + }else { + let body = prepareFetchBody(queryString); + fetch_options = {...fetch_options, body}; + } + const request = await fetch(String(url), fetch_options).then(res=>res.text()); + try{ + let json = JSON.parse(request); + return json; + }catch(e){ + return request; + } + }; } -/* -* Some notes for the next version -* - Nevermind, I had notes but they were redundant. -*/ -export default jraph; -export { jraph, JraphOptions, JraphQuery, JraphMutation } \ No newline at end of file + +export { jraph } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 14ccf5b..ae7a695 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "jraph", - "version": "1.1.9", + "version": "2.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -101,17 +101,10 @@ "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, "requires": { "iconv-lite": "~0.4.13" } }, - "es6-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", - "dev": true - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -166,7 +159,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -190,18 +182,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "dev": true, - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "minimatch": { "version": "3.0.4", @@ -256,7 +237,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, "requires": { "encoding": "^0.1.11", "is-stream": "^1.0.1" @@ -286,8 +266,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "supports-color": { "version": "5.4.0", @@ -307,12 +286,7 @@ "typescript": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", - "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==" - }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==", + "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", "dev": true }, "wrappy": { diff --git a/package.json b/package.json index 4452e2c..bf99899 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,16 @@ { "name": "jraph", - "version": "1.1.9", + "version": "2.0.1", "description": "A fetch wrapper for GraphQL", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc", - "version": "tsc && npm publish", - "test": "mocha --recursive \"./test/**/*.js\"" + "pretest": "npm install && npm run build", + "test": "mocha --recursive \"./test/**/*.js\"", + "preversion": "npm test", + "version": "npm run build && git add -A .", + "postversion": "git push && git push --tags && npm publish" }, "keywords": [ "graphql", @@ -17,15 +20,14 @@ "author": "Ian Fabs", "license": "MIT", "repository": { - "url": "https://github.com/ianfabs/jraph.git", + "url": "https://github.com/ianfabs/jraph/tree/gql", "type": "github" }, "dependencies": { - "typescript": "^3.1.6", - "es6-promise": "^4.2.5", - "isomorphic-fetch": "^2.2.1" + "node-fetch": "^1.0.1" }, "devDependencies": { + "typescript": "^3.1.6", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "mocha": "^5.2.0" diff --git a/test/examples/vanilla.mutation.js b/test/examples/vanilla.mutation.js deleted file mode 100644 index 0cf9191..0000000 --- a/test/examples/vanilla.mutation.js +++ /dev/null @@ -1,33 +0,0 @@ -const chai = require("chai"); -var chaiAsPromised = require("chai-as-promised"); -chai.use(chaiAsPromised); -const expect = chai.expect; -let {jraph, JraphMutation} = require('../../dist/index'); - -describe('JraphMutation', () => { - it('should return a json object with property `data`, without errors', () => { - async function addItem(){ - const JraphConfig = new JraphMutation({ - url: "https://csb-xpwq1o2824-alczxhlphl.now.sh/", - options: { - method: "POST" - }, - mutation:`{ - addItem(title: "sample", info: "test item"){ - title - info - } - }` - }); - return jraph(JraphConfig); - } - - let testPromise = new Promise( function(resolve, reject){ - resolve(addItem()); - } ); - return testPromise.then(function(result){ - console.dir(result, {depth: 10}); - expect(result).to.have.property("data"); - }) - }) -}); \ No newline at end of file diff --git a/test/examples/vanilla.query.js b/test/examples/vanilla.query.js deleted file mode 100644 index 30b04e4..0000000 --- a/test/examples/vanilla.query.js +++ /dev/null @@ -1,33 +0,0 @@ -const chai = require("chai"); -var chaiAsPromised = require("chai-as-promised"); -chai.use(chaiAsPromised); -const expect = chai.expect; -let {jraph, JraphQuery} = require('../../dist/index'); - -describe('JraphQuery', () => { - it('should return a json object with property `data`, without errors', () => { - async function getItems(){ - const JraphConfig = new JraphQuery({ - url: "https://csb-xpwq1o2824-alczxhlphl.now.sh/", - options: { - method: "POST" - }, - query:`{ - items{ - title - info - } - }` - }); - return jraph(JraphConfig); - } - - let testPromise = new Promise( function(resolve, reject){ - resolve(getItems()); - } ); - return testPromise.then(function(result){ - console.dir(result, {depth: 10}); - expect(result).to.have.property("data"); - }) - }) -}); \ No newline at end of file diff --git a/test/multiple.test.js b/test/multiple.test.js new file mode 100644 index 0000000..1bbb1e8 --- /dev/null +++ b/test/multiple.test.js @@ -0,0 +1,60 @@ +const chai = require("chai"); +const chaiAsPromised = require("chai-as-promised"); +chai.use(chaiAsPromised); +const expect = chai.expect; + +let {jraph} = require('../dist/index'); + +describe('reusing the jql function', () => { + const jql = jraph( + "https://csb-xpwq1o2824-xravvsjkul.now.sh/", + { + method: "POST" + } + ); + const item = { + title: "Toast", + info: "butter" + } + let results1 = ( + jql` + query{ + items{ + title + } + } + ` + ); + let results2 = ( + jql` + query{ + items{ + info + } + } + ` +); + //=============================================================== + let testPromise1 = new Promise(function (resolve, reject) { + resolve(results1); + }); + let testPromise2 = new Promise(function (resolve, reject) { + resolve(results2); + }); + //=============================================================== + it('should be okay', ()=>{ + return Promise.all([testPromise1, testPromise2]).then(res=>{ + expect(res).to.be.ok; + }) + }) + + it('should return a json object with property `data`', () => { + return Promise.all([testPromise1, testPromise2]).then(res=>{ + expect(res[0]).to.have.property("data"); + console.log(res[0]); + expect(res[1]).to.have.property("data"); + console.log(res[1]); + }) + }) + +}); \ No newline at end of file diff --git a/test/mutation.test.js b/test/mutation.test.js new file mode 100644 index 0000000..522a284 --- /dev/null +++ b/test/mutation.test.js @@ -0,0 +1,47 @@ +const chai = require("chai"); +const chaiAsPromised = require("chai-as-promised"); +chai.use(chaiAsPromised); +const expect = chai.expect; + +let {jraph} = require('../dist/index'); + +describe('jraph mutation', () => { + const jql = jraph( + "https://csb-xpwq1o2824-xravvsjkul.now.sh/", + { + method: "POST" + } + ); + const item = { + title: "Toast", + info: "butter" + } + let results = ( + jql` + mutation{ + addItem(title: "${item.title}", info: "${item.info}"){ + title + info + } + } + ` + ); + //=============================================================== + let testPromise = new Promise(function (resolve, reject) { + resolve(results); + }); + + it('should be okay', ()=>{ + return testPromise.then(function (result) { + expect(result).to.be.ok; + }) + }) + + it('should return a json object with property `data`', () => { + return testPromise.then(function (result) { + console.log(result); + expect(result).to.have.property("data"); + }) + }) + +}); \ No newline at end of file diff --git a/test/query.test.js b/test/query.test.js new file mode 100644 index 0000000..9a9db79 --- /dev/null +++ b/test/query.test.js @@ -0,0 +1,37 @@ +const chai = require("chai"); +const chaiAsPromised = require("chai-as-promised"); +chai.use(chaiAsPromised); +const expect = chai.expect; +let {jraph} = require('../dist/index'); + +describe('jraph query', () => { + let jql = jraph("https://csb-xpwq1o2824-xravvsjkul.now.sh/", { + method: "POST" + }); + + let results = jql` + query{ + items{ + title + } + } + `; + + let testPromise = new Promise(function (resolve, reject) { + resolve(results); + }); + + it('should be ok', ()=>{ + return testPromise.then(function (result) { + expect(result).to.be.ok; + }) + }); + + it('should return a json object with property `data`', () => { + return testPromise.then(function (result) { + console.log(result); + expect(result).to.have.property("data") + }) + }); + +}); \ No newline at end of file diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 522267f..0000000 --- a/test/test.js +++ /dev/null @@ -1,28 +0,0 @@ -const chai = require("chai"); -var chaiAsPromised = require("chai-as-promised"); -chai.use(chaiAsPromised); -const expect = chai.expect; -let {jraph, JraphQuery} = require('../dist/index'); - -describe('jraph()', () => { - it('should return a json object with property `data`', () => { - let options = new JraphQuery({ - url: 'https://csb-8kj415zvx9-yaccgwjitv.now.sh/', - options: { - method: "POST" - }, - query: `{ - posts{ - content - } - }` - }); - - let testPromise = new Promise( function(resolve, reject){ - resolve(jraph(options)); - } ); - return testPromise.then(function(result){ - expect(result).to.have.property("data"); - }) - }) -}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 288adb5..a03fb8a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ + "module": "umd", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "lib": ["es2017", "es7", "es6", "dom"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ @@ -14,7 +14,7 @@ "outDir": "dist", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ - // "removeComments": true, /* Do not emit comments to output. */ + "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */