diff --git a/packages/insomnia-app/app/common/render.js b/packages/insomnia-app/app/common/render.js index 212eb5da34..7b41e7ad6a 100644 --- a/packages/insomnia-app/app/common/render.js +++ b/packages/insomnia-app/app/common/render.js @@ -193,7 +193,7 @@ export async function getRenderContext( request: Request, environmentId: string, ancestors: Array | null = null, - purpose: string | null = null, + purpose: RenderPurpose | null = null, ): Promise { if (!ancestors) { ancestors = await db.withAncestors(request, [ @@ -218,7 +218,7 @@ export async function getRenderContext( keySource[key] = 'root'; } if (subEnvironment) { - for (let key in subEnvironment.data || {}) { + for (const key of Object.keys(subEnvironment.data || {})) { if (subEnvironment.name) { keySource[key] = subEnvironment.name; } @@ -232,7 +232,7 @@ export async function getRenderContext( ancestor.hasOwnProperty('environment') && ancestor.hasOwnProperty('name') ) { - for (let key in ancestor.environment || {}) { + for (const key of Object.keys(ancestor.environment || {})) { keySource[key] = ancestor.name || ''; } } @@ -252,6 +252,8 @@ export async function getRenderContext( baseContext.getPurpose = () => purpose; + baseContext.getEnvironmentId = () => environmentId; + // Generate the context we need to render return buildRenderContext(ancestors, rootEnvironment, subEnvironment, baseContext); } @@ -259,7 +261,7 @@ export async function getRenderContext( export async function getRenderedRequestAndContext( request: Request, environmentId: string, - purpose?: string, + purpose?: RenderPurpose, ): Promise<{ request: RenderedRequest, context: Object }> { const ancestors = await db.withAncestors(request, [ models.request.type, @@ -315,7 +317,6 @@ export async function getRenderedRequestAndContext( context: renderContext, request: { // Add the yummy cookies - // TODO: Eventually get rid of RenderedRequest type and put these elsewhere cookieJar: renderedCookieJar, cookies: [], isPrivate: false, @@ -349,7 +350,7 @@ export async function getRenderedRequestAndContext( export async function getRenderedRequest( request: Request, environmentId: string, - purpose?: string, + purpose?: RenderPurpose, ): Promise { const result = await getRenderedRequestAndContext(request, environmentId, purpose); return result.request; diff --git a/packages/insomnia-app/app/plugins/context/index.js b/packages/insomnia-app/app/plugins/context/index.js index 0dc04585db..6ebfe18b28 100644 --- a/packages/insomnia-app/app/plugins/context/index.js +++ b/packages/insomnia-app/app/plugins/context/index.js @@ -3,8 +3,10 @@ import * as _app from './app'; import * as _store from './store'; import * as _request from './request'; import * as _response from './response'; +import * as _network from './network'; export const app = _app; export const store = _store; export const request = _request; export const response = _response; +export const network = _network; diff --git a/packages/insomnia-app/app/plugins/context/network.js b/packages/insomnia-app/app/plugins/context/network.js new file mode 100644 index 0000000000..b85b4fc2e4 --- /dev/null +++ b/packages/insomnia-app/app/plugins/context/network.js @@ -0,0 +1,17 @@ +// @flow + +import { send } from '../../network/network'; +import type { Request } from '../../models/request'; +import * as models from '../../models'; + +export function init(activeEnvironmentId: string): { network: Object } { + const network = { + async sendRequest(request: Request): Promise { + const responsePatch = await send(request._id, activeEnvironmentId); + const settings = await models.settings.getOrCreate(); + return models.response.create(responsePatch, settings.maxHistoryResponses); + }, + }; + + return { network }; +} diff --git a/packages/insomnia-app/app/templating/base-extension.js b/packages/insomnia-app/app/templating/base-extension.js index 4328c35245..a177c8d4d1 100644 --- a/packages/insomnia-app/app/templating/base-extension.js +++ b/packages/insomnia-app/app/templating/base-extension.js @@ -70,6 +70,9 @@ export default class BaseExtension { // Pull out the purpose const renderPurpose = renderContext.getPurpose ? renderContext.getPurpose() : null; + // Pull out the environment ID + const environmentId = renderContext.getEnvironmentId ? renderContext.getEnvironmentId() : 'n/a'; + // Extract the rest of the args const args = runArgs.slice(0, runArgs.length - 1).filter(a => a !== EMPTY_ARG); @@ -77,8 +80,10 @@ export default class BaseExtension { const helperContext = { ...pluginContexts.app.init(renderPurpose), ...pluginContexts.store.init(this._plugin), + ...pluginContexts.network.init(environmentId), context: renderContext, meta: renderMeta, + renderPurpose, util: { render: str => templating.render(str, { context: renderContext }), models: { diff --git a/plugins/insomnia-plugin-response/index.js b/plugins/insomnia-plugin-response/index.js index f23f7bf2dc..6e811e7e0c 100644 --- a/plugins/insomnia-plugin-response/index.js +++ b/plugins/insomnia-plugin-response/index.js @@ -48,9 +48,31 @@ module.exports.templateTags = [ } }, }, + { + displayName: 'Trigger Behavior', + help: 'Configure when to resend the dependent request', + type: 'enum', + options: [ + { + displayName: 'Always', + description: 'resend request when needed', + value: 'ALWAYS', + }, + { + displayName: 'Sometimes', + description: 'resend when no response exists yet', + value: 'NO_HISTORY', + }, + { + displayName: 'Never', + description: 'never resend request', + value: 'NEVER', + }, + ], + }, ], - async run(context, field, id, filter) { + async run(context, field, id, filter, resendBehavior) { filter = filter || ''; if (!['body', 'header', 'raw'].includes(field)) { @@ -66,7 +88,22 @@ module.exports.templateTags = [ throw new Error(`Could not find request ${id}`); } - const response = await context.util.models.response.getLatestForRequestId(id); + let response = await context.util.models.response.getLatestForRequestId(id); + + let shouldResend = false; + if (resendBehavior === 'ALWAYS') { + shouldResend = true; + } else if (resendBehavior === 'NO_HISTORY' && !response) { + shouldResend = true; + } else if (resendBehavior === 'NEVER') { + shouldResend = false; + } + + // Resend dependent request if needed but only if we're rendering for a send + if (shouldResend && (!response || context.renderPurpose === 'send')) { + console.log('[response tag] Resending dependency'); + response = await context.network.sendRequest(request); + } if (!response) { throw new Error('No responses for request');