mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[data views] More dev docs (#132817)
* more data view code comments Co-authored-by: Jean-Louis Leysens <jloleysens@gmail.com>
This commit is contained in:
parent
5a0aab77d5
commit
d3e5764102
66 changed files with 1279 additions and 272 deletions
|
@ -110,15 +110,12 @@ export type {
|
|||
OnNotification,
|
||||
OnError,
|
||||
UiSettingsCommon,
|
||||
SavedObjectsClientCommonFindArgs,
|
||||
SavedObjectsClientCommon,
|
||||
GetFieldsOptions,
|
||||
IDataViewsApiClient,
|
||||
SavedObject,
|
||||
AggregationRestrictions,
|
||||
TypeMeta,
|
||||
FieldSpecConflictDescriptions,
|
||||
FieldSpecExportFmt,
|
||||
FieldSpec,
|
||||
DataViewFieldMap,
|
||||
DataViewSpec,
|
||||
|
|
|
@ -14,10 +14,10 @@ import { Filter } from '@kbn/es-query';
|
|||
import { Query, uniqFilters } from '@kbn/es-query';
|
||||
import { unboxExpressionValue } from '@kbn/expressions-plugin/common';
|
||||
import { SavedObjectReference } from '@kbn/core/types';
|
||||
import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/common';
|
||||
import { ExecutionContextSearch, KibanaContext, KibanaFilter } from './kibana_context_type';
|
||||
import { KibanaQueryOutput } from './kibana_context_type';
|
||||
import { KibanaTimerangeOutput } from './timerange';
|
||||
import { SavedObjectsClientCommon } from '../..';
|
||||
|
||||
export interface KibanaContextStartDependencies {
|
||||
savedObjectsClient: SavedObjectsClientCommon;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
import { StartServicesAccessor } from '@kbn/core/public';
|
||||
import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/public';
|
||||
import { getKibanaContextFn } from '../../../common/search/expressions';
|
||||
import { DataPublicPluginStart, DataStartDependencies } from '../../types';
|
||||
import { SavedObjectsClientCommon } from '../../../common';
|
||||
|
||||
/**
|
||||
* This is some glue code that takes in `core.getStartServices`, extracts the dependencies
|
||||
|
|
|
@ -12,14 +12,14 @@ import type {
|
|||
UiSettingsServiceStart,
|
||||
} from '@kbn/core/server';
|
||||
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/server';
|
||||
import type { IndexPatternsServiceStart } from '@kbn/data-views-plugin/server';
|
||||
import type { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server';
|
||||
import { DatatableUtilitiesService as DatatableUtilitiesServiceCommon } from '../../common';
|
||||
import type { AggsStart } from '../search';
|
||||
|
||||
export class DatatableUtilitiesService {
|
||||
constructor(
|
||||
private aggs: AggsStart,
|
||||
private dataViews: IndexPatternsServiceStart,
|
||||
private dataViews: DataViewsServerPluginStart,
|
||||
private fieldFormats: FieldFormatsStart,
|
||||
private uiSettings: UiSettingsServiceStart
|
||||
) {
|
||||
|
|
|
@ -38,12 +38,8 @@ export { DATA_VIEW_SAVED_OBJECT_TYPE } from '../common';
|
|||
* Index patterns:
|
||||
*/
|
||||
|
||||
export type { FieldDescriptor, IndexPatternsServiceStart } from './data_views';
|
||||
export {
|
||||
IndexPatternsFetcher,
|
||||
shouldReadFieldFromDocValues,
|
||||
getCapabilitiesForRollupIndices,
|
||||
} from './data_views';
|
||||
export type { FieldDescriptor, DataViewsServerPluginStart } from './data_views';
|
||||
export { IndexPatternsFetcher, getCapabilitiesForRollupIndices } from './data_views';
|
||||
|
||||
export {
|
||||
ES_FIELD_TYPES,
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
} from '@kbn/core/server';
|
||||
import { ExpressionsServiceSetup } from '@kbn/expressions-plugin/common';
|
||||
import { FieldFormatsStart } from '@kbn/field-formats-plugin/server';
|
||||
import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server';
|
||||
import {
|
||||
AggsCommonService,
|
||||
AggConfigs,
|
||||
|
@ -23,7 +24,6 @@ import {
|
|||
calculateBounds,
|
||||
TimeRange,
|
||||
} from '../../../common';
|
||||
import { IndexPatternsServiceStart } from '../../data_views';
|
||||
import { AggsSetup, AggsStart } from './types';
|
||||
|
||||
/** @internal */
|
||||
|
@ -35,7 +35,7 @@ export interface AggsSetupDependencies {
|
|||
export interface AggsStartDependencies {
|
||||
fieldFormats: FieldFormatsStart;
|
||||
uiSettings: UiSettingsServiceStart;
|
||||
indexPatterns: IndexPatternsServiceStart;
|
||||
indexPatterns: DataViewsServerPluginStart;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +75,7 @@ export class AggsService {
|
|||
const { calculateAutoTimeExpression, types } = this.aggsCommonService.start({
|
||||
getConfig,
|
||||
getIndexPattern: (
|
||||
await indexPatterns.indexPatternsServiceFactory(savedObjectsClient, elasticsearchClient)
|
||||
await indexPatterns.dataViewsServiceFactory(savedObjectsClient, elasticsearchClient)
|
||||
).get,
|
||||
isDefaultTimezone,
|
||||
});
|
||||
|
|
|
@ -111,7 +111,7 @@ export function getEsaggs({
|
|||
|
||||
return {
|
||||
aggs: await search.aggs.asScopedToClient(savedObjectsClient, esClient.asCurrentUser),
|
||||
indexPatterns: await indexPatterns.indexPatternsServiceFactory(
|
||||
indexPatterns: await indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
esClient.asCurrentUser
|
||||
),
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
import { StartServicesAccessor } from '@kbn/core/server';
|
||||
import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/server';
|
||||
import { getKibanaContextFn } from '../../../common/search/expressions';
|
||||
import { DataPluginStart, DataPluginStartDependencies } from '../../plugin';
|
||||
import { SavedObjectsClientCommon } from '../../../common';
|
||||
|
||||
/**
|
||||
* This is some glue code that takes in `core.getStartServices`, extracts the dependencies
|
||||
|
|
|
@ -30,6 +30,7 @@ import type {
|
|||
TaskManagerStartContract,
|
||||
} from '@kbn/task-manager-plugin/server';
|
||||
import type { SecurityPluginSetup } from '@kbn/security-plugin/server';
|
||||
import type { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server';
|
||||
import type {
|
||||
DataRequestHandlerContext,
|
||||
IScopedSearchClient,
|
||||
|
@ -41,7 +42,6 @@ import type {
|
|||
|
||||
import { AggsService } from './aggs';
|
||||
|
||||
import { IndexPatternsServiceStart } from '../data_views';
|
||||
import { registerSearchRoute, registerSessionRoutes } from './routes';
|
||||
import { ES_SEARCH_STRATEGY, esSearchStrategyProvider } from './strategies/es_search';
|
||||
import { DataPluginStart, DataPluginStartDependencies } from '../plugin';
|
||||
|
@ -116,7 +116,7 @@ export interface SearchServiceSetupDependencies {
|
|||
/** @internal */
|
||||
export interface SearchServiceStartDependencies {
|
||||
fieldFormats: FieldFormatsStart;
|
||||
indexPatterns: IndexPatternsServiceStart;
|
||||
indexPatterns: DataViewsServerPluginStart;
|
||||
taskManager?: TaskManagerStartContract;
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
asScoped: async (request: KibanaRequest) => {
|
||||
const esClient = elasticsearch.client.asScoped(request);
|
||||
const savedObjectsClient = savedObjects.getScopedClient(request);
|
||||
const scopedIndexPatterns = await indexPatterns.indexPatternsServiceFactory(
|
||||
const scopedIndexPatterns = await indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
esClient.asCurrentUser
|
||||
);
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* All runtime field types.
|
||||
* @public
|
||||
*/
|
||||
export const RUNTIME_FIELD_TYPES = [
|
||||
'keyword',
|
||||
'long',
|
||||
|
@ -32,9 +36,20 @@ export const DEFAULT_ASSETS_TO_IGNORE = {
|
|||
METRICS_ENDPOINT_INDEX_TO_IGNORE: 'metrics-endpoint.metadata_current_default', // ignore index created by Fleet endpoint package installed by default in Cloud
|
||||
};
|
||||
|
||||
/**
|
||||
* UiSettings key for metaFields list.
|
||||
* @public
|
||||
*/
|
||||
export const META_FIELDS = 'metaFields';
|
||||
|
||||
/** @public **/
|
||||
/**
|
||||
* Data view saved object type.
|
||||
* @public
|
||||
*/
|
||||
export const DATA_VIEW_SAVED_OBJECT_TYPE = 'index-pattern';
|
||||
|
||||
/**
|
||||
* Data views plugin name.
|
||||
* @public
|
||||
*/
|
||||
export const PLUGIN_NAME = 'DataViews';
|
||||
|
|
|
@ -45,47 +45,102 @@ interface SavedObjectBody {
|
|||
* An interface representing a data view that is time based.
|
||||
*/
|
||||
export interface TimeBasedDataView extends DataView {
|
||||
/**
|
||||
* The timestamp field name.
|
||||
*/
|
||||
timeFieldName: NonNullable<DataView['timeFieldName']>;
|
||||
/**
|
||||
* The timestamp field.
|
||||
*/
|
||||
getTimeField: () => DataViewField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data view class. Central kibana abstraction around multiple indices.
|
||||
*/
|
||||
export class DataView implements DataViewBase {
|
||||
/**
|
||||
* Saved object id
|
||||
*/
|
||||
public id?: string;
|
||||
/**
|
||||
* Title of data view
|
||||
*/
|
||||
public title: string = '';
|
||||
/**
|
||||
* Map of field formats by field name
|
||||
*/
|
||||
public fieldFormatMap: Record<string, any>;
|
||||
/**
|
||||
* Only used by rollup indices, used by rollup specific endpoint to load field list
|
||||
* Only used by rollup indices, used by rollup specific endpoint to load field list.
|
||||
*/
|
||||
public typeMeta?: TypeMeta;
|
||||
/**
|
||||
* Field list, in extended array format
|
||||
*/
|
||||
public fields: IIndexPatternFieldList & { toSpec: () => DataViewFieldMap };
|
||||
/**
|
||||
* Timestamp field name
|
||||
*/
|
||||
public timeFieldName: string | undefined;
|
||||
/**
|
||||
* Type is used to identify rollup index patterns
|
||||
* Type is used to identify rollup index patterns.
|
||||
*/
|
||||
public type: string | undefined;
|
||||
/**
|
||||
* @deprecated Use `flattenHit` utility method exported from data plugin instead.
|
||||
*/
|
||||
public flattenHit: (hit: Record<string, any>, deep?: boolean) => Record<string, any>;
|
||||
/**
|
||||
* List of meta fields by name
|
||||
*/
|
||||
public metaFields: string[];
|
||||
/**
|
||||
* SavedObject version
|
||||
*/
|
||||
public version: string | undefined;
|
||||
/**
|
||||
* Array of filters - hides fields in discover
|
||||
*/
|
||||
public sourceFilters?: SourceFilter[];
|
||||
/**
|
||||
* Array of namespace ids
|
||||
*/
|
||||
public namespaces: string[];
|
||||
/**
|
||||
* Original saved object body. Used to check for saved object changes.
|
||||
*/
|
||||
private originalSavedObjectBody: SavedObjectBody = {};
|
||||
/**
|
||||
* Returns true if short dot notation is enabled
|
||||
*/
|
||||
private shortDotsEnable: boolean = false;
|
||||
/**
|
||||
* FieldFormats service interface
|
||||
*/
|
||||
private fieldFormats: FieldFormatsStartCommon;
|
||||
/**
|
||||
* Map of field attributes by field name. Currently count and customLabel.
|
||||
*/
|
||||
private fieldAttrs: FieldAttrs;
|
||||
/**
|
||||
* Map of runtime field definitions by field name
|
||||
*/
|
||||
private runtimeFieldMap: Record<string, RuntimeFieldSpec>;
|
||||
|
||||
/**
|
||||
* prevents errors when index pattern exists before indices
|
||||
* Prevents errors when index pattern exists before indices
|
||||
*/
|
||||
public readonly allowNoIndex: boolean = false;
|
||||
|
||||
constructor({ spec = {}, fieldFormats, shortDotsEnable = false, metaFields = [] }: DataViewDeps) {
|
||||
/**
|
||||
* constructor
|
||||
* @param config - config data and dependencies
|
||||
*/
|
||||
|
||||
constructor(config: DataViewDeps) {
|
||||
const { spec = {}, fieldFormats, shortDotsEnable = false, metaFields = [] } = config;
|
||||
|
||||
// set dependencies
|
||||
this.fieldFormats = fieldFormats;
|
||||
// set config
|
||||
|
@ -120,12 +175,15 @@ export class DataView implements DataViewBase {
|
|||
getOriginalSavedObjectBody = () => ({ ...this.originalSavedObjectBody });
|
||||
|
||||
/**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
* Reset last saved saved object fields. Used after saving.
|
||||
*/
|
||||
resetOriginalSavedObjectBody = () => {
|
||||
this.originalSavedObjectBody = this.getAsSavedObjectBody();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns field attributes map
|
||||
*/
|
||||
getFieldAttrs = () => {
|
||||
const newFieldAttrs = { ...this.fieldAttrs };
|
||||
|
||||
|
@ -151,6 +209,10 @@ export class DataView implements DataViewBase {
|
|||
return newFieldAttrs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns scripted fields
|
||||
*/
|
||||
|
||||
getComputedFields() {
|
||||
const scriptFields: Record<string, estypes.ScriptField> = {};
|
||||
if (!this.fields) {
|
||||
|
@ -195,7 +257,7 @@ export class DataView implements DataViewBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create static representation of index pattern
|
||||
* Creates static representation of the data view.
|
||||
*/
|
||||
public toSpec(): DataViewSpec {
|
||||
return {
|
||||
|
@ -225,8 +287,8 @@ export class DataView implements DataViewBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove scripted field from field list
|
||||
* @param fieldName
|
||||
* Removes scripted field from field list.
|
||||
* @param fieldName name of scripted field to remove
|
||||
* @deprecated use runtime field instead
|
||||
*/
|
||||
|
||||
|
@ -239,7 +301,7 @@ export class DataView implements DataViewBase {
|
|||
|
||||
/**
|
||||
*
|
||||
* @deprecated Will be removed when scripted fields are removed
|
||||
* @deprecated Will be removed when scripted fields are removed.
|
||||
*/
|
||||
getNonScriptedFields() {
|
||||
return [...this.fields.getAll().filter((field) => !field.scripted)];
|
||||
|
@ -247,31 +309,51 @@ export class DataView implements DataViewBase {
|
|||
|
||||
/**
|
||||
*
|
||||
* @deprecated use runtime field instead
|
||||
* @deprecated Use runtime field instead.
|
||||
*/
|
||||
getScriptedFields() {
|
||||
return [...this.fields.getAll().filter((field) => field.scripted)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the data view have a timestamp field?
|
||||
*/
|
||||
|
||||
isTimeBased(): this is TimeBasedDataView {
|
||||
return !!this.timeFieldName && (!this.fields || !!this.getTimeField());
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the data view have a timestamp field and is it a date nanos field?
|
||||
*/
|
||||
|
||||
isTimeNanosBased(): this is TimeBasedDataView {
|
||||
const timeField = this.getTimeField();
|
||||
return !!(timeField && timeField.esTypes && timeField.esTypes.indexOf('date_nanos') !== -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timestamp field as DataViewField or return undefined
|
||||
*/
|
||||
getTimeField() {
|
||||
if (!this.timeFieldName || !this.fields || !this.fields.getByName) return undefined;
|
||||
return this.fields.getByName(this.timeFieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field by name.
|
||||
* @param name field name
|
||||
*/
|
||||
|
||||
getFieldByName(name: string): DataViewField | undefined {
|
||||
if (!this.fields || !this.fields.getByName) return undefined;
|
||||
return this.fields.getByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get aggregation restrictions. Rollup fields can only perform a subset of aggregations.
|
||||
*/
|
||||
|
||||
getAggregationRestrictions() {
|
||||
return this.typeMeta?.aggs;
|
||||
}
|
||||
|
@ -302,7 +384,7 @@ export class DataView implements DataViewBase {
|
|||
|
||||
/**
|
||||
* Provide a field, get its formatter
|
||||
* @param field
|
||||
* @param field field to get formatter for
|
||||
*/
|
||||
getFormatterForField(field: DataViewField | DataViewField['spec']): FieldFormat {
|
||||
const fieldFormat = this.getFormatterForFieldNoDefault(field.name);
|
||||
|
@ -350,7 +432,7 @@ export class DataView implements DataViewBase {
|
|||
|
||||
/**
|
||||
* Checks if runtime field exists
|
||||
* @param name
|
||||
* @param name field name
|
||||
*/
|
||||
hasRuntimeField(name: string): boolean {
|
||||
return !!this.runtimeFieldMap[name];
|
||||
|
@ -358,7 +440,7 @@ export class DataView implements DataViewBase {
|
|||
|
||||
/**
|
||||
* Returns runtime field if exists
|
||||
* @param name
|
||||
* @param name Runtime field name
|
||||
*/
|
||||
getRuntimeField(name: string): RuntimeField | null {
|
||||
if (!this.runtimeFieldMap[name]) {
|
||||
|
@ -378,6 +460,11 @@ export class DataView implements DataViewBase {
|
|||
return runtimeField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all runtime field definitions.
|
||||
* @returns map of runtime field definitions by field name
|
||||
*/
|
||||
|
||||
getAllRuntimeFields(): Record<string, RuntimeField> {
|
||||
return Object.keys(this.runtimeFieldMap).reduce<Record<string, RuntimeField>>(
|
||||
(acc, fieldName) => ({
|
||||
|
@ -388,6 +475,12 @@ export class DataView implements DataViewBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data view fields backed by runtime fields.
|
||||
* @param name runtime field name
|
||||
* @returns map of DataViewFields (that are runtime fields) by field name
|
||||
*/
|
||||
|
||||
getFieldsByRuntimeFieldName(name: string): Record<string, DataViewField> | undefined {
|
||||
const runtimeField = this.getRuntimeField(name);
|
||||
if (!runtimeField) {
|
||||
|
@ -418,8 +511,8 @@ export class DataView implements DataViewBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Replaces all existing runtime fields with new fields
|
||||
* @param newFields
|
||||
* Replaces all existing runtime fields with new fields.
|
||||
* @param newFields Map of runtime field definitions by field name
|
||||
*/
|
||||
replaceAllRuntimeFields(newFields: Record<string, RuntimeField>) {
|
||||
const oldRuntimeFieldNames = Object.keys(this.runtimeFieldMap);
|
||||
|
@ -452,7 +545,7 @@ export class DataView implements DataViewBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the "runtime_mappings" section of the ES search query
|
||||
* Return the "runtime_mappings" section of the ES search query.
|
||||
*/
|
||||
getRuntimeMappings(): estypes.MappingRuntimeFields {
|
||||
// @ts-expect-error The ES client does not yet include the "composite" runtime type
|
||||
|
@ -460,8 +553,8 @@ export class DataView implements DataViewBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get formatter for a given field name. Return undefined if none exists
|
||||
* @param field
|
||||
* Get formatter for a given field name. Return undefined if none exists.
|
||||
* @param fieldname name of field to get formatter for
|
||||
*/
|
||||
getFormatterForFieldNoDefault(fieldname: string) {
|
||||
const formatSpec = this.fieldFormatMap[fieldname];
|
||||
|
@ -470,6 +563,13 @@ export class DataView implements DataViewBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field attribute
|
||||
* @param fieldName name of field to set attribute on
|
||||
* @param attrName name of attribute to set
|
||||
* @param value value of attribute
|
||||
*/
|
||||
|
||||
protected setFieldAttrs<K extends keyof FieldAttrSet>(
|
||||
fieldName: string,
|
||||
attrName: K,
|
||||
|
@ -481,6 +581,12 @@ export class DataView implements DataViewBase {
|
|||
this.fieldAttrs[fieldName][attrName] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field custom label
|
||||
* @param fieldName name of field to set custom label on
|
||||
* @param customLabel custom label value. If undefined, custom label is removed
|
||||
*/
|
||||
|
||||
public setFieldCustomLabel(fieldName: string, customLabel: string | undefined | null) {
|
||||
const fieldObject = this.fields.getByName(fieldName);
|
||||
const newCustomLabel: string | undefined = customLabel === null ? undefined : customLabel;
|
||||
|
@ -492,6 +598,12 @@ export class DataView implements DataViewBase {
|
|||
this.setFieldAttrs(fieldName, 'customLabel', newCustomLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field count
|
||||
* @param fieldName name of field to set count on
|
||||
* @param count count value. If undefined, count is removed
|
||||
*/
|
||||
|
||||
public setFieldCount(fieldName: string, count: number | undefined | null) {
|
||||
const fieldObject = this.fields.getByName(fieldName);
|
||||
const newCount: number | undefined = count === null ? undefined : count;
|
||||
|
@ -503,14 +615,31 @@ export class DataView implements DataViewBase {
|
|||
this.setFieldAttrs(fieldName, 'count', newCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field formatter
|
||||
* @param fieldName name of field to set format on
|
||||
* @param format field format in serialized form
|
||||
*/
|
||||
public readonly setFieldFormat = (fieldName: string, format: SerializedFieldFormat) => {
|
||||
this.fieldFormatMap[fieldName] = format;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove field format from the field format map.
|
||||
* @param fieldName field name associated with the format for removal
|
||||
*/
|
||||
|
||||
public readonly deleteFieldFormat = (fieldName: string) => {
|
||||
delete this.fieldFormatMap[fieldName];
|
||||
};
|
||||
|
||||
/**
|
||||
* Add composite runtime field and all subfields.
|
||||
* @param name field name
|
||||
* @param runtimeField runtime field definition
|
||||
* @returns data view field instance
|
||||
*/
|
||||
|
||||
private addCompositeRuntimeField(name: string, runtimeField: RuntimeField): DataViewField[] {
|
||||
const { fields } = runtimeField;
|
||||
|
||||
|
|
|
@ -13,11 +13,8 @@ import { PublicMethodsOf } from '@kbn/utility-types';
|
|||
import { castEsToKbnFieldTypeName } from '@kbn/field-types';
|
||||
import { FieldFormatsStartCommon, FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common';
|
||||
import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/common';
|
||||
import {
|
||||
DATA_VIEW_SAVED_OBJECT_TYPE,
|
||||
DEFAULT_ASSETS_TO_IGNORE,
|
||||
SavedObjectsClientCommon,
|
||||
} from '..';
|
||||
import { DATA_VIEW_SAVED_OBJECT_TYPE, DEFAULT_ASSETS_TO_IGNORE } from '..';
|
||||
import { SavedObjectsClientCommon } from '../types';
|
||||
|
||||
import { createDataViewCache } from '.';
|
||||
import type { RuntimeField, RuntimeFieldSpec, RuntimeType } from '../types';
|
||||
|
@ -43,63 +40,214 @@ import { DuplicateDataViewError, DataViewInsufficientAccessError } from '../erro
|
|||
|
||||
const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3;
|
||||
|
||||
export type IndexPatternSavedObjectAttrs = Pick<DataViewAttributes, 'title' | 'type' | 'typeMeta'>;
|
||||
export type DataViewSavedObjectAttrs = Pick<DataViewAttributes, 'title' | 'type' | 'typeMeta'>;
|
||||
|
||||
export type IndexPatternListSavedObjectAttrs = Pick<
|
||||
DataViewAttributes,
|
||||
'title' | 'type' | 'typeMeta'
|
||||
>;
|
||||
|
||||
/**
|
||||
* Result from data view search - summary data.
|
||||
*/
|
||||
export interface DataViewListItem {
|
||||
/**
|
||||
* Saved object id
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Namespace ids
|
||||
*/
|
||||
namespaces?: string[];
|
||||
/**
|
||||
* Data view title
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Data view type
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* Data view type meta
|
||||
*/
|
||||
typeMeta?: TypeMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data views API service dependencies
|
||||
*/
|
||||
export interface DataViewsServiceDeps {
|
||||
/**
|
||||
* UiSettings service instance wrapped in a common interface
|
||||
*/
|
||||
uiSettings: UiSettingsCommon;
|
||||
/**
|
||||
* Saved objects client interface wrapped in a common interface
|
||||
*/
|
||||
savedObjectsClient: SavedObjectsClientCommon;
|
||||
/**
|
||||
* Wrapper around http call functionality so it can be used on client or server
|
||||
*/
|
||||
apiClient: IDataViewsApiClient;
|
||||
/**
|
||||
* Field formats service
|
||||
*/
|
||||
fieldFormats: FieldFormatsStartCommon;
|
||||
/**
|
||||
* Hander for service notifications
|
||||
*/
|
||||
onNotification: OnNotification;
|
||||
/**
|
||||
* Handler for service errors
|
||||
*/
|
||||
onError: OnError;
|
||||
/**
|
||||
* Redirects when there's no data view. only used on client
|
||||
*/
|
||||
onRedirectNoIndexPattern?: () => void;
|
||||
/**
|
||||
* Determines whether the user can save data views
|
||||
*/
|
||||
getCanSave: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data views API service methods
|
||||
* @public
|
||||
*/
|
||||
export interface DataViewsServicePublicMethods {
|
||||
/**
|
||||
* Clear the cache of data views.
|
||||
* @param id
|
||||
*/
|
||||
clearCache: (id?: string | undefined) => void;
|
||||
/**
|
||||
* Create data view based on the provided spec.
|
||||
* @param spec - Data view spec.
|
||||
* @param skipFetchFields - If true, do not fetch fields.
|
||||
*/
|
||||
create: (spec: DataViewSpec, skipFetchFields?: boolean) => Promise<DataView>;
|
||||
/**
|
||||
* Create and save data view based on provided spec.
|
||||
* @param spec - Data view spec.
|
||||
* @param override - If true, save over existing data view
|
||||
* @param skipFetchFields - If true, do not fetch fields.
|
||||
*/
|
||||
createAndSave: (
|
||||
spec: DataViewSpec,
|
||||
override?: boolean,
|
||||
skipFetchFields?: boolean
|
||||
) => Promise<DataView>;
|
||||
/**
|
||||
* Save data view
|
||||
* @param dataView - Data view instance to save.
|
||||
* @param override - If true, save over existing data view
|
||||
*/
|
||||
createSavedObject: (indexPattern: DataView, override?: boolean) => Promise<DataView>;
|
||||
/**
|
||||
* Delete data view
|
||||
* @param indexPatternId - Id of the data view to delete.
|
||||
*/
|
||||
delete: (indexPatternId: string) => Promise<{}>;
|
||||
/**
|
||||
* @deprecated Use `getDefaultDataView` instead (when loading data view) and handle
|
||||
* 'no data view' case in api consumer code - no more auto redirect
|
||||
*/
|
||||
ensureDefaultDataView: EnsureDefaultDataView;
|
||||
/**
|
||||
* Takes field array and field attributes and returns field map by name.
|
||||
* @param fields - Array of fieldspecs
|
||||
* @params fieldAttrs - Field attributes, map by name
|
||||
* @returns Field map by name
|
||||
*/
|
||||
fieldArrayToMap: (fields: FieldSpec[], fieldAttrs?: FieldAttrs | undefined) => DataViewFieldMap;
|
||||
/**
|
||||
* Search for data views based on title
|
||||
* @param search - Search string
|
||||
* @param size - Number of results to return
|
||||
*/
|
||||
find: (search: string, size?: number) => Promise<DataView[]>;
|
||||
/**
|
||||
* Get data view by id.
|
||||
* @param id - Id of the data view to get.
|
||||
*/
|
||||
get: (id: string) => Promise<DataView>;
|
||||
getCache: () => Promise<Array<SavedObject<IndexPatternSavedObjectAttrs>> | null | undefined>;
|
||||
/**
|
||||
* Get populated data view saved object cache.
|
||||
*/
|
||||
getCache: () => Promise<Array<SavedObject<DataViewSavedObjectAttrs>> | null | undefined>;
|
||||
/**
|
||||
* If user can save data view, return true.
|
||||
*/
|
||||
getCanSave: () => Promise<boolean>;
|
||||
/**
|
||||
* Get default data view as data view instance.
|
||||
*/
|
||||
getDefault: () => Promise<DataView | null>;
|
||||
/**
|
||||
* Get default data view id.
|
||||
*/
|
||||
getDefaultId: () => Promise<string | null>;
|
||||
/**
|
||||
* Get default data view, if it doesn't exist, choose and save new default data view and return it.
|
||||
*/
|
||||
getDefaultDataView: () => Promise<DataView | null>;
|
||||
/**
|
||||
* Get fields for data view
|
||||
* @param dataView - Data view instance or spec
|
||||
* @param options - Options for getting fields
|
||||
* @returns FieldSpec array
|
||||
*/
|
||||
getFieldsForIndexPattern: (
|
||||
indexPattern: DataView | DataViewSpec,
|
||||
options?: GetFieldsOptions | undefined
|
||||
) => Promise<FieldSpec[]>;
|
||||
/**
|
||||
* Get fields for index pattern string
|
||||
* @param options - options for getting fields
|
||||
*/
|
||||
getFieldsForWildcard: (options: GetFieldsOptions) => Promise<FieldSpec[]>;
|
||||
/**
|
||||
* Get list of data view ids.
|
||||
* @param refresh - clear cache and fetch from server
|
||||
*/
|
||||
getIds: (refresh?: boolean) => Promise<string[]>;
|
||||
/**
|
||||
* Get list of data view ids and title (and more) for each data view.
|
||||
* @param refresh - clear cache and fetch from server
|
||||
*/
|
||||
getIdsWithTitle: (refresh?: boolean) => Promise<DataViewListItem[]>;
|
||||
/**
|
||||
* Get list of data view ids and title (and more) for each data view.
|
||||
* @param refresh - clear cache and fetch from server
|
||||
*/
|
||||
getTitles: (refresh?: boolean) => Promise<string[]>;
|
||||
/**
|
||||
* Returns true if user has access to view a data view.
|
||||
*/
|
||||
hasUserDataView: () => Promise<boolean>;
|
||||
/**
|
||||
* Refresh fields for data view instance
|
||||
* @params dataView - Data view instance
|
||||
*/
|
||||
refreshFields: (indexPattern: DataView) => Promise<void>;
|
||||
/**
|
||||
* Converts data view saved object to spec
|
||||
* @params savedObject - Data view saved object
|
||||
*/
|
||||
savedObjectToSpec: (savedObject: SavedObject<DataViewAttributes>) => DataViewSpec;
|
||||
/**
|
||||
* Set default data view.
|
||||
* @param id - Id of the data view to set as default.
|
||||
* @param force - Overwrite if true
|
||||
*/
|
||||
setDefault: (id: string | null, force?: boolean) => Promise<void>;
|
||||
/**
|
||||
* Save saved object
|
||||
* @param indexPattern - data view instance
|
||||
* @param saveAttempts - number of times to try saving
|
||||
* @oaram ignoreErrors - if true, do not throw error on failure
|
||||
*/
|
||||
updateSavedObject: (
|
||||
indexPattern: DataView,
|
||||
saveAttempts?: number,
|
||||
|
@ -107,25 +255,32 @@ export interface DataViewsServicePublicMethods {
|
|||
) => Promise<void | Error>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data views service, providing CRUD operations for data views.
|
||||
* @public
|
||||
*/
|
||||
export class DataViewsService {
|
||||
private config: UiSettingsCommon;
|
||||
private savedObjectsClient: SavedObjectsClientCommon;
|
||||
private savedObjectsCache?: Array<SavedObject<IndexPatternSavedObjectAttrs>> | null;
|
||||
private savedObjectsCache?: Array<SavedObject<DataViewSavedObjectAttrs>> | null;
|
||||
private apiClient: IDataViewsApiClient;
|
||||
private fieldFormats: FieldFormatsStartCommon;
|
||||
/**
|
||||
* Handler for service notifications
|
||||
* Handler for service notifications
|
||||
* @param toastInputFields notification content in toast format
|
||||
* @param key used to indicate uniqueness of the notification
|
||||
*/
|
||||
private onNotification: OnNotification;
|
||||
/*
|
||||
* Handler for service errors
|
||||
* Handler for service errors
|
||||
* @param error notification content in toast format
|
||||
* @param key used to indicate uniqueness of the error
|
||||
*/
|
||||
private onError: OnError;
|
||||
private dataViewCache: ReturnType<typeof createDataViewCache>;
|
||||
/**
|
||||
* Can the user save data views?
|
||||
*/
|
||||
public getCanSave: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
|
@ -134,33 +289,38 @@ export class DataViewsService {
|
|||
*/
|
||||
ensureDefaultDataView: EnsureDefaultDataView;
|
||||
|
||||
constructor({
|
||||
uiSettings,
|
||||
savedObjectsClient,
|
||||
apiClient,
|
||||
fieldFormats,
|
||||
onNotification,
|
||||
onError,
|
||||
onRedirectNoIndexPattern = () => {},
|
||||
getCanSave = () => Promise.resolve(false),
|
||||
}: DataViewsServiceDeps) {
|
||||
/**
|
||||
* DataViewsService constructor
|
||||
* @param deps Service dependencies
|
||||
*/
|
||||
constructor(deps: DataViewsServiceDeps) {
|
||||
const {
|
||||
uiSettings,
|
||||
savedObjectsClient,
|
||||
apiClient,
|
||||
fieldFormats,
|
||||
onNotification,
|
||||
onError,
|
||||
onRedirectNoIndexPattern = () => {},
|
||||
getCanSave = () => Promise.resolve(false),
|
||||
} = deps;
|
||||
this.apiClient = apiClient;
|
||||
this.config = uiSettings;
|
||||
this.savedObjectsClient = savedObjectsClient;
|
||||
this.fieldFormats = fieldFormats;
|
||||
this.onNotification = onNotification;
|
||||
this.onError = onError;
|
||||
this.ensureDefaultDataView = createEnsureDefaultDataView(uiSettings, onRedirectNoIndexPattern);
|
||||
this.ensureDefaultDataView = createEnsureDefaultDataView(onRedirectNoIndexPattern);
|
||||
this.getCanSave = getCanSave;
|
||||
|
||||
this.dataViewCache = createDataViewCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh cache of index pattern ids and titles
|
||||
* Refresh cache of index pattern ids and titles.
|
||||
*/
|
||||
private async refreshSavedObjectsCache() {
|
||||
const so = await this.savedObjectsClient.find<IndexPatternSavedObjectAttrs>({
|
||||
const so = await this.savedObjectsClient.find<DataViewSavedObjectAttrs>({
|
||||
type: DATA_VIEW_SAVED_OBJECT_TYPE,
|
||||
fields: ['title', 'type', 'typeMeta'],
|
||||
perPage: 10000,
|
||||
|
@ -169,7 +329,7 @@ export class DataViewsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get list of index pattern ids
|
||||
* Gets list of index pattern ids.
|
||||
* @param refresh Force refresh of index pattern list
|
||||
*/
|
||||
getIds = async (refresh: boolean = false) => {
|
||||
|
@ -183,7 +343,7 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get list of index pattern titles
|
||||
* Gets list of index pattern titles.
|
||||
* @param refresh Force refresh of index pattern list
|
||||
*/
|
||||
getTitles = async (refresh: boolean = false): Promise<string[]> => {
|
||||
|
@ -197,13 +357,13 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Find and load index patterns by title
|
||||
* @param search
|
||||
* @param size
|
||||
* @returns IndexPattern[]
|
||||
* Find and load index patterns by title.
|
||||
* @param search Search string
|
||||
* @param size Number of data views to return
|
||||
* @returns DataView[]
|
||||
*/
|
||||
find = async (search: string, size: number = 10): Promise<DataView[]> => {
|
||||
const savedObjects = await this.savedObjectsClient.find<IndexPatternSavedObjectAttrs>({
|
||||
const savedObjects = await this.savedObjectsClient.find<DataViewSavedObjectAttrs>({
|
||||
type: DATA_VIEW_SAVED_OBJECT_TYPE,
|
||||
fields: ['title'],
|
||||
search,
|
||||
|
@ -217,7 +377,7 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get list of index pattern ids with titles
|
||||
* Gets list of index pattern ids with titles.
|
||||
* @param refresh Force refresh of index pattern list
|
||||
*/
|
||||
getIdsWithTitle = async (refresh: boolean = false): Promise<DataViewListItem[]> => {
|
||||
|
@ -237,7 +397,7 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Clear index pattern list cache
|
||||
* Clear index pattern list cache.
|
||||
* @param id optionally clear a single id
|
||||
*/
|
||||
clearCache = (id?: string) => {
|
||||
|
@ -249,6 +409,10 @@ export class DataViewsService {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get cache, contains data view saved objects.
|
||||
*/
|
||||
|
||||
getCache = async () => {
|
||||
if (!this.savedObjectsCache) {
|
||||
await this.refreshSavedObjectsCache();
|
||||
|
@ -278,8 +442,8 @@ export class DataViewsService {
|
|||
|
||||
/**
|
||||
* Optionally set default index pattern, unless force = true
|
||||
* @param id
|
||||
* @param force
|
||||
* @param id data view id
|
||||
* @param force set default data view even if there's an existing default
|
||||
*/
|
||||
setDefault = async (id: string | null, force = false) => {
|
||||
if (force || !(await this.config.get('defaultIndex'))) {
|
||||
|
@ -288,15 +452,15 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Checks if current user has a user created index pattern ignoring fleet's server default index patterns
|
||||
* Checks if current user has a user created index pattern ignoring fleet's server default index patterns.
|
||||
*/
|
||||
async hasUserDataView(): Promise<boolean> {
|
||||
return this.apiClient.hasUserIndexPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field list by providing { pattern }
|
||||
* @param options
|
||||
* Get field list by providing { pattern }.
|
||||
* @param options options for getting field list
|
||||
* @returns FieldSpec[]
|
||||
*/
|
||||
getFieldsForWildcard = async (options: GetFieldsOptions): Promise<FieldSpec[]> => {
|
||||
|
@ -312,8 +476,8 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get field list by providing an index patttern (or spec)
|
||||
* @param options
|
||||
* Get field list by providing an index patttern (or spec).
|
||||
* @param options options for getting field list
|
||||
* @returns FieldSpec[]
|
||||
*/
|
||||
getFieldsForIndexPattern = async (
|
||||
|
@ -328,7 +492,7 @@ export class DataViewsService {
|
|||
});
|
||||
|
||||
/**
|
||||
* Refresh field list for a given index pattern
|
||||
* Refresh field list for a given index pattern.
|
||||
* @param indexPattern
|
||||
*/
|
||||
refreshFields = async (indexPattern: DataView) => {
|
||||
|
@ -363,7 +527,7 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Refreshes a field list from a spec before an index pattern instance is created
|
||||
* Refreshes a field list from a spec before an index pattern instance is created.
|
||||
* @param fields
|
||||
* @param id
|
||||
* @param title
|
||||
|
@ -417,7 +581,7 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Converts field array to map
|
||||
* Converts field array to map.
|
||||
* @param fields: FieldSpec[]
|
||||
* @param fieldAttrs: FieldAttrs
|
||||
* @returns Record<string, FieldSpec>
|
||||
|
@ -433,7 +597,7 @@ export class DataViewsService {
|
|||
}, {});
|
||||
|
||||
/**
|
||||
* Converts index pattern saved object to index pattern spec
|
||||
* Converts data view saved object to data view spec.
|
||||
* @param savedObject
|
||||
* @returns DataViewSpec
|
||||
*/
|
||||
|
@ -586,7 +750,7 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get an index pattern by id. Cache optimized
|
||||
* Get an index pattern by id, cache optimized.
|
||||
* @param id
|
||||
*/
|
||||
|
||||
|
@ -603,10 +767,10 @@ export class DataViewsService {
|
|||
};
|
||||
|
||||
/**
|
||||
* Create a new index pattern instance
|
||||
* @param spec
|
||||
* @param skipFetchFields
|
||||
* @returns IndexPattern
|
||||
* Create a new data view instance.
|
||||
* @param spec data view spec
|
||||
* @param skipFetchFields if true, will not fetch fields
|
||||
* @returns DataView
|
||||
*/
|
||||
async create(spec: DataViewSpec, skipFetchFields = false): Promise<DataView> {
|
||||
const shortDotsEnable = await this.config.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE);
|
||||
|
@ -627,8 +791,8 @@ export class DataViewsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a new index pattern and save it right away
|
||||
* @param spec
|
||||
* Create a new data view and save it right away.
|
||||
* @param spec data view spec
|
||||
* @param override Overwrite if existing index pattern exists.
|
||||
* @param skipFetchFields Whether to skip field refresh step.
|
||||
*/
|
||||
|
@ -641,30 +805,30 @@ export class DataViewsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Save a new index pattern
|
||||
* @param indexPattern
|
||||
* Save a new data view.
|
||||
* @param dataView data view instance
|
||||
* @param override Overwrite if existing index pattern exists
|
||||
*/
|
||||
|
||||
async createSavedObject(indexPattern: DataView, override = false) {
|
||||
async createSavedObject(dataView: DataView, override = false) {
|
||||
if (!(await this.getCanSave())) {
|
||||
throw new DataViewInsufficientAccessError();
|
||||
}
|
||||
const dupe = await findByTitle(this.savedObjectsClient, indexPattern.title);
|
||||
const dupe = await findByTitle(this.savedObjectsClient, dataView.title);
|
||||
if (dupe) {
|
||||
if (override) {
|
||||
await this.delete(dupe.id);
|
||||
} else {
|
||||
throw new DuplicateDataViewError(`Duplicate index pattern: ${indexPattern.title}`);
|
||||
throw new DuplicateDataViewError(`Duplicate data view: ${dataView.title}`);
|
||||
}
|
||||
}
|
||||
|
||||
const body = indexPattern.getAsSavedObjectBody();
|
||||
const body = dataView.getAsSavedObjectBody();
|
||||
const response: SavedObject<DataViewAttributes> = (await this.savedObjectsClient.create(
|
||||
DATA_VIEW_SAVED_OBJECT_TYPE,
|
||||
body,
|
||||
{
|
||||
id: indexPattern.id,
|
||||
id: dataView.id,
|
||||
}
|
||||
)) as SavedObject<DataViewAttributes>;
|
||||
|
||||
|
@ -677,7 +841,7 @@ export class DataViewsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Save existing index pattern. Will attempt to merge differences if there are conflicts
|
||||
* Save existing dat aview. Will attempt to merge differences if there are conflicts.
|
||||
* @param indexPattern
|
||||
* @param saveAttempts
|
||||
*/
|
||||
|
@ -773,7 +937,7 @@ export class DataViewsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deletes an index pattern from .kibana index
|
||||
* Deletes an index pattern from .kibana index.
|
||||
* @param indexPatternId: Id of kibana Index Pattern to delete
|
||||
*/
|
||||
async delete(indexPatternId: string) {
|
||||
|
@ -788,7 +952,7 @@ export class DataViewsService {
|
|||
* Returns the default data view as an object.
|
||||
* If no default is found, or it is missing
|
||||
* another data view is selected as default and returned.
|
||||
* If no possible data view found to become a default returns null
|
||||
* If no possible data view found to become a default returns null.
|
||||
*
|
||||
* @returns default data view
|
||||
*/
|
||||
|
@ -828,4 +992,9 @@ export class DataViewsService {
|
|||
*/
|
||||
export class IndexPatternsService extends DataViewsService {}
|
||||
|
||||
/**
|
||||
* Data views service interface
|
||||
* @public
|
||||
*/
|
||||
|
||||
export type DataViewsContract = PublicMethodsOf<DataViewsService>;
|
||||
|
|
|
@ -7,18 +7,21 @@
|
|||
*/
|
||||
|
||||
import { DataViewsContract } from './data_views';
|
||||
import { UiSettingsCommon } from '../types';
|
||||
/**
|
||||
* Checks whether a default data view is set and exists and defines
|
||||
* one otherwise.
|
||||
* @public
|
||||
*/
|
||||
export type EnsureDefaultDataView = () => Promise<void> | void;
|
||||
|
||||
export type EnsureDefaultDataView = () => Promise<unknown> | undefined;
|
||||
|
||||
export const createEnsureDefaultDataView = (
|
||||
uiSettings: UiSettingsCommon,
|
||||
onRedirectNoDefaultView: () => Promise<unknown> | void
|
||||
) => {
|
||||
/**
|
||||
* Checks whether a default data view is set and exists and defines
|
||||
* one otherwise.
|
||||
*/
|
||||
/**
|
||||
* Checks whether a default data view is set and exists and defines
|
||||
* one otherwise.
|
||||
* @public
|
||||
* @param onRedirectNoDefaultView - Callback to redirect to a new data view
|
||||
* @return returned promise resolves when the default data view is set
|
||||
*/
|
||||
export const createEnsureDefaultDataView = (onRedirectNoDefaultView: EnsureDefaultDataView) => {
|
||||
return async function ensureDefaultDataView(this: DataViewsContract) {
|
||||
if (!(await this.getDefaultDataView())) {
|
||||
return onRedirectNoDefaultView();
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error thrown when saved object has been changed when attempting to save.
|
||||
*/
|
||||
export class DataViewSavedObjectConflictError extends Error {
|
||||
/**
|
||||
* constructor
|
||||
* @param savedObjectId saved object id with conflict
|
||||
*/
|
||||
constructor(savedObjectId: string) {
|
||||
super(`Conflict loading DataView saved object, id: ${savedObjectId}`);
|
||||
this.name = 'DataViewSavedObjectConflictError';
|
||||
|
|
|
@ -6,7 +6,15 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error thrown when attempting to create duplicate index pattern based on title.
|
||||
* @public
|
||||
*/
|
||||
export class DuplicateDataViewError extends Error {
|
||||
/**
|
||||
* constructor
|
||||
* @param message - Error message
|
||||
*/
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'DuplicateDataViewError';
|
||||
|
|
|
@ -6,7 +6,16 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error thrown when action attempted without sufficient access.
|
||||
* @constructor
|
||||
* @param {string} message - Saved object id of data view for display in error message
|
||||
*/
|
||||
export class DataViewInsufficientAccessError extends Error {
|
||||
/**
|
||||
* constructor
|
||||
* @param {string} message - Saved object id of data view for display in error message
|
||||
*/
|
||||
constructor(savedObjectId?: string) {
|
||||
super(`Operation failed due to insufficient access, id: ${savedObjectId}`);
|
||||
this.name = 'DataViewInsufficientAccessError';
|
||||
|
|
|
@ -15,8 +15,18 @@ import { DataViewSpec } from '..';
|
|||
const name = 'indexPatternLoad';
|
||||
const type = 'index_pattern';
|
||||
|
||||
/**
|
||||
* Index pattern expression interface
|
||||
* @public
|
||||
*/
|
||||
export interface IndexPatternExpressionType {
|
||||
/**
|
||||
* Expression type
|
||||
*/
|
||||
type: typeof type;
|
||||
/**
|
||||
* Value - DataViewSpec
|
||||
*/
|
||||
value: DataViewSpec;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,34 @@ import {
|
|||
getDataViewFieldSubtypeNested,
|
||||
} from './utils';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Optional format getter when serializing a field
|
||||
* @public
|
||||
*/
|
||||
export interface ToSpecConfig {
|
||||
/**
|
||||
* Field format getter
|
||||
*/
|
||||
getFormatterForField?: DataView['getFormatterForField'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Data view field class
|
||||
* @public
|
||||
*/
|
||||
export class DataViewField implements DataViewFieldBase {
|
||||
readonly spec: FieldSpec;
|
||||
// not writable or serialized
|
||||
/**
|
||||
* Kbn field type, used mainly for formattering.
|
||||
*/
|
||||
private readonly kbnFieldType: KbnFieldType;
|
||||
|
||||
/**
|
||||
* DataView constructor
|
||||
* @constructor
|
||||
* @param spec Configuration for the field
|
||||
*/
|
||||
constructor(spec: FieldSpec) {
|
||||
this.spec = { ...spec, type: spec.name === '_source' ? '_source' : spec.type };
|
||||
|
||||
|
@ -33,20 +55,32 @@ export class DataViewField implements DataViewFieldBase {
|
|||
|
||||
// writable attrs
|
||||
/**
|
||||
* Count is used for field popularity
|
||||
* Count is used for field popularity in discover.
|
||||
*/
|
||||
public get count() {
|
||||
return this.spec.count || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set count, which is used for field popularity in discover.
|
||||
* @param count count number
|
||||
*/
|
||||
public set count(count: number) {
|
||||
this.spec.count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns runtime field definition or undefined if field is not runtime field.
|
||||
*/
|
||||
|
||||
public get runtimeField() {
|
||||
return this.spec.runtimeField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets runtime field definition or unsets if undefined is provided.
|
||||
* @param runtimeField runtime field definition
|
||||
*/
|
||||
public set runtimeField(runtimeField: RuntimeFieldSpec | undefined) {
|
||||
this.spec.runtimeField = runtimeField;
|
||||
}
|
||||
|
@ -58,6 +92,10 @@ export class DataViewField implements DataViewFieldBase {
|
|||
return this.spec.script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets scripted field painless code
|
||||
* @param script Painless code
|
||||
*/
|
||||
public set script(script) {
|
||||
this.spec.script = script;
|
||||
}
|
||||
|
@ -69,34 +107,59 @@ export class DataViewField implements DataViewFieldBase {
|
|||
return this.spec.lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets scripted field langauge.
|
||||
* @param lang Scripted field language
|
||||
*/
|
||||
public set lang(lang) {
|
||||
this.spec.lang = lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns custom label if set, otherwise undefined.
|
||||
*/
|
||||
|
||||
public get customLabel() {
|
||||
return this.spec.customLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets custom label for field, or unsets if passed undefined.
|
||||
* @param customLabel custom label value
|
||||
*/
|
||||
public set customLabel(customLabel) {
|
||||
this.spec.customLabel = customLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of field type conflicts across different indices in the same index pattern
|
||||
* Description of field type conflicts across different indices in the same index pattern.
|
||||
*/
|
||||
public get conflictDescriptions() {
|
||||
return this.spec.conflictDescriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets conflict descriptions for field.
|
||||
* @param conflictDescriptions conflict descriptions
|
||||
*/
|
||||
|
||||
public set conflictDescriptions(conflictDescriptions) {
|
||||
this.spec.conflictDescriptions = conflictDescriptions;
|
||||
}
|
||||
|
||||
// read only attrs
|
||||
|
||||
/**
|
||||
* Get field name
|
||||
*/
|
||||
public get name() {
|
||||
return this.spec.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets display name, calcualted based on name, custom label and shortDotsEnable.
|
||||
*/
|
||||
|
||||
public get displayName(): string {
|
||||
return this.spec.customLabel
|
||||
? this.spec.customLabel
|
||||
|
@ -105,30 +168,57 @@ export class DataViewField implements DataViewFieldBase {
|
|||
: this.spec.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets field type
|
||||
*/
|
||||
public get type() {
|
||||
return this.spec.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ES types as string array
|
||||
*/
|
||||
|
||||
public get esTypes() {
|
||||
return this.spec.esTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if scripted field
|
||||
*/
|
||||
|
||||
public get scripted() {
|
||||
return !!this.spec.scripted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is searchable
|
||||
*/
|
||||
|
||||
public get searchable() {
|
||||
return !!(this.spec.searchable || this.scripted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is aggregatable
|
||||
*/
|
||||
|
||||
public get aggregatable() {
|
||||
return !!(this.spec.aggregatable || this.scripted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is available via doc values
|
||||
*/
|
||||
|
||||
public get readFromDocValues() {
|
||||
return !!(this.spec.readFromDocValues && !this.scripted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns field subtype, multi, nested, or undefined if neither
|
||||
*/
|
||||
|
||||
public get subType() {
|
||||
return this.spec.subType;
|
||||
}
|
||||
|
@ -140,11 +230,19 @@ export class DataViewField implements DataViewFieldBase {
|
|||
return this.spec.isMapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if runtime field defined on data view
|
||||
*/
|
||||
|
||||
public get isRuntimeField() {
|
||||
return !this.isMapped && this.runtimeField !== undefined;
|
||||
}
|
||||
|
||||
// not writable, not serialized
|
||||
|
||||
/**
|
||||
* Returns true if field is sortable
|
||||
*/
|
||||
public get sortable() {
|
||||
return (
|
||||
this.name === '_score' ||
|
||||
|
@ -152,6 +250,10 @@ export class DataViewField implements DataViewFieldBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is filterable
|
||||
*/
|
||||
|
||||
public get filterable() {
|
||||
return (
|
||||
this.name === '_id' ||
|
||||
|
@ -160,31 +262,57 @@ export class DataViewField implements DataViewFieldBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is visualizable
|
||||
*/
|
||||
|
||||
public get visualizable() {
|
||||
const notVisualizableFieldTypes: string[] = [KBN_FIELD_TYPES.UNKNOWN, KBN_FIELD_TYPES.CONFLICT];
|
||||
return this.aggregatable && !notVisualizableFieldTypes.includes(this.spec.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is subtype nested
|
||||
*/
|
||||
public isSubtypeNested() {
|
||||
return isDataViewFieldSubtypeNested(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is subtype multi
|
||||
*/
|
||||
|
||||
public isSubtypeMulti() {
|
||||
return isDataViewFieldSubtypeMulti(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns subtype nested data if exists
|
||||
*/
|
||||
|
||||
public getSubtypeNested() {
|
||||
return getDataViewFieldSubtypeNested(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns subtype multi data if exists
|
||||
*/
|
||||
|
||||
public getSubtypeMulti() {
|
||||
return getDataViewFieldSubtypeMulti(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes count value. Popularity as used by discover
|
||||
*/
|
||||
|
||||
public deleteCount() {
|
||||
delete this.spec.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON version of field
|
||||
*/
|
||||
public toJSON() {
|
||||
return {
|
||||
count: this.count,
|
||||
|
@ -203,11 +331,14 @@ export class DataViewField implements DataViewFieldBase {
|
|||
};
|
||||
}
|
||||
|
||||
public toSpec({
|
||||
getFormatterForField,
|
||||
}: {
|
||||
getFormatterForField?: DataView['getFormatterForField'];
|
||||
} = {}): FieldSpec {
|
||||
/**
|
||||
* Get field in serialized form - fieldspec.
|
||||
* @param config provide a method to get a field formatter
|
||||
* @returns field in serialized form - field spec
|
||||
*/
|
||||
public toSpec(config: ToSpecConfig = {}): FieldSpec {
|
||||
const { getFormatterForField } = config;
|
||||
|
||||
return {
|
||||
count: this.count,
|
||||
script: this.script,
|
||||
|
@ -229,6 +360,10 @@ export class DataViewField implements DataViewFieldBase {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if composite runtime field
|
||||
*/
|
||||
|
||||
public isRuntimeCompositeSubField() {
|
||||
return this.runtimeField?.type === 'composite';
|
||||
}
|
||||
|
|
|
@ -13,21 +13,66 @@ import { DataView } from '../data_views';
|
|||
|
||||
type FieldMap = Map<DataViewField['name'], DataViewField>;
|
||||
|
||||
export interface IIndexPatternFieldList extends Array<DataViewField> {
|
||||
add(field: FieldSpec): DataViewField;
|
||||
getAll(): DataViewField[];
|
||||
getByName(name: DataViewField['name']): DataViewField | undefined;
|
||||
getByType(type: DataViewField['type']): DataViewField[];
|
||||
remove(field: DataViewField | FieldSpec): void;
|
||||
removeAll(): void;
|
||||
replaceAll(specs: FieldSpec[]): void;
|
||||
update(field: FieldSpec): void;
|
||||
toSpec(options?: { getFormatterForField?: DataView['getFormatterForField'] }): DataViewFieldMap;
|
||||
interface ToSpecOptions {
|
||||
getFormatterForField?: DataView['getFormatterForField'];
|
||||
}
|
||||
|
||||
// extending the array class and using a constructor doesn't work well
|
||||
/**
|
||||
* Interface for data view field list which _extends_ the array class.
|
||||
*/
|
||||
export interface IIndexPatternFieldList extends Array<DataViewField> {
|
||||
/**
|
||||
* Add field to field list.
|
||||
* @param field field spec to add field to list
|
||||
* @returns data view field instance which was added to list
|
||||
*/
|
||||
add(field: FieldSpec): DataViewField;
|
||||
/**
|
||||
* Returns fields as plain array of data view field instances.
|
||||
*/
|
||||
getAll(): DataViewField[];
|
||||
/**
|
||||
* Get field by name. Optimized, uses map to find field.
|
||||
* @param name name of field to find
|
||||
* @returns data view field instance if found, undefined otherwise
|
||||
*/
|
||||
getByName(name: DataViewField['name']): DataViewField | undefined;
|
||||
/**
|
||||
* Get fields by field type. Optimized, uses map to find fields.
|
||||
* @param type type of field to find
|
||||
* @returns array of data view field instances if found, empty array otherwise
|
||||
*/
|
||||
getByType(type: DataViewField['type']): DataViewField[];
|
||||
/**
|
||||
* Remove field from field list
|
||||
* @param field field for removal
|
||||
*/
|
||||
remove(field: DataViewField | FieldSpec): void;
|
||||
/**
|
||||
* Remove all fields from field list.
|
||||
*/
|
||||
removeAll(): void;
|
||||
/**
|
||||
* Replace all fields in field list with new fields.
|
||||
* @param specs array of field specs to add to list
|
||||
*/
|
||||
replaceAll(specs: FieldSpec[]): void;
|
||||
/**
|
||||
* Update a field in the list
|
||||
* @param field field spec to update
|
||||
*/
|
||||
update(field: FieldSpec): void;
|
||||
/**
|
||||
* Field list as field spec map by name
|
||||
* @param options optionally provide a function to get field formatter for fields
|
||||
* @return map of field specs by name
|
||||
*/
|
||||
toSpec(options?: ToSpecOptions): DataViewFieldMap;
|
||||
}
|
||||
|
||||
// Extending the array class and using a constructor doesn't work well
|
||||
// when calling filter and similar so wrapping in a callback.
|
||||
// to be removed in the future
|
||||
// To be removed in the future
|
||||
export const fieldList = (
|
||||
specs: FieldSpec[] = [],
|
||||
shortDotsEnable = false
|
||||
|
|
|
@ -55,6 +55,12 @@ export function isDataViewFieldSubtypeMulti(field: HasSubtype) {
|
|||
return !!subTypeNested?.multi?.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns subtype data for multi field
|
||||
* @public
|
||||
* @param field field to get subtype data from
|
||||
*/
|
||||
|
||||
export function getDataViewFieldSubtypeMulti(field: HasSubtype) {
|
||||
return isDataViewFieldSubtypeMulti(field) ? (field.subType as IFieldSubTypeMulti) : undefined;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ export {
|
|||
META_FIELDS,
|
||||
DATA_VIEW_SAVED_OBJECT_TYPE,
|
||||
} from './constants';
|
||||
|
||||
export type { ToSpecConfig } from './fields';
|
||||
export type { IIndexPatternFieldList } from './fields';
|
||||
export {
|
||||
isFilterable,
|
||||
|
@ -29,12 +31,9 @@ export type {
|
|||
RuntimeFieldSpec,
|
||||
RuntimeFieldSubField,
|
||||
DataViewAttributes,
|
||||
FieldAttrs,
|
||||
FieldAttrSet,
|
||||
OnNotification,
|
||||
OnError,
|
||||
UiSettingsCommon,
|
||||
SavedObjectsClientCommonFindArgs,
|
||||
SavedObjectsClientCommon,
|
||||
GetFieldsOptions,
|
||||
IDataViewsApiClient,
|
||||
|
@ -42,15 +41,22 @@ export type {
|
|||
AggregationRestrictions,
|
||||
TypeMeta,
|
||||
FieldSpecConflictDescriptions,
|
||||
FieldSpecExportFmt,
|
||||
FieldSpec,
|
||||
DataViewFieldMap,
|
||||
DataViewSpec,
|
||||
SourceFilter,
|
||||
HasDataService,
|
||||
RuntimeTypeExceptComposite,
|
||||
RuntimeFieldBase,
|
||||
FieldConfiguration,
|
||||
SavedObjectsClientCommonFindArgs,
|
||||
FieldAttrs,
|
||||
FieldAttrSet,
|
||||
} from './types';
|
||||
export { DataViewType } from './types';
|
||||
export type { DataViewsContract } from './data_views';
|
||||
|
||||
export type { DataViewsContract, DataViewsServiceDeps } from './data_views';
|
||||
export type { EnsureDefaultDataView } from './data_views/ensure_default_data_view';
|
||||
export { IndexPatternsService, DataViewsService } from './data_views';
|
||||
export type {
|
||||
DataViewListItem,
|
||||
|
|
|
@ -6,7 +6,19 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error code for when an index pattern contains illegal characters
|
||||
*/
|
||||
export const ILLEGAL_CHARACTERS_KEY = 'ILLEGAL_CHARACTERS';
|
||||
/**
|
||||
* Error code for when an index pattern contains spaces
|
||||
*/
|
||||
export const CONTAINS_SPACES_KEY = 'CONTAINS_SPACES';
|
||||
/**
|
||||
* Characters disallowed in index patterns that are visible.
|
||||
*/
|
||||
export const ILLEGAL_CHARACTERS_VISIBLE = ['\\', '/', '?', '"', '<', '>', '|'];
|
||||
/**
|
||||
* All characters disallowed in index patterns.
|
||||
*/
|
||||
export const ILLEGAL_CHARACTERS = ILLEGAL_CHARACTERS_VISIBLE.concat(' ');
|
||||
|
|
|
@ -23,6 +23,13 @@ function findIllegalCharacters(indexPattern: string): string[] {
|
|||
return illegalCharacters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate index pattern strings
|
||||
* @public
|
||||
* @param indexPattern string to validate
|
||||
* @returns errors object
|
||||
*/
|
||||
|
||||
export function validateDataView(indexPattern: string) {
|
||||
const errors: { [ILLEGAL_CHARACTERS_KEY]?: string[]; [CONTAINS_SPACES_KEY]?: boolean } = {};
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 { CONTAINS_SPACES_KEY, ILLEGAL_CHARACTERS_KEY, ILLEGAL_CHARACTERS_VISIBLE } from './types';
|
||||
|
||||
import { validateDataView } from './validate_data_view';
|
||||
|
||||
describe('Index Pattern Utils', () => {
|
||||
describe('Validation', () => {
|
||||
it('should not allow space in the pattern', () => {
|
||||
const errors = validateDataView('my pattern');
|
||||
expect(errors[CONTAINS_SPACES_KEY]).toBe(true);
|
||||
});
|
||||
|
||||
it('should not allow illegal characters', () => {
|
||||
ILLEGAL_CHARACTERS_VISIBLE.forEach((char) => {
|
||||
const errors = validateDataView(`pattern${char}`);
|
||||
expect(errors[ILLEGAL_CHARACTERS_KEY]).toEqual([char]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return empty object when there are no errors', () => {
|
||||
expect(validateDataView('my-pattern-*')).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
46
src/plugins/data_views/common/lib/validate_index_pattern.ts
Normal file
46
src/plugins/data_views/common/lib/validate_index_pattern.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 { ILLEGAL_CHARACTERS_VISIBLE, CONTAINS_SPACES_KEY, ILLEGAL_CHARACTERS_KEY } from './types';
|
||||
|
||||
function indexPatternContainsSpaces(indexPattern: string): boolean {
|
||||
return indexPattern.includes(' ');
|
||||
}
|
||||
|
||||
function findIllegalCharacters(indexPattern: string): string[] {
|
||||
const illegalCharacters = ILLEGAL_CHARACTERS_VISIBLE.reduce((chars: string[], char: string) => {
|
||||
if (indexPattern.includes(char)) {
|
||||
chars.push(char);
|
||||
}
|
||||
return chars;
|
||||
}, []);
|
||||
|
||||
return illegalCharacters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates index pattern strings
|
||||
* @param indexPattern
|
||||
* @returns Object with validation errors
|
||||
*/
|
||||
|
||||
export function validateIndexPattern(indexPattern: string) {
|
||||
const errors: { [ILLEGAL_CHARACTERS_KEY]?: string[]; [CONTAINS_SPACES_KEY]?: boolean } = {};
|
||||
|
||||
const illegalCharacters = findIllegalCharacters(indexPattern);
|
||||
|
||||
if (illegalCharacters.length) {
|
||||
errors[ILLEGAL_CHARACTERS_KEY] = illegalCharacters;
|
||||
}
|
||||
|
||||
if (indexPatternContainsSpaces(indexPattern)) {
|
||||
errors[CONTAINS_SPACES_KEY] = true;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
|
@ -5,12 +5,11 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { DataViewFieldBase, IFieldSubType } from '@kbn/es-query';
|
||||
|
||||
import type { DataViewFieldBase } from '@kbn/es-query';
|
||||
import { ToastInputFields, ErrorToastOptions } from '@kbn/core/public/notifications';
|
||||
// eslint-disable-next-line
|
||||
import type { SavedObject } from 'src/core/server';
|
||||
import { KBN_FIELD_TYPES } from '@kbn/field-types';
|
||||
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { SerializedFieldFormat } from '@kbn/field-formats-plugin/common';
|
||||
import { RUNTIME_FIELD_TYPES } from './constants';
|
||||
|
@ -19,13 +18,36 @@ export type { QueryDslQueryContainer };
|
|||
|
||||
export type FieldFormatMap = Record<string, SerializedFieldFormat>;
|
||||
|
||||
/**
|
||||
* Runtime field - type of value returned
|
||||
* @public
|
||||
*/
|
||||
|
||||
export type RuntimeType = typeof RUNTIME_FIELD_TYPES[number];
|
||||
|
||||
/**
|
||||
* Primitive runtime field types
|
||||
* @public
|
||||
*/
|
||||
|
||||
export type RuntimeTypeExceptComposite = Exclude<RuntimeType, 'composite'>;
|
||||
|
||||
/**
|
||||
* Runtime field definition
|
||||
* @public
|
||||
*/
|
||||
export interface RuntimeFieldBase {
|
||||
/**
|
||||
* Type of runtime field
|
||||
*/
|
||||
type: RuntimeType;
|
||||
/**
|
||||
* Runtime field script
|
||||
*/
|
||||
script?: {
|
||||
/**
|
||||
* Script source
|
||||
*/
|
||||
source: string;
|
||||
};
|
||||
}
|
||||
|
@ -43,90 +65,234 @@ export interface RuntimeFieldSpec extends RuntimeFieldBase {
|
|||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Field attributes that are user configurable
|
||||
* @public
|
||||
*/
|
||||
export interface FieldConfiguration {
|
||||
/**
|
||||
* Field format in serialized form
|
||||
*/
|
||||
format?: SerializedFieldFormat | null;
|
||||
/**
|
||||
* Custom label
|
||||
*/
|
||||
customLabel?: string;
|
||||
/**
|
||||
* Popularity - used for discover
|
||||
*/
|
||||
popularity?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the RuntimeField interface enhanced with Data view field
|
||||
* configuration: field format definition, customLabel or popularity.
|
||||
*
|
||||
* @see {@link RuntimeField}
|
||||
* @public
|
||||
*/
|
||||
export interface RuntimeField extends RuntimeFieldBase, FieldConfiguration {
|
||||
/**
|
||||
* Subfields of composite field
|
||||
*/
|
||||
fields?: Record<string, RuntimeFieldSubField>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime field composite subfield
|
||||
* @public
|
||||
*/
|
||||
export interface RuntimeFieldSubField extends FieldConfiguration {
|
||||
/**
|
||||
* Type of runtime field, can only be primitive type
|
||||
*/
|
||||
type: RuntimeTypeExceptComposite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for an index pattern saved object
|
||||
* Interface for the data view saved object
|
||||
* @public
|
||||
*/
|
||||
export interface DataViewAttributes {
|
||||
/**
|
||||
* Fields as a serialized array of field specs
|
||||
*/
|
||||
fields: string;
|
||||
/**
|
||||
* Data view title
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Data view type, default or rollup
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* Type metadata information, serialized. Only used by rollup data views.
|
||||
*/
|
||||
typeMeta?: string;
|
||||
/**
|
||||
* Time field name
|
||||
*/
|
||||
timeFieldName?: string;
|
||||
/**
|
||||
* Serialized array of filters. Used by discover to hide fields.
|
||||
*/
|
||||
sourceFilters?: string;
|
||||
/**
|
||||
* Serialized map of field formats by field name
|
||||
*/
|
||||
fieldFormatMap?: string;
|
||||
/**
|
||||
* Serialized map of field attributes, currently field count and name
|
||||
*/
|
||||
fieldAttrs?: string;
|
||||
/**
|
||||
* Serialized map of runtime field definitions, by field name
|
||||
*/
|
||||
runtimeFieldMap?: string;
|
||||
/**
|
||||
* prevents errors when index pattern exists before indices
|
||||
* Prevents errors when index pattern exists before indices
|
||||
*/
|
||||
allowNoIndex?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @intenal
|
||||
* Set of field attributes
|
||||
* @public
|
||||
* Storage of field attributes. Necessary since the field list isn't saved.
|
||||
*/
|
||||
export interface FieldAttrs {
|
||||
[key: string]: FieldAttrSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Field attributes that are stored on the data view
|
||||
* @public
|
||||
*/
|
||||
export interface FieldAttrSet {
|
||||
/**
|
||||
* Custom field label
|
||||
*/
|
||||
customLabel?: string;
|
||||
/**
|
||||
* Popularity count - used for discover
|
||||
*/
|
||||
count?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for data view notifications
|
||||
* @public
|
||||
* @param toastInputFields Toast notif config
|
||||
* @param key Used to dedupe notifs
|
||||
*/
|
||||
export type OnNotification = (toastInputFields: ToastInputFields, key: string) => void;
|
||||
|
||||
/**
|
||||
* Handler for data view errors
|
||||
* @public
|
||||
* @param error Error object
|
||||
* @param toastInputFields Toast notif config
|
||||
* @param key Used to dedupe notifs
|
||||
*/
|
||||
export type OnError = (error: Error, toastInputFields: ErrorToastOptions, key: string) => void;
|
||||
|
||||
/**
|
||||
* Interface for UiSettings common interface {@link UiSettingsClient}
|
||||
*/
|
||||
export interface UiSettingsCommon {
|
||||
/**
|
||||
* Get a setting value
|
||||
* @param key name of value
|
||||
*/
|
||||
get: <T = any>(key: string) => Promise<T>;
|
||||
/**
|
||||
* Get all settings values
|
||||
*/
|
||||
getAll: () => Promise<Record<string, unknown>>;
|
||||
set: (key: string, value: any) => Promise<void>;
|
||||
/**
|
||||
* Set a setting value
|
||||
* @param key name of value
|
||||
* @param value value to set
|
||||
*/
|
||||
set: <T = any>(key: string, value: T) => Promise<void>;
|
||||
/**
|
||||
* Remove a setting value
|
||||
* @param key name of value
|
||||
*/
|
||||
remove: (key: string) => Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saved objects common find args
|
||||
* @public
|
||||
*/
|
||||
export interface SavedObjectsClientCommonFindArgs {
|
||||
/**
|
||||
* Saved object type
|
||||
*/
|
||||
type: string | string[];
|
||||
/**
|
||||
* Saved object fields
|
||||
*/
|
||||
fields?: string[];
|
||||
/**
|
||||
* Results per page
|
||||
*/
|
||||
perPage?: number;
|
||||
/**
|
||||
* Query string
|
||||
*/
|
||||
search?: string;
|
||||
/**
|
||||
* Fields to search
|
||||
*/
|
||||
searchFields?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Common interface for the saved objects client
|
||||
* @public
|
||||
*/
|
||||
export interface SavedObjectsClientCommon {
|
||||
/**
|
||||
* Search for saved objects
|
||||
* @param options - options for search
|
||||
*/
|
||||
find: <T = unknown>(options: SavedObjectsClientCommonFindArgs) => Promise<Array<SavedObject<T>>>;
|
||||
/**
|
||||
* Get a single saved object by id
|
||||
* @param type - type of saved object
|
||||
* @param id - id of saved object
|
||||
*/
|
||||
get: <T = unknown>(type: string, id: string) => Promise<SavedObject<T>>;
|
||||
/**
|
||||
* Update a saved object by id
|
||||
* @param type - type of saved object
|
||||
* @param id - id of saved object
|
||||
* @param attributes - attributes to update
|
||||
* @param options - client options
|
||||
*/
|
||||
update: (
|
||||
type: string,
|
||||
id: string,
|
||||
attributes: Record<string, any>,
|
||||
options: Record<string, any>
|
||||
) => Promise<SavedObject>;
|
||||
/**
|
||||
* Create a saved object
|
||||
* @param type - type of saved object
|
||||
* @param attributes - attributes to set
|
||||
* @param options - client options
|
||||
*/
|
||||
create: (
|
||||
type: string,
|
||||
attributes: Record<string, any>,
|
||||
options: Record<string, any>
|
||||
) => Promise<SavedObject>;
|
||||
/**
|
||||
* Delete a saved object by id
|
||||
* @param type - type of saved object
|
||||
* @param id - id of saved object
|
||||
*/
|
||||
delete: (type: string, id: string) => Promise<{}>;
|
||||
}
|
||||
|
||||
|
@ -159,13 +325,28 @@ export type AggregationRestrictions = Record<
|
|||
}
|
||||
>;
|
||||
|
||||
/**
|
||||
* Interface for metadata about rollup indices
|
||||
*/
|
||||
export interface TypeMeta {
|
||||
/**
|
||||
* Aggregation restrictions for rollup fields
|
||||
*/
|
||||
aggs?: Record<string, AggregationRestrictions>;
|
||||
/**
|
||||
* Params for retrieving rollup field data
|
||||
*/
|
||||
params?: {
|
||||
/**
|
||||
* Rollup index name used for loading field list
|
||||
*/
|
||||
rollup_index: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Data View type. Default or rollup
|
||||
*/
|
||||
export enum DataViewType {
|
||||
DEFAULT = 'default',
|
||||
ROLLUP = 'rollup',
|
||||
|
@ -181,72 +362,122 @@ export enum IndexPatternType {
|
|||
|
||||
export type FieldSpecConflictDescriptions = Record<string, string[]>;
|
||||
|
||||
// This should become FieldSpec once types are cleaned up
|
||||
export interface FieldSpecExportFmt {
|
||||
count?: number;
|
||||
script?: string;
|
||||
lang?: estypes.ScriptLanguage;
|
||||
conflictDescriptions?: FieldSpecConflictDescriptions;
|
||||
name: string;
|
||||
type: KBN_FIELD_TYPES;
|
||||
esTypes?: string[];
|
||||
scripted: boolean;
|
||||
searchable: boolean;
|
||||
aggregatable: boolean;
|
||||
readFromDocValues?: boolean;
|
||||
subType?: IFieldSubType;
|
||||
format?: SerializedFieldFormat;
|
||||
indexed?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialized version of DataViewField
|
||||
* @public
|
||||
* Serialized version of IndexPatternField
|
||||
*/
|
||||
export interface FieldSpec extends DataViewFieldBase {
|
||||
/**
|
||||
* Popularity count is used by discover
|
||||
*/
|
||||
count?: number;
|
||||
/**
|
||||
* Description of field type conflicts across indices
|
||||
*/
|
||||
conflictDescriptions?: Record<string, string[]>;
|
||||
/**
|
||||
* Field formatting in serialized format
|
||||
*/
|
||||
format?: SerializedFieldFormat;
|
||||
/**
|
||||
* Elasticsearch field types used by backing indices
|
||||
*/
|
||||
esTypes?: string[];
|
||||
/**
|
||||
* True if field is searchable
|
||||
*/
|
||||
searchable: boolean;
|
||||
/**
|
||||
* True if field is aggregatable
|
||||
*/
|
||||
aggregatable: boolean;
|
||||
/**
|
||||
* True if can be read from doc values
|
||||
*/
|
||||
readFromDocValues?: boolean;
|
||||
/**
|
||||
* True if field is indexed
|
||||
*/
|
||||
indexed?: boolean;
|
||||
/**
|
||||
* Custom label for field, used for display in kibana
|
||||
*/
|
||||
customLabel?: string;
|
||||
/**
|
||||
* Runtime field definition
|
||||
*/
|
||||
runtimeField?: RuntimeFieldSpec;
|
||||
|
||||
// not persisted
|
||||
|
||||
/**
|
||||
* Whether short dots are enabled, based on uiSettings.
|
||||
*/
|
||||
shortDotsEnable?: boolean;
|
||||
/**
|
||||
* Is this field in the mapping? False if a scripted or runtime field defined on the data view.
|
||||
*/
|
||||
isMapped?: boolean;
|
||||
}
|
||||
|
||||
export type DataViewFieldMap = Record<string, FieldSpec>;
|
||||
|
||||
/**
|
||||
* Static index pattern format
|
||||
* Serialized data object, representing index pattern attributes and state
|
||||
* Static data view format
|
||||
* Serialized data object, representing data view attributes and state
|
||||
*/
|
||||
export interface DataViewSpec {
|
||||
/**
|
||||
* saved object id
|
||||
* Saved object id
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* saved object version string
|
||||
* Saved object version string
|
||||
*/
|
||||
version?: string;
|
||||
/**
|
||||
* Data view title
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* Name of timestamp field
|
||||
*/
|
||||
timeFieldName?: string;
|
||||
/**
|
||||
* List of filters which discover uses to hide fields
|
||||
*/
|
||||
sourceFilters?: SourceFilter[];
|
||||
/**
|
||||
* Map of fields by name
|
||||
*/
|
||||
fields?: DataViewFieldMap;
|
||||
/**
|
||||
* Metadata about data view, only used by rollup data views
|
||||
*/
|
||||
typeMeta?: TypeMeta;
|
||||
/**
|
||||
* Default or rollup
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* Map of serialized field formats by field name
|
||||
*/
|
||||
fieldFormats?: Record<string, SerializedFieldFormat>;
|
||||
/**
|
||||
* Map of runtime fields by field name
|
||||
*/
|
||||
runtimeFieldMap?: Record<string, RuntimeFieldSpec>;
|
||||
/**
|
||||
* Map of field attributes by field name, currently customName and count
|
||||
*/
|
||||
fieldAttrs?: FieldAttrs;
|
||||
/**
|
||||
* Determines whether failure to load field list should be reported as error
|
||||
*/
|
||||
allowNoIndex?: boolean;
|
||||
/**
|
||||
* Array of namespace ids
|
||||
*/
|
||||
namespaces?: string[];
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { IndexPatternSavedObjectAttrs } from './data_views';
|
||||
import type { DataViewSavedObjectAttrs } from './data_views';
|
||||
import type { SavedObjectsClientCommon } from './types';
|
||||
|
||||
import { DATA_VIEW_SAVED_OBJECT_TYPE } from './constants';
|
||||
|
@ -20,7 +20,7 @@ import { DATA_VIEW_SAVED_OBJECT_TYPE } from './constants';
|
|||
*/
|
||||
export async function findByTitle(client: SavedObjectsClientCommon, title: string) {
|
||||
if (title) {
|
||||
const savedObjects = await client.find<IndexPatternSavedObjectAttrs>({
|
||||
const savedObjects = await client.find<DataViewSavedObjectAttrs>({
|
||||
type: DATA_VIEW_SAVED_OBJECT_TYPE,
|
||||
perPage: 10,
|
||||
search: `"${title}"`,
|
||||
|
|
|
@ -12,9 +12,16 @@ import { GetFieldsOptions, IDataViewsApiClient } from '../../common';
|
|||
|
||||
const API_BASE_URL: string = `/api/index_patterns/`;
|
||||
|
||||
/**
|
||||
* Data Views API Client - client implementation
|
||||
*/
|
||||
export class DataViewsApiClient implements IDataViewsApiClient {
|
||||
private http: HttpSetup;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param http http dependency
|
||||
*/
|
||||
constructor(http: HttpSetup) {
|
||||
this.http = http;
|
||||
}
|
||||
|
@ -37,14 +44,12 @@ export class DataViewsApiClient implements IDataViewsApiClient {
|
|||
return API_BASE_URL + path.filter(Boolean).map(encodeURIComponent).join('/');
|
||||
}
|
||||
|
||||
getFieldsForWildcard({
|
||||
pattern,
|
||||
metaFields,
|
||||
type,
|
||||
rollupIndex,
|
||||
allowNoIndex,
|
||||
filter,
|
||||
}: GetFieldsOptions) {
|
||||
/**
|
||||
* Get field list for a given index pattern
|
||||
* @param options options for fields request
|
||||
*/
|
||||
getFieldsForWildcard(options: GetFieldsOptions) {
|
||||
const { pattern, metaFields, type, rollupIndex, allowNoIndex, filter } = options;
|
||||
return this._request(this._getUrl(['_fields_for_wildcard']), {
|
||||
pattern,
|
||||
meta_fields: metaFields,
|
||||
|
@ -55,6 +60,9 @@ export class DataViewsApiClient implements IDataViewsApiClient {
|
|||
}).then((resp: any) => resp.fields || []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a user created data view exist?
|
||||
*/
|
||||
async hasUserIndexPattern(): Promise<boolean> {
|
||||
const response = await this._request<{ result: boolean }>(
|
||||
this._getUrl(['has_user_index_pattern'])
|
||||
|
|
|
@ -59,5 +59,5 @@ export const onRedirectNoIndexPattern =
|
|||
}
|
||||
|
||||
// return never-resolving promise to stop resolving and wait for the url change
|
||||
return new Promise(() => {});
|
||||
return new Promise<void>(() => {});
|
||||
};
|
||||
|
|
|
@ -11,15 +11,34 @@ import { DataViewsService } from '.';
|
|||
import { DataViewsServiceDeps } from '../common/data_views/data_views';
|
||||
import { HasDataService } from '../common';
|
||||
|
||||
interface DataViewsServicePublicDeps extends DataViewsServiceDeps {
|
||||
/**
|
||||
* Data Views public service dependencies
|
||||
* @public
|
||||
*/
|
||||
export interface DataViewsServicePublicDeps extends DataViewsServiceDeps {
|
||||
/**
|
||||
* Get can user save data view - sync version
|
||||
*/
|
||||
getCanSaveSync: () => boolean;
|
||||
/**
|
||||
* Has data service
|
||||
*/
|
||||
hasData: HasDataService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Views public service
|
||||
* @public
|
||||
*/
|
||||
export class DataViewsServicePublic extends DataViewsService {
|
||||
public getCanSaveSync: () => boolean;
|
||||
public hasData: HasDataService;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param deps Service dependencies
|
||||
*/
|
||||
|
||||
constructor(deps: DataViewsServicePublicDeps) {
|
||||
super(deps);
|
||||
this.getCanSaveSync = deps.getCanSaveSync;
|
||||
|
|
|
@ -13,10 +13,14 @@ export {
|
|||
ILLEGAL_CHARACTERS,
|
||||
validateDataView,
|
||||
} from '../common/lib';
|
||||
export { onRedirectNoIndexPattern } from './data_views';
|
||||
|
||||
export type { IIndexPatternFieldList, TypeMeta, RuntimeType } from '../common';
|
||||
export type { DataViewSpec, FieldSpec, DataViewAttributes } from '../common';
|
||||
export type {
|
||||
DataViewSpec,
|
||||
FieldSpec,
|
||||
DataViewAttributes,
|
||||
SavedObjectsClientCommon,
|
||||
} from '../common';
|
||||
export {
|
||||
DataViewField,
|
||||
DataViewType,
|
||||
|
@ -27,8 +31,14 @@ export {
|
|||
getFieldSubtypeNested,
|
||||
} from '../common';
|
||||
|
||||
export type { DataViewListItem } from './data_views';
|
||||
export type { DataViewsPublicSetupDependencies, DataViewsPublicStartDependencies } from './types';
|
||||
|
||||
export type {
|
||||
DataViewsServicePublic,
|
||||
DataViewsServicePublicDeps,
|
||||
} from './data_views_service_public';
|
||||
export { IndexPatternsService, DataViewsApiClient, DataViewsService, DataView } from './data_views';
|
||||
export type { DataViewListItem } from './data_views';
|
||||
export { UiSettingsPublicToCommon } from './ui_settings_wrapper';
|
||||
export { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper';
|
||||
|
||||
|
@ -47,8 +57,6 @@ export type {
|
|||
DataViewsPublicPluginStart,
|
||||
DataViewsContract,
|
||||
HasDataViewsResponse,
|
||||
IndicesResponse,
|
||||
IndicesResponseModified,
|
||||
IndicesViaSearchResponse,
|
||||
} from './types';
|
||||
|
||||
|
|
|
@ -15,12 +15,11 @@ import {
|
|||
DataViewsPublicStartDependencies,
|
||||
} from './types';
|
||||
|
||||
import {
|
||||
onRedirectNoIndexPattern,
|
||||
DataViewsApiClient,
|
||||
UiSettingsPublicToCommon,
|
||||
SavedObjectsClientPublicToCommon,
|
||||
} from '.';
|
||||
import { DataViewsApiClient } from '.';
|
||||
import { onRedirectNoIndexPattern } from './data_views';
|
||||
import { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper';
|
||||
|
||||
import { UiSettingsPublicToCommon } from './ui_settings_wrapper';
|
||||
|
||||
import { DataViewsServicePublic } from './data_views_service_public';
|
||||
import { HasData } from './services';
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
SavedObjectsClientCommon,
|
||||
SavedObjectsClientCommonFindArgs,
|
||||
SavedObject,
|
||||
DataViewSavedObjectConflictError,
|
||||
} from '../common';
|
||||
} from '../common/types';
|
||||
import { DataViewSavedObjectConflictError } from '../common/errors';
|
||||
|
||||
type SOClient = Pick<
|
||||
SavedObjectsClientContract,
|
||||
|
|
|
@ -8,12 +8,8 @@
|
|||
|
||||
import { CoreStart, HttpStart } from '@kbn/core/public';
|
||||
import { DEFAULT_ASSETS_TO_IGNORE } from '../../common';
|
||||
import {
|
||||
HasDataViewsResponse,
|
||||
IndicesResponse,
|
||||
IndicesResponseModified,
|
||||
IndicesViaSearchResponse,
|
||||
} from '..';
|
||||
import { HasDataViewsResponse, IndicesViaSearchResponse } from '..';
|
||||
import { IndicesResponse, IndicesResponseModified } from '../types';
|
||||
|
||||
export class HasData {
|
||||
private removeAliases = (source: IndicesResponseModified): boolean => !source.item.indices;
|
||||
|
|
|
@ -65,12 +65,27 @@ export interface HasDataViewsResponse {
|
|||
hasUserDataView: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data views public setup dependencies
|
||||
*/
|
||||
export interface DataViewsPublicSetupDependencies {
|
||||
/**
|
||||
* Expressions
|
||||
*/
|
||||
expressions: ExpressionsSetup;
|
||||
/**
|
||||
* Field formats
|
||||
*/
|
||||
fieldFormats: FieldFormatsSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data views public start dependencies
|
||||
*/
|
||||
export interface DataViewsPublicStartDependencies {
|
||||
/**
|
||||
* Field formats
|
||||
*/
|
||||
fieldFormats: FieldFormatsStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,24 +6,73 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Service path for data views REST API
|
||||
*/
|
||||
export const SERVICE_PATH = '/api/data_views';
|
||||
/**
|
||||
* Legacy service path for data views REST API
|
||||
*/
|
||||
export const SERVICE_PATH_LEGACY = '/api/index_patterns';
|
||||
/**
|
||||
* Path for data view creation
|
||||
*/
|
||||
export const DATA_VIEW_PATH = `${SERVICE_PATH}/data_view`;
|
||||
/**
|
||||
* Legacy path for data view creation
|
||||
*/
|
||||
export const DATA_VIEW_PATH_LEGACY = `${SERVICE_PATH_LEGACY}/index_pattern`;
|
||||
/**
|
||||
* Path for single data view
|
||||
*/
|
||||
export const SPECIFIC_DATA_VIEW_PATH = `${DATA_VIEW_PATH}/{id}`;
|
||||
/**
|
||||
* Legacy path for single data view
|
||||
*/
|
||||
export const SPECIFIC_DATA_VIEW_PATH_LEGACY = `${DATA_VIEW_PATH_LEGACY}/{id}`;
|
||||
/**
|
||||
* Path to create runtime field
|
||||
*/
|
||||
export const RUNTIME_FIELD_PATH = `${SPECIFIC_DATA_VIEW_PATH}/runtime_field`;
|
||||
/**
|
||||
* Legacy path to create runtime field
|
||||
*/
|
||||
export const RUNTIME_FIELD_PATH_LEGACY = `${SPECIFIC_DATA_VIEW_PATH_LEGACY}/runtime_field`;
|
||||
/**
|
||||
* Path for runtime field
|
||||
*/
|
||||
export const SPECIFIC_RUNTIME_FIELD_PATH = `${RUNTIME_FIELD_PATH}/{name}`;
|
||||
/**
|
||||
* Legacy path for runtime field
|
||||
*/
|
||||
export const SPECIFIC_RUNTIME_FIELD_PATH_LEGACY = `${RUNTIME_FIELD_PATH_LEGACY}/{name}`;
|
||||
|
||||
/**
|
||||
* Path to create scripted field
|
||||
*/
|
||||
export const SCRIPTED_FIELD_PATH = `${SPECIFIC_DATA_VIEW_PATH}/scripted_field`;
|
||||
/**
|
||||
* Legacy path to create scripted field
|
||||
*/
|
||||
export const SCRIPTED_FIELD_PATH_LEGACY = `${SPECIFIC_DATA_VIEW_PATH_LEGACY}/scripted_field`;
|
||||
/**
|
||||
* Path for scripted field
|
||||
*/
|
||||
export const SPECIFIC_SCRIPTED_FIELD_PATH = `${SCRIPTED_FIELD_PATH}/{name}`;
|
||||
/**
|
||||
* Legacy path for scripted field
|
||||
*/
|
||||
export const SPECIFIC_SCRIPTED_FIELD_PATH_LEGACY = `${SCRIPTED_FIELD_PATH_LEGACY}/{name}`;
|
||||
|
||||
/**
|
||||
* name of service in path form
|
||||
*/
|
||||
export const SERVICE_KEY = 'data_view';
|
||||
/**
|
||||
* Legacy name of service in path form
|
||||
*/
|
||||
export const SERVICE_KEY_LEGACY = 'index_pattern';
|
||||
/**
|
||||
* Service keys as type
|
||||
*/
|
||||
export type SERVICE_KEY_TYPE = typeof SERVICE_KEY | typeof SERVICE_KEY_LEGACY;
|
||||
|
||||
export const CREATE_DATA_VIEW_COUNTER_NAME = `POST ${DATA_VIEW_PATH}`;
|
||||
|
|
|
@ -20,23 +20,25 @@ import { UiSettingsServerToCommon } from './ui_settings_wrapper';
|
|||
import { IndexPatternsApiServer } from './index_patterns_api_client';
|
||||
import { SavedObjectsClientServerToCommon } from './saved_objects_client_wrapper';
|
||||
|
||||
export const dataViewsServiceFactory = ({
|
||||
logger,
|
||||
uiSettings,
|
||||
fieldFormats,
|
||||
capabilities,
|
||||
}: {
|
||||
interface DataViewsServiceFactoryDeps {
|
||||
logger: Logger;
|
||||
uiSettings: UiSettingsServiceStart;
|
||||
fieldFormats: FieldFormatsStart;
|
||||
capabilities: CoreStart['capabilities'];
|
||||
}) =>
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DataViewsService instance.
|
||||
* @param deps - Dependencies required by the DataViewsService
|
||||
*/
|
||||
export const dataViewsServiceFactory = (deps: DataViewsServiceFactoryDeps) =>
|
||||
async function (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
elasticsearchClient: ElasticsearchClient,
|
||||
request?: KibanaRequest,
|
||||
byPassCapabilities?: boolean
|
||||
) {
|
||||
const { logger, uiSettings, fieldFormats, capabilities } = deps;
|
||||
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);
|
||||
const formats = await fieldFormats.fieldFormatServiceFactory(uiSettingsClient);
|
||||
|
||||
|
|
|
@ -80,10 +80,10 @@ export function getIndexPatternLoad({
|
|||
}) {
|
||||
return getFunctionDefinition({
|
||||
getStartDependencies: async (request: KibanaRequest) => {
|
||||
const [{ elasticsearch, savedObjects }, , { indexPatternsServiceFactory }] =
|
||||
const [{ elasticsearch, savedObjects }, , { dataViewsServiceFactory }] =
|
||||
await getStartServices();
|
||||
return {
|
||||
indexPatterns: await indexPatternsServiceFactory(
|
||||
indexPatterns: await dataViewsServiceFactory(
|
||||
savedObjects.getScopedClient(request),
|
||||
elasticsearch.client.asScoped(request).asCurrentUser,
|
||||
request
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
|
||||
import { mergeJobConfigurations } from './jobs_compatibility';
|
||||
|
||||
/**
|
||||
* Get rollup job capabilities
|
||||
* @public
|
||||
* @param indices rollup job index capabilites
|
||||
*/
|
||||
|
||||
export function getCapabilitiesForRollupIndices(indices: Record<string, { rollup_jobs: any }>) {
|
||||
const indexNames = Object.keys(indices);
|
||||
const capabilities = {} as { [key: string]: any };
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
SavedObjectsClientContract,
|
||||
SavedObjectsFindResponse,
|
||||
} from '@kbn/core/server';
|
||||
import { IndexPatternSavedObjectAttrs } from '../common/data_views';
|
||||
import { DataViewSavedObjectAttrs } from '../common/data_views';
|
||||
import { DEFAULT_ASSETS_TO_IGNORE } from '../common/constants';
|
||||
|
||||
interface Deps {
|
||||
|
@ -22,8 +22,8 @@ interface Deps {
|
|||
export const getIndexPattern = async ({
|
||||
esClient,
|
||||
soClient,
|
||||
}: Deps): Promise<SavedObjectsFindResponse<IndexPatternSavedObjectAttrs, unknown>> =>
|
||||
soClient.find<IndexPatternSavedObjectAttrs>({
|
||||
}: Deps): Promise<SavedObjectsFindResponse<DataViewSavedObjectAttrs, unknown>> =>
|
||||
soClient.find<DataViewSavedObjectAttrs>({
|
||||
type: 'index-pattern',
|
||||
fields: ['title'],
|
||||
search: `*`,
|
||||
|
@ -33,7 +33,7 @@ export const getIndexPattern = async ({
|
|||
|
||||
export const hasUserIndexPattern = async (
|
||||
{ esClient, soClient }: Deps,
|
||||
indexPatterns?: SavedObjectsFindResponse<IndexPatternSavedObjectAttrs, unknown>
|
||||
indexPatterns?: SavedObjectsFindResponse<DataViewSavedObjectAttrs, unknown>
|
||||
): Promise<boolean> => {
|
||||
if (!indexPatterns) {
|
||||
indexPatterns = await getIndexPattern({ esClient, soClient });
|
||||
|
|
|
@ -8,13 +8,12 @@
|
|||
|
||||
export { getFieldByName, findIndexPatternById } from './utils';
|
||||
export type { FieldDescriptor } from './fetcher';
|
||||
export {
|
||||
IndexPatternsFetcher,
|
||||
shouldReadFieldFromDocValues,
|
||||
mergeCapabilitiesWithFields,
|
||||
getCapabilitiesForRollupIndices,
|
||||
} from './fetcher';
|
||||
export type { IndexPatternsServiceStart } from './types';
|
||||
export { IndexPatternsFetcher, getCapabilitiesForRollupIndices } from './fetcher';
|
||||
export type {
|
||||
DataViewsServerPluginStart,
|
||||
DataViewsServerPluginSetupDependencies,
|
||||
DataViewsServerPluginStartDependencies,
|
||||
} from './types';
|
||||
|
||||
import { PluginInitializerContext } from '@kbn/core/server';
|
||||
import { DataViewsServerPlugin } from './plugin';
|
||||
|
@ -56,3 +55,6 @@ export {
|
|||
} from './constants';
|
||||
|
||||
export type { SERVICE_KEY_TYPE } from './constants';
|
||||
|
||||
export type { FieldSpec, SavedObjectsClientCommon } from '../common/types';
|
||||
export { DataViewsService, DataView } from '../common/data_views';
|
||||
|
|
|
@ -49,6 +49,9 @@ export class IndexPatternsApiServer implements IDataViewsApiClient {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a user created data view?
|
||||
*/
|
||||
async hasUserIndexPattern() {
|
||||
return hasUserIndexPattern({
|
||||
esClient: this.esClient,
|
||||
|
|
|
@ -11,7 +11,6 @@ import { DataViewsService } from '../common';
|
|||
export function createIndexPatternsStartMock() {
|
||||
const dataViewsServiceFactory = jest.fn().mockResolvedValue({ get: jest.fn() });
|
||||
return {
|
||||
indexPatternsServiceFactory: dataViewsServiceFactory,
|
||||
dataViewsServiceFactory,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ export class DataViewsServerPlugin
|
|||
});
|
||||
|
||||
return {
|
||||
indexPatternsServiceFactory: serviceFactory,
|
||||
dataViewsServiceFactory: serviceFactory,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -153,9 +153,9 @@ export function registerIndexPatternsUsageCollector(
|
|||
type: 'index-patterns',
|
||||
isReady: () => true,
|
||||
fetch: async () => {
|
||||
const [{ savedObjects, elasticsearch }, , { indexPatternsServiceFactory }] =
|
||||
const [{ savedObjects, elasticsearch }, , { dataViewsServiceFactory }] =
|
||||
await getStartServices();
|
||||
const indexPatternService = await indexPatternsServiceFactory(
|
||||
const indexPatternService = await dataViewsServiceFactory(
|
||||
new SavedObjectsClient(savedObjects.createInternalRepository()),
|
||||
elasticsearch.client.asInternalUser
|
||||
);
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { DataViewSpec, DataViewsService } from '../../common';
|
||||
import { DataViewSpec } from '../../common/types';
|
||||
import { DataViewsService } from '../../common/data_views';
|
||||
import { handleErrors } from './util/handle_errors';
|
||||
import { fieldSpecSchema, runtimeFieldSchema, serializedFieldFormatSchema } from './util/schemas';
|
||||
import type { DataViewsServerPluginStartDependencies, DataViewsServerPluginStart } from '../types';
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { DataViewsService, RuntimeField } from '../../../common';
|
||||
import { DataViewsService } from '../../../common/data_views';
|
||||
import { RuntimeField } from '../../../common/types';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { runtimeFieldSchema } from '../util/schemas';
|
||||
import type {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { DataViewsService } from '../../../common';
|
||||
import { DataViewsService } from '../../../common/data_views';
|
||||
import { ErrorIndexPatternFieldNotFound } from '../../error';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import type {
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { DataViewsService, RuntimeField } from '../../../common';
|
||||
import { DataViewsService } from '../../../common/data_views';
|
||||
import { RuntimeField } from '../../../common/types';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { runtimeFieldSchema } from '../util/schemas';
|
||||
import type {
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { DataViewsService, RuntimeField } from '../../../common';
|
||||
import { DataViewsService } from '../../../common/data_views';
|
||||
import { RuntimeField } from '../../../common/types';
|
||||
import { ErrorIndexPatternFieldNotFound } from '../../error';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { runtimeFieldSchema } from '../util/schemas';
|
||||
|
|
|
@ -45,8 +45,8 @@ export const registerCreateScriptedFieldRoute = (
|
|||
const core = await ctx.core;
|
||||
const savedObjectsClient = core.savedObjects.client;
|
||||
const elasticsearchClient = core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatternsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatternsServiceFactory(
|
||||
const [, , { dataViewsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
req
|
||||
|
|
|
@ -46,8 +46,8 @@ export const registerDeleteScriptedFieldRoute = (
|
|||
const core = await ctx.core;
|
||||
const savedObjectsClient = core.savedObjects.client;
|
||||
const elasticsearchClient = core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatternsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatternsServiceFactory(
|
||||
const [, , { dataViewsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
req
|
||||
|
|
|
@ -46,8 +46,8 @@ export const registerGetScriptedFieldRoute = (
|
|||
const core = await ctx.core;
|
||||
const savedObjectsClient = core.savedObjects.client;
|
||||
const elasticsearchClient = core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatternsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatternsServiceFactory(
|
||||
const [, , { dataViewsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
req
|
||||
|
|
|
@ -45,8 +45,8 @@ export const registerPutScriptedFieldRoute = (
|
|||
const core = await ctx.core;
|
||||
const savedObjectsClient = core.savedObjects.client;
|
||||
const elasticsearchClient = core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatternsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatternsServiceFactory(
|
||||
const [, , { dataViewsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
req
|
||||
|
|
|
@ -66,8 +66,8 @@ export const registerUpdateScriptedFieldRoute = (
|
|||
const core = await ctx.core;
|
||||
const savedObjectsClient = core.savedObjects.client;
|
||||
const elasticsearchClient = core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatternsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatternsServiceFactory(
|
||||
const [, , { dataViewsServiceFactory }] = await getStartServices();
|
||||
const indexPatternsService = await dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
req
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { DataViewSpec, DataViewsService } from '../../common';
|
||||
import { DataViewsService } from '../../common/data_views';
|
||||
import { DataViewSpec } from '../../common/types';
|
||||
import { handleErrors } from './util/handle_errors';
|
||||
import { fieldSpecSchema, runtimeFieldSchema, serializedFieldFormatSchema } from './util/schemas';
|
||||
import type { DataViewsServerPluginStartDependencies, DataViewsServerPluginStart } from '../types';
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
*/
|
||||
|
||||
import { SavedObjectsClientContract, SavedObject } from '@kbn/core/server';
|
||||
import {
|
||||
SavedObjectsClientCommon,
|
||||
SavedObjectsClientCommonFindArgs,
|
||||
DataViewSavedObjectConflictError,
|
||||
} from '../common';
|
||||
import { SavedObjectsClientCommon, SavedObjectsClientCommonFindArgs } from '../common/types';
|
||||
import { DataViewSavedObjectConflictError } from '../common/errors';
|
||||
|
||||
export class SavedObjectsClientServerToCommon implements SavedObjectsClientCommon {
|
||||
private savedObjectClient: SavedObjectsClientContract;
|
||||
|
|
|
@ -17,42 +17,74 @@ import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
|
|||
import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/server';
|
||||
import { DataViewsService } from '../common';
|
||||
|
||||
/**
|
||||
* Data Views service factory
|
||||
*/
|
||||
type ServiceFactory = (
|
||||
/**
|
||||
* Saved objects client
|
||||
*/
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
/**
|
||||
* Elasticsearch client
|
||||
*/
|
||||
elasticsearchClient: ElasticsearchClient,
|
||||
/**
|
||||
* Kibana request object
|
||||
*/
|
||||
request?: KibanaRequest,
|
||||
/**
|
||||
* Ignore capabilities
|
||||
*/
|
||||
byPassCapabilities?: boolean
|
||||
) => Promise<DataViewsService>;
|
||||
|
||||
/**
|
||||
* DataViews server plugin start api
|
||||
*/
|
||||
export interface DataViewsServerPluginStart {
|
||||
dataViewsServiceFactory: ServiceFactory;
|
||||
/**
|
||||
* @deprecated Renamed to dataViewsServiceFactory
|
||||
* Returns a DataViews service instance
|
||||
*/
|
||||
indexPatternsServiceFactory: ServiceFactory;
|
||||
}
|
||||
|
||||
export interface IndexPatternsServiceSetupDeps {
|
||||
expressions: ExpressionsServerSetup;
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
}
|
||||
|
||||
export interface IndexPatternsServiceStartDeps {
|
||||
fieldFormats: FieldFormatsStart;
|
||||
logger: Logger;
|
||||
dataViewsServiceFactory: ServiceFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* DataViews server plugin setup api
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface DataViewsServerPluginSetup {}
|
||||
|
||||
export type IndexPatternsServiceStart = DataViewsServerPluginStart;
|
||||
|
||||
/**
|
||||
* Data Views server setup dependencies
|
||||
* @public
|
||||
*/
|
||||
export interface DataViewsServerPluginSetupDependencies {
|
||||
/**
|
||||
* File formats
|
||||
*/
|
||||
fieldFormats: FieldFormatsSetup;
|
||||
/**
|
||||
* Expressions
|
||||
*/
|
||||
expressions: ExpressionsServerSetup;
|
||||
/**
|
||||
* Usage collection
|
||||
*/
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Views server start dependencies
|
||||
* @public
|
||||
*/
|
||||
export interface DataViewsServerPluginStartDependencies {
|
||||
/**
|
||||
* Field formats
|
||||
*/
|
||||
fieldFormats: FieldFormatsStart;
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
logger: Logger;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
import { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import { DATA_VIEW_SAVED_OBJECT_TYPE, DataViewAttributes, SavedObject, FieldSpec } from '../common';
|
||||
|
||||
/**
|
||||
* @deprecated Use data views api instead
|
||||
*/
|
||||
export const getFieldByName = (
|
||||
fieldName: string,
|
||||
indexPattern: SavedObject<DataViewAttributes>
|
||||
|
@ -19,6 +22,9 @@ export const getFieldByName = (
|
|||
return field;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use data views api instead
|
||||
*/
|
||||
export const findIndexPatternById = async (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
index: string
|
||||
|
|
|
@ -55,7 +55,7 @@ export class DataSearchTestPlugin
|
|||
|
||||
// Since the index pattern ID can change on each test run, we need
|
||||
// to look it up on the fly and insert it into the request.
|
||||
const indexPatterns = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
const indexPatterns = await data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
clusterClient,
|
||||
req
|
||||
|
|
|
@ -36,7 +36,7 @@ export class IndexPatternsTestPlugin
|
|||
async (context, req, res) => {
|
||||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
const service = await data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser,
|
||||
req
|
||||
|
@ -51,7 +51,7 @@ export class IndexPatternsTestPlugin
|
|||
async (context, req, res) => {
|
||||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
const service = await data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser,
|
||||
req
|
||||
|
@ -74,7 +74,7 @@ export class IndexPatternsTestPlugin
|
|||
const id = (req.params as Record<string, string>).id;
|
||||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
const service = await data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser,
|
||||
req
|
||||
|
@ -97,7 +97,7 @@ export class IndexPatternsTestPlugin
|
|||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const id = (req.params as Record<string, string>).id;
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
const service = await data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser,
|
||||
req
|
||||
|
@ -121,7 +121,7 @@ export class IndexPatternsTestPlugin
|
|||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const id = (req.params as Record<string, string>).id;
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
const service = await data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser,
|
||||
req
|
||||
|
|
|
@ -9,7 +9,7 @@ import { coreMock } from '@kbn/core/public/mocks';
|
|||
import { spacesPluginMock } from '@kbn/spaces-plugin/public/mocks';
|
||||
import { createMockGraphStore } from '../state_management/mocks';
|
||||
import { Workspace } from '../types';
|
||||
import { SavedObjectsClientCommon } from '@kbn/data-plugin/common';
|
||||
import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/public';
|
||||
import { renderHook, act, RenderHookOptions } from '@testing-library/react-hooks';
|
||||
|
||||
jest.mock('react-router-dom', () => {
|
||||
|
|
|
@ -84,6 +84,6 @@ export const createIndexPatternsStartMock = (
|
|||
indexPatterns: IndexPatternMock[]
|
||||
): any => {
|
||||
return {
|
||||
indexPatternsServiceFactory: async () => createIndexPatternsMock(asyncDelay, indexPatterns),
|
||||
dataViewsServiceFactory: async () => createIndexPatternsMock(asyncDelay, indexPatterns),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -219,7 +219,7 @@ export class KibanaFramework {
|
|||
elasticsearchClient: ElasticsearchClient
|
||||
) {
|
||||
const [, startPlugins] = await this.core.getStartServices();
|
||||
return startPlugins.data.indexPatterns.indexPatternsServiceFactory(
|
||||
return startPlugins.data.indexPatterns.dataViewsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient
|
||||
);
|
||||
|
|
|
@ -51,7 +51,7 @@ export function initIndexingRoutes({
|
|||
async (context, request, response) => {
|
||||
const coreContext = await context.core;
|
||||
const { index, mappings } = request.body;
|
||||
const indexPatternsService = await dataPlugin.indexPatterns.indexPatternsServiceFactory(
|
||||
const indexPatternsService = await dataPlugin.indexPatterns.dataViewsServiceFactory(
|
||||
coreContext.savedObjects.client,
|
||||
coreContext.elasticsearch.client.asCurrentUser,
|
||||
request
|
||||
|
|
|
@ -20,5 +20,5 @@ export const getSavedObjectClient = (extraTypes?: string[]) => {
|
|||
};
|
||||
|
||||
export const getIndexPatternsServiceFactory = () =>
|
||||
pluginsStart.data.indexPatterns.indexPatternsServiceFactory;
|
||||
pluginsStart.data.indexPatterns.dataViewsServiceFactory;
|
||||
export const getElasticsearch = () => coreStart.elasticsearch;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue