mirror of
https://github.com/Kong/insomnia.git
synced 2026-10-20 05:53:31 -04:00
Scope responses to active environment (#1905)
* Scope responses to active environment * Update response history to support scoped envs
This commit is contained in:
1 parent
6200c9e8c7
commit
de2fc0ba42
12 files changed
+230
-94
No files matched your search
@@ -137,6 +137,30 @@ describe('exportHar()', () => {
|
||||
req3.headers.push({ name: 'X-Request', value: '3' });
|
||||
await models.request.create(req3);
|
||||
|
||||
const envBase = await models.environment.getOrCreateForWorkspace(workspace);
|
||||
await models.environment.update(envBase, {
|
||||
data: {
|
||||
envvalue: '',
|
||||
},
|
||||
});
|
||||
const envPublic = await models.environment.create({
|
||||
_id: 'env_1',
|
||||
name: 'Public',
|
||||
parentId: envBase._id,
|
||||
data: {
|
||||
envvalue: 'public',
|
||||
},
|
||||
});
|
||||
const envPrivate = await models.environment.create({
|
||||
_id: 'env_2',
|
||||
name: 'Private',
|
||||
isPrivate: true,
|
||||
parentId: envBase._id,
|
||||
data: {
|
||||
envvalue: 'private',
|
||||
},
|
||||
});
|
||||
|
||||
await models.response.create({
|
||||
_id: 'res_1',
|
||||
parentId: req1._id,
|
||||
@@ -153,36 +177,8 @@ describe('exportHar()', () => {
|
||||
statusCode: 500,
|
||||
});
|
||||
|
||||
const envBase = await models.environment.getOrCreateForWorkspace(workspace);
|
||||
await models.environment.update(envBase, {
|
||||
data: {
|
||||
envvalue: '',
|
||||
},
|
||||
});
|
||||
const envPublic = await models.environment.create({
|
||||
_id: 'env_1',
|
||||
name: 'Public',
|
||||
parentId: envBase._id,
|
||||
});
|
||||
await models.environment.update(envPublic, {
|
||||
data: {
|
||||
envvalue: 'public',
|
||||
},
|
||||
});
|
||||
const envPrivate = await models.environment.create({
|
||||
_id: 'env_2',
|
||||
name: 'Private',
|
||||
isPrivate: true,
|
||||
parentId: envBase._id,
|
||||
});
|
||||
await models.environment.update(envPrivate, {
|
||||
data: {
|
||||
envvalue: 'private',
|
||||
},
|
||||
});
|
||||
|
||||
const exportRequests = [
|
||||
{ requestId: req1._id, environmentId: 'n/a' },
|
||||
{ requestId: req1._id, environmentId: null },
|
||||
{ requestId: req2._id, environmentId: envPublic._id },
|
||||
{ requestId: req3._id, environmentId: envPrivate._id },
|
||||
];
|
||||
|
||||
@@ -171,7 +171,7 @@ export type Har = {
|
||||
|
||||
export type ExportRequest = {
|
||||
requestId: string,
|
||||
environmentId: string,
|
||||
environmentId: string | null,
|
||||
};
|
||||
|
||||
export async function exportHar(exportRequests: Array<ExportRequest>): Promise<Har> {
|
||||
@@ -191,6 +191,7 @@ export async function exportHar(exportRequests: Array<ExportRequest>): Promise<H
|
||||
|
||||
const response: ResponseModel | null = await models.response.getLatestForRequest(
|
||||
exportRequest.requestId,
|
||||
exportRequest.environmentId || null,
|
||||
);
|
||||
const harResponse = await exportHarResponse(response);
|
||||
if (!harResponse) {
|
||||
@@ -276,7 +277,7 @@ export async function exportHarRequest(
|
||||
|
||||
export async function exportHarWithRequest(
|
||||
request: Request,
|
||||
environmentId: string,
|
||||
environmentId: string | null,
|
||||
addContentLength: boolean = false,
|
||||
): Promise<HarRequest | null> {
|
||||
try {
|
||||
|
||||
@@ -28,6 +28,7 @@ export type ResponseTimelineEntry = {
|
||||
};
|
||||
|
||||
type BaseResponse = {
|
||||
environmentId: string | null,
|
||||
statusCode: number,
|
||||
statusMessage: string,
|
||||
httpVersion: string,
|
||||
@@ -52,6 +53,7 @@ export type Response = BaseModel & BaseResponse;
|
||||
|
||||
export function init(): BaseResponse {
|
||||
return {
|
||||
environmentId: '__LEGACY__',
|
||||
statusCode: 0,
|
||||
statusMessage: '',
|
||||
httpVersion: '',
|
||||
@@ -80,10 +82,14 @@ export async function migrate(doc: Object) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
export async function hookDatabaseInit() {
|
||||
await models.response.cleanDeletedResponses();
|
||||
|
||||
export function hookDatabaseInit() {
|
||||
console.log('Init responses DB');
|
||||
process.nextTick(async () => {
|
||||
await models.response.cleanDeletedResponses();
|
||||
|
||||
// Can remove this after March 2020
|
||||
await addLegacyEnvironmentId();
|
||||
});
|
||||
}
|
||||
|
||||
export function hookRemove(doc: Response) {
|
||||
@@ -103,24 +109,57 @@ export async function all(): Promise<Array<Response>> {
|
||||
return db.all(type);
|
||||
}
|
||||
|
||||
export async function removeForRequest(parentId: string) {
|
||||
await db.removeWhere(type, { parentId });
|
||||
export async function removeForRequest(parentId: string, environmentId?: string | null) {
|
||||
const q: Object = {
|
||||
parentId,
|
||||
};
|
||||
|
||||
// Only add if not undefined. null is not the same as undefined
|
||||
// null: find responses sent from base environment
|
||||
// undefined: find all responses
|
||||
if (environmentId !== undefined) {
|
||||
q.environmentId = environmentId;
|
||||
}
|
||||
|
||||
// Also delete legacy responses here or else the user will be confused as to
|
||||
// why some responses are still showing in the UI.
|
||||
await db.removeWhere(type, { $or: [q, { parentId, environmentId: '__LEGACY__' }] });
|
||||
}
|
||||
|
||||
export function remove(response: Response) {
|
||||
return db.remove(response);
|
||||
}
|
||||
|
||||
export async function findRecentForRequest(
|
||||
async function _findRecentForRequest(
|
||||
requestId: string,
|
||||
environmentId: string | null,
|
||||
limit: number,
|
||||
): Promise<Array<Response>> {
|
||||
const responses = await db.findMostRecentlyModified(type, { parentId: requestId }, limit);
|
||||
return responses;
|
||||
const q = {
|
||||
parentId: requestId,
|
||||
environmentId: environmentId,
|
||||
};
|
||||
|
||||
return db.findMostRecentlyModified(
|
||||
type,
|
||||
{
|
||||
$or: [
|
||||
q,
|
||||
{
|
||||
parentId: requestId,
|
||||
environmentId: '__LEGACY__',
|
||||
},
|
||||
],
|
||||
},
|
||||
limit,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getLatestForRequest(requestId: string): Promise<Response | null> {
|
||||
const responses = await findRecentForRequest(requestId, 1);
|
||||
export async function getLatestForRequest(
|
||||
requestId: string,
|
||||
environmentId: string | null,
|
||||
): Promise<Response | null> {
|
||||
const responses = await _findRecentForRequest(requestId, environmentId, 1);
|
||||
const response = (responses[0]: ?Response);
|
||||
return response || null;
|
||||
}
|
||||
@@ -283,6 +322,33 @@ async function migrateTimelineToFileSystem(doc: Object) {
|
||||
}
|
||||
}
|
||||
|
||||
async function addLegacyEnvironmentId() {
|
||||
const all = await db.all(type);
|
||||
|
||||
// Bail early if none yet. This is mostly here so tests don't
|
||||
// get impacted
|
||||
if (all.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to query on the __LEGACY__ value so we need
|
||||
// to migrate it into the DB to make that possible. If we
|
||||
// don't do that, it will exist on queried document by default
|
||||
// but won't actually be in the DB.
|
||||
const promises = [];
|
||||
const flushId = await db.bufferChanges();
|
||||
for (const doc of all) {
|
||||
if (doc.environmentId !== '__LEGACY__') {
|
||||
continue;
|
||||
}
|
||||
|
||||
promises.push(db.docUpdate(doc));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
await db.flushChanges(flushId);
|
||||
}
|
||||
|
||||
export async function cleanDeletedResponses() {
|
||||
const responsesDir = path.join(getDataDirectory(), 'responses');
|
||||
mkdirp.sync(responsesDir);
|
||||
@@ -303,6 +369,10 @@ export async function cleanDeletedResponses() {
|
||||
continue;
|
||||
}
|
||||
|
||||
fs.unlinkSync(path.join(responsesDir, filePath));
|
||||
try {
|
||||
fs.unlinkSync(path.join(responsesDir, filePath));
|
||||
} catch (err) {
|
||||
// Just keep going, doesn't matter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,25 +60,27 @@ import { cookiesFromJar, jarFromCookies } from 'insomnia-cookies';
|
||||
import { urlMatchesCertHost } from './url-matches-cert-host';
|
||||
import aws4 from 'aws4';
|
||||
import { buildMultipart } from './multipart';
|
||||
import type { Environment } from '../models/environment';
|
||||
|
||||
export type ResponsePatch = {|
|
||||
statusMessage?: string,
|
||||
error?: string,
|
||||
url?: string,
|
||||
statusCode?: number,
|
||||
bytesContent?: number,
|
||||
bodyPath?: string,
|
||||
bodyCompression?: 'zip' | null,
|
||||
message?: string,
|
||||
httpVersion?: string,
|
||||
headers?: Array<ResponseHeader>,
|
||||
elapsedTime?: number,
|
||||
contentType?: string,
|
||||
bodyPath?: string,
|
||||
bytesContent?: number,
|
||||
bytesRead?: number,
|
||||
contentType?: string,
|
||||
elapsedTime?: number,
|
||||
environmentId?: string | null,
|
||||
error?: string,
|
||||
headers?: Array<ResponseHeader>,
|
||||
httpVersion?: string,
|
||||
message?: string,
|
||||
parentId?: string,
|
||||
settingStoreCookies?: boolean,
|
||||
settingSendCookies?: boolean,
|
||||
settingStoreCookies?: boolean,
|
||||
statusCode?: number,
|
||||
statusMessage?: string,
|
||||
timelinePath?: string,
|
||||
url?: string,
|
||||
|};
|
||||
|
||||
// Time since user's last keypress to wait before making the request
|
||||
@@ -101,6 +103,7 @@ export async function _actuallySend(
|
||||
renderContext: Object,
|
||||
workspace: Workspace,
|
||||
settings: Settings,
|
||||
environment: Environment | null,
|
||||
): Promise<ResponsePatch> {
|
||||
return new Promise(async resolve => {
|
||||
let timeline: Array<ResponseTimelineEntry> = [];
|
||||
@@ -124,9 +127,11 @@ export async function _actuallySend(
|
||||
): Promise<void> {
|
||||
const timelinePath = await storeTimeline(timeline);
|
||||
|
||||
const environmentId = environment ? environment._id : null;
|
||||
const responsePatchBeforeHooks = Object.assign(
|
||||
({
|
||||
timelinePath,
|
||||
environmentId,
|
||||
parentId: renderedRequest._id,
|
||||
bodyCompression: null, // Will default to .zip otherwise
|
||||
bodyPath: bodyPath || '',
|
||||
@@ -719,14 +724,14 @@ export async function _actuallySend(
|
||||
|
||||
// Return the response data
|
||||
const responsePatch = {
|
||||
headers,
|
||||
contentType,
|
||||
statusCode,
|
||||
headers,
|
||||
httpVersion,
|
||||
statusCode,
|
||||
statusMessage,
|
||||
elapsedTime: curl.getInfo(Curl.info.TOTAL_TIME) * 1000,
|
||||
bytesRead: curl.getInfo(Curl.info.SIZE_DOWNLOAD),
|
||||
bytesContent: responseBodyBytes,
|
||||
bytesRead: curl.getInfo(Curl.info.SIZE_DOWNLOAD),
|
||||
elapsedTime: curl.getInfo(Curl.info.TOTAL_TIME) * 1000,
|
||||
url: curl.getInfo(Curl.info.EFFECTIVE_URL),
|
||||
};
|
||||
|
||||
@@ -749,7 +754,14 @@ export async function _actuallySend(
|
||||
statusMessage = 'Abort';
|
||||
}
|
||||
|
||||
respond({ statusMessage, error }, null, true);
|
||||
respond(
|
||||
{
|
||||
statusMessage,
|
||||
error,
|
||||
},
|
||||
null,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
curl.perform();
|
||||
@@ -790,6 +802,8 @@ export async function sendWithSettings(
|
||||
parentId: request._id,
|
||||
});
|
||||
|
||||
const environment: Environment | null = await models.environment.getById(environmentId || 'n/a');
|
||||
|
||||
let renderResult: { request: RenderedRequest, context: Object };
|
||||
try {
|
||||
renderResult = await getRenderedRequestAndContext(newRequest, environmentId);
|
||||
@@ -797,12 +811,18 @@ export async function sendWithSettings(
|
||||
throw new Error(`Failed to render request: ${requestId}`);
|
||||
}
|
||||
|
||||
return _actuallySend(renderResult.request, renderResult.context, workspace, settings);
|
||||
return _actuallySend(
|
||||
renderResult.request,
|
||||
renderResult.context,
|
||||
workspace,
|
||||
settings,
|
||||
environment,
|
||||
);
|
||||
}
|
||||
|
||||
export async function send(
|
||||
requestId: string,
|
||||
environmentId: string | null,
|
||||
environmentId?: string,
|
||||
extraInfo?: ExtraRenderInfo,
|
||||
): Promise<ResponsePatch> {
|
||||
console.log(`[network] Sending req=${requestId}`);
|
||||
@@ -834,9 +854,11 @@ export async function send(
|
||||
throw new Error(`Failed to find request to send for ${requestId}`);
|
||||
}
|
||||
|
||||
const environment: Environment | null = await models.environment.getById(environmentId || 'n/a');
|
||||
|
||||
const renderResult = await getRenderedRequestAndContext(
|
||||
request,
|
||||
environmentId,
|
||||
environmentId || null,
|
||||
RENDER_PURPOSE_SEND,
|
||||
extraInfo,
|
||||
);
|
||||
@@ -858,13 +880,14 @@ export async function send(
|
||||
);
|
||||
} catch (err) {
|
||||
return {
|
||||
url: renderedRequestBeforePlugins.url,
|
||||
parentId: renderedRequestBeforePlugins._id,
|
||||
environmentId: environmentId,
|
||||
error: err.message,
|
||||
statusCode: STATUS_CODE_PLUGIN_ERROR,
|
||||
statusMessage: err.plugin ? `Plugin ${err.plugin.name}` : 'Plugin',
|
||||
parentId: renderedRequestBeforePlugins._id,
|
||||
settingSendCookies: renderedRequestBeforePlugins.settingSendCookies,
|
||||
settingStoreCookies: renderedRequestBeforePlugins.settingStoreCookies,
|
||||
statusCode: STATUS_CODE_PLUGIN_ERROR,
|
||||
statusMessage: err.plugin ? `Plugin ${err.plugin.name}` : 'Plugin',
|
||||
url: renderedRequestBeforePlugins.url,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -873,6 +896,7 @@ export async function send(
|
||||
renderedContextBeforePlugins,
|
||||
workspace,
|
||||
settings,
|
||||
environment,
|
||||
);
|
||||
|
||||
console.log(
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { ExtraRenderInfo } from '../../common/render';
|
||||
export function init(activeEnvironmentId: string | null): { network: Object } {
|
||||
const network = {
|
||||
async sendRequest(request: Request, extraInfo?: ExtraRenderInfo): Promise<Response> {
|
||||
const responsePatch = await send(request._id, activeEnvironmentId, extraInfo);
|
||||
const responsePatch = await send(request._id, activeEnvironmentId || undefined, extraInfo);
|
||||
const settings = await models.settings.getOrCreate();
|
||||
return models.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
},
|
||||
|
||||
@@ -15,15 +15,17 @@ import TimeFromNow from '../time-from-now';
|
||||
import type { Response } from '../../../models/response';
|
||||
import type { RequestVersion } from '../../../models/request-version';
|
||||
import { decompressObject } from '../../../common/misc';
|
||||
import type { Environment } from '../../../models/environment';
|
||||
|
||||
type Props = {
|
||||
handleSetActiveResponse: Response => Promise<void>,
|
||||
handleDeleteResponses: (requestId: string) => Promise<void>,
|
||||
handleDeleteResponses: (requestId: string, environmentId: string | null) => Promise<void>,
|
||||
handleDeleteResponse: Response => Promise<void>,
|
||||
requestId: string,
|
||||
responses: Array<Response>,
|
||||
requestVersions: Array<RequestVersion>,
|
||||
activeResponse: Response,
|
||||
activeEnvironment: ?Environment,
|
||||
};
|
||||
|
||||
@autobind
|
||||
@@ -35,7 +37,9 @@ class ResponseHistoryDropdown extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
_handleDeleteResponses() {
|
||||
this.props.handleDeleteResponses(this.props.requestId);
|
||||
const { requestId, activeEnvironment } = this.props;
|
||||
const environmentId = activeEnvironment ? activeEnvironment._id : null;
|
||||
this.props.handleDeleteResponses(requestId, environmentId);
|
||||
}
|
||||
|
||||
_handleDeleteResponse() {
|
||||
@@ -97,34 +101,39 @@ class ResponseHistoryDropdown extends React.PureComponent<Props> {
|
||||
renderPastResponses(responses: Array<Response>) {
|
||||
const now = moment();
|
||||
// Four arrays for four time groups
|
||||
const categories = [[], [], [], []];
|
||||
const categories = { minutes: [], hours: [], today: [], week: [], other: [] };
|
||||
responses.forEach(r => {
|
||||
const resTime = moment(r.modified);
|
||||
const resTime = moment(r.created);
|
||||
if (now.diff(resTime, 'minutes') < 5) {
|
||||
// Five minutes ago
|
||||
categories[0].push(r);
|
||||
categories.minutes.push(r);
|
||||
} else if (now.diff(resTime, 'hours') < 2) {
|
||||
// Two hours ago
|
||||
categories[1].push(r);
|
||||
categories.hours.push(r);
|
||||
} else if (now.isSame(resTime, 'day')) {
|
||||
// Today
|
||||
categories[2].push(r);
|
||||
categories.today.push(r);
|
||||
} else if (now.isSame(resTime, 'week')) {
|
||||
// This week
|
||||
categories[3].push(r);
|
||||
categories.week.push(r);
|
||||
} else {
|
||||
// Older
|
||||
categories.other.push(r);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<DropdownDivider>5 Minutes Ago</DropdownDivider>
|
||||
{categories[0].map(this.renderDropdownItem)}
|
||||
{categories.minutes.map(this.renderDropdownItem)}
|
||||
<DropdownDivider>2 Hours Ago</DropdownDivider>
|
||||
{categories[1].map(this.renderDropdownItem)}
|
||||
{categories.hours.map(this.renderDropdownItem)}
|
||||
<DropdownDivider>Today</DropdownDivider>
|
||||
{categories[2].map(this.renderDropdownItem)}
|
||||
{categories.today.map(this.renderDropdownItem)}
|
||||
<DropdownDivider>This Week</DropdownDivider>
|
||||
{categories[3].map(this.renderDropdownItem)}
|
||||
{categories.week.map(this.renderDropdownItem)}
|
||||
<DropdownDivider>Older Than This Week</DropdownDivider>
|
||||
{categories.other.map(this.renderDropdownItem)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
@@ -136,9 +145,12 @@ class ResponseHistoryDropdown extends React.PureComponent<Props> {
|
||||
handleDeleteResponses, // eslint-disable-line no-unused-vars
|
||||
handleDeleteResponse, // eslint-disable-line no-unused-vars
|
||||
responses,
|
||||
activeEnvironment,
|
||||
...extraProps
|
||||
} = this.props;
|
||||
|
||||
const environmentName = activeEnvironment ? activeEnvironment.name : 'Base';
|
||||
|
||||
const isLatestResponseActive = !responses.length || activeResponse._id === responses[0]._id;
|
||||
|
||||
return (
|
||||
@@ -155,7 +167,9 @@ class ResponseHistoryDropdown extends React.PureComponent<Props> {
|
||||
<i className="fa fa-caret-down space-left" />
|
||||
)}
|
||||
</DropdownButton>
|
||||
<DropdownDivider>Response History</DropdownDivider>
|
||||
<DropdownDivider>
|
||||
<strong>{environmentName}</strong> Responses
|
||||
</DropdownDivider>
|
||||
<DropdownItem buttonClass={PromptButton} addIcon onClick={this._handleDeleteResponse}>
|
||||
<i className="fa fa-trash-o" />
|
||||
Delete Current Response
|
||||
|
||||
@@ -30,6 +30,7 @@ import { hotKeyRefs } from '../../common/hotkeys';
|
||||
import type { RequestVersion } from '../../models/request-version';
|
||||
import { showError } from '../components/modals/index';
|
||||
import { json as jsonPrettify } from 'insomnia-prettify';
|
||||
import type { Environment } from '../../models/environment';
|
||||
|
||||
type Props = {
|
||||
// Functions
|
||||
@@ -59,6 +60,7 @@ type Props = {
|
||||
requestVersions: Array<RequestVersion>,
|
||||
request: ?Request,
|
||||
response: ?Response,
|
||||
environment: ?Environment,
|
||||
};
|
||||
|
||||
@autobind
|
||||
@@ -183,6 +185,7 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
editorIndentSize,
|
||||
editorKeyMap,
|
||||
editorLineWrapping,
|
||||
environment,
|
||||
filter,
|
||||
disableResponsePreviewLinks,
|
||||
filterHistory,
|
||||
@@ -289,6 +292,7 @@ class ResponsePane extends React.PureComponent<Props> {
|
||||
</div>
|
||||
<ResponseHistoryDropdown
|
||||
activeResponse={response}
|
||||
activeEnvironment={environment}
|
||||
responses={responses}
|
||||
requestVersions={requestVersions}
|
||||
requestId={request._id}
|
||||
|
||||
@@ -308,14 +308,14 @@ class Wrapper extends React.PureComponent<Props, State> {
|
||||
showModal(RequestSettingsModal, { request: this.props.activeRequest });
|
||||
}
|
||||
|
||||
async _handleDeleteResponses(): Promise<void> {
|
||||
if (!this.props.activeRequest) {
|
||||
console.warn('Tried to delete responses when request not active');
|
||||
return;
|
||||
}
|
||||
async _handleDeleteResponses(requestId: string, environmentId: string | null): Promise<void> {
|
||||
const { handleSetActiveResponse, activeRequest } = this.props;
|
||||
|
||||
await models.response.removeForRequest(this.props.activeRequest._id);
|
||||
this._handleSetActiveResponse(null);
|
||||
await models.response.removeForRequest(requestId, environmentId);
|
||||
|
||||
if (activeRequest && activeRequest._id === requestId) {
|
||||
await handleSetActiveResponse(requestId, null);
|
||||
}
|
||||
}
|
||||
|
||||
async _handleDeleteResponse(response: Response): Promise<void> {
|
||||
@@ -853,6 +853,7 @@ class Wrapper extends React.PureComponent<Props, State> {
|
||||
editorIndentSize={settings.editorIndentSize}
|
||||
editorKeyMap={settings.editorKeyMap}
|
||||
editorLineWrapping={settings.editorLineWrapping}
|
||||
environment={activeEnvironment}
|
||||
filter={responseFilter}
|
||||
filterHistory={responseFilterHistory}
|
||||
handleDeleteResponse={this._handleDeleteResponse}
|
||||
|
||||
@@ -709,6 +709,7 @@ class App extends PureComponent {
|
||||
}
|
||||
|
||||
async _handleSetActiveResponse(requestId, activeResponse = null) {
|
||||
const { activeEnvironment } = this.props;
|
||||
const activeResponseId = activeResponse ? activeResponse._id : null;
|
||||
await App._updateRequestMetaByParentId(requestId, { activeResponseId });
|
||||
|
||||
@@ -716,7 +717,8 @@ class App extends PureComponent {
|
||||
if (activeResponseId) {
|
||||
response = await models.response.getById(activeResponseId);
|
||||
} else {
|
||||
response = await models.response.getLatestForRequest(requestId);
|
||||
const environmentId = activeEnvironment ? activeEnvironment._id : null;
|
||||
response = await models.response.getLatestForRequest(requestId, environmentId);
|
||||
}
|
||||
|
||||
const requestVersionId = response ? response.requestVersionId : 'n/a';
|
||||
|
||||
@@ -269,10 +269,19 @@ export const selectActiveRequestMeta = createSelector(
|
||||
export const selectActiveRequestResponses = createSelector(
|
||||
selectActiveRequest,
|
||||
selectEntitiesLists,
|
||||
(activeRequest, entities) => {
|
||||
selectActiveWorkspaceMeta,
|
||||
(activeRequest, entities, meta) => {
|
||||
const requestId = activeRequest ? activeRequest._id : 'n/a';
|
||||
return entities.responses
|
||||
.filter(response => requestId === response.parentId)
|
||||
.filter(response => {
|
||||
const requestMatches = requestId === response.parentId;
|
||||
const environmentMatches = response.environmentId === meta.activeEnvironmentId;
|
||||
|
||||
// Legacy responses were sent before environment scoping existed
|
||||
const isLegacy = response.environmentId === '__LEGACY__';
|
||||
|
||||
return requestMatches && (environmentMatches || isLegacy);
|
||||
})
|
||||
.sort((a, b) => (a.created > b.created ? -1 : 1));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -533,6 +533,9 @@ function _genTestContext(requests, responses, extraInfoRoot) {
|
||||
return {
|
||||
renderPurpose: 'send',
|
||||
context: {
|
||||
getEnvironmentId() {
|
||||
return null;
|
||||
},
|
||||
getExtraInfo(key) {
|
||||
if (_extraInfo) {
|
||||
return _extraInfo[key] || null;
|
||||
|
||||
@@ -2,6 +2,10 @@ const jq = require('jsonpath');
|
||||
const iconv = require('iconv-lite');
|
||||
const { query: queryXPath } = require('insomnia-xpath');
|
||||
|
||||
function isFilterableField(field) {
|
||||
return field !== 'raw' && field !== 'url';
|
||||
}
|
||||
|
||||
module.exports.templateTags = [
|
||||
{
|
||||
name: 'response',
|
||||
@@ -27,6 +31,11 @@ module.exports.templateTags = [
|
||||
description: 'value of response header',
|
||||
value: 'header',
|
||||
},
|
||||
{
|
||||
displayName: 'Request URL',
|
||||
description: 'Url of initiating request',
|
||||
value: 'url',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -37,7 +46,7 @@ module.exports.templateTags = [
|
||||
{
|
||||
type: 'string',
|
||||
encoding: 'base64',
|
||||
hide: args => args[0].value === 'raw',
|
||||
hide: args => !isFilterableField(args[0].value),
|
||||
displayName: args => {
|
||||
switch (args[0].value) {
|
||||
case 'body':
|
||||
@@ -77,7 +86,7 @@ module.exports.templateTags = [
|
||||
filter = filter || '';
|
||||
resendBehavior = (resendBehavior || 'never').toLowerCase();
|
||||
|
||||
if (!['body', 'header', 'raw'].includes(field)) {
|
||||
if (!['body', 'header', 'raw', 'url'].includes(field)) {
|
||||
throw new Error(`Invalid response field ${field}`);
|
||||
}
|
||||
|
||||
@@ -90,7 +99,8 @@ module.exports.templateTags = [
|
||||
throw new Error(`Could not find request ${id}`);
|
||||
}
|
||||
|
||||
let response = await context.util.models.response.getLatestForRequestId(id);
|
||||
const environmentId = context.context.getEnvironmentId();
|
||||
let response = await context.util.models.response.getLatestForRequestId(id, environmentId);
|
||||
|
||||
let shouldResend = false;
|
||||
if (context.context.getExtraInfo('fromResponseTag')) {
|
||||
@@ -132,7 +142,7 @@ module.exports.templateTags = [
|
||||
throw new Error('No successful responses for request');
|
||||
}
|
||||
|
||||
if (field !== 'raw' && !filter) {
|
||||
if (isFilterableField(field) && !filter) {
|
||||
throw new Error(`No ${field} filter specified`);
|
||||
}
|
||||
|
||||
@@ -140,6 +150,8 @@ module.exports.templateTags = [
|
||||
|
||||
if (field === 'header') {
|
||||
return matchHeader(response.headers, sanitizedFilter);
|
||||
} else if (field === 'url') {
|
||||
return response.url;
|
||||
} else if (field === 'raw') {
|
||||
const bodyBuffer = context.util.models.response.getBodyBuffer(response, '');
|
||||
const match = response.contentType.match(/charset=([\w-]+)/);
|
||||
|
||||
Reference in new issue
Block a user