diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json index 53176ed9..36b1a165 100644 --- a/packages/bruno-app/package.json +++ b/packages/bruno-app/package.json @@ -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", diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js index a9f3b4b5..ee3145c0 100644 --- a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js +++ b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js @@ -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) { diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/useGraphqlSchema.js b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/useGraphqlSchema.js index 40daa63e..e6fc4295 100644 --- a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/useGraphqlSchema.js +++ b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/useGraphqlSchema.js @@ -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)); diff --git a/packages/bruno-app/src/components/RequestPane/QueryEditor/index.js b/packages/bruno-app/src/components/RequestPane/QueryEditor/index.js index d588c78d..8cdf90b2 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryEditor/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryEditor/index.js @@ -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() { diff --git a/packages/bruno-app/src/utils/network/index.js b/packages/bruno-app/src/utils/network/index.js index 6ddc81e4..df470b0b 100644 --- a/packages/bruno-app/src/utils/network/index.js +++ b/packages/bruno-app/src/utils/network/index.js @@ -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 diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json index e760bd67..8589bc40 100644 --- a/packages/bruno-electron/package.json +++ b/packages/bruno-electron/package.json @@ -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", diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index be5888f6..4312c55b 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -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; diff --git a/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js b/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js new file mode 100644 index 00000000..b096e53c --- /dev/null +++ b/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js @@ -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;