From 642912ffaf1475f39784de48aabefa973cbbeb02 Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Tue, 16 Sep 2025 23:33:22 -0300 Subject: [PATCH] Fix validation issue with data views API schema --- .../public/create_data_view.ts | 3 ++- .../public/fields/update_fields.ts | 3 ++- .../rest_api_routes/public/get_data_view.ts | 3 ++- .../runtime_fields/response_formatter.ts | 5 +++-- .../scripted_fields/create_scripted_field.ts | 5 ++++- .../scripted_fields/put_scripted_field.ts | 5 ++++- .../scripted_fields/update_scripted_field.ts | 5 ++++- .../public/update_data_view.ts | 3 ++- .../public/util/to_api_spec.ts | 21 +++++++++++++++++++ .../redux/actions/save_discover_session.ts | 1 + 10 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/platform/plugins/shared/data_views/server/rest_api_routes/public/util/to_api_spec.ts diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/create_data_view.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/create_data_view.ts index eb1bc9590ee4b..a6a74724bfa8a 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/create_data_view.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/create_data_view.ts @@ -27,6 +27,7 @@ import { CREATE_DATA_VIEW_DESCRIPTION, } from '../../constants'; import type { DataViewSpecRestResponse } from '../route_types'; +import { toApiSpec } from './util/to_api_spec'; interface CreateDataViewArgs { dataViewsService: DataViewsService; @@ -122,7 +123,7 @@ const registerCreateDataViewRouteFactory = const responseBody: Record = { [serviceKey]: { - ...(await dataView.toSpec(toSpecParams)), + ...toApiSpec(await dataView.toSpec(toSpecParams)), namespaces: dataView.namespaces, }, }; diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/fields/update_fields.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/fields/update_fields.ts index ad8747aeb7a0b..e0bdc478b76c9 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/fields/update_fields.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/fields/update_fields.ts @@ -29,6 +29,7 @@ import { INITIAL_REST_VERSION, UPDATE_DATA_VIEW_FIELDS_DESCRIPTION, } from '../../../constants'; +import { toApiSpec } from '../util/to_api_spec'; interface UpdateFieldsArgs { dataViewsService: DataViewsService; @@ -196,7 +197,7 @@ const updateFieldsActionRouteFactory = (path: string, serviceKey: string, descri }); const body: Record = { - [serviceKey]: await dataView.toSpec({ fieldParams: { fieldName: ['*'] } }), + [serviceKey]: toApiSpec(await dataView.toSpec({ fieldParams: { fieldName: ['*'] } })), }; return res.ok({ diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/get_data_view.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/get_data_view.ts index 70cc314497e10..830e6e0f999ec 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/get_data_view.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/get_data_view.ts @@ -26,6 +26,7 @@ import { INITIAL_REST_VERSION, GET_DATA_VIEW_DESCRIPTION, } from '../../constants'; +import { toApiSpec } from './util/to_api_spec'; interface GetDataViewArgs { dataViewsService: DataViewsService; @@ -113,7 +114,7 @@ const getDataViewRouteFactory = const responseBody: Record = { [serviceKey]: { - ...(await dataView.toSpec({ fieldParams: { fieldName: ['*'] } })), + ...toApiSpec(await dataView.toSpec({ fieldParams: { fieldName: ['*'] } })), namespaces: dataView.namespaces, }, }; diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/runtime_fields/response_formatter.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/runtime_fields/response_formatter.ts index d7b7fc90f85c9..373ac206accf3 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/runtime_fields/response_formatter.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/runtime_fields/response_formatter.ts @@ -10,6 +10,7 @@ import type { DataViewField, DataViewLazy } from '../../../../common'; import type { SERVICE_KEY_TYPE } from '../../../constants'; import { SERVICE_KEY_LEGACY, SERVICE_KEY } from '../../../constants'; +import { toApiSpec } from '../util/to_api_spec'; interface ResponseFormatterArgs { serviceKey: SERVICE_KEY_TYPE; @@ -25,13 +26,13 @@ export const responseFormatter = async ({ const response = { body: { fields: fields.map((field) => field.toSpec()), - [SERVICE_KEY]: await dataView.toSpec(), + [SERVICE_KEY]: toApiSpec(await dataView.toSpec()), }, }; const legacyResponse = { body: { - [SERVICE_KEY_LEGACY]: await dataView.toSpec(), + [SERVICE_KEY_LEGACY]: toApiSpec(await dataView.toSpec()), field: fields[0].toSpec(), }, }; diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/create_scripted_field.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/create_scripted_field.ts index 0bf3c2ccbebfa..3f4fdba633db7 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/create_scripted_field.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/create_scripted_field.ts @@ -18,6 +18,7 @@ import type { import { INITIAL_REST_VERSION } from '../../../constants'; import { indexPatternsRuntimeResponseSchema } from '../../schema'; import type { IndexPatternsRuntimeResponseType } from '../../route_types'; +import { toApiSpec } from '../util/to_api_spec'; export const registerCreateScriptedFieldRoute = ( router: IRouter, @@ -99,7 +100,9 @@ export const registerCreateScriptedFieldRoute = ( const body: IndexPatternsRuntimeResponseType = { field: fieldObject.toSpec(), - index_pattern: await indexPattern.toSpec({ fieldParams: { fieldName: ['*'] } }), + index_pattern: toApiSpec( + await indexPattern.toSpec({ fieldParams: { fieldName: ['*'] } }) + ), }; return res.ok({ diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/put_scripted_field.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/put_scripted_field.ts index a13d37e406063..2e41cdb7df0e8 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/put_scripted_field.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/put_scripted_field.ts @@ -18,6 +18,7 @@ import type { import { INITIAL_REST_VERSION } from '../../../constants'; import { indexPatternsRuntimeResponseSchema } from '../../schema'; import type { IndexPatternsRuntimeResponseType } from '../../route_types'; +import { toApiSpec } from '../util/to_api_spec'; export const registerPutScriptedFieldRoute = ( router: IRouter, @@ -94,7 +95,9 @@ export const registerPutScriptedFieldRoute = ( const body: IndexPatternsRuntimeResponseType = { field: fieldObject.toSpec(), - index_pattern: await indexPattern.toSpec({ fieldParams: { fieldName: ['*'] } }), + index_pattern: toApiSpec( + await indexPattern.toSpec({ fieldParams: { fieldName: ['*'] } }) + ), }; return res.ok({ diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/update_scripted_field.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/update_scripted_field.ts index a70e72c5470e5..cac4874d6b45a 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/update_scripted_field.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/scripted_fields/update_scripted_field.ts @@ -20,6 +20,7 @@ import type { import { INITIAL_REST_VERSION } from '../../../constants'; import { indexPatternsRuntimeResponseSchema } from '../../schema'; import type { IndexPatternsRuntimeResponseType } from '../../route_types'; +import { toApiSpec } from '../util/to_api_spec'; export const registerUpdateScriptedFieldRoute = ( router: IRouter, @@ -123,7 +124,9 @@ export const registerUpdateScriptedFieldRoute = ( const body: IndexPatternsRuntimeResponseType = { field: fieldObject.toSpec(), - index_pattern: await indexPattern.toSpec({ fieldParams: { fieldName: ['*'] } }), + index_pattern: toApiSpec( + await indexPattern.toSpec({ fieldParams: { fieldName: ['*'] } }) + ), }; return res.ok({ diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/update_data_view.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/update_data_view.ts index f5e088d18bda8..aafa9e0b8070c 100644 --- a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/update_data_view.ts +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/update_data_view.ts @@ -28,6 +28,7 @@ import { INITIAL_REST_VERSION, UPDATE_DATA_VIEW_DESCRIPTION, } from '../../constants'; +import { toApiSpec } from './util/to_api_spec'; const indexPatternUpdateSchema = schema.object({ title: schema.maybe(schema.string()), @@ -215,7 +216,7 @@ const updateDataViewRouteFactory = }); const body: Record = { - [serviceKey]: await dataView.toSpec({ fieldParams: { fieldName: ['*'] } }), + [serviceKey]: toApiSpec(await dataView.toSpec({ fieldParams: { fieldName: ['*'] } })), }; return res.ok({ diff --git a/src/platform/plugins/shared/data_views/server/rest_api_routes/public/util/to_api_spec.ts b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/util/to_api_spec.ts new file mode 100644 index 0000000000000..e79d276c6e3bb --- /dev/null +++ b/src/platform/plugins/shared/data_views/server/rest_api_routes/public/util/to_api_spec.ts @@ -0,0 +1,21 @@ +/* + * 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". + */ + +import type { DataViewSpec } from '../../../../common'; + +/** + * Converts a data view spec to an API compatible spec, removing unexposed properties + * @param dataViewSpec - The data view spec to convert to an API compatible spec + * @returns The API compatible data view spec + */ +export const toApiSpec = (dataViewSpec: DataViewSpec) => { + // Exclude managed property from the spec as it's not exposed in the API currently + const { managed, ...restSpec } = dataViewSpec; + return restSpec; +}; diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/save_discover_session.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/save_discover_session.ts index a28fd98e74589..e22169f072c4e 100644 --- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/save_discover_session.ts +++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/save_discover_session.ts @@ -164,6 +164,7 @@ export const saveDiscoverSession = createInternalStateAsyncThunk( newDataViewSpec = { ...dataViewSpec, id: uuidv4(), + managed: false, }; // Clear out the old data view since it's no longer needed