{
111 | const res = [];
112 | for (let i = 0; i < arr.length; i++) {
113 | const x = fn(arr[i], i);
114 | if (Array.isArray(x)) {
115 | res.push(...x);
116 | } else {
117 | res.push(x);
118 | }
119 | }
120 | return res;
121 | }
122 |
--------------------------------------------------------------------------------
/assets/app/build/static/media/index.js.02c24280.flow:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the license found in the
6 | * LICENSE file in the root directory of this source tree.
7 | *
8 | * @flow
9 | */
10 |
11 | export {
12 | getDefinitionState,
13 | getFieldDef,
14 | forEachState,
15 | objectValues,
16 | hintList,
17 | } from './autocompleteUtils';
18 |
19 | export {getAutocompleteSuggestions} from './getAutocompleteSuggestions';
20 |
21 | export {
22 | LANGUAGE,
23 | getDefinitionQueryResultForFragmentSpread,
24 | getDefinitionQueryResultForDefinitionNode,
25 | } from './getDefinition';
26 |
27 | export {getDiagnostics, validateQuery} from './getDiagnostics';
28 | export {getOutline} from './getOutline';
29 | export {getHoverInformation} from './getHoverInformation';
30 |
31 | export {GraphQLLanguageService} from './GraphQLLanguageService';
32 |
--------------------------------------------------------------------------------
/assets/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wp-graphiql",
3 | "description": "This plugin provides the GraphiQL IDE as an admin page in WordPress, allowing the GraphQL WPGraphQL schema to be browsed from within WordPress.",
4 | "author": "WPGraphQL, Digital First Media, Jason Bahl",
5 | "homepage": "http://wpgraphql.com",
6 | "bugs": {
7 | "url": "https://github.com/wp-graphql/wp-graphiql/issues"
8 | },
9 | "version": "1.0.0",
10 | "private": true,
11 | "devDependencies": {
12 | "react-scripts": "^1.1.4"
13 | },
14 | "dependencies": {
15 | "graphiql": "^0.13.2",
16 | "graphiql-code-exporter": "^2.0.5",
17 | "graphiql-explorer": "^0.4.3",
18 | "graphql": "^14.4.2",
19 | "react": "^16.8.6",
20 | "react-dom": "^16.8.6",
21 | "whatwg-fetch": "^3.0.0"
22 | },
23 | "scripts": {
24 | "start": "react-scripts start",
25 | "build": "react-scripts build",
26 | "test": "react-scripts test --env=jsdom",
27 | "eject": "react-scripts eject"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/assets/app/public/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/wp-graphiql/82518eafa5f383c5929111431e4a641caace3b57/assets/app/public/index.html
--------------------------------------------------------------------------------
/assets/app/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import GraphiQL from "graphiql"
4 | import GraphiQLExplorer from "graphiql-explorer"
5 | import CodeExporter from "graphiql-code-exporter"
6 | import {getIntrospectionQuery, buildClientSchema, parse, print} from "graphql"
7 | import "whatwg-fetch"
8 | import snippets from "./snippets"
9 |
10 | /**
11 | * Style the app
12 | */
13 | import 'graphiql/graphiql.css';
14 | import './app.css';
15 | import "graphiql-code-exporter/CodeExporter.css"
16 |
17 | const parameters = {}
18 |
19 | window.location.search
20 | .substr(1)
21 | .split(`&`)
22 | .forEach(function (entry) {
23 | var eq = entry.indexOf(`=`)
24 | if (eq >= 0) {
25 | parameters[decodeURIComponent(entry.slice(0, eq))] = decodeURIComponent(entry.slice(eq + 1).replace(/\+/g, '%20'))
26 | }
27 | })
28 |
29 | // Produce a Location query string from a parameter object.
30 | function locationQuery(params) {
31 | return (
32 | 'admin.php' +
33 | '?' +
34 | Object.keys(params)
35 | .map(function (key) {
36 | return encodeURIComponent(key) + `=` + encodeURIComponent(params[key])
37 | })
38 | .join(`&`)
39 | )
40 | }
41 |
42 | // Derive a fetch URL from the current URL, sans the GraphQL parameters.
43 | const graphqlParamNames = {
44 | query: true,
45 | variables: true,
46 | operationName: true,
47 | explorerIsOpen: true,
48 | }
49 |
50 | const otherParams = {}
51 |
52 | for (var k in parameters) {
53 | if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
54 | otherParams[k] = parameters[k]
55 | }
56 | }
57 |
58 | let nonce = (window.wpGraphiQLSettings && window.wpGraphiQLSettings.nonce) ? window.wpGraphiQLSettings.nonce : null;
59 | let endpoint = (window.wpGraphiQLSettings && window.wpGraphiQLSettings.graphqlEndpoint) ? window.wpGraphiQLSettings.graphqlEndpoint : window.location.origin;
60 |
61 |
62 | function graphQLFetcher(graphQLParams) {
63 | return fetch(endpoint, {
64 | method: `post`,
65 | headers: {
66 | Accept: `application/json`,
67 | "Content-Type": `application/json`,
68 | 'X-WP-Nonce': nonce
69 | },
70 | body: JSON.stringify(graphQLParams),
71 | credentials: `include`,
72 | }).then(function (response) {
73 | return response.json()
74 | })
75 | }
76 |
77 | // When the query and variables string is edited, update the URL bar so
78 | // that it can be easily shared.
79 | function onEditVariables(newVariables) {
80 | parameters.variables = newVariables
81 | updateURL()
82 | }
83 |
84 | function onEditOperationName(newOperationName) {
85 | parameters.operationName = newOperationName
86 | updateURL()
87 | }
88 |
89 | function updateURL() {
90 | // eslint-disable-next-line
91 | history.replaceState(null, null, locationQuery(parameters))
92 | }
93 |
94 | // We control query, so we need to recreate initial query text that show up
95 | // on visiting graphiql - in order it will be
96 | // - query from query string (if set)
97 | // - query stored in localStorage (which graphiql set when closing window)
98 | // - default empty query
99 | const DEFAULT_QUERY =
100 | parameters.query && print( parse( parameters.query ) ) ||
101 | (window.localStorage && window.localStorage.getItem(`graphiql:query`)) ||
102 | null
103 |
104 | const QUERY_EXAMPLE_SITEMETADATA_TITLE = `# {
105 | # generalSettings {
106 | # url
107 | # title
108 | # }
109 | # }`
110 |
111 | const QUERY_EXAMPLE_FALLBACK = `# {
112 | # posts {
113 | # nodes {
114 | # title
115 | # uri
116 | # }
117 | # }
118 | # }`
119 |
120 | function generateDefaultFallbackQuery(queryExample) {
121 | return `# Welcome to GraphiQL
122 | #
123 | # GraphiQL is an in-browser tool for writing, validating, and
124 | # testing GraphQL queries.
125 | #
126 | # Type queries into this side of the screen, and you will see intelligent
127 | # typeaheads aware of the current GraphQL type schema and live syntax and
128 | # validation errors highlighted within the text.
129 | #
130 | # GraphQL queries typically start with a "{" character. Lines that starts
131 | # with a # are ignored.
132 | #
133 | # An example GraphQL query might look like:
134 | #
135 | ${queryExample}
136 | #
137 | # Keyboard shortcuts:
138 | #
139 | # Prettify Query: Shift-Ctrl-P (or press the prettify button above)
140 | #
141 | # Merge Query: Shift-Ctrl-M (or press the merge button above)
142 | #
143 | # Run Query: Ctrl-Enter (or press the play button above)
144 | #
145 | # Auto Complete: Ctrl-Space (or just start typing)
146 | #
147 | `
148 | }
149 |
150 | const storedExplorerPaneState =
151 | typeof parameters.explorerIsOpen !== `undefined`
152 | ? parameters.explorerIsOpen === `false`
153 | ? false
154 | : true
155 | : window.localStorage
156 | ? window.localStorage.getItem(`graphiql:graphiqlExplorerOpen`) !== `false`
157 | : true
158 |
159 | const storedCodeExporterPaneState =
160 | typeof parameters.codeExporterIsOpen !== `undefined`
161 | ? parameters.codeExporterIsOpen === `false`
162 | ? false
163 | : true
164 | : window.localStorage
165 | ? window.localStorage.getItem(`graphiql:graphiqlCodeExporterOpen`) ===
166 | `true`
167 | : false
168 |
169 | class App extends React.Component {
170 | state = {
171 | schema: null,
172 | query: DEFAULT_QUERY,
173 | explorerIsOpen: storedExplorerPaneState,
174 | codeExporterIsOpen: storedCodeExporterPaneState,
175 | }
176 |
177 | componentDidMount() {
178 | graphQLFetcher({
179 | query: getIntrospectionQuery(),
180 | }).then(result => {
181 | const newState = {schema: buildClientSchema(result.data)}
182 |
183 | if (this.state.query === null) {
184 | try {
185 | const siteMetadataType = result.data.__schema.types.find(
186 | type => type.name === `SiteSiteMetadata` && type.kind === `OBJECT`
187 | )
188 | if (siteMetadataType) {
189 | const titleField = siteMetadataType.fields.find(
190 | field =>
191 | field.name === `title` &&
192 | field.type &&
193 | field.type.kind === `SCALAR` &&
194 | field.type.name === `String`
195 | )
196 |
197 | if (titleField) {
198 | newState.query = generateDefaultFallbackQuery(
199 | QUERY_EXAMPLE_SITEMETADATA_TITLE
200 | )
201 | }
202 | }
203 | // eslint-disable-next-line no-empty
204 | } catch (e) {
205 | console.error(e)
206 | }
207 | if (!newState.query) {
208 | newState.query = generateDefaultFallbackQuery(QUERY_EXAMPLE_FALLBACK)
209 | }
210 | }
211 |
212 | this.setState(newState)
213 | })
214 |
215 | const editor = this._graphiql.getQueryEditor()
216 | editor.setOption(`extraKeys`, {
217 | ...(editor.options.extraKeys || {}),
218 | "Shift-Alt-LeftClick": this._handleInspectOperation,
219 | })
220 | }
221 |
222 | _handleInspectOperation = (cm, mousePos) => {
223 | const parsedQuery = parse(this.state.query || ``)
224 |
225 | if (!parsedQuery) {
226 | console.error(`Couldn't parse query document`)
227 | return null
228 | }
229 |
230 | const token = cm.getTokenAt(mousePos)
231 | const start = {line: mousePos.line, ch: token.start}
232 | const end = {line: mousePos.line, ch: token.end}
233 | const relevantMousePos = {
234 | start: cm.indexFromPos(start),
235 | end: cm.indexFromPos(end),
236 | }
237 |
238 | const position = relevantMousePos
239 |
240 | const def = parsedQuery.definitions.find(definition => {
241 | if (!definition.loc) {
242 | console.log(`Missing location information for definition`)
243 | return false
244 | }
245 |
246 | const {start, end} = definition.loc
247 | return start <= position.start && end >= position.end
248 | })
249 |
250 | if (!def) {
251 | console.error(`Unable to find definition corresponding to mouse position`)
252 | return null
253 | }
254 |
255 | const operationKind =
256 | def.kind === `OperationDefinition`
257 | ? def.operation
258 | : def.kind === `FragmentDefinition`
259 | ? `fragment`
260 | : `unknown`
261 |
262 | const operationName =
263 | def.kind === `OperationDefinition` && !!def.name
264 | ? def.name.value
265 | : def.kind === `FragmentDefinition` && !!def.name
266 | ? def.name.value
267 | : `unknown`
268 |
269 | const selector = `.graphiql-explorer-root #${operationKind}-${operationName}`
270 |
271 | const el = document.querySelector(selector)
272 | if (el) {
273 | el.scrollIntoView()
274 | return true
275 | }
276 |
277 | return false
278 | }
279 |
280 | _handleEditQuery = query => {
281 | parameters.query = query
282 | updateURL()
283 | this.setState({query})
284 | }
285 |
286 | _handleToggleExplorer = () => {
287 | const newExplorerIsOpen = !this.state.explorerIsOpen
288 | if (window.localStorage) {
289 | window.localStorage.setItem(
290 | `graphiql:graphiqlExplorerOpen`,
291 | newExplorerIsOpen
292 | )
293 | }
294 | parameters.explorerIsOpen = newExplorerIsOpen
295 | updateURL()
296 | this.setState({explorerIsOpen: newExplorerIsOpen})
297 | }
298 |
299 | _handleToggleExporter = () => {
300 | const newCodeExporterIsOpen = !this.state.codeExporterIsOpen
301 | if (window.localStorage) {
302 | window.localStorage.setItem(
303 | `graphiql:graphiqlCodeExporterOpen`,
304 | newCodeExporterIsOpen
305 | )
306 | }
307 | parameters.codeExporterIsOpen = newCodeExporterIsOpen
308 | updateURL()
309 | this.setState({ codeExporterIsOpen: newCodeExporterIsOpen })
310 | }
311 |
312 |
313 |
314 | render() {
315 | const { query, schema, codeExporterIsOpen } = this.state
316 | const codeExporter = codeExporterIsOpen ? (
317 |
323 | ) : null
324 |
325 | return (
326 |
327 |
334 | this._graphiql.handleRunQuery(operationName)
335 | }
336 | />
337 | (this._graphiql = ref)}
339 | fetcher={graphQLFetcher}
340 | schema={schema}
341 | query={query}
342 | onEditQuery={this._handleEditQuery}
343 | onEditVariables={onEditVariables}
344 | onEditOperationName={onEditOperationName}
345 | >
346 |
347 | this._graphiql.handlePrettifyQuery()}
349 | label="Prettify"
350 | title="Prettify Query (Shift-Ctrl-P)"
351 | />
352 | this._graphiql.handleToggleHistory()}
354 | label="History"
355 | title="Show History"
356 | />
357 |
362 |
367 |
368 |
369 | {codeExporter}
370 |
371 | );
372 | }
373 | }
374 |
375 | export default App;
376 |
--------------------------------------------------------------------------------
/assets/app/src/app.css:
--------------------------------------------------------------------------------
1 | #wp-graphiql {
2 | display: flex;
3 | flex: 1;
4 | }
5 |
6 | #wp-graphiql .spinner{
7 | visibility: visible;
8 | background: none;
9 | }
10 |
--------------------------------------------------------------------------------
/assets/app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(, document.getElementById('wp-graphiql'));
6 |
--------------------------------------------------------------------------------
/assets/app/src/snippets.js:
--------------------------------------------------------------------------------
1 | const getQuery = (arg, spaceCount) => {
2 | const { operationDataList } = arg
3 | const { query } = operationDataList[0]
4 | const anonymousQuery = query.replace(/query\s.+{/gim, `{`)
5 | return (
6 | ` `.repeat(spaceCount) +
7 | anonymousQuery.replace(/\n/g, `\n` + ` `.repeat(spaceCount))
8 | )
9 | }
10 |
11 | const pageQuery = {
12 | name: `Page query`,
13 | language: `Gatsby`,
14 | codeMirrorMode: `jsx`,
15 | options: [],
16 | generate: arg => `import React from "react"
17 | import { graphql } from "gatsby"
18 |
19 | const ComponentName = ({ data }) => {JSON.stringify(data, null, 4)}
20 |
21 | export const query = graphql\`
22 | ${getQuery(arg, 2)}
23 | \`
24 |
25 | export default ComponentName
26 |
27 | `,
28 | }
29 |
30 | const staticHook = {
31 | name: `StaticQuery hook`,
32 | language: `Gatsby`,
33 | codeMirrorMode: `jsx`,
34 | options: [],
35 | generate: arg => `import React from "react"
36 | import { useStaticQuery, graphql } from "gatsby"
37 |
38 | const ComponentName = () => {
39 | const data = useStaticQuery(graphql\`
40 | ${getQuery(arg, 4)}
41 | \`)
42 | return {JSON.stringify(data, null, 4)}
43 | }
44 |
45 | export default ComponentName
46 |
47 | `,
48 | }
49 |
50 | const staticQuery = {
51 | name: `StaticQuery`,
52 | language: `Gatsby`,
53 | codeMirrorMode: `jsx`,
54 | options: [],
55 | generate: arg => `import React from "react"
56 | import { StaticQuery, graphql } from "gatsby"
57 |
58 | const ComponentName = () => (
59 | {JSON.stringify(data, null, 4)}
}
64 | >
65 | )
66 |
67 | export default ComponentName
68 |
69 | `,
70 | }
71 |
72 | export default [pageQuery, staticHook, staticQuery]
73 |
--------------------------------------------------------------------------------
/assets/img/wp-graphiql-wp-admin.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/wp-graphiql/82518eafa5f383c5929111431e4a641caace3b57/assets/img/wp-graphiql-wp-admin.gif
--------------------------------------------------------------------------------
/assets/js/wp-graphiql-helpers.js:
--------------------------------------------------------------------------------
1 | $j=jQuery.noConflict();
2 |
3 | $j(document).ready(function(){
4 |
5 | $j('.update-nag').hide();
6 | $j('.error').hide();
7 |
8 | $defaultHeight = '500px';
9 | $wpWrapHeight = $j('#wpwrap').height();
10 | $adminBarHeight = $j('#wpadminbar').height();
11 | $footerHeight = $j('#wpfooter').height();
12 | $height = ( $wpWrapHeight - $adminBarHeight - $footerHeight - 65 );
13 | $graphiqlHeight = ( $defaultHeight < $height ) ? $defaultHeight : $height;
14 | $j('#wp-graphiql').css( 'height', $graphiqlHeight );
15 | });
--------------------------------------------------------------------------------
/bin/install-wp-tests.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ $# -lt 3 ]; then
4 | echo "usage: $0 [db-host] [wp-version] [skip-database-creation]"
5 | exit 1
6 | fi
7 |
8 | DB_NAME=$1
9 | DB_USER=$2
10 | DB_PASS=$3
11 | DB_HOST=${4-localhost}
12 | WP_VERSION=${5-latest}
13 | SKIP_DB_CREATE=${6-false}
14 |
15 | WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
16 | WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
17 |
18 | download() {
19 | if [ `which curl` ]; then
20 | curl -s "$1" > "$2";
21 | elif [ `which wget` ]; then
22 | wget -nv -O "$2" "$1"
23 | fi
24 | }
25 |
26 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
27 | WP_TESTS_TAG="tags/$WP_VERSION"
28 | elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
29 | WP_TESTS_TAG="trunk"
30 | else
31 | # http serves a single offer, whereas https serves multiple. we only want one
32 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
33 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
34 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
35 | if [[ -z "$LATEST_VERSION" ]]; then
36 | echo "Latest WordPress version could not be found"
37 | exit 1
38 | fi
39 | WP_TESTS_TAG="tags/$LATEST_VERSION"
40 | fi
41 |
42 | set -ex
43 |
44 | install_wp() {
45 |
46 | if [ -d $WP_CORE_DIR ]; then
47 | return;
48 | fi
49 |
50 | mkdir -p $WP_CORE_DIR
51 |
52 | if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
53 | mkdir -p /tmp/wordpress-nightly
54 | download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
55 | unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
56 | mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
57 | else
58 | if [ $WP_VERSION == 'latest' ]; then
59 | local ARCHIVE_NAME='latest'
60 | else
61 | local ARCHIVE_NAME="wordpress-$WP_VERSION"
62 | fi
63 | download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
64 | tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
65 | fi
66 |
67 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
68 | }
69 |
70 | install_test_suite() {
71 | # portable in-place argument for both GNU sed and Mac OSX sed
72 | if [[ $(uname -s) == 'Darwin' ]]; then
73 | local ioption='-i .bak'
74 | else
75 | local ioption='-i'
76 | fi
77 |
78 | # set up testing suite if it doesn't yet exist
79 | if [ ! -d $WP_TESTS_DIR ]; then
80 | # set up testing suite
81 | mkdir -p $WP_TESTS_DIR
82 | svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
83 | svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
84 | fi
85 |
86 | if [ ! -f wp-tests-config.php ]; then
87 | download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
88 | # remove all forward slashes in the end
89 | WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
90 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
91 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
92 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
93 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
94 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
95 | fi
96 |
97 | }
98 |
99 | install_db() {
100 |
101 | if [ ${SKIP_DB_CREATE} = "true" ]; then
102 | return 0
103 | fi
104 |
105 | # parse DB_HOST for port or socket references
106 | local PARTS=(${DB_HOST//\:/ })
107 | local DB_HOSTNAME=${PARTS[0]};
108 | local DB_SOCK_OR_PORT=${PARTS[1]};
109 | local EXTRA=""
110 |
111 | if ! [ -z $DB_HOSTNAME ] ; then
112 | if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
113 | EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
114 | elif ! [ -z $DB_SOCK_OR_PORT ] ; then
115 | EXTRA=" --socket=$DB_SOCK_OR_PORT"
116 | elif ! [ -z $DB_HOSTNAME ] ; then
117 | EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
118 | fi
119 | fi
120 |
121 | # create database
122 | mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
123 | }
124 |
125 | install_wp
126 | install_test_suite
127 | install_db
128 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wp-graphql/wp-graphiql",
3 | "description": "GraphiQL IDE in the WP-Admin. Works with the WPGraphQL plugin. https://github.com/wp-graphql/wp-graphql",
4 | "type": "wordpress-plugin",
5 | "license": "GPL-3.0+",
6 | "version": "1.0.1",
7 | "authors": [
8 | {
9 | "name": "Jason Bahl",
10 | "email": "jasonbahl@mac.com"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "wp-graphiql",
4 | "description": "This plugin provides the GraphiQL IDE as an admin page in WordPress, allowing the GraphQL WPGraphQL schema to be browsed from within WordPress.",
5 | "author": "WPGraphQL, Digital First Media, Jason Bahl",
6 | "homepage": "http://wpgraphql.com",
7 | "bugs": {
8 | "url": "https://github.com/wp-graphql/wp-graphiql/issues"
9 | },
10 | "version": "1.0.0",
11 | "private": true,
12 | "main": "Gruntfile.js",
13 | "devDependencies": {
14 | "grunt": "~0.4.5",
15 | "grunt-wp-i18n": "~0.5.0",
16 | "grunt-wp-readme-to-markdown": "~1.0.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/phpcs.ruleset.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Generally-applicable sniffs for WordPress plugins
4 |
5 |
6 |
7 |
8 | */node_modules/*
9 | */vendor/*
10 |
11 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | ./tests/
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === WP GraphiQL ===
2 | Contributors: (this should be a list of wordpress.org userid's)
3 | Donate link: http://example.com/
4 | Tags: comments, spam
5 | Requires at least: 4.4
6 | Tested up to: 4.7.5
7 | Stable tag: 0.1.0
8 | License: GPLv3
9 | License URI: http://www.gnu.org/licenses/gpl-3.0.html
10 |
11 | Brings the GraphiQL IDE to the WP-Admin
12 |
13 | == Description ==
14 |
15 | Brings the GraphiQL IDE to the WP-Admin, with Authentication built-in.
16 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | assertTrue( true );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/wp-graphiql.php:
--------------------------------------------------------------------------------
1 | is_wpgraphql_active() ) {
50 | echo '';
51 | } else {
52 | echo 'This plugin requires WPGraphQL to be installed to work. Please install WPGraphQL (https://github.com/wp-graphql/wp-graphql) and visit this page again.
';
53 | }
54 |
55 | }
56 |
57 | /**
58 | * Gets the contents of the Create React App manifest file
59 | *
60 | * @return array|bool|string
61 | */
62 | public function get_app_manifest() {
63 | $manifest = file_get_contents( dirname( __FILE__ ) . '/assets/app/build/asset-manifest.json' );
64 | $manifest = (array) json_decode( $manifest );
65 | return $manifest;
66 | }
67 |
68 | /**
69 | * Gets the path to the stylesheet compiled by Create React App
70 | *
71 | * @return string
72 | */
73 | public function get_app_stylesheet() {
74 | $manifest = $this->get_app_manifest();
75 | if ( empty( $manifest['main.css'] ) ) {
76 | return '';
77 | }
78 | return WPGRAPHIQL_PLUGIN_DIR . 'assets/app/build/' . $manifest['main.css'];
79 | }
80 |
81 | /**
82 | * Gets the path to the built javascript file compiled by Create React App
83 | *
84 | * @return string
85 | */
86 | public function get_app_script() {
87 | $manifest = $this->get_app_manifest();
88 | if ( empty( $manifest['main.js'] ) ) {
89 | return '';
90 | }
91 | return WPGRAPHIQL_PLUGIN_DIR . 'assets/app/build/' . $manifest['main.js'];
92 | }
93 |
94 | public function get_app_script_helpers() {
95 | $manifest = $this->get_app_manifest();
96 | if ( empty( $manifest['main.js'] ) ) {
97 | return '';
98 | }
99 | return WPGRAPHIQL_PLUGIN_DIR . 'assets/js/wp-graphiql-helpers.js';
100 | }
101 |
102 | /**
103 | * Enqueues the stylesheet and js for the WPGraphiQL app
104 | */
105 | public function enqueue_react_app() {
106 |
107 | /**
108 | * Only enqueue the assets on the proper admin page, and only if WPGraphQL is also active
109 | */
110 | if ( strpos( get_current_screen()->id, 'wp-graphiql/wp-graphiql' ) && $this->is_wpgraphql_active() ) {
111 |
112 | wp_enqueue_style( 'wp-graphiql', $this->get_app_stylesheet(), array(), false, false );
113 | wp_enqueue_script( 'wp-graphiql-helpers', $this->get_app_script_helpers(), array( 'jquery' ), false, true );
114 | wp_enqueue_script( 'wp-graphiql', $this->get_app_script(), array(), false, true );
115 |
116 | /**
117 | * Create a nonce
118 | */
119 | wp_localize_script(
120 | 'wp-graphiql',
121 | 'wpGraphiQLSettings',
122 | array(
123 | 'nonce' => wp_create_nonce( 'wp_rest' ),
124 | 'graphqlEndpoint' => trailingslashit( site_url() ) . 'index.php?' . \WPGraphQL\Router::$route,
125 | )
126 | );
127 |
128 | }
129 | }
130 |
131 | }
132 |
133 | endif; // End if class_exists()
134 |
135 | add_action( 'plugins_loaded', function() {
136 |
137 | $wp_graphiql = new WPGraphiQL();
138 | $wp_graphiql->init();
139 |
140 | } );
141 |
--------------------------------------------------------------------------------