mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-20 14:17:29 -04:00
feat: migrate models to insomnia-data - p6 (#9763)
This commit is contained in:
@@ -10,8 +10,6 @@ import { pick } from 'es-toolkit';
|
||||
import { isDevelopment, JSON_ORDER_PREFIX, JSON_ORDER_SEPARATOR } from 'insomnia/src/common/constants';
|
||||
import { insomniaFetch } from 'insomnia/src/common/insomnia-fetch';
|
||||
import { getSendRequestCallbackMemDb } from 'insomnia/src/common/send-request';
|
||||
import type { Request } from 'insomnia/src/models/request';
|
||||
import type { RequestGroup } from 'insomnia/src/models/request-group';
|
||||
import { deserializeNDJSON } from 'insomnia/src/utils/ndjson';
|
||||
import { configureFetch } from 'insomnia-api';
|
||||
import { generate, runTestsCli } from 'insomnia-testing';
|
||||
@@ -19,7 +17,7 @@ import orderedJSON from 'json-order';
|
||||
import { parseArgsStringToArgv } from 'string-argv';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import type { Environment, UserUploadEnvironment, Workspace } from '~/insomnia-data';
|
||||
import type { Environment, Request, RequestGroup, UserUploadEnvironment, Workspace } from '~/insomnia-data';
|
||||
import { initServices, models } from '~/insomnia-data';
|
||||
import { servicesNodeImpl } from '~/insomnia-data/node';
|
||||
|
||||
|
||||
@@ -4,8 +4,14 @@ import nodePath from 'node:path';
|
||||
import type { Consola } from 'consola';
|
||||
import { pick } from 'es-toolkit';
|
||||
|
||||
import type { Environment, UserUploadEnvironment, Workspace } from '~/insomnia-data';
|
||||
import type { Request, RequestAuthentication, RequestHeader } from '~/models/request';
|
||||
import type {
|
||||
Environment,
|
||||
Request,
|
||||
RequestAuthentication,
|
||||
RequestHeader,
|
||||
UserUploadEnvironment,
|
||||
Workspace,
|
||||
} from '~/insomnia-data';
|
||||
import { typedKeys } from '~/utils';
|
||||
|
||||
import type { RequestTestResult } from '../../../../insomnia-scripting-environment/src/objects';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { OAuth2ResponseType, RequestAuthentication } from 'insomnia/src/models/request';
|
||||
import type { OAuth1SignatureMethod } from 'insomnia/src/network/o-auth-1/constants';
|
||||
|
||||
import type { OAuth2ResponseType, RequestAuthentication } from '~/insomnia-data';
|
||||
|
||||
import { Property } from './properties';
|
||||
import { Variable, VariableList } from './variables';
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { expect } from 'chai';
|
||||
import type { RequestHeader } from 'insomnia/src/models/request';
|
||||
import { filterClientCertificates } from 'insomnia/src/network/certificate';
|
||||
|
||||
import type { ClientCertificate, Settings } from '~/insomnia-data';
|
||||
import type { ClientCertificate, RequestHeader, Settings } from '~/insomnia-data';
|
||||
|
||||
import { toPreRequestAuth } from './auth';
|
||||
import { getExistingConsole } from './console';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { Request } from 'insomnia/src/models/request';
|
||||
import type { sendCurlAndWriteTimelineError, sendCurlAndWriteTimelineResponse } from 'insomnia/src/network/network';
|
||||
|
||||
import type { ClientCertificate, CookieJar, Settings } from '~/insomnia-data';
|
||||
import type { ClientCertificate, CookieJar, Request, Settings } from '~/insomnia-data';
|
||||
|
||||
import type { ExecutionOption } from './execution';
|
||||
import type { RequestInfoOption } from './request-info';
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type {
|
||||
ClientCertificate,
|
||||
Request as InsomniaRequest,
|
||||
RequestBody as InsomniaRequestBody,
|
||||
RequestBodyParameter,
|
||||
RequestPathParameter,
|
||||
} from 'insomnia/src/models/request';
|
||||
|
||||
import type { Settings } from '~/insomnia-data';
|
||||
import { type ClientCertificate, models } from '~/insomnia-data';
|
||||
Settings,
|
||||
} from '~/insomnia-data';
|
||||
import { models } from '~/insomnia-data';
|
||||
|
||||
import { type AuthOptions, type AuthOptionTypes, fromPreRequestAuth, RequestAuth } from './auth';
|
||||
import type { CertificateOptions } from './certificates';
|
||||
|
||||
@@ -2,13 +2,11 @@ import path from 'node:path';
|
||||
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import type { Cookie } from '~/insomnia-data';
|
||||
import type { Cookie, Request, Response } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import { database as db } from '../../common/database';
|
||||
import * as models from '../../models';
|
||||
import type { Request } from '../../models/request';
|
||||
import type { Response } from '../../models/response';
|
||||
import { exportHar, exportHarResponse, exportHarWithRequest } from '../har';
|
||||
import { getRenderedRequestAndContext } from '../render';
|
||||
|
||||
@@ -25,7 +23,7 @@ describe('export', () => {
|
||||
_id: 'wrk_1',
|
||||
name: 'Workspace',
|
||||
});
|
||||
const req1 = await models.request.create({
|
||||
const req1 = await services.request.create({
|
||||
_id: 'req_1',
|
||||
name: 'Request 1',
|
||||
parentId: wrk._id,
|
||||
@@ -52,7 +50,7 @@ describe('export', () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
await models.response.create({
|
||||
await services.response.create({
|
||||
parentId: req1._id,
|
||||
statusCode: 200,
|
||||
statusMessage: 'OK',
|
||||
@@ -149,7 +147,7 @@ describe('export', () => {
|
||||
_id: 'wrk_1',
|
||||
name: 'Workspace',
|
||||
});
|
||||
const baseReq = await models.request.create({
|
||||
const baseReq = await services.request.create({
|
||||
_id: 'req_0',
|
||||
type: models.request.type,
|
||||
name: 'Request',
|
||||
@@ -164,30 +162,30 @@ describe('export', () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
const req1 = await models.request.duplicate(baseReq);
|
||||
const req1 = await services.request.duplicate(baseReq);
|
||||
req1._id = 'req_1';
|
||||
req1.name = 'Request 1';
|
||||
req1.headers.push({
|
||||
name: 'X-Request',
|
||||
value: '1',
|
||||
});
|
||||
await models.request.create(req1);
|
||||
const req2 = await models.request.duplicate(baseReq);
|
||||
await services.request.create(req1);
|
||||
const req2 = await services.request.duplicate(baseReq);
|
||||
req2._id = 'req_2';
|
||||
req2.name = 'Request 2';
|
||||
req2.headers.push({
|
||||
name: 'X-Request',
|
||||
value: '2',
|
||||
});
|
||||
await models.request.create(req2);
|
||||
const req3 = await models.request.duplicate(baseReq);
|
||||
await services.request.create(req2);
|
||||
const req3 = await services.request.duplicate(baseReq);
|
||||
req3._id = 'req_3';
|
||||
req3.name = 'Request 3';
|
||||
req3.headers.push({
|
||||
name: 'X-Request',
|
||||
value: '3',
|
||||
});
|
||||
await models.request.create(req3);
|
||||
await services.request.create(req3);
|
||||
const envBase = await services.environment.getOrCreateForParentId(workspace._id);
|
||||
await services.environment.update(envBase, {
|
||||
data: {
|
||||
@@ -211,17 +209,17 @@ describe('export', () => {
|
||||
envvalue: 'private',
|
||||
},
|
||||
});
|
||||
await models.response.create({
|
||||
await services.response.create({
|
||||
_id: 'res_1',
|
||||
parentId: req1._id,
|
||||
statusCode: 204,
|
||||
});
|
||||
await models.response.create({
|
||||
await services.response.create({
|
||||
_id: 'res_2',
|
||||
parentId: req2._id,
|
||||
statusCode: 404,
|
||||
});
|
||||
await models.response.create({
|
||||
await services.response.create({
|
||||
_id: 'res_3',
|
||||
parentId: req3._id,
|
||||
statusCode: 500,
|
||||
|
||||
@@ -6,7 +6,6 @@ import { parse } from 'yaml';
|
||||
|
||||
import { EnvironmentKvPairDataType, EnvironmentType, services } from '~/insomnia-data';
|
||||
|
||||
import { request, requestGroup } from '../../models';
|
||||
import * as importUtil from '../import';
|
||||
import { INSOMNIA_SCHEMA_VERSION } from '../insomnia-schema-migrations/schema-version';
|
||||
import { tryImportV5Data } from '../insomnia-v5';
|
||||
@@ -162,7 +161,7 @@ describe('importRaw()', () => {
|
||||
|
||||
const workspacesCount = await services.workspace.count();
|
||||
const projectWorkspaces = await services.workspace.findByParentId(projectToImportTo._id);
|
||||
const curlRequests = await request.findByParentId(projectWorkspaces[0]._id);
|
||||
const curlRequests = await services.request.findByParentId(projectWorkspaces[0]._id);
|
||||
|
||||
expect(workspacesCount).toBe(1);
|
||||
|
||||
@@ -192,7 +191,7 @@ describe('importRaw()', () => {
|
||||
workspaceId: existingWorkspace._id,
|
||||
});
|
||||
|
||||
const curlRequests = await request.findByParentId(existingWorkspace._id);
|
||||
const curlRequests = await services.request.findByParentId(existingWorkspace._id);
|
||||
|
||||
expect(curlRequests[0]).toMatchObject({
|
||||
body: {
|
||||
@@ -220,8 +219,8 @@ describe('importRaw()', () => {
|
||||
|
||||
const projectWorkspaces = await services.workspace.findByParentId(projectToImportTo._id);
|
||||
|
||||
const requestGroups = await requestGroup.findByParentId(projectWorkspaces[0]._id);
|
||||
const requests = await request.findByParentId(requestGroups[0]._id);
|
||||
const requestGroups = await services.requestGroup.findByParentId(projectWorkspaces[0]._id);
|
||||
const requests = await services.request.findByParentId(requestGroups[0]._id);
|
||||
|
||||
expect(requests[0]).toMatchObject({
|
||||
url: 'https://insomnia.rest',
|
||||
@@ -247,8 +246,8 @@ describe('importRaw()', () => {
|
||||
workspaceId: existingWorkspace._id,
|
||||
});
|
||||
|
||||
const requestGroups = await requestGroup.findByParentId(existingWorkspace._id);
|
||||
const requests = await request.findByParentId(requestGroups[0]._id);
|
||||
const requestGroups = await services.requestGroup.findByParentId(existingWorkspace._id);
|
||||
const requests = await services.request.findByParentId(requestGroups[0]._id);
|
||||
|
||||
expect(requests[0]).toMatchObject({
|
||||
url: 'https://insomnia.rest',
|
||||
@@ -495,7 +494,7 @@ describe('importRaw()', () => {
|
||||
const workspaces = await importUtil.importResourcesToProject({ projectId: proj._id });
|
||||
expect(workspaces).toHaveLength(1);
|
||||
|
||||
const reqs = await request.findByParentId(workspaces[0]._id);
|
||||
const reqs = await services.request.findByParentId(workspaces[0]._id);
|
||||
expect(reqs).toHaveLength(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import YAML from 'yaml';
|
||||
|
||||
import type { Request } from '~/insomnia-data';
|
||||
import { EnvironmentKvPairDataType, services } from '~/insomnia-data';
|
||||
|
||||
import { INSOMNIA_SCHEMA_VERSION } from '../../common/insomnia-schema-migrations/schema-version';
|
||||
import * as models from '../../models';
|
||||
import type { Request } from '../../models/request';
|
||||
import { database as db } from '../database';
|
||||
import {
|
||||
getInsomniaV5DataExport,
|
||||
@@ -168,7 +167,7 @@ collection: []
|
||||
scope: 'collection',
|
||||
});
|
||||
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
_id: 'req_export_test',
|
||||
name: 'Export Test Request',
|
||||
parentId: workspace._id,
|
||||
@@ -244,7 +243,7 @@ collection: []
|
||||
data: {},
|
||||
});
|
||||
|
||||
const req1 = await models.request.create({
|
||||
const req1 = await services.request.create({
|
||||
_id: 'req_filter_1',
|
||||
name: 'Request 1',
|
||||
parentId: workspace._id,
|
||||
@@ -252,7 +251,7 @@ collection: []
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
_id: 'req_filter_2',
|
||||
name: 'Request 2',
|
||||
parentId: workspace._id,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { RequestHeader } from '~/insomnia-data';
|
||||
|
||||
import allCharsets from '../datasets/charsets';
|
||||
import allMimeTypes from '../datasets/content-types';
|
||||
import allEncodings from '../datasets/encodings';
|
||||
import allHeaderNames from '../datasets/header-names';
|
||||
import type { RequestHeader } from '../models/request';
|
||||
|
||||
export const SINGLE_VALUE_HEADERS = [
|
||||
'proxy-authorization',
|
||||
|
||||
@@ -2,15 +2,12 @@ import clone from 'clone';
|
||||
import type * as Har from 'har-format';
|
||||
import { Cookie as ToughCookie } from 'tough-cookie';
|
||||
|
||||
import type { Workspace } from '~/insomnia-data';
|
||||
import type { Request, RequestGroup, Response, Workspace } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { getBodyBuffer } from '~/models/helpers/response-operations';
|
||||
|
||||
import type { BaseModel } from '../models';
|
||||
import * as models from '../models';
|
||||
import { isRequest, type Request } from '../models/request';
|
||||
import type { RequestGroup } from '../models/request-group';
|
||||
import type { Response } from '../models/response';
|
||||
import { getAuthHeader } from '../network/authentication';
|
||||
import * as plugins from '../plugins';
|
||||
import * as pluginApp from '../plugins/context/app';
|
||||
@@ -26,6 +23,8 @@ import { database } from './database';
|
||||
import { filterHeaders, getSetCookieHeaders, hasAuthHeader } from './misc';
|
||||
import { getRenderedRequestAndContext } from './render';
|
||||
|
||||
const { isRequest } = models.request;
|
||||
|
||||
const getDocWithDescendants =
|
||||
(includePrivateDocs = false) =>
|
||||
async (parentDoc: BaseModel | null) => {
|
||||
@@ -139,7 +138,7 @@ export async function exportHar(exportRequests: ExportRequest[]) {
|
||||
const entries: Har.Entry[] = [];
|
||||
|
||||
for (const exportRequest of exportRequests) {
|
||||
const request = await models.request.getById(exportRequest.requestId);
|
||||
const request = await services.request.getById(exportRequest.requestId);
|
||||
|
||||
if (!request) {
|
||||
continue;
|
||||
@@ -152,8 +151,8 @@ export async function exportHar(exportRequests: ExportRequest[]) {
|
||||
}
|
||||
|
||||
const response = await (exportRequest.responseId
|
||||
? models.response.getById(exportRequest.responseId)
|
||||
: models.response.getLatestForRequestId(exportRequest.requestId, exportRequest.environmentId || null));
|
||||
? services.response.getById(exportRequest.responseId)
|
||||
: services.response.getLatestForRequestId(exportRequest.requestId, exportRequest.environmentId || null));
|
||||
|
||||
const harResponse = await exportHarResponse(response);
|
||||
|
||||
@@ -227,7 +226,7 @@ export async function exportHarResponse(response?: Response) {
|
||||
}
|
||||
|
||||
export async function exportHarRequest(requestId: string, environmentId: string, addContentLength = false) {
|
||||
const request = await models.request.getById(requestId);
|
||||
const request = await services.request.getById(requestId);
|
||||
|
||||
if (!request) {
|
||||
return null;
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
GrpcRequest,
|
||||
McpRequest,
|
||||
MockRoute,
|
||||
Request,
|
||||
SocketIORequest,
|
||||
UnitTest,
|
||||
UnitTestSuite,
|
||||
@@ -24,8 +25,6 @@ import { pathWithParamsAsPathParameters } from '../main/importers/importers/open
|
||||
import { id as postmanEnvImporterId } from '../main/importers/importers/postman-env';
|
||||
import * as models from '../models/index';
|
||||
import { type AllTypes, type BaseModel, getModel } from '../models/index';
|
||||
import { isRequest, type Request } from '../models/request';
|
||||
import { isRequestGroup } from '../models/request-group';
|
||||
import { invariant } from '../utils/invariant';
|
||||
import { parseApiSpec, type ParsedApiSpec } from './api-specs';
|
||||
import { JSON_ORDER_PREFIX, JSON_ORDER_SEPARATOR } from './constants';
|
||||
@@ -33,7 +32,9 @@ import { database as db } from './database';
|
||||
import { tryImportV5Data } from './insomnia-v5';
|
||||
import { generateId } from './misc';
|
||||
|
||||
const { isRequest } = models.request;
|
||||
const { isApiSpec } = models.apiSpec;
|
||||
const { isRequestGroup } = models.requestGroup;
|
||||
|
||||
export const IMPORT_SOURCE_TYPES = ['file', 'uri', 'curl', 'clipboard', 'mcp'] as const;
|
||||
export type ImportSourceType = (typeof IMPORT_SOURCE_TYPES)[number];
|
||||
@@ -560,7 +561,7 @@ export const importResourcesToWorkspace = async ({
|
||||
} else if (models.unitTest.isUnitTest(resource)) {
|
||||
await services.unitTest.create(objectToWrite);
|
||||
} else if (isRequest(resource)) {
|
||||
await models.request.create(objectToWrite);
|
||||
await services.request.create(objectToWrite);
|
||||
} else {
|
||||
await db.docCreate(model.type, objectToWrite);
|
||||
}
|
||||
@@ -649,7 +650,7 @@ export const importResourcesToNewWorkspace = async ({
|
||||
} else if (models.unitTest.isUnitTest(resource)) {
|
||||
await services.unitTest.create(objectToWrite);
|
||||
} else if (isRequest(resource)) {
|
||||
await models.request.create(objectToWrite);
|
||||
await services.request.create(objectToWrite);
|
||||
} else {
|
||||
await db.docCreate(model.type, objectToWrite);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@ import type {
|
||||
McpRequest,
|
||||
MockRoute,
|
||||
MockServer,
|
||||
Request,
|
||||
RequestBody,
|
||||
RequestGroup,
|
||||
RequestHeader,
|
||||
RequestParameter,
|
||||
SocketIORequest,
|
||||
UnitTest,
|
||||
UnitTestSuite,
|
||||
@@ -38,8 +43,6 @@ import { maskVaultEnvironmentData } from '~/utils/environment-utils';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
|
||||
import * as models from '../models';
|
||||
import type { Request, RequestBody, RequestHeader, RequestParameter } from '../models/request';
|
||||
import type { RequestGroup } from '../models/request-group';
|
||||
import { database } from './database';
|
||||
import {
|
||||
type Insomnia_GRPCRequest,
|
||||
|
||||
@@ -6,6 +6,8 @@ import type {
|
||||
GrpcRequest,
|
||||
GrpcRequestBody,
|
||||
McpRequest,
|
||||
Request,
|
||||
RequestGroup,
|
||||
SocketIORequest,
|
||||
UserUploadEnvironment,
|
||||
WebSocketRequest,
|
||||
@@ -14,8 +16,6 @@ import type {
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import * as models from '../models';
|
||||
import { PATH_PARAMETER_REGEX, type Request } from '../models/request';
|
||||
import { isRequestGroup, type RequestGroup } from '../models/request-group';
|
||||
import { getOrInheritAuthentication, getOrInheritHeaders } from '../network/network';
|
||||
import * as templating from '../templating';
|
||||
import { RenderError } from '../templating/render-error';
|
||||
@@ -33,6 +33,9 @@ import { setDefaultProtocol } from '../utils/url/protocol';
|
||||
import { CONTENT_TYPE_GRAPHQL, JSON_ORDER_SEPARATOR } from './constants';
|
||||
import { database as db } from './database';
|
||||
|
||||
const { PATH_PARAMETER_REGEX } = models.request;
|
||||
const { isRequestGroup } = models.requestGroup;
|
||||
|
||||
export async function buildRenderContext({
|
||||
ancestors,
|
||||
rootEnvironment,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { GrpcRequest } from '~/insomnia-data';
|
||||
import type { GrpcRequest, Request, RequestGroup } from '~/insomnia-data';
|
||||
import { models } from '~/insomnia-data';
|
||||
|
||||
import { isRequest, type Request } from '../models/request';
|
||||
import { isRequestGroup, type RequestGroup } from '../models/request-group';
|
||||
import { type DashboardSortOrder, HTTP_METHODS, type SortOrder } from './constants';
|
||||
|
||||
const { isRequest } = models.request;
|
||||
const { isRequestGroup } = models.requestGroup;
|
||||
|
||||
type SortableModel = Request | RequestGroup | GrpcRequest;
|
||||
type SortFunction<SortableType> = (a: SortableType, b: SortableType) => number;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import * as fs from 'node:fs';
|
||||
|
||||
import { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron';
|
||||
|
||||
import type { Compression } from '~/insomnia-data';
|
||||
|
||||
import {
|
||||
asyncTasksAllSettled,
|
||||
OriginalPromise,
|
||||
@@ -10,7 +12,6 @@ import {
|
||||
resetAsyncTasks,
|
||||
stopMonitorAsyncTasks,
|
||||
} from '../../insomnia-scripting-environment/src/objects';
|
||||
import type { Compression } from './models/response';
|
||||
// this will also import lots of node_modules into the preload script, consider moving this file insomnia-scripting-environment
|
||||
import { requireInterceptor } from './require-interceptor';
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ describe('onChange()', () => {
|
||||
};
|
||||
|
||||
db.onChange(callback);
|
||||
const newDoc = await models.request.create(doc);
|
||||
const updatedDoc = await models.request.update(newDoc, {
|
||||
const newDoc = await services.request.create(doc);
|
||||
const updatedDoc = await services.request.update(newDoc, {
|
||||
name: 'bar',
|
||||
});
|
||||
expect(changesSeen).toEqual([[['insert', newDoc, []]], [['update', updatedDoc, [{ name: 'bar' }]]]]);
|
||||
@@ -60,9 +60,9 @@ describe('bufferChanges()', () => {
|
||||
|
||||
db.onChange(callback);
|
||||
await db.bufferChanges();
|
||||
const newDoc = await models.request.create(doc);
|
||||
const newDoc = await services.request.create(doc);
|
||||
// @ts-expect-error -- TSCONVERSION appears to be genuine
|
||||
const updatedDoc = await models.request.update(newDoc);
|
||||
const updatedDoc = await services.request.update(newDoc);
|
||||
// Assert no change seen before flush
|
||||
expect(changesSeen.length).toBe(0);
|
||||
// Assert changes seen after flush
|
||||
@@ -97,9 +97,9 @@ describe('bufferChanges()', () => {
|
||||
|
||||
db.onChange(callback);
|
||||
await db.bufferChanges();
|
||||
const newDoc = await models.request.create(doc);
|
||||
const newDoc = await services.request.create(doc);
|
||||
// @ts-expect-error -- TSCONVERSION appears to be genuine
|
||||
const updatedDoc = await models.request.update(newDoc);
|
||||
const updatedDoc = await services.request.update(newDoc);
|
||||
// Default flush timeout is 1000ms after starting buffering
|
||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||
expect(changesSeen).toEqual([
|
||||
@@ -124,9 +124,9 @@ describe('bufferChanges()', () => {
|
||||
|
||||
db.onChange(callback);
|
||||
await db.bufferChanges(500);
|
||||
const newDoc = await models.request.create(doc);
|
||||
const newDoc = await services.request.create(doc);
|
||||
// @ts-expect-error -- TSCONVERSION appears to be genuine
|
||||
const updatedDoc = await models.request.update(newDoc);
|
||||
const updatedDoc = await services.request.update(newDoc);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
expect(changesSeen).toEqual([
|
||||
[
|
||||
@@ -152,9 +152,9 @@ describe('bufferChangesIndefinitely()', () => {
|
||||
|
||||
db.onChange(callback);
|
||||
await db.bufferChangesIndefinitely();
|
||||
const newDoc = await models.request.create(doc);
|
||||
const newDoc = await services.request.create(doc);
|
||||
// @ts-expect-error -- TSCONVERSION appears to be genuine
|
||||
const updatedDoc = await models.request.update(newDoc);
|
||||
const updatedDoc = await services.request.update(newDoc);
|
||||
// Default flush timeout is 1000ms after starting buffering
|
||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||
// Assert no change seen before flush
|
||||
@@ -177,7 +177,7 @@ describe('requestCreate()', () => {
|
||||
name: 'My Request',
|
||||
parentId: 'wrk_123',
|
||||
};
|
||||
const r = await models.request.create(patch);
|
||||
const r = await services.request.create(patch);
|
||||
expect(Object.keys(r).length).toBe(24);
|
||||
expect(r._id).toMatch(/^req_[a-zA-Z0-9]{32}$/);
|
||||
expect(r.created).toBeGreaterThanOrEqual(now);
|
||||
@@ -196,7 +196,7 @@ describe('requestCreate()', () => {
|
||||
|
||||
it('throws when missing parentID', () => {
|
||||
const fn = () =>
|
||||
models.request.create({
|
||||
services.request.create({
|
||||
name: 'My Request',
|
||||
});
|
||||
|
||||
@@ -623,13 +623,13 @@ describe('duplicate()', () => {
|
||||
|
||||
it('should rewrite chained request references when duplicating a folder', async () => {
|
||||
const workspace = await services.workspace.create({ name: 'Workspace' });
|
||||
const folder = await models.requestGroup.create({ parentId: workspace._id, name: 'Folder' });
|
||||
const req1 = await models.request.create({
|
||||
const folder = await services.requestGroup.create({ parentId: workspace._id, name: 'Folder' });
|
||||
const req1 = await services.request.create({
|
||||
parentId: folder._id,
|
||||
name: 'Request 1',
|
||||
url: 'https://example.com/first',
|
||||
});
|
||||
const req2 = await models.request.create({
|
||||
const req2 = await services.request.create({
|
||||
parentId: folder._id,
|
||||
name: 'Request 2',
|
||||
url: `https://example.com/{% response 'body', '${req1._id}', 'b64::JC5pZA==::46b', 'never', 60 %}`,
|
||||
@@ -678,16 +678,16 @@ describe('withAncestors()', () => {
|
||||
const wrk = await services.workspace.create({
|
||||
parentId: spc._id,
|
||||
});
|
||||
const wrkReq = await models.request.create({
|
||||
const wrkReq = await services.request.create({
|
||||
parentId: wrk._id,
|
||||
});
|
||||
const wrkGrpcReq = await services.grpcRequest.create({
|
||||
parentId: wrk._id,
|
||||
});
|
||||
const grp = await models.requestGroup.create({
|
||||
const grp = await services.requestGroup.create({
|
||||
parentId: wrk._id,
|
||||
});
|
||||
const grpReq = await models.request.create({
|
||||
const grpReq = await services.request.create({
|
||||
parentId: grp._id,
|
||||
});
|
||||
const grpGrpcReq = await services.grpcRequest.create({
|
||||
@@ -755,19 +755,19 @@ describe('getWithDescendants()', () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
const folder1 = await models.requestGroup.create({
|
||||
const folder1 = await services.requestGroup.create({
|
||||
_id: 'grp1',
|
||||
parentId: workspace._id,
|
||||
});
|
||||
const folder2 = await models.requestGroup.create({
|
||||
const folder2 = await services.requestGroup.create({
|
||||
_id: 'grp2',
|
||||
parentId: folder1._id,
|
||||
});
|
||||
const request1 = await models.request.create({
|
||||
const request1 = await services.request.create({
|
||||
_id: 'req1',
|
||||
parentId: workspace._id,
|
||||
});
|
||||
const request2 = await models.request.create({
|
||||
const request2 = await services.request.create({
|
||||
_id: 'req2',
|
||||
parentId: folder1._id,
|
||||
});
|
||||
|
||||
@@ -18,6 +18,12 @@ import * as pluginDataService from './plugin-data';
|
||||
import * as projectService from './project';
|
||||
import * as protoDirectoryService from './proto-directory';
|
||||
import * as protoFileService from './proto-file';
|
||||
import * as requestService from './request';
|
||||
import * as requestGroupService from './request-group';
|
||||
import * as requestGroupMetaService from './request-group-meta';
|
||||
import * as requestMetaService from './request-meta';
|
||||
import * as requestVersionService from './request-version';
|
||||
import * as responseService from './response';
|
||||
import * as runnerTestResultService from './runner-test-result';
|
||||
import * as settingsService from './settings';
|
||||
import * as socketIOPayloadService from './socket-io-payload';
|
||||
@@ -53,6 +59,12 @@ export const servicesNodeImpl = {
|
||||
pluginData: pluginDataService,
|
||||
protoDirectory: protoDirectoryService,
|
||||
protoFile: protoFileService,
|
||||
request: requestService,
|
||||
requestGroup: requestGroupService,
|
||||
requestGroupMeta: requestGroupMetaService,
|
||||
requestMeta: requestMetaService,
|
||||
requestVersion: requestVersionService,
|
||||
response: responseService,
|
||||
runnerTestResult: runnerTestResultService,
|
||||
project: projectService,
|
||||
settings: settingsService,
|
||||
|
||||
@@ -3,7 +3,8 @@ import * as requestOperations from '~/models/helpers/request-operations';
|
||||
|
||||
import { database as db } from '../../src/database';
|
||||
import { type McpResponse } from '../../src/models/types';
|
||||
import * as SettingsService from './settings';
|
||||
import * as requestVersionService from './request-version';
|
||||
import * as settingsService from './settings';
|
||||
|
||||
const { type } = models.mcpResponse;
|
||||
|
||||
@@ -27,14 +28,14 @@ export async function create(patch: Partial<McpResponse> = {}, maxResponses = 20
|
||||
const { parentId } = patch;
|
||||
// Create request version snapshot
|
||||
const request = await requestOperations.getById(parentId);
|
||||
const requestVersion = request ? await models.requestVersion.create(request) : null;
|
||||
const requestVersion = request ? await requestVersionService.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const query: Record<string, any> = {
|
||||
parentId,
|
||||
};
|
||||
|
||||
if ((await SettingsService.get()).filterResponsesByEnv && 'environmentId' in patch) {
|
||||
if ((await settingsService.get()).filterResponsesByEnv && 'environmentId' in patch) {
|
||||
query.environmentId = patch.environmentId;
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ export async function updateOrCreate(patch: Partial<McpResponse>, maxResponses =
|
||||
export async function getLatestForRequestId(requestId: string, environmentId: string | null) {
|
||||
// Filter responses by environment if setting is enabled
|
||||
|
||||
const shouldFilter = (await SettingsService.get()).filterResponsesByEnv;
|
||||
const shouldFilter = (await settingsService.get()).filterResponsesByEnv;
|
||||
|
||||
const response = await db.findOne<McpResponse>(
|
||||
type,
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { RequestGroupMeta } from '~/insomnia-data';
|
||||
import { database as db, models } from '~/insomnia-data';
|
||||
|
||||
const { type } = models.requestGroupMeta;
|
||||
|
||||
export function create(patch: Partial<RequestGroupMeta> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New RequestGroupMeta missing `parentId`: ' + JSON.stringify(patch));
|
||||
}
|
||||
|
||||
return db.docCreate<RequestGroupMeta>(type, patch);
|
||||
}
|
||||
|
||||
export function update(requestGroupMeta: RequestGroupMeta, patch: Partial<RequestGroupMeta>) {
|
||||
return db.docUpdate<RequestGroupMeta>(requestGroupMeta, patch);
|
||||
}
|
||||
|
||||
export function getByParentId(parentId: string) {
|
||||
return db.findOne<RequestGroupMeta>(type, { parentId });
|
||||
}
|
||||
|
||||
export function all() {
|
||||
return db.find<RequestGroupMeta>(type);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { RequestGroup } from '~/insomnia-data';
|
||||
import { database as db, models } from '~/insomnia-data';
|
||||
|
||||
const { type } = models.requestGroup;
|
||||
|
||||
export function create(patch: Partial<RequestGroup> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New RequestGroup missing `parentId`: ' + JSON.stringify(patch));
|
||||
}
|
||||
|
||||
return db.docCreate<RequestGroup>(type, patch);
|
||||
}
|
||||
|
||||
export function update(requestGroup: RequestGroup, patch: Partial<RequestGroup> = {}) {
|
||||
return db.docUpdate<RequestGroup>(requestGroup, patch);
|
||||
}
|
||||
|
||||
export function getById(id: string) {
|
||||
return db.findOne<RequestGroup>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<RequestGroup>(type, { parentId });
|
||||
}
|
||||
|
||||
export function remove(requestGroup: RequestGroup) {
|
||||
return db.remove(requestGroup);
|
||||
}
|
||||
|
||||
export function all() {
|
||||
return db.find<RequestGroup>(type);
|
||||
}
|
||||
|
||||
export async function duplicate(requestGroup: RequestGroup, patch: Partial<RequestGroup> = {}) {
|
||||
if (!patch.name) {
|
||||
patch.name = `${requestGroup.name} (Copy)`;
|
||||
}
|
||||
|
||||
const q = {
|
||||
metaSortKey: {
|
||||
$gt: requestGroup.metaSortKey,
|
||||
},
|
||||
};
|
||||
|
||||
const [nextRequestGroup] = await db.find<RequestGroup>(type, q, {
|
||||
metaSortKey: 1,
|
||||
});
|
||||
|
||||
const nextSortKey = nextRequestGroup ? nextRequestGroup.metaSortKey : requestGroup.metaSortKey + 100;
|
||||
|
||||
// Calculate new sort key
|
||||
const sortKeyIncrement = (nextSortKey - requestGroup.metaSortKey) / 2;
|
||||
const metaSortKey = requestGroup.metaSortKey + sortKeyIncrement;
|
||||
return db.duplicate<RequestGroup>(requestGroup, {
|
||||
metaSortKey,
|
||||
...patch,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { RequestMeta } from '~/insomnia-data';
|
||||
import { database as db, models } from '~/insomnia-data';
|
||||
|
||||
const { type } = models.requestMeta;
|
||||
|
||||
export function create(patch: Partial<RequestMeta> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New RequestMeta missing `parentId` ' + JSON.stringify(patch));
|
||||
}
|
||||
|
||||
return db.docCreate<RequestMeta>(type, patch);
|
||||
}
|
||||
|
||||
export function update(requestMeta: RequestMeta, patch: Partial<RequestMeta>) {
|
||||
return db.docUpdate<RequestMeta>(requestMeta, patch);
|
||||
}
|
||||
|
||||
export function getByParentId(parentId: string): Promise<RequestMeta | undefined> {
|
||||
return db.findOne<RequestMeta>(type, { parentId });
|
||||
}
|
||||
|
||||
export async function getOrCreateByParentId(parentId: string) {
|
||||
const requestMeta = await getByParentId(parentId);
|
||||
|
||||
if (requestMeta) {
|
||||
return requestMeta;
|
||||
}
|
||||
|
||||
return create({ parentId });
|
||||
}
|
||||
|
||||
export async function updateOrCreateByParentId(parentId: string, patch: Partial<RequestMeta>) {
|
||||
const requestMeta = await getByParentId(parentId);
|
||||
|
||||
if (requestMeta) {
|
||||
return update(requestMeta, patch);
|
||||
}
|
||||
const newPatch = Object.assign(
|
||||
{
|
||||
parentId,
|
||||
},
|
||||
patch,
|
||||
);
|
||||
return create(newPatch);
|
||||
}
|
||||
|
||||
export function all() {
|
||||
return db.find<RequestMeta>(type);
|
||||
}
|
||||
@@ -1,34 +1,19 @@
|
||||
import deepEqual from 'deep-equal';
|
||||
|
||||
import type { GrpcRequest, McpRequest, SocketIORequest, WebSocketRequest } from '~/insomnia-data';
|
||||
import { models } from '~/insomnia-data';
|
||||
import { compressObject, decompressObject } from '~/common/misc';
|
||||
import type {
|
||||
GrpcRequest,
|
||||
McpRequest,
|
||||
Request,
|
||||
RequestVersion,
|
||||
SocketIORequest,
|
||||
WebSocketRequest,
|
||||
} from '~/insomnia-data';
|
||||
import { database, database as db, models } from '~/insomnia-data';
|
||||
import * as requestOperations from '~/models/helpers/request-operations';
|
||||
|
||||
import { database, database as db } from '../common/database';
|
||||
import { compressObject, decompressObject } from '../common/misc';
|
||||
import * as requestOperations from '../models/helpers/request-operations';
|
||||
import { isRequest, type Request } from './request';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
/* When viewing a specific request, the user can click the Send button to test-send it.
|
||||
Each time the user sends the request, the parameters may differ—they might edit the body, headers, and so on—and Insomnia records every sent request as history.
|
||||
When the user browses the send history for a request and selects one of the entries, the current request is restored to the exact state it had when that request was sent, including the body, headers, and other settings.
|
||||
A Request Version is essentially a snapshot of the request at the moment it was test-sent. */
|
||||
|
||||
export const name = 'Request Version';
|
||||
|
||||
export const type = 'RequestVersion';
|
||||
|
||||
export const prefix = 'rvr';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
interface BaseRequestVersion {
|
||||
compressedRequest: string | null;
|
||||
}
|
||||
|
||||
export type RequestVersion = BaseModel & BaseRequestVersion;
|
||||
const { isRequest } = models.request;
|
||||
const { type } = models.requestVersion;
|
||||
|
||||
const FIELDS_TO_IGNORE = [
|
||||
'_id',
|
||||
@@ -41,18 +26,6 @@ const FIELDS_TO_IGNORE = [
|
||||
'name',
|
||||
] as const;
|
||||
|
||||
export const isRequestVersion = (model: Pick<BaseModel, 'type'>): model is RequestVersion => model.type === type;
|
||||
|
||||
export function init() {
|
||||
return {
|
||||
compressedRequest: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: RequestVersion) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
export function getById(id: string) {
|
||||
return db.findOne<RequestVersion>(type, { _id: id });
|
||||
}
|
||||
@@ -73,7 +46,7 @@ export async function create(request: Request | WebSocketRequest | GrpcRequest |
|
||||
|
||||
const parentId = request._id;
|
||||
const latestRequestVersion = await database.findOne<RequestVersion>(
|
||||
'RequestVersion',
|
||||
type,
|
||||
{
|
||||
parentId,
|
||||
},
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { Request } from '~/insomnia-data';
|
||||
import { database as db, models } from '~/insomnia-data';
|
||||
|
||||
const { type, name } = models.request;
|
||||
|
||||
export function create(patch: Partial<Request> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error(`New Requests missing \`parentId\`: ${JSON.stringify(patch)}`);
|
||||
}
|
||||
|
||||
return db.docCreate<Request>(type, patch);
|
||||
}
|
||||
|
||||
export function getById(id: string): Promise<Request | undefined> {
|
||||
return db.findOne<Request>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function getByParentId(parentId: string) {
|
||||
return db.findOne<Request>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<Request>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export function update(request: Request, patch: Partial<Request>) {
|
||||
return db.docUpdate<Request>(request, patch);
|
||||
}
|
||||
|
||||
export async function duplicate(request: Request, patch: Partial<Request> = {}) {
|
||||
// Only set name and "(Copy)" if the patch does
|
||||
// not define it and the request itself has a name.
|
||||
// Otherwise leave it blank so the request URL can
|
||||
// fill it in automatically.
|
||||
if (!patch.name && request.name) {
|
||||
patch.name = `${request.name} (Copy)`;
|
||||
}
|
||||
|
||||
// Get sort key of next request
|
||||
const q = {
|
||||
metaSortKey: {
|
||||
$gt: request.metaSortKey,
|
||||
},
|
||||
};
|
||||
|
||||
const [nextRequest] = await db.find<Request>(type, q, {
|
||||
metaSortKey: 1,
|
||||
});
|
||||
|
||||
const nextSortKey = nextRequest ? nextRequest.metaSortKey : request.metaSortKey + 100;
|
||||
// Calculate new sort key
|
||||
const sortKeyIncrement = (nextSortKey - request.metaSortKey) / 2;
|
||||
const metaSortKey = request.metaSortKey + sortKeyIncrement;
|
||||
return db.duplicate<Request>(request, {
|
||||
name,
|
||||
metaSortKey,
|
||||
...patch,
|
||||
});
|
||||
}
|
||||
|
||||
export function remove(request: Request) {
|
||||
return db.remove(request);
|
||||
}
|
||||
|
||||
export async function all() {
|
||||
return db.find<Request>(type);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { database as db } from '~/common/database';
|
||||
import type { Response } from '~/insomnia-data';
|
||||
import { models } from '~/insomnia-data';
|
||||
import * as requestOperations from '~/models/helpers/request-operations';
|
||||
|
||||
import * as requestVersionService from './request-version';
|
||||
import * as settingsService from './settings';
|
||||
|
||||
const { type } = models.response;
|
||||
|
||||
export function getById(id: string) {
|
||||
return db.findOne<Response>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<Response>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export async function all() {
|
||||
return db.find<Response>(type);
|
||||
}
|
||||
|
||||
export async function getLatestForRequestId(
|
||||
requestId: string,
|
||||
environmentId: string | null,
|
||||
): Promise<Response | undefined> {
|
||||
// Filter responses by environment if setting is enabled
|
||||
const shouldFilter = (await settingsService.get()).filterResponsesByEnv;
|
||||
|
||||
const response = await db.findOne<Response>(
|
||||
type,
|
||||
{
|
||||
parentId: requestId,
|
||||
...(shouldFilter ? { environmentId } : {}),
|
||||
},
|
||||
{ modified: -1 },
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function create(patch: Partial<Response> = {}, maxResponses = 20): Promise<Response> {
|
||||
if (!patch.parentId) {
|
||||
console.log('[db] Attempted to create response without `parentId`', patch);
|
||||
throw new Error('New Response missing `parentId`');
|
||||
}
|
||||
|
||||
const { parentId } = patch;
|
||||
// Create request version snapshot
|
||||
const request = await requestOperations.getById(parentId);
|
||||
const requestVersion = request ? await requestVersionService.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const settings = await settingsService.get();
|
||||
const shouldQueryByEnvId = 'environmentId' in patch && settings.filterResponsesByEnv;
|
||||
const query = {
|
||||
parentId,
|
||||
...(shouldQueryByEnvId ? { environmentId: patch.environmentId } : {}),
|
||||
};
|
||||
|
||||
// Delete all other responses before creating the new one
|
||||
const responsesToShow = Math.max(1, maxResponses);
|
||||
|
||||
const allResponses = await db.find<Response>(type, query, { modified: -1 }, responsesToShow);
|
||||
|
||||
const recentIds = allResponses.map(r => r._id);
|
||||
// Remove all that were in the last query, except the first `maxResponses` IDs
|
||||
await db.removeWhere(type, {
|
||||
...query,
|
||||
_id: {
|
||||
$nin: recentIds,
|
||||
},
|
||||
});
|
||||
// Actually create the new response
|
||||
return db.docCreate(type, patch);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import * as requestOperations from '~/models/helpers/request-operations';
|
||||
|
||||
import { database as db } from '../../src/database';
|
||||
import { type SocketIOResponse } from '../../src/models/types';
|
||||
import * as requestVersionService from './request-version';
|
||||
import * as settingsService from './settings';
|
||||
|
||||
const { type } = models.socketIOResponse;
|
||||
@@ -31,7 +32,7 @@ export async function create(patch: Partial<SocketIOResponse> = {}, maxResponses
|
||||
const { parentId } = patch;
|
||||
// Create request version snapshot
|
||||
const request = await requestOperations.getById(parentId);
|
||||
const requestVersion = request ? await models.requestVersion.create(request) : null;
|
||||
const requestVersion = request ? await requestVersionService.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const query: Record<string, any> = {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { Project, Stats, Workspace } from '~/insomnia-data';
|
||||
import type { Project, RequestGroup, Stats, Workspace } from '~/insomnia-data';
|
||||
import { database as db } from '~/insomnia-data';
|
||||
import * as models from '~/models';
|
||||
import type { RequestGroup } from '~/models/request-group';
|
||||
|
||||
const { type } = models.stats;
|
||||
const { isRequest } = models.request;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { requestVersion as requestVersionModel } from '~/models';
|
||||
import * as requestOperations from '~/models/helpers/request-operations';
|
||||
|
||||
import { database as db } from '../../src/database';
|
||||
import { models } from '../../src/models';
|
||||
import { type WebSocketResponse } from '../../src/models/types';
|
||||
import * as requestVersionService from './request-version';
|
||||
import * as settingsService from './settings';
|
||||
|
||||
const { type } = models.webSocketResponse;
|
||||
@@ -28,8 +28,7 @@ export async function create(patch: Partial<WebSocketResponse> = {}, maxResponse
|
||||
const { parentId } = patch;
|
||||
// Create request version snapshot
|
||||
const request = await requestOperations.getById(parentId);
|
||||
// FIX ME, this should be changed to insomnia data model after request version is migrated
|
||||
const requestVersion = request ? await requestVersionModel.create(request) : null;
|
||||
const requestVersion = request ? await requestVersionService.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const query: Record<string, any> = {
|
||||
|
||||
@@ -19,6 +19,12 @@ import * as pluginData from './plugin-data';
|
||||
import * as project from './project';
|
||||
import * as protoDirectory from './proto-directory';
|
||||
import * as protoFile from './proto-file';
|
||||
import * as request from './request';
|
||||
import * as requestGroup from './request-group';
|
||||
import * as requestGroupMeta from './request-group-meta';
|
||||
import * as requestMeta from './request-meta';
|
||||
import * as requestVersion from './request-version';
|
||||
import * as response from './response';
|
||||
import * as runnerTestResult from './runner-test-result';
|
||||
import * as settings from './settings';
|
||||
import * as socketIOPayload from './socket-io-payload';
|
||||
@@ -51,6 +57,12 @@ export const models = {
|
||||
pluginData,
|
||||
protoDirectory,
|
||||
protoFile,
|
||||
request,
|
||||
requestGroup,
|
||||
requestGroupMeta,
|
||||
requestMeta,
|
||||
requestVersion,
|
||||
response,
|
||||
runnerTestResult,
|
||||
project,
|
||||
settings,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Root } from '@modelcontextprotocol/sdk/types.js';
|
||||
|
||||
import type { RequestAuthentication, RequestHeader } from '~/models/request';
|
||||
import type { RequestAuthentication, RequestHeader } from '~/insomnia-data';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import type { EnvironmentKvPairData } from './environment';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ResponseHeader } from '~/models/response';
|
||||
import type { ResponseHeader } from '~/insomnia-data';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import { type McpTransportType, TRANSPORT_TYPES } from './mcp-request';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RequestHeader } from '~/models/request';
|
||||
import type { RequestHeader } from '~/insomnia-data';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
export const name = 'Mock Route';
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
export const name = 'Folder Meta';
|
||||
|
||||
export const type = 'RequestGroupMeta';
|
||||
|
||||
export const prefix = 'fldm';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
interface BaseRequestGroupMeta {
|
||||
collapsed: boolean;
|
||||
}
|
||||
|
||||
export type RequestGroupMeta = BaseModel & BaseRequestGroupMeta;
|
||||
|
||||
export const isRequestGroupMeta = (model: Pick<BaseModel, 'type'>): model is RequestGroupMeta => model.type === type;
|
||||
|
||||
export function init() {
|
||||
return {
|
||||
parentId: null,
|
||||
collapsed: false,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { replaceIdsInFields } from '~/models/helpers/replace-ids-in-fields';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import type { EnvironmentKvPairData, EnvironmentType } from './environment';
|
||||
import type { RequestAuthentication, RequestHeader } from './request';
|
||||
|
||||
export const name = 'Folder';
|
||||
|
||||
export const type = 'RequestGroup';
|
||||
|
||||
export const prefix = 'fld';
|
||||
|
||||
export const canDuplicate = true;
|
||||
|
||||
export const canSync = true;
|
||||
// for those keys do not need to add in model init method
|
||||
export const optionalKeys = ['kvPairData', 'environmentType'];
|
||||
interface BaseRequestGroup {
|
||||
name: string;
|
||||
description: string;
|
||||
environment: Record<string, any>;
|
||||
environmentPropertyOrder: Record<string, any> | null;
|
||||
kvPairData?: EnvironmentKvPairData[];
|
||||
environmentType?: EnvironmentType;
|
||||
metaSortKey: number;
|
||||
preRequestScript?: string;
|
||||
afterResponseScript?: string;
|
||||
authentication?: RequestAuthentication | {};
|
||||
headers?: RequestHeader[];
|
||||
}
|
||||
|
||||
export type RequestGroup = BaseModel & BaseRequestGroup;
|
||||
|
||||
export const isRequestGroup = (model: Pick<BaseModel, 'type'>): model is RequestGroup => model.type === type;
|
||||
export const isRequestGroupId = (id?: string | null) => id?.startsWith(prefix);
|
||||
|
||||
export function init(): BaseRequestGroup {
|
||||
return {
|
||||
name: 'New Folder',
|
||||
description: '',
|
||||
environment: {},
|
||||
environmentPropertyOrder: null,
|
||||
metaSortKey: -1 * Date.now(),
|
||||
preRequestScript: undefined,
|
||||
afterResponseScript: undefined,
|
||||
authentication: undefined,
|
||||
headers: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function rewriteReferences(group: RequestGroup, idMapping: Map<string, string>): RequestGroup {
|
||||
return {
|
||||
...group,
|
||||
...replaceIdsInFields(
|
||||
group,
|
||||
['authentication', 'headers', 'preRequestScript', 'afterResponseScript', 'environment', 'kvPairData'],
|
||||
idMapping,
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { PREVIEW_MODE_FRIENDLY, type PreviewMode } from '~/common/constants';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
export const name = 'Request Meta';
|
||||
export const type = 'RequestMeta';
|
||||
export const prefix = 'reqm';
|
||||
export const canDuplicate = false;
|
||||
export const canSync = false;
|
||||
|
||||
export type RequestAccordionKeys = 'OAuth2AdvancedOptions';
|
||||
|
||||
export interface BaseRequestMeta {
|
||||
parentId: string;
|
||||
previewMode: PreviewMode;
|
||||
responseFilter: string;
|
||||
responseFilterHistory: string[];
|
||||
activeResponseId: string | null;
|
||||
savedRequestBody: Record<string, any>;
|
||||
pinned: boolean;
|
||||
lastActive: number;
|
||||
downloadPath: string | null;
|
||||
expandedAccordionKeys: Partial<Record<RequestAccordionKeys, boolean>>;
|
||||
activeMcpPrimitive?: string | null;
|
||||
}
|
||||
|
||||
export type RequestMeta = BaseModel & BaseRequestMeta;
|
||||
|
||||
export const isRequestMeta = (model: Pick<BaseModel, 'type'>): model is RequestMeta => model.type === type;
|
||||
|
||||
export function init() {
|
||||
return {
|
||||
parentId: null,
|
||||
previewMode: PREVIEW_MODE_FRIENDLY,
|
||||
responseFilter: '',
|
||||
responseFilterHistory: [],
|
||||
activeResponseId: null,
|
||||
savedRequestBody: {},
|
||||
pinned: false,
|
||||
lastActive: 0,
|
||||
downloadPath: null,
|
||||
expandedAccordionKeys: {},
|
||||
activeMcpPrimitive: null,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
/* When viewing a specific request, the user can click the Send button to test-send it.
|
||||
Each time the user sends the request, the parameters may differ—they might edit the body, headers, and so on—and Insomnia records every sent request as history.
|
||||
When the user browses the send history for a request and selects one of the entries, the current request is restored to the exact state it had when that request was sent, including the body, headers, and other settings.
|
||||
A Request Version is essentially a snapshot of the request at the moment it was test-sent. */
|
||||
|
||||
export const name = 'Request Version';
|
||||
|
||||
export const type = 'RequestVersion';
|
||||
|
||||
export const prefix = 'rvr';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
interface BaseRequestVersion {
|
||||
compressedRequest: string | null;
|
||||
}
|
||||
|
||||
export type RequestVersion = BaseModel & BaseRequestVersion;
|
||||
|
||||
export const isRequestVersion = (model: Pick<BaseModel, 'type'>): model is RequestVersion => model.type === type;
|
||||
|
||||
export function init() {
|
||||
return {
|
||||
compressedRequest: null,
|
||||
};
|
||||
}
|
||||
@@ -15,13 +15,12 @@
|
||||
|
||||
import { OperationTypeNode } from 'graphql';
|
||||
|
||||
import { CONTENT_TYPE_FORM_URLENCODED, getContentTypeFromHeaders, METHOD_GET } from '../common/constants';
|
||||
import { database as db } from '../common/database';
|
||||
import type { OAuth1SignatureMethod } from '../network/o-auth-1/constants';
|
||||
import { getOperationType } from '../utils/graph-ql';
|
||||
import { deconstructQueryStringToParams } from '../utils/url/querystring';
|
||||
import { replaceIdsInFields } from './helpers/replace-ids-in-fields';
|
||||
import type { BaseModel } from './types';
|
||||
import { CONTENT_TYPE_FORM_URLENCODED, getContentTypeFromHeaders, METHOD_GET } from '~/common/constants';
|
||||
import { replaceIdsInFields } from '~/models/helpers/replace-ids-in-fields';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
import type { OAuth1SignatureMethod } from '~/network/o-auth-1/constants';
|
||||
import { getOperationType } from '~/utils/graph-ql';
|
||||
import { deconstructQueryStringToParams } from '~/utils/url/querystring';
|
||||
|
||||
export const name = 'Request';
|
||||
|
||||
@@ -342,69 +341,6 @@ export function migrate(doc: Request): Request {
|
||||
}
|
||||
}
|
||||
|
||||
export function create(patch: Partial<Request> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error(`New Requests missing \`parentId\`: ${JSON.stringify(patch)}`);
|
||||
}
|
||||
|
||||
return db.docCreate<Request>(type, patch);
|
||||
}
|
||||
|
||||
export function getById(id: string): Promise<Request | undefined> {
|
||||
return db.findOne<Request>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function getByParentId(parentId: string) {
|
||||
return db.findOne<Request>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<Request>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export function update(request: Request, patch: Partial<Request>) {
|
||||
return db.docUpdate<Request>(request, patch);
|
||||
}
|
||||
|
||||
export async function duplicate(request: Request, patch: Partial<Request> = {}) {
|
||||
// Only set name and "(Copy)" if the patch does
|
||||
// not define it and the request itself has a name.
|
||||
// Otherwise leave it blank so the request URL can
|
||||
// fill it in automatically.
|
||||
if (!patch.name && request.name) {
|
||||
patch.name = `${request.name} (Copy)`;
|
||||
}
|
||||
|
||||
// Get sort key of next request
|
||||
const q = {
|
||||
metaSortKey: {
|
||||
$gt: request.metaSortKey,
|
||||
},
|
||||
};
|
||||
|
||||
const [nextRequest] = await db.find<Request>(type, q, {
|
||||
metaSortKey: 1,
|
||||
});
|
||||
|
||||
const nextSortKey = nextRequest ? nextRequest.metaSortKey : request.metaSortKey + 100;
|
||||
// Calculate new sort key
|
||||
const sortKeyIncrement = (nextSortKey - request.metaSortKey) / 2;
|
||||
const metaSortKey = request.metaSortKey + sortKeyIncrement;
|
||||
return db.duplicate<Request>(request, {
|
||||
name,
|
||||
metaSortKey,
|
||||
...patch,
|
||||
});
|
||||
}
|
||||
|
||||
export function remove(request: Request) {
|
||||
return db.remove(request);
|
||||
}
|
||||
|
||||
export async function all() {
|
||||
return db.find<Request>(type);
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~ //
|
||||
// Migrations //
|
||||
// ~~~~~~~~~~ //
|
||||
99
packages/insomnia/src/insomnia-data/src/models/response.ts
Normal file
99
packages/insomnia/src/insomnia-data/src/models/response.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import type { RequestTestResult } from '../../../../../insomnia-scripting-environment/src/objects';
|
||||
|
||||
export const name = 'Response';
|
||||
|
||||
export const type = 'Response';
|
||||
|
||||
export const prefix = 'res';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
export interface ResponseHeader {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type Compression = 'zip' | null | '__NEEDS_MIGRATION__' | undefined;
|
||||
|
||||
export interface BaseResponse {
|
||||
environmentId: string | null;
|
||||
globalEnvironmentId: string | null;
|
||||
statusCode: number;
|
||||
statusMessage: string;
|
||||
httpVersion: string;
|
||||
contentType: string;
|
||||
url: string;
|
||||
bytesRead: number;
|
||||
bytesContent: number;
|
||||
elapsedTime: number;
|
||||
headers: ResponseHeader[];
|
||||
bodyPath: string;
|
||||
// if body is less than 5MB, it's stored in memory
|
||||
bodyBuffer?: Buffer;
|
||||
// Actual bodies are stored on the filesystem
|
||||
timelinePath: string;
|
||||
// Actual timelines are stored on the filesystem
|
||||
bodyCompression: Compression;
|
||||
error: string;
|
||||
requestVersionId: string | null;
|
||||
// Things from the request
|
||||
settingStoreCookies: boolean | null;
|
||||
settingSendCookies: boolean | null;
|
||||
requestTestResults: RequestTestResult[];
|
||||
}
|
||||
|
||||
export type Response = BaseModel & BaseResponse;
|
||||
|
||||
export const isResponse = (model: Pick<BaseModel, 'type'>): model is Response => model.type === type;
|
||||
|
||||
export function init(): BaseResponse {
|
||||
return {
|
||||
statusCode: 0,
|
||||
statusMessage: '',
|
||||
httpVersion: '',
|
||||
contentType: '',
|
||||
url: '',
|
||||
bytesRead: 0,
|
||||
// -1 means that it was legacy and this property didn't exist yet
|
||||
bytesContent: -1,
|
||||
elapsedTime: 0,
|
||||
headers: [],
|
||||
// Actual timelines are stored on the filesystem
|
||||
timelinePath: '',
|
||||
// Actual bodies are stored on the filesystem
|
||||
bodyPath: '',
|
||||
// For legacy bodies
|
||||
bodyCompression: '__NEEDS_MIGRATION__',
|
||||
error: '',
|
||||
// Things from the request
|
||||
requestVersionId: null,
|
||||
settingStoreCookies: null,
|
||||
settingSendCookies: null,
|
||||
// Responses sent before environment filtering will have a special value
|
||||
// so they don't show up at all when filtering is on.
|
||||
environmentId: '__LEGACY__',
|
||||
requestTestResults: [],
|
||||
globalEnvironmentId: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: Response) {
|
||||
try {
|
||||
return migrateBodyCompression(doc);
|
||||
} catch (e) {
|
||||
console.log('[db] Error during response migration', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
function migrateBodyCompression(doc: Response) {
|
||||
if (doc.bodyCompression === '__NEEDS_MIGRATION__') {
|
||||
doc.bodyCompression = 'zip';
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { replaceIdsInFields } from '~/models/helpers/replace-ids-in-fields';
|
||||
import type { RequestAuthentication, RequestHeader, RequestParameter, RequestPathParameter } from '~/models/request';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import type { RequestAuthentication, RequestHeader, RequestParameter, RequestPathParameter } from './request';
|
||||
|
||||
export const name = 'Socket.IO Request';
|
||||
|
||||
export const type = 'SocketIORequest';
|
||||
|
||||
@@ -38,6 +38,34 @@ export type { Environment, EnvironmentKvPairData, UserUploadEnvironment } from '
|
||||
// Keep these enums in the shared entrypoint: unlike type-only exports, enums also exist at runtime,
|
||||
// so they must be re-exported as values here to preserve a single import path for both type and value usage.
|
||||
export { EnvironmentType, EnvironmentKvPairDataType } from './environment';
|
||||
export type {
|
||||
AuthTypeAPIKey,
|
||||
AuthTypeAsap,
|
||||
AuthTypeAwsIam,
|
||||
AuthTypeBasic,
|
||||
AuthTypeBearer,
|
||||
AuthTypeDigest,
|
||||
AuthTypeHawk,
|
||||
AuthTypeNetrc,
|
||||
AuthTypeNone,
|
||||
AuthTypeNTLM,
|
||||
AuthTypeOAuth1,
|
||||
AuthTypeOAuth2,
|
||||
AuthTypeSingleToken,
|
||||
OAuth2ResponseType,
|
||||
Request,
|
||||
RequestAuthentication,
|
||||
RequestBody,
|
||||
RequestBodyParameter,
|
||||
RequestHeader,
|
||||
RequestParameter,
|
||||
RequestPathParameter,
|
||||
} from './request';
|
||||
export type { RequestGroup } from './request-group';
|
||||
export type { RequestGroupMeta } from './request-group-meta';
|
||||
export type { RequestAccordionKeys, RequestMeta } from './request-meta';
|
||||
export type { RequestVersion } from './request-version';
|
||||
export type { Compression, Response, ResponseHeader } from './response';
|
||||
export type { McpRequest, McpTransportType, McpServerPrimitiveTypes } from './mcp-request';
|
||||
export type { McpPayload } from './mcp-payload';
|
||||
export type { McpResponse } from './mcp-response';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { replaceIdsInFields } from '~/models/helpers/replace-ids-in-fields';
|
||||
import type { RequestAuthentication, RequestHeader, RequestParameter, RequestPathParameter } from '~/models/request';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import type { RequestAuthentication, RequestHeader, RequestParameter, RequestPathParameter } from './request';
|
||||
|
||||
export const name = 'WebSocket Request';
|
||||
|
||||
export const type = 'WebSocketRequest';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ResponseHeader } from '~/models/response';
|
||||
import type { BaseModel } from '~/models/types';
|
||||
|
||||
import type { ResponseHeader } from './response';
|
||||
|
||||
export const name = 'WebSocket Response';
|
||||
|
||||
export const type = 'WebSocketResponse';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type * as Har from 'har-format';
|
||||
|
||||
import type { RequestAuthentication } from '~/models/request';
|
||||
import type { RequestAuthentication } from '~/insomnia-data';
|
||||
|
||||
export interface Comment {
|
||||
comment?: string;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { URL } from 'node:url';
|
||||
|
||||
import { type ControlOperator, parse, type ParseEntry } from 'shell-quote';
|
||||
|
||||
import type { RequestAuthentication } from '~/models/request';
|
||||
import type { RequestAuthentication } from '~/insomnia-data';
|
||||
|
||||
import { type Converter, type ImportRequest, type Parameter } from '../entities';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { CONTENT_TYPE_JSON, CONTENT_TYPE_PLAINTEXT, CONTENT_TYPE_XML } from 'insomnia/src/common/constants';
|
||||
import type { AuthTypeOAuth2 } from 'insomnia/src/models/request';
|
||||
import { fakerFunctions } from 'insomnia/src/templating/faker-functions';
|
||||
import { forceBracketNotation } from 'insomnia/src/templating/utils';
|
||||
|
||||
import type { AuthTypeOAuth2 } from '~/insomnia-data';
|
||||
import { translateHandlersInScript } from '~/main/importers/importers/translate-postman-script';
|
||||
|
||||
import type { Converter, ImportRequest, Parameter, PathParameters } from '../entities';
|
||||
|
||||
@@ -8,10 +8,10 @@ import {
|
||||
import { BrowserWindow, ipcMain } from 'electron';
|
||||
|
||||
import { getOauthRedirectUrl } from '~/common/constants';
|
||||
import type { RequestAuthentication } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { authorizeUserInDefaultBrowser } from '~/main/authorize-user-in-default-browser';
|
||||
import type { ConnectionContext } from '~/main/mcp/common';
|
||||
import type { RequestAuthentication } from '~/models/request';
|
||||
import { encryptOAuthUrl } from '~/network/o-auth-2/utils';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ export const createStdioTransport = async (
|
||||
};
|
||||
const settings = await services.settings.get();
|
||||
const res = await services.mcpResponse.updateOrCreate(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
}
|
||||
|
||||
return originalSend(message);
|
||||
|
||||
@@ -9,12 +9,12 @@ import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { BrowserWindow } from 'electron';
|
||||
import type { Dispatcher } from 'undici';
|
||||
|
||||
import type { RequestHeader } from '~/insomnia-data';
|
||||
import { type McpResponse, services } from '~/insomnia-data';
|
||||
import { type ConnectionContext, getFetchDispatcher, writeEventLogAndNotify, writeTimeline } from '~/main/mcp/common';
|
||||
import { MCPAuthError, type McpOAuthClientProvider } from '~/main/mcp/oauth-client-provider';
|
||||
import type { McpAuthEventWithoutBase, OpenMcpHTTPClientConnectionOptions } from '~/main/mcp/types';
|
||||
import * as models from '~/models';
|
||||
import type { RequestHeader } from '~/models/request';
|
||||
|
||||
// Extend undici RequestInit to include dispatcher, it's in node.js fetch but not in dom fetch.
|
||||
interface NodeRequestInit extends RequestInit {
|
||||
@@ -137,7 +137,7 @@ const wrappedFetch = async (
|
||||
};
|
||||
const settings = await services.settings.get();
|
||||
const res = await services.mcpResponse.updateOrCreate(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
}
|
||||
|
||||
// Avoid infinite loop, only call auth flow once per request
|
||||
|
||||
@@ -4,8 +4,8 @@ import type { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/cl
|
||||
import type { ClientRequest, JSONRPCResponse, Notification } from '@modelcontextprotocol/sdk/types.js';
|
||||
import type z from 'zod';
|
||||
|
||||
import type { RequestAuthentication, RequestHeader } from '~/insomnia-data';
|
||||
import type * as models from '~/models';
|
||||
import type { RequestAuthentication, RequestHeader } from '~/models/request';
|
||||
|
||||
// Refer the SDK: https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/shared/protocol.ts#L504
|
||||
// The Client type has missing transport property
|
||||
|
||||
@@ -7,15 +7,12 @@ import electron, { BrowserWindow } from 'electron';
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
|
||||
import { REALTIME_EVENTS_CHANNELS } from '~/common/constants';
|
||||
import type { CookieJar } from '~/insomnia-data';
|
||||
import type { CookieJar, RequestAuthentication, RequestHeader, Response } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { insecureReadFile } from '~/main/secure-read-file';
|
||||
import { readCurlResponse } from '~/models/helpers/response-operations';
|
||||
|
||||
import { describeByteSize, generateId, getSetCookieHeaders } from '../../common/misc';
|
||||
import * as models from '../../models';
|
||||
import type { RequestAuthentication, RequestHeader } from '../../models/request';
|
||||
import type { Response } from '../../models/response';
|
||||
import { filterClientCertificates } from '../../network/certificate';
|
||||
import { addSetCookiesToToughCookieJar } from '../../network/set-cookie-util';
|
||||
import { invariant } from '../../utils/invariant';
|
||||
@@ -129,7 +126,7 @@ const openCurlConnection = async (
|
||||
console.warn('Connection still open to ' + existingConnection.getInfo(Curl.info.EFFECTIVE_URL));
|
||||
return;
|
||||
}
|
||||
const request = await models.request.getById(options.requestId);
|
||||
const request = await services.request.getById(options.requestId);
|
||||
const responseId = generateId('res');
|
||||
if (!request) {
|
||||
console.warn('Could not find request for ' + options.requestId);
|
||||
@@ -196,7 +193,7 @@ const openCurlConnection = async (
|
||||
window.webContents.send(readyStateChannel, false);
|
||||
}
|
||||
if (errorCode) {
|
||||
const res = await models.response.getById(responseId);
|
||||
const res = await services.response.getById(responseId);
|
||||
if (!res) {
|
||||
createErrorResponse(
|
||||
responseId,
|
||||
@@ -265,8 +262,8 @@ const openCurlConnection = async (
|
||||
bodyCompression: null,
|
||||
};
|
||||
const settings = await services.settings.get();
|
||||
const res = await models.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
const res = await services.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
services.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
|
||||
if (request.settingStoreCookies) {
|
||||
const setCookieStrings: string[] = getSetCookieHeaders(responseHeaders).map(h => h.value);
|
||||
@@ -352,8 +349,8 @@ const createErrorResponse = async (
|
||||
statusMessage: 'Error',
|
||||
error: message,
|
||||
};
|
||||
const res = await models.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
const res = await services.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
};
|
||||
|
||||
const deleteRequestMaps = async (requestId: string, message: string, event?: CurlCloseEvent | CurlErrorEvent) => {
|
||||
@@ -404,7 +401,7 @@ const closeCurlConnection = (_event: Electron.IpcMainInvokeEvent, options: { req
|
||||
const closeAllCurlConnections = (): void => CurlConnections.forEach(curl => curl.isOpen && curl.close());
|
||||
|
||||
const findMany = async (options: { responseId: string }): Promise<CurlEvent[]> => {
|
||||
const response = await models.response.getById(options.responseId);
|
||||
const response = await services.response.getById(options.responseId);
|
||||
if (!response || !response.bodyPath) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -21,13 +21,11 @@ import { isValid } from 'date-fns';
|
||||
import electron from 'electron';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import type { ClientCertificate } from '~/insomnia-data';
|
||||
import type { ClientCertificate, RequestHeader, ResponseHeader } from '~/insomnia-data';
|
||||
|
||||
import { version } from '../../../package.json';
|
||||
import { type AuthTypes, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED } from '../../common/constants';
|
||||
import { cannotAccessPathError, describeByteSize, hasAuthHeader } from '../../common/misc';
|
||||
import type { RequestHeader } from '../../models/request';
|
||||
import type { ResponseHeader } from '../../models/response';
|
||||
import { insecureReadFile, isPathAllowed } from '../secure-read-file';
|
||||
import { buildMultipart } from './multipart';
|
||||
import { parseHeaderStrings } from './parse-header-strings';
|
||||
|
||||
@@ -204,7 +204,7 @@ const createErrorResponse = async (
|
||||
};
|
||||
|
||||
const res = await services.mcpResponse.updateOrCreate(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
};
|
||||
|
||||
export const isOpenMcpHTTPClientConnectionOptions = (
|
||||
|
||||
@@ -8,7 +8,7 @@ import path from 'node:path';
|
||||
|
||||
import { lookup } from 'mime-types';
|
||||
|
||||
import type { RequestBodyParameter } from '../../models/request';
|
||||
import type { RequestBodyParameter } from '~/insomnia-data';
|
||||
|
||||
export const DEFAULT_BOUNDARY = 'X-INSOMNIA-BOUNDARY';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parse as urlParse } from 'node:url';
|
||||
import aws4 from 'aws4';
|
||||
import clone from 'clone';
|
||||
|
||||
import type { RequestAuthentication } from '~/models/request';
|
||||
import type { RequestAuthentication } from '~/insomnia-data';
|
||||
|
||||
import { CONTENT_TYPE_FORM_DATA } from '../../common/constants';
|
||||
import {
|
||||
|
||||
@@ -9,13 +9,17 @@ import { io as SocketIOClient, type ManagerOptions, type Socket, type SocketOpti
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
|
||||
import { REALTIME_EVENTS_CHANNELS } from '~/common/constants';
|
||||
import type { BaseSocketIORequest, CookieJar, SocketIOResponse } from '~/insomnia-data';
|
||||
import type {
|
||||
BaseSocketIORequest,
|
||||
CookieJar,
|
||||
RequestAuthentication,
|
||||
RequestHeader,
|
||||
SocketIOResponse,
|
||||
} from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import { jarFromCookies } from '../../common/cookies';
|
||||
import { generateId } from '../../common/misc';
|
||||
import * as models from '../../models';
|
||||
import { type RequestAuthentication, type RequestHeader } from '../../models/request';
|
||||
import { filterClientCertificates } from '../../network/certificate';
|
||||
import { invariant } from '../../utils/invariant';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
@@ -224,7 +228,7 @@ const createErrorResponse = async (
|
||||
error: message,
|
||||
};
|
||||
const res = await services.socketIOResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
};
|
||||
|
||||
const openSocketIOConnection = async (
|
||||
@@ -359,7 +363,7 @@ const openSocketIOConnection = async (
|
||||
};
|
||||
|
||||
const res = await services.socketIOResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
});
|
||||
|
||||
const engine = socket.io.engine;
|
||||
|
||||
@@ -12,14 +12,19 @@ import { type CloseEvent, type ErrorEvent, type Event, type MessageEvent, WebSoc
|
||||
|
||||
import { REALTIME_EVENTS_CHANNELS } from '~/common/constants';
|
||||
import { database } from '~/common/database';
|
||||
import type { BaseWebSocketRequest, CookieJar, WebSocketResponse } from '~/insomnia-data';
|
||||
import type {
|
||||
BaseWebSocketRequest,
|
||||
CookieJar,
|
||||
Request,
|
||||
RequestAuthentication,
|
||||
RequestHeader,
|
||||
WebSocketResponse,
|
||||
} from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import { jarFromCookies } from '../../common/cookies';
|
||||
import { generateId, getSetCookieHeaders } from '../../common/misc';
|
||||
import * as models from '../../models';
|
||||
import type { Request } from '../../models/request';
|
||||
import { type RequestAuthentication, type RequestHeader } from '../../models/request';
|
||||
import { COOKIE, HEADER, QUERY_PARAMS } from '../../network/api-key/constants';
|
||||
import { getBasicAuthHeader } from '../../network/basic-auth/get-header';
|
||||
import { getBearerAuthHeader } from '../../network/bearer-auth/get-header';
|
||||
@@ -146,7 +151,7 @@ const openWebSocketConnection = async (
|
||||
}
|
||||
|
||||
const request = options.isGraphqlSubscriptionRequest
|
||||
? await models.request.getById(options.requestId)
|
||||
? await services.request.getById(options.requestId)
|
||||
: await services.webSocketRequest.getById(options.requestId);
|
||||
const responseId = generateId('res');
|
||||
if (!request) {
|
||||
@@ -320,7 +325,7 @@ const openWebSocketConnection = async (
|
||||
|
||||
const settings = await services.settings.get();
|
||||
const res = await services.webSocketResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
|
||||
if (request.settingStoreCookies) {
|
||||
const setCookieStrings: string[] = getSetCookieHeaders(responseHeaders).map(h => h.value);
|
||||
@@ -376,7 +381,7 @@ const openWebSocketConnection = async (
|
||||
};
|
||||
const settings = await services.settings.get();
|
||||
const res = await services.webSocketResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
deleteRequestMaps(request._id, `Unexpected response ${incomingMessage.statusCode}`);
|
||||
});
|
||||
|
||||
@@ -520,7 +525,7 @@ const createErrorResponse = async (
|
||||
error: message,
|
||||
};
|
||||
const res = await services.webSocketResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: res._id });
|
||||
};
|
||||
|
||||
const deleteRequestMaps = async (
|
||||
|
||||
@@ -7,17 +7,14 @@ import iconv from 'iconv-lite';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { jarFromCookies } from '~/common/cookies';
|
||||
import type { CloudProviderCredential, Workspace } from '~/insomnia-data';
|
||||
import type { CloudProviderCredential, Request as DBRequest, RequestGroup, Response, Workspace } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { getBodyBuffer, readCurlResponse } from '~/models/helpers/response-operations';
|
||||
|
||||
import { getAppBundlePlugins, RESPONSE_CODE_REASONS } from '../common/constants';
|
||||
import { isDevelopment } from '../common/constants';
|
||||
import { database as db } from '../common/database';
|
||||
import * as models from '../models';
|
||||
import type { Request as DBRequest } from '../models/request';
|
||||
import type { RequestGroup } from '../models/request-group';
|
||||
import type { Response } from '../models/response';
|
||||
import type * as models from '../models';
|
||||
import { fetchRequestData, sendCurlAndWriteTimeline, tryToInterpolateRequest } from '../network/network';
|
||||
import { getPluginCommonContext, type Plugin, type TemplateTag } from '../plugins';
|
||||
import type { PluginTemplateTag, PluginTemplateTagContext, PluginToMainAPIPaths } from '../templating/types';
|
||||
@@ -90,7 +87,7 @@ const pluginToMainAPI: Record<PluginToMainAPIPaths, (...args: any[]) => Promise<
|
||||
return crypto.createHash('md5').update(body.input).digest(body.encoding);
|
||||
},
|
||||
'request.getById': async (body: { id: string }) => {
|
||||
return await models.request.getById(body.id);
|
||||
return await services.request.getById(body.id);
|
||||
},
|
||||
'request.getAncestors': async (body: { request: DBRequest | RequestGroup | Workspace; types: models.AllTypes[] }) => {
|
||||
return await db.withAncestors<DBRequest | RequestGroup | Workspace>(body.request, body.types);
|
||||
@@ -110,7 +107,7 @@ const pluginToMainAPI: Record<PluginToMainAPIPaths, (...args: any[]) => Promise<
|
||||
return jar.getCookiesSync(body.url);
|
||||
},
|
||||
'response.getLatestForRequestId': async (body: { requestId: string; environmentId: string }) => {
|
||||
return await models.response.getLatestForRequestId(body.requestId, body.environmentId);
|
||||
return await services.response.getLatestForRequestId(body.requestId, body.environmentId);
|
||||
},
|
||||
'response.getBodyBuffer': async (body: { response: Response; readFailureValue: string }) => {
|
||||
return await getBodyBuffer(body.response, body.readFailureValue);
|
||||
@@ -176,7 +173,7 @@ const pluginToMainAPI: Record<PluginToMainAPIPaths, (...args: any[]) => Promise<
|
||||
timelinePath,
|
||||
responseId,
|
||||
);
|
||||
return await models.response.create({ ...response, bodyCompression: null }, settings.maxHistoryResponses);
|
||||
return await services.response.create({ ...response, bodyCompression: null }, settings.maxHistoryResponses);
|
||||
},
|
||||
// use libcurl to send request without side effects(do not write to database about request and response)
|
||||
'network.sendRequestWithoutSideEffects': async (body: {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import type { Schema } from '@develohpanda/fluent-builder';
|
||||
import clone from 'clone';
|
||||
|
||||
import type { Environment, GrpcRequest, Workspace } from '~/insomnia-data';
|
||||
import type { Environment, GrpcRequest, Request, RequestGroup, Workspace } from '~/insomnia-data';
|
||||
import { EnvironmentKvPairDataType, EnvironmentType } from '~/insomnia-data';
|
||||
|
||||
import { type AllTypes, type BaseModel, environment, grpcRequest, request, requestGroup, workspace } from '..';
|
||||
import type { Request } from '../request';
|
||||
import type { RequestGroup } from '../request-group';
|
||||
|
||||
// move into fluent-builder
|
||||
const toSchema = <T>(obj: T): Schema<T> => {
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import * as models from '../index';
|
||||
|
||||
describe('create()', () => {
|
||||
it('fails when missing parentId', async () => {
|
||||
expect(() =>
|
||||
models.requestMeta.create({
|
||||
services.requestMeta.create({
|
||||
pinned: true,
|
||||
}),
|
||||
).toThrow('New RequestMeta missing `parentId`');
|
||||
}); // it('fails when parentId prefix is not that of a Request', async () => {
|
||||
// expect(() => models.requestMeta.create({ parentId: 'greq_123' })).toThrow(
|
||||
// expect(() => services.requestMeta.create({ parentId: 'greq_123' })).toThrow(
|
||||
// 'Expected the parent of RequestMeta to be a Request',
|
||||
// );
|
||||
// });
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
scope: 'collection',
|
||||
});
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_basic',
|
||||
name: 'Basic Request',
|
||||
parentId: workspace._id,
|
||||
@@ -88,7 +88,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
{ name: 'X-Custom-Header', value: 'custom-value' },
|
||||
];
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_headers',
|
||||
name: 'Request with Headers',
|
||||
parentId: workspace._id,
|
||||
@@ -115,7 +115,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
{ name: 'sort', value: 'created_at' },
|
||||
];
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_params',
|
||||
name: 'Request with Parameters',
|
||||
parentId: workspace._id,
|
||||
@@ -150,7 +150,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
useISO88591: false,
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_basic_auth',
|
||||
name: 'Basic Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -171,7 +171,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
useISO88591: true,
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_basic_auth_iso',
|
||||
name: 'Basic Auth ISO Request',
|
||||
parentId: workspace._id,
|
||||
@@ -194,7 +194,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
addTo: 'header',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_apikey_header',
|
||||
name: 'API Key Header Request',
|
||||
parentId: workspace._id,
|
||||
@@ -215,7 +215,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
addTo: 'query',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_apikey_query',
|
||||
name: 'API Key Query Request',
|
||||
parentId: workspace._id,
|
||||
@@ -245,7 +245,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
resource: 'https://api.example.com',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_oauth2_auth_code',
|
||||
name: 'OAuth2 Auth Code Request',
|
||||
parentId: workspace._id,
|
||||
@@ -268,7 +268,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
scope: 'read write',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_oauth2_client_creds',
|
||||
name: 'OAuth2 Client Creds Request',
|
||||
parentId: workspace._id,
|
||||
@@ -293,7 +293,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
scope: 'read write',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_oauth2_password',
|
||||
name: 'OAuth2 Password Request',
|
||||
parentId: workspace._id,
|
||||
@@ -315,7 +315,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
password: 'testpass',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_digest_auth',
|
||||
name: 'Digest Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -337,7 +337,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
password: 'testpass',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_ntlm_auth',
|
||||
name: 'NTLM Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -362,7 +362,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
service: 'execute-api',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_aws_iam_auth',
|
||||
name: 'AWS IAM Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -387,7 +387,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
validatePayload: true,
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_hawk_auth',
|
||||
name: 'Hawk Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -409,7 +409,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
prefix: 'Bearer',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_bearer_auth',
|
||||
name: 'Bearer Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -440,7 +440,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
verifier: 'test-verifier',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_oauth1_auth',
|
||||
name: 'OAuth 1.0 Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -466,7 +466,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
additionalClaims: '{"customClaim": "custom-value"}',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_asap_auth',
|
||||
name: 'ASAP Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -487,7 +487,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
token: 'test-single-token',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_single_token_auth',
|
||||
name: 'Single Token Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -507,7 +507,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
type: 'netrc',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_netrc_auth',
|
||||
name: 'Netrc Auth Request',
|
||||
parentId: workspace._id,
|
||||
@@ -541,7 +541,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
text: '{"name": "test", "value": 123}',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_json_body',
|
||||
name: 'JSON Body Request',
|
||||
parentId: workspace._id,
|
||||
@@ -565,7 +565,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
],
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_form_data_body',
|
||||
name: 'Form Data Body Request',
|
||||
parentId: workspace._id,
|
||||
@@ -589,7 +589,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
],
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_multipart_body',
|
||||
name: 'Multipart Body Request',
|
||||
parentId: workspace._id,
|
||||
@@ -610,7 +610,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
text: 'This is raw text content',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_raw_text_body',
|
||||
name: 'Raw Text Body Request',
|
||||
parentId: workspace._id,
|
||||
@@ -631,7 +631,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
text: '<?xml version="1.0"?><root><item>value</item></root>',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_xml_body',
|
||||
name: 'XML Body Request',
|
||||
parentId: workspace._id,
|
||||
@@ -652,7 +652,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
fileName: 'test.bin',
|
||||
};
|
||||
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_binary_body',
|
||||
name: 'Binary Body Request',
|
||||
parentId: workspace._id,
|
||||
@@ -680,7 +680,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should detect GraphQL query operation', async () => {
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_graphql_query',
|
||||
name: 'GraphQL Query',
|
||||
parentId: workspace._id,
|
||||
@@ -699,7 +699,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should detect GraphQL mutation operation', async () => {
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_graphql_mutation',
|
||||
name: 'GraphQL Mutation',
|
||||
parentId: workspace._id,
|
||||
@@ -716,7 +716,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should detect GraphQL subscription operation', async () => {
|
||||
const request = await models.request.create({
|
||||
const request = await services.request.create({
|
||||
_id: 'req_graphql_subscription',
|
||||
name: 'GraphQL Subscription',
|
||||
parentId: workspace._id,
|
||||
@@ -745,7 +745,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
scope: 'collection',
|
||||
});
|
||||
|
||||
request = await models.request.create({
|
||||
request = await services.request.create({
|
||||
_id: `req_update_${uuidv4()}`,
|
||||
name: 'Update Request',
|
||||
parentId: workspace._id,
|
||||
@@ -756,7 +756,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should update request name', async () => {
|
||||
const updatedRequest = await models.request.update(request, {
|
||||
const updatedRequest = await services.request.update(request, {
|
||||
name: 'Updated Request Name',
|
||||
});
|
||||
|
||||
@@ -764,7 +764,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should update request URL', async () => {
|
||||
const updatedRequest = await models.request.update(request, {
|
||||
const updatedRequest = await services.request.update(request, {
|
||||
url: 'https://api.example.com/updated',
|
||||
});
|
||||
|
||||
@@ -772,7 +772,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should update request method', async () => {
|
||||
const updatedRequest = await models.request.update(request, {
|
||||
const updatedRequest = await services.request.update(request, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
@@ -785,7 +785,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
{ name: 'Authorization', value: 'Bearer new-token' },
|
||||
];
|
||||
|
||||
const updatedRequest = await models.request.update(request, {
|
||||
const updatedRequest = await services.request.update(request, {
|
||||
headers: newHeaders,
|
||||
});
|
||||
|
||||
@@ -799,7 +799,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
password: 'newpass',
|
||||
};
|
||||
|
||||
const updatedRequest = await models.request.update(request, {
|
||||
const updatedRequest = await services.request.update(request, {
|
||||
authentication: newAuth,
|
||||
});
|
||||
|
||||
@@ -819,7 +819,7 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
scope: 'collection',
|
||||
});
|
||||
|
||||
request = await models.request.create({
|
||||
request = await services.request.create({
|
||||
_id: `req_delete_${uuidv4()}`,
|
||||
name: 'Delete Request',
|
||||
parentId: workspace._id,
|
||||
@@ -830,9 +830,9 @@ describe('Request Model - Comprehensive Tests', () => {
|
||||
});
|
||||
|
||||
it('should delete request', async () => {
|
||||
await models.request.remove(request);
|
||||
await services.request.remove(request);
|
||||
|
||||
const deletedRequest = await models.request.getById(request._id);
|
||||
const deletedRequest = await services.request.getById(request._id);
|
||||
expect(deletedRequest).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,11 +2,11 @@ import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { generateId } from '../../../common/misc';
|
||||
import * as models from '../../index';
|
||||
import { isRequest } from '../../request';
|
||||
import { isRequestGroup } from '../../request-group';
|
||||
|
||||
const { isProtoDirectory } = models.protoDirectory;
|
||||
const { isProtoFile } = models.protoFile;
|
||||
const { isRequest } = models.request;
|
||||
const { isRequestGroup } = models.requestGroup;
|
||||
|
||||
const allTypes = models.types();
|
||||
const allPrefixes = models.all().map(model => model.prefix);
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('queryAllWorkspaceUrls', () => {
|
||||
const w = await services.workspace.create({
|
||||
name: 'Workspace',
|
||||
});
|
||||
const r1 = await models.request.create({
|
||||
const r1 = await services.request.create({
|
||||
name: 'Request 1',
|
||||
parentId: w._id,
|
||||
url: 'r1.url',
|
||||
@@ -33,11 +33,11 @@ describe('queryAllWorkspaceUrls', () => {
|
||||
parentId: w._id,
|
||||
url: 'gr2.url',
|
||||
});
|
||||
const f2 = await models.requestGroup.create({
|
||||
const f2 = await services.requestGroup.create({
|
||||
name: 'Folder 2',
|
||||
parentId: w._id,
|
||||
});
|
||||
const r2 = await models.request.create({
|
||||
const r2 = await services.request.create({
|
||||
name: 'Request 2',
|
||||
parentId: f2._id,
|
||||
url: 'r2.url',
|
||||
@@ -48,12 +48,12 @@ describe('queryAllWorkspaceUrls', () => {
|
||||
parentId: w._id,
|
||||
url: gr2.url,
|
||||
});
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
name: 'Duplicate url',
|
||||
parentId: f2._id,
|
||||
url: r2.url,
|
||||
});
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
name: 'Undefined url',
|
||||
parentId: f2._id,
|
||||
url: undefined,
|
||||
@@ -66,7 +66,7 @@ describe('queryAllWorkspaceUrls', () => {
|
||||
const w2 = await services.workspace.create({
|
||||
name: 'Workspace 2',
|
||||
});
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
name: 'Different workspace',
|
||||
parentId: w2._id,
|
||||
url: 'diff.url',
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import type { GrpcRequest } from '~/insomnia-data';
|
||||
import { models, services } from '~/insomnia-data';
|
||||
import type { GrpcRequest, models, Request } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import { database as db } from '../../common/database';
|
||||
import { invariant } from '../../utils/invariant';
|
||||
import type { Request, type as RequestType } from '../request';
|
||||
|
||||
const grpcRequestType = models.grpcRequest.type;
|
||||
|
||||
export const queryAllWorkspaceUrls = async (
|
||||
workspaceId: string,
|
||||
reqType: typeof RequestType | typeof grpcRequestType,
|
||||
reqType: typeof models.request.type | typeof models.grpcRequest.type,
|
||||
reqId = 'n/a',
|
||||
): Promise<string[]> => {
|
||||
const workspace = await services.workspace.getById(workspaceId);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import type { GrpcRequest, McpRequest, SocketIORequest, WebSocketRequest } from '~/insomnia-data';
|
||||
import type { GrpcRequest, McpRequest, Request, SocketIORequest, WebSocketRequest } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import * as models from '../index';
|
||||
import type { Request } from '../request';
|
||||
|
||||
export function findByParentId(
|
||||
parentId: string,
|
||||
): Promise<(Request | GrpcRequest | WebSocketRequest | SocketIORequest | McpRequest)[]> {
|
||||
return Promise.all([
|
||||
models.request.findByParentId(parentId),
|
||||
services.request.findByParentId(parentId),
|
||||
services.grpcRequest.findByParentId(parentId),
|
||||
services.webSocketRequest.findByParentId(parentId),
|
||||
services.socketIORequest.findByParentId(parentId),
|
||||
@@ -37,7 +36,7 @@ export function getById(
|
||||
if (models.mcpRequest.isMcpRequestId(requestId)) {
|
||||
return services.mcpRequest.getById(requestId);
|
||||
}
|
||||
return models.request.getById(requestId);
|
||||
return services.request.getById(requestId);
|
||||
}
|
||||
|
||||
export function remove(request: Request | GrpcRequest | WebSocketRequest | SocketIORequest | McpRequest) {
|
||||
@@ -56,7 +55,7 @@ export function remove(request: Request | GrpcRequest | WebSocketRequest | Socke
|
||||
return services.mcpRequest.remove(request);
|
||||
}
|
||||
|
||||
return models.request.remove(request);
|
||||
return services.request.remove(request);
|
||||
}
|
||||
|
||||
export function update<T extends object>(request: T, patch: Partial<T> = {}): Promise<T> {
|
||||
@@ -83,7 +82,7 @@ export function update<T extends object>(request: T, patch: Partial<T> = {}): Pr
|
||||
}
|
||||
|
||||
// @ts-expect-error -- TSCONVERSION
|
||||
return models.request.update(request, patch);
|
||||
return services.request.update(request, patch);
|
||||
}
|
||||
|
||||
export function duplicate<T extends object>(request: T, patch: Partial<T> = {}): Promise<T> {
|
||||
@@ -103,5 +102,5 @@ export function duplicate<T extends object>(request: T, patch: Partial<T> = {}):
|
||||
return services.socketIORequest.duplicate(request, patch);
|
||||
}
|
||||
// @ts-expect-error -- TSCONVERSION
|
||||
return models.request.duplicate(request, patch);
|
||||
return services.request.duplicate(request, patch);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ import type { Readable } from 'node:stream';
|
||||
import zlib from 'node:zlib';
|
||||
|
||||
import { database as db } from '~/common/database';
|
||||
import type { McpResponse, SocketIOResponse, WebSocketResponse } from '~/insomnia-data';
|
||||
import type { Compression, McpResponse, Response, SocketIOResponse, WebSocketResponse } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import type { ResponseTimelineEntry } from '~/main/network/libcurl-promise';
|
||||
import * as models from '~/models/index';
|
||||
import { type Compression, isResponse, type Response, type as responseType } from '~/models/response';
|
||||
import { deserializeNDJSON } from '~/utils/ndjson';
|
||||
|
||||
const { isResponse, type: responseType } = models.response;
|
||||
|
||||
export async function removeResponsesForRequest(requestId: string, environmentId?: string | null) {
|
||||
const settings = await services.settings.get();
|
||||
const query: Record<string, any> = {
|
||||
|
||||
@@ -3,12 +3,6 @@ import type { AllTypes, BaseModel } from '~/models/types';
|
||||
|
||||
import { generateId } from '../common/misc';
|
||||
import { typedKeys } from '../utils';
|
||||
import * as _request from './request';
|
||||
import * as _requestGroup from './request-group';
|
||||
import * as _requestGroupMeta from './request-group-meta';
|
||||
import * as _requestMeta from './request-meta';
|
||||
import * as _requestVersion from './request-version';
|
||||
import * as _response from './response';
|
||||
|
||||
export type { AllTypes, BaseModel };
|
||||
// Reference to each model
|
||||
@@ -23,13 +17,13 @@ export const oAuth2Token = models.oAuth2Token;
|
||||
export const pluginData = models.pluginData;
|
||||
export const mockServer = models.mockServer;
|
||||
export const mockRoute = models.mockRoute;
|
||||
export const request = _request;
|
||||
export const requestGroup = _requestGroup;
|
||||
export const requestGroupMeta = _requestGroupMeta;
|
||||
export const requestMeta = _requestMeta;
|
||||
export const requestVersion = _requestVersion;
|
||||
export const request = models.request;
|
||||
export const requestGroup = models.requestGroup;
|
||||
export const requestGroupMeta = models.requestGroupMeta;
|
||||
export const requestMeta = models.requestMeta;
|
||||
export const requestVersion = models.requestVersion;
|
||||
export const runnerTestResult = models.runnerTestResult;
|
||||
export const response = _response;
|
||||
export const response = models.response;
|
||||
export const settings = models.settings;
|
||||
export const project = models.project;
|
||||
export const stats = models.stats;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import { database as db } from '../common/database';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'Folder Meta';
|
||||
|
||||
export const type = 'RequestGroupMeta';
|
||||
|
||||
export const prefix = 'fldm';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
interface BaseRequestGroupMeta {
|
||||
collapsed: boolean;
|
||||
}
|
||||
|
||||
export type RequestGroupMeta = BaseModel & BaseRequestGroupMeta;
|
||||
|
||||
export const isRequestGroupMeta = (model: Pick<BaseModel, 'type'>): model is RequestGroupMeta => model.type === type;
|
||||
|
||||
export function init() {
|
||||
return {
|
||||
parentId: null,
|
||||
collapsed: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: RequestGroupMeta) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
export function create(patch: Partial<RequestGroupMeta> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New RequestGroupMeta missing `parentId`: ' + JSON.stringify(patch));
|
||||
}
|
||||
|
||||
return db.docCreate<RequestGroupMeta>(type, patch);
|
||||
}
|
||||
|
||||
export function update(requestGroupMeta: RequestGroupMeta, patch: Partial<RequestGroupMeta>) {
|
||||
return db.docUpdate<RequestGroupMeta>(requestGroupMeta, patch);
|
||||
}
|
||||
|
||||
export function getByParentId(parentId: string) {
|
||||
return db.findOne<RequestGroupMeta>(type, { parentId });
|
||||
}
|
||||
|
||||
export function all() {
|
||||
return db.find<RequestGroupMeta>(type);
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
import type { EnvironmentKvPairData, EnvironmentType } from '~/insomnia-data';
|
||||
|
||||
import { database as db } from '../common/database';
|
||||
import { replaceIdsInFields } from './helpers/replace-ids-in-fields';
|
||||
import type { RequestAuthentication, RequestHeader } from './request';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'Folder';
|
||||
|
||||
export const type = 'RequestGroup';
|
||||
|
||||
export const prefix = 'fld';
|
||||
|
||||
export const canDuplicate = true;
|
||||
|
||||
export const canSync = true;
|
||||
// for those keys do not need to add in model init method
|
||||
export const optionalKeys = ['kvPairData', 'environmentType'];
|
||||
interface BaseRequestGroup {
|
||||
name: string;
|
||||
description: string;
|
||||
environment: Record<string, any>;
|
||||
environmentPropertyOrder: Record<string, any> | null;
|
||||
kvPairData?: EnvironmentKvPairData[];
|
||||
environmentType?: EnvironmentType;
|
||||
metaSortKey: number;
|
||||
preRequestScript?: string;
|
||||
afterResponseScript?: string;
|
||||
authentication?: RequestAuthentication | {};
|
||||
headers?: RequestHeader[];
|
||||
}
|
||||
|
||||
export type RequestGroup = BaseModel & BaseRequestGroup;
|
||||
|
||||
export const isRequestGroup = (model: Pick<BaseModel, 'type'>): model is RequestGroup => model.type === type;
|
||||
|
||||
export function init(): BaseRequestGroup {
|
||||
return {
|
||||
name: 'New Folder',
|
||||
description: '',
|
||||
environment: {},
|
||||
environmentPropertyOrder: null,
|
||||
metaSortKey: -1 * Date.now(),
|
||||
preRequestScript: undefined,
|
||||
afterResponseScript: undefined,
|
||||
authentication: undefined,
|
||||
headers: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: RequestGroup) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
export function create(patch: Partial<RequestGroup> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New RequestGroup missing `parentId`: ' + JSON.stringify(patch));
|
||||
}
|
||||
|
||||
return db.docCreate<RequestGroup>(type, patch);
|
||||
}
|
||||
|
||||
export function update(requestGroup: RequestGroup, patch: Partial<RequestGroup> = {}) {
|
||||
return db.docUpdate<RequestGroup>(requestGroup, patch);
|
||||
}
|
||||
|
||||
export function getById(id: string) {
|
||||
return db.findOne<RequestGroup>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<RequestGroup>(type, { parentId });
|
||||
}
|
||||
|
||||
export function remove(requestGroup: RequestGroup) {
|
||||
return db.remove(requestGroup);
|
||||
}
|
||||
|
||||
export function all() {
|
||||
return db.find<RequestGroup>(type);
|
||||
}
|
||||
|
||||
export async function duplicate(requestGroup: RequestGroup, patch: Partial<RequestGroup> = {}) {
|
||||
if (!patch.name) {
|
||||
patch.name = `${requestGroup.name} (Copy)`;
|
||||
}
|
||||
|
||||
// Get sort key of next request
|
||||
const q = {
|
||||
metaSortKey: {
|
||||
$gt: requestGroup.metaSortKey,
|
||||
},
|
||||
};
|
||||
|
||||
const [nextRequestGroup] = await db.find<RequestGroup>(type, q, {
|
||||
metaSortKey: 1,
|
||||
});
|
||||
|
||||
const nextSortKey = nextRequestGroup ? nextRequestGroup.metaSortKey : requestGroup.metaSortKey + 100;
|
||||
|
||||
// Calculate new sort key
|
||||
const sortKeyIncrement = (nextSortKey - requestGroup.metaSortKey) / 2;
|
||||
const metaSortKey = requestGroup.metaSortKey + sortKeyIncrement;
|
||||
return db.duplicate<RequestGroup>(requestGroup, {
|
||||
metaSortKey,
|
||||
...patch,
|
||||
});
|
||||
}
|
||||
|
||||
export const isRequestGroupId = (id?: string | null) => id?.startsWith(prefix);
|
||||
|
||||
export function rewriteReferences(group: RequestGroup, idMapping: Map<string, string>): RequestGroup {
|
||||
return {
|
||||
...group,
|
||||
...replaceIdsInFields(
|
||||
group,
|
||||
['authentication', 'headers', 'preRequestScript', 'afterResponseScript', 'environment', 'kvPairData'],
|
||||
idMapping,
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
import { PREVIEW_MODE_FRIENDLY, type PreviewMode } from '../common/constants';
|
||||
import { database as db } from '../common/database';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'Request Meta';
|
||||
export const type = 'RequestMeta';
|
||||
export const prefix = 'reqm';
|
||||
export const canDuplicate = false;
|
||||
export const canSync = false;
|
||||
|
||||
export type RequestAccordionKeys = 'OAuth2AdvancedOptions';
|
||||
|
||||
export interface BaseRequestMeta {
|
||||
parentId: string;
|
||||
previewMode: PreviewMode;
|
||||
responseFilter: string;
|
||||
responseFilterHistory: string[];
|
||||
activeResponseId: string | null;
|
||||
savedRequestBody: Record<string, any>;
|
||||
pinned: boolean;
|
||||
lastActive: number;
|
||||
downloadPath: string | null;
|
||||
expandedAccordionKeys: Partial<Record<RequestAccordionKeys, boolean>>;
|
||||
activeMcpPrimitive?: string | null;
|
||||
}
|
||||
|
||||
export type RequestMeta = BaseModel & BaseRequestMeta;
|
||||
|
||||
export const isRequestMeta = (model: Pick<BaseModel, 'type'>): model is RequestMeta => model.type === type;
|
||||
|
||||
export function init() {
|
||||
return {
|
||||
parentId: null,
|
||||
previewMode: PREVIEW_MODE_FRIENDLY,
|
||||
responseFilter: '',
|
||||
responseFilterHistory: [],
|
||||
activeResponseId: null,
|
||||
savedRequestBody: {},
|
||||
pinned: false,
|
||||
lastActive: 0,
|
||||
downloadPath: null,
|
||||
expandedAccordionKeys: {},
|
||||
activeMcpPrimitive: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: RequestMeta) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
export function create(patch: Partial<RequestMeta> = {}) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New RequestMeta missing `parentId` ' + JSON.stringify(patch));
|
||||
}
|
||||
|
||||
return db.docCreate<RequestMeta>(type, patch);
|
||||
}
|
||||
|
||||
export function update(requestMeta: RequestMeta, patch: Partial<RequestMeta>) {
|
||||
return db.docUpdate<RequestMeta>(requestMeta, patch);
|
||||
}
|
||||
|
||||
export function getByParentId(parentId: string): Promise<RequestMeta | undefined> {
|
||||
return db.findOne<RequestMeta>(type, { parentId });
|
||||
}
|
||||
|
||||
export async function getOrCreateByParentId(parentId: string) {
|
||||
const requestMeta = await getByParentId(parentId);
|
||||
|
||||
if (requestMeta) {
|
||||
return requestMeta;
|
||||
}
|
||||
|
||||
return create({ parentId });
|
||||
}
|
||||
|
||||
export async function updateOrCreateByParentId(parentId: string, patch: Partial<RequestMeta>) {
|
||||
const requestMeta = await getByParentId(parentId);
|
||||
|
||||
if (requestMeta) {
|
||||
return update(requestMeta, patch);
|
||||
}
|
||||
const newPatch = Object.assign(
|
||||
{
|
||||
parentId,
|
||||
},
|
||||
patch,
|
||||
);
|
||||
return create(newPatch);
|
||||
}
|
||||
|
||||
export function all() {
|
||||
return db.find<RequestMeta>(type);
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import type { RequestTestResult } from '../../../insomnia-scripting-environment/src/objects';
|
||||
import { database as db } from '../common/database';
|
||||
import * as requestOperations from '../models/helpers/request-operations';
|
||||
import * as requestVersionModel from './request-version';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'Response';
|
||||
|
||||
export const type = 'Response';
|
||||
|
||||
export const prefix = 'res';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
export interface ResponseHeader {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type Compression = 'zip' | null | '__NEEDS_MIGRATION__' | undefined;
|
||||
|
||||
export interface BaseResponse {
|
||||
environmentId: string | null;
|
||||
globalEnvironmentId: string | null;
|
||||
statusCode: number;
|
||||
statusMessage: string;
|
||||
httpVersion: string;
|
||||
contentType: string;
|
||||
url: string;
|
||||
bytesRead: number;
|
||||
bytesContent: number;
|
||||
elapsedTime: number;
|
||||
headers: ResponseHeader[];
|
||||
bodyPath: string;
|
||||
// if body is less than 5MB, it's stored in memory
|
||||
bodyBuffer?: Buffer;
|
||||
// Actual bodies are stored on the filesystem
|
||||
timelinePath: string;
|
||||
// Actual timelines are stored on the filesystem
|
||||
bodyCompression: Compression;
|
||||
error: string;
|
||||
requestVersionId: string | null;
|
||||
// Things from the request
|
||||
settingStoreCookies: boolean | null;
|
||||
settingSendCookies: boolean | null;
|
||||
requestTestResults: RequestTestResult[];
|
||||
}
|
||||
|
||||
export type Response = BaseModel & BaseResponse;
|
||||
|
||||
export const isResponse = (model: Pick<BaseModel, 'type'>): model is Response => model.type === type;
|
||||
|
||||
export function init(): BaseResponse {
|
||||
return {
|
||||
statusCode: 0,
|
||||
statusMessage: '',
|
||||
httpVersion: '',
|
||||
contentType: '',
|
||||
url: '',
|
||||
bytesRead: 0,
|
||||
// -1 means that it was legacy and this property didn't exist yet
|
||||
bytesContent: -1,
|
||||
elapsedTime: 0,
|
||||
headers: [],
|
||||
// Actual timelines are stored on the filesystem
|
||||
timelinePath: '',
|
||||
// Actual bodies are stored on the filesystem
|
||||
bodyPath: '',
|
||||
// For legacy bodies
|
||||
bodyCompression: '__NEEDS_MIGRATION__',
|
||||
error: '',
|
||||
// Things from the request
|
||||
requestVersionId: null,
|
||||
settingStoreCookies: null,
|
||||
settingSendCookies: null,
|
||||
// Responses sent before environment filtering will have a special value
|
||||
// so they don't show up at all when filtering is on.
|
||||
environmentId: '__LEGACY__',
|
||||
requestTestResults: [],
|
||||
globalEnvironmentId: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: Response) {
|
||||
try {
|
||||
return migrateBodyCompression(doc);
|
||||
} catch (e) {
|
||||
console.log('[db] Error during response migration', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
export function getById(id: string) {
|
||||
return db.findOne<Response>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<Response>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export async function all() {
|
||||
return db.find<Response>(type);
|
||||
}
|
||||
|
||||
export async function getLatestForRequestId(
|
||||
requestId: string,
|
||||
environmentId: string | null,
|
||||
): Promise<Response | undefined> {
|
||||
// Filter responses by environment if setting is enabled
|
||||
const shouldFilter = (await services.settings.get()).filterResponsesByEnv;
|
||||
|
||||
const response = await db.findOne<Response>(
|
||||
type,
|
||||
{
|
||||
parentId: requestId,
|
||||
...(shouldFilter ? { environmentId } : {}),
|
||||
},
|
||||
{ modified: -1 },
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function create(patch: Partial<Response> = {}, maxResponses = 20): Promise<Response> {
|
||||
if (!patch.parentId) {
|
||||
console.log('[db] Attempted to create response without `parentId`', patch);
|
||||
throw new Error('New Response missing `parentId`');
|
||||
}
|
||||
|
||||
const { parentId } = patch;
|
||||
// Create request version snapshot
|
||||
const request = await requestOperations.getById(parentId);
|
||||
const requestVersion = request ? await requestVersionModel.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const settings = await services.settings.get();
|
||||
const shouldQueryByEnvId = 'environmentId' in patch && settings.filterResponsesByEnv;
|
||||
const query = {
|
||||
parentId,
|
||||
...(shouldQueryByEnvId ? { environmentId: patch.environmentId } : {}),
|
||||
};
|
||||
|
||||
// Delete all other responses before creating the new one
|
||||
const responsesToShow = Math.max(1, maxResponses);
|
||||
|
||||
const allResponses = await db.find<Response>(type, query, { modified: -1 }, responsesToShow);
|
||||
|
||||
const recentIds = allResponses.map(r => r._id);
|
||||
// Remove all that were in the last query, except the first `maxResponses` IDs
|
||||
await db.removeWhere(type, {
|
||||
...query,
|
||||
_id: {
|
||||
$nin: recentIds,
|
||||
},
|
||||
});
|
||||
// Actually create the new response
|
||||
return db.docCreate(type, patch);
|
||||
}
|
||||
|
||||
function migrateBodyCompression(doc: Response) {
|
||||
if (doc.bodyCompression === '__NEEDS_MIGRATION__') {
|
||||
doc.bodyCompression = 'zip';
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
116
packages/insomnia/src/models/socket-io-request.ts
Normal file
116
packages/insomnia/src/models/socket-io-request.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import type { RequestAuthentication, RequestHeader, RequestParameter, RequestPathParameter } from '~/insomnia-data';
|
||||
|
||||
import { database } from '../common/database';
|
||||
import { replaceIdsInFields } from './helpers/replace-ids-in-fields';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'Socket.IO Request';
|
||||
|
||||
export const type = 'SocketIORequest';
|
||||
|
||||
export const prefix = 'socketio-req';
|
||||
|
||||
export const canDuplicate = true;
|
||||
|
||||
export const canSync = true;
|
||||
|
||||
export interface SocketIOEventListener {
|
||||
id: string;
|
||||
eventName: string;
|
||||
desc: string;
|
||||
isOpen: boolean;
|
||||
}
|
||||
|
||||
export interface BaseSocketIORequest {
|
||||
name: string;
|
||||
description: string;
|
||||
url: string;
|
||||
metaSortKey: number;
|
||||
headers: RequestHeader[];
|
||||
authentication: RequestAuthentication | {};
|
||||
parameters: RequestParameter[];
|
||||
pathParameters?: RequestPathParameter[];
|
||||
settingEncodeUrl: boolean;
|
||||
settingStoreCookies: boolean;
|
||||
settingSendCookies: boolean;
|
||||
settingPath?: string;
|
||||
eventListeners: SocketIOEventListener[];
|
||||
}
|
||||
|
||||
export type SocketIORequest = BaseModel & BaseSocketIORequest & { type: typeof type };
|
||||
|
||||
export const isSocketIORequest = (model: Pick<BaseModel, 'type'>): model is SocketIORequest => model.type === type;
|
||||
|
||||
export const isSocketIORequestId = (id?: string | null) => id?.startsWith(`${prefix}_`);
|
||||
|
||||
export const init = (): BaseSocketIORequest => ({
|
||||
name: 'New Socket.IO Request',
|
||||
url: '',
|
||||
metaSortKey: -1 * Date.now(),
|
||||
headers: [],
|
||||
authentication: {},
|
||||
parameters: [],
|
||||
pathParameters: undefined,
|
||||
settingEncodeUrl: true,
|
||||
settingStoreCookies: true,
|
||||
settingSendCookies: true,
|
||||
settingPath: undefined,
|
||||
description: '',
|
||||
eventListeners: [],
|
||||
});
|
||||
|
||||
export const create = (patch: Partial<SocketIORequest> = {}) => {
|
||||
if (!patch.parentId) {
|
||||
throw new Error(`New Socket.IO Request missing \`parentId\`: ${JSON.stringify(patch)}`);
|
||||
}
|
||||
|
||||
return database.docCreate<SocketIORequest>(type, patch);
|
||||
};
|
||||
|
||||
export const getById = (_id: string) => database.findOne<SocketIORequest>(type, { _id });
|
||||
|
||||
export const findByParentId = (parentId: string) => database.find<SocketIORequest>(type, { parentId });
|
||||
|
||||
export const migrate = (doc: SocketIORequest) => doc;
|
||||
|
||||
export const remove = (obj: SocketIORequest) => database.remove(obj);
|
||||
|
||||
export const update = (obj: SocketIORequest, patch: Partial<SocketIORequest> = {}) => database.docUpdate(obj, patch);
|
||||
|
||||
// This is duplicated (lol) from models/request.js
|
||||
export async function duplicate(request: SocketIORequest, patch: Partial<SocketIORequest> = {}) {
|
||||
// Only set name and "(Copy)" if the patch does
|
||||
// not define it and the request itself has a name.
|
||||
// Otherwise leave it blank so the request URL can
|
||||
// fill it in automatically.
|
||||
if (!patch.name && request.name) {
|
||||
patch.name = `${request.name} (Copy)`;
|
||||
}
|
||||
|
||||
// Get sort key of next request
|
||||
const q = {
|
||||
metaSortKey: {
|
||||
$gt: request.metaSortKey,
|
||||
},
|
||||
};
|
||||
|
||||
const [nextRequest] = await database.find<SocketIORequest>(type, q, {
|
||||
metaSortKey: 1,
|
||||
});
|
||||
const nextSortKey = nextRequest ? nextRequest.metaSortKey : request.metaSortKey + 100;
|
||||
// Calculate new sort key
|
||||
const sortKeyIncrement = (nextSortKey - request.metaSortKey) / 2;
|
||||
const metaSortKey = request.metaSortKey + sortKeyIncrement;
|
||||
return database.duplicate<SocketIORequest>(request, {
|
||||
name,
|
||||
metaSortKey,
|
||||
...patch,
|
||||
});
|
||||
}
|
||||
|
||||
export function rewriteReferences(request: SocketIORequest, idMapping: Map<string, string>): SocketIORequest {
|
||||
return {
|
||||
...request,
|
||||
...replaceIdsInFields(request, ['url', 'headers', 'authentication', 'parameters', 'pathParameters'], idMapping),
|
||||
};
|
||||
}
|
||||
113
packages/insomnia/src/models/websocket-request.ts
Normal file
113
packages/insomnia/src/models/websocket-request.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import type { RequestAuthentication, RequestHeader, RequestParameter, RequestPathParameter } from '~/insomnia-data';
|
||||
|
||||
import { database } from '../common/database';
|
||||
import { replaceIdsInFields } from './helpers/replace-ids-in-fields';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'WebSocket Request';
|
||||
|
||||
export const type = 'WebSocketRequest';
|
||||
|
||||
export const prefix = 'ws-req';
|
||||
|
||||
export const canDuplicate = true;
|
||||
|
||||
export const canSync = true;
|
||||
|
||||
export interface BaseWebSocketRequest {
|
||||
name: string;
|
||||
description: string;
|
||||
url: string;
|
||||
metaSortKey: number;
|
||||
headers: RequestHeader[];
|
||||
authentication: RequestAuthentication | {};
|
||||
parameters: RequestParameter[];
|
||||
pathParameters?: RequestPathParameter[];
|
||||
settingEncodeUrl: boolean;
|
||||
settingStoreCookies: boolean;
|
||||
settingSendCookies: boolean;
|
||||
settingFollowRedirects: 'global' | 'on' | 'off';
|
||||
settingUseProxy?: boolean;
|
||||
}
|
||||
|
||||
export type WebSocketRequest = BaseModel & BaseWebSocketRequest & { type: typeof type };
|
||||
|
||||
export const isWebSocketRequest = (model: Pick<BaseModel, 'type'>): model is WebSocketRequest => model.type === type;
|
||||
|
||||
export const isWebSocketRequestId = (id?: string | null) => id?.startsWith(`${prefix}_`);
|
||||
|
||||
// for those keys do not need to add in model init method but can update
|
||||
export const optionalKeys = ['settingUseProxy'];
|
||||
|
||||
export const init = (): BaseWebSocketRequest => ({
|
||||
name: 'New WebSocket Request',
|
||||
url: '',
|
||||
metaSortKey: -1 * Date.now(),
|
||||
headers: [],
|
||||
authentication: {},
|
||||
parameters: [],
|
||||
pathParameters: undefined,
|
||||
settingEncodeUrl: true,
|
||||
settingStoreCookies: true,
|
||||
settingSendCookies: true,
|
||||
settingFollowRedirects: 'global',
|
||||
description: '',
|
||||
});
|
||||
|
||||
export const migrate = (doc: WebSocketRequest) => doc;
|
||||
|
||||
export const create = (patch: Partial<WebSocketRequest> = {}) => {
|
||||
if (!patch.parentId) {
|
||||
throw new Error(`New WebSocketRequest missing \`parentId\`: ${JSON.stringify(patch)}`);
|
||||
}
|
||||
|
||||
return database.docCreate<WebSocketRequest>(type, patch);
|
||||
};
|
||||
|
||||
export const remove = (obj: WebSocketRequest) => database.remove(obj);
|
||||
|
||||
export const update = (obj: WebSocketRequest, patch: Partial<WebSocketRequest> = {}) => database.docUpdate(obj, patch);
|
||||
|
||||
// This is duplicated (lol) from models/request.js
|
||||
export async function duplicate(request: WebSocketRequest, patch: Partial<WebSocketRequest> = {}) {
|
||||
// Only set name and "(Copy)" if the patch does
|
||||
// not define it and the request itself has a name.
|
||||
// Otherwise leave it blank so the request URL can
|
||||
// fill it in automatically.
|
||||
if (!patch.name && request.name) {
|
||||
patch.name = `${request.name} (Copy)`;
|
||||
}
|
||||
|
||||
// Get sort key of next request
|
||||
const q = {
|
||||
metaSortKey: {
|
||||
$gt: request.metaSortKey,
|
||||
},
|
||||
};
|
||||
|
||||
const [nextRequest] = await database.find<WebSocketRequest>(type, q, {
|
||||
metaSortKey: 1,
|
||||
});
|
||||
const nextSortKey = nextRequest ? nextRequest.metaSortKey : request.metaSortKey + 100;
|
||||
// Calculate new sort key
|
||||
const sortKeyIncrement = (nextSortKey - request.metaSortKey) / 2;
|
||||
const metaSortKey = request.metaSortKey + sortKeyIncrement;
|
||||
return database.duplicate<WebSocketRequest>(request, {
|
||||
name,
|
||||
metaSortKey,
|
||||
...patch,
|
||||
});
|
||||
}
|
||||
|
||||
export const getById = (_id: string) => database.findOne<WebSocketRequest>(type, { _id });
|
||||
|
||||
export const findByParentId = (parentId: string) => database.find<WebSocketRequest>(type, { parentId });
|
||||
|
||||
export const all = () => database.find<WebSocketRequest>(type);
|
||||
|
||||
export function rewriteReferences(request: WebSocketRequest, idMapping: Map<string, string>): WebSocketRequest {
|
||||
return {
|
||||
...request,
|
||||
...replaceIdsInFields(request, ['url', 'headers', 'authentication', 'parameters', 'pathParameters'], idMapping),
|
||||
};
|
||||
}
|
||||
126
packages/insomnia/src/models/websocket-response.ts
Normal file
126
packages/insomnia/src/models/websocket-response.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import type { ResponseHeader } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
|
||||
import { database as db } from '../common/database';
|
||||
import * as requestOperations from './helpers/request-operations';
|
||||
import type { BaseModel } from './types';
|
||||
|
||||
export const name = 'WebSocket Response';
|
||||
|
||||
export const type = 'WebSocketResponse';
|
||||
|
||||
export const prefix = 'ws-res';
|
||||
|
||||
export const canDuplicate = false;
|
||||
|
||||
export const canSync = false;
|
||||
|
||||
export interface BaseWebSocketResponse {
|
||||
environmentId: string | null;
|
||||
statusCode: number;
|
||||
statusMessage: string;
|
||||
httpVersion: string;
|
||||
contentType: string;
|
||||
url: string;
|
||||
elapsedTime: number;
|
||||
headers: ResponseHeader[];
|
||||
// Event logs are stored on the filesystem
|
||||
eventLogPath: string;
|
||||
// Actual timelines are stored on the filesystem
|
||||
timelinePath: string;
|
||||
error: string;
|
||||
requestVersionId: string | null;
|
||||
settingStoreCookies: boolean | null;
|
||||
settingSendCookies: boolean | null;
|
||||
}
|
||||
|
||||
export type WebSocketResponse = BaseModel & BaseWebSocketResponse;
|
||||
|
||||
export const isWebSocketResponse = (model: Pick<BaseModel, 'type'>): model is WebSocketResponse => model.type === type;
|
||||
|
||||
export function init(): BaseWebSocketResponse {
|
||||
return {
|
||||
statusCode: 0,
|
||||
statusMessage: '',
|
||||
httpVersion: '',
|
||||
contentType: '',
|
||||
url: '',
|
||||
elapsedTime: 0,
|
||||
headers: [],
|
||||
timelinePath: '',
|
||||
eventLogPath: '',
|
||||
error: '',
|
||||
requestVersionId: null,
|
||||
settingStoreCookies: null,
|
||||
settingSendCookies: null,
|
||||
environmentId: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function migrate(doc: WebSocketResponse) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
export function getById(id: string) {
|
||||
return db.findOne<WebSocketResponse>(type, { _id: id });
|
||||
}
|
||||
|
||||
export function findByParentId(parentId: string) {
|
||||
return db.find<WebSocketResponse>(type, { parentId: parentId });
|
||||
}
|
||||
|
||||
export async function all() {
|
||||
return db.find<WebSocketResponse>(type);
|
||||
}
|
||||
|
||||
export async function create(patch: Partial<WebSocketResponse> = {}, maxResponses = 20) {
|
||||
if (!patch.parentId) {
|
||||
throw new Error('New Response missing `parentId`');
|
||||
}
|
||||
|
||||
const { parentId } = patch;
|
||||
// Create request version snapshot
|
||||
const request = await requestOperations.getById(parentId);
|
||||
const requestVersion = request ? await services.requestVersion.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const query: Record<string, any> = {
|
||||
parentId,
|
||||
};
|
||||
|
||||
if ((await services.settings.get()).filterResponsesByEnv && 'environmentId' in patch) {
|
||||
query.environmentId = patch.environmentId;
|
||||
}
|
||||
|
||||
// Delete all other responses before creating the new one
|
||||
const responsesToShow = Math.max(1, maxResponses);
|
||||
|
||||
const allResponses = await db.find<WebSocketResponse>(type, query, { modified: -1 }, responsesToShow);
|
||||
|
||||
const recentIds = allResponses.map(r => r._id);
|
||||
// Remove all that were in the last query, except the first `maxResponses` IDs
|
||||
await db.removeWhere(type, {
|
||||
...query,
|
||||
_id: {
|
||||
$nin: recentIds,
|
||||
},
|
||||
});
|
||||
// Actually create the new response
|
||||
return db.docCreate(type, patch);
|
||||
}
|
||||
|
||||
export async function getLatestForRequestId(requestId: string, environmentId: string | null) {
|
||||
// Filter responses by environment if setting is enabled
|
||||
|
||||
const shouldFilter = (await services.settings.get()).filterResponsesByEnv;
|
||||
|
||||
const response = await db.findOne<WebSocketResponse>(
|
||||
type,
|
||||
{
|
||||
parentId: requestId,
|
||||
...(shouldFilter ? { environmentId } : {}),
|
||||
},
|
||||
{ modified: -1 },
|
||||
);
|
||||
return response;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as Hawk from 'hawk';
|
||||
|
||||
import type { AuthTypeOAuth2, RequestAuthentication, RequestParameter } from '../models/request';
|
||||
import type { AuthTypeOAuth2, RequestAuthentication, RequestParameter } from '~/insomnia-data';
|
||||
|
||||
import type { RenderedRequest } from '../templating/types';
|
||||
import { COOKIE, HEADER, QUERY_PARAMS } from './api-key/constants';
|
||||
import { getBasicAuthHeader } from './basic-auth/get-header';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RequestHeader } from '../../models/request';
|
||||
import type { RequestHeader } from '~/insomnia-data';
|
||||
|
||||
export function getBasicAuthHeader(username?: string | null, password?: string | null, encoding = 'utf8') {
|
||||
const name = 'Authorization';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RequestHeader } from '../../models/request';
|
||||
import type { RequestHeader } from '~/insomnia-data';
|
||||
|
||||
export function getBearerAuthHeader(token: string, prefix?: string) {
|
||||
const name = 'Authorization';
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import type { queueAsPromised } from 'fastq';
|
||||
import * as fastq from 'fastq';
|
||||
|
||||
import type { ClientCertificate, CookieJar, Environment, Settings, UserUploadEnvironment } from '~/insomnia-data';
|
||||
import type {
|
||||
ClientCertificate,
|
||||
CookieJar,
|
||||
Environment,
|
||||
Request,
|
||||
Settings,
|
||||
UserUploadEnvironment,
|
||||
} from '~/insomnia-data';
|
||||
|
||||
import type { RequestContext, RequestTestResult } from '../../../insomnia-scripting-environment/src/objects';
|
||||
import type { Request } from '../models/request';
|
||||
import { cancellableExecution } from './cancellation';
|
||||
|
||||
export interface ExecuteScriptContext {
|
||||
|
||||
@@ -13,6 +13,11 @@ import type {
|
||||
MockRoute,
|
||||
MockServer,
|
||||
Project,
|
||||
Request,
|
||||
RequestAuthentication,
|
||||
RequestGroup,
|
||||
RequestHeader,
|
||||
RequestParameter,
|
||||
Settings,
|
||||
SocketIORequest,
|
||||
UserUploadEnvironment,
|
||||
@@ -35,15 +40,6 @@ import { getRenderedRequestAndContext } from '../common/render';
|
||||
import { ascendingFirstIndexStringSort } from '../common/sorting';
|
||||
import type { HeaderResult, ResponsePatch, ResponseTimelineEntry } from '../main/network/libcurl-promise';
|
||||
import * as models from '../models';
|
||||
import {
|
||||
type BaseRequest,
|
||||
isRequest,
|
||||
type Request,
|
||||
type RequestAuthentication,
|
||||
type RequestHeader,
|
||||
type RequestParameter,
|
||||
} from '../models/request';
|
||||
import { isRequestGroup, type RequestGroup } from '../models/request-group';
|
||||
import * as pluginApp from '../plugins/context/app';
|
||||
import * as pluginData from '../plugins/context/data';
|
||||
import * as pluginNetwork from '../plugins/context/network';
|
||||
@@ -63,6 +59,9 @@ import { filterClientCertificates } from './certificate';
|
||||
import { runScriptConcurrently, type TransformedExecuteScriptContext } from './concurrency';
|
||||
import { addSetCookiesToToughCookieJar } from './set-cookie-util';
|
||||
|
||||
const { isRequest } = models.request;
|
||||
const { isRequestGroup } = models.requestGroup;
|
||||
|
||||
export interface SendActionRuntime {
|
||||
appendTimeline: (timelinePath: string, logs: string[]) => Promise<void>;
|
||||
}
|
||||
@@ -95,7 +94,7 @@ export function getOrInheritHeaders({
|
||||
request,
|
||||
requestGroups,
|
||||
}: {
|
||||
request: Pick<BaseRequest, 'headers'>;
|
||||
request: Pick<Request, 'headers'>;
|
||||
requestGroups: Pick<RequestGroup, 'headers'>[];
|
||||
}): RequestHeader[] {
|
||||
const httpHeaders = new Map<string, string>();
|
||||
@@ -128,7 +127,7 @@ export function getOrInheritHeaders({
|
||||
}
|
||||
// (only used for getOAuth2 token) Intended to gather all required database objects and initialize ids
|
||||
export const fetchRequestGroupData = async (requestGroupId: string) => {
|
||||
const requestGroup = await models.requestGroup.getById(requestGroupId);
|
||||
const requestGroup = await services.requestGroup.getById(requestGroupId);
|
||||
invariant(requestGroup, 'failed to find requestGroup ' + requestGroupId);
|
||||
const ancestors = await db.withAncestors<RequestGroup | Workspace | MockRoute | MockServer>(requestGroup, [
|
||||
models.requestGroup.type,
|
||||
@@ -169,7 +168,7 @@ export const fetchRequestData = async (
|
||||
// Override the active environment id to use for the request
|
||||
overrideEnvironmentId?: string,
|
||||
) => {
|
||||
const request = await models.request.getById(requestId);
|
||||
const request = await services.request.getById(requestId);
|
||||
invariant(request, 'failed to find request ' + requestId);
|
||||
const ancestors = await db.withAncestors<Request | RequestGroup | Workspace | Project | MockRoute | MockServer>(
|
||||
request,
|
||||
@@ -478,7 +477,7 @@ export async function savePatchesMadeByScript(patches: {
|
||||
mutatedContext.parentFolders.forEach(mutatedFolder => {
|
||||
const originalFolder = originalRequestGroups.find(originalFolder => originalFolder._id === mutatedFolder.id);
|
||||
if (originalFolder) {
|
||||
models.requestGroup.update(originalFolder, {
|
||||
services.requestGroup.update(originalFolder, {
|
||||
environment: mutatedFolder.environment,
|
||||
// also update kvPairData when folder environment type is table view(kv pair)
|
||||
...(originalFolder.environmentType === EnvironmentType.KVPAIR && {
|
||||
|
||||
@@ -6,8 +6,9 @@ import crypto from 'node:crypto';
|
||||
|
||||
import OAuth1 from 'oauth-1.0a';
|
||||
|
||||
import type { RequestAuthentication, RequestBody } from '~/insomnia-data';
|
||||
|
||||
import { CONTENT_TYPE_FORM_URLENCODED } from '../../common/constants';
|
||||
import type { RequestAuthentication, RequestBody } from '../../models/request';
|
||||
import type { OAuth1SignatureMethod } from './constants';
|
||||
import {
|
||||
SIGNATURE_METHOD_HMAC_SHA1,
|
||||
|
||||
@@ -3,7 +3,16 @@ import querystring from 'node:querystring';
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import type { OAuth2Token } from '~/insomnia-data';
|
||||
import type {
|
||||
AuthTypeOAuth2,
|
||||
OAuth2ResponseType,
|
||||
OAuth2Token,
|
||||
Request,
|
||||
RequestGroup,
|
||||
RequestHeader,
|
||||
RequestParameter,
|
||||
Response,
|
||||
} from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { getBodyBuffer } from '~/models/helpers/response-operations';
|
||||
import { encryptOAuthUrl } from '~/network/o-auth-2/utils';
|
||||
@@ -13,10 +22,6 @@ import { getOauthRedirectUrl } from '../../common/constants';
|
||||
import { database as db } from '../../common/database';
|
||||
import { escapeRegex } from '../../common/misc';
|
||||
import * as models from '../../models';
|
||||
import type { AuthTypeOAuth2, OAuth2ResponseType, RequestHeader, RequestParameter } from '../../models/request';
|
||||
import type { Request } from '../../models/request';
|
||||
import { isRequestGroup, isRequestGroupId, type RequestGroup } from '../../models/request-group';
|
||||
import type { Response } from '../../models/response';
|
||||
import uiEventBus, { OAUTH2_AUTHORIZATION_STATUS_CHANGE } from '../../ui/event-bus';
|
||||
import { invariant } from '../../utils/invariant';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
@@ -33,6 +38,7 @@ import {
|
||||
} from '../network';
|
||||
import { type AuthKeys, GRANT_TYPE_AUTHORIZATION_CODE, PKCE_CHALLENGE_S256 } from './constants';
|
||||
|
||||
const { isRequestGroup, isRequestGroupId } = models.requestGroup;
|
||||
const LOCALSTORAGE_KEY_SESSION_ID = 'insomnia::current-oauth-session-id';
|
||||
|
||||
export function initNewOAuthSession() {
|
||||
@@ -267,7 +273,7 @@ async function getExistingAccessTokenAndRefreshIfExpired(
|
||||
let closestAuthId = requestId;
|
||||
|
||||
if (!models.mcpRequest.isMcpRequestId(requestId)) {
|
||||
const activeRequest = await models.request.getById(requestId);
|
||||
const activeRequest = await services.request.getById(requestId);
|
||||
const requestGroups = (
|
||||
await db.withAncestors<Request | RequestGroup>(activeRequest, [models.requestGroup.type])
|
||||
).filter(isRequestGroup) as RequestGroup[];
|
||||
@@ -465,7 +471,7 @@ const sendAccessTokenRequest = async (
|
||||
);
|
||||
const responsePatch = await responseTransform(response, activeEnvironmentId, renderedRequest, renderResult.context);
|
||||
|
||||
return await models.response.create(responsePatch);
|
||||
return await services.response.create(responsePatch);
|
||||
};
|
||||
export const encodePKCE = (buffer: Buffer) => {
|
||||
return (
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('init()', () => {
|
||||
_id: 'wrk_1',
|
||||
name: 'My Workspace',
|
||||
});
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
_id: 'req_1',
|
||||
parentId: 'wrk_1',
|
||||
name: 'My Request',
|
||||
@@ -33,7 +33,7 @@ describe('init()', () => {
|
||||
});
|
||||
|
||||
it('initializes correctly', async () => {
|
||||
const result = plugin.init(await models.request.getById('req_1'), CONTEXT);
|
||||
const result = plugin.init(await services.request.getById('req_1'), CONTEXT);
|
||||
expect(Object.keys(result)).toEqual(['request']);
|
||||
expect(Object.keys(result.request).sort()).toEqual([
|
||||
'addHeader',
|
||||
@@ -72,7 +72,7 @@ describe('init()', () => {
|
||||
});
|
||||
|
||||
it('initializes correctly in read-only mode', async () => {
|
||||
const result = plugin.init(await models.request.getById('req_1'), CONTEXT, true);
|
||||
const result = plugin.init(await services.request.getById('req_1'), CONTEXT, true);
|
||||
expect(Object.keys(result)).toEqual(['request']);
|
||||
expect(Object.keys(result.request).sort()).toEqual([
|
||||
'getAuthentication',
|
||||
@@ -106,7 +106,7 @@ describe('request.*', () => {
|
||||
_id: 'wrk_1',
|
||||
name: 'My Workspace',
|
||||
});
|
||||
await models.request.create({
|
||||
await services.request.create({
|
||||
_id: 'req_1',
|
||||
parentId: 'wrk_1',
|
||||
name: 'My Request',
|
||||
@@ -141,7 +141,7 @@ describe('request.*', () => {
|
||||
|
||||
it('works for basic getters', async () => {
|
||||
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
const result = plugin.init(await models.request.getById('req_1'), CONTEXT);
|
||||
const result = plugin.init(await services.request.getById('req_1'), CONTEXT);
|
||||
expect(result.request.getId()).toBe('req_1');
|
||||
expect(result.request.getName()).toBe('My Request');
|
||||
expect(result.request.getUrl()).toBe('');
|
||||
@@ -154,7 +154,7 @@ describe('request.*', () => {
|
||||
});
|
||||
|
||||
it('works for parameters', async () => {
|
||||
const result = plugin.init(await models.request.getById('req_1'), CONTEXT);
|
||||
const result = plugin.init(await services.request.getById('req_1'), CONTEXT);
|
||||
// getParameters()
|
||||
expect(result.request.getParameters()).toEqual([
|
||||
{
|
||||
@@ -186,7 +186,7 @@ describe('request.*', () => {
|
||||
});
|
||||
|
||||
it('works for headers', async () => {
|
||||
const result = plugin.init(await models.request.getById('req_1'), CONTEXT);
|
||||
const result = plugin.init(await services.request.getById('req_1'), CONTEXT);
|
||||
// getHeaders()
|
||||
expect(result.request.getHeaders()).toEqual([
|
||||
{
|
||||
@@ -218,7 +218,7 @@ describe('request.*', () => {
|
||||
});
|
||||
|
||||
it('works for cookies', async () => {
|
||||
const request = await models.request.getById('req_1');
|
||||
const request = await services.request.getById('req_1');
|
||||
request.cookies = []; // Because the plugin technically needs a RenderedRequest
|
||||
|
||||
const result = plugin.init(request, CONTEXT);
|
||||
@@ -233,7 +233,7 @@ describe('request.*', () => {
|
||||
});
|
||||
|
||||
it('works for environment', async () => {
|
||||
const request = await models.request.getById('req_1');
|
||||
const request = await services.request.getById('req_1');
|
||||
request.cookies = []; // Because the plugin technically needs a RenderedRequest
|
||||
|
||||
const result = plugin.init(request, CONTEXT);
|
||||
@@ -261,7 +261,7 @@ describe('request.*', () => {
|
||||
});
|
||||
|
||||
it('works for authentication', async () => {
|
||||
const request = await models.request.getById('req_1');
|
||||
const request = await services.request.getById('req_1');
|
||||
request.authentication = {}; // Because the plugin technically needs a RenderedRequest
|
||||
|
||||
const result = plugin.init(request, CONTEXT);
|
||||
@@ -276,7 +276,7 @@ describe('request.*', () => {
|
||||
});
|
||||
|
||||
it('works for request body', async () => {
|
||||
const result = plugin.init(await models.request.getById('req_1'), CONTEXT);
|
||||
const result = plugin.init(await services.request.getById('req_1'), CONTEXT);
|
||||
expect(result.request.getBody()).toEqual({
|
||||
text: 'body',
|
||||
});
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import type { Request, ResponseHeader } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { readCurlResponse } from '~/models/helpers/response-operations';
|
||||
|
||||
import { RESPONSE_CODE_REASONS } from '../../common/constants';
|
||||
import * as models from '../../models';
|
||||
import type { Request } from '../../models/request';
|
||||
import { type ResponseHeader } from '../../models/response';
|
||||
import {
|
||||
fetchRequestData,
|
||||
responseTransform,
|
||||
@@ -71,7 +69,7 @@ export function init(): {
|
||||
renderedRequest,
|
||||
renderResult.context,
|
||||
);
|
||||
return models.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
return services.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
},
|
||||
// using node-curl to send a request directly, without context render and database write for request and response
|
||||
async sendRequestWithoutSideEffects(options: NodeCurlRequestOptions): Promise<NodeCurlResponseType> {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { RequestBody } from '~/insomnia-data';
|
||||
|
||||
import * as misc from '../../common/misc';
|
||||
import type { RequestBody } from '../../models/request';
|
||||
import type { RenderedRequest } from '../../templating/types';
|
||||
export function filterParameters<T extends { name: string; value: string }>(parameters: T[], name: string): T[] {
|
||||
if (!Array.isArray(parameters) || !name) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from 'node:fs';
|
||||
|
||||
import type { ResponseHeader } from '~/insomnia-data';
|
||||
import { getBodyBuffer, getBodyStream } from '~/models/helpers/response-operations';
|
||||
|
||||
import type { ResponseHeader } from '../../models/response';
|
||||
|
||||
interface MaybeResponse {
|
||||
parentId?: string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from 'node:path';
|
||||
|
||||
import electron from 'electron';
|
||||
|
||||
import type { GrpcRequest, SocketIORequest, WebSocketRequest, Workspace } from '~/insomnia-data';
|
||||
import type { GrpcRequest, Request, RequestGroup, SocketIORequest, WebSocketRequest, Workspace } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { getBodyBuffer } from '~/models/helpers/response-operations';
|
||||
import { fetchFromTemplateWorkerDatabase } from '~/templating/base-extension-worker';
|
||||
@@ -13,8 +13,6 @@ import { getAppBundlePlugins, isDevelopment } from '../common/constants';
|
||||
import { database as db } from '../common/database';
|
||||
import type { PluginConfigMap } from '../common/settings';
|
||||
import * as models from '../models';
|
||||
import type { Request } from '../models/request';
|
||||
import type { RequestGroup } from '../models/request-group';
|
||||
import * as pluginApp from '../plugins/context/app';
|
||||
import * as pluginNetwork from '../plugins/context/network';
|
||||
import * as pluginStore from '../plugins/context/store';
|
||||
@@ -387,7 +385,7 @@ export function getPluginCommonContext({
|
||||
: electron.shell.openExternal(url),
|
||||
models: {
|
||||
request: {
|
||||
getById: models.request.getById,
|
||||
getById: services.request.getById,
|
||||
getAncestors: async (request: any) => {
|
||||
const ancestors = await db.withAncestors<Request | RequestGroup | Workspace>(request, [
|
||||
models.requestGroup.type,
|
||||
@@ -412,7 +410,7 @@ export function getPluginCommonContext({
|
||||
},
|
||||
},
|
||||
response: {
|
||||
getLatestForRequestId: models.response.getLatestForRequestId,
|
||||
getLatestForRequestId: services.response.getLatestForRequestId,
|
||||
getBodyBuffer,
|
||||
},
|
||||
settings: {
|
||||
|
||||
@@ -2,12 +2,18 @@ import type { Organization } from 'insomnia-api';
|
||||
|
||||
import { database } from '~/common/database';
|
||||
import { fuzzyMatch } from '~/common/misc';
|
||||
import type { Environment, GrpcRequest, Project, WebSocketRequest, Workspace } from '~/insomnia-data';
|
||||
import type {
|
||||
Environment,
|
||||
GrpcRequest,
|
||||
Project,
|
||||
Request,
|
||||
RequestGroup,
|
||||
WebSocketRequest,
|
||||
Workspace,
|
||||
} from '~/insomnia-data';
|
||||
import { models, services } from '~/insomnia-data';
|
||||
import { environment, grpcRequest, project, request, requestGroup, workspace } from '~/models';
|
||||
import { isScratchpadOrganizationId } from '~/models/organization';
|
||||
import type { Request } from '~/models/request';
|
||||
import type { RequestGroup } from '~/models/request-group';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherLoadHook } from '~/utils/router';
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import * as models from '~/models';
|
||||
import { models, services } from '~/insomnia-data';
|
||||
import { getById, update } from '~/models/helpers/request-operations';
|
||||
import { isRequestGroup, isRequestGroupId } from '~/models/request-group';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.reorder';
|
||||
|
||||
const { isRequestGroup, isRequestGroupId } = models.requestGroup;
|
||||
|
||||
const getCollectionItem = async (id: string) => {
|
||||
const item = await (isRequestGroupId(id) ? models.requestGroup.getById(id) : getById(id));
|
||||
const item = await (isRequestGroupId(id) ? services.requestGroup.getById(id) : getById(id));
|
||||
|
||||
invariant(item, 'Item not found');
|
||||
|
||||
@@ -33,7 +34,7 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
const parentId = dropPosition === 'after' && isRequestGroup(targetItem) ? targetItem._id : targetItem.parentId;
|
||||
|
||||
await (isRequestGroup(item)
|
||||
? models.requestGroup.update(item, { parentId, metaSortKey })
|
||||
? services.requestGroup.update(item, { parentId, metaSortKey })
|
||||
: update(item, { parentId, metaSortKey }));
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { href, redirect, useRouteLoaderData } from 'react-router';
|
||||
|
||||
import * as models from '~/models';
|
||||
import type { RequestGroup } from '~/models/request-group';
|
||||
import type { RequestGroup } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { showResourceNotFoundToast } from '~/ui/components/toast-notification';
|
||||
|
||||
import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.request-group.$requestGroupId';
|
||||
@@ -13,7 +13,7 @@ export interface RequestGroupLoaderData {
|
||||
export async function clientLoader({ params }: Route.ClientLoaderArgs) {
|
||||
const { organizationId, projectId, requestGroupId, workspaceId } = params;
|
||||
|
||||
const activeRequestGroup = await models.requestGroup.getById(requestGroupId);
|
||||
const activeRequestGroup = await services.requestGroup.getById(requestGroupId);
|
||||
if (!activeRequestGroup) {
|
||||
showResourceNotFoundToast(`Folder not found: ${requestGroupId}`);
|
||||
throw redirect(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import * as models from '~/models';
|
||||
import type { RequestGroupMeta } from '~/models/request-group-meta';
|
||||
import type { RequestGroupMeta } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
@@ -11,12 +11,12 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
|
||||
const { requestGroupId } = params;
|
||||
invariant(typeof requestGroupId === 'string', 'Request Group ID is required');
|
||||
const patch = (await request.json()) as Partial<RequestGroupMeta>;
|
||||
const requestGroupMeta = await models.requestGroupMeta.getByParentId(requestGroupId);
|
||||
const requestGroupMeta = await services.requestGroupMeta.getByParentId(requestGroupId);
|
||||
if (requestGroupMeta) {
|
||||
await models.requestGroupMeta.update(requestGroupMeta, patch);
|
||||
await services.requestGroupMeta.update(requestGroupMeta, patch);
|
||||
return null;
|
||||
}
|
||||
await models.requestGroupMeta.create({ parentId: requestGroupId, collapsed: Boolean(patch?.collapsed) });
|
||||
await services.requestGroupMeta.create({ parentId: requestGroupId, collapsed: Boolean(patch?.collapsed) });
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import * as models from '~/models';
|
||||
import type { RequestGroup } from '~/models/request-group';
|
||||
import type { RequestGroup } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
@@ -10,12 +10,12 @@ import type { Route } from './+types/organization.$organizationId.project.$proje
|
||||
export async function clientAction({ request, params }: Route.ActionArgs) {
|
||||
const { requestGroupId } = params;
|
||||
|
||||
const reqGroup = await models.requestGroup.getById(requestGroupId);
|
||||
const reqGroup = await services.requestGroup.getById(requestGroupId);
|
||||
invariant(reqGroup, 'Request Group not found');
|
||||
|
||||
const patch = (await request.json()) as Partial<RequestGroup>;
|
||||
|
||||
await models.requestGroup.update(reqGroup, patch);
|
||||
await services.requestGroup.update(reqGroup, patch);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import { services } from '~/insomnia-data';
|
||||
import * as models from '~/models';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
@@ -11,12 +10,12 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
const formData = await request.formData();
|
||||
const id = formData.get('id') as string;
|
||||
|
||||
const requestGroup = await models.requestGroup.getById(id);
|
||||
const requestGroup = await services.requestGroup.getById(id);
|
||||
invariant(requestGroup, 'Request Group not found');
|
||||
|
||||
services.stats.incrementDeletedRequestsForDescendents(requestGroup);
|
||||
|
||||
await models.requestGroup.remove(requestGroup);
|
||||
await services.requestGroup.remove(requestGroup);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import type { RequestGroup } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import * as models from '~/models';
|
||||
import type { RequestGroup } from '~/models/request-group';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
@@ -12,7 +11,7 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
const patch = (await request.json()) as Partial<RequestGroup>;
|
||||
invariant(patch._id, 'Request group id not found');
|
||||
|
||||
const requestGroup = await models.requestGroup.getById(patch._id);
|
||||
const requestGroup = await services.requestGroup.getById(patch._id);
|
||||
invariant(requestGroup, 'Request group not found');
|
||||
|
||||
if (patch.parentId) {
|
||||
@@ -20,7 +19,7 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
invariant(workspace, 'Workspace is required');
|
||||
// TODO: if gRPC, we should also copy the protofile to the destination workspace - INS-267
|
||||
// Move to top of sort order
|
||||
const newRequestGroup = await models.requestGroup.duplicate(requestGroup, {
|
||||
const newRequestGroup = await services.requestGroup.duplicate(requestGroup, {
|
||||
name: patch.name,
|
||||
parentId: patch.parentId,
|
||||
metaSortKey: -1e9,
|
||||
@@ -31,7 +30,7 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const newRequestGroup = await models.requestGroup.duplicate(requestGroup, { name: patch.name });
|
||||
const newRequestGroup = await services.requestGroup.duplicate(requestGroup, { name: patch.name });
|
||||
|
||||
services.stats.incrementCreatedRequestsForDescendents(newRequestGroup);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import { EnvironmentType } from '~/insomnia-data';
|
||||
import * as models from '~/models';
|
||||
import { EnvironmentType, services } from '~/insomnia-data';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.request-group.new';
|
||||
@@ -13,9 +12,9 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
|
||||
const parentId = formData.get('parentId') as string;
|
||||
// New folder environment to be key-value pair by default;
|
||||
const environmentType = (formData.get('environmentType') as EnvironmentType) || EnvironmentType.KVPAIR;
|
||||
const requestGroup = await models.requestGroup.create({ parentId: parentId || workspaceId, name, environmentType });
|
||||
const requestGroup = await services.requestGroup.create({ parentId: parentId || workspaceId, name, environmentType });
|
||||
|
||||
await models.requestGroupMeta.create({ parentId: requestGroup._id, collapsed: false });
|
||||
await services.requestGroupMeta.create({ parentId: requestGroup._id, collapsed: false });
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,9 @@ import { GRAPHQL_TRANSPORT_WS_PROTOCOL, MessageType } from 'graphql-ws';
|
||||
import { href } from 'react-router';
|
||||
|
||||
import type { ChangeBufferEvent } from '~/common/database';
|
||||
import type { CookieJar, McpTransportType } from '~/insomnia-data';
|
||||
import type { CookieJar, McpTransportType, RequestAuthentication, RequestHeader } from '~/insomnia-data';
|
||||
import { models } from '~/insomnia-data';
|
||||
import * as requestOperations from '~/models/helpers/request-operations';
|
||||
import type { RequestAuthentication, RequestHeader } from '~/models/request';
|
||||
import { isEventStreamRequest, isGraphqlSubscriptionRequest } from '~/models/request';
|
||||
import { isRequestMeta } from '~/models/request-meta';
|
||||
import { getAuthHeader } from '~/network/authentication';
|
||||
import type { RenderedRequest } from '~/templating/types';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
@@ -15,6 +12,9 @@ import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.request.$requestId.connect';
|
||||
|
||||
const { isGraphqlSubscriptionRequest, isEventStreamRequest } = models.request;
|
||||
const { isRequestMeta } = models.requestMeta;
|
||||
|
||||
export interface ConnectActionParams {
|
||||
url: string;
|
||||
headers: RequestHeader[];
|
||||
|
||||
@@ -32,7 +32,7 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
|
||||
} else if (isMcpRequest) {
|
||||
responseModel = services.mcpResponse;
|
||||
} else {
|
||||
responseModel = models.response;
|
||||
responseModel = services.response;
|
||||
}
|
||||
|
||||
const res = await responseModel.getById(responseId);
|
||||
@@ -41,9 +41,9 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
|
||||
await removeResponse(res);
|
||||
const response = await responseModel.getLatestForRequestId(requestId, workspaceMeta.activeEnvironmentId);
|
||||
if (response?.requestVersionId) {
|
||||
await models.requestVersion.restore(response.requestVersionId);
|
||||
await services.requestVersion.restore(response.requestVersionId);
|
||||
}
|
||||
await models.requestMeta.updateOrCreateByParentId(requestId, {
|
||||
await services.requestMeta.updateOrCreateByParentId(requestId, {
|
||||
activeResponseId: response?._id || null,
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import { getContentDispositionHeader } from '~/common/misc';
|
||||
import type {
|
||||
Environment,
|
||||
RequestMeta,
|
||||
ResponseInfo,
|
||||
RunnerResultPerRequestPerIteration,
|
||||
UserUploadEnvironment,
|
||||
@@ -18,7 +19,6 @@ import type { ResponsePatch } from '~/main/network/libcurl-promise';
|
||||
import type { TimingStep } from '~/main/network/request-timing';
|
||||
import * as models from '~/models';
|
||||
import { getBodyStream } from '~/models/helpers/response-operations';
|
||||
import type { RequestMeta } from '~/models/request-meta';
|
||||
import {
|
||||
defaultSendActionRuntime,
|
||||
fetchRequestData,
|
||||
@@ -87,14 +87,14 @@ const writeToDownloadPath = (
|
||||
return new Promise(resolve => {
|
||||
readStream.on('end', async () => {
|
||||
responsePatch.error = `Saved to ${downloadPathAndName}`;
|
||||
const response = await models.response.create(responsePatch, maxHistoryResponses);
|
||||
await models.requestMeta.update(requestMeta, { activeResponseId: response._id });
|
||||
const response = await services.response.create(responsePatch, maxHistoryResponses);
|
||||
await services.requestMeta.update(requestMeta, { activeResponseId: response._id });
|
||||
resolve(null);
|
||||
});
|
||||
readStream.on('error', async err => {
|
||||
console.warn('Failed to download request after sending', responsePatch.bodyPath, err);
|
||||
const response = await models.response.create(responsePatch, maxHistoryResponses);
|
||||
await models.requestMeta.update(requestMeta, { activeResponseId: response._id });
|
||||
const response = await services.response.create(responsePatch, maxHistoryResponses);
|
||||
await services.requestMeta.update(requestMeta, { activeResponseId: response._id });
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
@@ -130,7 +130,7 @@ export const sendActionImplementation = async (options: {
|
||||
|
||||
window.main.startExecution({ requestId });
|
||||
const requestData = await fetchRequestData(requestId);
|
||||
const requestMeta = await models.requestMeta.getOrCreateByParentId(requestId);
|
||||
const requestMeta = await services.requestMeta.getOrCreateByParentId(requestId);
|
||||
const transientVariables = nullableTransientVariables || {
|
||||
...models.environment.init(),
|
||||
_id: uuidv4(),
|
||||
@@ -153,7 +153,7 @@ export const sendActionImplementation = async (options: {
|
||||
);
|
||||
|
||||
if ('error' in mutatedContext) {
|
||||
const createdResponse = await models.response.create(
|
||||
const createdResponse = await services.response.create(
|
||||
{
|
||||
_id: requestData.responseId,
|
||||
parentId: requestId,
|
||||
@@ -164,7 +164,7 @@ export const sendActionImplementation = async (options: {
|
||||
},
|
||||
requestData.settings.maxHistoryResponses,
|
||||
);
|
||||
await models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
await services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
window.main.completeExecutionStep({ requestId });
|
||||
return { nextRequestIdOrName: mutatedContext.execution?.nextRequestIdOrName };
|
||||
}
|
||||
@@ -173,7 +173,7 @@ export const sendActionImplementation = async (options: {
|
||||
// cancel request running if skipRequest in pre-request script
|
||||
|
||||
// create and update response to activeResponse
|
||||
const createdResponse = await models.response.create(
|
||||
const createdResponse = await services.response.create(
|
||||
{
|
||||
_id: requestData.responseId,
|
||||
parentId: requestId,
|
||||
@@ -184,7 +184,7 @@ export const sendActionImplementation = async (options: {
|
||||
},
|
||||
requestData.settings.maxHistoryResponses,
|
||||
);
|
||||
await models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
await services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
window.main.completeExecutionStep({ requestId });
|
||||
return { nextRequestIdOrName: mutatedContext.execution?.nextRequestIdOrName };
|
||||
}
|
||||
@@ -228,7 +228,7 @@ export const sendActionImplementation = async (options: {
|
||||
window.main.completeExecutionStep({ requestId });
|
||||
|
||||
if ('error' in response) {
|
||||
const createdResponse = await models.response.create(
|
||||
const createdResponse = await services.response.create(
|
||||
{
|
||||
_id: requestData.responseId,
|
||||
parentId: requestId,
|
||||
@@ -239,7 +239,7 @@ export const sendActionImplementation = async (options: {
|
||||
},
|
||||
requestData.settings.maxHistoryResponses,
|
||||
);
|
||||
await models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
await services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
window.main.completeExecutionStep({ requestId });
|
||||
return { nextRequestIdOrName: mutatedContext.execution?.nextRequestIdOrName };
|
||||
}
|
||||
@@ -270,7 +270,7 @@ export const sendActionImplementation = async (options: {
|
||||
});
|
||||
|
||||
if ('error' in postMutatedContext) {
|
||||
const createdResponse = await models.response.create(
|
||||
const createdResponse = await services.response.create(
|
||||
{
|
||||
_id: requestData.responseId,
|
||||
parentId: requestId,
|
||||
@@ -281,7 +281,7 @@ export const sendActionImplementation = async (options: {
|
||||
},
|
||||
requestData.settings.maxHistoryResponses,
|
||||
);
|
||||
await models.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
await services.requestMeta.updateOrCreateByParentId(requestId, { activeResponseId: createdResponse._id });
|
||||
window.main.completeExecutionStep({ requestId });
|
||||
return { nextRequestIdOrName: postMutatedContext.execution?.nextRequestIdOrName };
|
||||
}
|
||||
@@ -307,8 +307,8 @@ export const sendActionImplementation = async (options: {
|
||||
: baseResponsePatch;
|
||||
|
||||
if (!shouldWriteToFile) {
|
||||
const response = await models.response.create(responsePatch, requestData.settings.maxHistoryResponses);
|
||||
await models.requestMeta.update(requestMeta, { activeResponseId: response._id });
|
||||
const response = await services.response.create(responsePatch, requestData.settings.maxHistoryResponses);
|
||||
await services.requestMeta.update(requestMeta, { activeResponseId: response._id });
|
||||
return { nextRequestIdOrName: postMutatedContext.execution?.nextRequestIdOrName };
|
||||
}
|
||||
|
||||
@@ -351,13 +351,13 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
|
||||
ignoreUndefinedEnvVariable,
|
||||
});
|
||||
|
||||
const requestMeta = await models.requestMeta.getByParentId(requestId);
|
||||
const requestMeta = await services.requestMeta.getByParentId(requestId);
|
||||
|
||||
if (requestMeta?.activeResponseId) {
|
||||
const response = await models.response.getById(requestMeta.activeResponseId);
|
||||
const response = await services.response.getById(requestMeta.activeResponseId);
|
||||
if (response) {
|
||||
const settings = await services.settings.getOrCreate();
|
||||
const activeRequest = await models.request.getById(requestId);
|
||||
const activeRequest = await services.request.getById(requestId);
|
||||
|
||||
if (activeRequest) {
|
||||
window.main.trackSegmentEvent({
|
||||
|
||||
@@ -9,6 +9,10 @@ import type {
|
||||
McpResponse,
|
||||
MockRoute,
|
||||
MockServer,
|
||||
Request,
|
||||
RequestMeta,
|
||||
RequestVersion,
|
||||
Response,
|
||||
SocketIOPayload,
|
||||
SocketIORequest,
|
||||
SocketIOResponse,
|
||||
@@ -20,11 +24,6 @@ import type { BaseModel } from '~/models';
|
||||
import * as models from '~/models';
|
||||
import * as requestOperations from '~/models/helpers/request-operations';
|
||||
import { getBodyBuffer } from '~/models/helpers/response-operations';
|
||||
import { isGraphqlSubscriptionRequest } from '~/models/request';
|
||||
import { type Request } from '~/models/request';
|
||||
import { type RequestMeta } from '~/models/request-meta';
|
||||
import type { RequestVersion } from '~/models/request-version';
|
||||
import type { Response } from '~/models/response';
|
||||
import { showResourceNotFoundToast } from '~/ui/components/toast-notification';
|
||||
|
||||
import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.request.$requestId';
|
||||
@@ -70,15 +69,19 @@ export interface RequestLoaderData {
|
||||
mockServerAndRoutes: (MockServer & { routes: MockRoute[] })[];
|
||||
}
|
||||
|
||||
const getResponseModelName = (request: Request | WebSocketRequest | SocketIORequest | GrpcRequest) => {
|
||||
const { isGraphqlSubscriptionRequest } = models.request;
|
||||
const getResponseOperations = (request: Request | WebSocketRequest | SocketIORequest | GrpcRequest) => {
|
||||
const isGraphqlWsRequest = isGraphqlSubscriptionRequest(request);
|
||||
|
||||
if (models.webSocketRequest.isWebSocketRequest(request) || isGraphqlWsRequest) {
|
||||
return 'webSocketResponse' as const;
|
||||
return services.webSocketResponse;
|
||||
}
|
||||
|
||||
if (models.socketIORequest.isSocketIORequest(request)) {
|
||||
return 'socketIOResponse' as const;
|
||||
return services.socketIOResponse;
|
||||
}
|
||||
return 'response' as const;
|
||||
|
||||
return services.response;
|
||||
};
|
||||
|
||||
export async function clientLoader({ params }: Route.ClientLoaderArgs) {
|
||||
@@ -122,7 +125,7 @@ export async function clientLoader({ params }: Route.ClientLoaderArgs) {
|
||||
requestVersions: [],
|
||||
} as GrpcRequestLoaderData;
|
||||
}
|
||||
const activeRequestMeta = await models.requestMeta.updateOrCreateByParentId(requestId, { lastActive: Date.now() });
|
||||
const activeRequestMeta = await services.requestMeta.updateOrCreateByParentId(requestId, { lastActive: Date.now() });
|
||||
const { filterResponsesByEnv } = await services.settings.get();
|
||||
const isGraphqlWsRequest = isGraphqlSubscriptionRequest(activeRequest);
|
||||
|
||||
@@ -145,22 +148,16 @@ export async function clientLoader({ params }: Route.ClientLoaderArgs) {
|
||||
activeResponse: activeResponse || null,
|
||||
requestPayload,
|
||||
responses,
|
||||
requestVersions: await models.requestVersion.findByParentId(requestId),
|
||||
requestVersions: await services.requestVersion.findByParentId(requestId),
|
||||
} as McpRequestLoaderData;
|
||||
}
|
||||
|
||||
const responseModelName = getResponseModelName(activeRequest);
|
||||
const responseService =
|
||||
responseModelName === 'webSocketResponse'
|
||||
? services.webSocketResponse
|
||||
: responseModelName === 'socketIOResponse'
|
||||
? services.socketIOResponse
|
||||
: models.response;
|
||||
const responseOperations = getResponseOperations(activeRequest);
|
||||
|
||||
const activeResponse = activeRequestMeta.activeResponseId
|
||||
? await responseService.getById(activeRequestMeta.activeResponseId)
|
||||
: await responseService.getLatestForRequestId(requestId, activeWorkspaceMeta.activeEnvironmentId);
|
||||
const allResponses = (await responseService.findByParentId(requestId)) as (
|
||||
? await responseOperations.getById(activeRequestMeta.activeResponseId)
|
||||
: await responseOperations.getLatestForRequestId(requestId, activeWorkspaceMeta.activeEnvironmentId);
|
||||
const allResponses = (await responseOperations.findByParentId(requestId)) as (
|
||||
| Response
|
||||
| WebSocketResponse
|
||||
| SocketIOResponse
|
||||
@@ -211,7 +208,7 @@ export async function clientLoader({ params }: Route.ClientLoaderArgs) {
|
||||
activeRequestMeta,
|
||||
activeResponse,
|
||||
responses,
|
||||
requestVersions: await models.requestVersion.findByParentId(requestId),
|
||||
requestVersions: await services.requestVersion.findByParentId(requestId),
|
||||
mockServerAndRoutes,
|
||||
requestPayload: socketIOPayload,
|
||||
} as SocketIORequestLoaderData;
|
||||
@@ -222,7 +219,7 @@ export async function clientLoader({ params }: Route.ClientLoaderArgs) {
|
||||
activeRequestMeta,
|
||||
activeResponse,
|
||||
responses,
|
||||
requestVersions: await models.requestVersion.findByParentId(requestId),
|
||||
requestVersions: await services.requestVersion.findByParentId(requestId),
|
||||
mockServerAndRoutes,
|
||||
} as RequestLoaderData | WebSocketRequestLoaderData;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import type { GrpcRequestMeta } from '~/insomnia-data';
|
||||
import type { GrpcRequestMeta, RequestMeta } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import * as models from '~/models';
|
||||
import type { RequestMeta } from '~/models/request-meta';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
@@ -17,7 +16,7 @@ export async function clientAction({ params, request }: Route.ClientActionArgs)
|
||||
await services.grpcRequestMeta.updateOrCreateByParentId(requestId, patch);
|
||||
return null;
|
||||
}
|
||||
await models.requestMeta.updateOrCreateByParentId(requestId, patch);
|
||||
await services.requestMeta.updateOrCreateByParentId(requestId, patch);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { href } from 'react-router';
|
||||
import type { WebSocketRequest } from '~/insomnia-data';
|
||||
import { models } from '~/insomnia-data';
|
||||
import * as requestOperations from '~/models/helpers/request-operations';
|
||||
import { getPathParametersFromUrl, isRequest } from '~/models/request';
|
||||
import { SegmentEvent } from '~/ui/analytics';
|
||||
import { updateMimeType } from '~/ui/components/dropdowns/content-type-dropdown';
|
||||
import { invariant } from '~/utils/invariant';
|
||||
@@ -11,6 +10,8 @@ import { createFetcherSubmitHook } from '~/utils/router';
|
||||
|
||||
import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.request.$requestId.update';
|
||||
|
||||
const { getPathParametersFromUrl, isRequest } = models.request;
|
||||
|
||||
export async function clientAction({ params, request }: Route.ClientActionArgs) {
|
||||
const { requestId } = params;
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { href } from 'react-router';
|
||||
|
||||
import type { Request } from '~/insomnia-data';
|
||||
import { services } from '~/insomnia-data';
|
||||
import * as models from '~/models';
|
||||
import type { Request } from '~/models/request';
|
||||
import {
|
||||
fetchRequestData,
|
||||
responseTransform,
|
||||
@@ -23,10 +22,10 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
const mockRoute = await services.mockRoute.getById(patch.parentId);
|
||||
invariant(mockRoute, 'mock route not found');
|
||||
// Get or create a testing request for this mock route
|
||||
const childRequests = await models.request.findByParentId(mockRoute._id);
|
||||
const testRequest = childRequests[0] || (await models.request.create({ parentId: mockRoute._id, isPrivate: true }));
|
||||
const childRequests = await services.request.findByParentId(mockRoute._id);
|
||||
const testRequest = childRequests[0] || (await services.request.create({ parentId: mockRoute._id, isPrivate: true }));
|
||||
invariant(testRequest, 'mock route is missing a testing request');
|
||||
const req = await models.request.update(testRequest, patch);
|
||||
const req = await services.request.update(testRequest, patch);
|
||||
|
||||
const { environment, settings, clientCertificates, caCert, activeEnvironmentId, timelinePath, responseId } =
|
||||
await fetchRequestData(req._id);
|
||||
@@ -55,7 +54,7 @@ export async function clientAction({ request }: Route.ClientActionArgs) {
|
||||
);
|
||||
|
||||
const response = await responseTransform(res, activeEnvironmentId, renderedRequest, renderResult.context);
|
||||
await models.response.create(response);
|
||||
await services.response.create(response);
|
||||
window.main.completeExecutionStep({ requestId: req._id });
|
||||
return null;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user