diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md index 1a0a08f44451a..ac8ddce6e7016 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md @@ -8,7 +8,7 @@ Signature: ```typescript -export declare type FieldFormatsStart = Omit & { +export declare type FieldFormatsStart = Omit & { deserialize: FormatFactory; }; ``` diff --git a/src/plugins/data/common/field_formats/field_formats_registry.test.ts b/src/plugins/data/common/field_formats/field_formats_registry.test.ts index 5e9866787f81c..86e44b69c05bf 100644 --- a/src/plugins/data/common/field_formats/field_formats_registry.test.ts +++ b/src/plugins/data/common/field_formats/field_formats_registry.test.ts @@ -76,6 +76,27 @@ describe('FieldFormatsRegistry', () => { expect(registeredFieldFormatters.get(StringFormat.id)).toBe(StringFormat); expect(registeredFieldFormatters.get(PercentFormat.id)).toBeUndefined(); }); + + test('should throw if registering a formatter with existing id ', () => { + fieldFormatsRegistry.register([BoolFormat]); + + expect(() => fieldFormatsRegistry.register([BoolFormat])).toThrowErrorMatchingInlineSnapshot( + `"Failed to register field format with id \\"boolean\\" as it already has been registered"` + ); + }); + }); + + describe('has', () => { + test('should provide an public "has" method', () => { + expect(fieldFormatsRegistry.has).toBeDefined(); + expect(typeof fieldFormatsRegistry.has).toBe('function'); + }); + + test('should check if field format registered', () => { + fieldFormatsRegistry.register([StringFormat]); + expect(fieldFormatsRegistry.has(StringFormat.id)).toBe(true); + expect(fieldFormatsRegistry.has(BoolFormat.id)).toBe(false); + }); }); describe('getType', () => { diff --git a/src/plugins/data/common/field_formats/field_formats_registry.ts b/src/plugins/data/common/field_formats/field_formats_registry.ts index 6ee4d15aab042..58660f5856923 100644 --- a/src/plugins/data/common/field_formats/field_formats_registry.ts +++ b/src/plugins/data/common/field_formats/field_formats_registry.ts @@ -253,7 +253,21 @@ export class FieldFormatsRegistry { } register(fieldFormats: FieldFormatInstanceType[]) { - fieldFormats.forEach((fieldFormat) => this.fieldFormats.set(fieldFormat.id, fieldFormat)); + fieldFormats.forEach((fieldFormat) => { + if (this.fieldFormats.has(fieldFormat.id)) + throw new Error( + `Failed to register field format with id "${fieldFormat.id}" as it already has been registered` + ); + this.fieldFormats.set(fieldFormat.id, fieldFormat); + }); + } + + /** + * Checks if field format with id already registered + * @param id + */ + has(id: string): boolean { + return this.fieldFormats.has(id); } /** diff --git a/src/plugins/data/common/field_formats/mocks.ts b/src/plugins/data/common/field_formats/mocks.ts index b027e021dea68..fa56afb2c277c 100644 --- a/src/plugins/data/common/field_formats/mocks.ts +++ b/src/plugins/data/common/field_formats/mocks.ts @@ -25,6 +25,7 @@ export const fieldFormatsMock: IFieldFormatsRegistry = { getTypeNameByEsTypes: jest.fn(), init: jest.fn(), register: jest.fn(), + has: jest.fn(), parseDefaultTypeMap: jest.fn(), deserialize: jest.fn().mockImplementation(() => { const DefaultFieldFormat = FieldFormat.from(identity); diff --git a/src/plugins/data/common/field_formats/types.ts b/src/plugins/data/common/field_formats/types.ts index 017dca1969fe7..b1d290388a42b 100644 --- a/src/plugins/data/common/field_formats/types.ts +++ b/src/plugins/data/common/field_formats/types.ts @@ -94,4 +94,4 @@ export interface IFieldFormatMetaParams { }; } -export type FieldFormatsStartCommon = Omit; +export type FieldFormatsStartCommon = Omit; diff --git a/src/plugins/data/public/field_formats/field_formats_service.ts b/src/plugins/data/public/field_formats/field_formats_service.ts index 4edea8788328d..89b3bf2249315 100644 --- a/src/plugins/data/public/field_formats/field_formats_service.ts +++ b/src/plugins/data/public/field_formats/field_formats_service.ts @@ -49,9 +49,9 @@ export class FieldFormatsService { } /** @public */ -export type FieldFormatsSetup = Pick; +export type FieldFormatsSetup = Pick; /** @public */ -export type FieldFormatsStart = Omit & { +export type FieldFormatsStart = Omit & { deserialize: FormatFactory; }; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 8ec5eeca70b06..d065cedce36b3 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1069,7 +1069,7 @@ export type FieldFormatsContentType = 'html' | 'text'; export type FieldFormatsGetConfigFn = GetConfigFn; // @public (undocumented) -export type FieldFormatsStart = Omit & { +export type FieldFormatsStart = Omit & { deserialize: FormatFactory; }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts index 35afd28c0f1ab..b5844fa5cf4d6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts @@ -35,7 +35,7 @@ export class IndexPatternDatasource { setup( core: CoreSetup, - { expressions, editorFrame, charts }: IndexPatternDatasourceSetupPlugins + { expressions, editorFrame, charts, data: dataSetup }: IndexPatternDatasourceSetupPlugins ) { editorFrame.registerDatasource(async () => { const { @@ -48,8 +48,11 @@ export class IndexPatternDatasource { } = await import('../async_services'); return core .getStartServices() - .then(([coreStart, { data, indexPatternFieldEditor, uiActions }]) => { - data.fieldFormats.register([getSuffixFormatter(data.fieldFormats.deserialize)]); + .then(([coreStart, { indexPatternFieldEditor, uiActions, data }]) => { + const suffixFormatter = getSuffixFormatter(data.fieldFormats.deserialize); + if (!dataSetup.fieldFormats.has(suffixFormatter.id)) { + dataSetup.fieldFormats.register([suffixFormatter]); + } expressions.registerFunction(timeScale); expressions.registerFunction(counterRate); expressions.registerFunction(renameColumns);