Fix ts types for AggType folder (#50049) (#52816)

This commit is contained in:
Luke Elmers 2019-12-11 15:23:11 -07:00 committed by GitHub
parent fce83bed03
commit a5e8fe4be2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 195 additions and 149 deletions

View file

@ -29,7 +29,6 @@ import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
import { SearchSourceContract, FetchOptions } from '../courier/types';
import { AggType } from './agg_type';
import { FieldParamType } from './param_types/field';
import { AggGroupNames } from '../vis/editors/default/agg_groups';
import { writeParams } from './agg_params';
import { AggConfigs } from './agg_configs';
@ -204,7 +203,7 @@ export class AggConfig {
}
write(aggs?: AggConfigs) {
return writeParams(this.type.params, this, aggs);
return writeParams<AggConfig>(this.type.params, this, aggs);
}
isFilterable() {
@ -425,13 +424,15 @@ export class AggConfig {
}
this.__type = type;
let availableFields = [];
const fieldParam = this.type && this.type.params.find((p: any) => p.type === 'field');
if (fieldParam) {
// @ts-ignore
availableFields = fieldParam.getAvailableFields(this.getIndexPattern().fields);
}
const fieldParam =
this.type && (this.type.params.find((p: any) => p.type === 'field') as FieldParamType);
// @ts-ignore
const availableFields = fieldParam
? fieldParam.getAvailableFields(this.getIndexPattern().fields)
: [];
// clear out the previous params except for a few special ones
this.setParams({
// split row/columns is "outside" of the agg, so don't reset it

View file

@ -126,7 +126,10 @@ export class AggConfigs {
return aggConfigs;
}
createAggConfig(params: AggConfig | AggConfigOptions, { addToAggConfigs = true } = {}) {
createAggConfig<T extends AggConfig = AggConfig>(
params: AggConfig | AggConfigOptions,
{ addToAggConfigs = true } = {}
) {
let aggConfig;
if (params instanceof AggConfig) {
aggConfig = params;
@ -137,7 +140,7 @@ export class AggConfigs {
if (addToAggConfigs) {
this.aggs.push(aggConfig);
}
return aggConfig;
return aggConfig as T;
}
/**

View file

@ -17,17 +17,18 @@
* under the License.
*/
import { AggParam, initParams } from './agg_params';
import { initParams } from './agg_params';
import { BaseParamType } from './param_types/base';
import { FieldParamType } from './param_types/field';
import { OptionedParamType } from './param_types/optioned';
import { AggParamType } from '../agg_types/param_types/agg';
jest.mock('ui/new_platform');
describe('AggParams class', () => {
describe('constructor args', () => {
it('accepts an array of param defs', () => {
const params = [{ name: 'one' }, { name: 'two' }] as AggParam[];
const params = [{ name: 'one' }, { name: 'two' }] as AggParamType[];
const aggParams = initParams(params);
expect(aggParams).toHaveLength(params.length);
@ -37,7 +38,7 @@ describe('AggParams class', () => {
describe('AggParam creation', () => {
it('Uses the FieldParamType class for params with the name "field"', () => {
const params = [{ name: 'field', type: 'field' }] as AggParam[];
const params = [{ name: 'field', type: 'field' }] as AggParamType[];
const aggParams = initParams(params);
expect(aggParams).toHaveLength(params.length);
@ -50,7 +51,7 @@ describe('AggParams class', () => {
name: 'order',
type: 'optioned',
},
];
] as AggParamType[];
const aggParams = initParams(params);
expect(aggParams).toHaveLength(params.length);
@ -71,7 +72,7 @@ describe('AggParams class', () => {
name: 'waist',
displayName: 'waist',
},
] as AggParam[];
] as AggParamType[];
const aggParams = initParams(params);

View file

@ -44,17 +44,10 @@ export interface AggParamOption {
enabled?(agg: AggConfig): boolean;
}
export interface AggParamConfig {
type: string;
}
export const initParams = <
TAggParam extends AggParam = AggParam,
TAggParamConfig extends AggParamConfig = AggParamConfig
>(
params: TAggParamConfig[]
export const initParams = <TAggParam extends AggParamType = AggParamType>(
params: TAggParam[]
): TAggParam[] =>
params.map((config: TAggParamConfig) => {
params.map((config: TAggParam) => {
const Class = paramTypeMap[config.type] || paramTypeMap._default;
return new Class(config);
@ -74,20 +67,25 @@ export const initParams = <
* output object which is used to create the agg dsl for the search request. All other properties
* are dependent on the AggParam#write methods which should be studied for each AggType.
*/
export const writeParams = (
params: AggParam[],
aggConfig: AggConfig,
export const writeParams = <
TAggConfig extends AggConfig = AggConfig,
TAggParam extends AggParamType<TAggConfig> = AggParamType<TAggConfig>
>(
params: Array<Partial<TAggParam>> = [],
aggConfig: TAggConfig,
aggs?: AggConfigs,
locals?: Record<string, any>
) => {
const output = { params: {} as Record<string, any> };
locals = locals || {};
params.forEach(function(param) {
params.forEach(param => {
if (param.write) {
param.write(aggConfig, output, aggs, locals);
} else {
output.params[param.name] = aggConfig.params[param.name];
if (param && param.name) {
output.params[param.name] = aggConfig.params[param.name];
}
}
});

View file

@ -20,19 +20,19 @@
import { constant, noop, identity } from 'lodash';
import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
import { AggParam, initParams } from './agg_params';
import { initParams } from './agg_params';
import { AggConfig } from '../vis';
import { AggConfigs } from './agg_configs';
import { SearchSource } from '../courier';
import { Adapters } from '../inspector';
import { BaseParamType } from './param_types/base';
import { AggParamType } from '../agg_types/param_types/agg';
import { KBN_FIELD_TYPES, FieldFormat } from '../../../../plugins/data/public';
export interface AggTypeConfig<
TAggConfig extends AggConfig = AggConfig,
TParam extends AggParam = AggParam
TParam extends AggParamType<TAggConfig> = AggParamType<TAggConfig>
> {
name: string;
title: string;
@ -46,7 +46,7 @@ export interface AggTypeConfig<
getRequestAggs?: ((aggConfig: TAggConfig) => TAggConfig[]) | (() => TAggConfig[] | void);
getResponseAggs?: ((aggConfig: TAggConfig) => TAggConfig[]) | (() => TAggConfig[] | void);
customLabels?: boolean;
decorateAggConfig?: () => Record<string, any>;
decorateAggConfig?: () => any;
postFlightRequest?: (
resp: any,
aggConfigs: AggConfigs,
@ -67,7 +67,10 @@ const getFormat = (agg: AggConfig) => {
return field ? field.format : fieldFormats.getDefaultInstance(KBN_FIELD_TYPES.STRING);
};
export class AggType<TAggConfig extends AggConfig = AggConfig, TParam extends AggParam = AggParam> {
export class AggType<
TAggConfig extends AggConfig = AggConfig,
TParam extends AggParamType<TAggConfig> = AggParamType<TAggConfig>
> {
/**
* the unique, unchanging, name that we have assigned this aggType
*
@ -162,7 +165,7 @@ export class AggType<TAggConfig extends AggConfig = AggConfig, TParam extends Ag
* A function that will be called each time an aggConfig of this type
* is created, giving the agg type a chance to modify the agg config
*/
decorateAggConfig: () => Record<string, any>;
decorateAggConfig: () => any;
/**
* A function that needs to be called after the main request has been made
* and should return an updated response
@ -196,7 +199,7 @@ export class AggType<TAggConfig extends AggConfig = AggConfig, TParam extends Ag
getKey?: (bucket: any, key: any, agg: TAggConfig) => any;
paramByName = (name: string) => {
return this.params.find((p: AggParam) => p.name === name);
return this.params.find((p: TParam) => p.name === name);
};
/**

View file

@ -17,29 +17,33 @@
* under the License.
*/
import { AggParamType } from '../param_types/agg';
import { AggConfig } from '../../vis';
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
import { AggType, AggTypeConfig } from '../agg_type';
import { AggParamType } from '../param_types/agg';
export type IBucketAggConfig = AggConfig;
export interface IBucketAggConfig extends AggConfig {
type: InstanceType<typeof BucketAggType>;
}
export interface BucketAggParam extends AggParamType {
export interface BucketAggParam<TBucketAggConfig extends AggConfig>
extends AggParamType<TBucketAggConfig> {
scriptable?: boolean;
filterFieldTypes?: KBN_FIELD_TYPES | KBN_FIELD_TYPES[] | '*';
}
export interface BucketAggTypeConfig<TBucketAggConfig extends IBucketAggConfig>
extends AggTypeConfig<TBucketAggConfig, BucketAggParam> {
const bucketType = 'buckets';
interface BucketAggTypeConfig<TBucketAggConfig extends AggConfig>
extends AggTypeConfig<TBucketAggConfig, BucketAggParam<TBucketAggConfig>> {
getKey?: (bucket: any, key: any, agg: AggConfig) => any;
}
const bucketType = 'buckets';
export class BucketAggType<
TBucketAggConfig extends IBucketAggConfig = IBucketAggConfig
> extends AggType<TBucketAggConfig, BucketAggParam> {
getKey: (bucket: any, key: any, agg: IBucketAggConfig) => any;
export class BucketAggType<TBucketAggConfig extends AggConfig = IBucketAggConfig> extends AggType<
TBucketAggConfig,
BucketAggParam<TBucketAggConfig>
> {
getKey: (bucket: any, key: any, agg: TBucketAggConfig) => any;
type = bucketType;
constructor(config: BucketAggTypeConfig<TBucketAggConfig>) {

View file

@ -22,6 +22,7 @@ import { createFilterDateRange } from './date_range';
import { DateFormat } from '../../../../../../plugins/data/public';
import { AggConfigs } from '../../agg_configs';
import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../_bucket_agg_type';
jest.mock('ui/new_platform');
@ -61,7 +62,7 @@ describe('AggConfig Filters', () => {
const aggConfigs = getAggConfigs();
const from = new Date('1 Feb 2015');
const to = new Date('7 Feb 2015');
const filter = createFilterDateRange(aggConfigs.aggs[0], {
const filter = createFilterDateRange(aggConfigs.aggs[0] as IBucketAggConfig, {
from: from.valueOf(),
to: to.valueOf(),
});

View file

@ -18,6 +18,7 @@
*/
import { createFilterFilters } from './filters';
import { AggConfigs } from '../../agg_configs';
import { IBucketAggConfig } from '../_bucket_agg_type';
jest.mock('ui/new_platform');
@ -56,7 +57,7 @@ describe('AggConfig Filters', () => {
};
it('should return a filters filter', () => {
const aggConfigs = getAggConfigs();
const filter = createFilterFilters(aggConfigs.aggs[0], 'type:nginx');
const filter = createFilterFilters(aggConfigs.aggs[0] as IBucketAggConfig, 'type:nginx');
expect(filter!.query.bool.must[0].query_string.query).toBe('type:nginx');
expect(filter!.meta).toHaveProperty('index', '1234');

View file

@ -19,6 +19,7 @@
import { createFilterHistogram } from './histogram';
import { AggConfigs } from '../../agg_configs';
import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../_bucket_agg_type';
import { BytesFormat } from '../../../../../../plugins/data/public';
jest.mock('ui/new_platform');
@ -59,7 +60,7 @@ describe('AggConfig Filters', () => {
it('should return an range filter for histogram', () => {
const aggConfigs = getAggConfigs();
const filter = createFilterHistogram(aggConfigs.aggs[0], '2048');
const filter = createFilterHistogram(aggConfigs.aggs[0] as IBucketAggConfig, '2048');
expect(filter).toHaveProperty('meta');
expect(filter.meta).toHaveProperty('index', '1234');

View file

@ -21,6 +21,7 @@ import { createFilterIpRange } from './ip_range';
import { AggConfigs } from '../../agg_configs';
import { IpFormat } from '../../../../../../plugins/data/public';
import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../_bucket_agg_type';
jest.mock('ui/new_platform');
@ -59,7 +60,7 @@ describe('AggConfig Filters', () => {
},
]);
const filter = createFilterIpRange(aggConfigs.aggs[0], {
const filter = createFilterIpRange(aggConfigs.aggs[0] as IBucketAggConfig, {
type: 'range',
from: '0.0.0.0',
to: '1.1.1.1',
@ -88,7 +89,7 @@ describe('AggConfig Filters', () => {
},
]);
const filter = createFilterIpRange(aggConfigs.aggs[0], {
const filter = createFilterIpRange(aggConfigs.aggs[0] as IBucketAggConfig, {
type: 'mask',
mask: '67.129.65.201/27',
});

View file

@ -21,6 +21,7 @@ import { createFilterRange } from './range';
import { BytesFormat } from '../../../../../../plugins/data/public';
import { AggConfigs } from '../../agg_configs';
import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../_bucket_agg_type';
jest.mock('ui/new_platform');
@ -60,7 +61,10 @@ describe('AggConfig Filters', () => {
it('should return a range filter for range agg', () => {
const aggConfigs = getAggConfigs();
const filter = createFilterRange(aggConfigs.aggs[0], { gte: 1024, lt: 2048.0 });
const filter = createFilterRange(aggConfigs.aggs[0] as IBucketAggConfig, {
gte: 1024,
lt: 2048.0,
});
expect(filter).toHaveProperty('range');
expect(filter).toHaveProperty('meta');

View file

@ -20,6 +20,7 @@
import { createFilterTerms } from './terms';
import { AggConfigs } from '../../agg_configs';
import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../_bucket_agg_type';
import { esFilters } from '../../../../../../plugins/data/public';
jest.mock('ui/new_platform');
@ -49,7 +50,11 @@ describe('AggConfig Filters', () => {
{ type: BUCKET_TYPES.TERMS, schema: 'segment', params: { field: 'field' } },
]);
const filter = createFilterTerms(aggConfigs.aggs[0], 'apache', {}) as esFilters.Filter;
const filter = createFilterTerms(
aggConfigs.aggs[0] as IBucketAggConfig,
'apache',
{}
) as esFilters.Filter;
expect(filter).toHaveProperty('query');
expect(filter.query).toHaveProperty('match_phrase');
@ -64,27 +69,35 @@ describe('AggConfig Filters', () => {
{ type: BUCKET_TYPES.TERMS, schema: 'segment', params: { field: 'field' } },
]);
const filterFalse = createFilterTerms(aggConfigs.aggs[0], '', {}) as esFilters.Filter;
const filterFalse = createFilterTerms(
aggConfigs.aggs[0] as IBucketAggConfig,
'',
{}
) as esFilters.Filter;
expect(filterFalse).toHaveProperty('query');
expect(filterFalse.query).toHaveProperty('match_phrase');
expect(filterFalse.query.match_phrase).toHaveProperty('field');
expect(filterFalse.query.match_phrase.field).toBeFalsy();
const filterTrue = createFilterTerms(aggConfigs.aggs[0], '1', {}) as esFilters.Filter;
const filterTrue = createFilterTerms(
aggConfigs.aggs[0] as IBucketAggConfig,
'1',
{}
) as esFilters.Filter;
expect(filterTrue).toHaveProperty('query');
expect(filterTrue.query).toHaveProperty('match_phrase');
expect(filterTrue.query.match_phrase).toHaveProperty('field');
expect(filterTrue.query.match_phrase.field).toBeTruthy();
});
//
it('should generate correct __missing__ filter', () => {
const aggConfigs = getAggConfigs([
{ type: BUCKET_TYPES.TERMS, schema: 'segment', params: { field: 'field' } },
]);
const filter = createFilterTerms(
aggConfigs.aggs[0],
aggConfigs.aggs[0] as IBucketAggConfig,
'__missing__',
{}
) as esFilters.ExistsFilter;
@ -95,13 +108,13 @@ describe('AggConfig Filters', () => {
expect(filter.meta).toHaveProperty('index', '1234');
expect(filter.meta).toHaveProperty('negate', true);
});
//
it('should generate correct __other__ filter', () => {
const aggConfigs = getAggConfigs([
{ type: BUCKET_TYPES.TERMS, schema: 'segment', params: { field: 'field' } },
]);
const [filter] = createFilterTerms(aggConfigs.aggs[0], '__other__', {
const [filter] = createFilterTerms(aggConfigs.aggs[0] as IBucketAggConfig, '__other__', {
terms: ['apache'],
}) as esFilters.Filter[];

View file

@ -20,9 +20,10 @@
import _ from 'lodash';
import moment from 'moment-timezone';
import { i18n } from '@kbn/i18n';
import { BUCKET_TYPES } from 'ui/agg_types/buckets/bucket_agg_types';
import { npStart } from 'ui/new_platform';
import { BucketAggParam, BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { createFilterDateHistogram } from './create_filter/date_histogram';
import { intervalOptions } from './_interval_options';
import { TimeIntervalParamEditor } from '../../vis/editors/default/controls/time_interval';
@ -31,7 +32,6 @@ import { DropPartialsParamEditor } from '../../vis/editors/default/controls/drop
import { ScaleMetricsParamEditor } from '../../vis/editors/default/controls/scale_metrics';
import { dateHistogramInterval } from '../../../../core_plugins/data/public';
import { writeParams } from '../agg_params';
import { AggConfigs } from '../agg_configs';
import { isMetricAggType } from '../metrics/metric_agg_type';
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
@ -77,7 +77,12 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
date: true,
},
makeLabel(agg) {
const output: Record<string, any> = writeParams(this.params as BucketAggParam[], agg);
let output: Record<string, any> = {};
if (this.params) {
output = writeParams(this.params, agg);
}
const field = agg.getFieldDisplayName();
return i18n.translate('common.ui.aggTypes.buckets.dateHistogramLabel', {
defaultMessage: '{fieldName} per {intervalDescription}',
@ -102,7 +107,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
return buckets;
},
},
} as any,
};
},
getFormat(agg) {
@ -144,7 +149,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
{
name: 'interval',
editorComponent: TimeIntervalParamEditor,
deserialize(state: any, agg: IBucketDateHistogramAggConfig) {
deserialize(state: any, agg) {
// For upgrading from 7.0.x to 7.1.x - intervals are now stored as key of options or custom value
if (state === 'custom') {
return _.get(agg, 'params.customInterval');
@ -164,7 +169,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
modifyAggConfigOnSearchRequestStart(agg: IBucketDateHistogramAggConfig) {
setBounds(agg, true);
},
write(agg: IBucketDateHistogramAggConfig, output: Record<string, any>, aggs: AggConfigs) {
write(agg, output, aggs) {
setBounds(agg, true);
agg.buckets.setInterval(getInterval(agg));
const { useNormalizedEsInterval, scaleMetricValues } = agg.params;
@ -200,7 +205,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
}
}
},
} as BucketAggParam,
},
{
name: 'time_zone',
default: undefined,
@ -208,7 +213,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
// since we do all the logic handling it "on the fly" in the `write` method, to prevent
// time_zones being persisted into saved_objects
serialize: _.noop,
write(agg: IBucketDateHistogramAggConfig, output: Record<string, any>) {
write(agg, output) {
// If a time_zone has been set explicitly always prefer this.
let tz = agg.params.time_zone;
if (!tz && agg.params.field) {
@ -230,7 +235,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
}
output.params.time_zone = tz;
},
} as BucketAggParam,
},
{
name: 'drop_partials',
default: false,
@ -251,7 +256,7 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
{
name: 'extended_bounds',
default: {},
write(agg: IBucketDateHistogramAggConfig, output: Record<string, any>) {
write(agg, output) {
const val = agg.params.extended_bounds;
if (val.min != null || val.max != null) {
@ -263,6 +268,6 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
return;
}
},
} as BucketAggParam,
},
],
});

View file

@ -86,7 +86,7 @@ export const dateRangeBucketAgg = new BucketAggType({
default: undefined,
// Implimentation method is the same as that of date_histogram
serialize: () => undefined,
write: (agg: IBucketAggConfig, output: Record<string, any>) => {
write: (agg, output) => {
const field = agg.getParam('field');
let tz = agg.getParam('time_zone');

View file

@ -25,7 +25,7 @@ import { i18n } from '@kbn/i18n';
import chrome from 'ui/chrome';
import { FiltersParamEditor, FilterValue } from '../../vis/editors/default/controls/filters';
import { createFilterFilters } from './create_filter/filters';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { BucketAggType } from './_bucket_agg_type';
import { Storage } from '../../../../../plugins/kibana_utils/public';
import { getQueryLog, esQuery } from '../../../../../plugins/data/public';
@ -48,7 +48,7 @@ export const filtersBucketAgg = new BucketAggType({
name: 'filters',
editorComponent: FiltersParamEditor,
default: [{ input: { query: '', language: config.get('search:queryLanguage') }, label: '' }],
write(aggConfig: IBucketAggConfig, output: Record<string, any>) {
write(aggConfig, output) {
const inFilters: FilterValue[] = aggConfig.params.filters;
if (!_.size(inFilters)) return;

View file

@ -141,7 +141,7 @@ export const geoHashBucketAgg = new BucketAggType<IBucketGeoHashGridAggConfig>({
},
],
getRequestAggs(agg) {
const aggs: IBucketAggConfig[] = [];
const aggs = [];
const params = agg.params;
if (params.isFilteredByCollar && agg.getField()) {

View file

@ -19,12 +19,13 @@
import { i18n } from '@kbn/i18n';
import { noop } from 'lodash';
import { METRIC_TYPES } from 'ui/agg_types/metrics/metric_agg_types';
import { AggConfigOptions } from 'ui/agg_types/agg_config';
import { AggConfigOptions } from '../agg_config';
import { BucketAggType } from './_bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
import { IBucketAggConfig } from './_bucket_agg_type';
import { METRIC_TYPES } from '../metrics/metric_agg_types';
const geotileGridTitle = i18n.translate('common.ui.aggTypes.buckets.geotileGridTitle', {
defaultMessage: 'Geotile',
@ -67,6 +68,6 @@ export const geoTileBucketAgg = new BucketAggType({
aggs.push(agg.aggConfigs.createAggConfig(aggConfig, { addToAggConfigs: false }));
}
return aggs;
return aggs as IBucketAggConfig[];
},
});

View file

@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
import { toastNotifications } from 'ui/notify';
import { npStart } from 'ui/new_platform';
import { BucketAggType, IBucketAggConfig, BucketAggParam } from './_bucket_agg_type';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { createFilterHistogram } from './create_filter/histogram';
import { NumberIntervalParamEditor } from '../../vis/editors/default/controls/number_interval';
import { MinDocCountParamEditor } from '../../vis/editors/default/controls/min_doc_count';
@ -130,7 +130,7 @@ export const histogramBucketAgg = new BucketAggType<IBucketHistogramAggConfig>({
);
});
},
write(aggConfig: IBucketHistogramAggConfig, output: Record<string, any>) {
write(aggConfig, output) {
let interval = parseFloat(aggConfig.params.interval);
if (interval <= 0) {
interval = 1;
@ -171,12 +171,12 @@ export const histogramBucketAgg = new BucketAggType<IBucketHistogramAggConfig>({
output.params.interval = interval;
},
} as BucketAggParam,
},
{
name: 'min_doc_count',
default: false,
editorComponent: MinDocCountParamEditor,
write(aggConfig: IBucketAggConfig, output: Record<string, any>) {
write(aggConfig, output) {
if (aggConfig.params.min_doc_count) {
output.params.min_doc_count = 0;
} else {
@ -197,7 +197,7 @@ export const histogramBucketAgg = new BucketAggType<IBucketHistogramAggConfig>({
max: '',
},
editorComponent: ExtendedBoundsParamEditor,
write(aggConfig: IBucketAggConfig, output: Record<string, any>) {
write(aggConfig, output) {
const { min, max } = aggConfig.params.extended_bounds;
if (aggConfig.params.has_extended_bounds && (min || min === 0) && (max || max === 0)) {

View file

@ -20,7 +20,7 @@
import { noop, map, omit, isNull } from 'lodash';
import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { BucketAggType } from './_bucket_agg_type';
import { IpRangeTypeParamEditor } from '../../vis/editors/default/controls/ip_range_type';
import { IpRangesParamEditor } from '../../vis/editors/default/controls/ip_ranges';
import { BUCKET_TYPES } from './bucket_agg_types';
@ -92,7 +92,7 @@ export const ipRangeBucketAgg = new BucketAggType({
mask: [{ mask: '0.0.0.0/1' }, { mask: '128.0.0.0/2' }],
},
editorComponent: IpRangesParamEditor,
write(aggConfig: IBucketAggConfig, output: Record<string, any>) {
write(aggConfig, output) {
const ipRangeType = aggConfig.params.ipRangeType;
let ranges = aggConfig.params.ranges[ipRangeType];

View file

@ -19,9 +19,10 @@
import { isString, isObject } from 'lodash';
import { IBucketAggConfig, BucketAggType, BucketAggParam } from './_bucket_agg_type';
import { AggConfig } from '../agg_config';
export const isType = (type: string) => {
return (agg: IBucketAggConfig): boolean => {
return (agg: AggConfig): boolean => {
const field = agg.params.field;
return field && field.type === type;
@ -31,7 +32,7 @@ export const isType = (type: string) => {
export const isStringType = isType('string');
export const migrateIncludeExcludeFormat = {
serialize(this: BucketAggParam, value: any, agg: IBucketAggConfig) {
serialize(this: BucketAggParam<IBucketAggConfig>, value: any, agg: IBucketAggConfig) {
if (this.shouldShow && !this.shouldShow(agg)) return;
if (!value || isString(value)) return value;
else return value.pattern;
@ -49,4 +50,4 @@ export const migrateIncludeExcludeFormat = {
output.params[this.name] = value;
}
},
};
} as Partial<BucketAggParam<IBucketAggConfig>>;

View file

@ -18,7 +18,6 @@
*/
import { i18n } from '@kbn/i18n';
import { IBucketAggConfig } from './_bucket_agg_type';
import { BucketAggType } from './_bucket_agg_type';
import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
import { RangeKey } from './range_key';
@ -102,7 +101,7 @@ export const rangeBucketAgg = new BucketAggType({
{ from: 1000, to: 2000 },
],
editorComponent: RangesEditor,
write(aggConfig: IBucketAggConfig, output: Record<string, any>) {
write(aggConfig, output) {
output.params.ranges = aggConfig.params.ranges;
output.params.keyed = true;
},

View file

@ -20,6 +20,7 @@
import { AggConfigs } from '../index';
import { BUCKET_TYPES } from './bucket_agg_types';
import { significantTermsBucketAgg } from './significant_terms';
import { IBucketAggConfig } from './_bucket_agg_type';
jest.mock('ui/new_platform');
@ -71,7 +72,7 @@ describe('Significant Terms Agg', () => {
name: 'FIELD',
},
});
const label = significantTermsBucketAgg.makeLabel(aggConfigs.aggs[0]);
const label = significantTermsBucketAgg.makeLabel(aggConfigs.aggs[0] as IBucketAggConfig);
expect(label).toBe('Top SIZE unusual terms in FIELD');
});

View file

@ -19,7 +19,7 @@
import { i18n } from '@kbn/i18n';
import { SizeParamEditor } from '../../vis/editors/default/controls/size';
import { BucketAggType, BucketAggParam } from './_bucket_agg_type';
import { BucketAggType } from './_bucket_agg_type';
import { createFilterTerms } from './create_filter/terms';
import { isStringType, migrateIncludeExcludeFormat } from './migrate_include_exclude_format';
import { BUCKET_TYPES } from './bucket_agg_types';
@ -63,7 +63,7 @@ export const significantTermsBucketAgg = new BucketAggType({
advanced: true,
shouldShow: isStringType,
...migrateIncludeExcludeFormat,
} as BucketAggParam,
},
{
name: 'include',
displayName: i18n.translate('common.ui.aggTypes.buckets.significantTerms.includeLabel', {
@ -73,6 +73,6 @@ export const significantTermsBucketAgg = new BucketAggType({
advanced: true,
shouldShow: isStringType,
...migrateIncludeExcludeFormat,
} as BucketAggParam,
},
],
});

View file

@ -21,9 +21,8 @@ import chrome from 'ui/chrome';
import { noop } from 'lodash';
import { i18n } from '@kbn/i18n';
import { SearchSource, getRequestInspectorStats, getResponseInspectorStats } from '../../courier';
import { BucketAggType, BucketAggParam } from './_bucket_agg_type';
import { BucketAggType } from './_bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { AggConfigOptions } from '../agg_config';
import { IBucketAggConfig } from './_bucket_agg_type';
import { createFilterTerms } from './create_filter/terms';
import { wrapWithInlineComp } from './inline_comp_wrapper';
@ -158,18 +157,21 @@ export const termsBucketAgg = new BucketAggType({
type: 'agg',
default: null,
editorComponent: OrderAggParamEditor,
makeAgg(termsAgg: IBucketAggConfig, state: AggConfigOptions) {
makeAgg(termsAgg, state) {
state = state || {};
state.schema = orderAggSchema;
const orderAgg = termsAgg.aggConfigs.createAggConfig(state, { addToAggConfigs: false });
const orderAgg = termsAgg.aggConfigs.createAggConfig<IBucketAggConfig>(state, {
addToAggConfigs: false,
});
orderAgg.id = termsAgg.id + '-orderAgg';
return orderAgg;
},
write(agg: IBucketAggConfig, output: Record<string, any>, aggs: AggConfigs) {
write(agg, output, aggs) {
const dir = agg.params.order.value;
const order: Record<string, any> = (output.params.order = {});
let orderAgg = agg.params.orderAgg || aggs.getResponseAggById(agg.params.orderBy);
let orderAgg = agg.params.orderAgg || aggs!.getResponseAggById(agg.params.orderBy);
// TODO: This works around an Elasticsearch bug the always casts terms agg scripts to strings
// thus causing issues with filtering. This probably causes other issues since float might not
@ -194,7 +196,8 @@ export const termsBucketAgg = new BucketAggType({
}
const orderAggId = orderAgg.id;
if (orderAgg.parentId) {
if (orderAgg.parentId && aggs) {
orderAgg = aggs.byId(orderAgg.parentId);
}
@ -243,9 +246,9 @@ export const termsBucketAgg = new BucketAggType({
displayName: i18n.translate('common.ui.aggTypes.otherBucket.labelForOtherBucketLabel', {
defaultMessage: 'Label for other bucket',
}),
shouldShow: (agg: IBucketAggConfig) => agg.getParam('otherBucket'),
shouldShow: agg => agg.getParam('otherBucket'),
write: noop,
} as BucketAggParam,
},
{
name: 'missingBucket',
default: false,
@ -263,7 +266,7 @@ export const termsBucketAgg = new BucketAggType({
displayName: i18n.translate('common.ui.aggTypes.otherBucket.labelForMissingValuesLabel', {
defaultMessage: 'Label for missing values',
}),
shouldShow: (agg: IBucketAggConfig) => agg.getParam('missingBucket'),
shouldShow: agg => agg.getParam('missingBucket'),
write: noop,
},
{
@ -286,5 +289,5 @@ export const termsBucketAgg = new BucketAggType({
shouldShow: isStringType,
...migrateIncludeExcludeFormat,
},
] as BucketAggParam[],
],
});

View file

@ -44,7 +44,7 @@ export const forwardModifyAggConfigOnSearchRequestStart = (paramName: string) =>
const nestedAggConfig = aggConfig.getParam(paramName);
if (nestedAggConfig && nestedAggConfig.type && nestedAggConfig.type.params) {
nestedAggConfig.type.params.forEach((param: MetricAggParam) => {
nestedAggConfig.type.params.forEach((param: MetricAggParam<IMetricAggConfig>) => {
// Check if this parameter of the nested aggConfig has a modifyAggConfigOnSearchRequestStart
// function, that needs to be called.
if (param.modifyAggConfigOnSearchRequestStart) {

View file

@ -22,7 +22,7 @@ import { noop } from 'lodash';
import { MetricAggParamEditor } from '../../../vis/editors/default/controls/metric_agg';
import { SubAggParamEditor } from '../../../vis/editors/default/controls/sub_agg';
import { forwardModifyAggConfigOnSearchRequestStart } from './nested_agg_helpers';
import { IMetricAggConfig } from '../metric_agg_type';
import { IMetricAggConfig, MetricAggParam } from '../metric_agg_type';
import { parentPipelineAggWriter } from './parent_pipeline_agg_writer';
// @ts-ignore
@ -74,7 +74,7 @@ export const parentPipelineAggHelper = {
name: 'customMetric',
editorComponent: SubAggParamEditor,
type: 'agg',
makeAgg(termsAgg: IMetricAggConfig, state: any) {
makeAgg(termsAgg, state: any) {
state = state || { type: 'count' };
state.schema = metricAggSchema;
@ -93,7 +93,7 @@ export const parentPipelineAggHelper = {
name: 'buckets_path',
write: noop,
},
];
] as Array<MetricAggParam<IMetricAggConfig>>;
},
getFormat(agg: IMetricAggConfig) {

View file

@ -22,7 +22,7 @@ import { siblingPipelineAggWriter } from './sibling_pipeline_agg_writer';
import { SubMetricParamEditor } from '../../../vis/editors/default/controls/sub_metric';
import { forwardModifyAggConfigOnSearchRequestStart } from './nested_agg_helpers';
import { IMetricAggConfig } from '../metric_agg_type';
import { IMetricAggConfig, MetricAggParam } from '../metric_agg_type';
// @ts-ignore
import { Schemas } from '../../../vis/editors/default/schemas';
@ -110,7 +110,7 @@ const siblingPipelineAggHelper = {
),
write: siblingPipelineAggWriter,
},
];
] as Array<MetricAggParam<IMetricAggConfig>>;
},
getFormat(agg: IMetricAggConfig) {

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { i18n } from '@kbn/i18n';
import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { MetricAggType } from './metric_agg_type';
import { METRIC_TYPES } from './metric_agg_types';
// @ts-ignore
@ -49,7 +49,7 @@ export const medianMetricAgg = new MetricAggType({
default: [50],
},
{
write(agg: IMetricAggConfig, output: Record<string, any>) {
write(agg, output) {
output.params.keyed = false;
},
},

View file

@ -25,24 +25,28 @@ import { AggConfig } from '../agg_config';
import { METRIC_TYPES } from './metric_agg_types';
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
export type IMetricAggConfig = AggConfig;
export interface MetricAggTypeConfig<TMetricAggConfig extends IMetricAggConfig>
extends AggTypeConfig<TMetricAggConfig, MetricAggParam> {
isScalable?: () => boolean;
subtype?: string;
export interface IMetricAggConfig extends AggConfig {
type: InstanceType<typeof MetricAggType>;
}
export interface MetricAggParam extends AggParamType {
export interface MetricAggParam<TMetricAggConfig extends AggConfig>
extends AggParamType<TMetricAggConfig> {
filterFieldTypes?: KBN_FIELD_TYPES | KBN_FIELD_TYPES[] | '*';
onlyAggregatable?: boolean;
}
const metricType = 'metrics';
export class MetricAggType<
TMetricAggConfig extends IMetricAggConfig = IMetricAggConfig
> extends AggType<TMetricAggConfig, MetricAggParam> {
interface MetricAggTypeConfig<TMetricAggConfig extends AggConfig>
extends AggTypeConfig<TMetricAggConfig, MetricAggParam<TMetricAggConfig>> {
isScalable?: () => boolean;
subtype?: string;
}
export class MetricAggType<TMetricAggConfig extends AggConfig = IMetricAggConfig> extends AggType<
TMetricAggConfig,
MetricAggParam<TMetricAggConfig>
> {
subtype: string;
isScalable: () => boolean;
type = metricType;

View file

@ -111,7 +111,7 @@ describe('parent pipeline aggs', function() {
// Grab the aggConfig off the vis (we don't actually use the vis for anything else)
metricAgg = metric.provider;
aggConfig = aggConfigs.aggs[1];
aggConfig = aggConfigs.aggs[1] as IMetricAggConfig;
aggDsl = aggConfig.toDsl(aggConfigs);
};

View file

@ -20,7 +20,7 @@
import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
import { PercentileRanksEditor } from '../../vis/editors/default/controls/percentile_ranks';
import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { MetricAggType } from './metric_agg_type';
import { getResponseAggConfigClass, IResponseAggConfig } from './lib/get_response_agg_config_class';
import { getPercentileValue } from './percentiles_get_value';
@ -72,7 +72,7 @@ export const percentileRanksMetricAgg = new MetricAggType<IPercentileRanksAggCon
default: [],
},
{
write(agg: IMetricAggConfig, output: Record<string, any>) {
write(agg, output) {
output.params.keyed = false;
},
},

View file

@ -19,7 +19,7 @@
import { i18n } from '@kbn/i18n';
import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { MetricAggType } from './metric_agg_type';
import { METRIC_TYPES } from './metric_agg_types';
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
@ -67,7 +67,7 @@ export const percentilesMetricAgg = new MetricAggType<IPercentileAggConfig>({
default: [1, 5, 25, 50, 75, 95, 99],
},
{
write(agg: IMetricAggConfig, output: Record<string, any>) {
write(agg, output) {
output.params.keyed = false;
},
},

View file

@ -107,7 +107,7 @@ describe('sibling pipeline aggs', () => {
// Grab the aggConfig off the vis (we don't actually use the vis for anything else)
metricAgg = metric.provider;
aggConfig = aggConfigs.aggs[1];
aggConfig = aggConfigs.aggs[1] as IMetricAggConfig;
aggDsl = aggConfig.toDsl(aggConfigs);
};

View file

@ -85,7 +85,7 @@ describe('Top hit metric', () => {
);
// Grab the aggConfig off the vis (we don't actually use the vis for anything else)
aggConfig = aggConfigs.aggs[0];
aggConfig = aggConfigs.aggs[0] as IMetricAggConfig;
aggDsl = aggConfig.toDsl(aggConfigs);
};

View file

@ -38,7 +38,7 @@ const isNumericFieldSelected = (agg: IMetricAggConfig) => {
return field && field.type && field.type === KBN_FIELD_TYPES.NUMBER;
};
aggTypeFieldFilters.addFilter((field, aggConfig: IMetricAggConfig) => {
aggTypeFieldFilters.addFilter((field, aggConfig) => {
if (
aggConfig.type.name !== METRIC_TYPES.TOP_HITS ||
_.get(aggConfig.schema, 'aggSettings.top_hits.allowStrings', false)
@ -82,7 +82,7 @@ export const topHitMetricAgg = new MetricAggType({
editorComponent: TopFieldParamEditor,
onlyAggregatable: false,
filterFieldTypes: '*',
write(agg: IMetricAggConfig, output: Record<string, any>) {
write(agg, output) {
const field = agg.getParam('field');
output.params = {};
@ -196,7 +196,7 @@ export const topHitMetricAgg = new MetricAggType({
value: 'asc',
},
],
write(agg: IMetricAggConfig, output: Record<string, any>) {
write(agg, output) {
const sortField = agg.params.sortField;
const sortOrder = agg.params.sortOrder;

View file

@ -20,26 +20,28 @@
import { AggConfig } from '../agg_config';
import { BaseParamType } from './base';
export class AggParamType extends BaseParamType {
makeAgg: (agg: AggConfig, state?: any) => AggConfig;
export class AggParamType<TAggConfig extends AggConfig = AggConfig> extends BaseParamType<
TAggConfig
> {
makeAgg: (agg: TAggConfig, state?: any) => TAggConfig;
constructor(config: Record<string, any>) {
super(config);
if (!config.write) {
this.write = (aggConfig: AggConfig, output: Record<string, any>) => {
this.write = (aggConfig: TAggConfig, output: Record<string, any>) => {
if (aggConfig.params[this.name] && aggConfig.params[this.name].length) {
output.params[this.name] = aggConfig.params[this.name];
}
};
}
if (!config.serialize) {
this.serialize = (agg: AggConfig) => {
this.serialize = (agg: TAggConfig) => {
return agg.toJSON();
};
}
if (!config.deserialize) {
this.deserialize = (state: unknown, agg?: AggConfig): AggConfig => {
this.deserialize = (state: unknown, agg?: TAggConfig): TAggConfig => {
if (!agg) {
throw new Error('aggConfig was not provided to AggParamType deserialize function');
}

View file

@ -17,12 +17,11 @@
* under the License.
*/
import { AggParam } from '../';
import { AggConfigs } from '../agg_configs';
import { AggConfig } from '../../vis';
import { SearchSourceContract, FetchOptions } from '../../courier/types';
export class BaseParamType implements AggParam {
export class BaseParamType<TAggConfig extends AggConfig = AggConfig> {
name: string;
type: string;
displayName: string;
@ -31,18 +30,18 @@ export class BaseParamType implements AggParam {
editorComponent: any = null;
default: any;
write: (
aggConfig: AggConfig,
aggConfig: TAggConfig,
output: Record<string, any>,
aggConfigs?: AggConfigs,
locals?: Record<string, any>
) => void;
serialize: (value: any, aggConfig?: AggConfig) => any;
deserialize: (value: any, aggConfig?: AggConfig) => any;
serialize: (value: any, aggConfig?: TAggConfig) => any;
deserialize: (value: any, aggConfig?: TAggConfig) => any;
options: any[];
valueType?: any;
onChange?(agg: AggConfig): void;
shouldShow?(agg: AggConfig): boolean;
onChange?(agg: TAggConfig): void;
shouldShow?(agg: TAggConfig): boolean;
/**
* A function that will be called before an aggConfig is serialized and sent to ES.
@ -54,7 +53,7 @@ export class BaseParamType implements AggParam {
* @returns {Promise<undefined>|undefined}
*/
modifyAggConfigOnSearchRequestStart: (
aggConfig: AggConfig,
aggConfig: TAggConfig,
searchSource?: SearchSourceContract,
options?: FetchOptions
) => void;
@ -70,7 +69,7 @@ export class BaseParamType implements AggParam {
this.default = config.default;
this.editorComponent = config.editorComponent;
const defaultWrite = (aggConfig: AggConfig, output: Record<string, any>) => {
const defaultWrite = (aggConfig: TAggConfig, output: Record<string, any>) => {
if (aggConfig.params[this.name]) {
output.params[this.name] = aggConfig.params[this.name] || this.default;
}