mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-22 23:28:33 -04:00
Fix/fetch body (#6134)
* fix body, extract backoff * fix two way commands * add docs * fix ai calls and errors
This commit is contained in:
@@ -103,7 +103,7 @@ export async function changePasswordWithToken(rawNewPassphrase: string, confirma
|
||||
return window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
path: '/auth/change-password',
|
||||
obj: {
|
||||
data: {
|
||||
code: confirmationCode,
|
||||
newEmail: newEmail,
|
||||
encSymmetricKey: encSymmetricKey,
|
||||
@@ -252,7 +252,7 @@ function _getAuthSalts(email: string) {
|
||||
return window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
path: '/auth/login-s',
|
||||
obj: { email },
|
||||
data: { email },
|
||||
sessionId: getCurrentSessionId(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,75 +1,65 @@
|
||||
import { parse as urlParse } from 'url';
|
||||
import { BrowserWindow, net } from 'electron';
|
||||
|
||||
import { getApiBaseURL, getClientString } from '../common/constants';
|
||||
import { delay } from '../common/misc';
|
||||
import { invariant } from '../utils/invariant';
|
||||
|
||||
const _commandListeners: Function[] = [];
|
||||
export function onCommand(callback: Function) {
|
||||
_commandListeners.push(callback);
|
||||
}
|
||||
|
||||
let _userAgent = getClientString();
|
||||
let _baseUrl = getApiBaseURL();
|
||||
|
||||
export function setup(userAgent: string, baseUrl: string) {
|
||||
_userAgent = userAgent;
|
||||
_baseUrl = baseUrl;
|
||||
}
|
||||
interface FetchConfig {
|
||||
method: 'POST' | 'PUT' | 'GET';
|
||||
path: string;
|
||||
sessionId: string | null;
|
||||
obj?: unknown;
|
||||
data?: unknown;
|
||||
retries?: number;
|
||||
origin?: string;
|
||||
}
|
||||
export async function insomniaFetch<T = any>({ method, path, obj, sessionId, retries = 0 }: FetchConfig): Promise<T | string> {
|
||||
const config: {
|
||||
method: string;
|
||||
headers: Record<string, string>;
|
||||
body?: string | Buffer;
|
||||
} = {
|
||||
method: method,
|
||||
// internal request (insomniaFetch)
|
||||
// should validate ssl certs on our server
|
||||
// should only go to insomnia API
|
||||
// should be able to listen for specific messages in headers
|
||||
// should be able to retry on 502
|
||||
|
||||
// external request (axiosRequest)
|
||||
// should respect settings for proxy and ssl validation
|
||||
// should be for all third party APIs, github, gitlab, isometric-git
|
||||
|
||||
const exponentialBackOff = async (url: string, init: RequestInit, retries = 0): Promise<Response> => {
|
||||
try {
|
||||
const response = await net.fetch(url, init);
|
||||
if (response.status === 502 && retries < 5) {
|
||||
retries++;
|
||||
await delay(retries * 200);
|
||||
return exponentialBackOff(url, init, retries);
|
||||
}
|
||||
if (!response.ok) {
|
||||
const err = new Error(`Response ${response.status} for ${url}`);
|
||||
err.message = await response.text();
|
||||
throw err;
|
||||
}
|
||||
return response;
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to fetch ${url}: ${err.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
export async function insomniaFetch<T = any>({ method, path, data, sessionId, origin }: FetchConfig): Promise<T | string> {
|
||||
const config: RequestInit = {
|
||||
method,
|
||||
headers: {
|
||||
'X-Insomnia-Client': getClientString(),
|
||||
...(sessionId ? { 'X-Session-Id': sessionId } : {}),
|
||||
...(_userAgent ? { 'X-Insomnia-Client': _userAgent } : {}),
|
||||
...(obj ? { 'Content-Type': 'application/json' } : {}),
|
||||
...(obj ? { body: JSON.stringify(obj) } : {}),
|
||||
...(data ? { 'Content-Type': 'application/json' } : {}),
|
||||
},
|
||||
...(data ? { body: JSON.stringify(data) } : {}),
|
||||
};
|
||||
if (sessionId === undefined) {
|
||||
throw new Error(`No session ID provided to ${method}:${path}`);
|
||||
}
|
||||
|
||||
invariant(_baseUrl, 'API base URL not configured!');
|
||||
const url = `${_baseUrl}${path}`;
|
||||
let response: Response | undefined;
|
||||
try {
|
||||
response = await window.fetch(url, config);
|
||||
|
||||
// Exponential backoff for 502 errors
|
||||
if (response.status === 502 && retries < 5) {
|
||||
retries++;
|
||||
await delay(retries * 200);
|
||||
return insomniaFetch({ method, path, obj, sessionId, retries });
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to fetch '${url}'`);
|
||||
}
|
||||
|
||||
const response = await exponentialBackOff(`${origin || getApiBaseURL()}${path}`, config);
|
||||
const uri = response.headers.get('x-insomnia-command');
|
||||
if (uri) {
|
||||
const parsed = urlParse(uri, true);
|
||||
_commandListeners.map(fn => fn(`${parsed.hostname}${parsed.pathname}`, JSON.parse(JSON.stringify(parsed.query))));
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
window.webContents.send('shell:open', uri);
|
||||
}
|
||||
}
|
||||
if (!response.ok) {
|
||||
const err = new Error(`Response ${response.status} for ${path}`);
|
||||
err.message = await response.text();
|
||||
// @ts-expect-error -- TSCONVERSION
|
||||
err.statusCode = response.status;
|
||||
throw err;
|
||||
}
|
||||
|
||||
const isJson = response.headers.get('content-type') === 'application/json' || path.match(/\.json$/);
|
||||
return isJson ? response.json() : response.text();
|
||||
}
|
||||
|
||||
@@ -712,7 +712,7 @@ export class VCS {
|
||||
const { data, errors } = await window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
path: '/graphql?' + name,
|
||||
obj: { query, variables },
|
||||
data: { query, variables },
|
||||
sessionId,
|
||||
});
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ export const Toast: FC = () => {
|
||||
const notificationOrEmpty = await window.main.insomniaFetch<ToastNotification>({
|
||||
method: 'POST',
|
||||
path: '/notification',
|
||||
obj: data,
|
||||
data,
|
||||
sessionId: session.getCurrentSessionId(),
|
||||
});
|
||||
if (notificationOrEmpty && typeof notificationOrEmpty !== 'string') {
|
||||
|
||||
@@ -626,13 +626,11 @@ export const generateCollectionAndTestsAction: ActionFunction = async ({ params
|
||||
|
||||
const methodInfo = resolveComponentSchemaRefs(spec, getMethodInfo(request));
|
||||
|
||||
const response = await window.main.axiosRequest({
|
||||
const response = await window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
url: 'https://ai.insomnia.rest/v1/generate-test',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Session-Id': session.getCurrentSessionId(),
|
||||
},
|
||||
origin: 'https://ai.insomnia.rest',
|
||||
path: '/v1/generate-test',
|
||||
sessionId: session.getCurrentSessionId(),
|
||||
data: {
|
||||
teamId: organizationId,
|
||||
request: requests.find(r => r._id === test.requestId),
|
||||
@@ -709,13 +707,11 @@ export const generateTestsAction: ActionFunction = async ({ params }) => {
|
||||
for (const test of tests) {
|
||||
async function generateTest() {
|
||||
try {
|
||||
const response = await window.main.axiosRequest({
|
||||
const response = await window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
url: 'https://ai.insomnia.rest/v1/generate-test',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Session-Id': session.getCurrentSessionId(),
|
||||
},
|
||||
origin: 'https://ai.insomnia.rest',
|
||||
path: '/v1/generate-test',
|
||||
sessionId: session.getCurrentSessionId(),
|
||||
data: {
|
||||
teamId: organizationId,
|
||||
request: requests.find(r => r._id === test.requestId),
|
||||
@@ -753,13 +749,11 @@ export const accessAIApiAction: ActionFunction = async ({ params }) => {
|
||||
invariant(typeof workspaceId === 'string', 'Workspace ID is required');
|
||||
|
||||
try {
|
||||
const response = await window.main.axiosRequest({
|
||||
const response = await window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
url: 'https://ai.insomnia.rest/v1/access',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Session-Id': session.getCurrentSessionId(),
|
||||
},
|
||||
origin: 'https://ai.insomnia.rest',
|
||||
path: '/v1/access',
|
||||
sessionId: session.getCurrentSessionId(),
|
||||
data: {
|
||||
teamId: organizationId,
|
||||
},
|
||||
|
||||
@@ -30,6 +30,7 @@ import { showError, showModal } from '../components/modals';
|
||||
import { AlertModal } from '../components/modals/alert-modal';
|
||||
import { AskModal } from '../components/modals/ask-modal';
|
||||
import { ImportModal } from '../components/modals/import-modal';
|
||||
import { LoginModal } from '../components/modals/login-modal';
|
||||
import {
|
||||
SettingsModal,
|
||||
TAB_INDEX_PLUGINS,
|
||||
@@ -133,6 +134,14 @@ const Root = () => {
|
||||
});
|
||||
break;
|
||||
|
||||
case 'insomnia://app/auth/login':
|
||||
showModal(LoginModal, {
|
||||
title: params.title,
|
||||
message: params.message,
|
||||
reauth: true,
|
||||
});
|
||||
break;
|
||||
|
||||
case 'insomnia://app/import':
|
||||
setImportUri(params.uri);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user