Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby): use graphiql-explorer #14280

Merged
merged 25 commits into from
May 27, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3c8299d
feat(gatsby): use graphiql-explorer
pieh May 23, 2019
08f6417
chore(docs): add some basic info to the README
DSchau May 23, 2019
ca9f47c
chore: format
pieh May 23, 2019
311485b
Update README.md
DSchau May 23, 2019
f2c10ac
Update packages/gatsby-graphiql-explorer/package.json
pieh May 23, 2019
3c02259
Update packages/gatsby-graphiql-explorer/src/app/webpack.config.js
pieh May 23, 2019
a8fc37f
show welcom to graphiql message with example tailored for gatsby users
pieh May 23, 2019
0cae8b2
store explorer pane state
pieh May 23, 2019
0e3cd30
actually commit the-thing
pieh May 23, 2019
ee4c119
add graphiql e2e tests
pieh May 24, 2019
866c30f
ooops :)
pieh May 24, 2019
7688af9
seems like sometimes there is timing issue when we execute query to f…
pieh May 24, 2019
b5c209b
tmp: record to personal cypress dashboard to investigate
pieh May 24, 2019
fa07a83
doh
pieh May 24, 2019
93f4f4d
use queryString instead of typing
pieh May 24, 2019
d57901f
doh again and again
pieh May 24, 2019
504eb84
revert tmp cypress dashboard integration
pieh May 24, 2019
cd709e8
Merge remote-tracking branch 'origin/master' into graphiql-explorer
pieh May 24, 2019
0069988
revert changes to package.json, fix double spaces
pieh May 24, 2019
44cbf89
Update packages/gatsby-graphiql-explorer/README.md
DSchau May 24, 2019
d6502e7
Update e2e-tests/development-runtime/cypress/integration/functionalit…
pieh May 24, 2019
67acb19
chore: fix issue
DSchau May 24, 2019
0556731
Merge branch 'graphiql-explorer' of github.com:gatsbyjs/gatsby into g…
DSchau May 24, 2019
ea49673
underscoregate
pieh May 24, 2019
b5229d1
you won the battle, not the war, mr underscore
pieh May 24, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/gatsby-graphiql-explorer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*.js
/*.html
yarn.lock
34 changes: 34 additions & 0 deletions packages/gatsby-graphiql-explorer/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
*.un~
yarn.lock
src
flow-typed
coverage
decls
examples
16 changes: 16 additions & 0 deletions packages/gatsby-graphiql-explorer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# gatsby-graphiql-explorer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple and concise 🤷‍♂ I think this will suffice!


A package to extend the default [GraphiQL][graphiql] IDE with useful features for Gatsby users.

_Note: accessible at http://localhost:8000/___graphql after running `gatby develop`_

![Gatsby GraphiQL Explorer](./assets/gatsby-graphiql-explorer.png)

## Features

- Offline support - for when you need to work on your excellent Gatsby app on a plane, train, or elsewhere off the grid
- [GraphiQL Explorer][graphiql-explorer] - an interactive explorer plugin to visually create and interact with the GraphQL schema
- _All_ the expected features you know and love from [GraphiQL][graphiql]

[graphiql]: https://github.com/graphql/graphiql
[graphiql-explorer]: https://github.com/OneGraph/graphiql-explorer
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions packages/gatsby-graphiql-explorer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "gatsby-graphiql-explorer",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this probably need better package name - this is kind of express middleware, but not exactly, because it's not used as express.use(someMiddleware()), instead it is used as graphiqlExplorer(expressApp, params) as I need to have 2 route handlers (one for html and one for bundle)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's easy to bike shed here--I don't really have a problem with the name. We could also scope it, e.g. @gatsbyjs/graphiql which is really what we've done here. We tweaked graphiql with some extra functionality.

"version": "0.0.1",
"description": "Stub description for gatsby-graphiql-explorer",
pieh marked this conversation as resolved.
Show resolved Hide resolved
"main": "index.js",
"scripts": {
"build:app": "webpack --config ./src/app/webpack.config.js",
"build:babel": "babel src/index.js --out-dir . --ignore **/__tests__",
"build": "npm-run-all --parallel build:app build:babel",
"prepare": "cross-env NODE_ENV=production npm run build",
"test": "echo \"Error: no test specified\" && exit 1",
"watch:app": "npm run build:app -- --watch",
"watch:babel": "npm run build:babel -- --watch",
"watch": "npm-run-all --parallel watch:app watch:babel"
},
"keywords": [
"gatsby"
],
"author": "",
"bugs": {
"url": "https://github.com/gatsbyjs/gatsby/issues"
},
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-graphiql-explorer#readme",
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby.git"
},
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.0.0",
"graphiql": "^0.13.0",
"graphiql-explorer": "^0.3.7",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"whatwg-fetch": "^3.0.0"
},
"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.4.1",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"babel-preset-gatsby-package": "^0.1.4",
"cross-env": "^5.0.5",
"css-loader": "^1.0.0",
"html-webpack-plugin": "^3.2.0",
"npm-run-all": "4.1.5",
"style-loader": "^0.21.0",
"webpack-cli": "^3.3.2"
}
}
19 changes: 19 additions & 0 deletions packages/gatsby-graphiql-explorer/src/app/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}

.graphiql-container {
height: 100vh;
width: 100vw;
}
159 changes: 159 additions & 0 deletions packages/gatsby-graphiql-explorer/src/app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import React from "react"
import ReactDOM from "react-dom"

import GraphiQL from "graphiql"
import GraphiQLExplorer from "graphiql-explorer"
import { getIntrospectionQuery, buildClientSchema } from "graphql"

import "whatwg-fetch"

import "graphiql/graphiql.css"
import "./app.css"

const parameters = {}
window.location.search
.substr(1)
.split(`&`)
.forEach(function(entry) {
var eq = entry.indexOf(`=`)
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] = decodeURIComponent(
entry.slice(eq + 1)
)
}
})
// Produce a Location query string from a parameter object.
function locationQuery(params) {
return (
`?` +
Object.keys(params)
.filter(function(key) {
return Boolean(params[key])
})
.map(function(key) {
return encodeURIComponent(key) + `=` + encodeURIComponent(params[key])
})
.join(`&`)
)
}

// Derive a fetch URL from the current URL, sans the GraphQL parameters.
const graphqlParamNames = {
query: true,
variables: true,
operationName: true,
}
const otherParams = {}
for (var k in parameters) {
if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
otherParams[k] = parameters[k]
}
}
const fetchURL = locationQuery(otherParams)

function graphQLFetcher(graphQLParams) {
return fetch(fetchURL, {
method: `post`,
headers: {
Accept: `application/json`,
"Content-Type": `application/json`,
},
body: JSON.stringify(graphQLParams),
credentials: `include`,
}).then(function(response) {
return response.json()
})
}

// When the query and variables string is edited, update the URL bar so
// that it can be easily shared.
function onEditVariables(newVariables) {
parameters.variables = newVariables
updateURL()
}
function onEditOperationName(newOperationName) {
parameters.operationName = newOperationName
updateURL()
}
function updateURL() {
history.replaceState(null, null, locationQuery(parameters))
}

// We control query, so we need to recreate initial query text that show up
// on visiting graphiql - in order it will be
// - query from query string (if set)
// - query stored in localStorage (which graphiql set when closing window)
// - default empty query
const DEFAULT_QUERY =
parameters.query ||
(window.localStorage && window.localStorage.getItem(`graphiql:query`)) ||
`{

}`
pieh marked this conversation as resolved.
Show resolved Hide resolved

class App extends React.Component {
state = { schema: null, query: DEFAULT_QUERY, explorerIsOpen: true }
pieh marked this conversation as resolved.
Show resolved Hide resolved

componentDidMount() {
graphQLFetcher({
query: getIntrospectionQuery(),
}).then(result => {
this.setState({ schema: buildClientSchema(result.data) })
})
}

_handleEditQuery = query => {
parameters.query = query
updateURL()
this.setState({ query })
}

_handleToggleExplorer = () => {
this.setState({ explorerIsOpen: !this.state.explorerIsOpen })
}

render() {
const { query, schema } = this.state

return (
<React.Fragment>
<GraphiQLExplorer
schema={schema}
query={query}
onEdit={this._handleEditQuery}
explorerIsOpen={this.state.explorerIsOpen}
onToggleExplorer={this._handleToggleExplorer}
/>
<GraphiQL
ref={ref => (this._graphiql = ref)}
fetcher={graphQLFetcher}
schema={schema}
query={query}
onEditQuery={this._handleEditQuery}
onEditVariables={onEditVariables}
onEditOperationName={onEditOperationName}
>
<GraphiQL.Toolbar>
<GraphiQL.Button
onClick={() => this._graphiql.handlePrettifyQuery()}
label="Prettify"
title="Prettify Query (Shift-Ctrl-P)"
/>
<GraphiQL.Button
onClick={() => this._graphiql.handleToggleHistory()}
label="History"
title="Show History"
/>
<GraphiQL.Button
onClick={this._handleToggleExplorer}
label="Explorer"
title="Toggle Explorer"
/>
</GraphiQL.Toolbar>
</GraphiQL>
</React.Fragment>
)
}
}

ReactDOM.render(<App />, document.getElementById(`root`))
17 changes: 17 additions & 0 deletions packages/gatsby-graphiql-explorer/src/app/index.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>GraphiQL</title>
<meta name="robots" content="noindex" />
<meta name="referrer" content="origin" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div id="root" class="graphiql-container">Loading...</div>
<script
type="text/javascript"
src="/___graphql/<%= htmlWebpackPlugin.files.chunks.main.entry %>?<%= htmlWebpackPlugin.files.chunks.main.hash %>"
pieh marked this conversation as resolved.
Show resolved Hide resolved
></script>
</body>
</html>
72 changes: 72 additions & 0 deletions packages/gatsby-graphiql-explorer/src/app/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const path = require(`path`)
const HtmlWebpackPlugin = require(`html-webpack-plugin`)
const webpack = require(`webpack`)

const mode = `production`
module.exports = {
entry: path.join(__dirname, `app.js`),
mode,
output: {
path: path.join(__dirname, `..`, `..`),
filename: `./app.js`,
},
devtool: false,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: `babel-loader`,
options: {
presets: [
[
`@babel/preset-env`,
{
corejs: 2,
loose: true,
modules: `commonjs`,
useBuiltIns: `usage`,
targets: [`>0.25%`, `not dead`],
},
],
[
`@babel/preset-react`,
{
useBuiltIns: true,
pragma: `React.createElement`,
development: false,
},
],
],
plugins: [
[
`@babel/plugin-proposal-class-properties`,
{
loose: true,
},
],
],
},
},
},
{
test: /\.css$/,
use: [{ loader: `style-loader` }, { loader: `css-loader` }],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, `index.ejs`),
filename: `index.html`,
inject: false,
}),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(`${mode}`),
pieh marked this conversation as resolved.
Show resolved Hide resolved
}),
],
stats: {
warnings: false,
},
}
13 changes: 13 additions & 0 deletions packages/gatsby-graphiql-explorer/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const path = require(`path`)

module.exports = (expressApp, { graphqlEndpoint }) => {
const bundleUrlHandler = path.posix.join(graphqlEndpoint, `app.js`)
expressApp.get(bundleUrlHandler, (req, res) => {
res.set(`Cache-Control`, `public, max-age=31557600`)
res.sendFile(path.join(__dirname, `app.js`))
})

expressApp.get(graphqlEndpoint, (req, res) => {
res.sendFile(path.join(__dirname, `index.html`))
})
}
Loading