Enable noImplicitAny. (#4864)

* Enable noImplicitAny.

* extracts PreviewMode

* Update packages/insomnia/src/network/certificate-url-parse.ts

* Add missing type.

* un-any-ifies some of the modal onDone callbacks

easy enough.

* few more onDone, but the async ones this time

* Get rid of jsonlint any.

* adds noImplicitAny support for insomnia-smoke-test

* fixes playwright type error

* avoid full @ts-ignore in playwright

Co-authored-by: Dimitri Mitropoulos <dimitrimitropoulos@gmail.com>
This commit is contained in:
John Chadwick 2022-06-15 03:41:19 +00:00 committed by GitHub
parent d1f4063e7d
commit 3234c05c6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
113 changed files with 13797 additions and 13624 deletions

57
package-lock.json generated
View File

@ -12,6 +12,7 @@
"devDependencies": {
"@jest/globals": "^28.1.0",
"@jest/types": "^28.1.0",
"@types/eslint": "^8.4.3",
"@types/node": "^17.0.21",
"@types/svgo": "^2.6.3",
"@typescript-eslint/eslint-plugin": "^5.10.2",
@ -4082,6 +4083,22 @@
"@babel/types": "^7.3.0"
}
},
"node_modules/@types/eslint": {
"version": "8.4.3",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.3.tgz",
"integrity": "sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw==",
"dev": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
}
},
"node_modules/@types/estree": {
"version": "0.0.51",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
"dev": true
},
"node_modules/@types/graceful-fs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@ -4115,6 +4132,12 @@
"@types/istanbul-lib-report": "*"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -4488,12 +4511,6 @@
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@types/json-schema": {
"version": "7.0.9",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
"dev": true
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
"version": "5.10.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz",
@ -19426,6 +19443,22 @@
"@babel/types": "^7.3.0"
}
},
"@types/eslint": {
"version": "8.4.3",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.3.tgz",
"integrity": "sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw==",
"dev": true,
"requires": {
"@types/estree": "*",
"@types/json-schema": "*"
}
},
"@types/estree": {
"version": "0.0.51",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
"dev": true
},
"@types/graceful-fs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@ -19459,6 +19492,12 @@
"@types/istanbul-lib-report": "*"
}
},
"@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -19711,12 +19750,6 @@
"eslint-utils": "^3.0.0"
},
"dependencies": {
"@types/json-schema": {
"version": "7.0.9",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
"dev": true
},
"@typescript-eslint/scope-manager": {
"version": "5.10.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz",

View File

@ -39,12 +39,14 @@
"dev": "npm start --prefix packages/insomnia"
},
"devDependencies": {
"@jest/types": "^28.1.0",
"@jest/globals": "^28.1.0",
"@jest/types": "^28.1.0",
"@types/eslint": "^8.4.3",
"@types/node": "^17.0.21",
"@types/svgo": "^2.6.3",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"esbuild-runner": "^2.2.1",
"eslint": "^8.8.0",
"eslint-config-helpers": "^1.1.0",
"eslint-plugin-filenames": "^1.3.2",
@ -55,7 +57,6 @@
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"esbuild-runner": "^2.2.1",
"jest": "^28.1.0",
"lerna": "^4.0.0",
"markdownlint-cli2": "^0.2.0",

View File

@ -1,4 +1,4 @@
const getCreds = (user, pass, encoding) => ({
const getCreds = (user: string, pass: string, encoding: BufferEncoding) => ({
raw: { user, pass },
encoded: {
user: Buffer.from(user, encoding).toString(),

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
"clean": "tsc --build tsconfig.build.json --clean",
"postclean": "rimraf dist",
"build": "tsc --build tsconfig.build.json",
"type-check": "tsc --noEmit --project tsconfig.build.json",
"test:dev": "xvfb-maybe cross-env BUNDLE=dev playwright test",
"test:build": "xvfb-maybe cross-env BUNDLE=build playwright test",
"test:package": "xvfb-maybe cross-env BUNDLE=package playwright test",

View File

@ -15,7 +15,7 @@ export const loadFixture = async (fixturePath: string) => {
export const randomDataPath = () => path.join(os.tmpdir(), 'insomnia-smoke-test', `${uuidv4()}`);
export const INSOMNIA_DATA_PATH = randomDataPath();
const pathLookup = {
const pathLookup: Record<string, string> = {
win32: path.join('win-unpacked', 'Insomnia.exe'),
darwin: path.join('mac', 'Insomnia.app', 'Contents', 'MacOS', 'Insomnia'),
linux: path.join('linux-unpacked', 'insomnia'),

View File

@ -1,5 +1,6 @@
// inspiration: https://github.com/grpc/grpc/blob/e963544eef6a76f9f86d43418ee2ac57aebba6f6/examples/node/dynamic_codegen/greeter_server.js
import * as grpc from '@grpc/grpc-js';
import { HandleCall } from '@grpc/grpc-js/build/src/server-call';
import * as protoLoader from '@grpc/proto-loader';
import path from 'path';
@ -19,9 +20,10 @@ const helloProto = grpc.loadPackageDefinition(packageDefinition).hello;
/**
* Implements the SayHello RPC method.
*/
function sayHello(call, callback) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const sayHello: HandleCall<any, any> = (call: any, callback: any) => {
callback(null, { reply: call.request.greeting });
}
};
/**
* Starts an RPC server that receives requests for the Greeter service at the given port
@ -30,7 +32,7 @@ export const startGRPCServer = (port: number) => {
return new Promise<void>((resolve, reject) => {
const server = new grpc.Server();
// @ts-expect-error generated from proto file
server.addService(helloProto.HelloService.service, { sayHello: sayHello });
server.addService(helloProto.HelloService.service, { sayHello });
server.bindAsync(`localhost:${port}`, grpc.ServerCredentials.createInsecure(), error => {
if (error) {
return reject(error);

View File

@ -1,5 +1,6 @@
import express, { urlencoded } from 'express';
import { Configuration, Provider } from 'oidc-provider';
// @ts-expect-error no typings available for this module
import { InvalidGrant } from 'oidc-provider/lib/helpers/errors';
export const oauthRoutes = (port: number) => {
@ -255,7 +256,7 @@ export const oauthRoutes = (port: number) => {
function allowLocalhostImplicit(oidc: Provider) {
const { invalidate: orig } = (oidc.Client as any).Schema.prototype;
(oidc.Client as any).Schema.prototype.invalidate = function invalidate(message, code) {
(oidc.Client as any).Schema.prototype.invalidate = function invalidate(message: any, code: any) {
if (code === 'implicit-force-https' || code === 'implicit-forbid-localhost') {
return;
}

View File

@ -14,8 +14,8 @@ test('Sign in with GitHub', async ({ app, page }) => {
const webContents = electron.BrowserWindow.getAllWindows()[0].webContents;
// Remove all navigation listeners so that only the one we inject will run
webContents.removeAllListeners('will-navigate');
webContents.on('will-navigate', (e, url) => {
e.preventDefault();
webContents.on('will-navigate', (event: Event, url: string) => {
event.preventDefault();
const parsedUrl = new URL(url);
// We use the same state parameter that the app created to assert that we prevent CSRF
const stateSearchParam = parsedUrl.searchParams.get('state') || '';

View File

@ -10,8 +10,8 @@ test('Sign in with Gitlab', async ({ app, page }) => {
const webContents = electron.BrowserWindow.getAllWindows()[0].webContents;
// Remove all navigation listeners so that only the one we inject will run
webContents.removeAllListeners('will-navigate');
webContents.on('will-navigate', (e, url) => {
e.preventDefault();
webContents.on('will-navigate', (event: Event, url: string) => {
event.preventDefault();
const parsedUrl = new URL(url);
// We use the same state parameter that the app created to assert that we prevent CSRF
const stateSearchParam = parsedUrl.searchParams.get('state') || '';

View File

@ -5,15 +5,15 @@
"outDir": "dist",
"rootDir": ".",
"resolveJsonModule": true,
"esModuleInterop": true,
"noImplicitAny": false
"esModuleInterop": true
},
"include": [
"cli",
"core",
"fixtures",
"modules",
"server"
"server",
"**/*.d.ts",
],
"exclude": [
"dist",

View File

@ -14,6 +14,7 @@
"server",
"jest.config.js",
".eslintrc.js",
"**/*.d.ts",
],
"exclude": [
"dist"

View File

@ -1,4 +1,5 @@
build
bin
send-request
coverage
**/main.min.js

View File

@ -70,6 +70,7 @@
"@types/codemirror": "^5.60.2",
"@types/color": "^3.0.1",
"@types/deep-equal": "^1.0.1",
"@types/dompurify": "^2.3.3",
"@types/fs-extra": "^5.1.0",
"@types/hapi__hawk": "^8.0.2",
"@types/js-yaml": "^4.0.1",
@ -90,6 +91,7 @@
"@types/react-redux": "^7.1.22",
"@types/react-tabs": "^2.3.4",
"@types/redux-mock-store": "^1.0.2",
"@types/rimraf": "^3.0.2",
"@types/styled-components": "^5.1.23",
"@types/swagger-ui-react": "^4.1.1",
"@types/tough-cookie": "^2.3.7",
@ -4520,6 +4522,15 @@
"integrity": "sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg==",
"dev": true
},
"node_modules/@types/dompurify": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.3.3.tgz",
"integrity": "sha512-nnVQSgRVuZ/843oAfhA25eRSNzUFcBPk/LOiw5gm8mD9/X7CNcbRkQu/OsjCewO8+VIYfPxUnXvPEVGenw14+w==",
"dev": true,
"dependencies": {
"@types/trusted-types": "*"
}
},
"node_modules/@types/estree": {
"version": "0.0.47",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz",
@ -4540,7 +4551,6 @@
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
"dev": true,
"optional": true,
"dependencies": {
"@types/minimatch": "*",
"@types/node": "*"
@ -4731,8 +4741,7 @@
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
"dev": true,
"optional": true
"dev": true
},
"node_modules/@types/mkdirp": {
"version": "0.5.2",
@ -4924,6 +4933,16 @@
"node": ">= 0.12"
}
},
"node_modules/@types/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==",
"dev": true,
"dependencies": {
"@types/glob": "*",
"@types/node": "*"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
@ -4979,6 +4998,12 @@
"integrity": "sha512-rMQbgMGxnLsdn8e9aPVyuN+zMQLrZ2QW8xlv7eWS1mydfGXN+tsTKffcIzd8rGCcLdmi3xvQw2MDaZI1bBNTaw==",
"dev": true
},
"node_modules/@types/trusted-types": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz",
"integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==",
"dev": true
},
"node_modules/@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
@ -23886,6 +23911,15 @@
"integrity": "sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg==",
"dev": true
},
"@types/dompurify": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.3.3.tgz",
"integrity": "sha512-nnVQSgRVuZ/843oAfhA25eRSNzUFcBPk/LOiw5gm8mD9/X7CNcbRkQu/OsjCewO8+VIYfPxUnXvPEVGenw14+w==",
"dev": true,
"requires": {
"@types/trusted-types": "*"
}
},
"@types/estree": {
"version": "0.0.47",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz",
@ -23906,7 +23940,6 @@
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
"dev": true,
"optional": true,
"requires": {
"@types/minimatch": "*",
"@types/node": "*"
@ -24097,8 +24130,7 @@
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
"dev": true,
"optional": true
"dev": true
},
"@types/mkdirp": {
"version": "0.5.2",
@ -24289,6 +24321,16 @@
}
}
},
"@types/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==",
"dev": true,
"requires": {
"@types/glob": "*",
"@types/node": "*"
}
},
"@types/scheduler": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
@ -24344,6 +24386,12 @@
"integrity": "sha512-rMQbgMGxnLsdn8e9aPVyuN+zMQLrZ2QW8xlv7eWS1mydfGXN+tsTKffcIzd8rGCcLdmi3xvQw2MDaZI1bBNTaw==",
"dev": true
},
"@types/trusted-types": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz",
"integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==",
"dev": true
},
"@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",

View File

@ -124,6 +124,7 @@
"@types/codemirror": "^5.60.2",
"@types/color": "^3.0.1",
"@types/deep-equal": "^1.0.1",
"@types/dompurify": "^2.3.3",
"@types/fs-extra": "^5.1.0",
"@types/hapi__hawk": "^8.0.2",
"@types/js-yaml": "^4.0.1",
@ -144,6 +145,7 @@
"@types/react-redux": "^7.1.22",
"@types/react-tabs": "^2.3.4",
"@types/redux-mock-store": "^1.0.2",
"@types/rimraf": "^3.0.2",
"@types/styled-components": "^5.1.23",
"@types/swagger-ui-react": "^4.1.1",
"@types/tough-cookie": "^2.3.7",

View File

@ -1,7 +1,7 @@
// This file implements just enough of the electron module to get sending requests to work
module.exports = {
app: {
getPath: (name) => name === 'temp' ? require('os').tmpdir() : require('path').join(require('os').tmpdir(), 'insomnia-send-request'),
getPath: (/** @type {string} */ name) => name === 'temp' ? require('os').tmpdir() : require('path').join(require('os').tmpdir(), 'insomnia-send-request'),
},
ipcMain: {
on: () => {

View File

@ -3,7 +3,7 @@ import { AxiosRequestConfig } from 'axios';
import { v4 as uuidv4 } from 'uuid';
import { getAccountId } from '../account/session';
import { database as db } from '../common/database';
import { ChangeBufferEvent, database as db } from '../common/database';
import * as models from '../models/index';
import { isSettings } from '../models/settings';
import {
@ -195,7 +195,7 @@ function _getOsName() {
// Monitor database changes to see if analytics gets enabled.
// If analytics become enabled, flush any queued events.
db.onChange(async changes => {
db.onChange(async (changes: ChangeBufferEvent[]) => {
for (const change of changes) {
const [event, doc] = change;
const isUpdatingSettings = isSettings(doc) && event === 'update';

View File

@ -244,7 +244,7 @@ const previewModeMap = {
[PREVIEW_MODE_SOURCE]: ['Source', 'Source Code'],
[PREVIEW_MODE_RAW]: ['Raw', 'Raw Data'],
};
export const PREVIEW_MODES = Object.keys(previewModeMap);
export const PREVIEW_MODES = Object.keys(previewModeMap) as (keyof typeof previewModeMap)[];
// Content Types
export const CONTENT_TYPE_JSON = 'application/json';
@ -257,7 +257,7 @@ export const CONTENT_TYPE_FORM_DATA = 'multipart/form-data';
export const CONTENT_TYPE_FILE = 'application/octet-stream';
export const CONTENT_TYPE_GRAPHQL = 'application/graphql';
export const CONTENT_TYPE_OTHER = '';
const contentTypesMap = {
const contentTypesMap: Record<string, string[]> = {
[CONTENT_TYPE_EDN]: ['EDN', 'EDN'],
[CONTENT_TYPE_FILE]: ['File', 'Binary File'],
[CONTENT_TYPE_FORM_DATA]: ['Multipart', 'Multipart Form'],
@ -289,7 +289,7 @@ export const HAWK_ALGORITHM_SHA1 = 'sha1';
export const JSON_ORDER_PREFIX = '&';
export const JSON_ORDER_SEPARATOR = '~|';
const authTypesMap = {
const authTypesMap: Record<string, string[]> = {
[AUTH_BASIC]: ['Basic', 'Basic Auth'],
[AUTH_DIGEST]: ['Digest', 'Digest Auth'],
[AUTH_NTLM]: ['NTLM', 'Microsoft NTLM'],
@ -300,7 +300,7 @@ const authTypesMap = {
[AUTH_AWS_IAM]: ['AWS', 'AWS IAM v4'],
[AUTH_ASAP]: ['ASAP', 'Atlassian ASAP'],
[AUTH_NETRC]: ['Netrc', 'Netrc File'],
} as const;
};
// Sort Orders
export type SortOrder =
@ -346,7 +346,7 @@ export type DashboardSortOrder =
| 'created-desc'
| 'modified-desc';
export const DASHBOARD_SORT_ORDERS = [
export const DASHBOARD_SORT_ORDERS: DashboardSortOrder[] = [
SORT_MODIFIED_DESC,
SORT_NAME_ASC,
SORT_NAME_DESC,
@ -362,7 +362,9 @@ export const dashboardSortOrderName: Record<DashboardSortOrder, string> = {
[SORT_MODIFIED_DESC]: 'Last Modified',
};
export function getPreviewModeName(previewMode, useLong = false) {
export type PreviewMode = 'friendly' | 'source' | 'raw';
export function getPreviewModeName(previewMode: PreviewMode, useLong = false) {
if (previewModeMap.hasOwnProperty(previewMode)) {
return useLong ? previewModeMap[previewMode][1] : previewModeMap[previewMode][0];
} else {
@ -382,7 +384,7 @@ export function getContentTypeName(contentType?: string | null, useLong = false)
return useLong ? contentTypesMap[CONTENT_TYPE_OTHER][1] : contentTypesMap[CONTENT_TYPE_OTHER][0];
}
export function getAuthTypeName(authType, useLong = false) {
export function getAuthTypeName(authType: string, useLong = false) {
if (authTypesMap.hasOwnProperty(authType)) {
return useLong ? authTypesMap[authType][1] : authTypesMap[authType][0];
} else {
@ -390,7 +392,7 @@ export function getAuthTypeName(authType, useLong = false) {
}
}
export function getContentTypeFromHeaders(headers, defaultValue: string | null = null) {
export function getContentTypeFromHeaders(headers: any[], defaultValue: string | null = null) {
if (!Array.isArray(headers)) {
return null;
}
@ -400,7 +402,7 @@ export function getContentTypeFromHeaders(headers, defaultValue: string | null =
}
// Sourced from https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
export const RESPONSE_CODE_DESCRIPTIONS = {
export const RESPONSE_CODE_DESCRIPTIONS: Record<number, string> = {
// Special
[STATUS_CODE_PLUGIN_ERROR]:
'An Insomnia plugin threw an error which prevented the request from sending',
@ -471,7 +473,7 @@ export const RESPONSE_CODE_DESCRIPTIONS = {
511: 'The 511 status code indicates that the client needs to authenticate to gain network access.',
};
export const RESPONSE_CODE_REASONS = {
export const RESPONSE_CODE_REASONS: Record<number, string> = {
// Special
[STATUS_CODE_PLUGIN_ERROR]: 'Plugin Error',
// 100s

View File

@ -351,6 +351,7 @@ export const database = {
delete db._empty;
electron.ipcMain.on('db.fn', async (e, fnName, replyChannel, ...args) => {
try {
// @ts-expect-error -- mapping unsoundness
const result = await database[fnName](...args);
e.sender.send(replyChannel, null, result);
} catch (err) {
@ -370,7 +371,7 @@ export const database = {
// This isn't the best place for this but w/e
// Listen for response deletions and delete corresponding response body files
database.onChange(async changes => {
database.onChange(async (changes: ChangeBufferEvent[]) => {
for (const [type, doc] of changes) {
// TODO(TSCONVERSION) what's returned here is the entire model implementation, not just a model
// The type definition will be a little confusing
@ -684,7 +685,7 @@ function getDBFilePath(modelType: string) {
let bufferingChanges = false;
let bufferChangesId = 1;
type ChangeBufferEvent = [
export type ChangeBufferEvent = [
event: string,
doc: BaseModel,
fromSync: boolean
@ -692,7 +693,7 @@ type ChangeBufferEvent = [
let changeBuffer: ChangeBufferEvent[] = [];
type ChangeListener = Function;
type ChangeListener = (changes: ChangeBufferEvent[]) => void;
let changeListeners: ChangeListener[] = [];

View File

@ -535,7 +535,7 @@ function getRequestPostData(renderedRequest: RenderedRequest): HarPostData | und
body = renderedRequest.body;
}
let params = [];
let params: any[] = [];
if (body.params) {
params = body.params.map(param => {

View File

@ -162,7 +162,7 @@ export async function importRaw(
// Workspace > Environment > RequestGroup > Request
// Import everything backwards so they get inserted in the correct order
data.resources.reverse();
const importedDocs = {};
const importedDocs: Record<string, any[]> = {};
for (const model of models.all()) {
importedDocs[model.type] = [];

View File

@ -1,4 +1,4 @@
export const keyboardKeys = {
export const keyboardKeys: Record<string, { keyCode: number; label: string }> = {
backspace: {
keyCode: 8,
label: 'Backspace',
@ -399,7 +399,7 @@ export const keyboardKeys = {
keyCode: 222,
label: "'",
},
} as const;
};
type KeyName = keyof typeof keyboardKeys;

View File

@ -361,7 +361,7 @@ export function pluralize(text: string) {
return `${text.slice(0, text.length - chop)}${trailer}`;
}
export function diffPatchObj(baseObj: {}, patchObj: {}, deep = false) {
export function diffPatchObj(baseObj: any, patchObj: any, deep = false) {
const clonedBaseObj = JSON.parse(JSON.stringify(baseObj));
for (const prop in baseObj) {

View File

@ -169,7 +169,7 @@ export async function buildRenderContext(
const keys = _getOrderedEnvironmentKeys(finalRenderContext);
// Render recursive references and tags.
const skipNextTime = {};
const skipNextTime: Record<string, boolean> = {};
for (let i = 0; i < 3; i++) {
for (const key of keys) {
@ -273,9 +273,11 @@ export async function render<T>(
for (const key of keys) {
if (first && key.indexOf('_') === 0) {
// @ts-expect-error -- mapping unsoundness
x[key] = await next(x[key], path);
} else {
const pathPrefix = path ? path + '.' : '';
// @ts-expect-error -- mapping unsoundness
x[key] = await next(x[key], `${pathPrefix}${key}`);
}
}
@ -322,10 +324,10 @@ export async function getRenderContext(
workspace ? workspace._id : 'n/a',
);
const subEnvironment = await models.environment.getById(environmentId || 'n/a');
const keySource = {};
const keySource: Record<string, string> = {};
// Function that gets Keys and stores their Source location
function getKeySource(subObject, inKey, inSource) {
function getKeySource(subObject: string | Record<string, any>, inKey: string, inSource: string) {
// Add key to map if it's not root
if (inKey) {
keySource[templatingUtils.normalizeToDotAndBracketNotation(inKey)] = inSource;
@ -336,10 +338,12 @@ export async function getRenderContext(
if (typeStr === '[object Object]') {
for (const key of Object.keys(subObject)) {
// @ts-expect-error -- mapping unsoundness
getKeySource(subObject[key], templatingUtils.forceBracketNotation(inKey, key), inSource);
}
} else if (typeStr === '[object Array]') {
for (let i = 0; i < subObject.length; i++) {
// @ts-expect-error -- mapping unsoundness
getKeySource(subObject[i], templatingUtils.forceBracketNotation(inKey, i), inSource);
}
}
@ -539,7 +543,7 @@ export async function getRenderedRequestAndContext(
* @param v
* @returns {number}
*/
function _nunjucksSortValue(v) {
function _nunjucksSortValue(v: string) {
return v?.match?.(/({{|{%)/) ? 2 : 1;
}

View File

@ -1,3 +1,5 @@
import { ErrorResult } from 'insomnia-config';
import { getConfigSettings, isConfigError, isParseError } from '../models/helpers/settings';
interface Result {
@ -30,7 +32,7 @@ export const validateInsomniaConfig = (): Result => {
].join('\n');
} else if (isConfigError(configSettings)) {
const { humanReadableErrors, configPath } = configSettings.error;
const errors = humanReadableErrors.map(({ message, path, suggestion }, index) => ([
const errors = humanReadableErrors.map(({ message, path, suggestion }: ErrorResult['humanReadableErrors'][0], index: number) => ([
`[Error ${index + 1}]`,
`Path: ${path}`,
`${message}.${suggestion ? ` ${suggestion}` : ''}`,

2
packages/insomnia/src/jsonlint.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
declare module 'jsonlint-mod-fixed' {
}

View File

@ -66,7 +66,7 @@ class LocalStorage {
}
}
_getKeyPath(key) {
_getKeyPath(key: string) {
// @ts-expect-error -- TSCONVERSION this appears to be a genuine error
return path.join(this._basePath, key);
}

View File

@ -1,7 +1,7 @@
import * as Sentry from '@sentry/electron/main';
import type { SentryRequestType } from '@sentry/types';
import { database as db } from '../common/database';
import { ChangeBufferEvent, database as db } from '../common/database';
import { SENTRY_OPTIONS } from '../common/sentry';
import * as models from '../models/index';
import { isSettings } from '../models/settings';
@ -16,7 +16,7 @@ export function sentryWatchAnalyticsEnabled() {
enabled = settings.enableAnalytics;
});
db.onChange(async changes => {
db.onChange(async (changes: ChangeBufferEvent[]) => {
for (const change of changes) {
const [event, doc] = change;
if (isSettings(doc) && event === 'update') {

View File

@ -2,7 +2,7 @@ import { spawn } from 'child_process';
import { app } from 'electron';
import path from 'path';
function run(args, done) {
function run(args: readonly string[] | undefined, done: (...args: any[]) => void) {
const updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
spawn(updateExe, args, {
detached: true,

View File

@ -64,7 +64,7 @@ async function getUpdateUrl(force: boolean): Promise<string | null> {
return fullUrl;
}
function _sendUpdateStatus(status) {
function _sendUpdateStatus(status: string) {
const windows = BrowserWindow.getAllWindows();
for (const window of windows) {

View File

@ -15,6 +15,7 @@ const toSchema = <T>(obj: T): Schema<T> => {
const output: Partial<Schema<T>> = {};
Object.keys(cloned).forEach(key => {
// @ts-expect-error -- mapping unsoundness
output[key] = () => cloned[key];
});

View File

@ -196,6 +196,7 @@ export async function initModel<T extends BaseModel>(type: string, ...sources: R
// Prune extra keys from doc
for (const key of Object.keys(migratedDoc)) {
if (!objectDefaults.hasOwnProperty(key)) {
// @ts-expect-error -- mapping unsoundness
delete migratedDoc[key];
}
}
@ -204,7 +205,7 @@ export async function initModel<T extends BaseModel>(type: string, ...sources: R
return migratedDoc;
}
export const MODELS_BY_EXPORT_TYPE = {
export const MODELS_BY_EXPORT_TYPE: Record<string, any> = {
[EXPORT_TYPE_REQUEST]: request,
[EXPORT_TYPE_GRPC_REQUEST]: grpcRequest,
[EXPORT_TYPE_REQUEST_GROUP]: requestGroup,

View File

@ -1,4 +1,4 @@
import { PREVIEW_MODE_FRIENDLY } from '../common/constants';
import { PREVIEW_MODE_FRIENDLY, PreviewMode } from '../common/constants';
import { database as db } from '../common/database';
import type { BaseModel } from './index';
@ -12,7 +12,7 @@ export type RequestAccordionKeys = 'OAuth2AdvancedOptions';
export interface BaseRequestMeta {
parentId: string;
previewMode: string;
previewMode: PreviewMode;
responseFilter: string;
responseFilterHistory: string[];
activeResponseId: string | null;

View File

@ -109,7 +109,7 @@ function _diffRequests(rOld: Request | null, rNew: Request) {
return true;
}
for (const key of Object.keys(rOld)) {
for (const key of Object.keys(rOld) as (keyof Request)[]) {
// Skip fields that aren't useful
if (FIELDS_TO_IGNORE.includes(key)) {
continue;

View File

@ -4,7 +4,7 @@ const WILDCARD_CHARACTER = '*';
const WILDCARD_SUBSTITUTION = Math.random().toString().split('.')[1];
const WILDCARD_SUBSTITUTION_PATTERN = new RegExp(`${WILDCARD_SUBSTITUTION}`, 'g');
export default function certificateUrlParse(url) {
export default function certificateUrlParse(url: string) {
if (url.indexOf(WILDCARD_CHARACTER) === -1) {
return urlParse(url);
} else {
@ -17,7 +17,9 @@ export default function certificateUrlParse(url) {
}
}
function _reinstateWildcards(string) {
function _reinstateWildcards(string: string): string;
function _reinstateWildcards(string: string | null): string | null;
function _reinstateWildcards(string: string | null) {
if (string) {
return string.replace(WILDCARD_SUBSTITUTION_PATTERN, WILDCARD_CHARACTER);
} else {

View File

@ -16,23 +16,23 @@ export class ResponseCallbacks implements IResponseCallbacks {
this._event = event;
}
sendData(requestId, val) {
sendData(requestId: string, val: Record<string, any>) {
this._event.reply(GrpcResponseEventEnum.data, requestId, val);
}
sendError(requestId, err) {
sendError(requestId: string, err: Error) {
this._event.reply(GrpcResponseEventEnum.error, requestId, err);
}
sendStart(requestId) {
sendStart(requestId: string) {
this._event.reply(GrpcResponseEventEnum.start, requestId);
}
sendEnd(requestId) {
sendEnd(requestId: string) {
this._event.reply(GrpcResponseEventEnum.end, requestId);
}
sendStatus(requestId, status) {
sendStatus(requestId: string, status: StatusObject) {
this._event.reply(GrpcResponseEventEnum.status, requestId, status);
}
}

View File

@ -1,12 +1,12 @@
import { parse as urlParse } from 'url';
function formatHostname(rawHostname) {
function formatHostname(rawHostname: string) {
// canonicalize the hostname, so that 'oogle.com' won't match 'google.com'
const hostname = rawHostname.replace(/^\.*/, '.').toLowerCase();
return hostname.endsWith('.') ? hostname.slice(0, -1) : hostname;
}
function parseNoProxyZone(zone) {
function parseNoProxyZone(zone: string) {
zone = zone.trim().toLowerCase();
const zoneParts = zone.split(':', 2);
const zoneHost = formatHostname(zoneParts[0]);
@ -16,7 +16,7 @@ function parseNoProxyZone(zone) {
return { hostname: zoneHost, port: zonePort, hasPort: hasPort };
}
function matchesHostname(hostname, noProxyZoneHostname) {
function matchesHostname(hostname: string, noProxyZoneHostname: string) {
const wildcardNeedle = noProxyZoneHostname.startsWith('.*.') ? noProxyZoneHostname.slice(2) : noProxyZoneHostname;
const isMatchedAt = hostname.indexOf(wildcardNeedle);
return (isMatchedAt > -1 && (isMatchedAt === hostname.length - wildcardNeedle.length));
@ -31,7 +31,9 @@ export function isUrlMatchedInNoProxyRule(url: string | undefined, noProxyRule:
return false;
}
const port = uri.port || (uri.protocol === 'https:' ? '443' : '80');
const hostname = formatHostname(uri.hostname);
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const hostname = formatHostname(uri.hostname!);
const noProxyList = noProxyRule.split(',');
// iterate through the noProxyList until it finds a match.

View File

@ -73,8 +73,8 @@ interface CurlRequestOutput {
const getDataDirectory = () => process.env.INSOMNIA_DATA_PATH || electron.app.getPath('userData');
// NOTE: this is a dictionary of functions to close open listeners
const cancelCurlRequestHandlers = {};
export const cancelCurlRequest = id => cancelCurlRequestHandlers[id]();
const cancelCurlRequestHandlers: Record<string, () => void> = {};
export const cancelCurlRequest = (id: string) => cancelCurlRequestHandlers[id]();
export const curlRequest = (options: CurlRequestOptions) => new Promise<CurlRequestOutput>(async resolve => {
try {
const responsesDir = path.join(getDataDirectory(), 'responses');
@ -208,7 +208,7 @@ export const curlRequest = (options: CurlRequestOptions) => new Promise<CurlRequ
const requestBody = parseRequestBody({ body, method });
const requestBodyPath = await parseRequestBodyPath(body);
const isMultipart = body.mimeType === CONTENT_TYPE_FORM_DATA && requestBodyPath;
let requestFileDescriptor;
let requestFileDescriptor: number;
const { authentication } = req;
if (requestBodyPath) {
// AWS IAM file upload not supported
@ -358,7 +358,7 @@ const closeReadFunction = (fd: number, isMultipart: boolean, path?: string) => {
};
// Because node-libcurl changed some names that we used in the timeline
const LIBCURL_DEBUG_MIGRATION_MAP = {
const LIBCURL_DEBUG_MIGRATION_MAP: Record<string, string> = {
HeaderIn: 'HEADER_IN',
DataIn: 'DATA_IN',
SslDataIn: 'SSL_DATA_IN',
@ -416,13 +416,13 @@ async function waitForStreamToFinish(stream: Readable | Writable) {
});
});
}
const parseRequestBody = ({ body, method }) => {
const parseRequestBody = ({ body, method }: { body: any; method: string }) => {
const isUrlEncodedForm = body.mimeType === CONTENT_TYPE_FORM_URLENCODED;
const expectsBody = ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase());
const hasMimetypeAndUpdateMethod = typeof body.mimeType === 'string' || expectsBody;
if (isUrlEncodedForm) {
const urlSearchParams = new URLSearchParams();
(body.params || []).map(p => urlSearchParams.append(p.name, p?.value || ''));
(body.params || []).map((p: { name: string; value: any }) => urlSearchParams.append(p.name, p?.value || ''));
return urlSearchParams.toString();
}
@ -432,7 +432,7 @@ const parseRequestBody = ({ body, method }) => {
return undefined;
};
const parseRequestBodyPath = async body => {
const parseRequestBodyPath = async (body: any) => {
const isMultipartForm = body.mimeType === CONTENT_TYPE_FORM_DATA;
if (!isMultipartForm) {
return body.fileName;
@ -441,7 +441,7 @@ const parseRequestBodyPath = async body => {
return filePath;
};
export const getHttpVersion = preferredHttpVersion => {
export const getHttpVersion = (preferredHttpVersion: string) => {
switch (preferredHttpVersion) {
case 'V1_0':
return { log: 'Using HTTP 1.0', curlHttpVersion: CurlHttpVersion.V1_0 };

View File

@ -26,7 +26,7 @@ export async function buildMultipart(params: RequestBodyParameter[]) {
function addFile(path: string) {
return new Promise<void>((resolve, reject) => {
let size;
let size: number | undefined;
try {
size = fs.statSync(path).size;
@ -44,7 +44,9 @@ export async function buildMultipart(params: RequestBodyParameter[]) {
stream.pipe(writeStream, {
end: false,
});
totalSize += size;
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
totalSize += size!;
});
}

View File

@ -64,11 +64,11 @@ export interface ResponsePatch {
// Time since user's last keypress to wait before making the request
const MAX_DELAY_TIME = 1000;
const cancelRequestFunctionMap = {};
const cancelRequestFunctionMap: Record<string, () => void> = {};
let lastUserInteraction = Date.now();
export async function cancelRequestById(requestId) {
export async function cancelRequestById(requestId: string) {
const hasCancelFunction = cancelRequestFunctionMap.hasOwnProperty(requestId) && typeof cancelRequestFunctionMap[requestId] === 'function';
if (hasCancelFunction) {
return cancelRequestFunctionMap[requestId]();
@ -154,7 +154,7 @@ export async function _actuallySend(
// add set-cookie headers to file(cookiejar) and database
if (settingStoreCookies) {
// supports many set-cookies over many redirects
const redirects: string[][] = headerResults.map(({ headers }) => getSetCookiesFromResponseHeaders(headers));
const redirects: string[][] = headerResults.map(({ headers }: any) => getSetCookiesFromResponseHeaders(headers));
const setCookieStrings: string[] = redirects.flat();
const totalSetCookies = setCookieStrings.length;
if (totalSetCookies) {
@ -206,9 +206,9 @@ export async function _actuallySend(
});
}
export const getSetCookiesFromResponseHeaders = headers => getSetCookieHeaders(headers).map(h => h.value);
export const getSetCookiesFromResponseHeaders = (headers: any[]) => getSetCookieHeaders(headers).map(h => h.value);
export const getCurrentUrl = ({ headerResults, finalUrl }) => {
export const getCurrentUrl = ({ headerResults, finalUrl }: { headerResults: any; finalUrl: string }): string => {
if (!headerResults || !headerResults.length) {
return finalUrl;
}
@ -224,7 +224,7 @@ export const getCurrentUrl = ({ headerResults, finalUrl }) => {
}
};
const addSetCookiesToToughCookieJar = async ({ setCookieStrings, currentUrl, cookieJar }) => {
const addSetCookiesToToughCookieJar = async ({ setCookieStrings, currentUrl, cookieJar }: any) => {
const rejectedCookies: string[] = [];
const jar = jarFromCookies(cookieJar.cookies);
for (const setCookieStr of setCookieStrings) {

View File

@ -59,7 +59,7 @@ export default async function(
hash_function: hashFunction(authentication.signatureMethod),
realm: authentication.realm || null,
});
const requestData = {
const requestData: OAuth1.RequestOptions = {
url: url,
method: method,
includeBodyHash: false,
@ -69,22 +69,18 @@ export default async function(
};
if (authentication.callback) {
// @ts-expect-error -- TSCONVERSION needs type widening
requestData.data.oauth_callback = authentication.callback;
}
if (authentication.nonce) {
// @ts-expect-error -- TSCONVERSION needs type widening
requestData.data.oauth_nonce = authentication.nonce;
}
if (authentication.timestamp) {
// @ts-expect-error -- TSCONVERSION needs type widening
requestData.data.oauth_timestamp = authentication.timestamp;
}
if (authentication.verifier) {
// @ts-expect-error -- TSCONVERSION needs type widening
requestData.data.oauth_verifier = authentication.verifier;
}

View File

@ -74,6 +74,7 @@ export default async function(
credentialsInBody,
clientId,
clientSecret,
// @ts-expect-error -- unsound typing
authorizeResults[c.P_CODE],
redirectUri,
state,
@ -85,8 +86,8 @@ export default async function(
}
async function _authorize(
url,
clientId,
url: string,
clientId: string,
redirectUri = '',
scope = '',
state = '',

View File

@ -22,18 +22,22 @@ export function initNewOAuthSession() {
return authWindowSessionId;
}
export function responseToObject(body, keys, defaults = {}) {
export function responseToObject(body: string | null, keys: string[], defaults: Record<string, string | string[]> = {}) {
let data: querystring.ParsedUrlQuery | null = null;
try {
data = JSON.parse(body);
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
data = JSON.parse(body!);
} catch (err) {}
if (!data) {
try {
// NOTE: parse does not return a JS Object, so
// we cannot use hasOwnProperty on it
data = querystring.parse(body);
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
data = querystring.parse(body!);
} catch (err) {}
}
@ -42,7 +46,7 @@ export function responseToObject(body, keys, defaults = {}) {
data = {};
}
const results = {};
const results: Record<string, string | string[] | null | undefined> = {};
for (const key of keys) {
if (data[key] !== undefined) {
@ -62,7 +66,12 @@ export function authorizeUserInWindow({
urlSuccessRegex = /(code=).*/,
urlFailureRegex = /(error=).*/,
sessionId,
}) {
}: {
url: string;
urlSuccessRegex: RegExp;
urlFailureRegex: RegExp;
sessionId: string;
}): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
let finalUrl: string | null = null;

View File

@ -86,8 +86,8 @@ export const parseHeaderStrings = ({ req, finalUrl, requestBody, requestBodyPath
headers.push({ name: 'content-type', value: DISABLE_HEADER_VALUE });
}
return headers.filter(h => h.name)
.map(({ name, value }) =>
return headers.filter((h: any) => h.name)
.map(({ name, value }: any) =>
value === '' ? `${name};` // Curl needs a semicolon suffix to send empty header values
: value === DISABLE_HEADER_VALUE ? `${name}:` // Tell Curl NOT to send the header if value is null
: `${name}: ${value}`);

View File

@ -6,7 +6,7 @@ import certificateUrlParse from './certificate-url-parse';
const DEFAULT_PORT = 443;
export function urlMatchesCertHost(certificateHost, requestUrl) {
export function urlMatchesCertHost(certificateHost: string, requestUrl: string) {
const cHostWithProtocol = setDefaultProtocol(certificateHost, 'https:');
const { hostname, port } = urlParse(requestUrl);
const { hostname: cHostname, port: cPort } = certificateUrlParse(cHostWithProtocol);

3
packages/insomnia/src/nunjucks.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
declare module 'nunjucks/browser/nunjucks' {
export function configure(options: any);
}

View File

@ -216,7 +216,7 @@ async function _installPluginToTmpDir(lookupName: string) {
});
}
export function containsOnlyDeprecationWarnings(stderr) {
export function containsOnlyDeprecationWarnings(stderr: string) {
// Split on line breaks and remove falsy values (null, undefined, 0, -0, NaN, "", false)
const arr = stderr.split(/\r?\n/).filter(error => error);
// Retrieve all matching deprecated dependency warning
@ -258,7 +258,7 @@ function _getYarnPath() {
}
}
function escape(p) {
function escape(p: string) {
if (isWindows()) {
// Quote for Windows paths
return `"${p}"`;

View File

@ -173,7 +173,7 @@ function getThemeBlockCSS(block?: ThemeBlock) {
css += `${indent}--${variable}: ${value};\n`;
};
const addComment = comment => {
const addComment = (comment: string) => {
css += `${indent}/* ${comment} */\n`;
};

View File

@ -2,23 +2,23 @@ const { contextBridge, ipcRenderer } = require('electron');
const main = {
restart: () => ipcRenderer.send('restart'),
authorizeUserInWindow: options => ipcRenderer.invoke('authorizeUserInWindow', options),
setMenuBarVisibility: options => ipcRenderer.send('setMenuBarVisibility', options),
installPlugin: options => ipcRenderer.invoke('installPlugin', options),
curlRequest: options => ipcRenderer.invoke('curlRequest', options),
cancelCurlRequest: options => ipcRenderer.send('cancelCurlRequest', options),
writeFile: options => ipcRenderer.invoke('writeFile', options),
authorizeUserInWindow: (/** @type {any} */ options) => ipcRenderer.invoke('authorizeUserInWindow', options),
setMenuBarVisibility: (/** @type {any} */ options) => ipcRenderer.send('setMenuBarVisibility', options),
installPlugin: (/** @type {any} */ options) => ipcRenderer.invoke('installPlugin', options),
curlRequest: (/** @type {any} */ options) => ipcRenderer.invoke('curlRequest', options),
cancelCurlRequest: (/** @type {any} */ options) => ipcRenderer.send('cancelCurlRequest', options),
writeFile: (/** @type {any} */ options) => ipcRenderer.invoke('writeFile', options),
};
const dialog = {
showOpenDialog: options => ipcRenderer.invoke('showOpenDialog', options),
showSaveDialog: options => ipcRenderer.invoke('showSaveDialog', options),
showOpenDialog: (/** @type {any} */ options) => ipcRenderer.invoke('showOpenDialog', options),
showSaveDialog: (/** @type {any} */ options) => ipcRenderer.invoke('showSaveDialog', options),
};
const app = {
getPath: options => ipcRenderer.sendSync('getPath', options),
getAppPath: options => ipcRenderer.sendSync('getAppPath', options),
getPath: (/** @type {any} */ options) => ipcRenderer.sendSync('getPath', options),
getAppPath: (/** @type {any} */ options) => ipcRenderer.sendSync('getAppPath', options),
};
const shell = {
showItemInFolder: options => ipcRenderer.send('showItemInFolder', options),
showItemInFolder: (/** @type {any} */ options) => ipcRenderer.send('showItemInFolder', options),
};
if (process.contextIsolated) {

View File

@ -29,7 +29,6 @@ export function diff(source: string, target: string, blockSize: number): Operati
const targetBlock = getBlock(target, targetPosition, blockSize);
const sourceBlocks = sourceBlockMap[targetBlock.hash] || [];
// @ts-expect-error -- TSCONVERSION appears to be a genuine error
if (sourceBlocks.length === 0) {
targetPosition++;
continue;
@ -101,8 +100,8 @@ function getBlock(value: string, start: number, blockSize: number): Block {
};
}
function getBlockMap(value: string, blockSize: number): Record<string, Block> {
const map = {};
function getBlockMap(value: string, blockSize: number): Record<string, Block[]> {
const map: Record<string, Block[]> = {};
for (let i = 0; i < value.length;) {
const block = getBlock(value, i, blockSize);

View File

@ -2,7 +2,7 @@ import { axiosRequest } from '../../network/axios-request';
/** This is a client for isomorphic-git {@link https://isomorphic-git.org/docs/en/http} */
export const httpClient = {
request: async config => {
request: async (config: any) => {
let response;
let body: Buffer | null = null;

View File

@ -1,6 +1,8 @@
import * as git from 'isomorphic-git';
import path from 'path';
type Methods = 'readFile' | 'writeFile' | 'unlink' | 'readdir' | 'mkdir' | 'rmdir' | 'stat' | 'lstat' | 'readlink' | 'symlink';
/**
* An isometric-git FS client that can route to various client depending on what the filePath is.
*
@ -12,19 +14,23 @@ export function routableFSClient(
defaultFS: git.PromiseFsClient,
otherFS: Record<string, git.PromiseFsClient>,
) {
const execMethod = async (method: string, filePath: string, ...args: any[]) => {
const execMethod = async (method: Methods, filePath: string, ...args: any[]) => {
filePath = path.normalize(filePath);
for (const prefix of Object.keys(otherFS)) {
if (filePath.indexOf(path.normalize(prefix)) === 0) {
return otherFS[prefix].promises[method](filePath, ...args);
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return otherFS[prefix].promises[method]!(filePath, ...args);
}
}
// Uncomment this to debug operations
// console.log('[routablefs] Executing', method, filePath, { args });
// Fallback to default if no prefix matched
const result = await defaultFS.promises[method](filePath, ...args);
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const result = await defaultFS.promises[method]!(filePath, ...args);
// Uncomment this to debug operations
// console.log('[routablefs] Executing', method, filePath, { args }, { result });
return result;

View File

@ -35,8 +35,9 @@ export const deleteKeys = <T extends BaseModel>(doc: T) => {
export const resetKeys = <T extends BaseModel>(doc: T) => {
if (isWorkspace(doc)) {
Object.keys(RESET_WORKSPACE_KEYS)
(Object.keys(RESET_WORKSPACE_KEYS) as (keyof typeof RESET_WORKSPACE_KEYS)[])
.forEach(key => {
// @ts-expect-error -- mapping unsoundness
doc[key] = RESET_WORKSPACE_KEYS[key];
});
}

View File

@ -101,7 +101,7 @@ export default class FileSystemDriver implements BaseDriver {
}
async keys(prefix: string, recursive: boolean) {
const next = dir => {
const next = (dir: string) => {
return new Promise<string[]>(async (resolve, reject) => {
let keys: string[] = [];
let names: string[] = [];

View File

@ -31,7 +31,7 @@ export function generateStateMap(state: SnapshotState | null): SnapshotStateMap
return {};
}
const map = {};
const map: SnapshotStateMap = {};
for (const entry of state) {
map[entry.key] = entry;
@ -41,7 +41,7 @@ export function generateStateMap(state: SnapshotState | null): SnapshotStateMap
}
export function generateCandidateMap(candidates: StatusCandidate[]): StatusCandidateMap {
const map = {};
const map: StatusCandidateMap = {};
for (const candidate of candidates) {
map[candidate.key] = candidate;
@ -53,7 +53,7 @@ export function generateCandidateMap(candidates: StatusCandidate[]): StatusCandi
export function combinedMapKeys<T extends SnapshotStateMap | StatusCandidateMap>(
...maps: T[]
): DocumentKey[] {
const keyMap = {};
const keyMap: Record<string, unknown> = {};
for (const map of maps) {
for (const key of Object.keys(map)) {
@ -524,7 +524,7 @@ export function describeChanges<T extends BaseModel>(a: T, b: T): string[] {
}
const changes: string[] = [];
const allKeys = [...Object.keys({ ...a, ...b })];
const allKeys = [...Object.keys({ ...a, ...b })] as (keyof T)[];
for (const key of allKeys) {
if (shouldIgnoreKey(key as keyof T, a)) {
@ -547,6 +547,7 @@ export function describeChanges<T extends BaseModel>(a: T, b: T): string[] {
}
if (aStr !== bStr) {
// @ts-expect-error -- type unsoundness
changes.push(key);
}
}

View File

@ -914,7 +914,7 @@ export class VCS {
);
// Store them in case something has changed
await this._storeSnapshots(snapshotsCreate);
console.log('[sync] Pushed snapshots', snapshotsCreate.map(s => s.id).join(', '));
console.log('[sync] Pushed snapshots', snapshotsCreate.map((s: any) => s.id).join(', '));
}
}

View File

@ -63,12 +63,12 @@ export default class BaseExtension {
return this._ext?.deprecated || false;
}
run(...args) {
run(...args: any[]) {
// @ts-expect-error -- TSCONVERSION
return this._ext?.run(...args);
}
parse(parser, nodes, lexer) {
parse(parser: any, nodes: any, lexer: any) {
const tok = parser.nextToken();
let args;
@ -84,7 +84,7 @@ export default class BaseExtension {
return new nodes.CallExtensionAsync(this, 'asyncRun', args);
}
asyncRun({ ctx: renderContext }, ...runArgs) {
asyncRun({ ctx: renderContext }: any, ...runArgs: any[]) {
// Pull the callback off the end
const callback = runArgs[runArgs.length - 1];
// Pull out the meta helper
@ -108,14 +108,14 @@ export default class BaseExtension {
meta: renderMeta,
renderPurpose,
util: {
render: str =>
render: (str: string) =>
templating.render(str, {
context: renderContext,
}),
models: {
request: {
getById: models.request.getById,
getAncestors: async request => {
getAncestors: async (request: any) => {
const ancestors = await db.withAncestors(request, [
models.requestGroup.type,
models.workspace.type,
@ -130,7 +130,7 @@ export default class BaseExtension {
getByRequestId: models.oAuth2Token.getByParentId,
},
cookieJar: {
getOrCreateForWorkspace: workspace => {
getOrCreateForWorkspace: (workspace: any) => {
return models.cookieJar.getOrCreateForParentId(workspace._id);
},
},

View File

@ -62,7 +62,7 @@ export function render(
// NOTE: this is added as a breadcrumb because renderString sometimes hangs
const id = setTimeout(() => console.log('Warning: nunjucks failed to respond within 5 seconds'), 5000);
const nj = await getNunjucks(renderMode);
nj?.renderString(text, templatingContext, (err, result) => {
nj?.renderString(text, templatingContext, (err: Error | null, result: any) => {
clearTimeout(id);
if (err) {
const sanitizedMsg = err.message
@ -190,7 +190,7 @@ async function getNunjucks(renderMode: string) {
nj.addExtension(instance.getTag(), instance);
// Hidden helper filter to debug complicated things
// eg. `{{ foo | urlencode | debug | upper }}`
nj.addFilter('debug', o => o);
nj.addFilter('debug', (o: any) => o);
}
// ~~~~~~~~~~~~~~~~~~~~ //

View File

@ -23,14 +23,14 @@ export class CheckForUpdatesButton extends PureComponent<Props, State> {
updateAvailable: false,
};
_listenerCheckComplete(_e, updateAvailable: true, status: string) {
_listenerCheckComplete(_e: Electron.IpcRendererEvent, updateAvailable: true, status: string) {
this.setState({
status,
updateAvailable,
});
}
_listenerCheckStatus(_e, status: string) {
_listenerCheckStatus(_e: Electron.IpcRendererEvent, status: string) {
if (this.state.checking) {
this.setState({
status,

View File

@ -38,6 +38,11 @@ import 'codemirror/addon/selection/selection-pointer';
import 'codemirror/addon/display/placeholder';
import 'codemirror/addon/lint/lint';
declare global {
// eslint-disable-next-line no-var -- necessary, let will not work here
var jsonlint: unknown;
}
/**/
/**
* Unfortunately, the CodeMirror addon for linting makes use of a pattern whereby linting dependencies are required to be attached to `window` (i.e. `global`) at runtime.

View File

@ -41,8 +41,16 @@ import { shouldIndentWithTabs } from './should-indent-with-tabs';
const TAB_SIZE = 4;
const MAX_SIZE_FOR_LINTING = 1000000; // Around 1MB
interface EditorState {
scroll: CodeMirror.ScrollInfo;
selections: CodeMirror.Range[];
cursor: CodeMirror.Position;
history: any;
marks: Partial<CodeMirror.MarkerRange>[];
}
// Global object used for storing and persisting editor states
const editorStates = {};
const editorStates: Record<string, EditorState> = {};
const BASE_CODEMIRROR_OPTIONS: CodeMirror.EditorConfiguration = {
lineNumbers: true,
placeholder: 'Start Typing...',
@ -254,9 +262,9 @@ export class UnconnectedCodeEditor extends Component<CodeEditorProps, State> {
}
}
shouldComponentUpdate(nextProps) {
shouldComponentUpdate(nextProps: CodeEditorProps) {
// Update if any properties changed, except value. We ignore value.
for (const key of Object.keys(nextProps)) {
for (const key of Object.keys(nextProps) as (keyof CodeEditorProps)[]) {
if (key === 'defaultValue') {
continue;
}
@ -468,7 +476,7 @@ export class UnconnectedCodeEditor extends Component<CodeEditorProps, State> {
const marks = this.codeMirror
.getAllMarks()
.filter(mark => mark.__isFold)
.map(mark => {
.map((mark): Partial<CodeMirror.MarkerRange> => {
const result = mark.find();
if (isMarkerRange(result)) {
@ -512,6 +520,7 @@ export class UnconnectedCodeEditor extends Component<CodeEditorProps, State> {
// Restore marks one-by-one
for (const { from, to } of marks || []) {
// @ts-expect-error -- type unsoundness
this.codeMirror.foldCode(from, to);
}
}
@ -904,7 +913,7 @@ export class UnconnectedCodeEditor extends Component<CodeEditorProps, State> {
Object.keys(options).map(key =>
this._codemirrorSmartSetOption(
key as keyof CodeMirror.EditorConfiguration,
options[key]
options[key as keyof CodeMirror.EditorConfiguration]
)
);
}
@ -1146,7 +1155,7 @@ export class UnconnectedCodeEditor extends Component<CodeEditorProps, State> {
this._setFilter(filter);
}
_handleFilterChange(event) {
_handleFilterChange(event: React.ChangeEvent<HTMLInputElement>) {
this._setFilter(event.target.value);
}

View File

@ -358,7 +358,7 @@ function hint(cm: CodeMirror.EditorFromTextArea, options: ShowHintOptions) {
* @param self
* @param data
*/
async function replaceHintMatch(cm: CodeMirror.EditorFromTextArea, _self, data) {
async function replaceHintMatch(cm: CodeMirror.EditorFromTextArea, _self: any, data: any) {
if (typeof data.text === 'function') {
data.text = await data.text();
}

View File

@ -9,7 +9,7 @@ const entities = new AllHtmlEntities();
CodeMirror.defineExtension('makeLinksClickable', function(handleClick: CodeMirrorLinkClickCallback) {
// Only add the click mode if we have links to click
this.addOverlay({
token: function(stream) {
token: function(stream: any) {
if (stream.match(FLEXIBLE_URL_REGEX, true)) {
return 'clickable';
}
@ -24,7 +24,7 @@ CodeMirror.defineExtension('makeLinksClickable', function(handleClick: CodeMirro
},
});
const el = this.getWrapperElement();
const el: HTMLElement = this.getWrapperElement();
let movedDuringClick = false;
el.addEventListener('mousemove', () => {
movedDuringClick = true;
@ -37,9 +37,11 @@ CodeMirror.defineExtension('makeLinksClickable', function(handleClick: CodeMirro
return;
}
// @ts-expect-error -- type unsoundness
const cls = event.target.className;
if (cls.indexOf('cm-clickable') >= 0) {
// @ts-expect-error -- mapping unsoundness
handleClick(entities.decode(event.target.innerHTML));
}
});

View File

@ -25,7 +25,7 @@ CodeMirror.defineExtension('enableNunjucksTags', function(
);
const debouncedRefreshFn = misc.debounce(refreshFn);
this.on('change', (_cm, change) => {
this.on('change', (_cm: any, change: any) => {
const origin = change.origin || 'unknown';
if (!origin.match(/^[+*]/)) {
@ -44,10 +44,10 @@ CodeMirror.defineExtension('enableNunjucksTags', function(
},
);
async function _highlightNunjucksTags(render, renderContext, showVariableSourceAndValue: boolean) {
async function _highlightNunjucksTags(render: any, renderContext: any, showVariableSourceAndValue: boolean) {
const renderCacheKey = Math.random() + '';
const renderString = text => render(text, renderCacheKey);
const renderString = (text: any) => render(text, renderCacheKey);
const activeMarks: CodeMirror.TextMarker[] = [];
const doc: CodeMirror.Doc = this.getDoc();
@ -57,7 +57,7 @@ async function _highlightNunjucksTags(render, renderContext, showVariableSourceA
for (let lineNo = vp.from; lineNo < vp.to; lineNo++) {
const line = this.getLineTokens(lineNo);
const tokens = line.filter(({ type }) => type?.indexOf('nunjucks') >= 0);
const tokens = line.filter(({ type }: any) => type?.indexOf('nunjucks') >= 0);
// Aggregate same tokens
const newTokens: Token[] = [];
@ -159,7 +159,7 @@ async function _highlightNunjucksTags(render, renderContext, showVariableSourceA
// Define the dialog HTML
showModal(NunjucksModal, {
template: mark.__template,
onDone: template => {
onDone: (template: string | null) => {
const pos = mark.find();
if (pos) {
@ -177,7 +177,7 @@ async function _highlightNunjucksTags(render, renderContext, showVariableSourceA
let droppedInSameEditor = false;
// Modify paste events so we can merge into them
const beforeChangeCb = (_cm, change) => {
const beforeChangeCb = (_cm: any, change: any) => {
if (change.origin === 'paste') {
change.origin = '+dnd';
}
@ -255,7 +255,7 @@ async function _highlightNunjucksTags(render, renderContext, showVariableSourceA
}
}
async function _updateElementText(render, mark, text, renderContext, showVariableSourceAndValue: boolean) {
async function _updateElementText(render: any, mark: any, text: any, renderContext: any, showVariableSourceAndValue: boolean) {
const el = mark.replacedWith;
let innerHTML = '';
let title = '';

View File

@ -4,7 +4,7 @@ import { initializeSpectral, isLintError } from '../../../../common/spectral';
const spectral = initializeSpectral();
CodeMirror.registerHelper('lint', 'openapi', async function(text) {
CodeMirror.registerHelper('lint', 'openapi', async function(text: string) {
const results = (await spectral.run(text)).filter(isLintError);
return results.map(result => ({

View File

@ -26,7 +26,7 @@ function _nunjucksMode() {
};
},
token(stream, state) {
token(stream: any, state: any) {
let m;
// This makes sure that adjacent tags still have unique types
ticker *= -1;

View File

@ -2,7 +2,7 @@ import { autoBindMethodsForReact } from 'class-autobind-decorator';
import classnames from 'classnames';
import React, { Fragment, PureComponent, ReactNode } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { AnyAction, bindActionCreators, Dispatch } from 'redux';
import { SegmentEvent, trackSegmentEvent, vcsSegmentEventProperties } from '../../../common/analytics';
import { AUTOBIND_CFG } from '../../../common/constants';
@ -145,7 +145,7 @@ class GitSyncDropdown extends PureComponent<Props, State> {
});
}
async _handlePush(_e, force = false) {
async _handlePush(_e: unknown, force = false) {
this.setState({
loadingPush: true,
});
@ -398,7 +398,7 @@ class GitSyncDropdown extends PureComponent<Props, State> {
}
}
function mapDispatchToProps(dispatch) {
function mapDispatchToProps(dispatch: Dispatch<AnyAction>) {
const boundGitActions = bindActionCreators(gitActions, dispatch);
return {
setupGitRepository: boundGitActions.setupGitRepository,

View File

@ -1,6 +1,6 @@
import React, { FC, useCallback } from 'react';
import { getPreviewModeName, PREVIEW_MODES } from '../../../common/constants';
import { getPreviewModeName, PREVIEW_MODES, PreviewMode } from '../../../common/constants';
import { Dropdown } from '../base/dropdown/dropdown';
import { DropdownButton } from '../base/dropdown/dropdown-button';
import { DropdownDivider } from '../base/dropdown/dropdown-divider';
@ -12,7 +12,7 @@ interface Props {
exportAsHAR: () => void;
copyToClipboard: () => any;
updatePreviewMode: Function;
previewMode: string;
previewMode: PreviewMode;
showPrettifyOption?: boolean;
}

View File

@ -2,7 +2,7 @@ import { autoBindMethodsForReact } from 'class-autobind-decorator';
import classnames from 'classnames';
import React, { Fragment, PureComponent } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { AnyAction, bindActionCreators, Dispatch } from 'redux';
import * as session from '../../../account/session';
import { AUTOBIND_CFG, DEFAULT_BRANCH_NAME } from '../../../common/constants';
@ -49,7 +49,7 @@ const mapStateToProps = (state: RootState) => ({
remoteProjects: selectRemoteProjects(state),
});
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch: Dispatch<AnyAction>) => {
const bound = bindActionCreators({ activateWorkspace }, dispatch);
return {
handleActivateWorkspace: bound.activateWorkspace,

View File

@ -101,7 +101,7 @@ export const BodyEditor: FC<Props> = ({
Do you want set the <span className="monospace">Content-Type</span> header to{' '}
<span className="monospace">{newContentType}</span>?
</p>,
onDone: saidYes => {
onDone: (saidYes: boolean) => {
if (saidYes) {
onChangeHeaders(newRequest, headers);
}

View File

@ -33,7 +33,7 @@ export class MarkdownEditor extends PureComponent<Props, State> {
};
}
_handleChange(markdown) {
_handleChange(markdown: string) {
this.props.onChange(markdown);
this.setState({
markdown,

View File

@ -36,7 +36,7 @@ class MarkdownPreviewInternal extends PureComponent<Props, State> {
/**
* Debounce and compile the markdown (won't debounce first render)
*/
_compileMarkdown(markdown) {
_compileMarkdown(markdown: string) {
if (this._compileTimeout !== null) {
clearTimeout(this._compileTimeout);
}
@ -65,7 +65,7 @@ class MarkdownPreviewInternal extends PureComponent<Props, State> {
this._preview = preview;
}
_handleClickLink(event) {
_handleClickLink(event: any) {
event.preventDefault();
clickLink(event.target.getAttribute('href'));
}

View File

@ -15,7 +15,7 @@ import { ModalHeader } from '../base/modal-header';
import { CodeEditor } from '../codemirror/code-editor';
import { MarkdownEditor } from '../markdown-editor';
const MODES = {
const MODES: Record<string, string> = {
'text/plain': 'Plain Text',
'application/json': 'JSON',
'application/xml': 'XML',
@ -58,11 +58,11 @@ export class CodePromptModal extends PureComponent<{}, State> {
this.modal = modal;
}
_handleChange(value) {
_handleChange(value: any) {
this._onChange(value);
}
_handleChangeMode(mode) {
_handleChangeMode(mode: any) {
this.setState({ mode });
this._onModeChange?.(mode);
}
@ -71,7 +71,7 @@ export class CodePromptModal extends PureComponent<{}, State> {
this.modal?.hide();
}
show(options) {
show(options: any) {
const {
title,
defaultValue,

View File

@ -45,6 +45,7 @@ export class UnconnectedCookieModifyModal extends PureComponent<Props, State> {
async show(cookie: Cookie) {
// Dunno why this is sent as an array
// @ts-expect-error -- type unsoundness
cookie = cookie[0] || cookie;
const { activeCookeJar } = this.props;
const prevCookie = activeCookeJar?.cookies.find(c => c.id === cookie.id);
@ -73,7 +74,7 @@ export class UnconnectedCookieModifyModal extends PureComponent<Props, State> {
}
this._rawTimeout = setTimeout(async () => {
const prevCookie = this.state.cookie;
let cookie;
let cookie: Cookie;
try {
// NOTE: Perform toJSON so we have a plain JS object instead of Cookie instance
@ -181,6 +182,7 @@ export class UnconnectedCookieModifyModal extends PureComponent<Props, State> {
return null;
}
// @ts-expect-error -- mapping unsoundness
const val = (cookie[field] || '').toString();
return (
<div className="form-control form-control--outlined">
@ -230,6 +232,7 @@ export class UnconnectedCookieModifyModal extends PureComponent<Props, State> {
</div>
<div className="pad no-pad-top cookie-modify__checkboxes row-around txt-lg">
{checkFields.map((field, i) => {
// @ts-expect-error -- mapping unsoundness
const checked = !!cookie[field];
return (
<label key={i}>

View File

@ -69,7 +69,7 @@ export class EnvironmentEditModal extends PureComponent<Props, State> {
}
}
show(requestGroup) {
show(requestGroup: RequestGroup) {
this.setState({ requestGroup });
this.modal?.show();
}

View File

@ -111,7 +111,7 @@ export class ExportRequestsModal extends PureComponent<Props, State> {
}
createNode(item: Record<string, any>): Node {
const children: Node[] = item.children.map(child => this.createNode(child));
const children: Node[] = item.children.map((child: Record<string, any>) => this.createNode(child));
let totalRequests = children
.map(child => child.totalRequests)
.reduce((acc, totalRequests) => acc + totalRequests, 0);

View File

@ -18,7 +18,7 @@ import { CodeEditor, UnconnectedCodeEditor } from '../codemirror/code-editor';
const DEFAULT_TARGET = HTTPSnippet.availableTargets().find(t => t.key === 'shell') as HTTPSnippetTarget;
const DEFAULT_CLIENT = DEFAULT_TARGET?.clients.find(t => t.key === 'curl') as HTTPSnippetClient;
const MODE_MAP = {
const MODE_MAP: Record<string, string> = {
c: 'clike',
java: 'clike',
csharp: 'clike',
@ -26,7 +26,7 @@ const MODE_MAP = {
objc: 'clike',
ocaml: 'mllike',
};
const TO_ADD_CONTENT_LENGTH = {
const TO_ADD_CONTENT_LENGTH: Record<string, string[]> = {
node: ['native'],
};
@ -80,7 +80,7 @@ export class GenerateCodeModal extends PureComponent<Props, State> {
this.modal?.hide();
}
_handleClientChange(client) {
_handleClientChange(client: HTTPSnippetClient) {
const { target, request } = this.state;
if (!request) {
@ -89,7 +89,7 @@ export class GenerateCodeModal extends PureComponent<Props, State> {
this._generateCode(request, target, client);
}
_handleTargetChange(target) {
_handleTargetChange(target: HTTPSnippetTarget) {
const { target: currentTarget, request } = this.state;
if (currentTarget.key === target.key) {
@ -102,12 +102,14 @@ export class GenerateCodeModal extends PureComponent<Props, State> {
if (!request) {
return;
}
this._generateCode(request, target, client);
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this._generateCode(request, target, client!);
}
async _generateCode(request: Request, target: HTTPSnippetTarget, client: HTTPSnippetClient) {
// Some clients need a content-length for the request to succeed
const addContentLength = (TO_ADD_CONTENT_LENGTH[target.key] || []).find(c => c === client.key);
const addContentLength = Boolean((TO_ADD_CONTENT_LENGTH[target.key] || []).find(c => c === client.key));
const { environmentId } = this.props;
const har = await exportHarRequest(request._id, environmentId, addContentLength);
// @TODO Should we throw instead?

View File

@ -207,7 +207,7 @@ export class GitStagingModal extends PureComponent<Props, State> {
}
// Create status items
const items = {};
const items: Record<string, Item> = {};
const log = (await vcs.log(1)) || [];
for (const gitPath of allPaths) {
@ -255,7 +255,7 @@ export class GitStagingModal extends PureComponent<Props, State> {
}
items[gitPath] = {
type,
type: type as any,
staged,
editable,
status,

View File

@ -3,9 +3,9 @@ import { AlertModal, AlertModalOptions } from './alert-modal';
import { ErrorModal, ErrorModalOptions } from './error-modal';
import { PromptModal, PromptModalOptions } from './prompt-modal';
const modals = {};
const modals: Record<string, any> = {};
export function registerModal(instance) {
export function registerModal(instance: any) {
if (instance === null) {
// Modal was unmounted
return;
@ -14,7 +14,7 @@ export function registerModal(instance) {
modals[instance.constructor.name] = instance;
}
export function showModal(modalCls, ...args) {
export function showModal(modalCls: any, ...args: any[]) {
trackPageView(modalCls.name);
return _getModal(modalCls).show(...args);
}
@ -42,7 +42,7 @@ export function hideAllModals() {
}
}
function _getModal(modalCls) {
function _getModal(modalCls: any) {
const m = modals[modalCls.name || modalCls.WrappedComponent?.name];
if (!m) {

View File

@ -42,7 +42,7 @@ export class LoginModal extends PureComponent<{}, State> {
this._emailInput = emailInput;
}
async _handleLogin(event) {
async _handleLogin(event: React.FormEvent) {
event.preventDefault();
this.setState({
error: '',

View File

@ -37,7 +37,7 @@ export class NunjucksModal extends PureComponent<Props, State> {
this._currentTemplate = template;
}
_handleSubmit(event) {
_handleSubmit(event: React.FormEvent) {
event.preventDefault();
this.hide();
}
@ -52,7 +52,7 @@ export class NunjucksModal extends PureComponent<Props, State> {
}
}
show({ template, onDone }) {
show({ template, onDone }: any) {
this._onDone = onDone;
this._currentTemplate = template;
this.setState({

View File

@ -1,7 +1,7 @@
import { autoBindMethodsForReact } from 'class-autobind-decorator';
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { AnyAction, bindActionCreators, Dispatch } from 'redux';
import { AUTOBIND_CFG } from '../../../common/constants';
import { strings } from '../../../common/strings';
@ -105,7 +105,7 @@ const mapStateToProps = (state: RootState) => ({
project: selectActiveProject(state),
});
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch: Dispatch<AnyAction>) => {
const boundProjectActions = bindActionCreators(projectActions, dispatch);
return {
handleRemoveProject: boundProjectActions.removeProject,

View File

@ -36,7 +36,7 @@ export class RequestRenderErrorModal extends PureComponent<{}, State> {
});
}
show({ request, error }) {
show({ request, error }: Pick<State, 'request' | 'error'>) {
this.setState({ request, error });
this.modal?.show();
}
@ -45,7 +45,7 @@ export class RequestRenderErrorModal extends PureComponent<{}, State> {
this.modal?.hide();
}
renderModalBody(request, error) {
renderModalBody(request: any, error: any) {
const fullPath = `Request.${error.path}`;
const result = JSONPath({ json: request, path: `$.${error.path}` });
const template = result && result.length ? result[0] : null;

View File

@ -238,6 +238,7 @@ export class UnconnectedRequestSettingsModal extends PureComponent<Props, State>
<input
type="checkbox"
name={setting}
// @ts-expect-error -- mapping unsoundness
checked={request[setting]}
onChange={this._updateRequestSettingBoolean}
/>

View File

@ -24,20 +24,19 @@ interface Props extends ReduxProps {
vcs: VCS;
}
type LookupMap = Record<string, {
entry: StageEntry;
changes: null | string[];
type: string;
checked: boolean;
}>;
interface State {
status: Status;
message: string;
error: string;
branch: string;
lookupMap: Record<
string,
{
entry: StageEntry;
changes: null | string[];
type: string;
checked: boolean;
}
>;
lookupMap: LookupMap;
}
const _initialState: State = {
@ -154,7 +153,7 @@ export class UnconnectedSyncStagingModal extends PureComponent<Props, State> {
const { vcs, syncItems } = this.props;
const branch = await vcs.getBranch();
const status = await vcs.status(syncItems, newStage);
const lookupMap = {};
const lookupMap: LookupMap = {};
const allKeys = [...Object.keys(status.stage), ...Object.keys(status.unstaged)];
for (const key of allKeys) {

View File

@ -8,7 +8,7 @@ import { extension as mimeExtension } from 'mime-types';
import React, { PureComponent } from 'react';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
import { AUTOBIND_CFG, PREVIEW_MODE_SOURCE } from '../../../common/constants';
import { AUTOBIND_CFG, PREVIEW_MODE_SOURCE, PreviewMode } from '../../../common/constants';
import { exportHarCurrentRequest } from '../../../common/har';
import { getSetCookieHeaders } from '../../../common/misc';
import * as models from '../../../models';
@ -42,7 +42,7 @@ interface Props {
handleDeleteResponses: Function;
handleDeleteResponse: Function;
handleShowRequestSettings: Function;
previewMode: string;
previewMode: PreviewMode;
filter: string;
filterHistory: string[];
disableHtmlPreviewJs: boolean;

View File

@ -101,7 +101,7 @@ const moveDoc = async ({
}
}
function __updateDoc(doc, patch) {
function __updateDoc(doc: BaseModel, patch: any) {
// @ts-expect-error -- TSCONVERSION
return models.getModel(docToMove.type).update(doc, patch);
}

View File

@ -91,7 +91,7 @@ class UnconnectedSidebarChildren extends PureComponent<Props> {
// We have a RequestGroup!
const requestGroup = child.doc;
function hasActiveChild(children) {
function hasActiveChild(children: Child[]) {
for (const c of children) {
if (hasActiveChild(c.children || [])) {
return true;

View File

@ -66,7 +66,7 @@ class UnconnectedSidebarRequestGroupRow extends PureComponent<Props, State> {
this.dropdownRef.current?.show();
}
setDragDirection(dragDirection) {
setDragDirection(dragDirection: number) {
if (dragDirection !== this.state.dragDirection) {
this.setState({
dragDirection,

View File

@ -239,7 +239,7 @@ export const _SidebarRequestRow: FC<Props> = forwardRef(({
className="inline-block"
onEditStart={startEditing}
onSubmit={handleRequestUpdateName}
renderReadView={(value, props) => (
renderReadView={(value: string, props: any) => (
<Highlight
search={filter}
text={value}

View File

@ -72,7 +72,9 @@ export class SpecEditorSidebar extends Component<Props, State> {
);
const itemMappedPosition = sourceMap.lookup(itemPath, specMap);
const isServersSection = itemPath[0] === 'servers';
scrollPosition.start.line += itemMappedPosition.start.line;
// TODO: remove non-null assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
scrollPosition.start.line += itemMappedPosition!.start.line;
if (!isServersSection) {
scrollPosition.start.line -= 1;
@ -83,7 +85,7 @@ export class SpecEditorSidebar extends Component<Props, State> {
this._handleScrollEditor(scrollPosition);
}
_handleItemClick = (...itemPath): void => {
_handleItemClick = (...itemPath: any[]): void => {
this._mapPosition(itemPath);
};

View File

@ -147,7 +147,7 @@ class TagEditorInternal extends PureComponent<Props, State> {
this.setState({
loadingDocs: true,
});
const allDocs = {};
const allDocs: Record<string, models.BaseModel[]> = {};
for (const type of models.types()) {
allDocs[type] = [];
@ -160,6 +160,7 @@ class TagEditorInternal extends PureComponent<Props, State> {
const requests = allDocs[models.request.type] || [];
const requestGroups = allDocs[models.requestGroup.type] || [];
// @ts-expect-error -- type unsoundness
const sortedReqs = this._sortRequests(requests.concat(requestGroups), this.props.workspace._id);
allDocs[models.request.type] = sortedReqs;

View File

@ -47,7 +47,7 @@ class VariableEditorInternal extends PureComponent<Props, State> {
this._resize();
}
_handleChange(event) {
_handleChange(event: React.ChangeEvent<HTMLSelectElement | HTMLInputElement>) {
const name = event.target.value;
this._update(name);
}
@ -70,7 +70,7 @@ class VariableEditorInternal extends PureComponent<Props, State> {
}, 100);
}
async _update(value, noCallback = false) {
async _update(value: string, noCallback = false) {
const { handleRender } = this.props;
const cleanedValue = value
.replace(/^{%/, '')

View File

@ -182,7 +182,7 @@ export class Toast extends PureComponent<{}, State> {
}, 1000);
}
_listenerShowNotification(_e, notification: ToastNotification) {
_listenerShowNotification(_e: Electron.IpcRendererEvent, notification: ToastNotification) {
this._handleNotification(notification);
}

View File

@ -11,7 +11,7 @@ interface Props {
}
export const ResponseCookiesViewer: FC<Props> = props => {
const renderRow = (h, i) => {
const renderRow = (h: any, i: number) => {
let cookie: Cookie | undefined | null = null;
try {

View File

@ -26,7 +26,7 @@ export class ResponseTimelineViewer extends PureComponent<Props, State> {
this.refreshTimeline();
}
componentDidUpdate(prevProps) {
componentDidUpdate(prevProps: Props) {
const { response } = this.props;
if (response._id !== prevProps.response._id) {

View File

@ -11,7 +11,7 @@ import {
} from 'insomnia-components';
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { AnyAction, bindActionCreators, Dispatch } from 'redux';
import styled from 'styled-components';
import { unreachableCase } from 'ts-assert-unreachable';
@ -404,7 +404,7 @@ const mapStateToProps = (state: RootState) => ({
workspacesForActiveProject: selectWorkspacesForActiveProject(state),
});
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch: Dispatch<AnyAction>) => {
const bound = bindActionCreators(
{
createWorkspace,

View File

@ -19,7 +19,7 @@ import { SegmentEvent, trackSegmentEvent } from '../../common/analytics';
import { AUTOBIND_CFG } from '../../common/constants';
import { documentationLinks } from '../../common/documentation';
import * as models from '../../models';
import { isRequest } from '../../models/request';
import { isRequest, Request } from '../../models/request';
import { isRequestGroup } from '../../models/request-group';
import type { UnitTest } from '../../models/unit-test';
import type { UnitTestSuite } from '../../models/unit-test-suite';
@ -33,7 +33,7 @@ import { showAlert, showModal, showPrompt } from './modals';
import { SelectModal } from './modals/select-modal';
import { PageLayout } from './page-layout';
import { EmptyStatePane } from './panes/empty-state-pane';
import type { SidebarChildObjects } from './sidebar/sidebar-children';
import type { Child, SidebarChildObjects } from './sidebar/sidebar-children';
import { UnitTestEditable } from './unit-test-editable';
import { WorkspacePageHeader } from './workspace-page-header';
import type { HandleActivityChange, WrapperProps } from './wrapper';
@ -127,11 +127,10 @@ class UnconnectedWrapperUnitTest extends PureComponent<Props, State> {
...this.buildSelectableRequests().map(({ name, request }) => ({
name: name,
displayValue: '',
// @ts-expect-error -- TSCONVERSION
value: this.generateSendReqSnippet(unitTest.code, `'${request._id}'`),
})),
],
onDone: value => resolve(value),
onDone: (value: string | null) => resolve(value),
});
});
},
@ -329,7 +328,7 @@ class UnconnectedWrapperUnitTest extends PureComponent<Props, State> {
request: Request;
}[] = [];
const next = (p, children) => {
const next = (p: string, children: Child[]) => {
for (const c of children) {
if (isRequest(c.doc)) {
selectableRequests.push({
@ -399,7 +398,7 @@ class UnconnectedWrapperUnitTest extends PureComponent<Props, State> {
)}
</div>
<ListGroup>
{tests.map((t, i) => (
{tests.map((t: any, i: number) => (
<UnitTestResultItem key={i} item={t} />
))}
</ListGroup>

View File

@ -460,7 +460,7 @@ export class Wrapper extends PureComponent<WrapperProps, State> {
});
}
_handleGitBranchChanged(branch) {
_handleGitBranchChanged(branch: string) {
this.setState({
activeGitBranch: branch || 'no-vcs',
});

View File

@ -25,9 +25,10 @@ import {
MIN_PANE_HEIGHT,
MIN_PANE_WIDTH,
MIN_SIDEBAR_REMS,
PreviewMode,
SortOrder,
} from '../../common/constants';
import { database as db } from '../../common/database';
import { type ChangeBufferEvent, database as db } from '../../common/database';
import { getDataDirectory } from '../../common/electron-helpers';
import { exportHarRequest } from '../../common/har';
import { hotKeyRefs } from '../../common/hotkeys';
@ -46,6 +47,7 @@ import * as requestOperations from '../../models/helpers/request-operations';
import { isNotDefaultProject } from '../../models/project';
import { Request, updateMimeType } from '../../models/request';
import { isRequestGroup, RequestGroup } from '../../models/request-group';
import { type RequestGroupMeta } from '../../models/request-group-meta';
import { RequestMeta } from '../../models/request-meta';
import { Response } from '../../models/response';
import { isWorkspace } from '../../models/workspace';
@ -58,6 +60,7 @@ import { GIT_CLONE_DIR, GIT_INSOMNIA_DIR, GIT_INTERNAL_DIR, GitVCS } from '../..
import { NeDBClient } from '../../sync/git/ne-db-client';
import { routableFSClient } from '../../sync/git/routable-fs-client';
import FileSystemDriver from '../../sync/store/drivers/file-system-driver';
import { type MergeConflict } from '../../sync/types';
import { VCS } from '../../sync/vcs/vcs';
import * as templating from '../../templating/index';
import { ErrorBoundary } from '../components/error-boundary';
@ -298,7 +301,7 @@ class App extends PureComponent<AppProps, State> {
showModal(AskModal, {
title: 'Delete Request?',
message: `Really delete ${activeRequest.name}?`,
onDone: async confirmed => {
onDone: async (confirmed: boolean) => {
if (!confirmed) {
return;
}
@ -347,7 +350,7 @@ class App extends PureComponent<AppProps, State> {
? entities.grpcRequestMetas
: entities.requestMetas;
const meta = Object.values<GrpcRequestMeta | RequestMeta>(entitiesToCheck).find(m => m.parentId === activeRequest._id);
await this._handleSetRequestPinned(this.props.activeRequest, !meta?.pinned);
await this._handleSetRequestPinned(activeRequest, !meta?.pinned);
},
],
[hotKeyRefs.PLUGIN_RELOAD, this._handleReloadPlugins],
@ -390,7 +393,7 @@ class App extends PureComponent<AppProps, State> {
}
async _recalculateMetaSortKey(docs: (RequestGroup | Request | GrpcRequest)[]) {
function __updateDoc(doc, metaSortKey) {
function __updateDoc(doc: RequestGroup | Request | GrpcRequest, metaSortKey: number) {
// @ts-expect-error -- TSCONVERSION the fetched model will only ever be a RequestGroup, Request, or GrpcRequest
// Which all have the .update method. How do we better filter types?
return models.getModel(doc.type)?.update(doc, {
@ -486,7 +489,7 @@ class App extends PureComponent<AppProps, State> {
}
}
static async _updateRequestGroupMetaByParentId(requestGroupId, patch) {
static async _updateRequestGroupMetaByParentId(requestGroupId: string, patch: Partial<RequestGroupMeta>) {
const requestGroupMeta = await models.requestGroupMeta.getByParentId(requestGroupId);
if (requestGroupMeta) {
@ -576,25 +579,25 @@ class App extends PureComponent<AppProps, State> {
});
}
async _handleSetRequestPinned(request, pinned) {
async _handleSetRequestPinned(request: Request | GrpcRequest, pinned: boolean) {
updateRequestMetaByParentId(request._id, {
pinned,
});
}
_handleSetResponsePreviewMode(requestId, previewMode) {
_handleSetResponsePreviewMode(requestId: string, previewMode: PreviewMode) {
updateRequestMetaByParentId(requestId, {
previewMode,
});
}
_handleUpdateDownloadPath(requestId, downloadPath) {
_handleUpdateDownloadPath(requestId: string, downloadPath: string) {
updateRequestMetaByParentId(requestId, {
downloadPath,
});
}
async _handleSetResponseFilter(requestId, responseFilter) {
async _handleSetResponseFilter(requestId: string, responseFilter: string) {
await updateRequestMetaByParentId(requestId, {
responseFilter,
});
@ -706,7 +709,7 @@ class App extends PureComponent<AppProps, State> {
const extension = sanitizedExtension || 'unknown';
const name =
nameFromHeader || `${request.name.replace(/\s/g, '-').toLowerCase()}.${extension}`;
let filename;
let filename: string | null;
if (dir) {
filename = path.join(dir, name);
@ -763,7 +766,7 @@ class App extends PureComponent<AppProps, State> {
}
}
async _handleSendRequestWithEnvironment(requestId, environmentId) {
async _handleSendRequestWithEnvironment(requestId: string, environmentId?: string) {
const { handleStartLoading, handleStopLoading, settings } = this.props;
const request = await models.request.getById(requestId);
@ -878,7 +881,7 @@ class App extends PureComponent<AppProps, State> {
setTimeout(() => this._handleSetPaneHeight(DEFAULT_PANE_HEIGHT), 50);
}
_handleMouseMove(event) {
_handleMouseMove(event: MouseEvent) {
if (this.state.draggingPaneHorizontal) {
// Only pop the overlay after we've moved it a bit (so we don't block doubleclick);
const distance = this.props.paneWidth - this.state.paneWidth;
@ -1166,7 +1169,7 @@ class App extends PureComponent<AppProps, State> {
return new Promise(resolve => {
showModal(SyncMergeModal, {
conflicts,
handleDone: conflicts => resolve(conflicts),
handleDone: (conflicts: MergeConflict[]) => resolve(conflicts),
});
});
});
@ -1186,7 +1189,7 @@ class App extends PureComponent<AppProps, State> {
}
}
async _handleDbChange(changes) {
async _handleDbChange(changes: ChangeBufferEvent[]) {
let needsRefresh = false;
for (const change of changes) {
@ -1270,7 +1273,7 @@ class App extends PureComponent<AppProps, State> {
message: 'Are you sure you want to clear all models? This operation cannot be undone.',
yesText: 'Yes',
noText: 'No',
onDone: async yes => {
onDone: async (yes: boolean) => {
if (yes) {
const bufferId = await db.bufferChanges();
const promises = models

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