From d4f05fa84378f81d0852fe058445224a3f5222db Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 1 Feb 2023 09:23:11 +0530 Subject: [PATCH] feat: support for graphql variables --- .../RequestPane/GraphQLRequestPane/index.js | 8 ++++ .../GraphQLVariables/StyledWrapper.js | 10 +++++ .../RequestPane/GraphQLVariables/index.js | 43 +++++++++++++++++++ .../ReduxStore/slices/collections/index.js | 17 ++++++++ packages/bruno-lang/src/body-tag.js | 14 ++++++ packages/bruno-lang/src/index.js | 14 ++++++ 6 files changed, 106 insertions(+) create mode 100644 packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js index ee3145c0..a0ffb77d 100644 --- a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js +++ b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js @@ -6,6 +6,7 @@ import { IconRefresh, IconLoader2, IconBook, IconDownload } from '@tabler/icons' import { useSelector, useDispatch } from 'react-redux'; import { updateRequestPaneTab } from 'providers/ReduxStore/slices/tabs'; import QueryEditor from 'components/RequestPane/QueryEditor'; +import GraphQLVariables from 'components/RequestPane/GraphQLVariables'; import RequestHeaders from 'components/RequestPane/RequestHeaders'; import { useTheme } from 'providers/Theme'; import { updateRequestGraphqlQuery } from 'providers/ReduxStore/slices/collections'; @@ -19,6 +20,7 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog const tabs = useSelector((state) => state.tabs.tabs); const activeTabUid = useSelector((state) => state.tabs.activeTabUid); const query = item.draft ? get(item, 'draft.request.body.graphql.query') : get(item, 'request.body.graphql.query'); + const variables = item.draft ? get(item, 'draft.request.body.graphql.variables') : get(item, 'request.body.graphql.variables'); const url = item.draft ? get(item, 'draft.request.url') : get(item, 'request.url'); const { storedTheme @@ -81,6 +83,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog onClickReference={handleGqlClickReference} />; } + case 'variables': { + return ; + } case 'headers': { return ; } @@ -111,6 +116,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
selectTab('query')}> Query
+
selectTab('variables')}> + Variables +
selectTab('headers')}> Headers
diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js new file mode 100644 index 00000000..9f758322 --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js @@ -0,0 +1,10 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + div.CodeMirror { + /* todo: find a better way */ + height: calc(100vh - 220px); + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js new file mode 100644 index 00000000..f5c51c63 --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { useDispatch } from 'react-redux'; +import CodeEditor from 'components/CodeEditor'; +import { updateRequestGraphqlVariables } from 'providers/ReduxStore/slices/collections'; +import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions'; +import { useTheme } from 'providers/Theme'; +import StyledWrapper from './StyledWrapper'; + +const GraphQLVariables = ({ variables, item, collection }) => { + const dispatch = useDispatch(); + + const { + storedTheme + } = useTheme(); + + const onEdit = (value) => { + dispatch( + updateRequestGraphqlVariables({ + variables: value, + itemUid: item.uid, + collectionUid: collection.uid + }) + ); + }; + + const onRun = () => dispatch(sendRequest(item, collection.uid)); + const onSave = () => dispatch(saveRequest(item.uid, collection.uid)); + + return ( + + + + ); +}; + +export default GraphQLVariables; diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js index a87db2eb..31f421f4 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js @@ -622,6 +622,22 @@ export const collectionsSlice = createSlice({ } } }, + updateRequestGraphqlVariables: (state, action) => { + const collection = findCollectionByUid(state.collections, action.payload.collectionUid); + + if (collection) { + const item = findItemInCollection(collection, action.payload.itemUid); + + if (item && isItemARequest(item)) { + if (!item.draft) { + item.draft = cloneDeep(item); + } + item.draft.request.body.mode = 'graphql'; + item.draft.request.body.graphql = item.draft.request.body.graphql || {}; + item.draft.request.body.graphql.variables = action.payload.variables; + } + } + }, updateRequestScript: (state, action) => { const collection = findCollectionByUid(state.collections, action.payload.collectionUid); @@ -865,6 +881,7 @@ export const { updateRequestBodyMode, updateRequestBody, updateRequestGraphqlQuery, + updateRequestGraphqlVariables, updateRequestScript, updateRequestTests, updateRequestMethod, diff --git a/packages/bruno-lang/src/body-tag.js b/packages/bruno-lang/src/body-tag.js index de4dbbc8..c51f435e 100644 --- a/packages/bruno-lang/src/body-tag.js +++ b/packages/bruno-lang/src/body-tag.js @@ -11,6 +11,9 @@ const bodyJsonBegin = regex(/^body\s*\(\s*type\s*=\s*json\s*\)\s*\r?\n/); // body(type=graphql) const bodyGraphqlBegin = regex(/^body\s*\(\s*type\s*=\s*graphql\s*\)\s*\r?\n/); +// body(type=graphql-vars) +const bodyGraphqlVarsBegin = regex(/^body\s*\(\s*type\s*=\s*graphql-vars\s*\)\s*\r?\n/); + // body(type=text) const bodyTextBegin = regex(/^body\s*\(\s*type\s*=\s*text\s*\)\s*\r?\n/); @@ -37,6 +40,16 @@ const bodyGraphqlTag = between(bodyGraphqlBegin)(bodyEnd)(everyCharUntil(bodyEnd } }); +const bodyGraphqlVarsTag = between(bodyGraphqlVarsBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((varsGraphql) => { + return { + body: { + graphql: { + variables: varsGraphql + } + } + } +}); + const bodyTextTag = between(bodyTextBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((bodyText) => { return { body: { @@ -104,6 +117,7 @@ const bodyMultipartFormTag = between(bodyMultipartForm)(bodyEndRelaxed)(keyvalLi module.exports = { bodyJsonTag, bodyGraphqlTag, + bodyGraphqlVarsTag, bodyTextTag, bodyXmlTag, bodyFormUrlEncodedTagDeprecated, diff --git a/packages/bruno-lang/src/index.js b/packages/bruno-lang/src/index.js index 71511c36..877e8ce3 100644 --- a/packages/bruno-lang/src/index.js +++ b/packages/bruno-lang/src/index.js @@ -16,6 +16,7 @@ const headersTag = require('./headers-tag'); const { bodyJsonTag, bodyGraphqlTag, + bodyGraphqlVarsTag, bodyTextTag, bodyXmlTag, bodyFormUrlEncodedTagDeprecated, @@ -32,6 +33,7 @@ const bruToJson = (fileContents) => { headersTag, bodyJsonTag, bodyGraphqlTag, + bodyGraphqlVarsTag, bodyTextTag, bodyXmlTag, bodyFormUrlEncodedTagDeprecated, @@ -80,6 +82,10 @@ const bruToJson = (fileContents) => { body.graphql.query = outdentString(body.graphql.query); } + if(body && body.graphql && body.graphql.variables) { + body.graphql.variables = outdentString(body.graphql.variables); + } + return json; }; @@ -139,6 +145,14 @@ ${indentString(body.graphql.query)} `; } + if(body && body.graphql && body.graphql.variables) { + bru += ` +body(type=graphql-vars) +${indentString(body.graphql.variables)} +/body +`; + } + if(body && body.text && body.text.length) { bru += ` body(type=text)