fix: folder scripts are not executed if request script is not enabled (#7646)

* fix: folder scripts are not executed if request script is not enabled

* fix: move test script to folder

* fix: lint error

* fix: tear down folder env
This commit is contained in:
Hexxa 2024-07-03 15:10:08 +08:00 committed by GitHub
parent 191acf0298
commit 1ba964ea5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 83 additions and 51 deletions

View File

@ -205,6 +205,10 @@ resources:
environmentPropertyOrder: null
metaSortKey: -1668533312225
_type: request_group
preRequestScript: |-
insomnia.environment.set('onlySetByFolderPreScript', 888);
afterResponseScript: |-
insomnia.environment.unset('onlySetByFolderPreScript');
- _id: req_89dade2ee9ee42fbb22d588783a9df3c
parentId: fld_01de564274824ecaad272330339ea6b2
modified: 1636707449231
@ -1194,3 +1198,32 @@ resources:
"setByScript": "{{ setByScript }}"
}
_type: request
- _id: req_89dade2ee9ee42fbb22d588783a9df20
parentId: fld_01de564274824ecaad272330339ea6b2
modified: 1636707449231
created: 1636141014552
url: http://127.0.0.1:4010/echo
name: run parent scripts only
description: ""
method: POST
parameters: []
headers:
- name: 'Content-Type'
value: 'application/json'
authentication: {}
metaSortKey: -1636141014553
isPrivate: false
settingStoreCookies: true
settingSendCookies: true
settingDisableRenderRequestBody: false
settingEncodeUrl: true
settingRebuildPath: true
settingFollowRedirects: global
preRequestScript: ''
body:
mimeType: "application/json"
text: |-
{
"onlySetByFolderPreScript": {{ onlySetByFolderPreScript }}
}
_type: request

View File

@ -174,12 +174,12 @@ test.describe('pre-request features tests', async () => {
asyncTaskDone: true,
},
},
// {
// name: 'can manipulate global envs',
// expectedBody: {
// setByScript: 'setByScript',
// },
// },
{
name: 'run parent scripts only',
expectedBody: {
'onlySetByFolderPreScript': 888,
},
},
];
for (let i = 0; i < testCases.length; i++) {

View File

@ -105,7 +105,8 @@ export const fetchRequestData = async (requestId: string) => {
const timelinePath = pathJoin(responsesDir, responseId + '.timeline');
return { request, environment, settings, clientCertificates, caCert, activeEnvironmentId, timelinePath, responseId };
};
export const getPreRequestScriptOutput = async ({
export const tryToExecutePreRequestScript = async ({
request,
environment,
settings,
@ -122,16 +123,32 @@ export const getPreRequestScriptOutput = async ({
activeGlobalEnvironment = await models.environment.getById(workspaceMeta.activeGlobalEnvironmentId) || undefined;
}
if (!request.preRequestScript) {
const requestGroups = await db.withAncestors<Request | RequestGroup>(request, [
models.requestGroup.type,
]) as (Request | RequestGroup)[];
const folderScripts = requestGroups.reverse()
.filter(group => group?.preRequestScript)
.map((group, i) => `const fn${i} = async ()=>{
${group.preRequestScript}
}
await fn${i}();
`);
if (folderScripts.length === 0) {
return {
request,
environment,
baseEnvironment,
clientCertificates,
settings,
cookieJar,
globals: activeGlobalEnvironment,
};
}
const mutatedContext = await tryToExecutePreRequestScript({
const joinedScript = [...folderScripts].join('\n');
const mutatedContext = await tryToExecuteScript({
script: joinedScript,
request,
environment,
timelinePath,
@ -155,6 +172,7 @@ export const getPreRequestScriptOutput = async ({
clientCertificates: mutatedContext.clientCertificates || clientCertificates,
settings: mutatedContext.settings || settings,
globals: mutatedContext.globals,
cookieJar: mutatedContext.cookieJar,
};
};
@ -163,7 +181,7 @@ export const getPreRequestScriptOutput = async ({
// - If no global environment is seleted, no operation
// - If one global environment is selected, it persists content to the selected global environment (base or sub).
export async function savePatchesMadeByScript(
mutatedContext: Awaited<ReturnType<typeof tryToExecutePreRequestScript>>,
mutatedContext: Awaited<ReturnType<typeof tryToExecuteScript>>,
environment: Environment,
baseEnvironment: Environment,
activeGlobalEnvironment: Environment | undefined,
@ -334,29 +352,15 @@ interface RequestContextForScript {
cookieJar: CookieJar;
globals?: Environment; // there could be no global environment
}
type RequestAndContextAndResponse = RequestContextForScript & {
response: sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse;
};
type RequestAndContextAndOptionalResponse = RequestContextForScript & {
script: string;
response?: sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse;
};
export async function tryToExecutePreRequestScript(context: RequestContextForScript) {
const requestGroups = await db.withAncestors<Request | RequestGroup>(context.request, [
models.requestGroup.type,
]) as (Request | RequestGroup)[];
const folderScripts = requestGroups.reverse()
.filter(group => group?.preRequestScript)
.map((group, i) => `const fn${i} = async ()=>{
${group.preRequestScript}
}
await fn${i}();
`);
const joinedScript = [...folderScripts].join('\n');
return tryToExecuteScript({ script: joinedScript, ...context });
};
export async function tryToExecuteAfterResponseScript(context: RequestAndContextAndResponse) {
const requestGroups = await db.withAncestors<Request | RequestGroup>(context.request, [
@ -370,9 +374,18 @@ export async function tryToExecuteAfterResponseScript(context: RequestAndContext
}
await fn${i}();
`);
if (folderScripts.length === 0) {
return context;
}
const joinedScript = [...folderScripts].join('\n');
return tryToExecuteScript({ script: joinedScript, ...context });
const postMutatedContext = await tryToExecuteScript({ script: joinedScript, ...context });
if (!postMutatedContext?.request) {
return null;
}
await savePatchesMadeByScript(postMutatedContext, context.environment, context.baseEnvironment, context.globals);
return postMutatedContext;
}
export const tryToInterpolateRequest = async (

View File

@ -26,7 +26,7 @@ import { Response } from '../../models/response';
import { isWebSocketRequest, isWebSocketRequestId, WebSocketRequest } from '../../models/websocket-request';
import { WebSocketResponse } from '../../models/websocket-response';
import { getAuthHeader } from '../../network/authentication';
import { fetchRequestData, getPreRequestScriptOutput, responseTransform, savePatchesMadeByScript, sendCurlAndWriteTimeline, tryToExecuteAfterResponseScript, tryToInterpolateRequest, tryToTransformRequestWithPlugins } from '../../network/network';
import { fetchRequestData, responseTransform, sendCurlAndWriteTimeline, tryToExecuteAfterResponseScript, tryToExecutePreRequestScript, tryToInterpolateRequest, tryToTransformRequestWithPlugins } from '../../network/network';
import { RenderErrorSubType } from '../../templating';
import { invariant } from '../../utils/invariant';
import { SegmentEvent } from '../analytics';
@ -367,8 +367,9 @@ export const sendAction: ActionFunction = async ({ request, params }) => {
try {
window.main.startExecution({ requestId });
const requestData = await fetchRequestData(requestId);
window.main.addExecutionStep({ requestId, stepName: 'Executing pre-request script' });
const mutatedContext = await getPreRequestScriptOutput(requestData, workspaceId);
const mutatedContext = await tryToExecutePreRequestScript(requestData, workspaceId);
window.main.completeExecutionStep({ requestId });
if (mutatedContext === null) {
return null;
@ -421,29 +422,14 @@ export const sendAction: ActionFunction = async ({ request, params }) => {
const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath;
mutatedContext.request.afterResponseScript = afterResponseScript;
if (requestData.request.afterResponseScript) {
const baseEnvironment = await models.environment.getOrCreateForParentId(workspaceId);
const cookieJar = await models.cookieJar.getOrCreateForParentId(workspaceId);
const globals = mutatedContext.globals;
window.main.addExecutionStep({ requestId, stepName: 'Executing after-response script' });
await tryToExecuteAfterResponseScript({
...requestData,
...mutatedContext,
response,
});
window.main.completeExecutionStep({ requestId });
window.main.addExecutionStep({ requestId, stepName: 'Executing after-response script' });
const postMutatedContext = await tryToExecuteAfterResponseScript({
...requestData,
...mutatedContext,
baseEnvironment,
cookieJar,
response,
globals,
});
window.main.completeExecutionStep({ requestId });
if (!postMutatedContext?.request) {
// exiy early if there was a problem with the pre-request script
// TODO: improve error message?
return null;
}
await savePatchesMadeByScript(postMutatedContext, requestData.environment, baseEnvironment, globals);
}
if (!shouldWriteToFile) {
const response = await models.response.create(responsePatch, requestData.settings.maxHistoryResponses);
await models.requestMeta.update(requestMeta, { activeResponseId: response._id });