forked from extern/bruno
feat: graphql schema introspection
This commit is contained in:
parent
05a290839b
commit
8bfb2591c2
@ -27,7 +27,7 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"formik": "^2.2.9",
|
||||
"graphiql": "^1.5.9",
|
||||
"graphql": "^16.2.0",
|
||||
"graphql": "^16.6.0",
|
||||
"graphql-request": "^3.7.0",
|
||||
"idb": "^7.0.0",
|
||||
"immer": "^9.0.15",
|
||||
|
@ -10,6 +10,7 @@ import RequestHeaders from 'components/RequestPane/RequestHeaders';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import { updateRequestGraphqlQuery } from 'providers/ReduxStore/slices/collections';
|
||||
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { findEnvironmentInCollection } from 'utils/collections';
|
||||
import useGraphqlSchema from './useGraphqlSchema';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
@ -22,13 +23,15 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
|
||||
const {
|
||||
storedTheme
|
||||
} = useTheme();
|
||||
|
||||
const environment = findEnvironmentInCollection(collection, collection.activeEnvironmentUid);
|
||||
|
||||
let {
|
||||
schema,
|
||||
loadSchema,
|
||||
isLoading: isSchemaLoading,
|
||||
error: schemaError
|
||||
} = useGraphqlSchema(url);
|
||||
} = useGraphqlSchema(url, environment);
|
||||
|
||||
const loadGqlSchema = () => {
|
||||
if(!isSchemaLoading) {
|
||||
|
@ -1,27 +1,12 @@
|
||||
import { useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { getIntrospectionQuery, buildClientSchema } from 'graphql';
|
||||
import { buildClientSchema } from 'graphql';
|
||||
import { fetchGqlSchema } from 'utils/network';
|
||||
import { simpleHash } from 'utils/common';
|
||||
|
||||
const schemaHashPrefix = 'bruno.graphqlSchema';
|
||||
|
||||
const fetchSchema = (endpoint) => {
|
||||
const introspectionQuery = getIntrospectionQuery();
|
||||
const queryParams = {
|
||||
query: introspectionQuery
|
||||
};
|
||||
|
||||
return fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(queryParams)
|
||||
});
|
||||
}
|
||||
|
||||
const useGraphqlSchema = (endpoint) => {
|
||||
const useGraphqlSchema = (endpoint, environment) => {
|
||||
const localStorageKey = `${schemaHashPrefix}.${simpleHash(endpoint)}`;
|
||||
const [error, setError] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@ -40,8 +25,8 @@ const useGraphqlSchema = (endpoint) => {
|
||||
|
||||
const loadSchema = () => {
|
||||
setIsLoading(true);
|
||||
fetchSchema(endpoint)
|
||||
.then((res) => res.json())
|
||||
fetchGqlSchema(endpoint, environment)
|
||||
.then((res) => res.data)
|
||||
.then((s) => {
|
||||
if (s && s.data) {
|
||||
setSchema(buildClientSchema(s.data));
|
||||
|
@ -40,7 +40,8 @@ export default class QueryEditor extends React.Component {
|
||||
value: this.props.value || '',
|
||||
lineNumbers: true,
|
||||
tabSize: 2,
|
||||
mode: 'brunovariables',
|
||||
mode: 'graphql',
|
||||
// mode: 'brunovariables',
|
||||
brunoVarInfo: {
|
||||
variables: getEnvironmentVariables(this.props.collection),
|
||||
},
|
||||
@ -176,12 +177,14 @@ export default class QueryEditor extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Overlay is messing up with schema hint
|
||||
// Fix this
|
||||
addOverlay = () => {
|
||||
let variables = getEnvironmentVariables(this.props.collection);
|
||||
this.variables = variables;
|
||||
// let variables = getEnvironmentVariables(this.props.collection);
|
||||
// this.variables = variables;
|
||||
|
||||
defineCodeMirrorBrunoVariablesMode(variables, 'graphql');
|
||||
this.editor.setOption('mode', 'brunovariables');
|
||||
// defineCodeMirrorBrunoVariablesMode(variables, 'graphql');
|
||||
// this.editor.setOption('mode', 'brunovariables');
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -31,6 +31,17 @@ const sendHttpRequest = async (item, collection, environment) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchGqlSchema = async (endpoint, environment) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
ipcRenderer
|
||||
.invoke('fetch-gql-schema', endpoint, environment)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
export const cancelNetworkRequest = async (cancelTokenUid) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer
|
||||
|
@ -28,6 +28,7 @@
|
||||
"electron-util": "^0.17.2",
|
||||
"form-data": "^4.0.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"graphql": "^16.6.0",
|
||||
"is-valid-path": "^0.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
|
@ -5,6 +5,7 @@ const { ipcMain } = require('electron');
|
||||
const { forOwn, extend, each, get } = require('lodash');
|
||||
const { ScriptRuntime, TestRuntime } = require('@usebruno/js');
|
||||
const prepareRequest = require('./prepare-request');
|
||||
const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request');
|
||||
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
|
||||
const { uuid } = require('../../utils/common');
|
||||
const interpolateVars = require('./interpolate-vars');
|
||||
@ -169,6 +170,33 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.handle('fetch-gql-schema', async (event, endpoint, environment) => {
|
||||
try {
|
||||
const envVars = getEnvVars(environment);
|
||||
const request = prepareGqlIntrospectionRequest(endpoint, envVars);
|
||||
|
||||
const response = await axios(request);
|
||||
|
||||
return {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: response.headers,
|
||||
data: response.data
|
||||
};
|
||||
} catch (error) {
|
||||
if(error.response) {
|
||||
return {
|
||||
status: error.response.status,
|
||||
statusText: error.response.statusText,
|
||||
headers: error.response.headers,
|
||||
data: error.response.data
|
||||
}
|
||||
};
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = registerNetworkIpc;
|
||||
|
@ -0,0 +1,31 @@
|
||||
const Mustache = require('mustache');
|
||||
const { getIntrospectionQuery } = require('graphql');
|
||||
|
||||
// override the default escape function to prevent escaping
|
||||
Mustache.escape = function (value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
const prepareGqlIntrospectionRequest = (endpoint, envVars) => {
|
||||
if(endpoint && endpoint.length) {
|
||||
endpoint = Mustache.render(endpoint, envVars);
|
||||
}
|
||||
const introspectionQuery = getIntrospectionQuery();
|
||||
const queryParams = {
|
||||
query: introspectionQuery
|
||||
};
|
||||
|
||||
const request = {
|
||||
method: 'POST',
|
||||
url: endpoint,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: JSON.stringify(queryParams)
|
||||
};
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
module.exports = prepareGqlIntrospectionRequest;
|
Loading…
Reference in New Issue
Block a user