Merge branch 'develop' into chore/node-20-actions

This commit is contained in:
Vivek Thuravupala
2026-06-02 17:29:35 -07:00
committed by GitHub
734 changed files with 10752 additions and 5711 deletions

1
.gitignore vendored
View File

@@ -41,3 +41,4 @@ rootCA2.*
final.cpp
insomnia.ico
final.rc
.tmp*

View File

@@ -30,6 +30,7 @@
"Dismissable",
"getinsomnia",
"inso",
"Konnect",
"libcurl",
"mockbin",
"Revalidator",

View File

@@ -1,6 +1,7 @@
# AGENTS.md
## Tech Stack
- **UI:** React with React Router (loaders/actions pattern)
- **Components:** React Aria Components
- **Desktop Shell:** Electron (main + renderer processes)
@@ -9,14 +10,17 @@
- **Database:** NeDB (`@seald-io/nedb`) — embedded NoSQL
- **Build/Dev:** Vite, npm workspaces monorepo
*See `package.json` for current versions and `.nvmrc` for the Node version.*
_See `package.json` for current versions and `.nvmrc` for the Node version._
## Strict Rules
- **No unsolicited formatting.** Rely on ESLint/Prettier. Do not reformat existing code.
- **Strict scoping.** Only modify code directly related to the prompt. Do not refactor adjacent code unless asked.
## Command Output
Prefer quiet command variants to minimise output volume:
- `git log --oneline -20` not `git log`
- `git diff --stat` not `git diff`
- `npm test --silent` not `npm test`
@@ -25,6 +29,7 @@ Prefer quiet command variants to minimise output volume:
- Use `Grep` with `head_limit` rather than unrestricted searches
## Validation Commands
Run from repo root before considering work complete:
```bash
@@ -33,13 +38,26 @@ npm run type-check # TypeScript check all workspaces
npm test # Tests all workspaces (or: npm test -w packages/insomnia)
```
## Worktree Setup
- New git worktrees may not have `node_modules` yet. Before installing or validating, switch to the repo's required runtime from the worktree root:
```bash
fnm use "$(cat .nvmrc)"
node -v
npm -v
```
- This repo expects the `.nvmrc` Node version and npm 11+. If `fnm` is unavailable, manually use an equivalent Node/npm version before running any `npm` commands.
- After switching versions in a fresh worktree, install dependencies from repo root with `npm ci`.
- Do **not** use `npm ci --ignore-scripts` for normal worktree setup. It leaves Electron partially installed, which later breaks builds, renderer import checks, and other validation commands.
## Repository Structure
`packages/`
`insomnia/` ← Main Electron app
`src/`
`common/` ← Shared utils, settings types
`models/` ← Data model definitions
`insomnia-data/` ← Model defaults, init(), NeDB db implementation, business logic
`routes/` ← React Router files (clientLoader/clientAction)
`ui/` ← React components, hooks, `insomnia-fetch.ts`
`main/` ← Electron IPC handlers, `preload.ts`
@@ -47,11 +65,13 @@ npm test # Tests all workspaces (or: npm test -w packages/insomnia)
`sync/` ← Git/VCS sync
`network/` ← Request execution engine
`templating/` ← Nunjucks rendering (Web Worker)
`insomnia-data/` ← Data models, services, NeDB implementation, shared data utilities
`insomnia-api/` ← Cloud API client
`insomnia-inso/` ← CLI tool
`insomnia-testing/` ← Test framework
## Data Model Hierarchy
Organization
→ Project (local | remote/cloud | git-backed)
→ Workspace (scope: 'collection' | 'design')
@@ -64,6 +84,7 @@ Organization
**Note:** A Workspace with `scope: 'collection'` IS the collection.
## Key Patterns
- **Route-Based Actions:** Mutations use React Router's `clientAction` (`src/routes/`).
- **CRITICAL:** `clientAction` blocks navigation. For long-running UI operations, use plain async functions instead.
- **Database Buffering:** Always buffer bulk writes (`database.bufferChangesIndefinitely()`, then `flushChanges()`). Unbuffered writes fire UI revalidation per operation, causing severe lag.
@@ -79,49 +100,6 @@ Organization
- New test imports: `import { test } from '../../playwright/test'` and `import { expect } from '@playwright/test'`.
## Sensitive Data
- **Vault system (AES-GCM):** For environment secrets (`EnvironmentKvPairDataType.SECRET`).
- **Electron safeStorage:** Platform-native encryption (`window.main.secretStorage`).
## cx — Semantic Code Navigation
Prefer cx over reading files. Escalate: overview → symbols → definition/references → Read tool.
### Quick reference
```
cx overview PATH file or directory table of contents
cx overview DIR --full directory overview with signatures
cx symbols [--kind K] [--name GLOB] [--file PATH] search symbols project-wide
cx symbols --kinds [--file PATH] list distinct kinds with counts
cx definition --name NAME [--from PATH] [--kind K] get a function/type body
cx references --name NAME [--file PATH] [--unique] find all usages (--unique: one per caller)
cx lang list show supported languages
cx lang add LANG [LANG...] install language grammars
```
Aliases: `cx o`, `cx s`, `cx d`, `cx r`
Kinds: fn, struct, enum, trait, type, const, class, interface, module, event
### Key patterns
- Start with `cx overview .`, drill into subdirectories — cheaper than ls + reading files
- `cx definition --name X` gives exact text for Edit tool's `old_string` without reading the whole file
- `cx references --name X --unique` shows one row per caller — use before refactoring to check blast radius
- After context compression, use `cx overview` / `cx definition` to re-orient — don't re-read full files
- Check signatures for `pub`/`export` to identify public API without reading the file
### Pagination
Default limits: definition 3, symbols 100, references 50. When truncated, stderr shows:
```
cx: 3/32 definitions for "X" | --from PATH to narrow | --offset 3 for more | --all
```
`--offset N` pages forward, `--all` bypasses, `--limit N` overrides. Narrowing with `--from`/`--file`/`--kind` is usually better than paging.
JSON: paginated → `{total, offset, limit, results: [...]}`, non-paginated → bare array.
### Missing grammars
If cx reports a missing grammar, install with `cx lang add <lang>`. Run `cx lang list` to see what's installed.

View File

@@ -22,6 +22,7 @@ There are a few more technologies and tools worth mentioning:
Insomnia uses [`npm workspaces`](https://docs.npmjs.com/cli/v9/using-npm/workspaces?v=true) to manage multiple npm packages within a single repository. There are currently the following package locations:
- `/packages` contains related packages that are consumed by `insomnia` or externally.
- `/packages/insomnia-data` contains shared data models, model services, database adapters, and common data utilities used by the app and CLI.
Insomnia Inso CLI is built using a series of steps
@@ -61,7 +62,6 @@ There are a few notable directories inside it:
- `/src/ui` React components and styling.
- `/src/common` Utilities used across both main and render processes.
- `/src/plugins` Logic around installation and usage of plugins.
- `/src/insomnia-data` Data models, services and database for managing application state.
- `/src/network` Sending requests and performing auth (e.g. OAuth 2).
- `/src/templating` Nunjucks and rendering related code.
- `/src/sync` and `/src/account` Team sync and account stuff.

View File

@@ -21,12 +21,12 @@ const generalRestrictedImportPatterns = [
// Block relative paths to insomnia-data
{
group: ['./**/insomnia-data', './**/insomnia-data/**', '../**/insomnia-data', '../**/insomnia-data/**'],
message: "Please use '~/insomnia-data' instead of relative paths",
message: "Please use 'insomnia-data' instead of relative paths",
},
// Only allow ~/insomnia-data and ~/insomnia-data/node
// Only allow supported insomnia-data entrypoints
{
regex: '^~/insomnia-data/(?!node($|/)).+',
message: "Only '~/insomnia-data' and '~/insomnia-data/node' are allowed",
regex: '^insomnia-data/(?!node($|/)|common($|/)).+',
message: "Only 'insomnia-data', 'insomnia-data/node' and 'insomnia-data/common' are allowed",
},
];
const rendererNodeMigrationOffenders = [
@@ -43,6 +43,8 @@ const rendererNodeRestrictionIgnores = [
...rendererNodeMigrationOffenders,
'packages/insomnia/src/common/__tests__/**/*.{ts,tsx}',
'packages/insomnia/src/common/send-request.ts',
'packages/insomnia/src/common/bundle-spectral-ruleset.ts',
'packages/insomnia/src/common/private-host.ts',
];
export default defineConfig([

116
package-lock.json generated
View File

@@ -12,6 +12,7 @@
"workspaces": [
"packages/insomnia-testing",
"packages/insomnia",
"packages/insomnia-data",
"packages/insomnia-analytics",
"packages/insomnia-api",
"packages/insomnia-inso",
@@ -10490,13 +10491,6 @@
"@types/node": "*"
}
},
"node_modules/@types/nunjucks": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.6.tgz",
"integrity": "sha512-pHiGtf83na1nCzliuAdq8GowYiXvH5l931xZ0YEHaLMNFgynpEqx+IPStlu7UaDkehfvl01e4x/9Tpwhy7Ue3w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/oidc-provider": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/@types/oidc-provider/-/oidc-provider-8.8.1.tgz",
@@ -11354,12 +11348,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/a-sync-waterfall": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
"integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",
"license": "MIT"
},
"node_modules/abbrev": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz",
@@ -11998,12 +11986,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"license": "MIT"
},
"node_modules/assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
@@ -18418,6 +18400,10 @@
"resolved": "packages/insomnia-api",
"link": true
},
"node_modules/insomnia-data": {
"resolved": "packages/insomnia-data",
"link": true
},
"node_modules/insomnia-inso": {
"resolved": "packages/insomnia-inso",
"link": true
@@ -20563,6 +20549,35 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"license": "MIT"
},
"node_modules/liquidjs": {
"version": "10.27.0",
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.27.0.tgz",
"integrity": "sha512-tw/OA59K7aIBlMKIrKlumr37fiZUheShVHXY8cVctWisgY1p9mc5hreOvlreoS0wTiwlWk14Ya7305c2a/Cg5w==",
"license": "MIT",
"dependencies": {
"commander": "^10.0.0"
},
"bin": {
"liquid": "bin/liquid.js",
"liquidjs": "bin/liquid.js"
},
"engines": {
"node": ">=16"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/liquidjs"
}
},
"node_modules/liquidjs/node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/localforage": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
@@ -22347,40 +22362,6 @@
"integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==",
"license": "MIT"
},
"node_modules/nunjucks": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz",
"integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==",
"license": "BSD-2-Clause",
"dependencies": {
"a-sync-waterfall": "^1.0.0",
"asap": "^2.0.3",
"commander": "^5.1.0"
},
"bin": {
"nunjucks-precompile": "bin/precompile"
},
"engines": {
"node": ">= 6.9.0"
},
"peerDependencies": {
"chokidar": "^3.3.0"
},
"peerDependenciesMeta": {
"chokidar": {
"optional": true
}
}
},
"node_modules/nunjucks/node_modules/commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/nwsapi": {
"version": "2.2.23",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz",
@@ -29187,10 +29168,10 @@
"@rjsf/core": "6.0.0-beta.15",
"@rjsf/utils": "6.0.0-beta.15",
"@rjsf/validator-ajv8": "6.0.0-beta.15",
"@seald-io/nedb": "^4.1.1",
"@sentry/electron": "^6.5.0",
"@stoplight/spectral-core": "^1.22.0",
"@stoplight/spectral-formats": "^1.8.2",
"@stoplight/spectral-ref-resolver": "^1.0.5",
"@stoplight/spectral-ruleset-bundler": "1.7.0",
"@stoplight/spectral-rulesets": "^1.22.1",
"@tailwindcss/typography": "^0.5.16",
@@ -29245,13 +29226,13 @@
"json-order": "^1.1.3",
"jsonlint-mod-fixed": "1.7.7",
"jsonpath-plus": "^10.3.0",
"liquidjs": "^10.27.0",
"marked": "^5.1.2",
"mime-types": "^2.1.35",
"mocha": "^11.7.5",
"monaco-editor": "^0.52.2",
"multiparty": "^4.2.3",
"node-forge": "^1.3.1",
"nunjucks": "^3.2.4",
"oauth-1.0a": "^2.2.6",
"objectpath": "^2.0.0",
"papaparse": "^5.5.2",
@@ -29309,7 +29290,6 @@
"@types/ncp": "^2.0.8",
"@types/nedb": "^1.8.16",
"@types/node-forge": "^1.3.11",
"@types/nunjucks": "^3.2.6",
"@types/papaparse": "^5.3.15",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.6",
@@ -29354,6 +29334,23 @@
"@getinsomnia/insomnia-v3-fetch": "^1.0.1"
}
},
"packages/insomnia-data": {
"version": "12.5.1-alpha.0",
"license": "Apache-2.0",
"dependencies": {
"@seald-io/nedb": "^4.1.1",
"deep-equal": "2.2.3",
"graphql": "^16.10.0",
"uuid": "^9.0.1"
},
"devDependencies": {
"@getinsomnia/node-libcurl": "3.2.2",
"@modelcontextprotocol/sdk": "^1.17.5",
"@types/deep-equal": "^1.0.4",
"mocha": "^11.7.5",
"type-fest": "^4.40.0"
}
},
"packages/insomnia-inso": {
"version": "12.5.1-alpha.0",
"license": "Apache-2.0",
@@ -29365,7 +29362,7 @@
"@stoplight/spectral-rulesets": "^1.22.1",
"@stoplight/types": "^14.1.1",
"commander": "^12.1.0",
"consola": "^2.15.3",
"consola": "^3.4.2",
"cosmiconfig": "^9.0.0",
"enquirer": "^2.4.1",
"picocolors": "^1.1.1",
@@ -29398,10 +29395,6 @@
"node": "^12.20 || >=14.13"
}
},
"packages/insomnia-inso/node_modules/consola": {
"version": "2.15.3",
"license": "MIT"
},
"packages/insomnia-scripting-environment": {
"version": "12.5.1-alpha.0",
"license": "Apache-2.0",
@@ -29416,6 +29409,7 @@
"csv-parse": "^5.5.5",
"deep-equal": "2.2.3",
"es-toolkit": "^1.39.8",
"liquidjs": "^10.27.0",
"moment": "^2.30.1",
"tv4": "^1.3.0",
"uuid": "^9.0.1",

View File

@@ -17,6 +17,7 @@
"workspaces": [
"packages/insomnia-testing",
"packages/insomnia",
"packages/insomnia-data",
"packages/insomnia-analytics",
"packages/insomnia-api",
"packages/insomnia-inso",

View File

@@ -86,6 +86,7 @@ export enum AnalyticsEvent {
aiFeatureEnabled = 'AI Feature Enabled',
aiFeatureDisabled = 'AI Feature Disabled',
installPlugin = 'Plugin Installed',
AppMenuPreferencesClicked = 'App Menu Preferences Clicked',
homepageFiltered = 'homepage-filtered',
quickSearchOpenedByKeyboard = 'quick-search-opened-by-keyboard',
@@ -134,6 +135,7 @@ export enum AnalyticsEvent {
projectListFiltered = 'project-list-filtered',
projectSwitched = 'project-switched',
organizationSwitched = 'organization-switched',
uploadLintRulesetClicked = 'upload-lint-ruleset-clicked',
}
export enum InsoEvent {

View File

@@ -95,9 +95,9 @@ Renderer services path:
### Main
```ts
import { initDatabase, initServices } from '~/insomnia-data';
import { initDatabase, initServices } from 'insomnia-data';
import { mainDatabase } from '~/main/database.main';
import { servicesNodeImpl } from '~/insomnia-data/node';
import { servicesNodeImpl } from 'insomnia-data/node';
await initDatabase(mainDatabase);
initServices(servicesNodeImpl);
@@ -106,7 +106,7 @@ initServices(servicesNodeImpl);
### Renderer
```ts
import { initDatabase, initServices } from '~/insomnia-data';
import { initDatabase, initServices } from 'insomnia-data';
import { clientDatabase } from '~/ui/database.client';
await initDatabase(clientDatabase);
@@ -116,8 +116,8 @@ initServices(window._dataServices);
### Inso / Node
```ts
import { initDatabase, initServices } from '~/insomnia-data';
import { createNedbDatabase, servicesNodeImpl } from '~/insomnia-data/node';
import { initDatabase, initServices } from 'insomnia-data';
import { createNedbDatabase, servicesNodeImpl } from 'insomnia-data/node';
await initDatabase(createNedbDatabase());
initServices(servicesNodeImpl);
@@ -126,7 +126,7 @@ initServices(servicesNodeImpl);
### Consuming
```ts
import { services, models, type Request } from '~/insomnia-data';
import { services, models, type Request } from 'insomnia-data';
const mcpRequest = await services.mcpRequest.create({ url: 'http://localhost:3000' });
const all = await services.mcpRequest.all();

View File

@@ -1,8 +1,7 @@
import type { BaseGitCredentialsV2 } from 'insomnia-data';
import { models, services } from 'insomnia-data';
import { describe, expect, it } from 'vitest';
import type { BaseGitCredentialsV2 } from '~/insomnia-data';
import { models, services } from '~/insomnia-data';
const { init, isGitCredentialsV2, supportsRenewal } = models.gitCredentials;
describe('init()', () => {

View File

@@ -1,7 +1,6 @@
import { models, services } from 'insomnia-data';
import { describe, expect, it, vi } from 'vitest';
import { models, services } from '~/insomnia-data';
describe('init()', () => {
it('contains all required fields', async () => {
expect(models.grpcRequestMeta.init()).toEqual({

View File

@@ -1,7 +1,6 @@
import { models, services } from 'insomnia-data';
import { describe, expect, it, vi } from 'vitest';
import { models, services } from '~/insomnia-data';
describe('init()', () => {
it('contains all required fields', async () => {
Date.now = vi.fn().mockReturnValue(1_478_795_580_200);

View File

@@ -1,7 +1,6 @@
import { models } from 'insomnia-data';
import { describe, expect, it } from 'vitest';
import { models } from '~/insomnia-data';
const { getModel, mustGetModel } = models;
describe('index', () => {

View File

@@ -1,7 +1,6 @@
import { models, services } from 'insomnia-data';
import { describe, expect, it, vi } from 'vitest';
import { models, services } from '~/insomnia-data';
describe('init()', () => {
it('contains all required fields', async () => {
expect(models.protoFile.init()).toEqual({

View File

@@ -1,7 +1,6 @@
import { services } from 'insomnia-data';
import { describe, expect, it } from 'vitest';
import { services } from '~/insomnia-data';
describe('create()', () => {
it('fails when missing parentId', async () => {
expect(() =>

View File

@@ -5,9 +5,6 @@
* we added comments to in request.ts, ensuring they work correctly.
*/
import { v4 as uuidv4 } from 'uuid';
import { beforeEach, describe, expect, it } from 'vitest';
import type {
AuthTypeAPIKey,
AuthTypeAsap,
@@ -24,8 +21,10 @@ import type {
RequestBody,
RequestHeader,
RequestParameter,
} from '~/insomnia-data';
import { services } from '~/insomnia-data';
} from 'insomnia-data';
import { services } from 'insomnia-data';
import { v4 as uuidv4 } from 'uuid';
import { beforeEach, describe, expect, it } from 'vitest';
// @vitest-environment jsdom
describe('Request Model - Comprehensive Tests', () => {

View File

@@ -0,0 +1,23 @@
export const CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded';
export const CONTENT_TYPE_GRAPHQL = 'application/graphql';
export const CONTENT_TYPE_JSON = 'application/json';
export const METHOD_GET = 'GET';
export function getContentTypeFromHeaders(headers: any[], defaultValue: string | null = null) {
if (!Array.isArray(headers)) {
return null;
}
const header = headers.find(({ name }) => name.toLowerCase() === 'content-type');
return header ? header.value : defaultValue;
}
export type OAuth1SignatureMethod = 'HMAC-SHA1' | 'RSA-SHA1' | 'HMAC-SHA256' | 'PLAINTEXT';
export const SIGNATURE_METHOD_HMAC_SHA1: OAuth1SignatureMethod = 'HMAC-SHA1';
export const SIGNATURE_METHOD_HMAC_SHA256: OAuth1SignatureMethod = 'HMAC-SHA256';
export const SIGNATURE_METHOD_RSA_SHA1: OAuth1SignatureMethod = 'RSA-SHA1';
export const SIGNATURE_METHOD_PLAINTEXT: OAuth1SignatureMethod = 'PLAINTEXT';
export const getAppDefaultTheme = () => 'default';
export const getAppDefaultLightTheme = () => 'studio-light';
export const getAppDefaultDarkTheme = () => 'default';

View File

@@ -0,0 +1,12 @@
export * from './querystring';
export * from './invariant';
export * from './ndjson';
export * from './type';
export * from './misc';
export * from './constants';
export * from './preview-mode';
export * from './platform';
export * from './strings';
export * from './hotkeys';
export * from './settings';
export * from './keyboard-keys';

View File

@@ -0,0 +1,15 @@
// Throw an error if the condition fails
// > Not providing an inline default argument for message as the result is smaller
export function invariant(
condition: any,
// Can provide a string, or a function that returns a string for cases where
// the message takes a fair amount of effort to compute
message?: string | (() => string),
): asserts condition {
if (condition) {
return;
}
// Condition not passed
throw new Error(typeof message === 'function' ? message() : message);
}

View File

@@ -0,0 +1,15 @@
import { v4 as uuidv4 } from 'uuid';
/**
* Generate an ID of the format "<MODEL_NAME>_<TIMESTAMP><RANDOM>"
* @param prefix
* @returns {string}
*/
export function generateId(prefix?: string) {
const id = uuidv4().replace(/-/g, '');
if (prefix) {
return `${prefix}_${id}`;
}
return id;
}

View File

@@ -4,8 +4,15 @@ interface INodeProcess {
platform: string;
}
declare const window: {
app?: {
process: INodeProcess;
};
};
let nodeProcess: INodeProcess | undefined;
if (
// eslint-disable-next-line unicorn/no-typeof-undefined
typeof window !== 'undefined' &&
window.app?.process !== undefined &&
typeof window.app.process.platform === 'string'

View File

@@ -0,0 +1,19 @@
// Preview Modes
export const PREVIEW_MODE_FRIENDLY = 'friendly';
export const PREVIEW_MODE_SOURCE = 'source';
export const PREVIEW_MODE_RAW = 'raw';
const previewModeMap = {
[PREVIEW_MODE_FRIENDLY]: ['Preview', 'Visual Preview'],
[PREVIEW_MODE_SOURCE]: ['Source', 'Source Code'],
[PREVIEW_MODE_RAW]: ['Raw', 'Raw Data'],
};
export const PREVIEW_MODES = Object.keys(previewModeMap) as (keyof typeof previewModeMap)[];
export type PreviewMode = 'friendly' | 'source' | 'raw';
export function getPreviewModeName(previewMode: PreviewMode, useLong = false) {
if (previewMode in previewModeMap) {
return useLong ? previewModeMap[previewMode][1] : previewModeMap[previewMode][0];
}
return '';
}

View File

@@ -0,0 +1,48 @@
import { describe, expect, it } from 'vitest';
import { deconstructQueryStringToParams } from './querystring';
describe('querystring', () => {
describe('deconstructToParams()', () => {
it('builds from params', () => {
const str = deconstructQueryStringToParams('foo=bar%3F%3F&hello&hi%20there=bar%3F%3F&=&=val');
expect(str).toEqual([
{ name: 'foo', value: 'bar??' },
{ name: 'hello', value: '' },
{ name: 'hi there', value: 'bar??' },
]);
});
it('builds from params with =', () => {
const str = deconstructQueryStringToParams('foo=bar&1=2=3=4&hi');
expect(str).toEqual([
{ name: 'foo', value: 'bar' },
{ name: '1', value: '2=3=4' },
{ name: 'hi', value: '' },
]);
});
it('builds from params not strict', () => {
const str = deconstructQueryStringToParams('foo=bar%3F%3F&hello&hi%20there=bar%3F%3F&=&=val', false);
expect(str).toEqual([
{ name: 'foo', value: 'bar??' },
{ name: 'hello', value: '' },
{ name: 'hi there', value: 'bar??' },
{ name: '', value: '' },
{ name: '', value: 'val' },
]);
});
it('builds from params with strictNullHandle', () => {
const str = deconstructQueryStringToParams('foo=bar&foo1&foo2=', true, { strictNullHandling: true });
expect(str).toEqual([
{ name: 'foo', value: 'bar' },
{ name: 'foo1', value: null },
{ name: 'foo2', value: '' },
]);
});
});
});

View File

@@ -0,0 +1,78 @@
export interface IQueryStringOptions {
// Option to distinguish between parameters with(&foo=) and without(&foo) equal signs. Both are converted to empty string by default.
strictNullHandling?: boolean;
// Option to encode parameters, default to true, necessary to disable for request.settingEncodeUrl = false
encodeParams?: boolean;
}
type SearchParamsValueType = string;
export type StrictNullSearchParamsValueType = string | null;
interface ISearchParams {
name: string;
value: SearchParamsValueType;
}
interface IStrictNullSearchParams extends Omit<ISearchParams, 'value'> {
value: StrictNullSearchParamsValueType;
}
// helper function to process deconstructQueryStringToParams return type base on options parameter
type ProcessDeconstructFuncReturnType<T> = T extends { strictNullHandling: true }
? IStrictNullSearchParams[]
: ISearchParams[];
/**
* Deconstruct a querystring to name/value pairs
* @param [qs] {string}
* @param [strict=true] {boolean} - allow empty names and values
* @param [options] {IQueryStringOptions} - deconstruct options like strict null handling
* @returns {{name: string, value: string | null}[]}
*/
export const deconstructQueryStringToParams = <T extends IQueryStringOptions>(
qs?: string,
/** allow empty names and values */
strict?: boolean,
/** extra deconstruct options like strict handle null value */
options?: T,
): ProcessDeconstructFuncReturnType<T> => {
strict = strict === undefined ? true : strict;
const { strictNullHandling = false } = options || {};
const pairs: ProcessDeconstructFuncReturnType<T> = [];
type ValueType = (typeof pairs)[number]['value'];
if (!qs) {
return pairs;
}
const stringPairs = qs.split('&');
for (const stringPair of stringPairs) {
// NOTE: This only splits on first equals sign. '1=2=3' --> ['1', '2=3']
const [encodedName, ...encodedValues] = stringPair.split('=');
// Use null as value when strictNullHandling is enabled and no equal sign in string pair
const encodedValue: ValueType = encodedValues.length === 0 && strictNullHandling ? null : encodedValues.join('=');
let name = '';
try {
name = decodeURIComponent(encodedName || '');
} catch {
// Just leave it
name = encodedName;
}
let value: ValueType = '';
try {
value = strictNullHandling && encodedValue === null ? null : decodeURIComponent(encodedValue || '');
} catch {
// Just leave it
value = encodedValue;
}
if (strict && !name) {
continue;
}
// @ts-expect-error value type is converted from pairs type automatically
pairs.push({ name, value });
}
return pairs;
};

View File

@@ -145,7 +145,6 @@ export interface Settings {
pluginConfig: PluginConfigMap;
pluginNodeExtraCerts: string;
pluginPath: string;
pluginsAllowElevatedAccess: boolean;
preferredHttpVersion: HttpVersion;
proxyEnabled: boolean;
showPasswords: boolean;

View File

@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"lib": ["ES2023", "WebWorker"],
"types": []
},
"include": ["./**/*.ts"]
}

View File

@@ -0,0 +1,3 @@
export const typedKeys = <T extends object>(obj: T) => {
return Object.keys(obj) as (keyof T)[];
};

View File

@@ -5,8 +5,6 @@ import os from 'node:os';
import fsPath from 'node:path';
import NeDB from '@seald-io/nedb';
import { generateId } from '~/common/misc';
import type {
AllTypes,
ApiSpec,
@@ -22,11 +20,13 @@ import type {
GitRepository,
IDatabase,
Operation,
ProjectLintRuleset,
Query,
Workspace,
WorkspaceMeta,
} from '~/insomnia-data';
import { models } from '~/insomnia-data';
} from 'insomnia-data';
import { models } from 'insomnia-data';
import { generateId } from 'insomnia-data/common';
import { initModel } from './init-model';
import { repairDatabase } from './repair-database';
@@ -278,6 +278,10 @@ export const createNedbDatabase = <O = initOptions>(
...defaultConfig,
filename: fsPath.join(dbPath, 'insomnia.Project.db'),
}),
ProjectLintRuleset: new NeDB<ProjectLintRuleset>({
...defaultConfig,
filename: fsPath.join(dbPath, 'insomnia.ProjectLintRuleset.db'),
}),
ProtoDirectory: new NeDB({
...defaultConfig,
filename: fsPath.join(dbPath, 'insomnia.ProtoDirectory.db'),
@@ -464,7 +468,7 @@ export const createNedbDatabase = <O = initOptions>(
return docWithDefaults;
},
/** get all ancestors of specified types of a document including the original */
/** get all ancestors of specified types of a document including the original, the order of the returned array is leaf to root */
withAncestors: async function <T extends BaseModel>(doc: T | undefined, types: AllTypes[] = []) {
if (!doc) {
return [];

View File

@@ -1,9 +1,8 @@
// @ts-nocheck
import type { BaseModel } from 'insomnia-data';
import { models, services } from 'insomnia-data';
import { afterEach, assert, beforeEach, describe, expect, it, vi } from 'vitest';
import type { BaseModel } from '~/insomnia-data';
import { models, services } from '~/insomnia-data';
import type { ChangeBufferEvent } from '../..';
import { database as db } from '../..';
import * as workspaceInitModel from './init-model/workspace';

View File

@@ -1,7 +1,6 @@
import type { CookieJar } from 'insomnia-data';
import { v4 as uuidv4 } from 'uuid';
import type { CookieJar } from '~/insomnia-data';
/** Ensure every cookie has an ID property */
function migrateCookieId(cookieJar: CookieJar) {
for (const cookie of cookieJar.cookies) {

View File

@@ -1,7 +1,6 @@
import { generateId } from '~/common/misc';
import type { AllTypes, BaseModel } from '~/insomnia-data';
import { models } from '~/insomnia-data';
import { typedKeys } from '~/utils';
import type { AllTypes, BaseModel } from 'insomnia-data';
import { models } from 'insomnia-data';
import { generateId, typedKeys } from 'insomnia-data/common';
import { migrate as migrateCookieJar } from './cookie-jar';
import { migrate as migrateRequest } from './request';

View File

@@ -1,6 +1,9 @@
import { CONTENT_TYPE_FORM_URLENCODED, getContentTypeFromHeaders } from '~/common/constants';
import type { Request } from '~/insomnia-data';
import { deconstructQueryStringToParams } from '~/utils/url/querystring';
import type { Request } from 'insomnia-data';
import {
CONTENT_TYPE_FORM_URLENCODED,
deconstructQueryStringToParams,
getContentTypeFromHeaders,
} from 'insomnia-data/common';
export function migrate(doc: Request): Request {
try {

View File

@@ -3,11 +3,10 @@ import { tmpdir } from 'node:os';
import path from 'node:path';
import zlib from 'node:zlib';
import type { Response } from 'insomnia-data';
import { models, services } from 'insomnia-data';
import { describe, expect, it } from 'vitest';
import type { Response } from '~/insomnia-data';
import { models, services } from '~/insomnia-data';
import { initModel } from './index';
describe('migrate()', () => {

View File

@@ -1,4 +1,4 @@
import type { Response } from '~/insomnia-data';
import type { Response } from 'insomnia-data';
export function migrate(doc: Response) {
try {

View File

@@ -1,6 +1,6 @@
import * as hotkeys from '~/common/hotkeys';
import type { KeyboardShortcut } from '~/common/settings';
import type { Settings } from '~/insomnia-data';
import type { Settings } from 'insomnia-data';
import type { KeyboardShortcut } from 'insomnia-data/common';
import { newDefaultRegistry } from 'insomnia-data/common';
export function migrate(doc: Settings) {
try {
@@ -16,7 +16,7 @@ export function migrate(doc: Settings) {
* Ensure map is updated when new hotkeys are added
*/
function migrateEnsureHotKeys(settings: Settings): Settings {
const defaultHotKeyRegistry = hotkeys.newDefaultRegistry();
const defaultHotKeyRegistry = newDefaultRegistry();
// Remove any hotkeys that are no longer in the default registry
const hotKeyRegistry = (Object.keys(settings.hotKeyRegistry) as KeyboardShortcut[]).reduce(

View File

@@ -1,7 +1,6 @@
import { models, services } from 'insomnia-data';
import { describe, expect, it } from 'vitest';
import { models, services } from '~/insomnia-data';
import { migrate as migrateWorkspace } from './workspace';
describe('migrate()', () => {

View File

@@ -1,8 +1,7 @@
import type { Workspace } from 'insomnia-data';
import { models } from 'insomnia-data';
import type { Merge } from 'type-fest';
import type { Workspace } from '~/insomnia-data';
import { models } from '~/insomnia-data';
import * as clientCertificateService from '../../services/client-certificate';
const { WorkspaceScopeKeys } = models.workspace;

View File

@@ -1,5 +1,5 @@
import type { CookieJar, Environment, GitRepository, Workspace } from '~/insomnia-data';
import { database, models } from '~/insomnia-data';
import type { CookieJar, Environment, GitRepository, Workspace } from 'insomnia-data';
import { database, models } from 'insomnia-data';
import * as apiSpecServices from '../services/api-spec';

View File

@@ -1,5 +1,5 @@
import type { ApiSpec } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { ApiSpec } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.apiSpec;

View File

@@ -1,5 +1,5 @@
import type { CaCertificate } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { CaCertificate } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.caCertificate;

View File

@@ -1,5 +1,5 @@
import type { ClientCertificate } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { ClientCertificate } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.clientCertificate;

View File

@@ -1,5 +1,5 @@
import type { CloudProviderCredential, CloudProviderName } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { CloudProviderCredential, CloudProviderName } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.cloudCredential;

View File

@@ -1,7 +1,7 @@
import * as crypto from 'node:crypto';
import type { CookieJar } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { CookieJar } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type, prefix } = models.cookieJar;

View File

@@ -1,7 +1,7 @@
import * as crypto from 'node:crypto';
import type { Environment, Project, Workspace } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { Environment, Project, Workspace } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type, prefix, vaultEnvironmentPath } = models.environment;
const { EnvironmentKvPairDataType, EnvironmentType } = models.environment;

View File

@@ -1,5 +1,5 @@
import type { BaseGitCredentialsV2, GitCredentials, GitCredentialsV2 } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { BaseGitCredentialsV2, GitCredentials, GitCredentialsV2 } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.gitCredentials;

View File

@@ -1,5 +1,5 @@
import type { GitRepository } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { GitRepository } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const type = models.gitRepository.type;

View File

@@ -1,5 +1,5 @@
import type { GrpcRequestMeta } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { GrpcRequestMeta } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.grpcRequestMeta;
const { isGrpcRequestId } = models.grpcRequest;

View File

@@ -1,5 +1,5 @@
import type { GrpcRequest } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { GrpcRequest } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type, name } = models.grpcRequest;

View File

@@ -1,7 +1,6 @@
import { models, services } from 'insomnia-data';
import { describe, expect, it } from 'vitest';
import { models, services } from '~/insomnia-data';
import { queryAllWorkspaceUrls } from './query-all-workspace-urls';
describe('queryAllWorkspaceUrls', () => {

View File

@@ -1,6 +1,6 @@
import type { GrpcRequest, models, Request } from '~/insomnia-data';
import { database as db } from '~/insomnia-data';
import { invariant } from '~/utils/invariant';
import type { GrpcRequest, models, Request } from 'insomnia-data';
import { database as db } from 'insomnia-data';
import { invariant } from 'insomnia-data/common';
import * as workspaceService from '../workspace';

View File

@@ -1,5 +1,5 @@
import type { GrpcRequest, McpRequest, Request, SocketIORequest, WebSocketRequest } from '~/insomnia-data';
import { models } from '~/insomnia-data';
import type { GrpcRequest, McpRequest, Request, SocketIORequest, WebSocketRequest } from 'insomnia-data';
import { models } from 'insomnia-data';
import * as grpcRequestService from '../grpc-request';
import * as mcpRequestService from '../mcp-request';

View File

@@ -1,10 +1,16 @@
import fs from 'node:fs';
import zlib from 'node:zlib';
import type { Compression, McpResponse, Response, SocketIOResponse, WebSocketResponse } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { ResponseTimelineEntry } from '~/main/network/libcurl-promise';
import { deserializeNDJSON } from '~/utils/ndjson';
import type {
Compression,
McpResponse,
Response,
ResponseTimelineEntry,
SocketIOResponse,
WebSocketResponse,
} from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import { deserializeNDJSON } from 'insomnia-data/common';
import * as settingsService from '../settings';

View File

@@ -18,6 +18,7 @@ import * as oAuth2TokenService from './o-auth-2-token';
import * as organizationService from './organization';
import * as pluginDataService from './plugin-data';
import * as projectService from './project';
import * as projectLintRulesetService from './project-lint-ruleset';
import * as protoDirectoryService from './proto-directory';
import * as protoFileService from './proto-file';
import * as requestService from './request';
@@ -72,6 +73,7 @@ export const servicesNodeImpl = {
response: responseService,
runnerTestResult: runnerTestResultService,
project: projectService,
projectLintRuleset: projectLintRulesetService,
settings: settingsService,
stats: statsService,
userSession: userSessionService,

View File

@@ -1,5 +1,5 @@
import type { McpPayload } from '~/insomnia-data';
import { database, models } from '~/insomnia-data';
import type { McpPayload } from 'insomnia-data';
import { database, models } from 'insomnia-data';
const { type, name } = models.mcpPayload;

View File

@@ -1,6 +1,6 @@
import type { McpRequest } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import { invariant } from '~/utils/invariant';
import type { McpRequest } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import { invariant } from 'insomnia-data/common';
const { type } = models.mcpRequest;

View File

@@ -1,5 +1,5 @@
import type { McpResponse } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { McpResponse } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import * as requestHelpers from './helpers/request-operations';
import * as requestVersionService from './request-version';

View File

@@ -1,5 +1,5 @@
import type { MockRoute } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { MockRoute } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.mockRoute;

View File

@@ -1,5 +1,5 @@
import type { MockServer } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { MockServer } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import * as workspace from './workspace';

View File

@@ -1,5 +1,5 @@
import type { OAuth2Token } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { OAuth2Token } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.oAuth2Token;

View File

@@ -1,6 +1,5 @@
import { getOrganizations, type Organization } from 'insomnia-api';
import { models } from '~/insomnia-data';
import { models } from 'insomnia-data';
import * as userSessionService from './user-session';

View File

@@ -1,5 +1,5 @@
import type { PluginData } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { PluginData } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.pluginData;

View File

@@ -0,0 +1,24 @@
import type { ProjectLintRuleset } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.projectLintRuleset;
export function getByParentId(projectId: string) {
return db.findOne<ProjectLintRuleset>(type, { parentId: projectId });
}
export async function upsert(projectId: string, patch: Partial<ProjectLintRuleset> = {}) {
const existing = await db.findOne<ProjectLintRuleset>(type, {
parentId: projectId,
});
if (!existing) {
return db.docCreate<ProjectLintRuleset>(type, { ...patch, parentId: projectId });
}
return db.docUpdate(existing, patch);
}
export function remove(projectId: string) {
return db.removeWhere(type, { parentId: projectId });
}

View File

@@ -1,5 +1,5 @@
import type { Project, Query } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { Project, Query } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.project;

View File

@@ -1,5 +1,5 @@
import type { ProtoDirectory } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { ProtoDirectory } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.protoDirectory;

View File

@@ -1,5 +1,5 @@
import type { ProtoFile } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { ProtoFile } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.protoFile;

View File

@@ -1,5 +1,5 @@
import type { RequestGroupMeta } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { RequestGroupMeta } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.requestGroupMeta;

View File

@@ -1,5 +1,5 @@
import type { RequestGroup } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { RequestGroup } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.requestGroup;

View File

@@ -1,5 +1,5 @@
import type { RequestMeta } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { RequestMeta } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.requestMeta;

View File

@@ -1,6 +1,7 @@
import deepEqual from 'deep-equal';
import { promisify } from 'node:util';
import zlib from 'node:zlib';
import { compressObject, decompressObject } from '~/common/misc';
import deepEqual from 'deep-equal';
import type {
GrpcRequest,
McpRequest,
@@ -8,12 +9,14 @@ import type {
RequestVersion,
SocketIORequest,
WebSocketRequest,
} from '~/insomnia-data';
import { database, database as db, models } from '~/insomnia-data';
} from 'insomnia-data';
import { database, database as db, models } from 'insomnia-data';
import * as requestHelpers from './helpers/request-operations';
const { isRequest } = models.request;
const { isWebSocketRequest } = models.webSocketRequest;
const { isSocketIORequest } = models.socketIORequest;
const { type } = models.requestVersion;
const FIELDS_TO_IGNORE = [
@@ -35,11 +38,31 @@ export function findByParentId(parentId: string) {
return db.find<RequestVersion>(type, { parentId });
}
function compressObject(obj: any) {
const compressed = zlib.gzipSync(JSON.stringify(obj));
return compressed.toString('base64');
}
export async function decompressObject<ObjectType>(input: string | null): Promise<ObjectType | null> {
if (typeof input !== 'string') {
return null;
}
const jsonBuffer = await promisify(zlib.gunzip)(Buffer.from(input, 'base64'));
return JSON.parse(jsonBuffer.toString('utf8')) as ObjectType;
}
export async function getRequest<T extends Request | WebSocketRequest | SocketIORequest>(
requestVersion: RequestVersion,
) {
return await decompressObject<T>(requestVersion.compressedRequest);
}
export async function create(request: Request | WebSocketRequest | GrpcRequest | SocketIORequest | McpRequest) {
if (
!isRequest(request) &&
!models.webSocketRequest.isWebSocketRequest(request) &&
!models.socketIORequest.isSocketIORequest(request) &&
!isWebSocketRequest(request) &&
!isSocketIORequest(request) &&
!models.mcpRequest.isMcpRequest(request)
) {
throw new Error(`New ${type} was not given a valid ${request.type} instance`);
@@ -53,9 +76,7 @@ export async function create(request: Request | WebSocketRequest | GrpcRequest |
},
{ modified: -1 },
);
const latestRequest = latestRequestVersion
? decompressObject<Request | WebSocketRequest | SocketIORequest>(latestRequestVersion.compressedRequest)
: null;
const latestRequest = latestRequestVersion ? await getRequest(latestRequestVersion) : null;
const hasChanged = _diffRequests(latestRequest, request);
@@ -79,7 +100,9 @@ export async function restore(requestVersionId: string) {
return null;
}
const requestPatch = decompressObject<Request | WebSocketRequest | GrpcRequest>(requestVersion.compressedRequest);
const requestPatch = await decompressObject<Request | WebSocketRequest | GrpcRequest>(
requestVersion.compressedRequest,
);
if (!requestPatch) {
return null;

View File

@@ -1,5 +1,5 @@
import type { Request } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { Request } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type, name } = models.request;

View File

@@ -1,6 +1,5 @@
import { database as db } from '~/common/database';
import type { Response } from '~/insomnia-data';
import { models } from '~/insomnia-data';
import type { Response } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import * as requestHelpers from './helpers/request-operations';
import * as requestVersionService from './request-version';

View File

@@ -1,5 +1,5 @@
import type { RunnerTestResult } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { RunnerTestResult } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.runnerTestResult;

View File

@@ -1,5 +1,5 @@
import type { Settings } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { Settings } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
export async function all() {
let settingsList = await db.find<Settings>(models.settings.type);

View File

@@ -1,5 +1,5 @@
import type { SocketIOPayload } from '~/insomnia-data';
import { database, models } from '~/insomnia-data';
import type { SocketIOPayload } from 'insomnia-data';
import { database, models } from 'insomnia-data';
const { type, name } = models.socketIOPayload;

View File

@@ -1,5 +1,5 @@
import type { SocketIORequestMeta } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { SocketIORequestMeta } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.socketIORequestMeta;
const { isSocketIORequestId } = models.socketIORequest;

View File

@@ -1,5 +1,5 @@
import type { SocketIORequest } from '~/insomnia-data';
import { database, models } from '~/insomnia-data';
import type { SocketIORequest } from 'insomnia-data';
import { database, models } from 'insomnia-data';
const { type, name } = models.socketIORequest;

View File

@@ -1,5 +1,5 @@
import type { SocketIOResponse } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { SocketIOResponse } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import * as requestHelpers from './helpers/request-operations';
import * as requestVersionService from './request-version';

View File

@@ -1,5 +1,5 @@
import type { Project, RequestGroup, Stats, Workspace } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { Project, RequestGroup, Stats, Workspace } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.stats;
const { isRequest } = models.request;

View File

@@ -1,5 +1,5 @@
import type { UnitTestResult } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { UnitTestResult } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.unitTestResult;

View File

@@ -1,5 +1,5 @@
import type { UnitTestSuite } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { UnitTestSuite } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.unitTestSuite;

View File

@@ -1,5 +1,5 @@
import type { UnitTest } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { UnitTest } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.unitTest;

View File

@@ -1,5 +1,5 @@
import type { UserSession } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { UserSession } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.userSession;

View File

@@ -1,5 +1,5 @@
import type { WebSocketPayload } from '~/insomnia-data';
import { database, models } from '~/insomnia-data';
import type { WebSocketPayload } from 'insomnia-data';
import { database, models } from 'insomnia-data';
const { type, name } = models.webSocketPayload;

View File

@@ -1,5 +1,5 @@
import type { WebSocketRequestMeta } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { WebSocketRequestMeta } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.webSocketRequestMeta;
const { isWebSocketRequestId } = models.webSocketRequest;

View File

@@ -1,5 +1,5 @@
import type { WebSocketRequest } from '~/insomnia-data';
import { database, models } from '~/insomnia-data';
import type { WebSocketRequest } from 'insomnia-data';
import { database, models } from 'insomnia-data';
const { type, name } = models.webSocketRequest;

View File

@@ -1,5 +1,5 @@
import type { WebSocketResponse } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { WebSocketResponse } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
import * as requestHelpers from './helpers/request-operations';
import * as requestVersionService from './request-version';

View File

@@ -1,5 +1,5 @@
import type { WorkspaceMeta } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { WorkspaceMeta } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.workspaceMeta;

View File

@@ -1,5 +1,5 @@
import type { Workspace } from '~/insomnia-data';
import { database as db, models } from '~/insomnia-data';
import type { Workspace } from 'insomnia-data';
import { database as db, models } from 'insomnia-data';
const { type } = models.workspace;

View File

@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"lib": ["ES2023", "WebWorker"],
"types": ["node"]
},
"include": ["./**/*.ts"]
}

View File

@@ -0,0 +1,49 @@
{
"private": true,
"name": "insomnia-data",
"license": "Apache-2.0",
"version": "12.5.1-alpha.0",
"author": "Kong <office@konghq.com>",
"description": "Insomnia data functionalities",
"repository": {
"type": "git",
"url": "git+https://github.com/Kong/insomnia.git",
"directory": "packages/insomnia-data"
},
"bugs": {
"url": "https://github.com/kong/insomnia/issues"
},
"homepage": "https://github.com/Kong/insomnia#readme",
"exports": {
".": {
"import": "./src/index.ts",
"types": "./src/index.ts"
},
"./node": {
"import": "./node-src/index.ts",
"types": "./node-src/index.ts"
},
"./common": {
"import": "./common-src/index.ts",
"types": "./common-src/index.ts"
}
},
"scripts": {
"lint": "eslint . --ext .ts,.tsx --cache",
"type-check": "tsc -p src/tsconfig.json && tsc -p common-src/tsconfig.json && tsc -p node-src/tsconfig.json && tsc -p tsconfig.test.json",
"test": "vitest run"
},
"dependencies": {
"@seald-io/nedb": "^4.1.1",
"deep-equal": "2.2.3",
"graphql": "^16.10.0",
"uuid": "^9.0.1"
},
"devDependencies": {
"@getinsomnia/node-libcurl": "3.2.2",
"@modelcontextprotocol/sdk": "^1.17.5",
"@types/deep-equal": "^1.0.4",
"mocha": "^11.7.5",
"type-fest": "^4.40.0"
}
}

View File

@@ -0,0 +1,13 @@
import { initDatabase, initServices } from 'insomnia-data';
import { createNedbDatabase, servicesNodeImpl } from 'insomnia-data/node';
import { vi } from 'vitest';
const database = createNedbDatabase();
await initDatabase(database, { inMemoryOnly: true }, true);
await initServices(servicesNodeImpl);
import { v4Mock } from './__mocks__/uuid';
vi.mock('uuid', () => ({
v4: () => v4Mock(),
}));

Some files were not shown because too many files have changed in this diff Show More