diff --git a/docs/canvas/canvas-function-reference.asciidoc b/docs/canvas/canvas-function-reference.asciidoc index 67210c9d77057..272cd524c2c20 100644 --- a/docs/canvas/canvas-function-reference.asciidoc +++ b/docs/canvas/canvas-function-reference.asciidoc @@ -2893,6 +2893,33 @@ Alias: `type` [[u_fns]] == U +[float] +[[uiSetting_fn]] +=== `uiSetting` + +Returns a UI settings parameter value. + +*Accepts:* `null` + +[cols="3*^<"] +|=== +|Argument |Type |Description + +|_Unnamed_ *** + +Aliases: `parameter` +|`string` +|The parameter name. + +|`default` +|`any` +|A default value in case of the parameter is not set. + +Default: `null` +|=== + +*Returns:* `ui_setting` + [float] [[urlparam_fn]] === `urlparam` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md index 6ba0f0feb82b3..9afd603bc4869 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md @@ -70,7 +70,7 @@ The actual function is defined in the fn key. The function can be \ | Method | Modifiers | Description | | --- | --- | --- | -| [setup()](./kibana-plugin-plugins-expressions-public.expressionsservice.setup.md) | | Returns Kibana Platform \*setup\* life-cycle contract. Useful to return the same contract on server-side and browser-side. | -| [start()](./kibana-plugin-plugins-expressions-public.expressionsservice.start.md) | | Returns Kibana Platform \*start\* life-cycle contract. Useful to return the same contract on server-side and browser-side. | +| [setup(args)](./kibana-plugin-plugins-expressions-public.expressionsservice.setup.md) | | Returns Kibana Platform \*setup\* life-cycle contract. Useful to return the same contract on server-side and browser-side. | +| [start(args)](./kibana-plugin-plugins-expressions-public.expressionsservice.start.md) | | Returns Kibana Platform \*start\* life-cycle contract. Useful to return the same contract on server-side and browser-side. | | [stop()](./kibana-plugin-plugins-expressions-public.expressionsservice.stop.md) | | | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md index a51f3f073d518..991f1f717d5f5 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md @@ -9,8 +9,15 @@ Returns Kibana Platform \*setup\* life-cycle contract. Useful to return the same Signature: ```typescript -setup(): ExpressionsServiceSetup; +setup(...args: unknown[]): ExpressionsServiceSetup; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| args | unknown[] | | + Returns: `ExpressionsServiceSetup` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md index 766d703a0729d..34d33cacabebb 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md @@ -9,8 +9,15 @@ Returns Kibana Platform \*start\* life-cycle contract. Useful to return the same Signature: ```typescript -start(): ExpressionsServiceStart; +start(...args: unknown[]): ExpressionsServiceStart; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| args | unknown[] | | + Returns: `ExpressionsServiceStart` diff --git a/src/plugins/expressions/common/executor/executor.test.ts b/src/plugins/expressions/common/executor/executor.test.ts index 6175c9e170a90..3c24a3c24e01b 100644 --- a/src/plugins/expressions/common/executor/executor.test.ts +++ b/src/plugins/expressions/common/executor/executor.test.ts @@ -52,12 +52,6 @@ describe('Executor', () => { executor.registerFunction(expressionFunctions.clog); }); - test('can register all functions', () => { - const executor = new Executor(); - for (const functionDefinition of expressionFunctions.functionSpecs) - executor.registerFunction(functionDefinition); - }); - test('can retrieve all functions', () => { const executor = new Executor(); executor.registerFunction(expressionFunctions.clog); @@ -67,12 +61,24 @@ describe('Executor', () => { test('can retrieve all functions - 2', () => { const executor = new Executor(); - for (const functionDefinition of expressionFunctions.functionSpecs) + const functionSpecs = [ + expressionFunctions.clog, + expressionFunctions.font, + expressionFunctions.variableSet, + expressionFunctions.variable, + expressionFunctions.theme, + expressionFunctions.cumulativeSum, + expressionFunctions.derivative, + expressionFunctions.movingAverage, + expressionFunctions.mapColumn, + expressionFunctions.math, + ]; + for (const functionDefinition of functionSpecs) { executor.registerFunction(functionDefinition); + } const functions = executor.getFunctions(); - expect(Object.keys(functions).sort()).toEqual( - expressionFunctions.functionSpecs.map((spec) => spec.name).sort() - ); + + expect(Object.keys(functions).sort()).toEqual(functionSpecs.map((spec) => spec.name).sort()); }); }); diff --git a/src/plugins/expressions/common/executor/executor.ts b/src/plugins/expressions/common/executor/executor.ts index 1eea51a0e1ec4..a307172aff973 100644 --- a/src/plugins/expressions/common/executor/executor.ts +++ b/src/plugins/expressions/common/executor/executor.ts @@ -19,7 +19,6 @@ import { ExpressionType } from '../expression_types/expression_type'; import { AnyExpressionTypeDefinition } from '../expression_types/types'; import { ExpressionAstExpression, ExpressionAstFunction } from '../ast'; import { ExpressionValueError, typeSpecs } from '../expression_types/specs'; -import { functionSpecs } from '../expression_functions/specs'; import { getByAlias } from '../util'; import { SavedObjectReference } from '../../../../core/types'; import { PersistableStateService, SerializableState } from '../../../kibana_utils/common'; @@ -85,7 +84,7 @@ export class Executor = Record { const executor = new Executor(state); for (const type of typeSpecs) executor.registerType(type); - for (const func of functionSpecs) executor.registerFunction(func); + return executor; } diff --git a/src/plugins/expressions/common/expression_functions/specs/index.ts b/src/plugins/expressions/common/expression_functions/specs/index.ts index 9408b3a433712..20a6f9aac4567 100644 --- a/src/plugins/expressions/common/expression_functions/specs/index.ts +++ b/src/plugins/expressions/common/expression_functions/specs/index.ts @@ -6,31 +6,6 @@ * Side Public License, v 1. */ -import { clog } from './clog'; -import { font } from './font'; -import { variableSet } from './var_set'; -import { variable } from './var'; -import { AnyExpressionFunctionDefinition } from '../types'; -import { theme } from './theme'; -import { cumulativeSum } from './cumulative_sum'; -import { derivative } from './derivative'; -import { movingAverage } from './moving_average'; -import { mapColumn } from './map_column'; -import { math } from './math'; - -export const functionSpecs: AnyExpressionFunctionDefinition[] = [ - clog, - font, - variableSet, - variable, - theme, - cumulativeSum, - derivative, - movingAverage, - mapColumn, - math, -]; - export * from './clog'; export * from './font'; export * from './var_set'; @@ -39,5 +14,6 @@ export * from './theme'; export * from './cumulative_sum'; export * from './derivative'; export * from './moving_average'; +export * from './ui_setting'; export { mapColumn, MapColumnArguments } from './map_column'; export { math, MathArguments, MathInput } from './math'; diff --git a/src/plugins/expressions/common/expression_functions/specs/tests/ui_setting.test.ts b/src/plugins/expressions/common/expression_functions/specs/tests/ui_setting.test.ts new file mode 100644 index 0000000000000..fb2c87588a4d4 --- /dev/null +++ b/src/plugins/expressions/common/expression_functions/specs/tests/ui_setting.test.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +jest.mock('../../../../common'); + +import { IUiSettingsClient } from 'src/core/public'; +import { getUiSettingFn } from '../ui_setting'; + +describe('uiSetting', () => { + describe('fn', () => { + let getStartDependencies: jest.MockedFunction< + Parameters[0]['getStartDependencies'] + >; + let uiSetting: ReturnType; + let uiSettings: jest.Mocked; + + beforeEach(() => { + uiSettings = ({ + get: jest.fn(), + } as unknown) as jest.Mocked; + getStartDependencies = (jest.fn(async () => ({ + uiSettings, + })) as unknown) as typeof getStartDependencies; + + uiSetting = getUiSettingFn({ getStartDependencies }); + }); + + it('should return a value', () => { + uiSettings.get.mockReturnValueOnce('value'); + + expect(uiSetting.fn(null, { parameter: 'something' }, {} as any)).resolves.toEqual({ + type: 'ui_setting', + key: 'something', + value: 'value', + }); + }); + + it('should pass a default value', async () => { + await uiSetting.fn(null, { parameter: 'something', default: 'default' }, {} as any); + + expect(uiSettings.get).toHaveBeenCalledWith('something', 'default'); + }); + + it('should throw an error when parameter does not exist', () => { + uiSettings.get.mockImplementationOnce(() => { + throw new Error(); + }); + + expect(uiSetting.fn(null, { parameter: 'something' }, {} as any)).rejects.toEqual( + new Error('Invalid parameter "something".') + ); + }); + + it('should get a request instance on the server-side', async () => { + const request = {}; + await uiSetting.fn(null, { parameter: 'something' }, { + getKibanaRequest: () => request, + } as any); + + const [[getKibanaRequest]] = getStartDependencies.mock.calls; + + expect(getKibanaRequest()).toBe(request); + }); + + it('should throw an error if request is not provided on the server-side', async () => { + await uiSetting.fn(null, { parameter: 'something' }, {} as any); + + const [[getKibanaRequest]] = getStartDependencies.mock.calls; + + expect(getKibanaRequest).toThrow(); + }); + }); +}); diff --git a/src/plugins/expressions/common/expression_functions/specs/ui_setting.ts b/src/plugins/expressions/common/expression_functions/specs/ui_setting.ts new file mode 100644 index 0000000000000..8e352e12d49c5 --- /dev/null +++ b/src/plugins/expressions/common/expression_functions/specs/ui_setting.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import type { KibanaRequest } from 'src/core/server'; +import { i18n } from '@kbn/i18n'; +import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; +import { UiSetting } from '../../expression_types/specs/ui_setting'; + +interface UiSettingsClient { + get(key: string, defaultValue?: T): T | Promise; +} + +interface UiSettingStartDependencies { + uiSettings: UiSettingsClient; +} + +interface UiSettingFnArguments { + getStartDependencies(getKibanaRequest: () => KibanaRequest): Promise; +} + +export interface UiSettingArguments { + default?: unknown; + parameter: string; +} + +export type ExpressionFunctionUiSetting = ExpressionFunctionDefinition< + 'uiSetting', + unknown, + UiSettingArguments, + Promise +>; + +export function getUiSettingFn({ + getStartDependencies, +}: UiSettingFnArguments): ExpressionFunctionUiSetting { + return { + name: 'uiSetting', + help: i18n.translate('expressions.functions.uiSetting.help', { + defaultMessage: 'Returns a UI settings parameter value.', + }), + args: { + default: { + help: i18n.translate('expressions.functions.uiSetting.args.default', { + defaultMessage: 'A default value in case of the parameter is not set.', + }), + }, + parameter: { + aliases: ['_'], + help: i18n.translate('expressions.functions.uiSetting.args.parameter', { + defaultMessage: 'The parameter name.', + }), + required: true, + types: ['string'], + }, + }, + async fn(input, { default: defaultValue, parameter }, { getKibanaRequest }) { + const { uiSettings } = await getStartDependencies(() => { + const request = getKibanaRequest?.(); + if (!request) { + throw new Error( + i18n.translate('expressions.functions.uiSetting.error.kibanaRequest', { + defaultMessage: + 'A KibanaRequest is required to get UI settings on the server. ' + + 'Please provide a request object to the expression execution params.', + }) + ); + } + + return request; + }); + + try { + return { + type: 'ui_setting', + key: parameter, + value: await uiSettings.get(parameter, defaultValue), + }; + } catch { + throw new Error( + i18n.translate('expressions.functions.uiSetting.error.parameter', { + defaultMessage: 'Invalid parameter "{parameter}".', + values: { parameter }, + }) + ); + } + }, + }; +} diff --git a/src/plugins/expressions/common/expression_types/specs/index.ts b/src/plugins/expressions/common/expression_types/specs/index.ts index 70427f8b337d8..c990d74672fcc 100644 --- a/src/plugins/expressions/common/expression_types/specs/index.ts +++ b/src/plugins/expressions/common/expression_types/specs/index.ts @@ -21,6 +21,7 @@ import { shape } from './shape'; import { string } from './string'; import { style } from './style'; import { AnyExpressionTypeDefinition } from '../types'; +import { uiSetting } from './ui_setting'; export const typeSpecs: AnyExpressionTypeDefinition[] = [ boolean, @@ -37,6 +38,7 @@ export const typeSpecs: AnyExpressionTypeDefinition[] = [ shape, string, style, + uiSetting, ]; export * from './boolean'; @@ -53,3 +55,4 @@ export * from './render'; export * from './shape'; export * from './string'; export * from './style'; +export * from './ui_setting'; diff --git a/src/plugins/expressions/common/expression_types/specs/tests/ui_setting.test.ts b/src/plugins/expressions/common/expression_types/specs/tests/ui_setting.test.ts new file mode 100644 index 0000000000000..a0a3d0d396b6e --- /dev/null +++ b/src/plugins/expressions/common/expression_types/specs/tests/ui_setting.test.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { UiSetting, uiSetting } from '../ui_setting'; + +function createUiSetting(value: unknown, key = 'something'): UiSetting { + return { + key, + value, + type: 'ui_setting', + }; +} + +describe('uiSetting', () => { + describe('to', () => { + describe('render', () => { + it.each` + value | expected + ${{ a: 'b' }} | ${JSON.stringify({ a: 'b' })} + ${null} | ${''} + ${'something'} | ${'something'} + `('should render "$value" as "$expected"', ({ expected, value }) => { + expect(uiSetting.to?.render(createUiSetting(value), {})).toHaveProperty( + 'value.text', + expected + ); + }); + }); + + describe('datatable', () => { + it('should use parameter name as a datatable column', () => { + expect(uiSetting.to?.datatable(createUiSetting('value', 'column'), {})).toHaveProperty( + 'columns.0', + expect.objectContaining({ id: 'column', name: 'column' }) + ); + }); + + it.each` + value | type + ${null} | ${'null'} + ${undefined} | ${'null'} + ${'something'} | ${'string'} + ${['123']} | ${'string'} + ${123} | ${'number'} + ${[123]} | ${'number'} + ${true} | ${'boolean'} + ${{ a: 'b' }} | ${'object'} + ${[]} | ${'unknown'} + `('should determine $type type', ({ value, type }) => { + expect(uiSetting.to?.datatable(createUiSetting(value, 'column'), {})).toHaveProperty( + 'columns.0.meta.type', + type + ); + }); + + it('should put a value into a row', () => { + expect(uiSetting.to?.datatable(createUiSetting('value'), {})).toHaveProperty( + 'rows.0.something', + 'value' + ); + }); + + it('should put an array value into multiple rows', () => { + expect(uiSetting.to?.datatable(createUiSetting(['a', 'b']), {})).toHaveProperty( + 'rows', + expect.arrayContaining([ + expect.objectContaining({ something: 'a' }), + expect.objectContaining({ something: 'b' }), + ]) + ); + }); + }); + }); +}); diff --git a/src/plugins/expressions/common/expression_types/specs/ui_setting.ts b/src/plugins/expressions/common/expression_types/specs/ui_setting.ts new file mode 100644 index 0000000000000..aaea92e89a832 --- /dev/null +++ b/src/plugins/expressions/common/expression_types/specs/ui_setting.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Datatable, DatatableColumnType } from './datatable'; +import { ExpressionTypeDefinition, ExpressionValueBoxed } from '../types'; +import { ExpressionValueRender } from './render'; + +const name = 'ui_setting'; + +function getType(value: unknown): DatatableColumnType { + if (value == null) { + return 'null'; + } + + if (Array.isArray(value)) { + return value.length ? getType(value[0]) : 'unknown'; + } + + if (['boolean', 'number', 'object', 'string'].includes(typeof value)) { + return typeof value as DatatableColumnType; + } + + return 'unknown'; +} + +export type UiSetting = ExpressionValueBoxed<'ui_setting', { key: string; value: unknown }>; + +export const uiSetting: ExpressionTypeDefinition<'ui_setting', UiSetting> = { + name, + to: { + boolean({ value }) { + return Boolean(value); + }, + number({ value }) { + return Number(value); + }, + string({ value }) { + return String(value ?? ''); + }, + render({ value }): ExpressionValueRender<{ text: string }> { + return { + type: 'render', + as: 'text', + value: { + text: + typeof value === 'object' && value !== null + ? JSON.stringify(value) + : String(value ?? ''), + }, + }; + }, + datatable({ key, value }): Datatable { + return { + type: 'datatable', + columns: [{ id: key, name: key, meta: { type: getType(value) } }], + rows: (Array.isArray(value) ? value : [value]).map((cell) => ({ [key]: cell })), + }; + }, + }, +}; diff --git a/src/plugins/expressions/common/service/expressions_services.ts b/src/plugins/expressions/common/service/expressions_services.ts index d57c1748954ab..a8839c9b0d71e 100644 --- a/src/plugins/expressions/common/service/expressions_services.ts +++ b/src/plugins/expressions/common/service/expressions_services.ts @@ -19,6 +19,18 @@ import { AnyExpressionFunctionDefinition } from '../expression_functions'; import { SavedObjectReference } from '../../../../core/types'; import { PersistableStateService, SerializableState } from '../../../kibana_utils/common'; import { Adapters } from '../../../inspector/common/adapters'; +import { + clog, + font, + variableSet, + variable, + theme, + cumulativeSum, + derivative, + movingAverage, + mapColumn, + math, +} from '../expression_functions'; /** * The public contract that `ExpressionsService` provides to other plugins @@ -269,7 +281,7 @@ export class ExpressionsService implements PersistableStateService { const executor = this.executor.fork(); const renderers = this.renderers; - const fork = new ExpressionsService({ executor, renderers }); + const fork = new (this.constructor as typeof ExpressionsService)({ executor, renderers }); return fork; }; @@ -318,7 +330,22 @@ export class ExpressionsService implements PersistableStateService) { + return getCommonUiSettingFn({ + async getStartDependencies() { + const [{ uiSettings }] = await getStartServices(); + + return { uiSettings }; + }, + }); +} diff --git a/src/plugins/expressions/public/plugin.test.ts b/src/plugins/expressions/public/plugin.test.ts index b83c92f5d1a96..93353ebbb51b6 100644 --- a/src/plugins/expressions/public/plugin.test.ts +++ b/src/plugins/expressions/public/plugin.test.ts @@ -8,7 +8,7 @@ import { expressionsPluginMock } from './mocks'; import { add } from '../common/test_helpers/expression_functions/add'; -import { ExpressionsService } from '../common'; +import { ExpressionsService } from './services'; describe('ExpressionsPublicPlugin', () => { test('can instantiate from mocks', async () => { diff --git a/src/plugins/expressions/public/plugin.ts b/src/plugins/expressions/public/plugin.ts index 2410ad8741312..37d519ac45133 100644 --- a/src/plugins/expressions/public/plugin.ts +++ b/src/plugins/expressions/public/plugin.ts @@ -6,9 +6,15 @@ * Side Public License, v 1. */ +import { pick } from 'lodash'; import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { ExpressionsService, ExpressionsServiceSetup, ExpressionsServiceStart } from '../common'; -import { setRenderersRegistry, setNotifications, setExpressionsService } from './services'; +import { ExpressionsServiceSetup, ExpressionsServiceStart } from '../common'; +import { + ExpressionsService, + setRenderersRegistry, + setNotifications, + setExpressionsService, +} from './services'; import { ReactExpressionRenderer } from './react_expression_renderer'; import { ExpressionLoader, IExpressionLoader, loader } from './loader'; import { render, ExpressionRenderHandler } from './render'; @@ -51,7 +57,7 @@ export class ExpressionsPublicPlugin implements Plugin) => Record; diff --git a/src/plugins/expressions/public/services/expressions_services.ts b/src/plugins/expressions/public/services/expressions_services.ts new file mode 100644 index 0000000000000..388af81629c31 --- /dev/null +++ b/src/plugins/expressions/public/services/expressions_services.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreSetup } from 'src/core/public'; +import { ExpressionsService as CommonExpressionsService } from '../../common'; +import { getUiSettingFn } from '../expression_functions'; + +export class ExpressionsService extends CommonExpressionsService { + setup({ getStartServices }: Pick) { + this.registerFunction(getUiSettingFn({ getStartServices })); + + return super.setup(); + } +} diff --git a/src/plugins/expressions/public/services.ts b/src/plugins/expressions/public/services/index.ts similarity index 87% rename from src/plugins/expressions/public/services.ts rename to src/plugins/expressions/public/services/index.ts index a700e54d77e19..db473037a0a4a 100644 --- a/src/plugins/expressions/public/services.ts +++ b/src/plugins/expressions/public/services/index.ts @@ -7,8 +7,8 @@ */ import { NotificationsStart } from 'kibana/public'; -import { createGetterSetter } from '../../kibana_utils/public'; -import { ExpressionsService, ExpressionRendererRegistry } from '../common'; +import { createGetterSetter } from '../../../kibana_utils/public'; +import { ExpressionsService, ExpressionRendererRegistry } from '../../common'; export const [getNotifications, setNotifications] = createGetterSetter( 'Notifications' @@ -23,3 +23,5 @@ export const [ getExpressionsService, setExpressionsService, ] = createGetterSetter('ExpressionsService'); + +export * from './expressions_services'; diff --git a/src/plugins/expressions/server/expression_functions/index.ts b/src/plugins/expressions/server/expression_functions/index.ts new file mode 100644 index 0000000000000..eb36291c613c6 --- /dev/null +++ b/src/plugins/expressions/server/expression_functions/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './ui_setting'; diff --git a/src/plugins/expressions/server/expression_functions/ui_setting.ts b/src/plugins/expressions/server/expression_functions/ui_setting.ts new file mode 100644 index 0000000000000..0d3d5b1c1f997 --- /dev/null +++ b/src/plugins/expressions/server/expression_functions/ui_setting.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreSetup } from 'src/core/server'; +import { getUiSettingFn as getCommonUiSettingFn } from '../../common'; + +export function getUiSettingFn({ getStartServices }: Pick) { + return getCommonUiSettingFn({ + async getStartDependencies(getKibanaRequest) { + const [{ savedObjects, uiSettings }] = await getStartServices(); + const savedObjectsClient = savedObjects.getScopedClient(getKibanaRequest()); + const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); + + return { uiSettings: uiSettingsClient }; + }, + }); +} diff --git a/src/plugins/expressions/server/plugin.ts b/src/plugins/expressions/server/plugin.ts index 2c638d496ece6..2e45daf6e0f8c 100644 --- a/src/plugins/expressions/server/plugin.ts +++ b/src/plugins/expressions/server/plugin.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { pick } from 'lodash'; import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core/server'; import { ExpressionsService, ExpressionsServiceSetup, ExpressionsServiceStart } from '../common'; @@ -24,7 +25,7 @@ export class ExpressionsServerPlugin environment: 'server', }); - const setup = this.expressions.setup(); + const setup = this.expressions.setup(pick(core, 'getStartServices')); return Object.freeze(setup); } diff --git a/src/plugins/expressions/server/services/expressions_services.ts b/src/plugins/expressions/server/services/expressions_services.ts new file mode 100644 index 0000000000000..914745436f151 --- /dev/null +++ b/src/plugins/expressions/server/services/expressions_services.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreSetup } from 'src/core/server'; +import { ExpressionsService as CommonExpressionsService } from '../../common'; +import { getUiSettingFn } from '../expression_functions'; + +export class ExpressionsService extends CommonExpressionsService { + setup({ getStartServices }: Pick) { + this.registerFunction(getUiSettingFn({ getStartServices })); + + return super.setup(); + } +} diff --git a/src/plugins/expressions/server/services/index.ts b/src/plugins/expressions/server/services/index.ts new file mode 100644 index 0000000000000..c239c4efdb02c --- /dev/null +++ b/src/plugins/expressions/server/services/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './expressions_services';