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 environmentPropertyOrder: null
metaSortKey: -1668533312225 metaSortKey: -1668533312225
_type: request_group _type: request_group
preRequestScript: |-
insomnia.environment.set('onlySetByFolderPreScript', 888);
afterResponseScript: |-
insomnia.environment.unset('onlySetByFolderPreScript');
- _id: req_89dade2ee9ee42fbb22d588783a9df3c - _id: req_89dade2ee9ee42fbb22d588783a9df3c
parentId: fld_01de564274824ecaad272330339ea6b2 parentId: fld_01de564274824ecaad272330339ea6b2
modified: 1636707449231 modified: 1636707449231
@ -1194,3 +1198,32 @@ resources:
"setByScript": "{{ setByScript }}" "setByScript": "{{ setByScript }}"
} }
_type: request _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, asyncTaskDone: true,
}, },
}, },
// { {
// name: 'can manipulate global envs', name: 'run parent scripts only',
// expectedBody: { expectedBody: {
// setByScript: 'setByScript', 'onlySetByFolderPreScript': 888,
// }, },
// }, },
]; ];
for (let i = 0; i < testCases.length; i++) { 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'); const timelinePath = pathJoin(responsesDir, responseId + '.timeline');
return { request, environment, settings, clientCertificates, caCert, activeEnvironmentId, timelinePath, responseId }; return { request, environment, settings, clientCertificates, caCert, activeEnvironmentId, timelinePath, responseId };
}; };
export const getPreRequestScriptOutput = async ({
export const tryToExecutePreRequestScript = async ({
request, request,
environment, environment,
settings, settings,
@ -122,16 +123,32 @@ export const getPreRequestScriptOutput = async ({
activeGlobalEnvironment = await models.environment.getById(workspaceMeta.activeGlobalEnvironmentId) || undefined; 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 { return {
request, request,
environment, environment,
baseEnvironment, baseEnvironment,
clientCertificates, clientCertificates,
settings, settings,
cookieJar,
globals: activeGlobalEnvironment,
}; };
} }
const mutatedContext = await tryToExecutePreRequestScript({ const joinedScript = [...folderScripts].join('\n');
const mutatedContext = await tryToExecuteScript({
script: joinedScript,
request, request,
environment, environment,
timelinePath, timelinePath,
@ -155,6 +172,7 @@ export const getPreRequestScriptOutput = async ({
clientCertificates: mutatedContext.clientCertificates || clientCertificates, clientCertificates: mutatedContext.clientCertificates || clientCertificates,
settings: mutatedContext.settings || settings, settings: mutatedContext.settings || settings,
globals: mutatedContext.globals, globals: mutatedContext.globals,
cookieJar: mutatedContext.cookieJar,
}; };
}; };
@ -163,7 +181,7 @@ export const getPreRequestScriptOutput = async ({
// - If no global environment is seleted, no operation // - 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). // - If one global environment is selected, it persists content to the selected global environment (base or sub).
export async function savePatchesMadeByScript( export async function savePatchesMadeByScript(
mutatedContext: Awaited<ReturnType<typeof tryToExecutePreRequestScript>>, mutatedContext: Awaited<ReturnType<typeof tryToExecuteScript>>,
environment: Environment, environment: Environment,
baseEnvironment: Environment, baseEnvironment: Environment,
activeGlobalEnvironment: Environment | undefined, activeGlobalEnvironment: Environment | undefined,
@ -334,29 +352,15 @@ interface RequestContextForScript {
cookieJar: CookieJar; cookieJar: CookieJar;
globals?: Environment; // there could be no global environment globals?: Environment; // there could be no global environment
} }
type RequestAndContextAndResponse = RequestContextForScript & { type RequestAndContextAndResponse = RequestContextForScript & {
response: sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse; response: sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse;
}; };
type RequestAndContextAndOptionalResponse = RequestContextForScript & { type RequestAndContextAndOptionalResponse = RequestContextForScript & {
script: string; script: string;
response?: sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse; 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) { export async function tryToExecuteAfterResponseScript(context: RequestAndContextAndResponse) {
const requestGroups = await db.withAncestors<Request | RequestGroup>(context.request, [ const requestGroups = await db.withAncestors<Request | RequestGroup>(context.request, [
@ -370,9 +374,18 @@ export async function tryToExecuteAfterResponseScript(context: RequestAndContext
} }
await fn${i}(); await fn${i}();
`); `);
if (folderScripts.length === 0) {
return context;
}
const joinedScript = [...folderScripts].join('\n'); 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 ( export const tryToInterpolateRequest = async (

View File

@ -26,7 +26,7 @@ import { Response } from '../../models/response';
import { isWebSocketRequest, isWebSocketRequestId, WebSocketRequest } from '../../models/websocket-request'; import { isWebSocketRequest, isWebSocketRequestId, WebSocketRequest } from '../../models/websocket-request';
import { WebSocketResponse } from '../../models/websocket-response'; import { WebSocketResponse } from '../../models/websocket-response';
import { getAuthHeader } from '../../network/authentication'; 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 { RenderErrorSubType } from '../../templating';
import { invariant } from '../../utils/invariant'; import { invariant } from '../../utils/invariant';
import { SegmentEvent } from '../analytics'; import { SegmentEvent } from '../analytics';
@ -367,8 +367,9 @@ export const sendAction: ActionFunction = async ({ request, params }) => {
try { try {
window.main.startExecution({ requestId }); window.main.startExecution({ requestId });
const requestData = await fetchRequestData(requestId); const requestData = await fetchRequestData(requestId);
window.main.addExecutionStep({ requestId, stepName: 'Executing pre-request script' }); 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 }); window.main.completeExecutionStep({ requestId });
if (mutatedContext === null) { if (mutatedContext === null) {
return null; return null;
@ -421,29 +422,14 @@ export const sendAction: ActionFunction = async ({ request, params }) => {
const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath; const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath;
mutatedContext.request.afterResponseScript = afterResponseScript; mutatedContext.request.afterResponseScript = afterResponseScript;
if (requestData.request.afterResponseScript) { window.main.addExecutionStep({ requestId, stepName: 'Executing after-response script' });
const baseEnvironment = await models.environment.getOrCreateForParentId(workspaceId); await tryToExecuteAfterResponseScript({
const cookieJar = await models.cookieJar.getOrCreateForParentId(workspaceId); ...requestData,
const globals = mutatedContext.globals; ...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) { if (!shouldWriteToFile) {
const response = await models.response.create(responsePatch, requestData.settings.maxHistoryResponses); const response = await models.response.create(responsePatch, requestData.settings.maxHistoryResponses);
await models.requestMeta.update(requestMeta, { activeResponseId: response._id }); await models.requestMeta.update(requestMeta, { activeResponseId: response._id });