From b3233f8713e0f5c8685d9eb4d337c5bbad7289b2 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 27 Jul 2021 11:56:20 +0200 Subject: [PATCH 1/4] =?UTF-8?q?fix=20field=20formats=20contract=20expose?= =?UTF-8?q?=20register,=20when=20it=20shouldn=E2=80=99t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../field_formats_registry.test.ts | 21 +++++++++++++++++++ .../field_formats/field_formats_registry.ts | 16 +++++++++++++- .../data/common/field_formats/types.ts | 2 +- .../field_formats/field_formats_service.ts | 4 ++-- .../public/indexpattern_datasource/index.ts | 9 +++++--- 5 files changed, 45 insertions(+), 7 deletions(-) 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/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/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts index 35afd28c0f1ab..9d38163466b5a 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); From 757b64403edd1851abf7c358cedb94e2201e0e6c Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 27 Jul 2021 11:57:55 +0200 Subject: [PATCH 2/4] fix docs --- .../kibana-plugin-plugins-data-public.fieldformatsstart.md | 2 +- src/plugins/data/public/public.api.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/public/public.api.md b/src/plugins/data/public/public.api.md index 781d073b34978..2238dca93fb9f 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; }; From e59e1d9636c3bce6e854cf336d5a52c8548ec11b Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 27 Jul 2021 12:27:11 +0200 Subject: [PATCH 3/4] fix --- x-pack/plugins/lens/public/indexpattern_datasource/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts index 9d38163466b5a..b5844fa5cf4d6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts @@ -49,7 +49,7 @@ export class IndexPatternDatasource { return core .getStartServices() .then(([coreStart, { indexPatternFieldEditor, uiActions, data }]) => { - const suffixFormatter = getSuffixFormatter(() => data.fieldFormats.deserialize); + const suffixFormatter = getSuffixFormatter(data.fieldFormats.deserialize); if (!dataSetup.fieldFormats.has(suffixFormatter.id)) { dataSetup.fieldFormats.register([suffixFormatter]); } From 692c987627c65f1b728265ccededc80e1c333715 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 27 Jul 2021 12:59:45 +0200 Subject: [PATCH 4/4] fix --- src/plugins/data/common/field_formats/mocks.ts | 1 + 1 file changed, 1 insertion(+) 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);