-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[Dashboards as code] Define schemas for As Code API filter interface #241198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nickpeihl
wants to merge
25
commits into
elastic:main
Choose a base branch
from
nickpeihl:simple-filters-schema
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+418
−91
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
d264710
Define schemas for simple filter interface
nickpeihl 5989e98
Add descriptions to schemas
nickpeihl f900770
Remove id and rename indexPattern to dataViewId
nickpeihl 5037bbe
Merge remote-tracking branch 'upstream/main' into simple-filters-schema
nickpeihl fb0f138
Changes from node scripts/lint_ts_projects --fix
kibanamachine b49449a
Fix filter value schema arrays to be homogeneous
nickpeihl ab20892
Fix casing inconsistency
nickpeihl 48689fc
Naming consistency
nickpeihl f13c024
Stricter discriminated filter conditions
nickpeihl 539a159
Document controlledBy field
nickpeihl 565848a
Remove duplicate stored filter schema
nickpeihl 7f85963
Changes from node scripts/lint_ts_projects --fix
kibanamachine 51c30b1
Rename path
nickpeihl a2979a9
Merge remote-tracking branch 'refs/remotes/origin/simple-filters-sche…
nickpeihl 883b3b6
Rename stored filter schema to "storedFilterSchema" and "simpleFilter…
nickpeihl 3cbf28b
Add constants package to avoid circular references
nickpeihl 00bd945
Add isMultiIindex, filterType, and BWC legacy properties
nickpeihl 8aa68b4
Changes from node scripts/generate codeowners
kibanamachine e72bb46
Merge branch 'main' into simple-filters-schema
nickpeihl 6b5e025
Rename AsCodeFilter types
nickpeihl f94f926
Merge remote-tracking branch 'origin/simple-filters-schema' into simp…
nickpeihl d1c1ea2
As "asCode" prefix to exported schemas
nickpeihl 27870ca
Don't export StoredFilter types
nickpeihl 36da619
Use schema extend instead of spread
nickpeihl 7702432
Remove unnecessary nested query object from DSL schema
nickpeihl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
src/platform/packages/shared/kbn-es-query-constants/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # @kbn/es-query-constants | ||
|
|
||
| Constants that can be used by both `@kbn/es-query` and `@kbn/es-query-server` packages to avoid circular references. |
10 changes: 10 additions & 0 deletions
10
src/platform/packages/shared/kbn-es-query-constants/index.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| export { FilterStateStore } from './src/constants'; |
14 changes: 14 additions & 0 deletions
14
src/platform/packages/shared/kbn-es-query-constants/jest.config.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| module.exports = { | ||
| preset: '@kbn/test/jest_node', | ||
| rootDir: '../../../../..', | ||
| roots: ['<rootDir>/src/platform/packages/shared/kbn-es-query-constants'], | ||
| }; |
7 changes: 7 additions & 0 deletions
7
src/platform/packages/shared/kbn-es-query-constants/kibana.jsonc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "shared-common", | ||
| "id": "@kbn/es-query-constants", | ||
| "owner": "@elastic/kibana-data-discovery", | ||
| "group": "platform", | ||
| "visibility": "shared" | ||
| } |
6 changes: 6 additions & 0 deletions
6
src/platform/packages/shared/kbn-es-query-constants/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "name": "@kbn/es-query-constants", | ||
| "private": true, | ||
| "version": "1.0.0", | ||
| "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0" | ||
| } | ||
18 changes: 18 additions & 0 deletions
18
src/platform/packages/shared/kbn-es-query-constants/src/constants.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| /** | ||
| Filter, | ||
| * An enum to denote whether a filter is specific to an application's context or whether it should be applied globally. | ||
| * @public | ||
| */ | ||
| export enum FilterStateStore { | ||
| APP_STATE = 'appState', | ||
| GLOBAL_STATE = 'globalState', | ||
| } |
17 changes: 17 additions & 0 deletions
17
src/platform/packages/shared/kbn-es-query-constants/tsconfig.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| { | ||
| "extends": "../../../../../tsconfig.base.json", | ||
| "compilerOptions": { | ||
| "outDir": "target/types", | ||
| "types": [ | ||
| "jest", | ||
| "node" | ||
| ] | ||
| }, | ||
| "include": [ | ||
| "**/*.ts", | ||
| ], | ||
| "exclude": [ | ||
| "target/**/*" | ||
| ], | ||
| "kbn_references": [] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,56 +7,231 @@ | |
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| /** | ||
| * Validation Schemas for Simplified Filter Interface | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Validation Schemas for "As code" Filter Interface |
||
| * | ||
| * These schemas are used for server validation of API requests and responses | ||
| * in * as Code APIs. | ||
| */ | ||
|
|
||
| import { schema } from '@kbn/config-schema'; | ||
| import { FilterStateStore } from '@kbn/es-query'; | ||
|
|
||
| const filterStateStoreSchema = schema.oneOf( | ||
| [schema.literal(FilterStateStore.APP_STATE), schema.literal(FilterStateStore.GLOBAL_STATE)], | ||
| { | ||
| meta: { | ||
| description: | ||
| "Denote whether a filter is specific to an application's context (e.g. 'appState') or whether it should be applied globally (e.g. 'globalState').", | ||
| }, | ||
| } | ||
| // ==================================================================== | ||
| // CORE FILTER OPERATOR AND VALUE SCHEMAS | ||
| // ==================================================================== | ||
|
|
||
| /** | ||
| * Schema for range values used in numeric and date filters | ||
| */ | ||
| const rangeSchema = schema.object({ | ||
| gte: schema.maybe( | ||
| schema.oneOf([schema.number(), schema.string()], { | ||
| meta: { description: 'Greater than or equal to' }, | ||
| }) | ||
| ), | ||
| lte: schema.maybe( | ||
| schema.oneOf([schema.number(), schema.string()], { | ||
| meta: { description: 'Less than or equal to' }, | ||
| }) | ||
| ), | ||
| gt: schema.maybe( | ||
| schema.oneOf([schema.number(), schema.string()], { | ||
| meta: { description: 'Greater than' }, | ||
| }) | ||
| ), | ||
| lt: schema.maybe( | ||
| schema.oneOf([schema.number(), schema.string()], { | ||
| meta: { description: 'Less than' }, | ||
| }) | ||
| ), | ||
| }); | ||
|
|
||
| // ==================================================================== | ||
| // BASE PROPERTIES (SHARED BY ALL FILTERS) | ||
| // ==================================================================== | ||
|
|
||
| /** | ||
| * Base properties shared by all simplified filters | ||
| */ | ||
| const basePropertiesSchema = schema.object({ | ||
| pinned: schema.maybe( | ||
| schema.boolean({ | ||
| meta: { description: 'Whether the filter is pinned' }, | ||
| }) | ||
| ), | ||
| disabled: schema.maybe( | ||
| schema.boolean({ | ||
| meta: { description: 'Whether the filter is disabled' }, | ||
| }) | ||
| ), | ||
| controlledBy: schema.maybe( | ||
| schema.string({ | ||
| meta: { | ||
| description: 'Optional identifier for the component/plugin managing this filter', | ||
| }, | ||
| }) | ||
| ), | ||
| dataViewId: schema.maybe( | ||
| schema.string({ | ||
| meta: { description: 'Data view ID that this filter applies to' }, | ||
| }) | ||
| ), | ||
davismcphee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| negate: schema.maybe( | ||
| schema.boolean({ | ||
| meta: { description: 'Whether to negate the filter condition' }, | ||
| }) | ||
| ), | ||
| label: schema.maybe( | ||
| schema.string({ | ||
| meta: { description: 'Human-readable label for the filter' }, | ||
| }) | ||
| ), | ||
| isMultiIndex: schema.maybe( | ||
| schema.boolean({ | ||
| meta: { description: 'Whether this filter can be applied to multiple indices' }, | ||
| }) | ||
| ), | ||
| filterType: schema.maybe( | ||
| schema.string({ | ||
| meta: { | ||
| description: | ||
| 'Filter type from legacy filters (e.g., "spatial_filter", "query_string") for backwards compatibility', | ||
| }, | ||
| }) | ||
| ), | ||
| key: schema.maybe( | ||
| schema.string({ | ||
| meta: { | ||
| description: 'Field name metadata from legacy filters for backwards compatibility', | ||
| }, | ||
| }) | ||
| ), | ||
| value: schema.maybe( | ||
| schema.string({ | ||
| meta: { | ||
| description: 'Value metadata from legacy filters for backwards compatibility', | ||
| }, | ||
| }) | ||
| ), | ||
|
Comment on lines
+94
to
+115
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these all related to the spatial filter? |
||
| }); | ||
|
|
||
| // ==================================================================== | ||
| // FILTER CONDITION SCHEMAS | ||
| // ==================================================================== | ||
|
|
||
| /** | ||
| * Common field property for all filter conditions | ||
| */ | ||
| const conditionFieldSchema = schema.object({ | ||
| field: schema.string({ meta: { description: 'Field the filter applies to' } }), | ||
| }); | ||
|
|
||
| /** | ||
| * Schema for 'is' and 'is_not' operators with single value | ||
| */ | ||
| const singleConditionSchema = conditionFieldSchema.extends({ | ||
| operator: schema.oneOf([schema.literal('is'), schema.literal('is_not')], { | ||
| meta: { description: 'Single value comparison operators' }, | ||
| }), | ||
| value: schema.oneOf([schema.string(), schema.number(), schema.boolean()], { | ||
| meta: { description: 'Single value for comparison' }, | ||
| }), | ||
| }); | ||
|
|
||
| /** | ||
| * Schema for 'is_one_of' and 'is_not_one_of' operators with array values | ||
| */ | ||
| const oneOfConditionSchema = conditionFieldSchema.extends({ | ||
| operator: schema.oneOf([schema.literal('is_one_of'), schema.literal('is_not_one_of')], { | ||
| meta: { description: 'Array value comparison operators' }, | ||
| }), | ||
| value: schema.oneOf( | ||
| [ | ||
| schema.arrayOf(schema.string()), | ||
| schema.arrayOf(schema.number()), | ||
| schema.arrayOf(schema.boolean()), | ||
| ], | ||
| { meta: { description: 'Homogeneous array of values' } } | ||
| ), | ||
| }); | ||
|
|
||
| /** | ||
| * Schema for 'range' operator with range value | ||
| */ | ||
| const rangeConditionSchema = conditionFieldSchema.extends({ | ||
| operator: schema.literal('range'), | ||
| value: rangeSchema, | ||
| }); | ||
|
|
||
| /** | ||
| * Schema for 'exists' and 'not_exists' operators without value | ||
| */ | ||
| const existsConditionSchema = conditionFieldSchema.extends({ | ||
| operator: schema.oneOf([schema.literal('exists'), schema.literal('not_exists')], { | ||
| meta: { description: 'Field existence check operators' }, | ||
| }), | ||
| // value is intentionally omitted for exists/not_exists operators | ||
| }); | ||
|
|
||
| /** | ||
| * Discriminated union schema for simple filter conditions with proper operator/value type combinations | ||
| */ | ||
| const conditionSchema = schema.oneOf( | ||
| [singleConditionSchema, oneOfConditionSchema, rangeConditionSchema, existsConditionSchema], | ||
| { meta: { description: 'A filter condition with strict operator/value type matching' } } | ||
| ); | ||
|
|
||
| export const filterMetaSchema = schema.object( | ||
| // ==================================================================== | ||
| // FILTER DISCRIMINATED UNION SCHEMA | ||
| // ==================================================================== | ||
|
|
||
| /** | ||
| * Schema for condition filters | ||
| */ | ||
| export const asCodeConditionFilterSchema = basePropertiesSchema.extends( | ||
| { | ||
| alias: schema.maybe(schema.nullable(schema.string())), | ||
| disabled: schema.maybe(schema.boolean()), | ||
| negate: schema.maybe(schema.boolean()), | ||
| controlledBy: schema.maybe( | ||
| schema.string({ meta: { description: 'Identifies the owner the filter.' } }) | ||
| ), | ||
| group: schema.maybe( | ||
| schema.string({ meta: { description: 'The group to which this filter belongs.' } }) | ||
| ), | ||
| // field is missing from the Filter type, but is stored in SerializedSearchSourceFields | ||
| // see the todo in src/platform/packages/shared/kbn-es-query/src/filters/helpers/update_filter.ts | ||
| field: schema.maybe(schema.string()), | ||
| index: schema.maybe(schema.string()), | ||
| isMultiIndex: schema.maybe(schema.boolean()), | ||
| type: schema.maybe(schema.string()), | ||
| key: schema.maybe(schema.string()), | ||
| // We could consider creating FilterMetaParams as a schema to match the concrete Filter type. | ||
| // However, this is difficult because FilterMetaParams can be a `filterSchema` which is defined below. | ||
| // This would require a more complex schema definition that can handle recursive types. | ||
| // For now, we use `schema.any()` to allow flexibility in the params field. | ||
| params: schema.maybe(schema.any()), | ||
| value: schema.maybe(schema.string()), | ||
| condition: conditionSchema, | ||
| }, | ||
| { unknowns: 'allow' } | ||
| { meta: { description: 'Condition filter' } } | ||
| ); | ||
|
|
||
| export const filterSchema = schema.object( | ||
| /** | ||
| * Schema for logical filter groups with recursive structure | ||
| * Uses lazy schema to handle recursive references | ||
| */ | ||
| const GROUP_FILTER_ID = '@kbn/es-query-server_groupFilter'; // package prefix for global uniqueness in OAS specs | ||
| export const asCodeGroupFilterSchema = basePropertiesSchema.extends( | ||
| { | ||
| meta: filterMetaSchema, | ||
| query: schema.maybe(schema.recordOf(schema.string(), schema.any())), | ||
| $state: schema.maybe( | ||
| schema.object({ | ||
| store: filterStateStoreSchema, | ||
| }) | ||
| group: schema.object( | ||
| { | ||
| type: schema.oneOf([schema.literal('and'), schema.literal('or')]), | ||
| conditions: schema.arrayOf( | ||
| schema.oneOf([ | ||
| conditionSchema, | ||
| schema.lazy(GROUP_FILTER_ID), // Recursive reference for nested groups | ||
| ]) | ||
| ), | ||
| }, | ||
| { meta: { description: 'Condition or nested group filter', id: GROUP_FILTER_ID } } | ||
| ), | ||
| }, | ||
| { meta: { id: 'kbn-es-query-server-filterSchema' } } | ||
| { meta: { description: 'Grouped condition filter' } } | ||
| ); | ||
|
|
||
| /** | ||
| * Schema for DSL filters | ||
| */ | ||
| export const asCodeDSLFilterSchema = basePropertiesSchema.extends({ | ||
| dsl: schema.recordOf(schema.string(), schema.any(), { | ||
| meta: { description: 'Elasticsearch Query DSL object' }, | ||
| }), | ||
| }); | ||
|
|
||
| /** | ||
| * Main discriminated union schema for Filter | ||
| * Ensures exactly one of: condition, group, or dsl is present | ||
| */ | ||
| export const asCodeFilterSchema = schema.oneOf( | ||
| [asCodeConditionFilterSchema, asCodeGroupFilterSchema, asCodeDSLFilterSchema], | ||
| { meta: { description: 'A filter which can be a condition, group, or raw DSL' } } | ||
| ); | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably worth disabling side effects for this package even if it's tiny atm.