Skip to content

Commit

Permalink
Merge pull request #9 from Dosant/d/2022-04-26-script-based-visualiza…
Browse files Browse the repository at this point in the history
…tions

add sql api
  • Loading branch information
drewdaemon authored Apr 28, 2022
2 parents affc827 + dfa51d6 commit c80b12d
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 6 deletions.
84 changes: 80 additions & 4 deletions src/plugins/vis_type_script/public/kibana_api/kibana_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,69 @@

import type * as estypes from '@elastic/elasticsearch/lib/api/types';
import { lastValueFrom } from 'rxjs';
import {
ENHANCED_ES_SEARCH_STRATEGY,
SQL_SEARCH_STRATEGY,
SqlSearchStrategyRequest,
SqlSearchStrategyResponse,
} from '@kbn/data-plugin/common';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { VisSearchContext } from '../types';

export interface VisTypeScriptKibanaApiDeps {
data: DataPublicPluginStart;
}

export interface EsSearchOptions {
export interface ESSearchOptions {
useKibanaContext: boolean;
timeField?: string;
}
export type ESSearchRequest = estypes.SearchRequest;

// disallow transport properties that are handled by data_plugin and allow only query related properties
const allowedESSearchRequestKeys = [
'index',
'aggregations',
'aggs',
'query',
'q',
'sort',
'from',
] as const;
export type ESSearchRequest = Pick<
estypes.SearchRequest,
typeof allowedESSearchRequestKeys[number]
>;
export type ESSearchResponse = estypes.SearchResponse;

export interface SQLSearchOptions {
useKibanaContext: boolean;
timeField?: string;
}

const allowedSQLSearchRequestKeys = [
'query',
'columnar',
'cursor',
'fetch_size',
'filter',
'time_zone',
] as const;
export type SQLSearchRequest = Pick<
estypes.SqlQueryRequest,
typeof allowedSQLSearchRequestKeys[number]
>;
export type SQLSearchResponse = estypes.SqlQueryResponse;

function sanitizeRequest<T extends Record<string, unknown>>(payload: T, allowedKeys: string[]): T {
if (payload == null || typeof payload !== 'object') return payload;
return allowedKeys.reduce((sanitized, allowedKey) => {
if (allowedKey in payload) {
sanitized[allowedKey] = payload[allowedKey];
}
return sanitized;
}, {} as Record<string, unknown>) as T;
}

export class VisTypeScriptKibanaApi {
constructor(
private readonly deps: VisTypeScriptKibanaApiDeps,
Expand All @@ -29,15 +79,41 @@ export class VisTypeScriptKibanaApi {

async esSearch(
payload: ESSearchRequest,
{ useKibanaContext = true }: EsSearchOptions = { useKibanaContext: true }
{ useKibanaContext = true }: ESSearchOptions = { useKibanaContext: true }
): Promise<ESSearchResponse> {
payload = sanitizeRequest(payload, [...allowedESSearchRequestKeys]);

if (useKibanaContext) {
// TODO: adjust request based on this.visSearchContext
// eslint-disable-next-line no-console
console.log(this.visSearchContext);
}

const response = await lastValueFrom(
this.deps.data.search.search({ params: payload }, { strategy: ENHANCED_ES_SEARCH_STRATEGY })
);
return response.rawResponse;
}

async sqlSearch(
payload: SQLSearchRequest,
{ useKibanaContext = true }: ESSearchOptions = { useKibanaContext: true }
): Promise<SQLSearchResponse> {
payload = sanitizeRequest(payload, [...allowedSQLSearchRequestKeys]);

if (useKibanaContext) {
// TODO: adjust request based on this.visSearchContext
// eslint-disable-next-line no-console
console.log(this.visSearchContext);
}

const response = await lastValueFrom(this.deps.data.search.search({ params: payload }));
const response = await lastValueFrom(
this.deps.data.search.search<SqlSearchStrategyRequest, SqlSearchStrategyResponse>(
{ params: payload },
{ strategy: SQL_SEARCH_STRATEGY }
)
);

return response.rawResponse;
}
}
16 changes: 14 additions & 2 deletions src/plugins/vis_type_script/public/renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import { createEndpoint, fromIframe } from '@remote-ui/rpc';
import './index.scss';
import { IExternalUrl } from '@kbn/core/public';
import {
EsSearchOptions,
ESSearchOptions,
VisTypeScriptKibanaApi,
ESSearchResponse,
ESSearchRequest,
SQLSearchRequest,
SQLSearchOptions,
SQLSearchResponse,
} from '../kibana_api';

export const KIBANA_API_CONSTANT_NAME = 'KIBANA';
Expand All @@ -41,6 +44,9 @@ const getSandboxDocument = (script: string, dependencies: string[], nonce: strin
searchEs: (payload, options) => {
return endpoint.call.esSearch(payload, options);
},
searchSql: (payload, options) => {
return endpoint.call.sqlSearch(payload, options);
},
subscribeToResize: (fn) => {
onResize = fn;
},
Expand Down Expand Up @@ -102,10 +108,16 @@ export const ScriptRenderer: React.FunctionComponent<{
endpoint.expose({
esSearch: async (
payload: ESSearchRequest,
options?: EsSearchOptions
options?: ESSearchOptions
): Promise<ESSearchResponse> => {
return kibanaApi.esSearch(payload, options);
},
sqlSearch: async (
payload: SQLSearchRequest,
options?: SQLSearchOptions
): Promise<SQLSearchResponse> => {
return kibanaApi.sqlSearch(payload, options);
},
});

return () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ const provideSuggestions = (
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: wordRange,
},
{
label: 'searchSql',
kind: monacoEditor.languages.CompletionItemKind.Method,
documentation: {
value: 'Runs an Elasticsearch SQL query',
isTrusted: true,
},
insertText: 'searchSql({\n\tquery: "$0"\n})',
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: wordRange,
},
{
label: 'subscribeToResize',
kind: monacoEditor.languages.CompletionItemKind.Method,
Expand Down

0 comments on commit c80b12d

Please sign in to comment.