diff --git a/src/legacy/server/index_patterns/index.d.ts b/src/legacy/server/index_patterns/index.ts similarity index 88% rename from src/legacy/server/index_patterns/index.d.ts rename to src/legacy/server/index_patterns/index.ts index a68bc1c34544a..adf121dbec666 100644 --- a/src/legacy/server/index_patterns/index.d.ts +++ b/src/legacy/server/index_patterns/index.ts @@ -17,5 +17,6 @@ * under the License. */ -export { IndexPatternsService } from './service'; +export { indexPatternsMixin } from './mixin'; +export { IndexPatternsService, FieldDescriptor } from './service'; export { IndexPatternsServiceFactory } from './mixin'; diff --git a/src/legacy/server/index_patterns/mixin.d.ts b/src/legacy/server/index_patterns/mixin.d.ts deleted file mode 100644 index 0ebbc41608b1a..0000000000000 --- a/src/legacy/server/index_patterns/mixin.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { IndexPatternsService } from './service'; - -export type IndexPatternsServiceFactory = (args: { - callCluster: (endpoint: string, clientParams: any, options: any) => Promise; -}) => IndexPatternsService; diff --git a/src/legacy/server/index_patterns/mixin.js b/src/legacy/server/index_patterns/mixin.ts similarity index 56% rename from src/legacy/server/index_patterns/mixin.js rename to src/legacy/server/index_patterns/mixin.ts index 1903af7683c2e..2e232ef060f35 100644 --- a/src/legacy/server/index_patterns/mixin.js +++ b/src/legacy/server/index_patterns/mixin.ts @@ -17,25 +17,38 @@ * under the License. */ +import Hapi from 'hapi'; +import { APICaller } from 'src/core/server'; +import { Legacy } from 'kibana'; +import KbnServer from 'src/legacy/server/kbn_server'; import { IndexPatternsService } from './service'; -import { - createFieldsForWildcardRoute, - createFieldsForTimePatternRoute, -} from './routes'; +import { createFieldsForWildcardRoute, createFieldsForTimePatternRoute } from './routes'; -export function indexPatternsMixin(kbnServer, server) { - const pre = { +export type IndexPatternsServiceFactory = (args: { + callCluster: (endpoint: string, clientParams: any, options: any) => Promise; +}) => IndexPatternsService; + +interface IndexPatternRequest extends Legacy.Request { + getIndexPatternsService: () => IndexPatternsService; +} + +interface ServerWithFactory extends Legacy.Server { + addMemoizedFactoryToRequest: (...args: any) => void; +} + +export function indexPatternsMixin(kbnServer: KbnServer, server: ServerWithFactory) { + const pre: Record = { /** - * Create an instance of the `indexPatterns` service - * @type {Hapi.Pre} - */ + * Create an instance of the `indexPatterns` service + * @type {Hapi.Pre} + */ getIndexPatternsService: { assign: 'indexPatterns', - method(request) { + method(request: IndexPatternRequest) { return request.getIndexPatternsService(); - } - } + }, + }, }; /** @@ -44,9 +57,13 @@ export function indexPatternsMixin(kbnServer, server) { * @method server.indexPatternsServiceFactory * @type {IndexPatternsService} */ - server.decorate('server', 'indexPatternsServiceFactory', ({ callCluster }) => { - return new IndexPatternsService(callCluster); - }); + server.decorate( + 'server', + 'indexPatternsServiceFactory', + ({ callCluster }: { callCluster: APICaller }) => { + return new IndexPatternsService(callCluster); + } + ); /** * Get an instance of the IndexPatternsService configured for use @@ -55,9 +72,10 @@ export function indexPatternsMixin(kbnServer, server) { * @method request.getIndexPatternsService * @type {IndexPatternsService} */ - server.addMemoizedFactoryToRequest('getIndexPatternsService', request => { + server.addMemoizedFactoryToRequest('getIndexPatternsService', (request: Legacy.Request) => { const { callWithRequest } = request.server.plugins.elasticsearch.getCluster('data'); - const callCluster = (...args) => callWithRequest(request, ...args); + const callCluster = (endpoint: string, params: any, options: any) => + callWithRequest(request, endpoint, params, options); return server.indexPatternsServiceFactory({ callCluster }); }); diff --git a/src/legacy/server/index_patterns/routes/fields_for_time_pattern_route.js b/src/legacy/server/index_patterns/routes/fields_for_time_pattern_route.ts similarity index 55% rename from src/legacy/server/index_patterns/routes/fields_for_time_pattern_route.js rename to src/legacy/server/index_patterns/routes/fields_for_time_pattern_route.ts index f7ec6e751c7e7..4553a982e7653 100644 --- a/src/legacy/server/index_patterns/routes/fields_for_time_pattern_route.js +++ b/src/legacy/server/index_patterns/routes/fields_for_time_pattern_route.ts @@ -17,37 +17,56 @@ * under the License. */ +import Hapi from 'hapi'; import Joi from 'joi'; +import { IndexPatternsService } from '../service'; -export const createFieldsForTimePatternRoute = pre => ({ +interface FieldsForTimePatternRequest extends Hapi.Request { + pre: { + indexPatterns: IndexPatternsService; + }; + query: { + pattern: string; + interval: string; + look_back: number; + meta_fields: string[]; + }; +} + +interface Prerequisites { + getIndexPatternsService: Hapi.RouteOptionsPreAllOptions; +} + +export const createFieldsForTimePatternRoute = (pre: Prerequisites) => ({ path: '/api/index_patterns/_fields_for_time_pattern', method: 'GET', config: { pre: [pre.getIndexPatternsService], validate: { - query: Joi.object().keys({ - pattern: Joi.string().required(), - look_back: Joi.number().min(1).required(), - meta_fields: Joi.array().items(Joi.string()).default([]), - }).default() + query: Joi.object() + .keys({ + pattern: Joi.string().required(), + look_back: Joi.number() + .min(1) + .required(), + meta_fields: Joi.array() + .items(Joi.string()) + .default([]), + }) + .default(), }, - async handler(req) { + async handler(req: FieldsForTimePatternRequest) { const { indexPatterns } = req.pre; - const { - pattern, - interval, - look_back: lookBack, - meta_fields: metaFields, - } = req.query; + const { pattern, interval, look_back: lookBack, meta_fields: metaFields } = req.query; const fields = await indexPatterns.getFieldsForTimePattern({ pattern, interval, lookBack, - metaFields + metaFields, }); return { fields }; - } - } + }, + }, }); diff --git a/src/legacy/server/index_patterns/routes/fields_for_wildcard_route.js b/src/legacy/server/index_patterns/routes/fields_for_wildcard_route.ts similarity index 59% rename from src/legacy/server/index_patterns/routes/fields_for_wildcard_route.js rename to src/legacy/server/index_patterns/routes/fields_for_wildcard_route.ts index 953bba3e0b16d..7de946250d02f 100644 --- a/src/legacy/server/index_patterns/routes/fields_for_wildcard_route.js +++ b/src/legacy/server/index_patterns/routes/fields_for_wildcard_route.ts @@ -17,32 +17,49 @@ * under the License. */ +import Hapi from 'hapi'; import Joi from 'joi'; +import { IndexPatternsService } from '../service'; -export const createFieldsForWildcardRoute = pre => ({ +interface FieldsForWildcardPatternRequest extends Hapi.Request { + pre: { + indexPatterns: IndexPatternsService; + }; + query: { + pattern: string; + meta_fields: string[]; + }; +} + +interface Prerequisites { + getIndexPatternsService: Hapi.RouteOptionsPreAllOptions; +} + +export const createFieldsForWildcardRoute = (pre: Prerequisites) => ({ path: '/api/index_patterns/_fields_for_wildcard', method: 'GET', config: { pre: [pre.getIndexPatternsService], validate: { - query: Joi.object().keys({ - pattern: Joi.string().required(), - meta_fields: Joi.array().items(Joi.string()).default([]), - }).default() + query: Joi.object() + .keys({ + pattern: Joi.string().required(), + meta_fields: Joi.array() + .items(Joi.string()) + .default([]), + }) + .default(), }, - async handler(req) { + async handler(req: FieldsForWildcardPatternRequest) { const { indexPatterns } = req.pre; - const { - pattern, - meta_fields: metaFields, - } = req.query; + const { pattern, meta_fields: metaFields } = req.query; const fields = await indexPatterns.getFieldsForWildcard({ pattern, - metaFields + metaFields, }); return { fields }; - } - } + }, + }, }); diff --git a/src/legacy/server/index_patterns/routes/index.js b/src/legacy/server/index_patterns/routes/index.ts similarity index 100% rename from src/legacy/server/index_patterns/routes/index.js rename to src/legacy/server/index_patterns/routes/index.ts diff --git a/src/legacy/server/index_patterns/service/index.d.ts b/src/legacy/server/index_patterns/service/index.d.ts deleted file mode 100644 index 55c8811754197..0000000000000 --- a/src/legacy/server/index_patterns/service/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export { IndexPatternsService } from './index_patterns_service'; diff --git a/src/legacy/server/index_patterns/service/index.js b/src/legacy/server/index_patterns/service/index.js deleted file mode 100644 index 55c8811754197..0000000000000 --- a/src/legacy/server/index_patterns/service/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export { IndexPatternsService } from './index_patterns_service'; diff --git a/src/legacy/server/index_patterns/index.js b/src/legacy/server/index_patterns/service/index.ts similarity index 94% rename from src/legacy/server/index_patterns/index.js rename to src/legacy/server/index_patterns/service/index.ts index a2c2c1d79e031..496c4ba7b5b6f 100644 --- a/src/legacy/server/index_patterns/index.js +++ b/src/legacy/server/index_patterns/service/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { indexPatternsMixin } from './mixin'; +export * from './index_patterns_service'; diff --git a/src/legacy/server/index_patterns/service/index_patterns_service.d.ts b/src/legacy/server/index_patterns/service/index_patterns_service.d.ts deleted file mode 100644 index 75746e3c79bdc..0000000000000 --- a/src/legacy/server/index_patterns/service/index_patterns_service.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export interface IndexPatternsService { - // ATTENTION: this interface is incomplete - - getFieldsForWildcard(options: { pattern: string | string[] }): Promise; -} - -export interface FieldDescriptor { - aggregatable: boolean; - name: string; - readFromDocValues: boolean; - searchable: boolean; - type: string; - esTypes: string[]; - parent?: string; - subType?: string; -} diff --git a/src/legacy/server/index_patterns/service/index_patterns_service.js b/src/legacy/server/index_patterns/service/index_patterns_service.ts similarity index 75% rename from src/legacy/server/index_patterns/service/index_patterns_service.js rename to src/legacy/server/index_patterns/service/index_patterns_service.ts index 62b99b26ed7e4..6c32d99ad83f9 100644 --- a/src/legacy/server/index_patterns/service/index_patterns_service.js +++ b/src/legacy/server/index_patterns/service/index_patterns_service.ts @@ -17,27 +17,41 @@ * under the License. */ -import { - getFieldCapabilities, - resolveTimePattern, - createNoMatchingIndicesError, -} from './lib'; +import { APICaller } from 'src/core/server'; + +import { getFieldCapabilities, resolveTimePattern, createNoMatchingIndicesError } from './lib'; + +export interface FieldDescriptor { + aggregatable: boolean; + name: string; + readFromDocValues: boolean; + searchable: boolean; + type: string; + esTypes: string[]; + parent?: string; + subType?: string; +} export class IndexPatternsService { - constructor(callDataCluster) { + private _callDataCluster: APICaller; + + constructor(callDataCluster: APICaller) { this._callDataCluster = callDataCluster; } /** * Get a list of field objects for an index pattern that may contain wildcards * - * @param {Object} [options={}] + * @param {Object} [options] * @property {String} options.pattern The index pattern * @property {Number} options.metaFields The list of underscore prefixed fields that should * be left in the field list (all others are removed). * @return {Promise>} */ - async getFieldsForWildcard(options = {}) { + async getFieldsForWildcard(options: { + pattern: string | string[]; + metaFields?: string[]; + }): Promise { const { pattern, metaFields } = options; return await getFieldCapabilities(this._callDataCluster, pattern, metaFields); } @@ -52,7 +66,12 @@ export class IndexPatternsService { * be left in the field list (all others are removed). * @return {Promise>} */ - async getFieldsForTimePattern(options = {}) { + async getFieldsForTimePattern(options: { + pattern: string; + metaFields: string[]; + lookBack: number; + interval: string; + }) { const { pattern, lookBack, metaFields } = options; const { matches } = await resolveTimePattern(this._callDataCluster, pattern); const indices = matches.slice(0, lookBack); @@ -61,5 +80,4 @@ export class IndexPatternsService { } return await getFieldCapabilities(this._callDataCluster, indices, metaFields); } - } diff --git a/src/legacy/server/index_patterns/service/lib/errors.test.js b/src/legacy/server/index_patterns/service/lib/errors.test.ts similarity index 100% rename from src/legacy/server/index_patterns/service/lib/errors.test.js rename to src/legacy/server/index_patterns/service/lib/errors.test.ts diff --git a/src/legacy/server/index_patterns/service/lib/errors.js b/src/legacy/server/index_patterns/service/lib/errors.ts similarity index 87% rename from src/legacy/server/index_patterns/service/lib/errors.js rename to src/legacy/server/index_patterns/service/lib/errors.ts index b6c659c53ea8d..603d558aaf11a 100644 --- a/src/legacy/server/index_patterns/service/lib/errors.js +++ b/src/legacy/server/index_patterns/service/lib/errors.ts @@ -29,7 +29,7 @@ const ERR_NO_MATCHING_INDICES = 'no_matching_indices'; * @param {Any} err * @return {Boolean} */ -export function isEsIndexNotFoundError(err) { +export function isEsIndexNotFoundError(err: any) { return get(err, ['body', 'error', 'type']) === ERR_ES_INDEX_NOT_FOUND; } @@ -39,9 +39,9 @@ export function isEsIndexNotFoundError(err) { * @param {String} pattern the pattern which indexes were supposed to match * @return {Boom} */ -export function createNoMatchingIndicesError(pattern) { +export function createNoMatchingIndicesError(pattern: string[] | string) { const err = Boom.notFound(`No indices match pattern "${pattern}"`); - err.output.payload.code = ERR_NO_MATCHING_INDICES; + (err.output.payload as any).code = ERR_NO_MATCHING_INDICES; return err; } @@ -51,7 +51,7 @@ export function createNoMatchingIndicesError(pattern) { * @param {Any} err * @return {Boolean} */ -export function isNoMatchingIndicesError(err) { +export function isNoMatchingIndicesError(err: Error) { return get(err, ['output', 'payload', 'code']) === ERR_NO_MATCHING_INDICES; } @@ -61,7 +61,7 @@ export function isNoMatchingIndicesError(err) { * @param {[type]} indices [description] * @return {[type]} [description] */ -export function convertEsError(indices, error) { +export function convertEsError(indices: string[] | string, error: any) { if (isEsIndexNotFoundError(error)) { return createNoMatchingIndicesError(indices); } diff --git a/src/legacy/server/index_patterns/service/lib/es_api.test.js b/src/legacy/server/index_patterns/service/lib/es_api.test.ts similarity index 94% rename from src/legacy/server/index_patterns/service/lib/es_api.test.js rename to src/legacy/server/index_patterns/service/lib/es_api.test.ts index 5a77f6fec5b1b..046da7bbb29af 100644 --- a/src/legacy/server/index_patterns/service/lib/es_api.test.js +++ b/src/legacy/server/index_patterns/service/lib/es_api.test.ts @@ -27,8 +27,8 @@ import { callIndexAliasApi, callFieldCapsApi } from './es_api'; describe('server/index_patterns/service/lib/es_api', () => { describe('#callIndexAliasApi()', () => { - let sandbox; - beforeEach(() => sandbox = sinon.createSandbox()); + let sandbox: sinon.SinonSandbox; + beforeEach(() => (sandbox = sinon.createSandbox())); afterEach(() => sandbox.restore()); it('calls indices.getAlias() via callCluster', async () => { @@ -70,7 +70,9 @@ describe('server/index_patterns/service/lib/es_api', () => { const convertedError = new Error('convertedError'); sandbox.stub(convertEsErrorNS, 'convertEsError').throws(convertedError); - const callCluster = sinon.spy(async () => { throw esError; }); + const callCluster = sinon.spy(async () => { + throw esError; + }); try { await callIndexAliasApi(callCluster, indices); throw new Error('expected callIndexAliasApi() to throw'); @@ -85,7 +87,7 @@ describe('server/index_patterns/service/lib/es_api', () => { describe('#callFieldCapsApi()', () => { let sandbox; - beforeEach(() => sandbox = sinon.createSandbox()); + beforeEach(() => (sandbox = sinon.createSandbox())); afterEach(() => sandbox.restore()); it('calls fieldCaps() via callCluster', async () => { @@ -128,7 +130,9 @@ describe('server/index_patterns/service/lib/es_api', () => { const convertedError = new Error('convertedError'); sandbox.stub(convertEsErrorNS, 'convertEsError').throws(convertedError); - const callCluster = sinon.spy(async () => { throw esError; }); + const callCluster = sinon.spy(async () => { + throw esError; + }); try { await callFieldCapsApi(callCluster, indices); throw new Error('expected callFieldCapsApi() to throw'); diff --git a/src/legacy/server/index_patterns/service/lib/es_api.js b/src/legacy/server/index_patterns/service/lib/es_api.ts similarity index 83% rename from src/legacy/server/index_patterns/service/lib/es_api.js rename to src/legacy/server/index_patterns/service/lib/es_api.ts index 9c698bbfe4329..50969eacc75a1 100644 --- a/src/legacy/server/index_patterns/service/lib/es_api.js +++ b/src/legacy/server/index_patterns/service/lib/es_api.ts @@ -17,7 +17,9 @@ * under the License. */ +import { APICaller } from 'src/core/server'; import { convertEsError } from './errors'; +import { FieldCapsResponse } from './field_capabilities'; /** * Call the index.getAlias API for a list of indices. @@ -33,12 +35,12 @@ import { convertEsError } from './errors'; * @param {Array|String} indices * @return {Promise} */ -export async function callIndexAliasApi(callCluster, indices) { +export async function callIndexAliasApi(callCluster: APICaller, indices: string[] | string) { try { return await callCluster('indices.getAlias', { index: indices, ignoreUnavailable: true, - allowNoIndices: false + allowNoIndices: false, }); } catch (error) { throw convertEsError(indices, error); @@ -56,14 +58,14 @@ export async function callIndexAliasApi(callCluster, indices) { * @param {Array|String} indices * @return {Promise} */ -export async function callFieldCapsApi(callCluster, indices) { +export async function callFieldCapsApi(callCluster: APICaller, indices: string[] | string) { try { - return await callCluster('fieldCaps', { + return (await callCluster('fieldCaps', { index: indices, fields: '*', ignoreUnavailable: true, - allowNoIndices: false - }); + allowNoIndices: false, + })) as FieldCapsResponse; } catch (error) { throw convertEsError(indices, error); } diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.test.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.test.ts similarity index 83% rename from src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.test.js rename to src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.test.ts index ad5a391f3a3fc..08f92fe3bc462 100644 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.test.js +++ b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.test.ts @@ -21,7 +21,7 @@ import sinon from 'sinon'; import { identity, shuffle, sortBy } from 'lodash'; -import { getFieldCapabilities } from '../field_capabilities'; +import { getFieldCapabilities } from '.'; import { callFieldCapsApi } from '../es_api'; import * as callFieldCapsApiNS from '../es_api'; @@ -33,26 +33,22 @@ import { mergeOverrides } from './overrides'; import * as mergeOverridesNS from './overrides'; describe('index_patterns/field_capabilities/field_capabilities', () => { - let sandbox; - beforeEach(() => sandbox = sinon.createSandbox()); + let sandbox: sinon.SinonSandbox; + beforeEach(() => (sandbox = sinon.createSandbox())); afterEach(() => sandbox.restore()); const footballs = [ { 'could be aything': true }, - { 'used to verify that values are directly passed through': true } + { 'used to verify that values are directly passed through': true }, ]; // assert that the stub was called with the exact `args`, using === matching - const calledWithExactly = (stub, args, matcher = sinon.match.same) => { - sinon.assert.calledWithExactly(stub, ...args.map(arg => matcher(arg))); + const calledWithExactly = (stub: sinon.SinonStub, args: any, matcher = sinon.match.same) => { + sinon.assert.calledWithExactly(stub, ...args.map((arg: any) => matcher(arg))); }; const stubDeps = (options = {}) => { - const { - esResponse = {}, - fieldsFromFieldCaps = [], - mergeOverrides = identity - } = options; + const { esResponse = {}, fieldsFromFieldCaps = [], mergeOverrides = identity } = options; sandbox.stub(callFieldCapsApiNS, 'callFieldCapsApi').callsFake(async () => esResponse); sandbox.stub(readFieldCapsResponseNS, 'readFieldCapsResponse').returns(fieldsFromFieldCaps); @@ -72,7 +68,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { describe('calls `readFieldCapsResponse`', () => { it('passes exact es response', async () => { stubDeps({ - esResponse: footballs[0] + esResponse: footballs[0], }); await getFieldCapabilities(); @@ -87,7 +83,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { const sortedLetters = sortBy(letters); stubDeps({ - fieldsFromFieldCaps: shuffle(letters.map(name => ({ name }))) + fieldsFromFieldCaps: shuffle(letters.map(name => ({ name }))), }); const fieldNames = (await getFieldCapabilities()).map(field => field.name); @@ -98,10 +94,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { describe('metaFields', () => { it('ensures there is a response for each metaField', async () => { stubDeps({ - fieldsFromFieldCaps: [ - { name: 'foo' }, - { name: 'bar' }, - ] + fieldsFromFieldCaps: [{ name: 'foo' }, { name: 'bar' }], }); const resp = await getFieldCapabilities(undefined, undefined, ['meta1', 'meta2']); @@ -111,20 +104,14 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { }); describe('defaults', () => { - const properties = [ - 'name', - 'type', - 'searchable', - 'aggregatable', - 'readFromDocValues', - ]; + const properties = ['name', 'type', 'searchable', 'aggregatable', 'readFromDocValues']; const createField = () => ({ name: footballs[0], type: footballs[0], searchable: footballs[0], aggregatable: footballs[0], - readFromDocValues: footballs[0] + readFromDocValues: footballs[0], }); describe('ensures that every field has property:', () => { @@ -134,7 +121,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { delete field[property]; stubDeps({ - fieldsFromFieldCaps: [field] + fieldsFromFieldCaps: [field], }); const resp = await getFieldCapabilities(); @@ -155,11 +142,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { describe('overrides', () => { it('passes each field to `mergeOverrides()`', async () => { - const fieldsFromFieldCaps = [ - { name: 'foo' }, - { name: 'bar' }, - { name: 'baz' }, - ]; + const fieldsFromFieldCaps = [{ name: 'foo' }, { name: 'bar' }, { name: 'baz' }]; stubDeps({ fieldsFromFieldCaps }); @@ -173,21 +156,18 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { }); it('replaces field with return value', async () => { - const fieldsFromFieldCaps = [ - { name: 'foo', bar: 1 }, - { name: 'baz', box: 2 }, - ]; + const fieldsFromFieldCaps = [{ name: 'foo', bar: 1 }, { name: 'baz', box: 2 }]; stubDeps({ fieldsFromFieldCaps, mergeOverrides() { return { notFieldAnymore: 1 }; - } + }, }); expect(await getFieldCapabilities()).toEqual([ { notFieldAnymore: 1 }, - { notFieldAnymore: 1 } + { notFieldAnymore: 1 }, ]); }); }); diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.ts similarity index 62% rename from src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.js rename to src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.ts index d409a4ed7d314..05e8d591f13a9 100644 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.js +++ b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_capabilities.ts @@ -19,13 +19,15 @@ import { defaults, indexBy, sortBy } from 'lodash'; +import { APICaller } from 'src/core/server'; import { callFieldCapsApi } from '../es_api'; -import { readFieldCapsResponse } from './field_caps_response'; +import { FieldCapsResponse, readFieldCapsResponse } from './field_caps_response'; import { mergeOverrides } from './overrides'; +import { FieldDescriptor } from '../../index_patterns_service'; -export const concatIfUniq = (arr, value) => ( - arr.includes(value) ? arr : arr.concat(value) -); +export function concatIfUniq(arr: T[], value: T) { + return arr.includes(value) ? arr : arr.concat(value); +} /** * Get the field capabilities for field in `indices`, excluding @@ -34,24 +36,29 @@ export const concatIfUniq = (arr, value) => ( * @param {Function} callCluster bound function for accessing an es client * @param {Array} [indices=[]] the list of indexes to check * @param {Array} [metaFields=[]] the list of internal fields to include - * @return {Promise>} + * @return {Promise>} */ -export async function getFieldCapabilities(callCluster, indices = [], metaFields = []) { - const esFieldCaps = await callFieldCapsApi(callCluster, indices); +export async function getFieldCapabilities( + callCluster: APICaller, + indices: string | string[] = [], + metaFields: string[] = [] +) { + const esFieldCaps: FieldCapsResponse = await callFieldCapsApi(callCluster, indices); const fieldsFromFieldCapsByName = indexBy(readFieldCapsResponse(esFieldCaps), 'name'); - const allFieldsUnsorted = Object - .keys(fieldsFromFieldCapsByName) + const allFieldsUnsorted = Object.keys(fieldsFromFieldCapsByName) .filter(name => !name.startsWith('_')) .concat(metaFields) - .reduce(concatIfUniq, []) - .map(name => defaults({}, fieldsFromFieldCapsByName[name], { - name, - type: 'string', - searchable: false, - aggregatable: false, - readFromDocValues: false - })) + .reduce(concatIfUniq, [] as string[]) + .map(name => + defaults({}, fieldsFromFieldCapsByName[name], { + name, + type: 'string', + searchable: false, + aggregatable: false, + readFromDocValues: false, + }) + ) .map(mergeOverrides); return sortBy(allFieldsUnsorted, 'name'); diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.test.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.test.js deleted file mode 100644 index 73d30c7ef1a61..0000000000000 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.test.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* eslint import/no-duplicates: 0 */ -import { cloneDeep, omit } from 'lodash'; -import sinon from 'sinon'; - -import * as shouldReadFieldFromDocValuesNS from './should_read_field_from_doc_values'; -import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_values'; - -import { getKbnFieldType } from '../../../../../utils'; -import { readFieldCapsResponse } from './field_caps_response'; -import esResponse from './__fixtures__/es_field_caps_response.json'; - -describe('index_patterns/field_capabilities/field_caps_response', () => { - let sandbox; - beforeEach(() => sandbox = sinon.createSandbox()); - afterEach(() => sandbox.restore()); - - describe('readFieldCapsResponse()', () => { - describe('conflicts', () => { - it('returns a field for each in response, no filtering', () => { - const fields = readFieldCapsResponse(esResponse); - expect(fields).toHaveLength(22); - }); - - it('includes only name, type, esTypes, searchable, aggregatable, readFromDocValues, and maybe conflictDescriptions, parent, ' + - 'and subType of each field', () => { - const responseClone = cloneDeep(esResponse); - // try to trick it into including an extra field - responseClone.fields['@timestamp'].date.extraCapability = true; - const fields = readFieldCapsResponse(responseClone); - - fields.forEach(field => { - const fieldWithoutOptionalKeys = omit(field, 'conflictDescriptions', 'parent', 'subType'); - - expect(Object.keys(fieldWithoutOptionalKeys)).toEqual([ - 'name', - 'type', - 'esTypes', - 'searchable', - 'aggregatable', - 'readFromDocValues' - ]); - }); - }); - - it('calls shouldReadFieldFromDocValues() for each non-conflict field', () => { - sandbox.spy(shouldReadFieldFromDocValuesNS, 'shouldReadFieldFromDocValues'); - const fields = readFieldCapsResponse(esResponse); - const conflictCount = fields.filter(f => f.type === 'conflict').length; - // +1 is for the object field which gets filtered out of the final return value from readFieldCapsResponse - sinon.assert.callCount(shouldReadFieldFromDocValues, fields.length - conflictCount + 1); - }); - - it('converts es types to kibana types', () => { - readFieldCapsResponse(esResponse).forEach(field => { - if (!getKbnFieldType(field.type)) { - throw new Error(`expected field to have kibana type, got ${field.type}`); - } - }); - }); - - it('should include the original ES types found for each field across indices', () => { - const fields = readFieldCapsResponse(esResponse); - fields.forEach((field) => { - const fixtureTypes = Object.keys(esResponse.fields[field.name]); - expect(field.esTypes).toEqual(fixtureTypes); - }); - }); - - it('returns fields with multiple types as conflicts', () => { - const fields = readFieldCapsResponse(esResponse); - const conflicts = fields.filter(f => f.type === 'conflict'); - expect(conflicts).toEqual([ - { - name: 'success', - type: 'conflict', - esTypes: ['boolean', 'keyword'], - searchable: true, - aggregatable: true, - readFromDocValues: false, - conflictDescriptions: { - boolean: [ - 'index1' - ], - keyword: [ - 'index2' - ] - } - } - ]); - }); - - it('does not return conflicted fields if the types are resolvable to the same kibana type', () => { - const fields = readFieldCapsResponse(esResponse); - const resolvableToString = fields.find(f => f.name === 'resolvable_to_string'); - const resolvableToNumber = fields.find(f => f.name === 'resolvable_to_number'); - expect(resolvableToString.type).toBe('string'); - expect(resolvableToNumber.type).toBe('number'); - }); - - it('returns aggregatable if at least one field is aggregatable', () => { - const fields = readFieldCapsResponse(esResponse); - const mixAggregatable = fields.find(f => f.name === 'mix_aggregatable'); - const mixAggregatableOther = fields.find(f => f.name === 'mix_aggregatable_other'); - expect(mixAggregatable.aggregatable).toBe(true); - expect(mixAggregatableOther.aggregatable).toBe(true); - }); - - it('returns searchable if at least one field is searchable', () => { - const fields = readFieldCapsResponse(esResponse); - const mixSearchable = fields.find(f => f.name === 'mix_searchable'); - const mixSearchableOther = fields.find(f => f.name === 'mix_searchable_other'); - expect(mixSearchable.searchable).toBe(true); - expect(mixSearchableOther.searchable).toBe(true); - }); - - it('returns multi fields with parent and subType keys describing the relationship', () => { - const fields = readFieldCapsResponse(esResponse); - const child = fields.find(f => f.name === 'multi_parent.child'); - expect(child).toHaveProperty('parent', 'multi_parent'); - expect(child).toHaveProperty('subType', 'multi'); - }); - - it('should not confuse object children for multi field children', () => { - // We detect multi fields by finding fields that have a dot in their name and then looking - // to see if their parents are *not* object or nested fields. In the future we may want to - // add parent and subType info for object and nested fields but for now we don't need it. - const fields = readFieldCapsResponse(esResponse); - const child = fields.find(f => f.name === 'object_parent.child'); - expect(child).not.toHaveProperty('parent'); - expect(child).not.toHaveProperty('subType'); - }); - }); - }); -}); diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.ts similarity index 77% rename from src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.js rename to src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.ts index 682ab01b48ece..6489402252957 100644 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.js +++ b/src/legacy/server/index_patterns/service/lib/field_capabilities/field_caps_response.ts @@ -20,6 +20,20 @@ import { uniq } from 'lodash'; import { castEsToKbnFieldTypeName } from '../../../../../utils'; import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_values'; +import { FieldDescriptor } from '../..'; + +interface FieldCapObject { + type: string; + searchable: boolean; + aggregatable: boolean; + indices?: string[]; + non_searchable_indices?: string[]; + non_aggregatable_indices?: string[]; +} + +export interface FieldCapsResponse { + fields: Record>; +} /** * Read the response from the _field_caps API to determine the type and @@ -62,8 +76,7 @@ import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_value * { * "name": "", * "type": "conflict", - * "aggregatable": false, - * "searchable": false, + * "aggregatable": false, * "searchable": false, * conflictDescriptions: { * "": [ * "" @@ -75,26 +88,31 @@ import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_value * } * * @param {FieldCapsResponse} fieldCapsResponse - * @return {Promise>} + * @return {Array} */ -export function readFieldCapsResponse(fieldCapsResponse) { +export function readFieldCapsResponse(fieldCapsResponse: FieldCapsResponse): FieldDescriptor[] { const capsByNameThenType = fieldCapsResponse.fields; - const kibanaFormattedCaps = Object.keys(capsByNameThenType).map(fieldName => { + const kibanaFormattedCaps: FieldDescriptor[] = Object.keys(capsByNameThenType).map(fieldName => { const capsByType = capsByNameThenType[fieldName]; const types = Object.keys(capsByType); // If a single type is marked as searchable or aggregatable, all the types are searchable or aggregatable const isSearchable = types.some(type => { - return !!capsByType[type].searchable || - (!!capsByType[type].non_searchable_indices && capsByType[type].non_searchable_indices.length > 0); + return ( + !!capsByType[type].searchable || + (!!capsByType[type].non_searchable_indices && + capsByType[type].non_searchable_indices!.length > 0) + ); }); const isAggregatable = types.some(type => { - return !!capsByType[type].aggregatable || - (!!capsByType[type].non_aggregatable_indices && capsByType[type].non_aggregatable_indices.length > 0); + return ( + !!capsByType[type].aggregatable || + (!!capsByType[type].non_aggregatable_indices && + capsByType[type].non_aggregatable_indices!.length > 0) + ); }); - // If there are multiple types but they all resolve to the same kibana type // ignore the conflict and carry on (my wayward son) const uniqueKibanaTypes = uniq(types.map(castEsToKbnFieldTypeName)); @@ -106,10 +124,13 @@ export function readFieldCapsResponse(fieldCapsResponse) { searchable: isSearchable, aggregatable: isAggregatable, readFromDocValues: false, - conflictDescriptions: types.reduce((acc, esType) => ({ - ...acc, - [esType]: capsByType[esType].indices - }), {}) + conflictDescriptions: types.reduce( + (acc, esType) => ({ + ...acc, + [esType]: capsByType[esType].indices, + }), + {} + ), }; } @@ -132,7 +153,10 @@ export function readFieldCapsResponse(fieldCapsResponse) { // Discern which sub fields are multi fields. If the parent field is not an object or nested field // the child must be a multi field. subFields.forEach(field => { - const parentFieldName = field.name.split('.').slice(0, -1).join('.'); + const parentFieldName = field.name + .split('.') + .slice(0, -1) + .join('.'); const parentFieldCaps = kibanaFormattedCaps.find(caps => caps.name === parentFieldName); if (parentFieldCaps && !['object', 'nested'].includes(parentFieldCaps.type)) { diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/index.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/index.ts similarity index 93% rename from src/legacy/server/index_patterns/service/lib/field_capabilities/index.js rename to src/legacy/server/index_patterns/service/lib/field_capabilities/index.ts index ffc8e16e645da..8ac4225557784 100644 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/index.js +++ b/src/legacy/server/index_patterns/service/lib/field_capabilities/index.ts @@ -18,3 +18,4 @@ */ export { getFieldCapabilities } from './field_capabilities'; +export { FieldCapsResponse } from './field_caps_response'; diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/overrides.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/overrides.ts similarity index 80% rename from src/legacy/server/index_patterns/service/lib/field_capabilities/overrides.js rename to src/legacy/server/index_patterns/service/lib/field_capabilities/overrides.ts index 86c06ef6f3c61..6310bf02e4430 100644 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/overrides.js +++ b/src/legacy/server/index_patterns/service/lib/field_capabilities/overrides.ts @@ -18,8 +18,9 @@ */ import { merge } from 'lodash'; +import { FieldDescriptor } from '../../index_patterns_service'; -const OVERRIDES = { +const OVERRIDES: Record> = { _source: { type: '_source' }, _index: { type: 'string' }, _type: { type: 'string' }, @@ -27,22 +28,22 @@ const OVERRIDES = { _timestamp: { type: 'date', searchable: true, - aggregatable: true + aggregatable: true, }, _score: { type: 'number', searchable: false, - aggregatable: false + aggregatable: false, }, }; /** * Merge overrides for specific metaFields * - * @param {FieldInfo} field - * @return {FieldInfo} + * @param {FieldDescriptor} field + * @return {FieldDescriptor} */ -export function mergeOverrides(field) { +export function mergeOverrides(field: FieldDescriptor): FieldDescriptor { if (OVERRIDES.hasOwnProperty(field.name)) { return merge(field, OVERRIDES[field.name]); } else { diff --git a/src/legacy/server/index_patterns/service/lib/field_capabilities/should_read_field_from_doc_values.js b/src/legacy/server/index_patterns/service/lib/field_capabilities/should_read_field_from_doc_values.ts similarity index 91% rename from src/legacy/server/index_patterns/service/lib/field_capabilities/should_read_field_from_doc_values.js rename to src/legacy/server/index_patterns/service/lib/field_capabilities/should_read_field_from_doc_values.ts index 635f616d00527..6d58f7a02c134 100644 --- a/src/legacy/server/index_patterns/service/lib/field_capabilities/should_read_field_from_doc_values.js +++ b/src/legacy/server/index_patterns/service/lib/field_capabilities/should_read_field_from_doc_values.ts @@ -17,6 +17,6 @@ * under the License. */ -export function shouldReadFieldFromDocValues(aggregatable, esType) { +export function shouldReadFieldFromDocValues(aggregatable: boolean, esType: string) { return aggregatable && esType !== 'text' && !esType.startsWith('_'); } diff --git a/src/legacy/server/index_patterns/service/lib/index.js b/src/legacy/server/index_patterns/service/lib/index.ts similarity index 100% rename from src/legacy/server/index_patterns/service/lib/index.js rename to src/legacy/server/index_patterns/service/lib/index.ts diff --git a/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.test.js b/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.test.ts similarity index 95% rename from src/legacy/server/index_patterns/service/lib/resolve_time_pattern.test.js rename to src/legacy/server/index_patterns/service/lib/resolve_time_pattern.test.ts index f1b67d3d7f880..af44eddc3d894 100644 --- a/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.test.js +++ b/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.test.ts @@ -31,8 +31,8 @@ import { resolveTimePattern } from './resolve_time_pattern'; const TIME_PATTERN = '[logs-]dddd-YYYY.w'; describe('server/index_patterns/service/lib/resolve_time_pattern', () => { - let sandbox; - beforeEach(() => sandbox = sinon.createSandbox()); + let sandbox: sinon.SinonSandbox; + beforeEach(() => (sandbox = sinon.createSandbox())); afterEach(() => sandbox.restore()); describe('resolveTimePattern()', () => { @@ -47,8 +47,7 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => { const timePattern = {}; const wildcard = {}; - sandbox.stub(timePatternToWildcardNS, 'timePatternToWildcard') - .returns(wildcard); + sandbox.stub(timePatternToWildcardNS, 'timePatternToWildcard').returns(wildcard); await resolveTimePattern(noop, timePattern); sinon.assert.calledOnce(timePatternToWildcard); @@ -60,8 +59,7 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => { const wildcard = {}; sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({}); - sandbox.stub(timePatternToWildcardNS, 'timePatternToWildcard') - .returns(wildcard); + sandbox.stub(timePatternToWildcardNS, 'timePatternToWildcard').returns(wildcard); await resolveTimePattern(noop, timePattern); sinon.assert.calledOnce(callIndexAliasApi); @@ -110,7 +108,7 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => { expect(resp.matches).toEqual([ 'logs-Saturday-2017.1', 'logs-Friday-2017.1', - 'logs-Sunday-2017.1' + 'logs-Sunday-2017.1', ]); }); }); diff --git a/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.js b/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.ts similarity index 73% rename from src/legacy/server/index_patterns/service/lib/resolve_time_pattern.js rename to src/legacy/server/index_patterns/service/lib/resolve_time_pattern.ts index 21ea91baf5937..2f44775af01ea 100644 --- a/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.js +++ b/src/legacy/server/index_patterns/service/lib/resolve_time_pattern.ts @@ -20,9 +20,17 @@ import { chain } from 'lodash'; import moment from 'moment'; +import { APICaller } from 'src/core/server'; import { timePatternToWildcard } from './time_pattern_to_wildcard'; import { callIndexAliasApi } from './es_api'; +interface IndexDetail { + valid: boolean; + indexName: string; + order: moment.Moment; + isMatch: boolean; +} + /** * Convert a time pattern into a list of indexes it could * have matched and ones it did match. @@ -34,24 +42,24 @@ import { callIndexAliasApi } from './es_api'; * and the indices that actually match the time * pattern (matches); */ -export async function resolveTimePattern(callCluster, timePattern) { +export async function resolveTimePattern(callCluster: APICaller, timePattern: string) { const aliases = await callIndexAliasApi(callCluster, timePatternToWildcard(timePattern)); - const allIndexDetails = chain(aliases) - .reduce((acc, index, indexName) => acc.concat( - indexName, - Object.keys(index.aliases || {}) - ), []) + const allIndexDetails: IndexDetail[] = chain(aliases) + .reduce( + (acc, index, indexName) => acc.concat(indexName, Object.keys(index.aliases || {})), + [] as string[] + ) .sort() .uniq(true) - .map(indexName => { + .map((indexName: string) => { const parsed = moment(indexName, timePattern, true); if (!parsed.isValid()) { return { valid: false, indexName, order: indexName, - isMatch: false + isMatch: false, }; } @@ -59,18 +67,15 @@ export async function resolveTimePattern(callCluster, timePattern) { valid: true, indexName, order: parsed, - isMatch: indexName === parsed.format(timePattern) + isMatch: indexName === parsed.format(timePattern), }; }) .sortByOrder(['valid', 'order'], ['desc', 'desc']) .value(); return { - all: allIndexDetails - .map(details => details.indexName), + all: allIndexDetails.map(details => details.indexName), - matches: allIndexDetails - .filter(details => details.isMatch) - .map(details => details.indexName), + matches: allIndexDetails.filter(details => details.isMatch).map(details => details.indexName), }; } diff --git a/src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.test.js b/src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.test.ts similarity index 100% rename from src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.test.js rename to src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.test.ts diff --git a/src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.js b/src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.ts similarity index 96% rename from src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.js rename to src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.ts index 7db1cbae267b1..27872cb84810a 100644 --- a/src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.js +++ b/src/legacy/server/index_patterns/service/lib/time_pattern_to_wildcard.ts @@ -25,7 +25,7 @@ * @param {String} timePattern * @return {String} */ -export function timePatternToWildcard(timePattern) { +export function timePatternToWildcard(timePattern: string) { let wildcard = ''; let inEscape = false; let inPattern = false; diff --git a/src/legacy/utils/index.d.ts b/src/legacy/utils/index.d.ts index a7317f59637ed..5319f842d76c9 100644 --- a/src/legacy/utils/index.d.ts +++ b/src/legacy/utils/index.d.ts @@ -20,3 +20,5 @@ export function parseCommaSeparatedList(input: string | string[]): string[]; export function formatListAsProse(list: string[], options?: { inclusive?: boolean }): string; + +export function castEsToKbnFieldTypeName(name: string): string;