console: provide checkbox to remove body in rest connectors v2

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3544
GitOrigin-RevId: 2beb58f09577bda72470fb0deb1099287ab4c8a9
This commit is contained in:
Abhijeet Khangarot 2022-03-01 20:50:59 +05:30 committed by hasura-bot
parent 7c3698d91f
commit 0d120471cd
14 changed files with 454 additions and 149 deletions

View File

@ -14,6 +14,7 @@
- server: add support for customising the GraphQL schema descriptions of table root fields
- console: include cron trigger with include in metadata as false on cron trigger manage page
- console: show an error notification if Hasura CLI migrations fail
- console: provide checkbox to remove body in rest connectors
- cli: fix metadata version being set to 3 when doing `hasura init --version 2` (#8148)
## v2.3.0-beta.3

View File

@ -99,3 +99,89 @@ export const checkTransformRequestBodyError = (exists: boolean) => {
cy.getBySel('transform-requestBody-error').should('not.exist');
}
};
export const getActionTransfromV1RequestBody = (actionName: string) => ({
type: 'bulk',
source: 'default',
args: [
{
type: 'set_custom_types',
args: {
scalars: [],
input_objects: [
{
name: 'SampleInput',
description: null,
fields: [
{
name: 'username',
type: 'String!',
description: null,
},
{
name: 'password',
type: 'String!',
description: null,
},
],
},
],
objects: [
{
name: 'SampleOutput',
description: null,
fields: [
{
name: 'accessToken',
type: 'String!',
description: null,
},
],
},
{
name: 'LoginResponse',
fields: [
{
name: 'accessToken',
type: 'String!',
},
],
},
],
enums: [],
},
},
{
type: 'create_action',
args: {
name: actionName,
definition: {
arguments: [
{
name: 'arg1',
type: 'SampleInput!',
description: null,
},
],
kind: 'synchronous',
output_type: 'SampleOutput',
handler: 'http://host.docker.internal:3000',
type: 'mutation',
headers: [],
timeout: null,
request_transform: {
version: 1,
template_engine: 'Kriti',
method: 'GET',
url: '{{$base_url}}/users',
query_params: {},
body:
'{\n "users": {\n "name": {{$body.input.arg1.username}}\n }\n}',
content_type: 'application/json',
},
},
comment: null,
},
},
],
});

View File

@ -15,6 +15,7 @@ import {
clearRequestUrl,
toggleContextArea,
typeIntoContextAreaEnvVars,
getActionTransfromV1RequestBody,
} from '../../helpers/webhookTransformHelpers';
const ACTION_REQUEST_BODY_TRANSFORM_TEXTAREA = 4;
@ -292,7 +293,7 @@ export const deleteQueryAction = () => deleteAction('addNumbers');
export const createActionTransform = () => {
// Click on create
cy.getBySel('data-create-actions').click();
cy.getBySel('actions-sidebar-add-table').click();
// Clear default text on
clearActionDef();
// type statement
@ -415,3 +416,45 @@ export const modifyActionTransform = () => {
};
export const deleteActionTransform = () => deleteAction('login');
const createV1ActionTransform = (actionName: string) => {
cy.request(
'POST',
'http://localhost:8080/v1/metadata',
getActionTransfromV1RequestBody(actionName)
).then(response => {
expect(response.body).to.not.be.null;
expect(response.body).to.be.a('array');
expect(response.body[0]).to.have.property('message', 'success'); // true
});
};
export const modifyV1ActionTransform = () => {
// Creates an action with v1 transform
createV1ActionTransform('login');
cy.wait(AWAIT_SHORT);
// modify and save the action, the action should be converted into v2 and checkbox to remove body should be visible
cy.visit('/actions/manage/login/modify');
cy.url({ timeout: AWAIT_LONG }).should(
'eq',
`${baseUrl}/actions/manage/login/modify`
);
cy.getBySel('transform-POST').click();
cy.getBySel('transform-requestUrl')
.clear()
.type('/{{$body.action.name}}/actions', {
parseSpecialCharSequences: false,
});
cy.getBySel('save-modify-action-changes').click();
cy.get('.notification', { timeout: AWAIT_LONG })
.should('be.visible')
.and('contain', 'Action saved successfully');
// check if checkbox to remove body is visible
cy.getBySel('transform-showRequestBody-checkbox').should('be.visible');
// delete the action
deleteActionTransform();
};

View File

@ -8,6 +8,7 @@ import {
createActionTransform,
modifyActionTransform,
deleteActionTransform,
modifyV1ActionTransform,
} from './spec';
import { testMode } from '../../helpers/common';
import { setMetaData } from '../validators/validators';
@ -35,6 +36,10 @@ export const runActionsTests = () => {
it('Create Action With Transform', createActionTransform);
it('Update Action With Transform', modifyActionTransform);
it('Delete Action With Transform', deleteActionTransform);
it(
'Create an action with V1 Transform and edit it through console, which will lead to the action being saved as V2',
modifyV1ActionTransform
);
});
};

View File

@ -20,6 +20,7 @@ type ConfigureTransformationProps = {
requestQueryParamsOnChange: (requestQueryParams: KeyValuePair[]) => void;
requestAddHeadersOnChange: (requestAddHeaders: KeyValuePair[]) => void;
requestBodyOnChange: (requestBody: string) => void;
requestBodyEnabledOnChange: (enableRequestBody: boolean) => void;
requestSampleInputOnChange: (requestSampleInput: string) => void;
requestContentTypeOnChange: (
requestContentType: RequestTransformContentType
@ -38,6 +39,7 @@ const ConfigureTransformation: React.FC<ConfigureTransformationProps> = ({
requestQueryParamsOnChange,
requestAddHeadersOnChange,
requestBodyOnChange,
requestBodyEnabledOnChange,
requestSampleInputOnChange,
requestContentTypeOnChange,
requestUrlTransformOnChange,
@ -56,6 +58,7 @@ const ConfigureTransformation: React.FC<ConfigureTransformationProps> = ({
requestBodyError,
requestSampleInput,
requestTransformedBody,
enableRequestBody,
requestContentType,
isRequestUrlTransform,
isRequestPayloadTransform,
@ -171,9 +174,11 @@ const ConfigureTransformation: React.FC<ConfigureTransformationProps> = ({
requestBodyError={requestBodyError}
requestSampleInput={requestSampleInput}
requestTransformedBody={requestTransformedBody}
enableRequestBody={enableRequestBody}
requestContentType={requestContentType}
resetSampleInput={resetSampleInput}
requestBodyOnChange={requestBodyOnChange}
requestBodyEnabledOnChange={requestBodyEnabledOnChange}
requestSampleInputOnChange={requestSampleInputOnChange}
requestContentTypeOnChange={requestContentTypeOnChange}
/>

View File

@ -13,8 +13,10 @@ type PayloadOptionsTransformsProps = {
requestSampleInput: string;
requestTransformedBody: string;
requestContentType: RequestTransformContentType;
enableRequestBody: boolean;
resetSampleInput: () => void;
requestBodyOnChange: (requestBody: string) => void;
requestBodyEnabledOnChange: (enableRequestBody: boolean) => void;
requestSampleInputOnChange: (requestSampleInput: string) => void;
requestContentTypeOnChange: (
requestContentType: RequestTransformContentType
@ -27,8 +29,10 @@ const PayloadOptionsTransforms: React.FC<PayloadOptionsTransformsProps> = ({
requestSampleInput,
requestTransformedBody,
requestContentType,
enableRequestBody,
resetSampleInput,
requestBodyOnChange,
requestBodyEnabledOnChange,
requestSampleInputOnChange,
requestContentTypeOnChange,
}) => {
@ -83,56 +87,81 @@ const PayloadOptionsTransforms: React.FC<PayloadOptionsTransformsProps> = ({
number="2"
url="https://hasura.io/docs/latest/graphql/core/actions/transforms.html#request-body"
/>
<TemplateEditor
requestBody={requestBody}
requestBodyError={requestBodyError}
requestSampleInput={requestSampleInput}
requestBodyOnChange={requestBodyOnChange}
/>
<div className="mb-sm">
<input
checked={enableRequestBody}
id="request-enable"
name="request-body"
type="checkbox"
onChange={e => requestBodyEnabledOnChange(e.target.checked)}
className="rounded border-gray-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-400"
data-test="transform-showRequestBody-checkbox"
/>
<label className="ml-xs" htmlFor="request-enable">
Enable Request Body
</label>
</div>
{enableRequestBody ? (
<TemplateEditor
requestBody={requestBody}
requestBodyError={requestBodyError}
requestSampleInput={requestSampleInput}
requestBodyOnChange={requestBodyOnChange}
/>
) : (
<div className="flex items-center text-gray-600 bg-gray-200 border border-gray-400 text-sm rounded p-sm">
<i className="fa fa-exclamation-circle mr-sm" />
The request body is disabled. No request body will be sent with this
action. Enable the request body to modify your request
transformation.
</div>
)}
</div>
<div className="mb-md">
<NumberedSidebar
title="Transformed Request Body"
description="Sample request body to be delivered based on your input and
{enableRequestBody ? (
<div className="mb-md">
<NumberedSidebar
title="Transformed Request Body"
description="Sample request body to be delivered based on your input and
transformation template."
number="3"
>
{showRequestContentTypeOptions ? (
<select
className={`ml-auto ${inputStyles}`}
value={requestContentType}
onChange={e =>
requestContentTypeOnChange(
e.target.value as RequestTransformContentType
)
}
>
<option disabled>Data Type</option>
{requestContentTypeOptions.map(option => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
) : null}
</NumberedSidebar>
<AceEditor
mode="json"
editorRef={editorRef}
value={requestTransformedBody}
showPrintMargin={false}
highlightActiveLine={false}
height="200px"
width="100%"
fontSize="12px"
style={{ background: '#e2e8f0' }}
setOptions={{
highlightGutterLine: false,
}}
readOnly
/>
</div>
number="3"
>
{showRequestContentTypeOptions ? (
<select
className={`ml-auto ${inputStyles}`}
value={requestContentType}
onChange={e =>
requestContentTypeOnChange(
e.target.value as RequestTransformContentType
)
}
>
<option disabled>Data Type</option>
{requestContentTypeOptions.map(option => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
) : null}
</NumberedSidebar>
<AceEditor
mode="json"
editorRef={editorRef}
value={requestTransformedBody}
showPrintMargin={false}
highlightActiveLine={false}
height="200px"
width="100%"
fontSize="12px"
style={{ background: '#e2e8f0' }}
setOptions={{
highlightGutterLine: false,
}}
readOnly
/>
</div>
) : null}
</div>
);
};

View File

@ -15,6 +15,7 @@ import {
SET_REQUEST_BODY_ERROR,
SET_REQUEST_SAMPLE_INPUT,
SET_REQUEST_TRANSFORMED_BODY,
SET_ENABLE_REQUEST_BODY,
SET_REQUEST_CONTENT_TYPE,
SET_REQUEST_URL_TRANSFORM,
SET_REQUEST_PAYLOAD_TRANSFORM,
@ -31,6 +32,7 @@ import {
SetRequestBodyError,
SetRequestSampleInput,
SetRequestTransformedBody,
SetEnableRequestBody,
SetRequestTransformState,
SetRequestContentType,
SetRequestUrlTransform,
@ -125,6 +127,13 @@ export const setRequestTransformedBody = (
requestTransformedBody,
});
export const setEnableRequestBody = (
enableRequestBody: boolean
): SetEnableRequestBody => ({
type: SET_ENABLE_REQUEST_BODY,
enableRequestBody,
});
export const setRequestContentType = (
requestContentType: RequestTransformContentType
): SetRequestContentType => ({
@ -153,7 +162,10 @@ export const setRequestTransformState = (
newState,
});
const currentVersion = 2;
export const requestTransformState: RequestTransformState = {
version: currentVersion,
envVars: [],
sessionVars: [],
requestMethod: null,
@ -166,6 +178,7 @@ export const requestTransformState: RequestTransformState = {
requestBodyError: '',
requestSampleInput: '',
requestTransformedBody: '',
enableRequestBody: true,
requestContentType: defaultRequestContentType,
isRequestUrlTransform: false,
isRequestPayloadTransform: false,
@ -261,6 +274,11 @@ export const requestTransformReducer = (
...state,
requestTransformedBody: action.requestTransformedBody,
};
case SET_ENABLE_REQUEST_BODY:
return {
...state,
enableRequestBody: action.enableRequestBody,
};
case SET_REQUEST_CONTENT_TYPE:
return {
...state,

View File

@ -29,6 +29,8 @@ export const SET_REQUEST_SAMPLE_INPUT =
'RequestTransform/SET_REQUEST_SAMPLE_INPUT';
export const SET_REQUEST_TRANSFORMED_BODY =
'RequestTransform/SET_REQUEST_TRANSFORMED_BODY';
export const SET_ENABLE_REQUEST_BODY =
'RequestTransform/SET_ENABLE_REQUEST_BODY';
export const SET_REQUEST_CONTENT_TYPE =
'RequestTransform/SET_REQUEST_CONTENT_TYPE';
export const SET_REQUEST_URL_TRANSFORM =
@ -98,6 +100,11 @@ export interface SetRequestTransformedBody extends ReduxAction {
requestTransformedBody: string;
}
export interface SetEnableRequestBody extends ReduxAction {
type: typeof SET_ENABLE_REQUEST_BODY;
enableRequestBody: boolean;
}
export interface SetRequestContentType extends ReduxAction {
type: typeof SET_REQUEST_CONTENT_TYPE;
requestContentType: RequestTransformContentType;
@ -131,12 +138,14 @@ export type RequestTransformEvents =
| SetRequestBodyError
| SetRequestSampleInput
| SetRequestTransformedBody
| SetEnableRequestBody
| SetRequestContentType
| SetRequestUrlTransform
| SetRequestPayloadTransform
| SetRequestTransformState;
export type RequestTransformState = {
version: 1 | 2;
envVars: KeyValuePair[];
sessionVars: KeyValuePair[];
requestMethod: Nullable<RequestTransformMethod>;
@ -149,6 +158,7 @@ export type RequestTransformState = {
requestBodyError: string;
requestSampleInput: string;
requestTransformedBody: string;
enableRequestBody: boolean;
requestContentType: RequestTransformContentType;
isRequestUrlTransform: boolean;
isRequestPayloadTransform: boolean;

View File

@ -106,10 +106,12 @@ export const getRequestTransformObject = (
) => {
const isRequestUrlTransform = transformState.isRequestUrlTransform;
const isRequestPayloadTransform = transformState.isRequestPayloadTransform;
const enableRequestBody = transformState.enableRequestBody;
if (!isRequestUrlTransform && !isRequestPayloadTransform) return null;
let obj: RequestTransform = {
version: 2,
template_engine: transformState.templatingEngine,
};
@ -120,12 +122,27 @@ export const getRequestTransformObject = (
url: getUrlWithBasePrefix(transformState.requestUrl),
query_params: getPairsObjFromArray(transformState.requestQueryParams),
};
if (transformState.requestMethod === 'GET') {
obj = {
...obj,
request_headers: {
remove_headers: ['content-type'],
},
};
}
}
if (isRequestPayloadTransform) {
obj = {
...obj,
body: checkEmptyString(transformState.requestBody),
body: enableRequestBody
? {
action: 'transform',
template: checkEmptyString(transformState.requestBody),
}
: {
action: 'remove',
},
content_type: transformState.requestContentType,
};
}
@ -178,27 +195,57 @@ export const parseValidateApiData = (
}
};
type RequestTransformer = {
body?: string;
// fields for `request_transform` key in `test_webhook_transform` api
type RequestTransformerFields = {
url?: string;
method?: Nullable<RequestTransformMethod>;
query_params?: Record<string, string>;
template_engine?: string;
};
type RequestTransformerV1 = RequestTransformerFields & {
version: 1;
body?: string;
};
type RequestTransformerV2 = RequestTransformerFields & {
version: 2;
body?: Record<string, string>;
};
type RequestTransformer = RequestTransformerV1 | RequestTransformerV2;
const getTransformer = (
version: 1 | 2,
transformerBody?: string,
transformerUrl?: string,
requestMethod?: Nullable<RequestTransformMethod>,
queryParams?: KeyValuePair[]
): RequestTransformer => {
return {
body: checkEmptyString(transformerBody),
url: checkEmptyString(transformerUrl),
method: requestMethod,
query_params: queryParams ? getPairsObjFromArray(queryParams) : undefined,
template_engine: 'Kriti',
};
return version === 1
? {
version,
body: checkEmptyString(transformerBody),
url: checkEmptyString(transformerUrl),
method: requestMethod,
query_params: queryParams
? getPairsObjFromArray(queryParams)
: undefined,
template_engine: 'Kriti',
}
: {
version,
body: {
action: 'transform',
template: checkEmptyString(transformerBody) ?? '{}',
},
url: checkEmptyString(transformerUrl),
method: requestMethod,
query_params: queryParams
? getPairsObjFromArray(queryParams)
: undefined,
template_engine: 'Kriti',
};
};
const generateValidateTransformQuery = (
@ -223,17 +270,31 @@ const generateValidateTransformQuery = (
};
};
export const getValidateTransformOptions = (
inputPayloadString: string,
webhookUrl: string,
envVarsFromContext?: KeyValuePair[],
sessionVarsFromContext?: KeyValuePair[],
transformerBody?: string,
requestUrl?: string,
queryParams?: KeyValuePair[],
isEnvVar?: boolean,
requestMethod?: Nullable<RequestTransformMethod>
) => {
type ValidateTransformOptionsArgsType = {
version: 1 | 2;
inputPayloadString: string;
webhookUrl: string;
envVarsFromContext?: KeyValuePair[];
sessionVarsFromContext?: KeyValuePair[];
transformerBody?: string;
requestUrl?: string;
queryParams?: KeyValuePair[];
isEnvVar?: boolean;
requestMethod?: Nullable<RequestTransformMethod>;
};
export const getValidateTransformOptions = ({
version,
inputPayloadString,
webhookUrl,
envVarsFromContext,
sessionVarsFromContext,
transformerBody,
requestUrl,
queryParams,
isEnvVar,
requestMethod,
}: ValidateTransformOptionsArgsType) => {
const requestPayload = isJsonString(inputPayloadString)
? JSON.parse(inputPayloadString)
: null;
@ -242,7 +303,13 @@ export const getValidateTransformOptions = (
: `{{$base_url}}`;
const finalReqBody = generateValidateTransformQuery(
getTransformer(transformerBody, transformerUrl, requestMethod, queryParams),
getTransformer(
version,
transformerBody,
transformerUrl,
requestMethod,
queryParams
),
requestPayload,
webhookUrl,
sessionVarsFromContext,
@ -321,7 +388,8 @@ const getTrimmedRequestUrl = (val: string) => {
export const getTransformState = (
transform: RequestTransform,
sampleInput: string
) => ({
): RequestTransformState => ({
version: transform?.version,
envVars: getEnvVarsFromLS(),
sessionVars: getSessionVarsFromLS(),
requestMethod: transform?.method ?? null,
@ -332,12 +400,17 @@ export const getTransformState = (
{ name: '', value: '' },
],
requestAddHeaders: getArrayFromServerPairObject(
transform?.request_headers?.addHeaders
transform?.request_headers?.add_headers
) ?? [{ name: '', value: '' }],
requestBody: transform?.body ?? '',
requestBody:
transform?.version === 1
? transform?.body ?? ''
: transform?.body?.template ?? '',
requestBodyError: '',
requestSampleInput: sampleInput,
requestTransformedBody: '',
enableRequestBody:
transform?.version === 2 ? transform?.body?.action === 'transform' : true,
requestContentType: transform?.content_type ?? defaultRequestContentType,
isRequestUrlTransform:
!!transform?.method ||

View File

@ -24,6 +24,7 @@ import {
setRequestBodyError,
setRequestSampleInput,
setRequestTransformedBody,
setEnableRequestBody,
setRequestContentType,
setRequestUrlTransform,
setRequestPayloadTransform,
@ -205,6 +206,10 @@ const AddAction: React.FC<AddActionProps> = ({
transformDispatch(setRequestTransformedBody(requestTransformedBody));
};
const requestBodyEnabledOnChange = (enableRequestBody: boolean) => {
transformDispatch(setEnableRequestBody(enableRequestBody));
};
const requestContentTypeOnChange = (
requestContentType: RequestTransformContentType
) => {
@ -231,15 +236,15 @@ const AddAction: React.FC<AddActionProps> = ({
requestUrlPreviewOnChange
);
};
const options = getValidateTransformOptions(
transformState.requestSampleInput,
handler,
transformState.envVars,
transformState.sessionVars,
undefined,
transformState.requestUrl,
transformState.requestQueryParams
);
const options = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: handler,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
requestUrl: transformState.requestUrl,
queryParams: transformState.requestQueryParams,
});
if (!handler) {
requestUrlErrorOnChange(
'Please configure your webhook handler to generate request url transform'
@ -276,13 +281,14 @@ const AddAction: React.FC<AddActionProps> = ({
requestTransformedBodyOnChange
);
};
const options = getValidateTransformOptions(
transformState.requestSampleInput,
handler,
transformState.envVars,
transformState.sessionVars,
transformState.requestBody
);
const options = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: handler,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
transformerBody: transformState.requestBody,
});
if (!handler) {
requestBodyErrorOnChange(
'Please configure your webhook handler to generate request body transform'
@ -364,6 +370,7 @@ const AddAction: React.FC<AddActionProps> = ({
requestQueryParamsOnChange={requestQueryParamsOnChange}
requestAddHeadersOnChange={requestAddHeadersOnChange}
requestBodyOnChange={requestBodyOnChange}
requestBodyEnabledOnChange={requestBodyEnabledOnChange}
requestSampleInputOnChange={requestSampleInputOnChange}
requestContentTypeOnChange={requestContentTypeOnChange}
requestUrlTransformOnChange={requestUrlTransformOnChange}

View File

@ -24,6 +24,7 @@ import {
setRequestBodyError,
setRequestSampleInput,
setRequestTransformedBody,
setEnableRequestBody,
setRequestContentType,
setRequestUrlTransform,
setRequestPayloadTransform,
@ -218,6 +219,10 @@ const ModifyAction: React.FC<ModifyProps> = ({
transformDispatch(setRequestBody(requestBody));
};
const requestBodyEnabledOnChange = (enableRequestBody: boolean) => {
transformDispatch(setEnableRequestBody(enableRequestBody));
};
const requestBodyErrorOnChange = (requestBodyError: string) => {
transformDispatch(setRequestBodyError(requestBodyError));
};
@ -254,15 +259,15 @@ const ModifyAction: React.FC<ModifyProps> = ({
requestUrlPreviewOnChange
);
};
const options = getValidateTransformOptions(
transformState.requestSampleInput,
handler,
transformState.envVars,
transformState.sessionVars,
undefined,
transformState.requestUrl,
transformState.requestQueryParams
);
const options = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: handler,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
requestUrl: transformState.requestUrl,
queryParams: transformState.requestQueryParams,
});
if (!handler) {
requestUrlErrorOnChange(
'Please configure your webhook handler to generate request url transform'
@ -296,13 +301,14 @@ const ModifyAction: React.FC<ModifyProps> = ({
requestTransformedBodyOnChange
);
};
const reqBodyoptions = getValidateTransformOptions(
transformState.requestSampleInput,
handler,
transformState.envVars,
transformState.sessionVars,
transformState.requestBody
);
const reqBodyoptions = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: handler,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
transformerBody: transformState.requestBody,
});
useEffect(() => {
requestBodyErrorOnChange('');
requestTransformedBodyOnChange('');
@ -403,6 +409,7 @@ const ModifyAction: React.FC<ModifyProps> = ({
requestQueryParamsOnChange={requestQueryParamsOnChange}
requestAddHeadersOnChange={requestAddHeadersOnChange}
requestBodyOnChange={requestBodyOnChange}
requestBodyEnabledOnChange={requestBodyEnabledOnChange}
requestSampleInputOnChange={requestSampleInputOnChange}
requestContentTypeOnChange={requestContentTypeOnChange}
requestUrlTransformOnChange={requestUrlTransformOnChange}

View File

@ -16,6 +16,7 @@ import {
setRequestBodyError,
setRequestSampleInput,
setRequestTransformedBody,
setEnableRequestBody,
setRequestContentType,
setRequestUrlTransform,
setRequestPayloadTransform,
@ -187,6 +188,10 @@ const Add: React.FC<Props> = props => {
transformDispatch(setRequestBody(requestBody));
};
const requestBodyEnabledOnChange = (enableRequestBody: boolean) => {
transformDispatch(setEnableRequestBody(enableRequestBody));
};
const requestBodyErrorOnChange = (requestBodyError: string) => {
transformDispatch(setRequestBodyError(requestBodyError));
};
@ -223,16 +228,16 @@ const Add: React.FC<Props> = props => {
requestUrlPreviewOnChange
);
};
const options = getValidateTransformOptions(
transformState.requestSampleInput,
webhook.value,
transformState.envVars,
transformState.sessionVars,
undefined,
transformState.requestUrl,
transformState.requestQueryParams,
webhook.type === 'env'
);
const options = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: webhook.value,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
requestUrl: transformState.requestUrl,
queryParams: transformState.requestQueryParams,
isEnvVar: webhook.type === 'env',
});
if (!webhook.value) {
requestUrlErrorOnChange(
'Please configure your webhook handler to generate request url transform'
@ -269,16 +274,15 @@ const Add: React.FC<Props> = props => {
requestTransformedBodyOnChange
);
};
const options = getValidateTransformOptions(
transformState.requestSampleInput,
webhook.value,
transformState.envVars,
transformState.sessionVars,
transformState.requestBody,
undefined,
undefined,
webhook.type === 'env'
);
const options = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: webhook.value,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
transformerBody: transformState.requestBody,
isEnvVar: webhook.type === 'env',
});
if (!webhook.value) {
requestBodyErrorOnChange(
'Please configure your webhook handler to generate request body transform'
@ -412,6 +416,7 @@ const Add: React.FC<Props> = props => {
requestQueryParamsOnChange={requestQueryParamsOnChange}
requestAddHeadersOnChange={requestAddHeadersOnChange}
requestBodyOnChange={requestBodyOnChange}
requestBodyEnabledOnChange={requestBodyEnabledOnChange}
requestSampleInputOnChange={requestSampleInputOnChange}
requestContentTypeOnChange={requestContentTypeOnChange}
requestUrlTransformOnChange={requestUrlTransformOnChange}

View File

@ -14,6 +14,7 @@ import {
setRequestBodyError,
setRequestSampleInput,
setRequestTransformedBody,
setEnableRequestBody,
setRequestContentType,
setRequestUrlTransform,
setRequestTransformState,
@ -165,6 +166,10 @@ const Modify: React.FC<Props> = props => {
transformDispatch(setRequestBody(requestBody));
};
const requestBodyEnabledOnChange = (enableRequestBody: boolean) => {
transformDispatch(setEnableRequestBody(enableRequestBody));
};
const requestBodyErrorOnChange = (requestBodyError: string) => {
transformDispatch(setRequestBodyError(requestBodyError));
};
@ -201,16 +206,16 @@ const Modify: React.FC<Props> = props => {
requestUrlPreviewOnChange
);
};
const options = getValidateTransformOptions(
transformState.requestSampleInput,
state.webhook?.value,
transformState.envVars,
transformState.sessionVars,
undefined,
transformState.requestUrl,
transformState.requestQueryParams,
state.webhook.type === 'env'
);
const options = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: state.webhook?.value,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
requestUrl: transformState.requestUrl,
queryParams: transformState.requestQueryParams,
isEnvVar: state.webhook.type === 'env',
});
if (!state.webhook?.value) {
requestUrlErrorOnChange(
'Please configure your webhook handler to generate request url transform'
@ -244,16 +249,15 @@ const Modify: React.FC<Props> = props => {
requestTransformedBodyOnChange
);
};
const reqBodyoptions = getValidateTransformOptions(
transformState.requestSampleInput,
state.webhook?.value,
transformState.envVars,
transformState.sessionVars,
transformState.requestBody,
undefined,
undefined,
state.webhook.type === 'env'
);
const reqBodyoptions = getValidateTransformOptions({
version: transformState.version,
inputPayloadString: transformState.requestSampleInput,
webhookUrl: state.webhook?.value,
envVarsFromContext: transformState.envVars,
sessionVarsFromContext: transformState.sessionVars,
transformerBody: transformState.requestBody,
isEnvVar: state.webhook.type === 'env',
});
useEffect(() => {
requestBodyErrorOnChange('');
requestTransformedBodyOnChange('');
@ -384,6 +388,7 @@ const Modify: React.FC<Props> = props => {
requestQueryParamsOnChange={requestQueryParamsOnChange}
requestAddHeadersOnChange={requestAddHeadersOnChange}
requestBodyOnChange={requestBodyOnChange}
requestBodyEnabledOnChange={requestBodyEnabledOnChange}
requestSampleInputOnChange={requestSampleInputOnChange}
requestContentTypeOnChange={requestContentTypeOnChange}
requestUrlTransformOnChange={requestUrlTransformOnChange}

View File

@ -857,22 +857,33 @@ export type RequestTransformContentType =
| 'application/x-www-form-urlencoded';
export type RequestTransformHeaders = {
addHeaders: Record<string, string>;
removeHeaders: string[];
add_headers?: Record<string, string>;
remove_headers?: string[];
};
export type RequestTransformTemplateEngine = 'Kriti';
export interface RequestTransform {
interface RequestTransformFields {
method?: Nullable<RequestTransformMethod>;
url?: Nullable<string>;
body?: Nullable<string>;
content_type?: Nullable<RequestTransformContentType>;
request_headers?: Nullable<RequestTransformHeaders>;
query_params?: Nullable<Record<string, string>>;
template_engine?: Nullable<RequestTransformTemplateEngine>;
}
interface RequestTransformV1 extends RequestTransformFields {
version: 1;
body?: string;
}
interface RequestTransformV2 extends RequestTransformFields {
version: 2;
body?: Record<string, Nullable<string>>;
}
export type RequestTransform = RequestTransformV1 | RequestTransformV2;
/**
* https://hasura.io/docs/latest/graphql/core/api-reference/schema-metadata-api/actions.html#actiondefinition
*/