diff --git a/package.json b/package.json index 0e5958788c..8eab85f4d0 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "prepack": "./scripts/build" }, "dependencies": { - "@types/graphql": "^0.13.4", + "@types/graphql": "^14.0.3", "@types/jsonwebtoken": "<7.2.1", "@types/koa": "^2.0.44", "@types/pg": "^7.4.10", @@ -54,7 +54,7 @@ "css-loader": "1.0.0", "debug": "^2.3.3", "finalhandler": "^1.0.6", - "graphql": "^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0", + "graphql": "^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.2", "http-errors": "^1.5.1", "jsonwebtoken": "^8.0.0", "lru-cache": ">=4 <5", @@ -62,7 +62,7 @@ "pg": ">=6.1.0 <8", "pg-connection-string": "^0.1.3", "pg-sql2": "^2.2.1", - "postgraphile-core": "4.1.0-alpha.1", + "postgraphile-core": "4.1.0-rc.0", "tslib": "^1.5.0" }, "devDependencies": { @@ -85,7 +85,6 @@ "connect": "^3.5.0", "css-loader": "1.0.0", "express": "^4.14.0", - "graphiql": "^0.11.11", "html-webpack-inline-source-plugin": "^0.0.10", "html-webpack-plugin": "^3.2.0", "jest": "^18.1.0", @@ -94,9 +93,6 @@ "nodemon": "^1.11.0", "pg-minify": "~0.5.3", "prettier": "^1.13.7", - "react": "^15.3.2", - "react-dom": "^15.3.2", - "react-scripts": "^1.1.1", "source-map-support": "^0.4.6", "style-loader": "^0.23.0", "supertest": "^2.0.1", @@ -110,23 +106,14 @@ "transform": { ".*": "/resources/jest-preprocessor.js" }, - "moduleFileExtensions": [ - "ts", - "js" - ], - "setupFiles": [ - "/resources/jest-setup.js" - ], + "moduleFileExtensions": ["ts", "js"], + "setupFiles": ["/resources/jest-setup.js"], "browser": false, "testEnvironment": "node", - "testPathDirs": [ - "/src" - ], + "testPathDirs": ["/src"], "testRegex": "/__tests__/[^.]+-test.(t|j)s$" }, - "files": [ - "build" - ], + "files": ["build"], "engines": { "node": ">=8.6" } diff --git a/postgraphiql/package.json b/postgraphiql/package.json index 992754f5bb..a98a1b4ba0 100644 --- a/postgraphiql/package.json +++ b/postgraphiql/package.json @@ -2,5 +2,12 @@ "private": true, "name": "postgraphile-graphiql", "version": "1.0.0", - "homepage": "https://graphile.org/postgraphile/" + "homepage": "https://graphile.org/postgraphile/", + "dependencies": { + "graphiql": "^0.12.0", + "graphql": "0.13.x", + "react": "^15.3.2", + "react-dom": "^15.3.2", + "react-scripts": "^1.1.1" + } } diff --git a/postgraphiql/public/index.html b/postgraphiql/public/index.html index 30c6e8307d..e17faf410a 100644 --- a/postgraphiql/public/index.html +++ b/postgraphiql/public/index.html @@ -5,6 +5,8 @@ PostGraphile GraphiQL + +
diff --git a/postgraphiql/src/components/PostGraphiQL.js b/postgraphiql/src/components/PostGraphiQL.js index b8ee011828..a01431b960 100644 --- a/postgraphiql/src/components/PostGraphiQL.js +++ b/postgraphiql/src/components/PostGraphiQL.js @@ -1,14 +1,25 @@ import React from 'react'; import GraphiQL from 'graphiql'; +import './postgraphiql.css'; import { buildClientSchema, introspectionQuery, isType, GraphQLObjectType } from 'graphql'; const { POSTGRAPHILE_CONFIG = { graphqlUrl: 'http://localhost:5000/graphql', streamUrl: 'http://localhost:5000/_postgraphile/stream', + enhanceGraphiql: true, }, } = window; +const isValidJSON = json => { + try { + JSON.parse(json); + return true; + } catch (e) { + return false; + } +}; + /** * The standard GraphiQL interface wrapped with some PostGraphile extensions. * Including a JWT setter and live schema udpate capabilities. @@ -18,6 +29,9 @@ class PostGraphiQL extends React.Component { // Our GraphQL schema which GraphiQL will use to do its intelligence // stuffs. schema: null, + showHeaderEditor: true, // REMOVE ME + headersText: '{\n"Authorization": null\n}\n', + headersTextValid: true, }; componentDidMount() { @@ -73,7 +87,19 @@ class PostGraphiQL extends React.Component { * Executes a GraphQL query with some extra information then the standard * parameters. Namely a JWT which may be added as an `Authorization` header. */ - async executeQuery(graphQLParams, { jwtToken } = {}) { + async executeQuery(graphQLParams) { + const { headersText } = this.state; + let extraHeaders; + try { + extraHeaders = JSON.parse(headersText); + for (const k in extraHeaders) { + if (extraHeaders[k] == null) { + delete extraHeaders[k]; + } + } + } catch (e) { + // Do nothing + } const response = await fetch(POSTGRAPHILE_CONFIG.graphqlUrl, { method: 'POST', headers: Object.assign( @@ -81,11 +107,7 @@ class PostGraphiQL extends React.Component { Accept: 'application/json', 'Content-Type': 'application/json', }, - jwtToken - ? { - Authorization: `Bearer ${jwtToken}`, - } - : {}, + extraHeaders, ), credentials: 'same-origin', body: JSON.stringify(graphQLParams), @@ -221,16 +243,137 @@ class PostGraphiQL extends React.Component { } } + getQueryEditor = () => { + return this.graphiql.getQueryEditor(); + }; + + handlePrettifyQuery = () => { + const editor = this.getQueryEditor(); + if (typeof window.prettier !== 'undefined' && typeof window.prettierPlugins !== 'undefined') { + // TODO: window.prettier.formatWithCursor + editor.setValue( + window.prettier.format(editor.getValue(), { + parser: 'graphql', + plugins: window.prettierPlugins, + }), + ); + } else { + return this.graphiql.handlePrettifyQuery(); + } + }; + + handleToggleHistory = e => { + this.graphiql.handleToggleHistory(e); + }; + + handlePostGraphile = () => { + window.open('https://graphile.org/postgraphile/', 'postgraphile'); + }; + + handleDonate = () => { + window.open('https://graphile.org/donate', 'postgraphile'); + }; + + handleToggleHeaders = () => { + this.setState({ showHeaderEditor: !this.state.showHeaderEditor }); + }; + render() { const { schema } = this.state; - return ( - (this.graphiql = ref)} - schema={schema} - fetcher={params => this.executeQuery(params)} - /> - ); + const sharedProps = { + ref: ref => { + this.graphiql = ref; + }, + schema: schema, + fetcher: params => this.executeQuery(params), + }; + if (!POSTGRAPHILE_CONFIG.enhanceGraphiql) { + return ; + } else { + return ( +
+ + + PostGraph + i + QL + + + + + + + + + + + this.setState({ + headersText: e.target.value, + headersTextValid: isValidJSON(e.target.value), + }) + } + > +
+ {'\u2715'} +
+
+
+ ); + } } } +function EditHeaders({ children, open, value, onChange, valid }) { + return ( +
+
+
+
+
Edit Headers
+
{children}
+
+
+