diff --git a/packages/insomnia/src/common/spectral.ts b/packages/insomnia/src/common/spectral.ts deleted file mode 100644 index f99088aa53..0000000000 --- a/packages/insomnia/src/common/spectral.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { IRuleResult, RulesetDefinition, Spectral } from '@stoplight/spectral-core'; -import { oas } from '@stoplight/spectral-rulesets'; - -export const initializeSpectral = () => { - const spectral = new Spectral(); - spectral.setRuleset(oas as RulesetDefinition); - return spectral; -}; - -export const isLintError = (result: IRuleResult) => result.severity === 0; diff --git a/packages/insomnia/src/main/ipc/main.ts b/packages/insomnia/src/main/ipc/main.ts index d77781525d..6858f6fb7a 100644 --- a/packages/insomnia/src/main/ipc/main.ts +++ b/packages/insomnia/src/main/ipc/main.ts @@ -1,3 +1,7 @@ +import type { ISpectralDiagnostic } from '@stoplight/spectral-core'; +import type { RulesetDefinition } from '@stoplight/spectral-core'; +import { Spectral } from '@stoplight/spectral-core'; +import { oas } from '@stoplight/spectral-rulesets'; import { app, ipcMain, IpcRendererEvent } from 'electron'; import { writeFile } from 'fs/promises'; @@ -8,6 +12,7 @@ import { WebSocketBridgeAPI } from '../network/websocket'; export interface MainBridgeAPI { restart: () => void; + spectralRun: (content: string) => Promise; authorizeUserInWindow: typeof authorizeUserInWindow; setMenuBarVisibility: (visible: boolean) => void; installPlugin: typeof installPlugin; @@ -47,4 +52,10 @@ export function registerMainHandlers() { app.relaunch(); app.exit(); }); + + ipcMain.handle('spectralRun', (_, content: string) => { + const spectral = new Spectral(); + spectral.setRuleset(oas as RulesetDefinition); + return spectral.run(content); + }); } diff --git a/packages/insomnia/src/preload.ts b/packages/insomnia/src/preload.ts index c33dba7910..20123de468 100644 --- a/packages/insomnia/src/preload.ts +++ b/packages/insomnia/src/preload.ts @@ -18,6 +18,7 @@ const webSocket: WebSocketBridgeAPI = { const main: Window['main'] = { restart: () => ipcRenderer.send('restart'), authorizeUserInWindow: options => ipcRenderer.invoke('authorizeUserInWindow', options), + spectralRun: options => ipcRenderer.invoke('spectralRun', options), setMenuBarVisibility: options => ipcRenderer.send('setMenuBarVisibility', options), installPlugin: options => ipcRenderer.invoke('installPlugin', options), curlRequest: options => ipcRenderer.invoke('curlRequest', options), diff --git a/packages/insomnia/src/ui/components/codemirror/lint/openapi.ts b/packages/insomnia/src/ui/components/codemirror/lint/openapi.ts index 013fb3ac96..55b68baa11 100644 --- a/packages/insomnia/src/ui/components/codemirror/lint/openapi.ts +++ b/packages/insomnia/src/ui/components/codemirror/lint/openapi.ts @@ -1,13 +1,11 @@ +import type { IRuleResult } from '@stoplight/spectral-core'; import CodeMirror from 'codemirror'; -import { initializeSpectral, isLintError } from '../../../../common/spectral'; - -const spectral = initializeSpectral(); - CodeMirror.registerHelper('lint', 'openapi', async function(text: string) { - const results = (await spectral.run(text)).filter(isLintError); + const isLintError = (result: IRuleResult) => result.severity === 0; - return results.map(result => ({ + const run = await window.main.spectralRun(text); + return run.filter(isLintError).map(result => ({ from: CodeMirror.Pos(result.range.start.line, result.range.start.character), to: CodeMirror.Pos(result.range.end.line, result.range.end.character), message: result.message, diff --git a/packages/insomnia/src/ui/routes/design.tsx b/packages/insomnia/src/ui/routes/design.tsx index 05db44aab9..f3da2f43fd 100644 --- a/packages/insomnia/src/ui/routes/design.tsx +++ b/packages/insomnia/src/ui/routes/design.tsx @@ -1,4 +1,4 @@ -import { IRuleResult } from '@stoplight/spectral-core'; +import type { IRuleResult } from '@stoplight/spectral-core'; import React, { createRef, FC, RefObject, useCallback, useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; @@ -6,7 +6,6 @@ import styled from 'styled-components'; import { parseApiSpec, ParsedApiSpec } from '../../common/api-specs'; import { database } from '../../common/database'; import { debounce } from '../../common/misc'; -import { initializeSpectral, isLintError } from '../../common/spectral'; import * as models from '../../models/index'; import { CodeEditor, CodeEditorHandle } from '../components/codemirror/code-editor'; import { DesignEmptyState } from '../components/design-empty-state'; @@ -19,6 +18,8 @@ import { superFaint } from '../css/css-in-js'; import { useActiveApiSpecSyncVCSVersion, useGitVCSVersion } from '../hooks/use-vcs-version'; import { selectActiveApiSpec } from '../redux/selectors'; +const isLintError = (result: IRuleResult) => result.severity === 0; + const EmptySpaceHelper = styled.div({ ...superFaint, display: 'flex', @@ -28,9 +29,6 @@ const EmptySpaceHelper = styled.div({ textAlign: 'center', }); -// TODO(jackkav): find the right place to do this -const spectral = initializeSpectral(); - interface LintMessage extends Notice { range: IRuleResult['range']; } @@ -68,8 +66,9 @@ const RenderEditor: FC<{ editor: RefObject }> = ({ editor }) = const update = async () => { // Lint only if spec has content if (contents && contents.length !== 0) { - const results: LintMessage[] = (await spectral.run(contents)) - .filter(isLintError) + const run = await window.main.spectralRun(contents); + + const results: LintMessage[] = run.filter(isLintError) .map(({ severity, code, message, range }) => ({ type: severity === 0 ? 'error' : 'warning', message: `${code} ${message}`,