Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export declare class Executor<Context extends Record<string, unknown> = Record<s
| [getType(name)](./kibana-plugin-plugins-expressions-public.executor.gettype.md) | | |
| [getTypes()](./kibana-plugin-plugins-expressions-public.executor.gettypes.md) | | |
| [inject(ast, references)](./kibana-plugin-plugins-expressions-public.executor.inject.md) | | |
| [migrate(ast, version)](./kibana-plugin-plugins-expressions-public.executor.migrate.md) | | |
| [migrateToLatest(ast, version)](./kibana-plugin-plugins-expressions-public.executor.migratetolatest.md) | | |
| [registerFunction(functionDefinition)](./kibana-plugin-plugins-expressions-public.executor.registerfunction.md) | | |
| [registerType(typeDefinition)](./kibana-plugin-plugins-expressions-public.executor.registertype.md) | | |
| [run(ast, input, params)](./kibana-plugin-plugins-expressions-public.executor.run.md) | | Execute expression and return result. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [Executor](./kibana-plugin-plugins-expressions-public.executor.md) &gt; [migrate](./kibana-plugin-plugins-expressions-public.executor.migrate.md)

## Executor.migrate() method

<b>Signature:</b>

```typescript
migrate(ast: SerializableState, version: string): ExpressionAstExpression;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>SerializableState</code> | |
| version | <code>string</code> | |

<b>Returns:</b>

`ExpressionAstExpression`

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [Executor](./kibana-plugin-plugins-expressions-public.executor.md) &gt; [migrateToLatest](./kibana-plugin-plugins-expressions-public.executor.migratetolatest.md)

## Executor.migrateToLatest() method

<b>Signature:</b>

```typescript
migrateToLatest(ast: unknown, version: string): ExpressionAstExpression;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>unknown</code> | |
| version | <code>string</code> | |

<b>Returns:</b>

`ExpressionAstExpression`

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export declare class ExpressionFunction implements PersistableState<ExpressionAs
| [help](./kibana-plugin-plugins-expressions-public.expressionfunction.help.md) | | <code>string</code> | A short help text. |
| [inject](./kibana-plugin-plugins-expressions-public.expressionfunction.inject.md) | | <code>(state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) =&gt; ExpressionAstFunction['arguments']</code> | |
| [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md) | | <code>string[] &#124; undefined</code> | Type of inputs that this function supports. |
| [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md) | | <code>{</code><br/><code> [key: string]: (state: SerializableState) =&gt; SerializableState;</code><br/><code> }</code> | |
| [name](./kibana-plugin-plugins-expressions-public.expressionfunction.name.md) | | <code>string</code> | Name of function |
| [telemetry](./kibana-plugin-plugins-expressions-public.expressionfunction.telemetry.md) | | <code>(state: ExpressionAstFunction['arguments'], telemetryData: Record&lt;string, any&gt;) =&gt; Record&lt;string, any&gt;</code> | |
| [type](./kibana-plugin-plugins-expressions-public.expressionfunction.type.md) | | <code>string</code> | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) &gt; [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md)

## ExpressionFunction.migrations property

<b>Signature:</b>

```typescript
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
```
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export declare class ExpressionsService implements PersistableState<ExpressionAs
| [getType](./kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md) | | <code>ExpressionsServiceStart['getType']</code> | |
| [getTypes](./kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md) | | <code>() =&gt; ReturnType&lt;Executor['getTypes']&gt;</code> | Returns POJO map of all registered expression types, where keys are names of the types and values are <code>ExpressionType</code> instances. |
| [inject](./kibana-plugin-plugins-expressions-public.expressionsservice.inject.md) | | <code>(state: ExpressionAstExpression, references: SavedObjectReference[]) =&gt; ExpressionAstExpression</code> | Injects saved object references into expression AST |
| [migrate](./kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md) | | <code>(state: SerializableState, version: string) =&gt; ExpressionAstExpression</code> | Injects saved object references into expression AST |
| [migrateToLatest](./kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md) | | <code>(state: unknown, version: string) =&gt; ExpressionAstExpression</code> | Injects saved object references into expression AST |
| [registerFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md) | | <code>(functionDefinition: AnyExpressionFunctionDefinition &#124; (() =&gt; AnyExpressionFunctionDefinition)) =&gt; void</code> | Register an expression function, which will be possible to execute as part of the expression pipeline.<!-- -->Below we register a function which simply sleeps for given number of milliseconds to delay the execution and outputs its input as-is.
```ts
expressions.registerFunction({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) &gt; [migrate](./kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md)

## ExpressionsService.migrate property

Injects saved object references into expression AST

<b>Signature:</b>

```typescript
readonly migrate: (state: SerializableState, version: string) => ExpressionAstExpression;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) &gt; [migrateToLatest](./kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md)

## ExpressionsService.migrateToLatest property

Injects saved object references into expression AST

<b>Signature:</b>

```typescript
readonly migrateToLatest: (state: unknown, version: string) => ExpressionAstExpression;
```
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export declare class Executor<Context extends Record<string, unknown> = Record<s
| [getType(name)](./kibana-plugin-plugins-expressions-server.executor.gettype.md) | | |
| [getTypes()](./kibana-plugin-plugins-expressions-server.executor.gettypes.md) | | |
| [inject(ast, references)](./kibana-plugin-plugins-expressions-server.executor.inject.md) | | |
| [migrate(ast, version)](./kibana-plugin-plugins-expressions-server.executor.migrate.md) | | |
| [migrateToLatest(ast, version)](./kibana-plugin-plugins-expressions-server.executor.migratetolatest.md) | | |
| [registerFunction(functionDefinition)](./kibana-plugin-plugins-expressions-server.executor.registerfunction.md) | | |
| [registerType(typeDefinition)](./kibana-plugin-plugins-expressions-server.executor.registertype.md) | | |
| [run(ast, input, params)](./kibana-plugin-plugins-expressions-server.executor.run.md) | | Execute expression and return result. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) &gt; [Executor](./kibana-plugin-plugins-expressions-server.executor.md) &gt; [migrate](./kibana-plugin-plugins-expressions-server.executor.migrate.md)

## Executor.migrate() method

<b>Signature:</b>

```typescript
migrate(ast: SerializableState, version: string): ExpressionAstExpression;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>SerializableState</code> | |
| version | <code>string</code> | |

<b>Returns:</b>

`ExpressionAstExpression`

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) &gt; [Executor](./kibana-plugin-plugins-expressions-server.executor.md) &gt; [migrateToLatest](./kibana-plugin-plugins-expressions-server.executor.migratetolatest.md)

## Executor.migrateToLatest() method

<b>Signature:</b>

```typescript
migrateToLatest(ast: unknown, version: string): ExpressionAstExpression;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>unknown</code> | |
| version | <code>string</code> | |

<b>Returns:</b>

`ExpressionAstExpression`

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export declare class ExpressionFunction implements PersistableState<ExpressionAs
| [help](./kibana-plugin-plugins-expressions-server.expressionfunction.help.md) | | <code>string</code> | A short help text. |
| [inject](./kibana-plugin-plugins-expressions-server.expressionfunction.inject.md) | | <code>(state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) =&gt; ExpressionAstFunction['arguments']</code> | |
| [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md) | | <code>string[] &#124; undefined</code> | Type of inputs that this function supports. |
| [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md) | | <code>{</code><br/><code> [key: string]: (state: SerializableState) =&gt; SerializableState;</code><br/><code> }</code> | |
| [name](./kibana-plugin-plugins-expressions-server.expressionfunction.name.md) | | <code>string</code> | Name of function |
| [telemetry](./kibana-plugin-plugins-expressions-server.expressionfunction.telemetry.md) | | <code>(state: ExpressionAstFunction['arguments'], telemetryData: Record&lt;string, any&gt;) =&gt; Record&lt;string, any&gt;</code> | |
| [type](./kibana-plugin-plugins-expressions-server.expressionfunction.type.md) | | <code>string</code> | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) &gt; [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) &gt; [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md)

## ExpressionFunction.migrations property

<b>Signature:</b>

```typescript
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
```
31 changes: 31 additions & 0 deletions src/plugins/expressions/common/executor/executor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as expressionTypes from '../expression_types';
import * as expressionFunctions from '../expression_functions';
import { Execution } from '../execution';
import { ExpressionAstFunction, parseExpression } from '../ast';
import { MigrateFunction } from '../../../kibana_utils/common/persistable_state';

describe('Executor', () => {
test('can instantiate', () => {
Expand Down Expand Up @@ -158,6 +159,7 @@ describe('Executor', () => {

const injectFn = jest.fn().mockImplementation((args, references) => args);
const extractFn = jest.fn().mockReturnValue({ args: {}, references: [] });
const migrateFn = jest.fn().mockImplementation((args) => args);

const fooFn = {
name: 'foo',
Expand All @@ -174,6 +176,14 @@ describe('Executor', () => {
inject: (state: ExpressionAstFunction['arguments']) => {
return injectFn(state);
},
migrations: {
'7.10.0': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => {
return migrateFn(state, version);
}) as any) as MigrateFunction,
'7.10.1': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => {
return migrateFn(state, version);
}) as any) as MigrateFunction,
},
fn: jest.fn(),
};
executor.registerFunction(fooFn);
Expand All @@ -194,5 +204,26 @@ describe('Executor', () => {
expect(extractFn).toBeCalledTimes(5);
});
});

describe('.migrate', () => {
test('calls migrate function for every expression function in expression', () => {
executor.migrate(
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
'7.10.0'
);
expect(migrateFn).toBeCalledTimes(5);
});
});

describe('.migrateToLatest', () => {
test('calls extract function for every expression function in expression', () => {
migrateFn.mockClear();
executor.migrateToLatest(
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
'7.10.0'
);
expect(migrateFn).toBeCalledTimes(10);
});
});
});
});
37 changes: 36 additions & 1 deletion src/plugins/expressions/common/executor/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { typeSpecs } from '../expression_types/specs';
import { functionSpecs } from '../expression_functions/specs';
import { getByAlias } from '../util';
import { SavedObjectReference } from '../../../../core/types';
import { PersistableState } from '../../../kibana_utils/common';
import { PersistableState, SerializableState } from '../../../kibana_utils/common';
import { ExpressionExecutionParams } from '../service';

export interface ExpressionExecOptions {
Expand Down Expand Up @@ -88,6 +88,20 @@ export class FunctionsRegistry implements IRegistry<ExpressionFunction> {
}
}

const semverGte = (semver1: string, semver2: string) => {
const regex = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/;
const matches1 = regex.exec(semver1) as RegExpMatchArray;
const matches2 = regex.exec(semver2) as RegExpMatchArray;

const [, major1, minor1, patch1] = matches1;
const [, major2, minor2, patch2] = matches2;

return (
major1 > major2 ||
(major1 === major2 && (minor1 > minor2 || (minor1 === minor2 && patch1 >= patch2)))
);
};

export class Executor<Context extends Record<string, unknown> = Record<string, unknown>>
implements PersistableState<ExpressionAstExpression> {
static createWithDefaults<Ctx extends Record<string, unknown> = Record<string, unknown>>(
Expand Down Expand Up @@ -249,6 +263,27 @@ export class Executor<Context extends Record<string, unknown> = Record<string, u
return telemetryData;
}

public migrate(ast: SerializableState, version: string) {
return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => {
if (!fn.migrations[version]) return link;
const updatedAst = fn.migrations[version](link) as ExpressionAstFunction;
link.arguments = updatedAst.arguments;
link.type = updatedAst.type;
});
}

public migrateToLatest(ast: unknown, version: string) {
return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => {
for (const key of Object.keys(fn.migrations)) {
if (semverGte(key, version)) {
const updatedAst = fn.migrations[key](link) as ExpressionAstFunction;
link.arguments = updatedAst.arguments;
link.type = updatedAst.type;
}
}
});
}

public fork(): Executor<Context> {
const initialState = this.state.get();
const fork = new Executor<Context>(initialState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ExpressionValue } from '../expression_types/types';
import { ExecutionContext } from '../execution';
import { ExpressionAstFunction } from '../ast';
import { SavedObjectReference } from '../../../../core/types';
import { PersistableState } from '../../../kibana_utils/common';
import { PersistableState, SerializableState } from '../../../kibana_utils/common';

export class ExpressionFunction implements PersistableState<ExpressionAstFunction['arguments']> {
/**
Expand Down Expand Up @@ -76,6 +76,9 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
state: ExpressionAstFunction['arguments'],
references: SavedObjectReference[]
) => ExpressionAstFunction['arguments'];
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};

constructor(functionDefinition: AnyExpressionFunctionDefinition) {
const {
Expand All @@ -91,6 +94,7 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
telemetry,
inject,
extract,
migrations,
} = functionDefinition;

this.name = name;
Expand All @@ -104,6 +108,7 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
this.telemetry = telemetry || ((s, c) => c);
this.inject = inject || identity;
this.extract = extract || ((s) => ({ state: s, references: [] }));
this.migrations = migrations || {};

for (const [key, arg] of Object.entries(args || {})) {
this.args[key] = new ExpressionFunctionParameter(key, arg);
Expand Down
22 changes: 21 additions & 1 deletion src/plugins/expressions/common/service/expressions_services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ExecutionContract } from '../execution/execution_contract';
import { AnyExpressionTypeDefinition } from '../expression_types';
import { AnyExpressionFunctionDefinition } from '../expression_functions';
import { SavedObjectReference } from '../../../../core/types';
import { PersistableState } from '../../../kibana_utils/common';
import { PersistableState, SerializableState } from '../../../kibana_utils/common';
import { Adapters } from '../../../inspector/common/adapters';
import { ExecutionContextSearch } from '../execution';

Expand Down Expand Up @@ -303,6 +303,26 @@ export class ExpressionsService implements PersistableState<ExpressionAstExpress
return this.executor.inject(state, references);
};

/**
* Runs the migration (if it exists) for specified version. This will run a single migration step (ie from 7.10.0 to 7.10.1)
* @param state expression AST to update
* @param version defines which migration version to run
* @returns new migrated expression AST
*/
public readonly migrate = (state: SerializableState, version: string) => {
return this.executor.migrate(state, version);
};

/**
* Migrates expression to the latest version
* @param state expression AST to update
* @param version the version of kibana in which expression was created
* @returns migrated expression AST
*/
public readonly migrateToLatest = (state: unknown, version: string) => {
return this.executor.migrateToLatest(state, version);
};

/**
* Returns Kibana Platform *setup* life-cycle contract. Useful to return the
* same contract on server-side and browser-side.
Expand Down
Loading