mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* cleaned up autocomplete.ts and get_endpoint_from_postition.ts of anys * general clean up of lowering hanging fruit * cleaned up remaining anys, still need to test * fix remaining TS compilation issues * also tidy up use of "as any" and some more ": any" * addressed type issues and introduced the default editor settings object * clean up @ts-ignore * added comments to interface Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
875af045a2
commit
7365f3b26d
52 changed files with 402 additions and 219 deletions
|
@ -16,7 +16,7 @@ import { i18n } from '@kbn/i18n';
|
|||
interface Props {
|
||||
getCurl: () => Promise<string>;
|
||||
getDocumentation: () => Promise<string | null>;
|
||||
autoIndent: (ev?: React.MouseEvent) => void;
|
||||
autoIndent: (ev: React.MouseEvent) => void;
|
||||
addNotification?: (opts: { title: string }) => void;
|
||||
}
|
||||
|
||||
|
@ -84,8 +84,7 @@ export class ConsoleMenu extends Component<Props, State> {
|
|||
window.open(documentation, '_blank');
|
||||
};
|
||||
|
||||
// Using `any` here per this issue: https://github.com/elastic/eui/issues/2265
|
||||
autoIndent: any = (event: React.MouseEvent) => {
|
||||
autoIndent = (event: React.MouseEvent) => {
|
||||
this.closePopover();
|
||||
this.props.autoIndent(event);
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@ export type AutocompleteOptions = 'fields' | 'indices' | 'templates';
|
|||
interface Props {
|
||||
onSaveSettings: (newSettings: DevToolsSettings) => void;
|
||||
onClose: () => void;
|
||||
refreshAutocompleteSettings: (selectedSettings: any) => void;
|
||||
refreshAutocompleteSettings: (selectedSettings: DevToolsSettings['autocomplete']) => void;
|
||||
settings: DevToolsSettings;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ export function DevToolsSettingsModal(props: Props) {
|
|||
return rest;
|
||||
})}
|
||||
idToSelectedMap={checkboxIdToSelectedMap}
|
||||
onChange={(e: any) => {
|
||||
onChange={(e: unknown) => {
|
||||
onAutocompleteChange(e as AutocompleteOptions);
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -53,7 +53,7 @@ export function ConsoleHistory({ close }: Props) {
|
|||
const selectedReq = useRef<any>(null);
|
||||
|
||||
const describeReq = useMemo(() => {
|
||||
const _describeReq = (req: any) => {
|
||||
const _describeReq = (req: { endpoint: string; time: string }) => {
|
||||
const endpoint = req.endpoint;
|
||||
const date = moment(req.time);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import { applyCurrentSettings } from '../editor/legacy/console_editor/apply_edit
|
|||
|
||||
interface Props {
|
||||
settings: DevToolsSettings;
|
||||
req: any | null;
|
||||
req: { method: string; endpoint: string; data: string; time: string } | null;
|
||||
}
|
||||
|
||||
export function HistoryViewer({ settings, req }: Props) {
|
||||
|
|
|
@ -14,7 +14,7 @@ export function applyCurrentSettings(
|
|||
editor: CoreEditor | CustomAceEditor,
|
||||
settings: DevToolsSettings
|
||||
) {
|
||||
if ((editor as any).setStyles) {
|
||||
if ((editor as { setStyles?: Function }).setStyles) {
|
||||
(editor as CoreEditor).setStyles({
|
||||
wrapLines: settings.wrapMode,
|
||||
fontSize: settings.fontSize + 'px',
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
// Mocked functions
|
||||
import { sendRequestToES } from '../../../../hooks/use_send_current_request_to_es/send_request_to_es';
|
||||
import { getEndpointFromPosition } from '../../../../../lib/autocomplete/get_endpoint_from_position';
|
||||
|
||||
import type { DevToolsSettings } from '../../../../../services';
|
||||
import * as consoleMenuActions from '../console_menu_actions';
|
||||
import { Editor } from './editor';
|
||||
|
||||
|
@ -40,7 +40,7 @@ describe('Legacy (Ace) Console Editor Component Smoke Test', () => {
|
|||
<I18nProvider>
|
||||
<ServicesContextProvider value={mockedAppContextValue}>
|
||||
<RequestContextProvider>
|
||||
<EditorContextProvider settings={{} as any}>
|
||||
<EditorContextProvider settings={({} as unknown) as DevToolsSettings}>
|
||||
<Editor initialTextValue="" />
|
||||
</EditorContextProvider>
|
||||
</RequestContextProvider>
|
||||
|
|
|
@ -229,7 +229,7 @@ function EditorUI({ initialTextValue }: EditorProps) {
|
|||
getDocumentation={() => {
|
||||
return getDocumentation(editorInstanceRef.current!, docLinkVersion);
|
||||
}}
|
||||
autoIndent={(event: any) => {
|
||||
autoIndent={(event) => {
|
||||
autoIndent(editorInstanceRef.current!, event);
|
||||
}}
|
||||
addNotification={({ title }) => notifications.toasts.add({ title })}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { getEndpointFromPosition } from '../../../../lib/autocomplete/get_endpoint_from_position';
|
||||
import { SenseEditor } from '../../../models/sense_editor';
|
||||
|
||||
export async function autoIndent(editor: SenseEditor, event: Event) {
|
||||
export async function autoIndent(editor: SenseEditor, event: React.MouseEvent) {
|
||||
event.preventDefault();
|
||||
await editor.autoIndent();
|
||||
editor.getCoreEditor().getContainer().focus();
|
||||
|
|
|
@ -15,14 +15,20 @@ import { retrieveAutoCompleteInfo } from '../../lib/mappings/mappings';
|
|||
import { useServicesContext, useEditorActionContext } from '../contexts';
|
||||
import { DevToolsSettings, Settings as SettingsService } from '../../services';
|
||||
|
||||
const getAutocompleteDiff = (newSettings: DevToolsSettings, prevSettings: DevToolsSettings) => {
|
||||
const getAutocompleteDiff = (
|
||||
newSettings: DevToolsSettings,
|
||||
prevSettings: DevToolsSettings
|
||||
): AutocompleteOptions[] => {
|
||||
return Object.keys(newSettings.autocomplete).filter((key) => {
|
||||
// @ts-ignore
|
||||
return prevSettings.autocomplete[key] !== newSettings.autocomplete[key];
|
||||
});
|
||||
}) as AutocompleteOptions[];
|
||||
};
|
||||
|
||||
const refreshAutocompleteSettings = (settings: SettingsService, selectedSettings: any) => {
|
||||
const refreshAutocompleteSettings = (
|
||||
settings: SettingsService,
|
||||
selectedSettings: DevToolsSettings['autocomplete']
|
||||
) => {
|
||||
retrieveAutoCompleteInfo(settings, selectedSettings);
|
||||
};
|
||||
|
||||
|
@ -44,12 +50,12 @@ const fetchAutocompleteSettingsIfNeeded = (
|
|||
if (isSettingsChanged) {
|
||||
// If the user has changed one of the autocomplete settings, then we'll fetch just the
|
||||
// ones which have changed.
|
||||
const changedSettings: any = autocompleteDiff.reduce(
|
||||
(changedSettingsAccum: any, setting: string): any => {
|
||||
changedSettingsAccum[setting] = newSettings.autocomplete[setting as AutocompleteOptions];
|
||||
const changedSettings: DevToolsSettings['autocomplete'] = autocompleteDiff.reduce(
|
||||
(changedSettingsAccum, setting) => {
|
||||
changedSettingsAccum[setting] = newSettings.autocomplete[setting];
|
||||
return changedSettingsAccum;
|
||||
},
|
||||
{}
|
||||
{} as DevToolsSettings['autocomplete']
|
||||
);
|
||||
retrieveAutoCompleteInfo(settings, changedSettings);
|
||||
} else if (isPollingChanged && newSettings.polling) {
|
||||
|
@ -89,7 +95,7 @@ export function Settings({ onClose }: Props) {
|
|||
<DevToolsSettingsModal
|
||||
onClose={onClose}
|
||||
onSaveSettings={onSaveSettings}
|
||||
refreshAutocompleteSettings={(selectedSettings: any) =>
|
||||
refreshAutocompleteSettings={(selectedSettings) =>
|
||||
refreshAutocompleteSettings(settings, selectedSettings)
|
||||
}
|
||||
settings={settings.toJSON()}
|
||||
|
|
|
@ -11,11 +11,11 @@ import * as editor from '../../stores/editor';
|
|||
import { DevToolsSettings } from '../../../services';
|
||||
import { createUseContext } from '../create_use_context';
|
||||
|
||||
const EditorReadContext = createContext<editor.Store>(null as any);
|
||||
const EditorActionContext = createContext<Dispatch<editor.Action>>(null as any);
|
||||
const EditorReadContext = createContext<editor.Store>(editor.initialValue);
|
||||
const EditorActionContext = createContext<Dispatch<editor.Action>>(() => {});
|
||||
|
||||
export interface EditorContextArgs {
|
||||
children: any;
|
||||
children: JSX.Element;
|
||||
settings: DevToolsSettings;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ export function EditorContextProvider({ children, settings }: EditorContextArgs)
|
|||
settings,
|
||||
}));
|
||||
return (
|
||||
<EditorReadContext.Provider value={state as any}>
|
||||
<EditorReadContext.Provider value={state}>
|
||||
<EditorActionContext.Provider value={dispatch}>{children}</EditorActionContext.Provider>
|
||||
</EditorReadContext.Provider>
|
||||
);
|
||||
|
|
|
@ -10,8 +10,8 @@ import React, { createContext, useReducer, Dispatch } from 'react';
|
|||
import { createUseContext } from './create_use_context';
|
||||
import * as store from '../stores/request';
|
||||
|
||||
const RequestReadContext = createContext<store.Store>(null as any);
|
||||
const RequestActionContext = createContext<Dispatch<store.Actions>>(null as any);
|
||||
const RequestReadContext = createContext<store.Store>(store.initialValue);
|
||||
const RequestActionContext = createContext<Dispatch<store.Actions>>(() => {});
|
||||
|
||||
export function RequestContextProvider({ children }: { children: React.ReactNode }) {
|
||||
const [state, dispatch] = useReducer(store.reducer, store.initialValue);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import { notificationServiceMock } from '../../../../../core/public/mocks';
|
||||
import { httpServiceMock } from '../../../../../core/public/mocks';
|
||||
|
||||
import type { ObjectStorageClient } from '../../../common/types';
|
||||
import { HistoryMock } from '../../services/history.mock';
|
||||
import { SettingsMock } from '../../services/settings.mock';
|
||||
import { StorageMock } from '../../services/storage.mock';
|
||||
|
@ -18,7 +19,7 @@ import { ContextValue } from './services_context';
|
|||
|
||||
export const serviceContextMock = {
|
||||
create: (): ContextValue => {
|
||||
const storage = new StorageMock({} as any, 'test');
|
||||
const storage = new StorageMock(({} as unknown) as Storage, 'test');
|
||||
const http = httpServiceMock.createSetupContract();
|
||||
const api = createApi({ http });
|
||||
const esHostService = createEsHostService({ api });
|
||||
|
@ -31,7 +32,7 @@ export const serviceContextMock = {
|
|||
settings: new SettingsMock(storage),
|
||||
history: new HistoryMock(storage),
|
||||
notifications: notificationServiceMock.createSetupContract(),
|
||||
objectStorageClient: {} as any,
|
||||
objectStorageClient: ({} as unknown) as ObjectStorageClient,
|
||||
},
|
||||
docLinkVersion: 'NA',
|
||||
};
|
||||
|
|
|
@ -30,10 +30,10 @@ export interface ContextValue {
|
|||
|
||||
interface ContextProps {
|
||||
value: ContextValue;
|
||||
children: any;
|
||||
children: JSX.Element;
|
||||
}
|
||||
|
||||
const ServicesContext = createContext<ContextValue>(null as any);
|
||||
const ServicesContext = createContext<ContextValue | null>(null);
|
||||
|
||||
export function ServicesContextProvider({ children, value }: ContextProps) {
|
||||
useEffect(() => {
|
||||
|
@ -46,8 +46,8 @@ export function ServicesContextProvider({ children, value }: ContextProps) {
|
|||
|
||||
export const useServicesContext = () => {
|
||||
const context = useContext(ServicesContext);
|
||||
if (context === undefined) {
|
||||
if (context == null) {
|
||||
throw new Error('useServicesContext must be used inside the ServicesContextProvider.');
|
||||
}
|
||||
return context;
|
||||
return context!;
|
||||
};
|
||||
|
|
|
@ -7,12 +7,10 @@
|
|||
*/
|
||||
|
||||
import RowParser from '../../../lib/row_parser';
|
||||
import { ESRequest } from '../../../types';
|
||||
import { SenseEditor } from '../../models/sense_editor';
|
||||
/**
|
||||
* This function is considered legacy and should not be changed or updated before we have editor
|
||||
* interfaces in place (it's using a customized version of Ace directly).
|
||||
*/
|
||||
export function restoreRequestFromHistory(editor: SenseEditor, req: any) {
|
||||
|
||||
export function restoreRequestFromHistory(editor: SenseEditor, req: ESRequest) {
|
||||
const coreEditor = editor.getCoreEditor();
|
||||
let pos = coreEditor.getCurrentPosition();
|
||||
let prefix = '';
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
import { useCallback } from 'react';
|
||||
import { instance as registry } from '../../contexts/editor_context/editor_registry';
|
||||
import { ESRequest } from '../../../types';
|
||||
import { restoreRequestFromHistory } from './restore_request_from_history';
|
||||
|
||||
export const useRestoreRequestFromHistory = () => {
|
||||
return useCallback((req: any) => {
|
||||
return useCallback((req: ESRequest) => {
|
||||
const editor = registry.getInputEditor();
|
||||
restoreRequestFromHistory(editor, req);
|
||||
}, []);
|
||||
|
|
|
@ -8,19 +8,14 @@
|
|||
|
||||
import { extractWarningMessages } from '../../../lib/utils';
|
||||
import { XJson } from '../../../../../es_ui_shared/public';
|
||||
const { collapseLiteralStrings } = XJson;
|
||||
// @ts-ignore
|
||||
import * as es from '../../../lib/es/es';
|
||||
import { BaseResponseType } from '../../../types';
|
||||
|
||||
export interface EsRequestArgs {
|
||||
requests: any;
|
||||
}
|
||||
const { collapseLiteralStrings } = XJson;
|
||||
|
||||
export interface ESRequestObject {
|
||||
path: string;
|
||||
data: any;
|
||||
method: string;
|
||||
export interface EsRequestArgs {
|
||||
requests: Array<{ url: string; method: string; data: string[] }>;
|
||||
}
|
||||
|
||||
export interface ESResponseObject<V = unknown> {
|
||||
|
@ -32,7 +27,7 @@ export interface ESResponseObject<V = unknown> {
|
|||
}
|
||||
|
||||
export interface ESRequestResult<V = unknown> {
|
||||
request: ESRequestObject;
|
||||
request: { data: string; method: string; path: string };
|
||||
response: ESResponseObject<V>;
|
||||
}
|
||||
|
||||
|
@ -61,7 +56,7 @@ export function sendRequestToES(args: EsRequestArgs): Promise<ESRequestResult[]>
|
|||
resolve(results);
|
||||
return;
|
||||
}
|
||||
const req = requests.shift();
|
||||
const req = requests.shift()!;
|
||||
const esPath = req.url;
|
||||
const esMethod = req.method;
|
||||
let esData = collapseLiteralStrings(req.data.join('\n'));
|
||||
|
@ -71,7 +66,7 @@ export function sendRequestToES(args: EsRequestArgs): Promise<ESRequestResult[]>
|
|||
|
||||
const startTime = Date.now();
|
||||
es.send(esMethod, esPath, esData).always(
|
||||
(dataOrjqXHR: any, textStatus: string, jqXhrORerrorThrown: any) => {
|
||||
(dataOrjqXHR, textStatus: string, jqXhrORerrorThrown) => {
|
||||
if (reqId !== CURRENT_REQ_ID) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,11 @@ import { SenseEditor } from '../../models/sense_editor';
|
|||
import { getEndpointFromPosition } from '../../../lib/autocomplete/get_endpoint_from_position';
|
||||
import { MetricsTracker } from '../../../types';
|
||||
|
||||
export const track = (requests: any[], editor: SenseEditor, trackUiMetric: MetricsTracker) => {
|
||||
export const track = (
|
||||
requests: Array<{ method: string }>,
|
||||
editor: SenseEditor,
|
||||
trackUiMetric: MetricsTracker
|
||||
) => {
|
||||
const coreEditor = editor.getCoreEditor();
|
||||
// `getEndpointFromPosition` gets values from the server-side generated JSON files which
|
||||
// are a combination of JS, automatically generated JSON and manual overrides. That means
|
||||
|
|
|
@ -26,8 +26,8 @@ import { useSendCurrentRequestToES } from './use_send_current_request_to_es';
|
|||
|
||||
describe('useSendCurrentRequestToES', () => {
|
||||
let mockContextValue: ContextValue;
|
||||
let dispatch: (...args: any[]) => void;
|
||||
const contexts = ({ children }: { children?: any }) => (
|
||||
let dispatch: (...args: unknown[]) => void;
|
||||
const contexts = ({ children }: { children: JSX.Element }) => (
|
||||
<ServicesContextProvider value={mockContextValue}>{children}</ServicesContextProvider>
|
||||
);
|
||||
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useEditorActionContext } from '../contexts/editor_context';
|
||||
import { instance as registry } from '../contexts/editor_context/editor_registry';
|
||||
import { SenseEditor } from '../models';
|
||||
|
||||
export const useSetInputEditor = () => {
|
||||
const dispatch = useEditorActionContext();
|
||||
|
||||
return useCallback(
|
||||
(editor: any) => {
|
||||
(editor: SenseEditor) => {
|
||||
dispatch({ type: 'setInputEditor', payload: editor });
|
||||
registry.setInputEditor(editor);
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { HttpSetup, NotificationsSetup } from 'src/core/public';
|
||||
import { HttpSetup, NotificationsSetup, I18nStart } from 'src/core/public';
|
||||
import { ServicesContextProvider, EditorContextProvider, RequestContextProvider } from './contexts';
|
||||
import { Main } from './containers';
|
||||
import { createStorage, createHistory, createSettings } from '../services';
|
||||
|
@ -20,7 +20,7 @@ import { createApi, createEsHostService } from './lib';
|
|||
export interface BootDependencies {
|
||||
http: HttpSetup;
|
||||
docLinkVersion: string;
|
||||
I18nContext: any;
|
||||
I18nContext: I18nStart['Context'];
|
||||
notifications: NotificationsSetup;
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
element: HTMLElement;
|
||||
|
|
|
@ -13,7 +13,7 @@ import * as OutputMode from './mode/output';
|
|||
import smartResize from './smart_resize';
|
||||
|
||||
export interface CustomAceEditor extends ace.Editor {
|
||||
update: (text: string, mode?: any, cb?: () => void) => void;
|
||||
update: (text: string, mode?: unknown, cb?: () => void) => void;
|
||||
append: (text: string, foldPrevious?: boolean, cb?: () => void) => void;
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,9 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor {
|
|||
|
||||
output.$blockScrolling = Infinity;
|
||||
output.resize = smartResize(output);
|
||||
output.update = (val: string, mode?: any, cb?: () => void) => {
|
||||
output.update = (val: string, mode?: unknown, cb?: () => void) => {
|
||||
if (typeof mode === 'function') {
|
||||
cb = mode;
|
||||
cb = mode as () => void;
|
||||
mode = void 0;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor {
|
|||
|
||||
(function setupSession(session) {
|
||||
session.setMode('ace/mode/text');
|
||||
(session as any).setFoldStyle('markbeginend');
|
||||
((session as unknown) as { setFoldStyle: (v: string) => void }).setFoldStyle('markbeginend');
|
||||
session.setTabSize(2);
|
||||
session.setUseWrapMode(true);
|
||||
})(output.getSession());
|
||||
|
|
|
@ -13,7 +13,7 @@ jest.mock('./mode/worker', () => {
|
|||
// @ts-ignore
|
||||
window.Worker = function () {
|
||||
this.postMessage = () => {};
|
||||
(this as any).terminate = () => {};
|
||||
((this as unknown) as { terminate: () => void }).terminate = () => {};
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
|
|
|
@ -31,8 +31,8 @@ const rangeToAceRange = ({ start, end }: Range) =>
|
|||
new _AceRange(start.lineNumber - 1, start.column - 1, end.lineNumber - 1, end.column - 1);
|
||||
|
||||
export class LegacyCoreEditor implements CoreEditor {
|
||||
private _aceOnPaste: any;
|
||||
$actions: any;
|
||||
private _aceOnPaste: Function;
|
||||
$actions: JQuery<HTMLElement>;
|
||||
resize: () => void;
|
||||
|
||||
constructor(private readonly editor: IAceEditor, actions: HTMLElement) {
|
||||
|
@ -41,7 +41,9 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
|
||||
const session = this.editor.getSession();
|
||||
session.setMode(new InputMode.Mode());
|
||||
(session as any).setFoldStyle('markbeginend');
|
||||
((session as unknown) as { setFoldStyle: (style: string) => void }).setFoldStyle(
|
||||
'markbeginend'
|
||||
);
|
||||
session.setTabSize(2);
|
||||
session.setUseWrapMode(true);
|
||||
|
||||
|
@ -72,7 +74,7 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
// torn down, e.g. by closing the History tab, and we don't need to do anything further.
|
||||
if (session.bgTokenizer) {
|
||||
// Wait until the bgTokenizer is done running before executing the callback.
|
||||
if ((session.bgTokenizer as any).running) {
|
||||
if (((session.bgTokenizer as unknown) as { running: boolean }).running) {
|
||||
setTimeout(check, checkInterval);
|
||||
} else {
|
||||
resolve();
|
||||
|
@ -197,7 +199,7 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
.addMarker(rangeToAceRange(range), 'ace_snippet-marker', 'fullLine', false);
|
||||
}
|
||||
|
||||
removeMarker(ref: any) {
|
||||
removeMarker(ref: number) {
|
||||
this.editor.getSession().removeMarker(ref);
|
||||
}
|
||||
|
||||
|
@ -222,8 +224,10 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
}
|
||||
|
||||
isCompleterActive() {
|
||||
// Secrets of the arcane here.
|
||||
return Boolean((this.editor as any).completer && (this.editor as any).completer.activated);
|
||||
return Boolean(
|
||||
((this.editor as unknown) as { completer: { activated: unknown } }).completer &&
|
||||
((this.editor as unknown) as { completer: { activated: unknown } }).completer.activated
|
||||
);
|
||||
}
|
||||
|
||||
private forceRetokenize() {
|
||||
|
@ -250,7 +254,7 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
this._aceOnPaste.call(this.editor, text);
|
||||
}
|
||||
|
||||
private setActionsBar = (value?: any, topOrBottom: 'top' | 'bottom' = 'top') => {
|
||||
private setActionsBar = (value: number | null, topOrBottom: 'top' | 'bottom' = 'top') => {
|
||||
if (value === null) {
|
||||
this.$actions.css('visibility', 'hidden');
|
||||
} else {
|
||||
|
@ -271,7 +275,7 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
};
|
||||
|
||||
private hideActionsBar = () => {
|
||||
this.setActionsBar();
|
||||
this.setActionsBar(null);
|
||||
};
|
||||
|
||||
execCommand(cmd: string) {
|
||||
|
@ -295,7 +299,7 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
});
|
||||
}
|
||||
|
||||
legacyUpdateUI(range: any) {
|
||||
legacyUpdateUI(range: Range) {
|
||||
if (!this.$actions) {
|
||||
return;
|
||||
}
|
||||
|
@ -360,14 +364,19 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
ace.define(
|
||||
'ace/autocomplete/text_completer',
|
||||
['require', 'exports', 'module'],
|
||||
function (require: any, exports: any) {
|
||||
exports.getCompletions = function (
|
||||
innerEditor: any,
|
||||
session: any,
|
||||
pos: any,
|
||||
prefix: any,
|
||||
callback: any
|
||||
) {
|
||||
function (
|
||||
require: unknown,
|
||||
exports: {
|
||||
getCompletions: (
|
||||
innerEditor: unknown,
|
||||
session: unknown,
|
||||
pos: unknown,
|
||||
prefix: unknown,
|
||||
callback: (e: null | Error, values: string[]) => void
|
||||
) => void;
|
||||
}
|
||||
) {
|
||||
exports.getCompletions = function (innerEditor, session, pos, prefix, callback) {
|
||||
callback(null, []);
|
||||
};
|
||||
}
|
||||
|
@ -387,7 +396,7 @@ export class LegacyCoreEditor implements CoreEditor {
|
|||
DO_NOT_USE_2: IAceEditSession,
|
||||
pos: { row: number; column: number },
|
||||
prefix: string,
|
||||
callback: (...args: any[]) => void
|
||||
callback: (...args: unknown[]) => void
|
||||
) => {
|
||||
const position: Position = {
|
||||
lineNumber: pos.row + 1,
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
*/
|
||||
|
||||
import { get, throttle } from 'lodash';
|
||||
import type { Editor } from 'brace';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function (editor: any) {
|
||||
export default function (editor: Editor) {
|
||||
const resize = editor.resize;
|
||||
|
||||
const throttledResize = throttle(() => {
|
||||
|
|
|
@ -25,7 +25,7 @@ export function detectCURL(text: string) {
|
|||
export function parseCURL(text: string) {
|
||||
let state = 'NONE';
|
||||
const out = [];
|
||||
let body: any[] = [];
|
||||
let body: string[] = [];
|
||||
let line = '';
|
||||
const lines = text.trim().split('\n');
|
||||
let matches;
|
||||
|
@ -62,7 +62,7 @@ export function parseCURL(text: string) {
|
|||
}
|
||||
|
||||
function unescapeLastBodyEl() {
|
||||
const str = body.pop().replace(/\\([\\"'])/g, '$1');
|
||||
const str = body.pop()!.replace(/\\([\\"'])/g, '$1');
|
||||
body.push(str);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import RowParser from '../../../lib/row_parser';
|
||||
|
||||
import { XJson } from '../../../../../es_ui_shared/public';
|
||||
|
||||
import RowParser from '../../../lib/row_parser';
|
||||
import * as utils from '../../../lib/utils';
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -16,22 +18,20 @@ import * as es from '../../../lib/es/es';
|
|||
|
||||
import { CoreEditor, Position, Range } from '../../../types';
|
||||
import { createTokenIterator } from '../../factories';
|
||||
|
||||
import Autocomplete from '../../../lib/autocomplete/autocomplete';
|
||||
import createAutocompleter from '../../../lib/autocomplete/autocomplete';
|
||||
|
||||
const { collapseLiteralStrings } = XJson;
|
||||
|
||||
export class SenseEditor {
|
||||
currentReqRange: (Range & { markerRef: any }) | null;
|
||||
parser: any;
|
||||
currentReqRange: (Range & { markerRef: unknown }) | null;
|
||||
parser: RowParser;
|
||||
|
||||
// @ts-ignore
|
||||
private readonly autocomplete: any;
|
||||
private readonly autocomplete: ReturnType<typeof createAutocompleter>;
|
||||
|
||||
constructor(private readonly coreEditor: CoreEditor) {
|
||||
this.currentReqRange = null;
|
||||
this.parser = new RowParser(this.coreEditor);
|
||||
this.autocomplete = new (Autocomplete as any)({
|
||||
this.autocomplete = createAutocompleter({
|
||||
coreEditor,
|
||||
parser: this.parser,
|
||||
});
|
||||
|
@ -114,7 +114,10 @@ export class SenseEditor {
|
|||
return this.coreEditor.setValue(data, reTokenizeAll);
|
||||
};
|
||||
|
||||
replaceRequestRange = (newRequest: any, requestRange: Range) => {
|
||||
replaceRequestRange = (
|
||||
newRequest: { method: string; url: string; data: string | string[] },
|
||||
requestRange: Range
|
||||
) => {
|
||||
const text = utils.textFromRequest(newRequest);
|
||||
if (requestRange) {
|
||||
this.coreEditor.replaceRange(requestRange, text);
|
||||
|
@ -207,12 +210,12 @@ export class SenseEditor {
|
|||
const request: {
|
||||
method: string;
|
||||
data: string[];
|
||||
url: string | null;
|
||||
url: string;
|
||||
range: Range;
|
||||
} = {
|
||||
method: '',
|
||||
data: [],
|
||||
url: null,
|
||||
url: '',
|
||||
range,
|
||||
};
|
||||
|
||||
|
@ -284,7 +287,7 @@ export class SenseEditor {
|
|||
return [];
|
||||
}
|
||||
|
||||
const requests: any = [];
|
||||
const requests: unknown[] = [];
|
||||
|
||||
let rangeStartCursor = expandedRange.start.lineNumber;
|
||||
const endLineNumber = expandedRange.end.lineNumber;
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
import { Reducer } from 'react';
|
||||
import { produce } from 'immer';
|
||||
import { identity } from 'fp-ts/lib/function';
|
||||
import { DevToolsSettings } from '../../services';
|
||||
import { DevToolsSettings, DEFAULT_SETTINGS } from '../../services';
|
||||
import { TextObject } from '../../../common/text_object';
|
||||
import { SenseEditor } from '../models';
|
||||
|
||||
export interface Store {
|
||||
ready: boolean;
|
||||
|
@ -21,15 +22,15 @@ export interface Store {
|
|||
export const initialValue: Store = produce<Store>(
|
||||
{
|
||||
ready: false,
|
||||
settings: null as any,
|
||||
settings: DEFAULT_SETTINGS,
|
||||
currentTextObject: null,
|
||||
},
|
||||
identity
|
||||
);
|
||||
|
||||
export type Action =
|
||||
| { type: 'setInputEditor'; payload: any }
|
||||
| { type: 'setCurrentTextObject'; payload: any }
|
||||
| { type: 'setInputEditor'; payload: SenseEditor }
|
||||
| { type: 'setCurrentTextObject'; payload: TextObject }
|
||||
| { type: 'updateSettings'; payload: DevToolsSettings };
|
||||
|
||||
export const reducer: Reducer<Store, Action> = (state, action) =>
|
||||
|
|
|
@ -63,7 +63,7 @@ export class AceTokensProvider implements TokensProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
const tokens: TokenInfo[] = this.session.getTokens(lineNumber - 1) as any;
|
||||
const tokens = (this.session.getTokens(lineNumber - 1) as unknown) as TokenInfo[];
|
||||
if (!tokens || !tokens.length) {
|
||||
// We are inside of the document but have no tokens for this line. Return an empty
|
||||
// array to represent this empty line.
|
||||
|
@ -74,7 +74,7 @@ export class AceTokensProvider implements TokensProvider {
|
|||
}
|
||||
|
||||
getTokenAt(pos: Position): Token | null {
|
||||
const tokens: TokenInfo[] = this.session.getTokens(pos.lineNumber - 1) as any;
|
||||
const tokens = (this.session.getTokens(pos.lineNumber - 1) as unknown) as TokenInfo[];
|
||||
if (tokens) {
|
||||
return extractTokenFromAceTokenRow(pos.lineNumber, pos.column, tokens);
|
||||
}
|
||||
|
|
|
@ -18,19 +18,21 @@ import {
|
|||
// @ts-ignore
|
||||
} from '../kb/kb';
|
||||
|
||||
import { createTokenIterator } from '../../application/factories';
|
||||
import { Position, Token, Range, CoreEditor } from '../../types';
|
||||
import type RowParser from '../row_parser';
|
||||
|
||||
import * as utils from '../utils';
|
||||
|
||||
// @ts-ignore
|
||||
import { populateContext } from './engine';
|
||||
import { AutoCompleteContext, ResultTerm } from './types';
|
||||
// @ts-ignore
|
||||
import { URL_PATH_END_MARKER } from './components/index';
|
||||
import { createTokenIterator } from '../../application/factories';
|
||||
|
||||
import { Position, Token, Range, CoreEditor } from '../../types';
|
||||
let lastEvaluatedToken: Token | null = null;
|
||||
|
||||
let lastEvaluatedToken: any = null;
|
||||
|
||||
function isUrlParamsToken(token: any) {
|
||||
function isUrlParamsToken(token: { type: string } | null) {
|
||||
switch ((token || {}).type) {
|
||||
case 'url.param':
|
||||
case 'url.equal':
|
||||
|
@ -54,7 +56,7 @@ function isUrlParamsToken(token: any) {
|
|||
export function getCurrentMethodAndTokenPaths(
|
||||
editor: CoreEditor,
|
||||
pos: Position,
|
||||
parser: any,
|
||||
parser: RowParser,
|
||||
forceEndOfUrl?: boolean /* Flag for indicating whether we want to avoid early escape optimization. */
|
||||
) {
|
||||
const tokenIter = createTokenIterator({
|
||||
|
@ -62,8 +64,8 @@ export function getCurrentMethodAndTokenPaths(
|
|||
position: pos,
|
||||
});
|
||||
const startPos = pos;
|
||||
let bodyTokenPath: any = [];
|
||||
const ret: any = {};
|
||||
let bodyTokenPath: string[] | null = [];
|
||||
const ret: AutoCompleteContext = {};
|
||||
|
||||
const STATES = {
|
||||
looking_for_key: 0, // looking for a key but without jumping over anything but white space and colon.
|
||||
|
@ -210,7 +212,12 @@ export function getCurrentMethodAndTokenPaths(
|
|||
|
||||
ret.urlParamsTokenPath = null;
|
||||
ret.requestStartRow = tokenIter.getCurrentPosition().lineNumber;
|
||||
let curUrlPart: any;
|
||||
let curUrlPart:
|
||||
| null
|
||||
| string
|
||||
| Array<string | Record<string, unknown>>
|
||||
| undefined
|
||||
| Record<string, unknown>;
|
||||
|
||||
while (t && isUrlParamsToken(t)) {
|
||||
switch (t.type) {
|
||||
|
@ -240,7 +247,7 @@ export function getCurrentMethodAndTokenPaths(
|
|||
if (!ret.urlParamsTokenPath) {
|
||||
ret.urlParamsTokenPath = [];
|
||||
}
|
||||
ret.urlParamsTokenPath.unshift(curUrlPart || {});
|
||||
ret.urlParamsTokenPath.unshift((curUrlPart as Record<string, string>) || {});
|
||||
curUrlPart = null;
|
||||
break;
|
||||
}
|
||||
|
@ -268,7 +275,7 @@ export function getCurrentMethodAndTokenPaths(
|
|||
break;
|
||||
case 'url.slash':
|
||||
if (curUrlPart) {
|
||||
ret.urlTokenPath.unshift(curUrlPart);
|
||||
ret.urlTokenPath.unshift(curUrlPart as string);
|
||||
curUrlPart = null;
|
||||
}
|
||||
break;
|
||||
|
@ -277,7 +284,7 @@ export function getCurrentMethodAndTokenPaths(
|
|||
}
|
||||
|
||||
if (curUrlPart) {
|
||||
ret.urlTokenPath.unshift(curUrlPart);
|
||||
ret.urlTokenPath.unshift(curUrlPart as string);
|
||||
}
|
||||
|
||||
if (!ret.bodyTokenPath && !ret.urlParamsTokenPath) {
|
||||
|
@ -297,9 +304,15 @@ export function getCurrentMethodAndTokenPaths(
|
|||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEditor; parser: any }) {
|
||||
export default function ({
|
||||
coreEditor: editor,
|
||||
parser,
|
||||
}: {
|
||||
coreEditor: CoreEditor;
|
||||
parser: RowParser;
|
||||
}) {
|
||||
function isUrlPathToken(token: Token | null) {
|
||||
switch ((token || ({} as any)).type) {
|
||||
switch ((token || ({} as Token)).type) {
|
||||
case 'url.slash':
|
||||
case 'url.comma':
|
||||
case 'url.part':
|
||||
|
@ -309,8 +322,12 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}
|
||||
}
|
||||
|
||||
function addMetaToTermsList(list: any, meta: any, template?: string) {
|
||||
return _.map(list, function (t: any) {
|
||||
function addMetaToTermsList(
|
||||
list: unknown[],
|
||||
meta: unknown,
|
||||
template?: string
|
||||
): Array<{ meta: unknown; template: unknown; name?: string }> {
|
||||
return _.map(list, function (t) {
|
||||
if (typeof t !== 'object') {
|
||||
t = { name: t };
|
||||
}
|
||||
|
@ -318,8 +335,13 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
});
|
||||
}
|
||||
|
||||
function applyTerm(term: any) {
|
||||
const context = term.context;
|
||||
function applyTerm(term: {
|
||||
value?: string;
|
||||
context?: AutoCompleteContext;
|
||||
template?: { __raw: boolean; value: string };
|
||||
insertValue?: string;
|
||||
}) {
|
||||
const context = term.context!;
|
||||
|
||||
// make sure we get up to date replacement info.
|
||||
addReplacementInfoToContext(context, editor.getCurrentPosition(), term.insertValue);
|
||||
|
@ -346,7 +368,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
} else {
|
||||
indentedTemplateLines = utils.jsonToString(term.template, true).split('\n');
|
||||
}
|
||||
let currentIndentation = editor.getLineValue(context.rangeToReplace.start.lineNumber);
|
||||
let currentIndentation = editor.getLineValue(context.rangeToReplace!.start.lineNumber);
|
||||
currentIndentation = currentIndentation.match(/^\s*/)![0];
|
||||
for (
|
||||
let i = 1;
|
||||
|
@ -374,8 +396,8 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
// disable listening to the changes we are making.
|
||||
editor.off('changeSelection', editorChangeListener);
|
||||
|
||||
if (context.rangeToReplace.start.column !== context.rangeToReplace.end.column) {
|
||||
editor.replace(context.rangeToReplace, valueToInsert);
|
||||
if (context.rangeToReplace!.start.column !== context.rangeToReplace!.end.column) {
|
||||
editor.replace(context.rangeToReplace!, valueToInsert);
|
||||
} else {
|
||||
editor.insert(valueToInsert);
|
||||
}
|
||||
|
@ -384,12 +406,12 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
|
||||
// go back to see whether we have one of ( : { & [ do not require a comma. All the rest do.
|
||||
let newPos = {
|
||||
lineNumber: context.rangeToReplace.start.lineNumber,
|
||||
lineNumber: context.rangeToReplace!.start.lineNumber,
|
||||
column:
|
||||
context.rangeToReplace.start.column +
|
||||
context.rangeToReplace!.start.column +
|
||||
termAsString.length +
|
||||
context.prefixToAdd.length +
|
||||
(templateInserted ? 0 : context.suffixToAdd.length),
|
||||
context.prefixToAdd!.length +
|
||||
(templateInserted ? 0 : context.suffixToAdd!.length),
|
||||
};
|
||||
|
||||
const tokenIter = createTokenIterator({
|
||||
|
@ -406,7 +428,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
break;
|
||||
case 'punctuation.colon':
|
||||
nonEmptyToken = parser.nextNonEmptyToken(tokenIter);
|
||||
if ((nonEmptyToken || ({} as any)).type === 'paren.lparen') {
|
||||
if ((nonEmptyToken || ({} as Token)).type === 'paren.lparen') {
|
||||
nonEmptyToken = parser.nextNonEmptyToken(tokenIter);
|
||||
newPos = tokenIter.getCurrentPosition();
|
||||
if (nonEmptyToken && nonEmptyToken.value.indexOf('"') === 0) {
|
||||
|
@ -429,7 +451,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
|
||||
function getAutoCompleteContext(ctxEditor: CoreEditor, pos: Position) {
|
||||
// deduces all the parameters need to position and insert the auto complete
|
||||
const context: any = {
|
||||
const context: AutoCompleteContext = {
|
||||
autoCompleteSet: null, // instructions for what can be here
|
||||
endpoint: null,
|
||||
urlPath: null,
|
||||
|
@ -501,7 +523,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
case 'whitespace':
|
||||
t = parser.prevNonEmptyToken(tokenIter);
|
||||
|
||||
switch ((t || ({} as any)).type) {
|
||||
switch ((t || ({} as Token)).type) {
|
||||
case 'method':
|
||||
// we moved one back
|
||||
return 'path';
|
||||
|
@ -552,7 +574,11 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
return null;
|
||||
}
|
||||
|
||||
function addReplacementInfoToContext(context: any, pos: Position, replacingTerm?: any) {
|
||||
function addReplacementInfoToContext(
|
||||
context: AutoCompleteContext,
|
||||
pos: Position,
|
||||
replacingTerm?: unknown
|
||||
) {
|
||||
// extract the initial value, rangeToReplace & textBoxPosition
|
||||
|
||||
// Scenarios for current token:
|
||||
|
@ -605,7 +631,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
default:
|
||||
if (replacingTerm && context.updatedForToken.value === replacingTerm) {
|
||||
context.rangeToReplace = {
|
||||
start: { lineNumber: pos.lineNumber, column: anchorToken.column },
|
||||
start: { lineNumber: pos.lineNumber, column: anchorToken.position.column },
|
||||
end: {
|
||||
lineNumber: pos.lineNumber,
|
||||
column:
|
||||
|
@ -645,7 +671,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}
|
||||
}
|
||||
|
||||
function addBodyPrefixSuffixToContext(context: any) {
|
||||
function addBodyPrefixSuffixToContext(context: AutoCompleteContext) {
|
||||
// Figure out what happens next to the token to see whether it needs trailing commas etc.
|
||||
|
||||
// Templates will be used if not destroying existing structure.
|
||||
|
@ -680,9 +706,9 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}
|
||||
context.addTemplate = true;
|
||||
// extend range to replace to include all up to token
|
||||
context.rangeToReplace.end.lineNumber = tokenIter.getCurrentTokenLineNumber();
|
||||
context.rangeToReplace.end.column =
|
||||
tokenIter.getCurrentTokenColumn() + nonEmptyToken.value.length;
|
||||
context.rangeToReplace!.end.lineNumber = tokenIter.getCurrentTokenLineNumber() as number;
|
||||
context.rangeToReplace!.end.column =
|
||||
(tokenIter.getCurrentTokenColumn() as number) + nonEmptyToken.value.length;
|
||||
|
||||
// move one more time to check if we need a trailing comma
|
||||
nonEmptyToken = parser.nextNonEmptyToken(tokenIter);
|
||||
|
@ -711,11 +737,11 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
insertingRelativeToToken = 0;
|
||||
} else {
|
||||
const pos = editor.getCurrentPosition();
|
||||
if (pos.column === context.updatedForToken.position.column) {
|
||||
if (pos.column === context.updatedForToken!.position.column) {
|
||||
insertingRelativeToToken = -1;
|
||||
} else if (
|
||||
pos.column <
|
||||
context.updatedForToken.position.column + context.updatedForToken.value.length
|
||||
context.updatedForToken!.position.column + context.updatedForToken!.value.length
|
||||
) {
|
||||
insertingRelativeToToken = 0;
|
||||
} else {
|
||||
|
@ -743,12 +769,12 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
return context;
|
||||
}
|
||||
|
||||
function addUrlParamsPrefixSuffixToContext(context: any) {
|
||||
function addUrlParamsPrefixSuffixToContext(context: AutoCompleteContext) {
|
||||
context.prefixToAdd = '';
|
||||
context.suffixToAdd = '';
|
||||
}
|
||||
|
||||
function addMethodPrefixSuffixToContext(context: any) {
|
||||
function addMethodPrefixSuffixToContext(context: AutoCompleteContext) {
|
||||
context.prefixToAdd = '';
|
||||
context.suffixToAdd = '';
|
||||
const tokenIter = createTokenIterator({ editor, position: editor.getCurrentPosition() });
|
||||
|
@ -761,12 +787,12 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}
|
||||
}
|
||||
|
||||
function addPathPrefixSuffixToContext(context: any) {
|
||||
function addPathPrefixSuffixToContext(context: AutoCompleteContext) {
|
||||
context.prefixToAdd = '';
|
||||
context.suffixToAdd = '';
|
||||
}
|
||||
|
||||
function addMethodAutoCompleteSetToContext(context: any) {
|
||||
function addMethodAutoCompleteSetToContext(context: AutoCompleteContext) {
|
||||
context.autoCompleteSet = ['GET', 'PUT', 'POST', 'DELETE', 'HEAD'].map((m, i) => ({
|
||||
name: m,
|
||||
score: -i,
|
||||
|
@ -774,7 +800,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}));
|
||||
}
|
||||
|
||||
function addPathAutoCompleteSetToContext(context: any, pos: Position) {
|
||||
function addPathAutoCompleteSetToContext(context: AutoCompleteContext, pos: Position) {
|
||||
const ret = getCurrentMethodAndTokenPaths(editor, pos, parser);
|
||||
context.method = ret.method;
|
||||
context.token = ret.token;
|
||||
|
@ -783,10 +809,10 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
const components = getTopLevelUrlCompleteComponents(context.method);
|
||||
populateContext(ret.urlTokenPath, context, editor, true, components);
|
||||
|
||||
context.autoCompleteSet = addMetaToTermsList(context.autoCompleteSet, 'endpoint');
|
||||
context.autoCompleteSet = addMetaToTermsList(context.autoCompleteSet!, 'endpoint');
|
||||
}
|
||||
|
||||
function addUrlParamsAutoCompleteSetToContext(context: any, pos: Position) {
|
||||
function addUrlParamsAutoCompleteSetToContext(context: AutoCompleteContext, pos: Position) {
|
||||
const ret = getCurrentMethodAndTokenPaths(editor, pos, parser);
|
||||
context.method = ret.method;
|
||||
context.otherTokenValues = ret.otherTokenValues;
|
||||
|
@ -813,7 +839,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
// zero length tokenPath is true
|
||||
return context;
|
||||
}
|
||||
let tokenPath: any[] = [];
|
||||
let tokenPath: string[] = [];
|
||||
const currentParam = ret.urlParamsTokenPath.pop();
|
||||
if (currentParam) {
|
||||
tokenPath = Object.keys(currentParam); // single key object
|
||||
|
@ -830,7 +856,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
return context;
|
||||
}
|
||||
|
||||
function addBodyAutoCompleteSetToContext(context: any, pos: Position) {
|
||||
function addBodyAutoCompleteSetToContext(context: AutoCompleteContext, pos: Position) {
|
||||
const ret = getCurrentMethodAndTokenPaths(editor, pos, parser);
|
||||
context.method = ret.method;
|
||||
context.otherTokenValues = ret.otherTokenValues;
|
||||
|
@ -859,7 +885,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
// needed for scope linking + global term resolving
|
||||
context.endpointComponentResolver = getEndpointBodyCompleteComponents;
|
||||
context.globalComponentResolver = getGlobalAutocompleteComponents;
|
||||
let components;
|
||||
let components: unknown;
|
||||
if (context.endpoint) {
|
||||
components = context.endpoint.bodyAutocompleteRootComponents;
|
||||
} else {
|
||||
|
@ -935,15 +961,19 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}
|
||||
}
|
||||
|
||||
function getCompletions(position: Position, prefix: string, callback: (...args: any[]) => void) {
|
||||
function getCompletions(
|
||||
position: Position,
|
||||
prefix: string,
|
||||
callback: (e: Error | null, result: ResultTerm[] | null) => void
|
||||
) {
|
||||
try {
|
||||
const context = getAutoCompleteContext(editor, position);
|
||||
if (!context) {
|
||||
callback(null, []);
|
||||
} else {
|
||||
const terms = _.map(
|
||||
context.autoCompleteSet.filter((term: any) => Boolean(term) && term.name != null),
|
||||
function (term: any) {
|
||||
context.autoCompleteSet!.filter((term) => Boolean(term) && term.name != null),
|
||||
function (term) {
|
||||
if (typeof term !== 'object') {
|
||||
term = {
|
||||
name: term,
|
||||
|
@ -951,7 +981,13 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
} else {
|
||||
term = _.clone(term);
|
||||
}
|
||||
const defaults: any = {
|
||||
const defaults: {
|
||||
value?: string;
|
||||
meta: string;
|
||||
score: number;
|
||||
context: AutoCompleteContext;
|
||||
completer?: { insertMatch: (v: unknown) => void };
|
||||
} = {
|
||||
value: term.name,
|
||||
meta: 'API',
|
||||
score: 0,
|
||||
|
@ -969,7 +1005,10 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
}
|
||||
);
|
||||
|
||||
terms.sort(function (t1: any, t2: any) {
|
||||
terms.sort(function (
|
||||
t1: { score: number; name?: string },
|
||||
t2: { score: number; name?: string }
|
||||
) {
|
||||
/* score sorts from high to low */
|
||||
if (t1.score > t2.score) {
|
||||
return -1;
|
||||
|
@ -978,7 +1017,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
return 1;
|
||||
}
|
||||
/* names sort from low to high */
|
||||
if (t1.name < t2.name) {
|
||||
if (t1.name! < t2.name!) {
|
||||
return -1;
|
||||
}
|
||||
if (t1.name === t2.name) {
|
||||
|
@ -989,7 +1028,7 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
|
||||
callback(
|
||||
null,
|
||||
_.map(terms, function (t: any, i: any) {
|
||||
_.map(terms, function (t, i) {
|
||||
t.insertValue = t.insertValue || t.value;
|
||||
t.value = '' + t.value; // normalize to strings
|
||||
t.score = -i;
|
||||
|
@ -1010,8 +1049,13 @@ export default function ({ coreEditor: editor, parser }: { coreEditor: CoreEdito
|
|||
getCompletions,
|
||||
// TODO: This needs to be cleaned up
|
||||
_test: {
|
||||
getCompletions: (_editor: any, _editSession: any, pos: any, prefix: any, callback: any) =>
|
||||
getCompletions(pos, prefix, callback),
|
||||
getCompletions: (
|
||||
_editor: unknown,
|
||||
_editSession: unknown,
|
||||
pos: Position,
|
||||
prefix: string,
|
||||
callback: (e: Error | null, result: ResultTerm[] | null) => void
|
||||
) => getCompletions(pos, prefix, callback),
|
||||
addReplacementInfoToContext,
|
||||
addChangeListener: () => editor.on('changeSelection', editorChangeListener),
|
||||
removeChangeListener: () => editor.off('changeSelection', editorChangeListener),
|
||||
|
|
|
@ -11,7 +11,7 @@ import { ConstantComponent } from './constant_component';
|
|||
|
||||
export class FullRequestComponent extends ConstantComponent {
|
||||
private readonly name: string;
|
||||
constructor(name: string, parent: any, private readonly template: string) {
|
||||
constructor(name: string, parent: unknown, private readonly template: string) {
|
||||
super(name, parent);
|
||||
this.name = name;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
|
||||
import { CoreEditor, Position } from '../../types';
|
||||
import { getCurrentMethodAndTokenPaths } from './autocomplete';
|
||||
import type RowParser from '../row_parser';
|
||||
|
||||
// @ts-ignore
|
||||
import { getTopLevelUrlCompleteComponents } from '../kb/kb';
|
||||
// @ts-ignore
|
||||
import { populateContext } from './engine';
|
||||
|
||||
export function getEndpointFromPosition(editor: CoreEditor, pos: Position, parser: any) {
|
||||
export function getEndpointFromPosition(editor: CoreEditor, pos: Position, parser: RowParser) {
|
||||
const lineValue = editor.getLineValue(pos.lineNumber);
|
||||
const context = {
|
||||
...getCurrentMethodAndTokenPaths(
|
||||
|
|
61
src/plugins/console/public/lib/autocomplete/types.ts
Normal file
61
src/plugins/console/public/lib/autocomplete/types.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { CoreEditor, Range, Token } from '../../types';
|
||||
|
||||
export interface ResultTerm {
|
||||
context?: AutoCompleteContext;
|
||||
insertValue?: string;
|
||||
name?: string;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export interface AutoCompleteContext {
|
||||
autoCompleteSet?: null | ResultTerm[];
|
||||
endpoint?: null | {
|
||||
paramsAutocomplete: {
|
||||
getTopLevelComponents: (method?: string | null) => unknown;
|
||||
};
|
||||
bodyAutocompleteRootComponents: unknown;
|
||||
id?: string;
|
||||
documentation?: string;
|
||||
};
|
||||
urlPath?: null | unknown;
|
||||
urlParamsTokenPath?: Array<Record<string, string>> | null;
|
||||
method?: string | null;
|
||||
token?: Token;
|
||||
activeScheme?: unknown;
|
||||
replacingToken?: boolean;
|
||||
rangeToReplace?: Range;
|
||||
autoCompleteType?: null | string;
|
||||
editor?: CoreEditor;
|
||||
|
||||
/**
|
||||
* The tokenized user input that prompted the current autocomplete at the cursor. This can be out of sync with
|
||||
* the input that is currently being displayed in the editor.
|
||||
*/
|
||||
createdWithToken?: Token | null;
|
||||
|
||||
/**
|
||||
* The tokenized user input that is currently being displayed at the cursor in the editor when the user accepted
|
||||
* the autocomplete suggestion.
|
||||
*/
|
||||
updatedForToken?: Token | null;
|
||||
|
||||
addTemplate?: unknown;
|
||||
prefixToAdd?: string;
|
||||
suffixToAdd?: string;
|
||||
textBoxPosition?: { lineNumber: number; column: number };
|
||||
urlTokenPath?: string[];
|
||||
otherTokenValues?: string;
|
||||
requestStartRow?: number | null;
|
||||
bodyTokenPath?: string[] | null;
|
||||
endpointComponentResolver?: unknown;
|
||||
globalComponentResolver?: unknown;
|
||||
documentation?: string;
|
||||
}
|
|
@ -19,7 +19,7 @@ export function getVersion() {
|
|||
return esVersion;
|
||||
}
|
||||
|
||||
export function getContentType(body: any) {
|
||||
export function getContentType(body: unknown) {
|
||||
if (!body) return;
|
||||
return 'application/json';
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export function getContentType(body: any) {
|
|||
export function send(
|
||||
method: string,
|
||||
path: string,
|
||||
data: any,
|
||||
data: string | object,
|
||||
{ asSystemRequest }: SendOptions = {}
|
||||
) {
|
||||
const wrappedDfd = $.Deferred();
|
||||
|
@ -47,10 +47,10 @@ export function send(
|
|||
};
|
||||
|
||||
$.ajax(options).then(
|
||||
(responseData: any, textStatus: string, jqXHR: any) => {
|
||||
(responseData, textStatus: string, jqXHR: unknown) => {
|
||||
wrappedDfd.resolveWith({}, [responseData, textStatus, jqXHR]);
|
||||
},
|
||||
((jqXHR: any, textStatus: string, errorThrown: Error) => {
|
||||
((jqXHR: { status: number; responseText: string }, textStatus: string, errorThrown: Error) => {
|
||||
if (jqXHR.status === 0) {
|
||||
jqXHR.responseText =
|
||||
"\n\nFailed to connect to Console's backend.\nPlease check the Kibana server is up and running";
|
||||
|
|
|
@ -75,7 +75,7 @@ export default class RowParser {
|
|||
return MODE.REQUEST_START;
|
||||
}
|
||||
|
||||
rowPredicate(lineNumber: number | undefined, editor: CoreEditor, value: any) {
|
||||
rowPredicate(lineNumber: number | undefined, editor: CoreEditor, value: number) {
|
||||
const mode = this.getRowParseMode(lineNumber);
|
||||
// eslint-disable-next-line no-bitwise
|
||||
return (mode & value) > 0;
|
||||
|
|
|
@ -15,7 +15,7 @@ const mockTokensProviderFactory = (tokenMtx: Token[][]): TokensProvider => {
|
|||
return tokenMtx[lineNumber - 1] || null;
|
||||
},
|
||||
getTokenAt(pos: Position): Token | null {
|
||||
return null as any;
|
||||
return null;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ import { XJson } from '../../../../es_ui_shared/public';
|
|||
|
||||
const { collapseLiteralStrings, expandLiteralStrings } = XJson;
|
||||
|
||||
export function textFromRequest(request: any) {
|
||||
export function textFromRequest(request: { method: string; url: string; data: string | string[] }) {
|
||||
let data = request.data;
|
||||
if (typeof data !== 'string') {
|
||||
data = data.join('\n');
|
||||
|
@ -19,7 +19,7 @@ export function textFromRequest(request: any) {
|
|||
return request.method + ' ' + request.url + '\n' + data;
|
||||
}
|
||||
|
||||
export function jsonToString(data: any, indent: boolean) {
|
||||
export function jsonToString(data: object, indent: boolean) {
|
||||
return JSON.stringify(data, null, indent ? 2 : 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ export class History {
|
|||
// be triggered from different places in the app. The alternative would be to store
|
||||
// this in state so that we hook into the React model, but it would require loading history
|
||||
// every time the application starts even if a user is not going to view history.
|
||||
change(listener: (reqs: any[]) => void) {
|
||||
change(listener: (reqs: unknown[]) => void) {
|
||||
const subscription = this.changeEmitter.subscribe(listener);
|
||||
return () => subscription.unsubscribe();
|
||||
}
|
||||
|
||||
addToHistory(endpoint: string, method: string, data: any) {
|
||||
addToHistory(endpoint: string, method: string, data?: string) {
|
||||
const keys = this.getHistoryKeys();
|
||||
keys.splice(0, MAX_NUMBER_OF_HISTORY_ITEMS); // only maintain most recent X;
|
||||
keys.forEach((key) => {
|
||||
|
@ -59,7 +59,7 @@ export class History {
|
|||
this.changeEmitter.next(this.getHistory());
|
||||
}
|
||||
|
||||
updateCurrentState(content: any) {
|
||||
updateCurrentState(content: string) {
|
||||
const timestamp = new Date().getTime();
|
||||
this.storage.set('editor_state', {
|
||||
time: timestamp,
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
export { createHistory, History } from './history';
|
||||
export { createStorage, Storage, StorageKeys } from './storage';
|
||||
export { createSettings, Settings, DevToolsSettings } from './settings';
|
||||
export { createSettings, Settings, DevToolsSettings, DEFAULT_SETTINGS } from './settings';
|
||||
|
|
|
@ -8,6 +8,14 @@
|
|||
|
||||
import { Storage } from './index';
|
||||
|
||||
export const DEFAULT_SETTINGS = Object.freeze({
|
||||
fontSize: 14,
|
||||
polling: true,
|
||||
tripleQuotes: true,
|
||||
wrapMode: true,
|
||||
autocomplete: Object.freeze({ fields: true, indices: true, templates: true }),
|
||||
});
|
||||
|
||||
export interface DevToolsSettings {
|
||||
fontSize: number;
|
||||
wrapMode: boolean;
|
||||
|
@ -24,50 +32,46 @@ export class Settings {
|
|||
constructor(private readonly storage: Storage) {}
|
||||
|
||||
getFontSize() {
|
||||
return this.storage.get('font_size', 14);
|
||||
return this.storage.get('font_size', DEFAULT_SETTINGS.fontSize);
|
||||
}
|
||||
|
||||
setFontSize(size: any) {
|
||||
setFontSize(size: number) {
|
||||
this.storage.set('font_size', size);
|
||||
return true;
|
||||
}
|
||||
|
||||
getWrapMode() {
|
||||
return this.storage.get('wrap_mode', true);
|
||||
return this.storage.get('wrap_mode', DEFAULT_SETTINGS.wrapMode);
|
||||
}
|
||||
|
||||
setWrapMode(mode: any) {
|
||||
setWrapMode(mode: boolean) {
|
||||
this.storage.set('wrap_mode', mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
setTripleQuotes(tripleQuotes: any) {
|
||||
setTripleQuotes(tripleQuotes: boolean) {
|
||||
this.storage.set('triple_quotes', tripleQuotes);
|
||||
return true;
|
||||
}
|
||||
|
||||
getTripleQuotes() {
|
||||
return this.storage.get('triple_quotes', true);
|
||||
return this.storage.get('triple_quotes', DEFAULT_SETTINGS.tripleQuotes);
|
||||
}
|
||||
|
||||
getAutocomplete() {
|
||||
return this.storage.get('autocomplete_settings', {
|
||||
fields: true,
|
||||
indices: true,
|
||||
templates: true,
|
||||
});
|
||||
return this.storage.get('autocomplete_settings', DEFAULT_SETTINGS.autocomplete);
|
||||
}
|
||||
|
||||
setAutocomplete(settings: any) {
|
||||
setAutocomplete(settings: object) {
|
||||
this.storage.set('autocomplete_settings', settings);
|
||||
return true;
|
||||
}
|
||||
|
||||
getPolling() {
|
||||
return this.storage.get('console_polling', true);
|
||||
return this.storage.get('console_polling', DEFAULT_SETTINGS.polling);
|
||||
}
|
||||
|
||||
setPolling(polling: any) {
|
||||
setPolling(polling: boolean) {
|
||||
this.storage.set('console_polling', polling);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@ export enum StorageKeys {
|
|||
export class Storage {
|
||||
constructor(private readonly engine: IStorageEngine, private readonly prefix: string) {}
|
||||
|
||||
encode(val: any) {
|
||||
encode(val: unknown) {
|
||||
return JSON.stringify(val);
|
||||
}
|
||||
|
||||
decode(val: any) {
|
||||
decode(val: string | null) {
|
||||
if (typeof val === 'string') {
|
||||
return JSON.parse(val);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
set(key: string, val: any) {
|
||||
set(key: string, val: unknown) {
|
||||
this.engine.setItem(this.encodeKey(key), this.encode(val));
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,12 @@ export interface MetricsTracker {
|
|||
load: (eventName: string) => void;
|
||||
}
|
||||
|
||||
export interface ESRequest {
|
||||
method: string;
|
||||
endpoint: string;
|
||||
data?: string;
|
||||
}
|
||||
|
||||
export type BaseResponseType =
|
||||
| 'application/json'
|
||||
| 'text/csv'
|
||||
|
|
|
@ -21,7 +21,7 @@ export type EditorEvent =
|
|||
export type AutoCompleterFunction = (
|
||||
pos: Position,
|
||||
prefix: string,
|
||||
callback: (...args: any[]) => void
|
||||
callback: (...args: unknown[]) => void
|
||||
) => void;
|
||||
|
||||
export interface Position {
|
||||
|
@ -235,7 +235,7 @@ export interface CoreEditor {
|
|||
* have this backdoor to update UI in response to request range changes, for example, as the user
|
||||
* moves the cursor around
|
||||
*/
|
||||
legacyUpdateUI(opts: any): void;
|
||||
legacyUpdateUI(opts: unknown): void;
|
||||
|
||||
/**
|
||||
* A method to for the editor to resize, useful when, for instance, window size changes.
|
||||
|
@ -250,7 +250,11 @@ export interface CoreEditor {
|
|||
/**
|
||||
* Register a keyboard shortcut and provide a function to be called.
|
||||
*/
|
||||
registerKeyboardShortcut(opts: { keys: any; fn: () => void; name: string }): void;
|
||||
registerKeyboardShortcut(opts: {
|
||||
keys: string | { win?: string; mac?: string };
|
||||
fn: () => void;
|
||||
name: string;
|
||||
}): void;
|
||||
|
||||
/**
|
||||
* Register a completions function that will be called when the editor
|
||||
|
|
|
@ -14,7 +14,7 @@ import url from 'url';
|
|||
import { ESConfigForProxy } from '../types';
|
||||
|
||||
const createAgent = (legacyConfig: ESConfigForProxy) => {
|
||||
const target = url.parse(_.head(legacyConfig.hosts) as any);
|
||||
const target = url.parse(_.head(legacyConfig.hosts)!);
|
||||
if (!/^https/.test(target.protocol || '')) return new http.Agent();
|
||||
|
||||
const agentOptions: https.AgentOptions = {};
|
||||
|
@ -28,7 +28,7 @@ const createAgent = (legacyConfig: ESConfigForProxy) => {
|
|||
agentOptions.rejectUnauthorized = true;
|
||||
|
||||
// by default, NodeJS is checking the server identify
|
||||
agentOptions.checkServerIdentity = _.noop as any;
|
||||
agentOptions.checkServerIdentity = (_.noop as unknown) as https.AgentOptions['checkServerIdentity'];
|
||||
break;
|
||||
case 'full':
|
||||
agentOptions.rejectUnauthorized = true;
|
||||
|
|
|
@ -12,6 +12,17 @@ import { Agent as HttpsAgent, AgentOptions } from 'https';
|
|||
|
||||
import { WildcardMatcher } from './wildcard_matcher';
|
||||
|
||||
interface Config {
|
||||
match: {
|
||||
protocol: string;
|
||||
host: string;
|
||||
port: string;
|
||||
path: string;
|
||||
};
|
||||
ssl?: { verify?: boolean; ca?: string; cert?: string; key?: string };
|
||||
timeout: number;
|
||||
}
|
||||
|
||||
export class ProxyConfig {
|
||||
// @ts-ignore
|
||||
private id: string;
|
||||
|
@ -26,9 +37,9 @@ export class ProxyConfig {
|
|||
|
||||
private readonly sslAgent?: HttpsAgent;
|
||||
|
||||
private verifySsl: any;
|
||||
private verifySsl: undefined | boolean;
|
||||
|
||||
constructor(config: { match: any; timeout: number }) {
|
||||
constructor(config: Config) {
|
||||
config = {
|
||||
...config,
|
||||
};
|
||||
|
@ -61,8 +72,8 @@ export class ProxyConfig {
|
|||
this.sslAgent = this._makeSslAgent(config);
|
||||
}
|
||||
|
||||
_makeSslAgent(config: any) {
|
||||
const ssl = config.ssl || {};
|
||||
_makeSslAgent(config: Config) {
|
||||
const ssl: Config['ssl'] = config.ssl || {};
|
||||
this.verifySsl = ssl.verify;
|
||||
|
||||
const sslAgentOpts: AgentOptions = {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { Agent } from 'http';
|
||||
import { defaultsDeep } from 'lodash';
|
||||
import { parse as parseUrl } from 'url';
|
||||
|
||||
|
@ -14,7 +15,12 @@ import { ProxyConfig } from './proxy_config';
|
|||
export class ProxyConfigCollection {
|
||||
private configs: ProxyConfig[];
|
||||
|
||||
constructor(configs: Array<{ match: any; timeout: number }> = []) {
|
||||
constructor(
|
||||
configs: Array<{
|
||||
match: { protocol: string; host: string; port: string; path: string };
|
||||
timeout: number;
|
||||
}> = []
|
||||
) {
|
||||
this.configs = configs.map((settings) => new ProxyConfig(settings));
|
||||
}
|
||||
|
||||
|
@ -22,7 +28,7 @@ export class ProxyConfigCollection {
|
|||
return Boolean(this.configs.length);
|
||||
}
|
||||
|
||||
configForUri(uri: string): object {
|
||||
configForUri(uri: string): { agent: Agent; timeout: number } {
|
||||
const parsedUri = parseUrl(uri);
|
||||
const settings = this.configs.map((config) => config.getForParsedUri(parsedUri as any));
|
||||
return defaultsDeep({}, ...settings);
|
||||
|
|
|
@ -55,7 +55,7 @@ describe(`Console's send request`, () => {
|
|||
fakeRequest = {
|
||||
abort: sinon.stub(),
|
||||
on() {},
|
||||
once(event: string, fn: any) {
|
||||
once(event: string, fn: (v: string) => void) {
|
||||
if (event === 'response') {
|
||||
return fn('done');
|
||||
}
|
||||
|
|
|
@ -46,9 +46,9 @@ export const proxyRequest = ({
|
|||
const client = uri.protocol === 'https:' ? https : http;
|
||||
let resolved = false;
|
||||
|
||||
let resolve: any;
|
||||
let reject: any;
|
||||
const reqPromise = new Promise<http.ServerResponse>((res, rej) => {
|
||||
let resolve: (res: http.IncomingMessage) => void;
|
||||
let reject: (res: unknown) => void;
|
||||
const reqPromise = new Promise<http.IncomingMessage>((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { IKibanaResponse } from 'src/core/server';
|
||||
import { getProxyRouteHandlerDeps } from './mocks';
|
||||
|
||||
import { Readable } from 'stream';
|
||||
|
@ -16,10 +16,14 @@ import * as requestModule from '../../../../lib/proxy_request';
|
|||
import { createResponseStub } from './stubs';
|
||||
|
||||
describe('Console Proxy Route', () => {
|
||||
let request: any;
|
||||
let request: (
|
||||
method: string,
|
||||
path: string,
|
||||
response?: string
|
||||
) => Promise<IKibanaResponse> | IKibanaResponse;
|
||||
|
||||
beforeEach(() => {
|
||||
request = (method: string, path: string, response: string) => {
|
||||
request = (method, path, response) => {
|
||||
(requestModule.proxyRequest as jest.Mock).mockResolvedValue(createResponseStub(response));
|
||||
const handler = createHandler(getProxyRouteHandlerDeps({}));
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ function toURL(base: string, path: string) {
|
|||
}
|
||||
|
||||
function filterHeaders(originalHeaders: object, headersToKeep: string[]): object {
|
||||
const normalizeHeader = function (header: any) {
|
||||
const normalizeHeader = function (header: string) {
|
||||
if (!header) {
|
||||
return '';
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ function getRequestConfig(
|
|||
return {
|
||||
...proxyConfigCollection.configForUri(uri),
|
||||
headers: newHeaders,
|
||||
} as any;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -81,7 +81,7 @@ function getProxyHeaders(req: KibanaRequest) {
|
|||
const headers = Object.create(null);
|
||||
|
||||
// Scope this proto-unsafe functionality to where it is being used.
|
||||
function extendCommaList(obj: Record<string, any>, property: string, value: any) {
|
||||
function extendCommaList(obj: Record<string, any>, property: string, value: string) {
|
||||
obj[property] = (obj[property] ? obj[property] + ',' : '') + value;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ export const createHandler = ({
|
|||
};
|
||||
|
||||
esIncomingMessage = await proxyRequest({
|
||||
method: method.toLowerCase() as any,
|
||||
method: method.toLowerCase() as 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head',
|
||||
headers: requestHeaders,
|
||||
uri,
|
||||
timeout,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from 'src/core/server';
|
||||
import { kibanaResponseFactory } from '../../../../../../../core/server';
|
||||
import { getProxyRouteHandlerDeps } from './mocks';
|
||||
import { createResponseStub } from './stubs';
|
||||
|
@ -14,7 +15,7 @@ import * as requestModule from '../../../../lib/proxy_request';
|
|||
import { createHandler } from './create_handler';
|
||||
|
||||
describe('Console Proxy Route', () => {
|
||||
let request: any;
|
||||
let request: (method: string, path: string) => Promise<IKibanaResponse> | IKibanaResponse;
|
||||
beforeEach(() => {
|
||||
(requestModule.proxyRequest as jest.Mock).mockResolvedValue(createResponseStub('foo'));
|
||||
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
import { IncomingMessage } from 'http';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
export function createResponseStub(response: any) {
|
||||
const resp: any = new Readable({
|
||||
export function createResponseStub(response?: string) {
|
||||
const resp: Readable & {
|
||||
statusCode?: number;
|
||||
statusMessage?: string;
|
||||
headers?: Record<string, unknown>;
|
||||
} = new Readable({
|
||||
read() {
|
||||
if (response) {
|
||||
this.push(response);
|
||||
|
|
|
@ -15,6 +15,15 @@ import { jsSpecLoaders } from '../lib';
|
|||
|
||||
const PATH_TO_OSS_JSON_SPEC = resolve(__dirname, '../lib/spec_definitions/json');
|
||||
|
||||
interface EndpointDescription {
|
||||
methods?: string[];
|
||||
patterns?: string | string[];
|
||||
url_params?: Record<string, unknown>;
|
||||
data_autocomplete_rules?: Record<string, unknown>;
|
||||
url_components?: Record<string, unknown>;
|
||||
priority?: number;
|
||||
}
|
||||
|
||||
export class SpecDefinitionsService {
|
||||
private readonly name = 'es';
|
||||
|
||||
|
@ -24,16 +33,23 @@ export class SpecDefinitionsService {
|
|||
|
||||
private hasLoadedSpec = false;
|
||||
|
||||
public addGlobalAutocompleteRules(parentNode: string, rules: any) {
|
||||
public addGlobalAutocompleteRules(parentNode: string, rules: unknown) {
|
||||
this.globalRules[parentNode] = rules;
|
||||
}
|
||||
|
||||
public addEndpointDescription(endpoint: string, description: any = {}) {
|
||||
let copiedDescription: any = {};
|
||||
public addEndpointDescription(endpoint: string, description: EndpointDescription = {}) {
|
||||
let copiedDescription: { patterns?: string; url_params?: Record<string, unknown> } = {};
|
||||
if (this.endpoints[endpoint]) {
|
||||
copiedDescription = { ...this.endpoints[endpoint] };
|
||||
}
|
||||
let urlParamsDef: any;
|
||||
let urlParamsDef:
|
||||
| {
|
||||
ignore_unavailable?: string;
|
||||
allow_no_indices?: string;
|
||||
expand_wildcards?: string[];
|
||||
}
|
||||
| undefined;
|
||||
|
||||
_.each(description.patterns || [], function (p) {
|
||||
if (p.indexOf('{indices}') >= 0) {
|
||||
urlParamsDef = urlParamsDef || {};
|
||||
|
@ -70,7 +86,7 @@ export class SpecDefinitionsService {
|
|||
this.extensionSpecFilePaths.push(path);
|
||||
}
|
||||
|
||||
public addProcessorDefinition(processor: any) {
|
||||
public addProcessorDefinition(processor: unknown) {
|
||||
if (!this.hasLoadedSpec) {
|
||||
throw new Error(
|
||||
'Cannot add a processor definition because spec definitions have not loaded!'
|
||||
|
@ -104,11 +120,13 @@ export class SpecDefinitionsService {
|
|||
|
||||
return generatedFiles.reduce((acc, file) => {
|
||||
const overrideFile = overrideFiles.find((f) => basename(f) === basename(file));
|
||||
const loadedSpec = JSON.parse(readFileSync(file, 'utf8'));
|
||||
const loadedSpec: Record<string, EndpointDescription> = JSON.parse(
|
||||
readFileSync(file, 'utf8')
|
||||
);
|
||||
if (overrideFile) {
|
||||
merge(loadedSpec, JSON.parse(readFileSync(overrideFile, 'utf8')));
|
||||
}
|
||||
const spec: any = {};
|
||||
const spec: Record<string, EndpointDescription> = {};
|
||||
Object.entries(loadedSpec).forEach(([key, value]) => {
|
||||
if (acc[key]) {
|
||||
// add time to remove key collision
|
||||
|
@ -119,7 +137,7 @@ export class SpecDefinitionsService {
|
|||
});
|
||||
|
||||
return { ...acc, ...spec };
|
||||
}, {} as any);
|
||||
}, {} as Record<string, EndpointDescription>);
|
||||
}
|
||||
|
||||
private loadJsonSpec() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue