From 8bbe2f10194732e404807b747457a2bfe130f2b1 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 17 Apr 2026 11:05:19 +0200 Subject: [PATCH 1/6] migrate from zod.merge to zod.extend --- .../templates/zod_schema_item.handlebars | 2 +- .../routes/public/schedules/schedules.gen.ts | 2 +- .../public/schedules/schedules_api.gen.ts | 2 +- .../conversations/common_attributes.gen.ts | 20 +-- .../entries/common_attributes.gen.ts | 24 +-- .../get_unified_history.gen.ts | 4 +- .../create_exception_list_item.gen.ts | 26 +-- .../update_exception_list_item.gen.ts | 26 +-- .../model/rule_schema/rule_schemas.gen.ts | 160 +++++++++--------- .../bulk_actions/bulk_actions_route.gen.ts | 16 +- .../rule_preview/rule_preview.gen.ts | 16 +- .../create_signals_migration.gen.ts | 2 +- .../response_actions/cancel/cancel.gen.ts | 2 +- .../response_actions/execute/execute.gen.ts | 2 +- .../response_actions/get_file/get_file.gen.ts | 2 +- .../kill_process/kill_process.gen.ts | 2 +- .../run_script/run_script.gen.ts | 2 +- .../actions/response_actions/scan/scan.gen.ts | 2 +- .../suspend_process/suspend_process.gen.ts | 2 +- .../response_actions/upload/upload.gen.ts | 2 +- .../bulk_upload_asset_criticality.gen.ts | 2 +- .../asset_criticality/common.gen.ts | 6 +- .../create_asset_criticality.gen.ts | 2 +- .../api/entity_analytics/common/common.gen.ts | 6 +- .../entity_store/status.gen.ts | 2 +- .../monitoring_entity_source.gen.ts | 11 +- .../monitoring/users/common.gen.ts | 2 +- .../watchlists/data_source/common.gen.ts | 11 +- .../watchlists/management/create.gen.ts | 2 +- .../api/timeline/model/components.gen.ts | 18 +- .../siem_migrations/model/common.gen.ts | 8 +- .../model/dashboard_migration.gen.ts | 4 +- .../model/rule_migration.gen.ts | 8 +- 33 files changed, 199 insertions(+), 199 deletions(-) diff --git a/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars b/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars index be1727f5bea2b..a89db93025948 100644 --- a/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars +++ b/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars @@ -23,7 +23,7 @@ {{~#if @first~}} {{> zod_schema_item }} {{~else~}} - .merge({{> zod_schema_item }}) + .extend({{> zod_schema_item }}) {{~/if~}} {{~/each~}} {{~/if~}} diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts index 99d9be8ef8189..89043b86d465c 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts @@ -46,7 +46,7 @@ export const AttackDiscoveryScheduleParams = z.object({ /** * LLM API configuration. */ - apiConfig: ApiConfig.merge( + apiConfig: ApiConfig.extend( z.object({ /** * The name of the connector diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts index 8036ffd2f05f6..460ee5ccc9b30 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts @@ -46,7 +46,7 @@ export const AttackDiscoveryApiScheduleParams = z.object({ /** * LLM API configuration. */ - api_config: ApiConfig.merge( + api_config: ApiConfig.extend( z.object({ /** * The name of the connector diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts index a3e14fb15cf15..cdcebfd37f0ca 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts @@ -97,7 +97,7 @@ export const SelectOptionInterruptOption = z.object({ * Interrupt that requests user to select one of the provided options */ export type SelectOptionInterruptValue = z.infer; -export const SelectOptionInterruptValue = BaseInterruptValue.merge( +export const SelectOptionInterruptValue = BaseInterruptValue.extend( z.object({ type: z.literal('SELECT_OPTION'), /** @@ -115,7 +115,7 @@ export const SelectOptionInterruptValue = BaseInterruptValue.merge( * A request approval resume schema */ export type SelectOptionInterruptResumeValue = z.infer; -export const SelectOptionInterruptResumeValue = BaseInterruptResumeValue.merge( +export const SelectOptionInterruptResumeValue = BaseInterruptResumeValue.extend( z.object({ type: z.literal('SELECT_OPTION'), /** @@ -144,7 +144,7 @@ export const SelectOptionInterrupt = z.object({ * Interrupt that requests user to provide text input */ export type InputTextInterruptValue = z.infer; -export const InputTextInterruptValue = BaseInterruptValue.merge( +export const InputTextInterruptValue = BaseInterruptValue.extend( z.object({ type: z.literal('INPUT_TEXT'), /** @@ -162,7 +162,7 @@ export const InputTextInterruptValue = BaseInterruptValue.merge( * A resume value for input text */ export type InputTextInterruptResumeValue = z.infer; -export const InputTextInterruptResumeValue = BaseInterruptResumeValue.merge( +export const InputTextInterruptResumeValue = BaseInterruptResumeValue.extend( z.object({ type: z.literal('INPUT_TEXT'), /** @@ -221,7 +221,7 @@ export const BaseContentReference = z.object({ * References a knowledge base entry */ export type KnowledgeBaseEntryContentReference = z.infer; -export const KnowledgeBaseEntryContentReference = BaseContentReference.merge( +export const KnowledgeBaseEntryContentReference = BaseContentReference.extend( z.object({ type: z.literal('KnowledgeBaseEntry'), /** @@ -239,7 +239,7 @@ export const KnowledgeBaseEntryContentReference = BaseContentReference.merge( * References an ESQL query */ export type EsqlContentReference = z.infer; -export const EsqlContentReference = BaseContentReference.merge( +export const EsqlContentReference = BaseContentReference.extend( z.object({ type: z.literal('EsqlQuery'), /** @@ -266,7 +266,7 @@ export const EsqlContentReference = BaseContentReference.merge( * References a security alert */ export type SecurityAlertContentReference = z.infer; -export const SecurityAlertContentReference = BaseContentReference.merge( +export const SecurityAlertContentReference = BaseContentReference.extend( z.object({ type: z.literal('SecurityAlert'), /** @@ -280,7 +280,7 @@ export const SecurityAlertContentReference = BaseContentReference.merge( * References an external URL */ export type HrefContentReference = z.infer; -export const HrefContentReference = BaseContentReference.merge( +export const HrefContentReference = BaseContentReference.extend( z.object({ type: z.literal('Href'), /** @@ -298,7 +298,7 @@ export const HrefContentReference = BaseContentReference.merge( * References the security alerts page */ export type SecurityAlertsPageContentReference = z.infer; -export const SecurityAlertsPageContentReference = BaseContentReference.merge( +export const SecurityAlertsPageContentReference = BaseContentReference.extend( z.object({ type: z.literal('SecurityAlertsPage'), }) @@ -310,7 +310,7 @@ export const SecurityAlertsPageContentReference = BaseContentReference.merge( export type ProductDocumentationContentReference = z.infer< typeof ProductDocumentationContentReference >; -export const ProductDocumentationContentReference = BaseContentReference.merge( +export const ProductDocumentationContentReference = BaseContentReference.extend( z.object({ type: z.literal('ProductDocumentation'), /** diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts index fbe2f9fbdcfa5..453e45af31d48 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts @@ -121,17 +121,17 @@ export const BaseDefaultableFields = z.object({ }); export type BaseCreateProps = z.infer; -export const BaseCreateProps = BaseRequiredFields.merge(BaseDefaultableFields); +export const BaseCreateProps = BaseRequiredFields.extend(BaseDefaultableFields); export type BaseUpdateProps = z.infer; -export const BaseUpdateProps = BaseCreateProps.partial().merge( +export const BaseUpdateProps = BaseCreateProps.partial().extend( z.object({ id: NonEmptyString, }) ); export type BaseResponseProps = z.infer; -export const BaseResponseProps = BaseRequiredFields.merge(BaseDefaultableFields.required()); +export const BaseResponseProps = BaseRequiredFields.extend(BaseDefaultableFields.required()); export type ResponseFields = z.infer; export const ResponseFields = z.object({ @@ -160,7 +160,7 @@ export const DeleteResponseFields = z.object({ }); export type SharedResponseProps = z.infer; -export const SharedResponseProps = BaseResponseProps.merge(ResponseFields); +export const SharedResponseProps = BaseResponseProps.extend(ResponseFields); export type DocumentEntryType = z.infer; export const DocumentEntryType = z.literal('document'); @@ -192,20 +192,20 @@ export const DocumentEntryOptionalFields = z.object({ }); export type DocumentEntryCreateFields = z.infer; -export const DocumentEntryCreateFields = BaseCreateProps.merge(DocumentEntryRequiredFields).merge( +export const DocumentEntryCreateFields = BaseCreateProps.extend(DocumentEntryRequiredFields).extend( DocumentEntryOptionalFields ); export type DocumentEntryUpdateFields = z.infer; -export const DocumentEntryUpdateFields = BaseUpdateProps.merge(DocumentEntryCreateFields); +export const DocumentEntryUpdateFields = BaseUpdateProps.extend(DocumentEntryCreateFields); export type DocumentEntryResponseFields = z.infer; -export const DocumentEntryResponseFields = DocumentEntryRequiredFields.merge( +export const DocumentEntryResponseFields = DocumentEntryRequiredFields.extend( DocumentEntryOptionalFields ); export type DocumentEntry = z.infer; -export const DocumentEntry = SharedResponseProps.merge(DocumentEntryResponseFields); +export const DocumentEntry = SharedResponseProps.extend(DocumentEntryResponseFields); export type IndexEntryType = z.infer; export const IndexEntryType = z.literal('index'); @@ -245,16 +245,16 @@ export const IndexEntryOptionalFields = z.object({ export type IndexEntryCreateFields = z.infer; export const IndexEntryCreateFields = - BaseCreateProps.merge(IndexEntryRequiredFields).merge(IndexEntryOptionalFields); + BaseCreateProps.extend(IndexEntryRequiredFields).extend(IndexEntryOptionalFields); export type IndexEntryUpdateFields = z.infer; -export const IndexEntryUpdateFields = BaseUpdateProps.merge(IndexEntryCreateFields); +export const IndexEntryUpdateFields = BaseUpdateProps.extend(IndexEntryCreateFields); export type IndexEntryResponseFields = z.infer; -export const IndexEntryResponseFields = IndexEntryRequiredFields.merge(IndexEntryOptionalFields); +export const IndexEntryResponseFields = IndexEntryRequiredFields.extend(IndexEntryOptionalFields); export type IndexEntry = z.infer; -export const IndexEntry = SharedResponseProps.merge(IndexEntryResponseFields); +export const IndexEntry = SharedResponseProps.extend(IndexEntryResponseFields); export type KnowledgeBaseEntryCreateProps = z.infer; export const KnowledgeBaseEntryCreateProps = z.discriminatedUnion('type', [ diff --git a/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts index 20a232cebd9dd..4aeb598332cfd 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts @@ -113,7 +113,7 @@ export const UnifiedHistoryRowBase = z.object({ }); export type LiveHistoryRow = z.infer; -export const LiveHistoryRow = UnifiedHistoryRowBase.merge( +export const LiveHistoryRow = UnifiedHistoryRowBase.extend( z.object({ /** * Identifies this as a live query history row. @@ -175,7 +175,7 @@ export const LiveHistoryRow = UnifiedHistoryRowBase.merge( ); export type ScheduledHistoryRow = z.infer; -export const ScheduledHistoryRow = UnifiedHistoryRowBase.merge( +export const ScheduledHistoryRow = UnifiedHistoryRowBase.extend( z.object({ /** * Identifies this as a scheduled query history row. diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts index 66e7fab157a44..3716dc28e617e 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts @@ -67,7 +67,7 @@ export const CreateExceptionListItemBase = z.object({ }); export type CreateExceptionListItemGeneric = z.infer; -export const CreateExceptionListItemGeneric = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemGeneric = CreateExceptionListItemBase.extend( z.object({ list_id: ExceptionListHumanId, entries: ExceptionListItemEntryArray, @@ -80,12 +80,12 @@ export type CreateExceptionListItemEndpointList = z.infer< typeof CreateExceptionListItemEndpointList >; export const CreateExceptionListItemEndpointList = - CreateExceptionListItemBase.merge(EndpointListProperties); + CreateExceptionListItemBase.extend(EndpointListProperties); export type CreateExceptionListItemTrustedAppsWindows = z.infer< typeof CreateExceptionListItemTrustedAppsWindows >; -export const CreateExceptionListItemTrustedAppsWindows = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemTrustedAppsWindows = CreateExceptionListItemBase.extend( TrustedAppsWindowsProperties ); @@ -93,33 +93,33 @@ export type CreateExceptionListItemTrustedAppsMac = z.infer< typeof CreateExceptionListItemTrustedAppsMac >; export const CreateExceptionListItemTrustedAppsMac = - CreateExceptionListItemBase.merge(TrustedAppsMacProperties); + CreateExceptionListItemBase.extend(TrustedAppsMacProperties); export type CreateExceptionListItemTrustedAppsLinux = z.infer< typeof CreateExceptionListItemTrustedAppsLinux >; -export const CreateExceptionListItemTrustedAppsLinux = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemTrustedAppsLinux = CreateExceptionListItemBase.extend( TrustedAppsLinuxProperties ); export type CreateExceptionListItemTrustedDevicesWindows = z.infer< typeof CreateExceptionListItemTrustedDevicesWindows >; -export const CreateExceptionListItemTrustedDevicesWindows = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemTrustedDevicesWindows = CreateExceptionListItemBase.extend( TrustedDevicesWindowsProperties ); export type CreateExceptionListItemTrustedDevicesMac = z.infer< typeof CreateExceptionListItemTrustedDevicesMac >; -export const CreateExceptionListItemTrustedDevicesMac = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemTrustedDevicesMac = CreateExceptionListItemBase.extend( TrustedDevicesMacProperties ); export type CreateExceptionListItemTrustedDevicesWindowsMac = z.infer< typeof CreateExceptionListItemTrustedDevicesWindowsMac >; -export const CreateExceptionListItemTrustedDevicesWindowsMac = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemTrustedDevicesWindowsMac = CreateExceptionListItemBase.extend( TrustedDevicesWindowsMacProperties ); @@ -127,18 +127,18 @@ export type CreateExceptionListItemEventFilters = z.infer< typeof CreateExceptionListItemEventFilters >; export const CreateExceptionListItemEventFilters = - CreateExceptionListItemBase.merge(EventFiltersProperties); + CreateExceptionListItemBase.extend(EventFiltersProperties); export type CreateExceptionListItemHostIsolation = z.infer< typeof CreateExceptionListItemHostIsolation >; export const CreateExceptionListItemHostIsolation = - CreateExceptionListItemBase.merge(HostIsolationProperties); + CreateExceptionListItemBase.extend(HostIsolationProperties); export type CreateExceptionListItemBlocklistWindows = z.infer< typeof CreateExceptionListItemBlocklistWindows >; -export const CreateExceptionListItemBlocklistWindows = CreateExceptionListItemBase.merge( +export const CreateExceptionListItemBlocklistWindows = CreateExceptionListItemBase.extend( BlocklistWindowsProperties ); @@ -146,13 +146,13 @@ export type CreateExceptionListItemBlocklistLinux = z.infer< typeof CreateExceptionListItemBlocklistLinux >; export const CreateExceptionListItemBlocklistLinux = - CreateExceptionListItemBase.merge(BlocklistLinuxProperties); + CreateExceptionListItemBase.extend(BlocklistLinuxProperties); export type CreateExceptionListItemBlocklistMac = z.infer< typeof CreateExceptionListItemBlocklistMac >; export const CreateExceptionListItemBlocklistMac = - CreateExceptionListItemBase.merge(BlocklistMacProperties); + CreateExceptionListItemBase.extend(BlocklistMacProperties); export type CreateExceptionListItemRequestBody = z.infer; export const CreateExceptionListItemRequestBody = z.union([ diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts index 6fa4b1c43de2b..32f837651aa80 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts @@ -80,7 +80,7 @@ export const UpdateExceptionListItemBase = z.object({ }); export type UpdateExceptionListItemGeneric = z.infer; -export const UpdateExceptionListItemGeneric = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemGeneric = UpdateExceptionListItemBase.extend( z.object({ list_id: ExceptionListHumanId.optional(), entries: ExceptionListItemEntryArray, @@ -93,12 +93,12 @@ export type UpdateExceptionListItemEndpointList = z.infer< typeof UpdateExceptionListItemEndpointList >; export const UpdateExceptionListItemEndpointList = - UpdateExceptionListItemBase.merge(EndpointListProperties); + UpdateExceptionListItemBase.extend(EndpointListProperties); export type UpdateExceptionListItemTrustedAppsWindows = z.infer< typeof UpdateExceptionListItemTrustedAppsWindows >; -export const UpdateExceptionListItemTrustedAppsWindows = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemTrustedAppsWindows = UpdateExceptionListItemBase.extend( TrustedAppsWindowsProperties ); @@ -106,33 +106,33 @@ export type UpdateExceptionListItemTrustedAppsMac = z.infer< typeof UpdateExceptionListItemTrustedAppsMac >; export const UpdateExceptionListItemTrustedAppsMac = - UpdateExceptionListItemBase.merge(TrustedAppsMacProperties); + UpdateExceptionListItemBase.extend(TrustedAppsMacProperties); export type UpdateExceptionListItemTrustedAppsLinux = z.infer< typeof UpdateExceptionListItemTrustedAppsLinux >; -export const UpdateExceptionListItemTrustedAppsLinux = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemTrustedAppsLinux = UpdateExceptionListItemBase.extend( TrustedAppsLinuxProperties ); export type UpdateExceptionListItemTrustedDevicesWindows = z.infer< typeof UpdateExceptionListItemTrustedDevicesWindows >; -export const UpdateExceptionListItemTrustedDevicesWindows = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemTrustedDevicesWindows = UpdateExceptionListItemBase.extend( TrustedDevicesWindowsProperties ); export type UpdateExceptionListItemTrustedDevicesMac = z.infer< typeof UpdateExceptionListItemTrustedDevicesMac >; -export const UpdateExceptionListItemTrustedDevicesMac = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemTrustedDevicesMac = UpdateExceptionListItemBase.extend( TrustedDevicesMacProperties ); export type UpdateExceptionListItemTrustedDevicesWindowsMac = z.infer< typeof UpdateExceptionListItemTrustedDevicesWindowsMac >; -export const UpdateExceptionListItemTrustedDevicesWindowsMac = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemTrustedDevicesWindowsMac = UpdateExceptionListItemBase.extend( TrustedDevicesWindowsMacProperties ); @@ -140,18 +140,18 @@ export type UpdateExceptionListItemEventFilters = z.infer< typeof UpdateExceptionListItemEventFilters >; export const UpdateExceptionListItemEventFilters = - UpdateExceptionListItemBase.merge(EventFiltersProperties); + UpdateExceptionListItemBase.extend(EventFiltersProperties); export type UpdateExceptionListItemHostIsolation = z.infer< typeof UpdateExceptionListItemHostIsolation >; export const UpdateExceptionListItemHostIsolation = - UpdateExceptionListItemBase.merge(HostIsolationProperties); + UpdateExceptionListItemBase.extend(HostIsolationProperties); export type UpdateExceptionListItemBlocklistWindows = z.infer< typeof UpdateExceptionListItemBlocklistWindows >; -export const UpdateExceptionListItemBlocklistWindows = UpdateExceptionListItemBase.merge( +export const UpdateExceptionListItemBlocklistWindows = UpdateExceptionListItemBase.extend( BlocklistWindowsProperties ); @@ -159,13 +159,13 @@ export type UpdateExceptionListItemBlocklistLinux = z.infer< typeof UpdateExceptionListItemBlocklistLinux >; export const UpdateExceptionListItemBlocklistLinux = - UpdateExceptionListItemBase.merge(BlocklistLinuxProperties); + UpdateExceptionListItemBase.extend(BlocklistLinuxProperties); export type UpdateExceptionListItemBlocklistMac = z.infer< typeof UpdateExceptionListItemBlocklistMac >; export const UpdateExceptionListItemBlocklistMac = - UpdateExceptionListItemBase.merge(BlocklistMacProperties); + UpdateExceptionListItemBase.extend(BlocklistMacProperties); export type UpdateExceptionListItemRequestBody = z.infer; export const UpdateExceptionListItemRequestBody = z.union([ diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts index 3b5e4fa9c48b2..242113608a33f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts @@ -154,15 +154,15 @@ export const BaseDefaultableFields = z.object({ export type BaseCreateProps = z.infer; export const BaseCreateProps = - BaseRequiredFields.merge(BaseOptionalFields).merge(BaseDefaultableFields); + BaseRequiredFields.extend(BaseOptionalFields).extend(BaseDefaultableFields); export type BasePatchProps = z.infer; export const BasePatchProps = BaseRequiredFields.partial() - .merge(BaseOptionalFields) - .merge(BaseDefaultableFields); + .extend(BaseOptionalFields) + .extend(BaseDefaultableFields); export type BaseResponseProps = z.infer; -export const BaseResponseProps = BaseRequiredFields.merge(BaseOptionalFields).merge( +export const BaseResponseProps = BaseRequiredFields.extend(BaseOptionalFields).extend( BaseDefaultableFields.required() ); @@ -182,14 +182,14 @@ export const ResponseFields = z.object({ }); export type SharedCreateProps = z.infer; -export const SharedCreateProps = BaseCreateProps.merge( +export const SharedCreateProps = BaseCreateProps.extend( z.object({ rule_id: RuleSignatureId.optional(), }) ); export type SharedUpdateProps = z.infer; -export const SharedUpdateProps = BaseCreateProps.merge( +export const SharedUpdateProps = BaseCreateProps.extend( z.object({ id: RuleObjectId.optional(), rule_id: RuleSignatureId.optional(), @@ -197,7 +197,7 @@ export const SharedUpdateProps = BaseCreateProps.merge( ); export type SharedPatchProps = z.infer; -export const SharedPatchProps = BasePatchProps.merge( +export const SharedPatchProps = BasePatchProps.extend( z.object({ id: RuleObjectId.optional(), rule_id: RuleSignatureId.optional(), @@ -205,7 +205,7 @@ export const SharedPatchProps = BasePatchProps.merge( ); export type SharedResponseProps = z.infer; -export const SharedResponseProps = BaseResponseProps.merge(ResponseFields); +export const SharedResponseProps = BaseResponseProps.extend(ResponseFields); export type EqlQueryLanguage = z.infer; export const EqlQueryLanguage = z.literal('eql'); @@ -235,25 +235,25 @@ export const EqlOptionalFields = z.object({ }); export type EqlRuleCreateFields = z.infer; -export const EqlRuleCreateFields = EqlRequiredFields.merge(EqlOptionalFields); +export const EqlRuleCreateFields = EqlRequiredFields.extend(EqlOptionalFields); export type EqlRuleResponseFields = z.infer; -export const EqlRuleResponseFields = EqlRequiredFields.merge(EqlOptionalFields); +export const EqlRuleResponseFields = EqlRequiredFields.extend(EqlOptionalFields); export type EqlRulePatchFields = z.infer; -export const EqlRulePatchFields = EqlRequiredFields.partial().merge(EqlOptionalFields); +export const EqlRulePatchFields = EqlRequiredFields.partial().extend(EqlOptionalFields); export type EqlRule = z.infer; -export const EqlRule = SharedResponseProps.merge(EqlRuleResponseFields); +export const EqlRule = SharedResponseProps.extend(EqlRuleResponseFields); export type EqlRuleCreateProps = z.infer; -export const EqlRuleCreateProps = SharedCreateProps.merge(EqlRuleCreateFields); +export const EqlRuleCreateProps = SharedCreateProps.extend(EqlRuleCreateFields); export type EqlRuleUpdateProps = z.infer; -export const EqlRuleUpdateProps = SharedUpdateProps.merge(EqlRuleCreateFields); +export const EqlRuleUpdateProps = SharedUpdateProps.extend(EqlRuleCreateFields); export type EqlRulePatchProps = z.infer; -export const EqlRulePatchProps = SharedPatchProps.merge(EqlRulePatchFields); +export const EqlRulePatchProps = SharedPatchProps.extend(EqlRulePatchFields); export type QueryRuleRequiredFields = z.infer; export const QueryRuleRequiredFields = z.object({ @@ -279,31 +279,31 @@ export const QueryRuleDefaultableFields = z.object({ }); export type QueryRuleCreateFields = z.infer; -export const QueryRuleCreateFields = QueryRuleRequiredFields.merge(QueryRuleOptionalFields).merge( +export const QueryRuleCreateFields = QueryRuleRequiredFields.extend(QueryRuleOptionalFields).extend( QueryRuleDefaultableFields ); export type QueryRulePatchFields = z.infer; export const QueryRulePatchFields = QueryRuleRequiredFields.partial() - .merge(QueryRuleOptionalFields) - .merge(QueryRuleDefaultableFields); + .extend(QueryRuleOptionalFields) + .extend(QueryRuleDefaultableFields); export type QueryRuleResponseFields = z.infer; -export const QueryRuleResponseFields = QueryRuleRequiredFields.merge(QueryRuleOptionalFields).merge( - QueryRuleDefaultableFields.required() -); +export const QueryRuleResponseFields = QueryRuleRequiredFields.extend( + QueryRuleOptionalFields +).extend(QueryRuleDefaultableFields.required()); export type QueryRule = z.infer; -export const QueryRule = SharedResponseProps.merge(QueryRuleResponseFields); +export const QueryRule = SharedResponseProps.extend(QueryRuleResponseFields); export type QueryRuleCreateProps = z.infer; -export const QueryRuleCreateProps = SharedCreateProps.merge(QueryRuleCreateFields); +export const QueryRuleCreateProps = SharedCreateProps.extend(QueryRuleCreateFields); export type QueryRuleUpdateProps = z.infer; -export const QueryRuleUpdateProps = SharedUpdateProps.merge(QueryRuleCreateFields); +export const QueryRuleUpdateProps = SharedUpdateProps.extend(QueryRuleCreateFields); export type QueryRulePatchProps = z.infer; -export const QueryRulePatchProps = SharedPatchProps.merge(QueryRulePatchFields); +export const QueryRulePatchProps = SharedPatchProps.extend(QueryRulePatchFields); export type SavedQueryRuleRequiredFields = z.infer; export const SavedQueryRuleRequiredFields = z.object({ @@ -329,31 +329,31 @@ export const SavedQueryRuleDefaultableFields = z.object({ }); export type SavedQueryRuleCreateFields = z.infer; -export const SavedQueryRuleCreateFields = SavedQueryRuleRequiredFields.merge( +export const SavedQueryRuleCreateFields = SavedQueryRuleRequiredFields.extend( SavedQueryRuleOptionalFields -).merge(SavedQueryRuleDefaultableFields); +).extend(SavedQueryRuleDefaultableFields); export type SavedQueryRulePatchFields = z.infer; export const SavedQueryRulePatchFields = SavedQueryRuleRequiredFields.partial() - .merge(SavedQueryRuleOptionalFields) - .merge(SavedQueryRuleDefaultableFields); + .extend(SavedQueryRuleOptionalFields) + .extend(SavedQueryRuleDefaultableFields); export type SavedQueryRuleResponseFields = z.infer; -export const SavedQueryRuleResponseFields = SavedQueryRuleRequiredFields.merge( +export const SavedQueryRuleResponseFields = SavedQueryRuleRequiredFields.extend( SavedQueryRuleOptionalFields -).merge(SavedQueryRuleDefaultableFields.required()); +).extend(SavedQueryRuleDefaultableFields.required()); export type SavedQueryRule = z.infer; -export const SavedQueryRule = SharedResponseProps.merge(SavedQueryRuleResponseFields); +export const SavedQueryRule = SharedResponseProps.extend(SavedQueryRuleResponseFields); export type SavedQueryRuleCreateProps = z.infer; -export const SavedQueryRuleCreateProps = SharedCreateProps.merge(SavedQueryRuleCreateFields); +export const SavedQueryRuleCreateProps = SharedCreateProps.extend(SavedQueryRuleCreateFields); export type SavedQueryRuleUpdateProps = z.infer; -export const SavedQueryRuleUpdateProps = SharedUpdateProps.merge(SavedQueryRuleCreateFields); +export const SavedQueryRuleUpdateProps = SharedUpdateProps.extend(SavedQueryRuleCreateFields); export type SavedQueryRulePatchProps = z.infer; -export const SavedQueryRulePatchProps = SharedPatchProps.merge(SavedQueryRulePatchFields); +export const SavedQueryRulePatchProps = SharedPatchProps.extend(SavedQueryRulePatchFields); export type ThresholdRuleRequiredFields = z.infer; export const ThresholdRuleRequiredFields = z.object({ @@ -380,31 +380,31 @@ export const ThresholdRuleDefaultableFields = z.object({ }); export type ThresholdRuleCreateFields = z.infer; -export const ThresholdRuleCreateFields = ThresholdRuleRequiredFields.merge( +export const ThresholdRuleCreateFields = ThresholdRuleRequiredFields.extend( ThresholdRuleOptionalFields -).merge(ThresholdRuleDefaultableFields); +).extend(ThresholdRuleDefaultableFields); export type ThresholdRulePatchFields = z.infer; export const ThresholdRulePatchFields = ThresholdRuleRequiredFields.partial() - .merge(ThresholdRuleOptionalFields) - .merge(ThresholdRuleDefaultableFields); + .extend(ThresholdRuleOptionalFields) + .extend(ThresholdRuleDefaultableFields); export type ThresholdRuleResponseFields = z.infer; -export const ThresholdRuleResponseFields = ThresholdRuleRequiredFields.merge( +export const ThresholdRuleResponseFields = ThresholdRuleRequiredFields.extend( ThresholdRuleOptionalFields -).merge(ThresholdRuleDefaultableFields.required()); +).extend(ThresholdRuleDefaultableFields.required()); export type ThresholdRule = z.infer; -export const ThresholdRule = SharedResponseProps.merge(ThresholdRuleResponseFields); +export const ThresholdRule = SharedResponseProps.extend(ThresholdRuleResponseFields); export type ThresholdRuleCreateProps = z.infer; -export const ThresholdRuleCreateProps = SharedCreateProps.merge(ThresholdRuleCreateFields); +export const ThresholdRuleCreateProps = SharedCreateProps.extend(ThresholdRuleCreateFields); export type ThresholdRuleUpdateProps = z.infer; -export const ThresholdRuleUpdateProps = SharedUpdateProps.merge(ThresholdRuleCreateFields); +export const ThresholdRuleUpdateProps = SharedUpdateProps.extend(ThresholdRuleCreateFields); export type ThresholdRulePatchProps = z.infer; -export const ThresholdRulePatchProps = SharedPatchProps.merge(ThresholdRulePatchFields); +export const ThresholdRulePatchProps = SharedPatchProps.extend(ThresholdRulePatchFields); export type ThreatMatchRuleRequiredFields = z.infer; export const ThreatMatchRuleRequiredFields = z.object({ @@ -438,31 +438,31 @@ export const ThreatMatchRuleDefaultableFields = z.object({ }); export type ThreatMatchRuleCreateFields = z.infer; -export const ThreatMatchRuleCreateFields = ThreatMatchRuleRequiredFields.merge( +export const ThreatMatchRuleCreateFields = ThreatMatchRuleRequiredFields.extend( ThreatMatchRuleOptionalFields -).merge(ThreatMatchRuleDefaultableFields); +).extend(ThreatMatchRuleDefaultableFields); export type ThreatMatchRulePatchFields = z.infer; export const ThreatMatchRulePatchFields = ThreatMatchRuleRequiredFields.partial() - .merge(ThreatMatchRuleOptionalFields) - .merge(ThreatMatchRuleDefaultableFields); + .extend(ThreatMatchRuleOptionalFields) + .extend(ThreatMatchRuleDefaultableFields); export type ThreatMatchRuleResponseFields = z.infer; -export const ThreatMatchRuleResponseFields = ThreatMatchRuleRequiredFields.merge( +export const ThreatMatchRuleResponseFields = ThreatMatchRuleRequiredFields.extend( ThreatMatchRuleOptionalFields -).merge(ThreatMatchRuleDefaultableFields.required()); +).extend(ThreatMatchRuleDefaultableFields.required()); export type ThreatMatchRule = z.infer; -export const ThreatMatchRule = SharedResponseProps.merge(ThreatMatchRuleResponseFields); +export const ThreatMatchRule = SharedResponseProps.extend(ThreatMatchRuleResponseFields); export type ThreatMatchRuleCreateProps = z.infer; -export const ThreatMatchRuleCreateProps = SharedCreateProps.merge(ThreatMatchRuleCreateFields); +export const ThreatMatchRuleCreateProps = SharedCreateProps.extend(ThreatMatchRuleCreateFields); export type ThreatMatchRuleUpdateProps = z.infer; -export const ThreatMatchRuleUpdateProps = SharedUpdateProps.merge(ThreatMatchRuleCreateFields); +export const ThreatMatchRuleUpdateProps = SharedUpdateProps.extend(ThreatMatchRuleCreateFields); export type ThreatMatchRulePatchProps = z.infer; -export const ThreatMatchRulePatchProps = SharedPatchProps.merge(ThreatMatchRulePatchFields); +export const ThreatMatchRulePatchProps = SharedPatchProps.extend(ThreatMatchRulePatchFields); export type MachineLearningRuleRequiredFields = z.infer; export const MachineLearningRuleRequiredFields = z.object({ @@ -480,35 +480,37 @@ export const MachineLearningRuleOptionalFields = z.object({ }); export type MachineLearningRulePatchFields = z.infer; -export const MachineLearningRulePatchFields = MachineLearningRuleRequiredFields.partial().merge( +export const MachineLearningRulePatchFields = MachineLearningRuleRequiredFields.partial().extend( MachineLearningRuleOptionalFields ); export type MachineLearningRuleResponseFields = z.infer; -export const MachineLearningRuleResponseFields = MachineLearningRuleRequiredFields.merge( +export const MachineLearningRuleResponseFields = MachineLearningRuleRequiredFields.extend( MachineLearningRuleOptionalFields ); export type MachineLearningRuleCreateFields = z.infer; -export const MachineLearningRuleCreateFields = MachineLearningRuleRequiredFields.merge( +export const MachineLearningRuleCreateFields = MachineLearningRuleRequiredFields.extend( MachineLearningRuleOptionalFields ); export type MachineLearningRule = z.infer; -export const MachineLearningRule = SharedResponseProps.merge(MachineLearningRuleResponseFields); +export const MachineLearningRule = SharedResponseProps.extend(MachineLearningRuleResponseFields); export type MachineLearningRuleCreateProps = z.infer; -export const MachineLearningRuleCreateProps = SharedCreateProps.merge( +export const MachineLearningRuleCreateProps = SharedCreateProps.extend( MachineLearningRuleCreateFields ); export type MachineLearningRuleUpdateProps = z.infer; -export const MachineLearningRuleUpdateProps = SharedUpdateProps.merge( +export const MachineLearningRuleUpdateProps = SharedUpdateProps.extend( MachineLearningRuleCreateFields ); export type MachineLearningRulePatchProps = z.infer; -export const MachineLearningRulePatchProps = SharedPatchProps.merge(MachineLearningRulePatchFields); +export const MachineLearningRulePatchProps = SharedPatchProps.extend( + MachineLearningRulePatchFields +); export type NewTermsRuleRequiredFields = z.infer; export const NewTermsRuleRequiredFields = z.object({ @@ -536,30 +538,30 @@ export const NewTermsRuleDefaultableFields = z.object({ export type NewTermsRulePatchFields = z.infer; export const NewTermsRulePatchFields = NewTermsRuleRequiredFields.partial() - .merge(NewTermsRuleOptionalFields) - .merge(NewTermsRuleDefaultableFields); + .extend(NewTermsRuleOptionalFields) + .extend(NewTermsRuleDefaultableFields); export type NewTermsRuleResponseFields = z.infer; -export const NewTermsRuleResponseFields = NewTermsRuleRequiredFields.merge( +export const NewTermsRuleResponseFields = NewTermsRuleRequiredFields.extend( NewTermsRuleOptionalFields -).merge(NewTermsRuleDefaultableFields.required()); +).extend(NewTermsRuleDefaultableFields.required()); export type NewTermsRuleCreateFields = z.infer; -export const NewTermsRuleCreateFields = NewTermsRuleRequiredFields.merge( +export const NewTermsRuleCreateFields = NewTermsRuleRequiredFields.extend( NewTermsRuleOptionalFields -).merge(NewTermsRuleDefaultableFields); +).extend(NewTermsRuleDefaultableFields); export type NewTermsRule = z.infer; -export const NewTermsRule = SharedResponseProps.merge(NewTermsRuleResponseFields); +export const NewTermsRule = SharedResponseProps.extend(NewTermsRuleResponseFields); export type NewTermsRuleCreateProps = z.infer; -export const NewTermsRuleCreateProps = SharedCreateProps.merge(NewTermsRuleCreateFields); +export const NewTermsRuleCreateProps = SharedCreateProps.extend(NewTermsRuleCreateFields); export type NewTermsRuleUpdateProps = z.infer; -export const NewTermsRuleUpdateProps = SharedUpdateProps.merge(NewTermsRuleCreateFields); +export const NewTermsRuleUpdateProps = SharedUpdateProps.extend(NewTermsRuleCreateFields); export type NewTermsRulePatchProps = z.infer; -export const NewTermsRulePatchProps = SharedPatchProps.merge(NewTermsRulePatchFields); +export const NewTermsRulePatchProps = SharedPatchProps.extend(NewTermsRulePatchFields); export type EsqlQueryLanguage = z.infer; export const EsqlQueryLanguage = z.literal('esql'); @@ -580,25 +582,25 @@ export const EsqlRuleOptionalFields = z.object({ }); export type EsqlRulePatchFields = z.infer; -export const EsqlRulePatchFields = EsqlRuleOptionalFields.merge(EsqlRuleRequiredFields.partial()); +export const EsqlRulePatchFields = EsqlRuleOptionalFields.extend(EsqlRuleRequiredFields.partial()); export type EsqlRuleResponseFields = z.infer; -export const EsqlRuleResponseFields = EsqlRuleOptionalFields.merge(EsqlRuleRequiredFields); +export const EsqlRuleResponseFields = EsqlRuleOptionalFields.extend(EsqlRuleRequiredFields); export type EsqlRuleCreateFields = z.infer; -export const EsqlRuleCreateFields = EsqlRuleOptionalFields.merge(EsqlRuleRequiredFields); +export const EsqlRuleCreateFields = EsqlRuleOptionalFields.extend(EsqlRuleRequiredFields); export type EsqlRule = z.infer; -export const EsqlRule = SharedResponseProps.merge(EsqlRuleResponseFields); +export const EsqlRule = SharedResponseProps.extend(EsqlRuleResponseFields); export type EsqlRuleCreateProps = z.infer; -export const EsqlRuleCreateProps = SharedCreateProps.merge(EsqlRuleCreateFields); +export const EsqlRuleCreateProps = SharedCreateProps.extend(EsqlRuleCreateFields); export type EsqlRuleUpdateProps = z.infer; -export const EsqlRuleUpdateProps = SharedUpdateProps.merge(EsqlRuleCreateFields); +export const EsqlRuleUpdateProps = SharedUpdateProps.extend(EsqlRuleCreateFields); export type EsqlRulePatchProps = z.infer; -export const EsqlRulePatchProps = SharedPatchProps.merge(EsqlRulePatchFields.partial()); +export const EsqlRulePatchProps = SharedPatchProps.extend(EsqlRulePatchFields.partial()); export const TypeSpecificCreatePropsInternal = z.discriminatedUnion('type', [ EqlRuleCreateFields, diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts index 84b9aeb469f96..90367f16b752d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts @@ -144,35 +144,35 @@ Only valid when query property is undefined. }); export type BulkDeleteRules = z.infer; -export const BulkDeleteRules = BulkActionBase.merge( +export const BulkDeleteRules = BulkActionBase.extend( z.object({ action: z.literal('delete'), }) ); export type BulkDisableRules = z.infer; -export const BulkDisableRules = BulkActionBase.merge( +export const BulkDisableRules = BulkActionBase.extend( z.object({ action: z.literal('disable'), }) ); export type BulkEnableRules = z.infer; -export const BulkEnableRules = BulkActionBase.merge( +export const BulkEnableRules = BulkActionBase.extend( z.object({ action: z.literal('enable'), }) ); export type BulkExportRules = z.infer; -export const BulkExportRules = BulkActionBase.merge( +export const BulkExportRules = BulkActionBase.extend( z.object({ action: z.literal('export'), }) ); export type BulkDuplicateRules = z.infer; -export const BulkDuplicateRules = BulkActionBase.merge( +export const BulkDuplicateRules = BulkActionBase.extend( z.object({ action: z.literal('duplicate'), /** @@ -194,7 +194,7 @@ export const BulkDuplicateRules = BulkActionBase.merge( ); export type BulkManualRuleRun = z.infer; -export const BulkManualRuleRun = BulkActionBase.merge( +export const BulkManualRuleRun = BulkActionBase.extend( z.object({ action: z.literal('run'), /** @@ -214,7 +214,7 @@ export const BulkManualRuleRun = BulkActionBase.merge( ); export type BulkManualRuleFillGaps = z.infer; -export const BulkManualRuleFillGaps = BulkActionBase.merge( +export const BulkManualRuleFillGaps = BulkActionBase.extend( z.object({ action: z.literal('fill_gaps'), /** @@ -451,7 +451,7 @@ export const BulkActionEditPayload = BulkActionEditPayloadInternal as z.ZodType; export type BulkEditRules = z.infer; -export const BulkEditRules = BulkActionBase.merge( +export const BulkEditRules = BulkActionBase.extend( z.object({ action: z.literal('edit'), /** diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts index c0c350e1c7cc5..7e5a910a5e6e4 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts @@ -66,14 +66,14 @@ export type RulePreviewRequestQueryInput = z.input; export const RulePreviewRequestBody = z.discriminatedUnion('type', [ - EqlRuleCreateProps.merge(RulePreviewParams), - QueryRuleCreateProps.merge(RulePreviewParams), - SavedQueryRuleCreateProps.merge(RulePreviewParams), - ThresholdRuleCreateProps.merge(RulePreviewParams), - ThreatMatchRuleCreateProps.merge(RulePreviewParams), - MachineLearningRuleCreateProps.merge(RulePreviewParams), - NewTermsRuleCreateProps.merge(RulePreviewParams), - EsqlRuleCreateProps.merge(RulePreviewParams), + EqlRuleCreateProps.extend(RulePreviewParams), + QueryRuleCreateProps.extend(RulePreviewParams), + SavedQueryRuleCreateProps.extend(RulePreviewParams), + ThresholdRuleCreateProps.extend(RulePreviewParams), + ThreatMatchRuleCreateProps.extend(RulePreviewParams), + MachineLearningRuleCreateProps.extend(RulePreviewParams), + NewTermsRuleCreateProps.extend(RulePreviewParams), + EsqlRuleCreateProps.extend(RulePreviewParams), ]); export type RulePreviewRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts index 5bc3d143b9163..39eeb647a5993 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts @@ -62,7 +62,7 @@ export const CreateAlertsMigrationRequestBody = z */ index: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), }) - .merge(AlertsReindexOptions); + .extend(AlertsReindexOptions); export type CreateAlertsMigrationRequestBodyInput = z.input< typeof CreateAlertsMigrationRequestBody >; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts index 77db1ba54ab33..1eb5e0fc37beb 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type CancelRouteRequestBody = z.infer; -export const CancelRouteRequestBody = BaseActionSchema.merge( +export const CancelRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.object({ /** diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts index 3b8edf4a15f59..55795e85925ce 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type ExecuteRouteRequestBody = z.infer; -export const ExecuteRouteRequestBody = BaseActionSchema.merge( +export const ExecuteRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.object({ /** diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts index 5882da8ab5247..7d6bb5cd69890 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type GetFileRouteRequestBody = z.infer; -export const GetFileRouteRequestBody = BaseActionSchema.merge( +export const GetFileRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.object({ /** diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts index b26cf38798b89..a2195369d79b5 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type KillProcessRouteRequestBody = z.infer; -export const KillProcessRouteRequestBody = BaseActionSchema.merge( +export const KillProcessRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.union([ z.object({ diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts index 9dad5ea51fc3d..4a0f89cc08334 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts @@ -100,7 +100,7 @@ export const MDERunScriptParameters = z.object({ }); export type RunScriptRouteRequestBody = z.infer; -export const RunScriptRouteRequestBody = BaseActionSchema.merge( +export const RunScriptRouteRequestBody = BaseActionSchema.extend( z.object({ /** * One of the following set of parameters must be provided diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts index 7aadcfbd9d7e0..10563d0df4c2e 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type ScanRouteRequestBody = z.infer; -export const ScanRouteRequestBody = BaseActionSchema.merge( +export const ScanRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.object({ /** diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts index a6ef00453ebe2..7b864462c1df8 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type SuspendProcessRouteRequestBody = z.infer; -export const SuspendProcessRouteRequestBody = BaseActionSchema.merge( +export const SuspendProcessRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.union([ z.object({ diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts index 34bc7ed7365d8..b7058a610237d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts @@ -22,7 +22,7 @@ import { } from '../../../model/schema/common.gen'; export type UploadRouteRequestBody = z.infer; -export const UploadRouteRequestBody = BaseActionSchema.merge( +export const UploadRouteRequestBody = BaseActionSchema.extend( z.object({ parameters: z.object({ /** diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts index e72f642a9ee45..4bf1c82cc88ad 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts @@ -56,7 +56,7 @@ export type BulkUpsertAssetCriticalityRecordsRequestBody = z.infer< export const BulkUpsertAssetCriticalityRecordsRequestBody = z.object({ records: z .array( - AssetCriticalityRecordIdParts.merge( + AssetCriticalityRecordIdParts.extend( z.object({ criticality_level: AssetCriticalityLevelsForBulkUpload, }) diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts index 3c7d5ec4cf661..4c5f3c3f8fd94 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts @@ -47,7 +47,7 @@ export type AssetCriticalityLevelEnum = typeof AssetCriticalityLevel.enum; export const AssetCriticalityLevelEnum = AssetCriticalityLevel.enum; export type CreateAssetCriticalityRecord = z.infer; -export const CreateAssetCriticalityRecord = AssetCriticalityRecordIdParts.merge( +export const CreateAssetCriticalityRecord = AssetCriticalityRecordIdParts.extend( z.object({ criticality_level: AssetCriticalityLevel, }) @@ -101,9 +101,9 @@ export const AssetCriticalityRecordEcsParts = z.object({ }); export type AssetCriticalityRecord = z.infer; -export const AssetCriticalityRecord = CreateAssetCriticalityRecord.merge( +export const AssetCriticalityRecord = CreateAssetCriticalityRecord.extend( AssetCriticalityRecordEcsParts -).merge( +).extend( z.object({ /** * The time the record was created or updated. diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts index f2c8bb827d310..cda379daabd0d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts @@ -21,7 +21,7 @@ import { CreateAssetCriticalityRecord, AssetCriticalityRecord } from './common.g export type CreateAssetCriticalityRecordRequestBody = z.infer< typeof CreateAssetCriticalityRecordRequestBody >; -export const CreateAssetCriticalityRecordRequestBody = CreateAssetCriticalityRecord.merge( +export const CreateAssetCriticalityRecordRequestBody = CreateAssetCriticalityRecord.extend( z.object({ /** * If 'wait_for' the request will wait for the index refresh. diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts index 763074bd144a8..89af54f49cb7d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts @@ -206,7 +206,7 @@ export const RiskScoreWeightGlobalShared = z.object({ }); export const RiskScoreWeightInternal = z.union([ - RiskScoreWeightGlobalShared.merge( + RiskScoreWeightGlobalShared.extend( z.object({ host: RiskScoreEntityIdentifierWeights, user: RiskScoreEntityIdentifierWeights.optional(), @@ -214,7 +214,7 @@ export const RiskScoreWeightInternal = z.union([ generic: RiskScoreEntityIdentifierWeights.optional(), }) ), - RiskScoreWeightGlobalShared.merge( + RiskScoreWeightGlobalShared.extend( z.object({ host: RiskScoreEntityIdentifierWeights.optional(), user: RiskScoreEntityIdentifierWeights, @@ -222,7 +222,7 @@ export const RiskScoreWeightInternal = z.union([ generic: RiskScoreEntityIdentifierWeights.optional(), }) ), - RiskScoreWeightGlobalShared.merge( + RiskScoreWeightGlobalShared.extend( z.object({ host: RiskScoreEntityIdentifierWeights.optional(), user: RiskScoreEntityIdentifierWeights.optional(), diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts index 7381cca147d00..da6502a59ea2b 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts @@ -40,7 +40,7 @@ export const GetEntityStoreStatusResponse = z.object({ * Per-engine status information. */ engines: z.array( - EngineDescriptor.merge( + EngineDescriptor.extend( z.object({ /** * Detailed component-level status. Only included when include_components is true. diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts index 69e2eee18d78b..cf52621a00b30 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts @@ -76,12 +76,11 @@ export const UpdateableMonitoringEntitySourceProperties = z.object({ export type UpdateEntitySourceNoadditionalProps = z.infer< typeof UpdateEntitySourceNoadditionalProps >; -export const UpdateEntitySourceNoadditionalProps = UpdateableMonitoringEntitySourceProperties.merge( - z.object({}).strict() -); +export const UpdateEntitySourceNoadditionalProps = + UpdateableMonitoringEntitySourceProperties.extend(z.object({}).strict()); export type MonitoringEntitySourceProperties = z.infer; -export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySourceProperties.merge( +export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySourceProperties.extend( z.object({ type: MonitoringEntitySourceType.optional(), managed: z.boolean().optional(), @@ -91,12 +90,12 @@ export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySource ); export type MonitoringEntitySourceAttributes = z.infer; -export const MonitoringEntitySourceAttributes = MonitoringEntitySourceProperties.merge( +export const MonitoringEntitySourceAttributes = MonitoringEntitySourceProperties.extend( z.object({}) ); export type MonitoringEntitySource = z.infer; -export const MonitoringEntitySource = MonitoringEntitySourceProperties.merge( +export const MonitoringEntitySource = MonitoringEntitySourceProperties.extend( z.object({ id: z.string(), }) diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts index 16e40db33773f..529cedba693c2 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts @@ -90,7 +90,7 @@ export const MonitoredUserUpdateDoc = z.object({ }); export type MonitoredUserDoc = z.infer; -export const MonitoredUserDoc = MonitoredUserUpdateDoc.merge( +export const MonitoredUserDoc = MonitoredUserUpdateDoc.extend( z.object({ event: z .object({ diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts index 23c50b58dabf8..3a27d348f6f56 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts @@ -83,12 +83,11 @@ export const UpdateableMonitoringEntitySourceProperties = z.object({ export type UpdateEntitySourceNoadditionalProps = z.infer< typeof UpdateEntitySourceNoadditionalProps >; -export const UpdateEntitySourceNoadditionalProps = UpdateableMonitoringEntitySourceProperties.merge( - z.object({}).strict() -); +export const UpdateEntitySourceNoadditionalProps = + UpdateableMonitoringEntitySourceProperties.extend(z.object({}).strict()); export type MonitoringEntitySourceProperties = z.infer; -export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySourceProperties.merge( +export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySourceProperties.extend( z.object({ type: EntitySourceType.optional(), managed: z.boolean().optional(), @@ -96,12 +95,12 @@ export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySource ); export type MonitoringEntitySourceAttributes = z.infer; -export const MonitoringEntitySourceAttributes = MonitoringEntitySourceProperties.merge( +export const MonitoringEntitySourceAttributes = MonitoringEntitySourceProperties.extend( z.object({}) ); export type MonitoringEntitySource = z.infer; -export const MonitoringEntitySource = MonitoringEntitySourceProperties.merge( +export const MonitoringEntitySource = MonitoringEntitySourceProperties.extend( z.object({ id: z.string(), }) diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts index bccfc734d8c6f..159f2c29a9497 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts @@ -75,7 +75,7 @@ export const CreateWatchlistRequestBody = z.object({ export type CreateWatchlistRequestBodyInput = z.input; export type CreateWatchlistResponse = z.infer; -export const CreateWatchlistResponse = WatchlistObject.merge( +export const CreateWatchlistResponse = WatchlistObject.extend( z.object({ entitySources: z.array(MonitoringEntitySource).optional(), }) diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts index bb49647ad41b1..a79160cab7e3a 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts @@ -298,7 +298,7 @@ export const SavedTimeline = z.object({ }); export type SavedTimelineWithSavedObjectId = z.infer; -export const SavedTimelineWithSavedObjectId = SavedTimeline.merge( +export const SavedTimelineWithSavedObjectId = SavedTimeline.extend( z.object({ /** * The `savedObjectId` of the Timeline or Timeline template @@ -332,7 +332,7 @@ export const NoteCreatedAndUpdatedMetadata = z.object({ }); export type BareNote = z.infer; -export const BareNote = NoteCreatedAndUpdatedMetadata.merge( +export const BareNote = NoteCreatedAndUpdatedMetadata.extend( z.object({ /** * The `_id` of the associated event for this note. @@ -350,7 +350,7 @@ export const BareNote = NoteCreatedAndUpdatedMetadata.merge( ); export type Note = z.infer; -export const Note = BareNote.merge( +export const Note = BareNote.extend( z.object({ /** * The `savedObjectId` of the note @@ -386,7 +386,7 @@ export const PinnedEventCreatedAndUpdatedMetadata = z.object({ }); export type BarePinnedEvent = z.infer; -export const BarePinnedEvent = PinnedEventCreatedAndUpdatedMetadata.merge( +export const BarePinnedEvent = PinnedEventCreatedAndUpdatedMetadata.extend( z.object({ /** * The `_id` of the associated event for this pinned event. @@ -400,7 +400,7 @@ export const BarePinnedEvent = PinnedEventCreatedAndUpdatedMetadata.merge( ); export type PinnedEvent = z.infer; -export const PinnedEvent = BarePinnedEvent.merge( +export const PinnedEvent = BarePinnedEvent.extend( z.object({ /** * The `savedObjectId` of this pinned event @@ -414,7 +414,7 @@ export const PinnedEvent = BarePinnedEvent.merge( ); export type TimelineResponse = z.infer; -export const TimelineResponse = SavedTimeline.merge(SavedTimelineWithSavedObjectId).merge( +export const TimelineResponse = SavedTimeline.extend(SavedTimelineWithSavedObjectId).extend( z.object({ /** * A list of all the notes that are associated to this Timeline. @@ -440,7 +440,7 @@ export const TimelineResponse = SavedTimeline.merge(SavedTimelineWithSavedObject ); export type TimelineSavedToReturnObject = z.infer; -export const TimelineSavedToReturnObject = SavedTimeline.merge( +export const TimelineSavedToReturnObject = SavedTimeline.extend( z.object({ savedObjectId: z.string(), version: z.string(), @@ -487,7 +487,7 @@ export type PersistTimelineResponse = z.infer; export const PersistTimelineResponse = TimelineResponse; export type BareNoteWithoutExternalRefs = z.infer; -export const BareNoteWithoutExternalRefs = NoteCreatedAndUpdatedMetadata.merge( +export const BareNoteWithoutExternalRefs = NoteCreatedAndUpdatedMetadata.extend( z.object({ /** * The `_id` of the associated event for this note. @@ -518,7 +518,7 @@ export type SortDirectionEnum = typeof SortDirection.enum; export const SortDirectionEnum = SortDirection.enum; export type ImportTimelines = z.infer; -export const ImportTimelines = SavedTimeline.merge( +export const ImportTimelines = SavedTimeline.extend( z.object({ savedObjectId: z.string().nullable(), version: z.string().nullable(), diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts index 669ac5bc1cf5b..c1b4bdbffff69 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts @@ -45,7 +45,7 @@ export const LangSmithOptions = z.object({ * The LangSmith settings object for evaluations. */ export type LangSmithEvaluationOptions = z.infer; -export const LangSmithEvaluationOptions = LangSmithOptions.merge( +export const LangSmithEvaluationOptions = LangSmithOptions.extend( z.object({ /** * The dataset name to use for evaluations. @@ -299,7 +299,7 @@ export const SiemMigrationResourceContent = z.object({ * The rule migration resource data. */ export type SiemMigrationResourceData = z.infer; -export const SiemMigrationResourceData = SiemMigrationResourceBase.merge( +export const SiemMigrationResourceData = SiemMigrationResourceBase.extend( SiemMigrationResourceContent ); @@ -307,9 +307,9 @@ export const SiemMigrationResourceData = SiemMigrationResourceBase.merge( * The rule migration resource document object. */ export type SiemMigrationResource = z.infer; -export const SiemMigrationResource = SiemMigrationResourceBase.merge( +export const SiemMigrationResource = SiemMigrationResourceBase.extend( SiemMigrationResourceContent.partial() -).merge( +).extend( z.object({ /** * The rule resource migration id diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts index 22208b5f96686..e5e191795fc1b 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts @@ -66,7 +66,7 @@ export const DashboardMigration = z */ id: NonEmptyString, }) - .merge(DashboardMigrationData); + .extend(DashboardMigrationData); /** * The dashboard migration translation stats object. @@ -242,7 +242,7 @@ export const DashboardMigrationDashboard = z */ id: NonEmptyString, }) - .merge(DashboardMigrationDashboardData); + .extend(DashboardMigrationDashboardData); /** * The partial version of the migrated elastic dashboard. diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts index b6d69f789580a..01bd9084aa952 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts @@ -163,7 +163,7 @@ export const PrebuiltRuleVersion = z.object({ * The last execution of the rule migration task. */ export type RuleMigrationLastExecution = z.infer; -export const RuleMigrationLastExecution = MigrationLastExecution.merge( +export const RuleMigrationLastExecution = MigrationLastExecution.extend( z.object({ /** * Indicates if the last execution skipped matching prebuilt rules. @@ -206,7 +206,7 @@ export const RuleMigration = z */ name: NonEmptyString, }) - .merge(RuleMigrationData); + .extend(RuleMigrationData); /** * The rule migration document object. @@ -266,13 +266,13 @@ export const RuleMigrationRule = z */ id: NonEmptyString, }) - .merge(RuleMigrationRuleData); + .extend(RuleMigrationRuleData); /** * The rule migration task stats object. */ export type RuleMigrationTaskStats = z.infer; -export const RuleMigrationTaskStats = MigrationTaskStats.merge( +export const RuleMigrationTaskStats = MigrationTaskStats.extend( z.object({ /** * The last execution of the rule migration task. From 72c664f462a351640841a7076f2b6e309245be23 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 17 Apr 2026 13:44:32 +0200 Subject: [PATCH 2/6] avoid exporting schemas --- .../common/api/detection_engine/prebuilt_rules/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts index 029b17ba383ae..c1fe80c2ae276 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/index.ts @@ -7,13 +7,13 @@ export * from './read_prebuilt_rules_and_timelines_status/read_prebuilt_rules_and_timelines_status_route.gen'; export type * from './get_prebuilt_rules_status/get_prebuilt_rules_status_route'; -export * from './install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.gen'; +export type * from './install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.gen'; export * from './perform_rule_installation/perform_rule_installation_route'; export * from './perform_rule_upgrade/perform_rule_upgrade_route'; export type * from './review_rule_installation/review_rule_installation_route'; export * from './review_rule_upgrade/review_rule_upgrade_route'; export * from './urls'; -export * from './model/aggregated_prebuilt_rules_error'; +export type * from './model/aggregated_prebuilt_rules_error'; export * from './model/diff/diffable_rule/diffable_field_types'; export * from './model/diff/diffable_rule/diffable_rule'; export type * from './model/diff/three_way_diff/three_way_fields_diff'; From 2134993b39129fc48fa4efcf6526f8787e9dcbfd Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 17 Apr 2026 15:34:35 +0200 Subject: [PATCH 3/6] load Zod schemas lazily --- .../schemas/error_responses.gen.ts | 24 +- .../schemas/primitives.gen.ts | 6 +- .../templates/zod_operation_schema.handlebars | 16 +- .../templates/zod_schema_item.handlebars | 2 +- .../packages/shared/kbn-zod/v4/index.ts | 1 + .../shared/kbn-zod/v4/lazy_schema.test.ts | 146 + .../packages/shared/kbn-zod/v4/lazy_schema.ts | 45 + ...ost_actions_connector_execute_route.gen.ts | 112 +- .../bulk_crud_alert_summary_route.gen.ts | 160 +- .../find_alert_summary_route.gen.ts | 82 +- ...ulk_crud_anonymization_fields_route.gen.ts | 365 +-- .../find_anonymization_fields_route.gen.ts | 144 +- .../attack_discovery_alert.gen.ts | 216 +- .../attack_discovery_api_alert.gen.ts | 216 +- ...ck_discovery_find_internal_response.gen.ts | 22 +- .../attack_discovery/common_attributes.gen.ts | 536 ++-- .../attack_discovery/generation.gen.ts | 110 +- .../privileges/get_missing_privileges.gen.ts | 30 +- .../get/find_attack_discoveries_route.gen.ts | 200 +- ...t_attack_discovery_generation_route.gen.ts | 60 +- ..._attack_discovery_generations_route.gen.ts | 46 +- .../post_attack_discovery_bulk_route.gen.ts | 70 +- .../post_attack_discovery_generate.gen.ts | 20 +- ...discovery_generations_dismiss.route.gen.ts | 124 +- ...ud_attack_discovery_schedules_route.gen.ts | 160 +- ...nd_attack_discovery_schedules_route.gen.ts | 78 +- .../routes/public/schedules/schedules.gen.ts | 391 +-- .../public/schedules/schedules_api.gen.ts | 391 +-- .../get_capabilities_route.gen.ts | 12 +- .../chat/post_chat_complete_route.gen.ts | 148 +- .../impl/schemas/common_attributes.gen.ts | 128 +- .../conversations/append_message.gen.ts | 22 +- .../bulk_crud_conversations_route.gen.ts | 214 +- .../conversations/common_attributes.gen.ts | 879 +++--- .../crud_conversation_route.gen.ts | 82 +- .../find_conversations_route.gen.ts | 106 +- .../defend_insights/common_attributes.gen.ts | 340 +-- .../get_defend_insight_route.gen.ts | 24 +- .../get_defend_insights_route.gen.ts | 64 +- .../post_defend_insights_route.gen.ts | 34 +- .../evaluation/get_evaluate_route.gen.ts | 24 +- .../evaluation/post_evaluate_route.gen.ts | 42 +- .../knowledge_base/crud_kb_route.gen.ts | 188 +- ...k_crud_knowledge_base_entries_route.gen.ts | 272 +- .../entries/common_attributes.gen.ts | 406 +-- .../crud_knowledge_base_entries_route.gen.ts | 58 +- .../find_knowledge_base_entries_route.gen.ts | 103 +- .../prompts/bulk_crud_prompts_route.gen.ts | 468 +-- .../schemas/prompts/find_prompts_route.gen.ts | 98 +- .../common_attributes.gen.ts | 14 +- .../find_prompts_route.gen.ts | 40 +- .../update_anonymization_fields_route.gen.ts | 10 +- .../impl/schemas/users/suggest_route.gen.ts | 80 +- .../shared/cases/common/bundled-types.gen.ts | 2567 +++++++++-------- .../osquery/common/api/asset/assets.gen.ts | 22 +- .../common/api/asset/assets_status.gen.ts | 4 +- .../api/fleet_wrapper/fleet_wrapper.gen.ts | 36 +- .../api/fleet_wrapper/get_agent_status.gen.ts | 14 +- .../api/live_query/create_live_query.gen.ts | 204 +- .../api/live_query/find_live_query.gen.ts | 280 +- .../live_query/get_live_query_results.gen.ts | 52 +- .../common/api/live_query/live_queries.gen.ts | 140 +- .../api/model/schema/common_attributes.gen.ts | 164 +- .../osquery/common/api/packs/copy_pack.gen.ts | 106 +- .../common/api/packs/create_pack.gen.ts | 126 +- .../common/api/packs/find_packs.gen.ts | 170 +- .../osquery/common/api/packs/packs.gen.ts | 112 +- .../common/api/packs/update_packs.gen.ts | 74 +- .../api/saved_query/copy_saved_query.gen.ts | 44 +- .../api/saved_query/create_saved_query.gen.ts | 102 +- .../api/saved_query/find_saved_query.gen.ts | 100 +- .../common/api/saved_query/saved_query.gen.ts | 112 +- .../api/saved_query/update_saved_query.gen.ts | 78 +- .../get_scheduled_action_results.gen.ts | 168 +- .../get_scheduled_query_results.gen.ts | 46 +- .../scheduled_results.gen.ts | 154 +- .../common/api/status/privileges_check.gen.ts | 4 +- .../osquery/common/api/status/status.gen.ts | 4 +- .../get_unified_history.gen.ts | 307 +- .../unified_history/unified_history.gen.ts | 66 +- .../create_endpoint_list.gen.ts | 3 +- .../create_endpoint_list_item.gen.ts | 28 +- .../delete_endpoint_list_item.gen.ts | 26 +- .../find_endpoint_list_item.gen.ts | 94 +- .../api/model/endpoint_list_common.gen.ts | 6 +- .../read_endpoint_list_item.gen.ts | 26 +- .../update_endpoint_list_item.gen.ts | 50 +- .../create_exception_list.gen.ts | 28 +- .../create_exception_list_item.gen.ts | 154 +- .../create_rule_exceptions.gen.ts | 68 +- .../create_shared_exceptions_list.gen.ts | 14 +- .../delete_exception_list.gen.ts | 28 +- .../delete_exception_list_item.gen.ts | 28 +- .../duplicate_exception_list.gen.ts | 22 +- .../export_exception_list.gen.ts | 22 +- .../find_exception_list_items.gen.ts | 78 +- .../find_exception_lists.gen.ts | 66 +- .../import_exceptions.gen.ts | 62 +- .../api/model/exception_list_common.gen.ts | 1280 ++++---- .../model/exception_list_item_entry.gen.ts | 122 +- .../read_exception_list.gen.ts | 28 +- .../read_exception_list_item.gen.ts | 28 +- .../read_exception_list_summary.gen.ts | 48 +- .../update_exception_list.gen.ts | 38 +- .../update_exception_list_item.gen.ts | 178 +- .../api/create_list/create_list.gen.ts | 22 +- .../create_list_index.gen.ts | 10 +- .../create_list_item/create_list_item.gen.ts | 26 +- .../api/delete_list/delete_list.gen.ts | 28 +- .../delete_list_index.gen.ts | 10 +- .../delete_list_item/delete_list_item.gen.ts | 42 +- .../export_list_items.gen.ts | 16 +- .../find_list_items/find_list_items.gen.ts | 72 +- .../api/find_lists/find_lists.gen.ts | 74 +- .../import_list_items.gen.ts | 28 +- .../api/model/list_common.gen.ts | 76 +- .../api/model/list_schemas.gen.ts | 126 +- .../api/patch_list/patch_list.gen.ts | 22 +- .../patch_list_item/patch_list_item.gen.ts | 26 +- .../api/read_list/read_list.gen.ts | 12 +- .../read_list_index/read_list_index.gen.ts | 12 +- .../api/read_list_item/read_list_item.gen.ts | 34 +- .../read_list_privileges.gen.ts | 46 +- .../api/update_list/update_list.gen.ts | 22 +- .../update_list_item/update_list_item.gen.ts | 18 +- .../set_alert_assignees_route.gen.ts | 3 +- .../set_alert_tags/set_alert_tags.gen.ts | 6 +- .../create_index/create_index.gen.ts | 10 +- .../delete_index/delete_index.gen.ts | 10 +- .../read_index/read_index.gen.ts | 12 +- .../read_privileges/read_privileges.gen.ts | 12 +- .../model/error_schema.gen.ts | 28 +- .../detection_engine/model/pagination.gen.ts | 24 +- .../response_actions.gen.ts | 260 +- .../rule_schema/common_attributes.gen.ts | 548 ++-- .../model/rule_schema/rule_schemas.gen.ts | 937 +++--- .../specific_attributes/eql_attributes.gen.ts | 8 +- .../specific_attributes/ml_attributes.gen.ts | 8 +- .../new_terms_attributes.gen.ts | 6 +- .../threat_match_attributes.gen.ts | 44 +- .../threshold_attributes.gen.ts | 78 +- .../model/set_alert_assignees_body.gen.ts | 28 +- .../model/set_alert_tags_body.gen.ts | 22 +- .../api/detection_engine/model/sorting.gen.ts | 4 +- .../model/warning_schema.gen.ts | 16 +- .../bootstrap_prebuilt_rules.gen.ts | 144 +- ..._prebuilt_rules_and_timelines_route.gen.ts | 44 +- ...lt_rules_and_timelines_status_route.gen.ts | 68 +- .../bulk_actions/bulk_actions_route.gen.ts | 626 ++-- .../crud/create_rule/create_rule_route.gen.ts | 5 +- .../crud/delete_rule/delete_rule_route.gen.ts | 26 +- .../crud/patch_rule/patch_rule_route.gen.ts | 5 +- .../crud/read_rule/read_rule_route.gen.ts | 26 +- .../crud/update_rule/update_rule_route.gen.ts | 5 +- .../export_rules/export_rules_route.gen.ts | 48 +- .../find_rules/find_rules_route.gen.ts | 130 +- .../import_rules/import_rules_route.gen.ts | 72 +- .../read_tags/read_tags_route.gen.ts | 3 +- .../model/execution_event.gen.ts | 34 +- .../model/execution_metrics.gen.ts | 100 +- .../model/execution_run_type.gen.ts | 4 +- .../model/execution_status.gen.ts | 14 +- .../model/execution_summary.gen.ts | 34 +- .../model/unified_execution_result.gen.ts | 126 +- .../read_rule_execution_results_route.gen.ts | 146 +- .../rule_preview/rule_preview.gen.ts | 96 +- .../query_signals/query_signals_route.gen.ts | 36 +- .../set_signals_status_route.gen.ts | 102 +- .../create_signals_migration.gen.ts | 98 +- .../delete_signals_migration.gen.ts | 48 +- .../finalize_signals_migration.gen.ts | 52 +- .../read_signals_migration_status.gen.ts | 64 +- .../unified_alerts/search/search_route.gen.ts | 6 +- .../set_alert_assignees_route.gen.ts | 8 +- .../set_alert_tags_route.gen.ts | 6 +- .../set_workflow_status_route.gen.ts | 8 +- .../users/suggest_user_profiles_route.gen.ts | 16 +- .../file_download/file_download.gen.ts | 22 +- .../actions/file_info/file_info.gen.ts | 24 +- .../api/endpoint/actions/list/list.gen.ts | 124 +- .../response_actions/cancel/cancel.gen.ts | 28 +- .../response_actions/execute/execute.gen.ts | 36 +- .../response_actions/get_file/get_file.gen.ts | 28 +- .../response_actions/isolate/isolate.gen.ts | 22 +- .../kill_process/kill_process.gen.ts | 58 +- .../run_script/run_script.gen.ts | 166 +- .../running_procs/running_procs.gen.ts | 9 +- .../actions/response_actions/scan/scan.gen.ts | 28 +- .../suspend_process/suspend_process.gen.ts | 48 +- .../unisolate/unisolate.gen.ts | 22 +- .../response_actions/upload/upload.gen.ts | 30 +- .../api/endpoint/actions/state/state.gen.ts | 26 +- .../api/endpoint/actions/status/status.gen.ts | 122 +- ...dpoint_exceptions_per_policy_opt_in.gen.ts | 12 +- .../api/endpoint/metadata/get_metadata.gen.ts | 22 +- .../endpoint/metadata/list_metadata.gen.ts | 6 +- .../api/endpoint/model/schema/common.gen.ts | 371 +-- .../endpoint/policy/policy_response.gen.ts | 18 +- .../protection_updates_note.gen.ts | 50 +- .../suggestions/get_suggestions.gen.ts | 26 +- .../bulk_upload_asset_criticality.gen.ts | 70 +- .../asset_criticality/common.gen.ts | 157 +- .../create_asset_criticality.gen.ts | 22 +- .../delete_asset_criticality.gen.ts | 54 +- .../get_asset_criticality.gen.ts | 26 +- .../get_asset_criticality_privileges.gen.ts | 3 +- .../get_asset_criticality_status.gen.ts | 10 +- .../list_asset_criticality.gen.ts | 62 +- .../upload_asset_criticality_csv.gen.ts | 62 +- .../api/entity_analytics/common/common.gen.ts | 360 +-- .../entity_details/highlights.gen.ts | 80 +- .../entity_store/common.gen.ts | 418 +-- .../entity_store/enable.gen.ts | 134 +- .../engine/apply_dataview_indices.gen.ts | 60 +- .../entity_store/engine/delete.gen.ts | 96 +- .../entity_store/engine/get.gen.ts | 18 +- .../entity_store/engine/get_privileges.gen.ts | 3 +- .../entity_store/engine/init.gen.ts | 126 +- .../entity_store/engine/list.gen.ts | 24 +- .../entity_store/engine/start.gen.ts | 30 +- .../entity_store/engine/stop.gen.ts | 30 +- .../entity_store/entities/common.gen.ts | 780 ++--- .../entities/delete_entity.gen.ts | 38 +- .../entities/list_entities.gen.ts | 96 +- .../entities/upsert_entities_bulk.gen.ts | 54 +- .../entities/upsert_entity.gen.ts | 28 +- .../entity_store/status.gen.ts | 56 +- .../migrations/run_migrations_route.gen.ts | 10 +- .../entity_analytics/monitoring/common.gen.ts | 69 +- .../monitoring/create_index.gen.ts | 32 +- .../monitoring/engine/delete.gen.ts | 24 +- .../monitoring/engine/disable.gen.ts | 3 +- .../monitoring/engine/init.gen.ts | 3 +- .../monitoring/engine/schedule_now.gen.ts | 16 +- .../entity_analytics/monitoring/health.gen.ts | 50 +- .../monitoring_entity_source.gen.ts | 221 +- .../install.gen.ts | 10 +- .../privileged_access_detection/status.gen.ts | 26 +- .../monitoring/privileges.gen.ts | 3 +- .../monitoring/search_indices.gen.ts | 12 +- .../monitoring/users/common.gen.ts | 190 +- .../monitoring/users/create.gen.ts | 5 +- .../monitoring/users/delete.gen.ts | 32 +- .../monitoring/users/list.gen.ts | 18 +- .../monitoring/users/update.gen.ts | 14 +- .../monitoring/users/upload_csv.gen.ts | 38 +- .../risk_engine/calculation_route.gen.ts | 80 +- .../risk_engine/engine_cleanup_route.gen.ts | 30 +- ...engine_configure_saved_object_route.gen.ts | 76 +- .../risk_engine/engine_disable_route.gen.ts | 20 +- .../risk_engine/engine_enable_route.gen.ts | 20 +- .../risk_engine/engine_init_route.gen.ts | 34 +- .../engine_schedule_now_route.gen.ts | 22 +- .../risk_engine/engine_settings_route.gen.ts | 48 +- .../risk_engine/engine_status_route.gen.ts | 40 +- .../entity_calculation_route.gen.ts | 58 +- .../get_risk_engine_privileges.gen.ts | 3 +- .../risk_engine/preview_route.gen.ts | 172 +- .../watchlists/csv_upload/csv_upload.gen.ts | 80 +- .../watchlists/data_source/common.gen.ts | 145 +- .../watchlists/data_source/create.gen.ts | 58 +- .../watchlists/data_source/delete.gen.ts | 12 +- .../watchlists/data_source/get.gen.ts | 14 +- .../watchlists/data_source/list.gen.ts | 44 +- .../watchlists/data_source/update.gen.ts | 18 +- .../watchlists/entities/assign.gen.ts | 94 +- .../watchlists/entities/unassign.gen.ts | 94 +- .../watchlists/management/common.gen.ts | 80 +- .../watchlists/management/create.gen.ts | 110 +- .../watchlists/management/get.gen.ts | 18 +- .../watchlists/management/list.gen.ts | 4 +- .../watchlists/management/update.gen.ts | 56 +- .../watchlists/sync/sync.gen.ts | 18 +- .../api/initialization/initialization.gen.ts | 92 +- .../common/api/model/alert.gen.ts | 18 +- .../common/api/model/error_responses.gen.ts | 24 +- .../common/api/model/primitives.gen.ts | 6 +- .../clean_draft_timelines_route.gen.ts | 12 +- .../copy_timeline/copy_timeline_route.gen.ts | 14 +- .../create_timelines_route.gen.ts | 42 +- .../delete_note/delete_note_route.gen.ts | 28 +- .../delete_timelines_route.gen.ts | 24 +- .../export_timelines_route.gen.ts | 24 +- .../get_draft_timelines_route.gen.ts | 12 +- .../timeline/get_notes/get_notes_route.gen.ts | 54 +- .../get_timeline/get_timeline_route.gen.ts | 26 +- .../get_timelines/get_timelines_route.gen.ts | 110 +- .../import_timelines_route.gen.ts | 20 +- ...install_prepackaged_timelines_route.gen.ts | 16 +- .../api/timeline/model/components.gen.ts | 915 +++--- .../patch_timeline_route.gen.ts | 34 +- .../persist_favorite_route.gen.ts | 18 +- .../persist_note/persist_note_route.gen.ts | 42 +- .../pinned_events/pinned_events_route.gen.ts | 50 +- .../resolve_timeline_route.gen.ts | 26 +- .../api/dashboards/dashboard_migration.gen.ts | 332 ++- .../model/api/rules/rule_migration.gen.ts | 502 ++-- .../siem_migrations/model/common.gen.ts | 422 +-- .../model/dashboard_migration.gen.ts | 388 +-- .../model/rule_migration.gen.ts | 564 ++-- .../model/vendor/common/qradar.gen.ts | 28 +- .../model/vendor/common/splunk.gen.ts | 4 +- .../model/vendor/dashboards/splunk.gen.ts | 132 +- .../model/vendor/rules/qradar.gen.ts | 84 +- 304 files changed, 16575 insertions(+), 14303 deletions(-) create mode 100644 src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts create mode 100644 src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts diff --git a/src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.gen.ts b/src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.gen.ts index 43ef506e32ca1..62aa6b706635f 100644 --- a/src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.gen.ts +++ b/src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.gen.ts @@ -16,17 +16,21 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const PlatformErrorResponse = lazySchema(() => + z.object({ + statusCode: z.number().int(), + error: z.string(), + message: z.string(), + }) +); export type PlatformErrorResponse = z.infer; -export const PlatformErrorResponse = z.object({ - statusCode: z.number().int(), - error: z.string(), - message: z.string(), -}); +export const SiemErrorResponse = lazySchema(() => + z.object({ + status_code: z.number().int(), + message: z.string(), + }) +); export type SiemErrorResponse = z.infer; -export const SiemErrorResponse = z.object({ - status_code: z.number().int(), - message: z.string(), -}); diff --git a/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.gen.ts b/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.gen.ts index 404af8d249073..09514afb6c9be 100644 --- a/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.gen.ts +++ b/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.gen.ts @@ -16,17 +16,17 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; /** * A string that does not contain only whitespace characters */ +export const NonEmptyString = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type NonEmptyString = z.infer; -export const NonEmptyString = z.string().min(1).superRefine(isNonEmptyString); /** * A universally unique identifier */ +export const UUID = lazySchema(() => z.string().uuid()); export type UUID = z.infer; -export const UUID = z.string().uuid(); diff --git a/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars b/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars index b239ed171cc31..6f0b880284fcf 100644 --- a/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars +++ b/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars @@ -7,7 +7,7 @@ {{> disclaimer}} -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; {{#if useZodHelpers}} import { isValidDateMath, isNonEmptyString, ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; {{/if}} @@ -30,18 +30,18 @@ import { {{#if (isCircularSchema @key)}} export type {{transformSchemaName @key}} = {{> ts_type}}; export type {{transformSchemaName @key}}Input = {{> ts_input_type }}; -export const {{transformSchemaName @key}}: z.ZodType<{{transformSchemaName @key}}, {{transformSchemaName @key}}Input> = {{> zod_schema_item }}; +export const {{transformSchemaName @key}}: z.ZodType<{{transformSchemaName @key}}, {{transformSchemaName @key}}Input> = lazySchema(() => {{> zod_schema_item }} as z.ZodType<{{transformSchemaName @key}}, {{transformSchemaName @key}}Input>); {{else}} {{#if (shouldCastExplicitly this)}} {{!-- We need this temporary type to infer from it below, but in the end we want to export as a casted {{transformSchemaName @key}} type --}} {{!-- error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. --}} -export const {{transformSchemaName @key}}Internal = {{> zod_schema_item}}; +export const {{transformSchemaName @key}}Internal = lazySchema(() => {{> zod_schema_item}}); export type {{transformSchemaName @key}} = z.infer; export const {{transformSchemaName @key}} = {{transformSchemaName @key}}Internal as z.ZodType<{{transformSchemaName @key}}>; {{else}} +export const {{transformSchemaName @key}} = lazySchema(() => {{> zod_schema_item}}); export type {{transformSchemaName @key}} = z.infer; -export const {{transformSchemaName @key}} = {{> zod_schema_item}}; {{/if }} {{/if}} {{#if enum}} @@ -60,8 +60,8 @@ export const {{transformSchemaName @key}}Enum = {{transformSchemaName @key}}.enu * {{{requestQuery.description}}} */ {{/if}} +export const {{operationId}}RequestQuery = lazySchema(() => {{> zod_query_item requestQuery }}); export type {{operationId}}RequestQuery = z.infer; -export const {{operationId}}RequestQuery = {{> zod_query_item requestQuery }}; export type {{operationId}}RequestQueryInput = z.input; {{/if}} @@ -71,8 +71,8 @@ export type {{operationId}}RequestQueryInput = z.input {{> zod_schema_item requestParams }}); export type {{operationId}}RequestParams = z.infer; -export const {{operationId}}RequestParams = {{> zod_schema_item requestParams }}; export type {{operationId}}RequestParamsInput = z.input; {{/if}} @@ -82,8 +82,8 @@ export type {{operationId}}RequestParamsInput = z.input {{> zod_schema_item requestBody }}); export type {{operationId}}RequestBody = z.infer; -export const {{operationId}}RequestBody = {{> zod_schema_item requestBody }}; export type {{operationId}}RequestBodyInput = z.input; {{/if}} @@ -93,7 +93,7 @@ export type {{operationId}}RequestBodyInput = z.input {{> zod_schema_item response }}); export type {{operationId}}Response = z.infer; -export const {{operationId}}Response = {{> zod_schema_item response }}; {{/if}} {{/each}} diff --git a/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars b/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars index a89db93025948..be1727f5bea2b 100644 --- a/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars +++ b/src/platform/packages/shared/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars @@ -23,7 +23,7 @@ {{~#if @first~}} {{> zod_schema_item }} {{~else~}} - .extend({{> zod_schema_item }}) + .merge({{> zod_schema_item }}) {{~/if~}} {{~/each~}} {{~/if~}} diff --git a/src/platform/packages/shared/kbn-zod/v4/index.ts b/src/platform/packages/shared/kbn-zod/v4/index.ts index b30571fea216c..d4ee0a3830384 100644 --- a/src/platform/packages/shared/kbn-zod/v4/index.ts +++ b/src/platform/packages/shared/kbn-zod/v4/index.ts @@ -9,3 +9,4 @@ export * from 'zod/v4'; export { isZod } from './util'; +export { lazySchema } from './lazy_schema'; diff --git a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts new file mode 100644 index 0000000000000..7c3d933e6af63 --- /dev/null +++ b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts @@ -0,0 +1,146 @@ +/* + * 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 { z } from '.'; +import { lazySchema } from './lazy_schema'; + +describe('lazySchema', () => { + it('defers factory invocation until first property access', () => { + const factory = jest.fn(() => z.object({ id: z.string() })); + const schema = lazySchema(factory); + + expect(factory).not.toHaveBeenCalled(); + + schema.parse({ id: 'a' }); + + expect(factory).toHaveBeenCalledTimes(1); + }); + + it('memoizes the materialized schema', () => { + const factory = jest.fn(() => z.object({ id: z.string() })); + const schema = lazySchema(factory); + + schema.parse({ id: 'a' }); + schema.parse({ id: 'b' }); + schema.safeParse({ id: 'c' }); + + expect(factory).toHaveBeenCalledTimes(1); + }); + + it('forwards parse/safeParse and applies validation', () => { + const schema = lazySchema(() => + z.object({ id: z.string(), count: z.number().int().min(0) }).strict() + ); + + expect(schema.parse({ id: 'a', count: 1 })).toEqual({ id: 'a', count: 1 }); + expect(schema.safeParse({ id: 'a', count: -1 }).success).toBe(false); + expect(schema.safeParse({ id: 'a', count: 0, extra: 1 }).success).toBe(false); + }); + + it('supports z.infer', () => { + const User = lazySchema(() => z.object({ id: z.string(), active: z.boolean() })); + type User = z.infer; + const sample: User = { id: 'x', active: true }; + + expect(User.parse(sample)).toEqual(sample); + }); + + it('forwards .extend() on the underlying object schema', () => { + const Base = lazySchema(() => z.object({ id: z.string() })); + const Extended = Base.extend({ name: z.string() }); + + expect(Extended.parse({ id: 'a', name: 'b' })).toEqual({ id: 'a', name: 'b' }); + expect(Extended.safeParse({ id: 'a' }).success).toBe(false); + }); + + it('works as a nested field of another schema', () => { + const Inner = lazySchema(() => z.object({ value: z.number() })); + const Outer = z.object({ inner: Inner, tag: z.string() }); + + expect(Outer.parse({ inner: { value: 1 }, tag: 't' })).toEqual({ + inner: { value: 1 }, + tag: 't', + }); + expect(Outer.safeParse({ inner: { value: 'not-a-number' }, tag: 't' }).success).toBe(false); + }); + + it('supports .optional() / .nullable() chained on the lazy schema', () => { + const Inner = lazySchema(() => z.object({ value: z.number() })); + const Outer = z.object({ inner: Inner.optional().nullable() }); + + expect(Outer.parse({ inner: null }).inner).toBeNull(); + expect(Outer.parse({}).inner).toBeUndefined(); + expect(Outer.parse({ inner: { value: 1 } }).inner).toEqual({ value: 1 }); + }); + + describe('generator-emitted patterns', () => { + // Mirrors the z.discriminatedUnion + `as z.ZodType` pattern the + // openapi-generator emits for schemas whose inferred type exceeds the + // TS serialization limit. + it('supports the Internal + cast pattern', () => { + const FooInternal = lazySchema(() => + z.discriminatedUnion('type', [ + z.object({ type: z.literal('a'), value: z.number() }), + z.object({ type: z.literal('b'), name: z.string() }), + ]) + ); + type Foo = z.infer; + const Foo = FooInternal as z.ZodType; + + expect(Foo.parse({ type: 'a', value: 1 })).toEqual({ type: 'a', value: 1 }); + expect(Foo.parse({ type: 'b', name: 'x' })).toEqual({ type: 'b', name: 'x' }); + expect(Foo.safeParse({ type: 'c' }).success).toBe(false); + }); + + // Mirrors the circular-ref pattern: explicit z.ZodType + // annotation on the exported const, with z.lazy(() => Node) inside. + it('supports circular references via z.lazy inside the factory', () => { + interface Node { + value: number; + next?: Node; + } + const Node: z.ZodType = lazySchema( + () => + z.object({ + value: z.number(), + next: z.lazy(() => Node).optional(), + }) as z.ZodType + ); + + expect(Node.parse({ value: 1, next: { value: 2, next: { value: 3 } } })).toEqual({ + value: 1, + next: { value: 2, next: { value: 3 } }, + }); + expect(Node.safeParse({ value: 1, next: { value: 'bad' } }).success).toBe(false); + }); + + // Mirrors the cross-schema reference pattern where one generated schema + // references another generated schema that is itself lazy. + it('supports a lazy schema referencing another lazy schema', () => { + const Inner = lazySchema(() => z.object({ value: z.number() })); + const Outer = lazySchema(() => z.object({ inner: Inner, tag: z.string() })); + + expect(Outer.parse({ inner: { value: 1 }, tag: 't' })).toEqual({ + inner: { value: 1 }, + tag: 't', + }); + expect(Outer.safeParse({ inner: { value: 'x' }, tag: 't' }).success).toBe(false); + }); + + // Mirrors the .enum export pattern on enum-typed components. + it('exposes .enum via the proxy for enum schemas', () => { + const Color = lazySchema(() => z.enum(['red', 'green', 'blue'])); + const ColorEnum = Color.enum; + + expect(ColorEnum.red).toBe('red'); + expect(Color.parse('green')).toBe('green'); + expect(Color.safeParse('purple').success).toBe(false); + }); + }); +}); diff --git a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts new file mode 100644 index 0000000000000..58b7353e4ef98 --- /dev/null +++ b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts @@ -0,0 +1,45 @@ +/* + * 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 * as z4 from 'zod/v4'; + +/** + * Wraps a Zod schema factory in a Proxy that defers construction of the + * underlying schema until any property (including `.parse`, `.safeParse`, + * `.extend`, `.optional`, etc.) is first accessed. The materialized schema + * is memoized, so subsequent accesses reuse it. + * + * Intended for generated schemas (e.g. from `@kbn/openapi-generator`) where + * many schemas are declared at module-load time but only a subset is used + * at runtime. Unused schemas stay as a single Proxy instance plus a closure, + * keeping baseline heap low. + * + * Caveat: `instanceof z.ZodObject` / `instanceof z.ZodType` on the returned + * value will be `false` because the Proxy target is an empty object. Zod's + * own internals and typical consumers use structural `_zod` / `.def` checks + * rather than `instanceof`, so this is safe in practice. + */ +export function lazySchema(factory: () => T): T { + let instance: T | undefined; + const materialize = (): T => (instance ??= factory()); + + return new Proxy({} as T, { + get(_target, prop) { + const real = materialize() as unknown as Record; + const value = real[prop]; + if (typeof value === 'function') { + return (value as (...args: unknown[]) => unknown).bind(real); + } + return value; + }, + has(_target, prop) { + return prop in (materialize() as unknown as object); + }, + }); +} diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/actions_connector/post_actions_connector_execute_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/actions_connector/post_actions_connector_execute_route.gen.ts index 49ec53cc98ac3..224fa64e69bd7 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/actions_connector/post_actions_connector_execute_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/actions_connector/post_actions_connector_execute_route.gen.ts @@ -14,70 +14,78 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { NonEmptyString, ScreenContext, PromptIds } from '../common_attributes.gen'; import { Replacements } from '../conversations/common_attributes.gen'; +export const ExecuteConnectorRequestQuery = lazySchema(() => + z.object({ + /** + * If true, the response will not include content references. + */ + content_references_disabled: BooleanFromString.optional().default(false), + }) +); export type ExecuteConnectorRequestQuery = z.infer; -export const ExecuteConnectorRequestQuery = z.object({ - /** - * If true, the response will not include content references. - */ - content_references_disabled: BooleanFromString.optional().default(false), -}); export type ExecuteConnectorRequestQueryInput = z.input; +export const ExecuteConnectorRequestParams = lazySchema(() => + z.object({ + /** + * The connector's `id` value. + */ + connectorId: z.string(), + }) +); export type ExecuteConnectorRequestParams = z.infer; -export const ExecuteConnectorRequestParams = z.object({ - /** - * The connector's `id` value. - */ - connectorId: z.string(), -}); export type ExecuteConnectorRequestParamsInput = z.input; +export const ExecuteConnectorRequestBody = lazySchema(() => + z.object({ + conversationId: NonEmptyString.optional(), + message: z.string().optional(), + model: z.string().optional(), + subAction: z.enum(['invokeAI', 'invokeStream']), + actionTypeId: z.string(), + alertsIndexPattern: z.string().optional(), + allow: z.array(z.string()).optional(), + allowReplacement: z.array(z.string()).optional(), + replacements: Replacements, + size: z.number().optional(), + langSmithProject: z.string().optional(), + langSmithApiKey: z.string().optional(), + screenContext: ScreenContext.optional(), + /** + * System prompt, will be appended to default system prompt. Different from conversation system prompt, which is retrieved on the server + */ + promptIds: PromptIds.optional(), + }) +); export type ExecuteConnectorRequestBody = z.infer; -export const ExecuteConnectorRequestBody = z.object({ - conversationId: NonEmptyString.optional(), - message: z.string().optional(), - model: z.string().optional(), - subAction: z.enum(['invokeAI', 'invokeStream']), - actionTypeId: z.string(), - alertsIndexPattern: z.string().optional(), - allow: z.array(z.string()).optional(), - allowReplacement: z.array(z.string()).optional(), - replacements: Replacements, - size: z.number().optional(), - langSmithProject: z.string().optional(), - langSmithApiKey: z.string().optional(), - screenContext: ScreenContext.optional(), - /** - * System prompt, will be appended to default system prompt. Different from conversation system prompt, which is retrieved on the server - */ - promptIds: PromptIds.optional(), -}); export type ExecuteConnectorRequestBodyInput = z.input; +export const ExecuteConnectorResponse = lazySchema(() => + z.object({ + data: z.string(), + connector_id: z.string(), + status: z.string(), + /** + * Trace Data + */ + trace_data: z + .object({ + /** + * Could be any string, not necessarily a UUID + */ + transactionId: z.string().optional(), + /** + * Could be any string, not necessarily a UUID + */ + traceId: z.string().optional(), + }) + .optional(), + }) +); export type ExecuteConnectorResponse = z.infer; -export const ExecuteConnectorResponse = z.object({ - data: z.string(), - connector_id: z.string(), - status: z.string(), - /** - * Trace Data - */ - trace_data: z - .object({ - /** - * Could be any string, not necessarily a UUID - */ - transactionId: z.string().optional(), - /** - * Could be any string, not necessarily a UUID - */ - traceId: z.string().optional(), - }) - .optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/bulk_crud_alert_summary_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/bulk_crud_alert_summary_route.gen.ts index f97a965584dba..296169761c23b 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/bulk_crud_alert_summary_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/bulk_crud_alert_summary_route.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BulkActionBase, @@ -25,99 +25,121 @@ import { } from '../common_attributes.gen'; import { Replacements } from '../conversations/common_attributes.gen'; +export const AlertSummaryBulkActionSkipReason = lazySchema(() => + z.literal('ALERT_SUMMARY_NOT_MODIFIED') +); export type AlertSummaryBulkActionSkipReason = z.infer; -export const AlertSummaryBulkActionSkipReason = z.literal('ALERT_SUMMARY_NOT_MODIFIED'); +export const AlertSummaryBulkActionSkipResult = lazySchema(() => + z.object({ + id: z.string(), + alertId: z.string().optional(), + skip_reason: AlertSummaryBulkActionSkipReason, + }) +); export type AlertSummaryBulkActionSkipResult = z.infer; -export const AlertSummaryBulkActionSkipResult = z.object({ - id: z.string(), - alertId: z.string().optional(), - skip_reason: AlertSummaryBulkActionSkipReason, -}); +export const AlertSummaryDetailsInError = lazySchema(() => + z.object({ + alertId: z.string().optional(), + id: z.string(), + }) +); export type AlertSummaryDetailsInError = z.infer; -export const AlertSummaryDetailsInError = z.object({ - alertId: z.string().optional(), - id: z.string(), -}); +export const NormalizedAlertSummaryError = lazySchema(() => + z.object({ + message: z.string(), + status_code: z.number().int(), + err_code: z.string().optional(), + alert_summaries: z.array(AlertSummaryDetailsInError), + }) +); export type NormalizedAlertSummaryError = z.infer; -export const NormalizedAlertSummaryError = z.object({ - message: z.string(), - status_code: z.number().int(), - err_code: z.string().optional(), - alert_summaries: z.array(AlertSummaryDetailsInError), -}); +export const AlertSummaryResponse = lazySchema(() => + z.object({ + id: NonEmptyString, + alertId: NonEmptyString, + timestamp: NonEmptyTimestamp.optional(), + summary: z.string(), + recommendedActions: z.string().optional(), + replacements: Replacements, + updatedAt: z.string().optional(), + updatedBy: z.string().optional(), + createdAt: z.string().optional(), + createdBy: z.string().optional(), + users: z.array(User).optional(), + /** + * Kibana space + */ + namespace: z.string().optional(), + }) +); export type AlertSummaryResponse = z.infer; -export const AlertSummaryResponse = z.object({ - id: NonEmptyString, - alertId: NonEmptyString, - timestamp: NonEmptyTimestamp.optional(), - summary: z.string(), - recommendedActions: z.string().optional(), - replacements: Replacements, - updatedAt: z.string().optional(), - updatedBy: z.string().optional(), - createdAt: z.string().optional(), - createdBy: z.string().optional(), - users: z.array(User).optional(), - /** - * Kibana space - */ - namespace: z.string().optional(), -}); +export const AlertSummaryBulkCrudActionResults = lazySchema(() => + z.object({ + updated: z.array(AlertSummaryResponse), + created: z.array(AlertSummaryResponse), + deleted: z.array(z.string()), + skipped: z.array(AlertSummaryBulkActionSkipResult), + }) +); export type AlertSummaryBulkCrudActionResults = z.infer; -export const AlertSummaryBulkCrudActionResults = z.object({ - updated: z.array(AlertSummaryResponse), - created: z.array(AlertSummaryResponse), - deleted: z.array(z.string()), - skipped: z.array(AlertSummaryBulkActionSkipResult), -}); +export const AlertSummaryBulkCrudActionResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + status_code: z.number().int().optional(), + message: z.string().optional(), + alert_summaries_count: z.number().int().optional(), + attributes: z.object({ + results: AlertSummaryBulkCrudActionResults, + summary: BulkCrudActionSummary, + errors: z.array(NormalizedAlertSummaryError).optional(), + }), + }) +); export type AlertSummaryBulkCrudActionResponse = z.infer; -export const AlertSummaryBulkCrudActionResponse = z.object({ - success: z.boolean().optional(), - status_code: z.number().int().optional(), - message: z.string().optional(), - alert_summaries_count: z.number().int().optional(), - attributes: z.object({ - results: AlertSummaryBulkCrudActionResults, - summary: BulkCrudActionSummary, - errors: z.array(NormalizedAlertSummaryError).optional(), - }), -}); +export const AlertSummaryCreateProps = lazySchema(() => + z.object({ + alertId: z.string(), + summary: z.string(), + recommendedActions: z.string().optional(), + replacements: Replacements, + }) +); export type AlertSummaryCreateProps = z.infer; -export const AlertSummaryCreateProps = z.object({ - alertId: z.string(), - summary: z.string(), - recommendedActions: z.string().optional(), - replacements: Replacements, -}); +export const AlertSummaryUpdateProps = lazySchema(() => + z.object({ + id: z.string(), + summary: z.string().optional(), + recommendedActions: z.string().optional(), + replacements: Replacements.optional(), + }) +); export type AlertSummaryUpdateProps = z.infer; -export const AlertSummaryUpdateProps = z.object({ - id: z.string(), - summary: z.string().optional(), - recommendedActions: z.string().optional(), - replacements: Replacements.optional(), -}); +export const PerformAlertSummaryBulkActionRequestBody = lazySchema(() => + z.object({ + delete: BulkActionBase.optional(), + create: z.array(AlertSummaryCreateProps).optional(), + update: z.array(AlertSummaryUpdateProps).optional(), + }) +); export type PerformAlertSummaryBulkActionRequestBody = z.infer< typeof PerformAlertSummaryBulkActionRequestBody >; -export const PerformAlertSummaryBulkActionRequestBody = z.object({ - delete: BulkActionBase.optional(), - create: z.array(AlertSummaryCreateProps).optional(), - update: z.array(AlertSummaryUpdateProps).optional(), -}); export type PerformAlertSummaryBulkActionRequestBodyInput = z.input< typeof PerformAlertSummaryBulkActionRequestBody >; +export const PerformAlertSummaryBulkActionResponse = lazySchema( + () => AlertSummaryBulkCrudActionResponse +); export type PerformAlertSummaryBulkActionResponse = z.infer< typeof PerformAlertSummaryBulkActionResponse >; -export const PerformAlertSummaryBulkActionResponse = AlertSummaryBulkCrudActionResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/find_alert_summary_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/find_alert_summary_route.gen.ts index 0537b150f454b..037ed1240524f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/find_alert_summary_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/alert_summary/find_alert_summary_route.gen.ts @@ -14,55 +14,59 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../common_attributes.gen'; import { AlertSummaryResponse } from './bulk_crud_alert_summary_route.gen'; +export const FindAlertSummarySortField = lazySchema(() => z.enum(['created_at', 'updated_at'])); export type FindAlertSummarySortField = z.infer; -export const FindAlertSummarySortField = z.enum(['created_at', 'updated_at']); export type FindAlertSummarySortFieldEnum = typeof FindAlertSummarySortField.enum; export const FindAlertSummarySortFieldEnum = FindAlertSummarySortField.enum; +export const FindAlertSummaryRequestQuery = lazySchema(() => + z.object({ + fields: ArrayFromString(z.string()).optional(), + /** + * Search query + */ + filter: z.string().optional(), + /** + * Connector id used for prompt lookup + */ + connector_id: z.string(), + /** + * Field to sort by + */ + sort_field: FindAlertSummarySortField.optional(), + /** + * Sort order + */ + sort_order: SortOrder.optional(), + /** + * Page number + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * Alert Summary per page + */ + per_page: z.coerce.number().int().min(0).optional().default(20), + }) +); export type FindAlertSummaryRequestQuery = z.infer; -export const FindAlertSummaryRequestQuery = z.object({ - fields: ArrayFromString(z.string()).optional(), - /** - * Search query - */ - filter: z.string().optional(), - /** - * Connector id used for prompt lookup - */ - connector_id: z.string(), - /** - * Field to sort by - */ - sort_field: FindAlertSummarySortField.optional(), - /** - * Sort order - */ - sort_order: SortOrder.optional(), - /** - * Page number - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * Alert Summary per page - */ - per_page: z.coerce.number().int().min(0).optional().default(20), -}); export type FindAlertSummaryRequestQueryInput = z.input; +export const FindAlertSummaryResponse = lazySchema(() => + z.object({ + /** + * Prompt to use to generate new alert summary + */ + prompt: z.string(), + page: z.number().int(), + perPage: z.number().int(), + total: z.number().int(), + data: z.array(AlertSummaryResponse), + }) +); export type FindAlertSummaryResponse = z.infer; -export const FindAlertSummaryResponse = z.object({ - /** - * Prompt to use to generate new alert summary - */ - prompt: z.string(), - page: z.number().int(), - perPage: z.number().int(), - total: z.number().int(), - data: z.array(AlertSummaryResponse), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen.ts index 2064d57b9b6a4..36f280da98123 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BulkActionBase, @@ -26,211 +26,230 @@ import { /** * Reason why the anonymization field was not modified. */ +export const AnonymizationFieldsBulkActionSkipReason = lazySchema(() => + z.literal('ANONYMIZATION_FIELD_NOT_MODIFIED') +); export type AnonymizationFieldsBulkActionSkipReason = z.infer< typeof AnonymizationFieldsBulkActionSkipReason >; -export const AnonymizationFieldsBulkActionSkipReason = z.literal( - 'ANONYMIZATION_FIELD_NOT_MODIFIED' -); +export const AnonymizationFieldsBulkActionSkipResult = lazySchema(() => + z.object({ + /** + * The ID of the anonymization field that was not modified. + */ + id: z.string(), + /** + * Name of the anonymization field that was not modified. + */ + name: z.string().optional(), + /** + * Reason why the anonymization field was not modified. + */ + skip_reason: AnonymizationFieldsBulkActionSkipReason, + }) +); export type AnonymizationFieldsBulkActionSkipResult = z.infer< typeof AnonymizationFieldsBulkActionSkipResult >; -export const AnonymizationFieldsBulkActionSkipResult = z.object({ - /** - * The ID of the anonymization field that was not modified. - */ - id: z.string(), - /** - * Name of the anonymization field that was not modified. - */ - name: z.string().optional(), - /** - * Reason why the anonymization field was not modified. - */ - skip_reason: AnonymizationFieldsBulkActionSkipReason, -}); +export const AnonymizationFieldDetailsInError = lazySchema(() => + z.object({ + /** + * The ID of the anonymization field. + */ + id: z.string(), + /** + * Name of the anonymization field. + */ + name: z.string().optional(), + }) +); export type AnonymizationFieldDetailsInError = z.infer; -export const AnonymizationFieldDetailsInError = z.object({ - /** - * The ID of the anonymization field. - */ - id: z.string(), - /** - * Name of the anonymization field. - */ - name: z.string().optional(), -}); +export const NormalizedAnonymizationFieldError = lazySchema(() => + z.object({ + /** + * Error message. + */ + message: z.string(), + /** + * Status code of the response. + */ + status_code: z.number().int(), + /** + * Error code indicating the type of failure. + */ + err_code: z.string().optional(), + /** + * Array of anonymization fields that caused the error. + */ + anonymization_fields: z.array(AnonymizationFieldDetailsInError), + }) +); export type NormalizedAnonymizationFieldError = z.infer; -export const NormalizedAnonymizationFieldError = z.object({ - /** - * Error message. - */ - message: z.string(), - /** - * Status code of the response. - */ - status_code: z.number().int(), - /** - * Error code indicating the type of failure. - */ - err_code: z.string().optional(), - /** - * Array of anonymization fields that caused the error. - */ - anonymization_fields: z.array(AnonymizationFieldDetailsInError), -}); +export const AnonymizationFieldResponse = lazySchema(() => + z.object({ + /** + * The ID of the anonymization field. + */ + id: NonEmptyString, + /** + * Timestamp when the anonymization field was initially created. + */ + timestamp: NonEmptyTimestamp.optional(), + /** + * Name of the anonymization field. + */ + field: z.string(), + /** + * Whether this field is allowed to be sent to the model. + */ + allowed: z.boolean().optional(), + /** + * Whether this field should be anonymized. + */ + anonymized: z.boolean().optional(), + /** + * Timestamp of the last update. + */ + updatedAt: z.string().optional(), + /** + * Username of the person who last updated the field. + */ + updatedBy: z.string().optional(), + /** + * Timestamp of when the anonymization field was created. + */ + createdAt: z.string().optional(), + /** + * Username of the person who created the anonymization field. + */ + createdBy: z.string().optional(), + /** + * Kibana space in which this anonymization field exists. + */ + namespace: z.string().optional(), + }) +); export type AnonymizationFieldResponse = z.infer; -export const AnonymizationFieldResponse = z.object({ - /** - * The ID of the anonymization field. - */ - id: NonEmptyString, - /** - * Timestamp when the anonymization field was initially created. - */ - timestamp: NonEmptyTimestamp.optional(), - /** - * Name of the anonymization field. - */ - field: z.string(), - /** - * Whether this field is allowed to be sent to the model. - */ - allowed: z.boolean().optional(), - /** - * Whether this field should be anonymized. - */ - anonymized: z.boolean().optional(), - /** - * Timestamp of the last update. - */ - updatedAt: z.string().optional(), - /** - * Username of the person who last updated the field. - */ - updatedBy: z.string().optional(), - /** - * Timestamp of when the anonymization field was created. - */ - createdAt: z.string().optional(), - /** - * Username of the person who created the anonymization field. - */ - createdBy: z.string().optional(), - /** - * Kibana space in which this anonymization field exists. - */ - namespace: z.string().optional(), -}); +export const AnonymizationFieldsBulkCrudActionResults = lazySchema(() => + z.object({ + /** + * List of anonymization fields successfully updated. + */ + updated: z.array(AnonymizationFieldResponse), + /** + * List of anonymization fields successfully created. + */ + created: z.array(AnonymizationFieldResponse), + deleted: z.array(z.string()), + /** + * List of anonymization fields that were skipped during the operation. + */ + skipped: z.array(AnonymizationFieldsBulkActionSkipResult), + }) +); export type AnonymizationFieldsBulkCrudActionResults = z.infer< typeof AnonymizationFieldsBulkCrudActionResults >; -export const AnonymizationFieldsBulkCrudActionResults = z.object({ - /** - * List of anonymization fields successfully updated. - */ - updated: z.array(AnonymizationFieldResponse), - /** - * List of anonymization fields successfully created. - */ - created: z.array(AnonymizationFieldResponse), - deleted: z.array(z.string()), - /** - * List of anonymization fields that were skipped during the operation. - */ - skipped: z.array(AnonymizationFieldsBulkActionSkipResult), -}); +export const AnonymizationFieldsBulkCrudActionResponse = lazySchema(() => + z.object({ + /** + * Indicates if the bulk action was successful. + */ + success: z.boolean().optional(), + /** + * HTTP status code returned. + */ + status_code: z.number().int().optional(), + /** + * Message providing information about the bulk action result. + */ + message: z.string().optional(), + /** + * Total number of anonymization fields processed. + */ + anonymization_fields_count: z.number().int().optional(), + attributes: z.object({ + results: AnonymizationFieldsBulkCrudActionResults, + summary: BulkCrudActionSummary, + /** + * List of errors that occurred during the bulk operation. + */ + errors: z.array(NormalizedAnonymizationFieldError).optional(), + }), + }) +); export type AnonymizationFieldsBulkCrudActionResponse = z.infer< typeof AnonymizationFieldsBulkCrudActionResponse >; -export const AnonymizationFieldsBulkCrudActionResponse = z.object({ - /** - * Indicates if the bulk action was successful. - */ - success: z.boolean().optional(), - /** - * HTTP status code returned. - */ - status_code: z.number().int().optional(), - /** - * Message providing information about the bulk action result. - */ - message: z.string().optional(), - /** - * Total number of anonymization fields processed. - */ - anonymization_fields_count: z.number().int().optional(), - attributes: z.object({ - results: AnonymizationFieldsBulkCrudActionResults, - summary: BulkCrudActionSummary, - /** - * List of errors that occurred during the bulk operation. - */ - errors: z.array(NormalizedAnonymizationFieldError).optional(), - }), -}); +export const AnonymizationFieldCreateProps = lazySchema(() => + z.object({ + /** + * Name of the anonymization field to create. + */ + field: z.string(), + /** + * Whether this field is allowed to be sent to the model. + */ + allowed: z.boolean().optional(), + /** + * Whether this field should be anonymized. + */ + anonymized: z.boolean().optional(), + }) +); export type AnonymizationFieldCreateProps = z.infer; -export const AnonymizationFieldCreateProps = z.object({ - /** - * Name of the anonymization field to create. - */ - field: z.string(), - /** - * Whether this field is allowed to be sent to the model. - */ - allowed: z.boolean().optional(), - /** - * Whether this field should be anonymized. - */ - anonymized: z.boolean().optional(), -}); +export const AnonymizationFieldUpdateProps = lazySchema(() => + z.object({ + /** + * The ID of the anonymization field to update. + */ + id: z.string(), + /** + * Whether this field is allowed to be sent to the model. + */ + allowed: z.boolean().optional(), + /** + * Whether this field should be anonymized. + */ + anonymized: z.boolean().optional(), + }) +); export type AnonymizationFieldUpdateProps = z.infer; -export const AnonymizationFieldUpdateProps = z.object({ - /** - * The ID of the anonymization field to update. - */ - id: z.string(), - /** - * Whether this field is allowed to be sent to the model. - */ - allowed: z.boolean().optional(), - /** - * Whether this field should be anonymized. - */ - anonymized: z.boolean().optional(), -}); +export const PerformAnonymizationFieldsBulkActionRequestBody = lazySchema(() => + z.object({ + /** + * Object containing the query to filter anonymization fields and/or an array of anonymization field IDs to delete. + */ + delete: BulkActionBase.optional(), + /** + * Array of anonymization fields to create. + */ + create: z.array(AnonymizationFieldCreateProps).optional(), + /** + * Array of anonymization fields to update. + */ + update: z.array(AnonymizationFieldUpdateProps).optional(), + }) +); export type PerformAnonymizationFieldsBulkActionRequestBody = z.infer< typeof PerformAnonymizationFieldsBulkActionRequestBody >; -export const PerformAnonymizationFieldsBulkActionRequestBody = z.object({ - /** - * Object containing the query to filter anonymization fields and/or an array of anonymization field IDs to delete. - */ - delete: BulkActionBase.optional(), - /** - * Array of anonymization fields to create. - */ - create: z.array(AnonymizationFieldCreateProps).optional(), - /** - * Array of anonymization fields to update. - */ - update: z.array(AnonymizationFieldUpdateProps).optional(), -}); export type PerformAnonymizationFieldsBulkActionRequestBodyInput = z.input< typeof PerformAnonymizationFieldsBulkActionRequestBody >; +export const PerformAnonymizationFieldsBulkActionResponse = lazySchema( + () => AnonymizationFieldsBulkCrudActionResponse +); export type PerformAnonymizationFieldsBulkActionResponse = z.infer< typeof PerformAnonymizationFieldsBulkActionResponse >; -export const PerformAnonymizationFieldsBulkActionResponse = - AnonymizationFieldsBulkCrudActionResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/find_anonymization_fields_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/find_anonymization_fields_route.gen.ts index f0bb818ea2dd7..3c6a1ac9ef8b2 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/find_anonymization_fields_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/anonymization_fields/find_anonymization_fields_route.gen.ts @@ -14,92 +14,92 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../common_attributes.gen'; import { AnonymizationFieldResponse } from './bulk_crud_anonymization_fields_route.gen'; +export const FindAnonymizationFieldsSortField = lazySchema(() => + z.enum(['created_at', 'anonymized', 'allowed', 'field', 'updated_at']) +); export type FindAnonymizationFieldsSortField = z.infer; -export const FindAnonymizationFieldsSortField = z.enum([ - 'created_at', - 'anonymized', - 'allowed', - 'field', - 'updated_at', -]); export type FindAnonymizationFieldsSortFieldEnum = typeof FindAnonymizationFieldsSortField.enum; export const FindAnonymizationFieldsSortFieldEnum = FindAnonymizationFieldsSortField.enum; +export const FindAnonymizationFieldsRequestQuery = lazySchema(() => + z.object({ + /** + * Fields to return + */ + fields: ArrayFromString(z.string()).optional(), + /** + * Search query + */ + filter: z.string().optional(), + /** + * Field to sort by + */ + sort_field: FindAnonymizationFieldsSortField.optional(), + /** + * Sort order + */ + sort_order: SortOrder.optional(), + /** + * Page number + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * AnonymizationFields per page + */ + per_page: z.coerce.number().int().min(0).optional().default(20), + /** + * If true, additionally fetch all anonymization fields, otherwise fetch only the provided page + */ + all_data: BooleanFromString.optional(), + }) +); export type FindAnonymizationFieldsRequestQuery = z.infer< typeof FindAnonymizationFieldsRequestQuery >; -export const FindAnonymizationFieldsRequestQuery = z.object({ - /** - * Fields to return - */ - fields: ArrayFromString(z.string()).optional(), - /** - * Search query - */ - filter: z.string().optional(), - /** - * Field to sort by - */ - sort_field: FindAnonymizationFieldsSortField.optional(), - /** - * Sort order - */ - sort_order: SortOrder.optional(), - /** - * Page number - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * AnonymizationFields per page - */ - per_page: z.coerce.number().int().min(0).optional().default(20), - /** - * If true, additionally fetch all anonymization fields, otherwise fetch only the provided page - */ - all_data: BooleanFromString.optional(), -}); export type FindAnonymizationFieldsRequestQueryInput = z.input< typeof FindAnonymizationFieldsRequestQuery >; +export const FindAnonymizationFieldsResponse = lazySchema(() => + z.object({ + page: z.number().int(), + perPage: z.number().int(), + total: z.number().int(), + data: z.array(AnonymizationFieldResponse), + all: z.array(AnonymizationFieldResponse).optional(), + aggregations: z + .object({ + field_status: z + .object({ + buckets: z + .object({ + anonymized: z + .object({ + doc_count: z.number().int().optional().default(0), + }) + .optional(), + allowed: z + .object({ + doc_count: z.number().int().optional().default(0), + }) + .optional(), + denied: z + .object({ + doc_count: z.number().int().optional().default(0), + }) + .optional(), + }) + .optional(), + }) + .optional(), + }) + .optional(), + }) +); export type FindAnonymizationFieldsResponse = z.infer; -export const FindAnonymizationFieldsResponse = z.object({ - page: z.number().int(), - perPage: z.number().int(), - total: z.number().int(), - data: z.array(AnonymizationFieldResponse), - all: z.array(AnonymizationFieldResponse).optional(), - aggregations: z - .object({ - field_status: z - .object({ - buckets: z - .object({ - anonymized: z - .object({ - doc_count: z.number().int().optional().default(0), - }) - .optional(), - allowed: z - .object({ - doc_count: z.number().int().optional().default(0), - }) - .optional(), - denied: z - .object({ - doc_count: z.number().int().optional().default(0), - }) - .optional(), - }) - .optional(), - }) - .optional(), - }) - .optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_alert.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_alert.gen.ts index 3d3b517e80657..3bb96542459aa 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_alert.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_alert.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Replacements } from '../conversations/common_attributes.gen'; import { NonEmptyTimestamp, User } from '../common_attributes.gen'; @@ -22,110 +22,112 @@ import { NonEmptyTimestamp, User } from '../common_attributes.gen'; /** * An attack discovery that's also an alert */ +export const AttackDiscoveryAlert = lazySchema(() => + z.object({ + /** + * The alert IDs that the attack discovery is based on + */ + alertIds: z.array(z.string()), + /** + * The optional kibana.alert.rule.uuid of the rule that generated this attack discovery (not applicable to ad hock runs) + */ + alertRuleUuid: z.string().optional(), + /** + * The optional kibana.alert.workflow_status of this attack discovery + */ + alertWorkflowStatus: z.string().optional(), + /** + * The ID of the connector that generated the attack discovery + */ + connectorId: z.string(), + /** + * The (human readable) name of the connector that generated the attack discovery + */ + connectorName: z.string(), + /** + * The optional time the attack discovery alert was created + */ + alertStart: z.string().optional(), + /** + * The optional time the attack discovery alert was last updated + */ + alertUpdatedAt: z.string().optional(), + /** + * The optional id of the user who last updated the attack discovery alert + */ + alertUpdatedByUserId: z.string().optional(), + /** + * The optional username of the user who updated the attack discovery alert + */ + alertUpdatedByUserName: z.string().optional(), + /** + * The optional time the attack discovery alert workflow status was last updated + */ + alertWorkflowStatusUpdatedAt: z.string().optional(), + /** + * Details of the attack with bulleted markdown that always uses special syntax for field names and values from the source data. + */ + detailsMarkdown: z.string(), + /** + * An optional, short (no more than a sentence) summary of the attack discovery featuring only the host.name and user.name fields (when they are applicable), using the same syntax + */ + entitySummaryMarkdown: z.string().optional(), + /** + * The generation ID of the run that created the attack discovery + */ + generationUuid: z.string(), + /** + * The unique ID of the attack discovery + */ + id: z.string(), + /** + * An optional array of MITRE ATT&CK tactic for the attack discovery + */ + mitreAttackTactics: z.array(z.string()).optional(), + /** + * Key-value pairs that are used to replace placeholders in the markdown fields + */ + replacements: Replacements.optional(), + /** + * The optional, (but typically populated after generation) risk score of the alert + */ + riskScore: z.number().int().optional(), + /** + * A markdown summary of attack discovery, using the same syntax + */ + summaryMarkdown: z.string(), + /** + * The time the attack discovery was generated + */ + timestamp: NonEmptyTimestamp, + /** + * A title for the attack discovery, in plain text + */ + title: z.string(), + /** + * The optional id of the user who generated the attack discovery + */ + userId: z.string().optional(), + /** + * The optional username of the user who generated the attack discovery, (not applicable to attack discoveries generated by rules) + */ + userName: z.string().optional(), + /** + * The optional array of users who may view the attack discovery. When empty, (or not present), all users may view the attack discovery. + */ + users: z.array(User).optional(), + /** + * The optional array of user-IDs who have been assigned the attack + */ + assignees: z.array(z.string()).optional(), + /** + * The optional array of tags assigned the attack + */ + tags: z.array(z.string()).optional(), + /** + * The concrete Elasticsearch index where this attack discovery is stored + */ + index: z.string().optional(), + }) +); export type AttackDiscoveryAlert = z.infer; -export const AttackDiscoveryAlert = z.object({ - /** - * The alert IDs that the attack discovery is based on - */ - alertIds: z.array(z.string()), - /** - * The optional kibana.alert.rule.uuid of the rule that generated this attack discovery (not applicable to ad hock runs) - */ - alertRuleUuid: z.string().optional(), - /** - * The optional kibana.alert.workflow_status of this attack discovery - */ - alertWorkflowStatus: z.string().optional(), - /** - * The ID of the connector that generated the attack discovery - */ - connectorId: z.string(), - /** - * The (human readable) name of the connector that generated the attack discovery - */ - connectorName: z.string(), - /** - * The optional time the attack discovery alert was created - */ - alertStart: z.string().optional(), - /** - * The optional time the attack discovery alert was last updated - */ - alertUpdatedAt: z.string().optional(), - /** - * The optional id of the user who last updated the attack discovery alert - */ - alertUpdatedByUserId: z.string().optional(), - /** - * The optional username of the user who updated the attack discovery alert - */ - alertUpdatedByUserName: z.string().optional(), - /** - * The optional time the attack discovery alert workflow status was last updated - */ - alertWorkflowStatusUpdatedAt: z.string().optional(), - /** - * Details of the attack with bulleted markdown that always uses special syntax for field names and values from the source data. - */ - detailsMarkdown: z.string(), - /** - * An optional, short (no more than a sentence) summary of the attack discovery featuring only the host.name and user.name fields (when they are applicable), using the same syntax - */ - entitySummaryMarkdown: z.string().optional(), - /** - * The generation ID of the run that created the attack discovery - */ - generationUuid: z.string(), - /** - * The unique ID of the attack discovery - */ - id: z.string(), - /** - * An optional array of MITRE ATT&CK tactic for the attack discovery - */ - mitreAttackTactics: z.array(z.string()).optional(), - /** - * Key-value pairs that are used to replace placeholders in the markdown fields - */ - replacements: Replacements.optional(), - /** - * The optional, (but typically populated after generation) risk score of the alert - */ - riskScore: z.number().int().optional(), - /** - * A markdown summary of attack discovery, using the same syntax - */ - summaryMarkdown: z.string(), - /** - * The time the attack discovery was generated - */ - timestamp: NonEmptyTimestamp, - /** - * A title for the attack discovery, in plain text - */ - title: z.string(), - /** - * The optional id of the user who generated the attack discovery - */ - userId: z.string().optional(), - /** - * The optional username of the user who generated the attack discovery, (not applicable to attack discoveries generated by rules) - */ - userName: z.string().optional(), - /** - * The optional array of users who may view the attack discovery. When empty, (or not present), all users may view the attack discovery. - */ - users: z.array(User).optional(), - /** - * The optional array of user-IDs who have been assigned the attack - */ - assignees: z.array(z.string()).optional(), - /** - * The optional array of tags assigned the attack - */ - tags: z.array(z.string()).optional(), - /** - * The concrete Elasticsearch index where this attack discovery is stored - */ - index: z.string().optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_api_alert.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_api_alert.gen.ts index 7f6b5ef34b0d8..cfe658f4f145b 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_api_alert.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_api_alert.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Replacements } from '../conversations/common_attributes.gen'; import { NonEmptyTimestamp, User } from '../common_attributes.gen'; @@ -22,110 +22,112 @@ import { NonEmptyTimestamp, User } from '../common_attributes.gen'; /** * An attack discovery that's also an alert (Public API with snake_case) */ +export const AttackDiscoveryApiAlert = lazySchema(() => + z.object({ + /** + * The alert IDs that the attack discovery is based on + */ + alert_ids: z.array(z.string()), + /** + * The optional kibana.alert.rule.uuid of the rule that generated this attack discovery (not applicable to ad hock runs) + */ + alert_rule_uuid: z.string().optional(), + /** + * The optional kibana.alert.workflow_status of this attack discovery + */ + alert_workflow_status: z.string().optional(), + /** + * The ID of the connector that generated the attack discovery + */ + connector_id: z.string(), + /** + * The (human readable) name of the connector that generated the attack discovery + */ + connector_name: z.string(), + /** + * The optional time the attack discovery alert was created + */ + alert_start: z.string().optional(), + /** + * The optional time the attack discovery alert was last updated + */ + alert_updated_at: z.string().optional(), + /** + * The optional id of the user who last updated the attack discovery alert + */ + alert_updated_by_user_id: z.string().optional(), + /** + * The optional username of the user who updated the attack discovery alert + */ + alert_updated_by_user_name: z.string().optional(), + /** + * The optional time the attack discovery alert workflow status was last updated + */ + alert_workflow_status_updated_at: z.string().optional(), + /** + * Details of the attack with bulleted markdown that always uses special syntax for field names and values from the source data. + */ + details_markdown: z.string(), + /** + * An optional, short (no more than a sentence) summary of the attack discovery featuring only the host.name and user.name fields (when they are applicable), using the same syntax + */ + entity_summary_markdown: z.string().optional(), + /** + * The generation ID of the run that created the attack discovery + */ + generation_uuid: z.string(), + /** + * The unique ID of the attack discovery + */ + id: z.string(), + /** + * An optional array of MITRE ATT&CK tactic for the attack discovery + */ + mitre_attack_tactics: z.array(z.string()).optional(), + /** + * Key-value pairs that are used to replace placeholders in the markdown fields + */ + replacements: Replacements.optional(), + /** + * The optional, (but typically populated after generation) risk score of the alert + */ + risk_score: z.number().int().optional(), + /** + * A markdown summary of attack discovery, using the same syntax + */ + summary_markdown: z.string(), + /** + * The time the attack discovery was generated + */ + timestamp: NonEmptyTimestamp, + /** + * A title for the attack discovery, in plain text + */ + title: z.string(), + /** + * The optional id of the user who generated the attack discovery + */ + user_id: z.string().optional(), + /** + * The optional username of the user who generated the attack discovery, (not applicable to attack discoveries generated by rules) + */ + user_name: z.string().optional(), + /** + * The optional array of users who may view the attack discovery. When empty, (or not present), all users may view the attack discovery. + */ + users: z.array(User).optional(), + /** + * The optional array of user-IDs who have been assigned the attack + */ + assignees: z.array(z.string()).optional(), + /** + * The optional array of tags assigned the attack + */ + tags: z.array(z.string()).optional(), + /** + * The concrete Elasticsearch index where this attack discovery is stored + */ + index: z.string().optional(), + }) +); export type AttackDiscoveryApiAlert = z.infer; -export const AttackDiscoveryApiAlert = z.object({ - /** - * The alert IDs that the attack discovery is based on - */ - alert_ids: z.array(z.string()), - /** - * The optional kibana.alert.rule.uuid of the rule that generated this attack discovery (not applicable to ad hock runs) - */ - alert_rule_uuid: z.string().optional(), - /** - * The optional kibana.alert.workflow_status of this attack discovery - */ - alert_workflow_status: z.string().optional(), - /** - * The ID of the connector that generated the attack discovery - */ - connector_id: z.string(), - /** - * The (human readable) name of the connector that generated the attack discovery - */ - connector_name: z.string(), - /** - * The optional time the attack discovery alert was created - */ - alert_start: z.string().optional(), - /** - * The optional time the attack discovery alert was last updated - */ - alert_updated_at: z.string().optional(), - /** - * The optional id of the user who last updated the attack discovery alert - */ - alert_updated_by_user_id: z.string().optional(), - /** - * The optional username of the user who updated the attack discovery alert - */ - alert_updated_by_user_name: z.string().optional(), - /** - * The optional time the attack discovery alert workflow status was last updated - */ - alert_workflow_status_updated_at: z.string().optional(), - /** - * Details of the attack with bulleted markdown that always uses special syntax for field names and values from the source data. - */ - details_markdown: z.string(), - /** - * An optional, short (no more than a sentence) summary of the attack discovery featuring only the host.name and user.name fields (when they are applicable), using the same syntax - */ - entity_summary_markdown: z.string().optional(), - /** - * The generation ID of the run that created the attack discovery - */ - generation_uuid: z.string(), - /** - * The unique ID of the attack discovery - */ - id: z.string(), - /** - * An optional array of MITRE ATT&CK tactic for the attack discovery - */ - mitre_attack_tactics: z.array(z.string()).optional(), - /** - * Key-value pairs that are used to replace placeholders in the markdown fields - */ - replacements: Replacements.optional(), - /** - * The optional, (but typically populated after generation) risk score of the alert - */ - risk_score: z.number().int().optional(), - /** - * A markdown summary of attack discovery, using the same syntax - */ - summary_markdown: z.string(), - /** - * The time the attack discovery was generated - */ - timestamp: NonEmptyTimestamp, - /** - * A title for the attack discovery, in plain text - */ - title: z.string(), - /** - * The optional id of the user who generated the attack discovery - */ - user_id: z.string().optional(), - /** - * The optional username of the user who generated the attack discovery, (not applicable to attack discoveries generated by rules) - */ - user_name: z.string().optional(), - /** - * The optional array of users who may view the attack discovery. When empty, (or not present), all users may view the attack discovery. - */ - users: z.array(User).optional(), - /** - * The optional array of user-IDs who have been assigned the attack - */ - assignees: z.array(z.string()).optional(), - /** - * The optional array of tags assigned the attack - */ - tags: z.array(z.string()).optional(), - /** - * The concrete Elasticsearch index where this attack discovery is stored - */ - index: z.string().optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_find_internal_response.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_find_internal_response.gen.ts index c9f0da2b43a4b..ac287d67775b3 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_find_internal_response.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/attack_discovery_find_internal_response.gen.ts @@ -14,19 +14,21 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AttackDiscoveryAlert } from './attack_discovery_alert.gen'; +export const AttackDiscoveryFindInternalResponse = lazySchema(() => + z.object({ + connector_names: z.array(z.string()), + data: z.array(AttackDiscoveryAlert), + page: z.number().int(), + per_page: z.number().int().optional(), + total: z.number().int(), + unique_alert_ids_count: z.number().int(), + unique_alert_ids: z.array(z.string()).optional(), + }) +); export type AttackDiscoveryFindInternalResponse = z.infer< typeof AttackDiscoveryFindInternalResponse >; -export const AttackDiscoveryFindInternalResponse = z.object({ - connector_names: z.array(z.string()), - data: z.array(AttackDiscoveryAlert), - page: z.number().int(), - per_page: z.number().int().optional(), - total: z.number().int(), - unique_alert_ids_count: z.number().int(), - unique_alert_ids: z.array(z.string()).optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/common_attributes.gen.ts index 644403c2d55f7..8f70d6dbef8ff 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/common_attributes.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyTimestamp, NonEmptyString, User } from '../common_attributes.gen'; import { Replacements, ApiConfig } from '../conversations/common_attributes.gen'; @@ -23,295 +23,311 @@ import { AnonymizationFieldResponse } from '../anonymization_fields/bulk_crud_an /** * An attack discovery generated from one or more alerts */ +export const AttackDiscovery = lazySchema(() => + z.object({ + /** + * The alert IDs that the attack discovery is based on + */ + alertIds: z.array(z.string()), + /** + * UUID of attack discovery + */ + id: z.string().optional(), + /** + * Details of the attack with bulleted markdown that always uses special syntax for field names and values from the source data. + */ + detailsMarkdown: z.string(), + /** + * A short (no more than a sentence) summary of the attack discovery featuring only the host.name and user.name fields (when they are applicable), using the same syntax + */ + entitySummaryMarkdown: z.string().optional(), + /** + * An array of MITRE ATT&CK tactic for the attack discovery + */ + mitreAttackTactics: z.array(z.string()).optional(), + /** + * A markdown summary of attack discovery, using the same syntax + */ + summaryMarkdown: z.string(), + /** + * A title for the attack discovery, in plain text + */ + title: z.string(), + /** + * The time the attack discovery was generated + */ + timestamp: NonEmptyTimestamp.optional(), + }) +); export type AttackDiscovery = z.infer; -export const AttackDiscovery = z.object({ - /** - * The alert IDs that the attack discovery is based on - */ - alertIds: z.array(z.string()), - /** - * UUID of attack discovery - */ - id: z.string().optional(), - /** - * Details of the attack with bulleted markdown that always uses special syntax for field names and values from the source data. - */ - detailsMarkdown: z.string(), - /** - * A short (no more than a sentence) summary of the attack discovery featuring only the host.name and user.name fields (when they are applicable), using the same syntax - */ - entitySummaryMarkdown: z.string().optional(), - /** - * An array of MITRE ATT&CK tactic for the attack discovery - */ - mitreAttackTactics: z.array(z.string()).optional(), - /** - * A markdown summary of attack discovery, using the same syntax - */ - summaryMarkdown: z.string(), - /** - * A title for the attack discovery, in plain text - */ - title: z.string(), - /** - * The time the attack discovery was generated - */ - timestamp: NonEmptyTimestamp.optional(), -}); /** * Array of attack discoveries */ +export const AttackDiscoveries = lazySchema(() => z.array(AttackDiscovery)); export type AttackDiscoveries = z.infer; -export const AttackDiscoveries = z.array(AttackDiscovery); /** * The status of the attack discovery. */ +export const AttackDiscoveryStatus = lazySchema(() => + z.enum(['running', 'succeeded', 'failed', 'canceled']) +); export type AttackDiscoveryStatus = z.infer; -export const AttackDiscoveryStatus = z.enum(['running', 'succeeded', 'failed', 'canceled']); export type AttackDiscoveryStatusEnum = typeof AttackDiscoveryStatus.enum; export const AttackDiscoveryStatusEnum = AttackDiscoveryStatus.enum; /** * Run durations for the attack discovery */ +export const GenerationInterval = lazySchema(() => + z.object({ + /** + * The time the attack discovery was generated + */ + date: z.string(), + /** + * The duration of the attack discovery generation + */ + durationMs: z.number().int(), + }) +); export type GenerationInterval = z.infer; -export const GenerationInterval = z.object({ - /** - * The time the attack discovery was generated - */ - date: z.string(), - /** - * The duration of the attack discovery generation - */ - durationMs: z.number().int(), -}); /** * Attack discovery stats */ +export const AttackDiscoveryStat = lazySchema(() => + z.object({ + /** + * Whether the user has viewed the results of the attack discovery run + */ + hasViewed: z.boolean(), + /** + * The number of attack discoveries for the connector + */ + count: z.number().int(), + /** + * The connector ID for the attack discovery + */ + connectorId: z.string(), + /** + * The status of the attack discovery. + */ + status: AttackDiscoveryStatus, + }) +); export type AttackDiscoveryStat = z.infer; -export const AttackDiscoveryStat = z.object({ - /** - * Whether the user has viewed the results of the attack discovery run - */ - hasViewed: z.boolean(), - /** - * The number of attack discoveries for the connector - */ - count: z.number().int(), - /** - * The connector ID for the attack discovery - */ - connectorId: z.string(), - /** - * The status of the attack discovery. - */ - status: AttackDiscoveryStatus, -}); /** * Stats on existing attack discovery documents */ +export const AttackDiscoveryStats = lazySchema(() => + z.object({ + /** + * The number of attack discoveries that have not yet been viewed + */ + newDiscoveriesCount: z.number().int(), + /** + * The number of connectors with new results that have not yet been viewed + */ + newConnectorResultsCount: z.number().int(), + /** + * Attack discovery stats per connector + */ + statsPerConnector: z.array(AttackDiscoveryStat), + }) +); export type AttackDiscoveryStats = z.infer; -export const AttackDiscoveryStats = z.object({ - /** - * The number of attack discoveries that have not yet been viewed - */ - newDiscoveriesCount: z.number().int(), - /** - * The number of connectors with new results that have not yet been viewed - */ - newConnectorResultsCount: z.number().int(), - /** - * Attack discovery stats per connector - */ - statsPerConnector: z.array(AttackDiscoveryStat), -}); +export const AttackDiscoveryResponse = lazySchema(() => + z.object({ + id: NonEmptyString, + timestamp: NonEmptyString.optional(), + /** + * The last time attack discovery was updated. + */ + updatedAt: z.string(), + /** + * The last time attack discovery was viewed in the browser. + */ + lastViewedAt: z.string(), + /** + * The number of alerts in the context. + */ + alertsContextCount: z.number().int().optional(), + /** + * The time attack discovery was created. + */ + createdAt: z.string(), + replacements: Replacements.optional(), + users: z.array(User), + /** + * The status of the attack discovery. + */ + status: AttackDiscoveryStatus, + /** + * The attack discoveries. + */ + attackDiscoveries: AttackDiscoveries, + /** + * LLM API configuration. + */ + apiConfig: ApiConfig, + /** + * Kibana space + */ + namespace: z.string(), + /** + * The backing index required for update requests. + */ + backingIndex: z.string(), + /** + * The most 5 recent generation intervals + */ + generationIntervals: z.array(GenerationInterval), + /** + * The average generation interval in milliseconds + */ + averageIntervalMs: z.number().int(), + /** + * The reason for a status of failed. + */ + failureReason: z.string().optional(), + }) +); export type AttackDiscoveryResponse = z.infer; -export const AttackDiscoveryResponse = z.object({ - id: NonEmptyString, - timestamp: NonEmptyString.optional(), - /** - * The last time attack discovery was updated. - */ - updatedAt: z.string(), - /** - * The last time attack discovery was viewed in the browser. - */ - lastViewedAt: z.string(), - /** - * The number of alerts in the context. - */ - alertsContextCount: z.number().int().optional(), - /** - * The time attack discovery was created. - */ - createdAt: z.string(), - replacements: Replacements.optional(), - users: z.array(User), - /** - * The status of the attack discovery. - */ - status: AttackDiscoveryStatus, - /** - * The attack discoveries. - */ - attackDiscoveries: AttackDiscoveries, - /** - * LLM API configuration. - */ - apiConfig: ApiConfig, - /** - * Kibana space - */ - namespace: z.string(), - /** - * The backing index required for update requests. - */ - backingIndex: z.string(), - /** - * The most 5 recent generation intervals - */ - generationIntervals: z.array(GenerationInterval), - /** - * The average generation interval in milliseconds - */ - averageIntervalMs: z.number().int(), - /** - * The reason for a status of failed. - */ - failureReason: z.string().optional(), -}); +export const CreateAttackDiscoveryAlertsParams = lazySchema(() => + z.object({ + /** + * The number of alerts provided as context to the LLM + */ + alertsContextCount: z.number().int(), + /** + * The anonymized alerts that were used to generate the attack discovery + */ + anonymizedAlerts: z.array( + z.object({ + id: z.string().optional(), + metadata: z.object({}), + pageContent: z.string(), + }) + ), + /** + * LLM API configuration + */ + apiConfig: ApiConfig, + /** + * The generated Attack discoveries + */ + attackDiscoveries: AttackDiscoveries, + /** + * The name of the connector that generated the attack discovery + */ + connectorName: z.string(), + /** + * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. + */ + enableFieldRendering: z.boolean(), + /** + * The generation ID of the run that created the attack discovery + */ + generationUuid: z.string(), + /** + * Replacements enable anonymization of data sent to the LLM. When Attack discoveries are added to an assistant conversation, replacements must be provided at the same time. + */ + replacements: Replacements.optional(), + /** + * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. + */ + withReplacements: z.boolean(), + }) +); export type CreateAttackDiscoveryAlertsParams = z.infer; -export const CreateAttackDiscoveryAlertsParams = z.object({ - /** - * The number of alerts provided as context to the LLM - */ - alertsContextCount: z.number().int(), - /** - * The anonymized alerts that were used to generate the attack discovery - */ - anonymizedAlerts: z.array( - z.object({ - id: z.string().optional(), - metadata: z.object({}), - pageContent: z.string(), - }) - ), - /** - * LLM API configuration - */ - apiConfig: ApiConfig, - /** - * The generated Attack discoveries - */ - attackDiscoveries: AttackDiscoveries, - /** - * The name of the connector that generated the attack discovery - */ - connectorName: z.string(), - /** - * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. - */ - enableFieldRendering: z.boolean(), - /** - * The generation ID of the run that created the attack discovery - */ - generationUuid: z.string(), - /** - * Replacements enable anonymization of data sent to the LLM. When Attack discoveries are added to an assistant conversation, replacements must be provided at the same time. - */ - replacements: Replacements.optional(), - /** - * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. - */ - withReplacements: z.boolean(), -}); +export const FindAttackDiscoveryAlertsParams = lazySchema(() => + z.object({ + /** + * filter by alert IDs within Attack discovery + */ + alertIds: z.array(z.string()).optional(), + /** + * filter by connector names + */ + connectorNames: z.array(z.string()).optional(), + /** + * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. + */ + enableFieldRendering: z.boolean(), + /** + * filter by end date (relative or absolute) + */ + end: z.string().optional(), + /** + * filter by execution UUID + */ + executionUuid: z.string().optional(), + /** + * whether to include attack alert IDs in the response + */ + includeUniqueAlertIds: z.boolean().optional(), + /** + * filter by Attack discovery IDs + */ + ids: z.array(z.string()).optional(), + page: z.number().int().min(1).optional().default(1), + perPage: z.number().int().min(0).optional().default(10), + /** + * filter by search query + */ + search: z.string().optional(), + /** + * `undefined`: show both shared, and only visible to me Attack discoveries. `true`: show only shared Attack discoveries. `false`: show only visible to me Attack discoveries. + */ + shared: z.boolean().optional(), + /** + * Whether to return scheduled or ad-hoc attack discoveries. If omitted, both types of attack discoveries are returned. Use `true` to return only scheduled discoveries or `false` to return only ad-hoc discoveries. + */ + scheduled: z.boolean().optional(), + sortField: z.string().optional().default('@timestamp'), + sortOrder: z.string().optional(), + /** + * filter by start date (relative or absolute) + */ + start: z.string().optional(), + /** + * filter by kibana.alert.workflow.status + */ + status: z.array(z.string()).optional(), + /** + * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. + */ + withReplacements: z.boolean(), + }) +); export type FindAttackDiscoveryAlertsParams = z.infer; -export const FindAttackDiscoveryAlertsParams = z.object({ - /** - * filter by alert IDs within Attack discovery - */ - alertIds: z.array(z.string()).optional(), - /** - * filter by connector names - */ - connectorNames: z.array(z.string()).optional(), - /** - * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. - */ - enableFieldRendering: z.boolean(), - /** - * filter by end date (relative or absolute) - */ - end: z.string().optional(), - /** - * filter by execution UUID - */ - executionUuid: z.string().optional(), - /** - * whether to include attack alert IDs in the response - */ - includeUniqueAlertIds: z.boolean().optional(), - /** - * filter by Attack discovery IDs - */ - ids: z.array(z.string()).optional(), - page: z.number().int().min(1).optional().default(1), - perPage: z.number().int().min(0).optional().default(10), - /** - * filter by search query - */ - search: z.string().optional(), - /** - * `undefined`: show both shared, and only visible to me Attack discoveries. `true`: show only shared Attack discoveries. `false`: show only visible to me Attack discoveries. - */ - shared: z.boolean().optional(), - /** - * Whether to return scheduled or ad-hoc attack discoveries. If omitted, both types of attack discoveries are returned. Use `true` to return only scheduled discoveries or `false` to return only ad-hoc discoveries. - */ - scheduled: z.boolean().optional(), - sortField: z.string().optional().default('@timestamp'), - sortOrder: z.string().optional(), - /** - * filter by start date (relative or absolute) - */ - start: z.string().optional(), - /** - * filter by kibana.alert.workflow.status - */ - status: z.array(z.string()).optional(), - /** - * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. - */ - withReplacements: z.boolean(), -}); -export type AttackDiscoveryGenerationConfig = z.infer; -export const AttackDiscoveryGenerationConfig = z.object({ - /** +export const AttackDiscoveryGenerationConfig = lazySchema(() => + z.object({ + /** * The (space specific) index pattern that contains the alerts to use as context for the attack discovery. Example: .alerts-security.alerts-default */ - alertsIndexPattern: z.string(), - /** - * The list of fields, and whether or not they are anonymized, allowed to be sent to LLMs. Consider using the output of the `/api/security_ai_assistant/anonymization_fields/_find` API (for a specific Kibana space) to provide this value. - */ - anonymizationFields: z.array(AnonymizationFieldResponse), - /** - * LLM API configuration. - */ - apiConfig: ApiConfig, - connectorName: z.string().optional(), - end: z.string().optional(), - /** + alertsIndexPattern: z.string(), + /** + * The list of fields, and whether or not they are anonymized, allowed to be sent to LLMs. Consider using the output of the `/api/security_ai_assistant/anonymization_fields/_find` API (for a specific Kibana space) to provide this value. + */ + anonymizationFields: z.array(AnonymizationFieldResponse), + /** + * LLM API configuration. + */ + apiConfig: ApiConfig, + connectorName: z.string().optional(), + end: z.string().optional(), + /** * An Elasticsearch-style query DSL object used to filter alerts. For example: ```json { "filter": { @@ -337,12 +353,14 @@ Example: .alerts-security.alerts-default } } ``` */ - filter: z.object({}).catchall(z.unknown()).optional(), - langSmithProject: z.string().optional(), - langSmithApiKey: z.string().optional(), - model: z.string().optional(), - replacements: Replacements.optional(), - size: z.number(), - start: z.string().optional(), - subAction: z.enum(['invokeAI', 'invokeStream']), -}); + filter: z.object({}).catchall(z.unknown()).optional(), + langSmithProject: z.string().optional(), + langSmithApiKey: z.string().optional(), + model: z.string().optional(), + replacements: Replacements.optional(), + size: z.number(), + start: z.string().optional(), + subAction: z.enum(['invokeAI', 'invokeStream']), + }) +); +export type AttackDiscoveryGenerationConfig = z.infer; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/generation.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/generation.gen.ts index 9293a88b52998..ad6c0f2971d2f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/generation.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/generation.gen.ts @@ -14,59 +14,61 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const AttackDiscoveryGeneration = lazySchema(() => + z.object({ + /** + * The number of alerts sent as context (max kibana.alert.rule.execution.metrics.alert_counts.active) to the LLM for the generation + */ + alerts_context_count: z.number().optional(), + /** + * The connector id (event.dataset) for this generation + */ + connector_id: z.string(), + /** + * Stats applicable to the connector for this generation + */ + connector_stats: z + .object({ + /** + * The average duration (avg event.duration) in nanoseconds of successful generations for the same connector id, for the current user + */ + average_successful_duration_nanoseconds: z.number().optional(), + /** + * The number of successful generations for the same connector id, for the current user + */ + successful_generations: z.number().optional(), + }) + .optional(), + /** + * The number of new Attack discovery alerts (max kibana.alert.rule.execution.metrics.alert_counts.new) for this generation + */ + discoveries: z.number(), + /** + * When generation ended (max event.end) + */ + end: z.string().optional(), + /** + * The unique identifier (kibana.alert.rule.execution.uuid) for the generation + */ + execution_uuid: z.string(), + /** + * Generation loading message (kibana.alert.rule.execution.status) + */ + loading_message: z.string(), + /** + * Reason for failed generations (event.reason) + */ + reason: z.string().optional(), + /** + * When generation started (min event.start) + */ + start: z.string(), + /** + * The status of the attack discovery generation + */ + status: z.enum(['canceled', 'dismissed', 'failed', 'started', 'succeeded']), + }) +); export type AttackDiscoveryGeneration = z.infer; -export const AttackDiscoveryGeneration = z.object({ - /** - * The number of alerts sent as context (max kibana.alert.rule.execution.metrics.alert_counts.active) to the LLM for the generation - */ - alerts_context_count: z.number().optional(), - /** - * The connector id (event.dataset) for this generation - */ - connector_id: z.string(), - /** - * Stats applicable to the connector for this generation - */ - connector_stats: z - .object({ - /** - * The average duration (avg event.duration) in nanoseconds of successful generations for the same connector id, for the current user - */ - average_successful_duration_nanoseconds: z.number().optional(), - /** - * The number of successful generations for the same connector id, for the current user - */ - successful_generations: z.number().optional(), - }) - .optional(), - /** - * The number of new Attack discovery alerts (max kibana.alert.rule.execution.metrics.alert_counts.new) for this generation - */ - discoveries: z.number(), - /** - * When generation ended (max event.end) - */ - end: z.string().optional(), - /** - * The unique identifier (kibana.alert.rule.execution.uuid) for the generation - */ - execution_uuid: z.string(), - /** - * Generation loading message (kibana.alert.rule.execution.status) - */ - loading_message: z.string(), - /** - * Reason for failed generations (event.reason) - */ - reason: z.string().optional(), - /** - * When generation started (min event.start) - */ - start: z.string(), - /** - * The status of the attack discovery generation - */ - status: z.enum(['canceled', 'dismissed', 'failed', 'started', 'succeeded']), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/internal/privileges/get_missing_privileges.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/internal/privileges/get_missing_privileges.gen.ts index 0fcd92237c55f..ffe3c1afb25ae 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/internal/privileges/get_missing_privileges.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/internal/privileges/get_missing_privileges.gen.ts @@ -14,26 +14,28 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const AttackDiscoveryMissingPrivileges = lazySchema(() => + z.object({ + /** + * The index name of the privilege missing + */ + index_name: z.string(), + /** + * The index privileges level missing + */ + privileges: z.array(z.string()), + }) +); export type AttackDiscoveryMissingPrivileges = z.infer; -export const AttackDiscoveryMissingPrivileges = z.object({ - /** - * The index name of the privilege missing - */ - index_name: z.string(), - /** - * The index privileges level missing - */ - privileges: z.array(z.string()), -}); /** * The missing index privileges required for Attack discovery */ +export const GetAttackDiscoveryMissingPrivilegesInternalResponse = lazySchema(() => + z.array(AttackDiscoveryMissingPrivileges) +); export type GetAttackDiscoveryMissingPrivilegesInternalResponse = z.infer< typeof GetAttackDiscoveryMissingPrivilegesInternalResponse >; -export const GetAttackDiscoveryMissingPrivilegesInternalResponse = z.array( - AttackDiscoveryMissingPrivileges -); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/find_attack_discoveries_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/find_attack_discoveries_route.gen.ts index e70a6d604ed7e..ceafb25d2ea3f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/find_attack_discoveries_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/find_attack_discoveries_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../../../../common_attributes.gen'; @@ -23,106 +23,110 @@ import { AttackDiscoveryApiAlert } from '../../../attack_discovery_api_alert.gen /** * Allowed field names to sort Attack discovery results by. Clients should only pass one of the listed values. */ +export const AttackDiscoveryFindSortField = lazySchema(() => z.literal('@timestamp')); export type AttackDiscoveryFindSortField = z.infer; -export const AttackDiscoveryFindSortField = z.literal('@timestamp'); +export const AttackDiscoveryFindRequestQuery = lazySchema(() => + z.object({ + /** + * Filter results to Attack discoveries that include any of the provided alert IDs + */ + alert_ids: ArrayFromString(z.string()).optional(), + /** + * Filter results to Attack discoveries created by any of the provided human readable connector names. Note that values must match the human readable `connector_name` property of an Attack discovery, e.g. "GPT-5 Chat", which are distinct from `connector_id` values used to generate Attack discoveries. + */ + connector_names: ArrayFromString(z.string()).optional(), + /** + * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. + */ + enable_field_rendering: BooleanFromString.optional().default(false), + /** + * End of the time range for the search. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now", "now-24h"). + */ + end: z.string().optional(), + /** + * Filter results to the Attack discoveries with the specified IDs + */ + ids: ArrayFromString(z.string()).optional(), + /** + * If `true`, the response will include `unique_alert_ids` and `unique_alert_ids_count` aggregated across the matched Attack discoveries + */ + include_unique_alert_ids: BooleanFromString.optional(), + /** + * Page number to return (used for pagination). Defaults to 1. + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * Number of Attack discoveries to return per page (used for pagination). Defaults to 10. + */ + per_page: z.coerce.number().int().min(1).optional().default(10), + /** + * Free-text search query applied to relevant text fields of Attack discoveries (title, description, tags, etc.) + */ + search: z.string().optional(), + /** + * Whether to filter by shared visibility. If omitted, both shared and privately visible Attack discoveries are returned. Use `true` to return only shared discoveries, `false` to return only those visible to the current user. + */ + shared: BooleanFromString.optional(), + /** + * Whether to filter by scheduled or ad-hoc attack discoveries. If omitted, both types of attack discoveries are returned. Use `true` to return only scheduled discoveries or `false` to return only ad-hoc discoveries. + */ + scheduled: BooleanFromString.optional(), + /** + * Field used to sort results. See `AttackDiscoveryFindSortField` for allowed values. + */ + sort_field: AttackDiscoveryFindSortField.optional().default('@timestamp'), + /** + * Sort order direction `asc` for ascending or `desc` for descending. Defaults to `desc`. + */ + sort_order: SortOrder.optional().default('desc'), + /** + * Start of the time range for the search. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now-7d"). + */ + start: z.string().optional(), + /** + * Filter by alert workflow status. Provide one or more of the allowed workflow states. + */ + status: ArrayFromString(z.enum(['acknowledged', 'closed', 'open'])).optional(), + /** + * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. Defaults to `true`. + */ + with_replacements: BooleanFromString.optional().default(true), + }) +); export type AttackDiscoveryFindRequestQuery = z.infer; -export const AttackDiscoveryFindRequestQuery = z.object({ - /** - * Filter results to Attack discoveries that include any of the provided alert IDs - */ - alert_ids: ArrayFromString(z.string()).optional(), - /** - * Filter results to Attack discoveries created by any of the provided human readable connector names. Note that values must match the human readable `connector_name` property of an Attack discovery, e.g. "GPT-5 Chat", which are distinct from `connector_id` values used to generate Attack discoveries. - */ - connector_names: ArrayFromString(z.string()).optional(), - /** - * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. - */ - enable_field_rendering: BooleanFromString.optional().default(false), - /** - * End of the time range for the search. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now", "now-24h"). - */ - end: z.string().optional(), - /** - * Filter results to the Attack discoveries with the specified IDs - */ - ids: ArrayFromString(z.string()).optional(), - /** - * If `true`, the response will include `unique_alert_ids` and `unique_alert_ids_count` aggregated across the matched Attack discoveries - */ - include_unique_alert_ids: BooleanFromString.optional(), - /** - * Page number to return (used for pagination). Defaults to 1. - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * Number of Attack discoveries to return per page (used for pagination). Defaults to 10. - */ - per_page: z.coerce.number().int().min(1).optional().default(10), - /** - * Free-text search query applied to relevant text fields of Attack discoveries (title, description, tags, etc.) - */ - search: z.string().optional(), - /** - * Whether to filter by shared visibility. If omitted, both shared and privately visible Attack discoveries are returned. Use `true` to return only shared discoveries, `false` to return only those visible to the current user. - */ - shared: BooleanFromString.optional(), - /** - * Whether to filter by scheduled or ad-hoc attack discoveries. If omitted, both types of attack discoveries are returned. Use `true` to return only scheduled discoveries or `false` to return only ad-hoc discoveries. - */ - scheduled: BooleanFromString.optional(), - /** - * Field used to sort results. See `AttackDiscoveryFindSortField` for allowed values. - */ - sort_field: AttackDiscoveryFindSortField.optional().default('@timestamp'), - /** - * Sort order direction `asc` for ascending or `desc` for descending. Defaults to `desc`. - */ - sort_order: SortOrder.optional().default('desc'), - /** - * Start of the time range for the search. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now-7d"). - */ - start: z.string().optional(), - /** - * Filter by alert workflow status. Provide one or more of the allowed workflow states. - */ - status: ArrayFromString(z.enum(['acknowledged', 'closed', 'open'])).optional(), - /** - * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. Defaults to `true`. - */ - with_replacements: BooleanFromString.optional().default(true), -}); export type AttackDiscoveryFindRequestQueryInput = z.input; +export const AttackDiscoveryFindResponse = lazySchema(() => + z.object({ + /** + * List of human readable connector names that are present in the matched Attack discoveries. Useful for building client filters or summaries. + */ + connector_names: z.array(z.string()), + /** + * Array of matched Attack discovery objects. Each item follows the `AttackDiscoveryApiAlert` schema. + */ + data: z.array(AttackDiscoveryApiAlert), + /** + * Current page number of the paginated result set. + */ + page: z.number().int(), + /** + * Number of items requested per page. + */ + per_page: z.number().int(), + /** + * Total number of Attack discoveries matching the query (across all pages). + */ + total: z.number().int(), + /** + * List of unique alert IDs aggregated from the matched Attack discoveries. Only present if `include_unique_alert_ids=true` in the request. + */ + unique_alert_ids: z.array(z.string()).optional(), + /** + * Number of unique alert IDs across all matched Attack discoveries. Only present if `include_unique_alert_ids=true` in the request. + */ + unique_alert_ids_count: z.number().int(), + }) +); export type AttackDiscoveryFindResponse = z.infer; -export const AttackDiscoveryFindResponse = z.object({ - /** - * List of human readable connector names that are present in the matched Attack discoveries. Useful for building client filters or summaries. - */ - connector_names: z.array(z.string()), - /** - * Array of matched Attack discovery objects. Each item follows the `AttackDiscoveryApiAlert` schema. - */ - data: z.array(AttackDiscoveryApiAlert), - /** - * Current page number of the paginated result set. - */ - page: z.number().int(), - /** - * Number of items requested per page. - */ - per_page: z.number().int(), - /** - * Total number of Attack discoveries matching the query (across all pages). - */ - total: z.number().int(), - /** - * List of unique alert IDs aggregated from the matched Attack discoveries. Only present if `include_unique_alert_ids=true` in the request. - */ - unique_alert_ids: z.array(z.string()).optional(), - /** - * Number of unique alert IDs across all matched Attack discoveries. Only present if `include_unique_alert_ids=true` in the request. - */ - unique_alert_ids_count: z.number().int(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generation_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generation_route.gen.ts index 7c52c3576e41b..277b8a8ba65fd 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generation_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generation_route.gen.ts @@ -14,53 +14,59 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '../../../../common_attributes.gen'; import { AttackDiscoveryApiAlert } from '../../../attack_discovery_api_alert.gen'; import { AttackDiscoveryGeneration } from '../../../generation.gen'; +export const GetAttackDiscoveryGenerationRequestQuery = lazySchema(() => + z.object({ + /** + * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. + */ + enable_field_rendering: BooleanFromString.optional().default(false), + /** + * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. Defaults to `true`. + */ + with_replacements: BooleanFromString.optional().default(true), + }) +); export type GetAttackDiscoveryGenerationRequestQuery = z.infer< typeof GetAttackDiscoveryGenerationRequestQuery >; -export const GetAttackDiscoveryGenerationRequestQuery = z.object({ - /** - * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. - */ - enable_field_rendering: BooleanFromString.optional().default(false), - /** - * When true, return the created Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. Defaults to `true`. - */ - with_replacements: BooleanFromString.optional().default(true), -}); export type GetAttackDiscoveryGenerationRequestQueryInput = z.input< typeof GetAttackDiscoveryGenerationRequestQuery >; +export const GetAttackDiscoveryGenerationRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier for the Attack discovery generation execution. This UUID is returned at the start of an Attack discovery generation. + */ + execution_uuid: NonEmptyString, + }) +); export type GetAttackDiscoveryGenerationRequestParams = z.infer< typeof GetAttackDiscoveryGenerationRequestParams >; -export const GetAttackDiscoveryGenerationRequestParams = z.object({ - /** - * The unique identifier for the Attack discovery generation execution. This UUID is returned at the start of an Attack discovery generation. - */ - execution_uuid: NonEmptyString, -}); export type GetAttackDiscoveryGenerationRequestParamsInput = z.input< typeof GetAttackDiscoveryGenerationRequestParams >; +export const GetAttackDiscoveryGenerationResponse = lazySchema(() => + z.object({ + /** + * Array of Attack discoveries generated during this execution. + */ + data: z.array(AttackDiscoveryApiAlert), + /** + * Optional metadata about the attack discovery generation process, metadata including execution status and statistics. This metadata may not be available for all generations. + */ + generation: AttackDiscoveryGeneration.optional(), + }) +); export type GetAttackDiscoveryGenerationResponse = z.infer< typeof GetAttackDiscoveryGenerationResponse >; -export const GetAttackDiscoveryGenerationResponse = z.object({ - /** - * Array of Attack discoveries generated during this execution. - */ - data: z.array(AttackDiscoveryApiAlert), - /** - * Optional metadata about the attack discovery generation process, metadata including execution status and statistics. This metadata may not be available for all generations. - */ - generation: AttackDiscoveryGeneration.optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generations_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generations_route.gen.ts index 5f3d37c531218..512295636ab04 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generations_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/get/get_attack_discovery_generations_route.gen.ts @@ -14,37 +14,41 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AttackDiscoveryGeneration } from '../../../generation.gen'; +export const GetAttackDiscoveryGenerationsRequestQuery = lazySchema(() => + z.object({ + /** + * End of the time range for filtering generations. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now", "now-24h"). + */ + end: z.string().optional(), + /** + * The maximum number of generations to retrieve + */ + size: z.coerce.number().min(1).optional().default(50), + /** + * Start of the time range for filtering generations. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now-7d"). + */ + start: z.string().optional(), + }) +); export type GetAttackDiscoveryGenerationsRequestQuery = z.infer< typeof GetAttackDiscoveryGenerationsRequestQuery >; -export const GetAttackDiscoveryGenerationsRequestQuery = z.object({ - /** - * End of the time range for filtering generations. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now", "now-24h"). - */ - end: z.string().optional(), - /** - * The maximum number of generations to retrieve - */ - size: z.coerce.number().min(1).optional().default(50), - /** - * Start of the time range for filtering generations. Accepts absolute timestamps (ISO 8601) or relative date math (e.g. "now-7d"). - */ - start: z.string().optional(), -}); export type GetAttackDiscoveryGenerationsRequestQueryInput = z.input< typeof GetAttackDiscoveryGenerationsRequestQuery >; +export const GetAttackDiscoveryGenerationsResponse = lazySchema(() => + z.object({ + /** + * List of attack discovery generations + */ + generations: z.array(AttackDiscoveryGeneration), + }) +); export type GetAttackDiscoveryGenerationsResponse = z.infer< typeof GetAttackDiscoveryGenerationsResponse >; -export const GetAttackDiscoveryGenerationsResponse = z.object({ - /** - * List of attack discovery generations - */ - generations: z.array(AttackDiscoveryGeneration), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_bulk_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_bulk_route.gen.ts index bd2315527bf25..c33deeeb4d1a1 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_bulk_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_bulk_route.gen.ts @@ -14,46 +14,50 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AttackDiscoveryApiAlert } from '../../../attack_discovery_api_alert.gen'; -export type PostAttackDiscoveryBulkRequestBody = z.infer; -export const PostAttackDiscoveryBulkRequestBody = z.object({ - /** - * Configuration object containing all parameters for the bulk update operation - */ - update: z.object({ - /** - * Array of Attack discovery IDs to update - */ - ids: z.array(z.string()), - /** - * When provided, update the kibana.alert.workflow_status of the attack discovery alerts - */ - kibana_alert_workflow_status: z.enum(['open', 'acknowledged', 'closed']).optional(), - /** - * When provided, update the visibility of the alert, as determined by the kibana.alert.attack_discovery.users field - */ - visibility: z.enum(['not_shared', 'shared']).optional(), - /** - * When true, returns the updated Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. This substitutes anonymized values with human-readable equivalents. Defaults to `true`. - */ - with_replacements: z.boolean().optional().default(true), +export const PostAttackDiscoveryBulkRequestBody = lazySchema(() => + z.object({ /** - * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. + * Configuration object containing all parameters for the bulk update operation */ - enable_field_rendering: z.boolean().optional().default(false), - }), -}); + update: z.object({ + /** + * Array of Attack discovery IDs to update + */ + ids: z.array(z.string()), + /** + * When provided, update the kibana.alert.workflow_status of the attack discovery alerts + */ + kibana_alert_workflow_status: z.enum(['open', 'acknowledged', 'closed']).optional(), + /** + * When provided, update the visibility of the alert, as determined by the kibana.alert.attack_discovery.users field + */ + visibility: z.enum(['not_shared', 'shared']).optional(), + /** + * When true, returns the updated Attack discoveries with text replacements applied to the detailsMarkdown, entitySummaryMarkdown, summaryMarkdown, and title fields. This substitutes anonymized values with human-readable equivalents. Defaults to `true`. + */ + with_replacements: z.boolean().optional().default(true), + /** + * Enables a markdown syntax used to render pivot fields, for example `{{ user.name james }}`. When disabled, the same example would be rendered as `james`. This is primarily used for Attack discovery views within Kibana. Defaults to `false`. + */ + enable_field_rendering: z.boolean().optional().default(false), + }), + }) +); +export type PostAttackDiscoveryBulkRequestBody = z.infer; export type PostAttackDiscoveryBulkRequestBodyInput = z.input< typeof PostAttackDiscoveryBulkRequestBody >; +export const PostAttackDiscoveryBulkResponse = lazySchema(() => + z.object({ + /** + * Array of updated Attack discovery alert objects. Each item includes the applied modifications from the bulk update request. + */ + data: z.array(AttackDiscoveryApiAlert), + }) +); export type PostAttackDiscoveryBulkResponse = z.infer; -export const PostAttackDiscoveryBulkResponse = z.object({ - /** - * Array of updated Attack discovery alert objects. Each item includes the applied modifications from the bulk update request. - */ - data: z.array(AttackDiscoveryApiAlert), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generate.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generate.gen.ts index 8d8c102609325..86948f94c62dc 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generate.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generate.gen.ts @@ -14,25 +14,29 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AttackDiscoveryGenerationConfig } from '../../../common_attributes.gen'; import { NonEmptyString } from '../../../../common_attributes.gen'; +export const PostAttackDiscoveryGenerateRequestBody = lazySchema( + () => AttackDiscoveryGenerationConfig +); export type PostAttackDiscoveryGenerateRequestBody = z.infer< typeof PostAttackDiscoveryGenerateRequestBody >; -export const PostAttackDiscoveryGenerateRequestBody = AttackDiscoveryGenerationConfig; export type PostAttackDiscoveryGenerateRequestBodyInput = z.input< typeof PostAttackDiscoveryGenerateRequestBody >; +export const PostAttackDiscoveryGenerateResponse = lazySchema(() => + z.object({ + /** + * The unique identifier for the attack discovery generation process. Use this UUID to track the generation progress and retrieve results via the find endpoint. + */ + execution_uuid: NonEmptyString, + }) +); export type PostAttackDiscoveryGenerateResponse = z.infer< typeof PostAttackDiscoveryGenerateResponse >; -export const PostAttackDiscoveryGenerateResponse = z.object({ - /** - * The unique identifier for the attack discovery generation process. Use this UUID to track the generation progress and retrieve results via the find endpoint. - */ - execution_uuid: NonEmptyString, -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generations_dismiss.route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generations_dismiss.route.gen.ts index e0286d6fcd8d3..b99d5e45924fb 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generations_dismiss.route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/post/post_attack_discovery_generations_dismiss.route.gen.ts @@ -14,76 +14,80 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../../../../common_attributes.gen'; +export const PostAttackDiscoveryGenerationsDismissRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier for the Attack discovery generation execution. This UUID is returned when an attack discovery generation is created and can be found in generation responses. + */ + execution_uuid: NonEmptyString, + }) +); export type PostAttackDiscoveryGenerationsDismissRequestParams = z.infer< typeof PostAttackDiscoveryGenerationsDismissRequestParams >; -export const PostAttackDiscoveryGenerationsDismissRequestParams = z.object({ - /** - * The unique identifier for the Attack discovery generation execution. This UUID is returned when an attack discovery generation is created and can be found in generation responses. - */ - execution_uuid: NonEmptyString, -}); export type PostAttackDiscoveryGenerationsDismissRequestParamsInput = z.input< typeof PostAttackDiscoveryGenerationsDismissRequestParams >; +export const PostAttackDiscoveryGenerationsDismissResponse = lazySchema(() => + z.object({ + /** + * The number of alerts that were sent as context to the LLM for this generation. + */ + alerts_context_count: z.number().optional(), + /** + * The unique identifier of the connector used to generate the attack discoveries. + */ + connector_id: z.string(), + /** + * Statistical information about the connector's performance for this user, providing insights into usage patterns and success rates. + */ + connector_stats: z + .object({ + /** + * The average duration in nanoseconds for successful generations using this connector by the current user. + */ + average_successful_duration_nanoseconds: z.number().optional(), + /** + * The total number of Attack discoveries successfully created for this generation + */ + successful_generations: z.number().optional(), + }) + .optional(), + /** + * The number of attack discoveries that were generated during this execution. + */ + discoveries: z.number(), + /** + * The timestamp when the generation process completed, in ISO 8601 format. This field may be absent for generations that haven't finished. + */ + end: z.string().optional(), + /** + * The unique identifier for this attack discovery generation execution. This UUID can be used to reference this specific generation in other API calls. + */ + execution_uuid: z.string(), + /** + * A human-readable message describing the current state or progress of the generation process. Provides context about what the AI is analyzing. + */ + loading_message: z.string(), + /** + * Additional context or reasoning provided when a generation fails or encounters issues. This field helps diagnose problems with the generation process. + */ + reason: z.string().optional(), + /** + * The timestamp when the generation process began, in ISO 8601 format. This marks the beginning of the AI analysis. + */ + start: z.string(), + /** + * The current status of the attack discovery generation. After dismissing, this will be set to "dismissed". + */ + status: z.enum(['canceled', 'dismissed', 'failed', 'started', 'succeeded']), + }) +); export type PostAttackDiscoveryGenerationsDismissResponse = z.infer< typeof PostAttackDiscoveryGenerationsDismissResponse >; -export const PostAttackDiscoveryGenerationsDismissResponse = z.object({ - /** - * The number of alerts that were sent as context to the LLM for this generation. - */ - alerts_context_count: z.number().optional(), - /** - * The unique identifier of the connector used to generate the attack discoveries. - */ - connector_id: z.string(), - /** - * Statistical information about the connector's performance for this user, providing insights into usage patterns and success rates. - */ - connector_stats: z - .object({ - /** - * The average duration in nanoseconds for successful generations using this connector by the current user. - */ - average_successful_duration_nanoseconds: z.number().optional(), - /** - * The total number of Attack discoveries successfully created for this generation - */ - successful_generations: z.number().optional(), - }) - .optional(), - /** - * The number of attack discoveries that were generated during this execution. - */ - discoveries: z.number(), - /** - * The timestamp when the generation process completed, in ISO 8601 format. This field may be absent for generations that haven't finished. - */ - end: z.string().optional(), - /** - * The unique identifier for this attack discovery generation execution. This UUID can be used to reference this specific generation in other API calls. - */ - execution_uuid: z.string(), - /** - * A human-readable message describing the current state or progress of the generation process. Provides context about what the AI is analyzing. - */ - loading_message: z.string(), - /** - * Additional context or reasoning provided when a generation fails or encounters issues. This field helps diagnose problems with the generation process. - */ - reason: z.string().optional(), - /** - * The timestamp when the generation process began, in ISO 8601 format. This marks the beginning of the AI analysis. - */ - start: z.string(), - /** - * The current status of the attack discovery generation. After dismissing, this will be set to "dismissed". - */ - status: z.enum(['canceled', 'dismissed', 'failed', 'started', 'succeeded']), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/crud_attack_discovery_schedules_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/crud_attack_discovery_schedules_route.gen.ts index e74a921c2d0fa..1860560a0af5b 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/crud_attack_discovery_schedules_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/crud_attack_discovery_schedules_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AttackDiscoveryApiScheduleCreateProps, @@ -26,150 +26,172 @@ import { NonEmptyString } from '../../../../common_attributes.gen'; /** * Object containing Attack Discovery schedule. */ +export const AttackDiscoveryGenericResponse = lazySchema(() => z.object({}).catchall(z.unknown())); export type AttackDiscoveryGenericResponse = z.infer; -export const AttackDiscoveryGenericResponse = z.object({}).catchall(z.unknown()); /** * Generic error response for Attack discovery schedule operations */ +export const AttackDiscoveryGenericError = lazySchema(() => + z.object({ + /** + * HTTP status code + */ + status_code: z.number().optional(), + /** + * Error type + */ + error: z.string().optional(), + /** + * Human-readable error message describing what went wrong + */ + message: z.string().optional(), + }) +); export type AttackDiscoveryGenericError = z.infer; -export const AttackDiscoveryGenericError = z.object({ - /** - * HTTP status code - */ - status_code: z.number().optional(), - /** - * Error type - */ - error: z.string().optional(), - /** - * Human-readable error message describing what went wrong - */ - message: z.string().optional(), -}); +export const CreateAttackDiscoverySchedulesRequestBody = lazySchema( + () => AttackDiscoveryApiScheduleCreateProps +); export type CreateAttackDiscoverySchedulesRequestBody = z.infer< typeof CreateAttackDiscoverySchedulesRequestBody >; -export const CreateAttackDiscoverySchedulesRequestBody = AttackDiscoveryApiScheduleCreateProps; export type CreateAttackDiscoverySchedulesRequestBodyInput = z.input< typeof CreateAttackDiscoverySchedulesRequestBody >; +export const CreateAttackDiscoverySchedulesResponse = lazySchema(() => AttackDiscoveryApiSchedule); export type CreateAttackDiscoverySchedulesResponse = z.infer< typeof CreateAttackDiscoverySchedulesResponse >; -export const CreateAttackDiscoverySchedulesResponse = AttackDiscoveryApiSchedule; +export const DeleteAttackDiscoverySchedulesRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (UUID) of the Attack Discovery schedule to delete. This ID is returned when creating a schedule and can be found in schedule listings. + */ + id: NonEmptyString, + }) +); export type DeleteAttackDiscoverySchedulesRequestParams = z.infer< typeof DeleteAttackDiscoverySchedulesRequestParams >; -export const DeleteAttackDiscoverySchedulesRequestParams = z.object({ - /** - * The unique identifier (UUID) of the Attack Discovery schedule to delete. This ID is returned when creating a schedule and can be found in schedule listings. - */ - id: NonEmptyString, -}); export type DeleteAttackDiscoverySchedulesRequestParamsInput = z.input< typeof DeleteAttackDiscoverySchedulesRequestParams >; +export const DeleteAttackDiscoverySchedulesResponse = lazySchema(() => + z.object({ + /** + * The unique identifier of the deleted Attack Discovery schedule + */ + id: NonEmptyString, + }) +); export type DeleteAttackDiscoverySchedulesResponse = z.infer< typeof DeleteAttackDiscoverySchedulesResponse >; -export const DeleteAttackDiscoverySchedulesResponse = z.object({ - /** - * The unique identifier of the deleted Attack Discovery schedule - */ - id: NonEmptyString, -}); +export const DisableAttackDiscoverySchedulesRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (UUID) of the Attack Discovery schedule to disable. This ID is returned when creating a schedule and can be found in schedule listings. + */ + id: NonEmptyString, + }) +); export type DisableAttackDiscoverySchedulesRequestParams = z.infer< typeof DisableAttackDiscoverySchedulesRequestParams >; -export const DisableAttackDiscoverySchedulesRequestParams = z.object({ - /** - * The unique identifier (UUID) of the Attack Discovery schedule to disable. This ID is returned when creating a schedule and can be found in schedule listings. - */ - id: NonEmptyString, -}); export type DisableAttackDiscoverySchedulesRequestParamsInput = z.input< typeof DisableAttackDiscoverySchedulesRequestParams >; +export const DisableAttackDiscoverySchedulesResponse = lazySchema(() => + z.object({ + /** + * The unique identifier of the disabled Attack Discovery schedule + */ + id: NonEmptyString, + }) +); export type DisableAttackDiscoverySchedulesResponse = z.infer< typeof DisableAttackDiscoverySchedulesResponse >; -export const DisableAttackDiscoverySchedulesResponse = z.object({ - /** - * The unique identifier of the disabled Attack Discovery schedule - */ - id: NonEmptyString, -}); +export const EnableAttackDiscoverySchedulesRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (UUID) of the Attack Discovery schedule to enable. This ID is returned when creating a schedule and can be found in schedule listings. + */ + id: NonEmptyString, + }) +); export type EnableAttackDiscoverySchedulesRequestParams = z.infer< typeof EnableAttackDiscoverySchedulesRequestParams >; -export const EnableAttackDiscoverySchedulesRequestParams = z.object({ - /** - * The unique identifier (UUID) of the Attack Discovery schedule to enable. This ID is returned when creating a schedule and can be found in schedule listings. - */ - id: NonEmptyString, -}); export type EnableAttackDiscoverySchedulesRequestParamsInput = z.input< typeof EnableAttackDiscoverySchedulesRequestParams >; +export const EnableAttackDiscoverySchedulesResponse = lazySchema(() => + z.object({ + /** + * The unique identifier of the enabled Attack Discovery schedule + */ + id: NonEmptyString, + }) +); export type EnableAttackDiscoverySchedulesResponse = z.infer< typeof EnableAttackDiscoverySchedulesResponse >; -export const EnableAttackDiscoverySchedulesResponse = z.object({ - /** - * The unique identifier of the enabled Attack Discovery schedule - */ - id: NonEmptyString, -}); +export const GetAttackDiscoverySchedulesRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (UUID) of the Attack Discovery schedule to retrieve. This ID is returned when creating a schedule and can be found in schedule listings. + */ + id: NonEmptyString, + }) +); export type GetAttackDiscoverySchedulesRequestParams = z.infer< typeof GetAttackDiscoverySchedulesRequestParams >; -export const GetAttackDiscoverySchedulesRequestParams = z.object({ - /** - * The unique identifier (UUID) of the Attack Discovery schedule to retrieve. This ID is returned when creating a schedule and can be found in schedule listings. - */ - id: NonEmptyString, -}); export type GetAttackDiscoverySchedulesRequestParamsInput = z.input< typeof GetAttackDiscoverySchedulesRequestParams >; +export const GetAttackDiscoverySchedulesResponse = lazySchema(() => AttackDiscoveryApiSchedule); export type GetAttackDiscoverySchedulesResponse = z.infer< typeof GetAttackDiscoverySchedulesResponse >; -export const GetAttackDiscoverySchedulesResponse = AttackDiscoveryApiSchedule; +export const UpdateAttackDiscoverySchedulesRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (UUID) of the Attack Discovery schedule to update. This ID is returned when creating a schedule and can be found in schedule listings. + */ + id: NonEmptyString, + }) +); export type UpdateAttackDiscoverySchedulesRequestParams = z.infer< typeof UpdateAttackDiscoverySchedulesRequestParams >; -export const UpdateAttackDiscoverySchedulesRequestParams = z.object({ - /** - * The unique identifier (UUID) of the Attack Discovery schedule to update. This ID is returned when creating a schedule and can be found in schedule listings. - */ - id: NonEmptyString, -}); export type UpdateAttackDiscoverySchedulesRequestParamsInput = z.input< typeof UpdateAttackDiscoverySchedulesRequestParams >; +export const UpdateAttackDiscoverySchedulesRequestBody = lazySchema( + () => AttackDiscoveryApiScheduleUpdateProps +); export type UpdateAttackDiscoverySchedulesRequestBody = z.infer< typeof UpdateAttackDiscoverySchedulesRequestBody >; -export const UpdateAttackDiscoverySchedulesRequestBody = AttackDiscoveryApiScheduleUpdateProps; export type UpdateAttackDiscoverySchedulesRequestBodyInput = z.input< typeof UpdateAttackDiscoverySchedulesRequestBody >; +export const UpdateAttackDiscoverySchedulesResponse = lazySchema(() => AttackDiscoveryApiSchedule); export type UpdateAttackDiscoverySchedulesResponse = z.infer< typeof UpdateAttackDiscoverySchedulesResponse >; -export const UpdateAttackDiscoverySchedulesResponse = AttackDiscoveryApiSchedule; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/get/find_attack_discovery_schedules_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/get/find_attack_discovery_schedules_route.gen.ts index 44b523d17dec1..3fe2ad25e0ac9 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/get/find_attack_discovery_schedules_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/get/find_attack_discovery_schedules_route.gen.ts @@ -14,54 +14,58 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../../../../../common_attributes.gen'; import { AttackDiscoveryApiSchedule } from '../schedules_api.gen'; +export const FindAttackDiscoverySchedulesRequestQuery = lazySchema(() => + z.object({ + /** + * Page number to return (used for pagination). Defaults to 1. + */ + page: z.coerce.number().optional(), + /** + * Number of Attack discovery schedules to return per page (used for pagination). Defaults to 10. + */ + per_page: z.coerce.number().optional(), + /** + * Field used to sort results. Common fields include 'name', 'created_at', 'updated_at', and 'enabled'. + */ + sort_field: NonEmptyString.optional(), + /** + * Sort order direction. Use 'asc' for ascending or 'desc' for descending. Defaults to 'asc'. + */ + sort_direction: z.enum(['asc', 'desc']).optional(), + }) +); export type FindAttackDiscoverySchedulesRequestQuery = z.infer< typeof FindAttackDiscoverySchedulesRequestQuery >; -export const FindAttackDiscoverySchedulesRequestQuery = z.object({ - /** - * Page number to return (used for pagination). Defaults to 1. - */ - page: z.coerce.number().optional(), - /** - * Number of Attack discovery schedules to return per page (used for pagination). Defaults to 10. - */ - per_page: z.coerce.number().optional(), - /** - * Field used to sort results. Common fields include 'name', 'created_at', 'updated_at', and 'enabled'. - */ - sort_field: NonEmptyString.optional(), - /** - * Sort order direction. Use 'asc' for ascending or 'desc' for descending. Defaults to 'asc'. - */ - sort_direction: z.enum(['asc', 'desc']).optional(), -}); export type FindAttackDiscoverySchedulesRequestQueryInput = z.input< typeof FindAttackDiscoverySchedulesRequestQuery >; +export const FindAttackDiscoverySchedulesResponse = lazySchema(() => + z.object({ + /** + * Current page number of the paginated result set. + */ + page: z.number(), + /** + * Number of items requested per page. + */ + per_page: z.number(), + /** + * Total number of Attack discovery schedules matching the query (across all pages). + */ + total: z.number(), + /** + * Array of matched Attack discovery schedule objects. + */ + data: z.array(AttackDiscoveryApiSchedule), + }) +); export type FindAttackDiscoverySchedulesResponse = z.infer< typeof FindAttackDiscoverySchedulesResponse >; -export const FindAttackDiscoverySchedulesResponse = z.object({ - /** - * Current page number of the paginated result set. - */ - page: z.number(), - /** - * Number of items requested per page. - */ - per_page: z.number(), - /** - * Total number of Attack discovery schedules matching the query (across all pages). - */ - total: z.number(), - /** - * Array of matched Attack discovery schedule objects. - */ - data: z.array(AttackDiscoveryApiSchedule), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts index 89043b86d465c..38c1bcc0395a7 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ApiConfig } from '../../../../conversations/common_attributes.gen'; import { NonEmptyString } from '../../../../common_attributes.gen'; @@ -22,90 +22,98 @@ import { NonEmptyString } from '../../../../common_attributes.gen'; /** * An query condition to filter alerts */ +export const Query = lazySchema(() => + z.object({ + query: z.union([z.string(), z.object({}).catchall(z.unknown())]), + language: z.string(), + }) +); export type Query = z.infer; -export const Query = z.object({ - query: z.union([z.string(), z.object({}).catchall(z.unknown())]), - language: z.string(), -}); /** * The filter array used to define the conditions for when alerts are selected as an attack discovery context. Defaults to an empty array. */ +export const Filters = lazySchema(() => z.array(z.unknown())); export type Filters = z.infer; -export const Filters = z.array(z.unknown()); /** * An attack discovery schedule params */ +export const AttackDiscoveryScheduleParams = lazySchema(() => + z.object({ + /** + * The index pattern to get alerts from + */ + alertsIndexPattern: z.string(), + /** + * LLM API configuration. + */ + apiConfig: ApiConfig.merge( + z.object({ + /** + * The name of the connector + */ + name: z.string(), + }) + ), + end: z.string().optional(), + query: Query.optional(), + filters: Filters.optional(), + combinedFilter: z.object({}).catchall(z.unknown()).optional(), + size: z.number(), + start: z.string().optional(), + }) +); export type AttackDiscoveryScheduleParams = z.infer; -export const AttackDiscoveryScheduleParams = z.object({ - /** - * The index pattern to get alerts from - */ - alertsIndexPattern: z.string(), - /** - * LLM API configuration. - */ - apiConfig: ApiConfig.extend( - z.object({ - /** - * The name of the connector - */ - name: z.string(), - }) - ), - end: z.string().optional(), - query: Query.optional(), - filters: Filters.optional(), - combinedFilter: z.object({}).catchall(z.unknown()).optional(), - size: z.number(), - start: z.string().optional(), -}); +export const IntervalSchedule = lazySchema(() => + z.object({ + /** + * The schedule interval + */ + interval: z.string(), + }) +); export type IntervalSchedule = z.infer; -export const IntervalSchedule = z.object({ - /** - * The schedule interval - */ - interval: z.string(), -}); /** * Groups actions by use cases. Use `default` for alert notifications. */ +export const AttackDiscoveryScheduleActionGroup = lazySchema(() => z.string()); export type AttackDiscoveryScheduleActionGroup = z.infer; -export const AttackDiscoveryScheduleActionGroup = z.string(); /** * The connector ID. */ +export const AttackDiscoveryScheduleActionId = lazySchema(() => z.string()); export type AttackDiscoveryScheduleActionId = z.infer; -export const AttackDiscoveryScheduleActionId = z.string(); /** * Object containing the allowed connector fields, which varies according to the connector type. */ +export const AttackDiscoveryScheduleActionParams = lazySchema(() => + z.object({}).catchall(z.unknown()) +); export type AttackDiscoveryScheduleActionParams = z.infer< typeof AttackDiscoveryScheduleActionParams >; -export const AttackDiscoveryScheduleActionParams = z.object({}).catchall(z.unknown()); +export const AttackDiscoveryScheduleActionAlertsFilter = lazySchema(() => + z.object({}).catchall(z.unknown()) +); export type AttackDiscoveryScheduleActionAlertsFilter = z.infer< typeof AttackDiscoveryScheduleActionAlertsFilter >; -export const AttackDiscoveryScheduleActionAlertsFilter = z.object({}).catchall(z.unknown()); /** * The condition for throttling the notification: `onActionGroupChange`, `onActiveAlert`, or `onThrottleInterval` */ +export const AttackDiscoveryScheduleActionNotifyWhen = lazySchema(() => + z.enum(['onActiveAlert', 'onThrottleInterval', 'onActionGroupChange']) +); export type AttackDiscoveryScheduleActionNotifyWhen = z.infer< typeof AttackDiscoveryScheduleActionNotifyWhen >; -export const AttackDiscoveryScheduleActionNotifyWhen = z.enum([ - 'onActiveAlert', - 'onThrottleInterval', - 'onActionGroupChange', -]); export type AttackDiscoveryScheduleActionNotifyWhenEnum = typeof AttackDiscoveryScheduleActionNotifyWhen.enum; export const AttackDiscoveryScheduleActionNotifyWhenEnum = @@ -114,74 +122,77 @@ export const AttackDiscoveryScheduleActionNotifyWhenEnum = /** * Defines how often schedule actions are taken. Time interval in seconds, minutes, hours, or days. */ +export const AttackDiscoveryScheduleActionThrottle = lazySchema(() => + z.string().regex(/^[1-9]\d*[smhd]$/) +); export type AttackDiscoveryScheduleActionThrottle = z.infer< typeof AttackDiscoveryScheduleActionThrottle >; -export const AttackDiscoveryScheduleActionThrottle = z.string().regex(/^[1-9]\d*[smhd]$/); /** * The action frequency defines when the action runs (for example, only on schedule execution or at specific time intervals). */ +export const AttackDiscoveryScheduleActionFrequency = lazySchema(() => + z.object({ + /** + * Action summary indicates whether we will send a summary notification about all the generate alerts or notification per individual alert + */ + summary: z.boolean(), + notifyWhen: AttackDiscoveryScheduleActionNotifyWhen, + throttle: AttackDiscoveryScheduleActionThrottle.nullable(), + }) +); export type AttackDiscoveryScheduleActionFrequency = z.infer< typeof AttackDiscoveryScheduleActionFrequency >; -export const AttackDiscoveryScheduleActionFrequency = z.object({ - /** - * Action summary indicates whether we will send a summary notification about all the generate alerts or notification per individual alert - */ - summary: z.boolean(), - notifyWhen: AttackDiscoveryScheduleActionNotifyWhen, - throttle: AttackDiscoveryScheduleActionThrottle.nullable(), -}); +export const AttackDiscoveryScheduleGeneralAction = lazySchema(() => + z.object({ + /** + * The action type used for sending notifications. + */ + actionTypeId: z.string(), + group: AttackDiscoveryScheduleActionGroup, + id: AttackDiscoveryScheduleActionId, + params: AttackDiscoveryScheduleActionParams, + uuid: NonEmptyString.optional(), + alertsFilter: AttackDiscoveryScheduleActionAlertsFilter.optional(), + frequency: AttackDiscoveryScheduleActionFrequency.optional(), + }) +); export type AttackDiscoveryScheduleGeneralAction = z.infer< typeof AttackDiscoveryScheduleGeneralAction >; -export const AttackDiscoveryScheduleGeneralAction = z.object({ - /** - * The action type used for sending notifications. - */ - actionTypeId: z.string(), - group: AttackDiscoveryScheduleActionGroup, - id: AttackDiscoveryScheduleActionId, - params: AttackDiscoveryScheduleActionParams, - uuid: NonEmptyString.optional(), - alertsFilter: AttackDiscoveryScheduleActionAlertsFilter.optional(), - frequency: AttackDiscoveryScheduleActionFrequency.optional(), -}); +export const AttackDiscoveryScheduleSystemAction = lazySchema(() => + z.object({ + /** + * The action type used for sending notifications. + */ + actionTypeId: z.string(), + id: AttackDiscoveryScheduleActionId, + params: AttackDiscoveryScheduleActionParams, + uuid: NonEmptyString.optional(), + }) +); export type AttackDiscoveryScheduleSystemAction = z.infer< typeof AttackDiscoveryScheduleSystemAction >; -export const AttackDiscoveryScheduleSystemAction = z.object({ - /** - * The action type used for sending notifications. - */ - actionTypeId: z.string(), - id: AttackDiscoveryScheduleActionId, - params: AttackDiscoveryScheduleActionParams, - uuid: NonEmptyString.optional(), -}); +export const AttackDiscoveryScheduleAction = lazySchema(() => + z.union([AttackDiscoveryScheduleGeneralAction, AttackDiscoveryScheduleSystemAction]) +); export type AttackDiscoveryScheduleAction = z.infer; -export const AttackDiscoveryScheduleAction = z.union([ - AttackDiscoveryScheduleGeneralAction, - AttackDiscoveryScheduleSystemAction, -]); /** * An attack discovery schedule execution status */ +export const AttackDiscoveryScheduleExecutionStatus = lazySchema(() => + z.enum(['ok', 'active', 'error', 'unknown', 'warning']) +); export type AttackDiscoveryScheduleExecutionStatus = z.infer< typeof AttackDiscoveryScheduleExecutionStatus >; -export const AttackDiscoveryScheduleExecutionStatus = z.enum([ - 'ok', - 'active', - 'error', - 'unknown', - 'warning', -]); export type AttackDiscoveryScheduleExecutionStatusEnum = typeof AttackDiscoveryScheduleExecutionStatus.enum; export const AttackDiscoveryScheduleExecutionStatusEnum = @@ -190,120 +201,128 @@ export const AttackDiscoveryScheduleExecutionStatusEnum = /** * An attack discovery schedule execution information */ +export const AttackDiscoveryScheduleExecution = lazySchema(() => + z.object({ + /** + * Date of the execution + */ + date: z.string().datetime(), + /** + * Duration of the execution + */ + duration: z.number().optional(), + /** + * Status of the execution + */ + status: AttackDiscoveryScheduleExecutionStatus, + message: z.string().optional(), + }) +); export type AttackDiscoveryScheduleExecution = z.infer; -export const AttackDiscoveryScheduleExecution = z.object({ - /** - * Date of the execution - */ - date: z.string().datetime(), - /** - * Duration of the execution - */ - duration: z.number().optional(), - /** - * Status of the execution - */ - status: AttackDiscoveryScheduleExecutionStatus, - message: z.string().optional(), -}); /** * An attack discovery schedule */ +export const AttackDiscoverySchedule = lazySchema(() => + z.object({ + /** + * UUID of attack discovery schedule + */ + id: z.string(), + /** + * The name of the schedule + */ + name: z.string(), + /** + * The name of the user that created the schedule + */ + createdBy: z.string(), + /** + * The name of the user that updated the schedule + */ + updatedBy: z.string(), + /** + * The date the schedule was created + */ + createdAt: z.string().datetime(), + /** + * The date the schedule was updated + */ + updatedAt: z.string().datetime(), + /** + * Indicates whether the schedule is enabled + */ + enabled: z.boolean(), + /** + * The attack discovery schedule configuration parameters + */ + params: AttackDiscoveryScheduleParams, + /** + * The attack discovery schedule interval + */ + schedule: IntervalSchedule, + /** + * The attack discovery schedule actions + */ + actions: z.array(AttackDiscoveryScheduleAction), + /** + * The attack discovery schedule last execution summary + */ + lastExecution: AttackDiscoveryScheduleExecution.optional(), + }) +); export type AttackDiscoverySchedule = z.infer; -export const AttackDiscoverySchedule = z.object({ - /** - * UUID of attack discovery schedule - */ - id: z.string(), - /** - * The name of the schedule - */ - name: z.string(), - /** - * The name of the user that created the schedule - */ - createdBy: z.string(), - /** - * The name of the user that updated the schedule - */ - updatedBy: z.string(), - /** - * The date the schedule was created - */ - createdAt: z.string().datetime(), - /** - * The date the schedule was updated - */ - updatedAt: z.string().datetime(), - /** - * Indicates whether the schedule is enabled - */ - enabled: z.boolean(), - /** - * The attack discovery schedule configuration parameters - */ - params: AttackDiscoveryScheduleParams, - /** - * The attack discovery schedule interval - */ - schedule: IntervalSchedule, - /** - * The attack discovery schedule actions - */ - actions: z.array(AttackDiscoveryScheduleAction), - /** - * The attack discovery schedule last execution summary - */ - lastExecution: AttackDiscoveryScheduleExecution.optional(), -}); /** * An attack discovery schedule create properties */ +export const AttackDiscoveryScheduleCreateProps = lazySchema(() => + z.object({ + /** + * The name of the schedule + */ + name: z.string(), + /** + * Indicates whether the schedule is enabled + */ + enabled: z.boolean().optional(), + /** + * The attack discovery schedule configuration parameters + */ + params: AttackDiscoveryScheduleParams, + /** + * The attack discovery schedule interval + */ + schedule: IntervalSchedule, + /** + * The attack discovery schedule actions + */ + actions: z.array(AttackDiscoveryScheduleAction).optional(), + }) +); export type AttackDiscoveryScheduleCreateProps = z.infer; -export const AttackDiscoveryScheduleCreateProps = z.object({ - /** - * The name of the schedule - */ - name: z.string(), - /** - * Indicates whether the schedule is enabled - */ - enabled: z.boolean().optional(), - /** - * The attack discovery schedule configuration parameters - */ - params: AttackDiscoveryScheduleParams, - /** - * The attack discovery schedule interval - */ - schedule: IntervalSchedule, - /** - * The attack discovery schedule actions - */ - actions: z.array(AttackDiscoveryScheduleAction).optional(), -}); /** * An attack discovery schedule update properties */ +export const AttackDiscoveryScheduleUpdateProps = lazySchema(() => + z.object({ + /** + * The name of the schedule + */ + name: z.string(), + /** + * The attack discovery schedule configuration parameters + */ + params: AttackDiscoveryScheduleParams, + /** + * The attack discovery schedule interval + */ + schedule: IntervalSchedule, + /** + * The attack discovery schedule actions + */ + actions: z.array(AttackDiscoveryScheduleAction), + }) +); export type AttackDiscoveryScheduleUpdateProps = z.infer; -export const AttackDiscoveryScheduleUpdateProps = z.object({ - /** - * The name of the schedule - */ - name: z.string(), - /** - * The attack discovery schedule configuration parameters - */ - params: AttackDiscoveryScheduleParams, - /** - * The attack discovery schedule interval - */ - schedule: IntervalSchedule, - /** - * The attack discovery schedule actions - */ - actions: z.array(AttackDiscoveryScheduleAction), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts index 460ee5ccc9b30..7991df10a900b 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/attack_discovery/routes/public/schedules/schedules_api.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ApiConfig } from '../../../../conversations/common_attributes.gen'; import { NonEmptyString } from '../../../../common_attributes.gen'; @@ -22,92 +22,100 @@ import { NonEmptyString } from '../../../../common_attributes.gen'; /** * An query condition to filter alerts */ +export const Query = lazySchema(() => + z.object({ + query: z.union([z.string(), z.object({}).catchall(z.unknown())]), + language: z.string(), + }) +); export type Query = z.infer; -export const Query = z.object({ - query: z.union([z.string(), z.object({}).catchall(z.unknown())]), - language: z.string(), -}); /** * The filter array used to define the conditions for when alerts are selected as an attack discovery context. Defaults to an empty array. */ +export const Filters = lazySchema(() => z.array(z.unknown())); export type Filters = z.infer; -export const Filters = z.array(z.unknown()); /** * An attack discovery schedule params */ +export const AttackDiscoveryApiScheduleParams = lazySchema(() => + z.object({ + /** + * The index pattern to get alerts from + */ + alerts_index_pattern: z.string(), + /** + * LLM API configuration. + */ + api_config: ApiConfig.merge( + z.object({ + /** + * The name of the connector + */ + name: z.string(), + }) + ), + end: z.string().optional(), + query: Query.optional(), + filters: Filters.optional(), + combined_filter: z.object({}).catchall(z.unknown()).optional(), + size: z.number(), + start: z.string().optional(), + }) +); export type AttackDiscoveryApiScheduleParams = z.infer; -export const AttackDiscoveryApiScheduleParams = z.object({ - /** - * The index pattern to get alerts from - */ - alerts_index_pattern: z.string(), - /** - * LLM API configuration. - */ - api_config: ApiConfig.extend( - z.object({ - /** - * The name of the connector - */ - name: z.string(), - }) - ), - end: z.string().optional(), - query: Query.optional(), - filters: Filters.optional(), - combined_filter: z.object({}).catchall(z.unknown()).optional(), - size: z.number(), - start: z.string().optional(), -}); +export const IntervalApiSchedule = lazySchema(() => + z.object({ + /** + * The schedule interval + */ + interval: z.string(), + }) +); export type IntervalApiSchedule = z.infer; -export const IntervalApiSchedule = z.object({ - /** - * The schedule interval - */ - interval: z.string(), -}); /** * Groups actions by use cases. Use `default` for alert notifications. */ +export const AttackDiscoveryApiScheduleActionGroup = lazySchema(() => z.string()); export type AttackDiscoveryApiScheduleActionGroup = z.infer< typeof AttackDiscoveryApiScheduleActionGroup >; -export const AttackDiscoveryApiScheduleActionGroup = z.string(); /** * The connector ID. */ +export const AttackDiscoveryApiScheduleActionId = lazySchema(() => z.string()); export type AttackDiscoveryApiScheduleActionId = z.infer; -export const AttackDiscoveryApiScheduleActionId = z.string(); /** * Object containing the allowed connector fields, which varies according to the connector type. */ +export const AttackDiscoveryApiScheduleActionParams = lazySchema(() => + z.object({}).catchall(z.unknown()) +); export type AttackDiscoveryApiScheduleActionParams = z.infer< typeof AttackDiscoveryApiScheduleActionParams >; -export const AttackDiscoveryApiScheduleActionParams = z.object({}).catchall(z.unknown()); +export const AttackDiscoveryApiScheduleActionAlertsFilter = lazySchema(() => + z.object({}).catchall(z.unknown()) +); export type AttackDiscoveryApiScheduleActionAlertsFilter = z.infer< typeof AttackDiscoveryApiScheduleActionAlertsFilter >; -export const AttackDiscoveryApiScheduleActionAlertsFilter = z.object({}).catchall(z.unknown()); /** * The condition for throttling the notification: `onActionGroupChange`, `onActiveAlert`, or `onThrottleInterval` */ +export const AttackDiscoveryApiScheduleActionNotifyWhen = lazySchema(() => + z.enum(['onActiveAlert', 'onThrottleInterval', 'onActionGroupChange']) +); export type AttackDiscoveryApiScheduleActionNotifyWhen = z.infer< typeof AttackDiscoveryApiScheduleActionNotifyWhen >; -export const AttackDiscoveryApiScheduleActionNotifyWhen = z.enum([ - 'onActiveAlert', - 'onThrottleInterval', - 'onActionGroupChange', -]); export type AttackDiscoveryApiScheduleActionNotifyWhenEnum = typeof AttackDiscoveryApiScheduleActionNotifyWhen.enum; export const AttackDiscoveryApiScheduleActionNotifyWhenEnum = @@ -116,74 +124,77 @@ export const AttackDiscoveryApiScheduleActionNotifyWhenEnum = /** * Defines how often schedule actions are taken. Time interval in seconds, minutes, hours, or days. */ +export const AttackDiscoveryApiScheduleActionThrottle = lazySchema(() => + z.string().regex(/^[1-9]\d*[smhd]$/) +); export type AttackDiscoveryApiScheduleActionThrottle = z.infer< typeof AttackDiscoveryApiScheduleActionThrottle >; -export const AttackDiscoveryApiScheduleActionThrottle = z.string().regex(/^[1-9]\d*[smhd]$/); /** * The action frequency defines when the action runs (for example, only on schedule execution or at specific time intervals). */ +export const AttackDiscoveryApiScheduleActionFrequency = lazySchema(() => + z.object({ + /** + * Action summary indicates whether we will send a summary notification about all the generate alerts or notification per individual alert + */ + summary: z.boolean(), + notify_when: AttackDiscoveryApiScheduleActionNotifyWhen, + throttle: AttackDiscoveryApiScheduleActionThrottle.nullable(), + }) +); export type AttackDiscoveryApiScheduleActionFrequency = z.infer< typeof AttackDiscoveryApiScheduleActionFrequency >; -export const AttackDiscoveryApiScheduleActionFrequency = z.object({ - /** - * Action summary indicates whether we will send a summary notification about all the generate alerts or notification per individual alert - */ - summary: z.boolean(), - notify_when: AttackDiscoveryApiScheduleActionNotifyWhen, - throttle: AttackDiscoveryApiScheduleActionThrottle.nullable(), -}); +export const AttackDiscoveryApiScheduleGeneralAction = lazySchema(() => + z.object({ + /** + * The action type used for sending notifications. + */ + action_type_id: z.string(), + group: AttackDiscoveryApiScheduleActionGroup, + id: AttackDiscoveryApiScheduleActionId, + params: AttackDiscoveryApiScheduleActionParams, + uuid: NonEmptyString.optional(), + alerts_filter: AttackDiscoveryApiScheduleActionAlertsFilter.optional(), + frequency: AttackDiscoveryApiScheduleActionFrequency.optional(), + }) +); export type AttackDiscoveryApiScheduleGeneralAction = z.infer< typeof AttackDiscoveryApiScheduleGeneralAction >; -export const AttackDiscoveryApiScheduleGeneralAction = z.object({ - /** - * The action type used for sending notifications. - */ - action_type_id: z.string(), - group: AttackDiscoveryApiScheduleActionGroup, - id: AttackDiscoveryApiScheduleActionId, - params: AttackDiscoveryApiScheduleActionParams, - uuid: NonEmptyString.optional(), - alerts_filter: AttackDiscoveryApiScheduleActionAlertsFilter.optional(), - frequency: AttackDiscoveryApiScheduleActionFrequency.optional(), -}); +export const AttackDiscoveryApiScheduleSystemAction = lazySchema(() => + z.object({ + /** + * The action type used for sending notifications. + */ + action_type_id: z.string(), + id: AttackDiscoveryApiScheduleActionId, + params: AttackDiscoveryApiScheduleActionParams, + uuid: NonEmptyString.optional(), + }) +); export type AttackDiscoveryApiScheduleSystemAction = z.infer< typeof AttackDiscoveryApiScheduleSystemAction >; -export const AttackDiscoveryApiScheduleSystemAction = z.object({ - /** - * The action type used for sending notifications. - */ - action_type_id: z.string(), - id: AttackDiscoveryApiScheduleActionId, - params: AttackDiscoveryApiScheduleActionParams, - uuid: NonEmptyString.optional(), -}); +export const AttackDiscoveryApiScheduleAction = lazySchema(() => + z.union([AttackDiscoveryApiScheduleGeneralAction, AttackDiscoveryApiScheduleSystemAction]) +); export type AttackDiscoveryApiScheduleAction = z.infer; -export const AttackDiscoveryApiScheduleAction = z.union([ - AttackDiscoveryApiScheduleGeneralAction, - AttackDiscoveryApiScheduleSystemAction, -]); /** * An attack discovery schedule execution status */ +export const AttackDiscoveryApiScheduleExecutionStatus = lazySchema(() => + z.enum(['ok', 'active', 'error', 'unknown', 'warning']) +); export type AttackDiscoveryApiScheduleExecutionStatus = z.infer< typeof AttackDiscoveryApiScheduleExecutionStatus >; -export const AttackDiscoveryApiScheduleExecutionStatus = z.enum([ - 'ok', - 'active', - 'error', - 'unknown', - 'warning', -]); export type AttackDiscoveryApiScheduleExecutionStatusEnum = typeof AttackDiscoveryApiScheduleExecutionStatus.enum; export const AttackDiscoveryApiScheduleExecutionStatusEnum = @@ -192,126 +203,134 @@ export const AttackDiscoveryApiScheduleExecutionStatusEnum = /** * An attack discovery schedule execution information */ +export const AttackDiscoveryApiScheduleExecution = lazySchema(() => + z.object({ + /** + * Date of the execution + */ + date: z.string().datetime(), + /** + * Duration of the execution + */ + duration: z.number().optional(), + /** + * Status of the execution + */ + status: AttackDiscoveryApiScheduleExecutionStatus, + message: z.string().optional(), + }) +); export type AttackDiscoveryApiScheduleExecution = z.infer< typeof AttackDiscoveryApiScheduleExecution >; -export const AttackDiscoveryApiScheduleExecution = z.object({ - /** - * Date of the execution - */ - date: z.string().datetime(), - /** - * Duration of the execution - */ - duration: z.number().optional(), - /** - * Status of the execution - */ - status: AttackDiscoveryApiScheduleExecutionStatus, - message: z.string().optional(), -}); /** * An attack discovery schedule */ +export const AttackDiscoveryApiSchedule = lazySchema(() => + z.object({ + /** + * UUID of attack discovery schedule + */ + id: z.string(), + /** + * The name of the schedule + */ + name: z.string(), + /** + * The name of the user that created the schedule + */ + created_by: z.string(), + /** + * The name of the user that updated the schedule + */ + updated_by: z.string(), + /** + * The date the schedule was created + */ + created_at: z.string().datetime(), + /** + * The date the schedule was updated + */ + updated_at: z.string().datetime(), + /** + * Indicates whether the schedule is enabled + */ + enabled: z.boolean(), + /** + * The attack discovery schedule configuration parameters + */ + params: AttackDiscoveryApiScheduleParams, + /** + * The attack discovery schedule interval + */ + schedule: IntervalApiSchedule, + /** + * The attack discovery schedule actions + */ + actions: z.array(AttackDiscoveryApiScheduleAction), + /** + * The attack discovery schedule last execution summary + */ + last_execution: AttackDiscoveryApiScheduleExecution.optional(), + }) +); export type AttackDiscoveryApiSchedule = z.infer; -export const AttackDiscoveryApiSchedule = z.object({ - /** - * UUID of attack discovery schedule - */ - id: z.string(), - /** - * The name of the schedule - */ - name: z.string(), - /** - * The name of the user that created the schedule - */ - created_by: z.string(), - /** - * The name of the user that updated the schedule - */ - updated_by: z.string(), - /** - * The date the schedule was created - */ - created_at: z.string().datetime(), - /** - * The date the schedule was updated - */ - updated_at: z.string().datetime(), - /** - * Indicates whether the schedule is enabled - */ - enabled: z.boolean(), - /** - * The attack discovery schedule configuration parameters - */ - params: AttackDiscoveryApiScheduleParams, - /** - * The attack discovery schedule interval - */ - schedule: IntervalApiSchedule, - /** - * The attack discovery schedule actions - */ - actions: z.array(AttackDiscoveryApiScheduleAction), - /** - * The attack discovery schedule last execution summary - */ - last_execution: AttackDiscoveryApiScheduleExecution.optional(), -}); /** * An attack discovery schedule create properties */ +export const AttackDiscoveryApiScheduleCreateProps = lazySchema(() => + z.object({ + /** + * The name of the schedule + */ + name: z.string(), + /** + * Indicates whether the schedule is enabled + */ + enabled: z.boolean().optional(), + /** + * The attack discovery schedule configuration parameters + */ + params: AttackDiscoveryApiScheduleParams, + /** + * The attack discovery schedule interval + */ + schedule: IntervalApiSchedule, + /** + * The attack discovery schedule actions + */ + actions: z.array(AttackDiscoveryApiScheduleAction).optional(), + }) +); export type AttackDiscoveryApiScheduleCreateProps = z.infer< typeof AttackDiscoveryApiScheduleCreateProps >; -export const AttackDiscoveryApiScheduleCreateProps = z.object({ - /** - * The name of the schedule - */ - name: z.string(), - /** - * Indicates whether the schedule is enabled - */ - enabled: z.boolean().optional(), - /** - * The attack discovery schedule configuration parameters - */ - params: AttackDiscoveryApiScheduleParams, - /** - * The attack discovery schedule interval - */ - schedule: IntervalApiSchedule, - /** - * The attack discovery schedule actions - */ - actions: z.array(AttackDiscoveryApiScheduleAction).optional(), -}); /** * An attack discovery schedule update properties */ +export const AttackDiscoveryApiScheduleUpdateProps = lazySchema(() => + z.object({ + /** + * The name of the schedule + */ + name: z.string(), + /** + * The attack discovery schedule configuration parameters + */ + params: AttackDiscoveryApiScheduleParams, + /** + * The attack discovery schedule interval + */ + schedule: IntervalApiSchedule, + /** + * The attack discovery schedule actions + */ + actions: z.array(AttackDiscoveryApiScheduleAction), + }) +); export type AttackDiscoveryApiScheduleUpdateProps = z.infer< typeof AttackDiscoveryApiScheduleUpdateProps >; -export const AttackDiscoveryApiScheduleUpdateProps = z.object({ - /** - * The name of the schedule - */ - name: z.string(), - /** - * The attack discovery schedule configuration parameters - */ - params: AttackDiscoveryApiScheduleParams, - /** - * The attack discovery schedule interval - */ - schedule: IntervalApiSchedule, - /** - * The attack discovery schedule actions - */ - actions: z.array(AttackDiscoveryApiScheduleAction), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/capabilities/get_capabilities_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/capabilities/get_capabilities_route.gen.ts index e76aa816d34f8..92178f2d481f0 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/capabilities/get_capabilities_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/capabilities/get_capabilities_route.gen.ts @@ -14,10 +14,12 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const GetCapabilitiesResponse = lazySchema(() => + z.object({ + assistantModelEvaluation: z.boolean(), + defendInsightsPolicyResponseFailure: z.boolean(), + }) +); export type GetCapabilitiesResponse = z.infer; -export const GetCapabilitiesResponse = z.object({ - assistantModelEvaluation: z.boolean(), - defendInsightsPolicyResponseFailure: z.boolean(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts index 3ef8d048af406..53f2a2e364382 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '../common_attributes.gen'; @@ -22,102 +22,108 @@ import { NonEmptyString } from '../common_attributes.gen'; /** * The operational context for the assistant. */ +export const RootContext = lazySchema(() => z.literal('security')); export type RootContext = z.infer; -export const RootContext = z.literal('security'); /** * The role associated with the message in the chat. */ +export const ChatMessageRole = lazySchema(() => z.enum(['system', 'user', 'assistant'])); export type ChatMessageRole = z.infer; -export const ChatMessageRole = z.enum(['system', 'user', 'assistant']); export type ChatMessageRoleEnum = typeof ChatMessageRole.enum; export const ChatMessageRoleEnum = ChatMessageRole.enum; /** * ECS-style metadata attached to the message. */ +export const MessageData = lazySchema(() => z.object({}).catchall(z.unknown())); export type MessageData = z.infer; -export const MessageData = z.object({}).catchall(z.unknown()); /** * A message exchanged within the AI chat conversation. */ +export const ChatMessage = lazySchema(() => + z.object({ + /** + * The textual content of the message. + */ + content: z.string().optional(), + /** + * The sender role of the message. + */ + role: ChatMessageRole, + /** + * Metadata to attach to the context of the message. + */ + data: MessageData.optional(), + /** + * List of field names within the data object that should be anonymized. + */ + fields_to_anonymize: z.array(z.string()).optional(), + }) +); export type ChatMessage = z.infer; -export const ChatMessage = z.object({ - /** - * The textual content of the message. - */ - content: z.string().optional(), - /** - * The sender role of the message. - */ - role: ChatMessageRole, - /** - * Metadata to attach to the context of the message. - */ - data: MessageData.optional(), - /** - * List of field names within the data object that should be anonymized. - */ - fields_to_anonymize: z.array(z.string()).optional(), -}); /** * The request payload for creating a chat completion. */ +export const ChatCompleteProps = lazySchema(() => + z.object({ + /** + * Existing conversation ID to continue. + */ + conversationId: NonEmptyString.optional(), + /** + * Prompt template identifier. + */ + promptId: z.string().optional(), + /** + * If true, the response will be streamed in chunks. + */ + isStream: z.boolean().optional(), + /** + * ISO language code for the assistant's response. + */ + responseLanguage: z.string().optional(), + /** + * LangSmith project name for tracing. + */ + langSmithProject: z.string().optional(), + /** + * API key for LangSmith integration. + */ + langSmithApiKey: z.string().optional(), + /** + * Required connector identifier to route the request. + */ + connectorId: z.string(), + /** + * Model ID or name to use for the response. + */ + model: z.string().optional(), + /** + * Whether to persist the chat and response to storage. + */ + persist: z.boolean(), + /** + * List of chat messages exchanged so far. + */ + messages: z.array(ChatMessage), + }) +); export type ChatCompleteProps = z.infer; -export const ChatCompleteProps = z.object({ - /** - * Existing conversation ID to continue. - */ - conversationId: NonEmptyString.optional(), - /** - * Prompt template identifier. - */ - promptId: z.string().optional(), - /** - * If true, the response will be streamed in chunks. - */ - isStream: z.boolean().optional(), - /** - * ISO language code for the assistant's response. - */ - responseLanguage: z.string().optional(), - /** - * LangSmith project name for tracing. - */ - langSmithProject: z.string().optional(), - /** - * API key for LangSmith integration. - */ - langSmithApiKey: z.string().optional(), - /** - * Required connector identifier to route the request. - */ - connectorId: z.string(), - /** - * Model ID or name to use for the response. - */ - model: z.string().optional(), - /** - * Whether to persist the chat and response to storage. - */ - persist: z.boolean(), - /** - * List of chat messages exchanged so far. - */ - messages: z.array(ChatMessage), -}); +export const ChatCompleteRequestQuery = lazySchema(() => + z.object({ + /** + * If true, the response will not include content references. + */ + content_references_disabled: BooleanFromString.optional().default(false), + }) +); export type ChatCompleteRequestQuery = z.infer; -export const ChatCompleteRequestQuery = z.object({ - /** - * If true, the response will not include content references. - */ - content_references_disabled: BooleanFromString.optional().default(false), -}); export type ChatCompleteRequestQueryInput = z.input; +export const ChatCompleteRequestBody = lazySchema(() => ChatCompleteProps); export type ChatCompleteRequestBody = z.infer; -export const ChatCompleteRequestBody = ChatCompleteProps; export type ChatCompleteRequestBodyInput = z.input; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/common_attributes.gen.ts index abe5c57c65b9d..ba8effe2d9d8a 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/common_attributes.gen.ts @@ -14,104 +14,114 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; /** * A string that does not contain only whitespace characters. */ +export const NonEmptyString = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type NonEmptyString = z.infer; -export const NonEmptyString = z.string().min(1).superRefine(isNonEmptyString); /** * A string that represents a timestamp in ISO 8601 format and does not contain only whitespace characters. */ +export const NonEmptyTimestamp = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type NonEmptyTimestamp = z.infer; -export const NonEmptyTimestamp = z.string().min(1).superRefine(isNonEmptyString); /** * A universally unique identifier. */ +export const UUID = lazySchema(() => z.string().uuid()); export type UUID = z.infer; -export const UUID = z.string().uuid(); /** * Could be any string, not necessarily a UUID. */ +export const User = lazySchema(() => + z.object({ + /** + * User id. + */ + id: z.string().optional(), + /** + * User name. + */ + name: z.string().optional(), + }) +); export type User = z.infer; -export const User = z.object({ - /** - * User id. - */ - id: z.string().optional(), - /** - * User name. - */ - name: z.string().optional(), -}); /** * The order in which results are sorted. */ +export const SortOrder = lazySchema(() => z.enum(['asc', 'desc'])); export type SortOrder = z.infer; -export const SortOrder = z.enum(['asc', 'desc']); export type SortOrderEnum = typeof SortOrder.enum; export const SortOrderEnum = SortOrder.enum; /** * User screen context. */ +export const ScreenContext = lazySchema(() => + z.object({ + /** + * The local timezone of the user. + */ + timeZone: z.string().optional(), + }) +); export type ScreenContext = z.infer; -export const ScreenContext = z.object({ - /** - * The local timezone of the user. - */ - timeZone: z.string().optional(), -}); +export const BulkCrudActionSummary = lazySchema(() => + z.object({ + /** + * The number of failed actions. + */ + failed: z.number().int(), + /** + * The number of skipped actions. + */ + skipped: z.number().int(), + /** + * The number of successfully performed actions. + */ + succeeded: z.number().int(), + /** + * The total number of actions attempted. + */ + total: z.number().int(), + }) +); export type BulkCrudActionSummary = z.infer; -export const BulkCrudActionSummary = z.object({ - /** - * The number of failed actions. - */ - failed: z.number().int(), - /** - * The number of skipped actions. - */ - skipped: z.number().int(), - /** - * The number of successfully performed actions. - */ - succeeded: z.number().int(), - /** - * The total number of actions attempted. - */ - total: z.number().int(), -}); +export const BulkActionBase = lazySchema(() => + z.object({ + /** + * Query to filter the bulk action. + */ + query: z.string().optional(), + /** + * Array of IDs to apply the action to. + */ + ids: z.array(z.string()).min(1).optional(), + }) +); export type BulkActionBase = z.infer; -export const BulkActionBase = z.object({ - /** - * Query to filter the bulk action. - */ - query: z.string().optional(), - /** - * Array of IDs to apply the action to. - */ - ids: z.array(z.string()).min(1).optional(), -}); /** * IDs for a specific prompt within a group of prompts. */ +export const PromptIds = lazySchema(() => + z.object({ + /** + * The unique identifier for a specific prompt. + */ + promptId: z.string(), + /** + * The unique identifier for a group of prompts. + */ + promptGroupId: z.string(), + }) +); export type PromptIds = z.infer; -export const PromptIds = z.object({ - /** - * The unique identifier for a specific prompt. - */ - promptId: z.string(), - /** - * The unique identifier for a group of prompts. - */ - promptGroupId: z.string(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/append_message.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/append_message.gen.ts index 5aa32aec0ab97..615095dee0b0d 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/append_message.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/append_message.gen.ts @@ -14,31 +14,35 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../common_attributes.gen'; import { ConversationMessageCreateProps, ConversationResponse } from './common_attributes.gen'; +export const AppendConversationMessageRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (`id`) of the conversation to which the message will be appended. + */ + id: NonEmptyString, + }) +); export type AppendConversationMessageRequestParams = z.infer< typeof AppendConversationMessageRequestParams >; -export const AppendConversationMessageRequestParams = z.object({ - /** - * The unique identifier (`id`) of the conversation to which the message will be appended. - */ - id: NonEmptyString, -}); export type AppendConversationMessageRequestParamsInput = z.input< typeof AppendConversationMessageRequestParams >; +export const AppendConversationMessageRequestBody = lazySchema( + () => ConversationMessageCreateProps +); export type AppendConversationMessageRequestBody = z.infer< typeof AppendConversationMessageRequestBody >; -export const AppendConversationMessageRequestBody = ConversationMessageCreateProps; export type AppendConversationMessageRequestBodyInput = z.input< typeof AppendConversationMessageRequestBody >; +export const AppendConversationMessageResponse = lazySchema(() => ConversationResponse); export type AppendConversationMessageResponse = z.infer; -export const AppendConversationMessageResponse = ConversationResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/bulk_crud_conversations_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/bulk_crud_conversations_route.gen.ts index 59627ed1dad33..ea31557c9afa3 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/bulk_crud_conversations_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/bulk_crud_conversations_route.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BulkActionBase, BulkCrudActionSummary } from '../common_attributes.gen'; import { @@ -26,120 +26,134 @@ import { /** * Reason for skipping a conversation during bulk action. */ +export const ConversationsBulkActionSkipReason = lazySchema(() => + z.literal('CONVERSATION_NOT_MODIFIED') +); export type ConversationsBulkActionSkipReason = z.infer; -export const ConversationsBulkActionSkipReason = z.literal('CONVERSATION_NOT_MODIFIED'); +export const ConversationsBulkActionSkipResult = lazySchema(() => + z.object({ + /** + * The ID of the conversation that was skipped. + */ + id: z.string(), + /** + * The name of the conversation that was skipped. + */ + name: z.string().optional(), + /** + * The reason the conversation was skipped. + */ + skip_reason: ConversationsBulkActionSkipReason, + }) +); export type ConversationsBulkActionSkipResult = z.infer; -export const ConversationsBulkActionSkipResult = z.object({ - /** - * The ID of the conversation that was skipped. - */ - id: z.string(), - /** - * The name of the conversation that was skipped. - */ - name: z.string().optional(), - /** - * The reason the conversation was skipped. - */ - skip_reason: ConversationsBulkActionSkipReason, -}); +export const ConversationDetailsInError = lazySchema(() => + z.object({ + /** + * The ID of the conversation that encountered an error. + */ + id: z.string(), + /** + * The name of the conversation in error. + */ + name: z.string().optional(), + }) +); export type ConversationDetailsInError = z.infer; -export const ConversationDetailsInError = z.object({ - /** - * The ID of the conversation that encountered an error. - */ - id: z.string(), - /** - * The name of the conversation in error. - */ - name: z.string().optional(), -}); +export const NormalizedConversationError = lazySchema(() => + z.object({ + /** + * Error message. + */ + message: z.string(), + /** + * HTTP status code for the error. + */ + status_code: z.number().int(), + /** + * A specific error code identifying the error. + */ + err_code: z.string().optional(), + /** + * A list of conversations that caused errors. + */ + conversations: z.array(ConversationDetailsInError), + }) +); export type NormalizedConversationError = z.infer; -export const NormalizedConversationError = z.object({ - /** - * Error message. - */ - message: z.string(), - /** - * HTTP status code for the error. - */ - status_code: z.number().int(), - /** - * A specific error code identifying the error. - */ - err_code: z.string().optional(), - /** - * A list of conversations that caused errors. - */ - conversations: z.array(ConversationDetailsInError), -}); +export const ConversationsBulkCrudActionResults = lazySchema(() => + z.object({ + /** + * List of conversations that were successfully updated. + */ + updated: z.array(ConversationResponse), + /** + * List of conversations that were successfully created. + */ + created: z.array(ConversationResponse), + /** + * List of conversation IDs that were successfully deleted. + */ + deleted: z.array(z.string()), + /** + * List of conversations that were skipped during the bulk action. + */ + skipped: z.array(ConversationsBulkActionSkipResult), + }) +); export type ConversationsBulkCrudActionResults = z.infer; -export const ConversationsBulkCrudActionResults = z.object({ - /** - * List of conversations that were successfully updated. - */ - updated: z.array(ConversationResponse), - /** - * List of conversations that were successfully created. - */ - created: z.array(ConversationResponse), - /** - * List of conversation IDs that were successfully deleted. - */ - deleted: z.array(z.string()), - /** - * List of conversations that were skipped during the bulk action. - */ - skipped: z.array(ConversationsBulkActionSkipResult), -}); +export const ConversationsBulkCrudActionResponse = lazySchema(() => + z.object({ + /** + * Indicates whether the bulk action was successful. + */ + success: z.boolean().optional(), + /** + * The HTTP status code returned for the bulk action. + */ + status_code: z.number().int().optional(), + /** + * A message providing additional details about the bulk action result. + */ + message: z.string().optional(), + /** + * The total number of conversations involved in the bulk action. + */ + conversations_count: z.number().int().optional(), + attributes: z.object({ + results: ConversationsBulkCrudActionResults, + summary: BulkCrudActionSummary, + errors: z.array(NormalizedConversationError).optional(), + }), + }) +); export type ConversationsBulkCrudActionResponse = z.infer< typeof ConversationsBulkCrudActionResponse >; -export const ConversationsBulkCrudActionResponse = z.object({ - /** - * Indicates whether the bulk action was successful. - */ - success: z.boolean().optional(), - /** - * The HTTP status code returned for the bulk action. - */ - status_code: z.number().int().optional(), - /** - * A message providing additional details about the bulk action result. - */ - message: z.string().optional(), - /** - * The total number of conversations involved in the bulk action. - */ - conversations_count: z.number().int().optional(), - attributes: z.object({ - results: ConversationsBulkCrudActionResults, - summary: BulkCrudActionSummary, - errors: z.array(NormalizedConversationError).optional(), - }), -}); +export const PerformBulkActionRequestBody = lazySchema(() => + z.object({ + /** + * Details of the bulk delete action to apply. + */ + delete: BulkActionBase.optional(), + /** + * List of conversations to create in bulk. + */ + create: z.array(ConversationCreateProps).optional(), + /** + * List of conversations to update in bulk. + */ + update: z.array(ConversationUpdateProps).optional(), + }) +); export type PerformBulkActionRequestBody = z.infer; -export const PerformBulkActionRequestBody = z.object({ - /** - * Details of the bulk delete action to apply. - */ - delete: BulkActionBase.optional(), - /** - * List of conversations to create in bulk. - */ - create: z.array(ConversationCreateProps).optional(), - /** - * List of conversations to update in bulk. - */ - update: z.array(ConversationUpdateProps).optional(), -}); export type PerformBulkActionRequestBodyInput = z.input; +export const PerformBulkActionResponse = lazySchema(() => ConversationsBulkCrudActionResponse); export type PerformBulkActionResponse = z.infer; -export const PerformBulkActionResponse = ConversationsBulkCrudActionResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts index cdcebfd37f0ca..decf3801a2304 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/common_attributes.gen.ts @@ -14,327 +14,364 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString, User, NonEmptyTimestamp } from '../common_attributes.gen'; /** * Trace Data */ +export const TraceData = lazySchema(() => + z.object({ + /** + * Could be any string, not necessarily a UUID + */ + transactionId: z.string().optional(), + /** + * Could be any string, not necessarily a UUID + */ + traceId: z.string().optional(), + }) +); export type TraceData = z.infer; -export const TraceData = z.object({ - /** - * Could be any string, not necessarily a UUID - */ - transactionId: z.string().optional(), - /** - * Could be any string, not necessarily a UUID - */ - traceId: z.string().optional(), -}); /** * The type of interrupt */ +export const InterruptType = lazySchema(() => z.enum(['SELECT_OPTION', 'INPUT_TEXT'])); export type InterruptType = z.infer; -export const InterruptType = z.enum(['SELECT_OPTION', 'INPUT_TEXT']); export type InterruptTypeEnum = typeof InterruptType.enum; export const InterruptTypeEnum = InterruptType.enum; /** * The basis of an agent interrupt */ +export const BaseInterruptValue = lazySchema(() => + z.object({ + /** + * Type of the interrupt + */ + type: InterruptType, + /** + * Whether the interrupt has expired and can no longer be resumed. + */ + expired: z.boolean().optional(), + /** + * Thread ID of the graph execution that produced this message. + */ + threadId: z.string(), + }) +); export type BaseInterruptValue = z.infer; -export const BaseInterruptValue = z.object({ - /** - * Type of the interrupt - */ - type: InterruptType, - /** - * Whether the interrupt has expired and can no longer be resumed. - */ - expired: z.boolean().optional(), - /** - * Thread ID of the graph execution that produced this message. - */ - threadId: z.string(), -}); /** * The basis of an interrupt resume value */ +export const BaseInterruptResumeValue = lazySchema(() => + z.object({ + /** + * Type of the resume value + */ + type: InterruptType, + }) +); export type BaseInterruptResumeValue = z.infer; -export const BaseInterruptResumeValue = z.object({ - /** - * Type of the resume value - */ - type: InterruptType, -}); /** * A request approval option */ +export const SelectOptionInterruptOption = lazySchema(() => + z.object({ + label: z.string(), + value: z.string(), + buttonColor: z + .enum([ + 'text', + 'accent', + 'accentSecondary', + 'primary', + 'success', + 'warning', + 'danger', + 'neutral', + 'risk', + ]) + .optional(), + }) +); export type SelectOptionInterruptOption = z.infer; -export const SelectOptionInterruptOption = z.object({ - label: z.string(), - value: z.string(), - buttonColor: z - .enum([ - 'text', - 'accent', - 'accentSecondary', - 'primary', - 'success', - 'warning', - 'danger', - 'neutral', - 'risk', - ]) - .optional(), -}); /** * Interrupt that requests user to select one of the provided options */ -export type SelectOptionInterruptValue = z.infer; -export const SelectOptionInterruptValue = BaseInterruptValue.extend( - z.object({ - type: z.literal('SELECT_OPTION'), - /** - * Description of action required - */ - description: z.string(), - /** - * List of actions to choose from - */ - options: z.array(SelectOptionInterruptOption), - }) +export const SelectOptionInterruptValue = lazySchema(() => + BaseInterruptValue.merge( + z.object({ + type: z.literal('SELECT_OPTION'), + /** + * Description of action required + */ + description: z.string(), + /** + * List of actions to choose from + */ + options: z.array(SelectOptionInterruptOption), + }) + ) ); +export type SelectOptionInterruptValue = z.infer; /** * A request approval resume schema */ -export type SelectOptionInterruptResumeValue = z.infer; -export const SelectOptionInterruptResumeValue = BaseInterruptResumeValue.extend( - z.object({ - type: z.literal('SELECT_OPTION'), - /** - * The value of the selected option to resume the graph execution with - */ - value: z.string(), - }) +export const SelectOptionInterruptResumeValue = lazySchema(() => + BaseInterruptResumeValue.merge( + z.object({ + type: z.literal('SELECT_OPTION'), + /** + * The value of the selected option to resume the graph execution with + */ + value: z.string(), + }) + ) ); +export type SelectOptionInterruptResumeValue = z.infer; /** * A request approval interrupt */ -export type SelectOptionInterrupt = z.infer; -export const SelectOptionInterrupt = z.object({ - /** - * The interrupt value - */ - interruptValue: SelectOptionInterruptValue, - /** - * The resume value - */ - resumeValue: SelectOptionInterruptResumeValue, -}); - -/** - * Interrupt that requests user to provide text input - */ -export type InputTextInterruptValue = z.infer; -export const InputTextInterruptValue = BaseInterruptValue.extend( +export const SelectOptionInterrupt = lazySchema(() => z.object({ - type: z.literal('INPUT_TEXT'), /** - * Description of action required + * The interrupt value */ - description: z.string().optional(), + interruptValue: SelectOptionInterruptValue, /** - * Placeholder text for the input field + * The resume value */ - placeholder: z.string().optional(), + resumeValue: SelectOptionInterruptResumeValue, }) ); +export type SelectOptionInterrupt = z.infer; + +/** + * Interrupt that requests user to provide text input + */ +export const InputTextInterruptValue = lazySchema(() => + BaseInterruptValue.merge( + z.object({ + type: z.literal('INPUT_TEXT'), + /** + * Description of action required + */ + description: z.string().optional(), + /** + * Placeholder text for the input field + */ + placeholder: z.string().optional(), + }) + ) +); +export type InputTextInterruptValue = z.infer; /** * A resume value for input text */ +export const InputTextInterruptResumeValue = lazySchema(() => + BaseInterruptResumeValue.merge( + z.object({ + type: z.literal('INPUT_TEXT'), + /** + * Text value used to resume the graph execution with. + */ + value: z.string(), + }) + ) +); export type InputTextInterruptResumeValue = z.infer; -export const InputTextInterruptResumeValue = BaseInterruptResumeValue.extend( + +/** + * A request text interrupt + */ +export const InputTextInterrupt = lazySchema(() => z.object({ - type: z.literal('INPUT_TEXT'), /** - * Text value used to resume the graph execution with. + * The interrupt value */ - value: z.string(), + interruptValue: InputTextInterruptValue, + /** + * The resume value + */ + resumeValue: InputTextInterruptResumeValue, }) ); - -/** - * A request text interrupt - */ export type InputTextInterrupt = z.infer; -export const InputTextInterrupt = z.object({ - /** - * The interrupt value - */ - interruptValue: InputTextInterruptValue, - /** - * The resume value - */ - resumeValue: InputTextInterruptResumeValue, -}); /** * Union of the interrupt values */ +export const InterruptValue = lazySchema(() => + z.union([SelectOptionInterruptValue, InputTextInterruptValue]) +); export type InterruptValue = z.infer; -export const InterruptValue = z.union([SelectOptionInterruptValue, InputTextInterruptValue]); /** * Union of the interrupt resume values */ +export const InterruptResumeValue = lazySchema(() => + z.union([SelectOptionInterruptResumeValue, InputTextInterruptResumeValue]) +); export type InterruptResumeValue = z.infer; -export const InterruptResumeValue = z.union([ - SelectOptionInterruptResumeValue, - InputTextInterruptResumeValue, -]); /** * The basis of a content reference */ -export type BaseContentReference = z.infer; -export const BaseContentReference = z.object({ - /** - * Id of the content reference - */ - id: z.string(), - /** - * Type of the content reference - */ - type: z.string(), -}); - -/** - * References a knowledge base entry - */ -export type KnowledgeBaseEntryContentReference = z.infer; -export const KnowledgeBaseEntryContentReference = BaseContentReference.extend( +export const BaseContentReference = lazySchema(() => z.object({ - type: z.literal('KnowledgeBaseEntry'), /** - * Id of the Knowledge Base Entry + * Id of the content reference */ - knowledgeBaseEntryId: z.string(), + id: z.string(), /** - * Name of the knowledge base entry + * Type of the content reference */ - knowledgeBaseEntryName: z.string(), + type: z.string(), }) ); +export type BaseContentReference = z.infer; + +/** + * References a knowledge base entry + */ +export const KnowledgeBaseEntryContentReference = lazySchema(() => + BaseContentReference.merge( + z.object({ + type: z.literal('KnowledgeBaseEntry'), + /** + * Id of the Knowledge Base Entry + */ + knowledgeBaseEntryId: z.string(), + /** + * Name of the knowledge base entry + */ + knowledgeBaseEntryName: z.string(), + }) + ) +); +export type KnowledgeBaseEntryContentReference = z.infer; /** * References an ESQL query */ -export type EsqlContentReference = z.infer; -export const EsqlContentReference = BaseContentReference.extend( - z.object({ - type: z.literal('EsqlQuery'), - /** - * An ESQL query - */ - query: z.string(), - /** - * Label of the query - */ - label: z.string(), - /** - * Time range to select in the time picker. - */ - timerange: z - .object({ - from: z.string(), - to: z.string(), - }) - .optional(), - }) +export const EsqlContentReference = lazySchema(() => + BaseContentReference.merge( + z.object({ + type: z.literal('EsqlQuery'), + /** + * An ESQL query + */ + query: z.string(), + /** + * Label of the query + */ + label: z.string(), + /** + * Time range to select in the time picker. + */ + timerange: z + .object({ + from: z.string(), + to: z.string(), + }) + .optional(), + }) + ) ); +export type EsqlContentReference = z.infer; /** * References a security alert */ -export type SecurityAlertContentReference = z.infer; -export const SecurityAlertContentReference = BaseContentReference.extend( - z.object({ - type: z.literal('SecurityAlert'), - /** - * ID of the Alert - */ - alertId: z.string(), - }) +export const SecurityAlertContentReference = lazySchema(() => + BaseContentReference.merge( + z.object({ + type: z.literal('SecurityAlert'), + /** + * ID of the Alert + */ + alertId: z.string(), + }) + ) ); +export type SecurityAlertContentReference = z.infer; /** * References an external URL */ -export type HrefContentReference = z.infer; -export const HrefContentReference = BaseContentReference.extend( - z.object({ - type: z.literal('Href'), - /** - * Label of the query - */ - label: z.string().optional(), - /** - * URL to the external resource - */ - href: z.string(), - }) +export const HrefContentReference = lazySchema(() => + BaseContentReference.merge( + z.object({ + type: z.literal('Href'), + /** + * Label of the query + */ + label: z.string().optional(), + /** + * URL to the external resource + */ + href: z.string(), + }) + ) ); +export type HrefContentReference = z.infer; /** * References the security alerts page */ -export type SecurityAlertsPageContentReference = z.infer; -export const SecurityAlertsPageContentReference = BaseContentReference.extend( - z.object({ - type: z.literal('SecurityAlertsPage'), - }) +export const SecurityAlertsPageContentReference = lazySchema(() => + BaseContentReference.merge( + z.object({ + type: z.literal('SecurityAlertsPage'), + }) + ) ); +export type SecurityAlertsPageContentReference = z.infer; /** * References the product documentation */ +export const ProductDocumentationContentReference = lazySchema(() => + BaseContentReference.merge( + z.object({ + type: z.literal('ProductDocumentation'), + /** + * Title of the documentation + */ + title: z.string(), + /** + * URL to the documentation + */ + url: z.string(), + }) + ) +); export type ProductDocumentationContentReference = z.infer< typeof ProductDocumentationContentReference >; -export const ProductDocumentationContentReference = BaseContentReference.extend( - z.object({ - type: z.literal('ProductDocumentation'), - /** - * Title of the documentation - */ - title: z.string(), - /** - * URL to the documentation - */ - url: z.string(), - }) -); /** * A content reference */ -export const ContentReferenceInternal = z.union([ - KnowledgeBaseEntryContentReference, - SecurityAlertContentReference, - SecurityAlertsPageContentReference, - ProductDocumentationContentReference, - EsqlContentReference, - HrefContentReference, -]); +export const ContentReferenceInternal = lazySchema(() => + z.union([ + KnowledgeBaseEntryContentReference, + SecurityAlertContentReference, + SecurityAlertsPageContentReference, + ProductDocumentationContentReference, + EsqlContentReference, + HrefContentReference, + ]) +); export type ContentReference = z.infer; export const ContentReference = ContentReferenceInternal as z.ZodType; @@ -342,258 +379,276 @@ export const ContentReference = ContentReferenceInternal as z.ZodType + z + .object({}) + .catchall( + z.union([ + KnowledgeBaseEntryContentReference, + SecurityAlertContentReference, + SecurityAlertsPageContentReference, + ProductDocumentationContentReference, + EsqlContentReference, + HrefContentReference, + ]) + ) +); export type ContentReferences = z.infer; -export const ContentReferences = z - .object({}) - .catchall( - z.union([ - KnowledgeBaseEntryContentReference, - SecurityAlertContentReference, - SecurityAlertsPageContentReference, - ProductDocumentationContentReference, - EsqlContentReference, - HrefContentReference, - ]) - ); /** * Message metadata */ +export const MessageMetadata = lazySchema(() => + z.object({ + /** + * Data referred to by the message content. + */ + contentReferences: ContentReferences.optional(), + /** + * When the agent is interrupted (for example, when user input is required), this field is populated with the details of the interrupt. Messages containing interruptValues in the metadata are excluded from the LLM context. + */ + interruptValue: InterruptValue.optional(), + /** + * When the agent is resumed after an interrupt, this field is populated with the details of the resume value. + */ + interruptResumeValue: InterruptResumeValue.optional(), + }) +); export type MessageMetadata = z.infer; -export const MessageMetadata = z.object({ - /** - * Data referred to by the message content. - */ - contentReferences: ContentReferences.optional(), - /** - * When the agent is interrupted (for example, when user input is required), this field is populated with the details of the interrupt. Messages containing interruptValues in the metadata are excluded from the LLM context. - */ - interruptValue: InterruptValue.optional(), - /** - * When the agent is resumed after an interrupt, this field is populated with the details of the resume value. - */ - interruptResumeValue: InterruptResumeValue.optional(), -}); /** * Replacements object used to anonymize/deanonymize messages */ +export const Replacements = lazySchema(() => z.object({}).catchall(z.string())); export type Replacements = z.infer; -export const Replacements = z.object({}).catchall(z.string()); +export const Reader = lazySchema(() => z.object({}).catchall(z.unknown())); export type Reader = z.infer; -export const Reader = z.object({}).catchall(z.unknown()); /** * Provider */ +export const Provider = lazySchema(() => z.enum(['OpenAI', 'Azure OpenAI', 'Other'])); export type Provider = z.infer; -export const Provider = z.enum(['OpenAI', 'Azure OpenAI', 'Other']); export type ProviderEnum = typeof Provider.enum; export const ProviderEnum = Provider.enum; /** * Message role. */ +export const MessageRole = lazySchema(() => z.enum(['system', 'user', 'assistant'])); export type MessageRole = z.infer; -export const MessageRole = z.enum(['system', 'user', 'assistant']); export type MessageRoleEnum = typeof MessageRole.enum; export const MessageRoleEnum = MessageRole.enum; /** * The conversation category. */ +export const ConversationCategory = lazySchema(() => z.enum(['assistant', 'insights'])); export type ConversationCategory = z.infer; -export const ConversationCategory = z.enum(['assistant', 'insights']); export type ConversationCategoryEnum = typeof ConversationCategory.enum; export const ConversationCategoryEnum = ConversationCategory.enum; /** * AI assistant conversation message. */ +export const Message = lazySchema(() => + z.object({ + /** + * Message id + */ + id: NonEmptyString.optional(), + /** + * Message content. + */ + content: z.string(), + /** + * Refusal reason returned by the model when content is filtered. + */ + refusal: z.string().optional(), + /** + * Message content. + */ + reader: Reader.optional(), + /** + * Message role. + */ + role: MessageRole, + /** + * The user who sent the message. + */ + user: User.optional(), + /** + * The timestamp message was sent or received. + */ + timestamp: NonEmptyTimestamp, + /** + * Is error message. + */ + isError: z.boolean().optional(), + /** + * Trace data + */ + traceData: TraceData.optional(), + /** + * Metadata + */ + metadata: MessageMetadata.optional(), + }) +); export type Message = z.infer; -export const Message = z.object({ - /** - * Message id - */ - id: NonEmptyString.optional(), - /** - * Message content. - */ - content: z.string(), - /** - * Refusal reason returned by the model when content is filtered. - */ - refusal: z.string().optional(), - /** - * Message content. - */ - reader: Reader.optional(), - /** - * Message role. - */ - role: MessageRole, - /** - * The user who sent the message. - */ - user: User.optional(), - /** - * The timestamp message was sent or received. - */ - timestamp: NonEmptyTimestamp, - /** - * Is error message. - */ - isError: z.boolean().optional(), - /** - * Trace data - */ - traceData: TraceData.optional(), - /** - * Metadata - */ - metadata: MessageMetadata.optional(), -}); +export const ApiConfig = lazySchema(() => + z.object({ + /** + * Connector ID + */ + connectorId: z.string(), + /** + * Action type ID + */ + actionTypeId: z.string(), + /** + * Default system prompt ID + */ + defaultSystemPromptId: z.string().optional(), + /** + * Provider + */ + provider: Provider.optional(), + /** + * Model + */ + model: z.string().optional(), + }) +); export type ApiConfig = z.infer; -export const ApiConfig = z.object({ - /** - * Connector ID - */ - connectorId: z.string(), - /** - * Action type ID - */ - actionTypeId: z.string(), - /** - * Default system prompt ID - */ - defaultSystemPromptId: z.string().optional(), - /** - * Provider - */ - provider: Provider.optional(), - /** - * Model - */ - model: z.string().optional(), -}); +export const ErrorSchema = lazySchema(() => + z + .object({ + id: NonEmptyString.optional(), + error: z.object({ + status_code: z.number().int().min(400), + message: z.string(), + }), + }) + .strict() +); export type ErrorSchema = z.infer; -export const ErrorSchema = z - .object({ - id: NonEmptyString.optional(), - error: z.object({ - status_code: z.number().int().min(400), - message: z.string(), - }), - }) - .strict(); +export const ConversationResponse = lazySchema(() => + z.object({ + id: NonEmptyString, + /** + * The conversation title. + */ + title: z.string(), + /** + * The conversation category. + */ + category: ConversationCategory, + timestamp: NonEmptyTimestamp.optional(), + /** + * The last time conversation was updated. + */ + updatedAt: z.string().optional(), + /** + * The time conversation was created. + */ + createdAt: z.string(), + replacements: Replacements.optional(), + /** + * The user who created the conversation. + */ + createdBy: User, + users: z.array(User), + /** + * The conversation messages. + */ + messages: z.array(Message).optional(), + /** + * LLM API configuration. + */ + apiConfig: ApiConfig.optional(), + /** + * Exclude from last conversation storage. + */ + excludeFromLastConversationStorage: z.boolean().optional(), + /** + * Kibana space + */ + namespace: z.string(), + }) +); export type ConversationResponse = z.infer; -export const ConversationResponse = z.object({ - id: NonEmptyString, - /** - * The conversation title. - */ - title: z.string(), - /** - * The conversation category. - */ - category: ConversationCategory, - timestamp: NonEmptyTimestamp.optional(), - /** - * The last time conversation was updated. - */ - updatedAt: z.string().optional(), - /** - * The time conversation was created. - */ - createdAt: z.string(), - replacements: Replacements.optional(), - /** - * The user who created the conversation. - */ - createdBy: User, - users: z.array(User), - /** - * The conversation messages. - */ - messages: z.array(Message).optional(), - /** - * LLM API configuration. - */ - apiConfig: ApiConfig.optional(), - /** - * Exclude from last conversation storage. - */ - excludeFromLastConversationStorage: z.boolean().optional(), - /** - * Kibana space - */ - namespace: z.string(), -}); +export const ConversationUpdateProps = lazySchema(() => + z.object({ + id: NonEmptyString, + /** + * The conversation title. + */ + title: z.string().optional(), + /** + * The conversation category. + */ + category: ConversationCategory.optional(), + /** + * The conversation messages. + */ + messages: z.array(Message).optional(), + /** + * LLM API configuration. + */ + apiConfig: ApiConfig.optional(), + /** + * Exclude from last conversation storage. + */ + excludeFromLastConversationStorage: z.boolean().optional(), + replacements: Replacements.optional(), + users: z.array(User).optional(), + }) +); export type ConversationUpdateProps = z.infer; -export const ConversationUpdateProps = z.object({ - id: NonEmptyString, - /** - * The conversation title. - */ - title: z.string().optional(), - /** - * The conversation category. - */ - category: ConversationCategory.optional(), - /** - * The conversation messages. - */ - messages: z.array(Message).optional(), - /** - * LLM API configuration. - */ - apiConfig: ApiConfig.optional(), - /** - * Exclude from last conversation storage. - */ - excludeFromLastConversationStorage: z.boolean().optional(), - replacements: Replacements.optional(), - users: z.array(User).optional(), -}); +export const ConversationCreateProps = lazySchema(() => + z.object({ + /** + * The conversation id. + */ + id: z.string().optional(), + /** + * The conversation title. + */ + title: z.string(), + /** + * The conversation category. + */ + category: ConversationCategory.optional(), + /** + * The conversation messages. + */ + messages: z.array(Message).optional(), + /** + * LLM API configuration. + */ + apiConfig: ApiConfig.optional(), + /** + * Exclude from last conversation storage. + */ + excludeFromLastConversationStorage: z.boolean().optional(), + replacements: Replacements.optional(), + }) +); export type ConversationCreateProps = z.infer; -export const ConversationCreateProps = z.object({ - /** - * The conversation id. - */ - id: z.string().optional(), - /** - * The conversation title. - */ - title: z.string(), - /** - * The conversation category. - */ - category: ConversationCategory.optional(), - /** - * The conversation messages. - */ - messages: z.array(Message).optional(), - /** - * LLM API configuration. - */ - apiConfig: ApiConfig.optional(), - /** - * Exclude from last conversation storage. - */ - excludeFromLastConversationStorage: z.boolean().optional(), - replacements: Replacements.optional(), -}); +export const ConversationMessageCreateProps = lazySchema(() => + z.object({ + /** + * The conversation messages. + */ + messages: z.array(Message), + }) +); export type ConversationMessageCreateProps = z.infer; -export const ConversationMessageCreateProps = z.object({ - /** - * The conversation messages. - */ - messages: z.array(Message), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.gen.ts index 22c591c5c2fc9..7e74c97d27b4e 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ConversationCreateProps, @@ -23,67 +23,77 @@ import { } from './common_attributes.gen'; import { NonEmptyString } from '../common_attributes.gen'; +export const CreateConversationRequestBody = lazySchema(() => ConversationCreateProps); export type CreateConversationRequestBody = z.infer; -export const CreateConversationRequestBody = ConversationCreateProps; export type CreateConversationRequestBodyInput = z.input; +export const CreateConversationResponse = lazySchema(() => ConversationResponse); export type CreateConversationResponse = z.infer; -export const CreateConversationResponse = ConversationResponse; +export const DeleteAllConversationsRequestBody = lazySchema(() => + z.object({ + /** + * Optional list of conversation IDs to delete. + */ + excludedIds: z.array(z.string()).optional(), + }) +); export type DeleteAllConversationsRequestBody = z.infer; -export const DeleteAllConversationsRequestBody = z.object({ - /** - * Optional list of conversation IDs to delete. - */ - excludedIds: z.array(z.string()).optional(), -}); export type DeleteAllConversationsRequestBodyInput = z.input< typeof DeleteAllConversationsRequestBody >; +export const DeleteAllConversationsResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + totalDeleted: z.number().optional(), + failures: z.array(z.string()).optional(), + }) +); export type DeleteAllConversationsResponse = z.infer; -export const DeleteAllConversationsResponse = z.object({ - success: z.boolean().optional(), - totalDeleted: z.number().optional(), - failures: z.array(z.string()).optional(), -}); +export const DeleteConversationRequestParams = lazySchema(() => + z.object({ + /** + * The conversation's `id` value. + */ + id: NonEmptyString, + }) +); export type DeleteConversationRequestParams = z.infer; -export const DeleteConversationRequestParams = z.object({ - /** - * The conversation's `id` value. - */ - id: NonEmptyString, -}); export type DeleteConversationRequestParamsInput = z.input; +export const DeleteConversationResponse = lazySchema(() => ConversationResponse); export type DeleteConversationResponse = z.infer; -export const DeleteConversationResponse = ConversationResponse; +export const ReadConversationRequestParams = lazySchema(() => + z.object({ + /** + * The conversation's `id` value, a unique identifier for the conversation. + */ + id: NonEmptyString, + }) +); export type ReadConversationRequestParams = z.infer; -export const ReadConversationRequestParams = z.object({ - /** - * The conversation's `id` value, a unique identifier for the conversation. - */ - id: NonEmptyString, -}); export type ReadConversationRequestParamsInput = z.input; +export const ReadConversationResponse = lazySchema(() => ConversationResponse); export type ReadConversationResponse = z.infer; -export const ReadConversationResponse = ConversationResponse; +export const UpdateConversationRequestParams = lazySchema(() => + z.object({ + /** + * The conversation's `id` value. + */ + id: NonEmptyString, + }) +); export type UpdateConversationRequestParams = z.infer; -export const UpdateConversationRequestParams = z.object({ - /** - * The conversation's `id` value. - */ - id: NonEmptyString, -}); export type UpdateConversationRequestParamsInput = z.input; +export const UpdateConversationRequestBody = lazySchema(() => ConversationUpdateProps); export type UpdateConversationRequestBody = z.infer; -export const UpdateConversationRequestBody = ConversationUpdateProps; export type UpdateConversationRequestBodyInput = z.input; +export const UpdateConversationResponse = lazySchema(() => ConversationResponse); export type UpdateConversationResponse = z.infer; -export const UpdateConversationResponse = ConversationResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/find_conversations_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/find_conversations_route.gen.ts index c5e8dcab63dab..3c3235a4d7052 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/find_conversations_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/conversations/find_conversations_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../common_attributes.gen'; @@ -23,60 +23,66 @@ import { ConversationResponse } from './common_attributes.gen'; /** * The field by which to sort the conversations. Possible values are `created_at`, `title`, and `updated_at`. */ +export const FindConversationsSortField = lazySchema(() => + z.enum(['created_at', 'title', 'updated_at']) +); export type FindConversationsSortField = z.infer; -export const FindConversationsSortField = z.enum(['created_at', 'title', 'updated_at']); export type FindConversationsSortFieldEnum = typeof FindConversationsSortField.enum; export const FindConversationsSortFieldEnum = FindConversationsSortField.enum; +export const FindConversationsRequestQuery = lazySchema(() => + z.object({ + /** + * A list of fields to include in the response. If omitted, all fields are returned. + */ + fields: ArrayFromString(z.string()).optional(), + /** + * A search query to filter the conversations. Can match against titles, messages, or other conversation attributes. + */ + filter: z.string().optional(), + /** + * The field by which to sort the results. Valid fields are `created_at`, `title`, and `updated_at`. + */ + sort_field: FindConversationsSortField.optional(), + /** + * The order in which to sort the results. Can be either `asc` for ascending or `desc` for descending. + */ + sort_order: SortOrder.optional(), + /** + * The page number of the results to retrieve. Default is 1. + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * The number of conversations to return per page. Default is 20. + */ + per_page: z.coerce.number().int().min(0).optional().default(20), + /** + * Whether to return conversations that the current user owns. If true, only conversations owned by the user are returned. + */ + is_owner: BooleanFromString.optional().default(false), + }) +); export type FindConversationsRequestQuery = z.infer; -export const FindConversationsRequestQuery = z.object({ - /** - * A list of fields to include in the response. If omitted, all fields are returned. - */ - fields: ArrayFromString(z.string()).optional(), - /** - * A search query to filter the conversations. Can match against titles, messages, or other conversation attributes. - */ - filter: z.string().optional(), - /** - * The field by which to sort the results. Valid fields are `created_at`, `title`, and `updated_at`. - */ - sort_field: FindConversationsSortField.optional(), - /** - * The order in which to sort the results. Can be either `asc` for ascending or `desc` for descending. - */ - sort_order: SortOrder.optional(), - /** - * The page number of the results to retrieve. Default is 1. - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * The number of conversations to return per page. Default is 20. - */ - per_page: z.coerce.number().int().min(0).optional().default(20), - /** - * Whether to return conversations that the current user owns. If true, only conversations owned by the user are returned. - */ - is_owner: BooleanFromString.optional().default(false), -}); export type FindConversationsRequestQueryInput = z.input; +export const FindConversationsResponse = lazySchema(() => + z.object({ + /** + * The current page of the results. + */ + page: z.number().int(), + /** + * The number of results returned per page. + */ + perPage: z.number().int(), + /** + * The total number of conversations matching the filter criteria. + */ + total: z.number().int(), + /** + * A list of conversations. + */ + data: z.array(ConversationResponse), + }) +); export type FindConversationsResponse = z.infer; -export const FindConversationsResponse = z.object({ - /** - * The current page of the results. - */ - page: z.number().int(), - /** - * The number of results returned per page. - */ - perPage: z.number().int(), - /** - * The total number of conversations matching the filter criteria. - */ - total: z.number().int(), - /** - * A list of conversations. - */ - data: z.array(ConversationResponse), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/common_attributes.gen.ts index a6f0a10bfd7e9..5345b8ddd4dff 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/common_attributes.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString, NonEmptyTimestamp, User } from '../common_attributes.gen'; import { Replacements, ApiConfig } from '../conversations/common_attributes.gen'; @@ -22,204 +22,216 @@ import { Replacements, ApiConfig } from '../conversations/common_attributes.gen' /** * A Defend insight event */ +export const DefendInsightEvent = lazySchema(() => + z.object({ + /** + * The event's ID + */ + id: z.string(), + /** + * The endpoint's ID + */ + endpointId: z.string(), + /** + * The value of the event + */ + value: z.string(), + }) +); export type DefendInsightEvent = z.infer; -export const DefendInsightEvent = z.object({ - /** - * The event's ID - */ - id: z.string(), - /** - * The endpoint's ID - */ - endpointId: z.string(), - /** - * The value of the event - */ - value: z.string(), -}); /** * The insight type (ie. incompatible_antivirus) */ +export const DefendInsightType = lazySchema(() => + z.enum(['incompatible_antivirus', 'policy_response_failure', 'custom']) +); export type DefendInsightType = z.infer; -export const DefendInsightType = z.enum([ - 'incompatible_antivirus', - 'policy_response_failure', - 'custom', -]); export type DefendInsightTypeEnum = typeof DefendInsightType.enum; export const DefendInsightTypeEnum = DefendInsightType.enum; /** * A Defend insight generated from endpoint events */ +export const DefendInsight = lazySchema(() => + z.object({ + /** + * The group category of the events (ie. Windows Defender) + */ + group: z.string(), + /** + * An array of event objects + */ + events: z.array(DefendInsightEvent).optional(), + /** + * The suggested remediation for the insight + */ + remediation: z.object({}).catchall(z.unknown()).optional(), + }) +); export type DefendInsight = z.infer; -export const DefendInsight = z.object({ - /** - * The group category of the events (ie. Windows Defender) - */ - group: z.string(), - /** - * An array of event objects - */ - events: z.array(DefendInsightEvent).optional(), - /** - * The suggested remediation for the insight - */ - remediation: z.object({}).catchall(z.unknown()).optional(), -}); /** * Array of Defend insights */ +export const DefendInsights = lazySchema(() => z.array(DefendInsight)); export type DefendInsights = z.infer; -export const DefendInsights = z.array(DefendInsight); /** * The status of the Defend insight. */ +export const DefendInsightStatus = lazySchema(() => + z.enum(['running', 'succeeded', 'failed', 'canceled']) +); export type DefendInsightStatus = z.infer; -export const DefendInsightStatus = z.enum(['running', 'succeeded', 'failed', 'canceled']); export type DefendInsightStatusEnum = typeof DefendInsightStatus.enum; export const DefendInsightStatusEnum = DefendInsightStatus.enum; /** * Run durations for the Defend insight */ +export const DefendInsightGenerationInterval = lazySchema(() => + z.object({ + /** + * The time the Defend insight was generated + */ + date: z.string(), + /** + * The duration of the Defend insight generation + */ + durationMs: z.number().int(), + }) +); export type DefendInsightGenerationInterval = z.infer; -export const DefendInsightGenerationInterval = z.object({ - /** - * The time the Defend insight was generated - */ - date: z.string(), - /** - * The duration of the Defend insight generation - */ - durationMs: z.number().int(), -}); +export const DefendInsightsResponse = lazySchema(() => + z.object({ + id: NonEmptyString, + timestamp: NonEmptyTimestamp.optional(), + /** + * The last time the Defend insight was updated. + */ + updatedAt: z.string(), + /** + * The last time the Defend insight was viewed in the browser. + */ + lastViewedAt: z.string(), + /** + * The number of events in the context. + */ + eventsContextCount: z.number().int().optional(), + /** + * The time the Defend insight was created. + */ + createdAt: z.string(), + replacements: Replacements.optional(), + users: z.array(User), + /** + * The status of the Defend insight. + */ + status: DefendInsightStatus, + endpointIds: z.array(NonEmptyString), + insightType: DefendInsightType, + /** + * The Defend insights. + */ + insights: DefendInsights, + /** + * LLM API configuration. + */ + apiConfig: ApiConfig, + /** + * Kibana space + */ + namespace: z.string(), + /** + * The backing index required for update requests. + */ + backingIndex: z.string(), + /** + * The most 5 recent generation intervals + */ + generationIntervals: z.array(DefendInsightGenerationInterval), + /** + * The average generation interval in milliseconds + */ + averageIntervalMs: z.number().int(), + /** + * The reason for a status of failed. + */ + failureReason: z.string().optional(), + }) +); export type DefendInsightsResponse = z.infer; -export const DefendInsightsResponse = z.object({ - id: NonEmptyString, - timestamp: NonEmptyTimestamp.optional(), - /** - * The last time the Defend insight was updated. - */ - updatedAt: z.string(), - /** - * The last time the Defend insight was viewed in the browser. - */ - lastViewedAt: z.string(), - /** - * The number of events in the context. - */ - eventsContextCount: z.number().int().optional(), - /** - * The time the Defend insight was created. - */ - createdAt: z.string(), - replacements: Replacements.optional(), - users: z.array(User), - /** - * The status of the Defend insight. - */ - status: DefendInsightStatus, - endpointIds: z.array(NonEmptyString), - insightType: DefendInsightType, - /** - * The Defend insights. - */ - insights: DefendInsights, - /** - * LLM API configuration. - */ - apiConfig: ApiConfig, - /** - * Kibana space - */ - namespace: z.string(), - /** - * The backing index required for update requests. - */ - backingIndex: z.string(), - /** - * The most 5 recent generation intervals - */ - generationIntervals: z.array(DefendInsightGenerationInterval), - /** - * The average generation interval in milliseconds - */ - averageIntervalMs: z.number().int(), - /** - * The reason for a status of failed. - */ - failureReason: z.string().optional(), -}); +export const DefendInsightUpdateProps = lazySchema(() => + z.object({ + id: NonEmptyString, + /** + * LLM API configuration. + */ + apiConfig: ApiConfig.optional(), + /** + * The number of events in the context. + */ + eventsContextCount: z.number().int().optional(), + /** + * The Defend insights. + */ + insights: DefendInsights.optional(), + /** + * The status of the Defend insight. + */ + status: DefendInsightStatus.optional(), + replacements: Replacements.optional(), + /** + * The most 5 recent generation intervals + */ + generationIntervals: z.array(DefendInsightGenerationInterval).optional(), + /** + * The backing index required for update requests. + */ + backingIndex: z.string(), + /** + * The reason for a status of failed. + */ + failureReason: z.string().optional(), + /** + * The last time the Defend insight was viewed in the browser. + */ + lastViewedAt: z.string().optional(), + }) +); export type DefendInsightUpdateProps = z.infer; -export const DefendInsightUpdateProps = z.object({ - id: NonEmptyString, - /** - * LLM API configuration. - */ - apiConfig: ApiConfig.optional(), - /** - * The number of events in the context. - */ - eventsContextCount: z.number().int().optional(), - /** - * The Defend insights. - */ - insights: DefendInsights.optional(), - /** - * The status of the Defend insight. - */ - status: DefendInsightStatus.optional(), - replacements: Replacements.optional(), - /** - * The most 5 recent generation intervals - */ - generationIntervals: z.array(DefendInsightGenerationInterval).optional(), - /** - * The backing index required for update requests. - */ - backingIndex: z.string(), - /** - * The reason for a status of failed. - */ - failureReason: z.string().optional(), - /** - * The last time the Defend insight was viewed in the browser. - */ - lastViewedAt: z.string().optional(), -}); +export const DefendInsightsUpdateProps = lazySchema(() => z.array(DefendInsightUpdateProps)); export type DefendInsightsUpdateProps = z.infer; -export const DefendInsightsUpdateProps = z.array(DefendInsightUpdateProps); +export const DefendInsightCreateProps = lazySchema(() => + z.object({ + /** + * The Defend insight id. + */ + id: z.string().optional(), + /** + * The status of the Defend insight. + */ + status: DefendInsightStatus, + /** + * The number of events in the context. + */ + eventsContextCount: z.number().int().optional(), + endpointIds: z.array(NonEmptyString), + insightType: DefendInsightType, + /** + * The Defend insights. + */ + insights: DefendInsights, + /** + * LLM API configuration. + */ + apiConfig: ApiConfig, + replacements: Replacements.optional(), + }) +); export type DefendInsightCreateProps = z.infer; -export const DefendInsightCreateProps = z.object({ - /** - * The Defend insight id. - */ - id: z.string().optional(), - /** - * The status of the Defend insight. - */ - status: DefendInsightStatus, - /** - * The number of events in the context. - */ - eventsContextCount: z.number().int().optional(), - endpointIds: z.array(NonEmptyString), - insightType: DefendInsightType, - /** - * The Defend insights. - */ - insights: DefendInsights, - /** - * LLM API configuration. - */ - apiConfig: ApiConfig, - replacements: Replacements.optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insight_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insight_route.gen.ts index 87357b90ea6bb..947e9ecfd68f6 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insight_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insight_route.gen.ts @@ -14,21 +14,25 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../common_attributes.gen'; import { DefendInsightsResponse } from './common_attributes.gen'; +export const DefendInsightGetRequestParams = lazySchema(() => + z.object({ + /** + * The Defend insight id + */ + id: NonEmptyString, + }) +); export type DefendInsightGetRequestParams = z.infer; -export const DefendInsightGetRequestParams = z.object({ - /** - * The Defend insight id - */ - id: NonEmptyString, -}); export type DefendInsightGetRequestParamsInput = z.input; +export const DefendInsightGetResponse = lazySchema(() => + z.object({ + data: DefendInsightsResponse.nullable().optional(), + }) +); export type DefendInsightGetResponse = z.infer; -export const DefendInsightGetResponse = z.object({ - data: DefendInsightsResponse.nullable().optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insights_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insights_route.gen.ts index c603c5e00f121..d03b264c6e483 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insights_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/get_defend_insights_route.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '../common_attributes.gen'; @@ -24,36 +24,40 @@ import { DefendInsightsResponse, } from './common_attributes.gen'; +export const DefendInsightsGetRequestQuery = lazySchema(() => + z.object({ + /** + * The insight ids for which to get Defend insights + */ + ids: ArrayFromString(NonEmptyString).optional(), + /** + * The connector id for which to get Defend insights + */ + connector_id: NonEmptyString.optional(), + /** + * The insight type for which to get Defend insights + */ + type: DefendInsightType.optional(), + /** + * The status for which to get Defend insights + */ + status: DefendInsightStatus.optional(), + /** + * The endpoint ids for which to get Defend insights + */ + endpoint_ids: ArrayFromString(NonEmptyString).optional(), + /** + * The number of Defend insights to return + */ + size: z.coerce.number().optional(), + }) +); export type DefendInsightsGetRequestQuery = z.infer; -export const DefendInsightsGetRequestQuery = z.object({ - /** - * The insight ids for which to get Defend insights - */ - ids: ArrayFromString(NonEmptyString).optional(), - /** - * The connector id for which to get Defend insights - */ - connector_id: NonEmptyString.optional(), - /** - * The insight type for which to get Defend insights - */ - type: DefendInsightType.optional(), - /** - * The status for which to get Defend insights - */ - status: DefendInsightStatus.optional(), - /** - * The endpoint ids for which to get Defend insights - */ - endpoint_ids: ArrayFromString(NonEmptyString).optional(), - /** - * The number of Defend insights to return - */ - size: z.coerce.number().optional(), -}); export type DefendInsightsGetRequestQueryInput = z.input; +export const DefendInsightsGetResponse = lazySchema(() => + z.object({ + data: z.array(DefendInsightsResponse), + }) +); export type DefendInsightsGetResponse = z.infer; -export const DefendInsightsGetResponse = z.object({ - data: z.array(DefendInsightsResponse), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/post_defend_insights_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/post_defend_insights_route.gen.ts index f6cf826b4b9ae..d17e9e9c28e6f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/post_defend_insights_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/defend_insights/post_defend_insights_route.gen.ts @@ -14,29 +14,31 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../common_attributes.gen'; import { DefendInsightType, DefendInsightsResponse } from './common_attributes.gen'; import { AnonymizationFieldResponse } from '../anonymization_fields/bulk_crud_anonymization_fields_route.gen'; import { ApiConfig, Replacements } from '../conversations/common_attributes.gen'; +export const DefendInsightsPostRequestBody = lazySchema(() => + z.object({ + endpointIds: z.array(NonEmptyString), + insightType: DefendInsightType, + anonymizationFields: z.array(AnonymizationFieldResponse), + /** + * LLM API configuration. + */ + apiConfig: ApiConfig, + langSmithProject: z.string().optional(), + langSmithApiKey: z.string().optional(), + model: z.string().optional(), + replacements: Replacements.optional(), + subAction: z.enum(['invokeAI', 'invokeStream']), + }) +); export type DefendInsightsPostRequestBody = z.infer; -export const DefendInsightsPostRequestBody = z.object({ - endpointIds: z.array(NonEmptyString), - insightType: DefendInsightType, - anonymizationFields: z.array(AnonymizationFieldResponse), - /** - * LLM API configuration. - */ - apiConfig: ApiConfig, - langSmithProject: z.string().optional(), - langSmithApiKey: z.string().optional(), - model: z.string().optional(), - replacements: Replacements.optional(), - subAction: z.enum(['invokeAI', 'invokeStream']), -}); export type DefendInsightsPostRequestBodyInput = z.input; +export const DefendInsightsPostResponse = lazySchema(() => DefendInsightsResponse); export type DefendInsightsPostResponse = z.infer; -export const DefendInsightsPostResponse = DefendInsightsResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/get_evaluate_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/get_evaluate_route.gen.ts index 83fc4c761f645..0ded276ccd5ba 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/get_evaluate_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/get_evaluate_route.gen.ts @@ -14,16 +14,18 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const GetEvaluateResponse = lazySchema(() => + z.object({ + datasets: z.array(z.string()), + graphs: z.array(z.string()), + results: z.array( + z.object({ + id: z.string(), + status: z.string(), + }) + ), + }) +); export type GetEvaluateResponse = z.infer; -export const GetEvaluateResponse = z.object({ - datasets: z.array(z.string()), - graphs: z.array(z.string()), - results: z.array( - z.object({ - id: z.string(), - status: z.string(), - }) - ), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/post_evaluate_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/post_evaluate_route.gen.ts index 166d9480602e7..8ba7884b557e2 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/post_evaluate_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/evaluation/post_evaluate_route.gen.ts @@ -14,32 +14,36 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Replacements } from '../conversations/common_attributes.gen'; import { ScreenContext } from '../common_attributes.gen'; +export const PostEvaluateBody = lazySchema(() => + z.object({ + graphs: z.array(z.string()).min(1).max(1), + datasetName: z.string(), + evaluatorConnectorId: z.string().optional(), + connectorIds: z.array(z.string()), + runName: z.string().optional(), + alertsIndexPattern: z.string().optional().default('.alerts-security.alerts-default'), + langSmithApiKey: z.string().optional(), + langSmithProject: z.string().optional(), + replacements: Replacements.optional().default({}), + screenContext: ScreenContext.optional(), + size: z.number().optional().default(20), + }) +); export type PostEvaluateBody = z.infer; -export const PostEvaluateBody = z.object({ - graphs: z.array(z.string()).min(1).max(1), - datasetName: z.string(), - evaluatorConnectorId: z.string().optional(), - connectorIds: z.array(z.string()), - runName: z.string().optional(), - alertsIndexPattern: z.string().optional().default('.alerts-security.alerts-default'), - langSmithApiKey: z.string().optional(), - langSmithProject: z.string().optional(), - replacements: Replacements.optional().default({}), - screenContext: ScreenContext.optional(), - size: z.number().optional().default(20), -}); +export const PostEvaluateRequestBody = lazySchema(() => PostEvaluateBody); export type PostEvaluateRequestBody = z.infer; -export const PostEvaluateRequestBody = PostEvaluateBody; export type PostEvaluateRequestBodyInput = z.input; +export const PostEvaluateResponse = lazySchema(() => + z.object({ + evaluationId: z.string(), + success: z.boolean(), + }) +); export type PostEvaluateResponse = z.infer; -export const PostEvaluateResponse = z.object({ - evaluationId: z.string(), - success: z.boolean(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/crud_kb_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/crud_kb_route.gen.ts index 68fa46be2d8d7..97f20d061bc68 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/crud_kb_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/crud_kb_route.gen.ts @@ -14,121 +14,135 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; /** * AI assistant KnowledgeBase. */ +export const KnowledgeBaseResponse = lazySchema(() => + z.object({ + /** + * Identify the success of the method execution. + */ + success: z.boolean().optional(), + }) +); export type KnowledgeBaseResponse = z.infer; -export const KnowledgeBaseResponse = z.object({ - /** - * Identify the success of the method execution. - */ - success: z.boolean().optional(), -}); +export const KnowledgeBaseResponse400 = lazySchema(() => + z.object({ + /** + * The HTTP status code of the error. + */ + statusCode: z.number().optional(), + /** + * A short description of the error. + */ + error: z.string().optional(), + /** + * A detailed error message. + */ + message: z.string().optional(), + }) +); export type KnowledgeBaseResponse400 = z.infer; -export const KnowledgeBaseResponse400 = z.object({ - /** - * The HTTP status code of the error. - */ - statusCode: z.number().optional(), - /** - * A short description of the error. - */ - error: z.string().optional(), - /** - * A detailed error message. - */ - message: z.string().optional(), -}); +export const KnowledgeBaseReadResponse200 = lazySchema(() => + z.object({ + /** + * Indicates if the ELSER model exists for the KnowledgeBase. + */ + elser_exists: z.boolean().optional(), + /** + * Indicates if the setup process is available for the KnowledgeBase. + */ + is_setup_available: z.boolean().optional(), + /** + * Indicates if the setup process is currently in progress. + */ + is_setup_in_progress: z.boolean().optional(), + /** + * Indicates if Security Labs documentation exists in the KnowledgeBase. + */ + security_labs_exists: z.boolean().optional(), + /** + * Indicates if Defend Insights documentation exists in the KnowledgeBase. + */ + defend_insights_exists: z.boolean().optional(), + /** + * Indicates if user data exists in the KnowledgeBase. + */ + user_data_exists: z.boolean().optional(), + /** + * The status of the product documentation in the KnowledgeBase. + */ + product_documentation_status: z.string().optional(), + }) +); export type KnowledgeBaseReadResponse200 = z.infer; -export const KnowledgeBaseReadResponse200 = z.object({ - /** - * Indicates if the ELSER model exists for the KnowledgeBase. - */ - elser_exists: z.boolean().optional(), - /** - * Indicates if the setup process is available for the KnowledgeBase. - */ - is_setup_available: z.boolean().optional(), - /** - * Indicates if the setup process is currently in progress. - */ - is_setup_in_progress: z.boolean().optional(), - /** - * Indicates if Security Labs documentation exists in the KnowledgeBase. - */ - security_labs_exists: z.boolean().optional(), - /** - * Indicates if Defend Insights documentation exists in the KnowledgeBase. - */ - defend_insights_exists: z.boolean().optional(), - /** - * Indicates if user data exists in the KnowledgeBase. - */ - user_data_exists: z.boolean().optional(), - /** - * The status of the product documentation in the KnowledgeBase. - */ - product_documentation_status: z.string().optional(), -}); +export const CreateKnowledgeBaseRequestQuery = lazySchema(() => + z.object({ + /** + * ELSER modelId to use when setting up the Knowledge Base. If not provided, a default model will be used. + */ + modelId: z.string().optional(), + /** + * Indicates whether we should or should not install Security Labs docs when setting up the Knowledge Base. Defaults to `false`. + */ + ignoreSecurityLabs: BooleanFromString.optional().default(false), + }) +); export type CreateKnowledgeBaseRequestQuery = z.infer; -export const CreateKnowledgeBaseRequestQuery = z.object({ - /** - * ELSER modelId to use when setting up the Knowledge Base. If not provided, a default model will be used. - */ - modelId: z.string().optional(), - /** - * Indicates whether we should or should not install Security Labs docs when setting up the Knowledge Base. Defaults to `false`. - */ - ignoreSecurityLabs: BooleanFromString.optional().default(false), -}); export type CreateKnowledgeBaseRequestQueryInput = z.input; +export const CreateKnowledgeBaseRequestParams = lazySchema(() => + z.object({ + /** + * The KnowledgeBase `resource` value. + */ + resource: z.string(), + }) +); export type CreateKnowledgeBaseRequestParams = z.infer; -export const CreateKnowledgeBaseRequestParams = z.object({ - /** - * The KnowledgeBase `resource` value. - */ - resource: z.string(), -}); export type CreateKnowledgeBaseRequestParamsInput = z.input< typeof CreateKnowledgeBaseRequestParams >; +export const CreateKnowledgeBaseResponse = lazySchema(() => KnowledgeBaseResponse); export type CreateKnowledgeBaseResponse = z.infer; -export const CreateKnowledgeBaseResponse = KnowledgeBaseResponse; +export const GetKnowledgeBaseResponse = lazySchema(() => KnowledgeBaseReadResponse200); export type GetKnowledgeBaseResponse = z.infer; -export const GetKnowledgeBaseResponse = KnowledgeBaseReadResponse200; +export const PostKnowledgeBaseRequestQuery = lazySchema(() => + z.object({ + /** + * ELSER modelId to use when setting up the Knowledge Base. If not provided, a default model will be used. + */ + modelId: z.string().optional(), + /** + * Indicates whether we should or should not install Security Labs docs when setting up the Knowledge Base. Defaults to `false`. + */ + ignoreSecurityLabs: BooleanFromString.optional().default(false), + }) +); export type PostKnowledgeBaseRequestQuery = z.infer; -export const PostKnowledgeBaseRequestQuery = z.object({ - /** - * ELSER modelId to use when setting up the Knowledge Base. If not provided, a default model will be used. - */ - modelId: z.string().optional(), - /** - * Indicates whether we should or should not install Security Labs docs when setting up the Knowledge Base. Defaults to `false`. - */ - ignoreSecurityLabs: BooleanFromString.optional().default(false), -}); export type PostKnowledgeBaseRequestQueryInput = z.input; +export const PostKnowledgeBaseResponse = lazySchema(() => KnowledgeBaseResponse); export type PostKnowledgeBaseResponse = z.infer; -export const PostKnowledgeBaseResponse = KnowledgeBaseResponse; +export const ReadKnowledgeBaseRequestParams = lazySchema(() => + z.object({ + /** + * The KnowledgeBase `resource` value. + */ + resource: z.string(), + }) +); export type ReadKnowledgeBaseRequestParams = z.infer; -export const ReadKnowledgeBaseRequestParams = z.object({ - /** - * The KnowledgeBase `resource` value. - */ - resource: z.string(), -}); export type ReadKnowledgeBaseRequestParamsInput = z.input; +export const ReadKnowledgeBaseResponse = lazySchema(() => KnowledgeBaseReadResponse200); export type ReadKnowledgeBaseResponse = z.infer; -export const ReadKnowledgeBaseResponse = KnowledgeBaseReadResponse200; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/bulk_crud_knowledge_base_entries_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/bulk_crud_knowledge_base_entries_route.gen.ts index 537a24dbafef0..c55e1f07eeb08 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/bulk_crud_knowledge_base_entries_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/bulk_crud_knowledge_base_entries_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { KnowledgeBaseEntryCreateProps, @@ -25,165 +25,183 @@ import { /** * Reason why a Knowledge Base Entry was skipped during the bulk action. */ +export const KnowledgeBaseEntryBulkActionSkipReason = lazySchema(() => + z.literal('KNOWLEDGE_BASE_ENTRY_NOT_MODIFIED') +); export type KnowledgeBaseEntryBulkActionSkipReason = z.infer< typeof KnowledgeBaseEntryBulkActionSkipReason >; -export const KnowledgeBaseEntryBulkActionSkipReason = z.literal( - 'KNOWLEDGE_BASE_ENTRY_NOT_MODIFIED' -); +export const KnowledgeBaseEntryBulkActionSkipResult = lazySchema(() => + z.object({ + /** + * ID of the skipped Knowledge Base Entry. + */ + id: z.string(), + /** + * Name of the skipped Knowledge Base Entry. + */ + name: z.string().optional(), + skip_reason: KnowledgeBaseEntryBulkActionSkipReason, + }) +); export type KnowledgeBaseEntryBulkActionSkipResult = z.infer< typeof KnowledgeBaseEntryBulkActionSkipResult >; -export const KnowledgeBaseEntryBulkActionSkipResult = z.object({ - /** - * ID of the skipped Knowledge Base Entry. - */ - id: z.string(), - /** - * Name of the skipped Knowledge Base Entry. - */ - name: z.string().optional(), - skip_reason: KnowledgeBaseEntryBulkActionSkipReason, -}); +export const KnowledgeBaseEntryDetailsInError = lazySchema(() => + z.object({ + /** + * ID of the Knowledge Base Entry that encountered an error. + */ + id: z.string(), + /** + * Name of the Knowledge Base Entry that encountered an error. + */ + name: z.string().optional(), + }) +); export type KnowledgeBaseEntryDetailsInError = z.infer; -export const KnowledgeBaseEntryDetailsInError = z.object({ - /** - * ID of the Knowledge Base Entry that encountered an error. - */ - id: z.string(), - /** - * Name of the Knowledge Base Entry that encountered an error. - */ - name: z.string().optional(), -}); +export const NormalizedKnowledgeBaseEntryError = lazySchema(() => + z.object({ + /** + * Error message describing the issue. + */ + message: z.string(), + /** + * HTTP status code associated with the error. + */ + statusCode: z.number().int(), + /** + * Specific error code for the issue. + */ + err_code: z.string().optional(), + /** + * List of Knowledge Base Entries that encountered the error. + */ + knowledgeBaseEntries: z.array(KnowledgeBaseEntryDetailsInError), + }) +); export type NormalizedKnowledgeBaseEntryError = z.infer; -export const NormalizedKnowledgeBaseEntryError = z.object({ - /** - * Error message describing the issue. - */ - message: z.string(), - /** - * HTTP status code associated with the error. - */ - statusCode: z.number().int(), - /** - * Specific error code for the issue. - */ - err_code: z.string().optional(), - /** - * List of Knowledge Base Entries that encountered the error. - */ - knowledgeBaseEntries: z.array(KnowledgeBaseEntryDetailsInError), -}); +export const KnowledgeBaseEntryBulkCrudActionResults = lazySchema(() => + z.object({ + /** + * List of Knowledge Base Entries that were successfully updated. + */ + updated: z.array(KnowledgeBaseEntryResponse), + /** + * List of Knowledge Base Entries that were successfully created. + */ + created: z.array(KnowledgeBaseEntryResponse), + /** + * List of IDs of Knowledge Base Entries that were successfully deleted. + */ + deleted: z.array(z.string()), + /** + * List of Knowledge Base Entries that were skipped during the bulk action. + */ + skipped: z.array(KnowledgeBaseEntryBulkActionSkipResult), + }) +); export type KnowledgeBaseEntryBulkCrudActionResults = z.infer< typeof KnowledgeBaseEntryBulkCrudActionResults >; -export const KnowledgeBaseEntryBulkCrudActionResults = z.object({ - /** - * List of Knowledge Base Entries that were successfully updated. - */ - updated: z.array(KnowledgeBaseEntryResponse), - /** - * List of Knowledge Base Entries that were successfully created. - */ - created: z.array(KnowledgeBaseEntryResponse), - /** - * List of IDs of Knowledge Base Entries that were successfully deleted. - */ - deleted: z.array(z.string()), - /** - * List of Knowledge Base Entries that were skipped during the bulk action. - */ - skipped: z.array(KnowledgeBaseEntryBulkActionSkipResult), -}); +export const KnowledgeBaseEntryBulkCrudActionSummary = lazySchema(() => + z.object({ + /** + * Number of Knowledge Base Entries that failed during the bulk action. + */ + failed: z.number().int(), + /** + * Number of Knowledge Base Entries that were skipped during the bulk action. + */ + skipped: z.number().int(), + /** + * Number of Knowledge Base Entries that were successfully processed during the bulk action. + */ + succeeded: z.number().int(), + /** + * Total number of Knowledge Base Entries involved in the bulk action. + */ + total: z.number().int(), + }) +); export type KnowledgeBaseEntryBulkCrudActionSummary = z.infer< typeof KnowledgeBaseEntryBulkCrudActionSummary >; -export const KnowledgeBaseEntryBulkCrudActionSummary = z.object({ - /** - * Number of Knowledge Base Entries that failed during the bulk action. - */ - failed: z.number().int(), - /** - * Number of Knowledge Base Entries that were skipped during the bulk action. - */ - skipped: z.number().int(), - /** - * Number of Knowledge Base Entries that were successfully processed during the bulk action. - */ - succeeded: z.number().int(), - /** - * Total number of Knowledge Base Entries involved in the bulk action. - */ - total: z.number().int(), -}); +export const KnowledgeBaseEntryBulkCrudActionResponse = lazySchema(() => + z.object({ + /** + * Indicates whether the bulk action was successful. + */ + success: z.boolean().optional(), + /** + * HTTP status code of the response. + */ + statusCode: z.number().int().optional(), + /** + * Message describing the result of the bulk action. + */ + message: z.string().optional(), + /** + * Total number of Knowledge Base Entries processed. + */ + knowledgeBaseEntriesCount: z.number().int().optional(), + attributes: z.object({ + results: KnowledgeBaseEntryBulkCrudActionResults, + summary: KnowledgeBaseEntryBulkCrudActionSummary, + /** + * List of errors encountered during the bulk action. + */ + errors: z.array(NormalizedKnowledgeBaseEntryError).optional(), + }), + }) +); export type KnowledgeBaseEntryBulkCrudActionResponse = z.infer< typeof KnowledgeBaseEntryBulkCrudActionResponse >; -export const KnowledgeBaseEntryBulkCrudActionResponse = z.object({ - /** - * Indicates whether the bulk action was successful. - */ - success: z.boolean().optional(), - /** - * HTTP status code of the response. - */ - statusCode: z.number().int().optional(), - /** - * Message describing the result of the bulk action. - */ - message: z.string().optional(), - /** - * Total number of Knowledge Base Entries processed. - */ - knowledgeBaseEntriesCount: z.number().int().optional(), - attributes: z.object({ - results: KnowledgeBaseEntryBulkCrudActionResults, - summary: KnowledgeBaseEntryBulkCrudActionSummary, - /** - * List of errors encountered during the bulk action. - */ - errors: z.array(NormalizedKnowledgeBaseEntryError).optional(), - }), -}); +export const KnowledgeBaseEntryBulkActionBase = lazySchema(() => + z.object({ + /** + * Query to filter Knowledge Base Entries. + */ + query: z.string().optional(), + /** + * Array of Knowledge Base Entry IDs. + */ + ids: z.array(z.string()).min(1).optional(), + }) +); export type KnowledgeBaseEntryBulkActionBase = z.infer; -export const KnowledgeBaseEntryBulkActionBase = z.object({ - /** - * Query to filter Knowledge Base Entries. - */ - query: z.string().optional(), - /** - * Array of Knowledge Base Entry IDs. - */ - ids: z.array(z.string()).min(1).optional(), -}); +export const PerformKnowledgeBaseEntryBulkActionRequestBody = lazySchema(() => + z.object({ + delete: KnowledgeBaseEntryBulkActionBase.optional(), + /** + * List of Knowledge Base Entries to create. + */ + create: z.array(KnowledgeBaseEntryCreateProps).optional(), + /** + * List of Knowledge Base Entries to update. + */ + update: z.array(KnowledgeBaseEntryUpdateProps).optional(), + }) +); export type PerformKnowledgeBaseEntryBulkActionRequestBody = z.infer< typeof PerformKnowledgeBaseEntryBulkActionRequestBody >; -export const PerformKnowledgeBaseEntryBulkActionRequestBody = z.object({ - delete: KnowledgeBaseEntryBulkActionBase.optional(), - /** - * List of Knowledge Base Entries to create. - */ - create: z.array(KnowledgeBaseEntryCreateProps).optional(), - /** - * List of Knowledge Base Entries to update. - */ - update: z.array(KnowledgeBaseEntryUpdateProps).optional(), -}); export type PerformKnowledgeBaseEntryBulkActionRequestBodyInput = z.input< typeof PerformKnowledgeBaseEntryBulkActionRequestBody >; +export const PerformKnowledgeBaseEntryBulkActionResponse = lazySchema( + () => KnowledgeBaseEntryBulkCrudActionResponse +); export type PerformKnowledgeBaseEntryBulkActionResponse = z.infer< typeof PerformKnowledgeBaseEntryBulkActionResponse >; -export const PerformKnowledgeBaseEntryBulkActionResponse = KnowledgeBaseEntryBulkCrudActionResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts index 453e45af31d48..463d445f93f4e 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/common_attributes.gen.ts @@ -14,268 +14,306 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { User, NonEmptyString } from '../../common_attributes.gen'; /** * Array of objects defining the input schema, allowing the LLM to extract structured data to be used in retrieval. */ -export type InputSchema = z.infer; -export const InputSchema = z.array( - z.object({ - /** - * Name of the field. - */ - fieldName: z.string(), - /** - * Type of the field. - */ - fieldType: z.string(), - /** - * Description of the field. - */ - description: z.string(), - }) +export const InputSchema = lazySchema(() => + z.array( + z.object({ + /** + * Name of the field. + */ + fieldName: z.string(), + /** + * Type of the field. + */ + fieldType: z.string(), + /** + * Description of the field. + */ + description: z.string(), + }) + ) ); +export type InputSchema = z.infer; +export const KnowledgeBaseEntryErrorSchema = lazySchema(() => + z + .object({ + /** + * HTTP status code of the error. + */ + statusCode: z.number(), + /** + * Error type or category. + */ + error: z.string(), + /** + * Detailed error message. + */ + message: z.string(), + }) + .strict() +); export type KnowledgeBaseEntryErrorSchema = z.infer; -export const KnowledgeBaseEntryErrorSchema = z - .object({ - /** - * HTTP status code of the error. - */ - statusCode: z.number(), - /** - * Error type or category. - */ - error: z.string(), - /** - * Detailed error message. - */ - message: z.string(), - }) - .strict(); /** * Knowledge Base resource name for grouping entries, e.g. 'security_labs', 'user', etc. */ +export const KnowledgeBaseResource = lazySchema(() => + z.enum(['security_labs', 'defend_insights', 'user']) +); export type KnowledgeBaseResource = z.infer; -export const KnowledgeBaseResource = z.enum(['security_labs', 'defend_insights', 'user']); export type KnowledgeBaseResourceEnum = typeof KnowledgeBaseResource.enum; export const KnowledgeBaseResourceEnum = KnowledgeBaseResource.enum; /** * Metadata about a Knowledge Base Entry. */ +export const Metadata = lazySchema(() => + z.object({ + kbResource: KnowledgeBaseResource, + /** + * Source document name or filepath. + */ + source: z.string(), + /** + * Whether this resource should always be included. + */ + required: z.boolean(), + }) +); export type Metadata = z.infer; -export const Metadata = z.object({ - kbResource: KnowledgeBaseResource, - /** - * Source document name or filepath. - */ - source: z.string(), - /** - * Whether this resource should always be included. - */ - required: z.boolean(), -}); /** * Object containing Knowledge Base Entry text embeddings and modelId used to create the embeddings. */ +export const Vector = lazySchema(() => + z.object({ + /** + * ID of the model used to create the embeddings. + */ + modelId: z.string(), + /** + * Tokens with their corresponding values. + */ + tokens: z.object({}).catchall(z.number()), + }) +); export type Vector = z.infer; -export const Vector = z.object({ - /** - * ID of the model used to create the embeddings. - */ - modelId: z.string(), - /** - * Tokens with their corresponding values. - */ - tokens: z.object({}).catchall(z.number()), -}); +export const BaseRequiredFields = lazySchema(() => + z.object({ + /** + * Name of the Knowledge Base Entry. + */ + name: z.string(), + }) +); export type BaseRequiredFields = z.infer; -export const BaseRequiredFields = z.object({ - /** - * Name of the Knowledge Base Entry. - */ - name: z.string(), -}); +export const BaseDefaultableFields = lazySchema(() => + z.object({ + /** + * Kibana Space, defaults to 'default' space. + */ + namespace: z.string().optional(), + /** + * Whether this Knowledge Base Entry is global, defaults to false. + */ + global: z.boolean().optional(), + /** + * Users who have access to the Knowledge Base Entry, defaults to current user. Empty array provides access to all users. + */ + users: z.array(User).optional(), + }) +); export type BaseDefaultableFields = z.infer; -export const BaseDefaultableFields = z.object({ - /** - * Kibana Space, defaults to 'default' space. - */ - namespace: z.string().optional(), - /** - * Whether this Knowledge Base Entry is global, defaults to false. - */ - global: z.boolean().optional(), - /** - * Users who have access to the Knowledge Base Entry, defaults to current user. Empty array provides access to all users. - */ - users: z.array(User).optional(), -}); +export const BaseCreateProps = lazySchema(() => BaseRequiredFields.merge(BaseDefaultableFields)); export type BaseCreateProps = z.infer; -export const BaseCreateProps = BaseRequiredFields.extend(BaseDefaultableFields); +export const BaseUpdateProps = lazySchema(() => + BaseCreateProps.partial().merge( + z.object({ + id: NonEmptyString, + }) + ) +); export type BaseUpdateProps = z.infer; -export const BaseUpdateProps = BaseCreateProps.partial().extend( + +export const BaseResponseProps = lazySchema(() => + BaseRequiredFields.merge(BaseDefaultableFields.required()) +); +export type BaseResponseProps = z.infer; + +export const ResponseFields = lazySchema(() => z.object({ id: NonEmptyString, + /** + * Time the Knowledge Base Entry was created. + */ + createdAt: z.string(), + /** + * User who created the Knowledge Base Entry. + */ + createdBy: z.string(), + /** + * Time the Knowledge Base Entry was last updated. + */ + updatedAt: z.string(), + /** + * User who last updated the Knowledge Base Entry. + */ + updatedBy: z.string(), }) ); - -export type BaseResponseProps = z.infer; -export const BaseResponseProps = BaseRequiredFields.extend(BaseDefaultableFields.required()); - export type ResponseFields = z.infer; -export const ResponseFields = z.object({ - id: NonEmptyString, - /** - * Time the Knowledge Base Entry was created. - */ - createdAt: z.string(), - /** - * User who created the Knowledge Base Entry. - */ - createdBy: z.string(), - /** - * Time the Knowledge Base Entry was last updated. - */ - updatedAt: z.string(), - /** - * User who last updated the Knowledge Base Entry. - */ - updatedBy: z.string(), -}); +export const DeleteResponseFields = lazySchema(() => + z.object({ + id: NonEmptyString, + }) +); export type DeleteResponseFields = z.infer; -export const DeleteResponseFields = z.object({ - id: NonEmptyString, -}); +export const SharedResponseProps = lazySchema(() => BaseResponseProps.merge(ResponseFields)); export type SharedResponseProps = z.infer; -export const SharedResponseProps = BaseResponseProps.extend(ResponseFields); +export const DocumentEntryType = lazySchema(() => z.literal('document')); export type DocumentEntryType = z.infer; -export const DocumentEntryType = z.literal('document'); +export const DocumentEntryRequiredFields = lazySchema(() => + z.object({ + /** + * Entry type. + */ + type: z.literal('document'), + kbResource: KnowledgeBaseResource, + /** + * Source document name or filepath. + */ + source: z.string(), + /** + * Knowledge Base Entry content. + */ + text: z.string(), + }) +); export type DocumentEntryRequiredFields = z.infer; -export const DocumentEntryRequiredFields = z.object({ - /** - * Entry type. - */ - type: z.literal('document'), - kbResource: KnowledgeBaseResource, - /** - * Source document name or filepath. - */ - source: z.string(), - /** - * Knowledge Base Entry content. - */ - text: z.string(), -}); +export const DocumentEntryOptionalFields = lazySchema(() => + z.object({ + /** + * Whether this resource should always be included, defaults to false. + */ + required: z.boolean().optional(), + vector: Vector.optional(), + }) +); export type DocumentEntryOptionalFields = z.infer; -export const DocumentEntryOptionalFields = z.object({ - /** - * Whether this resource should always be included, defaults to false. - */ - required: z.boolean().optional(), - vector: Vector.optional(), -}); -export type DocumentEntryCreateFields = z.infer; -export const DocumentEntryCreateFields = BaseCreateProps.extend(DocumentEntryRequiredFields).extend( - DocumentEntryOptionalFields +export const DocumentEntryCreateFields = lazySchema(() => + BaseCreateProps.merge(DocumentEntryRequiredFields).merge(DocumentEntryOptionalFields) ); +export type DocumentEntryCreateFields = z.infer; +export const DocumentEntryUpdateFields = lazySchema(() => + BaseUpdateProps.merge(DocumentEntryCreateFields) +); export type DocumentEntryUpdateFields = z.infer; -export const DocumentEntryUpdateFields = BaseUpdateProps.extend(DocumentEntryCreateFields); -export type DocumentEntryResponseFields = z.infer; -export const DocumentEntryResponseFields = DocumentEntryRequiredFields.extend( - DocumentEntryOptionalFields +export const DocumentEntryResponseFields = lazySchema(() => + DocumentEntryRequiredFields.merge(DocumentEntryOptionalFields) ); +export type DocumentEntryResponseFields = z.infer; +export const DocumentEntry = lazySchema(() => + SharedResponseProps.merge(DocumentEntryResponseFields) +); export type DocumentEntry = z.infer; -export const DocumentEntry = SharedResponseProps.extend(DocumentEntryResponseFields); +export const IndexEntryType = lazySchema(() => z.literal('index')); export type IndexEntryType = z.infer; -export const IndexEntryType = z.literal('index'); +export const IndexEntryRequiredFields = lazySchema(() => + z.object({ + /** + * Entry type. + */ + type: z.literal('index'), + /** + * Index or Data Stream to query for Knowledge Base content. + */ + index: z.string(), + /** + * Field to query for Knowledge Base content. + */ + field: z.string(), + /** + * Description for when this index or data stream should be queried for Knowledge Base content. Passed to the LLM as a tool description. + */ + description: z.string(), + /** + * Description of query field used to fetch Knowledge Base content. Passed to the LLM as part of the tool input schema. + */ + queryDescription: z.string(), + }) +); export type IndexEntryRequiredFields = z.infer; -export const IndexEntryRequiredFields = z.object({ - /** - * Entry type. - */ - type: z.literal('index'), - /** - * Index or Data Stream to query for Knowledge Base content. - */ - index: z.string(), - /** - * Field to query for Knowledge Base content. - */ - field: z.string(), - /** - * Description for when this index or data stream should be queried for Knowledge Base content. Passed to the LLM as a tool description. - */ - description: z.string(), - /** - * Description of query field used to fetch Knowledge Base content. Passed to the LLM as part of the tool input schema. - */ - queryDescription: z.string(), -}); +export const IndexEntryOptionalFields = lazySchema(() => + z.object({ + inputSchema: InputSchema.optional(), + /** + * Fields to extract from the query result, defaults to all fields if not provided or empty. + */ + outputFields: z.array(z.string()).optional(), + }) +); export type IndexEntryOptionalFields = z.infer; -export const IndexEntryOptionalFields = z.object({ - inputSchema: InputSchema.optional(), - /** - * Fields to extract from the query result, defaults to all fields if not provided or empty. - */ - outputFields: z.array(z.string()).optional(), -}); +export const IndexEntryCreateFields = lazySchema(() => + BaseCreateProps.merge(IndexEntryRequiredFields).merge(IndexEntryOptionalFields) +); export type IndexEntryCreateFields = z.infer; -export const IndexEntryCreateFields = - BaseCreateProps.extend(IndexEntryRequiredFields).extend(IndexEntryOptionalFields); +export const IndexEntryUpdateFields = lazySchema(() => + BaseUpdateProps.merge(IndexEntryCreateFields) +); export type IndexEntryUpdateFields = z.infer; -export const IndexEntryUpdateFields = BaseUpdateProps.extend(IndexEntryCreateFields); +export const IndexEntryResponseFields = lazySchema(() => + IndexEntryRequiredFields.merge(IndexEntryOptionalFields) +); export type IndexEntryResponseFields = z.infer; -export const IndexEntryResponseFields = IndexEntryRequiredFields.extend(IndexEntryOptionalFields); +export const IndexEntry = lazySchema(() => SharedResponseProps.merge(IndexEntryResponseFields)); export type IndexEntry = z.infer; -export const IndexEntry = SharedResponseProps.extend(IndexEntryResponseFields); +export const KnowledgeBaseEntryCreateProps = lazySchema(() => + z.discriminatedUnion('type', [DocumentEntryCreateFields, IndexEntryCreateFields]) +); export type KnowledgeBaseEntryCreateProps = z.infer; -export const KnowledgeBaseEntryCreateProps = z.discriminatedUnion('type', [ - DocumentEntryCreateFields, - IndexEntryCreateFields, -]); +export const KnowledgeBaseEntryUpdateProps = lazySchema(() => + z.discriminatedUnion('type', [DocumentEntryUpdateFields, IndexEntryUpdateFields]) +); export type KnowledgeBaseEntryUpdateProps = z.infer; -export const KnowledgeBaseEntryUpdateProps = z.discriminatedUnion('type', [ - DocumentEntryUpdateFields, - IndexEntryUpdateFields, -]); +export const KnowledgeBaseEntryUpdateRouteProps = lazySchema(() => + z.discriminatedUnion('type', [DocumentEntryCreateFields, IndexEntryCreateFields]) +); export type KnowledgeBaseEntryUpdateRouteProps = z.infer; -export const KnowledgeBaseEntryUpdateRouteProps = z.discriminatedUnion('type', [ - DocumentEntryCreateFields, - IndexEntryCreateFields, -]); +export const KnowledgeBaseEntryResponse = lazySchema(() => + z.discriminatedUnion('type', [DocumentEntry, IndexEntry]) +); export type KnowledgeBaseEntryResponse = z.infer; -export const KnowledgeBaseEntryResponse = z.discriminatedUnion('type', [DocumentEntry, IndexEntry]); +export const KnowledgeBaseEntryDeleteResponse = lazySchema(() => DeleteResponseFields); export type KnowledgeBaseEntryDeleteResponse = z.infer; -export const KnowledgeBaseEntryDeleteResponse = DeleteResponseFields; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/crud_knowledge_base_entries_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/crud_knowledge_base_entries_route.gen.ts index bd08897ecc03f..6475514478a0d 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/crud_knowledge_base_entries_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/crud_knowledge_base_entries_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { KnowledgeBaseEntryCreateProps, @@ -24,69 +24,77 @@ import { } from './common_attributes.gen'; import { NonEmptyString } from '../../common_attributes.gen'; +export const CreateKnowledgeBaseEntryRequestBody = lazySchema(() => KnowledgeBaseEntryCreateProps); export type CreateKnowledgeBaseEntryRequestBody = z.infer< typeof CreateKnowledgeBaseEntryRequestBody >; -export const CreateKnowledgeBaseEntryRequestBody = KnowledgeBaseEntryCreateProps; export type CreateKnowledgeBaseEntryRequestBodyInput = z.input< typeof CreateKnowledgeBaseEntryRequestBody >; +export const CreateKnowledgeBaseEntryResponse = lazySchema(() => KnowledgeBaseEntryResponse); export type CreateKnowledgeBaseEntryResponse = z.infer; -export const CreateKnowledgeBaseEntryResponse = KnowledgeBaseEntryResponse; +export const DeleteKnowledgeBaseEntryRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (`id`) of the Knowledge Base Entry to delete. + */ + id: NonEmptyString, + }) +); export type DeleteKnowledgeBaseEntryRequestParams = z.infer< typeof DeleteKnowledgeBaseEntryRequestParams >; -export const DeleteKnowledgeBaseEntryRequestParams = z.object({ - /** - * The unique identifier (`id`) of the Knowledge Base Entry to delete. - */ - id: NonEmptyString, -}); export type DeleteKnowledgeBaseEntryRequestParamsInput = z.input< typeof DeleteKnowledgeBaseEntryRequestParams >; +export const DeleteKnowledgeBaseEntryResponse = lazySchema(() => DeleteResponseFields); export type DeleteKnowledgeBaseEntryResponse = z.infer; -export const DeleteKnowledgeBaseEntryResponse = DeleteResponseFields; +export const ReadKnowledgeBaseEntryRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (`id`) of the Knowledge Base Entry to retrieve. + */ + id: NonEmptyString, + }) +); export type ReadKnowledgeBaseEntryRequestParams = z.infer< typeof ReadKnowledgeBaseEntryRequestParams >; -export const ReadKnowledgeBaseEntryRequestParams = z.object({ - /** - * The unique identifier (`id`) of the Knowledge Base Entry to retrieve. - */ - id: NonEmptyString, -}); export type ReadKnowledgeBaseEntryRequestParamsInput = z.input< typeof ReadKnowledgeBaseEntryRequestParams >; +export const ReadKnowledgeBaseEntryResponse = lazySchema(() => KnowledgeBaseEntryResponse); export type ReadKnowledgeBaseEntryResponse = z.infer; -export const ReadKnowledgeBaseEntryResponse = KnowledgeBaseEntryResponse; +export const UpdateKnowledgeBaseEntryRequestParams = lazySchema(() => + z.object({ + /** + * The unique identifier (`id`) of the Knowledge Base Entry to update. + */ + id: NonEmptyString, + }) +); export type UpdateKnowledgeBaseEntryRequestParams = z.infer< typeof UpdateKnowledgeBaseEntryRequestParams >; -export const UpdateKnowledgeBaseEntryRequestParams = z.object({ - /** - * The unique identifier (`id`) of the Knowledge Base Entry to update. - */ - id: NonEmptyString, -}); export type UpdateKnowledgeBaseEntryRequestParamsInput = z.input< typeof UpdateKnowledgeBaseEntryRequestParams >; +export const UpdateKnowledgeBaseEntryRequestBody = lazySchema( + () => KnowledgeBaseEntryUpdateRouteProps +); export type UpdateKnowledgeBaseEntryRequestBody = z.infer< typeof UpdateKnowledgeBaseEntryRequestBody >; -export const UpdateKnowledgeBaseEntryRequestBody = KnowledgeBaseEntryUpdateRouteProps; export type UpdateKnowledgeBaseEntryRequestBodyInput = z.input< typeof UpdateKnowledgeBaseEntryRequestBody >; +export const UpdateKnowledgeBaseEntryResponse = lazySchema(() => KnowledgeBaseEntryResponse); export type UpdateKnowledgeBaseEntryResponse = z.infer; -export const UpdateKnowledgeBaseEntryResponse = KnowledgeBaseEntryResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/find_knowledge_base_entries_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/find_knowledge_base_entries_route.gen.ts index 06e8dca02e11e..23163afb5ae2e 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/find_knowledge_base_entries_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/entries/find_knowledge_base_entries_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../../common_attributes.gen'; @@ -23,65 +23,66 @@ import { KnowledgeBaseEntryResponse } from './common_attributes.gen'; /** * Fields available for sorting Knowledge Base Entries. */ +export const FindKnowledgeBaseEntriesSortField = lazySchema(() => + z.enum(['created_at', 'is_default', 'title', 'updated_at']) +); export type FindKnowledgeBaseEntriesSortField = z.infer; -export const FindKnowledgeBaseEntriesSortField = z.enum([ - 'created_at', - 'is_default', - 'title', - 'updated_at', -]); export type FindKnowledgeBaseEntriesSortFieldEnum = typeof FindKnowledgeBaseEntriesSortField.enum; export const FindKnowledgeBaseEntriesSortFieldEnum = FindKnowledgeBaseEntriesSortField.enum; +export const FindKnowledgeBaseEntriesRequestQuery = lazySchema(() => + z.object({ + /** + * A list of fields to include in the response. If not provided, all fields will be included. + */ + fields: ArrayFromString(z.string()).optional(), + /** + * Search query to filter Knowledge Base Entries by specific criteria. + */ + filter: z.string().optional(), + /** + * Field to sort the Knowledge Base Entries by. + */ + sort_field: FindKnowledgeBaseEntriesSortField.optional(), + /** + * Sort order for the results, either asc or desc. + */ + sort_order: SortOrder.optional(), + /** + * Page number for paginated results. Defaults to 1. + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * Number of Knowledge Base Entries to return per page. Defaults to 20. + */ + per_page: z.coerce.number().int().min(0).optional().default(20), + }) +); export type FindKnowledgeBaseEntriesRequestQuery = z.infer< typeof FindKnowledgeBaseEntriesRequestQuery >; -export const FindKnowledgeBaseEntriesRequestQuery = z.object({ - /** - * A list of fields to include in the response. If not provided, all fields will be included. - */ - fields: ArrayFromString(z.string()).optional(), - /** - * Search query to filter Knowledge Base Entries by specific criteria. - */ - filter: z.string().optional(), - /** - * Field to sort the Knowledge Base Entries by. - */ - sort_field: FindKnowledgeBaseEntriesSortField.optional(), - /** - * Sort order for the results, either asc or desc. - */ - sort_order: SortOrder.optional(), - /** - * Page number for paginated results. Defaults to 1. - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * Number of Knowledge Base Entries to return per page. Defaults to 20. - */ - per_page: z.coerce.number().int().min(0).optional().default(20), -}); export type FindKnowledgeBaseEntriesRequestQueryInput = z.input< typeof FindKnowledgeBaseEntriesRequestQuery >; +export const FindKnowledgeBaseEntriesResponse = lazySchema(() => + z.object({ + /** + * The current page number. + */ + page: z.number().int(), + /** + * The number of Knowledge Base Entries returned per page. + */ + perPage: z.number().int(), + /** + * The total number of Knowledge Base Entries available. + */ + total: z.number().int(), + /** + * The list of Knowledge Base Entries for the current page. + */ + data: z.array(KnowledgeBaseEntryResponse), + }) +); export type FindKnowledgeBaseEntriesResponse = z.infer; -export const FindKnowledgeBaseEntriesResponse = z.object({ - /** - * The current page number. - */ - page: z.number().int(), - /** - * The number of Knowledge Base Entries returned per page. - */ - perPage: z.number().int(), - /** - * The total number of Knowledge Base Entries available. - */ - total: z.number().int(), - /** - * The list of Knowledge Base Entries for the current page. - */ - data: z.array(KnowledgeBaseEntryResponse), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/bulk_crud_prompts_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/bulk_crud_prompts_route.gen.ts index 565b07a5a4c8c..2fc30da292d8f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/bulk_crud_prompts_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/bulk_crud_prompts_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BulkActionBase, @@ -27,260 +27,278 @@ import { /** * Reason why a prompt was skipped during the bulk action. */ +export const PromptsBulkActionSkipReason = lazySchema(() => z.literal('PROMPT_FIELD_NOT_MODIFIED')); export type PromptsBulkActionSkipReason = z.infer; -export const PromptsBulkActionSkipReason = z.literal('PROMPT_FIELD_NOT_MODIFIED'); +export const PromptsBulkActionSkipResult = lazySchema(() => + z.object({ + /** + * The ID of the prompt that was skipped. + */ + id: z.string(), + /** + * The name of the prompt that was skipped. + */ + name: z.string().optional(), + /** + * The reason for skipping the prompt. + */ + skip_reason: PromptsBulkActionSkipReason, + }) +); export type PromptsBulkActionSkipResult = z.infer; -export const PromptsBulkActionSkipResult = z.object({ - /** - * The ID of the prompt that was skipped. - */ - id: z.string(), - /** - * The name of the prompt that was skipped. - */ - name: z.string().optional(), - /** - * The reason for skipping the prompt. - */ - skip_reason: PromptsBulkActionSkipReason, -}); +export const PromptDetailsInError = lazySchema(() => + z.object({ + /** + * The ID of the prompt that encountered an error. + */ + id: z.string(), + /** + * The name of the prompt that encountered an error. + */ + name: z.string().optional(), + }) +); export type PromptDetailsInError = z.infer; -export const PromptDetailsInError = z.object({ - /** - * The ID of the prompt that encountered an error. - */ - id: z.string(), - /** - * The name of the prompt that encountered an error. - */ - name: z.string().optional(), -}); /** * Type of the prompt (either system or quick). */ +export const PromptType = lazySchema(() => z.enum(['system', 'quick'])); export type PromptType = z.infer; -export const PromptType = z.enum(['system', 'quick']); export type PromptTypeEnum = typeof PromptType.enum; export const PromptTypeEnum = PromptType.enum; +export const NormalizedPromptError = lazySchema(() => + z.object({ + /** + * A message describing the error encountered. + */ + message: z.string(), + /** + * The HTTP status code associated with the error. + */ + status_code: z.number().int(), + /** + * A code representing the error type. + */ + err_code: z.string().optional(), + /** + * List of prompts that encountered errors. + */ + prompts: z.array(PromptDetailsInError), + }) +); export type NormalizedPromptError = z.infer; -export const NormalizedPromptError = z.object({ - /** - * A message describing the error encountered. - */ - message: z.string(), - /** - * The HTTP status code associated with the error. - */ - status_code: z.number().int(), - /** - * A code representing the error type. - */ - err_code: z.string().optional(), - /** - * List of prompts that encountered errors. - */ - prompts: z.array(PromptDetailsInError), -}); +export const PromptResponse = lazySchema(() => + z.object({ + id: NonEmptyString, + timestamp: NonEmptyTimestamp.optional(), + /** + * The name of the prompt. + */ + name: z.string(), + /** + * The type of the prompt. + */ + promptType: PromptType, + /** + * The content of the prompt. + */ + content: z.string(), + /** + * Categories associated with the prompt. + */ + categories: z.array(z.string()).optional(), + /** + * The color associated with the prompt. + */ + color: z.string().optional(), + /** + * Whether this prompt is the default for new conversations. + */ + isNewConversationDefault: z.boolean().optional(), + /** + * Whether this prompt is the default. + */ + isDefault: z.boolean().optional(), + /** + * The consumer that the prompt is associated with. + */ + consumer: z.string().optional(), + /** + * The timestamp of when the prompt was last updated. + */ + updatedAt: z.string().optional(), + /** + * The user who last updated the prompt. + */ + updatedBy: z.string().optional(), + /** + * The timestamp of when the prompt was created. + */ + createdAt: z.string().optional(), + /** + * The user who created the prompt. + */ + createdBy: z.string().optional(), + /** + * List of users associated with the prompt. + */ + users: z.array(User).optional(), + /** + * Kibana space where the prompt is located. + */ + namespace: z.string().optional(), + }) +); export type PromptResponse = z.infer; -export const PromptResponse = z.object({ - id: NonEmptyString, - timestamp: NonEmptyTimestamp.optional(), - /** - * The name of the prompt. - */ - name: z.string(), - /** - * The type of the prompt. - */ - promptType: PromptType, - /** - * The content of the prompt. - */ - content: z.string(), - /** - * Categories associated with the prompt. - */ - categories: z.array(z.string()).optional(), - /** - * The color associated with the prompt. - */ - color: z.string().optional(), - /** - * Whether this prompt is the default for new conversations. - */ - isNewConversationDefault: z.boolean().optional(), - /** - * Whether this prompt is the default. - */ - isDefault: z.boolean().optional(), - /** - * The consumer that the prompt is associated with. - */ - consumer: z.string().optional(), - /** - * The timestamp of when the prompt was last updated. - */ - updatedAt: z.string().optional(), - /** - * The user who last updated the prompt. - */ - updatedBy: z.string().optional(), - /** - * The timestamp of when the prompt was created. - */ - createdAt: z.string().optional(), - /** - * The user who created the prompt. - */ - createdBy: z.string().optional(), - /** - * List of users associated with the prompt. - */ - users: z.array(User).optional(), - /** - * Kibana space where the prompt is located. - */ - namespace: z.string().optional(), -}); +export const PromptsBulkCrudActionResults = lazySchema(() => + z.object({ + /** + * List of prompts that were updated. + */ + updated: z.array(PromptResponse), + /** + * List of prompts that were created. + */ + created: z.array(PromptResponse), + /** + * List of IDs of prompts that were deleted. + */ + deleted: z.array(z.string()), + /** + * List of prompts that were skipped. + */ + skipped: z.array(PromptsBulkActionSkipResult), + }) +); export type PromptsBulkCrudActionResults = z.infer; -export const PromptsBulkCrudActionResults = z.object({ - /** - * List of prompts that were updated. - */ - updated: z.array(PromptResponse), - /** - * List of prompts that were created. - */ - created: z.array(PromptResponse), - /** - * List of IDs of prompts that were deleted. - */ - deleted: z.array(z.string()), - /** - * List of prompts that were skipped. - */ - skipped: z.array(PromptsBulkActionSkipResult), -}); +export const PromptsBulkCrudActionResponse = lazySchema(() => + z.object({ + /** + * Indicates if the bulk action was successful. + */ + success: z.boolean().optional(), + /** + * The HTTP status code of the response. + */ + status_code: z.number().int().optional(), + /** + * A message describing the result of the bulk action. + */ + message: z.string().optional(), + /** + * The number of prompts processed in the bulk action. + */ + prompts_count: z.number().int().optional(), + attributes: z.object({ + results: PromptsBulkCrudActionResults, + summary: BulkCrudActionSummary, + errors: z.array(NormalizedPromptError).optional(), + }), + }) +); export type PromptsBulkCrudActionResponse = z.infer; -export const PromptsBulkCrudActionResponse = z.object({ - /** - * Indicates if the bulk action was successful. - */ - success: z.boolean().optional(), - /** - * The HTTP status code of the response. - */ - status_code: z.number().int().optional(), - /** - * A message describing the result of the bulk action. - */ - message: z.string().optional(), - /** - * The number of prompts processed in the bulk action. - */ - prompts_count: z.number().int().optional(), - attributes: z.object({ - results: PromptsBulkCrudActionResults, - summary: BulkCrudActionSummary, - errors: z.array(NormalizedPromptError).optional(), - }), -}); +export const PromptCreateProps = lazySchema(() => + z.object({ + /** + * The name of the prompt. + */ + name: z.string(), + /** + * The type of the prompt. + */ + promptType: PromptType, + /** + * The content of the prompt. + */ + content: z.string(), + /** + * The color associated with the prompt. + */ + color: z.string().optional(), + /** + * List of categories for the prompt. + */ + categories: z.array(z.string()).optional(), + /** + * Whether this prompt should be the default for new conversations. + */ + isNewConversationDefault: z.boolean().optional(), + /** + * Whether this prompt should be the default. + */ + isDefault: z.boolean().optional(), + /** + * The consumer associated with the prompt. + */ + consumer: z.string().optional(), + }) +); export type PromptCreateProps = z.infer; -export const PromptCreateProps = z.object({ - /** - * The name of the prompt. - */ - name: z.string(), - /** - * The type of the prompt. - */ - promptType: PromptType, - /** - * The content of the prompt. - */ - content: z.string(), - /** - * The color associated with the prompt. - */ - color: z.string().optional(), - /** - * List of categories for the prompt. - */ - categories: z.array(z.string()).optional(), - /** - * Whether this prompt should be the default for new conversations. - */ - isNewConversationDefault: z.boolean().optional(), - /** - * Whether this prompt should be the default. - */ - isDefault: z.boolean().optional(), - /** - * The consumer associated with the prompt. - */ - consumer: z.string().optional(), -}); +export const PromptUpdateProps = lazySchema(() => + z.object({ + /** + * The ID of the prompt to update. + */ + id: z.string(), + /** + * The updated content for the prompt. + */ + content: z.string().optional(), + /** + * The updated color associated with the prompt. + */ + color: z.string().optional(), + /** + * The updated categories for the prompt. + */ + categories: z.array(z.string()).optional(), + /** + * Whether the prompt should be the default for new conversations. + */ + isNewConversationDefault: z.boolean().optional(), + /** + * Whether this prompt should be the default. + */ + isDefault: z.boolean().optional(), + /** + * The updated consumer for the prompt. + */ + consumer: z.string().optional(), + }) +); export type PromptUpdateProps = z.infer; -export const PromptUpdateProps = z.object({ - /** - * The ID of the prompt to update. - */ - id: z.string(), - /** - * The updated content for the prompt. - */ - content: z.string().optional(), - /** - * The updated color associated with the prompt. - */ - color: z.string().optional(), - /** - * The updated categories for the prompt. - */ - categories: z.array(z.string()).optional(), - /** - * Whether the prompt should be the default for new conversations. - */ - isNewConversationDefault: z.boolean().optional(), - /** - * Whether this prompt should be the default. - */ - isDefault: z.boolean().optional(), - /** - * The updated consumer for the prompt. - */ - consumer: z.string().optional(), -}); +export const PerformPromptsBulkActionRequestBody = lazySchema(() => + z.object({ + /** + * Criteria for deleting prompts in bulk. + */ + delete: BulkActionBase.optional(), + /** + * List of prompts to be created. + */ + create: z.array(PromptCreateProps).optional(), + /** + * List of prompts to be updated. + */ + update: z.array(PromptUpdateProps).optional(), + }) +); export type PerformPromptsBulkActionRequestBody = z.infer< typeof PerformPromptsBulkActionRequestBody >; -export const PerformPromptsBulkActionRequestBody = z.object({ - /** - * Criteria for deleting prompts in bulk. - */ - delete: BulkActionBase.optional(), - /** - * List of prompts to be created. - */ - create: z.array(PromptCreateProps).optional(), - /** - * List of prompts to be updated. - */ - update: z.array(PromptUpdateProps).optional(), -}); export type PerformPromptsBulkActionRequestBodyInput = z.input< typeof PerformPromptsBulkActionRequestBody >; +export const PerformPromptsBulkActionResponse = lazySchema(() => PromptsBulkCrudActionResponse); export type PerformPromptsBulkActionResponse = z.infer; -export const PerformPromptsBulkActionResponse = PromptsBulkCrudActionResponse; diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/find_prompts_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/find_prompts_route.gen.ts index 424f36f12692f..5fa21a3144731 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/find_prompts_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/prompts/find_prompts_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../common_attributes.gen'; @@ -23,56 +23,62 @@ import { PromptResponse } from './bulk_crud_prompts_route.gen'; /** * Field by which to sort the prompts. */ +export const FindPromptsSortField = lazySchema(() => + z.enum(['created_at', 'is_default', 'name', 'updated_at']) +); export type FindPromptsSortField = z.infer; -export const FindPromptsSortField = z.enum(['created_at', 'is_default', 'name', 'updated_at']); export type FindPromptsSortFieldEnum = typeof FindPromptsSortField.enum; export const FindPromptsSortFieldEnum = FindPromptsSortField.enum; +export const FindPromptsRequestQuery = lazySchema(() => + z.object({ + /** + * List of specific fields to include in each returned prompt. + */ + fields: ArrayFromString(z.string()).optional(), + /** + * Search query string to filter prompts by matching fields. + */ + filter: z.string().optional(), + /** + * Field to sort prompts by. + */ + sort_field: FindPromptsSortField.optional(), + /** + * Sort order, either asc or desc. + */ + sort_order: SortOrder.optional(), + /** + * Page number for pagination. + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * Number of prompts per page. + */ + per_page: z.coerce.number().int().min(0).optional().default(20), + }) +); export type FindPromptsRequestQuery = z.infer; -export const FindPromptsRequestQuery = z.object({ - /** - * List of specific fields to include in each returned prompt. - */ - fields: ArrayFromString(z.string()).optional(), - /** - * Search query string to filter prompts by matching fields. - */ - filter: z.string().optional(), - /** - * Field to sort prompts by. - */ - sort_field: FindPromptsSortField.optional(), - /** - * Sort order, either asc or desc. - */ - sort_order: SortOrder.optional(), - /** - * Page number for pagination. - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * Number of prompts per page. - */ - per_page: z.coerce.number().int().min(0).optional().default(20), -}); export type FindPromptsRequestQueryInput = z.input; +export const FindPromptsResponse = lazySchema(() => + z.object({ + /** + * Current page number. + */ + page: z.number().int(), + /** + * Number of prompts per page. + */ + perPage: z.number().int(), + /** + * Total number of prompts matching the query. + */ + total: z.number().int(), + /** + * The list of prompts returned based on the search query, sorting, and pagination. + */ + data: z.array(PromptResponse), + }) +); export type FindPromptsResponse = z.infer; -export const FindPromptsResponse = z.object({ - /** - * Current page number. - */ - page: z.number().int(), - /** - * Number of prompts per page. - */ - perPage: z.number().int(), - /** - * Total number of prompts matching the query. - */ - total: z.number().int(), - /** - * The list of prompts returned based on the search query, sorting, and pagination. - */ - data: z.array(PromptResponse), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/common_attributes.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/common_attributes.gen.ts index eb5c74acfb56f..14f822f26389f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/common_attributes.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/common_attributes.gen.ts @@ -14,16 +14,18 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const PromptItem = lazySchema(() => + z.object({ + promptId: z.string(), + prompt: z.string(), + }) +); export type PromptItem = z.infer; -export const PromptItem = z.object({ - promptId: z.string(), - prompt: z.string(), -}); /** * Prompt array by prompt group id and prompt id. */ +export const PromptItemArray = lazySchema(() => z.array(PromptItem)); export type PromptItemArray = z.infer; -export const PromptItemArray = z.array(PromptItem); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/find_prompts_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/find_prompts_route.gen.ts index f4132a92b6ce0..4b544952df63d 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/find_prompts_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/security_ai_prompts/find_prompts_route.gen.ts @@ -14,31 +14,35 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { PromptItemArray } from './common_attributes.gen'; +export const FindSecurityAIPromptsRequestQuery = lazySchema(() => + z.object({ + /** + * Connector id used for prompt lookup + */ + connector_id: z.string().optional(), + /** + * The unique identifier for the prompt group + */ + prompt_group_id: z.string(), + /** + * Comma-separated list of prompt IDs to retrieve + */ + prompt_ids: ArrayFromString(z.string()), + }) +); export type FindSecurityAIPromptsRequestQuery = z.infer; -export const FindSecurityAIPromptsRequestQuery = z.object({ - /** - * Connector id used for prompt lookup - */ - connector_id: z.string().optional(), - /** - * The unique identifier for the prompt group - */ - prompt_group_id: z.string(), - /** - * Comma-separated list of prompt IDs to retrieve - */ - prompt_ids: ArrayFromString(z.string()), -}); export type FindSecurityAIPromptsRequestQueryInput = z.input< typeof FindSecurityAIPromptsRequestQuery >; +export const FindSecurityAIPromptsResponse = lazySchema(() => + z.object({ + prompts: PromptItemArray, + }) +); export type FindSecurityAIPromptsResponse = z.infer; -export const FindSecurityAIPromptsResponse = z.object({ - prompts: PromptItemArray, -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/test_internal/update_anonymization_fields_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/test_internal/update_anonymization_fields_route.gen.ts index 7b29f93ab929b..ba6986ccd7cf5 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/test_internal/update_anonymization_fields_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/test_internal/update_anonymization_fields_route.gen.ts @@ -14,9 +14,11 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const UpdateAnonymizationFieldsResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + }) +); export type UpdateAnonymizationFieldsResponse = z.infer; -export const UpdateAnonymizationFieldsResponse = z.object({ - success: z.boolean().optional(), -}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/users/suggest_route.gen.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/users/suggest_route.gen.ts index fc1ba0d5c0025..72f62cf750214 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/users/suggest_route.gen.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/users/suggest_route.gen.ts @@ -14,55 +14,59 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const SuggestUsersRequestBody = lazySchema(() => + z.object({ + /** + * Search term to filter users + */ + searchTerm: z.string().optional(), + /** + * Number of users to return + */ + size: z.number().optional(), + }) +); export type SuggestUsersRequestBody = z.infer; -export const SuggestUsersRequestBody = z.object({ - /** - * Search term to filter users - */ - searchTerm: z.string().optional(), - /** - * Number of users to return - */ - size: z.number().optional(), -}); export type SuggestUsersRequestBodyInput = z.input; /** * Array of user profiles */ -export type SuggestUsersResponse = z.infer; -export const SuggestUsersResponse = z.array( - z.object({ - /** - * A unique identifier for the user profile. - */ - uid: z.string(), - /** - * Indicates whether user profile is enabled or not. - */ - enabled: z.boolean(), - /** - * User specific data associated with the profile. - */ - data: z.object({}).catchall(z.unknown()), - /** - * Information about the user that owns profile. - */ - user: z.object({ +export const SuggestUsersResponse = lazySchema(() => + z.array( + z.object({ /** - * The username of the user. + * A unique identifier for the user profile. */ - username: z.string(), + uid: z.string(), /** - * The full name of the user. + * Indicates whether user profile is enabled or not. */ - full_name: z.string().optional(), + enabled: z.boolean(), /** - * The email address of the user. + * User specific data associated with the profile. */ - email: z.string().optional(), - }), - }) + data: z.object({}).catchall(z.unknown()), + /** + * Information about the user that owns profile. + */ + user: z.object({ + /** + * The username of the user. + */ + username: z.string(), + /** + * The full name of the user. + */ + full_name: z.string().optional(), + /** + * The email address of the user. + */ + email: z.string().optional(), + }), + }) + ) ); +export type SuggestUsersResponse = z.infer; diff --git a/x-pack/platform/plugins/shared/cases/common/bundled-types.gen.ts b/x-pack/platform/plugins/shared/cases/common/bundled-types.gen.ts index 3a89e0d478800..f5c27b03218c1 100644 --- a/x-pack/platform/plugins/shared/cases/common/bundled-types.gen.ts +++ b/x-pack/platform/plugins/shared/cases/common/bundled-types.gen.ts @@ -14,297 +14,315 @@ * version: 0.1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * An array containing users that are assigned to the case. */ +export const Assignees = lazySchema(() => + z + .array( + z.object({ + /** + * A unique identifier for the user profile. These identifiers can be found by using the suggest user profile API. + */ + uid: z.string(), + }) + ) + .max(10) + .nullable() +); export type Assignees = z.infer; -export const Assignees = z - .array( - z.object({ - /** - * A unique identifier for the user profile. These identifiers can be found by using the suggest user profile API. - */ - uid: z.string(), - }) - ) - .max(10) - .nullable(); /** * Defines properties for connectors when type is `.none`. */ +export const ConnectorPropertiesNone = lazySchema(() => + z.object({ + /** + * An object containing the connector fields. To create a case without a connector, specify null. To update a case to remove the connector, specify null. + */ + fields: z.string().nullable(), + /** + * The identifier for the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. + */ + id: z.string(), + /** + * The name of the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. + */ + name: z.string(), + /** + * The type of connector. To create a case without a connector, use `.none`. To update a case to remove the connector, specify `.none`. + */ + type: z.literal('.none'), + }) +); export type ConnectorPropertiesNone = z.infer; -export const ConnectorPropertiesNone = z.object({ - /** - * An object containing the connector fields. To create a case without a connector, specify null. To update a case to remove the connector, specify null. - */ - fields: z.string().nullable(), - /** - * The identifier for the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. - */ - id: z.string(), - /** - * The name of the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. - */ - name: z.string(), - /** - * The type of connector. To create a case without a connector, use `.none`. To update a case to remove the connector, specify `.none`. - */ - type: z.literal('.none'), -}); /** * Defines properties for connectors when type is `.cases-webhook`. */ +export const ConnectorPropertiesCasesWebhook = lazySchema(() => + z.object({ + fields: z.string().nullable(), + /** + * The identifier for the connector. To retrieve connector IDs, use the find connectors API. + */ + id: z.string(), + /** + * The name of the connector. + */ + name: z.string(), + /** + * The type of connector. + */ + type: z.literal('.cases-webhook'), + }) +); export type ConnectorPropertiesCasesWebhook = z.infer; -export const ConnectorPropertiesCasesWebhook = z.object({ - fields: z.string().nullable(), - /** - * The identifier for the connector. To retrieve connector IDs, use the find connectors API. - */ - id: z.string(), - /** - * The name of the connector. - */ - name: z.string(), - /** - * The type of connector. - */ - type: z.literal('.cases-webhook'), -}); /** * Defines properties for connectors when type is `.jira`. */ -export type ConnectorPropertiesJira = z.infer; -export const ConnectorPropertiesJira = z.object({ - /** - * An object containing the connector fields. If you want to omit any individual field, specify null as its value. - */ - fields: z.object({ - /** - * The type of issue. - */ - issueType: z.string().nullable(), - /** - * The key of the parent issue, when the issue type is sub-task. - */ - parent: z.string().nullable(), - /** - * The priority of the issue. - */ - priority: z.string().nullable(), - }), - /** - * The identifier for the connector. To retrieve connector IDs, use the find connectors API. - */ - id: z.string(), - /** - * The name of the connector. - */ - name: z.string(), - /** - * The type of connector. - */ - type: z.literal('.jira'), -}); - -/** - * Defines properties for connectors when type is `.resilient`. - */ -export type ConnectorPropertiesResilient = z.infer; -export const ConnectorPropertiesResilient = z.object({ - /** - * An object containing the connector fields. If you want to omit any individual field, specify null as its value. - */ - fields: z - .object({ +export const ConnectorPropertiesJira = lazySchema(() => + z.object({ + /** + * An object containing the connector fields. If you want to omit any individual field, specify null as its value. + */ + fields: z.object({ /** - * The type of incident. + * The type of issue. */ - issueTypes: z.array(z.string()), + issueType: z.string().nullable(), /** - * The severity code of the incident. + * The key of the parent issue, when the issue type is sub-task. */ - severityCode: z.string(), - }) - .nullable(), - /** - * The identifier for the connector. - */ - id: z.string(), - /** - * The name of the connector. - */ - name: z.string(), - /** - * The type of connector. - */ - type: z.literal('.resilient'), -}); + parent: z.string().nullable(), + /** + * The priority of the issue. + */ + priority: z.string().nullable(), + }), + /** + * The identifier for the connector. To retrieve connector IDs, use the find connectors API. + */ + id: z.string(), + /** + * The name of the connector. + */ + name: z.string(), + /** + * The type of connector. + */ + type: z.literal('.jira'), + }) +); +export type ConnectorPropertiesJira = z.infer; /** - * Defines properties for connectors when type is `.servicenow`. + * Defines properties for connectors when type is `.resilient`. */ -export type ConnectorPropertiesServicenow = z.infer; -export const ConnectorPropertiesServicenow = z.object({ - /** - * An object containing the connector fields. If you want to omit any individual field, specify null as its value. - */ - fields: z.object({ - /** - * The category of the incident. - */ - category: z.string().nullable(), +export const ConnectorPropertiesResilient = lazySchema(() => + z.object({ /** - * The effect an incident had on business. + * An object containing the connector fields. If you want to omit any individual field, specify null as its value. */ - impact: z.string().nullable(), + fields: z + .object({ + /** + * The type of incident. + */ + issueTypes: z.array(z.string()), + /** + * The severity code of the incident. + */ + severityCode: z.string(), + }) + .nullable(), /** - * The severity of the incident. + * The identifier for the connector. */ - severity: z.string().nullable(), + id: z.string(), /** - * The subcategory of the incident. + * The name of the connector. */ - subcategory: z.string().nullable(), + name: z.string(), /** - * The extent to which the incident resolution can be delayed. + * The type of connector. */ - urgency: z.string().nullable(), - }), - /** - * The identifier for the connector. To retrieve connector IDs, use the find connectors API. - */ - id: z.string(), - /** - * The name of the connector. - */ - name: z.string(), - /** - * The type of connector. - */ - type: z.literal('.servicenow'), -}); + type: z.literal('.resilient'), + }) +); +export type ConnectorPropertiesResilient = z.infer; /** - * Defines properties for connectors when type is `.servicenow-sir`. + * Defines properties for connectors when type is `.servicenow`. */ -export type ConnectorPropertiesServicenowSir = z.infer; -export const ConnectorPropertiesServicenowSir = z.object({ - /** - * An object containing the connector fields. If you want to omit any individual field, specify null as its value. - */ - fields: z.object({ +export const ConnectorPropertiesServicenow = lazySchema(() => + z.object({ + /** + * An object containing the connector fields. If you want to omit any individual field, specify null as its value. + */ + fields: z.object({ + /** + * The category of the incident. + */ + category: z.string().nullable(), + /** + * The effect an incident had on business. + */ + impact: z.string().nullable(), + /** + * The severity of the incident. + */ + severity: z.string().nullable(), + /** + * The subcategory of the incident. + */ + subcategory: z.string().nullable(), + /** + * The extent to which the incident resolution can be delayed. + */ + urgency: z.string().nullable(), + }), /** - * The category of the incident. + * The identifier for the connector. To retrieve connector IDs, use the find connectors API. */ - category: z.string().nullable(), + id: z.string(), /** - * Indicates whether cases will send a comma-separated list of destination IPs. + * The name of the connector. */ - destIp: z.boolean().nullable(), + name: z.string(), /** - * Indicates whether cases will send a comma-separated list of malware hashes. + * The type of connector. */ - malwareHash: z.boolean().nullable(), + type: z.literal('.servicenow'), + }) +); +export type ConnectorPropertiesServicenow = z.infer; + +/** + * Defines properties for connectors when type is `.servicenow-sir`. + */ +export const ConnectorPropertiesServicenowSir = lazySchema(() => + z.object({ /** - * Indicates whether cases will send a comma-separated list of malware URLs. + * An object containing the connector fields. If you want to omit any individual field, specify null as its value. */ - malwareUrl: z.boolean().nullable(), + fields: z.object({ + /** + * The category of the incident. + */ + category: z.string().nullable(), + /** + * Indicates whether cases will send a comma-separated list of destination IPs. + */ + destIp: z.boolean().nullable(), + /** + * Indicates whether cases will send a comma-separated list of malware hashes. + */ + malwareHash: z.boolean().nullable(), + /** + * Indicates whether cases will send a comma-separated list of malware URLs. + */ + malwareUrl: z.boolean().nullable(), + /** + * The priority of the issue. + */ + priority: z.string().nullable(), + /** + * Indicates whether cases will send a comma-separated list of source IPs. + */ + sourceIp: z.boolean().nullable(), + /** + * The subcategory of the incident. + */ + subcategory: z.string().nullable(), + }), /** - * The priority of the issue. + * The identifier for the connector. To retrieve connector IDs, use the find connectors API. */ - priority: z.string().nullable(), + id: z.string(), /** - * Indicates whether cases will send a comma-separated list of source IPs. + * The name of the connector. */ - sourceIp: z.boolean().nullable(), + name: z.string(), /** - * The subcategory of the incident. + * The type of connector. */ - subcategory: z.string().nullable(), - }), - /** - * The identifier for the connector. To retrieve connector IDs, use the find connectors API. - */ - id: z.string(), - /** - * The name of the connector. - */ - name: z.string(), - /** - * The type of connector. - */ - type: z.literal('.servicenow-sir'), -}); + type: z.literal('.servicenow-sir'), + }) +); +export type ConnectorPropertiesServicenowSir = z.infer; /** * Defines properties for connectors when type is `.swimlane`. */ +export const ConnectorPropertiesSwimlane = lazySchema(() => + z.object({ + /** + * An object containing the connector fields. If you want to omit any individual field, specify null as its value. + */ + fields: z.object({ + /** + * The case identifier for Swimlane connectors. + */ + caseId: z.string().nullable(), + }), + /** + * The identifier for the connector. To retrieve connector IDs, use the find connectors API. + */ + id: z.string(), + /** + * The name of the connector. + */ + name: z.string(), + /** + * The type of connector. + */ + type: z.literal('.swimlane'), + }) +); export type ConnectorPropertiesSwimlane = z.infer; -export const ConnectorPropertiesSwimlane = z.object({ - /** - * An object containing the connector fields. If you want to omit any individual field, specify null as its value. - */ - fields: z.object({ - /** - * The case identifier for Swimlane connectors. - */ - caseId: z.string().nullable(), - }), - /** - * The identifier for the connector. To retrieve connector IDs, use the find connectors API. - */ - id: z.string(), - /** - * The name of the connector. - */ - name: z.string(), - /** - * The type of connector. - */ - type: z.literal('.swimlane'), -}); /** * The description for the case. */ +export const CaseDescription = lazySchema(() => z.string().max(30000)); export type CaseDescription = z.infer; -export const CaseDescription = z.string().max(30000); /** * The application that owns the cases: Stack Management, Observability, or Elastic Security. */ +export const Owner = lazySchema(() => z.enum(['cases', 'observability', 'securitySolution'])); export type Owner = z.infer; -export const Owner = z.enum(['cases', 'observability', 'securitySolution']); export type OwnerEnum = typeof Owner.enum; export const OwnerEnum = Owner.enum; /** * An object that contains the case settings. */ -export type Settings = z.infer; -export const Settings = z.object({ - /** - * Turns alert syncing on or off. - */ - syncAlerts: z.boolean(), - /** +export const Settings = lazySchema(() => + z.object({ + /** + * Turns alert syncing on or off. + */ + syncAlerts: z.boolean(), + /** * When true, observables (e.g. IPs, hashes, URLs) are automatically extracted from case comments. Optional; defaults to false when omitted. */ - extractObservables: z.boolean().optional(), -}); + extractObservables: z.boolean().optional(), + }) +); +export type Settings = z.infer; /** * The severity of the case. */ +export const CaseSeverity = lazySchema(() => z.enum(['critical', 'high', 'low', 'medium'])); export type CaseSeverity = z.infer; -export const CaseSeverity = z.enum(['critical', 'high', 'low', 'medium']); export type CaseSeverityEnum = typeof CaseSeverity.enum; export const CaseSeverityEnum = CaseSeverity.enum; @@ -312,154 +330,97 @@ export const CaseSeverityEnum = CaseSeverity.enum; * The words and phrases that help categorize cases. It can be an empty array. */ +export const CaseTags = lazySchema(() => z.array(z.string().max(256)).max(200)); export type CaseTags = z.infer; -export const CaseTags = z.array(z.string().max(256)).max(200); /** * A word or phrase that categorizes the case. */ +export const CaseCategory = lazySchema(() => z.string().max(50)); export type CaseCategory = z.infer; -export const CaseCategory = z.string().max(50); /** * A title for the case. */ +export const CaseTitle = lazySchema(() => z.string().max(160)); export type CaseTitle = z.infer; -export const CaseTitle = z.string().max(160); /** * The create case API request body varies depending on the type of connector. */ -export type CreateCaseRequest = z.infer; -export const CreateCaseRequest = z.object({ - assignees: Assignees.optional(), - connector: z.union([ - ConnectorPropertiesNone, - ConnectorPropertiesCasesWebhook, - ConnectorPropertiesJira, - ConnectorPropertiesResilient, - ConnectorPropertiesServicenow, - ConnectorPropertiesServicenowSir, - ConnectorPropertiesSwimlane, - ]), - description: CaseDescription, - owner: Owner, - settings: Settings, - severity: CaseSeverity.optional(), - tags: CaseTags, - category: CaseCategory.optional(), - title: CaseTitle, - /** +export const CreateCaseRequest = lazySchema(() => + z.object({ + assignees: Assignees.optional(), + connector: z.union([ + ConnectorPropertiesNone, + ConnectorPropertiesCasesWebhook, + ConnectorPropertiesJira, + ConnectorPropertiesResilient, + ConnectorPropertiesServicenow, + ConnectorPropertiesServicenowSir, + ConnectorPropertiesSwimlane, + ]), + description: CaseDescription, + owner: Owner, + settings: Settings, + severity: CaseSeverity.optional(), + tags: CaseTags, + category: CaseCategory.optional(), + title: CaseTitle, + /** * Custom field values for a case. Any optional custom fields that are not specified in the request are set to null. */ - customFields: z - .array( - z.object({ - /** + customFields: z + .array( + z.object({ + /** * The unique identifier for the custom field. The key value must exist in the case configuration settings. */ - key: z.string(), - /** + key: z.string(), + /** * The custom field type. It must match the type specified in the case configuration settings. */ - type: z.enum(['text', 'toggle']), - /** + type: z.enum(['text', 'toggle']), + /** * The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. */ - value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]), - }) - ) - .max(10) - .optional(), -}); - -export type CaseResponseClosedByProperties = z.infer; -export const CaseResponseClosedByProperties = z - .object({ - email: z.string().nullable(), - full_name: z.string().nullable(), - username: z.string().nullable(), - profile_uid: z.string().optional(), + value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]), + }) + ) + .max(10) + .optional(), }) - .nullable(); - -export type CaseResponseCreatedByProperties = z.infer; -export const CaseResponseCreatedByProperties = z.object({ - email: z.string().nullable(), - full_name: z.string().nullable(), - username: z.string().nullable(), - profile_uid: z.string().optional(), -}); +); +export type CreateCaseRequest = z.infer; -export type CaseResponsePushedByProperties = z.infer; -export const CaseResponsePushedByProperties = z - .object({ - email: z.string().nullable(), - full_name: z.string().nullable(), - username: z.string().nullable(), - profile_uid: z.string().optional(), - }) - .nullable(); +export const CaseResponseClosedByProperties = lazySchema(() => + z + .object({ + email: z.string().nullable(), + full_name: z.string().nullable(), + username: z.string().nullable(), + profile_uid: z.string().optional(), + }) + .nullable() +); +export type CaseResponseClosedByProperties = z.infer; -export type CaseResponseUpdatedByProperties = z.infer; -export const CaseResponseUpdatedByProperties = z - .object({ +export const CaseResponseCreatedByProperties = lazySchema(() => + z.object({ email: z.string().nullable(), full_name: z.string().nullable(), username: z.string().nullable(), profile_uid: z.string().optional(), }) - .nullable(); - -export type ActionsCommentResponseProperties = z.infer; -export const ActionsCommentResponseProperties = z.object({ - actions: z - .object({ - targets: z - .array( - z.object({ - endpointId: z.string().optional(), - hostname: z.string().optional(), - }) - ) - .optional(), - type: z.string().optional(), - }) - .optional(), - comment: z.string().optional(), - created_at: z.string().datetime().optional(), - created_by: CaseResponseCreatedByProperties.optional(), - id: z.string().optional(), - owner: Owner.optional(), - pushed_at: z.string().datetime().nullable().optional(), - pushed_by: CaseResponsePushedByProperties.optional(), - type: z.literal('actions'), - updated_at: z.string().datetime().nullable().optional(), - updated_by: CaseResponseUpdatedByProperties.optional(), - version: z.string().optional(), -}); +); +export type CaseResponseCreatedByProperties = z.infer; -export type AlertCommentResponseProperties = z.infer; -export const AlertCommentResponseProperties = z.object({ - alertId: z.array(z.string()).optional(), - created_at: z.string().datetime().optional(), - created_by: z - .object({ - email: z.string().nullable(), - full_name: z.string().nullable(), - username: z.string().nullable(), - profile_uid: z.string().optional(), - }) - .optional(), - id: z.string().optional(), - index: z.array(z.string()).optional(), - owner: Owner.optional(), - pushed_at: z.string().datetime().nullable().optional(), - pushed_by: z +export const CaseResponsePushedByProperties = lazySchema(() => + z .object({ email: z.string().nullable(), full_name: z.string().nullable(), @@ -467,22 +428,11 @@ export const AlertCommentResponseProperties = z.object({ profile_uid: z.string().optional(), }) .nullable() - .optional(), - rule: z - .object({ - /** - * The rule identifier. - */ - id: z.string().nullable().optional(), - /** - * The rule name. - */ - name: z.string().nullable().optional(), - }) - .optional(), - type: z.literal('alert'), - updated_at: z.string().datetime().nullable().optional(), - updated_by: z +); +export type CaseResponsePushedByProperties = z.infer; + +export const CaseResponseUpdatedByProperties = lazySchema(() => + z .object({ email: z.string().nullable(), full_name: z.string().nullable(), @@ -490,376 +440,480 @@ export const AlertCommentResponseProperties = z.object({ profile_uid: z.string().optional(), }) .nullable() - .optional(), - version: z.string().optional(), -}); - -export type EventCommentResponseProperties = z.infer; -export const EventCommentResponseProperties = z.object({ - created_at: z.string().datetime().optional(), - created_by: CaseResponseCreatedByProperties.optional(), - eventId: z.array(z.string()).optional(), - id: z.string().optional(), - index: z.array(z.string()).optional(), - owner: Owner.optional(), - pushed_at: z.string().datetime().nullable().optional(), - pushed_by: CaseResponsePushedByProperties.optional(), - type: z.literal('event'), - updated_at: z.string().datetime().nullable().optional(), - updated_by: CaseResponseUpdatedByProperties.optional(), - version: z.string().optional(), -}); +); +export type CaseResponseUpdatedByProperties = z.infer; -export type UserCommentResponseProperties = z.infer; -export const UserCommentResponseProperties = z.object({ - comment: z.string().optional(), - created_at: z.string().datetime().optional(), - created_by: CaseResponseCreatedByProperties.optional(), - id: z.string().optional(), - owner: Owner.optional(), - pushed_at: z.string().datetime().nullable().optional(), - pushed_by: CaseResponsePushedByProperties.optional(), - type: z.literal('user'), - updated_at: z.string().datetime().nullable().optional(), - updated_by: CaseResponseUpdatedByProperties.optional(), - version: z.string().optional(), -}); +export const ActionsCommentResponseProperties = lazySchema(() => + z.object({ + actions: z + .object({ + targets: z + .array( + z.object({ + endpointId: z.string().optional(), + hostname: z.string().optional(), + }) + ) + .optional(), + type: z.string().optional(), + }) + .optional(), + comment: z.string().optional(), + created_at: z.string().datetime().optional(), + created_by: CaseResponseCreatedByProperties.optional(), + id: z.string().optional(), + owner: Owner.optional(), + pushed_at: z.string().datetime().nullable().optional(), + pushed_by: CaseResponsePushedByProperties.optional(), + type: z.literal('actions'), + updated_at: z.string().datetime().nullable().optional(), + updated_by: CaseResponseUpdatedByProperties.optional(), + version: z.string().optional(), + }) +); +export type ActionsCommentResponseProperties = z.infer; -export type ExternalService = z.infer; -export const ExternalService = z - .object({ - connector_id: z.string().optional(), - connector_name: z.string().optional(), - external_id: z.string().optional(), - external_title: z.string().optional(), - external_url: z.string().optional(), - pushed_at: z.string().datetime().optional(), +export const AlertCommentResponseProperties = lazySchema(() => + z.object({ + alertId: z.array(z.string()).optional(), + created_at: z.string().datetime().optional(), + created_by: z + .object({ + email: z.string().nullable(), + full_name: z.string().nullable(), + username: z.string().nullable(), + profile_uid: z.string().optional(), + }) + .optional(), + id: z.string().optional(), + index: z.array(z.string()).optional(), + owner: Owner.optional(), + pushed_at: z.string().datetime().nullable().optional(), pushed_by: z .object({ - email: z.string().nullable().optional(), - full_name: z.string().nullable().optional(), - username: z.string().nullable().optional(), + email: z.string().nullable(), + full_name: z.string().nullable(), + username: z.string().nullable(), + profile_uid: z.string().optional(), + }) + .nullable() + .optional(), + rule: z + .object({ + /** + * The rule identifier. + */ + id: z.string().nullable().optional(), + /** + * The rule name. + */ + name: z.string().nullable().optional(), + }) + .optional(), + type: z.literal('alert'), + updated_at: z.string().datetime().nullable().optional(), + updated_by: z + .object({ + email: z.string().nullable(), + full_name: z.string().nullable(), + username: z.string().nullable(), profile_uid: z.string().optional(), }) .nullable() .optional(), + version: z.string().optional(), }) - .nullable(); - -/** - * A single observable attached to a case. - */ -export type CaseObservable = z.infer; -export const CaseObservable = z.object({ - /** - * The observable identifier. - */ - id: z.string(), - /** - * The observable type key. - */ - typeKey: z.string(), - /** - * The observable value. - */ - value: z.string(), - /** - * An optional description for the observable. - */ - description: z.string().nullable(), - /** - * When the observable was created. - */ - createdAt: z.string().datetime(), - /** - * When the observable was last updated. - */ - updatedAt: z.string().datetime().nullable(), -}); +); +export type AlertCommentResponseProperties = z.infer; + +export const EventCommentResponseProperties = lazySchema(() => + z.object({ + created_at: z.string().datetime().optional(), + created_by: CaseResponseCreatedByProperties.optional(), + eventId: z.array(z.string()).optional(), + id: z.string().optional(), + index: z.array(z.string()).optional(), + owner: Owner.optional(), + pushed_at: z.string().datetime().nullable().optional(), + pushed_by: CaseResponsePushedByProperties.optional(), + type: z.literal('event'), + updated_at: z.string().datetime().nullable().optional(), + updated_by: CaseResponseUpdatedByProperties.optional(), + version: z.string().optional(), + }) +); +export type EventCommentResponseProperties = z.infer; + +export const UserCommentResponseProperties = lazySchema(() => + z.object({ + comment: z.string().optional(), + created_at: z.string().datetime().optional(), + created_by: CaseResponseCreatedByProperties.optional(), + id: z.string().optional(), + owner: Owner.optional(), + pushed_at: z.string().datetime().nullable().optional(), + pushed_by: CaseResponsePushedByProperties.optional(), + type: z.literal('user'), + updated_at: z.string().datetime().nullable().optional(), + updated_by: CaseResponseUpdatedByProperties.optional(), + version: z.string().optional(), + }) +); +export type UserCommentResponseProperties = z.infer; + +export const ExternalService = lazySchema(() => + z + .object({ + connector_id: z.string().optional(), + connector_name: z.string().optional(), + external_id: z.string().optional(), + external_title: z.string().optional(), + external_url: z.string().optional(), + pushed_at: z.string().datetime().optional(), + pushed_by: z + .object({ + email: z.string().nullable().optional(), + full_name: z.string().nullable().optional(), + username: z.string().nullable().optional(), + profile_uid: z.string().optional(), + }) + .nullable() + .optional(), + }) + .nullable() +); +export type ExternalService = z.infer; + +/** + * A single observable attached to a case. + */ +export const CaseObservable = lazySchema(() => + z.object({ + /** + * The observable identifier. + */ + id: z.string(), + /** + * The observable type key. + */ + typeKey: z.string(), + /** + * The observable value. + */ + value: z.string(), + /** + * An optional description for the observable. + */ + description: z.string().nullable(), + /** + * When the observable was created. + */ + createdAt: z.string().datetime(), + /** + * When the observable was last updated. + */ + updatedAt: z.string().datetime().nullable(), + }) +); +export type CaseObservable = z.infer; /** * The status of the case. */ +export const CaseStatus = lazySchema(() => z.enum(['closed', 'in-progress', 'open'])); export type CaseStatus = z.infer; -export const CaseStatus = z.enum(['closed', 'in-progress', 'open']); export type CaseStatusEnum = typeof CaseStatus.enum; export const CaseStatusEnum = CaseStatus.enum; -export type CaseResponseProperties = z.infer; -export const CaseResponseProperties = z.object({ - assignees: Assignees.optional(), - /** - * The case category. - */ - category: z.string().nullable().optional(), - closed_at: z.string().datetime().nullable(), - closed_by: CaseResponseClosedByProperties, - /** - * An array of comment objects for the case. - */ - comments: z - .array( - z.discriminatedUnion('type', [ - ActionsCommentResponseProperties, - AlertCommentResponseProperties, - EventCommentResponseProperties, - UserCommentResponseProperties, - ]) - ) - .max(10000), - connector: z.discriminatedUnion('type', [ - ConnectorPropertiesNone, - ConnectorPropertiesCasesWebhook, - ConnectorPropertiesJira, - ConnectorPropertiesResilient, - ConnectorPropertiesServicenow, - ConnectorPropertiesServicenowSir, - ConnectorPropertiesSwimlane, - ]), - created_at: z.string().datetime(), - created_by: CaseResponseCreatedByProperties, - /** - * Custom field values for the case. - */ - customFields: z - .array( - z.object({ - /** +export const CaseResponseProperties = lazySchema(() => + z.object({ + assignees: Assignees.optional(), + /** + * The case category. + */ + category: z.string().nullable().optional(), + closed_at: z.string().datetime().nullable(), + closed_by: CaseResponseClosedByProperties, + /** + * An array of comment objects for the case. + */ + comments: z + .array( + z.discriminatedUnion('type', [ + ActionsCommentResponseProperties, + AlertCommentResponseProperties, + EventCommentResponseProperties, + UserCommentResponseProperties, + ]) + ) + .max(10000), + connector: z.discriminatedUnion('type', [ + ConnectorPropertiesNone, + ConnectorPropertiesCasesWebhook, + ConnectorPropertiesJira, + ConnectorPropertiesResilient, + ConnectorPropertiesServicenow, + ConnectorPropertiesServicenowSir, + ConnectorPropertiesSwimlane, + ]), + created_at: z.string().datetime(), + created_by: CaseResponseCreatedByProperties, + /** + * Custom field values for the case. + */ + customFields: z + .array( + z.object({ + /** * The unique identifier for the custom field. The key value must exist in the case configuration settings. */ - key: z.string().optional(), - /** + key: z.string().optional(), + /** * The custom field type. It must match the type specified in the case configuration settings. */ - type: z.enum(['text', 'toggle']).optional(), - /** + type: z.enum(['text', 'toggle']).optional(), + /** * The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. */ - value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]).optional(), - }) - ) - .optional(), - description: z.string(), - /** + value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]).optional(), + }) + ) + .optional(), + description: z.string(), + /** * The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero. */ - duration: z.number().int().nullable(), - external_service: ExternalService, - id: z.string(), - /** - * Observables attached to the case. - */ - observables: z.array(CaseObservable), - owner: Owner, - settings: Settings, - severity: CaseSeverity, - status: CaseStatus, - tags: z.array(z.string()), - title: z.string(), - totalAlerts: z.number().int(), - totalComment: z.number().int(), - /** - * The number of observables attached to the case. - */ - total_observables: z.number().int().nullable(), - /** - * The number of events attached to the case. - */ - totalEvents: z.number().int().optional(), - updated_at: z.string().datetime().nullable(), - updated_by: CaseResponseUpdatedByProperties, - version: z.string(), -}); + duration: z.number().int().nullable(), + external_service: ExternalService, + id: z.string(), + /** + * Observables attached to the case. + */ + observables: z.array(CaseObservable), + owner: Owner, + settings: Settings, + severity: CaseSeverity, + status: CaseStatus, + tags: z.array(z.string()), + title: z.string(), + totalAlerts: z.number().int(), + totalComment: z.number().int(), + /** + * The number of observables attached to the case. + */ + total_observables: z.number().int().nullable(), + /** + * The number of events attached to the case. + */ + totalEvents: z.number().int().optional(), + updated_at: z.string().datetime().nullable(), + updated_by: CaseResponseUpdatedByProperties, + version: z.string(), + }) +); +export type CaseResponseProperties = z.infer; +export const Response4Xx = lazySchema(() => + z.object({ + error: z.string().optional(), + message: z.string().optional(), + statusCode: z.number().int().optional(), + }) +); export type Response4Xx = z.infer; -export const Response4Xx = z.object({ - error: z.string().optional(), - message: z.string().optional(), - statusCode: z.number().int().optional(), -}); /** * The close reason to sync to attached alerts when closing the case. Can be one of following predefined reasons: [false_positive, duplicate, true_positive, benign_positive, automated_closure, other] or a custom reason provided by the user. */ +export const CaseCloseSyncReason = lazySchema(() => + z.union([ + z.enum([ + 'false_positive', + 'duplicate', + 'true_positive', + 'benign_positive', + 'automated_closure', + 'other', + ]), + z.string(), + ]) +); export type CaseCloseSyncReason = z.infer; -export const CaseCloseSyncReason = z.union([ - z.enum([ - 'false_positive', - 'duplicate', - 'true_positive', - 'benign_positive', - 'automated_closure', - 'other', - ]), - z.string(), -]); /** * The update case API request body varies depending on the type of connector. */ -export type UpdateCaseRequest = z.infer; -export const UpdateCaseRequest = z.object({ - /** - * An array containing one or more case objects. - */ - cases: z - .array( - z.object({ - assignees: Assignees.optional(), - category: CaseCategory.optional(), - connector: z - .union([ - ConnectorPropertiesNone, - ConnectorPropertiesCasesWebhook, - ConnectorPropertiesJira, - ConnectorPropertiesResilient, - ConnectorPropertiesServicenow, - ConnectorPropertiesServicenowSir, - ConnectorPropertiesSwimlane, - ]) - .optional(), - /** +export const UpdateCaseRequest = lazySchema(() => + z.object({ + /** + * An array containing one or more case objects. + */ + cases: z + .array( + z.object({ + assignees: Assignees.optional(), + category: CaseCategory.optional(), + connector: z + .union([ + ConnectorPropertiesNone, + ConnectorPropertiesCasesWebhook, + ConnectorPropertiesJira, + ConnectorPropertiesResilient, + ConnectorPropertiesServicenow, + ConnectorPropertiesServicenowSir, + ConnectorPropertiesSwimlane, + ]) + .optional(), + /** * Custom field values for a case. Any optional custom fields that are not specified in the request are set to null. */ - customFields: z - .array( - z.object({ - /** + customFields: z + .array( + z.object({ + /** * The unique identifier for the custom field. The key value must exist in the case configuration settings. */ - key: z.string(), - /** + key: z.string(), + /** * The custom field type. It must match the type specified in the case configuration settings. */ - type: z.enum(['text', 'toggle']), - /** + type: z.enum(['text', 'toggle']), + /** * The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. */ - value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]), - }) - ) - .max(10) - .optional(), - description: CaseDescription.optional(), - /** - * The identifier for the case. - */ - id: z.string().max(30000), - settings: Settings.optional(), - severity: CaseSeverity.optional(), - status: CaseStatus.optional(), - tags: CaseTags.optional(), - title: CaseTitle.optional(), - closeReason: CaseCloseSyncReason.optional(), - /** + value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]), + }) + ) + .max(10) + .optional(), + description: CaseDescription.optional(), + /** + * The identifier for the case. + */ + id: z.string().max(30000), + settings: Settings.optional(), + severity: CaseSeverity.optional(), + status: CaseStatus.optional(), + tags: CaseTags.optional(), + title: CaseTitle.optional(), + closeReason: CaseCloseSyncReason.optional(), + /** * The current version of the case. To determine this value, use the get case or search cases (`_find`) APIs. */ - version: z.string(), - }) - ) - .min(1) - .max(100), -}); + version: z.string(), + }) + ) + .min(1) + .max(100), + }) +); +export type UpdateCaseRequest = z.infer; +export const String = lazySchema(() => z.string()); export type String = z.infer; -export const String = z.string(); +export const StringArray = lazySchema(() => z.array(String).max(100)); export type StringArray = z.infer; -export const StringArray = z.array(String).max(100); +export const CaseCategories = lazySchema(() => z.array(CaseCategory).max(100)); export type CaseCategories = z.infer; -export const CaseCategories = z.array(CaseCategory).max(100); +export const Owners = lazySchema(() => z.array(Owner)); export type Owners = z.infer; -export const Owners = z.array(Owner); /** * The fields to perform the `simple_query_string` parsed query against. */ +export const SearchFieldsType = lazySchema(() => z.enum(['description', 'title'])); export type SearchFieldsType = z.infer; -export const SearchFieldsType = z.enum(['description', 'title']); export type SearchFieldsTypeEnum = typeof SearchFieldsType.enum; export const SearchFieldsTypeEnum = SearchFieldsType.enum; +export const SearchFieldsTypeArray = lazySchema(() => z.array(SearchFieldsType)); export type SearchFieldsTypeArray = z.infer; -export const SearchFieldsTypeArray = z.array(SearchFieldsType); /** * Counts of alerts, events, and user comments attached to a case. */ +export const AttachmentTotals = lazySchema(() => + z.object({ + /** + * Number of alert attachments on the case. + */ + alerts: z.number().int(), + /** + * Number of event attachments on the case. + */ + events: z.number().int(), + /** + * Number of user comment attachments on the case. + */ + userComments: z.number().int(), + }) +); export type AttachmentTotals = z.infer; -export const AttachmentTotals = z.object({ - /** - * Number of alert attachments on the case. - */ - alerts: z.number().int(), - /** - * Number of event attachments on the case. - */ - events: z.number().int(), - /** - * Number of user comment attachments on the case. - */ - userComments: z.number().int(), -}); /** * Summary of a case returned when listing cases that contain a given alert. This is a subset of the full case response. */ +export const RelatedCase = lazySchema(() => + z.object({ + /** + * The case identifier. + */ + id: z.string(), + /** + * The case title. + */ + title: z.string(), + /** + * The case description. + */ + description: z.string(), + status: CaseStatus, + /** + * When the case was created. + */ + createdAt: z.string().datetime(), + totals: AttachmentTotals, + }) +); export type RelatedCase = z.infer; -export const RelatedCase = z.object({ - /** - * The case identifier. - */ - id: z.string(), - /** - * The case title. - */ - title: z.string(), - /** - * The case description. - */ - description: z.string(), - status: CaseStatus, - /** - * When the case was created. - */ - createdAt: z.string().datetime(), - totals: AttachmentTotals, -}); /** * Indicates whether a case is automatically closed when it is pushed to external systems (`close-by-pushing`) or not automatically closed (`close-by-user`). */ +export const ClosureTypes = lazySchema(() => z.enum(['close-by-pushing', 'close-by-user'])); export type ClosureTypes = z.infer; -export const ClosureTypes = z.enum(['close-by-pushing', 'close-by-user']); export type ClosureTypesEnum = typeof ClosureTypes.enum; export const ClosureTypesEnum = ClosureTypes.enum; /** * The type of connector. */ +export const ConnectorTypes = lazySchema(() => + z.enum([ + '.cases-webhook', + '.jira', + '.none', + '.resilient', + '.servicenow', + '.servicenow-sir', + '.swimlane', + ]) +); export type ConnectorTypes = z.infer; -export const ConnectorTypes = z.enum([ - '.cases-webhook', - '.jira', - '.none', - '.resilient', - '.servicenow', - '.servicenow-sir', - '.swimlane', -]); export type ConnectorTypesEnum = typeof ConnectorTypes.enum; export const ConnectorTypesEnum = ConnectorTypes.enum; @@ -867,152 +921,91 @@ export const ConnectorTypesEnum = ConnectorTypes.enum; * The words and phrases that help categorize templates. It can be an empty array. */ +export const TemplateTags = lazySchema(() => z.array(z.string().max(256)).max(200)); export type TemplateTags = z.infer; -export const TemplateTags = z.array(z.string().max(256)).max(200); -export type Templates = z.infer; -export const Templates = z.array( - z.object({ - caseFields: z - .object({ - assignees: Assignees.optional(), - category: CaseCategory.optional(), - connector: z - .object({ - /** - * The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - */ - fields: z.object({}).nullable().optional(), - /** - * The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. - */ - id: z.string().optional(), - /** - * The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. - */ - name: z.string().optional(), - type: ConnectorTypes.optional(), - }) - .optional(), - /** - * Custom field values in the template. - */ - customFields: z - .array( - z.object({ +export const Templates = lazySchema(() => + z.array( + z.object({ + caseFields: z + .object({ + assignees: Assignees.optional(), + category: CaseCategory.optional(), + connector: z + .object({ /** - * The unique key for the custom field. + * The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. */ - key: z.string().optional(), + fields: z.object({}).nullable().optional(), /** - * The type of the custom field. + * The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. */ - type: z.enum(['text', 'toggle']).optional(), + id: z.string().optional(), /** + * The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. + */ + name: z.string().optional(), + type: ConnectorTypes.optional(), + }) + .optional(), + /** + * Custom field values in the template. + */ + customFields: z + .array( + z.object({ + /** + * The unique key for the custom field. + */ + key: z.string().optional(), + /** + * The type of the custom field. + */ + type: z.enum(['text', 'toggle']).optional(), + /** * The default value for the custom field when a case uses the template. If the `type` is `text`, the default value must be a string. If the `type` is `toggle`, the default value must be boolean. */ - value: z.union([z.string(), z.boolean()]).optional(), - }) - ) - .optional(), - description: CaseDescription.optional(), - settings: Settings.optional(), - severity: CaseSeverity.optional(), - tags: CaseTags.optional(), - title: CaseTitle.optional(), - }) - .optional(), - /** - * A description for the template. - */ - description: z.string().optional(), - /** + value: z.union([z.string(), z.boolean()]).optional(), + }) + ) + .optional(), + description: CaseDescription.optional(), + settings: Settings.optional(), + severity: CaseSeverity.optional(), + tags: CaseTags.optional(), + title: CaseTitle.optional(), + }) + .optional(), + /** + * A description for the template. + */ + description: z.string().optional(), + /** * A unique key for the template. Must be lower case and composed only of a-z, 0-9, '_', and '-' characters. It is used in API calls to refer to a specific template. */ - key: z.string().optional(), - /** - * The name of the template. - */ - name: z.string().optional(), - tags: TemplateTags.optional(), - }) + key: z.string().optional(), + /** + * The name of the template. + */ + name: z.string().optional(), + tags: TemplateTags.optional(), + }) + ) ); +export type Templates = z.infer; /** * External connection details, such as the closure type and default connector for cases. */ -export type SetCaseConfigurationRequest = z.infer; -export const SetCaseConfigurationRequest = z.object({ - closure_type: ClosureTypes, - /** - * An object that contains the connector configuration. - */ - connector: z.object({ - /** - * The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - */ - fields: z.object({}).nullable(), - /** - * The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. - */ - id: z.string(), +export const SetCaseConfigurationRequest = lazySchema(() => + z.object({ + closure_type: ClosureTypes, /** - * The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. + * An object that contains the connector configuration. */ - name: z.string(), - type: ConnectorTypes, - }), - /** - * Custom fields case configuration. - */ - customFields: z - .array( - z.object({ - /** - * A default value for the custom field. If the `type` is `text`, the default value must be a string. If the `type` is `toggle`, the default value must be boolean. - - */ - defaultValue: z.union([z.string(), z.boolean()]).optional(), - /** - * A unique key for the custom field. Must be lower case and composed only of a-z, 0-9, '_', and '-' characters. It is used in API calls to refer to a specific custom field. - - */ - key: z.string().min(1).max(36), - /** - * The custom field label that is displayed in the case. - */ - label: z.string().min(1).max(50), - /** - * Indicates whether the field is required. If `false`, the custom field can be set to null or omitted when a case is created or updated. - - */ - required: z.boolean(), - /** - * The type of the custom field. - */ - type: z.enum(['text', 'toggle']), - }) - ) - .max(10) - .optional(), - owner: Owner, - templates: Templates.optional(), -}); - -/** - * You can update settings such as the closure type, custom fields, templates, and the default connector for cases. - - */ -export type UpdateCaseConfigurationRequest = z.infer; -export const UpdateCaseConfigurationRequest = z.object({ - closure_type: ClosureTypes.optional(), - /** - * An object that contains the connector configuration. - */ - connector: z - .object({ + connector: z.object({ /** * The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. */ @@ -1026,619 +1019,735 @@ export const UpdateCaseConfigurationRequest = z.object({ */ name: z.string(), type: ConnectorTypes, - }) - .optional(), - /** - * Custom fields case configuration. - */ - customFields: z - .array( - z.object({ - /** + }), + /** + * Custom fields case configuration. + */ + customFields: z + .array( + z.object({ + /** * A default value for the custom field. If the `type` is `text`, the default value must be a string. If the `type` is `toggle`, the default value must be boolean. */ - defaultValue: z.union([z.string(), z.boolean()]).optional(), - /** + defaultValue: z.union([z.string(), z.boolean()]).optional(), + /** * A unique key for the custom field. Must be lower case and composed only of a-z, 0-9, '_', and '-' characters. It is used in API calls to refer to a specific custom field. */ - key: z.string().min(1).max(36), - /** - * The custom field label that is displayed in the case. - */ - label: z.string().min(1).max(50), - /** + key: z.string().min(1).max(36), + /** + * The custom field label that is displayed in the case. + */ + label: z.string().min(1).max(50), + /** * Indicates whether the field is required. If `false`, the custom field can be set to null or omitted when a case is created or updated. */ - required: z.boolean(), - /** - * The type of the custom field. - */ - type: z.enum(['text', 'toggle']), - }) - ) - .optional(), - templates: Templates.optional(), - /** - * The version of the connector. To retrieve the version value, use the get configuration API. - - */ - version: z.string(), -}); + required: z.boolean(), + /** + * The type of the custom field. + */ + type: z.enum(['text', 'toggle']), + }) + ) + .max(10) + .optional(), + owner: Owner, + templates: Templates.optional(), + }) +); +export type SetCaseConfigurationRequest = z.infer; /** - * Case details returned by the get case API. The comments property is not included in the response. Use the find case comments API to retrieve comments. totalComment reflects the actual number of user comments. + * You can update settings such as the closure type, custom fields, templates, and the default connector for cases. */ -export type CaseResponseGetCase = z.infer; -export const CaseResponseGetCase = z.object({ - assignees: Assignees.optional(), - /** - * The case category. - */ - category: z.string().nullable().optional(), - closed_at: z.string().datetime().nullable(), - closed_by: CaseResponseClosedByProperties, - connector: z.discriminatedUnion('type', [ - ConnectorPropertiesNone, - ConnectorPropertiesCasesWebhook, - ConnectorPropertiesJira, - ConnectorPropertiesResilient, - ConnectorPropertiesServicenow, - ConnectorPropertiesServicenowSir, - ConnectorPropertiesSwimlane, - ]), - created_at: z.string().datetime(), - created_by: CaseResponseCreatedByProperties, - /** - * Custom field values for the case. - */ - customFields: z - .array( - z.object({ +export const UpdateCaseConfigurationRequest = lazySchema(() => + z.object({ + closure_type: ClosureTypes.optional(), + /** + * An object that contains the connector configuration. + */ + connector: z + .object({ /** - * The unique identifier for the custom field. The key value must exist in the case configuration settings. - - */ - key: z.string().optional(), + * The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. + */ + fields: z.object({}).nullable(), /** - * The custom field type. It must match the type specified in the case configuration settings. + * The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. + */ + id: z.string(), + /** + * The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. + */ + name: z.string(), + type: ConnectorTypes, + }) + .optional(), + /** + * Custom fields case configuration. + */ + customFields: z + .array( + z.object({ + /** + * A default value for the custom field. If the `type` is `text`, the default value must be a string. If the `type` is `toggle`, the default value must be boolean. */ - type: z.enum(['text', 'toggle']).optional(), - /** + defaultValue: z.union([z.string(), z.boolean()]).optional(), + /** + * A unique key for the custom field. Must be lower case and composed only of a-z, 0-9, '_', and '-' characters. It is used in API calls to refer to a specific custom field. + + */ + key: z.string().min(1).max(36), + /** + * The custom field label that is displayed in the case. + */ + label: z.string().min(1).max(50), + /** + * Indicates whether the field is required. If `false`, the custom field can be set to null or omitted when a case is created or updated. + + */ + required: z.boolean(), + /** + * The type of the custom field. + */ + type: z.enum(['text', 'toggle']), + }) + ) + .optional(), + templates: Templates.optional(), + /** + * The version of the connector. To retrieve the version value, use the get configuration API. + + */ + version: z.string(), + }) +); +export type UpdateCaseConfigurationRequest = z.infer; + +/** + * Case details returned by the get case API. The comments property is not included in the response. Use the find case comments API to retrieve comments. totalComment reflects the actual number of user comments. + + */ +export const CaseResponseGetCase = lazySchema(() => + z.object({ + assignees: Assignees.optional(), + /** + * The case category. + */ + category: z.string().nullable().optional(), + closed_at: z.string().datetime().nullable(), + closed_by: CaseResponseClosedByProperties, + connector: z.discriminatedUnion('type', [ + ConnectorPropertiesNone, + ConnectorPropertiesCasesWebhook, + ConnectorPropertiesJira, + ConnectorPropertiesResilient, + ConnectorPropertiesServicenow, + ConnectorPropertiesServicenowSir, + ConnectorPropertiesSwimlane, + ]), + created_at: z.string().datetime(), + created_by: CaseResponseCreatedByProperties, + /** + * Custom field values for the case. + */ + customFields: z + .array( + z.object({ + /** + * The unique identifier for the custom field. The key value must exist in the case configuration settings. + + */ + key: z.string().optional(), + /** + * The custom field type. It must match the type specified in the case configuration settings. + + */ + type: z.enum(['text', 'toggle']).optional(), + /** * The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. */ - value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]).optional(), - }) - ) - .optional(), - description: z.string(), - /** + value: z.union([z.string().min(1).max(160).nullable(), z.boolean()]).optional(), + }) + ) + .optional(), + description: z.string(), + /** * The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero. */ - duration: z.number().int().nullable(), - external_service: ExternalService, - id: z.string(), - /** - * Observables attached to the case. - */ - observables: z.array(CaseObservable), - owner: Owner, - settings: Settings, - severity: CaseSeverity, - status: CaseStatus, - tags: z.array(z.string()), - title: z.string(), - totalAlerts: z.number().int(), - /** - * The number of user comments on the case. Use the find case comments API to retrieve comment content. - */ - totalComment: z.number().int(), - /** - * The number of observables attached to the case. - */ - total_observables: z.number().int().nullable(), - /** - * The number of events attached to the case. - */ - totalEvents: z.number().int().optional(), - updated_at: z.string().datetime().nullable(), - updated_by: CaseResponseUpdatedByProperties, - version: z.string(), -}); + duration: z.number().int().nullable(), + external_service: ExternalService, + id: z.string(), + /** + * Observables attached to the case. + */ + observables: z.array(CaseObservable), + owner: Owner, + settings: Settings, + severity: CaseSeverity, + status: CaseStatus, + tags: z.array(z.string()), + title: z.string(), + totalAlerts: z.number().int(), + /** + * The number of user comments on the case. Use the find case comments API to retrieve comment content. + */ + totalComment: z.number().int(), + /** + * The number of observables attached to the case. + */ + total_observables: z.number().int().nullable(), + /** + * The number of events attached to the case. + */ + totalEvents: z.number().int().optional(), + updated_at: z.string().datetime().nullable(), + updated_by: CaseResponseUpdatedByProperties, + version: z.string(), + }) +); +export type CaseResponseGetCase = z.infer; +export const AlertResponseProperties = lazySchema(() => + z.object({ + attached_at: z.string().datetime().optional(), + /** + * The alert identifier. + */ + id: z.string().optional(), + /** + * The alert index. + */ + index: z.string().optional(), + }) +); export type AlertResponseProperties = z.infer; -export const AlertResponseProperties = z.object({ - attached_at: z.string().datetime().optional(), - /** - * The alert identifier. - */ - id: z.string().optional(), - /** - * The alert index. - */ - index: z.string().optional(), -}); /** * The alert identifiers. It is required only when `type` is `alert`. You can use an array of strings to add multiple alerts to a case, provided that they all relate to the same rule; `index` must also be an array with the same length or number of elements. Adding multiple alerts in this manner is recommended rather than calling the API multiple times. This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. */ +export const AlertIdentifiers = lazySchema(() => + z.union([z.string(), z.array(z.string()).max(1000)]) +); export type AlertIdentifiers = z.infer; -export const AlertIdentifiers = z.union([z.string(), z.array(z.string()).max(1000)]); /** * The alert indices. It is required only when `type` is `alert`. If you are adding multiple alerts to a case, use an array of strings; the position of each index name in the array must match the position of the corresponding alert identifier in the `alertId` array. This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. */ +export const AlertIndices = lazySchema(() => z.union([z.string(), z.array(z.string()).max(1000)])); export type AlertIndices = z.infer; -export const AlertIndices = z.union([z.string(), z.array(z.string()).max(1000)]); /** * The rule that is associated with the alerts. It is required only when `type` is `alert`. This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. */ +export const Rule = lazySchema(() => + z.object({ + /** + * The rule identifier. + */ + id: z.string().optional(), + /** + * The rule name. + */ + name: z.string().optional(), + }) +); export type Rule = z.infer; -export const Rule = z.object({ - /** - * The rule identifier. - */ - id: z.string().optional(), - /** - * The rule name. - */ - name: z.string().optional(), -}); /** * Defines properties for case comment requests when type is alert. */ +export const AddAlertCommentRequestProperties = lazySchema(() => + z.object({ + alertId: AlertIdentifiers, + index: AlertIndices, + owner: Owner, + rule: Rule, + /** + * The type of comment. + */ + type: z.literal('alert'), + }) +); export type AddAlertCommentRequestProperties = z.infer; -export const AddAlertCommentRequestProperties = z.object({ - alertId: AlertIdentifiers, - index: AlertIndices, - owner: Owner, - rule: Rule, - /** - * The type of comment. - */ - type: z.literal('alert'), -}); /** * Defines properties for case comment requests when type is user. */ +export const AddUserCommentRequestProperties = lazySchema(() => + z.object({ + /** + * The new comment. It is required only when `type` is `user`. + */ + comment: z.string().max(30000), + owner: Owner, + /** + * The type of comment. + */ + type: z.literal('user'), + }) +); export type AddUserCommentRequestProperties = z.infer; -export const AddUserCommentRequestProperties = z.object({ - /** - * The new comment. It is required only when `type` is `user`. - */ - comment: z.string().max(30000), - owner: Owner, - /** - * The type of comment. - */ - type: z.literal('user'), -}); /** * The add comment to case API request body varies depending on whether you are adding an alert or a comment. */ +export const AddCaseCommentRequest = lazySchema(() => + z.discriminatedUnion('type', [AddAlertCommentRequestProperties, AddUserCommentRequestProperties]) +); export type AddCaseCommentRequest = z.infer; -export const AddCaseCommentRequest = z.discriminatedUnion('type', [ - AddAlertCommentRequestProperties, - AddUserCommentRequestProperties, -]); /** * Defines properties for case comment requests when type is alert. */ -export type UpdateAlertCommentRequestProperties = z.infer< - typeof UpdateAlertCommentRequestProperties ->; -export const UpdateAlertCommentRequestProperties = z.object({ - alertId: AlertIdentifiers, - /** +export const UpdateAlertCommentRequestProperties = lazySchema(() => + z.object({ + alertId: AlertIdentifiers, + /** * The identifier for the comment. To retrieve comment IDs, use the get comments API. */ - id: z.string(), - index: AlertIndices, - owner: Owner, - rule: Rule, - /** - * The type of comment. - */ - type: z.literal('alert'), - /** + id: z.string(), + index: AlertIndices, + owner: Owner, + rule: Rule, + /** + * The type of comment. + */ + type: z.literal('alert'), + /** * The current comment version. To retrieve version values, use the get comments API. */ - version: z.string(), -}); + version: z.string(), + }) +); +export type UpdateAlertCommentRequestProperties = z.infer< + typeof UpdateAlertCommentRequestProperties +>; /** * Defines properties for case comment requests when type is user. */ -export type UpdateUserCommentRequestProperties = z.infer; -export const UpdateUserCommentRequestProperties = z.object({ - /** - * The new comment. It is required only when `type` is `user`. - */ - comment: z.string().max(30000), - /** +export const UpdateUserCommentRequestProperties = lazySchema(() => + z.object({ + /** + * The new comment. It is required only when `type` is `user`. + */ + comment: z.string().max(30000), + /** * The identifier for the comment. To retrieve comment IDs, use the get comments API. */ - id: z.string(), - owner: Owner, - /** - * The type of comment. - */ - type: z.literal('user'), - /** + id: z.string(), + owner: Owner, + /** + * The type of comment. + */ + type: z.literal('user'), + /** * The current comment version. To retrieve version values, use the get comments API. */ - version: z.string(), -}); + version: z.string(), + }) +); +export type UpdateUserCommentRequestProperties = z.infer; /** * The update case comment API request body varies depending on whether you are updating an alert or a comment. */ +export const UpdateCaseCommentRequest = lazySchema(() => + z.discriminatedUnion('type', [ + UpdateAlertCommentRequestProperties, + UpdateUserCommentRequestProperties, + ]) +); export type UpdateCaseCommentRequest = z.infer; -export const UpdateCaseCommentRequest = z.discriminatedUnion('type', [ - UpdateAlertCommentRequestProperties, - UpdateUserCommentRequestProperties, -]); +export const FindCommentsResponse = lazySchema(() => + z.object({ + /** + * Paginated list of user comments for the case. + */ + comments: z.array(UserCommentResponseProperties), + /** + * The current page index. + */ + page: z.number().int(), + /** + * The number of items per page. + */ + per_page: z.number().int(), + /** + * The total number of comments. + */ + total: z.number().int(), + }) +); export type FindCommentsResponse = z.infer; -export const FindCommentsResponse = z.object({ - /** - * Paginated list of user comments for the case. - */ - comments: z.array(UserCommentResponseProperties), - /** - * The current page index. - */ - page: z.number().int(), - /** - * The number of items per page. - */ - per_page: z.number().int(), - /** - * The total number of comments. - */ - total: z.number().int(), -}); +export const Actions = lazySchema(() => + z.enum(['add', 'create', 'delete', 'push_to_service', 'update']) +); export type Actions = z.infer; -export const Actions = z.enum(['add', 'create', 'delete', 'push_to_service', 'update']); export type ActionsEnum = typeof Actions.enum; export const ActionsEnum = Actions.enum; +export const PayloadAlertComment = lazySchema(() => + z.object({ + comment: z + .object({ + alertId: z.union([z.string(), z.array(z.string())]).optional(), + index: z.union([z.string(), z.array(z.string())]).optional(), + owner: Owner.optional(), + rule: z + .object({ + /** + * The rule identifier. + */ + id: z.string().nullable().optional(), + /** + * The rule name. + */ + name: z.string().nullable().optional(), + }) + .optional(), + type: z.literal('alert').optional(), + }) + .optional(), + }) +); export type PayloadAlertComment = z.infer; -export const PayloadAlertComment = z.object({ - comment: z - .object({ - alertId: z.union([z.string(), z.array(z.string())]).optional(), - index: z.union([z.string(), z.array(z.string())]).optional(), - owner: Owner.optional(), - rule: z - .object({ - /** - * The rule identifier. - */ - id: z.string().nullable().optional(), - /** - * The rule name. - */ - name: z.string().nullable().optional(), - }) - .optional(), - type: z.literal('alert').optional(), - }) - .optional(), -}); +export const PayloadAssignees = lazySchema(() => + z.object({ + assignees: Assignees.optional(), + }) +); export type PayloadAssignees = z.infer; -export const PayloadAssignees = z.object({ - assignees: Assignees.optional(), -}); +export const PayloadConnector = lazySchema(() => + z.object({ + connector: z + .object({ + /** + * An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. + */ + fields: z + .object({ + /** + * The case identifier for Swimlane connectors. + */ + caseId: z.string().optional(), + /** + * The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors. + */ + category: z.string().optional(), + /** + * Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. + */ + destIp: z.boolean().nullable().optional(), + /** + * The effect an incident had on business for ServiceNow ITSM connectors. + */ + impact: z.string().optional(), + /** + * The type of issue for Jira connectors. + */ + issueType: z.string().optional(), + /** + * The type of incident for IBM Resilient connectors. + */ + issueTypes: z.array(z.string()).optional(), + /** + * Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. + */ + malwareHash: z.boolean().nullable().optional(), + /** + * Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. + */ + malwareUrl: z.boolean().nullable().optional(), + /** + * The key of the parent issue, when the issue type is sub-task for Jira connectors. + */ + parent: z.string().optional(), + /** + * The priority of the issue for Jira and ServiceNow SecOps connectors. + */ + priority: z.string().optional(), + /** + * The severity of the incident for ServiceNow ITSM connectors. + */ + severity: z.string().optional(), + /** + * The severity code of the incident for IBM Resilient connectors. + */ + severityCode: z.string().optional(), + /** + * Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. + */ + sourceIp: z.boolean().nullable().optional(), + /** + * The subcategory of the incident for ServiceNow ITSM connectors. + */ + subcategory: z.string().optional(), + /** + * The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. + */ + urgency: z.string().optional(), + }) + .nullable() + .optional(), + /** + * The identifier for the connector. To create a case without a connector, use `none`. + */ + id: z.string().optional(), + /** + * The name of the connector. To create a case without a connector, use `none`. + */ + name: z.string().optional(), + type: ConnectorTypes.optional(), + }) + .optional(), + }) +); export type PayloadConnector = z.infer; -export const PayloadConnector = z.object({ - connector: z - .object({ - /** - * An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. - */ - fields: z - .object({ - /** - * The case identifier for Swimlane connectors. - */ - caseId: z.string().optional(), - /** - * The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors. - */ - category: z.string().optional(), - /** - * Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. - */ - destIp: z.boolean().nullable().optional(), - /** - * The effect an incident had on business for ServiceNow ITSM connectors. - */ - impact: z.string().optional(), - /** - * The type of issue for Jira connectors. - */ - issueType: z.string().optional(), - /** - * The type of incident for IBM Resilient connectors. - */ - issueTypes: z.array(z.string()).optional(), - /** - * Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. - */ - malwareHash: z.boolean().nullable().optional(), - /** - * Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. - */ - malwareUrl: z.boolean().nullable().optional(), - /** - * The key of the parent issue, when the issue type is sub-task for Jira connectors. - */ - parent: z.string().optional(), - /** - * The priority of the issue for Jira and ServiceNow SecOps connectors. - */ - priority: z.string().optional(), - /** - * The severity of the incident for ServiceNow ITSM connectors. - */ - severity: z.string().optional(), - /** - * The severity code of the incident for IBM Resilient connectors. - */ - severityCode: z.string().optional(), - /** - * Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. - */ - sourceIp: z.boolean().nullable().optional(), - /** - * The subcategory of the incident for ServiceNow ITSM connectors. - */ - subcategory: z.string().optional(), - /** - * The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. - */ - urgency: z.string().optional(), - }) - .nullable() - .optional(), - /** - * The identifier for the connector. To create a case without a connector, use `none`. - */ - id: z.string().optional(), - /** - * The name of the connector. To create a case without a connector, use `none`. - */ - name: z.string().optional(), - type: ConnectorTypes.optional(), - }) - .optional(), -}); +export const PayloadCreateCase = lazySchema(() => + z.object({ + assignees: Assignees.optional(), + connector: z + .object({ + /** + * An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. + */ + fields: z + .object({ + /** + * The case identifier for Swimlane connectors. + */ + caseId: z.string().optional(), + /** + * The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors. + */ + category: z.string().optional(), + /** + * Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. + */ + destIp: z.boolean().nullable().optional(), + /** + * The effect an incident had on business for ServiceNow ITSM connectors. + */ + impact: z.string().optional(), + /** + * The type of issue for Jira connectors. + */ + issueType: z.string().optional(), + /** + * The type of incident for IBM Resilient connectors. + */ + issueTypes: z.array(z.string()).optional(), + /** + * Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. + */ + malwareHash: z.boolean().nullable().optional(), + /** + * Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. + */ + malwareUrl: z.boolean().nullable().optional(), + /** + * The key of the parent issue, when the issue type is sub-task for Jira connectors. + */ + parent: z.string().optional(), + /** + * The priority of the issue for Jira and ServiceNow SecOps connectors. + */ + priority: z.string().optional(), + /** + * The severity of the incident for ServiceNow ITSM connectors. + */ + severity: z.string().optional(), + /** + * The severity code of the incident for IBM Resilient connectors. + */ + severityCode: z.string().optional(), + /** + * Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. + */ + sourceIp: z.boolean().nullable().optional(), + /** + * The subcategory of the incident for ServiceNow ITSM connectors. + */ + subcategory: z.string().optional(), + /** + * The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. + */ + urgency: z.string().optional(), + }) + .nullable() + .optional(), + /** + * The identifier for the connector. To create a case without a connector, use `none`. + */ + id: z.string().optional(), + /** + * The name of the connector. To create a case without a connector, use `none`. + */ + name: z.string().optional(), + type: ConnectorTypes.optional(), + }) + .optional(), + description: z.string().optional(), + owner: Owner.optional(), + settings: Settings.optional(), + severity: CaseSeverity.optional(), + status: CaseStatus.optional(), + tags: z.array(z.string()).optional(), + title: z.string().optional(), + }) +); export type PayloadCreateCase = z.infer; -export const PayloadCreateCase = z.object({ - assignees: Assignees.optional(), - connector: z - .object({ - /** - * An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. - */ - fields: z - .object({ - /** - * The case identifier for Swimlane connectors. - */ - caseId: z.string().optional(), - /** - * The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors. - */ - category: z.string().optional(), - /** - * Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. - */ - destIp: z.boolean().nullable().optional(), - /** - * The effect an incident had on business for ServiceNow ITSM connectors. - */ - impact: z.string().optional(), - /** - * The type of issue for Jira connectors. - */ - issueType: z.string().optional(), - /** - * The type of incident for IBM Resilient connectors. - */ - issueTypes: z.array(z.string()).optional(), - /** - * Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. - */ - malwareHash: z.boolean().nullable().optional(), - /** - * Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. - */ - malwareUrl: z.boolean().nullable().optional(), - /** - * The key of the parent issue, when the issue type is sub-task for Jira connectors. - */ - parent: z.string().optional(), - /** - * The priority of the issue for Jira and ServiceNow SecOps connectors. - */ - priority: z.string().optional(), - /** - * The severity of the incident for ServiceNow ITSM connectors. - */ - severity: z.string().optional(), - /** - * The severity code of the incident for IBM Resilient connectors. - */ - severityCode: z.string().optional(), - /** - * Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. - */ - sourceIp: z.boolean().nullable().optional(), - /** - * The subcategory of the incident for ServiceNow ITSM connectors. - */ - subcategory: z.string().optional(), - /** - * The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. - */ - urgency: z.string().optional(), - }) - .nullable() - .optional(), - /** - * The identifier for the connector. To create a case without a connector, use `none`. - */ - id: z.string().optional(), - /** - * The name of the connector. To create a case without a connector, use `none`. - */ - name: z.string().optional(), - type: ConnectorTypes.optional(), - }) - .optional(), - description: z.string().optional(), - owner: Owner.optional(), - settings: Settings.optional(), - severity: CaseSeverity.optional(), - status: CaseStatus.optional(), - tags: z.array(z.string()).optional(), - title: z.string().optional(), -}); /** * If the `action` is `delete` and the `type` is `delete_case`, the payload is nullable. */ +export const PayloadDelete = lazySchema(() => z.object({}).nullable()); export type PayloadDelete = z.infer; -export const PayloadDelete = z.object({}).nullable(); +export const PayloadDescription = lazySchema(() => + z.object({ + description: z.string().optional(), + }) +); export type PayloadDescription = z.infer; -export const PayloadDescription = z.object({ - description: z.string().optional(), -}); +export const PayloadPushed = lazySchema(() => + z.object({ + externalService: ExternalService.optional(), + }) +); export type PayloadPushed = z.infer; -export const PayloadPushed = z.object({ - externalService: ExternalService.optional(), -}); +export const PayloadSettings = lazySchema(() => + z.object({ + settings: Settings.optional(), + }) +); export type PayloadSettings = z.infer; -export const PayloadSettings = z.object({ - settings: Settings.optional(), -}); +export const PayloadSeverity = lazySchema(() => + z.object({ + severity: CaseSeverity.optional(), + }) +); export type PayloadSeverity = z.infer; -export const PayloadSeverity = z.object({ - severity: CaseSeverity.optional(), -}); +export const PayloadStatus = lazySchema(() => + z.object({ + status: CaseStatus.optional(), + }) +); export type PayloadStatus = z.infer; -export const PayloadStatus = z.object({ - status: CaseStatus.optional(), -}); +export const PayloadTags = lazySchema(() => + z.object({ + tags: z.array(z.string()).optional(), + }) +); export type PayloadTags = z.infer; -export const PayloadTags = z.object({ - tags: z.array(z.string()).optional(), -}); +export const PayloadTitle = lazySchema(() => + z.object({ + title: z.string().optional(), + }) +); export type PayloadTitle = z.infer; -export const PayloadTitle = z.object({ - title: z.string().optional(), -}); +export const PayloadUserComment = lazySchema(() => + z.object({ + comment: z + .object({ + comment: z.string().optional(), + owner: Owner.optional(), + type: z.literal('user').optional(), + }) + .optional(), + }) +); export type PayloadUserComment = z.infer; -export const PayloadUserComment = z.object({ - comment: z - .object({ - comment: z.string().optional(), - owner: Owner.optional(), - type: z.literal('user').optional(), - }) - .optional(), -}); +export const UserActionsFindResponseProperties = lazySchema(() => + z.object({ + action: Actions, + comment_id: z.string().nullable(), + created_at: z.string().datetime(), + created_by: z.object({ + email: z.string().nullable(), + full_name: z.string().nullable(), + username: z.string().nullable(), + profile_uid: z.string().optional(), + }), + id: z.string(), + owner: Owner, + payload: z.union([ + PayloadAlertComment, + PayloadAssignees, + PayloadConnector, + PayloadCreateCase, + PayloadDelete, + PayloadDescription, + PayloadPushed, + PayloadSettings, + PayloadSeverity, + PayloadStatus, + PayloadTags, + PayloadTitle, + PayloadUserComment, + ]), + version: z.string(), + /** + * The type of action. + */ + type: z.enum([ + 'assignees', + 'create_case', + 'comment', + 'connector', + 'description', + 'pushed', + 'tags', + 'title', + 'status', + 'settings', + 'severity', + ]), + }) +); export type UserActionsFindResponseProperties = z.infer; -export const UserActionsFindResponseProperties = z.object({ - action: Actions, - comment_id: z.string().nullable(), - created_at: z.string().datetime(), - created_by: z.object({ - email: z.string().nullable(), - full_name: z.string().nullable(), - username: z.string().nullable(), - profile_uid: z.string().optional(), - }), - id: z.string(), - owner: Owner, - payload: z.union([ - PayloadAlertComment, - PayloadAssignees, - PayloadConnector, - PayloadCreateCase, - PayloadDelete, - PayloadDescription, - PayloadPushed, - PayloadSettings, - PayloadSeverity, - PayloadStatus, - PayloadTags, - PayloadTitle, - PayloadUserComment, - ]), - version: z.string(), - /** - * The type of action. - */ - type: z.enum([ - 'assignees', - 'create_case', - 'comment', - 'connector', - 'description', - 'pushed', - 'tags', - 'title', - 'status', - 'settings', - 'severity', - ]), -}); /** * Defines the file that will be attached to the case. Optional parameters will be generated automatically from the file metadata if not defined. */ +export const AddCaseFileRequest = lazySchema(() => + z.object({ + /** + * The file being attached to the case. + */ + file: z.string(), + /** + * The desired name of the file being attached to the case, it can be different than the name of the file in the filesystem. **This should not include the file extension.** + */ + filename: z.string().optional(), + }) +); export type AddCaseFileRequest = z.infer; -export const AddCaseFileRequest = z.object({ - /** - * The file being attached to the case. - */ - file: z.string(), - /** - * The desired name of the file being attached to the case, it can be different than the name of the file in the filesystem. **This should not include the file extension.** - */ - filename: z.string().optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/asset/assets.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/asset/assets.gen.ts index 9c0c0327199fa..a68d1a4fcadd3 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/asset/assets.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/asset/assets.gen.ts @@ -14,23 +14,27 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AssetsRequestQuery } from './assets_status.gen'; +export const ReadAssetsStatusRequestQuery = lazySchema(() => + z.object({ + query: AssetsRequestQuery, + }) +); export type ReadAssetsStatusRequestQuery = z.infer; -export const ReadAssetsStatusRequestQuery = z.object({ - query: AssetsRequestQuery, -}); export type ReadAssetsStatusRequestQueryInput = z.input; +export const ReadAssetsStatusResponse = lazySchema(() => z.object({})); export type ReadAssetsStatusResponse = z.infer; -export const ReadAssetsStatusResponse = z.object({}); +export const UpdateAssetsStatusRequestQuery = lazySchema(() => + z.object({ + query: AssetsRequestQuery, + }) +); export type UpdateAssetsStatusRequestQuery = z.infer; -export const UpdateAssetsStatusRequestQuery = z.object({ - query: AssetsRequestQuery, -}); export type UpdateAssetsStatusRequestQueryInput = z.input; +export const UpdateAssetsStatusResponse = lazySchema(() => z.object({})); export type UpdateAssetsStatusResponse = z.infer; -export const UpdateAssetsStatusResponse = z.object({}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/asset/assets_status.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/asset/assets_status.gen.ts index 953385fa6a3de..8f7e932fe4d88 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/asset/assets_status.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/asset/assets_status.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const AssetsRequestQuery = lazySchema(() => z.object({})); export type AssetsRequestQuery = z.infer; -export const AssetsRequestQuery = z.object({}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/fleet_wrapper.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/fleet_wrapper.gen.ts index 2314bf24d8f94..a0a8dbc9bb182 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/fleet_wrapper.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/fleet_wrapper.gen.ts @@ -14,36 +14,42 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const GetAgentDetailsRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type GetAgentDetailsRequestParams = z.infer; -export const GetAgentDetailsRequestParams = z.object({ - id: z.string(), -}); export type GetAgentDetailsRequestParamsInput = z.input; +export const GetAgentDetailsResponse = lazySchema(() => z.object({})); export type GetAgentDetailsResponse = z.infer; -export const GetAgentDetailsResponse = z.object({}); +export const GetAgentPackagePoliciesResponse = lazySchema(() => z.object({})); export type GetAgentPackagePoliciesResponse = z.infer; -export const GetAgentPackagePoliciesResponse = z.object({}); +export const GetAgentPoliciesResponse = lazySchema(() => z.object({})); export type GetAgentPoliciesResponse = z.infer; -export const GetAgentPoliciesResponse = z.object({}); +export const GetAgentPolicyRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type GetAgentPolicyRequestParams = z.infer; -export const GetAgentPolicyRequestParams = z.object({ - id: z.string(), -}); export type GetAgentPolicyRequestParamsInput = z.input; +export const GetAgentPolicyResponse = lazySchema(() => z.object({})); export type GetAgentPolicyResponse = z.infer; -export const GetAgentPolicyResponse = z.object({}); +export const GetAgentsRequestQuery = lazySchema(() => + z.object({ + query: z.object({}), + }) +); export type GetAgentsRequestQuery = z.infer; -export const GetAgentsRequestQuery = z.object({ - query: z.object({}), -}); export type GetAgentsRequestQueryInput = z.input; +export const GetAgentsResponse = lazySchema(() => z.object({})); export type GetAgentsResponse = z.infer; -export const GetAgentsResponse = z.object({}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/get_agent_status.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/get_agent_status.gen.ts index ba12ea7d37045..3f3187726bf5c 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/get_agent_status.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/fleet_wrapper/get_agent_status.gen.ts @@ -14,15 +14,17 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { KueryOrUndefined } from '../model/schema/common_attributes.gen'; +export const GetAgentStatusRequestParams = lazySchema(() => z.object({})); export type GetAgentStatusRequestParams = z.infer; -export const GetAgentStatusRequestParams = z.object({}); +export const GetAgentStatusRequestQueryParams = lazySchema(() => + z.object({ + kuery: KueryOrUndefined.optional(), + policyId: z.string().optional(), + }) +); export type GetAgentStatusRequestQueryParams = z.infer; -export const GetAgentStatusRequestQueryParams = z.object({ - kuery: KueryOrUndefined.optional(), - policyId: z.string().optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/live_query/create_live_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/live_query/create_live_query.gen.ts index 99b23b1e6c47d..768e91d7d4d2d 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/live_query/create_live_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/live_query/create_live_query.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { QueryOrUndefined, @@ -24,122 +24,126 @@ import { PackIdOrUndefined, } from '../model/schema/common_attributes.gen'; -export type CreateLiveQueryRequestBody = z.infer; -export const CreateLiveQueryRequestBody = z.object({ - /** - * A list of agent IDs to run the query on. - */ - agent_ids: z.array(z.string()).optional(), - /** - * When `true`, the query runs on all agents. - */ - agent_all: z.boolean().optional(), - /** - * A list of agent platforms to run the query on. - */ - agent_platforms: z.array(z.string()).optional(), - /** - * A list of agent policy IDs to run the query on. - */ - agent_policy_ids: z.array(z.string()).optional(), - query: QueryOrUndefined.optional(), - queries: ArrayQueries.optional(), - saved_query_id: SavedQueryIdOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - pack_id: PackIdOrUndefined.optional(), - /** - * A list of alert IDs associated with the live query. - */ - alert_ids: z.array(z.string()).optional(), - /** - * A list of case IDs associated with the live query. - */ - case_ids: z.array(z.string()).optional(), - /** - * A list of event IDs associated with the live query. - */ - event_ids: z.array(z.string()).optional(), - /** - * Custom metadata object associated with the live query. - */ - metadata: z.object({}).nullable().optional(), -}); - -/** - * The response for creating a live query. - */ -export type CreateLiveQueryResponse = z.infer; -export const CreateLiveQueryResponse = z.object({ - data: z.object({ - /** - * The ID of the action. - */ - action_id: z.string(), - /** - * The timestamp when the action was created. - */ - '@timestamp': z.string().datetime().optional(), - /** - * The expiration date of the action. - */ - expiration: z.string().datetime().optional(), +export const CreateLiveQueryRequestBody = lazySchema(() => + z.object({ /** - * The action type. - */ - type: z.string().optional(), - /** - * The input type. - */ - input_type: z.string().optional(), - /** - * The agent IDs targeted by the action. + * A list of agent IDs to run the query on. */ agent_ids: z.array(z.string()).optional(), /** - * Whether the query targets all agents. + * When `true`, the query runs on all agents. */ agent_all: z.boolean().optional(), /** - * The agent platforms targeted. + * A list of agent platforms to run the query on. */ agent_platforms: z.array(z.string()).optional(), /** - * The agent policy IDs targeted. + * A list of agent policy IDs to run the query on. */ agent_policy_ids: z.array(z.string()).optional(), + query: QueryOrUndefined.optional(), + queries: ArrayQueries.optional(), + saved_query_id: SavedQueryIdOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + pack_id: PackIdOrUndefined.optional(), /** - * The resolved list of agent IDs. - */ - agents: z.array(z.string()).optional(), - /** - * The user who created the action. + * A list of alert IDs associated with the live query. */ - user_id: z.string().optional(), + alert_ids: z.array(z.string()).optional(), /** - * The pack ID if the query was run from a pack. + * A list of case IDs associated with the live query. */ - pack_id: z.string().optional(), + case_ids: z.array(z.string()).optional(), /** - * Custom metadata associated with the action. + * A list of event IDs associated with the live query. */ - metadata: z.object({}).optional(), + event_ids: z.array(z.string()).optional(), /** - * The queries in this action. + * Custom metadata object associated with the live query. */ - queries: z - .array( - z.object({ - action_id: z.string().optional(), - id: z.string().optional(), - query: z.string().optional(), - timeout: z.number().int().optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - agents: z.array(z.string()).optional(), - saved_query_id: z.string().optional(), - version: z.string().optional(), - platform: z.string().optional(), - }) - ) - .optional(), - }), -}); + metadata: z.object({}).nullable().optional(), + }) +); +export type CreateLiveQueryRequestBody = z.infer; + +/** + * The response for creating a live query. + */ +export const CreateLiveQueryResponse = lazySchema(() => + z.object({ + data: z.object({ + /** + * The ID of the action. + */ + action_id: z.string(), + /** + * The timestamp when the action was created. + */ + '@timestamp': z.string().datetime().optional(), + /** + * The expiration date of the action. + */ + expiration: z.string().datetime().optional(), + /** + * The action type. + */ + type: z.string().optional(), + /** + * The input type. + */ + input_type: z.string().optional(), + /** + * The agent IDs targeted by the action. + */ + agent_ids: z.array(z.string()).optional(), + /** + * Whether the query targets all agents. + */ + agent_all: z.boolean().optional(), + /** + * The agent platforms targeted. + */ + agent_platforms: z.array(z.string()).optional(), + /** + * The agent policy IDs targeted. + */ + agent_policy_ids: z.array(z.string()).optional(), + /** + * The resolved list of agent IDs. + */ + agents: z.array(z.string()).optional(), + /** + * The user who created the action. + */ + user_id: z.string().optional(), + /** + * The pack ID if the query was run from a pack. + */ + pack_id: z.string().optional(), + /** + * Custom metadata associated with the action. + */ + metadata: z.object({}).optional(), + /** + * The queries in this action. + */ + queries: z + .array( + z.object({ + action_id: z.string().optional(), + id: z.string().optional(), + query: z.string().optional(), + timeout: z.number().int().optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + agents: z.array(z.string()).optional(), + saved_query_id: z.string().optional(), + version: z.string().optional(), + platform: z.string().optional(), + }) + ) + .optional(), + }), + }) +); +export type CreateLiveQueryResponse = z.infer; diff --git a/x-pack/platform/plugins/shared/osquery/common/api/live_query/find_live_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/live_query/find_live_query.gen.ts index 9e9e511d94174..f90a6dbfa5c49 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/live_query/find_live_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/live_query/find_live_query.gen.ts @@ -14,150 +14,156 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ECSMappingOrUndefined } from '../model/schema/common_attributes.gen'; -export type FindLiveQueryRequestQuery = z.infer; -export const FindLiveQueryRequestQuery = z.object({ - /** - * A KQL search string to filter live queries. - */ - kuery: z.string().optional(), - /** - * The page number to return. The default is 1. - */ - page: z.number().int().optional(), - /** - * The number of results to return per page. The default is 20. - */ - pageSize: z.number().int().optional(), - /** - * The field to sort results by. - */ - sort: z.string().optional(), - /** - * The sort order. - */ - sortOrder: z.enum(['asc', 'desc']).optional(), - /** +export const FindLiveQueryRequestQuery = lazySchema(() => + z.object({ + /** + * A KQL search string to filter live queries. + */ + kuery: z.string().optional(), + /** + * The page number to return. The default is 1. + */ + page: z.number().int().optional(), + /** + * The number of results to return per page. The default is 20. + */ + pageSize: z.number().int().optional(), + /** + * The field to sort results by. + */ + sort: z.string().optional(), + /** + * The sort order. + */ + sortOrder: z.enum(['asc', 'desc']).optional(), + /** * When true, the response includes result_counts on each item with aggregated result statistics from the action responses index. */ - withResultCounts: z.boolean().optional(), -}); + withResultCounts: z.boolean().optional(), + }) +); +export type FindLiveQueryRequestQuery = z.infer; -export type FindLiveQueryResponse = z.infer; -export const FindLiveQueryResponse = z.object({ - data: z - .object({ - /** - * The total number of live queries. - */ - total: z.number().int().optional(), - /** - * An array of live query action items. - */ - items: z - .array( - z.object({ - _source: z - .object({ - action_id: z.string().optional(), - expiration: z.string().datetime().optional(), - '@timestamp': z.string().datetime().optional(), - agents: z.array(z.string()).optional(), - user_id: z.string().optional(), - pack_id: z.string().optional(), - queries: z - .array( - z.object({ - action_id: z.string().optional(), - id: z.string().optional(), - query: z.string().optional(), - saved_query_id: z.string().optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - agents: z.array(z.string()).optional(), +export const FindLiveQueryResponse = lazySchema(() => + z.object({ + data: z + .object({ + /** + * The total number of live queries. + */ + total: z.number().int().optional(), + /** + * An array of live query action items. + */ + items: z + .array( + z.object({ + _source: z + .object({ + action_id: z.string().optional(), + expiration: z.string().datetime().optional(), + '@timestamp': z.string().datetime().optional(), + agents: z.array(z.string()).optional(), + user_id: z.string().optional(), + pack_id: z.string().optional(), + queries: z + .array( + z.object({ + action_id: z.string().optional(), + id: z.string().optional(), + query: z.string().optional(), + saved_query_id: z.string().optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + agents: z.array(z.string()).optional(), + }) + ) + .optional(), + /** + * Result count statistics (present when withResultCounts is true). + */ + result_counts: z + .object({ + total_rows: z.number().int().optional(), + responded_agents: z.number().int().optional(), + successful_agents: z.number().int().optional(), + error_agents: z.number().int().optional(), }) - ) - .optional(), - /** - * Result count statistics (present when withResultCounts is true). - */ - result_counts: z - .object({ - total_rows: z.number().int().optional(), - responded_agents: z.number().int().optional(), - successful_agents: z.number().int().optional(), - error_agents: z.number().int().optional(), - }) - .optional(), - }) - .optional(), - }) - ) - .optional(), - }) - .optional(), -}); + .optional(), + }) + .optional(), + }) + ) + .optional(), + }) + .optional(), + }) +); +export type FindLiveQueryResponse = z.infer; +export const FindLiveQueryDetailsResponse = lazySchema(() => + z.object({ + data: z + .object({ + action_id: z.string().optional(), + expiration: z.string().datetime().optional(), + '@timestamp': z.string().datetime().optional(), + agents: z.array(z.string()).optional(), + user_id: z.string().optional(), + user_profile_uid: z.string().optional(), + pack_id: z.string().optional(), + pack_name: z.string().optional(), + prebuilt_pack: z.boolean().optional(), + tags: z.array(z.string()).optional(), + /** + * Global status of the live query (completed, running). + */ + status: z.enum(['completed', 'running']).optional(), + /** + * The queries with their execution status. + */ + queries: z + .array( + z.object({ + action_id: z.string().optional(), + id: z.string().optional(), + query: z.string().optional(), + saved_query_id: z.string().optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + agents: z.array(z.string()).optional(), + /** + * Number of result documents. + */ + docs: z.number().int().optional(), + /** + * Number of failed queries. + */ + failed: z.number().int().optional(), + /** + * Number of pending agents. + */ + pending: z.number().int().optional(), + /** + * Total responded agents. + */ + responded: z.number().int().optional(), + /** + * Number of successful agents. + */ + successful: z.number().int().optional(), + /** + * Status of this individual query. + */ + status: z.enum(['completed', 'running']).optional(), + }) + ) + .optional(), + }) + .optional(), + }) +); export type FindLiveQueryDetailsResponse = z.infer; -export const FindLiveQueryDetailsResponse = z.object({ - data: z - .object({ - action_id: z.string().optional(), - expiration: z.string().datetime().optional(), - '@timestamp': z.string().datetime().optional(), - agents: z.array(z.string()).optional(), - user_id: z.string().optional(), - user_profile_uid: z.string().optional(), - pack_id: z.string().optional(), - pack_name: z.string().optional(), - prebuilt_pack: z.boolean().optional(), - tags: z.array(z.string()).optional(), - /** - * Global status of the live query (completed, running). - */ - status: z.enum(['completed', 'running']).optional(), - /** - * The queries with their execution status. - */ - queries: z - .array( - z.object({ - action_id: z.string().optional(), - id: z.string().optional(), - query: z.string().optional(), - saved_query_id: z.string().optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - agents: z.array(z.string()).optional(), - /** - * Number of result documents. - */ - docs: z.number().int().optional(), - /** - * Number of failed queries. - */ - failed: z.number().int().optional(), - /** - * Number of pending agents. - */ - pending: z.number().int().optional(), - /** - * Total responded agents. - */ - responded: z.number().int().optional(), - /** - * Number of successful agents. - */ - successful: z.number().int().optional(), - /** - * Status of this individual query. - */ - status: z.enum(['completed', 'running']).optional(), - }) - ) - .optional(), - }) - .optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/live_query/get_live_query_results.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/live_query/get_live_query_results.gen.ts index fc27e033763ac..85e80f65d0163 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/live_query/get_live_query_results.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/live_query/get_live_query_results.gen.ts @@ -14,33 +14,35 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The response for getting live query results. */ +export const GetLiveQueryResultsResponse = lazySchema(() => + z.object({ + data: z + .object({ + /** + * The total number of result rows. + */ + total: z.number().int().optional(), + /** + * The result rows from the query execution. + */ + edges: z + .array( + z.object({ + _id: z.string().optional(), + /** + * The Elasticsearch document source containing query results. + */ + _source: z.object({}).optional(), + }) + ) + .optional(), + }) + .optional(), + }) +); export type GetLiveQueryResultsResponse = z.infer; -export const GetLiveQueryResultsResponse = z.object({ - data: z - .object({ - /** - * The total number of result rows. - */ - total: z.number().int().optional(), - /** - * The result rows from the query execution. - */ - edges: z - .array( - z.object({ - _id: z.string().optional(), - /** - * The Elasticsearch document source containing query results. - */ - _source: z.object({}).optional(), - }) - ) - .optional(), - }) - .optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/live_query/live_queries.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/live_query/live_queries.gen.ts index 0576008602ff4..051eedbff7cc3 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/live_query/live_queries.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/live_query/live_queries.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { KueryOrUndefined, @@ -27,104 +27,112 @@ import { FindLiveQueryResponse, FindLiveQueryDetailsResponse } from './find_live import { CreateLiveQueryRequestBody, CreateLiveQueryResponse } from './create_live_query.gen'; import { GetLiveQueryResultsResponse } from './get_live_query_results.gen'; +export const OsqueryCreateLiveQueryRequestBody = lazySchema(() => CreateLiveQueryRequestBody); export type OsqueryCreateLiveQueryRequestBody = z.infer; -export const OsqueryCreateLiveQueryRequestBody = CreateLiveQueryRequestBody; export type OsqueryCreateLiveQueryRequestBodyInput = z.input< typeof OsqueryCreateLiveQueryRequestBody >; +export const OsqueryCreateLiveQueryResponse = lazySchema(() => CreateLiveQueryResponse); export type OsqueryCreateLiveQueryResponse = z.infer; -export const OsqueryCreateLiveQueryResponse = CreateLiveQueryResponse; +export const OsqueryFindLiveQueriesRequestQuery = lazySchema(() => + z.object({ + /** + * A KQL search string to filter live queries. + */ + kuery: KueryOrUndefined.optional(), + /** + * The page number to return. + */ + page: PageOrUndefined.optional(), + /** + * The number of results to return per page. + */ + pageSize: PageSizeOrUndefined.optional(), + /** + * The field to sort results by. + */ + sort: SortOrUndefined.optional(), + /** + * The sort order. + */ + sortOrder: SortOrderOrUndefined.optional(), + }) +); export type OsqueryFindLiveQueriesRequestQuery = z.infer; -export const OsqueryFindLiveQueriesRequestQuery = z.object({ - /** - * A KQL search string to filter live queries. - */ - kuery: KueryOrUndefined.optional(), - /** - * The page number to return. - */ - page: PageOrUndefined.optional(), - /** - * The number of results to return per page. - */ - pageSize: PageSizeOrUndefined.optional(), - /** - * The field to sort results by. - */ - sort: SortOrUndefined.optional(), - /** - * The sort order. - */ - sortOrder: SortOrderOrUndefined.optional(), -}); export type OsqueryFindLiveQueriesRequestQueryInput = z.input< typeof OsqueryFindLiveQueriesRequestQuery >; +export const OsqueryFindLiveQueriesResponse = lazySchema(() => FindLiveQueryResponse); export type OsqueryFindLiveQueriesResponse = z.infer; -export const OsqueryFindLiveQueriesResponse = FindLiveQueryResponse; +export const OsqueryGetLiveQueryDetailsRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the live query. + */ + id: z.string(), + }) +); export type OsqueryGetLiveQueryDetailsRequestParams = z.infer< typeof OsqueryGetLiveQueryDetailsRequestParams >; -export const OsqueryGetLiveQueryDetailsRequestParams = z.object({ - /** - * The ID of the live query. - */ - id: z.string(), -}); export type OsqueryGetLiveQueryDetailsRequestParamsInput = z.input< typeof OsqueryGetLiveQueryDetailsRequestParams >; +export const OsqueryGetLiveQueryDetailsResponse = lazySchema(() => FindLiveQueryDetailsResponse); export type OsqueryGetLiveQueryDetailsResponse = z.infer; -export const OsqueryGetLiveQueryDetailsResponse = FindLiveQueryDetailsResponse; +export const OsqueryGetLiveQueryResultsRequestQuery = lazySchema(() => + z.object({ + /** + * A KQL search string to filter results. + */ + kuery: KueryOrUndefined.optional(), + /** + * The page number to return. + */ + page: PageOrUndefined.optional(), + /** + * The number of results to return per page. + */ + pageSize: PageSizeOrUndefined.optional(), + /** + * The field to sort results by. + */ + sort: SortOrUndefined.optional(), + /** + * The sort order. + */ + sortOrder: SortOrderOrUndefined.optional(), + }) +); export type OsqueryGetLiveQueryResultsRequestQuery = z.infer< typeof OsqueryGetLiveQueryResultsRequestQuery >; -export const OsqueryGetLiveQueryResultsRequestQuery = z.object({ - /** - * A KQL search string to filter results. - */ - kuery: KueryOrUndefined.optional(), - /** - * The page number to return. - */ - page: PageOrUndefined.optional(), - /** - * The number of results to return per page. - */ - pageSize: PageSizeOrUndefined.optional(), - /** - * The field to sort results by. - */ - sort: SortOrUndefined.optional(), - /** - * The sort order. - */ - sortOrder: SortOrderOrUndefined.optional(), -}); export type OsqueryGetLiveQueryResultsRequestQueryInput = z.input< typeof OsqueryGetLiveQueryResultsRequestQuery >; +export const OsqueryGetLiveQueryResultsRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the live query. + */ + id: z.string(), + /** + * The ID of the query action. + */ + actionId: z.string(), + }) +); export type OsqueryGetLiveQueryResultsRequestParams = z.infer< typeof OsqueryGetLiveQueryResultsRequestParams >; -export const OsqueryGetLiveQueryResultsRequestParams = z.object({ - /** - * The ID of the live query. - */ - id: z.string(), - /** - * The ID of the query action. - */ - actionId: z.string(), -}); export type OsqueryGetLiveQueryResultsRequestParamsInput = z.input< typeof OsqueryGetLiveQueryResultsRequestParams >; +export const OsqueryGetLiveQueryResultsResponse = lazySchema(() => GetLiveQueryResultsResponse); export type OsqueryGetLiveQueryResultsResponse = z.infer; -export const OsqueryGetLiveQueryResultsResponse = GetLiveQueryResultsResponse; diff --git a/x-pack/platform/plugins/shared/osquery/common/api/model/schema/common_attributes.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/model/schema/common_attributes.gen.ts index ab65437e2273b..0c6033e79614e 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/model/schema/common_attributes.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/model/schema/common_attributes.gen.ts @@ -14,248 +14,256 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The ID of the query. */ +export const QueryId = lazySchema(() => z.string()); export type QueryId = z.infer; -export const QueryId = z.string(); /** * The pack description. */ +export const PackDescription = lazySchema(() => z.string()); export type PackDescription = z.infer; -export const PackDescription = z.string(); +export const PackDescriptionOrUndefined = lazySchema(() => PackDescription.nullable()); export type PackDescriptionOrUndefined = z.infer; -export const PackDescriptionOrUndefined = PackDescription.nullable(); /** * Restricts the query to a specified platform. The default is all platforms. To specify multiple platforms, use commas. For example, `linux,darwin`. */ +export const Platform = lazySchema(() => z.string()); export type Platform = z.infer; -export const Platform = z.string(); +export const PlatformOrUndefined = lazySchema(() => Platform.nullable()); export type PlatformOrUndefined = z.infer; -export const PlatformOrUndefined = Platform.nullable(); /** * The SQL query you want to run. */ +export const Query = lazySchema(() => z.string()); export type Query = z.infer; -export const Query = z.string(); +export const QueryOrUndefined = lazySchema(() => Query.nullable()); export type QueryOrUndefined = z.infer; -export const QueryOrUndefined = Query.nullable(); /** * Uses the Osquery versions greater than or equal to the specified version string. */ +export const Version = lazySchema(() => z.string()); export type Version = z.infer; -export const Version = z.string(); +export const VersionOrUndefined = lazySchema(() => Version.nullable()); export type VersionOrUndefined = z.infer; -export const VersionOrUndefined = Version.nullable(); /** * An interval, in seconds, on which to run the query. */ +export const Interval = lazySchema(() => z.string()); export type Interval = z.infer; -export const Interval = z.string(); +export const IntervalOrUndefined = lazySchema(() => Interval.nullable()); export type IntervalOrUndefined = z.infer; -export const IntervalOrUndefined = Interval.nullable(); /** * Indicates whether the query is a snapshot. */ +export const Snapshot = lazySchema(() => z.boolean()); export type Snapshot = z.infer; -export const Snapshot = z.boolean(); +export const SnapshotOrUndefined = lazySchema(() => Snapshot.nullable()); export type SnapshotOrUndefined = z.infer; -export const SnapshotOrUndefined = Snapshot.nullable(); /** * Indicates whether the query is removed. */ +export const Removed = lazySchema(() => z.boolean()); export type Removed = z.infer; -export const Removed = z.boolean(); +export const RemovedOrUndefined = lazySchema(() => Removed.nullable()); export type RemovedOrUndefined = z.infer; -export const RemovedOrUndefined = Removed.nullable(); /** * The pack name. */ +export const PackName = lazySchema(() => z.string()); export type PackName = z.infer; -export const PackName = z.string(); /** * The ID of a saved query. */ +export const SavedQueryId = lazySchema(() => z.string()); export type SavedQueryId = z.infer; -export const SavedQueryId = z.string(); +export const SavedQueryIdOrUndefined = lazySchema(() => SavedQueryId.nullable()); export type SavedQueryIdOrUndefined = z.infer; -export const SavedQueryIdOrUndefined = SavedQueryId.nullable(); /** * The saved query description. */ +export const SavedQueryDescription = lazySchema(() => z.string()); export type SavedQueryDescription = z.infer; -export const SavedQueryDescription = z.string(); +export const SavedQueryDescriptionOrUndefined = lazySchema(() => SavedQueryDescription.nullable()); export type SavedQueryDescriptionOrUndefined = z.infer; -export const SavedQueryDescriptionOrUndefined = SavedQueryDescription.nullable(); /** * The ID of the pack. */ +export const PackId = lazySchema(() => z.string()); export type PackId = z.infer; -export const PackId = z.string(); +export const PackIdOrUndefined = lazySchema(() => PackId.nullable()); export type PackIdOrUndefined = z.infer; -export const PackIdOrUndefined = PackId.nullable(); /** * Enables the pack. */ +export const Enabled = lazySchema(() => z.boolean()); export type Enabled = z.infer; -export const Enabled = z.boolean(); +export const EnabledOrUndefined = lazySchema(() => Enabled.nullable()); export type EnabledOrUndefined = z.infer; -export const EnabledOrUndefined = Enabled.nullable(); /** * A list of agents policy IDs. */ +export const PolicyIds = lazySchema(() => z.array(z.string())); export type PolicyIds = z.infer; -export const PolicyIds = z.array(z.string()); +export const PolicyIdsOrUndefined = lazySchema(() => PolicyIds.nullable()); export type PolicyIdsOrUndefined = z.infer; -export const PolicyIdsOrUndefined = PolicyIds.nullable(); +export const ECSMappingItem = lazySchema(() => + z.object({ + /** + * The ECS field to map to. + */ + field: z.string().optional(), + /** + * The value to map to the ECS field. + */ + value: z.union([z.string(), z.array(z.string())]).optional(), + }) +); export type ECSMappingItem = z.infer; -export const ECSMappingItem = z.object({ - /** - * The ECS field to map to. - */ - field: z.string().optional(), - /** - * The value to map to the ECS field. - */ - value: z.union([z.string(), z.array(z.string())]).optional(), -}); /** * Map osquery results columns or static values to Elastic Common Schema (ECS) fields */ +export const ECSMapping = lazySchema(() => z.object({}).catchall(ECSMappingItem)); export type ECSMapping = z.infer; -export const ECSMapping = z.object({}).catchall(ECSMappingItem); +export const ECSMappingOrUndefined = lazySchema(() => ECSMapping.nullable()); export type ECSMappingOrUndefined = z.infer; -export const ECSMappingOrUndefined = ECSMapping.nullable(); /** * ECS mapping item in saved-object storage format (key-value pair). */ +export const ECSMappingArrayItem = lazySchema(() => + z.object({ + /** + * The ECS field name. + */ + key: z.string().optional(), + value: ECSMappingItem.optional(), + }) +); export type ECSMappingArrayItem = z.infer; -export const ECSMappingArrayItem = z.object({ - /** - * The ECS field name. - */ - key: z.string().optional(), - value: ECSMappingItem.optional(), -}); /** * ECS mapping in saved-object storage format (array of key-value pairs). The find and copy pack endpoints return this format. The read endpoint returns object format (ECSMapping). */ +export const ECSMappingArray = lazySchema(() => z.array(ECSMappingArrayItem)); export type ECSMappingArray = z.infer; -export const ECSMappingArray = z.array(ECSMappingArrayItem); +export const ECSMappingArrayOrUndefined = lazySchema(() => ECSMappingArray.nullable()); export type ECSMappingArrayOrUndefined = z.infer; -export const ECSMappingArrayOrUndefined = ECSMappingArray.nullable(); +export const ArrayQueriesItem = lazySchema(() => + z.object({ + id: QueryId.optional(), + query: Query.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + version: VersionOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + snapshot: SnapshotOrUndefined.optional(), + }) +); export type ArrayQueriesItem = z.infer; -export const ArrayQueriesItem = z.object({ - id: QueryId.optional(), - query: Query.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - version: VersionOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), - snapshot: SnapshotOrUndefined.optional(), -}); /** * An array of queries to run. */ +export const ArrayQueries = lazySchema(() => z.array(ArrayQueriesItem)); export type ArrayQueries = z.infer; -export const ArrayQueries = z.array(ArrayQueriesItem); +export const ObjectQueriesItem = lazySchema(() => + z.object({ + query: Query.optional(), + id: QueryId.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + version: VersionOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + saved_query_id: SavedQueryIdOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + snapshot: SnapshotOrUndefined.optional(), + }) +); export type ObjectQueriesItem = z.infer; -export const ObjectQueriesItem = z.object({ - query: Query.optional(), - id: QueryId.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - version: VersionOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - saved_query_id: SavedQueryIdOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), - snapshot: SnapshotOrUndefined.optional(), -}); /** * An object of queries. */ +export const ObjectQueries = lazySchema(() => z.object({}).catchall(ObjectQueriesItem)); export type ObjectQueries = z.infer; -export const ObjectQueries = z.object({}).catchall(ObjectQueriesItem); +export const Queries = lazySchema(() => z.union([ArrayQueries, ObjectQueries])); export type Queries = z.infer; -export const Queries = z.union([ArrayQueries, ObjectQueries]); +export const QueriesOrUndefined = lazySchema(() => Queries.nullable()); export type QueriesOrUndefined = z.infer; -export const QueriesOrUndefined = Queries.nullable(); /** * The kuery to filter the results by. */ +export const KueryOrUndefined = lazySchema(() => z.string().nullable()); export type KueryOrUndefined = z.infer; -export const KueryOrUndefined = z.string().nullable(); /** * The page number to return. The default is 1. */ +export const PageOrUndefined = lazySchema(() => z.number().int().nullable()); export type PageOrUndefined = z.infer; -export const PageOrUndefined = z.number().int().nullable(); /** * The number of results to return per page. The default is 20. */ +export const PageSizeOrUndefined = lazySchema(() => z.number().int().nullable()); export type PageSizeOrUndefined = z.infer; -export const PageSizeOrUndefined = z.number().int().nullable(); /** * The field that is used to sort the results. */ +export const SortOrUndefined = lazySchema(() => z.string().nullable().default('createdAt')); export type SortOrUndefined = z.infer; -export const SortOrUndefined = z.string().nullable().default('createdAt'); /** * Specifies the sort order. */ +export const SortOrderOrUndefined = lazySchema(() => z.enum(['asc', 'desc'])); export type SortOrderOrUndefined = z.infer; -export const SortOrderOrUndefined = z.enum(['asc', 'desc']); export type SortOrderOrUndefinedEnum = typeof SortOrderOrUndefined.enum; export const SortOrderOrUndefinedEnum = SortOrderOrUndefined.enum; /** * An object with shard configuration for policies included in the pack. For each policy, set the shard configuration to a percentage (1–100) of target hosts. */ +export const Shards = lazySchema(() => z.object({}).catchall(z.number())); export type Shards = z.infer; -export const Shards = z.object({}).catchall(z.number()); +export const DefaultSuccessResponse = lazySchema(() => z.object({})); export type DefaultSuccessResponse = z.infer; -export const DefaultSuccessResponse = z.object({}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/packs/copy_pack.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/packs/copy_pack.gen.ts index 61de4ca6e3a65..0db865ff3145e 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/packs/copy_pack.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/packs/copy_pack.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PackName, @@ -27,55 +27,57 @@ import { /** * The response for copying a pack. */ +export const CopyPacksResponse = lazySchema(() => + z.object({ + data: z.object({ + /** + * The saved object ID of the copied pack. + */ + saved_object_id: z.string(), + name: PackName, + description: PackDescriptionOrUndefined.optional(), + /** + * Pack queries in saved-object storage format (array). Note: the read endpoint returns object format. + */ + queries: z + .array( + z.object({ + id: z.string().optional(), + query: z.string().optional(), + interval: z.number().int().optional(), + platform: z.string().optional(), + version: z.string().optional(), + snapshot: z.boolean().optional(), + removed: z.boolean().optional(), + timeout: z.number().int().optional(), + ecs_mapping: ECSMappingArrayOrUndefined.optional(), + }) + ) + .optional(), + /** + * The pack version number. + */ + version: z.number().int().optional(), + enabled: EnabledOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + policy_ids: PolicyIdsOrUndefined.optional(), + /** + * Shard configuration as an array of key-value pairs. + */ + shards: z + .array( + z.object({ + key: z.string().optional(), + value: z.number().optional(), + }) + ) + .optional(), + }), + }) +); export type CopyPacksResponse = z.infer; -export const CopyPacksResponse = z.object({ - data: z.object({ - /** - * The saved object ID of the copied pack. - */ - saved_object_id: z.string(), - name: PackName, - description: PackDescriptionOrUndefined.optional(), - /** - * Pack queries in saved-object storage format (array). Note: the read endpoint returns object format. - */ - queries: z - .array( - z.object({ - id: z.string().optional(), - query: z.string().optional(), - interval: z.number().int().optional(), - platform: z.string().optional(), - version: z.string().optional(), - snapshot: z.boolean().optional(), - removed: z.boolean().optional(), - timeout: z.number().int().optional(), - ecs_mapping: ECSMappingArrayOrUndefined.optional(), - }) - ) - .optional(), - /** - * The pack version number. - */ - version: z.number().int().optional(), - enabled: EnabledOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - policy_ids: PolicyIdsOrUndefined.optional(), - /** - * Shard configuration as an array of key-value pairs. - */ - shards: z - .array( - z.object({ - key: z.string().optional(), - value: z.number().optional(), - }) - ) - .optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/packs/create_pack.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/packs/create_pack.gen.ts index 969e476a75c8d..f9dcfa8dde8bc 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/packs/create_pack.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/packs/create_pack.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PackName, @@ -25,69 +25,73 @@ import { ObjectQueries, } from '../model/schema/common_attributes.gen'; +export const CreatePacksRequestBody = lazySchema(() => + z.object({ + name: PackName.optional(), + description: PackDescriptionOrUndefined.optional(), + enabled: EnabledOrUndefined.optional(), + policy_ids: PolicyIdsOrUndefined.optional(), + shards: Shards.optional(), + queries: ObjectQueries.optional(), + }) +); export type CreatePacksRequestBody = z.infer; -export const CreatePacksRequestBody = z.object({ - name: PackName.optional(), - description: PackDescriptionOrUndefined.optional(), - enabled: EnabledOrUndefined.optional(), - policy_ids: PolicyIdsOrUndefined.optional(), - shards: Shards.optional(), - queries: ObjectQueries.optional(), -}); /** * The response for creating a pack. */ +export const CreatePacksResponse = lazySchema(() => + z.object({ + data: z.object({ + /** + * The saved object ID of the pack. + */ + saved_object_id: z.string(), + name: PackName, + description: PackDescriptionOrUndefined.optional(), + queries: ObjectQueries.optional(), + /** + * The pack version number. + */ + version: z.number().int().optional(), + enabled: EnabledOrUndefined.optional(), + /** + * The date and time the pack was created. + */ + created_at: z.string().datetime().optional(), + /** + * The user who created the pack. + */ + created_by: z.string().nullable().optional(), + /** + * The profile UID of the user who created the pack. + */ + created_by_profile_uid: z.string().optional(), + /** + * The date and time the pack was last updated. + */ + updated_at: z.string().datetime().optional(), + /** + * The user who last updated the pack. + */ + updated_by: z.string().nullable().optional(), + /** + * The profile UID of the user who last updated the pack. + */ + updated_by_profile_uid: z.string().optional(), + policy_ids: PolicyIdsOrUndefined.optional(), + /** + * Shard configuration as an array of key-value pairs. + */ + shards: z + .array( + z.object({ + key: z.string().optional(), + value: z.number().optional(), + }) + ) + .optional(), + }), + }) +); export type CreatePacksResponse = z.infer; -export const CreatePacksResponse = z.object({ - data: z.object({ - /** - * The saved object ID of the pack. - */ - saved_object_id: z.string(), - name: PackName, - description: PackDescriptionOrUndefined.optional(), - queries: ObjectQueries.optional(), - /** - * The pack version number. - */ - version: z.number().int().optional(), - enabled: EnabledOrUndefined.optional(), - /** - * The date and time the pack was created. - */ - created_at: z.string().datetime().optional(), - /** - * The user who created the pack. - */ - created_by: z.string().nullable().optional(), - /** - * The profile UID of the user who created the pack. - */ - created_by_profile_uid: z.string().optional(), - /** - * The date and time the pack was last updated. - */ - updated_at: z.string().datetime().optional(), - /** - * The user who last updated the pack. - */ - updated_by: z.string().nullable().optional(), - /** - * The profile UID of the user who last updated the pack. - */ - updated_by_profile_uid: z.string().optional(), - policy_ids: PolicyIdsOrUndefined.optional(), - /** - * Shard configuration as an array of key-value pairs. - */ - shards: z - .array( - z.object({ - key: z.string().optional(), - value: z.number().optional(), - }) - ) - .optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/packs/find_packs.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/packs/find_packs.gen.ts index 44a656ebd7502..d04ac628ca1a4 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/packs/find_packs.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/packs/find_packs.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PackName, @@ -29,49 +29,87 @@ import { /** * A paginated list of query packs. */ +export const FindPacksResponse = lazySchema(() => + z.object({ + /** + * The current page number. + */ + page: z.number().int(), + /** + * The number of results per page. + */ + per_page: z.number().int(), + /** + * The total number of packs. + */ + total: z.number().int(), + /** + * An array of pack objects. + */ + data: z.array( + z.object({ + /** + * The saved object ID of the pack. + */ + saved_object_id: z.string(), + name: PackName, + description: PackDescriptionOrUndefined.optional(), + /** + * Pack queries in saved-object storage format (array). Note: the read endpoint returns object format. + */ + queries: z + .array( + z.object({ + id: z.string().optional(), + query: z.string().optional(), + interval: z.number().int().optional(), + platform: z.string().optional(), + version: z.string().optional(), + snapshot: z.boolean().optional(), + removed: z.boolean().optional(), + timeout: z.number().int().optional(), + ecs_mapping: ECSMappingArrayOrUndefined.optional(), + }) + ) + .optional(), + /** + * The pack version number. + */ + version: z.number().int().optional(), + enabled: EnabledOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + policy_ids: PolicyIdsOrUndefined.optional(), + /** + * Whether the pack is read-only (true for prebuilt packs). + */ + read_only: z.boolean().optional(), + }) + ), + }) +); export type FindPacksResponse = z.infer; -export const FindPacksResponse = z.object({ - /** - * The current page number. - */ - page: z.number().int(), - /** - * The number of results per page. - */ - per_page: z.number().int(), - /** - * The total number of packs. - */ - total: z.number().int(), - /** - * An array of pack objects. - */ - data: z.array( - z.object({ + +/** + * The details of a single query pack. + */ +export const FindPackResponse = lazySchema(() => + z.object({ + /** + * The pack details. + */ + data: z.object({ /** * The saved object ID of the pack. */ saved_object_id: z.string(), name: PackName, description: PackDescriptionOrUndefined.optional(), - /** - * Pack queries in saved-object storage format (array). Note: the read endpoint returns object format. - */ - queries: z - .array( - z.object({ - id: z.string().optional(), - query: z.string().optional(), - interval: z.number().int().optional(), - platform: z.string().optional(), - version: z.string().optional(), - snapshot: z.boolean().optional(), - removed: z.boolean().optional(), - timeout: z.number().int().optional(), - ecs_mapping: ECSMappingArrayOrUndefined.optional(), - }) - ) - .optional(), + queries: ObjectQueries.optional(), /** * The pack version number. */ @@ -84,54 +122,20 @@ export const FindPacksResponse = z.object({ updated_by: z.string().nullable().optional(), updated_by_profile_uid: z.string().optional(), policy_ids: PolicyIdsOrUndefined.optional(), + shards: Shards.optional(), /** * Whether the pack is read-only (true for prebuilt packs). */ read_only: z.boolean().optional(), - }) - ), -}); - -/** - * The details of a single query pack. - */ + /** + * The saved object type. + */ + type: z.string().optional(), + /** + * The namespaces the pack belongs to. + */ + namespaces: z.array(z.string()).optional(), + }), + }) +); export type FindPackResponse = z.infer; -export const FindPackResponse = z.object({ - /** - * The pack details. - */ - data: z.object({ - /** - * The saved object ID of the pack. - */ - saved_object_id: z.string(), - name: PackName, - description: PackDescriptionOrUndefined.optional(), - queries: ObjectQueries.optional(), - /** - * The pack version number. - */ - version: z.number().int().optional(), - enabled: EnabledOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - policy_ids: PolicyIdsOrUndefined.optional(), - shards: Shards.optional(), - /** - * Whether the pack is read-only (true for prebuilt packs). - */ - read_only: z.boolean().optional(), - /** - * The saved object type. - */ - type: z.string().optional(), - /** - * The namespaces the pack belongs to. - */ - namespaces: z.array(z.string()).optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/packs/packs.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/packs/packs.gen.ts index ca174688a36fd..693c5364a39e6 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/packs/packs.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/packs/packs.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PageOrUndefined, @@ -28,88 +28,98 @@ import { CreatePacksRequestBody, CreatePacksResponse } from './create_pack.gen'; import { UpdatePacksRequestBody, UpdatePacksResponse } from './update_packs.gen'; import { CopyPacksResponse } from './copy_pack.gen'; +export const OsqueryCopyPacksRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the pack to copy. + */ + id: PackId, + }) +); export type OsqueryCopyPacksRequestParams = z.infer; -export const OsqueryCopyPacksRequestParams = z.object({ - /** - * The ID of the pack to copy. - */ - id: PackId, -}); export type OsqueryCopyPacksRequestParamsInput = z.input; +export const OsqueryCopyPacksResponse = lazySchema(() => CopyPacksResponse); export type OsqueryCopyPacksResponse = z.infer; -export const OsqueryCopyPacksResponse = CopyPacksResponse; +export const OsqueryCreatePacksRequestBody = lazySchema(() => CreatePacksRequestBody); export type OsqueryCreatePacksRequestBody = z.infer; -export const OsqueryCreatePacksRequestBody = CreatePacksRequestBody; export type OsqueryCreatePacksRequestBodyInput = z.input; +export const OsqueryCreatePacksResponse = lazySchema(() => CreatePacksResponse); export type OsqueryCreatePacksResponse = z.infer; -export const OsqueryCreatePacksResponse = CreatePacksResponse; +export const OsqueryDeletePacksRequestParams = lazySchema(() => + z.object({ + /** + * The pack ID. + */ + id: PackId, + }) +); export type OsqueryDeletePacksRequestParams = z.infer; -export const OsqueryDeletePacksRequestParams = z.object({ - /** - * The pack ID. - */ - id: PackId, -}); export type OsqueryDeletePacksRequestParamsInput = z.input; +export const OsqueryDeletePacksResponse = lazySchema(() => z.object({})); export type OsqueryDeletePacksResponse = z.infer; -export const OsqueryDeletePacksResponse = z.object({}); +export const OsqueryFindPacksRequestQuery = lazySchema(() => + z.object({ + /** + * The page number to return. + */ + page: PageOrUndefined.optional(), + /** + * The number of results to return per page. + */ + pageSize: PageSizeOrUndefined.optional(), + /** + * The field to sort results by. + */ + sort: SortOrUndefined.optional(), + /** + * The sort order. + */ + sortOrder: SortOrderOrUndefined.optional(), + }) +); export type OsqueryFindPacksRequestQuery = z.infer; -export const OsqueryFindPacksRequestQuery = z.object({ - /** - * The page number to return. - */ - page: PageOrUndefined.optional(), - /** - * The number of results to return per page. - */ - pageSize: PageSizeOrUndefined.optional(), - /** - * The field to sort results by. - */ - sort: SortOrUndefined.optional(), - /** - * The sort order. - */ - sortOrder: SortOrderOrUndefined.optional(), -}); export type OsqueryFindPacksRequestQueryInput = z.input; +export const OsqueryFindPacksResponse = lazySchema(() => FindPacksResponse); export type OsqueryFindPacksResponse = z.infer; -export const OsqueryFindPacksResponse = FindPacksResponse; +export const OsqueryGetPacksDetailsRequestParams = lazySchema(() => + z.object({ + /** + * The pack ID. + */ + id: PackId, + }) +); export type OsqueryGetPacksDetailsRequestParams = z.infer< typeof OsqueryGetPacksDetailsRequestParams >; -export const OsqueryGetPacksDetailsRequestParams = z.object({ - /** - * The pack ID. - */ - id: PackId, -}); export type OsqueryGetPacksDetailsRequestParamsInput = z.input< typeof OsqueryGetPacksDetailsRequestParams >; +export const OsqueryGetPacksDetailsResponse = lazySchema(() => FindPackResponse); export type OsqueryGetPacksDetailsResponse = z.infer; -export const OsqueryGetPacksDetailsResponse = FindPackResponse; +export const OsqueryUpdatePacksRequestParams = lazySchema(() => + z.object({ + /** + * The pack ID. + */ + id: PackId, + }) +); export type OsqueryUpdatePacksRequestParams = z.infer; -export const OsqueryUpdatePacksRequestParams = z.object({ - /** - * The pack ID. - */ - id: PackId, -}); export type OsqueryUpdatePacksRequestParamsInput = z.input; +export const OsqueryUpdatePacksRequestBody = lazySchema(() => UpdatePacksRequestBody); export type OsqueryUpdatePacksRequestBody = z.infer; -export const OsqueryUpdatePacksRequestBody = UpdatePacksRequestBody; export type OsqueryUpdatePacksRequestBodyInput = z.input; +export const OsqueryUpdatePacksResponse = lazySchema(() => UpdatePacksResponse); export type OsqueryUpdatePacksResponse = z.infer; -export const OsqueryUpdatePacksResponse = UpdatePacksResponse; diff --git a/x-pack/platform/plugins/shared/osquery/common/api/packs/update_packs.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/packs/update_packs.gen.ts index e5982a6917bad..c2a701ed126ae 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/packs/update_packs.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/packs/update_packs.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PackName, @@ -25,43 +25,47 @@ import { ObjectQueries, } from '../model/schema/common_attributes.gen'; +export const UpdatePacksRequestBody = lazySchema(() => + z.object({ + name: PackName.optional(), + description: PackDescriptionOrUndefined.optional(), + enabled: EnabledOrUndefined.optional(), + policy_ids: PolicyIdsOrUndefined.optional(), + shards: Shards.optional(), + queries: ObjectQueries.optional(), + }) +); export type UpdatePacksRequestBody = z.infer; -export const UpdatePacksRequestBody = z.object({ - name: PackName.optional(), - description: PackDescriptionOrUndefined.optional(), - enabled: EnabledOrUndefined.optional(), - policy_ids: PolicyIdsOrUndefined.optional(), - shards: Shards.optional(), - queries: ObjectQueries.optional(), -}); /** * The response for updating a pack. */ +export const UpdatePacksResponse = lazySchema(() => + z.object({ + data: z + .object({ + /** + * The saved object ID of the pack. + */ + saved_object_id: z.string().optional(), + name: PackName.optional(), + description: PackDescriptionOrUndefined.optional(), + queries: ObjectQueries.optional(), + /** + * The pack version number. + */ + version: z.number().int().optional(), + enabled: EnabledOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + policy_ids: PolicyIdsOrUndefined.optional(), + shards: Shards.optional(), + }) + .optional(), + }) +); export type UpdatePacksResponse = z.infer; -export const UpdatePacksResponse = z.object({ - data: z - .object({ - /** - * The saved object ID of the pack. - */ - saved_object_id: z.string().optional(), - name: PackName.optional(), - description: PackDescriptionOrUndefined.optional(), - queries: ObjectQueries.optional(), - /** - * The pack version number. - */ - version: z.number().int().optional(), - enabled: EnabledOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - policy_ids: PolicyIdsOrUndefined.optional(), - shards: Shards.optional(), - }) - .optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/copy_saved_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/copy_saved_query.gen.ts index 8282e431c703c..c0b90caaf361b 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/copy_saved_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/copy_saved_query.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedQueryId, @@ -29,24 +29,26 @@ import { /** * The response for copying a saved query. */ +export const CopySavedQueryResponse = lazySchema(() => + z.object({ + data: z.object({ + saved_object_id: z.string(), + id: SavedQueryId, + description: SavedQueryDescriptionOrUndefined.optional(), + query: Query.optional(), + interval: z.union([z.number().int(), z.string()]).optional(), + timeout: z.number().int().optional(), + snapshot: SnapshotOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + }), + }) +); export type CopySavedQueryResponse = z.infer; -export const CopySavedQueryResponse = z.object({ - data: z.object({ - saved_object_id: z.string(), - id: SavedQueryId, - description: SavedQueryDescriptionOrUndefined.optional(), - query: Query.optional(), - interval: z.union([z.number().int(), z.string()]).optional(), - timeout: z.number().int().optional(), - snapshot: SnapshotOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/create_saved_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/create_saved_query.gen.ts index 17f01b68e96f9..42e703d2e836a 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/create_saved_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/create_saved_query.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedQueryId, @@ -29,57 +29,61 @@ import { Query, } from '../model/schema/common_attributes.gen'; +export const CreateSavedQueryRequestBody = lazySchema(() => + z.object({ + id: SavedQueryId.optional(), + description: SavedQueryDescriptionOrUndefined.optional(), + query: QueryOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + version: VersionOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + interval: Interval.optional(), + snapshot: SnapshotOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + }) +); export type CreateSavedQueryRequestBody = z.infer; -export const CreateSavedQueryRequestBody = z.object({ - id: SavedQueryId.optional(), - description: SavedQueryDescriptionOrUndefined.optional(), - query: QueryOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - version: VersionOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - interval: Interval.optional(), - snapshot: SnapshotOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), -}); /** * The response for creating a saved query. */ +export const CreateSavedQueryResponse = lazySchema(() => + z.object({ + data: z.object({ + /** + * The saved object ID of the saved query. + */ + saved_object_id: z.string(), + id: SavedQueryId, + description: SavedQueryDescriptionOrUndefined.optional(), + query: Query.optional(), + /** + * An interval, in seconds, on which to run the query. May be returned as number or string. + */ + interval: z.union([z.number().int(), z.string()]).optional(), + /** + * The query timeout in seconds. + */ + timeout: z.number().int().optional(), + snapshot: SnapshotOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + /** + * Whether the saved query is prebuilt. + */ + prebuilt: z.boolean().optional(), + /** + * The saved query version. + */ + version: z.union([z.number().int(), z.string()]).optional(), + }), + }) +); export type CreateSavedQueryResponse = z.infer; -export const CreateSavedQueryResponse = z.object({ - data: z.object({ - /** - * The saved object ID of the saved query. - */ - saved_object_id: z.string(), - id: SavedQueryId, - description: SavedQueryDescriptionOrUndefined.optional(), - query: Query.optional(), - /** - * An interval, in seconds, on which to run the query. May be returned as number or string. - */ - interval: z.union([z.number().int(), z.string()]).optional(), - /** - * The query timeout in seconds. - */ - timeout: z.number().int().optional(), - snapshot: SnapshotOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - /** - * Whether the saved query is prebuilt. - */ - prebuilt: z.boolean().optional(), - /** - * The saved query version. - */ - version: z.union([z.number().int(), z.string()]).optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/find_saved_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/find_saved_query.gen.ts index ce11f384ca67a..8c4fffcbdcea4 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/find_saved_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/find_saved_query.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedQueryId, @@ -29,25 +29,55 @@ import { /** * A paginated list of saved queries. */ +export const FindSavedQueryResponse = lazySchema(() => + z.object({ + /** + * The current page number. + */ + page: z.number().int(), + /** + * The number of results per page. + */ + per_page: z.number().int(), + /** + * The total number of saved queries. + */ + total: z.number().int(), + /** + * An array of saved query objects. + */ + data: z.array( + z.object({ + saved_object_id: z.string(), + id: SavedQueryId, + description: SavedQueryDescriptionOrUndefined.optional(), + query: Query.optional(), + interval: z.union([z.number().int(), z.string()]).optional(), + timeout: z.number().int().optional(), + snapshot: SnapshotOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + prebuilt: z.boolean().optional(), + version: z.union([z.number().int(), z.string()]).optional(), + }) + ), + }) +); export type FindSavedQueryResponse = z.infer; -export const FindSavedQueryResponse = z.object({ - /** - * The current page number. - */ - page: z.number().int(), - /** - * The number of results per page. - */ - per_page: z.number().int(), - /** - * The total number of saved queries. - */ - total: z.number().int(), - /** - * An array of saved query objects. - */ - data: z.array( - z.object({ + +/** + * The details of a single saved query. + */ +export const FindSavedQueryDetailResponse = lazySchema(() => + z.object({ + data: z.object({ saved_object_id: z.string(), id: SavedQueryId, description: SavedQueryDescriptionOrUndefined.optional(), @@ -66,33 +96,7 @@ export const FindSavedQueryResponse = z.object({ updated_by_profile_uid: z.string().optional(), prebuilt: z.boolean().optional(), version: z.union([z.number().int(), z.string()]).optional(), - }) - ), -}); - -/** - * The details of a single saved query. - */ + }), + }) +); export type FindSavedQueryDetailResponse = z.infer; -export const FindSavedQueryDetailResponse = z.object({ - data: z.object({ - saved_object_id: z.string(), - id: SavedQueryId, - description: SavedQueryDescriptionOrUndefined.optional(), - query: Query.optional(), - interval: z.union([z.number().int(), z.string()]).optional(), - timeout: z.number().int().optional(), - snapshot: SnapshotOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - prebuilt: z.boolean().optional(), - version: z.union([z.number().int(), z.string()]).optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/saved_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/saved_query.gen.ts index fb4c62cff6668..67c4524da8332 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/saved_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/saved_query.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PageOrUndefined, @@ -29,108 +29,118 @@ import { CreateSavedQueryRequestBody, CreateSavedQueryResponse } from './create_ import { UpdateSavedQueryRequestBody, UpdateSavedQueryResponse } from './update_saved_query.gen'; import { CopySavedQueryResponse } from './copy_saved_query.gen'; +export const OsqueryCopySavedQueryRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the saved query to copy. + */ + id: SavedQueryId, + }) +); export type OsqueryCopySavedQueryRequestParams = z.infer; -export const OsqueryCopySavedQueryRequestParams = z.object({ - /** - * The ID of the saved query to copy. - */ - id: SavedQueryId, -}); export type OsqueryCopySavedQueryRequestParamsInput = z.input< typeof OsqueryCopySavedQueryRequestParams >; +export const OsqueryCopySavedQueryResponse = lazySchema(() => CopySavedQueryResponse); export type OsqueryCopySavedQueryResponse = z.infer; -export const OsqueryCopySavedQueryResponse = CopySavedQueryResponse; +export const OsqueryCreateSavedQueryRequestBody = lazySchema(() => CreateSavedQueryRequestBody); export type OsqueryCreateSavedQueryRequestBody = z.infer; -export const OsqueryCreateSavedQueryRequestBody = CreateSavedQueryRequestBody; export type OsqueryCreateSavedQueryRequestBodyInput = z.input< typeof OsqueryCreateSavedQueryRequestBody >; +export const OsqueryCreateSavedQueryResponse = lazySchema(() => CreateSavedQueryResponse); export type OsqueryCreateSavedQueryResponse = z.infer; -export const OsqueryCreateSavedQueryResponse = CreateSavedQueryResponse; +export const OsqueryDeleteSavedQueryRequestParams = lazySchema(() => + z.object({ + /** + * The saved query ID. + */ + id: SavedQueryId, + }) +); export type OsqueryDeleteSavedQueryRequestParams = z.infer< typeof OsqueryDeleteSavedQueryRequestParams >; -export const OsqueryDeleteSavedQueryRequestParams = z.object({ - /** - * The saved query ID. - */ - id: SavedQueryId, -}); export type OsqueryDeleteSavedQueryRequestParamsInput = z.input< typeof OsqueryDeleteSavedQueryRequestParams >; +export const OsqueryDeleteSavedQueryResponse = lazySchema(() => DefaultSuccessResponse); export type OsqueryDeleteSavedQueryResponse = z.infer; -export const OsqueryDeleteSavedQueryResponse = DefaultSuccessResponse; +export const OsqueryFindSavedQueriesRequestQuery = lazySchema(() => + z.object({ + /** + * The page number to return. + */ + page: PageOrUndefined.optional(), + /** + * The number of results to return per page. + */ + pageSize: PageSizeOrUndefined.optional(), + /** + * The field to sort results by. + */ + sort: SortOrUndefined.optional(), + /** + * The sort order. + */ + sortOrder: SortOrderOrUndefined.optional(), + }) +); export type OsqueryFindSavedQueriesRequestQuery = z.infer< typeof OsqueryFindSavedQueriesRequestQuery >; -export const OsqueryFindSavedQueriesRequestQuery = z.object({ - /** - * The page number to return. - */ - page: PageOrUndefined.optional(), - /** - * The number of results to return per page. - */ - pageSize: PageSizeOrUndefined.optional(), - /** - * The field to sort results by. - */ - sort: SortOrUndefined.optional(), - /** - * The sort order. - */ - sortOrder: SortOrderOrUndefined.optional(), -}); export type OsqueryFindSavedQueriesRequestQueryInput = z.input< typeof OsqueryFindSavedQueriesRequestQuery >; +export const OsqueryFindSavedQueriesResponse = lazySchema(() => FindSavedQueryResponse); export type OsqueryFindSavedQueriesResponse = z.infer; -export const OsqueryFindSavedQueriesResponse = FindSavedQueryResponse; +export const OsqueryGetSavedQueryDetailsRequestParams = lazySchema(() => + z.object({ + /** + * The saved query ID. + */ + id: SavedQueryId, + }) +); export type OsqueryGetSavedQueryDetailsRequestParams = z.infer< typeof OsqueryGetSavedQueryDetailsRequestParams >; -export const OsqueryGetSavedQueryDetailsRequestParams = z.object({ - /** - * The saved query ID. - */ - id: SavedQueryId, -}); export type OsqueryGetSavedQueryDetailsRequestParamsInput = z.input< typeof OsqueryGetSavedQueryDetailsRequestParams >; +export const OsqueryGetSavedQueryDetailsResponse = lazySchema(() => FindSavedQueryDetailResponse); export type OsqueryGetSavedQueryDetailsResponse = z.infer< typeof OsqueryGetSavedQueryDetailsResponse >; -export const OsqueryGetSavedQueryDetailsResponse = FindSavedQueryDetailResponse; +export const OsqueryUpdateSavedQueryRequestParams = lazySchema(() => + z.object({ + /** + * The saved query ID. + */ + id: SavedQueryId, + }) +); export type OsqueryUpdateSavedQueryRequestParams = z.infer< typeof OsqueryUpdateSavedQueryRequestParams >; -export const OsqueryUpdateSavedQueryRequestParams = z.object({ - /** - * The saved query ID. - */ - id: SavedQueryId, -}); export type OsqueryUpdateSavedQueryRequestParamsInput = z.input< typeof OsqueryUpdateSavedQueryRequestParams >; +export const OsqueryUpdateSavedQueryRequestBody = lazySchema(() => UpdateSavedQueryRequestBody); export type OsqueryUpdateSavedQueryRequestBody = z.infer; -export const OsqueryUpdateSavedQueryRequestBody = UpdateSavedQueryRequestBody; export type OsqueryUpdateSavedQueryRequestBodyInput = z.input< typeof OsqueryUpdateSavedQueryRequestBody >; +export const OsqueryUpdateSavedQueryResponse = lazySchema(() => UpdateSavedQueryResponse); export type OsqueryUpdateSavedQueryResponse = z.infer; -export const OsqueryUpdateSavedQueryResponse = UpdateSavedQueryResponse; diff --git a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/update_saved_query.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/update_saved_query.gen.ts index 96f86be8314d7..2ba7eb4393879 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/saved_query/update_saved_query.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/saved_query/update_saved_query.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedQueryId, @@ -29,45 +29,49 @@ import { Query, } from '../model/schema/common_attributes.gen'; +export const UpdateSavedQueryRequestBody = lazySchema(() => + z.object({ + id: SavedQueryId.optional(), + description: SavedQueryDescriptionOrUndefined.optional(), + query: QueryOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + version: VersionOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + interval: IntervalOrUndefined.optional(), + snapshot: SnapshotOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + }) +); export type UpdateSavedQueryRequestBody = z.infer; -export const UpdateSavedQueryRequestBody = z.object({ - id: SavedQueryId.optional(), - description: SavedQueryDescriptionOrUndefined.optional(), - query: QueryOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - version: VersionOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - interval: IntervalOrUndefined.optional(), - snapshot: SnapshotOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), -}); /** * The response for updating a saved query. */ +export const UpdateSavedQueryResponse = lazySchema(() => + z.object({ + data: z.object({ + saved_object_id: z.string(), + id: SavedQueryId, + description: SavedQueryDescriptionOrUndefined.optional(), + query: Query.optional(), + interval: z.union([z.number().int(), z.string()]).optional(), + timeout: z.number().int().optional(), + snapshot: SnapshotOrUndefined.optional(), + removed: RemovedOrUndefined.optional(), + platform: PlatformOrUndefined.optional(), + ecs_mapping: ECSMappingOrUndefined.optional(), + created_at: z.string().datetime().optional(), + created_by: z.string().nullable().optional(), + created_by_profile_uid: z.string().optional(), + updated_at: z.string().datetime().optional(), + updated_by: z.string().nullable().optional(), + updated_by_profile_uid: z.string().optional(), + prebuilt: z.boolean().optional(), + /** + * The saved query version. + */ + version: z.string().optional(), + }), + }) +); export type UpdateSavedQueryResponse = z.infer; -export const UpdateSavedQueryResponse = z.object({ - data: z.object({ - saved_object_id: z.string(), - id: SavedQueryId, - description: SavedQueryDescriptionOrUndefined.optional(), - query: Query.optional(), - interval: z.union([z.number().int(), z.string()]).optional(), - timeout: z.number().int().optional(), - snapshot: SnapshotOrUndefined.optional(), - removed: RemovedOrUndefined.optional(), - platform: PlatformOrUndefined.optional(), - ecs_mapping: ECSMappingOrUndefined.optional(), - created_at: z.string().datetime().optional(), - created_by: z.string().nullable().optional(), - created_by_profile_uid: z.string().optional(), - updated_at: z.string().datetime().optional(), - updated_by: z.string().nullable().optional(), - updated_by_profile_uid: z.string().optional(), - prebuilt: z.boolean().optional(), - /** - * The saved query version. - */ - version: z.string().optional(), - }), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_action_results.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_action_results.gen.ts index 8ead460f5f114..c91fa742a9307 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_action_results.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_action_results.gen.ts @@ -14,93 +14,99 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Execution metadata resolved from the pack saved object. */ +export const ScheduledExecutionMetadata = lazySchema(() => + z.object({ + /** + * The schedule ID for the scheduled query. + */ + scheduleId: z.string().optional(), + /** + * The execution count for this scheduled query run. + */ + executionCount: z.number().int().optional(), + /** + * The ID of the pack containing the query. + */ + packId: z.string().optional(), + /** + * The name of the pack containing the query. + */ + packName: z.string().optional(), + /** + * The name of the query within the pack. + */ + queryName: z.string().optional(), + /** + * The SQL query that was executed. + */ + queryText: z.string().optional(), + /** + * The timestamp of the most recent response for this execution. + */ + timestamp: z.string().optional(), + }) +); export type ScheduledExecutionMetadata = z.infer; -export const ScheduledExecutionMetadata = z.object({ - /** - * The schedule ID for the scheduled query. - */ - scheduleId: z.string().optional(), - /** - * The execution count for this scheduled query run. - */ - executionCount: z.number().int().optional(), - /** - * The ID of the pack containing the query. - */ - packId: z.string().optional(), - /** - * The name of the pack containing the query. - */ - packName: z.string().optional(), - /** - * The name of the query within the pack. - */ - queryName: z.string().optional(), - /** - * The SQL query that was executed. - */ - queryText: z.string().optional(), - /** - * The timestamp of the most recent response for this execution. - */ - timestamp: z.string().optional(), -}); +export const ScheduledActionResultsAggregations = lazySchema(() => + z.object({ + /** + * The total number of result rows across all agents. + */ + totalRowCount: z.number().int().optional(), + /** + * The total number of agents that responded. + */ + totalResponded: z.number().int().optional(), + /** + * The number of agents that completed successfully. + */ + successful: z.number().int().optional(), + /** + * The number of agents that returned errors. + */ + failed: z.number().int().optional(), + /** + * The number of agents with pending responses. + */ + pending: z.number().int().optional(), + }) +); export type ScheduledActionResultsAggregations = z.infer; -export const ScheduledActionResultsAggregations = z.object({ - /** - * The total number of result rows across all agents. - */ - totalRowCount: z.number().int().optional(), - /** - * The total number of agents that responded. - */ - totalResponded: z.number().int().optional(), - /** - * The number of agents that completed successfully. - */ - successful: z.number().int().optional(), - /** - * The number of agents that returned errors. - */ - failed: z.number().int().optional(), - /** - * The number of agents with pending responses. - */ - pending: z.number().int().optional(), -}); +export const GetScheduledActionResultsResponse = lazySchema(() => + z.object({ + metadata: ScheduledExecutionMetadata.optional(), + /** + * The paginated list of per-agent action results. + */ + edges: z.array(z.object({})).optional(), + /** + * The total number of action results. + */ + total: z.number().int().optional(), + /** + * The current page number (zero-based). + */ + currentPage: z.number().int().optional(), + /** + * The number of results per page. + */ + pageSize: z.number().int().optional(), + /** + * The total number of pages. + */ + totalPages: z.number().int().optional(), + aggregations: ScheduledActionResultsAggregations.optional(), + /** + * Debug/inspection data for the search query. + */ + inspect: z.object({}).optional(), + }) +); export type GetScheduledActionResultsResponse = z.infer; -export const GetScheduledActionResultsResponse = z.object({ - metadata: ScheduledExecutionMetadata.optional(), - /** - * The paginated list of per-agent action results. - */ - edges: z.array(z.object({})).optional(), - /** - * The total number of action results. - */ - total: z.number().int().optional(), - /** - * The current page number (zero-based). - */ - currentPage: z.number().int().optional(), - /** - * The number of results per page. - */ - pageSize: z.number().int().optional(), - /** - * The total number of pages. - */ - totalPages: z.number().int().optional(), - aggregations: ScheduledActionResultsAggregations.optional(), - /** - * Debug/inspection data for the search query. - */ - inspect: z.object({}).optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_query_results.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_query_results.gen.ts index 4eefe85bc5e5a..db454850c0122 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_query_results.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/get_scheduled_query_results.gen.ts @@ -14,30 +14,32 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The response for getting scheduled query results. */ +export const GetScheduledQueryResultsResponse = lazySchema(() => + z.object({ + /** + * The query results data wrapper. + */ + data: z + .object({ + /** + * The paginated list of query result rows. + */ + edges: z.array(z.object({})).optional(), + /** + * The total number of result rows. + */ + total: z.number().int().optional(), + /** + * Debug/inspection data for the search query. + */ + inspect: z.object({}).optional(), + }) + .optional(), + }) +); export type GetScheduledQueryResultsResponse = z.infer; -export const GetScheduledQueryResultsResponse = z.object({ - /** - * The query results data wrapper. - */ - data: z - .object({ - /** - * The paginated list of query result rows. - */ - edges: z.array(z.object({})).optional(), - /** - * The total number of result rows. - */ - total: z.number().int().optional(), - /** - * Debug/inspection data for the search query. - */ - inspect: z.object({}).optional(), - }) - .optional(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/scheduled_results.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/scheduled_results.gen.ts index a1a04b5ff8a34..869e0e499746b 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/scheduled_results.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/scheduled_results.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { KueryOrUndefined, @@ -26,107 +26,119 @@ import { import { GetScheduledActionResultsResponse } from './get_scheduled_action_results.gen'; import { GetScheduledQueryResultsResponse } from './get_scheduled_query_results.gen'; +export const OsqueryGetScheduledActionResultsRequestQuery = lazySchema(() => + z.object({ + /** + * The kuery to filter the results by. + */ + kuery: KueryOrUndefined.optional(), + /** + * The page number to return. The default is 1. + */ + page: PageOrUndefined.optional(), + /** + * The number of results to return per page. The default is 20. + */ + pageSize: PageSizeOrUndefined.optional(), + /** + * The field that is used to sort the results. + */ + sort: SortOrUndefined.optional(), + /** + * Specifies the sort order. + */ + sortOrder: SortOrderOrUndefined.optional(), + }) +); export type OsqueryGetScheduledActionResultsRequestQuery = z.infer< typeof OsqueryGetScheduledActionResultsRequestQuery >; -export const OsqueryGetScheduledActionResultsRequestQuery = z.object({ - /** - * The kuery to filter the results by. - */ - kuery: KueryOrUndefined.optional(), - /** - * The page number to return. The default is 1. - */ - page: PageOrUndefined.optional(), - /** - * The number of results to return per page. The default is 20. - */ - pageSize: PageSizeOrUndefined.optional(), - /** - * The field that is used to sort the results. - */ - sort: SortOrUndefined.optional(), - /** - * Specifies the sort order. - */ - sortOrder: SortOrderOrUndefined.optional(), -}); export type OsqueryGetScheduledActionResultsRequestQueryInput = z.input< typeof OsqueryGetScheduledActionResultsRequestQuery >; +export const OsqueryGetScheduledActionResultsRequestParams = lazySchema(() => + z.object({ + /** + * The schedule ID of the scheduled query. + */ + scheduleId: z.string(), + /** + * The execution count for this scheduled query run. + */ + executionCount: z.number().int(), + }) +); export type OsqueryGetScheduledActionResultsRequestParams = z.infer< typeof OsqueryGetScheduledActionResultsRequestParams >; -export const OsqueryGetScheduledActionResultsRequestParams = z.object({ - /** - * The schedule ID of the scheduled query. - */ - scheduleId: z.string(), - /** - * The execution count for this scheduled query run. - */ - executionCount: z.number().int(), -}); export type OsqueryGetScheduledActionResultsRequestParamsInput = z.input< typeof OsqueryGetScheduledActionResultsRequestParams >; +export const OsqueryGetScheduledActionResultsResponse = lazySchema( + () => GetScheduledActionResultsResponse +); export type OsqueryGetScheduledActionResultsResponse = z.infer< typeof OsqueryGetScheduledActionResultsResponse >; -export const OsqueryGetScheduledActionResultsResponse = GetScheduledActionResultsResponse; +export const OsqueryGetScheduledQueryResultsRequestQuery = lazySchema(() => + z.object({ + /** + * The kuery to filter the results by. + */ + kuery: KueryOrUndefined.optional(), + /** + * The page number to return. The default is 1. + */ + page: PageOrUndefined.optional(), + /** + * The number of results to return per page. The default is 20. + */ + pageSize: PageSizeOrUndefined.optional(), + /** + * The field that is used to sort the results. + */ + sort: SortOrUndefined.optional(), + /** + * Specifies the sort order. + */ + sortOrder: SortOrderOrUndefined.optional(), + /** + * The start date filter (ISO 8601) to narrow down results. + */ + startDate: z.string().optional(), + }) +); export type OsqueryGetScheduledQueryResultsRequestQuery = z.infer< typeof OsqueryGetScheduledQueryResultsRequestQuery >; -export const OsqueryGetScheduledQueryResultsRequestQuery = z.object({ - /** - * The kuery to filter the results by. - */ - kuery: KueryOrUndefined.optional(), - /** - * The page number to return. The default is 1. - */ - page: PageOrUndefined.optional(), - /** - * The number of results to return per page. The default is 20. - */ - pageSize: PageSizeOrUndefined.optional(), - /** - * The field that is used to sort the results. - */ - sort: SortOrUndefined.optional(), - /** - * Specifies the sort order. - */ - sortOrder: SortOrderOrUndefined.optional(), - /** - * The start date filter (ISO 8601) to narrow down results. - */ - startDate: z.string().optional(), -}); export type OsqueryGetScheduledQueryResultsRequestQueryInput = z.input< typeof OsqueryGetScheduledQueryResultsRequestQuery >; +export const OsqueryGetScheduledQueryResultsRequestParams = lazySchema(() => + z.object({ + /** + * The schedule ID of the scheduled query. + */ + scheduleId: z.string(), + /** + * The execution count for this scheduled query run. + */ + executionCount: z.number().int(), + }) +); export type OsqueryGetScheduledQueryResultsRequestParams = z.infer< typeof OsqueryGetScheduledQueryResultsRequestParams >; -export const OsqueryGetScheduledQueryResultsRequestParams = z.object({ - /** - * The schedule ID of the scheduled query. - */ - scheduleId: z.string(), - /** - * The execution count for this scheduled query run. - */ - executionCount: z.number().int(), -}); export type OsqueryGetScheduledQueryResultsRequestParamsInput = z.input< typeof OsqueryGetScheduledQueryResultsRequestParams >; +export const OsqueryGetScheduledQueryResultsResponse = lazySchema( + () => GetScheduledQueryResultsResponse +); export type OsqueryGetScheduledQueryResultsResponse = z.infer< typeof OsqueryGetScheduledQueryResultsResponse >; -export const OsqueryGetScheduledQueryResultsResponse = GetScheduledQueryResultsResponse; diff --git a/x-pack/platform/plugins/shared/osquery/common/api/status/privileges_check.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/status/privileges_check.gen.ts index dba6dc7b74b55..3b0c46503c609 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/status/privileges_check.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/status/privileges_check.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ReadPrivilegesCheckResponse = lazySchema(() => z.object({})); export type ReadPrivilegesCheckResponse = z.infer; -export const ReadPrivilegesCheckResponse = z.object({}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/status/status.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/status/status.gen.ts index 1758d3047343d..6f1dd40b12ce8 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/status/status.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/status/status.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ReadInstallationStatusResponse = lazySchema(() => z.object({})); export type ReadInstallationStatusResponse = z.infer; -export const ReadInstallationStatusResponse = z.object({}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts index 4aeb598332cfd..6af8eec9dfd95 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts @@ -14,210 +14,219 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The type of history source to include. */ +export const SourceFilter = lazySchema(() => z.enum(['live', 'rule', 'scheduled'])); export type SourceFilter = z.infer; -export const SourceFilter = z.enum(['live', 'rule', 'scheduled']); export type SourceFilterEnum = typeof SourceFilter.enum; export const SourceFilterEnum = SourceFilter.enum; /** * The display label for the history source. */ +export const UnifiedHistorySource = lazySchema(() => z.enum(['Live', 'Scheduled', 'Rule'])); export type UnifiedHistorySource = z.infer; -export const UnifiedHistorySource = z.enum(['Live', 'Scheduled', 'Rule']); export type UnifiedHistorySourceEnum = typeof UnifiedHistorySource.enum; export const UnifiedHistorySourceEnum = UnifiedHistorySource.enum; -export type GetUnifiedHistoryRequestQuery = z.infer; -export const GetUnifiedHistoryRequestQuery = z.object({ - /** - * The number of results to return per page. - */ - pageSize: z.number().int().min(1).max(100).optional().default(20), - /** - * A base64-encoded cursor for pagination. Use the value from the previous response to fetch the next page. - */ - nextPage: z.string().optional(), - /** - * A search string to filter history entries by pack name, query text, or query ID. - */ - kuery: z.string().optional(), - /** - * Comma-separated list of user IDs to filter live query history. - */ - userIds: z.string().optional(), - /** - * Comma-separated list of source types to include. Valid values are `live`, `rule`, and `scheduled`. - */ - sourceFilters: z.string().optional(), - /** - * The start of the time range filter (ISO 8601). - */ - startDate: z.string().optional(), - /** - * The end of the time range filter (ISO 8601). - */ - endDate: z.string().optional(), -}); - -export type UnifiedHistoryRowBase = z.infer; -export const UnifiedHistoryRowBase = z.object({ - /** - * Unique identifier for the history row. - */ - id: z.string(), - /** - * The timestamp of the query execution. - */ - timestamp: z.string(), - /** - * The SQL query that was executed. - */ - queryText: z.string(), - /** - * The name of the query, if available. - */ - queryName: z.string().optional(), - /** - * The name of the pack containing the query. - */ - packName: z.string().optional(), - /** - * The ID of the pack containing the query. - */ - packId: z.string().optional(), - /** - * The Kibana space ID where the query was executed. - */ - spaceId: z.string().optional(), - /** - * The number of agents targeted by the query. - */ - agentCount: z.number().int(), - /** - * The number of successful agent responses. - */ - successCount: z.number().int().nullable().optional(), - /** - * The number of agent responses with errors. - */ - errorCount: z.number().int().nullable().optional(), - /** - * The total number of result rows returned across all agents. - */ - totalRows: z.number().int().nullable().optional(), -}); - -export type LiveHistoryRow = z.infer; -export const LiveHistoryRow = UnifiedHistoryRowBase.extend( +export const GetUnifiedHistoryRequestQuery = lazySchema(() => z.object({ /** - * Identifies this as a live query history row. + * The number of results to return per page. */ - sourceType: z.literal('live'), + pageSize: z.number().int().min(1).max(100).optional().default(20), /** - * Whether this was a manually run live query or triggered by a rule. + * A base64-encoded cursor for pagination. Use the value from the previous response to fetch the next page. */ - source: z.enum(['Live', 'Rule']), + nextPage: z.string().optional(), /** - * The Fleet action ID for the live query. + * A search string to filter history entries by pack name, query text, or query ID. */ - actionId: z.string().optional(), + kuery: z.string().optional(), /** - * The ID of the user who ran the query. + * Comma-separated list of user IDs to filter live query history. */ - userId: z.string().optional(), + userIds: z.string().optional(), /** - * The user profile UID of the user who ran the query. + * Comma-separated list of source types to include. Valid values are `live`, `rule`, and `scheduled`. */ - userProfileUid: z.string().optional(), + sourceFilters: z.string().optional(), /** - * The number of sub-queries that returned results. + * The start of the time range filter (ISO 8601). */ - queriesWithResults: z.number().int().optional(), + startDate: z.string().optional(), /** - * The total number of sub-queries in the live action. + * The end of the time range filter (ISO 8601). */ - queriesTotal: z.number().int().optional(), - /** - * ECS mapping configuration used for the query. - */ - ecsMapping: z.object({}).catchall(z.unknown()).optional(), + endDate: z.string().optional(), + }) +); +export type GetUnifiedHistoryRequestQuery = z.infer; + +export const UnifiedHistoryRowBase = lazySchema(() => + z.object({ /** - * The saved query ID, if the live query was based on a saved query. + * Unique identifier for the history row. */ - savedQueryId: z.string().optional(), + id: z.string(), /** - * The query timeout in seconds. + * The timestamp of the query execution. */ - timeout: z.number().int().optional(), + timestamp: z.string(), /** - * List of targeted agent IDs. + * The SQL query that was executed. */ - agentIds: z.array(z.string()).optional(), + queryText: z.string(), /** - * Whether the query targeted all agents. + * The name of the query, if available. */ - agentAll: z.boolean().optional(), + queryName: z.string().optional(), /** - * List of targeted agent platforms. + * The name of the pack containing the query. */ - agentPlatforms: z.array(z.string()).optional(), + packName: z.string().optional(), /** - * List of targeted agent policy IDs. + * The ID of the pack containing the query. */ - agentPolicyIds: z.array(z.string()).optional(), - }) -); - -export type ScheduledHistoryRow = z.infer; -export const ScheduledHistoryRow = UnifiedHistoryRowBase.extend( - z.object({ + packId: z.string().optional(), /** - * Identifies this as a scheduled query history row. + * The Kibana space ID where the query was executed. */ - sourceType: z.literal('scheduled'), + spaceId: z.string().optional(), /** - * Indicates this is a scheduled query execution. + * The number of agents targeted by the query. */ - source: z.literal('Scheduled'), + agentCount: z.number().int(), /** - * The schedule ID for the scheduled query. + * The number of successful agent responses. */ - scheduleId: z.string().optional(), + successCount: z.number().int().nullable().optional(), /** - * The execution count for this scheduled query run. + * The number of agent responses with errors. */ - executionCount: z.number().int().optional(), + errorCount: z.number().int().nullable().optional(), /** - * The planned execution time for the scheduled query. + * The total number of result rows returned across all agents. */ - plannedTime: z.string().optional(), + totalRows: z.number().int().nullable().optional(), }) ); +export type UnifiedHistoryRowBase = z.infer; +export const LiveHistoryRow = lazySchema(() => + UnifiedHistoryRowBase.merge( + z.object({ + /** + * Identifies this as a live query history row. + */ + sourceType: z.literal('live'), + /** + * Whether this was a manually run live query or triggered by a rule. + */ + source: z.enum(['Live', 'Rule']), + /** + * The Fleet action ID for the live query. + */ + actionId: z.string().optional(), + /** + * The ID of the user who ran the query. + */ + userId: z.string().optional(), + /** + * The user profile UID of the user who ran the query. + */ + userProfileUid: z.string().optional(), + /** + * The number of sub-queries that returned results. + */ + queriesWithResults: z.number().int().optional(), + /** + * The total number of sub-queries in the live action. + */ + queriesTotal: z.number().int().optional(), + /** + * ECS mapping configuration used for the query. + */ + ecsMapping: z.object({}).catchall(z.unknown()).optional(), + /** + * The saved query ID, if the live query was based on a saved query. + */ + savedQueryId: z.string().optional(), + /** + * The query timeout in seconds. + */ + timeout: z.number().int().optional(), + /** + * List of targeted agent IDs. + */ + agentIds: z.array(z.string()).optional(), + /** + * Whether the query targeted all agents. + */ + agentAll: z.boolean().optional(), + /** + * List of targeted agent platforms. + */ + agentPlatforms: z.array(z.string()).optional(), + /** + * List of targeted agent policy IDs. + */ + agentPolicyIds: z.array(z.string()).optional(), + }) + ) +); +export type LiveHistoryRow = z.infer; + +export const ScheduledHistoryRow = lazySchema(() => + UnifiedHistoryRowBase.merge( + z.object({ + /** + * Identifies this as a scheduled query history row. + */ + sourceType: z.literal('scheduled'), + /** + * Indicates this is a scheduled query execution. + */ + source: z.literal('Scheduled'), + /** + * The schedule ID for the scheduled query. + */ + scheduleId: z.string().optional(), + /** + * The execution count for this scheduled query run. + */ + executionCount: z.number().int().optional(), + /** + * The planned execution time for the scheduled query. + */ + plannedTime: z.string().optional(), + }) + ) +); +export type ScheduledHistoryRow = z.infer; + +export const UnifiedHistoryRow = lazySchema(() => + z.discriminatedUnion('sourceType', [LiveHistoryRow, ScheduledHistoryRow]) +); export type UnifiedHistoryRow = z.infer; -export const UnifiedHistoryRow = z.discriminatedUnion('sourceType', [ - LiveHistoryRow, - ScheduledHistoryRow, -]); +export const GetUnifiedHistoryResponse = lazySchema(() => + z.object({ + /** + * The list of unified history rows for the current page. + */ + data: z.array(UnifiedHistoryRow), + /** + * A base64-encoded cursor to fetch the next page. Absent when there are no more results. + */ + nextPage: z.string().optional(), + /** + * Whether there are more results beyond the current page. + */ + hasMore: z.boolean(), + }) +); export type GetUnifiedHistoryResponse = z.infer; -export const GetUnifiedHistoryResponse = z.object({ - /** - * The list of unified history rows for the current page. - */ - data: z.array(UnifiedHistoryRow), - /** - * A base64-encoded cursor to fetch the next page. Absent when there are no more results. - */ - nextPage: z.string().optional(), - /** - * Whether there are more results beyond the current page. - */ - hasMore: z.boolean(), -}); diff --git a/x-pack/platform/plugins/shared/osquery/common/api/unified_history/unified_history.gen.ts b/x-pack/platform/plugins/shared/osquery/common/api/unified_history/unified_history.gen.ts index 41996e7c1afe7..cead314bdebdb 100644 --- a/x-pack/platform/plugins/shared/osquery/common/api/unified_history/unified_history.gen.ts +++ b/x-pack/platform/plugins/shared/osquery/common/api/unified_history/unified_history.gen.ts @@ -14,46 +14,48 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { GetUnifiedHistoryResponse } from './get_unified_history.gen'; +export const OsqueryGetUnifiedHistoryRequestQuery = lazySchema(() => + z.object({ + /** + * The number of results to return per page. + */ + pageSize: z.coerce.number().int().min(1).max(100).optional().default(20), + /** + * A base64-encoded cursor for pagination. Use the value from the previous response to fetch the next page. + */ + nextPage: z.string().optional(), + /** + * A search string to filter history entries by pack name, query text, or query ID. + */ + kuery: z.string().optional(), + /** + * Comma-separated list of user IDs to filter live query history. + */ + userIds: z.string().optional(), + /** + * Comma-separated list of source types to include. Valid values are `live`, `rule`, and `scheduled`. + */ + sourceFilters: z.string().optional(), + /** + * The start of the time range filter (ISO 8601). + */ + startDate: z.string().optional(), + /** + * The end of the time range filter (ISO 8601). + */ + endDate: z.string().optional(), + }) +); export type OsqueryGetUnifiedHistoryRequestQuery = z.infer< typeof OsqueryGetUnifiedHistoryRequestQuery >; -export const OsqueryGetUnifiedHistoryRequestQuery = z.object({ - /** - * The number of results to return per page. - */ - pageSize: z.coerce.number().int().min(1).max(100).optional().default(20), - /** - * A base64-encoded cursor for pagination. Use the value from the previous response to fetch the next page. - */ - nextPage: z.string().optional(), - /** - * A search string to filter history entries by pack name, query text, or query ID. - */ - kuery: z.string().optional(), - /** - * Comma-separated list of user IDs to filter live query history. - */ - userIds: z.string().optional(), - /** - * Comma-separated list of source types to include. Valid values are `live`, `rule`, and `scheduled`. - */ - sourceFilters: z.string().optional(), - /** - * The start of the time range filter (ISO 8601). - */ - startDate: z.string().optional(), - /** - * The end of the time range filter (ISO 8601). - */ - endDate: z.string().optional(), -}); export type OsqueryGetUnifiedHistoryRequestQueryInput = z.input< typeof OsqueryGetUnifiedHistoryRequestQuery >; +export const OsqueryGetUnifiedHistoryResponse = lazySchema(() => GetUnifiedHistoryResponse); export type OsqueryGetUnifiedHistoryResponse = z.infer; -export const OsqueryGetUnifiedHistoryResponse = GetUnifiedHistoryResponse; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list/create_endpoint_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list/create_endpoint_list.gen.ts index eee30bf2b034f..f5d0ae5cd6a96 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list/create_endpoint_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list/create_endpoint_list.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { EndpointList } from '../model/endpoint_list_common.gen'; +export const CreateEndpointListResponse = lazySchema(() => EndpointList); export type CreateEndpointListResponse = z.infer; -export const CreateEndpointListResponse = EndpointList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list_item/create_endpoint_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list_item/create_endpoint_list_item.gen.ts index 635ce10899943..d83659b87dab9 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list_item/create_endpoint_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/create_endpoint_list_item/create_endpoint_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListItemHumanId, @@ -29,21 +29,23 @@ import { import { ExceptionListItemEntryArray } from '@kbn/securitysolution-exceptions-common/api/model/exception_list_item_entry.gen'; import { EndpointListItem } from '../model/endpoint_list_common.gen'; +export const CreateEndpointListItemRequestBody = lazySchema(() => + z.object({ + item_id: ExceptionListItemHumanId.optional(), + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + entries: ExceptionListItemEntryArray, + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: ExceptionListItemTags.optional().default([]), + meta: ExceptionListItemMeta.optional(), + comments: ExceptionListItemCommentArray.optional().default([]), + }) +); export type CreateEndpointListItemRequestBody = z.infer; -export const CreateEndpointListItemRequestBody = z.object({ - item_id: ExceptionListItemHumanId.optional(), - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - entries: ExceptionListItemEntryArray, - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: ExceptionListItemTags.optional().default([]), - meta: ExceptionListItemMeta.optional(), - comments: ExceptionListItemCommentArray.optional().default([]), -}); export type CreateEndpointListItemRequestBodyInput = z.input< typeof CreateEndpointListItemRequestBody >; +export const CreateEndpointListItemResponse = lazySchema(() => EndpointListItem); export type CreateEndpointListItemResponse = z.infer; -export const CreateEndpointListItemResponse = EndpointListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/delete_endpoint_list_item/delete_endpoint_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/delete_endpoint_list_item/delete_endpoint_list_item.gen.ts index fb84468c70559..e5ab2d2e1058c 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/delete_endpoint_list_item/delete_endpoint_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/delete_endpoint_list_item/delete_endpoint_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListItemId, @@ -22,20 +22,22 @@ import { } from '@kbn/securitysolution-exceptions-common/api/model/exception_list_common.gen'; import { EndpointListItem } from '../model/endpoint_list_common.gen'; +export const DeleteEndpointListItemRequestQuery = lazySchema(() => + z.object({ + /** + * Either `id` or `item_id` must be specified + */ + id: ExceptionListItemId.optional(), + /** + * Either `id` or `item_id` must be specified + */ + item_id: ExceptionListItemHumanId.optional(), + }) +); export type DeleteEndpointListItemRequestQuery = z.infer; -export const DeleteEndpointListItemRequestQuery = z.object({ - /** - * Either `id` or `item_id` must be specified - */ - id: ExceptionListItemId.optional(), - /** - * Either `id` or `item_id` must be specified - */ - item_id: ExceptionListItemHumanId.optional(), -}); export type DeleteEndpointListItemRequestQueryInput = z.input< typeof DeleteEndpointListItemRequestQuery >; +export const DeleteEndpointListItemResponse = lazySchema(() => EndpointListItem); export type DeleteEndpointListItemResponse = z.infer; -export const DeleteEndpointListItemResponse = EndpointListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/find_endpoint_list_item/find_endpoint_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/find_endpoint_list_item/find_endpoint_list_item.gen.ts index 3b23ad4e9a9ec..cf30058c384af 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/find_endpoint_list_item/find_endpoint_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/find_endpoint_list_item/find_endpoint_list_item.gen.ts @@ -14,63 +14,67 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; import { EndpointListItem } from '../model/endpoint_list_common.gen'; +export const FindEndpointListItemsFilter = lazySchema(() => NonEmptyString); export type FindEndpointListItemsFilter = z.infer; -export const FindEndpointListItemsFilter = NonEmptyString; -export type FindEndpointListItemsRequestQuery = z.infer; -export const FindEndpointListItemsRequestQuery = z.object({ - /** +export const FindEndpointListItemsRequestQuery = lazySchema(() => + z.object({ + /** * Filters the returned results according to the value of the specified field, using the `:` syntax. */ - filter: FindEndpointListItemsFilter.optional(), - /** - * The page number to return - */ - page: z.coerce.number().int().min(0).optional(), - /** - * The number of exception list items to return per page - */ - per_page: z.coerce.number().int().min(0).optional(), - /** - * Determines which field is used to sort the results - */ - sort_field: NonEmptyString.optional(), - /** - * Determines the sort order, which can be `desc` or `asc` - */ - sort_order: z.enum(['desc', 'asc']).optional(), -}); + filter: FindEndpointListItemsFilter.optional(), + /** + * The page number to return + */ + page: z.coerce.number().int().min(0).optional(), + /** + * The number of exception list items to return per page + */ + per_page: z.coerce.number().int().min(0).optional(), + /** + * Determines which field is used to sort the results + */ + sort_field: NonEmptyString.optional(), + /** + * Determines the sort order, which can be `desc` or `asc` + */ + sort_order: z.enum(['desc', 'asc']).optional(), + }) +); +export type FindEndpointListItemsRequestQuery = z.infer; export type FindEndpointListItemsRequestQueryInput = z.input< typeof FindEndpointListItemsRequestQuery >; +export const FindEndpointListItemsResponse = lazySchema(() => + z.object({ + /** + * The list of endpoint exception list items. + */ + data: z.array(EndpointListItem), + /** + * The current page number. + */ + page: z.number().int().min(0), + /** + * The number of items per page. + */ + per_page: z.number().int().min(0), + /** + * The total number of endpoint exception list items. + */ + total: z.number().int().min(0), + /** + * The point-in-time ID for pagination. + */ + pit: z.string().optional(), + }) +); export type FindEndpointListItemsResponse = z.infer; -export const FindEndpointListItemsResponse = z.object({ - /** - * The list of endpoint exception list items. - */ - data: z.array(EndpointListItem), - /** - * The current page number. - */ - page: z.number().int().min(0), - /** - * The number of items per page. - */ - per_page: z.number().int().min(0), - /** - * The total number of endpoint exception list items. - */ - total: z.number().int().min(0), - /** - * The point-in-time ID for pagination. - */ - pit: z.string().optional(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/model/endpoint_list_common.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/model/endpoint_list_common.gen.ts index e9e0042bbb019..396b62c5c0605 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/model/endpoint_list_common.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/model/endpoint_list_common.gen.ts @@ -14,15 +14,15 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionList, ExceptionListItem, } from '@kbn/securitysolution-exceptions-common/api/model/exception_list_common.gen'; +export const EndpointList = lazySchema(() => z.union([ExceptionList, z.object({}).strict()])); export type EndpointList = z.infer; -export const EndpointList = z.union([ExceptionList, z.object({}).strict()]); +export const EndpointListItem = lazySchema(() => ExceptionListItem); export type EndpointListItem = z.infer; -export const EndpointListItem = ExceptionListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/read_endpoint_list_item/read_endpoint_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/read_endpoint_list_item/read_endpoint_list_item.gen.ts index 9756f85158a42..2b5d1d59d61d9 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/read_endpoint_list_item/read_endpoint_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/read_endpoint_list_item/read_endpoint_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListItemId, @@ -22,20 +22,22 @@ import { } from '@kbn/securitysolution-exceptions-common/api/model/exception_list_common.gen'; import { EndpointListItem } from '../model/endpoint_list_common.gen'; +export const ReadEndpointListItemRequestQuery = lazySchema(() => + z.object({ + /** + * Either `id` or `item_id` must be specified + */ + id: ExceptionListItemId.optional(), + /** + * Either `id` or `item_id` must be specified + */ + item_id: ExceptionListItemHumanId.optional(), + }) +); export type ReadEndpointListItemRequestQuery = z.infer; -export const ReadEndpointListItemRequestQuery = z.object({ - /** - * Either `id` or `item_id` must be specified - */ - id: ExceptionListItemId.optional(), - /** - * Either `id` or `item_id` must be specified - */ - item_id: ExceptionListItemHumanId.optional(), -}); export type ReadEndpointListItemRequestQueryInput = z.input< typeof ReadEndpointListItemRequestQuery >; +export const ReadEndpointListItemResponse = lazySchema(() => EndpointListItem); export type ReadEndpointListItemResponse = z.infer; -export const ReadEndpointListItemResponse = EndpointListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/update_endpoint_list_item/update_endpoint_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/update_endpoint_list_item/update_endpoint_list_item.gen.ts index a6eb730678d45..52d0ad25e0ecf 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/update_endpoint_list_item/update_endpoint_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/update_endpoint_list_item/update_endpoint_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListItemId, @@ -30,32 +30,34 @@ import { import { ExceptionListItemEntryArray } from '@kbn/securitysolution-exceptions-common/api/model/exception_list_item_entry.gen'; import { EndpointListItem } from '../model/endpoint_list_common.gen'; +export const UpdateEndpointListItemRequestBody = lazySchema(() => + z.object({ + /** + * Either `id` or `item_id` must be specified + */ + id: ExceptionListItemId.optional(), + /** + * Either `id` or `item_id` must be specified + */ + item_id: ExceptionListItemHumanId.optional(), + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + entries: ExceptionListItemEntryArray, + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: ExceptionListItemTags.optional(), + meta: ExceptionListItemMeta.optional(), + comments: ExceptionListItemCommentArray.optional().default([]), + /** + * The version id, normally returned by the API when the item is retrieved. Use it ensure updates are made against the latest version. + */ + _version: z.string().optional(), + }) +); export type UpdateEndpointListItemRequestBody = z.infer; -export const UpdateEndpointListItemRequestBody = z.object({ - /** - * Either `id` or `item_id` must be specified - */ - id: ExceptionListItemId.optional(), - /** - * Either `id` or `item_id` must be specified - */ - item_id: ExceptionListItemHumanId.optional(), - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - entries: ExceptionListItemEntryArray, - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: ExceptionListItemTags.optional(), - meta: ExceptionListItemMeta.optional(), - comments: ExceptionListItemCommentArray.optional().default([]), - /** - * The version id, normally returned by the API when the item is retrieved. Use it ensure updates are made against the latest version. - */ - _version: z.string().optional(), -}); export type UpdateEndpointListItemRequestBodyInput = z.input< typeof UpdateEndpointListItemRequestBody >; +export const UpdateEndpointListItemResponse = lazySchema(() => EndpointListItem); export type UpdateEndpointListItemResponse = z.infer; -export const UpdateEndpointListItemResponse = EndpointListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list/create_exception_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list/create_exception_list.gen.ts index 5f3f3369efa30..ceb61b1005526 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list/create_exception_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list/create_exception_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListHumanId, @@ -29,19 +29,21 @@ import { ExceptionList, } from '../model/exception_list_common.gen'; +export const CreateExceptionListRequestBody = lazySchema(() => + z.object({ + list_id: ExceptionListHumanId.optional(), + name: ExceptionListName, + description: ExceptionListDescription, + type: ExceptionListType, + namespace_type: ExceptionNamespaceType.optional().default('single'), + os_types: ExceptionListOsTypeArray.optional(), + tags: ExceptionListTags.optional().default([]), + meta: ExceptionListMeta.optional(), + version: ExceptionListVersion.optional().default(1), + }) +); export type CreateExceptionListRequestBody = z.infer; -export const CreateExceptionListRequestBody = z.object({ - list_id: ExceptionListHumanId.optional(), - name: ExceptionListName, - description: ExceptionListDescription, - type: ExceptionListType, - namespace_type: ExceptionNamespaceType.optional().default('single'), - os_types: ExceptionListOsTypeArray.optional(), - tags: ExceptionListTags.optional().default([]), - meta: ExceptionListMeta.optional(), - version: ExceptionListVersion.optional().default(1), -}); export type CreateExceptionListRequestBodyInput = z.input; +export const CreateExceptionListResponse = lazySchema(() => ExceptionList); export type CreateExceptionListResponse = z.infer; -export const CreateExceptionListResponse = ExceptionList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts index 3716dc28e617e..372b4c7cbb705 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_exception_list_item/create_exception_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; import { @@ -44,135 +44,151 @@ import { } from '../model/exception_list_common.gen'; import { ExceptionListItemEntryArray } from '../model/exception_list_item_entry.gen'; +export const CreateExceptionListItemComment = lazySchema(() => + z.object({ + comment: NonEmptyString, + }) +); export type CreateExceptionListItemComment = z.infer; -export const CreateExceptionListItemComment = z.object({ - comment: NonEmptyString, -}); +export const CreateExceptionListItemCommentArray = lazySchema(() => + z.array(CreateExceptionListItemComment) +); export type CreateExceptionListItemCommentArray = z.infer< typeof CreateExceptionListItemCommentArray >; -export const CreateExceptionListItemCommentArray = z.array(CreateExceptionListItemComment); -export type CreateExceptionListItemBase = z.infer; -export const CreateExceptionListItemBase = z.object({ - item_id: ExceptionListItemHumanId.optional(), - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - namespace_type: ExceptionNamespaceType.optional().default('single'), - meta: ExceptionListItemMeta.optional(), - expire_time: ExceptionListItemExpireTime.optional(), - comments: CreateExceptionListItemCommentArray.optional().default([]), -}); - -export type CreateExceptionListItemGeneric = z.infer; -export const CreateExceptionListItemGeneric = CreateExceptionListItemBase.extend( +export const CreateExceptionListItemBase = lazySchema(() => z.object({ - list_id: ExceptionListHumanId, - entries: ExceptionListItemEntryArray, - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: ExceptionListItemTags.optional().default([]), + item_id: ExceptionListItemHumanId.optional(), + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + namespace_type: ExceptionNamespaceType.optional().default('single'), + meta: ExceptionListItemMeta.optional(), + expire_time: ExceptionListItemExpireTime.optional(), + comments: CreateExceptionListItemCommentArray.optional().default([]), }) ); +export type CreateExceptionListItemBase = z.infer; +export const CreateExceptionListItemGeneric = lazySchema(() => + CreateExceptionListItemBase.merge( + z.object({ + list_id: ExceptionListHumanId, + entries: ExceptionListItemEntryArray, + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: ExceptionListItemTags.optional().default([]), + }) + ) +); +export type CreateExceptionListItemGeneric = z.infer; + +export const CreateExceptionListItemEndpointList = lazySchema(() => + CreateExceptionListItemBase.merge(EndpointListProperties) +); export type CreateExceptionListItemEndpointList = z.infer< typeof CreateExceptionListItemEndpointList >; -export const CreateExceptionListItemEndpointList = - CreateExceptionListItemBase.extend(EndpointListProperties); +export const CreateExceptionListItemTrustedAppsWindows = lazySchema(() => + CreateExceptionListItemBase.merge(TrustedAppsWindowsProperties) +); export type CreateExceptionListItemTrustedAppsWindows = z.infer< typeof CreateExceptionListItemTrustedAppsWindows >; -export const CreateExceptionListItemTrustedAppsWindows = CreateExceptionListItemBase.extend( - TrustedAppsWindowsProperties -); +export const CreateExceptionListItemTrustedAppsMac = lazySchema(() => + CreateExceptionListItemBase.merge(TrustedAppsMacProperties) +); export type CreateExceptionListItemTrustedAppsMac = z.infer< typeof CreateExceptionListItemTrustedAppsMac >; -export const CreateExceptionListItemTrustedAppsMac = - CreateExceptionListItemBase.extend(TrustedAppsMacProperties); +export const CreateExceptionListItemTrustedAppsLinux = lazySchema(() => + CreateExceptionListItemBase.merge(TrustedAppsLinuxProperties) +); export type CreateExceptionListItemTrustedAppsLinux = z.infer< typeof CreateExceptionListItemTrustedAppsLinux >; -export const CreateExceptionListItemTrustedAppsLinux = CreateExceptionListItemBase.extend( - TrustedAppsLinuxProperties -); +export const CreateExceptionListItemTrustedDevicesWindows = lazySchema(() => + CreateExceptionListItemBase.merge(TrustedDevicesWindowsProperties) +); export type CreateExceptionListItemTrustedDevicesWindows = z.infer< typeof CreateExceptionListItemTrustedDevicesWindows >; -export const CreateExceptionListItemTrustedDevicesWindows = CreateExceptionListItemBase.extend( - TrustedDevicesWindowsProperties -); +export const CreateExceptionListItemTrustedDevicesMac = lazySchema(() => + CreateExceptionListItemBase.merge(TrustedDevicesMacProperties) +); export type CreateExceptionListItemTrustedDevicesMac = z.infer< typeof CreateExceptionListItemTrustedDevicesMac >; -export const CreateExceptionListItemTrustedDevicesMac = CreateExceptionListItemBase.extend( - TrustedDevicesMacProperties -); +export const CreateExceptionListItemTrustedDevicesWindowsMac = lazySchema(() => + CreateExceptionListItemBase.merge(TrustedDevicesWindowsMacProperties) +); export type CreateExceptionListItemTrustedDevicesWindowsMac = z.infer< typeof CreateExceptionListItemTrustedDevicesWindowsMac >; -export const CreateExceptionListItemTrustedDevicesWindowsMac = CreateExceptionListItemBase.extend( - TrustedDevicesWindowsMacProperties -); +export const CreateExceptionListItemEventFilters = lazySchema(() => + CreateExceptionListItemBase.merge(EventFiltersProperties) +); export type CreateExceptionListItemEventFilters = z.infer< typeof CreateExceptionListItemEventFilters >; -export const CreateExceptionListItemEventFilters = - CreateExceptionListItemBase.extend(EventFiltersProperties); +export const CreateExceptionListItemHostIsolation = lazySchema(() => + CreateExceptionListItemBase.merge(HostIsolationProperties) +); export type CreateExceptionListItemHostIsolation = z.infer< typeof CreateExceptionListItemHostIsolation >; -export const CreateExceptionListItemHostIsolation = - CreateExceptionListItemBase.extend(HostIsolationProperties); +export const CreateExceptionListItemBlocklistWindows = lazySchema(() => + CreateExceptionListItemBase.merge(BlocklistWindowsProperties) +); export type CreateExceptionListItemBlocklistWindows = z.infer< typeof CreateExceptionListItemBlocklistWindows >; -export const CreateExceptionListItemBlocklistWindows = CreateExceptionListItemBase.extend( - BlocklistWindowsProperties -); +export const CreateExceptionListItemBlocklistLinux = lazySchema(() => + CreateExceptionListItemBase.merge(BlocklistLinuxProperties) +); export type CreateExceptionListItemBlocklistLinux = z.infer< typeof CreateExceptionListItemBlocklistLinux >; -export const CreateExceptionListItemBlocklistLinux = - CreateExceptionListItemBase.extend(BlocklistLinuxProperties); +export const CreateExceptionListItemBlocklistMac = lazySchema(() => + CreateExceptionListItemBase.merge(BlocklistMacProperties) +); export type CreateExceptionListItemBlocklistMac = z.infer< typeof CreateExceptionListItemBlocklistMac >; -export const CreateExceptionListItemBlocklistMac = - CreateExceptionListItemBase.extend(BlocklistMacProperties); +export const CreateExceptionListItemRequestBody = lazySchema(() => + z.union([ + CreateExceptionListItemGeneric, + CreateExceptionListItemEndpointList, + CreateExceptionListItemTrustedAppsWindows, + CreateExceptionListItemTrustedAppsMac, + CreateExceptionListItemTrustedAppsLinux, + CreateExceptionListItemTrustedDevicesWindows, + CreateExceptionListItemTrustedDevicesMac, + CreateExceptionListItemTrustedDevicesWindowsMac, + CreateExceptionListItemEventFilters, + CreateExceptionListItemHostIsolation, + CreateExceptionListItemBlocklistWindows, + CreateExceptionListItemBlocklistLinux, + CreateExceptionListItemBlocklistMac, + ]) +); export type CreateExceptionListItemRequestBody = z.infer; -export const CreateExceptionListItemRequestBody = z.union([ - CreateExceptionListItemGeneric, - CreateExceptionListItemEndpointList, - CreateExceptionListItemTrustedAppsWindows, - CreateExceptionListItemTrustedAppsMac, - CreateExceptionListItemTrustedAppsLinux, - CreateExceptionListItemTrustedDevicesWindows, - CreateExceptionListItemTrustedDevicesMac, - CreateExceptionListItemTrustedDevicesWindowsMac, - CreateExceptionListItemEventFilters, - CreateExceptionListItemHostIsolation, - CreateExceptionListItemBlocklistWindows, - CreateExceptionListItemBlocklistLinux, - CreateExceptionListItemBlocklistMac, -]); export type CreateExceptionListItemRequestBodyInput = z.input< typeof CreateExceptionListItemRequestBody >; +export const CreateExceptionListItemResponse = lazySchema(() => ExceptionListItem); export type CreateExceptionListItemResponse = z.infer; -export const CreateExceptionListItemResponse = ExceptionListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_rule_exceptions/create_rule_exceptions.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_rule_exceptions/create_rule_exceptions.gen.ts index 21a3bd652f43f..7c8f2889e447a 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_rule_exceptions/create_rule_exceptions.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_rule_exceptions/create_rule_exceptions.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { UUID, NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; import { @@ -30,58 +30,68 @@ import { } from '../model/exception_list_common.gen'; import { ExceptionListItemEntryArray } from '../model/exception_list_item_entry.gen'; +export const RuleId = lazySchema(() => UUID); export type RuleId = z.infer; -export const RuleId = UUID; +export const CreateRuleExceptionListItemComment = lazySchema(() => + z.object({ + comment: NonEmptyString, + }) +); export type CreateRuleExceptionListItemComment = z.infer; -export const CreateRuleExceptionListItemComment = z.object({ - comment: NonEmptyString, -}); +export const CreateRuleExceptionListItemCommentArray = lazySchema(() => + z.array(CreateRuleExceptionListItemComment) +); export type CreateRuleExceptionListItemCommentArray = z.infer< typeof CreateRuleExceptionListItemCommentArray >; -export const CreateRuleExceptionListItemCommentArray = z.array(CreateRuleExceptionListItemComment); +export const CreateRuleExceptionListItemProps = lazySchema(() => + z.object({ + item_id: ExceptionListItemHumanId.optional(), + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + entries: ExceptionListItemEntryArray, + namespace_type: ExceptionNamespaceType.optional().default('single'), + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: ExceptionListItemTags.optional().default([]), + meta: ExceptionListItemMeta.optional(), + expire_time: z.string().datetime().optional(), + comments: CreateRuleExceptionListItemCommentArray.optional().default([]), + }) +); export type CreateRuleExceptionListItemProps = z.infer; -export const CreateRuleExceptionListItemProps = z.object({ - item_id: ExceptionListItemHumanId.optional(), - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - entries: ExceptionListItemEntryArray, - namespace_type: ExceptionNamespaceType.optional().default('single'), - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: ExceptionListItemTags.optional().default([]), - meta: ExceptionListItemMeta.optional(), - expire_time: z.string().datetime().optional(), - comments: CreateRuleExceptionListItemCommentArray.optional().default([]), -}); +export const CreateRuleExceptionListItemsRequestParams = lazySchema(() => + z.object({ + /** + * Detection rule's identifier + */ + id: RuleId, + }) +); export type CreateRuleExceptionListItemsRequestParams = z.infer< typeof CreateRuleExceptionListItemsRequestParams >; -export const CreateRuleExceptionListItemsRequestParams = z.object({ - /** - * Detection rule's identifier - */ - id: RuleId, -}); export type CreateRuleExceptionListItemsRequestParamsInput = z.input< typeof CreateRuleExceptionListItemsRequestParams >; +export const CreateRuleExceptionListItemsRequestBody = lazySchema(() => + z.object({ + items: z.array(CreateRuleExceptionListItemProps), + }) +); export type CreateRuleExceptionListItemsRequestBody = z.infer< typeof CreateRuleExceptionListItemsRequestBody >; -export const CreateRuleExceptionListItemsRequestBody = z.object({ - items: z.array(CreateRuleExceptionListItemProps), -}); export type CreateRuleExceptionListItemsRequestBodyInput = z.input< typeof CreateRuleExceptionListItemsRequestBody >; +export const CreateRuleExceptionListItemsResponse = lazySchema(() => z.array(ExceptionListItem)); export type CreateRuleExceptionListItemsResponse = z.infer< typeof CreateRuleExceptionListItemsResponse >; -export const CreateRuleExceptionListItemsResponse = z.array(ExceptionListItem); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_shared_exceptions_list/create_shared_exceptions_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_shared_exceptions_list/create_shared_exceptions_list.gen.ts index b2be6241c1428..a1db84a9d882b 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_shared_exceptions_list/create_shared_exceptions_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/create_shared_exceptions_list/create_shared_exceptions_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListName, @@ -22,16 +22,18 @@ import { ExceptionList, } from '../model/exception_list_common.gen'; +export const CreateSharedExceptionListRequestBody = lazySchema(() => + z.object({ + name: ExceptionListName, + description: ExceptionListDescription, + }) +); export type CreateSharedExceptionListRequestBody = z.infer< typeof CreateSharedExceptionListRequestBody >; -export const CreateSharedExceptionListRequestBody = z.object({ - name: ExceptionListName, - description: ExceptionListDescription, -}); export type CreateSharedExceptionListRequestBodyInput = z.input< typeof CreateSharedExceptionListRequestBody >; +export const CreateSharedExceptionListResponse = lazySchema(() => ExceptionList); export type CreateSharedExceptionListResponse = z.infer; -export const CreateSharedExceptionListResponse = ExceptionList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list/delete_exception_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list/delete_exception_list.gen.ts index 60430f8186e3d..e48a3e1d93838 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list/delete_exception_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list/delete_exception_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListId, @@ -23,19 +23,21 @@ import { ExceptionList, } from '../model/exception_list_common.gen'; +export const DeleteExceptionListRequestQuery = lazySchema(() => + z.object({ + /** + * Exception list's identifier. Either `id` or `list_id` must be specified. + */ + id: ExceptionListId.optional(), + /** + * Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. + */ + list_id: ExceptionListHumanId.optional(), + namespace_type: ExceptionNamespaceType.optional().default('single'), + }) +); export type DeleteExceptionListRequestQuery = z.infer; -export const DeleteExceptionListRequestQuery = z.object({ - /** - * Exception list's identifier. Either `id` or `list_id` must be specified. - */ - id: ExceptionListId.optional(), - /** - * Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. - */ - list_id: ExceptionListHumanId.optional(), - namespace_type: ExceptionNamespaceType.optional().default('single'), -}); export type DeleteExceptionListRequestQueryInput = z.input; +export const DeleteExceptionListResponse = lazySchema(() => ExceptionList); export type DeleteExceptionListResponse = z.infer; -export const DeleteExceptionListResponse = ExceptionList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list_item/delete_exception_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list_item/delete_exception_list_item.gen.ts index 6833886059ca1..f3962ad4f689c 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list_item/delete_exception_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/delete_exception_list_item/delete_exception_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListItemId, @@ -23,23 +23,25 @@ import { ExceptionListItem, } from '../model/exception_list_common.gen'; +export const DeleteExceptionListItemRequestQuery = lazySchema(() => + z.object({ + /** + * Exception item's identifier. Either `id` or `item_id` must be specified + */ + id: ExceptionListItemId.optional(), + /** + * Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified + */ + item_id: ExceptionListItemHumanId.optional(), + namespace_type: ExceptionNamespaceType.optional().default('single'), + }) +); export type DeleteExceptionListItemRequestQuery = z.infer< typeof DeleteExceptionListItemRequestQuery >; -export const DeleteExceptionListItemRequestQuery = z.object({ - /** - * Exception item's identifier. Either `id` or `item_id` must be specified - */ - id: ExceptionListItemId.optional(), - /** - * Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified - */ - item_id: ExceptionListItemHumanId.optional(), - namespace_type: ExceptionNamespaceType.optional().default('single'), -}); export type DeleteExceptionListItemRequestQueryInput = z.input< typeof DeleteExceptionListItemRequestQuery >; +export const DeleteExceptionListItemResponse = lazySchema(() => ExceptionListItem); export type DeleteExceptionListItemResponse = z.infer; -export const DeleteExceptionListItemResponse = ExceptionListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/duplicate_exception_list/duplicate_exception_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/duplicate_exception_list/duplicate_exception_list.gen.ts index b7523f38dddc7..eaa504627bb73 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/duplicate_exception_list/duplicate_exception_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/duplicate_exception_list/duplicate_exception_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListHumanId, @@ -22,18 +22,20 @@ import { ExceptionList, } from '../model/exception_list_common.gen'; +export const DuplicateExceptionListRequestQuery = lazySchema(() => + z.object({ + list_id: ExceptionListHumanId, + namespace_type: ExceptionNamespaceType, + /** + * Determines whether to include expired exceptions in the duplicated list. Expiration date defined by `expire_time`. + */ + include_expired_exceptions: z.enum(['true', 'false']).default('true'), + }) +); export type DuplicateExceptionListRequestQuery = z.infer; -export const DuplicateExceptionListRequestQuery = z.object({ - list_id: ExceptionListHumanId, - namespace_type: ExceptionNamespaceType, - /** - * Determines whether to include expired exceptions in the duplicated list. Expiration date defined by `expire_time`. - */ - include_expired_exceptions: z.enum(['true', 'false']).default('true'), -}); export type DuplicateExceptionListRequestQueryInput = z.input< typeof DuplicateExceptionListRequestQuery >; +export const DuplicateExceptionListResponse = lazySchema(() => ExceptionList); export type DuplicateExceptionListResponse = z.infer; -export const DuplicateExceptionListResponse = ExceptionList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/export_exception_list/export_exception_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/export_exception_list/export_exception_list.gen.ts index 49323854f39d7..c0bf4523a8671 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/export_exception_list/export_exception_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/export_exception_list/export_exception_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListId, @@ -22,14 +22,16 @@ import { ExceptionNamespaceType, } from '../model/exception_list_common.gen'; +export const ExportExceptionListRequestQuery = lazySchema(() => + z.object({ + id: ExceptionListId, + list_id: ExceptionListHumanId, + namespace_type: ExceptionNamespaceType, + /** + * Determines whether to include expired exceptions in the exported list. Expiration date defined by `expire_time`. + */ + include_expired_exceptions: z.enum(['true', 'false']).default('true'), + }) +); export type ExportExceptionListRequestQuery = z.infer; -export const ExportExceptionListRequestQuery = z.object({ - id: ExceptionListId, - list_id: ExceptionListHumanId, - namespace_type: ExceptionNamespaceType, - /** - * Determines whether to include expired exceptions in the exported list. Expiration date defined by `expire_time`. - */ - include_expired_exceptions: z.enum(['true', 'false']).default('true'), -}); export type ExportExceptionListRequestQueryInput = z.input; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_list_items/find_exception_list_items.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_list_items/find_exception_list_items.gen.ts index 42364d842cd73..8e3532c60f8de 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_list_items/find_exception_list_items.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_list_items/find_exception_list_items.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; @@ -24,54 +24,58 @@ import { ExceptionListItem, } from '../model/exception_list_common.gen'; +export const FindExceptionListItemsFilter = lazySchema(() => NonEmptyString); export type FindExceptionListItemsFilter = z.infer; -export const FindExceptionListItemsFilter = NonEmptyString; -export type FindExceptionListItemsRequestQuery = z.infer; -export const FindExceptionListItemsRequestQuery = z.object({ - /** - * The `list_id`s of the items to fetch. - */ - list_id: ArrayFromString(ExceptionListHumanId), - /** +export const FindExceptionListItemsRequestQuery = lazySchema(() => + z.object({ + /** + * The `list_id`s of the items to fetch. + */ + list_id: ArrayFromString(ExceptionListHumanId), + /** * Filters the returned results according to the value of the specified field, using the `:` syntax. */ - filter: ArrayFromString(FindExceptionListItemsFilter).optional().default([]), - /** + filter: ArrayFromString(FindExceptionListItemsFilter).optional().default([]), + /** * Determines whether the returned containers are Kibana associated with a Kibana space or available in all spaces (`agnostic` or `single`) */ - namespace_type: ArrayFromString(ExceptionNamespaceType).optional().default(['single']), - search: z.string().optional(), - /** - * The page number to return - */ - page: z.coerce.number().int().min(0).optional(), - /** - * The number of exception list items to return per page - */ - per_page: z.coerce.number().int().min(0).optional(), - /** - * Determines which field is used to sort the results. - */ - sort_field: NonEmptyString.optional(), - /** - * Determines the sort order, which can be `desc` or `asc`. - */ - sort_order: z.enum(['desc', 'asc']).optional(), -}); + namespace_type: ArrayFromString(ExceptionNamespaceType).optional().default(['single']), + search: z.string().optional(), + /** + * The page number to return + */ + page: z.coerce.number().int().min(0).optional(), + /** + * The number of exception list items to return per page + */ + per_page: z.coerce.number().int().min(0).optional(), + /** + * Determines which field is used to sort the results. + */ + sort_field: NonEmptyString.optional(), + /** + * Determines the sort order, which can be `desc` or `asc`. + */ + sort_order: z.enum(['desc', 'asc']).optional(), + }) +); +export type FindExceptionListItemsRequestQuery = z.infer; export type FindExceptionListItemsRequestQueryInput = z.input< typeof FindExceptionListItemsRequestQuery >; +export const FindExceptionListItemsResponse = lazySchema(() => + z.object({ + data: z.array(ExceptionListItem), + page: z.number().int().min(1), + per_page: z.number().int().min(1), + total: z.number().int().min(0), + pit: z.string().optional(), + }) +); export type FindExceptionListItemsResponse = z.infer; -export const FindExceptionListItemsResponse = z.object({ - data: z.array(ExceptionListItem), - page: z.number().int().min(1), - per_page: z.number().int().min(1), - total: z.number().int().min(0), - pit: z.string().optional(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_lists/find_exception_lists.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_lists/find_exception_lists.gen.ts index fde972c11b74b..6f3b8930d6bf5 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_lists/find_exception_lists.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/find_exception_lists/find_exception_lists.gen.ts @@ -14,17 +14,17 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { ExceptionNamespaceType, ExceptionList } from '../model/exception_list_common.gen'; +export const FindExceptionListsFilter = lazySchema(() => z.string()); export type FindExceptionListsFilter = z.infer; -export const FindExceptionListsFilter = z.string(); -export type FindExceptionListsRequestQuery = z.infer; -export const FindExceptionListsRequestQuery = z.object({ - /** +export const FindExceptionListsRequestQuery = lazySchema(() => + z.object({ + /** * Filters the returned results according to the value of the specified field. Uses the `so type.field name:field` value syntax, where `so type` can be: @@ -33,36 +33,40 @@ Uses the `so type.field name:field` value syntax, where `so type` can be: - `exception-list-agnostic`: Specify an exception list that is shared across spaces. */ - filter: FindExceptionListsFilter.optional(), - /** + filter: FindExceptionListsFilter.optional(), + /** * Determines whether the returned containers are Kibana associated with a Kibana space or available in all spaces (`agnostic` or `single`) */ - namespace_type: ArrayFromString(ExceptionNamespaceType).optional().default(['single']), - /** - * The page number to return - */ - page: z.coerce.number().int().min(1).optional(), - /** - * The number of exception lists to return per page - */ - per_page: z.coerce.number().int().min(1).optional(), - /** - * Determines which field is used to sort the results. - */ - sort_field: z.string().optional(), - /** - * Determines the sort order, which can be `desc` or `asc`. - */ - sort_order: z.enum(['desc', 'asc']).optional(), -}); + namespace_type: ArrayFromString(ExceptionNamespaceType).optional().default(['single']), + /** + * The page number to return + */ + page: z.coerce.number().int().min(1).optional(), + /** + * The number of exception lists to return per page + */ + per_page: z.coerce.number().int().min(1).optional(), + /** + * Determines which field is used to sort the results. + */ + sort_field: z.string().optional(), + /** + * Determines the sort order, which can be `desc` or `asc`. + */ + sort_order: z.enum(['desc', 'asc']).optional(), + }) +); +export type FindExceptionListsRequestQuery = z.infer; export type FindExceptionListsRequestQueryInput = z.input; +export const FindExceptionListsResponse = lazySchema(() => + z.object({ + data: z.array(ExceptionList), + page: z.number().int().min(1), + per_page: z.number().int().min(1), + total: z.number().int().min(0), + }) +); export type FindExceptionListsResponse = z.infer; -export const FindExceptionListsResponse = z.object({ - data: z.array(ExceptionList), - page: z.number().int().min(1), - per_page: z.number().int().min(1), - total: z.number().int().min(0), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/import_exceptions/import_exceptions.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/import_exceptions/import_exceptions.gen.ts index fbe8f50a90103..0cda571d7c34f 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/import_exceptions/import_exceptions.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/import_exceptions/import_exceptions.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { @@ -23,45 +23,53 @@ import { ExceptionListItemHumanId, } from '../model/exception_list_common.gen'; +export const ExceptionListsImportBulkError = lazySchema(() => + z.object({ + error: z.object({ + status_code: z.number().int(), + message: z.string(), + }), + id: ExceptionListId.optional(), + list_id: ExceptionListHumanId.optional(), + item_id: ExceptionListItemHumanId.optional(), + }) +); export type ExceptionListsImportBulkError = z.infer; -export const ExceptionListsImportBulkError = z.object({ - error: z.object({ - status_code: z.number().int(), - message: z.string(), - }), - id: ExceptionListId.optional(), - list_id: ExceptionListHumanId.optional(), - item_id: ExceptionListItemHumanId.optional(), -}); +export const ExceptionListsImportBulkErrorArray = lazySchema(() => + z.array(ExceptionListsImportBulkError) +); export type ExceptionListsImportBulkErrorArray = z.infer; -export const ExceptionListsImportBulkErrorArray = z.array(ExceptionListsImportBulkError); -export type ImportExceptionListRequestQuery = z.infer; -export const ImportExceptionListRequestQuery = z.object({ - /** +export const ImportExceptionListRequestQuery = lazySchema(() => + z.object({ + /** * Determines whether existing exception lists with the same `list_id` are overwritten. If any exception items have the same `item_id`, those are also overwritten. */ - overwrite: BooleanFromString.optional().default(false), - /** + overwrite: BooleanFromString.optional().default(false), + /** * Determines whether the list being imported will have a new `list_id` generated. Additional `item_id`'s are generated for each exception item. Both the exception list and its items are overwritten. */ - as_new_list: BooleanFromString.optional().default(false), -}); + as_new_list: BooleanFromString.optional().default(false), + }) +); +export type ImportExceptionListRequestQuery = z.infer; export type ImportExceptionListRequestQueryInput = z.input; +export const ImportExceptionListResponse = lazySchema(() => + z.object({ + errors: ExceptionListsImportBulkErrorArray, + success: z.boolean(), + success_count: z.number().int().min(0), + success_exception_lists: z.boolean(), + success_count_exception_lists: z.number().int().min(0), + success_exception_list_items: z.boolean(), + success_count_exception_list_items: z.number().int().min(0), + }) +); export type ImportExceptionListResponse = z.infer; -export const ImportExceptionListResponse = z.object({ - errors: ExceptionListsImportBulkErrorArray, - success: z.boolean(), - success_count: z.number().int().min(0), - success_exception_lists: z.boolean(), - success_count_exception_lists: z.number().int().min(0), - success_exception_list_items: z.boolean(), - success_count_exception_list_items: z.number().int().min(0), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_common.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_common.gen.ts index a7badd0796426..a09d3d886ee28 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_common.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_common.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; @@ -23,8 +23,8 @@ import { ExceptionListItemEntryArray } from './exception_list_item_entry.gen'; /** * Exception list's identifier. */ +export const ExceptionListId = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type ExceptionListId = z.infer; -export const ExceptionListId = z.string().min(1).superRefine(isNonEmptyString); /** * The exception list's human-readable string identifier. @@ -39,43 +39,47 @@ For endpoint artifacts, use one of the following values: * `endpoint_blocklists`: [Blocklists list](https://www.elastic.co/docs/solutions/security/manage-elastic-defend/blocklist) */ +export const ExceptionListHumanId = lazySchema(() => + z.string().min(1).superRefine(isNonEmptyString) +); export type ExceptionListHumanId = z.infer; -export const ExceptionListHumanId = z.string().min(1).superRefine(isNonEmptyString); /** * The type of exception list to be created. Different list types may denote where they can be utilized. */ +export const ExceptionListType = lazySchema(() => + z.enum([ + 'detection', + 'rule_default', + 'endpoint', + 'endpoint_trusted_apps', + 'endpoint_trusted_devices', + 'endpoint_events', + 'endpoint_host_isolation_exceptions', + 'endpoint_blocklists', + ]) +); export type ExceptionListType = z.infer; -export const ExceptionListType = z.enum([ - 'detection', - 'rule_default', - 'endpoint', - 'endpoint_trusted_apps', - 'endpoint_trusted_devices', - 'endpoint_events', - 'endpoint_host_isolation_exceptions', - 'endpoint_blocklists', -]); export type ExceptionListTypeEnum = typeof ExceptionListType.enum; export const ExceptionListTypeEnum = ExceptionListType.enum; /** * The name of the exception list. */ +export const ExceptionListName = lazySchema(() => z.string()); export type ExceptionListName = z.infer; -export const ExceptionListName = z.string(); /** * Describes the exception list. */ +export const ExceptionListDescription = lazySchema(() => z.string()); export type ExceptionListDescription = z.infer; -export const ExceptionListDescription = z.string(); /** * Placeholder for metadata about the list container. */ +export const ExceptionListMeta = lazySchema(() => z.object({}).catchall(z.unknown())); export type ExceptionListMeta = z.infer; -export const ExceptionListMeta = z.object({}).catchall(z.unknown()); /** * Determines whether the exception container is available in all Kibana spaces or just the space @@ -87,114 +91,124 @@ in which it is created, where: For endpoint artifacts, the `namespace_type` must always be `agnostic`. Space awareness for endpoint artifacts is enforced based on Elastic Defend policy assignments. */ +export const ExceptionNamespaceType = lazySchema(() => z.enum(['agnostic', 'single'])); export type ExceptionNamespaceType = z.infer; -export const ExceptionNamespaceType = z.enum(['agnostic', 'single']); export type ExceptionNamespaceTypeEnum = typeof ExceptionNamespaceType.enum; export const ExceptionNamespaceTypeEnum = ExceptionNamespaceType.enum; /** * String array containing words and phrases to help categorize exception containers. */ +export const ExceptionListTags = lazySchema(() => z.array(z.string())); export type ExceptionListTags = z.infer; -export const ExceptionListTags = z.array(z.string()); /** * Use this field to specify the operating system. */ +export const ExceptionListOsType = lazySchema(() => z.enum(['linux', 'macos', 'windows'])); export type ExceptionListOsType = z.infer; -export const ExceptionListOsType = z.enum(['linux', 'macos', 'windows']); export type ExceptionListOsTypeEnum = typeof ExceptionListOsType.enum; export const ExceptionListOsTypeEnum = ExceptionListOsType.enum; /** * Use this field to specify the operating system. Only enter one value. */ +export const ExceptionListOsTypeArray = lazySchema(() => z.array(ExceptionListOsType)); export type ExceptionListOsTypeArray = z.infer; -export const ExceptionListOsTypeArray = z.array(ExceptionListOsType); /** * The document version, automatically increasd on updates. */ +export const ExceptionListVersion = lazySchema(() => z.number().int().min(1)); export type ExceptionListVersion = z.infer; -export const ExceptionListVersion = z.number().int().min(1); +export const ExceptionList = lazySchema(() => + z.object({ + id: ExceptionListId, + list_id: ExceptionListHumanId, + type: ExceptionListType, + name: ExceptionListName, + description: ExceptionListDescription, + immutable: z.boolean(), + namespace_type: ExceptionNamespaceType, + os_types: ExceptionListOsTypeArray.optional(), + tags: ExceptionListTags.optional(), + meta: ExceptionListMeta.optional(), + version: ExceptionListVersion, + /** + * The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. + */ + _version: z.string().optional(), + /** + * Field used in search to ensure all containers are sorted and returned correctly. + */ + tie_breaker_id: z.string(), + /** + * Autogenerated date of object creation. + */ + created_at: z.string().datetime(), + /** + * Autogenerated value - user that created object. + */ + created_by: z.string(), + /** + * Autogenerated date of last object update. + */ + updated_at: z.string().datetime(), + /** + * Autogenerated value - user that last updated object. + */ + updated_by: z.string(), + }) +); export type ExceptionList = z.infer; -export const ExceptionList = z.object({ - id: ExceptionListId, - list_id: ExceptionListHumanId, - type: ExceptionListType, - name: ExceptionListName, - description: ExceptionListDescription, - immutable: z.boolean(), - namespace_type: ExceptionNamespaceType, - os_types: ExceptionListOsTypeArray.optional(), - tags: ExceptionListTags.optional(), - meta: ExceptionListMeta.optional(), - version: ExceptionListVersion, - /** - * The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. - */ - _version: z.string().optional(), - /** - * Field used in search to ensure all containers are sorted and returned correctly. - */ - tie_breaker_id: z.string(), - /** - * Autogenerated date of object creation. - */ - created_at: z.string().datetime(), - /** - * Autogenerated value - user that created object. - */ - created_by: z.string(), - /** - * Autogenerated date of last object update. - */ - updated_at: z.string().datetime(), - /** - * Autogenerated value - user that last updated object. - */ - updated_by: z.string(), -}); /** * Exception's identifier. */ +export const ExceptionListItemId = lazySchema(() => + z.string().min(1).superRefine(isNonEmptyString) +); export type ExceptionListItemId = z.infer; -export const ExceptionListItemId = z.string().min(1).superRefine(isNonEmptyString); /** * Human readable string identifier, e.g. `trusted-linux-processes` */ +export const ExceptionListItemHumanId = lazySchema(() => + z.string().min(1).superRefine(isNonEmptyString) +); export type ExceptionListItemHumanId = z.infer; -export const ExceptionListItemHumanId = z.string().min(1).superRefine(isNonEmptyString); +export const ExceptionListItemType = lazySchema(() => z.literal('simple')); export type ExceptionListItemType = z.infer; -export const ExceptionListItemType = z.literal('simple'); /** * Exception list name. */ +export const ExceptionListItemName = lazySchema(() => + z.string().min(1).superRefine(isNonEmptyString) +); export type ExceptionListItemName = z.infer; -export const ExceptionListItemName = z.string().min(1).superRefine(isNonEmptyString); /** * Describes the exception list. */ +export const ExceptionListItemDescription = lazySchema(() => z.string()); export type ExceptionListItemDescription = z.infer; -export const ExceptionListItemDescription = z.string(); +export const ExceptionListItemMeta = lazySchema(() => z.object({}).catchall(z.unknown())); export type ExceptionListItemMeta = z.infer; -export const ExceptionListItemMeta = z.object({}).catchall(z.unknown()); /** * The exception item’s expiration date, in ISO format. This field is only available for regular exception items, not endpoint exceptions. */ +export const ExceptionListItemExpireTime = lazySchema(() => z.string().datetime()); export type ExceptionListItemExpireTime = z.infer; -export const ExceptionListItemExpireTime = z.string().datetime(); +export const ExceptionListItemTags = lazySchema(() => + z.array(z.string().min(1).superRefine(isNonEmptyString)) +); export type ExceptionListItemTags = z.infer; -export const ExceptionListItemTags = z.array(z.string().min(1).superRefine(isNonEmptyString)); /** * Tags for categorization. Special tags for scope control: @@ -202,250 +216,270 @@ export const ExceptionListItemTags = z.array(z.string().min(1).superRefine(isNon * `"policy:"` - Private artifact (applies to specific Elastic Defend policy only, where `` is the Elastic Defend integration policy ID) */ +export const EndpointArtifactTags = lazySchema(() => z.array(z.string()).default([])); export type EndpointArtifactTags = z.infer; -export const EndpointArtifactTags = z.array(z.string()).default([]); /** * Operating system types for trusted devices (Windows and macOS only - Linux not supported) */ +export const EndpointTrustedDeviceOsTypes = lazySchema(() => + z.array(z.enum(['windows', 'macos'])).min(1) +); export type EndpointTrustedDeviceOsTypes = z.infer; -export const EndpointTrustedDeviceOsTypes = z.array(z.enum(['windows', 'macos'])).min(1); +export const TrustedDeviceCommonFieldsEntry = lazySchema(() => + z.object({ + /** + * Device field to match against (available on all OS) + */ + field: z.enum([ + 'device.serial_number', + 'device.type', + 'host.name', + 'device.vendor.name', + 'device.vendor.id', + 'device.product.id', + 'device.product.name', + ]), + /** + * Entry match type + */ + type: z.enum(['match', 'wildcard', 'match_any']), + value: z.union([z.string(), z.array(z.string()).min(1)]), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) +); export type TrustedDeviceCommonFieldsEntry = z.infer; -export const TrustedDeviceCommonFieldsEntry = z.object({ - /** - * Device field to match against (available on all OS) - */ - field: z.enum([ - 'device.serial_number', - 'device.type', - 'host.name', - 'device.vendor.name', - 'device.vendor.id', - 'device.product.id', - 'device.product.name', - ]), - /** - * Entry match type - */ - type: z.enum(['match', 'wildcard', 'match_any']), - value: z.union([z.string(), z.array(z.string()).min(1)]), - /** - * Must be the value "included" - */ - operator: z.literal('included'), -}); +export const TrustedDeviceUsernameEntry = lazySchema(() => + z.object({ + /** + * Username field (Windows-only, requires os_types to be exclusively Windows) + */ + field: z.literal('user.name'), + /** + * Entry match type + */ + type: z.enum(['match', 'wildcard', 'match_any']), + value: z.union([z.string(), z.array(z.string()).min(1)]), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) +); export type TrustedDeviceUsernameEntry = z.infer; -export const TrustedDeviceUsernameEntry = z.object({ - /** - * Username field (Windows-only, requires os_types to be exclusively Windows) - */ - field: z.literal('user.name'), - /** - * Entry match type - */ - type: z.enum(['match', 'wildcard', 'match_any']), - value: z.union([z.string(), z.array(z.string()).min(1)]), - /** - * Must be the value "included" - */ - operator: z.literal('included'), -}); +export const BlocklistHashOrPathEntry = lazySchema(() => + z.object({ + /** + * File hash or path field + */ + field: z.enum([ + 'file.hash.md5', + 'file.hash.sha1', + 'file.hash.sha256', + 'file.path', + 'file.path.caseless', + ]), + /** + * Must be match_any for blocklists + */ + type: z.literal('match_any'), + /** + * Array of hash values or file paths + */ + value: z.array(z.string()).min(1), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) +); export type BlocklistHashOrPathEntry = z.infer; -export const BlocklistHashOrPathEntry = z.object({ - /** - * File hash or path field - */ - field: z.enum([ - 'file.hash.md5', - 'file.hash.sha1', - 'file.hash.sha256', - 'file.path', - 'file.path.caseless', - ]), - /** - * Must be match_any for blocklists - */ - type: z.literal('match_any'), - /** - * Array of hash values or file paths - */ - value: z.array(z.string()).min(1), - /** - * Must be the value "included" - */ - operator: z.literal('included'), -}); +export const BlocklistWindowsCodeSignatureEntry = lazySchema(() => + z.object({ + /** + * Windows code signature field + */ + field: z.literal('file.Ext.code_signature'), + /** + * Must be nested for Windows code signature + */ + type: z.literal('nested'), + /** + * Nested subject_name entries + */ + entries: z + .array( + z.object({ + /** + * Certificate subject name + */ + field: z.literal('subject_name'), + /** + * Match type for subject name + */ + type: z.enum(['match', 'match_any']), + value: z.union([z.string(), z.array(z.string()).min(1)]), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) + ) + .min(1), + }) +); export type BlocklistWindowsCodeSignatureEntry = z.infer; -export const BlocklistWindowsCodeSignatureEntry = z.object({ - /** - * Windows code signature field - */ - field: z.literal('file.Ext.code_signature'), - /** - * Must be nested for Windows code signature - */ - type: z.literal('nested'), - /** - * Nested subject_name entries - */ - entries: z - .array( - z.object({ - /** - * Certificate subject name - */ - field: z.literal('subject_name'), - /** - * Match type for subject name - */ - type: z.enum(['match', 'match_any']), - value: z.union([z.string(), z.array(z.string()).min(1)]), - /** - * Must be the value "included" - */ - operator: z.literal('included'), - }) - ) - .min(1), -}); +export const TrustedAppHashEntry = lazySchema(() => + z.object({ + /** + * Process hash field + */ + field: z.enum(['process.hash.md5', 'process.hash.sha1', 'process.hash.sha256']), + /** + * Hash entries only support match type + */ + type: z.literal('match'), + /** + * Hash value (MD5, SHA1, or SHA256) + */ + value: z.string(), + operator: z.literal('included'), + }) +); export type TrustedAppHashEntry = z.infer; -export const TrustedAppHashEntry = z.object({ - /** - * Process hash field - */ - field: z.enum(['process.hash.md5', 'process.hash.sha1', 'process.hash.sha256']), - /** - * Hash entries only support match type - */ - type: z.literal('match'), - /** - * Hash value (MD5, SHA1, or SHA256) - */ - value: z.string(), - operator: z.literal('included'), -}); +export const TrustedAppPathEntry = lazySchema(() => + z.object({ + /** + * Process executable path field + */ + field: z.literal('process.executable.caseless'), + /** + * Path supports both match and wildcard types + */ + type: z.enum(['match', 'wildcard']), + /** + * Executable path + */ + value: z.string(), + operator: z.literal('included'), + }) +); export type TrustedAppPathEntry = z.infer; -export const TrustedAppPathEntry = z.object({ - /** - * Process executable path field - */ - field: z.literal('process.executable.caseless'), - /** - * Path supports both match and wildcard types - */ - type: z.enum(['match', 'wildcard']), - /** - * Executable path - */ - value: z.string(), - operator: z.literal('included'), -}); +export const TrustedAppWindowsCodeSignatureEntry = lazySchema(() => + z.object({ + /** + * Windows code signature field + */ + field: z.literal('process.Ext.code_signature'), + type: z.literal('nested'), + /** + * Must include exactly 2 entries - one for subject_name and one for trusted + */ + entries: z + .array( + z.union([ + z.object({ + field: z.literal('subject_name'), + type: z.literal('match'), + /** + * Certificate subject name + */ + value: z.string(), + operator: z.literal('included'), + }), + z.object({ + field: z.literal('trusted'), + type: z.literal('match'), + /** + * Must be the string 'true' + */ + value: z.literal('true'), + operator: z.literal('included'), + }), + ]) + ) + .min(2) + .max(2), + }) +); export type TrustedAppWindowsCodeSignatureEntry = z.infer< typeof TrustedAppWindowsCodeSignatureEntry >; -export const TrustedAppWindowsCodeSignatureEntry = z.object({ - /** - * Windows code signature field - */ - field: z.literal('process.Ext.code_signature'), - type: z.literal('nested'), - /** - * Must include exactly 2 entries - one for subject_name and one for trusted - */ - entries: z - .array( - z.union([ - z.object({ - field: z.literal('subject_name'), - type: z.literal('match'), - /** - * Certificate subject name - */ - value: z.string(), - operator: z.literal('included'), - }), - z.object({ - field: z.literal('trusted'), - type: z.literal('match'), - /** - * Must be the string 'true' - */ - value: z.literal('true'), - operator: z.literal('included'), - }), - ]) - ) - .min(2) - .max(2), -}); +export const TrustedAppMacCodeSignatureEntry = lazySchema(() => + z.object({ + /** + * macOS code signature field + */ + field: z.literal('process.code_signature'), + type: z.literal('nested'), + /** + * Must include exactly 2 entries - one for subject_name and one for trusted + */ + entries: z + .array( + z.union([ + z.object({ + field: z.literal('subject_name'), + type: z.literal('match'), + /** + * Certificate subject name + */ + value: z.string(), + operator: z.literal('included'), + }), + z.object({ + field: z.literal('trusted'), + type: z.literal('match'), + /** + * Must be the string 'true' + */ + value: z.literal('true'), + operator: z.literal('included'), + }), + ]) + ) + .min(2) + .max(2), + }) +); export type TrustedAppMacCodeSignatureEntry = z.infer; -export const TrustedAppMacCodeSignatureEntry = z.object({ - /** - * macOS code signature field - */ - field: z.literal('process.code_signature'), - type: z.literal('nested'), - /** - * Must include exactly 2 entries - one for subject_name and one for trusted - */ - entries: z - .array( - z.union([ - z.object({ - field: z.literal('subject_name'), - type: z.literal('match'), - /** - * Certificate subject name - */ - value: z.string(), - operator: z.literal('included'), - }), - z.object({ - field: z.literal('trusted'), - type: z.literal('match'), - /** - * Must be the string 'true' - */ - value: z.literal('true'), - operator: z.literal('included'), - }), - ]) - ) - .min(2) - .max(2), -}); +export const ExceptionListItemOsType = lazySchema(() => z.enum(['linux', 'macos', 'windows'])); export type ExceptionListItemOsType = z.infer; -export const ExceptionListItemOsType = z.enum(['linux', 'macos', 'windows']); export type ExceptionListItemOsTypeEnum = typeof ExceptionListItemOsType.enum; export const ExceptionListItemOsTypeEnum = ExceptionListItemOsType.enum; +export const ExceptionListItemOsTypeArray = lazySchema(() => z.array(ExceptionListOsType)); export type ExceptionListItemOsTypeArray = z.infer; -export const ExceptionListItemOsTypeArray = z.array(ExceptionListOsType); +export const ExceptionListItemComment = lazySchema(() => + z.object({ + id: NonEmptyString, + comment: NonEmptyString, + /** + * Autogenerated date of object creation. + */ + created_at: z.string().datetime(), + created_by: NonEmptyString, + /** + * Autogenerated date of last object update. + */ + updated_at: z.string().datetime().optional(), + updated_by: NonEmptyString.optional(), + }) +); export type ExceptionListItemComment = z.infer; -export const ExceptionListItemComment = z.object({ - id: NonEmptyString, - comment: NonEmptyString, - /** - * Autogenerated date of object creation. - */ - created_at: z.string().datetime(), - created_by: NonEmptyString, - /** - * Autogenerated date of last object update. - */ - updated_at: z.string().datetime().optional(), - updated_by: NonEmptyString.optional(), -}); /** * Array of comment fields: @@ -453,230 +487,246 @@ export const ExceptionListItemComment = z.object({ - comment (string): Comments about the exception item. */ +export const ExceptionListItemCommentArray = lazySchema(() => z.array(ExceptionListItemComment)); export type ExceptionListItemCommentArray = z.infer; -export const ExceptionListItemCommentArray = z.array(ExceptionListItemComment); /** * Elastic Endpoint exception list item properties. */ -export type EndpointListProperties = z.infer; -export const EndpointListProperties = z.object({ - list_id: z.literal('endpoint_list'), - /** +export const EndpointListProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_list'), + /** * Exception entries for endpoint security exceptions (used to prevent detection rule alerts). **Fully flexible:** Supports any field name for maximum compatibility with detection rules. No field restrictions are enforced. */ - entries: ExceptionListItemEntryArray.optional(), - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: EndpointArtifactTags.optional(), -}); + entries: ExceptionListItemEntryArray.optional(), + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: EndpointArtifactTags.optional(), + }) +); +export type EndpointListProperties = z.infer; /** * Trusted applications list item properties (Windows). */ +export const TrustedAppsWindowsProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_trusted_apps'), + /** + * Must be Windows only + */ + os_types: z.array(z.literal('windows')).min(1).max(1).optional(), + /** + * Process hash, executable path, or code signature entries + */ + entries: z + .array( + z.union([TrustedAppHashEntry, TrustedAppPathEntry, TrustedAppWindowsCodeSignatureEntry]) + ) + .min(1) + .optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type TrustedAppsWindowsProperties = z.infer; -export const TrustedAppsWindowsProperties = z.object({ - list_id: z.literal('endpoint_trusted_apps'), - /** - * Must be Windows only - */ - os_types: z.array(z.literal('windows')).min(1).max(1).optional(), - /** - * Process hash, executable path, or code signature entries - */ - entries: z - .array(z.union([TrustedAppHashEntry, TrustedAppPathEntry, TrustedAppWindowsCodeSignatureEntry])) - .min(1) - .optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Trusted applications list item properties (macOS). */ +export const TrustedAppsMacProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_trusted_apps'), + /** + * Must be macOS only + */ + os_types: z.array(z.literal('macos')).min(1).max(1).optional(), + /** + * Process hash, executable path, or code signature entries + */ + entries: z + .array(z.union([TrustedAppHashEntry, TrustedAppPathEntry, TrustedAppMacCodeSignatureEntry])) + .min(1) + .optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type TrustedAppsMacProperties = z.infer; -export const TrustedAppsMacProperties = z.object({ - list_id: z.literal('endpoint_trusted_apps'), - /** - * Must be macOS only - */ - os_types: z.array(z.literal('macos')).min(1).max(1).optional(), - /** - * Process hash, executable path, or code signature entries - */ - entries: z - .array(z.union([TrustedAppHashEntry, TrustedAppPathEntry, TrustedAppMacCodeSignatureEntry])) - .min(1) - .optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Trusted applications list item properties (Linux). */ +export const TrustedAppsLinuxProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_trusted_apps'), + /** + * Must be Linux only + */ + os_types: z.array(z.literal('linux')).min(1).max(1).optional(), + /** + * Process hash or executable path entries (code signature not supported on Linux) + */ + entries: z + .array(z.union([TrustedAppHashEntry, TrustedAppPathEntry])) + .min(1) + .optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type TrustedAppsLinuxProperties = z.infer; -export const TrustedAppsLinuxProperties = z.object({ - list_id: z.literal('endpoint_trusted_apps'), - /** - * Must be Linux only - */ - os_types: z.array(z.literal('linux')).min(1).max(1).optional(), - /** - * Process hash or executable path entries (code signature not supported on Linux) - */ - entries: z - .array(z.union([TrustedAppHashEntry, TrustedAppPathEntry])) - .min(1) - .optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Trusted devices list item properties (Windows-only, allows username field). */ +export const TrustedDevicesWindowsProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_trusted_devices'), + /** + * Exception entries for the trusted device (duplicate field entries are not allowed) + */ + entries: z + .array( + z.object({ + /** + * Device field to match against (user.name is Windows-only) + */ + field: z.enum([ + 'device.serial_number', + 'device.type', + 'host.name', + 'device.vendor.name', + 'device.vendor.id', + 'device.product.id', + 'device.product.name', + 'user.name', + ]), + /** + * Entry match type + */ + type: z.enum(['match', 'wildcard', 'match_any']), + value: z.union([z.string(), z.array(z.string()).min(1)]), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) + ) + .min(1) + .optional(), + /** + * Must be Windows-only to allow username field + */ + os_types: z.array(z.literal('windows')).min(1).max(1).optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type TrustedDevicesWindowsProperties = z.infer; -export const TrustedDevicesWindowsProperties = z.object({ - list_id: z.literal('endpoint_trusted_devices'), - /** - * Exception entries for the trusted device (duplicate field entries are not allowed) - */ - entries: z - .array( - z.object({ - /** - * Device field to match against (user.name is Windows-only) - */ - field: z.enum([ - 'device.serial_number', - 'device.type', - 'host.name', - 'device.vendor.name', - 'device.vendor.id', - 'device.product.id', - 'device.product.name', - 'user.name', - ]), - /** - * Entry match type - */ - type: z.enum(['match', 'wildcard', 'match_any']), - value: z.union([z.string(), z.array(z.string()).min(1)]), - /** - * Must be the value "included" - */ - operator: z.literal('included'), - }) - ) - .min(1) - .optional(), - /** - * Must be Windows-only to allow username field - */ - os_types: z.array(z.literal('windows')).min(1).max(1).optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Trusted devices list item properties (macOS-only, username not supported). */ +export const TrustedDevicesMacProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_trusted_devices'), + /** + * Exception entries for the trusted device (duplicate field entries are not allowed) + */ + entries: z + .array( + z.object({ + /** + * Device field to match against + */ + field: z.enum([ + 'device.serial_number', + 'device.type', + 'host.name', + 'device.vendor.name', + 'device.vendor.id', + 'device.product.id', + 'device.product.name', + ]), + /** + * Entry match type + */ + type: z.enum(['match', 'wildcard', 'match_any']), + value: z.union([z.string(), z.array(z.string()).min(1)]), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) + ) + .min(1) + .optional(), + /** + * macOS-only + */ + os_types: z.array(z.literal('macos')).min(1).max(1).optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type TrustedDevicesMacProperties = z.infer; -export const TrustedDevicesMacProperties = z.object({ - list_id: z.literal('endpoint_trusted_devices'), - /** - * Exception entries for the trusted device (duplicate field entries are not allowed) - */ - entries: z - .array( - z.object({ - /** - * Device field to match against - */ - field: z.enum([ - 'device.serial_number', - 'device.type', - 'host.name', - 'device.vendor.name', - 'device.vendor.id', - 'device.product.id', - 'device.product.name', - ]), - /** - * Entry match type - */ - type: z.enum(['match', 'wildcard', 'match_any']), - value: z.union([z.string(), z.array(z.string()).min(1)]), - /** - * Must be the value "included" - */ - operator: z.literal('included'), - }) - ) - .min(1) - .optional(), - /** - * macOS-only - */ - os_types: z.array(z.literal('macos')).min(1).max(1).optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Trusted devices list item properties (Windows + macOS, username not supported). */ +export const TrustedDevicesWindowsMacProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_trusted_devices'), + /** + * Exception entries for the trusted device (duplicate field entries are not allowed, username not available when targeting both OS) + */ + entries: z + .array( + z.object({ + /** + * Device field to match against (username not available for multi-OS) + */ + field: z.enum([ + 'device.serial_number', + 'device.type', + 'host.name', + 'device.vendor.name', + 'device.vendor.id', + 'device.product.id', + 'device.product.name', + ]), + /** + * Entry match type + */ + type: z.enum(['match', 'wildcard', 'match_any']), + value: z.union([z.string(), z.array(z.string()).min(1)]), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) + ) + .min(1) + .optional(), + /** + * Must include both Windows and macOS (username field not allowed) + */ + os_types: z + .array(z.enum(['windows', 'macos'])) + .min(2) + .max(2) + .optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type TrustedDevicesWindowsMacProperties = z.infer; -export const TrustedDevicesWindowsMacProperties = z.object({ - list_id: z.literal('endpoint_trusted_devices'), - /** - * Exception entries for the trusted device (duplicate field entries are not allowed, username not available when targeting both OS) - */ - entries: z - .array( - z.object({ - /** - * Device field to match against (username not available for multi-OS) - */ - field: z.enum([ - 'device.serial_number', - 'device.type', - 'host.name', - 'device.vendor.name', - 'device.vendor.id', - 'device.product.id', - 'device.product.name', - ]), - /** - * Entry match type - */ - type: z.enum(['match', 'wildcard', 'match_any']), - value: z.union([z.string(), z.array(z.string()).min(1)]), - /** - * Must be the value "included" - */ - operator: z.literal('included'), - }) - ) - .min(1) - .optional(), - /** - * Must include both Windows and macOS (username field not allowed) - */ - os_types: z - .array(z.enum(['windows', 'macos'])) - .min(2) - .max(2) - .optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Event filters list item properties. */ -export type EventFiltersProperties = z.infer; -export const EventFiltersProperties = z.object({ - list_id: z.literal('endpoint_event_filters'), - /** +export const EventFiltersProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_event_filters'), + /** * Exception entries for the event filter. **Flexible field support:** Any event field name is allowed (e.g., `process.name`, `file.path`, `event.action`, `dns.question.name`, etc.) @@ -684,190 +734,204 @@ export const EventFiltersProperties = z.object({ **Minimum requirement:** At least 1 entry required */ - entries: ExceptionListItemEntryArray.optional(), - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: EndpointArtifactTags.optional(), -}); + entries: ExceptionListItemEntryArray.optional(), + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: EndpointArtifactTags.optional(), + }) +); +export type EventFiltersProperties = z.infer; /** * Host isolation exceptions list item properties. */ +export const HostIsolationProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_host_isolation_exceptions'), + /** + * Exactly one entry allowed for host isolation exceptions + */ + entries: z + .array( + z.object({ + /** + * Must be destination.ip + */ + field: z.literal('destination.ip'), + /** + * Must be match + */ + type: z.literal('match'), + /** + * Valid IPv4 address or CIDR notation (e.g., "192.168.1.1" or "10.0.0.0/8") + */ + value: z.string(), + /** + * Must be the value "included" + */ + operator: z.literal('included'), + }) + ) + .min(1) + .max(1) + .optional(), + /** + * Must include all three operating systems (windows, linux, macos) + */ + os_types: z + .array(z.enum(['windows', 'linux', 'macos'])) + .min(3) + .max(3) + .optional(), + tags: EndpointArtifactTags.optional(), + }) +); export type HostIsolationProperties = z.infer; -export const HostIsolationProperties = z.object({ - list_id: z.literal('endpoint_host_isolation_exceptions'), - /** - * Exactly one entry allowed for host isolation exceptions - */ - entries: z - .array( - z.object({ - /** - * Must be destination.ip - */ - field: z.literal('destination.ip'), - /** - * Must be match - */ - type: z.literal('match'), - /** - * Valid IPv4 address or CIDR notation (e.g., "192.168.1.1" or "10.0.0.0/8") - */ - value: z.string(), - /** - * Must be the value "included" - */ - operator: z.literal('included'), - }) - ) - .min(1) - .max(1) - .optional(), - /** - * Must include all three operating systems (windows, linux, macos) - */ - os_types: z - .array(z.enum(['windows', 'linux', 'macos'])) - .min(3) - .max(3) - .optional(), - tags: EndpointArtifactTags.optional(), -}); /** * Blocklist list item properties (Windows, supports code signature). */ -export type BlocklistWindowsProperties = z.infer; -export const BlocklistWindowsProperties = z.object({ - list_id: z.literal('endpoint_blocklists'), - /** +export const BlocklistWindowsProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_blocklists'), + /** * **Validation rules:** * Hash entries: up to 3 (one for each hash type: md5, sha1, sha256) * Path entry: only 1 allowed * Code signature entry: only 1 allowed */ - entries: z - .array(z.union([BlocklistHashOrPathEntry, BlocklistWindowsCodeSignatureEntry])) - .min(1) - .optional(), - /** - * Windows-only - */ - os_types: z.array(z.literal('windows')).min(1).max(1).optional(), - tags: EndpointArtifactTags.optional(), -}); + entries: z + .array(z.union([BlocklistHashOrPathEntry, BlocklistWindowsCodeSignatureEntry])) + .min(1) + .optional(), + /** + * Windows-only + */ + os_types: z.array(z.literal('windows')).min(1).max(1).optional(), + tags: EndpointArtifactTags.optional(), + }) +); +export type BlocklistWindowsProperties = z.infer; /** * Blocklist list item properties (Linux, code signature not supported). */ -export type BlocklistLinuxProperties = z.infer; -export const BlocklistLinuxProperties = z.object({ - list_id: z.literal('endpoint_blocklists'), - /** +export const BlocklistLinuxProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_blocklists'), + /** * **Validation rules:** * Hash entries: up to 3 (one for each hash type: md5, sha1, sha256) * Path entry: only 1 allowed */ - entries: z.array(BlocklistHashOrPathEntry).min(1).optional(), - /** - * Linux-only - */ - os_types: z.array(z.literal('linux')).min(1).max(1).optional(), - tags: EndpointArtifactTags.optional(), -}); + entries: z.array(BlocklistHashOrPathEntry).min(1).optional(), + /** + * Linux-only + */ + os_types: z.array(z.literal('linux')).min(1).max(1).optional(), + tags: EndpointArtifactTags.optional(), + }) +); +export type BlocklistLinuxProperties = z.infer; /** * Blocklist list item properties (macOS, code signature not supported). */ -export type BlocklistMacProperties = z.infer; -export const BlocklistMacProperties = z.object({ - list_id: z.literal('endpoint_blocklists'), - /** +export const BlocklistMacProperties = lazySchema(() => + z.object({ + list_id: z.literal('endpoint_blocklists'), + /** * **Validation rules:** * Hash entries: up to 3 (one for each hash type: md5, sha1, sha256) * Path entry: only 1 allowed */ - entries: z.array(BlocklistHashOrPathEntry).min(1).optional(), - /** - * macOS-only - */ - os_types: z.array(z.literal('macos')).min(1).max(1).optional(), - tags: EndpointArtifactTags.optional(), -}); + entries: z.array(BlocklistHashOrPathEntry).min(1).optional(), + /** + * macOS-only + */ + os_types: z.array(z.literal('macos')).min(1).max(1).optional(), + tags: EndpointArtifactTags.optional(), + }) +); +export type BlocklistMacProperties = z.infer; +export const ExceptionListItem = lazySchema(() => + z.object({ + id: ExceptionListItemId, + item_id: ExceptionListItemHumanId, + list_id: ExceptionListHumanId, + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + entries: ExceptionListItemEntryArray, + namespace_type: ExceptionNamespaceType, + os_types: ExceptionListItemOsTypeArray.optional(), + tags: ExceptionListItemTags.optional(), + meta: ExceptionListItemMeta.optional(), + expire_time: ExceptionListItemExpireTime.optional(), + comments: ExceptionListItemCommentArray, + /** + * The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. + */ + _version: z.string().optional(), + /** + * Field used in search to ensure all containers are sorted and returned correctly. + */ + tie_breaker_id: z.string(), + /** + * Autogenerated date of object creation. + */ + created_at: z.string().datetime(), + /** + * Autogenerated value - user that created object. + */ + created_by: z.string(), + /** + * Autogenerated date of last object update. + */ + updated_at: z.string().datetime(), + /** + * Autogenerated value - user that last updated object. + */ + updated_by: z.string(), + }) +); export type ExceptionListItem = z.infer; -export const ExceptionListItem = z.object({ - id: ExceptionListItemId, - item_id: ExceptionListItemHumanId, - list_id: ExceptionListHumanId, - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - entries: ExceptionListItemEntryArray, - namespace_type: ExceptionNamespaceType, - os_types: ExceptionListItemOsTypeArray.optional(), - tags: ExceptionListItemTags.optional(), - meta: ExceptionListItemMeta.optional(), - expire_time: ExceptionListItemExpireTime.optional(), - comments: ExceptionListItemCommentArray, - /** - * The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. - */ - _version: z.string().optional(), - /** - * Field used in search to ensure all containers are sorted and returned correctly. - */ - tie_breaker_id: z.string(), - /** - * Autogenerated date of object creation. - */ - created_at: z.string().datetime(), - /** - * Autogenerated value - user that created object. - */ - created_by: z.string(), - /** - * Autogenerated date of last object update. - */ - updated_at: z.string().datetime(), - /** - * Autogenerated value - user that last updated object. - */ - updated_by: z.string(), -}); +export const ExceptionListSO = lazySchema(() => + z.object({ + item_id: ExceptionListItemHumanId.optional(), + list_id: ExceptionListHumanId, + list_type: z.enum(['item', 'list']), + immutable: z.boolean().optional(), + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + entries: ExceptionListItemEntryArray.optional(), + os_types: ExceptionListItemOsTypeArray.optional(), + tags: ExceptionListItemTags.optional(), + meta: ExceptionListItemMeta.optional(), + expire_time: ExceptionListItemExpireTime.optional(), + comments: ExceptionListItemCommentArray.optional(), + version: NonEmptyString.optional(), + /** + * Field used in search to ensure all containers are sorted and returned correctly. + */ + tie_breaker_id: z.string(), + /** + * Autogenerated date of object creation. + */ + created_at: z.string().datetime(), + /** + * Autogenerated value - user that created object. + */ + created_by: z.string(), + /** + * Autogenerated value - user that last updated object. + */ + updated_by: z.string(), + }) +); export type ExceptionListSO = z.infer; -export const ExceptionListSO = z.object({ - item_id: ExceptionListItemHumanId.optional(), - list_id: ExceptionListHumanId, - list_type: z.enum(['item', 'list']), - immutable: z.boolean().optional(), - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - entries: ExceptionListItemEntryArray.optional(), - os_types: ExceptionListItemOsTypeArray.optional(), - tags: ExceptionListItemTags.optional(), - meta: ExceptionListItemMeta.optional(), - expire_time: ExceptionListItemExpireTime.optional(), - comments: ExceptionListItemCommentArray.optional(), - version: NonEmptyString.optional(), - /** - * Field used in search to ensure all containers are sorted and returned correctly. - */ - tie_breaker_id: z.string(), - /** - * Autogenerated date of object creation. - */ - created_at: z.string().datetime(), - /** - * Autogenerated value - user that created object. - */ - created_by: z.string(), - /** - * Autogenerated value - user that last updated object. - */ - updated_by: z.string(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_item_entry.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_item_entry.gen.ts index 2573715f45953..28ae08ca7238a 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_item_entry.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/model/exception_list_item_entry.gen.ts @@ -14,55 +14,65 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; import { ListId, ListType } from '@kbn/securitysolution-lists-common/api/model/list_common.gen'; +export const ExceptionListItemEntryOperator = lazySchema(() => z.enum(['excluded', 'included'])); export type ExceptionListItemEntryOperator = z.infer; -export const ExceptionListItemEntryOperator = z.enum(['excluded', 'included']); export type ExceptionListItemEntryOperatorEnum = typeof ExceptionListItemEntryOperator.enum; export const ExceptionListItemEntryOperatorEnum = ExceptionListItemEntryOperator.enum; +export const ExceptionListItemEntryMatch = lazySchema(() => + z.object({ + type: z.literal('match'), + field: NonEmptyString, + value: NonEmptyString, + operator: ExceptionListItemEntryOperator, + }) +); export type ExceptionListItemEntryMatch = z.infer; -export const ExceptionListItemEntryMatch = z.object({ - type: z.literal('match'), - field: NonEmptyString, - value: NonEmptyString, - operator: ExceptionListItemEntryOperator, -}); +export const ExceptionListItemEntryMatchAny = lazySchema(() => + z.object({ + type: z.literal('match_any'), + field: NonEmptyString, + value: z.array(NonEmptyString).min(1), + operator: ExceptionListItemEntryOperator, + }) +); export type ExceptionListItemEntryMatchAny = z.infer; -export const ExceptionListItemEntryMatchAny = z.object({ - type: z.literal('match_any'), - field: NonEmptyString, - value: z.array(NonEmptyString).min(1), - operator: ExceptionListItemEntryOperator, -}); +export const ExceptionListItemEntryList = lazySchema(() => + z.object({ + type: z.literal('list'), + field: NonEmptyString, + list: z.object({ + id: ListId, + type: ListType, + }), + operator: ExceptionListItemEntryOperator, + }) +); export type ExceptionListItemEntryList = z.infer; -export const ExceptionListItemEntryList = z.object({ - type: z.literal('list'), - field: NonEmptyString, - list: z.object({ - id: ListId, - type: ListType, - }), - operator: ExceptionListItemEntryOperator, -}); +export const ExceptionListItemEntryExists = lazySchema(() => + z.object({ + type: z.literal('exists'), + field: NonEmptyString, + operator: ExceptionListItemEntryOperator, + }) +); export type ExceptionListItemEntryExists = z.infer; -export const ExceptionListItemEntryExists = z.object({ - type: z.literal('exists'), - field: NonEmptyString, - operator: ExceptionListItemEntryOperator, -}); -export const ExceptionListItemEntryNestedEntryItemInternal = z.union([ - ExceptionListItemEntryMatch, - ExceptionListItemEntryMatchAny, - ExceptionListItemEntryExists, -]); +export const ExceptionListItemEntryNestedEntryItemInternal = lazySchema(() => + z.union([ + ExceptionListItemEntryMatch, + ExceptionListItemEntryMatchAny, + ExceptionListItemEntryExists, + ]) +); export type ExceptionListItemEntryNestedEntryItem = z.infer< typeof ExceptionListItemEntryNestedEntryItemInternal @@ -70,35 +80,41 @@ export type ExceptionListItemEntryNestedEntryItem = z.infer< export const ExceptionListItemEntryNestedEntryItem = ExceptionListItemEntryNestedEntryItemInternal as z.ZodType; +export const ExceptionListItemEntryNested = lazySchema(() => + z.object({ + type: z.literal('nested'), + field: NonEmptyString, + entries: z.array(ExceptionListItemEntryNestedEntryItem).min(1), + }) +); export type ExceptionListItemEntryNested = z.infer; -export const ExceptionListItemEntryNested = z.object({ - type: z.literal('nested'), - field: NonEmptyString, - entries: z.array(ExceptionListItemEntryNestedEntryItem).min(1), -}); +export const ExceptionListItemEntryMatchWildcard = lazySchema(() => + z.object({ + type: z.literal('wildcard'), + field: NonEmptyString, + value: NonEmptyString, + operator: ExceptionListItemEntryOperator, + }) +); export type ExceptionListItemEntryMatchWildcard = z.infer< typeof ExceptionListItemEntryMatchWildcard >; -export const ExceptionListItemEntryMatchWildcard = z.object({ - type: z.literal('wildcard'), - field: NonEmptyString, - value: NonEmptyString, - operator: ExceptionListItemEntryOperator, -}); -export const ExceptionListItemEntryInternal = z.discriminatedUnion('type', [ - ExceptionListItemEntryMatch, - ExceptionListItemEntryMatchAny, - ExceptionListItemEntryList, - ExceptionListItemEntryExists, - ExceptionListItemEntryNested, - ExceptionListItemEntryMatchWildcard, -]); +export const ExceptionListItemEntryInternal = lazySchema(() => + z.discriminatedUnion('type', [ + ExceptionListItemEntryMatch, + ExceptionListItemEntryMatchAny, + ExceptionListItemEntryList, + ExceptionListItemEntryExists, + ExceptionListItemEntryNested, + ExceptionListItemEntryMatchWildcard, + ]) +); export type ExceptionListItemEntry = z.infer; export const ExceptionListItemEntry = ExceptionListItemEntryInternal as z.ZodType; +export const ExceptionListItemEntryArray = lazySchema(() => z.array(ExceptionListItemEntry)); export type ExceptionListItemEntryArray = z.infer; -export const ExceptionListItemEntryArray = z.array(ExceptionListItemEntry); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list/read_exception_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list/read_exception_list.gen.ts index 223b0d191d7d7..8b2ae497bc4c9 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list/read_exception_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list/read_exception_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListId, @@ -23,19 +23,21 @@ import { ExceptionList, } from '../model/exception_list_common.gen'; +export const ReadExceptionListRequestQuery = lazySchema(() => + z.object({ + /** + * Exception list's identifier. Either `id` or `list_id` must be specified. + */ + id: ExceptionListId.optional(), + /** + * Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. + */ + list_id: ExceptionListHumanId.optional(), + namespace_type: ExceptionNamespaceType.optional().default('single'), + }) +); export type ReadExceptionListRequestQuery = z.infer; -export const ReadExceptionListRequestQuery = z.object({ - /** - * Exception list's identifier. Either `id` or `list_id` must be specified. - */ - id: ExceptionListId.optional(), - /** - * Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. - */ - list_id: ExceptionListHumanId.optional(), - namespace_type: ExceptionNamespaceType.optional().default('single'), -}); export type ReadExceptionListRequestQueryInput = z.input; +export const ReadExceptionListResponse = lazySchema(() => ExceptionList); export type ReadExceptionListResponse = z.infer; -export const ReadExceptionListResponse = ExceptionList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_item/read_exception_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_item/read_exception_list_item.gen.ts index 9a97d7dbc1326..092febe31abf0 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_item/read_exception_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_item/read_exception_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListItemId, @@ -23,21 +23,23 @@ import { ExceptionListItem, } from '../model/exception_list_common.gen'; +export const ReadExceptionListItemRequestQuery = lazySchema(() => + z.object({ + /** + * Exception list item's identifier. Either `id` or `item_id` must be specified. + */ + id: ExceptionListItemId.optional(), + /** + * Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified. + */ + item_id: ExceptionListItemHumanId.optional(), + namespace_type: ExceptionNamespaceType.optional().default('single'), + }) +); export type ReadExceptionListItemRequestQuery = z.infer; -export const ReadExceptionListItemRequestQuery = z.object({ - /** - * Exception list item's identifier. Either `id` or `item_id` must be specified. - */ - id: ExceptionListItemId.optional(), - /** - * Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified. - */ - item_id: ExceptionListItemHumanId.optional(), - namespace_type: ExceptionNamespaceType.optional().default('single'), -}); export type ReadExceptionListItemRequestQueryInput = z.input< typeof ReadExceptionListItemRequestQuery >; +export const ReadExceptionListItemResponse = lazySchema(() => ExceptionListItem); export type ReadExceptionListItemResponse = z.infer; -export const ReadExceptionListItemResponse = ExceptionListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_summary/read_exception_list_summary.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_summary/read_exception_list_summary.gen.ts index 44123295e35d6..e801ed6d3b0d0 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_summary/read_exception_list_summary.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/read_exception_list_summary/read_exception_list_summary.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListId, @@ -22,32 +22,36 @@ import { ExceptionNamespaceType, } from '../model/exception_list_common.gen'; +export const ReadExceptionListSummaryRequestQuery = lazySchema(() => + z.object({ + /** + * Exception list's identifier generated upon creation. + */ + id: ExceptionListId.optional(), + /** + * Exception list's human readable identifier. + */ + list_id: ExceptionListHumanId.optional(), + namespace_type: ExceptionNamespaceType.optional().default('single'), + /** + * Search filter clause + */ + filter: z.string().optional(), + }) +); export type ReadExceptionListSummaryRequestQuery = z.infer< typeof ReadExceptionListSummaryRequestQuery >; -export const ReadExceptionListSummaryRequestQuery = z.object({ - /** - * Exception list's identifier generated upon creation. - */ - id: ExceptionListId.optional(), - /** - * Exception list's human readable identifier. - */ - list_id: ExceptionListHumanId.optional(), - namespace_type: ExceptionNamespaceType.optional().default('single'), - /** - * Search filter clause - */ - filter: z.string().optional(), -}); export type ReadExceptionListSummaryRequestQueryInput = z.input< typeof ReadExceptionListSummaryRequestQuery >; +export const ReadExceptionListSummaryResponse = lazySchema(() => + z.object({ + windows: z.number().int().min(0).optional(), + linux: z.number().int().min(0).optional(), + macos: z.number().int().min(0).optional(), + total: z.number().int().min(0).optional(), + }) +); export type ReadExceptionListSummaryResponse = z.infer; -export const ReadExceptionListSummaryResponse = z.object({ - windows: z.number().int().min(0).optional(), - linux: z.number().int().min(0).optional(), - macos: z.number().int().min(0).optional(), - total: z.number().int().min(0).optional(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list/update_exception_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list/update_exception_list.gen.ts index a1998bc910ff6..e4f4a1e3e59ea 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list/update_exception_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list/update_exception_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ExceptionListId, @@ -30,24 +30,26 @@ import { ExceptionList, } from '../model/exception_list_common.gen'; +export const UpdateExceptionListRequestBody = lazySchema(() => + z.object({ + id: ExceptionListId.optional(), + list_id: ExceptionListHumanId.optional(), + name: ExceptionListName, + description: ExceptionListDescription, + type: ExceptionListType, + namespace_type: ExceptionNamespaceType.optional().default('single'), + os_types: ExceptionListOsTypeArray.optional().default([]), + tags: ExceptionListTags.optional(), + meta: ExceptionListMeta.optional(), + version: ExceptionListVersion.optional(), + /** + * The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. + */ + _version: z.string().optional(), + }) +); export type UpdateExceptionListRequestBody = z.infer; -export const UpdateExceptionListRequestBody = z.object({ - id: ExceptionListId.optional(), - list_id: ExceptionListHumanId.optional(), - name: ExceptionListName, - description: ExceptionListDescription, - type: ExceptionListType, - namespace_type: ExceptionNamespaceType.optional().default('single'), - os_types: ExceptionListOsTypeArray.optional().default([]), - tags: ExceptionListTags.optional(), - meta: ExceptionListMeta.optional(), - version: ExceptionListVersion.optional(), - /** - * The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. - */ - _version: z.string().optional(), -}); export type UpdateExceptionListRequestBodyInput = z.input; +export const UpdateExceptionListResponse = lazySchema(() => ExceptionList); export type UpdateExceptionListResponse = z.infer; -export const UpdateExceptionListResponse = ExceptionList; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts index 32f837651aa80..3aadfff9bb193 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exceptions-common/api/update_exception_list_item/update_exception_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '@kbn/openapi-common/schemas/primitives.gen'; import { @@ -45,147 +45,163 @@ import { } from '../model/exception_list_common.gen'; import { ExceptionListItemEntryArray } from '../model/exception_list_item_entry.gen'; +export const UpdateExceptionListItemComment = lazySchema(() => + z.object({ + id: NonEmptyString.optional(), + comment: NonEmptyString, + }) +); export type UpdateExceptionListItemComment = z.infer; -export const UpdateExceptionListItemComment = z.object({ - id: NonEmptyString.optional(), - comment: NonEmptyString, -}); +export const UpdateExceptionListItemCommentArray = lazySchema(() => + z.array(UpdateExceptionListItemComment) +); export type UpdateExceptionListItemCommentArray = z.infer< typeof UpdateExceptionListItemCommentArray >; -export const UpdateExceptionListItemCommentArray = z.array(UpdateExceptionListItemComment); -export type UpdateExceptionListItemBase = z.infer; -export const UpdateExceptionListItemBase = z.object({ - /** - * Either `id` or `item_id` must be specified - */ - id: ExceptionListItemId.optional(), - /** - * Either `id` or `item_id` must be specified - */ - item_id: ExceptionListItemHumanId.optional(), - type: ExceptionListItemType, - name: ExceptionListItemName, - description: ExceptionListItemDescription, - namespace_type: ExceptionNamespaceType.optional().default('single'), - meta: ExceptionListItemMeta.optional(), - expire_time: ExceptionListItemExpireTime.optional(), - comments: UpdateExceptionListItemCommentArray.optional().default([]), - /** - * The version ID, normally returned by the API when the item is retrieved. Use it to ensure updates are made against the latest version. - */ - _version: z.string().optional(), -}); - -export type UpdateExceptionListItemGeneric = z.infer; -export const UpdateExceptionListItemGeneric = UpdateExceptionListItemBase.extend( +export const UpdateExceptionListItemBase = lazySchema(() => z.object({ - list_id: ExceptionListHumanId.optional(), - entries: ExceptionListItemEntryArray, - os_types: ExceptionListItemOsTypeArray.optional().default([]), - tags: ExceptionListItemTags.optional(), + /** + * Either `id` or `item_id` must be specified + */ + id: ExceptionListItemId.optional(), + /** + * Either `id` or `item_id` must be specified + */ + item_id: ExceptionListItemHumanId.optional(), + type: ExceptionListItemType, + name: ExceptionListItemName, + description: ExceptionListItemDescription, + namespace_type: ExceptionNamespaceType.optional().default('single'), + meta: ExceptionListItemMeta.optional(), + expire_time: ExceptionListItemExpireTime.optional(), + comments: UpdateExceptionListItemCommentArray.optional().default([]), + /** + * The version ID, normally returned by the API when the item is retrieved. Use it to ensure updates are made against the latest version. + */ + _version: z.string().optional(), }) ); +export type UpdateExceptionListItemBase = z.infer; +export const UpdateExceptionListItemGeneric = lazySchema(() => + UpdateExceptionListItemBase.merge( + z.object({ + list_id: ExceptionListHumanId.optional(), + entries: ExceptionListItemEntryArray, + os_types: ExceptionListItemOsTypeArray.optional().default([]), + tags: ExceptionListItemTags.optional(), + }) + ) +); +export type UpdateExceptionListItemGeneric = z.infer; + +export const UpdateExceptionListItemEndpointList = lazySchema(() => + UpdateExceptionListItemBase.merge(EndpointListProperties) +); export type UpdateExceptionListItemEndpointList = z.infer< typeof UpdateExceptionListItemEndpointList >; -export const UpdateExceptionListItemEndpointList = - UpdateExceptionListItemBase.extend(EndpointListProperties); +export const UpdateExceptionListItemTrustedAppsWindows = lazySchema(() => + UpdateExceptionListItemBase.merge(TrustedAppsWindowsProperties) +); export type UpdateExceptionListItemTrustedAppsWindows = z.infer< typeof UpdateExceptionListItemTrustedAppsWindows >; -export const UpdateExceptionListItemTrustedAppsWindows = UpdateExceptionListItemBase.extend( - TrustedAppsWindowsProperties -); +export const UpdateExceptionListItemTrustedAppsMac = lazySchema(() => + UpdateExceptionListItemBase.merge(TrustedAppsMacProperties) +); export type UpdateExceptionListItemTrustedAppsMac = z.infer< typeof UpdateExceptionListItemTrustedAppsMac >; -export const UpdateExceptionListItemTrustedAppsMac = - UpdateExceptionListItemBase.extend(TrustedAppsMacProperties); +export const UpdateExceptionListItemTrustedAppsLinux = lazySchema(() => + UpdateExceptionListItemBase.merge(TrustedAppsLinuxProperties) +); export type UpdateExceptionListItemTrustedAppsLinux = z.infer< typeof UpdateExceptionListItemTrustedAppsLinux >; -export const UpdateExceptionListItemTrustedAppsLinux = UpdateExceptionListItemBase.extend( - TrustedAppsLinuxProperties -); +export const UpdateExceptionListItemTrustedDevicesWindows = lazySchema(() => + UpdateExceptionListItemBase.merge(TrustedDevicesWindowsProperties) +); export type UpdateExceptionListItemTrustedDevicesWindows = z.infer< typeof UpdateExceptionListItemTrustedDevicesWindows >; -export const UpdateExceptionListItemTrustedDevicesWindows = UpdateExceptionListItemBase.extend( - TrustedDevicesWindowsProperties -); +export const UpdateExceptionListItemTrustedDevicesMac = lazySchema(() => + UpdateExceptionListItemBase.merge(TrustedDevicesMacProperties) +); export type UpdateExceptionListItemTrustedDevicesMac = z.infer< typeof UpdateExceptionListItemTrustedDevicesMac >; -export const UpdateExceptionListItemTrustedDevicesMac = UpdateExceptionListItemBase.extend( - TrustedDevicesMacProperties -); +export const UpdateExceptionListItemTrustedDevicesWindowsMac = lazySchema(() => + UpdateExceptionListItemBase.merge(TrustedDevicesWindowsMacProperties) +); export type UpdateExceptionListItemTrustedDevicesWindowsMac = z.infer< typeof UpdateExceptionListItemTrustedDevicesWindowsMac >; -export const UpdateExceptionListItemTrustedDevicesWindowsMac = UpdateExceptionListItemBase.extend( - TrustedDevicesWindowsMacProperties -); +export const UpdateExceptionListItemEventFilters = lazySchema(() => + UpdateExceptionListItemBase.merge(EventFiltersProperties) +); export type UpdateExceptionListItemEventFilters = z.infer< typeof UpdateExceptionListItemEventFilters >; -export const UpdateExceptionListItemEventFilters = - UpdateExceptionListItemBase.extend(EventFiltersProperties); +export const UpdateExceptionListItemHostIsolation = lazySchema(() => + UpdateExceptionListItemBase.merge(HostIsolationProperties) +); export type UpdateExceptionListItemHostIsolation = z.infer< typeof UpdateExceptionListItemHostIsolation >; -export const UpdateExceptionListItemHostIsolation = - UpdateExceptionListItemBase.extend(HostIsolationProperties); +export const UpdateExceptionListItemBlocklistWindows = lazySchema(() => + UpdateExceptionListItemBase.merge(BlocklistWindowsProperties) +); export type UpdateExceptionListItemBlocklistWindows = z.infer< typeof UpdateExceptionListItemBlocklistWindows >; -export const UpdateExceptionListItemBlocklistWindows = UpdateExceptionListItemBase.extend( - BlocklistWindowsProperties -); +export const UpdateExceptionListItemBlocklistLinux = lazySchema(() => + UpdateExceptionListItemBase.merge(BlocklistLinuxProperties) +); export type UpdateExceptionListItemBlocklistLinux = z.infer< typeof UpdateExceptionListItemBlocklistLinux >; -export const UpdateExceptionListItemBlocklistLinux = - UpdateExceptionListItemBase.extend(BlocklistLinuxProperties); +export const UpdateExceptionListItemBlocklistMac = lazySchema(() => + UpdateExceptionListItemBase.merge(BlocklistMacProperties) +); export type UpdateExceptionListItemBlocklistMac = z.infer< typeof UpdateExceptionListItemBlocklistMac >; -export const UpdateExceptionListItemBlocklistMac = - UpdateExceptionListItemBase.extend(BlocklistMacProperties); +export const UpdateExceptionListItemRequestBody = lazySchema(() => + z.union([ + UpdateExceptionListItemGeneric, + UpdateExceptionListItemEndpointList, + UpdateExceptionListItemTrustedAppsWindows, + UpdateExceptionListItemTrustedAppsMac, + UpdateExceptionListItemTrustedAppsLinux, + UpdateExceptionListItemTrustedDevicesWindows, + UpdateExceptionListItemTrustedDevicesMac, + UpdateExceptionListItemTrustedDevicesWindowsMac, + UpdateExceptionListItemEventFilters, + UpdateExceptionListItemHostIsolation, + UpdateExceptionListItemBlocklistWindows, + UpdateExceptionListItemBlocklistLinux, + UpdateExceptionListItemBlocklistMac, + ]) +); export type UpdateExceptionListItemRequestBody = z.infer; -export const UpdateExceptionListItemRequestBody = z.union([ - UpdateExceptionListItemGeneric, - UpdateExceptionListItemEndpointList, - UpdateExceptionListItemTrustedAppsWindows, - UpdateExceptionListItemTrustedAppsMac, - UpdateExceptionListItemTrustedAppsLinux, - UpdateExceptionListItemTrustedDevicesWindows, - UpdateExceptionListItemTrustedDevicesMac, - UpdateExceptionListItemTrustedDevicesWindowsMac, - UpdateExceptionListItemEventFilters, - UpdateExceptionListItemHostIsolation, - UpdateExceptionListItemBlocklistWindows, - UpdateExceptionListItemBlocklistLinux, - UpdateExceptionListItemBlocklistMac, -]); export type UpdateExceptionListItemRequestBodyInput = z.input< typeof UpdateExceptionListItemRequestBody >; +export const UpdateExceptionListItemResponse = lazySchema(() => ExceptionListItem); export type UpdateExceptionListItemResponse = z.infer; -export const UpdateExceptionListItemResponse = ExceptionListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list/create_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list/create_list.gen.ts index 6d6ae81191764..e9858b9b4b223 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list/create_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list/create_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId, @@ -25,16 +25,18 @@ import { } from '../model/list_common.gen'; import { List } from '../model/list_schemas.gen'; +export const CreateListRequestBody = lazySchema(() => + z.object({ + id: ListId.optional(), + name: ListName, + description: ListDescription, + type: ListType, + meta: ListMetadata.optional(), + version: z.number().int().min(1).optional().default(1), + }) +); export type CreateListRequestBody = z.infer; -export const CreateListRequestBody = z.object({ - id: ListId.optional(), - name: ListName, - description: ListDescription, - type: ListType, - meta: ListMetadata.optional(), - version: z.number().int().min(1).optional().default(1), -}); export type CreateListRequestBodyInput = z.input; +export const CreateListResponse = lazySchema(() => List); export type CreateListResponse = z.infer; -export const CreateListResponse = List; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.gen.ts index c7c180aaf54f9..5de07ca22de0f 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.gen.ts @@ -14,9 +14,11 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const CreateListIndexResponse = lazySchema(() => + z.object({ + acknowledged: z.boolean(), + }) +); export type CreateListIndexResponse = z.infer; -export const CreateListIndexResponse = z.object({ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.gen.ts index 4f80a1c0b9783..bdd60f5bd166d 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.gen.ts @@ -14,23 +14,25 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListItemId, ListId, ListItemValue, ListItemMetadata } from '../model/list_common.gen'; import { ListItem } from '../model/list_schemas.gen'; +export const CreateListItemRequestBody = lazySchema(() => + z.object({ + id: ListItemId.optional(), + list_id: ListId, + value: ListItemValue, + meta: ListItemMetadata.optional(), + /** + * Determines when changes made by the request are made visible to search. + */ + refresh: z.enum(['true', 'false', 'wait_for']).optional(), + }) +); export type CreateListItemRequestBody = z.infer; -export const CreateListItemRequestBody = z.object({ - id: ListItemId.optional(), - list_id: ListId, - value: ListItemValue, - meta: ListItemMetadata.optional(), - /** - * Determines when changes made by the request are made visible to search. - */ - refresh: z.enum(['true', 'false', 'wait_for']).optional(), -}); export type CreateListItemRequestBodyInput = z.input; +export const CreateListItemResponse = lazySchema(() => ListItem); export type CreateListItemResponse = z.infer; -export const CreateListItemResponse = ListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.gen.ts index e62bc67de9a40..fe4900d4cb926 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.gen.ts @@ -14,25 +14,27 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { ListId } from '../model/list_common.gen'; import { List } from '../model/list_schemas.gen'; +export const DeleteListRequestQuery = lazySchema(() => + z.object({ + id: ListId, + /** + * Determines whether exception items referencing this value list should be deleted. + */ + deleteReferences: BooleanFromString.optional().default(false), + /** + * Determines whether to delete value list without performing any additional checks of where this list may be utilized. + */ + ignoreReferences: BooleanFromString.optional().default(false), + }) +); export type DeleteListRequestQuery = z.infer; -export const DeleteListRequestQuery = z.object({ - id: ListId, - /** - * Determines whether exception items referencing this value list should be deleted. - */ - deleteReferences: BooleanFromString.optional().default(false), - /** - * Determines whether to delete value list without performing any additional checks of where this list may be utilized. - */ - ignoreReferences: BooleanFromString.optional().default(false), -}); export type DeleteListRequestQueryInput = z.input; +export const DeleteListResponse = lazySchema(() => List); export type DeleteListResponse = z.infer; -export const DeleteListResponse = List; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.gen.ts index 959632c27d42b..189557cec0bbf 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.gen.ts @@ -14,9 +14,11 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const DeleteListIndexResponse = lazySchema(() => + z.object({ + acknowledged: z.boolean(), + }) +); export type DeleteListIndexResponse = z.infer; -export const DeleteListIndexResponse = z.object({ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.gen.ts index e1cf78bbda8d3..217e81e2980c0 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.gen.ts @@ -14,31 +14,33 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListItemId, ListId } from '../model/list_common.gen'; import { ListItem } from '../model/list_schemas.gen'; +export const DeleteListItemRequestQuery = lazySchema(() => + z.object({ + /** + * Value list item's identifier. Required if `list_id` and `value` are not specified. + */ + id: ListItemId.optional(), + /** + * Value list's identifier. Required if `id` is not specified. + */ + list_id: ListId.optional(), + /** + * The value used to evaluate exceptions. Required if `id` is not specified. + */ + value: z.string().optional(), + /** + * Determines when changes made by the request are made visible to search. + */ + refresh: z.enum(['true', 'false', 'wait_for']).optional().default('false'), + }) +); export type DeleteListItemRequestQuery = z.infer; -export const DeleteListItemRequestQuery = z.object({ - /** - * Value list item's identifier. Required if `list_id` and `value` are not specified. - */ - id: ListItemId.optional(), - /** - * Value list's identifier. Required if `id` is not specified. - */ - list_id: ListId.optional(), - /** - * The value used to evaluate exceptions. Required if `id` is not specified. - */ - value: z.string().optional(), - /** - * Determines when changes made by the request are made visible to search. - */ - refresh: z.enum(['true', 'false', 'wait_for']).optional().default('false'), -}); export type DeleteListItemRequestQueryInput = z.input; +export const DeleteListItemResponse = lazySchema(() => z.union([ListItem, z.array(ListItem)])); export type DeleteListItemResponse = z.infer; -export const DeleteListItemResponse = z.union([ListItem, z.array(ListItem)]); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.gen.ts index 894a44df7e460..f4c135c1dd5da 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.gen.ts @@ -14,15 +14,17 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId } from '../model/list_common.gen'; +export const ExportListItemsRequestQuery = lazySchema(() => + z.object({ + /** + * Value list's `id` to export. + */ + list_id: ListId, + }) +); export type ExportListItemsRequestQuery = z.infer; -export const ExportListItemsRequestQuery = z.object({ - /** - * Value list's `id` to export. - */ - list_id: ListId, -}); export type ExportListItemsRequestQueryInput = z.input; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.gen.ts index a3b7e689da39a..3a0e95f7ec132 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; import { ListId } from '../model/list_common.gen'; @@ -23,46 +23,52 @@ import { ListItem } from '../model/list_schemas.gen'; /** * Returns the items that come after the last item returned in the previous call (use the `cursor` value returned in the previous call). This parameter uses the `tie_breaker_id` field to ensure all items are sorted and returned correctly. */ +export const FindListItemsCursor = lazySchema(() => + z.string().min(1).superRefine(isNonEmptyString) +); export type FindListItemsCursor = z.infer; -export const FindListItemsCursor = z.string().min(1).superRefine(isNonEmptyString); +export const FindListItemsFilter = lazySchema(() => z.string()); export type FindListItemsFilter = z.infer; -export const FindListItemsFilter = z.string(); -export type FindListItemsRequestQuery = z.infer; -export const FindListItemsRequestQuery = z.object({ - list_id: ListId, - /** - * The page number to return. - */ - page: z.coerce.number().int().optional(), - /** - * The number of list items to return per page. - */ - per_page: z.coerce.number().int().optional(), - /** - * Determines which field is used to sort the results. - */ - sort_field: z.string().min(1).superRefine(isNonEmptyString).optional(), - /** - * Determines the sort order, which can be `desc` or `asc` - */ - sort_order: z.enum(['desc', 'asc']).optional(), - cursor: FindListItemsCursor.optional(), - /** +export const FindListItemsRequestQuery = lazySchema(() => + z.object({ + list_id: ListId, + /** + * The page number to return. + */ + page: z.coerce.number().int().optional(), + /** + * The number of list items to return per page. + */ + per_page: z.coerce.number().int().optional(), + /** + * Determines which field is used to sort the results. + */ + sort_field: z.string().min(1).superRefine(isNonEmptyString).optional(), + /** + * Determines the sort order, which can be `desc` or `asc` + */ + sort_order: z.enum(['desc', 'asc']).optional(), + cursor: FindListItemsCursor.optional(), + /** * Filters the returned results according to the value of the specified field, using the : syntax. */ - filter: FindListItemsFilter.optional(), -}); + filter: FindListItemsFilter.optional(), + }) +); +export type FindListItemsRequestQuery = z.infer; export type FindListItemsRequestQueryInput = z.input; +export const FindListItemsResponse = lazySchema(() => + z.object({ + data: z.array(ListItem), + page: z.number().int().min(0), + per_page: z.number().int().min(0), + total: z.number().int().min(0), + cursor: FindListItemsCursor, + }) +); export type FindListItemsResponse = z.infer; -export const FindListItemsResponse = z.object({ - data: z.array(ListItem), - page: z.number().int().min(0), - per_page: z.number().int().min(0), - total: z.number().int().min(0), - cursor: FindListItemsCursor, -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.gen.ts index 397e35f01afe0..60efea1735267 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.gen.ts @@ -14,53 +14,57 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; import { List } from '../model/list_schemas.gen'; +export const FindListsCursor = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type FindListsCursor = z.infer; -export const FindListsCursor = z.string().min(1).superRefine(isNonEmptyString); +export const FindListsFilter = lazySchema(() => z.string()); export type FindListsFilter = z.infer; -export const FindListsFilter = z.string(); -export type FindListsRequestQuery = z.infer; -export const FindListsRequestQuery = z.object({ - /** - * The page number to return. - */ - page: z.coerce.number().int().optional(), - /** - * The number of value lists to return per page. - */ - per_page: z.coerce.number().int().optional(), - /** - * Determines which field is used to sort the results. - */ - sort_field: z.string().min(1).superRefine(isNonEmptyString).optional(), - /** - * Determines the sort order, which can be `desc` or `asc` - */ - sort_order: z.enum(['desc', 'asc']).optional(), - /** - * Returns the lists that come after the last lists returned in the previous call (use the `cursor` value returned in the previous call). This parameter uses the `tie_breaker_id` field to ensure all lists are sorted and returned correctly. - */ - cursor: FindListsCursor.optional(), - /** +export const FindListsRequestQuery = lazySchema(() => + z.object({ + /** + * The page number to return. + */ + page: z.coerce.number().int().optional(), + /** + * The number of value lists to return per page. + */ + per_page: z.coerce.number().int().optional(), + /** + * Determines which field is used to sort the results. + */ + sort_field: z.string().min(1).superRefine(isNonEmptyString).optional(), + /** + * Determines the sort order, which can be `desc` or `asc` + */ + sort_order: z.enum(['desc', 'asc']).optional(), + /** + * Returns the lists that come after the last lists returned in the previous call (use the `cursor` value returned in the previous call). This parameter uses the `tie_breaker_id` field to ensure all lists are sorted and returned correctly. + */ + cursor: FindListsCursor.optional(), + /** * Filters the returned results according to the value of the specified field, using the : syntax. */ - filter: FindListsFilter.optional(), -}); + filter: FindListsFilter.optional(), + }) +); +export type FindListsRequestQuery = z.infer; export type FindListsRequestQueryInput = z.input; +export const FindListsResponse = lazySchema(() => + z.object({ + data: z.array(List), + page: z.number().int().min(0), + per_page: z.number().int().min(0), + total: z.number().int().min(0), + cursor: FindListsCursor, + }) +); export type FindListsResponse = z.infer; -export const FindListsResponse = z.object({ - data: z.array(List), - page: z.number().int().min(0), - per_page: z.number().int().min(0), - total: z.number().int().min(0), - cursor: FindListsCursor, -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.gen.ts index 3232d0d9e5916..7f5608f45f822 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.gen.ts @@ -14,33 +14,35 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId, ListType } from '../model/list_common.gen'; import { List } from '../model/list_schemas.gen'; -export type ImportListItemsRequestQuery = z.infer; -export const ImportListItemsRequestQuery = z.object({ - /** +export const ImportListItemsRequestQuery = lazySchema(() => + z.object({ + /** * List's id. Required when importing to an existing list. */ - list_id: ListId.optional(), - /** + list_id: ListId.optional(), + /** * Type of the importing list. Required when importing a new list whose list `id` is not specified. */ - type: ListType.optional(), - /** - * Determines when changes made by the request are made visible to search. - */ - refresh: z.enum(['true', 'false', 'wait_for']).optional(), -}); + type: ListType.optional(), + /** + * Determines when changes made by the request are made visible to search. + */ + refresh: z.enum(['true', 'false', 'wait_for']).optional(), + }) +); +export type ImportListItemsRequestQuery = z.infer; export type ImportListItemsRequestQueryInput = z.input; +export const ImportListItemsResponse = lazySchema(() => List); export type ImportListItemsResponse = z.infer; -export const ImportListItemsResponse = List; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_common.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_common.gen.ts index a87fde676c0e0..0c3806fb56618 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_common.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_common.gen.ts @@ -14,14 +14,14 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; /** * Value list's identifier. */ +export const ListId = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type ListId = z.infer; -export const ListId = z.string().min(1).superRefine(isNonEmptyString); /** * Specifies the Elasticsearch data type of excludes the list container holds. Some common examples: @@ -31,86 +31,90 @@ export const ListId = z.string().min(1).superRefine(isNonEmptyString); - `ip_range`: Range of IP addresses (supports IPv4, IPv6, and CIDR notation) */ +export const ListType = lazySchema(() => + z.enum([ + 'binary', + 'boolean', + 'byte', + 'date', + 'date_nanos', + 'date_range', + 'double', + 'double_range', + 'float', + 'float_range', + 'geo_point', + 'geo_shape', + 'half_float', + 'integer', + 'integer_range', + 'ip', + 'ip_range', + 'keyword', + 'long', + 'long_range', + 'shape', + 'short', + 'text', + ]) +); export type ListType = z.infer; -export const ListType = z.enum([ - 'binary', - 'boolean', - 'byte', - 'date', - 'date_nanos', - 'date_range', - 'double', - 'double_range', - 'float', - 'float_range', - 'geo_point', - 'geo_shape', - 'half_float', - 'integer', - 'integer_range', - 'ip', - 'ip_range', - 'keyword', - 'long', - 'long_range', - 'shape', - 'short', - 'text', -]); export type ListTypeEnum = typeof ListType.enum; export const ListTypeEnum = ListType.enum; /** * Value list's name. */ +export const ListName = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type ListName = z.infer; -export const ListName = z.string().min(1).superRefine(isNonEmptyString); /** * Describes the value list. */ +export const ListDescription = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type ListDescription = z.infer; -export const ListDescription = z.string().min(1).superRefine(isNonEmptyString); /** * Placeholder for metadata about the value list. */ +export const ListMetadata = lazySchema(() => z.object({}).catchall(z.unknown())); export type ListMetadata = z.infer; -export const ListMetadata = z.object({}).catchall(z.unknown()); /** * The document version number. */ +export const ListVersion = lazySchema(() => z.number().int().min(1)); export type ListVersion = z.infer; -export const ListVersion = z.number().int().min(1); /** * The version id, normally returned by the API when the document is retrieved. Use it ensure updates are done against the latest version. */ +export const ListVersionId = lazySchema(() => z.string()); export type ListVersionId = z.infer; -export const ListVersionId = z.string(); /** * Value list item's identifier. */ +export const ListItemId = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type ListItemId = z.infer; -export const ListItemId = z.string().min(1).superRefine(isNonEmptyString); /** * The value used to evaluate exceptions. */ +export const ListItemValue = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type ListItemValue = z.infer; -export const ListItemValue = z.string().min(1).superRefine(isNonEmptyString); /** * Describes the value list item. */ +export const ListItemDescription = lazySchema(() => + z.string().min(1).superRefine(isNonEmptyString) +); export type ListItemDescription = z.infer; -export const ListItemDescription = z.string().min(1).superRefine(isNonEmptyString); /** * Placeholder for metadata about the value list item. */ +export const ListItemMetadata = lazySchema(() => z.object({}).catchall(z.unknown())); export type ListItemMetadata = z.infer; -export const ListItemMetadata = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_schemas.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_schemas.gen.ts index 761602feda7de..ce9575174c4a2 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_schemas.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/model/list_schemas.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId, @@ -29,66 +29,70 @@ import { ListItemMetadata, } from './list_common.gen'; +export const List = lazySchema(() => + z.object({ + id: ListId, + type: ListType, + name: ListName, + description: ListDescription, + immutable: z.boolean(), + meta: ListMetadata.optional(), + '@timestamp': z.string().datetime().optional(), + version: ListVersion, + _version: ListVersionId.optional(), + /** + * Field used in search to ensure all containers are sorted and returned correctly. + */ + tie_breaker_id: z.string(), + /** + * Autogenerated date of object creation. + */ + created_at: z.string().datetime(), + /** + * Autogenerated value - user that created object. + */ + created_by: z.string(), + /** + * Autogenerated date of last object update. + */ + updated_at: z.string().datetime(), + /** + * Autogenerated value - user that last updated object. + */ + updated_by: z.string(), + }) +); export type List = z.infer; -export const List = z.object({ - id: ListId, - type: ListType, - name: ListName, - description: ListDescription, - immutable: z.boolean(), - meta: ListMetadata.optional(), - '@timestamp': z.string().datetime().optional(), - version: ListVersion, - _version: ListVersionId.optional(), - /** - * Field used in search to ensure all containers are sorted and returned correctly. - */ - tie_breaker_id: z.string(), - /** - * Autogenerated date of object creation. - */ - created_at: z.string().datetime(), - /** - * Autogenerated value - user that created object. - */ - created_by: z.string(), - /** - * Autogenerated date of last object update. - */ - updated_at: z.string().datetime(), - /** - * Autogenerated value - user that last updated object. - */ - updated_by: z.string(), -}); +export const ListItem = lazySchema(() => + z.object({ + id: ListItemId, + type: ListType, + list_id: ListId, + value: ListItemValue, + meta: ListItemMetadata.optional(), + '@timestamp': z.string().datetime().optional(), + _version: ListVersionId.optional(), + /** + * Field used in search to ensure all containers are sorted and returned correctly. + */ + tie_breaker_id: z.string(), + /** + * Autogenerated date of object creation. + */ + created_at: z.string().datetime(), + /** + * Autogenerated value - user that created object. + */ + created_by: z.string(), + /** + * Autogenerated date of last object update. + */ + updated_at: z.string().datetime(), + /** + * Autogenerated value - user that last updated object. + */ + updated_by: z.string(), + }) +); export type ListItem = z.infer; -export const ListItem = z.object({ - id: ListItemId, - type: ListType, - list_id: ListId, - value: ListItemValue, - meta: ListItemMetadata.optional(), - '@timestamp': z.string().datetime().optional(), - _version: ListVersionId.optional(), - /** - * Field used in search to ensure all containers are sorted and returned correctly. - */ - tie_breaker_id: z.string(), - /** - * Autogenerated date of object creation. - */ - created_at: z.string().datetime(), - /** - * Autogenerated value - user that created object. - */ - created_by: z.string(), - /** - * Autogenerated date of last object update. - */ - updated_at: z.string().datetime(), - /** - * Autogenerated value - user that last updated object. - */ - updated_by: z.string(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.gen.ts index 6a8340011a014..3d4b6a62fc0f3 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId, @@ -26,16 +26,18 @@ import { } from '../model/list_common.gen'; import { List } from '../model/list_schemas.gen'; +export const PatchListRequestBody = lazySchema(() => + z.object({ + id: ListId, + name: ListName.optional(), + description: ListDescription.optional(), + meta: ListMetadata.optional(), + version: ListVersion.optional(), + _version: ListVersionId.optional(), + }) +); export type PatchListRequestBody = z.infer; -export const PatchListRequestBody = z.object({ - id: ListId, - name: ListName.optional(), - description: ListDescription.optional(), - meta: ListMetadata.optional(), - version: ListVersion.optional(), - _version: ListVersionId.optional(), -}); export type PatchListRequestBodyInput = z.input; +export const PatchListResponse = lazySchema(() => List); export type PatchListResponse = z.infer; -export const PatchListResponse = List; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.gen.ts index 52370ba048b65..11f4e75b0f1be 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListItemId, @@ -24,18 +24,20 @@ import { } from '../model/list_common.gen'; import { ListItem } from '../model/list_schemas.gen'; +export const PatchListItemRequestBody = lazySchema(() => + z.object({ + id: ListItemId, + value: ListItemValue.optional(), + meta: ListItemMetadata.optional(), + _version: ListVersionId.optional(), + /** + * Determines when changes made by the request are made visible to search. + */ + refresh: z.enum(['true', 'false', 'wait_for']).optional(), + }) +); export type PatchListItemRequestBody = z.infer; -export const PatchListItemRequestBody = z.object({ - id: ListItemId, - value: ListItemValue.optional(), - meta: ListItemMetadata.optional(), - _version: ListVersionId.optional(), - /** - * Determines when changes made by the request are made visible to search. - */ - refresh: z.enum(['true', 'false', 'wait_for']).optional(), -}); export type PatchListItemRequestBodyInput = z.input; +export const PatchListItemResponse = lazySchema(() => ListItem); export type PatchListItemResponse = z.infer; -export const PatchListItemResponse = ListItem; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list/read_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list/read_list.gen.ts index ebe92210e98a8..6abb4243af8e0 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list/read_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list/read_list.gen.ts @@ -14,16 +14,18 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId } from '../model/list_common.gen'; import { List } from '../model/list_schemas.gen'; +export const ReadListRequestQuery = lazySchema(() => + z.object({ + id: ListId, + }) +); export type ReadListRequestQuery = z.infer; -export const ReadListRequestQuery = z.object({ - id: ListId, -}); export type ReadListRequestQueryInput = z.input; +export const ReadListResponse = lazySchema(() => List); export type ReadListResponse = z.infer; -export const ReadListResponse = List; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.gen.ts index d1bc70dab2e16..fed89d3f6f6eb 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.gen.ts @@ -14,10 +14,12 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ReadListIndexResponse = lazySchema(() => + z.object({ + list_index: z.boolean(), + list_item_index: z.boolean(), + }) +); export type ReadListIndexResponse = z.infer; -export const ReadListIndexResponse = z.object({ - list_index: z.boolean(), - list_item_index: z.boolean(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.gen.ts index 27765f3cba191..5b1f38b9b6695 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.gen.ts @@ -14,27 +14,29 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId } from '../model/list_common.gen'; import { ListItem } from '../model/list_schemas.gen'; +export const ReadListItemRequestQuery = lazySchema(() => + z.object({ + /** + * Value list item identifier. Required if `list_id` and `value` are not specified. + */ + id: ListId.optional(), + /** + * Value list item list's `id` identfier. Required if `id` is not specified. + */ + list_id: ListId.optional(), + /** + * The value used to evaluate exceptions. Required if `id` is not specified. + */ + value: z.string().optional(), + }) +); export type ReadListItemRequestQuery = z.infer; -export const ReadListItemRequestQuery = z.object({ - /** - * Value list item identifier. Required if `list_id` and `value` are not specified. - */ - id: ListId.optional(), - /** - * Value list item list's `id` identfier. Required if `id` is not specified. - */ - list_id: ListId.optional(), - /** - * The value used to evaluate exceptions. Required if `id` is not specified. - */ - value: z.string().optional(), -}); export type ReadListItemRequestQueryInput = z.input; +export const ReadListItemResponse = lazySchema(() => z.union([ListItem, z.array(ListItem)])); export type ReadListItemResponse = z.infer; -export const ReadListItemResponse = z.union([ListItem, z.array(ListItem)]); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.gen.ts index 96d15727177fb..95fc4887fe7e2 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.gen.ts @@ -14,29 +14,35 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ListPrivileges = lazySchema(() => + z.object({ + username: z.string(), + has_all_requested: z.boolean(), + cluster: z.object({}).catchall(z.boolean()), + index: z.object({}).catchall(z.object({}).catchall(z.boolean())), + application: z.object({}).catchall(z.boolean()), + }) +); export type ListPrivileges = z.infer; -export const ListPrivileges = z.object({ - username: z.string(), - has_all_requested: z.boolean(), - cluster: z.object({}).catchall(z.boolean()), - index: z.object({}).catchall(z.object({}).catchall(z.boolean())), - application: z.object({}).catchall(z.boolean()), -}); +export const ListItemPrivileges = lazySchema(() => + z.object({ + username: z.string(), + has_all_requested: z.boolean(), + cluster: z.object({}).catchall(z.boolean()), + index: z.object({}).catchall(z.object({}).catchall(z.boolean())), + application: z.object({}).catchall(z.boolean()), + }) +); export type ListItemPrivileges = z.infer; -export const ListItemPrivileges = z.object({ - username: z.string(), - has_all_requested: z.boolean(), - cluster: z.object({}).catchall(z.boolean()), - index: z.object({}).catchall(z.object({}).catchall(z.boolean())), - application: z.object({}).catchall(z.boolean()), -}); +export const ReadListPrivilegesResponse = lazySchema(() => + z.object({ + lists: ListPrivileges, + listItems: ListItemPrivileges, + is_authenticated: z.boolean(), + }) +); export type ReadListPrivilegesResponse = z.infer; -export const ReadListPrivilegesResponse = z.object({ - lists: ListPrivileges, - listItems: ListItemPrivileges, - is_authenticated: z.boolean(), -}); diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list/update_list.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list/update_list.gen.ts index ae079b6403ad1..91cf4b2a9e526 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list/update_list.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list/update_list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListId, @@ -26,16 +26,18 @@ import { } from '../model/list_common.gen'; import { List } from '../model/list_schemas.gen'; +export const UpdateListRequestBody = lazySchema(() => + z.object({ + id: ListId, + name: ListName, + description: ListDescription, + meta: ListMetadata.optional(), + version: ListVersion.optional(), + _version: ListVersionId.optional(), + }) +); export type UpdateListRequestBody = z.infer; -export const UpdateListRequestBody = z.object({ - id: ListId, - name: ListName, - description: ListDescription, - meta: ListMetadata.optional(), - version: ListVersion.optional(), - _version: ListVersionId.optional(), -}); export type UpdateListRequestBodyInput = z.input; +export const UpdateListResponse = lazySchema(() => List); export type UpdateListResponse = z.infer; -export const UpdateListResponse = List; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.gen.ts b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.gen.ts index 139e91cb90914..02926a06a9305 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.gen.ts +++ b/x-pack/solutions/security/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ListItemId, @@ -24,14 +24,16 @@ import { } from '../model/list_common.gen'; import { ListItem } from '../model/list_schemas.gen'; +export const UpdateListItemRequestBody = lazySchema(() => + z.object({ + id: ListItemId, + value: ListItemValue, + meta: ListItemMetadata.optional(), + _version: ListVersionId.optional(), + }) +); export type UpdateListItemRequestBody = z.infer; -export const UpdateListItemRequestBody = z.object({ - id: ListItemId, - value: ListItemValue, - meta: ListItemMetadata.optional(), - _version: ListVersionId.optional(), -}); export type UpdateListItemRequestBodyInput = z.input; +export const UpdateListItemResponse = lazySchema(() => ListItem); export type UpdateListItemResponse = z.infer; -export const UpdateListItemResponse = ListItem; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen.ts index fc4a8ffcf7749..0cec0df318866 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen.ts @@ -15,9 +15,10 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { SetAlertAssigneesBody } from '../model/set_alert_assignees_body.gen'; +export const SetAlertAssigneesRequestBody = lazySchema(() => SetAlertAssigneesBody); export type SetAlertAssigneesRequestBody = z.infer; -export const SetAlertAssigneesRequestBody = SetAlertAssigneesBody; export type SetAlertAssigneesRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags.gen.ts index 226ea505fb9e5..201be380a2076 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags.gen.ts @@ -14,16 +14,16 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SetAlertTagsBody } from '../../model/set_alert_tags_body.gen'; +export const SetAlertTagsRequestBody = lazySchema(() => SetAlertTagsBody); export type SetAlertTagsRequestBody = z.infer; -export const SetAlertTagsRequestBody = SetAlertTagsBody; export type SetAlertTagsRequestBodyInput = z.input; /** * Elasticsearch update by query response */ +export const SetAlertTagsResponse = lazySchema(() => z.object({}).catchall(z.unknown())); export type SetAlertTagsResponse = z.infer; -export const SetAlertTagsResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/create_index/create_index.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/create_index/create_index.gen.ts index cd4364800feeb..185f681c55915 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/create_index/create_index.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/create_index/create_index.gen.ts @@ -14,9 +14,11 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const CreateAlertsIndexResponse = lazySchema(() => + z.object({ + acknowledged: z.boolean(), + }) +); export type CreateAlertsIndexResponse = z.infer; -export const CreateAlertsIndexResponse = z.object({ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/delete_index/delete_index.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/delete_index/delete_index.gen.ts index 69b8cea2e9872..33d01945d7df9 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/delete_index/delete_index.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/delete_index/delete_index.gen.ts @@ -14,9 +14,11 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const DeleteAlertsIndexResponse = lazySchema(() => + z.object({ + acknowledged: z.boolean(), + }) +); export type DeleteAlertsIndexResponse = z.infer; -export const DeleteAlertsIndexResponse = z.object({ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_index/read_index.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_index/read_index.gen.ts index 75c623e5fb817..fe4cecec97639 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_index/read_index.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_index/read_index.gen.ts @@ -14,10 +14,12 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ReadAlertsIndexResponse = lazySchema(() => + z.object({ + name: z.string(), + index_mapping_outdated: z.boolean().nullable(), + }) +); export type ReadAlertsIndexResponse = z.infer; -export const ReadAlertsIndexResponse = z.object({ - name: z.string(), - index_mapping_outdated: z.boolean().nullable(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_privileges/read_privileges.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_privileges/read_privileges.gen.ts index 63273fc28f26e..fe30134ebc33c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_privileges/read_privileges.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/index_management/read_privileges/read_privileges.gen.ts @@ -14,10 +14,12 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ReadPrivilegesResponse = lazySchema(() => + z.object({ + is_authenticated: z.boolean(), + has_encryption_key: z.boolean(), + }) +); export type ReadPrivilegesResponse = z.infer; -export const ReadPrivilegesResponse = z.object({ - is_authenticated: z.boolean(), - has_encryption_key: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/error_schema.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/error_schema.gen.ts index 9de3ca817c5fd..75c07cb11be58 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/error_schema.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/error_schema.gen.ts @@ -14,20 +14,22 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { RuleSignatureId } from './rule_schema/common_attributes.gen'; +export const ErrorSchema = lazySchema(() => + z + .object({ + id: z.string().optional(), + rule_id: RuleSignatureId.optional(), + list_id: z.string().min(1).optional(), + item_id: z.string().min(1).optional(), + error: z.object({ + status_code: z.number().int().min(400), + message: z.string(), + }), + }) + .strict() +); export type ErrorSchema = z.infer; -export const ErrorSchema = z - .object({ - id: z.string().optional(), - rule_id: RuleSignatureId.optional(), - list_id: z.string().min(1).optional(), - item_id: z.string().min(1).optional(), - error: z.object({ - status_code: z.number().int().min(400), - message: z.string(), - }), - }) - .strict(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/pagination.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/pagination.gen.ts index 782a71b55f4a7..761a936ba0ca3 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/pagination.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/pagination.gen.ts @@ -14,26 +14,28 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Page number */ +export const Page = lazySchema(() => z.number().int().min(1)); export type Page = z.infer; -export const Page = z.number().int().min(1); /** * Number of items per page */ +export const PerPage = lazySchema(() => z.number().int().min(0)); export type PerPage = z.infer; -export const PerPage = z.number().int().min(0); +export const PaginationResult = lazySchema(() => + z.object({ + page: Page, + per_page: PerPage, + /** + * Total number of items + */ + total: z.number().int().min(0), + }) +); export type PaginationResult = z.infer; -export const PaginationResult = z.object({ - page: Page, - per_page: PerPage, - /** - * Total number of items - */ - total: z.number().int().min(0), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts index fb23515066303..30c117dbc763c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts @@ -14,167 +14,189 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ResponseActionTypes = lazySchema(() => z.enum(['.osquery', '.endpoint'])); export type ResponseActionTypes = z.infer; -export const ResponseActionTypes = z.enum(['.osquery', '.endpoint']); export type ResponseActionTypesEnum = typeof ResponseActionTypes.enum; export const ResponseActionTypesEnum = ResponseActionTypes.enum; /** * Map Osquery results columns or static values to Elastic Common Schema (ECS) fields. Example: "ecs_mapping": {"process.pid": {"field": "pid"}} */ +export const EcsMapping = lazySchema(() => + z.object({}).catchall( + z.object({ + field: z.string().optional(), + value: z.union([z.string(), z.array(z.string())]).optional(), + }) + ) +); export type EcsMapping = z.infer; -export const EcsMapping = z.object({}).catchall( + +export const OsqueryQuery = lazySchema(() => z.object({ - field: z.string().optional(), - value: z.union([z.string(), z.array(z.string())]).optional(), + /** + * Query ID + */ + id: z.string(), + /** + * Query to run + */ + query: z.string(), + ecs_mapping: EcsMapping.optional(), + /** + * Query version + */ + version: z.string().optional(), + platform: z.string().optional(), + removed: z.boolean().optional(), + snapshot: z.boolean().optional(), }) ); - export type OsqueryQuery = z.infer; -export const OsqueryQuery = z.object({ - /** - * Query ID - */ - id: z.string(), - /** - * Query to run - */ - query: z.string(), - ecs_mapping: EcsMapping.optional(), - /** - * Query version - */ - version: z.string().optional(), - platform: z.string().optional(), - removed: z.boolean().optional(), - snapshot: z.boolean().optional(), -}); +export const OsqueryParams = lazySchema(() => + z.object({ + /** + * To run a single query, use the query field and enter a SQL query. Example: "query": "SELECT * FROM processes;" + */ + query: z.string().optional(), + ecs_mapping: EcsMapping.optional(), + queries: z.array(OsqueryQuery).optional(), + /** + * To specify a query pack, use the packId field. Example: "packId": "processes_elastic" + */ + pack_id: z.string().optional(), + /** + * To run a saved query, use the saved_query_id field and specify the saved query ID. Example: "saved_query_id": "processes_elastic" + */ + saved_query_id: z.string().optional(), + /** + * A timeout period, in seconds, after which the query will stop running. Overwriting the default timeout allows you to support queries that require more time to complete. The default and minimum supported value is 60. The maximum supported value is 900. Example: "timeout": 120. + */ + timeout: z.number().optional(), + }) +); export type OsqueryParams = z.infer; -export const OsqueryParams = z.object({ - /** - * To run a single query, use the query field and enter a SQL query. Example: "query": "SELECT * FROM processes;" - */ - query: z.string().optional(), - ecs_mapping: EcsMapping.optional(), - queries: z.array(OsqueryQuery).optional(), - /** - * To specify a query pack, use the packId field. Example: "packId": "processes_elastic" - */ - pack_id: z.string().optional(), - /** - * To run a saved query, use the saved_query_id field and specify the saved query ID. Example: "saved_query_id": "processes_elastic" - */ - saved_query_id: z.string().optional(), - /** - * A timeout period, in seconds, after which the query will stop running. Overwriting the default timeout allows you to support queries that require more time to complete. The default and minimum supported value is 60. The maximum supported value is 900. Example: "timeout": 120. - */ - timeout: z.number().optional(), -}); +export const OsqueryParamsCamelCase = lazySchema(() => + z.object({ + query: z.string().optional(), + ecsMapping: EcsMapping.optional(), + queries: z.array(OsqueryQuery).optional(), + packId: z.string().optional(), + savedQueryId: z.string().optional(), + timeout: z.number().optional(), + }) +); export type OsqueryParamsCamelCase = z.infer; -export const OsqueryParamsCamelCase = z.object({ - query: z.string().optional(), - ecsMapping: EcsMapping.optional(), - queries: z.array(OsqueryQuery).optional(), - packId: z.string().optional(), - savedQueryId: z.string().optional(), - timeout: z.number().optional(), -}); +export const OsqueryResponseAction = lazySchema(() => + z.object({ + action_type_id: z.literal('.osquery'), + params: OsqueryParams, + }) +); export type OsqueryResponseAction = z.infer; -export const OsqueryResponseAction = z.object({ - action_type_id: z.literal('.osquery'), - params: OsqueryParams, -}); +export const RuleResponseOsqueryAction = lazySchema(() => + z.object({ + actionTypeId: z.literal('.osquery'), + params: OsqueryParamsCamelCase, + }) +); export type RuleResponseOsqueryAction = z.infer; -export const RuleResponseOsqueryAction = z.object({ - actionTypeId: z.literal('.osquery'), - params: OsqueryParamsCamelCase, -}); +export const DefaultParams = lazySchema(() => + z.object({ + command: z.literal('isolate'), + comment: z.string().optional(), + }) +); export type DefaultParams = z.infer; -export const DefaultParams = z.object({ - command: z.literal('isolate'), - comment: z.string().optional(), -}); +export const RunScriptOsConfigValues = lazySchema(() => + z.object({ + scriptId: z.string().optional(), + scriptInput: z.string().optional(), + /** + * Specify the timeout in seconds for the script execution + */ + timeout: z.number().int().optional(), + }) +); export type RunScriptOsConfigValues = z.infer; -export const RunScriptOsConfigValues = z.object({ - scriptId: z.string().optional(), - scriptInput: z.string().optional(), - /** - * Specify the timeout in seconds for the script execution - */ - timeout: z.number().int().optional(), -}); /** * > warn > This functionality is currently not available */ +export const RunscriptParams = lazySchema(() => + z.object({ + command: z.literal('runscript'), + /** + * Add a note that explains or describes the action. You can find your comment in the response actions history log + */ + comment: z.string().optional(), + config: z + .object({ + linux: RunScriptOsConfigValues.optional(), + macos: RunScriptOsConfigValues.optional(), + windows: RunScriptOsConfigValues.optional(), + }) + .optional(), + }) +); export type RunscriptParams = z.infer; -export const RunscriptParams = z.object({ - command: z.literal('runscript'), - /** - * Add a note that explains or describes the action. You can find your comment in the response actions history log - */ - comment: z.string().optional(), - config: z - .object({ - linux: RunScriptOsConfigValues.optional(), - macos: RunScriptOsConfigValues.optional(), - windows: RunScriptOsConfigValues.optional(), - }) - .optional(), -}); -export type ProcessesParams = z.infer; -export const ProcessesParams = z.object({ - /** - * To run an endpoint response action, specify a value for the command field. Example: "command": "isolate" - */ - command: z.enum(['kill-process', 'suspend-process']), - /** - * Add a note that explains or describes the action. You can find your comment in the response actions history log. Example: "comment": "Check processes" - */ - comment: z.string().optional(), - config: z.object({ +export const ProcessesParams = lazySchema(() => + z.object({ /** - * Field to use instead of process.pid + * To run an endpoint response action, specify a value for the command field. Example: "command": "isolate" */ - field: z.string(), + command: z.enum(['kill-process', 'suspend-process']), /** - * Whether to overwrite field with process.pid + * Add a note that explains or describes the action. You can find your comment in the response actions history log. Example: "comment": "Check processes" */ - overwrite: z.boolean().optional().default(true), - }), -}); + comment: z.string().optional(), + config: z.object({ + /** + * Field to use instead of process.pid + */ + field: z.string(), + /** + * Whether to overwrite field with process.pid + */ + overwrite: z.boolean().optional().default(true), + }), + }) +); +export type ProcessesParams = z.infer; +export const EndpointResponseAction = lazySchema(() => + z.object({ + action_type_id: z.literal('.endpoint'), + params: z.union([DefaultParams, ProcessesParams, RunscriptParams]), + }) +); export type EndpointResponseAction = z.infer; -export const EndpointResponseAction = z.object({ - action_type_id: z.literal('.endpoint'), - params: z.union([DefaultParams, ProcessesParams, RunscriptParams]), -}); +export const RuleResponseEndpointAction = lazySchema(() => + z.object({ + actionTypeId: z.literal('.endpoint'), + params: z.union([DefaultParams, ProcessesParams, RunscriptParams]), + }) +); export type RuleResponseEndpointAction = z.infer; -export const RuleResponseEndpointAction = z.object({ - actionTypeId: z.literal('.endpoint'), - params: z.union([DefaultParams, ProcessesParams, RunscriptParams]), -}); +export const ResponseAction = lazySchema(() => + z.discriminatedUnion('action_type_id', [OsqueryResponseAction, EndpointResponseAction]) +); export type ResponseAction = z.infer; -export const ResponseAction = z.discriminatedUnion('action_type_id', [ - OsqueryResponseAction, - EndpointResponseAction, -]); +export const RuleResponseAction = lazySchema(() => + z.discriminatedUnion('actionTypeId', [RuleResponseOsqueryAction, RuleResponseEndpointAction]) +); export type RuleResponseAction = z.infer; -export const RuleResponseAction = z.discriminatedUnion('actionTypeId', [ - RuleResponseOsqueryAction, - RuleResponseEndpointAction, -]); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts index 0c0fb8e3eed69..bbd7fef01100c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isValidDateMath, isNonEmptyString } from '@kbn/zod-helpers/v4'; import { UUID, NonEmptyString } from '../../../model/primitives.gen'; @@ -22,26 +22,26 @@ import { UUID, NonEmptyString } from '../../../model/primitives.gen'; /** * A dynamic unique identifier for the rule object. It is randomly generated when a rule is created and cannot be changed after that. It is always a UUID. It is unique within a given Kibana space. The same prebuilt Elastic rule, when installed in two different Kibana spaces or two different Elastic environments, will have different object `id`s. */ +export const RuleObjectId = lazySchema(() => UUID); export type RuleObjectId = z.infer; -export const RuleObjectId = UUID; /** * A stable unique identifier for the rule object. It can be assigned during rule creation. It can be any string, but often is a UUID. It should be unique not only within a given Kibana space, but also across spaces and Elastic environments. The same prebuilt Elastic rule, when installed in two different Kibana spaces or two different Elastic environments, will have the same `rule_id`s. */ +export const RuleSignatureId = lazySchema(() => z.string()); export type RuleSignatureId = z.infer; -export const RuleSignatureId = z.string(); /** * A human-readable name for the rule. */ +export const RuleName = lazySchema(() => z.string().min(1)); export type RuleName = z.infer; -export const RuleName = z.string().min(1); /** * The rule’s description. */ +export const RuleDescription = lazySchema(() => z.string().min(1)); export type RuleDescription = z.infer; -export const RuleDescription = z.string().min(1); /** * The rule's version number. @@ -52,8 +52,8 @@ export const RuleDescription = z.string().min(1); > It is not incremented on each update. Compare this to the `revision` field. */ +export const RuleVersion = lazySchema(() => z.number().int().min(1)); export type RuleVersion = z.infer; -export const RuleVersion = z.number().int().min(1); /** * The rule's revision number. @@ -63,16 +63,16 @@ It represents the version of rule's object in Kibana. It is set to `0` when the > Not all updates to any rule fields will increment the revision. Only those fields that are considered static `rule parameters` can trigger revision increments. For example, an update to a rule's query or index fields will increment the rule's revision by `1`. However, changes to dynamic or technical fields like enabled or execution_summary will not cause revision increments. */ +export const RuleRevision = lazySchema(() => z.number().int().min(0)); export type RuleRevision = z.infer; -export const RuleRevision = z.number().int().min(0); +export const QueryLanguage = lazySchema(() => z.enum(['kuery', 'lucene', 'eql', 'esql'])); export type QueryLanguage = z.infer; -export const QueryLanguage = z.enum(['kuery', 'lucene', 'eql', 'esql']); export type QueryLanguageEnum = typeof QueryLanguage.enum; export const QueryLanguageEnum = QueryLanguage.enum; +export const KqlQueryLanguage = lazySchema(() => z.enum(['kuery', 'lucene'])); export type KqlQueryLanguage = z.infer; -export const KqlQueryLanguage = z.enum(['kuery', 'lucene']); export type KqlQueryLanguageEnum = typeof KqlQueryLanguage.enum; export const KqlQueryLanguageEnum = KqlQueryLanguage.enum; @@ -80,79 +80,87 @@ export const KqlQueryLanguageEnum = KqlQueryLanguage.enum; * This field determines whether the rule is a prebuilt Elastic rule. It will be replaced with the `rule_source` field. * @deprecated */ +export const IsRuleImmutable = lazySchema(() => z.boolean()); export type IsRuleImmutable = z.infer; -export const IsRuleImmutable = z.boolean(); /** * Determines whether an external/prebuilt rule has been customized by the user (i.e. any of its fields have been modified and diverged from the base value). */ +export const IsExternalRuleCustomized = lazySchema(() => z.boolean()); export type IsExternalRuleCustomized = z.infer; -export const IsExternalRuleCustomized = z.boolean(); /** * Determines whether an external/prebuilt rule has its original, unmodified version present when the calculation of its customization status is performed (`rule_source.is_customized` and `rule_source.customized_fields`). */ +export const ExternalRuleHasBaseVersion = lazySchema(() => z.boolean()); export type ExternalRuleHasBaseVersion = z.infer; -export const ExternalRuleHasBaseVersion = z.boolean(); /** * An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array. */ -export type ExternalRuleCustomizedFields = z.infer; -export const ExternalRuleCustomizedFields = z.array( - z.object({ - /** - * Name of a user-modified field in the rule object. - */ - field_name: z.string(), - }) +export const ExternalRuleCustomizedFields = lazySchema(() => + z.array( + z.object({ + /** + * Name of a user-modified field in the rule object. + */ + field_name: z.string(), + }) + ) ); +export type ExternalRuleCustomizedFields = z.infer; /** * Type of rule source for internally sourced rules, i.e. created within the Kibana apps. */ +export const InternalRuleSource = lazySchema(() => + z.object({ + type: z.literal('internal'), + }) +); export type InternalRuleSource = z.infer; -export const InternalRuleSource = z.object({ - type: z.literal('internal'), -}); /** * Type of rule source for externally sourced rules, i.e. rules that have an external source, such as the Elastic Prebuilt rules repo. */ +export const ExternalRuleSource = lazySchema(() => + z.object({ + type: z.literal('external'), + is_customized: IsExternalRuleCustomized, + has_base_version: ExternalRuleHasBaseVersion, + customized_fields: ExternalRuleCustomizedFields, + }) +); export type ExternalRuleSource = z.infer; -export const ExternalRuleSource = z.object({ - type: z.literal('external'), - is_customized: IsExternalRuleCustomized, - has_base_version: ExternalRuleHasBaseVersion, - customized_fields: ExternalRuleCustomizedFields, -}); /** * Discriminated union that determines whether the rule is internally sourced (created within the Kibana app) or has an external source, such as the Elastic Prebuilt rules repo. */ +export const RuleSource = lazySchema(() => + z.discriminatedUnion('type', [ExternalRuleSource, InternalRuleSource]) +); export type RuleSource = z.infer; -export const RuleSource = z.discriminatedUnion('type', [ExternalRuleSource, InternalRuleSource]); /** * Determines whether the rule is enabled. Defaults to true. */ +export const IsRuleEnabled = lazySchema(() => z.boolean()); export type IsRuleEnabled = z.infer; -export const IsRuleEnabled = z.boolean(); /** * Frequency of rule execution, using a date math range. For example, "1h" means the rule runs every hour. Defaults to 5m (5 minutes). */ +export const RuleInterval = lazySchema(() => z.string()); export type RuleInterval = z.infer; -export const RuleInterval = z.string(); /** * Time from which data is analyzed each time the rule runs, using a date math range. For example, now-4200s means the rule analyzes data from 70 minutes before its start time. Defaults to now-6m (analyzes data from 6 minutes before the start time). */ +export const RuleIntervalFrom = lazySchema(() => z.string().superRefine(isValidDateMath)); export type RuleIntervalFrom = z.infer; -export const RuleIntervalFrom = z.string().superRefine(isValidDateMath); +export const RuleIntervalTo = lazySchema(() => z.string()); export type RuleIntervalTo = z.infer; -export const RuleIntervalTo = z.string(); /** * A numerical representation of the alert's severity from 0 to 100, where: @@ -162,24 +170,26 @@ export const RuleIntervalTo = z.string(); * `74` - `100` represents critical severity */ +export const RiskScore = lazySchema(() => z.number().int().min(0).max(100)); export type RiskScore = z.infer; -export const RiskScore = z.number().int().min(0).max(100); /** * Overrides generated alerts' risk_score with a value from the source event */ -export type RiskScoreMapping = z.infer; -export const RiskScoreMapping = z.array( - z.object({ - /** - * Source event field used to override the default `risk_score`. - */ - field: z.string(), - operator: z.literal('equals'), - value: z.string(), - risk_score: RiskScore.optional(), - }) +export const RiskScoreMapping = lazySchema(() => + z.array( + z.object({ + /** + * Source event field used to override the default `risk_score`. + */ + field: z.string(), + operator: z.literal('equals'), + value: z.string(), + risk_score: RiskScore.optional(), + }) + ) ); +export type RiskScoreMapping = z.infer; /** * Severity level of alerts produced by the rule, which must be one of the following: @@ -189,32 +199,34 @@ export const RiskScoreMapping = z.array( * `critical`: Alerts that indicate it is highly likely a security incident has occurred */ +export const Severity = lazySchema(() => z.enum(['low', 'medium', 'high', 'critical'])); export type Severity = z.infer; -export const Severity = z.enum(['low', 'medium', 'high', 'critical']); export type SeverityEnum = typeof Severity.enum; export const SeverityEnum = Severity.enum; /** * Overrides generated alerts' severity with values from the source event */ -export type SeverityMapping = z.infer; -export const SeverityMapping = z.array( - z.object({ - /** - * Source event field used to override the default `severity`. - */ - field: z.string(), - operator: z.literal('equals'), - severity: Severity, - value: z.string(), - }) +export const SeverityMapping = lazySchema(() => + z.array( + z.object({ + /** + * Source event field used to override the default `severity`. + */ + field: z.string(), + operator: z.literal('equals'), + severity: Severity, + value: z.string(), + }) + ) ); +export type SeverityMapping = z.infer; /** * String array containing words and phrases to help categorize, filter, and search rules. Defaults to an empty array. */ +export const RuleTagArray = lazySchema(() => z.array(z.string())); export type RuleTagArray = z.infer; -export const RuleTagArray = z.array(z.string()); /** * Placeholder for metadata about the rule. @@ -222,44 +234,44 @@ export const RuleTagArray = z.array(z.string()); > This field is overwritten when you save changes to the rule’s settings. */ +export const RuleMetadata = lazySchema(() => z.object({}).catchall(z.unknown())); export type RuleMetadata = z.infer; -export const RuleMetadata = z.object({}).catchall(z.unknown()); /** * The rule's license. */ +export const RuleLicense = lazySchema(() => z.string()); export type RuleLicense = z.infer; -export const RuleLicense = z.string(); /** * The rule’s author. */ +export const RuleAuthorArray = lazySchema(() => z.array(z.string())); export type RuleAuthorArray = z.infer; -export const RuleAuthorArray = z.array(z.string()); /** * String array used to describe common reasons why the rule may issue false-positive alerts. Defaults to an empty array. */ +export const RuleFalsePositiveArray = lazySchema(() => z.array(z.string())); export type RuleFalsePositiveArray = z.infer; -export const RuleFalsePositiveArray = z.array(z.string()); /** * Array containing notes about or references to relevant information about the rule. Defaults to an empty array. */ +export const RuleReferenceArray = lazySchema(() => z.array(z.string())); export type RuleReferenceArray = z.infer; -export const RuleReferenceArray = z.array(z.string()); /** * Notes to help investigate alerts produced by the rule. */ +export const InvestigationGuide = lazySchema(() => z.string()); export type InvestigationGuide = z.infer; -export const InvestigationGuide = z.string(); /** * Populates the rule’s setup guide with instructions on rule prerequisites such as required integrations, configuration steps, and anything else needed for the rule to work correctly. */ +export const SetupGuide = lazySchema(() => z.string()); export type SetupGuide = z.infer; -export const SetupGuide = z.string(); /** * Determines if the rule acts as a building block. If yes, the value must be `default`. @@ -267,21 +279,21 @@ By default, building-block alerts are not displayed in the UI. These rules are u For more information, refer to [About building block rules](https://www.elastic.co/docs/solutions/security/detect-and-alert/about-building-block-rules). */ +export const BuildingBlockType = lazySchema(() => z.string()); export type BuildingBlockType = z.infer; -export const BuildingBlockType = z.string(); /** * (deprecated) Has no effect. * @deprecated */ +export const AlertsIndex = lazySchema(() => z.string()); export type AlertsIndex = z.infer; -export const AlertsIndex = z.string(); /** * Has no effect. */ +export const AlertsIndexNamespace = lazySchema(() => z.string()); export type AlertsIndexNamespace = z.infer; -export const AlertsIndexNamespace = z.string(); /** * Maximum number of alerts the rule can create during a single run (the rule’s Max alerts per run [advanced setting](https://www.elastic.co/docs/solutions/security/detect-and-alert/create-detection-rule#rule-ui-advanced-params) value). @@ -289,86 +301,94 @@ export const AlertsIndexNamespace = z.string(); > This setting can be superseded by the [Kibana configuration setting](https://www.elastic.co/docs/reference/kibana/configuration-reference/alerting-settings) `xpack.alerting.rules.run.alerts.max`, which determines the maximum alerts generated by any rule in the Kibana alerting framework. For example, if `xpack.alerting.rules.run.alerts.max` is set to 1000, the rule can generate no more than 1000 alerts even if `max_signals` is set higher. */ +export const MaxSignals = lazySchema(() => z.number().int().min(1).default(100)); export type MaxSignals = z.infer; -export const MaxSignals = z.number().int().min(1).default(100); +export const ThreatSubtechnique = lazySchema(() => + z.object({ + /** + * Subtechnique ID + */ + id: z.string(), + /** + * Subtechnique name + */ + name: z.string(), + /** + * Subtechnique reference + */ + reference: z.string(), + }) +); export type ThreatSubtechnique = z.infer; -export const ThreatSubtechnique = z.object({ - /** - * Subtechnique ID - */ - id: z.string(), - /** - * Subtechnique name - */ - name: z.string(), - /** - * Subtechnique reference - */ - reference: z.string(), -}); -export type ThreatTechnique = z.infer; -export const ThreatTechnique = z.object({ - /** - * Technique ID - */ - id: z.string(), - /** - * Technique name - */ - name: z.string(), - /** - * Technique reference - */ - reference: z.string(), - /** +export const ThreatTechnique = lazySchema(() => + z.object({ + /** + * Technique ID + */ + id: z.string(), + /** + * Technique name + */ + name: z.string(), + /** + * Technique reference + */ + reference: z.string(), + /** * Array containing more specific information on the attack technique. */ - subtechnique: z.array(ThreatSubtechnique).optional(), -}); + subtechnique: z.array(ThreatSubtechnique).optional(), + }) +); +export type ThreatTechnique = z.infer; /** * Object containing information on the attack type */ +export const ThreatTactic = lazySchema(() => + z.object({ + /** + * Tactic ID + */ + id: z.string(), + /** + * Tactic name + */ + name: z.string(), + /** + * Tactic reference + */ + reference: z.string(), + }) +); export type ThreatTactic = z.infer; -export const ThreatTactic = z.object({ - /** - * Tactic ID - */ - id: z.string(), - /** - * Tactic name - */ - name: z.string(), - /** - * Tactic reference - */ - reference: z.string(), -}); /** * > info > Currently, only threats described using the MITRE ATT&CK™ framework are supported. */ +export const Threat = lazySchema(() => + z.object({ + /** + * Relevant attack framework + */ + framework: z.string(), + tactic: ThreatTactic, + /** + * Array containing information on the attack techniques (optional) + */ + technique: z.array(ThreatTechnique).optional(), + }) +); export type Threat = z.infer; -export const Threat = z.object({ - /** - * Relevant attack framework - */ - framework: z.string(), - tactic: ThreatTactic, - /** - * Array containing information on the attack techniques (optional) - */ - technique: z.array(ThreatTechnique).optional(), -}); +export const ThreatArray = lazySchema(() => z.array(Threat)); export type ThreatArray = z.infer; -export const ThreatArray = z.array(Threat); /** * Indices on which the rule functions. Defaults to the Security Solution indices defined on the Kibana Advanced Settings page (Kibana → Stack Management → Advanced Settings → `securitySolution:defaultIndex`). @@ -376,17 +396,17 @@ export const ThreatArray = z.array(Threat); > This field is not supported for ES|QL rules. */ +export const IndexPatternArray = lazySchema(() => z.array(z.string())); export type IndexPatternArray = z.infer; -export const IndexPatternArray = z.array(z.string()); +export const DataViewId = lazySchema(() => z.string()); export type DataViewId = z.infer; -export const DataViewId = z.string(); /** * Kibana [saved search](https://www.elastic.co/docs/explore-analyze/discover/search-sessions) used by the rule to create alerts. */ +export const SavedQueryId = lazySchema(() => z.string()); export type SavedQueryId = z.infer; -export const SavedQueryId = z.string(); /** * [Query](https://www.elastic.co/docs/explore-analyze/query-filter) used by the rule to create alerts. @@ -395,8 +415,8 @@ export const SavedQueryId = z.string(); - ES|QL rules have additional query requirements. Refer to [Create ES|QL](https://www.elastic.co/docs/solutions/security/detect-and-alert/create-detection-rule#create-esql-rule) rules for more information. */ +export const RuleQuery = lazySchema(() => z.string()); export type RuleQuery = z.infer; -export const RuleQuery = z.string(); /** * The query and filter context array used to define the conditions for when alerts are created from events. Defaults to an empty array. @@ -404,26 +424,26 @@ export const RuleQuery = z.string(); > This field is not supported for ES|QL rules. */ +export const RuleFilterArray = lazySchema(() => z.array(z.unknown())); export type RuleFilterArray = z.infer; -export const RuleFilterArray = z.array(z.unknown()); /** * Sets which field in the source event is used to populate the alert's `signal.rule.name` value (in the UI, this value is displayed on the Rules page in the Rule column). When unspecified, the rule’s `name` value is used. The source field must be a string data type. */ +export const RuleNameOverride = lazySchema(() => z.string()); export type RuleNameOverride = z.infer; -export const RuleNameOverride = z.string(); /** * Sets the time field used to query indices. When unspecified, rules query the `@timestamp` field. The source field must be an Elasticsearch date data type. */ +export const TimestampOverride = lazySchema(() => z.string()); export type TimestampOverride = z.infer; -export const TimestampOverride = z.string(); /** * Disables the fallback to the event's @timestamp field */ +export const TimestampOverrideFallbackDisabled = lazySchema(() => z.boolean()); export type TimestampOverrideFallbackDisabled = z.infer; -export const TimestampOverrideFallbackDisabled = z.boolean(); /** * Describes an Elasticsearch field that is needed for the rule to function. @@ -449,65 +469,70 @@ const nonEcsField: RequiredField = { }; */ +export const RequiredField = lazySchema(() => + z.object({ + /** + * Name of an Elasticsearch field + */ + name: z.string().min(1).superRefine(isNonEmptyString), + /** + * Type of the Elasticsearch field + */ + type: z.string().min(1).superRefine(isNonEmptyString), + /** + * Indicates whether the field is ECS-compliant. This property is only present in responses. Its value is computed based on field’s name and type. + */ + ecs: z.boolean(), + }) +); export type RequiredField = z.infer; -export const RequiredField = z.object({ - /** - * Name of an Elasticsearch field - */ - name: z.string().min(1).superRefine(isNonEmptyString), - /** - * Type of the Elasticsearch field - */ - type: z.string().min(1).superRefine(isNonEmptyString), - /** - * Indicates whether the field is ECS-compliant. This property is only present in responses. Its value is computed based on field’s name and type. - */ - ecs: z.boolean(), -}); /** * Input parameters to create a RequiredField. Does not include the `ecs` field, because `ecs` is calculated on the backend based on the field name and type. */ +export const RequiredFieldInput = lazySchema(() => + z.object({ + /** + * Name of an Elasticsearch field + */ + name: z.string().min(1).superRefine(isNonEmptyString), + /** + * Type of the Elasticsearch field + */ + type: z.string().min(1).superRefine(isNonEmptyString), + }) +); export type RequiredFieldInput = z.infer; -export const RequiredFieldInput = z.object({ - /** - * Name of an Elasticsearch field - */ - name: z.string().min(1).superRefine(isNonEmptyString), - /** - * Type of the Elasticsearch field - */ - type: z.string().min(1).superRefine(isNonEmptyString), -}); +export const RequiredFieldArray = lazySchema(() => z.array(RequiredField)); export type RequiredFieldArray = z.infer; -export const RequiredFieldArray = z.array(RequiredField); /** * Timeline template ID */ +export const TimelineTemplateId = lazySchema(() => z.string()); export type TimelineTemplateId = z.infer; -export const TimelineTemplateId = z.string(); /** * Timeline template title */ +export const TimelineTemplateTitle = lazySchema(() => z.string()); export type TimelineTemplateTitle = z.infer; -export const TimelineTemplateTitle = z.string(); +export const SavedObjectResolveOutcome = lazySchema(() => + z.enum(['exactMatch', 'aliasMatch', 'conflict']) +); export type SavedObjectResolveOutcome = z.infer; -export const SavedObjectResolveOutcome = z.enum(['exactMatch', 'aliasMatch', 'conflict']); export type SavedObjectResolveOutcomeEnum = typeof SavedObjectResolveOutcome.enum; export const SavedObjectResolveOutcomeEnum = SavedObjectResolveOutcome.enum; +export const SavedObjectResolveAliasTargetId = lazySchema(() => z.string()); export type SavedObjectResolveAliasTargetId = z.infer; -export const SavedObjectResolveAliasTargetId = z.string(); +export const SavedObjectResolveAliasPurpose = lazySchema(() => + z.enum(['savedObjectConversion', 'savedObjectImport']) +); export type SavedObjectResolveAliasPurpose = z.infer; -export const SavedObjectResolveAliasPurpose = z.enum([ - 'savedObjectConversion', - 'savedObjectImport', -]); export type SavedObjectResolveAliasPurposeEnum = typeof SavedObjectResolveAliasPurpose.enum; export const SavedObjectResolveAliasPurposeEnum = SavedObjectResolveAliasPurpose.enum; @@ -531,59 +556,62 @@ There are Fleet packages like `windows` that contain only one integration; in th several integrations; in this case, `integration` should be specified. */ +export const RelatedIntegration = lazySchema(() => + z.object({ + package: NonEmptyString, + version: NonEmptyString, + integration: NonEmptyString.optional(), + }) +); export type RelatedIntegration = z.infer; -export const RelatedIntegration = z.object({ - package: NonEmptyString, - version: NonEmptyString, - integration: NonEmptyString.optional(), -}); +export const RelatedIntegrationArray = lazySchema(() => z.array(RelatedIntegration)); export type RelatedIntegrationArray = z.infer; -export const RelatedIntegrationArray = z.array(RelatedIntegration); /** * Schema for fields relating to investigation fields. These are user defined fields we use to highlight in various features in the UI such as alert details flyout and exceptions auto-population from alert. */ +export const InvestigationFields = lazySchema(() => + z.object({ + field_names: z.array(NonEmptyString).min(1), + }) +); export type InvestigationFields = z.infer; -export const InvestigationFields = z.object({ - field_names: z.array(NonEmptyString).min(1), -}); /** * Defines how often rule actions are taken. */ +export const RuleActionThrottle = lazySchema(() => + z.union([z.enum(['no_actions', 'rule']), z.string().regex(/^[1-9]\d*[smhd]$/)]) +); export type RuleActionThrottle = z.infer; -export const RuleActionThrottle = z.union([ - z.enum(['no_actions', 'rule']), - z.string().regex(/^[1-9]\d*[smhd]$/), -]); /** * Defines how often rules run actions. */ +export const RuleActionNotifyWhen = lazySchema(() => + z.enum(['onActiveAlert', 'onThrottleInterval', 'onActionGroupChange']) +); export type RuleActionNotifyWhen = z.infer; -export const RuleActionNotifyWhen = z.enum([ - 'onActiveAlert', - 'onThrottleInterval', - 'onActionGroupChange', -]); export type RuleActionNotifyWhenEnum = typeof RuleActionNotifyWhen.enum; export const RuleActionNotifyWhenEnum = RuleActionNotifyWhen.enum; /** * The action frequency defines when the action runs (for example, only on rule execution or at specific time intervals). */ +export const RuleActionFrequency = lazySchema(() => + z.object({ + /** + * Action summary indicates whether we will send a summary notification about all the generate alerts or notification per individual alert + */ + summary: z.boolean(), + notifyWhen: RuleActionNotifyWhen, + throttle: RuleActionThrottle.nullable(), + }) +); export type RuleActionFrequency = z.infer; -export const RuleActionFrequency = z.object({ - /** - * Action summary indicates whether we will send a summary notification about all the generate alerts or notification per individual alert - */ - summary: z.boolean(), - notifyWhen: RuleActionNotifyWhen, - throttle: RuleActionThrottle.nullable(), -}); /** * Object containing an action’s conditional filters. @@ -599,8 +627,8 @@ export const RuleActionFrequency = z.object({ - `filters` (array of objects, required): Array of filter objects, as defined in the `kbn-es-query` package. */ +export const RuleActionAlertsFilter = lazySchema(() => z.object({}).catchall(z.unknown())); export type RuleActionAlertsFilter = z.infer; -export const RuleActionAlertsFilter = z.object({}).catchall(z.unknown()); /** * Object containing the allowed connector fields, which varies according to the connector type. @@ -632,24 +660,24 @@ For PagerDuty: - `class` (string, optional): Value indicating the class/type of the event. */ +export const RuleActionParams = lazySchema(() => z.object({}).catchall(z.unknown())); export type RuleActionParams = z.infer; -export const RuleActionParams = z.object({}).catchall(z.unknown()); /** * Optionally groups actions by use cases. Use `default` for alert notifications. */ +export const RuleActionGroup = lazySchema(() => z.string()); export type RuleActionGroup = z.infer; -export const RuleActionGroup = z.string(); /** * The connector ID. */ +export const RuleActionId = lazySchema(() => z.string()); export type RuleActionId = z.infer; -export const RuleActionId = z.string(); -export type RuleAction = z.infer; -export const RuleAction = z.object({ - /** +export const RuleAction = lazySchema(() => + z.object({ + /** * The action type used for sending notifications, can be: - `.slack` @@ -671,29 +699,33 @@ export const RuleAction = z.object({ - `.d3security` */ - action_type_id: z.string(), - group: RuleActionGroup.optional(), - id: RuleActionId, - params: RuleActionParams, - uuid: NonEmptyString.optional(), - alerts_filter: RuleActionAlertsFilter.optional(), - frequency: RuleActionFrequency.optional(), -}); + action_type_id: z.string(), + group: RuleActionGroup.optional(), + id: RuleActionId, + params: RuleActionParams, + uuid: NonEmptyString.optional(), + alerts_filter: RuleActionAlertsFilter.optional(), + frequency: RuleActionFrequency.optional(), + }) +); +export type RuleAction = z.infer; /** * The exception type */ +export const ExceptionListType = lazySchema(() => + z.enum([ + 'detection', + 'rule_default', + 'endpoint', + 'endpoint_trusted_apps', + 'endpoint_trusted_devices', + 'endpoint_events', + 'endpoint_host_isolation_exceptions', + 'endpoint_blocklists', + ]) +); export type ExceptionListType = z.infer; -export const ExceptionListType = z.enum([ - 'detection', - 'rule_default', - 'endpoint', - 'endpoint_trusted_apps', - 'endpoint_trusted_devices', - 'endpoint_events', - 'endpoint_host_isolation_exceptions', - 'endpoint_blocklists', -]); export type ExceptionListTypeEnum = typeof ExceptionListType.enum; export const ExceptionListTypeEnum = ExceptionListType.enum; @@ -701,71 +733,83 @@ export const ExceptionListTypeEnum = ExceptionListType.enum; * Array of [exception containers](https://www.elastic.co/docs/solutions/security/detect-and-alert/detection-rule-concepts), which define exceptions that prevent the rule from generating alerts even when its other criteria are met. */ +export const RuleExceptionList = lazySchema(() => + z.object({ + /** + * ID of the exception container + */ + id: z.string().min(1).superRefine(isNonEmptyString), + /** + * List ID of the exception container + */ + list_id: z.string().min(1).superRefine(isNonEmptyString), + type: ExceptionListType, + /** + * Determines the exceptions validity in rule's Kibana space + */ + namespace_type: z.enum(['agnostic', 'single']), + }) +); export type RuleExceptionList = z.infer; -export const RuleExceptionList = z.object({ - /** - * ID of the exception container - */ - id: z.string().min(1).superRefine(isNonEmptyString), - /** - * List ID of the exception container - */ - list_id: z.string().min(1).superRefine(isNonEmptyString), - type: ExceptionListType, - /** - * Determines the exceptions validity in rule's Kibana space - */ - namespace_type: z.enum(['agnostic', 'single']), -}); /** * Time unit */ +export const AlertSuppressionDurationUnit = lazySchema(() => z.enum(['s', 'm', 'h'])); export type AlertSuppressionDurationUnit = z.infer; -export const AlertSuppressionDurationUnit = z.enum(['s', 'm', 'h']); export type AlertSuppressionDurationUnitEnum = typeof AlertSuppressionDurationUnit.enum; export const AlertSuppressionDurationUnitEnum = AlertSuppressionDurationUnit.enum; +export const AlertSuppressionDuration = lazySchema(() => + z.object({ + value: z.number().int().min(1), + unit: AlertSuppressionDurationUnit, + }) +); export type AlertSuppressionDuration = z.infer; -export const AlertSuppressionDuration = z.object({ - value: z.number().int().min(1), - unit: AlertSuppressionDurationUnit, -}); /** * Describes how alerts will be generated for documents with missing suppress by fields: doNotSuppress - per each document a separate alert will be created suppress - only alert will be created per suppress by bucket */ +export const AlertSuppressionMissingFieldsStrategy = lazySchema(() => + z.enum(['doNotSuppress', 'suppress']) +); export type AlertSuppressionMissingFieldsStrategy = z.infer< typeof AlertSuppressionMissingFieldsStrategy >; -export const AlertSuppressionMissingFieldsStrategy = z.enum(['doNotSuppress', 'suppress']); export type AlertSuppressionMissingFieldsStrategyEnum = typeof AlertSuppressionMissingFieldsStrategy.enum; export const AlertSuppressionMissingFieldsStrategyEnum = AlertSuppressionMissingFieldsStrategy.enum; +export const AlertSuppressionGroupBy = lazySchema(() => z.array(z.string()).min(1).max(3)); export type AlertSuppressionGroupBy = z.infer; -export const AlertSuppressionGroupBy = z.array(z.string()).min(1).max(3); /** * Defines alert suppression configuration. */ +export const AlertSuppression = lazySchema(() => + z.object({ + group_by: AlertSuppressionGroupBy, + duration: AlertSuppressionDuration.optional(), + missing_fields_strategy: AlertSuppressionMissingFieldsStrategy.optional(), + }) +); export type AlertSuppression = z.infer; -export const AlertSuppression = z.object({ - group_by: AlertSuppressionGroupBy, - duration: AlertSuppressionDuration.optional(), - missing_fields_strategy: AlertSuppressionMissingFieldsStrategy.optional(), -}); +export const AlertSuppressionCamel = lazySchema(() => + z.object({ + groupBy: AlertSuppressionGroupBy, + duration: AlertSuppressionDuration.optional(), + missingFieldsStrategy: AlertSuppressionMissingFieldsStrategy.optional(), + }) +); export type AlertSuppressionCamel = z.infer; -export const AlertSuppressionCamel = z.object({ - groupBy: AlertSuppressionGroupBy, - duration: AlertSuppressionDuration.optional(), - missingFieldsStrategy: AlertSuppressionMissingFieldsStrategy.optional(), -}); +export const GapFillStatus = lazySchema(() => + z.enum(['unfilled', 'in_progress', 'filled', 'error']) +); export type GapFillStatus = z.infer; -export const GapFillStatus = z.enum(['unfilled', 'in_progress', 'filled', 'error']); export type GapFillStatusEnum = typeof GapFillStatus.enum; export const GapFillStatusEnum = GapFillStatus.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts index 242113608a33f..944f13cda7344 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schemas.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { RuleName, @@ -92,612 +92,753 @@ import { import { AnomalyThreshold, MachineLearningJobId } from './specific_attributes/ml_attributes.gen'; import { NewTermsFields, HistoryWindowStart } from './specific_attributes/new_terms_attributes.gen'; +export const BaseRequiredFields = lazySchema(() => + z.object({ + name: RuleName, + description: RuleDescription, + risk_score: RiskScore, + severity: Severity, + }) +); export type BaseRequiredFields = z.infer; -export const BaseRequiredFields = z.object({ - name: RuleName, - description: RuleDescription, - risk_score: RiskScore, - severity: Severity, -}); +export const BaseOptionalFields = lazySchema(() => + z.object({ + rule_name_override: RuleNameOverride.optional(), + timestamp_override: TimestampOverride.optional(), + timestamp_override_fallback_disabled: TimestampOverrideFallbackDisabled.optional(), + timeline_id: TimelineTemplateId.optional(), + timeline_title: TimelineTemplateTitle.optional(), + outcome: SavedObjectResolveOutcome.optional(), + alias_target_id: SavedObjectResolveAliasTargetId.optional(), + alias_purpose: SavedObjectResolveAliasPurpose.optional(), + license: RuleLicense.optional(), + note: InvestigationGuide.optional(), + building_block_type: BuildingBlockType.optional(), + output_index: AlertsIndex.optional(), + namespace: AlertsIndexNamespace.optional(), + meta: RuleMetadata.optional(), + investigation_fields: InvestigationFields.optional(), + throttle: RuleActionThrottle.optional(), + response_actions: z.array(ResponseAction).optional(), + }) +); export type BaseOptionalFields = z.infer; -export const BaseOptionalFields = z.object({ - rule_name_override: RuleNameOverride.optional(), - timestamp_override: TimestampOverride.optional(), - timestamp_override_fallback_disabled: TimestampOverrideFallbackDisabled.optional(), - timeline_id: TimelineTemplateId.optional(), - timeline_title: TimelineTemplateTitle.optional(), - outcome: SavedObjectResolveOutcome.optional(), - alias_target_id: SavedObjectResolveAliasTargetId.optional(), - alias_purpose: SavedObjectResolveAliasPurpose.optional(), - license: RuleLicense.optional(), - note: InvestigationGuide.optional(), - building_block_type: BuildingBlockType.optional(), - output_index: AlertsIndex.optional(), - namespace: AlertsIndexNamespace.optional(), - meta: RuleMetadata.optional(), - investigation_fields: InvestigationFields.optional(), - throttle: RuleActionThrottle.optional(), - response_actions: z.array(ResponseAction).optional(), -}); -export type BaseDefaultableFields = z.infer; -export const BaseDefaultableFields = z.object({ - version: RuleVersion.optional(), - tags: RuleTagArray.optional(), - enabled: IsRuleEnabled.optional(), - risk_score_mapping: RiskScoreMapping.optional(), - severity_mapping: SeverityMapping.optional(), - interval: RuleInterval.optional(), - from: RuleIntervalFrom.optional(), - to: RuleIntervalTo.optional(), - /** - * Array defining the automated actions (notifications) taken when alerts are generated. - */ - actions: z.array(RuleAction).optional(), - exceptions_list: z.array(RuleExceptionList).optional(), - author: RuleAuthorArray.optional(), - false_positives: RuleFalsePositiveArray.optional(), - references: RuleReferenceArray.optional(), - max_signals: MaxSignals.optional(), - threat: ThreatArray.optional(), - setup: SetupGuide.optional(), - related_integrations: RelatedIntegrationArray.optional(), - /** +export const BaseDefaultableFields = lazySchema(() => + z.object({ + version: RuleVersion.optional(), + tags: RuleTagArray.optional(), + enabled: IsRuleEnabled.optional(), + risk_score_mapping: RiskScoreMapping.optional(), + severity_mapping: SeverityMapping.optional(), + interval: RuleInterval.optional(), + from: RuleIntervalFrom.optional(), + to: RuleIntervalTo.optional(), + /** + * Array defining the automated actions (notifications) taken when alerts are generated. + */ + actions: z.array(RuleAction).optional(), + exceptions_list: z.array(RuleExceptionList).optional(), + author: RuleAuthorArray.optional(), + false_positives: RuleFalsePositiveArray.optional(), + references: RuleReferenceArray.optional(), + max_signals: MaxSignals.optional(), + threat: ThreatArray.optional(), + setup: SetupGuide.optional(), + related_integrations: RelatedIntegrationArray.optional(), + /** * Elasticsearch fields and their types that need to be present for the rule to function. > info > The value of `required_fields` does not affect the rule’s behavior, and specifying it incorrectly won’t cause the rule to fail. Use `required_fields` as an informational property to document the fields that the rule expects to be present in the data. */ - required_fields: z.array(RequiredFieldInput).optional(), -}); + required_fields: z.array(RequiredFieldInput).optional(), + }) +); +export type BaseDefaultableFields = z.infer; +export const BaseCreateProps = lazySchema(() => + BaseRequiredFields.merge(BaseOptionalFields).merge(BaseDefaultableFields) +); export type BaseCreateProps = z.infer; -export const BaseCreateProps = - BaseRequiredFields.extend(BaseOptionalFields).extend(BaseDefaultableFields); +export const BasePatchProps = lazySchema(() => + BaseRequiredFields.partial().merge(BaseOptionalFields).merge(BaseDefaultableFields) +); export type BasePatchProps = z.infer; -export const BasePatchProps = BaseRequiredFields.partial() - .extend(BaseOptionalFields) - .extend(BaseDefaultableFields); -export type BaseResponseProps = z.infer; -export const BaseResponseProps = BaseRequiredFields.extend(BaseOptionalFields).extend( - BaseDefaultableFields.required() +export const BaseResponseProps = lazySchema(() => + BaseRequiredFields.merge(BaseOptionalFields).merge(BaseDefaultableFields.required()) ); +export type BaseResponseProps = z.infer; -export type ResponseFields = z.infer; -export const ResponseFields = z.object({ - id: RuleObjectId, - rule_id: RuleSignatureId, - immutable: IsRuleImmutable, - rule_source: RuleSource, - updated_at: z.string().datetime(), - updated_by: z.string(), - created_at: z.string().datetime(), - created_by: z.string(), - revision: RuleRevision, - required_fields: RequiredFieldArray, - execution_summary: RuleExecutionSummary.optional(), -}); - -export type SharedCreateProps = z.infer; -export const SharedCreateProps = BaseCreateProps.extend( +export const ResponseFields = lazySchema(() => z.object({ - rule_id: RuleSignatureId.optional(), + id: RuleObjectId, + rule_id: RuleSignatureId, + immutable: IsRuleImmutable, + rule_source: RuleSource, + updated_at: z.string().datetime(), + updated_by: z.string(), + created_at: z.string().datetime(), + created_by: z.string(), + revision: RuleRevision, + required_fields: RequiredFieldArray, + execution_summary: RuleExecutionSummary.optional(), }) ); +export type ResponseFields = z.infer; + +export const SharedCreateProps = lazySchema(() => + BaseCreateProps.merge( + z.object({ + rule_id: RuleSignatureId.optional(), + }) + ) +); +export type SharedCreateProps = z.infer; -export type SharedUpdateProps = z.infer; -export const SharedUpdateProps = BaseCreateProps.extend( - z.object({ - id: RuleObjectId.optional(), - rule_id: RuleSignatureId.optional(), - }) +export const SharedUpdateProps = lazySchema(() => + BaseCreateProps.merge( + z.object({ + id: RuleObjectId.optional(), + rule_id: RuleSignatureId.optional(), + }) + ) ); +export type SharedUpdateProps = z.infer; -export type SharedPatchProps = z.infer; -export const SharedPatchProps = BasePatchProps.extend( - z.object({ - id: RuleObjectId.optional(), - rule_id: RuleSignatureId.optional(), - }) +export const SharedPatchProps = lazySchema(() => + BasePatchProps.merge( + z.object({ + id: RuleObjectId.optional(), + rule_id: RuleSignatureId.optional(), + }) + ) ); +export type SharedPatchProps = z.infer; +export const SharedResponseProps = lazySchema(() => BaseResponseProps.merge(ResponseFields)); export type SharedResponseProps = z.infer; -export const SharedResponseProps = BaseResponseProps.extend(ResponseFields); +export const EqlQueryLanguage = lazySchema(() => z.literal('eql')); export type EqlQueryLanguage = z.infer; -export const EqlQueryLanguage = z.literal('eql'); +export const EqlRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('eql'), + query: RuleQuery, + /** + * Query language to use + */ + language: EqlQueryLanguage, + }) +); export type EqlRequiredFields = z.infer; -export const EqlRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('eql'), - query: RuleQuery, - /** - * Query language to use - */ - language: EqlQueryLanguage, -}); +export const EqlOptionalFields = lazySchema(() => + z.object({ + index: IndexPatternArray.optional(), + data_view_id: DataViewId.optional(), + filters: RuleFilterArray.optional(), + event_category_override: EventCategoryOverride.optional(), + tiebreaker_field: TiebreakerField.optional(), + timestamp_field: TimestampField.optional(), + alert_suppression: AlertSuppression.optional(), + }) +); export type EqlOptionalFields = z.infer; -export const EqlOptionalFields = z.object({ - index: IndexPatternArray.optional(), - data_view_id: DataViewId.optional(), - filters: RuleFilterArray.optional(), - event_category_override: EventCategoryOverride.optional(), - tiebreaker_field: TiebreakerField.optional(), - timestamp_field: TimestampField.optional(), - alert_suppression: AlertSuppression.optional(), -}); +export const EqlRuleCreateFields = lazySchema(() => EqlRequiredFields.merge(EqlOptionalFields)); export type EqlRuleCreateFields = z.infer; -export const EqlRuleCreateFields = EqlRequiredFields.extend(EqlOptionalFields); +export const EqlRuleResponseFields = lazySchema(() => EqlRequiredFields.merge(EqlOptionalFields)); export type EqlRuleResponseFields = z.infer; -export const EqlRuleResponseFields = EqlRequiredFields.extend(EqlOptionalFields); +export const EqlRulePatchFields = lazySchema(() => + EqlRequiredFields.partial().merge(EqlOptionalFields) +); export type EqlRulePatchFields = z.infer; -export const EqlRulePatchFields = EqlRequiredFields.partial().extend(EqlOptionalFields); +export const EqlRule = lazySchema(() => SharedResponseProps.merge(EqlRuleResponseFields)); export type EqlRule = z.infer; -export const EqlRule = SharedResponseProps.extend(EqlRuleResponseFields); +export const EqlRuleCreateProps = lazySchema(() => SharedCreateProps.merge(EqlRuleCreateFields)); export type EqlRuleCreateProps = z.infer; -export const EqlRuleCreateProps = SharedCreateProps.extend(EqlRuleCreateFields); +export const EqlRuleUpdateProps = lazySchema(() => SharedUpdateProps.merge(EqlRuleCreateFields)); export type EqlRuleUpdateProps = z.infer; -export const EqlRuleUpdateProps = SharedUpdateProps.extend(EqlRuleCreateFields); +export const EqlRulePatchProps = lazySchema(() => SharedPatchProps.merge(EqlRulePatchFields)); export type EqlRulePatchProps = z.infer; -export const EqlRulePatchProps = SharedPatchProps.extend(EqlRulePatchFields); +export const QueryRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('query'), + }) +); export type QueryRuleRequiredFields = z.infer; -export const QueryRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('query'), -}); +export const QueryRuleOptionalFields = lazySchema(() => + z.object({ + index: IndexPatternArray.optional(), + data_view_id: DataViewId.optional(), + filters: RuleFilterArray.optional(), + saved_id: SavedQueryId.optional(), + alert_suppression: AlertSuppression.optional(), + }) +); export type QueryRuleOptionalFields = z.infer; -export const QueryRuleOptionalFields = z.object({ - index: IndexPatternArray.optional(), - data_view_id: DataViewId.optional(), - filters: RuleFilterArray.optional(), - saved_id: SavedQueryId.optional(), - alert_suppression: AlertSuppression.optional(), -}); +export const QueryRuleDefaultableFields = lazySchema(() => + z.object({ + query: RuleQuery.optional(), + language: KqlQueryLanguage.optional(), + }) +); export type QueryRuleDefaultableFields = z.infer; -export const QueryRuleDefaultableFields = z.object({ - query: RuleQuery.optional(), - language: KqlQueryLanguage.optional(), -}); -export type QueryRuleCreateFields = z.infer; -export const QueryRuleCreateFields = QueryRuleRequiredFields.extend(QueryRuleOptionalFields).extend( - QueryRuleDefaultableFields +export const QueryRuleCreateFields = lazySchema(() => + QueryRuleRequiredFields.merge(QueryRuleOptionalFields).merge(QueryRuleDefaultableFields) ); +export type QueryRuleCreateFields = z.infer; +export const QueryRulePatchFields = lazySchema(() => + QueryRuleRequiredFields.partial().merge(QueryRuleOptionalFields).merge(QueryRuleDefaultableFields) +); export type QueryRulePatchFields = z.infer; -export const QueryRulePatchFields = QueryRuleRequiredFields.partial() - .extend(QueryRuleOptionalFields) - .extend(QueryRuleDefaultableFields); +export const QueryRuleResponseFields = lazySchema(() => + QueryRuleRequiredFields.merge(QueryRuleOptionalFields).merge( + QueryRuleDefaultableFields.required() + ) +); export type QueryRuleResponseFields = z.infer; -export const QueryRuleResponseFields = QueryRuleRequiredFields.extend( - QueryRuleOptionalFields -).extend(QueryRuleDefaultableFields.required()); +export const QueryRule = lazySchema(() => SharedResponseProps.merge(QueryRuleResponseFields)); export type QueryRule = z.infer; -export const QueryRule = SharedResponseProps.extend(QueryRuleResponseFields); +export const QueryRuleCreateProps = lazySchema(() => + SharedCreateProps.merge(QueryRuleCreateFields) +); export type QueryRuleCreateProps = z.infer; -export const QueryRuleCreateProps = SharedCreateProps.extend(QueryRuleCreateFields); +export const QueryRuleUpdateProps = lazySchema(() => + SharedUpdateProps.merge(QueryRuleCreateFields) +); export type QueryRuleUpdateProps = z.infer; -export const QueryRuleUpdateProps = SharedUpdateProps.extend(QueryRuleCreateFields); +export const QueryRulePatchProps = lazySchema(() => SharedPatchProps.merge(QueryRulePatchFields)); export type QueryRulePatchProps = z.infer; -export const QueryRulePatchProps = SharedPatchProps.extend(QueryRulePatchFields); +export const SavedQueryRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('saved_query'), + saved_id: SavedQueryId, + }) +); export type SavedQueryRuleRequiredFields = z.infer; -export const SavedQueryRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('saved_query'), - saved_id: SavedQueryId, -}); +export const SavedQueryRuleOptionalFields = lazySchema(() => + z.object({ + index: IndexPatternArray.optional(), + data_view_id: DataViewId.optional(), + filters: RuleFilterArray.optional(), + alert_suppression: AlertSuppression.optional(), + query: RuleQuery.optional(), + }) +); export type SavedQueryRuleOptionalFields = z.infer; -export const SavedQueryRuleOptionalFields = z.object({ - index: IndexPatternArray.optional(), - data_view_id: DataViewId.optional(), - filters: RuleFilterArray.optional(), - alert_suppression: AlertSuppression.optional(), - query: RuleQuery.optional(), -}); +export const SavedQueryRuleDefaultableFields = lazySchema(() => + z.object({ + language: KqlQueryLanguage.optional(), + }) +); export type SavedQueryRuleDefaultableFields = z.infer; -export const SavedQueryRuleDefaultableFields = z.object({ - language: KqlQueryLanguage.optional(), -}); +export const SavedQueryRuleCreateFields = lazySchema(() => + SavedQueryRuleRequiredFields.merge(SavedQueryRuleOptionalFields).merge( + SavedQueryRuleDefaultableFields + ) +); export type SavedQueryRuleCreateFields = z.infer; -export const SavedQueryRuleCreateFields = SavedQueryRuleRequiredFields.extend( - SavedQueryRuleOptionalFields -).extend(SavedQueryRuleDefaultableFields); +export const SavedQueryRulePatchFields = lazySchema(() => + SavedQueryRuleRequiredFields.partial() + .merge(SavedQueryRuleOptionalFields) + .merge(SavedQueryRuleDefaultableFields) +); export type SavedQueryRulePatchFields = z.infer; -export const SavedQueryRulePatchFields = SavedQueryRuleRequiredFields.partial() - .extend(SavedQueryRuleOptionalFields) - .extend(SavedQueryRuleDefaultableFields); +export const SavedQueryRuleResponseFields = lazySchema(() => + SavedQueryRuleRequiredFields.merge(SavedQueryRuleOptionalFields).merge( + SavedQueryRuleDefaultableFields.required() + ) +); export type SavedQueryRuleResponseFields = z.infer; -export const SavedQueryRuleResponseFields = SavedQueryRuleRequiredFields.extend( - SavedQueryRuleOptionalFields -).extend(SavedQueryRuleDefaultableFields.required()); +export const SavedQueryRule = lazySchema(() => + SharedResponseProps.merge(SavedQueryRuleResponseFields) +); export type SavedQueryRule = z.infer; -export const SavedQueryRule = SharedResponseProps.extend(SavedQueryRuleResponseFields); +export const SavedQueryRuleCreateProps = lazySchema(() => + SharedCreateProps.merge(SavedQueryRuleCreateFields) +); export type SavedQueryRuleCreateProps = z.infer; -export const SavedQueryRuleCreateProps = SharedCreateProps.extend(SavedQueryRuleCreateFields); +export const SavedQueryRuleUpdateProps = lazySchema(() => + SharedUpdateProps.merge(SavedQueryRuleCreateFields) +); export type SavedQueryRuleUpdateProps = z.infer; -export const SavedQueryRuleUpdateProps = SharedUpdateProps.extend(SavedQueryRuleCreateFields); +export const SavedQueryRulePatchProps = lazySchema(() => + SharedPatchProps.merge(SavedQueryRulePatchFields) +); export type SavedQueryRulePatchProps = z.infer; -export const SavedQueryRulePatchProps = SharedPatchProps.extend(SavedQueryRulePatchFields); +export const ThresholdRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('threshold'), + query: RuleQuery, + threshold: Threshold, + }) +); export type ThresholdRuleRequiredFields = z.infer; -export const ThresholdRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('threshold'), - query: RuleQuery, - threshold: Threshold, -}); +export const ThresholdRuleOptionalFields = lazySchema(() => + z.object({ + index: IndexPatternArray.optional(), + data_view_id: DataViewId.optional(), + filters: RuleFilterArray.optional(), + saved_id: SavedQueryId.optional(), + alert_suppression: ThresholdAlertSuppression.optional(), + }) +); export type ThresholdRuleOptionalFields = z.infer; -export const ThresholdRuleOptionalFields = z.object({ - index: IndexPatternArray.optional(), - data_view_id: DataViewId.optional(), - filters: RuleFilterArray.optional(), - saved_id: SavedQueryId.optional(), - alert_suppression: ThresholdAlertSuppression.optional(), -}); +export const ThresholdRuleDefaultableFields = lazySchema(() => + z.object({ + language: KqlQueryLanguage.optional(), + }) +); export type ThresholdRuleDefaultableFields = z.infer; -export const ThresholdRuleDefaultableFields = z.object({ - language: KqlQueryLanguage.optional(), -}); +export const ThresholdRuleCreateFields = lazySchema(() => + ThresholdRuleRequiredFields.merge(ThresholdRuleOptionalFields).merge( + ThresholdRuleDefaultableFields + ) +); export type ThresholdRuleCreateFields = z.infer; -export const ThresholdRuleCreateFields = ThresholdRuleRequiredFields.extend( - ThresholdRuleOptionalFields -).extend(ThresholdRuleDefaultableFields); +export const ThresholdRulePatchFields = lazySchema(() => + ThresholdRuleRequiredFields.partial() + .merge(ThresholdRuleOptionalFields) + .merge(ThresholdRuleDefaultableFields) +); export type ThresholdRulePatchFields = z.infer; -export const ThresholdRulePatchFields = ThresholdRuleRequiredFields.partial() - .extend(ThresholdRuleOptionalFields) - .extend(ThresholdRuleDefaultableFields); +export const ThresholdRuleResponseFields = lazySchema(() => + ThresholdRuleRequiredFields.merge(ThresholdRuleOptionalFields).merge( + ThresholdRuleDefaultableFields.required() + ) +); export type ThresholdRuleResponseFields = z.infer; -export const ThresholdRuleResponseFields = ThresholdRuleRequiredFields.extend( - ThresholdRuleOptionalFields -).extend(ThresholdRuleDefaultableFields.required()); +export const ThresholdRule = lazySchema(() => + SharedResponseProps.merge(ThresholdRuleResponseFields) +); export type ThresholdRule = z.infer; -export const ThresholdRule = SharedResponseProps.extend(ThresholdRuleResponseFields); +export const ThresholdRuleCreateProps = lazySchema(() => + SharedCreateProps.merge(ThresholdRuleCreateFields) +); export type ThresholdRuleCreateProps = z.infer; -export const ThresholdRuleCreateProps = SharedCreateProps.extend(ThresholdRuleCreateFields); +export const ThresholdRuleUpdateProps = lazySchema(() => + SharedUpdateProps.merge(ThresholdRuleCreateFields) +); export type ThresholdRuleUpdateProps = z.infer; -export const ThresholdRuleUpdateProps = SharedUpdateProps.extend(ThresholdRuleCreateFields); +export const ThresholdRulePatchProps = lazySchema(() => + SharedPatchProps.merge(ThresholdRulePatchFields) +); export type ThresholdRulePatchProps = z.infer; -export const ThresholdRulePatchProps = SharedPatchProps.extend(ThresholdRulePatchFields); +export const ThreatMatchRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('threat_match'), + query: RuleQuery, + threat_query: ThreatQuery, + threat_mapping: ThreatMapping, + threat_index: ThreatIndex, + }) +); export type ThreatMatchRuleRequiredFields = z.infer; -export const ThreatMatchRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('threat_match'), - query: RuleQuery, - threat_query: ThreatQuery, - threat_mapping: ThreatMapping, - threat_index: ThreatIndex, -}); +export const ThreatMatchRuleOptionalFields = lazySchema(() => + z.object({ + index: IndexPatternArray.optional(), + data_view_id: DataViewId.optional(), + filters: RuleFilterArray.optional(), + saved_id: SavedQueryId.optional(), + threat_filters: ThreatFilters.optional(), + threat_indicator_path: ThreatIndicatorPath.optional(), + threat_language: KqlQueryLanguage.optional(), + concurrent_searches: ConcurrentSearches.optional(), + items_per_search: ItemsPerSearch.optional(), + alert_suppression: AlertSuppression.optional(), + }) +); export type ThreatMatchRuleOptionalFields = z.infer; -export const ThreatMatchRuleOptionalFields = z.object({ - index: IndexPatternArray.optional(), - data_view_id: DataViewId.optional(), - filters: RuleFilterArray.optional(), - saved_id: SavedQueryId.optional(), - threat_filters: ThreatFilters.optional(), - threat_indicator_path: ThreatIndicatorPath.optional(), - threat_language: KqlQueryLanguage.optional(), - concurrent_searches: ConcurrentSearches.optional(), - items_per_search: ItemsPerSearch.optional(), - alert_suppression: AlertSuppression.optional(), -}); +export const ThreatMatchRuleDefaultableFields = lazySchema(() => + z.object({ + language: KqlQueryLanguage.optional(), + }) +); export type ThreatMatchRuleDefaultableFields = z.infer; -export const ThreatMatchRuleDefaultableFields = z.object({ - language: KqlQueryLanguage.optional(), -}); +export const ThreatMatchRuleCreateFields = lazySchema(() => + ThreatMatchRuleRequiredFields.merge(ThreatMatchRuleOptionalFields).merge( + ThreatMatchRuleDefaultableFields + ) +); export type ThreatMatchRuleCreateFields = z.infer; -export const ThreatMatchRuleCreateFields = ThreatMatchRuleRequiredFields.extend( - ThreatMatchRuleOptionalFields -).extend(ThreatMatchRuleDefaultableFields); +export const ThreatMatchRulePatchFields = lazySchema(() => + ThreatMatchRuleRequiredFields.partial() + .merge(ThreatMatchRuleOptionalFields) + .merge(ThreatMatchRuleDefaultableFields) +); export type ThreatMatchRulePatchFields = z.infer; -export const ThreatMatchRulePatchFields = ThreatMatchRuleRequiredFields.partial() - .extend(ThreatMatchRuleOptionalFields) - .extend(ThreatMatchRuleDefaultableFields); +export const ThreatMatchRuleResponseFields = lazySchema(() => + ThreatMatchRuleRequiredFields.merge(ThreatMatchRuleOptionalFields).merge( + ThreatMatchRuleDefaultableFields.required() + ) +); export type ThreatMatchRuleResponseFields = z.infer; -export const ThreatMatchRuleResponseFields = ThreatMatchRuleRequiredFields.extend( - ThreatMatchRuleOptionalFields -).extend(ThreatMatchRuleDefaultableFields.required()); +export const ThreatMatchRule = lazySchema(() => + SharedResponseProps.merge(ThreatMatchRuleResponseFields) +); export type ThreatMatchRule = z.infer; -export const ThreatMatchRule = SharedResponseProps.extend(ThreatMatchRuleResponseFields); +export const ThreatMatchRuleCreateProps = lazySchema(() => + SharedCreateProps.merge(ThreatMatchRuleCreateFields) +); export type ThreatMatchRuleCreateProps = z.infer; -export const ThreatMatchRuleCreateProps = SharedCreateProps.extend(ThreatMatchRuleCreateFields); +export const ThreatMatchRuleUpdateProps = lazySchema(() => + SharedUpdateProps.merge(ThreatMatchRuleCreateFields) +); export type ThreatMatchRuleUpdateProps = z.infer; -export const ThreatMatchRuleUpdateProps = SharedUpdateProps.extend(ThreatMatchRuleCreateFields); +export const ThreatMatchRulePatchProps = lazySchema(() => + SharedPatchProps.merge(ThreatMatchRulePatchFields) +); export type ThreatMatchRulePatchProps = z.infer; -export const ThreatMatchRulePatchProps = SharedPatchProps.extend(ThreatMatchRulePatchFields); +export const MachineLearningRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('machine_learning'), + anomaly_threshold: AnomalyThreshold, + machine_learning_job_id: MachineLearningJobId, + }) +); export type MachineLearningRuleRequiredFields = z.infer; -export const MachineLearningRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('machine_learning'), - anomaly_threshold: AnomalyThreshold, - machine_learning_job_id: MachineLearningJobId, -}); +export const MachineLearningRuleOptionalFields = lazySchema(() => + z.object({ + alert_suppression: AlertSuppression.optional(), + }) +); export type MachineLearningRuleOptionalFields = z.infer; -export const MachineLearningRuleOptionalFields = z.object({ - alert_suppression: AlertSuppression.optional(), -}); -export type MachineLearningRulePatchFields = z.infer; -export const MachineLearningRulePatchFields = MachineLearningRuleRequiredFields.partial().extend( - MachineLearningRuleOptionalFields +export const MachineLearningRulePatchFields = lazySchema(() => + MachineLearningRuleRequiredFields.partial().merge(MachineLearningRuleOptionalFields) ); +export type MachineLearningRulePatchFields = z.infer; -export type MachineLearningRuleResponseFields = z.infer; -export const MachineLearningRuleResponseFields = MachineLearningRuleRequiredFields.extend( - MachineLearningRuleOptionalFields +export const MachineLearningRuleResponseFields = lazySchema(() => + MachineLearningRuleRequiredFields.merge(MachineLearningRuleOptionalFields) ); +export type MachineLearningRuleResponseFields = z.infer; -export type MachineLearningRuleCreateFields = z.infer; -export const MachineLearningRuleCreateFields = MachineLearningRuleRequiredFields.extend( - MachineLearningRuleOptionalFields +export const MachineLearningRuleCreateFields = lazySchema(() => + MachineLearningRuleRequiredFields.merge(MachineLearningRuleOptionalFields) ); +export type MachineLearningRuleCreateFields = z.infer; +export const MachineLearningRule = lazySchema(() => + SharedResponseProps.merge(MachineLearningRuleResponseFields) +); export type MachineLearningRule = z.infer; -export const MachineLearningRule = SharedResponseProps.extend(MachineLearningRuleResponseFields); -export type MachineLearningRuleCreateProps = z.infer; -export const MachineLearningRuleCreateProps = SharedCreateProps.extend( - MachineLearningRuleCreateFields +export const MachineLearningRuleCreateProps = lazySchema(() => + SharedCreateProps.merge(MachineLearningRuleCreateFields) ); +export type MachineLearningRuleCreateProps = z.infer; -export type MachineLearningRuleUpdateProps = z.infer; -export const MachineLearningRuleUpdateProps = SharedUpdateProps.extend( - MachineLearningRuleCreateFields +export const MachineLearningRuleUpdateProps = lazySchema(() => + SharedUpdateProps.merge(MachineLearningRuleCreateFields) ); +export type MachineLearningRuleUpdateProps = z.infer; -export type MachineLearningRulePatchProps = z.infer; -export const MachineLearningRulePatchProps = SharedPatchProps.extend( - MachineLearningRulePatchFields +export const MachineLearningRulePatchProps = lazySchema(() => + SharedPatchProps.merge(MachineLearningRulePatchFields) ); +export type MachineLearningRulePatchProps = z.infer; +export const NewTermsRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('new_terms'), + query: RuleQuery, + new_terms_fields: NewTermsFields, + history_window_start: HistoryWindowStart, + }) +); export type NewTermsRuleRequiredFields = z.infer; -export const NewTermsRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('new_terms'), - query: RuleQuery, - new_terms_fields: NewTermsFields, - history_window_start: HistoryWindowStart, -}); +export const NewTermsRuleOptionalFields = lazySchema(() => + z.object({ + index: IndexPatternArray.optional(), + data_view_id: DataViewId.optional(), + filters: RuleFilterArray.optional(), + alert_suppression: AlertSuppression.optional(), + }) +); export type NewTermsRuleOptionalFields = z.infer; -export const NewTermsRuleOptionalFields = z.object({ - index: IndexPatternArray.optional(), - data_view_id: DataViewId.optional(), - filters: RuleFilterArray.optional(), - alert_suppression: AlertSuppression.optional(), -}); +export const NewTermsRuleDefaultableFields = lazySchema(() => + z.object({ + language: KqlQueryLanguage.optional(), + }) +); export type NewTermsRuleDefaultableFields = z.infer; -export const NewTermsRuleDefaultableFields = z.object({ - language: KqlQueryLanguage.optional(), -}); +export const NewTermsRulePatchFields = lazySchema(() => + NewTermsRuleRequiredFields.partial() + .merge(NewTermsRuleOptionalFields) + .merge(NewTermsRuleDefaultableFields) +); export type NewTermsRulePatchFields = z.infer; -export const NewTermsRulePatchFields = NewTermsRuleRequiredFields.partial() - .extend(NewTermsRuleOptionalFields) - .extend(NewTermsRuleDefaultableFields); +export const NewTermsRuleResponseFields = lazySchema(() => + NewTermsRuleRequiredFields.merge(NewTermsRuleOptionalFields).merge( + NewTermsRuleDefaultableFields.required() + ) +); export type NewTermsRuleResponseFields = z.infer; -export const NewTermsRuleResponseFields = NewTermsRuleRequiredFields.extend( - NewTermsRuleOptionalFields -).extend(NewTermsRuleDefaultableFields.required()); +export const NewTermsRuleCreateFields = lazySchema(() => + NewTermsRuleRequiredFields.merge(NewTermsRuleOptionalFields).merge(NewTermsRuleDefaultableFields) +); export type NewTermsRuleCreateFields = z.infer; -export const NewTermsRuleCreateFields = NewTermsRuleRequiredFields.extend( - NewTermsRuleOptionalFields -).extend(NewTermsRuleDefaultableFields); +export const NewTermsRule = lazySchema(() => SharedResponseProps.merge(NewTermsRuleResponseFields)); export type NewTermsRule = z.infer; -export const NewTermsRule = SharedResponseProps.extend(NewTermsRuleResponseFields); +export const NewTermsRuleCreateProps = lazySchema(() => + SharedCreateProps.merge(NewTermsRuleCreateFields) +); export type NewTermsRuleCreateProps = z.infer; -export const NewTermsRuleCreateProps = SharedCreateProps.extend(NewTermsRuleCreateFields); +export const NewTermsRuleUpdateProps = lazySchema(() => + SharedUpdateProps.merge(NewTermsRuleCreateFields) +); export type NewTermsRuleUpdateProps = z.infer; -export const NewTermsRuleUpdateProps = SharedUpdateProps.extend(NewTermsRuleCreateFields); +export const NewTermsRulePatchProps = lazySchema(() => + SharedPatchProps.merge(NewTermsRulePatchFields) +); export type NewTermsRulePatchProps = z.infer; -export const NewTermsRulePatchProps = SharedPatchProps.extend(NewTermsRulePatchFields); +export const EsqlQueryLanguage = lazySchema(() => z.literal('esql')); export type EsqlQueryLanguage = z.infer; -export const EsqlQueryLanguage = z.literal('esql'); +export const EsqlRuleRequiredFields = lazySchema(() => + z.object({ + /** + * Rule type + */ + type: z.literal('esql'), + language: EsqlQueryLanguage, + query: RuleQuery, + }) +); export type EsqlRuleRequiredFields = z.infer; -export const EsqlRuleRequiredFields = z.object({ - /** - * Rule type - */ - type: z.literal('esql'), - language: EsqlQueryLanguage, - query: RuleQuery, -}); +export const EsqlRuleOptionalFields = lazySchema(() => + z.object({ + alert_suppression: AlertSuppression.optional(), + }) +); export type EsqlRuleOptionalFields = z.infer; -export const EsqlRuleOptionalFields = z.object({ - alert_suppression: AlertSuppression.optional(), -}); +export const EsqlRulePatchFields = lazySchema(() => + EsqlRuleOptionalFields.merge(EsqlRuleRequiredFields.partial()) +); export type EsqlRulePatchFields = z.infer; -export const EsqlRulePatchFields = EsqlRuleOptionalFields.extend(EsqlRuleRequiredFields.partial()); +export const EsqlRuleResponseFields = lazySchema(() => + EsqlRuleOptionalFields.merge(EsqlRuleRequiredFields) +); export type EsqlRuleResponseFields = z.infer; -export const EsqlRuleResponseFields = EsqlRuleOptionalFields.extend(EsqlRuleRequiredFields); +export const EsqlRuleCreateFields = lazySchema(() => + EsqlRuleOptionalFields.merge(EsqlRuleRequiredFields) +); export type EsqlRuleCreateFields = z.infer; -export const EsqlRuleCreateFields = EsqlRuleOptionalFields.extend(EsqlRuleRequiredFields); +export const EsqlRule = lazySchema(() => SharedResponseProps.merge(EsqlRuleResponseFields)); export type EsqlRule = z.infer; -export const EsqlRule = SharedResponseProps.extend(EsqlRuleResponseFields); +export const EsqlRuleCreateProps = lazySchema(() => SharedCreateProps.merge(EsqlRuleCreateFields)); export type EsqlRuleCreateProps = z.infer; -export const EsqlRuleCreateProps = SharedCreateProps.extend(EsqlRuleCreateFields); +export const EsqlRuleUpdateProps = lazySchema(() => SharedUpdateProps.merge(EsqlRuleCreateFields)); export type EsqlRuleUpdateProps = z.infer; -export const EsqlRuleUpdateProps = SharedUpdateProps.extend(EsqlRuleCreateFields); +export const EsqlRulePatchProps = lazySchema(() => + SharedPatchProps.merge(EsqlRulePatchFields.partial()) +); export type EsqlRulePatchProps = z.infer; -export const EsqlRulePatchProps = SharedPatchProps.extend(EsqlRulePatchFields.partial()); - -export const TypeSpecificCreatePropsInternal = z.discriminatedUnion('type', [ - EqlRuleCreateFields, - QueryRuleCreateFields, - SavedQueryRuleCreateFields, - ThresholdRuleCreateFields, - ThreatMatchRuleCreateFields, - MachineLearningRuleCreateFields, - NewTermsRuleCreateFields, - EsqlRuleCreateFields, -]); + +export const TypeSpecificCreatePropsInternal = lazySchema(() => + z.discriminatedUnion('type', [ + EqlRuleCreateFields, + QueryRuleCreateFields, + SavedQueryRuleCreateFields, + ThresholdRuleCreateFields, + ThreatMatchRuleCreateFields, + MachineLearningRuleCreateFields, + NewTermsRuleCreateFields, + EsqlRuleCreateFields, + ]) +); export type TypeSpecificCreateProps = z.infer; export const TypeSpecificCreateProps = TypeSpecificCreatePropsInternal as z.ZodType; -export const TypeSpecificPatchPropsInternal = z.union([ - EqlRulePatchFields, - QueryRulePatchFields, - SavedQueryRulePatchFields, - ThresholdRulePatchFields, - ThreatMatchRulePatchFields, - MachineLearningRulePatchFields, - NewTermsRulePatchFields, - EsqlRulePatchFields, -]); +export const TypeSpecificPatchPropsInternal = lazySchema(() => + z.union([ + EqlRulePatchFields, + QueryRulePatchFields, + SavedQueryRulePatchFields, + ThresholdRulePatchFields, + ThreatMatchRulePatchFields, + MachineLearningRulePatchFields, + NewTermsRulePatchFields, + EsqlRulePatchFields, + ]) +); export type TypeSpecificPatchProps = z.infer; export const TypeSpecificPatchProps = TypeSpecificPatchPropsInternal as z.ZodType; -export const TypeSpecificResponseInternal = z.discriminatedUnion('type', [ - EqlRuleResponseFields, - QueryRuleResponseFields, - SavedQueryRuleResponseFields, - ThresholdRuleResponseFields, - ThreatMatchRuleResponseFields, - MachineLearningRuleResponseFields, - NewTermsRuleResponseFields, - EsqlRuleResponseFields, -]); +export const TypeSpecificResponseInternal = lazySchema(() => + z.discriminatedUnion('type', [ + EqlRuleResponseFields, + QueryRuleResponseFields, + SavedQueryRuleResponseFields, + ThresholdRuleResponseFields, + ThreatMatchRuleResponseFields, + MachineLearningRuleResponseFields, + NewTermsRuleResponseFields, + EsqlRuleResponseFields, + ]) +); export type TypeSpecificResponse = z.infer; export const TypeSpecificResponse = TypeSpecificResponseInternal as z.ZodType; -export const RuleCreatePropsInternal = z.discriminatedUnion('type', [ - EqlRuleCreateProps, - QueryRuleCreateProps, - SavedQueryRuleCreateProps, - ThresholdRuleCreateProps, - ThreatMatchRuleCreateProps, - MachineLearningRuleCreateProps, - NewTermsRuleCreateProps, - EsqlRuleCreateProps, -]); +export const RuleCreatePropsInternal = lazySchema(() => + z.discriminatedUnion('type', [ + EqlRuleCreateProps, + QueryRuleCreateProps, + SavedQueryRuleCreateProps, + ThresholdRuleCreateProps, + ThreatMatchRuleCreateProps, + MachineLearningRuleCreateProps, + NewTermsRuleCreateProps, + EsqlRuleCreateProps, + ]) +); export type RuleCreateProps = z.infer; export const RuleCreateProps = RuleCreatePropsInternal as z.ZodType; -export const RuleUpdatePropsInternal = z.discriminatedUnion('type', [ - EqlRuleUpdateProps, - QueryRuleUpdateProps, - SavedQueryRuleUpdateProps, - ThresholdRuleUpdateProps, - ThreatMatchRuleUpdateProps, - MachineLearningRuleUpdateProps, - NewTermsRuleUpdateProps, - EsqlRuleUpdateProps, -]); +export const RuleUpdatePropsInternal = lazySchema(() => + z.discriminatedUnion('type', [ + EqlRuleUpdateProps, + QueryRuleUpdateProps, + SavedQueryRuleUpdateProps, + ThresholdRuleUpdateProps, + ThreatMatchRuleUpdateProps, + MachineLearningRuleUpdateProps, + NewTermsRuleUpdateProps, + EsqlRuleUpdateProps, + ]) +); export type RuleUpdateProps = z.infer; export const RuleUpdateProps = RuleUpdatePropsInternal as z.ZodType; -export const RulePatchPropsInternal = z.union([ - EqlRulePatchProps, - QueryRulePatchProps, - SavedQueryRulePatchProps, - ThresholdRulePatchProps, - ThreatMatchRulePatchProps, - MachineLearningRulePatchProps, - NewTermsRulePatchProps, - EsqlRulePatchProps, -]); +export const RulePatchPropsInternal = lazySchema(() => + z.union([ + EqlRulePatchProps, + QueryRulePatchProps, + SavedQueryRulePatchProps, + ThresholdRulePatchProps, + ThreatMatchRulePatchProps, + MachineLearningRulePatchProps, + NewTermsRulePatchProps, + EsqlRulePatchProps, + ]) +); export type RulePatchProps = z.infer; export const RulePatchProps = RulePatchPropsInternal as z.ZodType; -export const RuleResponseInternal = z.discriminatedUnion('type', [ - EqlRule, - QueryRule, - SavedQueryRule, - ThresholdRule, - ThreatMatchRule, - MachineLearningRule, - NewTermsRule, - EsqlRule, -]); +export const RuleResponseInternal = lazySchema(() => + z.discriminatedUnion('type', [ + EqlRule, + QueryRule, + SavedQueryRule, + ThresholdRule, + ThreatMatchRule, + MachineLearningRule, + NewTermsRule, + EsqlRule, + ]) +); export type RuleResponse = z.infer; export const RuleResponse = RuleResponseInternal as z.ZodType; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/eql_attributes.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/eql_attributes.gen.ts index 08915a37469af..2a763dc5350cf 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/eql_attributes.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/eql_attributes.gen.ts @@ -14,19 +14,19 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const EventCategoryOverride = lazySchema(() => z.string()); export type EventCategoryOverride = z.infer; -export const EventCategoryOverride = z.string(); /** * Specifies the name of the event timestamp field used for sorting a sequence of events. Not to be confused with `timestamp_override`, which specifies the more general field used for querying events within a range. Defaults to the @timestamp ECS field. */ +export const TimestampField = lazySchema(() => z.string()); export type TimestampField = z.infer; -export const TimestampField = z.string(); /** * Sets a secondary field for sorting events */ +export const TiebreakerField = lazySchema(() => z.string()); export type TiebreakerField = z.infer; -export const TiebreakerField = z.string(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/ml_attributes.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/ml_attributes.gen.ts index c9bdcc21bc907..b5e18956299d6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/ml_attributes.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/ml_attributes.gen.ts @@ -14,16 +14,18 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Anomaly score threshold above which the rule creates an alert. Valid values are from 0 to 100. */ +export const AnomalyThreshold = lazySchema(() => z.number().int().min(0)); export type AnomalyThreshold = z.infer; -export const AnomalyThreshold = z.number().int().min(0); /** * Machine learning job ID(s) the rule monitors for anomaly scores. */ +export const MachineLearningJobId = lazySchema(() => + z.union([z.string(), z.array(z.string()).min(1)]) +); export type MachineLearningJobId = z.infer; -export const MachineLearningJobId = z.union([z.string(), z.array(z.string()).min(1)]); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.gen.ts index 344217de28e2e..d4ae74d60e269 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/new_terms_attributes.gen.ts @@ -14,17 +14,17 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; /** * Fields to monitor for new values. */ +export const NewTermsFields = lazySchema(() => z.array(z.string()).min(1).max(3)); export type NewTermsFields = z.infer; -export const NewTermsFields = z.array(z.string()).min(1).max(3); /** * Start date to use when checking if a term has been seen before. Supports relative dates – for example, now-30d will search the last 30 days of data when checking if a term is new. We do not recommend using absolute dates, which can cause issues with rule performance due to querying increasing amounts of data over time. */ +export const HistoryWindowStart = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type HistoryWindowStart = z.infer; -export const HistoryWindowStart = z.string().min(1).superRefine(isNonEmptyString); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threat_match_attributes.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threat_match_attributes.gen.ts index a10a954b08b94..84cb523a8ed45 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threat_match_attributes.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threat_match_attributes.gen.ts @@ -14,23 +14,25 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../../../../model/primitives.gen'; /** * Query used to determine which fields in the Elasticsearch index are used for generating alerts. */ +export const ThreatQuery = lazySchema(() => z.string()); export type ThreatQuery = z.infer; -export const ThreatQuery = z.string(); +export const ThreatMappingEntry = lazySchema(() => + z.object({ + field: NonEmptyString, + type: z.literal('mapping'), + value: NonEmptyString, + negate: z.boolean().optional(), + }) +); export type ThreatMappingEntry = z.infer; -export const ThreatMappingEntry = z.object({ - field: NonEmptyString, - type: z.literal('mapping'), - value: NonEmptyString, - negate: z.boolean().optional(), -}); /** * Array of entries objects that define mappings between the source event fields and the values in the Elasticsearch threat index. Each entries object must contain these fields: @@ -42,32 +44,34 @@ export const ThreatMappingEntry = z.object({ You can use Boolean and and or logic to define the conditions for when matching fields and values generate alerts. Sibling entries objects are evaluated using or logic, whereas multiple entries in a single entries object use and logic. See Example of Threat Match rule which uses both `and` and `or` logic. */ +export const ThreatMapping = lazySchema(() => + z + .array( + z.object({ + entries: z.array(ThreatMappingEntry), + }) + ) + .min(1) +); export type ThreatMapping = z.infer; -export const ThreatMapping = z - .array( - z.object({ - entries: z.array(ThreatMappingEntry), - }) - ) - .min(1); /** * Elasticsearch indices used to check which field values generate alerts. */ +export const ThreatIndex = lazySchema(() => z.array(z.string())); export type ThreatIndex = z.infer; -export const ThreatIndex = z.array(z.string()); +export const ThreatFilters = lazySchema(() => z.array(z.unknown())); export type ThreatFilters = z.infer; -export const ThreatFilters = z.array(z.unknown()); /** * Defines the path to the threat indicator in the indicator documents (optional) */ +export const ThreatIndicatorPath = lazySchema(() => z.string()); export type ThreatIndicatorPath = z.infer; -export const ThreatIndicatorPath = z.string(); +export const ConcurrentSearches = lazySchema(() => z.number().int().min(1)); export type ConcurrentSearches = z.infer; -export const ConcurrentSearches = z.number().int().min(1); +export const ItemsPerSearch = lazySchema(() => z.number().int().min(1)); export type ItemsPerSearch = z.infer; -export const ItemsPerSearch = z.number().int().min(1); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threshold_attributes.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threshold_attributes.gen.ts index 3301f16bfca05..d23d34d135fa4 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threshold_attributes.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/specific_attributes/threshold_attributes.gen.ts @@ -14,70 +14,80 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AlertSuppressionDuration } from '../common_attributes.gen'; /** * The field on which the cardinality is applied. */ -export type ThresholdCardinality = z.infer; -export const ThresholdCardinality = z.array( - z.object({ - /** - * The field on which to calculate and compare the cardinality. - */ - field: z.string(), - /** - * The threshold value from which an alert is generated based on unique number of values of cardinality.field. - */ - value: z.number().int().min(0), - }) +export const ThresholdCardinality = lazySchema(() => + z.array( + z.object({ + /** + * The field on which to calculate and compare the cardinality. + */ + field: z.string(), + /** + * The threshold value from which an alert is generated based on unique number of values of cardinality.field. + */ + value: z.number().int().min(0), + }) + ) ); +export type ThresholdCardinality = z.infer; /** * The threshold value from which an alert is generated. */ +export const ThresholdValue = lazySchema(() => z.number().int().min(1)); export type ThresholdValue = z.infer; -export const ThresholdValue = z.number().int().min(1); /** * The field on which the threshold is applied. If you specify an empty array ([]), alerts are generated when the query returns at least the number of results specified in the value field. */ +export const ThresholdField = lazySchema(() => z.union([z.string(), z.array(z.string()).max(5)])); export type ThresholdField = z.infer; -export const ThresholdField = z.union([z.string(), z.array(z.string()).max(5)]); /** * Field to aggregate on */ +export const ThresholdFieldNormalized = lazySchema(() => z.array(z.string())); export type ThresholdFieldNormalized = z.infer; -export const ThresholdFieldNormalized = z.array(z.string()); +export const Threshold = lazySchema(() => + z.object({ + field: ThresholdField, + value: ThresholdValue, + cardinality: ThresholdCardinality.optional(), + }) +); export type Threshold = z.infer; -export const Threshold = z.object({ - field: ThresholdField, - value: ThresholdValue, - cardinality: ThresholdCardinality.optional(), -}); +export const ThresholdNormalized = lazySchema(() => + z.object({ + field: ThresholdFieldNormalized, + value: ThresholdValue, + cardinality: ThresholdCardinality.optional(), + }) +); export type ThresholdNormalized = z.infer; -export const ThresholdNormalized = z.object({ - field: ThresholdFieldNormalized, - value: ThresholdValue, - cardinality: ThresholdCardinality.optional(), -}); +export const ThresholdWithCardinality = lazySchema(() => + z.object({ + field: ThresholdFieldNormalized, + value: ThresholdValue, + cardinality: ThresholdCardinality, + }) +); export type ThresholdWithCardinality = z.infer; -export const ThresholdWithCardinality = z.object({ - field: ThresholdFieldNormalized, - value: ThresholdValue, - cardinality: ThresholdCardinality, -}); /** * Defines alert suppression configuration. */ +export const ThresholdAlertSuppression = lazySchema(() => + z.object({ + duration: AlertSuppressionDuration, + }) +); export type ThresholdAlertSuppression = z.infer; -export const ThresholdAlertSuppression = z.object({ - duration: AlertSuppressionDuration, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_assignees_body.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_assignees_body.gen.ts index f6fc776936f20..7d5e04953b309 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_assignees_body.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_assignees_body.gen.ts @@ -14,22 +14,26 @@ * version: 1.0.0 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; import { AlertIds } from '../../model/alert.gen'; +export const AlertAssignees = lazySchema(() => + z.object({ + add: z.array(z.string().min(1).superRefine(isNonEmptyString)), + remove: z.array(z.string().min(1).superRefine(isNonEmptyString)), + }) +); export type AlertAssignees = z.infer; -export const AlertAssignees = z.object({ - add: z.array(z.string().min(1).superRefine(isNonEmptyString)), - remove: z.array(z.string().min(1).superRefine(isNonEmptyString)), -}); +export const SetAlertAssigneesBody = lazySchema(() => + z.object({ + /** + * Details about the assignees to assign and unassign. + */ + assignees: AlertAssignees, + ids: AlertIds, + }) +); export type SetAlertAssigneesBody = z.infer; -export const SetAlertAssigneesBody = z.object({ - /** - * Details about the assignees to assign and unassign. - */ - assignees: AlertAssignees, - ids: AlertIds, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_tags_body.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_tags_body.gen.ts index d06b2687508bf..024ba834355d9 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_tags_body.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/set_alert_tags_body.gen.ts @@ -14,21 +14,25 @@ * version: 1.0.0 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AlertIds, AlertTags } from '../../model/alert.gen'; /** * Object with list of tags to add and remove. */ +export const SetAlertTags = lazySchema(() => + z.object({ + tags_to_add: AlertTags, + tags_to_remove: AlertTags, + }) +); export type SetAlertTags = z.infer; -export const SetAlertTags = z.object({ - tags_to_add: AlertTags, - tags_to_remove: AlertTags, -}); +export const SetAlertTagsBody = lazySchema(() => + z.object({ + ids: AlertIds, + tags: SetAlertTags, + }) +); export type SetAlertTagsBody = z.infer; -export const SetAlertTagsBody = z.object({ - ids: AlertIds, - tags: SetAlertTags, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/sorting.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/sorting.gen.ts index 43ad13f6af3e8..c61b1538217b7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/sorting.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/sorting.gen.ts @@ -14,9 +14,9 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const SortOrder = lazySchema(() => z.enum(['asc', 'desc'])); export type SortOrder = z.infer; -export const SortOrder = z.enum(['asc', 'desc']); export type SortOrderEnum = typeof SortOrder.enum; export const SortOrderEnum = SortOrder.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts index 0613ec574a955..4dad0205bc8b8 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts @@ -14,12 +14,14 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const WarningSchema = lazySchema(() => + z.object({ + type: z.string(), + message: z.string(), + actionPath: z.string(), + buttonLabel: z.string().optional(), + }) +); export type WarningSchema = z.infer; -export const WarningSchema = z.object({ - type: z.string(), - message: z.string(), - actionPath: z.string(), - buttonLabel: z.string().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.gen.ts index f95330fc5a520..60629507e32e6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.gen.ts @@ -14,79 +14,87 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const PackageInstallStatus = lazySchema(() => + z.object({ + /** + * The name of the package + */ + name: z.string(), + /** + * The version of the package + */ + version: z.string(), + /** + * The status of the package installation + */ + status: z.enum(['installed', 'already_installed']), + }) +); export type PackageInstallStatus = z.infer; -export const PackageInstallStatus = z.object({ - /** - * The name of the package - */ - name: z.string(), - /** - * The version of the package - */ - version: z.string(), - /** - * The status of the package installation - */ - status: z.enum(['installed', 'already_installed']), -}); +export const RuleBootstrapError = lazySchema(() => + z.object({ + /** + * The list of rules that failed to bootstrap + */ + rules: z.array( + z.object({ + /** + * The ID of the rule that failed to bootstrap + */ + rule_id: z.string(), + }) + ), + /** + * The error message + */ + message: z.string(), + }) +); export type RuleBootstrapError = z.infer; -export const RuleBootstrapError = z.object({ - /** - * The list of rules that failed to bootstrap - */ - rules: z.array( - z.object({ - /** - * The ID of the rule that failed to bootstrap - */ - rule_id: z.string(), - }) - ), - /** - * The error message - */ - message: z.string(), -}); +export const RuleBootstrapResults = lazySchema(() => + z.object({ + /** + * The total number of rules to be processed. This is a dynamic value and depends on the number of integrations installed that have bootstrappable rules + */ + total: z.number().optional(), + /** + * The number of rules that were installed + */ + installed: z.number(), + /** + * The number of rules that were updated + */ + updated: z.number(), + /** + * The number of rules that were deleted + */ + deleted: z.number(), + /** + * The number of rules that were skipped (already installed rules with no updates) + */ + skipped: z.number().optional(), + /** + * The list of bootstrap errors + */ + errors: z.array(RuleBootstrapError), + }) +); export type RuleBootstrapResults = z.infer; -export const RuleBootstrapResults = z.object({ - /** - * The total number of rules to be processed. This is a dynamic value and depends on the number of integrations installed that have bootstrappable rules - */ - total: z.number().optional(), - /** - * The number of rules that were installed - */ - installed: z.number(), - /** - * The number of rules that were updated - */ - updated: z.number(), - /** - * The number of rules that were deleted - */ - deleted: z.number(), - /** - * The number of rules that were skipped (already installed rules with no updates) - */ - skipped: z.number().optional(), - /** - * The list of bootstrap errors - */ - errors: z.array(RuleBootstrapError), -}); +export const BootstrapPrebuiltRulesResponse = lazySchema(() => + z.object({ + /** + * The list of packages that were installed or upgraded + */ + packages: z.array(PackageInstallStatus), + /** + * The list of rules that were installed or upgraded + */ + rules: RuleBootstrapResults.optional(), + }) +); export type BootstrapPrebuiltRulesResponse = z.infer; -export const BootstrapPrebuiltRulesResponse = z.object({ - /** - * The list of packages that were installed or upgraded - */ - packages: z.array(PackageInstallStatus), - /** - * The list of rules that were installed or upgraded - */ - rules: RuleBootstrapResults.optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.gen.ts index 20a2eaba779c2..a4bfa3a768e98 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.gen.ts @@ -14,28 +14,30 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const InstallPrebuiltRulesAndTimelinesResponse = lazySchema(() => + z + .object({ + /** + * The number of rules installed + */ + rules_installed: z.number().int().min(0), + /** + * The number of rules updated + */ + rules_updated: z.number().int().min(0), + /** + * The number of timelines installed + */ + timelines_installed: z.number().int().min(0), + /** + * The number of timelines updated + */ + timelines_updated: z.number().int().min(0), + }) + .strict() +); export type InstallPrebuiltRulesAndTimelinesResponse = z.infer< typeof InstallPrebuiltRulesAndTimelinesResponse >; -export const InstallPrebuiltRulesAndTimelinesResponse = z - .object({ - /** - * The number of rules installed - */ - rules_installed: z.number().int().min(0), - /** - * The number of rules updated - */ - rules_updated: z.number().int().min(0), - /** - * The number of timelines installed - */ - timelines_installed: z.number().int().min(0), - /** - * The number of timelines updated - */ - timelines_updated: z.number().int().min(0), - }) - .strict(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/read_prebuilt_rules_and_timelines_status/read_prebuilt_rules_and_timelines_status_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/read_prebuilt_rules_and_timelines_status/read_prebuilt_rules_and_timelines_status_route.gen.ts index 4c545fce40bfb..fb6680f450195 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/read_prebuilt_rules_and_timelines_status/read_prebuilt_rules_and_timelines_status_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/read_prebuilt_rules_and_timelines_status/read_prebuilt_rules_and_timelines_status_route.gen.ts @@ -14,40 +14,42 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ReadPrebuiltRulesAndTimelinesStatusResponse = lazySchema(() => + z + .object({ + /** + * The total number of custom rules + */ + rules_custom_installed: z.number().int().min(0), + /** + * The total number of installed prebuilt rules + */ + rules_installed: z.number().int().min(0), + /** + * The total number of available prebuilt rules that are not installed + */ + rules_not_installed: z.number().int().min(0), + /** + * The total number of outdated prebuilt rules + */ + rules_not_updated: z.number().int().min(0), + /** + * The total number of installed prebuilt timelines + */ + timelines_installed: z.number().int().min(0), + /** + * The total number of available prebuilt timelines that are not installed + */ + timelines_not_installed: z.number().int().min(0), + /** + * The total number of outdated prebuilt timelines + */ + timelines_not_updated: z.number().int().min(0), + }) + .strict() +); export type ReadPrebuiltRulesAndTimelinesStatusResponse = z.infer< typeof ReadPrebuiltRulesAndTimelinesStatusResponse >; -export const ReadPrebuiltRulesAndTimelinesStatusResponse = z - .object({ - /** - * The total number of custom rules - */ - rules_custom_installed: z.number().int().min(0), - /** - * The total number of installed prebuilt rules - */ - rules_installed: z.number().int().min(0), - /** - * The total number of available prebuilt rules that are not installed - */ - rules_not_installed: z.number().int().min(0), - /** - * The total number of outdated prebuilt rules - */ - rules_not_updated: z.number().int().min(0), - /** - * The total number of installed prebuilt timelines - */ - timelines_installed: z.number().int().min(0), - /** - * The total number of available prebuilt timelines that are not installed - */ - timelines_not_installed: z.number().int().min(0), - /** - * The total number of outdated prebuilt timelines - */ - timelines_not_updated: z.number().int().min(0), - }) - .strict(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts index 90367f16b752d..4084df52516f1 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { RuleResponse } from '../../model/rule_schema/rule_schemas.gen'; @@ -34,204 +34,234 @@ import { } from '../../model/rule_schema/common_attributes.gen'; import { ThresholdAlertSuppression } from '../../model/rule_schema/specific_attributes/threshold_attributes.gen'; +export const BulkEditSkipReason = lazySchema(() => z.literal('RULE_NOT_MODIFIED')); export type BulkEditSkipReason = z.infer; -export const BulkEditSkipReason = z.literal('RULE_NOT_MODIFIED'); +export const BulkGapsFillingSkipReason = lazySchema(() => z.literal('NO_GAPS_TO_FILL')); export type BulkGapsFillingSkipReason = z.infer; -export const BulkGapsFillingSkipReason = z.literal('NO_GAPS_TO_FILL'); +export const BulkActionSkipResult = lazySchema(() => + z.object({ + id: z.string(), + name: z.string().optional(), + skip_reason: z.union([BulkEditSkipReason, BulkGapsFillingSkipReason]), + }) +); export type BulkActionSkipResult = z.infer; -export const BulkActionSkipResult = z.object({ - id: z.string(), - name: z.string().optional(), - skip_reason: z.union([BulkEditSkipReason, BulkGapsFillingSkipReason]), -}); +export const RuleDetailsInError = lazySchema(() => + z.object({ + id: z.string(), + name: z.string().optional(), + }) +); export type RuleDetailsInError = z.infer; -export const RuleDetailsInError = z.object({ - id: z.string(), - name: z.string().optional(), -}); +export const BulkActionsDryRunErrCode = lazySchema(() => + z.enum([ + 'IMMUTABLE', + 'PREBUILT_CUSTOMIZATION_LICENSE', + 'MACHINE_LEARNING_AUTH', + 'MACHINE_LEARNING_INDEX_PATTERN', + 'ESQL_INDEX_PATTERN', + 'MANUAL_RULE_RUN_FEATURE', + 'MANUAL_RULE_RUN_DISABLED_RULE', + 'THRESHOLD_RULE_TYPE_IN_SUPPRESSION', + 'UNSUPPORTED_RULE_IN_SUPPRESSION_FOR_THRESHOLD', + 'RULE_FILL_GAPS_DISABLED_RULE', + 'USER_INSUFFICIENT_RULE_PRIVILEGES', + ]) +); export type BulkActionsDryRunErrCode = z.infer; -export const BulkActionsDryRunErrCode = z.enum([ - 'IMMUTABLE', - 'PREBUILT_CUSTOMIZATION_LICENSE', - 'MACHINE_LEARNING_AUTH', - 'MACHINE_LEARNING_INDEX_PATTERN', - 'ESQL_INDEX_PATTERN', - 'MANUAL_RULE_RUN_FEATURE', - 'MANUAL_RULE_RUN_DISABLED_RULE', - 'THRESHOLD_RULE_TYPE_IN_SUPPRESSION', - 'UNSUPPORTED_RULE_IN_SUPPRESSION_FOR_THRESHOLD', - 'RULE_FILL_GAPS_DISABLED_RULE', - 'USER_INSUFFICIENT_RULE_PRIVILEGES', -]); export type BulkActionsDryRunErrCodeEnum = typeof BulkActionsDryRunErrCode.enum; export const BulkActionsDryRunErrCodeEnum = BulkActionsDryRunErrCode.enum; +export const NormalizedRuleError = lazySchema(() => + z.object({ + message: z.string(), + status_code: z.number().int(), + err_code: BulkActionsDryRunErrCode.optional(), + rules: z.array(RuleDetailsInError), + }) +); export type NormalizedRuleError = z.infer; -export const NormalizedRuleError = z.object({ - message: z.string(), - status_code: z.number().int(), - err_code: BulkActionsDryRunErrCode.optional(), - rules: z.array(RuleDetailsInError), -}); +export const BulkEditActionResults = lazySchema(() => + z.object({ + updated: z.array(RuleResponse), + created: z.array(RuleResponse), + deleted: z.array(RuleResponse), + skipped: z.array(BulkActionSkipResult), + }) +); export type BulkEditActionResults = z.infer; -export const BulkEditActionResults = z.object({ - updated: z.array(RuleResponse), - created: z.array(RuleResponse), - deleted: z.array(RuleResponse), - skipped: z.array(BulkActionSkipResult), -}); /** * A rule can only be skipped when the bulk action to be performed on it results in nothing being done. For example, if the `edit` action is used to add a tag to a rule that already has that tag, or to delete an index pattern that is not specified in a rule. Objects returned in `attributes.results.skipped` will only include rules' `id`, `name`, and `skip_reason`. */ +export const BulkEditActionSummary = lazySchema(() => + z.object({ + failed: z.number().int(), + skipped: z.number().int(), + succeeded: z.number().int(), + total: z.number().int(), + }) +); export type BulkEditActionSummary = z.infer; -export const BulkEditActionSummary = z.object({ - failed: z.number().int(), - skipped: z.number().int(), - succeeded: z.number().int(), - total: z.number().int(), -}); +export const BulkEditActionResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + status_code: z.number().int().optional(), + message: z.string().optional(), + rules_count: z.number().int().optional(), + attributes: z.object({ + results: BulkEditActionResults, + summary: BulkEditActionSummary, + errors: z.array(NormalizedRuleError).optional(), + }), + }) +); export type BulkEditActionResponse = z.infer; -export const BulkEditActionResponse = z.object({ - success: z.boolean().optional(), - status_code: z.number().int().optional(), - message: z.string().optional(), - rules_count: z.number().int().optional(), - attributes: z.object({ - results: BulkEditActionResults, - summary: BulkEditActionSummary, - errors: z.array(NormalizedRuleError).optional(), - }), -}); +export const BulkExportActionResponse = lazySchema(() => z.string()); export type BulkExportActionResponse = z.infer; -export const BulkExportActionResponse = z.string(); -export type BulkActionBase = z.infer; -export const BulkActionBase = z.object({ - /** - * Query to filter rules. - */ - query: z.string().optional(), - /** +export const BulkActionBase = lazySchema(() => + z.object({ + /** + * Query to filter rules. + */ + query: z.string().optional(), + /** * Array of rule `id`s to which a bulk action will be applied. Do not use rule's `rule_id` here. Only valid when query property is undefined. */ - ids: z.array(z.string()).min(1).optional(), - /** - * Gaps range start, valid only when query is provided - */ - gaps_range_start: z.string().optional(), - /** - * Gaps range end, valid only when query is provided - */ - gaps_range_end: z.string().optional(), - /** - * Gap fill statuses to filter rules with gaps by status (used together with gaps_range_*). - */ - gap_fill_statuses: z.array(GapFillStatus).optional(), - /** - * Gap auto fill scheduler ID used to determine gap fill status for rules - */ - gap_auto_fill_scheduler_id: z.string().optional(), -}); - -export type BulkDeleteRules = z.infer; -export const BulkDeleteRules = BulkActionBase.extend( - z.object({ - action: z.literal('delete'), + ids: z.array(z.string()).min(1).optional(), + /** + * Gaps range start, valid only when query is provided + */ + gaps_range_start: z.string().optional(), + /** + * Gaps range end, valid only when query is provided + */ + gaps_range_end: z.string().optional(), + /** + * Gap fill statuses to filter rules with gaps by status (used together with gaps_range_*). + */ + gap_fill_statuses: z.array(GapFillStatus).optional(), + /** + * Gap auto fill scheduler ID used to determine gap fill status for rules + */ + gap_auto_fill_scheduler_id: z.string().optional(), }) ); +export type BulkActionBase = z.infer; -export type BulkDisableRules = z.infer; -export const BulkDisableRules = BulkActionBase.extend( - z.object({ - action: z.literal('disable'), - }) +export const BulkDeleteRules = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('delete'), + }) + ) ); +export type BulkDeleteRules = z.infer; -export type BulkEnableRules = z.infer; -export const BulkEnableRules = BulkActionBase.extend( - z.object({ - action: z.literal('enable'), - }) +export const BulkDisableRules = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('disable'), + }) + ) ); +export type BulkDisableRules = z.infer; -export type BulkExportRules = z.infer; -export const BulkExportRules = BulkActionBase.extend( - z.object({ - action: z.literal('export'), - }) +export const BulkEnableRules = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('enable'), + }) + ) ); +export type BulkEnableRules = z.infer; -export type BulkDuplicateRules = z.infer; -export const BulkDuplicateRules = BulkActionBase.extend( - z.object({ - action: z.literal('duplicate'), - /** - * Duplicate object that describes applying an update action. - */ - duplicate: z - .object({ - /** - * Whether to copy exceptions from the original rule - */ - include_exceptions: z.boolean(), - /** - * Whether to copy expired exceptions from the original rule - */ - include_expired_exceptions: z.boolean(), - }) - .optional(), - }) +export const BulkExportRules = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('export'), + }) + ) ); +export type BulkExportRules = z.infer; -export type BulkManualRuleRun = z.infer; -export const BulkManualRuleRun = BulkActionBase.extend( - z.object({ - action: z.literal('run'), - /** - * Object that describes applying a manual rule run action. - */ - run: z.object({ - /** - * Start date of the manual rule run - */ - start_date: z.string(), +export const BulkDuplicateRules = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('duplicate'), /** - * End date of the manual rule run + * Duplicate object that describes applying an update action. */ - end_date: z.string(), - }), - }) + duplicate: z + .object({ + /** + * Whether to copy exceptions from the original rule + */ + include_exceptions: z.boolean(), + /** + * Whether to copy expired exceptions from the original rule + */ + include_expired_exceptions: z.boolean(), + }) + .optional(), + }) + ) ); +export type BulkDuplicateRules = z.infer; -export type BulkManualRuleFillGaps = z.infer; -export const BulkManualRuleFillGaps = BulkActionBase.extend( - z.object({ - action: z.literal('fill_gaps'), - /** - * Object that describes applying a manual gap fill action for the specified time range. - */ - fill_gaps: z.object({ +export const BulkManualRuleRun = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('run'), /** - * Start date of the manual gap fill + * Object that describes applying a manual rule run action. */ - start_date: z.string(), + run: z.object({ + /** + * Start date of the manual rule run + */ + start_date: z.string(), + /** + * End date of the manual rule run + */ + end_date: z.string(), + }), + }) + ) +); +export type BulkManualRuleRun = z.infer; + +export const BulkManualRuleFillGaps = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('fill_gaps'), /** - * End date of the manual gap fill + * Object that describes applying a manual gap fill action for the specified time range. */ - end_date: z.string(), - }), - }) + fill_gaps: z.object({ + /** + * Start date of the manual gap fill + */ + start_date: z.string(), + /** + * End date of the manual gap fill + */ + end_date: z.string(), + }), + }) + ) ); +export type BulkManualRuleFillGaps = z.infer; /** * Defines the maximum interval in which a rule’s actions are executed. @@ -240,57 +270,54 @@ export const BulkManualRuleFillGaps = BulkActionBase.extend( > In Elastic Security 8.8 and later, you can use the `frequency` field to define frequencies for individual actions. Actions without frequencies will acquire a converted version of the rule’s `throttle` field. In the response, the converted `throttle` setting appears in the individual actions' `frequency` field. */ +export const ThrottleForBulkActions = lazySchema(() => z.enum(['rule', '1h', '1d', '7d'])); export type ThrottleForBulkActions = z.infer; -export const ThrottleForBulkActions = z.enum(['rule', '1h', '1d', '7d']); export type ThrottleForBulkActionsEnum = typeof ThrottleForBulkActions.enum; export const ThrottleForBulkActionsEnum = ThrottleForBulkActions.enum; +export const BulkActionType = lazySchema(() => + z.enum(['enable', 'disable', 'export', 'delete', 'duplicate', 'edit', 'run', 'fill_gaps']) +); export type BulkActionType = z.infer; -export const BulkActionType = z.enum([ - 'enable', - 'disable', - 'export', - 'delete', - 'duplicate', - 'edit', - 'run', - 'fill_gaps', -]); export type BulkActionTypeEnum = typeof BulkActionType.enum; export const BulkActionTypeEnum = BulkActionType.enum; +export const BulkActionEditType = lazySchema(() => + z.enum([ + 'add_tags', + 'delete_tags', + 'set_tags', + 'add_index_patterns', + 'delete_index_patterns', + 'set_index_patterns', + 'set_timeline', + 'add_rule_actions', + 'set_rule_actions', + 'set_schedule', + 'add_investigation_fields', + 'delete_investigation_fields', + 'set_investigation_fields', + 'delete_alert_suppression', + 'set_alert_suppression', + 'set_alert_suppression_for_threshold', + ]) +); export type BulkActionEditType = z.infer; -export const BulkActionEditType = z.enum([ - 'add_tags', - 'delete_tags', - 'set_tags', - 'add_index_patterns', - 'delete_index_patterns', - 'set_index_patterns', - 'set_timeline', - 'add_rule_actions', - 'set_rule_actions', - 'set_schedule', - 'add_investigation_fields', - 'delete_investigation_fields', - 'set_investigation_fields', - 'delete_alert_suppression', - 'set_alert_suppression', - 'set_alert_suppression_for_threshold', -]); export type BulkActionEditTypeEnum = typeof BulkActionEditType.enum; export const BulkActionEditTypeEnum = BulkActionEditType.enum; +export const NormalizedRuleAction = lazySchema(() => + z + .object({ + group: RuleActionGroup.optional(), + id: RuleActionId, + params: RuleActionParams, + frequency: RuleActionFrequency.optional(), + alerts_filter: RuleActionAlertsFilter.optional(), + }) + .strict() +); export type NormalizedRuleAction = z.infer; -export const NormalizedRuleAction = z - .object({ - group: RuleActionGroup.optional(), - id: RuleActionId, - params: RuleActionParams, - frequency: RuleActionFrequency.optional(), - alerts_filter: RuleActionAlertsFilter.optional(), - }) - .strict(); /** * Edits rule actions of rules. @@ -299,14 +326,16 @@ export const NormalizedRuleAction = z - `set_rule_actions` sets rule actions for rules. This action is non-idempotent, meaning that even if the same set of rule actions already exists for a rule, it will be set again and the actions will receive new unique IDs. */ +export const BulkActionEditPayloadRuleActions = lazySchema(() => + z.object({ + type: z.enum(['add_rule_actions', 'set_rule_actions']), + value: z.object({ + throttle: ThrottleForBulkActions.optional(), + actions: z.array(NormalizedRuleAction), + }), + }) +); export type BulkActionEditPayloadRuleActions = z.infer; -export const BulkActionEditPayloadRuleActions = z.object({ - type: z.enum(['add_rule_actions', 'set_rule_actions']), - value: z.object({ - throttle: ThrottleForBulkActions.optional(), - actions: z.array(NormalizedRuleAction), - }), -}); /** * Overwrites schedule of rules. @@ -316,23 +345,25 @@ export const BulkActionEditPayloadRuleActions = z.object({ Both `interval` and `lookback` have a format of "{integer}{time_unit}", where accepted time units are `s` for seconds, `m` for minutes, and `h` for hours. The integer must be positive and larger than 0. Examples: "45s", "30m", "6h" */ -export type BulkActionEditPayloadSchedule = z.infer; -export const BulkActionEditPayloadSchedule = z.object({ - type: z.literal('set_schedule'), - value: z.object({ - /** - * Interval in which the rule runs. For example, `"1h"` means the rule runs every hour. - */ - interval: z.string().regex(/^[1-9]\d*[smh]$/), - /** +export const BulkActionEditPayloadSchedule = lazySchema(() => + z.object({ + type: z.literal('set_schedule'), + value: z.object({ + /** + * Interval in which the rule runs. For example, `"1h"` means the rule runs every hour. + */ + interval: z.string().regex(/^[1-9]\d*[smh]$/), + /** * Lookback time for the rules. Additional look-back time that the rule analyzes. For example, "10m" means the rule analyzes the last 10 minutes of data in addition to the frequency interval. */ - lookback: z.string().regex(/^[1-9]\d*[smh]$/), - }), -}); + lookback: z.string().regex(/^[1-9]\d*[smh]$/), + }), + }) +); +export type BulkActionEditPayloadSchedule = z.infer; /** * Edits index patterns of rulesClient. @@ -342,15 +373,17 @@ Additional look-back time that the rule analyzes. For example, "10m" means the r - `set_index_patterns` sets index patterns for rules, overwriting any existing index patterns. If the set of index patterns is the same as the existing index patterns, no changes are made. */ +export const BulkActionEditPayloadIndexPatterns = lazySchema(() => + z.object({ + type: z.enum(['add_index_patterns', 'delete_index_patterns', 'set_index_patterns']), + value: IndexPatternArray, + /** + * Resets the data view for the rule. + */ + overwrite_data_views: z.boolean().optional(), + }) +); export type BulkActionEditPayloadIndexPatterns = z.infer; -export const BulkActionEditPayloadIndexPatterns = z.object({ - type: z.enum(['add_index_patterns', 'delete_index_patterns', 'set_index_patterns']), - value: IndexPatternArray, - /** - * Resets the data view for the rule. - */ - overwrite_data_views: z.boolean().optional(), -}); /** * Edits tags of rules. @@ -360,11 +393,13 @@ export const BulkActionEditPayloadIndexPatterns = z.object({ - `set_tags` sets tags for rules, overwriting any existing tags. If the set of tags is the same as the existing tags, no changes are made. */ +export const BulkActionEditPayloadTags = lazySchema(() => + z.object({ + type: z.enum(['add_tags', 'delete_tags', 'set_tags']), + value: RuleTagArray, + }) +); export type BulkActionEditPayloadTags = z.infer; -export const BulkActionEditPayloadTags = z.object({ - type: z.enum(['add_tags', 'delete_tags', 'set_tags']), - value: RuleTagArray, -}); /** * Edits investigation fields of rules. @@ -374,17 +409,19 @@ export const BulkActionEditPayloadTags = z.object({ - `set_investigation_fields` sets investigation fields for rules. If the set of investigation fields is the same as the existing investigation fields, no changes are made. */ +export const BulkActionEditPayloadInvestigationFields = lazySchema(() => + z.object({ + type: z.enum([ + 'add_investigation_fields', + 'delete_investigation_fields', + 'set_investigation_fields', + ]), + value: InvestigationFields, + }) +); export type BulkActionEditPayloadInvestigationFields = z.infer< typeof BulkActionEditPayloadInvestigationFields >; -export const BulkActionEditPayloadInvestigationFields = z.object({ - type: z.enum([ - 'add_investigation_fields', - 'delete_investigation_fields', - 'set_investigation_fields', - ]), - value: InvestigationFields, -}); /** * Edits timeline of rules. @@ -392,43 +429,53 @@ export const BulkActionEditPayloadInvestigationFields = z.object({ - `set_timeline` sets a timeline for rules. If the same timeline already exists for a rule, no changes are made. */ +export const BulkActionEditPayloadTimeline = lazySchema(() => + z.object({ + type: z.literal('set_timeline'), + value: z.object({ + timeline_id: TimelineTemplateId, + timeline_title: TimelineTemplateTitle, + }), + }) +); export type BulkActionEditPayloadTimeline = z.infer; -export const BulkActionEditPayloadTimeline = z.object({ - type: z.literal('set_timeline'), - value: z.object({ - timeline_id: TimelineTemplateId, - timeline_title: TimelineTemplateTitle, - }), -}); +export const BulkActionEditPayloadSetAlertSuppression = lazySchema(() => + z.object({ + type: z.literal('set_alert_suppression'), + value: AlertSuppression, + }) +); export type BulkActionEditPayloadSetAlertSuppression = z.infer< typeof BulkActionEditPayloadSetAlertSuppression >; -export const BulkActionEditPayloadSetAlertSuppression = z.object({ - type: z.literal('set_alert_suppression'), - value: AlertSuppression, -}); +export const BulkActionEditPayloadSetAlertSuppressionForThreshold = lazySchema(() => + z.object({ + type: z.literal('set_alert_suppression_for_threshold'), + value: ThresholdAlertSuppression, + }) +); export type BulkActionEditPayloadSetAlertSuppressionForThreshold = z.infer< typeof BulkActionEditPayloadSetAlertSuppressionForThreshold >; -export const BulkActionEditPayloadSetAlertSuppressionForThreshold = z.object({ - type: z.literal('set_alert_suppression_for_threshold'), - value: ThresholdAlertSuppression, -}); +export const BulkActionEditPayloadDeleteAlertSuppression = lazySchema(() => + z.object({ + type: z.literal('delete_alert_suppression'), + }) +); export type BulkActionEditPayloadDeleteAlertSuppression = z.infer< typeof BulkActionEditPayloadDeleteAlertSuppression >; -export const BulkActionEditPayloadDeleteAlertSuppression = z.object({ - type: z.literal('delete_alert_suppression'), -}); -export const BulkActionEditPayloadAlertSuppressionInternal = z.union([ - BulkActionEditPayloadSetAlertSuppression, - BulkActionEditPayloadSetAlertSuppressionForThreshold, - BulkActionEditPayloadDeleteAlertSuppression, -]); +export const BulkActionEditPayloadAlertSuppressionInternal = lazySchema(() => + z.union([ + BulkActionEditPayloadSetAlertSuppression, + BulkActionEditPayloadSetAlertSuppressionForThreshold, + BulkActionEditPayloadDeleteAlertSuppression, + ]) +); export type BulkActionEditPayloadAlertSuppression = z.infer< typeof BulkActionEditPayloadAlertSuppressionInternal @@ -436,34 +483,38 @@ export type BulkActionEditPayloadAlertSuppression = z.infer< export const BulkActionEditPayloadAlertSuppression = BulkActionEditPayloadAlertSuppressionInternal as z.ZodType; -export const BulkActionEditPayloadInternal = z.union([ - BulkActionEditPayloadTags, - BulkActionEditPayloadIndexPatterns, - BulkActionEditPayloadInvestigationFields, - BulkActionEditPayloadTimeline, - BulkActionEditPayloadRuleActions, - BulkActionEditPayloadSchedule, - BulkActionEditPayloadAlertSuppression, -]); +export const BulkActionEditPayloadInternal = lazySchema(() => + z.union([ + BulkActionEditPayloadTags, + BulkActionEditPayloadIndexPatterns, + BulkActionEditPayloadInvestigationFields, + BulkActionEditPayloadTimeline, + BulkActionEditPayloadRuleActions, + BulkActionEditPayloadSchedule, + BulkActionEditPayloadAlertSuppression, + ]) +); export type BulkActionEditPayload = z.infer; export const BulkActionEditPayload = BulkActionEditPayloadInternal as z.ZodType; +export const BulkEditRules = lazySchema(() => + BulkActionBase.merge( + z.object({ + action: z.literal('edit'), + /** + * Array of objects containing the edit operations + */ + edit: z.array(BulkActionEditPayload).min(1), + }) + ) +); export type BulkEditRules = z.infer; -export const BulkEditRules = BulkActionBase.extend( + +export const PerformRulesBulkActionRequestQuery = lazySchema(() => z.object({ - action: z.literal('edit'), /** - * Array of objects containing the edit operations - */ - edit: z.array(BulkActionEditPayload).min(1), - }) -); - -export type PerformRulesBulkActionRequestQuery = z.infer; -export const PerformRulesBulkActionRequestQuery = z.object({ - /** * Enables dry run mode for the request call. Enable dry run mode to verify that bulk actions can be applied to specified rules. Certain rules, such as prebuilt Elastic rules on a Basic subscription, can’t be edited and will return errors in the request response. Error details will contain an explanation, the rule name and/or ID, and additional troubleshooting information. @@ -473,29 +524,32 @@ To enable dry run mode on a request, add the query parameter `dry_run=true` to t > Dry run mode is not supported for the `export` bulk action. A 400 error will be returned in the request response. */ - dry_run: BooleanFromString.optional(), -}); + dry_run: BooleanFromString.optional(), + }) +); +export type PerformRulesBulkActionRequestQuery = z.infer; export type PerformRulesBulkActionRequestQueryInput = z.input< typeof PerformRulesBulkActionRequestQuery >; +export const PerformRulesBulkActionRequestBody = lazySchema(() => + z.union([ + BulkDeleteRules, + BulkDisableRules, + BulkEnableRules, + BulkExportRules, + BulkDuplicateRules, + BulkManualRuleRun, + BulkManualRuleFillGaps, + BulkEditRules, + ]) +); export type PerformRulesBulkActionRequestBody = z.infer; -export const PerformRulesBulkActionRequestBody = z.union([ - BulkDeleteRules, - BulkDisableRules, - BulkEnableRules, - BulkExportRules, - BulkDuplicateRules, - BulkManualRuleRun, - BulkManualRuleFillGaps, - BulkEditRules, -]); export type PerformRulesBulkActionRequestBodyInput = z.input< typeof PerformRulesBulkActionRequestBody >; +export const PerformRulesBulkActionResponse = lazySchema(() => + z.union([BulkEditActionResponse, BulkExportActionResponse]) +); export type PerformRulesBulkActionResponse = z.infer; -export const PerformRulesBulkActionResponse = z.union([ - BulkEditActionResponse, - BulkExportActionResponse, -]); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.gen.ts index 8039c5b9d72a4..eb2f4228fd8ac 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.gen.ts @@ -15,12 +15,13 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { RuleCreateProps, RuleResponse } from '../../../model/rule_schema/rule_schemas.gen'; +export const CreateRuleRequestBody = lazySchema(() => RuleCreateProps); export type CreateRuleRequestBody = z.infer; -export const CreateRuleRequestBody = RuleCreateProps; export type CreateRuleRequestBodyInput = z.input; +export const CreateRuleResponse = lazySchema(() => RuleResponse); export type CreateRuleResponse = z.infer; -export const CreateRuleResponse = RuleResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen.ts index 5e8c213e8d71a..e8ee0fb302317 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen.ts @@ -14,23 +14,25 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { RuleObjectId, RuleSignatureId } from '../../../model/rule_schema/common_attributes.gen'; import { RuleResponse } from '../../../model/rule_schema/rule_schemas.gen'; +export const DeleteRuleRequestQuery = lazySchema(() => + z.object({ + /** + * The rule's `id` value. + */ + id: RuleObjectId.optional(), + /** + * The rule's `rule_id` value. + */ + rule_id: RuleSignatureId.optional(), + }) +); export type DeleteRuleRequestQuery = z.infer; -export const DeleteRuleRequestQuery = z.object({ - /** - * The rule's `id` value. - */ - id: RuleObjectId.optional(), - /** - * The rule's `rule_id` value. - */ - rule_id: RuleSignatureId.optional(), -}); export type DeleteRuleRequestQueryInput = z.input; +export const DeleteRuleResponse = lazySchema(() => RuleResponse); export type DeleteRuleResponse = z.infer; -export const DeleteRuleResponse = RuleResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen.ts index 406aa64a84934..d6016054e1b49 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen.ts @@ -15,12 +15,13 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { RulePatchProps, RuleResponse } from '../../../model/rule_schema/rule_schemas.gen'; +export const PatchRuleRequestBody = lazySchema(() => RulePatchProps); export type PatchRuleRequestBody = z.infer; -export const PatchRuleRequestBody = RulePatchProps; export type PatchRuleRequestBodyInput = z.input; +export const PatchRuleResponse = lazySchema(() => RuleResponse); export type PatchRuleResponse = z.infer; -export const PatchRuleResponse = RuleResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.gen.ts index 3c68c4fab28fe..19f5d6eec898c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.gen.ts @@ -14,23 +14,25 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { RuleObjectId, RuleSignatureId } from '../../../model/rule_schema/common_attributes.gen'; import { RuleResponse } from '../../../model/rule_schema/rule_schemas.gen'; +export const ReadRuleRequestQuery = lazySchema(() => + z.object({ + /** + * The rule's `id` value. + */ + id: RuleObjectId.optional(), + /** + * The rule's `rule_id` value. + */ + rule_id: RuleSignatureId.optional(), + }) +); export type ReadRuleRequestQuery = z.infer; -export const ReadRuleRequestQuery = z.object({ - /** - * The rule's `id` value. - */ - id: RuleObjectId.optional(), - /** - * The rule's `rule_id` value. - */ - rule_id: RuleSignatureId.optional(), -}); export type ReadRuleRequestQueryInput = z.input; +export const ReadRuleResponse = lazySchema(() => RuleResponse); export type ReadRuleResponse = z.infer; -export const ReadRuleResponse = RuleResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen.ts index 11937b7dc090d..ba77a1c80e4b7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen.ts @@ -15,12 +15,13 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { RuleUpdateProps, RuleResponse } from '../../../model/rule_schema/rule_schemas.gen'; +export const UpdateRuleRequestBody = lazySchema(() => RuleUpdateProps); export type UpdateRuleRequestBody = z.infer; -export const UpdateRuleRequestBody = RuleUpdateProps; export type UpdateRuleRequestBodyInput = z.input; +export const UpdateRuleResponse = lazySchema(() => RuleResponse); export type UpdateRuleResponse = z.infer; -export const UpdateRuleResponse = RuleResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.gen.ts index 4ee7b400f059c..2e588fb617ba6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/export_rules/export_rules_route.gen.ts @@ -14,38 +14,42 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { RuleSignatureId } from '../../model/rule_schema/common_attributes.gen'; -export type ExportRulesRequestQuery = z.infer; -export const ExportRulesRequestQuery = z.object({ - /** - * Determines whether a summary of the exported rules is returned. - */ - exclude_export_details: BooleanFromString.optional().default(false), - /** +export const ExportRulesRequestQuery = lazySchema(() => + z.object({ + /** + * Determines whether a summary of the exported rules is returned. + */ + exclude_export_details: BooleanFromString.optional().default(false), + /** * File name for saving the exported rules. > info > When using cURL to export rules to a file, use the -O and -J options to save the rules to the file name specified in the URL. */ - file_name: z.string().optional().default('export.ndjson'), -}); + file_name: z.string().optional().default('export.ndjson'), + }) +); +export type ExportRulesRequestQuery = z.infer; export type ExportRulesRequestQueryInput = z.input; +export const ExportRulesRequestBody = lazySchema(() => + z + .object({ + /** + * Array of objects with a rule's `rule_id` field. Do not use rule's `id` here. Exports all rules when unspecified. + */ + objects: z.array( + z.object({ + rule_id: RuleSignatureId, + }) + ), + }) + .nullable() +); export type ExportRulesRequestBody = z.infer; -export const ExportRulesRequestBody = z - .object({ - /** - * Array of objects with a rule's `rule_id` field. Do not use rule's `id` here. Exports all rules when unspecified. - */ - objects: z.array( - z.object({ - rule_id: RuleSignatureId, - }) - ), - }) - .nullable(); export type ExportRulesRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/find_rules_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/find_rules_route.gen.ts index de4989ffc335e..c5343dd68deb0 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/find_rules_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/find_rules/find_rules_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { SortOrder } from '../../model/sorting.gen'; @@ -22,30 +22,32 @@ import { GapFillStatus } from '../../model/rule_schema/common_attributes.gen'; import { RuleResponse } from '../../model/rule_schema/rule_schemas.gen'; import { WarningSchema } from '../../model/warning_schema.gen'; +export const FindRulesSortField = lazySchema(() => + z.enum([ + 'created_at', + 'createdAt', + 'enabled', + 'execution_summary.last_execution.date', + 'execution_summary.last_execution.metrics.execution_gap_duration_s', + 'execution_summary.last_execution.metrics.total_indexing_duration_ms', + 'execution_summary.last_execution.metrics.total_search_duration_ms', + 'execution_summary.last_execution.status', + 'name', + 'risk_score', + 'riskScore', + 'severity', + 'updated_at', + 'updatedAt', + ]) +); export type FindRulesSortField = z.infer; -export const FindRulesSortField = z.enum([ - 'created_at', - 'createdAt', - 'enabled', - 'execution_summary.last_execution.date', - 'execution_summary.last_execution.metrics.execution_gap_duration_s', - 'execution_summary.last_execution.metrics.total_indexing_duration_ms', - 'execution_summary.last_execution.metrics.total_search_duration_ms', - 'execution_summary.last_execution.status', - 'name', - 'risk_score', - 'riskScore', - 'severity', - 'updated_at', - 'updatedAt', -]); export type FindRulesSortFieldEnum = typeof FindRulesSortField.enum; export const FindRulesSortFieldEnum = FindRulesSortField.enum; -export type FindRulesRequestQuery = z.infer; -export const FindRulesRequestQuery = z.object({ - fields: ArrayFromString(z.string()).optional(), - /** +export const FindRulesRequestQuery = lazySchema(() => + z.object({ + fields: ArrayFromString(z.string()).optional(), + /** * Search query Filters the returned results according to the value of the specified field, using the alert.attributes.: syntax, where can be: @@ -59,47 +61,51 @@ Filters the returned results according to the value of the specified field, usin > Even though the JSON rule object uses created_by and updated_by fields, you must use createdBy and updatedBy fields in the filter. */ - filter: z.string().optional(), - /** - * Field to sort by - */ - sort_field: FindRulesSortField.optional(), - /** - * Sort order - */ - sort_order: SortOrder.optional(), - /** - * Page number - */ - page: z.coerce.number().int().min(1).optional().default(1), - /** - * Rules per page - */ - per_page: z.coerce.number().int().min(0).optional().default(20), - /** - * Gaps range start - */ - gaps_range_start: z.string().optional(), - /** - * Gaps range end - */ - gaps_range_end: z.string().optional(), - /** - * Gap fill statuses - */ - gap_fill_statuses: ArrayFromString(GapFillStatus).optional(), - /** - * Gap auto fill scheduler ID used to determine gap fill status for rules - */ - gap_auto_fill_scheduler_id: z.string().optional(), -}); + filter: z.string().optional(), + /** + * Field to sort by + */ + sort_field: FindRulesSortField.optional(), + /** + * Sort order + */ + sort_order: SortOrder.optional(), + /** + * Page number + */ + page: z.coerce.number().int().min(1).optional().default(1), + /** + * Rules per page + */ + per_page: z.coerce.number().int().min(0).optional().default(20), + /** + * Gaps range start + */ + gaps_range_start: z.string().optional(), + /** + * Gaps range end + */ + gaps_range_end: z.string().optional(), + /** + * Gap fill statuses + */ + gap_fill_statuses: ArrayFromString(GapFillStatus).optional(), + /** + * Gap auto fill scheduler ID used to determine gap fill status for rules + */ + gap_auto_fill_scheduler_id: z.string().optional(), + }) +); +export type FindRulesRequestQuery = z.infer; export type FindRulesRequestQueryInput = z.input; +export const FindRulesResponse = lazySchema(() => + z.object({ + page: z.number().int(), + perPage: z.number().int(), + total: z.number().int(), + data: z.array(RuleResponse), + warnings: z.array(WarningSchema).optional(), + }) +); export type FindRulesResponse = z.infer; -export const FindRulesResponse = z.object({ - page: z.number().int(), - perPage: z.number().int(), - total: z.number().int(), - data: z.array(RuleResponse), - warnings: z.array(WarningSchema).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen.ts index 23fcaa850061f..f8d22deba5804 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen.ts @@ -14,46 +14,50 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { ErrorSchema } from '../../model/error_schema.gen'; import { WarningSchema } from '../../model/warning_schema.gen'; +export const ImportRulesRequestQuery = lazySchema(() => + z.object({ + /** + * Determines whether existing rules with the same `rule_id` are overwritten. + */ + overwrite: BooleanFromString.optional().default(false), + /** + * Determines whether existing exception lists with the same `list_id` are overwritten. Both the exception list container and its items are overwritten. + */ + overwrite_exceptions: BooleanFromString.optional().default(false), + /** + * Determines whether existing actions with the same `kibana.alert.rule.actions.id` are overwritten. + */ + overwrite_action_connectors: BooleanFromString.optional().default(false), + /** + * Generates a new list ID for each imported exception list. + */ + as_new_list: BooleanFromString.optional().default(false), + }) +); export type ImportRulesRequestQuery = z.infer; -export const ImportRulesRequestQuery = z.object({ - /** - * Determines whether existing rules with the same `rule_id` are overwritten. - */ - overwrite: BooleanFromString.optional().default(false), - /** - * Determines whether existing exception lists with the same `list_id` are overwritten. Both the exception list container and its items are overwritten. - */ - overwrite_exceptions: BooleanFromString.optional().default(false), - /** - * Determines whether existing actions with the same `kibana.alert.rule.actions.id` are overwritten. - */ - overwrite_action_connectors: BooleanFromString.optional().default(false), - /** - * Generates a new list ID for each imported exception list. - */ - as_new_list: BooleanFromString.optional().default(false), -}); export type ImportRulesRequestQueryInput = z.input; +export const ImportRulesResponse = lazySchema(() => + z + .object({ + exceptions_success: z.boolean(), + exceptions_success_count: z.number().int().min(0), + exceptions_errors: z.array(ErrorSchema), + rules_count: z.number().int().min(0), + success: z.boolean(), + success_count: z.number().int().min(0), + errors: z.array(ErrorSchema), + action_connectors_errors: z.array(ErrorSchema), + action_connectors_warnings: z.array(WarningSchema), + action_connectors_success: z.boolean(), + action_connectors_success_count: z.number().int().min(0), + }) + .strict() +); export type ImportRulesResponse = z.infer; -export const ImportRulesResponse = z - .object({ - exceptions_success: z.boolean(), - exceptions_success_count: z.number().int().min(0), - exceptions_errors: z.array(ErrorSchema), - rules_count: z.number().int().min(0), - success: z.boolean(), - success_count: z.number().int().min(0), - errors: z.array(ErrorSchema), - action_connectors_errors: z.array(ErrorSchema), - action_connectors_warnings: z.array(WarningSchema), - action_connectors_success: z.boolean(), - action_connectors_success_count: z.number().int().min(0), - }) - .strict(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/read_tags/read_tags_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/read_tags/read_tags_route.gen.ts index faee7ca351c41..f96e92001f40d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/read_tags/read_tags_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/read_tags/read_tags_route.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { RuleTagArray } from '../../model/rule_schema/common_attributes.gen'; +export const ReadTagsResponse = lazySchema(() => RuleTagArray); export type ReadTagsResponse = z.infer; -export const ReadTagsResponse = RuleTagArray; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.gen.ts index 6bdc1c03892fe..3d2fa6aaa7681 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_event.gen.ts @@ -14,10 +14,10 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const LogLevel = lazySchema(() => z.enum(['trace', 'debug', 'info', 'warn', 'error'])); export type LogLevel = z.infer; -export const LogLevel = z.enum(['trace', 'debug', 'info', 'warn', 'error']); export type LogLevelEnum = typeof LogLevel.enum; export const LogLevelEnum = LogLevel.enum; @@ -27,8 +27,10 @@ export const LogLevelEnum = LogLevel.enum; - status-change: We log an event of this type each time a rule changes its status during an execution. - execution-metrics: We log an event of this type at the end of a rule execution. It contains various execution metrics such as search and indexing durations. */ +export const RuleExecutionEventType = lazySchema(() => + z.enum(['message', 'status-change', 'execution-metrics']) +); export type RuleExecutionEventType = z.infer; -export const RuleExecutionEventType = z.enum(['message', 'status-change', 'execution-metrics']); export type RuleExecutionEventTypeEnum = typeof RuleExecutionEventType.enum; export const RuleExecutionEventTypeEnum = RuleExecutionEventType.enum; @@ -37,16 +39,18 @@ export const RuleExecutionEventTypeEnum = RuleExecutionEventType.enum; NOTE: This is a read model of rule execution events and it is pretty generic. It contains only a subset of their fields: only those fields that are common to all types of execution events. */ +export const RuleExecutionEvent = lazySchema(() => + z.object({ + timestamp: z.string().datetime(), + sequence: z.number().int(), + level: LogLevel, + type: RuleExecutionEventType, + execution_id: z.string().min(1), + message: z.string(), + /** + * Event details. The details vary per event type. + */ + details: z.object({}).catchall(z.unknown()).optional(), + }) +); export type RuleExecutionEvent = z.infer; -export const RuleExecutionEvent = z.object({ - timestamp: z.string().datetime(), - sequence: z.number().int(), - level: LogLevel, - type: RuleExecutionEventType, - execution_id: z.string().min(1), - message: z.string(), - /** - * Event details. The details vary per event type. - */ - details: z.object({}).catchall(z.unknown()).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_metrics.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_metrics.gen.ts index a2ed8417c7f23..1d944dfc726fb 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_metrics.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_metrics.gen.ts @@ -14,54 +14,56 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const RuleExecutionMetrics = lazySchema(() => + z.object({ + /** + * Total time spent performing ES searches as measured by Kibana; includes network latency and time spent serializing/deserializing request/response + */ + total_search_duration_ms: z.number().int().min(0).optional(), + /** + * Total time spent indexing documents during current rule execution cycle + */ + total_indexing_duration_ms: z.number().int().min(0).optional(), + /** + * Total time spent enriching documents during current rule execution cycle + */ + total_enrichment_duration_ms: z.number().int().min(0).optional(), + /** + * Duration in seconds of execution gap + */ + execution_gap_duration_s: z.number().int().min(0).optional(), + /** + * Count of frozen indices queried during the rule execution. These indices could not be entirely excluded after applying the time range filter. + */ + frozen_indices_queried_count: z.number().int().min(0).optional(), + /** + * Range of the execution gap + */ + gap_range: z + .object({ + /** + * Start date of the execution gap + */ + gte: z.string(), + /** + * End date of the execution gap + */ + lte: z.string(), + }) + .optional(), + /** + * Detected reason for the execution gap + */ + gap_reason: z + .object({ + /** + * The type of reason for the gap (rule_disabled or rule_did_not_run) + */ + type: z.enum(['rule_disabled', 'rule_did_not_run']), + }) + .optional(), + }) +); export type RuleExecutionMetrics = z.infer; -export const RuleExecutionMetrics = z.object({ - /** - * Total time spent performing ES searches as measured by Kibana; includes network latency and time spent serializing/deserializing request/response - */ - total_search_duration_ms: z.number().int().min(0).optional(), - /** - * Total time spent indexing documents during current rule execution cycle - */ - total_indexing_duration_ms: z.number().int().min(0).optional(), - /** - * Total time spent enriching documents during current rule execution cycle - */ - total_enrichment_duration_ms: z.number().int().min(0).optional(), - /** - * Duration in seconds of execution gap - */ - execution_gap_duration_s: z.number().int().min(0).optional(), - /** - * Count of frozen indices queried during the rule execution. These indices could not be entirely excluded after applying the time range filter. - */ - frozen_indices_queried_count: z.number().int().min(0).optional(), - /** - * Range of the execution gap - */ - gap_range: z - .object({ - /** - * Start date of the execution gap - */ - gte: z.string(), - /** - * End date of the execution gap - */ - lte: z.string(), - }) - .optional(), - /** - * Detected reason for the execution gap - */ - gap_reason: z - .object({ - /** - * The type of reason for the gap (rule_disabled or rule_did_not_run) - */ - type: z.enum(['rule_disabled', 'rule_did_not_run']), - }) - .optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_run_type.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_run_type.gen.ts index a2a3b84c603a0..054be4bedcb85 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_run_type.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_run_type.gen.ts @@ -14,12 +14,12 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Type of rule execution run. */ +export const RuleRunType = lazySchema(() => z.enum(['backfill', 'standard'])); export type RuleRunType = z.infer; -export const RuleRunType = z.enum(['backfill', 'standard']); export type RuleRunTypeEnum = typeof RuleRunType.enum; export const RuleRunTypeEnum = RuleRunType.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.gen.ts index 86500f59655f0..729a2a182071c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_status.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Custom execution status of Security rules that is different from the status used in the Alerting Framework. We merge our custom status with the Framework's status to determine the resulting status of a rule. @@ -24,16 +24,12 @@ import { z } from '@kbn/zod/v4'; - failed - Rule failed to execute due to unhandled exception or a reason defined in the business logic of its executor function. - succeeded - Rule executed successfully without any issues. Note: this status is just an indication of a rule's "health". The rule might or might not generate any alerts despite of it. */ +export const RuleExecutionStatus = lazySchema(() => + z.enum(['going to run', 'running', 'partial failure', 'failed', 'succeeded']) +); export type RuleExecutionStatus = z.infer; -export const RuleExecutionStatus = z.enum([ - 'going to run', - 'running', - 'partial failure', - 'failed', - 'succeeded', -]); export type RuleExecutionStatusEnum = typeof RuleExecutionStatus.enum; export const RuleExecutionStatusEnum = RuleExecutionStatus.enum; +export const RuleExecutionStatusOrder = lazySchema(() => z.number().int()); export type RuleExecutionStatusOrder = z.infer; -export const RuleExecutionStatusOrder = z.number().int(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.gen.ts index 7fbf1f4b2b4f2..c63978f3a5e96 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/execution_summary.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { RuleExecutionStatus, RuleExecutionStatusOrder } from './execution_status.gen'; import { RuleExecutionMetrics } from './execution_metrics.gen'; @@ -25,19 +25,21 @@ import { RuleExecutionMetrics } from './execution_metrics.gen'; > This field is under development and its usage or schema may change */ +export const RuleExecutionSummary = lazySchema(() => + z.object({ + last_execution: z.object({ + /** + * Date of the last execution + */ + date: z.string().datetime(), + /** + * Status of the last execution + */ + status: RuleExecutionStatus, + status_order: RuleExecutionStatusOrder, + message: z.string(), + metrics: RuleExecutionMetrics, + }), + }) +); export type RuleExecutionSummary = z.infer; -export const RuleExecutionSummary = z.object({ - last_execution: z.object({ - /** - * Date of the last execution - */ - date: z.string().datetime(), - /** - * Status of the last execution - */ - status: RuleExecutionStatus, - status_order: RuleExecutionStatusOrder, - message: z.string(), - metrics: RuleExecutionMetrics, - }), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/unified_execution_result.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/unified_execution_result.gen.ts index 1076510e44af2..a0baf5ecff8f5 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/unified_execution_result.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/model/unified_execution_result.gen.ts @@ -14,13 +14,13 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Final execution outcome as reported by the Alerting Framework (event.outcome). */ +export const UnifiedExecutionStatus = lazySchema(() => z.enum(['success', 'warning', 'failure'])); export type UnifiedExecutionStatus = z.infer; -export const UnifiedExecutionStatus = z.enum(['success', 'warning', 'failure']); export type UnifiedExecutionStatusEnum = typeof UnifiedExecutionStatus.enum; export const UnifiedExecutionStatusEnum = UnifiedExecutionStatus.enum; @@ -28,86 +28,90 @@ export const UnifiedExecutionStatusEnum = UnifiedExecutionStatus.enum; * A single unified rule execution result read from the Alerting Framework's "execute" event in the event log. Contains execution metadata and structured metrics. */ -export type UnifiedExecutionResult = z.infer; -export const UnifiedExecutionResult = z.object({ - /** - * Unique identifier of this execution. - */ - execution_uuid: z.string().nullable(), - /** - * Start time of the execution (event.start from the Alerting Framework execute event). - */ - execution_start: z.string().datetime(), - /** - * Total execution duration in milliseconds (converted from event.duration nanoseconds). - */ - execution_duration_ms: z.number().int().nullable(), - /** - * Delay between scheduled and actual start time in milliseconds (from kibana.task.schedule_delay). - */ - schedule_delay_ms: z.number().int().nullable(), - /** - * Source event time range for backfill (manual) executions, computed from start and interval. - */ - backfill: z - .object({ - from: z.string().datetime(), - to: z.string().datetime(), - }) - .nullable(), - /** - * Execution outcome information. - */ - outcome: z.object({ - status: UnifiedExecutionStatus, - /** - * Outcome message from the source event (event.message). - */ - message: z.string().nullable(), - }), - /** - * Execution metrics from kibana.alert.rule.execution.metrics in the Alerting Framework execute event. - */ - metrics: z.object({ +export const UnifiedExecutionResult = lazySchema(() => + z.object({ /** - * Total search duration in milliseconds. + * Unique identifier of this execution. */ - total_search_duration_ms: z.number().int().nullable(), + execution_uuid: z.string().nullable(), /** - * Total indexing duration in milliseconds. + * Start time of the execution (event.start from the Alerting Framework execute event). */ - total_indexing_duration_ms: z.number().int().nullable(), + execution_start: z.string().datetime(), /** - * Gap duration in seconds. + * Total execution duration in milliseconds (converted from event.duration nanoseconds). */ - execution_gap_duration_s: z.number().int().nullable(), + execution_duration_ms: z.number().int().nullable(), /** - * Number of candidate alerts evaluated during execution (from kibana.alert.rule.execution.metrics.alerts_candidate_count). + * Delay between scheduled and actual start time in milliseconds (from kibana.task.schedule_delay). */ - alerts_candidate_count: z.number().int().nullable(), + schedule_delay_ms: z.number().int().nullable(), /** - * Alert counts for this execution. + * Source event time range for backfill (manual) executions, computed from start and interval. */ - alert_counts: z + backfill: z .object({ - new: z.number().int().nullable(), + from: z.string().datetime(), + to: z.string().datetime(), }) .nullable(), /** - * Number of indices matched during execution (from kibana.alert.rule.execution.metrics.matched_indices_count). + * Execution outcome information. */ - matched_indices_count: z.number().int().nullable(), + outcome: z.object({ + status: UnifiedExecutionStatus, + /** + * Outcome message from the source event (event.message). + */ + message: z.string().nullable(), + }), /** - * Number of frozen indices queried during execution (from kibana.alert.rule.execution.metrics.frozen_indices_queried_count). + * Execution metrics from kibana.alert.rule.execution.metrics in the Alerting Framework execute event. */ - frozen_indices_queried_count: z.number().int().nullable(), - }), -}); + metrics: z.object({ + /** + * Total search duration in milliseconds. + */ + total_search_duration_ms: z.number().int().nullable(), + /** + * Total indexing duration in milliseconds. + */ + total_indexing_duration_ms: z.number().int().nullable(), + /** + * Gap duration in seconds. + */ + execution_gap_duration_s: z.number().int().nullable(), + /** + * Number of candidate alerts evaluated during execution (from kibana.alert.rule.execution.metrics.alerts_candidate_count). + */ + alerts_candidate_count: z.number().int().nullable(), + /** + * Alert counts for this execution. + */ + alert_counts: z + .object({ + new: z.number().int().nullable(), + }) + .nullable(), + /** + * Number of indices matched during execution (from kibana.alert.rule.execution.metrics.matched_indices_count). + */ + matched_indices_count: z.number().int().nullable(), + /** + * Number of frozen indices queried during execution (from kibana.alert.rule.execution.metrics.frozen_indices_queried_count). + */ + frozen_indices_queried_count: z.number().int().nullable(), + }), + }) +); +export type UnifiedExecutionResult = z.infer; /** * Fields available for sorting unified execution results. */ +export const UnifiedExecutionResultSortField = lazySchema(() => + z.enum(['execution_start', 'execution_duration_ms']) +); export type UnifiedExecutionResultSortField = z.infer; -export const UnifiedExecutionResultSortField = z.enum(['execution_start', 'execution_duration_ms']); export type UnifiedExecutionResultSortFieldEnum = typeof UnifiedExecutionResultSortField.enum; export const UnifiedExecutionResultSortFieldEnum = UnifiedExecutionResultSortField.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/read_rule_execution_results_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/read_rule_execution_results_route.gen.ts index 20ef4a1dbe51e..59885dcb32bca 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/read_rule_execution_results_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/read_rule_execution_results_route.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { UnifiedExecutionStatus, @@ -24,87 +24,93 @@ import { import { RuleRunType } from '../../model/execution_run_type.gen'; import { SortOrder } from '../../../model/sorting.gen'; +export const ReadRuleExecutionResultsRequestParams = lazySchema(() => + z.object({ + /** + * Saved object ID of the rule to get execution results for. + */ + ruleId: z.string().min(1), + }) +); export type ReadRuleExecutionResultsRequestParams = z.infer< typeof ReadRuleExecutionResultsRequestParams >; -export const ReadRuleExecutionResultsRequestParams = z.object({ - /** - * Saved object ID of the rule to get execution results for. - */ - ruleId: z.string().min(1), -}); export type ReadRuleExecutionResultsRequestParamsInput = z.input< typeof ReadRuleExecutionResultsRequestParams >; +export const ReadRuleExecutionResultsRequestBody = lazySchema(() => + z.object({ + /** + * Filtering criteria for execution results. If omitted, defaults to the last 2 hours (from: now-2h, to: now). + */ + filter: z + .object({ + /** + * Filter by execution outcome (success, warning, failure). Empty = all outcomes. + */ + outcome: z.array(UnifiedExecutionStatus).max(3).optional().default([]), + /** + * Filter by run type (standard, backfill). Empty = all run types. + */ + run_type: z.array(RuleRunType).max(2).optional().default([]), + /** + * Start of the time range (executions that started within this range). + */ + from: z.string().datetime(), + /** + * End of the time range (executions that started within this range). + */ + to: z.string().datetime(), + }) + .optional(), + /** + * Sorting configuration for execution results. + */ + sort: z + .object({ + /** + * Field to sort results by. + */ + field: UnifiedExecutionResultSortField.optional().default('execution_start'), + /** + * Sort order (asc or desc). + */ + order: SortOrder.optional().default('desc'), + }) + .optional(), + /** + * Page number to return. + */ + page: z.number().int().min(1).optional().default(1), + /** + * Number of results per page. + */ + per_page: z.number().int().min(1).max(100).optional().default(20), + }) +); export type ReadRuleExecutionResultsRequestBody = z.infer< typeof ReadRuleExecutionResultsRequestBody >; -export const ReadRuleExecutionResultsRequestBody = z.object({ - /** - * Filtering criteria for execution results. If omitted, defaults to the last 2 hours (from: now-2h, to: now). - */ - filter: z - .object({ - /** - * Filter by execution outcome (success, warning, failure). Empty = all outcomes. - */ - outcome: z.array(UnifiedExecutionStatus).max(3).optional().default([]), - /** - * Filter by run type (standard, backfill). Empty = all run types. - */ - run_type: z.array(RuleRunType).max(2).optional().default([]), - /** - * Start of the time range (executions that started within this range). - */ - from: z.string().datetime(), - /** - * End of the time range (executions that started within this range). - */ - to: z.string().datetime(), - }) - .optional(), - /** - * Sorting configuration for execution results. - */ - sort: z - .object({ - /** - * Field to sort results by. - */ - field: UnifiedExecutionResultSortField.optional().default('execution_start'), - /** - * Sort order (asc or desc). - */ - order: SortOrder.optional().default('desc'), - }) - .optional(), - /** - * Page number to return. - */ - page: z.number().int().min(1).optional().default(1), - /** - * Number of results per page. - */ - per_page: z.number().int().min(1).max(100).optional().default(20), -}); export type ReadRuleExecutionResultsRequestBodyInput = z.input< typeof ReadRuleExecutionResultsRequestBody >; +export const ReadRuleExecutionResultsResponse = lazySchema(() => + z.object({ + data: z.array(UnifiedExecutionResult), + /** + * Total number of results matching the filter. + */ + total: z.number().int(), + /** + * Current page number (echoed from request). + */ + page: z.number().int(), + /** + * Number of results per page (echoed from request). + */ + per_page: z.number().int(), + }) +); export type ReadRuleExecutionResultsResponse = z.infer; -export const ReadRuleExecutionResultsResponse = z.object({ - data: z.array(UnifiedExecutionResult), - /** - * Total number of results matching the filter. - */ - total: z.number().int(), - /** - * Current page number (echoed from request). - */ - page: z.number().int(), - /** - * Number of results per page (echoed from request). - */ - per_page: z.number().int(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts index 7e5a910a5e6e4..136a9c2ef38f7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_preview/rule_preview.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { @@ -29,57 +29,69 @@ import { } from '../model/rule_schema/rule_schemas.gen'; import { NonEmptyString } from '../../model/primitives.gen'; +export const RulePreviewParams = lazySchema(() => + z.object({ + invocationCount: z.number().int(), + timeframeEnd: z.string().datetime(), + }) +); export type RulePreviewParams = z.infer; -export const RulePreviewParams = z.object({ - invocationCount: z.number().int(), - timeframeEnd: z.string().datetime(), -}); +export const RulePreviewLoggedRequest = lazySchema(() => + z.object({ + request: NonEmptyString.optional(), + description: NonEmptyString.optional(), + duration: z.number().int().optional(), + request_type: NonEmptyString.optional(), + }) +); export type RulePreviewLoggedRequest = z.infer; -export const RulePreviewLoggedRequest = z.object({ - request: NonEmptyString.optional(), - description: NonEmptyString.optional(), - duration: z.number().int().optional(), - request_type: NonEmptyString.optional(), -}); +export const RulePreviewLogs = lazySchema(() => + z.object({ + errors: z.array(NonEmptyString), + warnings: z.array(NonEmptyString), + /** + * Execution duration in milliseconds + */ + duration: z.number().int(), + startedAt: NonEmptyString.optional(), + requests: z.array(RulePreviewLoggedRequest).optional(), + }) +); export type RulePreviewLogs = z.infer; -export const RulePreviewLogs = z.object({ - errors: z.array(NonEmptyString), - warnings: z.array(NonEmptyString), - /** - * Execution duration in milliseconds - */ - duration: z.number().int(), - startedAt: NonEmptyString.optional(), - requests: z.array(RulePreviewLoggedRequest).optional(), -}); +export const RulePreviewRequestQuery = lazySchema(() => + z.object({ + /** + * Enables logging and returning in response ES queries, performed during rule execution + */ + enable_logged_requests: BooleanFromString.optional(), + }) +); export type RulePreviewRequestQuery = z.infer; -export const RulePreviewRequestQuery = z.object({ - /** - * Enables logging and returning in response ES queries, performed during rule execution - */ - enable_logged_requests: BooleanFromString.optional(), -}); export type RulePreviewRequestQueryInput = z.input; +export const RulePreviewRequestBody = lazySchema(() => + z.discriminatedUnion('type', [ + EqlRuleCreateProps.merge(RulePreviewParams), + QueryRuleCreateProps.merge(RulePreviewParams), + SavedQueryRuleCreateProps.merge(RulePreviewParams), + ThresholdRuleCreateProps.merge(RulePreviewParams), + ThreatMatchRuleCreateProps.merge(RulePreviewParams), + MachineLearningRuleCreateProps.merge(RulePreviewParams), + NewTermsRuleCreateProps.merge(RulePreviewParams), + EsqlRuleCreateProps.merge(RulePreviewParams), + ]) +); export type RulePreviewRequestBody = z.infer; -export const RulePreviewRequestBody = z.discriminatedUnion('type', [ - EqlRuleCreateProps.extend(RulePreviewParams), - QueryRuleCreateProps.extend(RulePreviewParams), - SavedQueryRuleCreateProps.extend(RulePreviewParams), - ThresholdRuleCreateProps.extend(RulePreviewParams), - ThreatMatchRuleCreateProps.extend(RulePreviewParams), - MachineLearningRuleCreateProps.extend(RulePreviewParams), - NewTermsRuleCreateProps.extend(RulePreviewParams), - EsqlRuleCreateProps.extend(RulePreviewParams), -]); export type RulePreviewRequestBodyInput = z.input; +export const RulePreviewResponse = lazySchema(() => + z.object({ + logs: z.array(RulePreviewLogs), + previewId: NonEmptyString.optional(), + isAborted: z.boolean().optional(), + }) +); export type RulePreviewResponse = z.infer; -export const RulePreviewResponse = z.object({ - logs: z.array(RulePreviewLogs), - previewId: NonEmptyString.optional(), - isAborted: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.gen.ts index 9c3baf3fd5f18..33b6de7193f86 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/query_signals/query_signals_route.gen.ts @@ -14,35 +14,41 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const AlertsSortCombinations = lazySchema(() => + z.union([z.string(), z.object({}).catchall(z.unknown())]) +); export type AlertsSortCombinations = z.infer; -export const AlertsSortCombinations = z.union([z.string(), z.object({}).catchall(z.unknown())]); +export const AlertsSort = lazySchema(() => + z.union([AlertsSortCombinations, z.array(AlertsSortCombinations)]) +); export type AlertsSort = z.infer; -export const AlertsSort = z.union([AlertsSortCombinations, z.array(AlertsSortCombinations)]); +export const QueryAlertsBodyParams = lazySchema(() => + z.object({ + query: z.object({}).catchall(z.unknown()).optional(), + aggs: z.object({}).catchall(z.unknown()).optional(), + size: z.number().int().min(0).optional(), + track_total_hits: z.boolean().optional(), + _source: z.union([z.boolean(), z.string(), z.array(z.string())]).optional(), + fields: z.array(z.string()).optional(), + runtime_mappings: z.object({}).catchall(z.unknown()).optional(), + sort: AlertsSort.optional(), + }) +); export type QueryAlertsBodyParams = z.infer; -export const QueryAlertsBodyParams = z.object({ - query: z.object({}).catchall(z.unknown()).optional(), - aggs: z.object({}).catchall(z.unknown()).optional(), - size: z.number().int().min(0).optional(), - track_total_hits: z.boolean().optional(), - _source: z.union([z.boolean(), z.string(), z.array(z.string())]).optional(), - fields: z.array(z.string()).optional(), - runtime_mappings: z.object({}).catchall(z.unknown()).optional(), - sort: AlertsSort.optional(), -}); /** * Elasticsearch query and aggregation request */ +export const SearchAlertsRequestBody = lazySchema(() => QueryAlertsBodyParams); export type SearchAlertsRequestBody = z.infer; -export const SearchAlertsRequestBody = QueryAlertsBodyParams; export type SearchAlertsRequestBodyInput = z.input; /** * Elasticsearch search response */ +export const SearchAlertsResponse = lazySchema(() => z.object({}).catchall(z.unknown())); export type SearchAlertsResponse = z.infer; -export const SearchAlertsResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signals_status_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signals_status_route.gen.ts index 80cb6b9dfd748..6f5ffee0c0b39 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signals_status_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals/set_signal_status/set_signals_status_route.gen.ts @@ -14,81 +14,91 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; import { AlertStatusExceptClosed } from '../../../model/alert.gen'; +export const ReasonEnum = lazySchema(() => + z.enum([ + 'false_positive', + 'duplicate', + 'true_positive', + 'benign_positive', + 'automated_closure', + 'other', + ]) +); export type ReasonEnum = z.infer; -export const ReasonEnum = z.enum([ - 'false_positive', - 'duplicate', - 'true_positive', - 'benign_positive', - 'automated_closure', - 'other', -]); export type ReasonEnumEnum = typeof ReasonEnum.enum; export const ReasonEnumEnum = ReasonEnum.enum; /** * The reason for closing the alerts. Can be one of following predefined reasons: [false_positive, duplicate, true_positive, benign_positive, automated_closure, other] or a custom reason provided by the user through the advanced settings. */ +export const Reason = lazySchema(() => z.union([ReasonEnum, z.string()])); export type Reason = z.infer; -export const Reason = z.union([ReasonEnum, z.string()]); +export const SetAlertsStatusByIdsBase = lazySchema(() => + z.object({ + /** + * List of alert ids. Use field `_id` on alert document or `kibana.alert.uuid`. Note: signals are a deprecated term for alerts. + */ + signal_ids: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), + status: AlertStatusExceptClosed, + }) +); export type SetAlertsStatusByIdsBase = z.infer; -export const SetAlertsStatusByIdsBase = z.object({ - /** - * List of alert ids. Use field `_id` on alert document or `kibana.alert.uuid`. Note: signals are a deprecated term for alerts. - */ - signal_ids: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), - status: AlertStatusExceptClosed, -}); +export const CloseAlertsByIds = lazySchema(() => + z.object({ + /** + * List of alert ids. Use field `_id` on alert document or `kibana.alert.uuid`. Note: signals are a deprecated term for alerts. + */ + signal_ids: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), + status: z.literal('closed'), + reason: Reason.optional(), + }) +); export type CloseAlertsByIds = z.infer; -export const CloseAlertsByIds = z.object({ - /** - * List of alert ids. Use field `_id` on alert document or `kibana.alert.uuid`. Note: signals are a deprecated term for alerts. - */ - signal_ids: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), - status: z.literal('closed'), - reason: Reason.optional(), -}); +export const SetAlertsStatusByIds = lazySchema(() => + z.discriminatedUnion('status', [CloseAlertsByIds, SetAlertsStatusByIdsBase]) +); export type SetAlertsStatusByIds = z.infer; -export const SetAlertsStatusByIds = z.discriminatedUnion('status', [ - CloseAlertsByIds, - SetAlertsStatusByIdsBase, -]); +export const SetAlertsStatusByQueryBase = lazySchema(() => + z.object({ + query: z.object({}).catchall(z.unknown()), + status: AlertStatusExceptClosed, + conflicts: z.enum(['abort', 'proceed']).optional().default('abort'), + }) +); export type SetAlertsStatusByQueryBase = z.infer; -export const SetAlertsStatusByQueryBase = z.object({ - query: z.object({}).catchall(z.unknown()), - status: AlertStatusExceptClosed, - conflicts: z.enum(['abort', 'proceed']).optional().default('abort'), -}); +export const CloseAlertsByQuery = lazySchema(() => + z.object({ + query: z.object({}).catchall(z.unknown()), + status: z.literal('closed'), + conflicts: z.enum(['abort', 'proceed']).optional().default('abort'), + reason: Reason.optional(), + }) +); export type CloseAlertsByQuery = z.infer; -export const CloseAlertsByQuery = z.object({ - query: z.object({}).catchall(z.unknown()), - status: z.literal('closed'), - conflicts: z.enum(['abort', 'proceed']).optional().default('abort'), - reason: Reason.optional(), -}); +export const SetAlertsStatusByQuery = lazySchema(() => + z.discriminatedUnion('status', [CloseAlertsByQuery, SetAlertsStatusByQueryBase]) +); export type SetAlertsStatusByQuery = z.infer; -export const SetAlertsStatusByQuery = z.discriminatedUnion('status', [ - CloseAlertsByQuery, - SetAlertsStatusByQueryBase, -]); +export const SetAlertsStatusRequestBody = lazySchema(() => + z.union([SetAlertsStatusByIds, SetAlertsStatusByQuery]) +); export type SetAlertsStatusRequestBody = z.infer; -export const SetAlertsStatusRequestBody = z.union([SetAlertsStatusByIds, SetAlertsStatusByQuery]); export type SetAlertsStatusRequestBodyInput = z.input; /** * Elasticsearch update by query response */ +export const SetAlertsStatusResponse = lazySchema(() => z.object({}).catchall(z.unknown())); export type SetAlertsStatusResponse = z.infer; -export const SetAlertsStatusResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts index 39eeb647a5993..59bcf7120076b 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen.ts @@ -14,62 +14,74 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; +export const AlertsReindexOptions = lazySchema(() => + z.object({ + /** + * The throttle for the migration task in sub-requests per second. Corresponds to requests_per_second on the Reindex API. + */ + requests_per_second: z.number().int().min(1).optional(), + /** + * Number of alerts to migrate per batch. Corresponds to the source.size option on the Reindex API. + */ + size: z.number().int().min(1).optional(), + /** + * The number of subtasks for the migration task. Corresponds to slices on the Reindex API. + */ + slices: z.number().int().min(1).optional(), + }) +); export type AlertsReindexOptions = z.infer; -export const AlertsReindexOptions = z.object({ - /** - * The throttle for the migration task in sub-requests per second. Corresponds to requests_per_second on the Reindex API. - */ - requests_per_second: z.number().int().min(1).optional(), - /** - * Number of alerts to migrate per batch. Corresponds to the source.size option on the Reindex API. - */ - size: z.number().int().min(1).optional(), - /** - * The number of subtasks for the migration task. Corresponds to slices on the Reindex API. - */ - slices: z.number().int().min(1).optional(), -}); +export const AlertsIndexMigrationSuccess = lazySchema(() => + z.object({ + index: z.string(), + migration_id: z.string(), + migration_index: z.string(), + }) +); export type AlertsIndexMigrationSuccess = z.infer; -export const AlertsIndexMigrationSuccess = z.object({ - index: z.string(), - migration_id: z.string(), - migration_index: z.string(), -}); +export const AlertsIndexMigrationError = lazySchema(() => + z.object({ + index: z.string(), + error: z.object({ + message: z.string(), + status_code: z.string(), + }), + }) +); export type AlertsIndexMigrationError = z.infer; -export const AlertsIndexMigrationError = z.object({ - index: z.string(), - error: z.object({ - message: z.string(), - status_code: z.string(), - }), -}); +export const SkippedAlertsIndexMigration = lazySchema(() => + z.object({ + index: z.string(), + }) +); export type SkippedAlertsIndexMigration = z.infer; -export const SkippedAlertsIndexMigration = z.object({ - index: z.string(), -}); +export const CreateAlertsMigrationRequestBody = lazySchema(() => + z + .object({ + /** + * Array of index names to migrate. + */ + index: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), + }) + .merge(AlertsReindexOptions) +); export type CreateAlertsMigrationRequestBody = z.infer; -export const CreateAlertsMigrationRequestBody = z - .object({ - /** - * Array of index names to migrate. - */ - index: z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1), - }) - .extend(AlertsReindexOptions); export type CreateAlertsMigrationRequestBodyInput = z.input< typeof CreateAlertsMigrationRequestBody >; +export const CreateAlertsMigrationResponse = lazySchema(() => + z.object({ + indices: z.array( + z.union([AlertsIndexMigrationSuccess, AlertsIndexMigrationError, SkippedAlertsIndexMigration]) + ), + }) +); export type CreateAlertsMigrationResponse = z.infer; -export const CreateAlertsMigrationResponse = z.object({ - indices: z.array( - z.union([AlertsIndexMigrationSuccess, AlertsIndexMigrationError, SkippedAlertsIndexMigration]) - ), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/delete_signals_migration/delete_signals_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/delete_signals_migration/delete_signals_migration.gen.ts index b8ad2801bb1ec..aae25755d76a8 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/delete_signals_migration/delete_signals_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/delete_signals_migration/delete_signals_migration.gen.ts @@ -14,34 +14,38 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const MigrationCleanupResult = lazySchema(() => + z.object({ + id: z.string(), + destinationIndex: z.string(), + status: z.enum(['success', 'failure', 'pending']), + sourceIndex: z.string(), + version: z.string(), + updated: z.string().datetime(), + error: z + .object({ + message: z.string(), + status_code: z.number().int(), + }) + .optional(), + }) +); export type MigrationCleanupResult = z.infer; -export const MigrationCleanupResult = z.object({ - id: z.string(), - destinationIndex: z.string(), - status: z.enum(['success', 'failure', 'pending']), - sourceIndex: z.string(), - version: z.string(), - updated: z.string().datetime(), - error: z - .object({ - message: z.string(), - status_code: z.number().int(), - }) - .optional(), -}); +export const AlertsMigrationCleanupRequestBody = lazySchema(() => + z.object({ + /** + * Array of `migration_id`s to cleanup. + */ + migration_ids: z.array(z.string()).min(1), + }) +); export type AlertsMigrationCleanupRequestBody = z.infer; -export const AlertsMigrationCleanupRequestBody = z.object({ - /** - * Array of `migration_id`s to cleanup. - */ - migration_ids: z.array(z.string()).min(1), -}); export type AlertsMigrationCleanupRequestBodyInput = z.input< typeof AlertsMigrationCleanupRequestBody >; +export const AlertsMigrationCleanupResponse = lazySchema(() => z.array(MigrationCleanupResult)); export type AlertsMigrationCleanupResponse = z.infer; -export const AlertsMigrationCleanupResponse = z.array(MigrationCleanupResult); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration.gen.ts index 1d62d72d00021..eca65c2ef2f7f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration.gen.ts @@ -14,35 +14,41 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const MigrationFinalizationResult = lazySchema(() => + z.object({ + id: z.string(), + completed: z.boolean(), + destinationIndex: z.string(), + status: z.enum(['success', 'failure', 'pending']), + sourceIndex: z.string(), + version: z.string(), + updated: z.string().datetime(), + error: z + .object({ + message: z.string(), + status_code: z.number().int(), + }) + .optional(), + }) +); export type MigrationFinalizationResult = z.infer; -export const MigrationFinalizationResult = z.object({ - id: z.string(), - completed: z.boolean(), - destinationIndex: z.string(), - status: z.enum(['success', 'failure', 'pending']), - sourceIndex: z.string(), - version: z.string(), - updated: z.string().datetime(), - error: z - .object({ - message: z.string(), - status_code: z.number().int(), - }) - .optional(), -}); +export const FinalizeAlertsMigrationRequestBody = lazySchema(() => + z.object({ + /** + * Array of `migration_id`s to finalize. + */ + migration_ids: z.array(z.string()).min(1), + }) +); export type FinalizeAlertsMigrationRequestBody = z.infer; -export const FinalizeAlertsMigrationRequestBody = z.object({ - /** - * Array of `migration_id`s to finalize. - */ - migration_ids: z.array(z.string()).min(1), -}); export type FinalizeAlertsMigrationRequestBodyInput = z.input< typeof FinalizeAlertsMigrationRequestBody >; +export const FinalizeAlertsMigrationResponse = lazySchema(() => + z.array(MigrationFinalizationResult) +); export type FinalizeAlertsMigrationResponse = z.infer; -export const FinalizeAlertsMigrationResponse = z.array(MigrationFinalizationResult); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/read_signals_migration_status/read_signals_migration_status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/read_signals_migration_status/read_signals_migration_status.gen.ts index 632c4ec9215e3..f46a3a33c34f2 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/read_signals_migration_status/read_signals_migration_status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/signals_migration/read_signals_migration_status/read_signals_migration_status.gen.ts @@ -14,48 +14,58 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isValidDateMath } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '../../../model/primitives.gen'; +export const AlertVersion = lazySchema(() => + z.object({ + version: z.number().int(), + count: z.number().int(), + }) +); export type AlertVersion = z.infer; -export const AlertVersion = z.object({ - version: z.number().int(), - count: z.number().int(), -}); +export const MigrationStatus = lazySchema(() => + z.object({ + id: NonEmptyString, + status: z.enum(['success', 'failure', 'pending']), + version: z.number().int(), + updated: z.string().datetime(), + }) +); export type MigrationStatus = z.infer; -export const MigrationStatus = z.object({ - id: NonEmptyString, - status: z.enum(['success', 'failure', 'pending']), - version: z.number().int(), - updated: z.string().datetime(), -}); +export const IndexMigrationStatus = lazySchema(() => + z.object({ + index: NonEmptyString, + version: z.number().int(), + signal_versions: z.array(AlertVersion), + migrations: z.array(MigrationStatus), + is_outdated: z.boolean(), + }) +); export type IndexMigrationStatus = z.infer; -export const IndexMigrationStatus = z.object({ - index: NonEmptyString, - version: z.number().int(), - signal_versions: z.array(AlertVersion), - migrations: z.array(MigrationStatus), - is_outdated: z.boolean(), -}); +export const ReadAlertsMigrationStatusRequestQuery = lazySchema(() => + z.object({ + /** + * Maximum age of qualifying detection alerts + */ + from: z.string().superRefine(isValidDateMath), + }) +); export type ReadAlertsMigrationStatusRequestQuery = z.infer< typeof ReadAlertsMigrationStatusRequestQuery >; -export const ReadAlertsMigrationStatusRequestQuery = z.object({ - /** - * Maximum age of qualifying detection alerts - */ - from: z.string().superRefine(isValidDateMath), -}); export type ReadAlertsMigrationStatusRequestQueryInput = z.input< typeof ReadAlertsMigrationStatusRequestQuery >; +export const ReadAlertsMigrationStatusResponse = lazySchema(() => + z.object({ + indices: z.array(IndexMigrationStatus), + }) +); export type ReadAlertsMigrationStatusResponse = z.infer; -export const ReadAlertsMigrationStatusResponse = z.object({ - indices: z.array(IndexMigrationStatus), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/search/search_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/search/search_route.gen.ts index 34d09e5e01ebd..f090b0b1b46a7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/search/search_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/search/search_route.gen.ts @@ -14,19 +14,19 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { QueryAlertsBodyParams } from '../../signals/query_signals/query_signals_route.gen'; /** * Elasticsearch query and aggregation request */ +export const SearchUnifiedAlertsRequestBody = lazySchema(() => QueryAlertsBodyParams); export type SearchUnifiedAlertsRequestBody = z.infer; -export const SearchUnifiedAlertsRequestBody = QueryAlertsBodyParams; export type SearchUnifiedAlertsRequestBodyInput = z.input; /** * Elasticsearch search response */ +export const SearchUnifiedAlertsResponse = lazySchema(() => z.object({}).catchall(z.unknown())); export type SearchUnifiedAlertsResponse = z.infer; -export const SearchUnifiedAlertsResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_assignees/set_alert_assignees_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_assignees/set_alert_assignees_route.gen.ts index 15216715b5142..0c8bc28f0cb74 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_assignees/set_alert_assignees_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_assignees/set_alert_assignees_route.gen.ts @@ -14,14 +14,14 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SetAlertAssigneesBody } from '../../model/set_alert_assignees_body.gen'; +export const SetUnifiedAlertsAssigneesRequestBody = lazySchema(() => SetAlertAssigneesBody); export type SetUnifiedAlertsAssigneesRequestBody = z.infer< typeof SetUnifiedAlertsAssigneesRequestBody >; -export const SetUnifiedAlertsAssigneesRequestBody = SetAlertAssigneesBody; export type SetUnifiedAlertsAssigneesRequestBodyInput = z.input< typeof SetUnifiedAlertsAssigneesRequestBody >; @@ -29,5 +29,7 @@ export type SetUnifiedAlertsAssigneesRequestBodyInput = z.input< /** * Elasticsearch update by IDs response */ +export const SetUnifiedAlertsAssigneesResponse = lazySchema(() => + z.object({}).catchall(z.unknown()) +); export type SetUnifiedAlertsAssigneesResponse = z.infer; -export const SetUnifiedAlertsAssigneesResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_tags/set_alert_tags_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_tags/set_alert_tags_route.gen.ts index 8000e1785ad5b..6a84543d77b80 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_tags/set_alert_tags_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_alert_tags/set_alert_tags_route.gen.ts @@ -14,16 +14,16 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SetAlertTagsBody } from '../../model/set_alert_tags_body.gen'; +export const SetUnifiedAlertsTagsRequestBody = lazySchema(() => SetAlertTagsBody); export type SetUnifiedAlertsTagsRequestBody = z.infer; -export const SetUnifiedAlertsTagsRequestBody = SetAlertTagsBody; export type SetUnifiedAlertsTagsRequestBodyInput = z.input; /** * Elasticsearch update by IDs response */ +export const SetUnifiedAlertsTagsResponse = lazySchema(() => z.object({}).catchall(z.unknown())); export type SetUnifiedAlertsTagsResponse = z.infer; -export const SetUnifiedAlertsTagsResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_workflow_status/set_workflow_status_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_workflow_status/set_workflow_status_route.gen.ts index 11c7e56de70d1..5e1076f6110ce 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_workflow_status/set_workflow_status_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/unified_alerts/set_workflow_status/set_workflow_status_route.gen.ts @@ -14,17 +14,17 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SetAlertsStatusByIds } from '../../signals/set_signal_status/set_signals_status_route.gen'; /** * Set alerts status by IDs request */ +export const SetUnifiedAlertsWorkflowStatusRequestBody = lazySchema(() => SetAlertsStatusByIds); export type SetUnifiedAlertsWorkflowStatusRequestBody = z.infer< typeof SetUnifiedAlertsWorkflowStatusRequestBody >; -export const SetUnifiedAlertsWorkflowStatusRequestBody = SetAlertsStatusByIds; export type SetUnifiedAlertsWorkflowStatusRequestBodyInput = z.input< typeof SetUnifiedAlertsWorkflowStatusRequestBody >; @@ -32,7 +32,9 @@ export type SetUnifiedAlertsWorkflowStatusRequestBodyInput = z.input< /** * Elasticsearch update by IDs response */ +export const SetUnifiedAlertsWorkflowStatusResponse = lazySchema(() => + z.object({}).catchall(z.unknown()) +); export type SetUnifiedAlertsWorkflowStatusResponse = z.infer< typeof SetUnifiedAlertsWorkflowStatusResponse >; -export const SetUnifiedAlertsWorkflowStatusResponse = z.object({}).catchall(z.unknown()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/users/suggest_user_profiles_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/users/suggest_user_profiles_route.gen.ts index 552abd0a39dcb..a91689a05b732 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/users/suggest_user_profiles_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/users/suggest_user_profiles_route.gen.ts @@ -14,13 +14,15 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const SuggestUserProfilesRequestQuery = lazySchema(() => + z.object({ + /** + * Query string used to match name-related fields in user profiles. The following fields are treated as name-related: username, full_name and email + */ + searchTerm: z.string().optional(), + }) +); export type SuggestUserProfilesRequestQuery = z.infer; -export const SuggestUserProfilesRequestQuery = z.object({ - /** - * Query string used to match name-related fields in user profiles. The following fields are treated as name-related: username, full_name and email - */ - searchTerm: z.string().optional(), -}); export type SuggestUserProfilesRequestQueryInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_download/file_download.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_download/file_download.gen.ts index c828d88d21afb..6d13e07a4d576 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_download/file_download.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_download/file_download.gen.ts @@ -14,23 +14,25 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; -export type EndpointFileDownloadRequestParams = z.infer; -export const EndpointFileDownloadRequestParams = z.object({ - /** - * The ID of the response action that generated the file. - */ - action_id: z.string(), - /** +export const EndpointFileDownloadRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the response action that generated the file. + */ + action_id: z.string(), + /** * The file identifier is constructed in one of two ways: - For Elastic Defend agents (`agentType` of `endpoint`): combine the `action_id` and `agent_id` values using a dot (`.`) separator: `{file_id}` = `{action_id}.{agent_id}` - For all other agent types: the `file_id` is the `agent_id` for which the response action was sent to. */ - file_id: z.string(), -}); + file_id: z.string(), + }) +); +export type EndpointFileDownloadRequestParams = z.infer; export type EndpointFileDownloadRequestParamsInput = z.input< typeof EndpointFileDownloadRequestParams >; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_info/file_info.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_info/file_info.gen.ts index 1b59eee24f588..19cdc30b17d14 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_info/file_info.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_info/file_info.gen.ts @@ -14,24 +14,26 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; -export type EndpointFileInfoRequestParams = z.infer; -export const EndpointFileInfoRequestParams = z.object({ - /** - * The ID of the response action that generated the file. - */ - action_id: z.string(), - /** +export const EndpointFileInfoRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the response action that generated the file. + */ + action_id: z.string(), + /** * The file identifier is constructed in one of two ways: - For Elastic Defend agents (`agentType` of `endpoint`): combine the `action_id` and `agent_id` values using a dot (`.`) separator: `{file_id}` = `{action_id}.{agent_id}` - For all other agent types: the `file_id` is the `agent_id` for which the response action was sent to. */ - file_id: z.string(), -}); + file_id: z.string(), + }) +); +export type EndpointFileInfoRequestParams = z.infer; export type EndpointFileInfoRequestParamsInput = z.input; +export const EndpointFileInfoResponse = lazySchema(() => z.unknown()); export type EndpointFileInfoResponse = z.infer; -export const EndpointFileInfoResponse = z.unknown(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/list/list.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/list/list.gen.ts index 606f581f01d08..d0987fadfaee3 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/list/list.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/list/list.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Page, @@ -30,70 +30,74 @@ import { ResponseActionDetails, } from '../../model/schema/common.gen'; +export const GetEndpointActionListResponse = lazySchema(() => + z.object({ + /** + * The current page number. + */ + page: z.number().int().optional(), + /** + * The number of items per page. + */ + pageSize: z.number().int().optional(), + /** + * The start date filter applied to the query. + */ + startDate: z.string().optional(), + /** + * The end date filter applied to the query. + */ + endDate: z.string().optional(), + /** + * The list of agent types the query was filtered by. + */ + agentTypes: z.array(z.string()).optional(), + /** + * The list of elastic agent IDs the query was filtered by. + */ + elasticAgentIds: z.array(z.string()).optional(), + /** + * The list of user IDs the query was filtered by. + */ + userIds: z.array(z.string()).optional(), + /** + * The list of commands the query was filtered by. + */ + commands: z.array(z.string()).optional(), + /** + * The list of statuses the query was filtered by. + */ + statuses: z.array(z.string()).optional(), + /** + * The total number of response actions matching the query. + */ + total: z.number().int().optional(), + /** + * The list of response actions. + */ + data: z.array(ResponseActionDetails).optional(), + }) +); export type GetEndpointActionListResponse = z.infer; -export const GetEndpointActionListResponse = z.object({ - /** - * The current page number. - */ - page: z.number().int().optional(), - /** - * The number of items per page. - */ - pageSize: z.number().int().optional(), - /** - * The start date filter applied to the query. - */ - startDate: z.string().optional(), - /** - * The end date filter applied to the query. - */ - endDate: z.string().optional(), - /** - * The list of agent types the query was filtered by. - */ - agentTypes: z.array(z.string()).optional(), - /** - * The list of elastic agent IDs the query was filtered by. - */ - elasticAgentIds: z.array(z.string()).optional(), - /** - * The list of user IDs the query was filtered by. - */ - userIds: z.array(z.string()).optional(), - /** - * The list of commands the query was filtered by. - */ - commands: z.array(z.string()).optional(), - /** - * The list of statuses the query was filtered by. - */ - statuses: z.array(z.string()).optional(), - /** - * The total number of response actions matching the query. - */ - total: z.number().int().optional(), - /** - * The list of response actions. - */ - data: z.array(ResponseActionDetails).optional(), -}); +export const EndpointGetActionsListRequestQuery = lazySchema(() => + z.object({ + page: Page.optional(), + pageSize: PageSize.optional(), + commands: Commands.optional(), + agentIds: AgentIds.optional(), + userIds: UserIds.optional(), + startDate: StartDate.optional(), + endDate: EndDate.optional(), + agentTypes: AgentTypes.optional(), + withOutputs: WithOutputs.optional(), + types: Types.optional(), + }) +); export type EndpointGetActionsListRequestQuery = z.infer; -export const EndpointGetActionsListRequestQuery = z.object({ - page: Page.optional(), - pageSize: PageSize.optional(), - commands: Commands.optional(), - agentIds: AgentIds.optional(), - userIds: UserIds.optional(), - startDate: StartDate.optional(), - endDate: EndDate.optional(), - agentTypes: AgentTypes.optional(), - withOutputs: WithOutputs.optional(), - types: Types.optional(), -}); export type EndpointGetActionsListRequestQueryInput = z.input< typeof EndpointGetActionsListRequestQuery >; +export const EndpointGetActionsListResponse = lazySchema(() => GetEndpointActionListResponse); export type EndpointGetActionsListResponse = z.infer; -export const EndpointGetActionsListResponse = GetEndpointActionListResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts index 1eb5e0fc37beb..98dc31a21c682 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/cancel/cancel.gen.ts @@ -14,28 +14,30 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type CancelRouteRequestBody = z.infer; -export const CancelRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.object({ - /** - * ID of the response action to cancel - */ - id: z.string().min(1), - }), - }) +export const CancelRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.object({ + /** + * ID of the response action to cancel + */ + id: z.string().min(1), + }), + }) + ) ); +export type CancelRouteRequestBody = z.infer; +export const CancelActionRequestBody = lazySchema(() => CancelRouteRequestBody); export type CancelActionRequestBody = z.infer; -export const CancelActionRequestBody = CancelRouteRequestBody; export type CancelActionRequestBodyInput = z.input; +export const CancelActionResponse = lazySchema(() => ResponseActionCreateSuccessResponse); export type CancelActionResponse = z.infer; -export const CancelActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts index 55795e85925ce..5dd18bf79aac6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts @@ -14,34 +14,36 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type ExecuteRouteRequestBody = z.infer; -export const ExecuteRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.object({ - /** - * The shell command to execute on the endpoint. - */ - command: z.string().min(1), - /** - * The maximum timeout value in seconds before the command is terminated. - */ - timeout: z.number().int().min(1).optional(), - }), - }) +export const ExecuteRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.object({ + /** + * The shell command to execute on the endpoint. + */ + command: z.string().min(1), + /** + * The maximum timeout value in seconds before the command is terminated. + */ + timeout: z.number().int().min(1).optional(), + }), + }) + ) ); +export type ExecuteRouteRequestBody = z.infer; +export const EndpointExecuteActionRequestBody = lazySchema(() => ExecuteRouteRequestBody); export type EndpointExecuteActionRequestBody = z.infer; -export const EndpointExecuteActionRequestBody = ExecuteRouteRequestBody; export type EndpointExecuteActionRequestBodyInput = z.input< typeof EndpointExecuteActionRequestBody >; +export const EndpointExecuteActionResponse = lazySchema(() => ResponseActionCreateSuccessResponse); export type EndpointExecuteActionResponse = z.infer; -export const EndpointExecuteActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts index 7d6bb5cd69890..ebf4cc336a00f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts @@ -14,30 +14,32 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type GetFileRouteRequestBody = z.infer; -export const GetFileRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.object({ - /** - * The full file path to retrieve from the endpoint. - */ - path: z.string(), - }), - }) +export const GetFileRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.object({ + /** + * The full file path to retrieve from the endpoint. + */ + path: z.string(), + }), + }) + ) ); +export type GetFileRouteRequestBody = z.infer; +export const EndpointGetFileActionRequestBody = lazySchema(() => GetFileRouteRequestBody); export type EndpointGetFileActionRequestBody = z.infer; -export const EndpointGetFileActionRequestBody = GetFileRouteRequestBody; export type EndpointGetFileActionRequestBodyInput = z.input< typeof EndpointGetFileActionRequestBody >; +export const EndpointGetFileActionResponse = lazySchema(() => ResponseActionCreateSuccessResponse); export type EndpointGetFileActionResponse = z.infer; -export const EndpointGetFileActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/isolate/isolate.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/isolate/isolate.gen.ts index 2f8e37f683b37..98a5695cd4c3b 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/isolate/isolate.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/isolate/isolate.gen.ts @@ -14,24 +14,26 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BaseActionSchema, ResponseActionDetails } from '../../../model/schema/common.gen'; +export const IsolateRouteResponse = lazySchema(() => + z.object({ + /** + * The action ID (legacy field, same as `data.id`). + */ + action: z.string().optional(), + data: ResponseActionDetails.optional(), + }) +); export type IsolateRouteResponse = z.infer; -export const IsolateRouteResponse = z.object({ - /** - * The action ID (legacy field, same as `data.id`). - */ - action: z.string().optional(), - data: ResponseActionDetails.optional(), -}); +export const EndpointIsolateActionRequestBody = lazySchema(() => BaseActionSchema); export type EndpointIsolateActionRequestBody = z.infer; -export const EndpointIsolateActionRequestBody = BaseActionSchema; export type EndpointIsolateActionRequestBodyInput = z.input< typeof EndpointIsolateActionRequestBody >; +export const EndpointIsolateActionResponse = lazySchema(() => IsolateRouteResponse); export type EndpointIsolateActionResponse = z.infer; -export const EndpointIsolateActionResponse = IsolateRouteResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts index a2195369d79b5..3df3cffcf5631 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts @@ -14,46 +14,50 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type KillProcessRouteRequestBody = z.infer; -export const KillProcessRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.union([ - z.object({ - /** - * The process ID (PID) of the process to terminate. - */ - pid: z.number().int().min(1).optional(), - }), - z.object({ - /** - * The entity ID of the process to terminate. - */ - entity_id: z.string().min(1).optional(), - }), - z.object({ - /** - * The name of the process to terminate. Valid for SentinelOne agent type only. - */ - process_name: z.string().min(1).optional(), - }), - ]), - }) +export const KillProcessRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.union([ + z.object({ + /** + * The process ID (PID) of the process to terminate. + */ + pid: z.number().int().min(1).optional(), + }), + z.object({ + /** + * The entity ID of the process to terminate. + */ + entity_id: z.string().min(1).optional(), + }), + z.object({ + /** + * The name of the process to terminate. Valid for SentinelOne agent type only. + */ + process_name: z.string().min(1).optional(), + }), + ]), + }) + ) ); +export type KillProcessRouteRequestBody = z.infer; +export const EndpointKillProcessActionRequestBody = lazySchema(() => KillProcessRouteRequestBody); export type EndpointKillProcessActionRequestBody = z.infer< typeof EndpointKillProcessActionRequestBody >; -export const EndpointKillProcessActionRequestBody = KillProcessRouteRequestBody; export type EndpointKillProcessActionRequestBodyInput = z.input< typeof EndpointKillProcessActionRequestBody >; +export const EndpointKillProcessActionResponse = lazySchema( + () => ResponseActionCreateSuccessResponse +); export type EndpointKillProcessActionResponse = z.infer; -export const EndpointKillProcessActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts index 4a0f89cc08334..7fcf507e92d11 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts @@ -14,111 +14,123 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; +export const RawScriptParameters = lazySchema(() => + z.object({ + /** + * Raw script content. + */ + raw: z.string().min(1), + /** + * Command line arguments. + */ + commandLine: z.string().min(1).optional(), + /** + * Timeout in seconds. + */ + timeout: z.number().int().min(1).optional(), + }) +); export type RawScriptParameters = z.infer; -export const RawScriptParameters = z.object({ - /** - * Raw script content. - */ - raw: z.string().min(1), - /** - * Command line arguments. - */ - commandLine: z.string().min(1).optional(), - /** - * Timeout in seconds. - */ - timeout: z.number().int().min(1).optional(), -}); +export const HostPathScriptParameters = lazySchema(() => + z.object({ + /** + * Absolute or relative path of script on host machine. + */ + hostPath: z.string().min(1), + /** + * Command line arguments. + */ + commandLine: z.string().min(1).optional(), + /** + * Timeout in seconds. + */ + timeout: z.number().int().min(1).optional(), + }) +); export type HostPathScriptParameters = z.infer; -export const HostPathScriptParameters = z.object({ - /** - * Absolute or relative path of script on host machine. - */ - hostPath: z.string().min(1), - /** - * Command line arguments. - */ - commandLine: z.string().min(1).optional(), - /** - * Timeout in seconds. - */ - timeout: z.number().int().min(1).optional(), -}); +export const CloudFileScriptParameters = lazySchema(() => + z.object({ + /** + * Script name in cloud storage. + */ + cloudFile: z.string().min(1), + /** + * Command line arguments. + */ + commandLine: z.string().min(1).optional(), + /** + * Timeout in seconds. + */ + timeout: z.number().int().min(1).optional(), + }) +); export type CloudFileScriptParameters = z.infer; -export const CloudFileScriptParameters = z.object({ - /** - * Script name in cloud storage. - */ - cloudFile: z.string().min(1), - /** - * Command line arguments. - */ - commandLine: z.string().min(1).optional(), - /** - * Timeout in seconds. - */ - timeout: z.number().int().min(1).optional(), -}); /** * Parameters for Run Script response action against SentinelOne agent type. */ +export const SentinelOneRunScriptParameters = lazySchema(() => + z.object({ + /** + * The script ID from SentinelOne scripts library that will be executed. + */ + scriptId: z.string().min(1), + /** + * The input parameter arguments for the script that was selected. + */ + scriptInput: z.string().min(1).optional(), + }) +); export type SentinelOneRunScriptParameters = z.infer; -export const SentinelOneRunScriptParameters = z.object({ - /** - * The script ID from SentinelOne scripts library that will be executed. - */ - scriptId: z.string().min(1), - /** - * The input parameter arguments for the script that was selected. - */ - scriptInput: z.string().min(1).optional(), -}); /** * Parameters for Run Script response action against Microsoft Defender Endpoint agent type. */ -export type MDERunScriptParameters = z.infer; -export const MDERunScriptParameters = z.object({ - /** - * The name of the script to execute from the cloud storage. - */ - scriptName: z.string().min(1), - /** - * Optional command line arguments for the script. - */ - args: z.string().min(1).optional(), -}); - -export type RunScriptRouteRequestBody = z.infer; -export const RunScriptRouteRequestBody = BaseActionSchema.extend( +export const MDERunScriptParameters = lazySchema(() => z.object({ /** + * The name of the script to execute from the cloud storage. + */ + scriptName: z.string().min(1), + /** + * Optional command line arguments for the script. + */ + args: z.string().min(1).optional(), + }) +); +export type MDERunScriptParameters = z.infer; + +export const RunScriptRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + /** * One of the following set of parameters must be provided */ - parameters: z.union([ - RawScriptParameters, - HostPathScriptParameters, - CloudFileScriptParameters, - SentinelOneRunScriptParameters, - MDERunScriptParameters, - ]), - }) + parameters: z.union([ + RawScriptParameters, + HostPathScriptParameters, + CloudFileScriptParameters, + SentinelOneRunScriptParameters, + MDERunScriptParameters, + ]), + }) + ) ); +export type RunScriptRouteRequestBody = z.infer; +export const RunScriptActionRequestBody = lazySchema(() => RunScriptRouteRequestBody); export type RunScriptActionRequestBody = z.infer; -export const RunScriptActionRequestBody = RunScriptRouteRequestBody; export type RunScriptActionRequestBodyInput = z.input; +export const RunScriptActionResponse = lazySchema(() => ResponseActionCreateSuccessResponse); export type RunScriptActionResponse = z.infer; -export const RunScriptActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/running_procs/running_procs.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/running_procs/running_procs.gen.ts index 67071c07fa3d6..ae5b3764a8a89 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/running_procs/running_procs.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/running_procs/running_procs.gen.ts @@ -15,22 +15,25 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; +export const GetProcessesRouteRequestBody = lazySchema(() => BaseActionSchema); export type GetProcessesRouteRequestBody = z.infer; -export const GetProcessesRouteRequestBody = BaseActionSchema; +export const EndpointGetProcessesActionRequestBody = lazySchema(() => GetProcessesRouteRequestBody); export type EndpointGetProcessesActionRequestBody = z.infer< typeof EndpointGetProcessesActionRequestBody >; -export const EndpointGetProcessesActionRequestBody = GetProcessesRouteRequestBody; export type EndpointGetProcessesActionRequestBodyInput = z.input< typeof EndpointGetProcessesActionRequestBody >; +export const EndpointGetProcessesActionResponse = lazySchema( + () => ResponseActionCreateSuccessResponse +); export type EndpointGetProcessesActionResponse = z.infer; -export const EndpointGetProcessesActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts index 10563d0df4c2e..e5bb1cf5a705c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts @@ -14,28 +14,30 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type ScanRouteRequestBody = z.infer; -export const ScanRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.object({ - /** - * The folder or file's full path (including the file name). - */ - path: z.string(), - }), - }) +export const ScanRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.object({ + /** + * The folder or file's full path (including the file name). + */ + path: z.string(), + }), + }) + ) ); +export type ScanRouteRequestBody = z.infer; +export const EndpointScanActionRequestBody = lazySchema(() => ScanRouteRequestBody); export type EndpointScanActionRequestBody = z.infer; -export const EndpointScanActionRequestBody = ScanRouteRequestBody; export type EndpointScanActionRequestBodyInput = z.input; +export const EndpointScanActionResponse = lazySchema(() => ResponseActionCreateSuccessResponse); export type EndpointScanActionResponse = z.infer; -export const EndpointScanActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts index 7b864462c1df8..90e75cad68bf4 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts @@ -14,42 +14,48 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type SuspendProcessRouteRequestBody = z.infer; -export const SuspendProcessRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.union([ - z.object({ - /** - * The process ID (PID) of the process to suspend. - */ - pid: z.number().int().min(1).optional(), - }), - z.object({ - /** - * The entity ID of the process to suspend. - */ - entity_id: z.string().min(1).optional(), - }), - ]), - }) +export const SuspendProcessRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.union([ + z.object({ + /** + * The process ID (PID) of the process to suspend. + */ + pid: z.number().int().min(1).optional(), + }), + z.object({ + /** + * The entity ID of the process to suspend. + */ + entity_id: z.string().min(1).optional(), + }), + ]), + }) + ) ); +export type SuspendProcessRouteRequestBody = z.infer; +export const EndpointSuspendProcessActionRequestBody = lazySchema( + () => SuspendProcessRouteRequestBody +); export type EndpointSuspendProcessActionRequestBody = z.infer< typeof EndpointSuspendProcessActionRequestBody >; -export const EndpointSuspendProcessActionRequestBody = SuspendProcessRouteRequestBody; export type EndpointSuspendProcessActionRequestBodyInput = z.input< typeof EndpointSuspendProcessActionRequestBody >; +export const EndpointSuspendProcessActionResponse = lazySchema( + () => ResponseActionCreateSuccessResponse +); export type EndpointSuspendProcessActionResponse = z.infer< typeof EndpointSuspendProcessActionResponse >; -export const EndpointSuspendProcessActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/unisolate/unisolate.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/unisolate/unisolate.gen.ts index a400a11431b60..d265f41252e81 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/unisolate/unisolate.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/unisolate/unisolate.gen.ts @@ -14,24 +14,26 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BaseActionSchema, ResponseActionDetails } from '../../../model/schema/common.gen'; +export const UnisolateRouteResponse = lazySchema(() => + z.object({ + /** + * The action ID (legacy field, same as `data.id`). + */ + action: z.string().optional(), + data: ResponseActionDetails.optional(), + }) +); export type UnisolateRouteResponse = z.infer; -export const UnisolateRouteResponse = z.object({ - /** - * The action ID (legacy field, same as `data.id`). - */ - action: z.string().optional(), - data: ResponseActionDetails.optional(), -}); +export const EndpointUnisolateActionRequestBody = lazySchema(() => BaseActionSchema); export type EndpointUnisolateActionRequestBody = z.infer; -export const EndpointUnisolateActionRequestBody = BaseActionSchema; export type EndpointUnisolateActionRequestBodyInput = z.input< typeof EndpointUnisolateActionRequestBody >; +export const EndpointUnisolateActionResponse = lazySchema(() => UnisolateRouteResponse); export type EndpointUnisolateActionResponse = z.infer; -export const EndpointUnisolateActionResponse = UnisolateRouteResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts index b7058a610237d..73b0fd9a6a0bf 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts @@ -14,28 +14,30 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResponseActionCreateSuccessResponse, BaseActionSchema, } from '../../../model/schema/common.gen'; -export type UploadRouteRequestBody = z.infer; -export const UploadRouteRequestBody = BaseActionSchema.extend( - z.object({ - parameters: z.object({ +export const UploadRouteRequestBody = lazySchema(() => + BaseActionSchema.merge( + z.object({ + parameters: z.object({ + /** + * Overwrite the file on the host if it already exists. + */ + overwrite: z.boolean().optional().default(false), + }), /** - * Overwrite the file on the host if it already exists. + * The binary content of the file. */ - overwrite: z.boolean().optional().default(false), - }), - /** - * The binary content of the file. - */ - file: z.string(), - }) + file: z.string(), + }) + ) ); +export type UploadRouteRequestBody = z.infer; +export const EndpointUploadActionResponse = lazySchema(() => ResponseActionCreateSuccessResponse); export type EndpointUploadActionResponse = z.infer; -export const EndpointUploadActionResponse = ResponseActionCreateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/state/state.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/state/state.gen.ts index 7ba1252248c7e..c790b4e9fd4c7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/state/state.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/state/state.gen.ts @@ -14,19 +14,21 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; -export type ActionStateSuccessResponse = z.infer; -export const ActionStateSuccessResponse = z.object({ - body: z.object({ - data: z.object({ - /** - * Whether the Kibana instance has encryption enabled for response actions. - */ - canEncrypt: z.boolean().optional(), +export const ActionStateSuccessResponse = lazySchema(() => + z.object({ + body: z.object({ + data: z.object({ + /** + * Whether the Kibana instance has encryption enabled for response actions. + */ + canEncrypt: z.boolean().optional(), + }), }), - }), -}); + }) +); +export type ActionStateSuccessResponse = z.infer; +export const EndpointGetActionsStateResponse = lazySchema(() => ActionStateSuccessResponse); export type EndpointGetActionsStateResponse = z.infer; -export const EndpointGetActionsStateResponse = ActionStateSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/status/status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/status/status.gen.ts index 65cb1908d996c..983f0d5fa8a89 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/status/status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/status/status.gen.ts @@ -14,81 +14,87 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AgentIds, AgentId } from '../../model/schema/common.gen'; /** * Number of pending actions of this type. */ +export const PendingActionDataType = lazySchema(() => z.number().int()); export type PendingActionDataType = z.infer; -export const PendingActionDataType = z.number().int(); +export const PendingActionsSchema = lazySchema(() => + z.union([ + z.object({ + /** + * Number of pending isolate actions. + */ + isolate: PendingActionDataType.optional(), + /** + * Number of pending unisolate (release) actions. + */ + unisolate: PendingActionDataType.optional(), + /** + * Number of pending kill-process actions. + */ + 'kill-process': PendingActionDataType.optional(), + /** + * Number of pending suspend-process actions. + */ + 'suspend-process': PendingActionDataType.optional(), + /** + * Number of pending running-processes (get processes) actions. + */ + 'running-processes': PendingActionDataType.optional(), + /** + * Number of pending get-file actions. + */ + 'get-file': PendingActionDataType.optional(), + /** + * Number of pending execute actions. + */ + execute: PendingActionDataType.optional(), + /** + * Number of pending upload actions. + */ + upload: PendingActionDataType.optional(), + /** + * Number of pending scan actions. + */ + scan: PendingActionDataType.optional(), + }), + z.object({}).catchall(z.unknown()), + ]) +); export type PendingActionsSchema = z.infer; -export const PendingActionsSchema = z.union([ - z.object({ - /** - * Number of pending isolate actions. - */ - isolate: PendingActionDataType.optional(), - /** - * Number of pending unisolate (release) actions. - */ - unisolate: PendingActionDataType.optional(), - /** - * Number of pending kill-process actions. - */ - 'kill-process': PendingActionDataType.optional(), - /** - * Number of pending suspend-process actions. - */ - 'suspend-process': PendingActionDataType.optional(), - /** - * Number of pending running-processes (get processes) actions. - */ - 'running-processes': PendingActionDataType.optional(), - /** - * Number of pending get-file actions. - */ - 'get-file': PendingActionDataType.optional(), - /** - * Number of pending execute actions. - */ - execute: PendingActionDataType.optional(), - /** - * Number of pending upload actions. - */ - upload: PendingActionDataType.optional(), - /** - * Number of pending scan actions. - */ - scan: PendingActionDataType.optional(), - }), - z.object({}).catchall(z.unknown()), -]); -export type ActionStatusSuccessResponse = z.infer; -export const ActionStatusSuccessResponse = z.object({ - body: z.object({ - data: z.object({ - agent_id: AgentId, - pending_actions: PendingActionsSchema, +export const ActionStatusSuccessResponse = lazySchema(() => + z.object({ + body: z.object({ + data: z.object({ + agent_id: AgentId, + pending_actions: PendingActionsSchema, + }), }), - }), -}); + }) +); +export type ActionStatusSuccessResponse = z.infer; +export const EndpointGetActionsStatusRequestQuery = lazySchema(() => + z.object({ + /** + * A list of agent IDs to get the action status for. + */ + agent_ids: AgentIds, + }) +); export type EndpointGetActionsStatusRequestQuery = z.infer< typeof EndpointGetActionsStatusRequestQuery >; -export const EndpointGetActionsStatusRequestQuery = z.object({ - /** - * A list of agent IDs to get the action status for. - */ - agent_ids: AgentIds, -}); export type EndpointGetActionsStatusRequestQueryInput = z.input< typeof EndpointGetActionsStatusRequestQuery >; +export const EndpointGetActionsStatusResponse = lazySchema(() => ActionStatusSuccessResponse); export type EndpointGetActionsStatusResponse = z.infer; -export const EndpointGetActionsStatusResponse = ActionStatusSuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/endpoint_exceptions_per_policy_opt_in/endpoint_exceptions_per_policy_opt_in.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/endpoint_exceptions_per_policy_opt_in/endpoint_exceptions_per_policy_opt_in.gen.ts index b3417407d3b54..a49b5102b5559 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/endpoint_exceptions_per_policy_opt_in/endpoint_exceptions_per_policy_opt_in.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/endpoint_exceptions_per_policy_opt_in/endpoint_exceptions_per_policy_opt_in.gen.ts @@ -14,12 +14,14 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const GetEndpointExceptionsPerPolicyOptInResponse = lazySchema(() => + z.object({ + status: z.boolean(), + reason: z.enum(['newDeployment', 'userOptedIn']).optional(), + }) +); export type GetEndpointExceptionsPerPolicyOptInResponse = z.infer< typeof GetEndpointExceptionsPerPolicyOptInResponse >; -export const GetEndpointExceptionsPerPolicyOptInResponse = z.object({ - status: z.boolean(), - reason: z.enum(['newDeployment', 'userOptedIn']).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/get_metadata.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/get_metadata.gen.ts index 5d8e9957a237d..36d6ecdb05cc5 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/get_metadata.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/get_metadata.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Page, @@ -26,20 +26,22 @@ import { } from '../model/schema/common.gen'; import { MetadataListResponse } from './list_metadata.gen'; +export const GetEndpointMetadataListRequestQuery = lazySchema(() => + z.object({ + page: Page.optional(), + pageSize: PageSize.optional(), + kuery: Kuery.optional(), + hostStatuses: HostStatuses, + sortField: SortField.optional(), + sortDirection: SortDirection.optional(), + }) +); export type GetEndpointMetadataListRequestQuery = z.infer< typeof GetEndpointMetadataListRequestQuery >; -export const GetEndpointMetadataListRequestQuery = z.object({ - page: Page.optional(), - pageSize: PageSize.optional(), - kuery: Kuery.optional(), - hostStatuses: HostStatuses, - sortField: SortField.optional(), - sortDirection: SortDirection.optional(), -}); export type GetEndpointMetadataListRequestQueryInput = z.input< typeof GetEndpointMetadataListRequestQuery >; +export const GetEndpointMetadataListResponse = lazySchema(() => MetadataListResponse); export type GetEndpointMetadataListResponse = z.infer; -export const GetEndpointMetadataListResponse = MetadataListResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts index 97b0375c01c98..f30efcff962c6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts @@ -14,10 +14,10 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const EndpointMetadataResponse = lazySchema(() => z.object({})); export type EndpointMetadataResponse = z.infer; -export const EndpointMetadataResponse = z.object({}); +export const MetadataListResponse = lazySchema(() => z.object({})); export type MetadataListResponse = z.infer; -export const MetadataListResponse = z.object({}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts index 32be0d394c150..e922599882ba3 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts @@ -14,334 +14,351 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * A unique identifier */ +export const Id = lazySchema(() => z.string()); export type Id = z.infer; -export const Id = z.string(); +export const IdOrUndefined = lazySchema(() => Id.nullable()); export type IdOrUndefined = z.infer; -export const IdOrUndefined = Id.nullable(); /** * Page number */ +export const Page = lazySchema(() => z.number().int().min(1).default(1)); export type Page = z.infer; -export const Page = z.number().int().min(1).default(1); /** * Number of items per page */ +export const PageSize = lazySchema(() => z.number().int().min(1).max(100).default(10)); export type PageSize = z.infer; -export const PageSize = z.number().int().min(1).max(100).default(10); /** * A start date in ISO 8601 format or Date Math format. */ +export const StartDate = lazySchema(() => z.string()); export type StartDate = z.infer; -export const StartDate = z.string(); /** * An end date in ISO format or Date Math format. */ +export const EndDate = lazySchema(() => z.string()); export type EndDate = z.infer; -export const EndDate = z.string(); /** * Agent ID */ +export const AgentId = lazySchema(() => z.string()); export type AgentId = z.infer; -export const AgentId = z.string(); /** * A KQL string. */ +export const Kuery = lazySchema(() => z.string()); export type Kuery = z.infer; -export const Kuery = z.string(); /** * A set of agent health statuses to filter by. */ +export const HostStatuses = lazySchema(() => + z.array(z.enum(['healthy', 'offline', 'updating', 'inactive', 'unenrolled'])).max(20) +); export type HostStatuses = z.infer; -export const HostStatuses = z - .array(z.enum(['healthy', 'offline', 'updating', 'inactive', 'unenrolled'])) - .max(20); /** * Determines the sort order. */ +export const SortDirection = lazySchema(() => z.enum(['asc', 'desc'])); export type SortDirection = z.infer; -export const SortDirection = z.enum(['asc', 'desc']); export type SortDirectionEnum = typeof SortDirection.enum; export const SortDirectionEnum = SortDirection.enum; /** * Determines which field is used to sort the results. */ +export const SortField = lazySchema(() => + z.enum([ + 'enrolled_at', + 'metadata.host.hostname', + 'host_status', + 'metadata.Endpoint.policy.applied.name', + 'metadata.Endpoint.policy.applied.status', + 'metadata.host.os.name', + 'metadata.host.ip', + 'metadata.agent.version', + 'last_checkin', + ]) +); export type SortField = z.infer; -export const SortField = z.enum([ - 'enrolled_at', - 'metadata.host.hostname', - 'host_status', - 'metadata.Endpoint.policy.applied.name', - 'metadata.Endpoint.policy.applied.status', - 'metadata.host.os.name', - 'metadata.host.ip', - 'metadata.agent.version', - 'last_checkin', -]); export type SortFieldEnum = typeof SortField.enum; export const SortFieldEnum = SortField.enum; /** * A list of agent IDs. Max of 250. */ +export const AgentIds = lazySchema(() => + z.union([z.array(z.string().min(1)).min(1).max(250), z.string().min(1)]) +); export type AgentIds = z.infer; -export const AgentIds = z.union([z.array(z.string().min(1)).min(1).max(250), z.string().min(1)]); /** * The command for the response action */ +export const Command = lazySchema(() => + z.enum([ + 'isolate', + 'unisolate', + 'kill-process', + 'suspend-process', + 'running-processes', + 'get-file', + 'execute', + 'upload', + 'scan', + 'runscript', + 'cancel', + 'memory-dump', + ]) +); export type Command = z.infer; -export const Command = z.enum([ - 'isolate', - 'unisolate', - 'kill-process', - 'suspend-process', - 'running-processes', - 'get-file', - 'execute', - 'upload', - 'scan', - 'runscript', - 'cancel', - 'memory-dump', -]); export type CommandEnum = typeof Command.enum; export const CommandEnum = Command.enum; /** * A list of response action command names. */ +export const Commands = lazySchema(() => z.array(Command).max(50)); export type Commands = z.infer; -export const Commands = z.array(Command).max(50); /** * The maximum timeout value in milliseconds (optional) */ +export const Timeout = lazySchema(() => z.number().int().min(1)); export type Timeout = z.infer; -export const Timeout = z.number().int().min(1); /** * The status of a response action. */ +export const Status = lazySchema(() => z.enum(['failed', 'pending', 'successful'])); export type Status = z.infer; -export const Status = z.enum(['failed', 'pending', 'successful']); export type StatusEnum = typeof Status.enum; export const StatusEnum = Status.enum; /** * A list of response action statuses to filter by. */ +export const Statuses = lazySchema(() => z.array(Status)); export type Statuses = z.infer; -export const Statuses = z.array(Status); /** * A list of user IDs. Max of 50. */ +export const UserIds = lazySchema(() => + z.union([z.array(z.string().min(1)).min(1).max(50), z.string().min(1)]) +); export type UserIds = z.infer; -export const UserIds = z.union([z.array(z.string().min(1)).min(1).max(50), z.string().min(1)]); /** * A list of action IDs that should include the complete output of the action. Max of 50. */ +export const WithOutputs = lazySchema(() => + z.union([z.array(z.string().min(1)).min(1).max(50), z.string().min(1)]) +); export type WithOutputs = z.infer; -export const WithOutputs = z.union([z.array(z.string().min(1)).min(1).max(50), z.string().min(1)]); /** * Type of response action */ +export const Type = lazySchema(() => z.enum(['automated', 'manual'])); export type Type = z.infer; -export const Type = z.enum(['automated', 'manual']); export type TypeEnum = typeof Type.enum; export const TypeEnum = Type.enum; /** * List of types of response actions */ +export const Types = lazySchema(() => z.array(Type)); export type Types = z.infer; -export const Types = z.array(Type); /** * List of endpoint IDs (cannot contain empty strings). Max of 250. */ +export const EndpointIds = lazySchema(() => z.array(z.string().min(1)).min(1).max(250)); export type EndpointIds = z.infer; -export const EndpointIds = z.array(z.string().min(1)).min(1).max(250); /** * Optional comment */ +export const Comment = lazySchema(() => z.string()); export type Comment = z.infer; -export const Comment = z.string(); /** * Parameters object */ +export const Parameters = lazySchema(() => z.object({})); export type Parameters = z.infer; -export const Parameters = z.object({}); /** * List of agent types to retrieve. Defaults to `endpoint`. */ +export const AgentTypes = lazySchema(() => + z.enum(['endpoint', 'sentinel_one', 'crowdstrike', 'microsoft_defender_endpoint']) +); export type AgentTypes = z.infer; -export const AgentTypes = z.enum([ - 'endpoint', - 'sentinel_one', - 'crowdstrike', - 'microsoft_defender_endpoint', -]); export type AgentTypesEnum = typeof AgentTypes.enum; export const AgentTypesEnum = AgentTypes.enum; +export const BaseActionSchema = lazySchema(() => + z.object({ + endpoint_ids: EndpointIds, + /** + * If this action is associated with any alerts, they can be specified here. The action will be logged in any cases associated with the specified alerts. Max of 50. + */ + alert_ids: z.array(z.string().min(1)).min(1).max(50).optional(), + /** + * The IDs of cases where the action taken will be logged. Max of 50. + */ + case_ids: z.array(z.string().min(1)).min(1).max(50).optional(), + comment: Comment.optional(), + parameters: Parameters.optional(), + agent_type: AgentTypes.optional(), + }) +); export type BaseActionSchema = z.infer; -export const BaseActionSchema = z.object({ - endpoint_ids: EndpointIds, - /** - * If this action is associated with any alerts, they can be specified here. The action will be logged in any cases associated with the specified alerts. Max of 50. - */ - alert_ids: z.array(z.string().min(1)).min(1).max(50).optional(), - /** - * The IDs of cases where the action taken will be logged. Max of 50. - */ - case_ids: z.array(z.string().min(1)).min(1).max(50).optional(), - comment: Comment.optional(), - parameters: Parameters.optional(), - agent_type: AgentTypes.optional(), -}); +export const NoParametersRequestSchema = lazySchema(() => + z.object({ + body: BaseActionSchema, + }) +); export type NoParametersRequestSchema = z.infer; -export const NoParametersRequestSchema = z.object({ - body: BaseActionSchema, -}); +export const ProtectionUpdatesNoteResponse = lazySchema(() => + z.object({ + /** + * A note associated with the protection updates for the given package policy. + */ + note: z.string().optional(), + }) +); export type ProtectionUpdatesNoteResponse = z.infer; -export const ProtectionUpdatesNoteResponse = z.object({ - /** - * A note associated with the protection updates for the given package policy. - */ - note: z.string().optional(), -}); -export type ResponseActionDetails = z.infer; -export const ResponseActionDetails = z.object({ - /** - * The response action ID - */ - id: z.string().uuid().optional(), - command: Command, - agentType: AgentTypes.optional(), - /** - * Whether the response action is expired - */ - isExpired: z.boolean().optional(), - /** - * Whether the response action is complete - */ - isComplete: z.boolean().optional(), - /** - * Whether the response action was successful - */ - wasSuccessful: z.boolean().optional(), - /** - * The response action status - */ - status: z.string().optional(), - /** - * The response action start time - */ - startedAt: z.string().datetime().optional(), - /** - * The response action completion time - */ - completedAt: z.string().datetime().optional(), - /** - * The user who created the response action - */ - createdBy: z.string().optional(), - /** - * The agent IDs for the hosts that the response action was sent to - */ - agents: z.array(z.string().uuid()).optional(), - /** - * The parameters of the response action. Content different depending on the response action command - */ - parameters: z.object({}).optional(), - /** - * An object containing the host names associated with the agent IDs the response action was sent to - */ - hosts: z - .object({}) - .catchall( - z.object({ - /** - * The host name - */ - name: z.string().optional(), - }) - ) - .optional(), - /** - * The state of the response action for each agent ID that it was sent to - */ - agentState: z - .object({}) - .catchall( - z.object({ - /** - * Whether the response action is completed for the agent ID - */ - isCompleted: z.boolean().optional(), - /** - * Whether the response action was successful for the agent ID - */ - wasSuccessful: z.boolean().optional(), - /** - * The date and time the response action was completed for the agent ID - */ - completedAt: z.string().optional(), - }) - ) - .optional(), - /** +export const ResponseActionDetails = lazySchema(() => + z.object({ + /** + * The response action ID + */ + id: z.string().uuid().optional(), + command: Command, + agentType: AgentTypes.optional(), + /** + * Whether the response action is expired + */ + isExpired: z.boolean().optional(), + /** + * Whether the response action is complete + */ + isComplete: z.boolean().optional(), + /** + * Whether the response action was successful + */ + wasSuccessful: z.boolean().optional(), + /** + * The response action status + */ + status: z.string().optional(), + /** + * The response action start time + */ + startedAt: z.string().datetime().optional(), + /** + * The response action completion time + */ + completedAt: z.string().datetime().optional(), + /** + * The user who created the response action + */ + createdBy: z.string().optional(), + /** + * The agent IDs for the hosts that the response action was sent to + */ + agents: z.array(z.string().uuid()).optional(), + /** + * The parameters of the response action. Content different depending on the response action command + */ + parameters: z.object({}).optional(), + /** + * An object containing the host names associated with the agent IDs the response action was sent to + */ + hosts: z + .object({}) + .catchall( + z.object({ + /** + * The host name + */ + name: z.string().optional(), + }) + ) + .optional(), + /** + * The state of the response action for each agent ID that it was sent to + */ + agentState: z + .object({}) + .catchall( + z.object({ + /** + * Whether the response action is completed for the agent ID + */ + isCompleted: z.boolean().optional(), + /** + * Whether the response action was successful for the agent ID + */ + wasSuccessful: z.boolean().optional(), + /** + * The date and time the response action was completed for the agent ID + */ + completedAt: z.string().optional(), + }) + ) + .optional(), + /** * The outputs of the response action for each agent ID that it was sent to. Content different depending on the response action command and will only be present for agents that have responded to the response action */ - outputs: z - .object({}) - .catchall( - z.object({ - type: z.enum(['json', 'text']), - /** - * The response action output content for the agent ID. Exact format depends on the response action command. - */ - content: z.union([z.object({}), z.string()]), - }) - ) - .optional(), -}); + outputs: z + .object({}) + .catchall( + z.object({ + type: z.enum(['json', 'text']), + /** + * The response action output content for the agent ID. Exact format depends on the response action command. + */ + content: z.union([z.object({}), z.string()]), + }) + ) + .optional(), + }) +); +export type ResponseActionDetails = z.infer; +export const ResponseActionCreateSuccessResponse = lazySchema(() => + z.object({ + data: ResponseActionDetails.optional(), + }) +); export type ResponseActionCreateSuccessResponse = z.infer< typeof ResponseActionCreateSuccessResponse >; -export const ResponseActionCreateSuccessResponse = z.object({ - data: ResponseActionDetails.optional(), -}); /** * A generic successful response. */ +export const SuccessResponse = lazySchema(() => z.object({})); export type SuccessResponse = z.infer; -export const SuccessResponse = z.object({}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/policy/policy_response.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/policy/policy_response.gen.ts index 7a237ccb722f3..5d66cefae6725 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/policy/policy_response.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/policy/policy_response.gen.ts @@ -14,18 +14,20 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AgentId, SuccessResponse } from '../model/schema/common.gen'; +export const GetPolicyResponseRequestQuery = lazySchema(() => + z.object({ + /** + * The agent ID to retrieve the policy response for. + */ + agentId: AgentId, + }) +); export type GetPolicyResponseRequestQuery = z.infer; -export const GetPolicyResponseRequestQuery = z.object({ - /** - * The agent ID to retrieve the policy response for. - */ - agentId: AgentId, -}); export type GetPolicyResponseRequestQueryInput = z.input; +export const GetPolicyResponseResponse = lazySchema(() => SuccessResponse); export type GetPolicyResponseResponse = z.infer; -export const GetPolicyResponseResponse = SuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/protection_updates_note/protection_updates_note.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/protection_updates_note/protection_updates_note.gen.ts index 6c00ff77e7a33..5401aefe85c5f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/protection_updates_note/protection_updates_note.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/protection_updates_note/protection_updates_note.gen.ts @@ -14,53 +14,61 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ProtectionUpdatesNoteResponse } from '../model/schema/common.gen'; +export const CreateUpdateProtectionUpdatesNoteRequestParams = lazySchema(() => + z.object({ + /** + * The package policy ID to create or update the protection updates note for. + */ + package_policy_id: z.string(), + }) +); export type CreateUpdateProtectionUpdatesNoteRequestParams = z.infer< typeof CreateUpdateProtectionUpdatesNoteRequestParams >; -export const CreateUpdateProtectionUpdatesNoteRequestParams = z.object({ - /** - * The package policy ID to create or update the protection updates note for. - */ - package_policy_id: z.string(), -}); export type CreateUpdateProtectionUpdatesNoteRequestParamsInput = z.input< typeof CreateUpdateProtectionUpdatesNoteRequestParams >; +export const CreateUpdateProtectionUpdatesNoteRequestBody = lazySchema(() => + z.object({ + /** + * The note content. + */ + note: z.string().optional(), + }) +); export type CreateUpdateProtectionUpdatesNoteRequestBody = z.infer< typeof CreateUpdateProtectionUpdatesNoteRequestBody >; -export const CreateUpdateProtectionUpdatesNoteRequestBody = z.object({ - /** - * The note content. - */ - note: z.string().optional(), -}); export type CreateUpdateProtectionUpdatesNoteRequestBodyInput = z.input< typeof CreateUpdateProtectionUpdatesNoteRequestBody >; +export const CreateUpdateProtectionUpdatesNoteResponse = lazySchema( + () => ProtectionUpdatesNoteResponse +); export type CreateUpdateProtectionUpdatesNoteResponse = z.infer< typeof CreateUpdateProtectionUpdatesNoteResponse >; -export const CreateUpdateProtectionUpdatesNoteResponse = ProtectionUpdatesNoteResponse; +export const GetProtectionUpdatesNoteRequestParams = lazySchema(() => + z.object({ + /** + * The package policy ID to retrieve the protection updates note for. + */ + package_policy_id: z.string(), + }) +); export type GetProtectionUpdatesNoteRequestParams = z.infer< typeof GetProtectionUpdatesNoteRequestParams >; -export const GetProtectionUpdatesNoteRequestParams = z.object({ - /** - * The package policy ID to retrieve the protection updates note for. - */ - package_policy_id: z.string(), -}); export type GetProtectionUpdatesNoteRequestParamsInput = z.input< typeof GetProtectionUpdatesNoteRequestParams >; +export const GetProtectionUpdatesNoteResponse = lazySchema(() => ProtectionUpdatesNoteResponse); export type GetProtectionUpdatesNoteResponse = z.infer; -export const GetProtectionUpdatesNoteResponse = ProtectionUpdatesNoteResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts index 638c0a97fb21e..0cca1a2c66654 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts @@ -14,30 +14,34 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SuccessResponse } from '../model/schema/common.gen'; +export const GetEndpointSuggestionsRequestParams = lazySchema(() => + z.object({ + suggestion_type: z.literal('eventFilters'), + }) +); export type GetEndpointSuggestionsRequestParams = z.infer< typeof GetEndpointSuggestionsRequestParams >; -export const GetEndpointSuggestionsRequestParams = z.object({ - suggestion_type: z.literal('eventFilters'), -}); export type GetEndpointSuggestionsRequestParamsInput = z.input< typeof GetEndpointSuggestionsRequestParams >; +export const GetEndpointSuggestionsRequestBody = lazySchema(() => + z.object({ + field: z.string().optional(), + query: z.string().optional(), + filters: z.array(z.object({})).max(50).optional(), + fieldMeta: z.unknown(), + }) +); export type GetEndpointSuggestionsRequestBody = z.infer; -export const GetEndpointSuggestionsRequestBody = z.object({ - field: z.string().optional(), - query: z.string().optional(), - filters: z.array(z.object({})).max(50).optional(), - fieldMeta: z.unknown(), -}); export type GetEndpointSuggestionsRequestBodyInput = z.input< typeof GetEndpointSuggestionsRequestBody >; +export const GetEndpointSuggestionsResponse = lazySchema(() => SuccessResponse); export type GetEndpointSuggestionsResponse = z.infer; -export const GetEndpointSuggestionsResponse = SuccessResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts index 4bf1c82cc88ad..f495cd5a639d8 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/bulk_upload_asset_criticality.gen.ts @@ -14,65 +14,69 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AssetCriticalityRecordIdParts } from './common.gen'; +export const AssetCriticalityBulkUploadErrorItem = lazySchema(() => + z.object({ + message: z.string(), + index: z.number().int(), + }) +); export type AssetCriticalityBulkUploadErrorItem = z.infer< typeof AssetCriticalityBulkUploadErrorItem >; -export const AssetCriticalityBulkUploadErrorItem = z.object({ - message: z.string(), - index: z.number().int(), -}); +export const AssetCriticalityBulkUploadStats = lazySchema(() => + z.object({ + successful: z.number().int(), + failed: z.number().int(), + total: z.number().int(), + }) +); export type AssetCriticalityBulkUploadStats = z.infer; -export const AssetCriticalityBulkUploadStats = z.object({ - successful: z.number().int(), - failed: z.number().int(), - total: z.number().int(), -}); /** * The criticality level of the asset for bulk upload. The value `unassigned` is used to indicate that the criticality level is not assigned and is only used for bulk upload. */ +export const AssetCriticalityLevelsForBulkUpload = lazySchema(() => + z.enum(['low_impact', 'medium_impact', 'high_impact', 'extreme_impact', 'unassigned']) +); export type AssetCriticalityLevelsForBulkUpload = z.infer< typeof AssetCriticalityLevelsForBulkUpload >; -export const AssetCriticalityLevelsForBulkUpload = z.enum([ - 'low_impact', - 'medium_impact', - 'high_impact', - 'extreme_impact', - 'unassigned', -]); export type AssetCriticalityLevelsForBulkUploadEnum = typeof AssetCriticalityLevelsForBulkUpload.enum; export const AssetCriticalityLevelsForBulkUploadEnum = AssetCriticalityLevelsForBulkUpload.enum; +export const BulkUpsertAssetCriticalityRecordsRequestBody = lazySchema(() => + z.object({ + records: z + .array( + AssetCriticalityRecordIdParts.merge( + z.object({ + criticality_level: AssetCriticalityLevelsForBulkUpload, + }) + ) + ) + .min(1) + .max(1000), + }) +); export type BulkUpsertAssetCriticalityRecordsRequestBody = z.infer< typeof BulkUpsertAssetCriticalityRecordsRequestBody >; -export const BulkUpsertAssetCriticalityRecordsRequestBody = z.object({ - records: z - .array( - AssetCriticalityRecordIdParts.extend( - z.object({ - criticality_level: AssetCriticalityLevelsForBulkUpload, - }) - ) - ) - .min(1) - .max(1000), -}); export type BulkUpsertAssetCriticalityRecordsRequestBodyInput = z.input< typeof BulkUpsertAssetCriticalityRecordsRequestBody >; +export const BulkUpsertAssetCriticalityRecordsResponse = lazySchema(() => + z.object({ + errors: z.array(AssetCriticalityBulkUploadErrorItem), + stats: AssetCriticalityBulkUploadStats, + }) +); export type BulkUpsertAssetCriticalityRecordsResponse = z.infer< typeof BulkUpsertAssetCriticalityRecordsResponse >; -export const BulkUpsertAssetCriticalityRecordsResponse = z.object({ - errors: z.array(AssetCriticalityBulkUploadErrorItem), - stats: AssetCriticalityBulkUploadStats, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts index 4c5f3c3f8fd94..04c613c789d8a 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/common.gen.ts @@ -14,100 +14,105 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const IdField = lazySchema(() => + z.enum(['host.name', 'user.name', 'service.name', 'entity.id']) +); export type IdField = z.infer; -export const IdField = z.enum(['host.name', 'user.name', 'service.name', 'entity.id']); export type IdFieldEnum = typeof IdField.enum; export const IdFieldEnum = IdField.enum; +export const AssetCriticalityRecordIdParts = lazySchema(() => + z.object({ + /** + * The ID value of the asset. + */ + id_value: z.string(), + /** + * The field representing the ID. + */ + id_field: IdField, + }) +); export type AssetCriticalityRecordIdParts = z.infer; -export const AssetCriticalityRecordIdParts = z.object({ - /** - * The ID value of the asset. - */ - id_value: z.string(), - /** - * The field representing the ID. - */ - id_field: IdField, -}); /** * The criticality level of the asset. */ +export const AssetCriticalityLevel = lazySchema(() => + z.enum(['low_impact', 'medium_impact', 'high_impact', 'extreme_impact']) +); export type AssetCriticalityLevel = z.infer; -export const AssetCriticalityLevel = z.enum([ - 'low_impact', - 'medium_impact', - 'high_impact', - 'extreme_impact', -]); export type AssetCriticalityLevelEnum = typeof AssetCriticalityLevel.enum; export const AssetCriticalityLevelEnum = AssetCriticalityLevel.enum; +export const CreateAssetCriticalityRecord = lazySchema(() => + AssetCriticalityRecordIdParts.merge( + z.object({ + criticality_level: AssetCriticalityLevel, + }) + ) +); export type CreateAssetCriticalityRecord = z.infer; -export const CreateAssetCriticalityRecord = AssetCriticalityRecordIdParts.extend( + +export const AssetCriticalityRecordEcsParts = lazySchema(() => z.object({ - criticality_level: AssetCriticalityLevel, + asset: z.object({ + criticality: AssetCriticalityLevel.optional(), + }), + host: z + .object({ + name: z.string(), + asset: z + .object({ + criticality: AssetCriticalityLevel, + }) + .optional(), + }) + .optional(), + user: z + .object({ + name: z.string(), + asset: z + .object({ + criticality: AssetCriticalityLevel, + }) + .optional(), + }) + .optional(), + service: z + .object({ + name: z.string(), + asset: z + .object({ + criticality: AssetCriticalityLevel, + }) + .optional(), + }) + .optional(), + entity: z + .object({ + id: z.string(), + asset: z + .object({ + criticality: AssetCriticalityLevel, + }) + .optional(), + }) + .optional(), }) ); - export type AssetCriticalityRecordEcsParts = z.infer; -export const AssetCriticalityRecordEcsParts = z.object({ - asset: z.object({ - criticality: AssetCriticalityLevel.optional(), - }), - host: z - .object({ - name: z.string(), - asset: z - .object({ - criticality: AssetCriticalityLevel, - }) - .optional(), - }) - .optional(), - user: z - .object({ - name: z.string(), - asset: z - .object({ - criticality: AssetCriticalityLevel, - }) - .optional(), - }) - .optional(), - service: z - .object({ - name: z.string(), - asset: z - .object({ - criticality: AssetCriticalityLevel, - }) - .optional(), - }) - .optional(), - entity: z - .object({ - id: z.string(), - asset: z - .object({ - criticality: AssetCriticalityLevel, - }) - .optional(), - }) - .optional(), -}); -export type AssetCriticalityRecord = z.infer; -export const AssetCriticalityRecord = CreateAssetCriticalityRecord.extend( - AssetCriticalityRecordEcsParts -).extend( - z.object({ - /** - * The time the record was created or updated. - */ - '@timestamp': z.string().datetime(), - }) +export const AssetCriticalityRecord = lazySchema(() => + CreateAssetCriticalityRecord.merge(AssetCriticalityRecordEcsParts).merge( + z.object({ + /** + * The time the record was created or updated. + */ + '@timestamp': z.string().datetime(), + }) + ) ); +export type AssetCriticalityRecord = z.infer; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts index cda379daabd0d..1643975130939 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen.ts @@ -14,26 +14,28 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { CreateAssetCriticalityRecord, AssetCriticalityRecord } from './common.gen'; +export const CreateAssetCriticalityRecordRequestBody = lazySchema(() => + CreateAssetCriticalityRecord.merge( + z.object({ + /** + * If 'wait_for' the request will wait for the index refresh. + */ + refresh: z.literal('wait_for').optional(), + }) + ) +); export type CreateAssetCriticalityRecordRequestBody = z.infer< typeof CreateAssetCriticalityRecordRequestBody >; -export const CreateAssetCriticalityRecordRequestBody = CreateAssetCriticalityRecord.extend( - z.object({ - /** - * If 'wait_for' the request will wait for the index refresh. - */ - refresh: z.literal('wait_for').optional(), - }) -); export type CreateAssetCriticalityRecordRequestBodyInput = z.input< typeof CreateAssetCriticalityRecordRequestBody >; +export const CreateAssetCriticalityRecordResponse = lazySchema(() => AssetCriticalityRecord); export type CreateAssetCriticalityRecordResponse = z.infer< typeof CreateAssetCriticalityRecordResponse >; -export const CreateAssetCriticalityRecordResponse = AssetCriticalityRecord; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/delete_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/delete_asset_criticality.gen.ts index f8fac545f5507..9746427c4fc6c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/delete_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/delete_asset_criticality.gen.ts @@ -14,41 +14,45 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { IdField, AssetCriticalityRecord } from './common.gen'; +export const DeleteAssetCriticalityRecordRequestQuery = lazySchema(() => + z.object({ + /** + * The ID value of the asset. + */ + id_value: z.string(), + /** + * The field representing the ID. + */ + id_field: IdField, + /** + * If 'wait_for' the request will wait for the index refresh. + */ + refresh: z.literal('wait_for').optional(), + }) +); export type DeleteAssetCriticalityRecordRequestQuery = z.infer< typeof DeleteAssetCriticalityRecordRequestQuery >; -export const DeleteAssetCriticalityRecordRequestQuery = z.object({ - /** - * The ID value of the asset. - */ - id_value: z.string(), - /** - * The field representing the ID. - */ - id_field: IdField, - /** - * If 'wait_for' the request will wait for the index refresh. - */ - refresh: z.literal('wait_for').optional(), -}); export type DeleteAssetCriticalityRecordRequestQueryInput = z.input< typeof DeleteAssetCriticalityRecordRequestQuery >; +export const DeleteAssetCriticalityRecordResponse = lazySchema(() => + z.object({ + /** + * True if the record was deleted or false if the record did not exist. + */ + deleted: z.boolean(), + /** + * The deleted record if it existed. + */ + record: AssetCriticalityRecord.optional(), + }) +); export type DeleteAssetCriticalityRecordResponse = z.infer< typeof DeleteAssetCriticalityRecordResponse >; -export const DeleteAssetCriticalityRecordResponse = z.object({ - /** - * True if the record was deleted or false if the record did not exist. - */ - deleted: z.boolean(), - /** - * The deleted record if it existed. - */ - record: AssetCriticalityRecord.optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality.gen.ts index 5ab974603ed8f..47dc90cd18e63 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality.gen.ts @@ -14,26 +14,28 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { IdField, AssetCriticalityRecord } from './common.gen'; +export const GetAssetCriticalityRecordRequestQuery = lazySchema(() => + z.object({ + /** + * The ID value of the asset. + */ + id_value: z.string(), + /** + * The field representing the ID. + */ + id_field: IdField, + }) +); export type GetAssetCriticalityRecordRequestQuery = z.infer< typeof GetAssetCriticalityRecordRequestQuery >; -export const GetAssetCriticalityRecordRequestQuery = z.object({ - /** - * The ID value of the asset. - */ - id_value: z.string(), - /** - * The field representing the ID. - */ - id_field: IdField, -}); export type GetAssetCriticalityRecordRequestQueryInput = z.input< typeof GetAssetCriticalityRecordRequestQuery >; +export const GetAssetCriticalityRecordResponse = lazySchema(() => AssetCriticalityRecord); export type GetAssetCriticalityRecordResponse = z.infer; -export const GetAssetCriticalityRecordResponse = AssetCriticalityRecord; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_privileges.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_privileges.gen.ts index 9cb1ad1706580..cdcf76a6cb735 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_privileges.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_privileges.gen.ts @@ -15,10 +15,11 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { EntityAnalyticsPrivileges } from '../common/common.gen'; +export const AssetCriticalityGetPrivilegesResponse = lazySchema(() => EntityAnalyticsPrivileges); export type AssetCriticalityGetPrivilegesResponse = z.infer< typeof AssetCriticalityGetPrivilegesResponse >; -export const AssetCriticalityGetPrivilegesResponse = EntityAnalyticsPrivileges; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_status.gen.ts index 00af420072f02..5abfd1795ede7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/get_asset_criticality_status.gen.ts @@ -14,9 +14,11 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const GetAssetCriticalityStatusResponse = lazySchema(() => + z.object({ + asset_criticality_resources_installed: z.boolean().optional(), + }) +); export type GetAssetCriticalityStatusResponse = z.infer; -export const GetAssetCriticalityStatusResponse = z.object({ - asset_criticality_resources_installed: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/list_asset_criticality.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/list_asset_criticality.gen.ts index 5b508aa12e4e8..1d4ec56b77162 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/list_asset_criticality.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/list_asset_criticality.gen.ts @@ -14,45 +14,49 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AssetCriticalityRecord } from './common.gen'; +export const FindAssetCriticalityRecordsRequestQuery = lazySchema(() => + z.object({ + /** + * The field to sort by. + */ + sort_field: z.enum(['id_value', 'id_field', 'criticality_level', '@timestamp']).optional(), + /** + * The order to sort by. + */ + sort_direction: z.enum(['asc', 'desc']).optional(), + /** + * The page number to return. + */ + page: z.coerce.number().int().min(1).optional(), + /** + * The number of records to return per page. + */ + per_page: z.coerce.number().int().min(1).max(1000).optional(), + /** + * The kuery to filter by. + */ + kuery: z.string().optional(), + }) +); export type FindAssetCriticalityRecordsRequestQuery = z.infer< typeof FindAssetCriticalityRecordsRequestQuery >; -export const FindAssetCriticalityRecordsRequestQuery = z.object({ - /** - * The field to sort by. - */ - sort_field: z.enum(['id_value', 'id_field', 'criticality_level', '@timestamp']).optional(), - /** - * The order to sort by. - */ - sort_direction: z.enum(['asc', 'desc']).optional(), - /** - * The page number to return. - */ - page: z.coerce.number().int().min(1).optional(), - /** - * The number of records to return per page. - */ - per_page: z.coerce.number().int().min(1).max(1000).optional(), - /** - * The kuery to filter by. - */ - kuery: z.string().optional(), -}); export type FindAssetCriticalityRecordsRequestQueryInput = z.input< typeof FindAssetCriticalityRecordsRequestQuery >; +export const FindAssetCriticalityRecordsResponse = lazySchema(() => + z.object({ + records: z.array(AssetCriticalityRecord), + page: z.number().int().min(1), + per_page: z.number().int().min(1).max(1000), + total: z.number().int().min(0), + }) +); export type FindAssetCriticalityRecordsResponse = z.infer< typeof FindAssetCriticalityRecordsResponse >; -export const FindAssetCriticalityRecordsResponse = z.object({ - records: z.array(AssetCriticalityRecord), - page: z.number().int().min(1), - per_page: z.number().int().min(1).max(1000), - total: z.number().int().min(0), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/upload_asset_criticality_csv.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/upload_asset_criticality_csv.gen.ts index 7b8a76f23f1e2..56b801c66e650 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/upload_asset_criticality_csv.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/asset_criticality/upload_asset_criticality_csv.gen.ts @@ -14,45 +14,55 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const AssetCriticalityCsvUploadErrorItem = lazySchema(() => + z.object({ + message: z.string(), + index: z.number().int(), + }) +); export type AssetCriticalityCsvUploadErrorItem = z.infer; -export const AssetCriticalityCsvUploadErrorItem = z.object({ - message: z.string(), - index: z.number().int(), -}); +export const AssetCriticalityCsvUploadStats = lazySchema(() => + z.object({ + successful: z.number().int(), + failed: z.number().int(), + total: z.number().int(), + }) +); export type AssetCriticalityCsvUploadStats = z.infer; -export const AssetCriticalityCsvUploadStats = z.object({ - successful: z.number().int(), - failed: z.number().int(), - total: z.number().int(), -}); +export const AssetCriticalityCsvUploadV2ResponseItem = lazySchema(() => + z.object({ + status: z.enum(['success', 'failure', 'unmatched']), + matchedEntities: z.number().int(), + error: z.string().optional(), + }) +); export type AssetCriticalityCsvUploadV2ResponseItem = z.infer< typeof AssetCriticalityCsvUploadV2ResponseItem >; -export const AssetCriticalityCsvUploadV2ResponseItem = z.object({ - status: z.enum(['success', 'failure', 'unmatched']), - matchedEntities: z.number().int(), - error: z.string().optional(), -}); +export const InternalUploadAssetCriticalityV2CsvResponse = lazySchema(() => + z.object({ + successful: z.number().int(), + failed: z.number().int(), + total: z.number().int(), + unmatched: z.number().int(), + items: z.array(AssetCriticalityCsvUploadV2ResponseItem), + }) +); export type InternalUploadAssetCriticalityV2CsvResponse = z.infer< typeof InternalUploadAssetCriticalityV2CsvResponse >; -export const InternalUploadAssetCriticalityV2CsvResponse = z.object({ - successful: z.number().int(), - failed: z.number().int(), - total: z.number().int(), - unmatched: z.number().int(), - items: z.array(AssetCriticalityCsvUploadV2ResponseItem), -}); +export const UploadAssetCriticalityRecordsResponse = lazySchema(() => + z.object({ + errors: z.array(AssetCriticalityCsvUploadErrorItem), + stats: AssetCriticalityCsvUploadStats, + }) +); export type UploadAssetCriticalityRecordsResponse = z.infer< typeof UploadAssetCriticalityRecordsResponse >; -export const UploadAssetCriticalityRecordsResponse = z.object({ - errors: z.array(AssetCriticalityCsvUploadErrorItem), - stats: AssetCriticalityCsvUploadStats, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts index 89af54f49cb7d..48331795d8ffd 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts @@ -14,223 +14,239 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AssetCriticalityLevel } from '../asset_criticality/common.gen'; -export type EntityAnalyticsPrivileges = z.infer; -export const EntityAnalyticsPrivileges = z.object({ - has_all_required: z.boolean(), - has_read_permissions: z.boolean().optional(), - has_write_permissions: z.boolean().optional(), - privileges: z.object({ - elasticsearch: z.object({ - cluster: z.object({}).catchall(z.boolean()).optional(), - index: z.object({}).catchall(z.object({}).catchall(z.boolean())).optional(), +export const EntityAnalyticsPrivileges = lazySchema(() => + z.object({ + has_all_required: z.boolean(), + has_read_permissions: z.boolean().optional(), + has_write_permissions: z.boolean().optional(), + privileges: z.object({ + elasticsearch: z.object({ + cluster: z.object({}).catchall(z.boolean()).optional(), + index: z.object({}).catchall(z.object({}).catchall(z.boolean())).optional(), + }), + kibana: z.object({}).catchall(z.boolean()).optional(), }), - kibana: z.object({}).catchall(z.boolean()).optional(), - }), -}); + }) +); +export type EntityAnalyticsPrivileges = z.infer; +export const EntityAfterKey = lazySchema(() => z.object({}).catchall(z.string())); export type EntityAfterKey = z.infer; -export const EntityAfterKey = z.object({}).catchall(z.string()); +export const AfterKeys = lazySchema(() => + z.object({ + host: EntityAfterKey.optional(), + user: EntityAfterKey.optional(), + service: EntityAfterKey.optional(), + generic: EntityAfterKey.optional(), + }) +); export type AfterKeys = z.infer; -export const AfterKeys = z.object({ - host: EntityAfterKey.optional(), - user: EntityAfterKey.optional(), - service: EntityAfterKey.optional(), - generic: EntityAfterKey.optional(), -}); /** * The identifier of the Kibana data view to be used when generating risk scores. */ +export const DataViewId = lazySchema(() => z.string()); export type DataViewId = z.infer; -export const DataViewId = z.string(); /** * An elasticsearch DSL filter object. Used to filter the risk inputs involved, which implicitly filters the risk scores themselves. */ +export const Filter = lazySchema(() => z.object({}).catchall(z.unknown())); export type Filter = z.infer; -export const Filter = z.object({}).catchall(z.unknown()); /** * Specifies how many scores will be involved in a given calculation. Note that this value is per `identifier_type`, i.e. a value of 10 will calculate 10 host scores and 10 user scores, if available. To avoid missed data, keep this value consistent while paginating through scores. */ +export const PageSize = lazySchema(() => z.number().default(1000)); export type PageSize = z.infer; -export const PageSize = z.number().default(1000); +export const KibanaDate = lazySchema(() => z.string()); export type KibanaDate = z.infer; -export const KibanaDate = z.string(); /** * Defines the time period on which risk inputs will be filtered. */ +export const DateRange = lazySchema(() => + z.object({ + start: KibanaDate, + end: KibanaDate, + }) +); export type DateRange = z.infer; -export const DateRange = z.object({ - start: KibanaDate, - end: KibanaDate, -}); +export const IdentifierType = lazySchema(() => z.enum(['host', 'user', 'service', 'generic'])); export type IdentifierType = z.infer; -export const IdentifierType = z.enum(['host', 'user', 'service', 'generic']); export type IdentifierTypeEnum = typeof IdentifierType.enum; export const IdentifierTypeEnum = IdentifierType.enum; /** * A generic representation of a document contributing to a Risk Score. */ +export const RiskScoreInput = lazySchema(() => + z.object({ + /** + * The unique identifier (`_id`) of the original source document + */ + id: z.string(), + /** + * The unique index (`_index`) of the original source document + */ + index: z.string(), + /** + * The risk category of the risk input document. + */ + category: z.string(), + /** + * A human-readable description of the risk input document. + */ + description: z.string(), + /** + * The weighted risk score of the risk input document. + */ + risk_score: z.number().min(0).max(100).optional(), + /** + * The @timestamp of the risk input document. + */ + timestamp: z.string().optional(), + contribution_score: z.number().optional(), + /** + * The EUID of the entity within the graph that generated this alert. + */ + entity_id: z.string().optional(), + }) +); export type RiskScoreInput = z.infer; -export const RiskScoreInput = z.object({ - /** - * The unique identifier (`_id`) of the original source document - */ - id: z.string(), - /** - * The unique index (`_index`) of the original source document - */ - index: z.string(), - /** - * The risk category of the risk input document. - */ - category: z.string(), - /** - * A human-readable description of the risk input document. - */ - description: z.string(), - /** - * The weighted risk score of the risk input document. - */ - risk_score: z.number().min(0).max(100).optional(), - /** - * The @timestamp of the risk input document. - */ - timestamp: z.string().optional(), - contribution_score: z.number().optional(), - /** - * The EUID of the entity within the graph that generated this alert. - */ - entity_id: z.string().optional(), -}); +export const RiskScoreCategories = lazySchema(() => z.literal('category_1')); export type RiskScoreCategories = z.infer; -export const RiskScoreCategories = z.literal('category_1'); +export const EntityRiskLevels = lazySchema(() => + z.enum(['Unknown', 'Low', 'Moderate', 'High', 'Critical']) +); export type EntityRiskLevels = z.infer; -export const EntityRiskLevels = z.enum(['Unknown', 'Low', 'Moderate', 'High', 'Critical']); export type EntityRiskLevelsEnum = typeof EntityRiskLevels.enum; export const EntityRiskLevelsEnum = EntityRiskLevels.enum; +export const EntityRiskScoreRecord = lazySchema(() => + z.object({ + /** + * The time at which the risk score was calculated. + */ + '@timestamp': z.string().datetime(), + /** + * The identifier field defining this risk score. Coupled with `id_value`, uniquely identifies the entity being scored. + */ + id_field: z.string(), + /** + * The identifier value defining this risk score. Coupled with `id_field`, uniquely identifies the entity being scored. + */ + id_value: z.string(), + /** + * Unique identifier for the scoring run that produced this document. + */ + calculation_run_id: z.string().optional(), + /** + * Lexical description of the entity's risk. + */ + calculated_level: EntityRiskLevels, + /** + * The raw numeric value of the given entity's risk score. + */ + calculated_score: z.number(), + /** + * The normalized numeric value of the given entity's risk score. Useful for comparing with other entities. + */ + calculated_score_norm: z.number().min(0).max(100), + /** + * The contribution of Category 1 to the overall risk score (`calculated_score`). Category 1 contains Detection Engine Alerts. + */ + category_1_score: z.number(), + /** + * The number of risk input documents that contributed to the Category 1 score (`category_1_score`). + */ + category_1_count: z.number().int(), + /** + * A list of the highest-risk documents contributing to this risk score. Useful for investigative purposes. + */ + inputs: z.array(RiskScoreInput), + category_2_score: z.number().optional(), + category_2_count: z.number().int().optional(), + notes: z.array(z.string()), + criticality_modifier: z.number().optional(), + criticality_level: AssetCriticalityLevel.optional(), + /** + * A list of modifiers that were applied to the risk score calculation. + */ + modifiers: z + .array( + z.object({ + type: z.string(), + subtype: z.string().optional(), + modifier_value: z.number().optional(), + contribution: z.number(), + metadata: z.object({}).catchall(z.unknown()).optional(), + }) + ) + .optional(), + /** + * Distinguishes base, propagated, and resolution scores. + */ + score_type: z.enum(['base', 'propagated', 'resolution']).optional(), + related_entities: z + .array( + z.object({ + entity_id: z.string().optional(), + relationship_type: z.string().optional(), + }) + ) + .optional(), + }) +); export type EntityRiskScoreRecord = z.infer; -export const EntityRiskScoreRecord = z.object({ - /** - * The time at which the risk score was calculated. - */ - '@timestamp': z.string().datetime(), - /** - * The identifier field defining this risk score. Coupled with `id_value`, uniquely identifies the entity being scored. - */ - id_field: z.string(), - /** - * The identifier value defining this risk score. Coupled with `id_field`, uniquely identifies the entity being scored. - */ - id_value: z.string(), - /** - * Unique identifier for the scoring run that produced this document. - */ - calculation_run_id: z.string().optional(), - /** - * Lexical description of the entity's risk. - */ - calculated_level: EntityRiskLevels, - /** - * The raw numeric value of the given entity's risk score. - */ - calculated_score: z.number(), - /** - * The normalized numeric value of the given entity's risk score. Useful for comparing with other entities. - */ - calculated_score_norm: z.number().min(0).max(100), - /** - * The contribution of Category 1 to the overall risk score (`calculated_score`). Category 1 contains Detection Engine Alerts. - */ - category_1_score: z.number(), - /** - * The number of risk input documents that contributed to the Category 1 score (`category_1_score`). - */ - category_1_count: z.number().int(), - /** - * A list of the highest-risk documents contributing to this risk score. Useful for investigative purposes. - */ - inputs: z.array(RiskScoreInput), - category_2_score: z.number().optional(), - category_2_count: z.number().int().optional(), - notes: z.array(z.string()), - criticality_modifier: z.number().optional(), - criticality_level: AssetCriticalityLevel.optional(), - /** - * A list of modifiers that were applied to the risk score calculation. - */ - modifiers: z - .array( - z.object({ - type: z.string(), - subtype: z.string().optional(), - modifier_value: z.number().optional(), - contribution: z.number(), - metadata: z.object({}).catchall(z.unknown()).optional(), - }) - ) - .optional(), - /** - * Distinguishes base, propagated, and resolution scores. - */ - score_type: z.enum(['base', 'propagated', 'resolution']).optional(), - related_entities: z - .array( - z.object({ - entity_id: z.string().optional(), - relationship_type: z.string().optional(), - }) - ) - .optional(), -}); +export const RiskScoreEntityIdentifierWeights = lazySchema(() => z.number().min(0).max(1)); export type RiskScoreEntityIdentifierWeights = z.infer; -export const RiskScoreEntityIdentifierWeights = z.number().min(0).max(1); +export const RiskScoreWeightGlobalShared = lazySchema(() => + z.object({ + type: z.literal('global_identifier'), + }) +); export type RiskScoreWeightGlobalShared = z.infer; -export const RiskScoreWeightGlobalShared = z.object({ - type: z.literal('global_identifier'), -}); - -export const RiskScoreWeightInternal = z.union([ - RiskScoreWeightGlobalShared.extend( - z.object({ - host: RiskScoreEntityIdentifierWeights, - user: RiskScoreEntityIdentifierWeights.optional(), - service: RiskScoreEntityIdentifierWeights.optional(), - generic: RiskScoreEntityIdentifierWeights.optional(), - }) - ), - RiskScoreWeightGlobalShared.extend( - z.object({ - host: RiskScoreEntityIdentifierWeights.optional(), - user: RiskScoreEntityIdentifierWeights, - service: RiskScoreEntityIdentifierWeights.optional(), - generic: RiskScoreEntityIdentifierWeights.optional(), - }) - ), - RiskScoreWeightGlobalShared.extend( - z.object({ - host: RiskScoreEntityIdentifierWeights.optional(), - user: RiskScoreEntityIdentifierWeights.optional(), - service: RiskScoreEntityIdentifierWeights, - generic: RiskScoreEntityIdentifierWeights.optional(), - }) - ), -]); + +export const RiskScoreWeightInternal = lazySchema(() => + z.union([ + RiskScoreWeightGlobalShared.merge( + z.object({ + host: RiskScoreEntityIdentifierWeights, + user: RiskScoreEntityIdentifierWeights.optional(), + service: RiskScoreEntityIdentifierWeights.optional(), + generic: RiskScoreEntityIdentifierWeights.optional(), + }) + ), + RiskScoreWeightGlobalShared.merge( + z.object({ + host: RiskScoreEntityIdentifierWeights.optional(), + user: RiskScoreEntityIdentifierWeights, + service: RiskScoreEntityIdentifierWeights.optional(), + generic: RiskScoreEntityIdentifierWeights.optional(), + }) + ), + RiskScoreWeightGlobalShared.merge( + z.object({ + host: RiskScoreEntityIdentifierWeights.optional(), + user: RiskScoreEntityIdentifierWeights.optional(), + service: RiskScoreEntityIdentifierWeights, + generic: RiskScoreEntityIdentifierWeights.optional(), + }) + ), + ]) +); export type RiskScoreWeight = z.infer; export const RiskScoreWeight = RiskScoreWeightInternal as z.ZodType; @@ -238,14 +254,16 @@ export const RiskScoreWeight = RiskScoreWeightInternal as z.ZodType z.array(RiskScoreWeight)); export type RiskScoreWeights = z.infer; -export const RiskScoreWeights = z.array(RiskScoreWeight); /** * Task manager is unavailable */ +export const TaskManagerUnavailableResponse = lazySchema(() => + z.object({ + status_code: z.number().int().min(400), + message: z.string(), + }) +); export type TaskManagerUnavailableResponse = z.infer; -export const TaskManagerUnavailableResponse = z.object({ - status_code: z.number().int().min(400), - message: z.string(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_details/highlights.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_details/highlights.gen.ts index 1789a94f60093..885c9aa915297 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_details/highlights.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_details/highlights.gen.ts @@ -14,52 +14,56 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AnonymizationFieldResponse } from '@kbn/elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen'; import { Replacements } from '@kbn/elastic-assistant-common/impl/schemas/conversations/common_attributes.gen'; import { EntityType } from '../entity_store/common.gen'; +export const EntityDetailsHighlightsRequestBody = lazySchema(() => + z.object({ + entityType: EntityType, + /** + * The identifier of the entity. + */ + entityIdentifier: z.string(), + anonymizationFields: z.array(AnonymizationFieldResponse), + /** + * The 'from' date. + */ + from: z.number(), + /** + * The 'to' date. + */ + to: z.number(), + /** + * The connector id. + */ + connectorId: z.string(), + }) +); export type EntityDetailsHighlightsRequestBody = z.infer; -export const EntityDetailsHighlightsRequestBody = z.object({ - entityType: EntityType, - /** - * The identifier of the entity. - */ - entityIdentifier: z.string(), - anonymizationFields: z.array(AnonymizationFieldResponse), - /** - * The 'from' date. - */ - from: z.number(), - /** - * The 'to' date. - */ - to: z.number(), - /** - * The connector id. - */ - connectorId: z.string(), -}); export type EntityDetailsHighlightsRequestBodyInput = z.input< typeof EntityDetailsHighlightsRequestBody >; +export const EntityDetailsHighlightsResponse = lazySchema(() => + z.object({ + /** + * The highlights of the entity. + */ + summary: z.object({ + assetCriticality: z.array(z.object({}).catchall(z.unknown())).optional(), + riskScore: z.array(z.object({}).catchall(z.unknown())).optional(), + vulnerabilities: z.array(z.object({}).catchall(z.unknown())).optional(), + vulnerabilitiesTotal: z.object({}).catchall(z.number()).optional(), + anomalies: z.array(z.object({}).catchall(z.unknown())).optional(), + }), + replacements: Replacements, + /** + * The prompt used to generate the highlights. + */ + prompt: z.string(), + }) +); export type EntityDetailsHighlightsResponse = z.infer; -export const EntityDetailsHighlightsResponse = z.object({ - /** - * The highlights of the entity. - */ - summary: z.object({ - assetCriticality: z.array(z.object({}).catchall(z.unknown())).optional(), - riskScore: z.array(z.object({}).catchall(z.unknown())).optional(), - vulnerabilities: z.array(z.object({}).catchall(z.unknown())).optional(), - vulnerabilitiesTotal: z.object({}).catchall(z.number()).optional(), - anomalies: z.array(z.object({}).catchall(z.unknown())).optional(), - }), - replacements: Replacements, - /** - * The prompt used to generate the highlights. - */ - prompt: z.string(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts index 21b0622ac71ae..f8eb7cf86cf9c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts @@ -14,272 +14,286 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The type of entity. */ +export const EntityType = lazySchema(() => z.enum(['user', 'host', 'service', 'generic'])); export type EntityType = z.infer; -export const EntityType = z.enum(['user', 'host', 'service', 'generic']); export type EntityTypeEnum = typeof EntityType.enum; export const EntityTypeEnum = EntityType.enum; /** * The top-level Elastic Common Schema (ECS) field group that the entity maps to. */ +export const BaseECSEntityField = lazySchema(() => z.enum(['user', 'host', 'service', 'entity'])); export type BaseECSEntityField = z.infer; -export const BaseECSEntityField = z.enum(['user', 'host', 'service', 'entity']); export type BaseECSEntityFieldEnum = typeof BaseECSEntityField.enum; export const BaseECSEntityFieldEnum = BaseECSEntityField.enum; /** * An additional Elasticsearch index pattern to include as a source for entity data. Merged with the default data view indices when the engine runs. */ +export const IndexPattern = lazySchema(() => z.string()); export type IndexPattern = z.infer; -export const IndexPattern = z.string(); /** * The current operational status of an entity engine. */ +export const EngineStatus = lazySchema(() => + z.enum(['installing', 'started', 'stopped', 'updating', 'error']) +); export type EngineStatus = z.infer; -export const EngineStatus = z.enum(['installing', 'started', 'stopped', 'updating', 'error']); export type EngineStatusEnum = typeof EngineStatus.enum; export const EngineStatusEnum = EngineStatus.enum; /** * Describes a single entity engine, including its configuration and current status. */ +export const EngineDescriptor = lazySchema(() => + z.object({ + type: EntityType, + indexPattern: IndexPattern, + status: EngineStatus, + /** + * An optional Kibana Query Language (KQL) filter applied to source documents before aggregation. + */ + filter: z.string().optional(), + /** + * The number of historical values retained per field. + */ + fieldHistoryLength: z.number().int(), + /** + * How far back the transform looks when calculating aggregations. + */ + lookbackPeriod: z + .string() + .regex(/[smdh]$/) + .optional() + .default('24h'), + /** + * The field used as the timestamp for source documents. + */ + timestampField: z.string().optional(), + /** + * The timeout for initializing the aggregating transform. + */ + timeout: z + .string() + .regex(/[smdh]$/) + .optional() + .default('180s'), + /** + * How often the transform runs. + */ + frequency: z + .string() + .regex(/[smdh]$/) + .optional() + .default('1m'), + /** + * The delay before the transform processes new data, allowing late-arriving documents to be included. + */ + delay: z + .string() + .regex(/[smdh]$/) + .optional() + .default('1m'), + /** + * Throttle value for the number of documents processed per second. Use -1 for no throttle. + */ + docsPerSecond: z.number().int().optional(), + /** + * Present when the engine status is `error`. Describes the failure. + */ + error: z + .object({ + /** + * A human-readable error message. + */ + message: z.string(), + /** + * The lifecycle action that caused the error. + */ + action: z.literal('init'), + }) + .optional(), + }) +); export type EngineDescriptor = z.infer; -export const EngineDescriptor = z.object({ - type: EntityType, - indexPattern: IndexPattern, - status: EngineStatus, - /** - * An optional Kibana Query Language (KQL) filter applied to source documents before aggregation. - */ - filter: z.string().optional(), - /** - * The number of historical values retained per field. - */ - fieldHistoryLength: z.number().int(), - /** - * How far back the transform looks when calculating aggregations. - */ - lookbackPeriod: z - .string() - .regex(/[smdh]$/) - .optional() - .default('24h'), - /** - * The field used as the timestamp for source documents. - */ - timestampField: z.string().optional(), - /** - * The timeout for initializing the aggregating transform. - */ - timeout: z - .string() - .regex(/[smdh]$/) - .optional() - .default('180s'), - /** - * How often the transform runs. - */ - frequency: z - .string() - .regex(/[smdh]$/) - .optional() - .default('1m'), - /** - * The delay before the transform processes new data, allowing late-arriving documents to be included. - */ - delay: z - .string() - .regex(/[smdh]$/) - .optional() - .default('1m'), - /** - * Throttle value for the number of documents processed per second. Use -1 for no throttle. - */ - docsPerSecond: z.number().int().optional(), - /** - * Present when the engine status is `error`. Describes the failure. - */ - error: z - .object({ - /** - * A human-readable error message. - */ - message: z.string(), - /** - * The lifecycle action that caused the error. - */ - action: z.literal('init'), - }) - .optional(), -}); /** * Statistics from the underlying Elasticsearch transform. */ +export const TransformStatsMetadata = lazySchema(() => + z.object({ + /** + * Number of composite aggregation pages processed. + */ + pages_processed: z.number().int(), + /** + * Total number of source documents processed. + */ + documents_processed: z.number().int(), + /** + * Total number of documents written to the destination index. + */ + documents_indexed: z.number().int(), + /** + * Total number of documents deleted from the destination index. + */ + documents_deleted: z.number().int().optional(), + /** + * Number of times the transform has been triggered. + */ + trigger_count: z.number().int(), + /** + * Total time spent indexing documents, in milliseconds. + */ + index_time_in_ms: z.number().int(), + /** + * Total number of index operations. + */ + index_total: z.number().int(), + /** + * Total number of failed index operations. + */ + index_failures: z.number().int(), + /** + * Total time spent on search queries, in milliseconds. + */ + search_time_in_ms: z.number().int(), + /** + * Total number of search operations. + */ + search_total: z.number().int(), + /** + * Total number of failed search operations. + */ + search_failures: z.number().int(), + /** + * Total time spent processing results, in milliseconds. + */ + processing_time_in_ms: z.number().int(), + /** + * Total number of processing operations. + */ + processing_total: z.number().int(), + /** + * Total time spent deleting documents, in milliseconds. + */ + delete_time_in_ms: z.number().int().optional(), + /** + * Exponential moving average of checkpoint duration, in milliseconds. + */ + exponential_avg_checkpoint_duration_ms: z.number().int(), + /** + * Exponential moving average of documents indexed per checkpoint. + */ + exponential_avg_documents_indexed: z.number().int(), + /** + * Exponential moving average of documents processed per checkpoint. + */ + exponential_avg_documents_processed: z.number().int(), + }) +); export type TransformStatsMetadata = z.infer; -export const TransformStatsMetadata = z.object({ - /** - * Number of composite aggregation pages processed. - */ - pages_processed: z.number().int(), - /** - * Total number of source documents processed. - */ - documents_processed: z.number().int(), - /** - * Total number of documents written to the destination index. - */ - documents_indexed: z.number().int(), - /** - * Total number of documents deleted from the destination index. - */ - documents_deleted: z.number().int().optional(), - /** - * Number of times the transform has been triggered. - */ - trigger_count: z.number().int(), - /** - * Total time spent indexing documents, in milliseconds. - */ - index_time_in_ms: z.number().int(), - /** - * Total number of index operations. - */ - index_total: z.number().int(), - /** - * Total number of failed index operations. - */ - index_failures: z.number().int(), - /** - * Total time spent on search queries, in milliseconds. - */ - search_time_in_ms: z.number().int(), - /** - * Total number of search operations. - */ - search_total: z.number().int(), - /** - * Total number of failed search operations. - */ - search_failures: z.number().int(), - /** - * Total time spent processing results, in milliseconds. - */ - processing_time_in_ms: z.number().int(), - /** - * Total number of processing operations. - */ - processing_total: z.number().int(), - /** - * Total time spent deleting documents, in milliseconds. - */ - delete_time_in_ms: z.number().int().optional(), - /** - * Exponential moving average of checkpoint duration, in milliseconds. - */ - exponential_avg_checkpoint_duration_ms: z.number().int(), - /** - * Exponential moving average of documents indexed per checkpoint. - */ - exponential_avg_documents_indexed: z.number().int(), - /** - * Exponential moving average of documents processed per checkpoint. - */ - exponential_avg_documents_processed: z.number().int(), -}); +export const Metadata = lazySchema(() => TransformStatsMetadata); export type Metadata = z.infer; -export const Metadata = TransformStatsMetadata; /** * The type of Elasticsearch or Kibana resource backing an engine component. */ +export const EngineComponentResource = lazySchema(() => + z.enum([ + 'entity_engine', + 'entity_definition', + 'index', + 'data_stream', + 'component_template', + 'index_template', + 'ingest_pipeline', + 'enrich_policy', + 'task', + 'transform', + 'ilm_policy', + ]) +); export type EngineComponentResource = z.infer; -export const EngineComponentResource = z.enum([ - 'entity_engine', - 'entity_definition', - 'index', - 'data_stream', - 'component_template', - 'index_template', - 'ingest_pipeline', - 'enrich_policy', - 'task', - 'transform', - 'ilm_policy', -]); export type EngineComponentResourceEnum = typeof EngineComponentResource.enum; export const EngineComponentResourceEnum = EngineComponentResource.enum; /** * Status of an individual Elasticsearch or Kibana resource backing an engine. */ +export const EngineComponentStatus = lazySchema(() => + z.object({ + /** + * Unique identifier for the component. + */ + id: z.string(), + /** + * Whether the component is currently installed. + */ + installed: z.boolean(), + metadata: Metadata.optional(), + resource: EngineComponentResource, + /** + * The health status of the component. + */ + health: z.enum(['green', 'yellow', 'red', 'unavailable', 'unknown']).optional(), + /** + * Errors reported by this component, if any. + */ + errors: z + .array( + z.object({ + /** + * Short error title. + */ + title: z.string().optional(), + /** + * Detailed error message. + */ + message: z.string().optional(), + }) + ) + .optional(), + }) +); export type EngineComponentStatus = z.infer; -export const EngineComponentStatus = z.object({ - /** - * Unique identifier for the component. - */ - id: z.string(), - /** - * Whether the component is currently installed. - */ - installed: z.boolean(), - metadata: Metadata.optional(), - resource: EngineComponentResource, - /** - * The health status of the component. - */ - health: z.enum(['green', 'yellow', 'red', 'unavailable', 'unknown']).optional(), - /** - * Errors reported by this component, if any. - */ - errors: z - .array( - z.object({ - /** - * Short error title. - */ - title: z.string().optional(), - /** - * Detailed error message. - */ - message: z.string().optional(), - }) - ) - .optional(), -}); /** * The overall operational status of the Entity Store. */ +export const StoreStatus = lazySchema(() => + z.enum(['not_installed', 'installing', 'running', 'stopped', 'error']) +); export type StoreStatus = z.infer; -export const StoreStatus = z.enum(['not_installed', 'installing', 'running', 'stopped', 'error']); export type StoreStatusEnum = typeof StoreStatus.enum; export const StoreStatusEnum = StoreStatus.enum; /** * Debug information about the Elasticsearch query executed. */ +export const InspectQuery = lazySchema(() => + z.object({ + /** + * Raw Elasticsearch responses. + */ + response: z.array(z.string()), + /** + * Elasticsearch query DSL that was executed. + */ + dsl: z.array(z.string()), + }) +); export type InspectQuery = z.infer; -export const InspectQuery = z.object({ - /** - * Raw Elasticsearch responses. - */ - response: z.array(z.string()), - /** - * Elasticsearch query DSL that was executed. - */ - dsl: z.array(z.string()), -}); /** * Interval in which enrich policy runs. For example, `"1h"` means the rule runs every hour. Must be less than or equal to half the duration of the lookback period, */ +export const Interval = lazySchema(() => z.string().regex(/^[1-9]\d*[smh]$/)); export type Interval = z.infer; -export const Interval = z.string().regex(/^[1-9]\d*[smh]$/); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts index 9fcb28f77de13..ac8e6ff25892f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts @@ -14,75 +14,79 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { IndexPattern, EntityType, Interval, EngineDescriptor } from './common.gen'; +export const InitEntityStoreRequestBody = lazySchema(() => + z.object({ + /** + * The number of historical values to keep for each field. + */ + fieldHistoryLength: z.number().int().optional().default(10), + indexPattern: IndexPattern.optional(), + filter: z.string().optional(), + entityTypes: z.array(EntityType).optional(), + enrichPolicyExecutionInterval: Interval.optional(), + /** + * The field to use as the timestamp. + */ + timestampField: z.string().optional().default('@timestamp'), + /** + * The amount of time the transform looks back to calculate the aggregations. + */ + lookbackPeriod: z + .string() + .regex(/[smdh]$/) + .optional() + .default('3h'), + /** + * The timeout for initializing the aggregating transform. + */ + timeout: z + .string() + .regex(/[smdh]$/) + .optional() + .default('180s'), + /** + * The frequency at which the transform will run. + */ + frequency: z + .string() + .regex(/[smdh]$/) + .optional() + .default('1m'), + /** + * The delay before the transform will run. + */ + delay: z + .string() + .regex(/[smdh]$/) + .optional() + .default('1m'), + /** + * The number of documents per second to process. + */ + docsPerSecond: z.number().int().optional().default(-1), + /** + * The initial page size to use for the composite aggregation of each checkpoint. + */ + maxPageSearchSize: z.number().int().optional().default(500), + }) +); export type InitEntityStoreRequestBody = z.infer; -export const InitEntityStoreRequestBody = z.object({ - /** - * The number of historical values to keep for each field. - */ - fieldHistoryLength: z.number().int().optional().default(10), - indexPattern: IndexPattern.optional(), - filter: z.string().optional(), - entityTypes: z.array(EntityType).optional(), - enrichPolicyExecutionInterval: Interval.optional(), - /** - * The field to use as the timestamp. - */ - timestampField: z.string().optional().default('@timestamp'), - /** - * The amount of time the transform looks back to calculate the aggregations. - */ - lookbackPeriod: z - .string() - .regex(/[smdh]$/) - .optional() - .default('3h'), - /** - * The timeout for initializing the aggregating transform. - */ - timeout: z - .string() - .regex(/[smdh]$/) - .optional() - .default('180s'), - /** - * The frequency at which the transform will run. - */ - frequency: z - .string() - .regex(/[smdh]$/) - .optional() - .default('1m'), - /** - * The delay before the transform will run. - */ - delay: z - .string() - .regex(/[smdh]$/) - .optional() - .default('1m'), - /** - * The number of documents per second to process. - */ - docsPerSecond: z.number().int().optional().default(-1), - /** - * The initial page size to use for the composite aggregation of each checkpoint. - */ - maxPageSearchSize: z.number().int().optional().default(500), -}); export type InitEntityStoreRequestBodyInput = z.input; +export const InitEntityStoreResponse = lazySchema(() => + z.object({ + /** + * Whether the Entity Store was initialized successfully. + */ + succeeded: z.boolean().optional(), + /** + * The engine descriptors created during initialization. + */ + engines: z.array(EngineDescriptor).optional(), + }) +); export type InitEntityStoreResponse = z.infer; -export const InitEntityStoreResponse = z.object({ - /** - * Whether the Entity Store was initialized successfully. - */ - succeeded: z.boolean().optional(), - /** - * The engine descriptors created during initialization. - */ - engines: z.array(EngineDescriptor).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/apply_dataview_indices.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/apply_dataview_indices.gen.ts index 3f38a8099e091..846ed626ea947 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/apply_dataview_indices.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/apply_dataview_indices.gen.ts @@ -14,40 +14,44 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The result of applying data view index changes to a single engine. */ +export const EngineDataviewUpdateResult = lazySchema(() => + z.object({ + /** + * The entity type of the engine that was updated. + */ + type: z.string(), + /** + * The changes applied to the engine. + */ + changes: z + .object({ + /** + * The updated list of index patterns now used by the engine. + */ + indexPatterns: z.array(z.string()).optional(), + }) + .optional(), + }) +); export type EngineDataviewUpdateResult = z.infer; -export const EngineDataviewUpdateResult = z.object({ - /** - * The entity type of the engine that was updated. - */ - type: z.string(), - /** - * The changes applied to the engine. - */ - changes: z - .object({ - /** - * The updated list of index patterns now used by the engine. - */ - indexPatterns: z.array(z.string()).optional(), - }) - .optional(), -}); +export const ApplyEntityEngineDataviewIndicesResponse = lazySchema(() => + z.object({ + /** + * Whether all engines updated successfully. + */ + success: z.boolean().optional(), + /** + * Per-engine update results. + */ + result: z.array(EngineDataviewUpdateResult).optional(), + }) +); export type ApplyEntityEngineDataviewIndicesResponse = z.infer< typeof ApplyEntityEngineDataviewIndicesResponse >; -export const ApplyEntityEngineDataviewIndicesResponse = z.object({ - /** - * Whether all engines updated successfully. - */ - success: z.boolean().optional(), - /** - * Per-engine update results. - */ - result: z.array(EngineDataviewUpdateResult).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts index 9277d6d0f5baa..baa952e5852c6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts @@ -14,61 +14,71 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; import { EntityType } from '../common.gen'; +export const DeleteEntityEngineRequestQuery = lazySchema(() => + z.object({ + /** + * Control flag to also delete the entity data. + */ + delete_data: BooleanFromString.optional(), + /** + * Control flag to also delete the entity data. + */ + data: BooleanFromString.optional(), + }) +); export type DeleteEntityEngineRequestQuery = z.infer; -export const DeleteEntityEngineRequestQuery = z.object({ - /** - * Control flag to also delete the entity data. - */ - delete_data: BooleanFromString.optional(), - /** - * Control flag to also delete the entity data. - */ - data: BooleanFromString.optional(), -}); export type DeleteEntityEngineRequestQueryInput = z.input; +export const DeleteEntityEngineRequestParams = lazySchema(() => + z.object({ + /** + * The entity type of the engine (either 'user' or 'host'). + */ + entityType: EntityType, + }) +); export type DeleteEntityEngineRequestParams = z.infer; -export const DeleteEntityEngineRequestParams = z.object({ - /** - * The entity type of the engine (either 'user' or 'host'). - */ - entityType: EntityType, -}); export type DeleteEntityEngineRequestParamsInput = z.input; +export const DeleteEntityEngineResponse = lazySchema(() => + z.object({ + /** + * Whether the engine was successfully deleted. + */ + deleted: z.boolean().optional(), + }) +); export type DeleteEntityEngineResponse = z.infer; -export const DeleteEntityEngineResponse = z.object({ - /** - * Whether the engine was successfully deleted. - */ - deleted: z.boolean().optional(), -}); +export const DeleteEntityEnginesRequestQuery = lazySchema(() => + z.object({ + /** + * The entity type of the engine ('user', 'host', 'service', 'generic'). + */ + entityTypes: ArrayFromString(EntityType).optional(), + /** + * Control flag to also delete the entity data. + */ + delete_data: BooleanFromString.optional(), + }) +); export type DeleteEntityEnginesRequestQuery = z.infer; -export const DeleteEntityEnginesRequestQuery = z.object({ - /** - * The entity type of the engine ('user', 'host', 'service', 'generic'). - */ - entityTypes: ArrayFromString(EntityType).optional(), - /** - * Control flag to also delete the entity data. - */ - delete_data: BooleanFromString.optional(), -}); export type DeleteEntityEnginesRequestQueryInput = z.input; +export const DeleteEntityEnginesResponse = lazySchema(() => + z.object({ + /** + * Entity types whose engines were successfully deleted. + */ + deleted: z.array(EntityType).optional(), + /** + * Entity types whose engines are still running. + */ + still_running: z.array(EntityType).optional(), + }) +); export type DeleteEntityEnginesResponse = z.infer; -export const DeleteEntityEnginesResponse = z.object({ - /** - * Entity types whose engines were successfully deleted. - */ - deleted: z.array(EntityType).optional(), - /** - * Entity types whose engines are still running. - */ - still_running: z.array(EntityType).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts index f97b852955b7e..b6e2c7df4dbac 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts @@ -14,18 +14,20 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntityType, EngineDescriptor } from '../common.gen'; +export const GetEntityEngineRequestParams = lazySchema(() => + z.object({ + /** + * The entity type of the engine. + */ + entityType: EntityType, + }) +); export type GetEntityEngineRequestParams = z.infer; -export const GetEntityEngineRequestParams = z.object({ - /** - * The entity type of the engine. - */ - entityType: EntityType, -}); export type GetEntityEngineRequestParamsInput = z.input; +export const GetEntityEngineResponse = lazySchema(() => EngineDescriptor); export type GetEntityEngineResponse = z.infer; -export const GetEntityEngineResponse = EngineDescriptor; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get_privileges.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get_privileges.gen.ts index 077c1045ec0a9..9fa8c00d2957d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get_privileges.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get_privileges.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { EntityAnalyticsPrivileges } from '../../common/common.gen'; +export const EntityStoreGetPrivilegesResponse = lazySchema(() => EntityAnalyticsPrivileges); export type EntityStoreGetPrivilegesResponse = z.infer; -export const EntityStoreGetPrivilegesResponse = EntityAnalyticsPrivileges; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts index afb38e8e7b51d..cc0a34e70b693 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts @@ -14,74 +14,78 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntityType, IndexPattern, Interval, EngineDescriptor } from '../common.gen'; +export const InitEntityEngineRequestParams = lazySchema(() => + z.object({ + /** + * The entity type of the engine. + */ + entityType: EntityType, + }) +); export type InitEntityEngineRequestParams = z.infer; -export const InitEntityEngineRequestParams = z.object({ - /** - * The entity type of the engine. - */ - entityType: EntityType, -}); export type InitEntityEngineRequestParamsInput = z.input; +export const InitEntityEngineRequestBody = lazySchema(() => + z.object({ + /** + * The number of historical values to keep for each field. + */ + fieldHistoryLength: z.number().int().optional().default(10), + indexPattern: IndexPattern.optional(), + filter: z.string().optional(), + enrichPolicyExecutionInterval: Interval.optional(), + /** + * The field to use as the timestamp for the entity type. + */ + timestampField: z.string().optional().default('@timestamp'), + /** + * The amount of time the transform looks back to calculate the aggregations. + */ + lookbackPeriod: z + .string() + .regex(/[smdh]$/) + .optional() + .default('3h'), + /** + * The timeout for initializing the aggregating transform. + */ + timeout: z + .string() + .regex(/[smdh]$/) + .optional() + .default('180s'), + /** + * The frequency at which the transform will run. + */ + frequency: z + .string() + .regex(/[smdh]$/) + .optional() + .default('1m'), + /** + * The delay before the transform will run. + */ + delay: z + .string() + .regex(/[smdh]$/) + .optional() + .default('1m'), + /** + * The number of documents per second to process. + */ + docsPerSecond: z.number().int().optional().default(-1), + /** + * The initial page size to use for the composite aggregation of each checkpoint. + */ + maxPageSearchSize: z.number().int().optional().default(500), + }) +); export type InitEntityEngineRequestBody = z.infer; -export const InitEntityEngineRequestBody = z.object({ - /** - * The number of historical values to keep for each field. - */ - fieldHistoryLength: z.number().int().optional().default(10), - indexPattern: IndexPattern.optional(), - filter: z.string().optional(), - enrichPolicyExecutionInterval: Interval.optional(), - /** - * The field to use as the timestamp for the entity type. - */ - timestampField: z.string().optional().default('@timestamp'), - /** - * The amount of time the transform looks back to calculate the aggregations. - */ - lookbackPeriod: z - .string() - .regex(/[smdh]$/) - .optional() - .default('3h'), - /** - * The timeout for initializing the aggregating transform. - */ - timeout: z - .string() - .regex(/[smdh]$/) - .optional() - .default('180s'), - /** - * The frequency at which the transform will run. - */ - frequency: z - .string() - .regex(/[smdh]$/) - .optional() - .default('1m'), - /** - * The delay before the transform will run. - */ - delay: z - .string() - .regex(/[smdh]$/) - .optional() - .default('1m'), - /** - * The number of documents per second to process. - */ - docsPerSecond: z.number().int().optional().default(-1), - /** - * The initial page size to use for the composite aggregation of each checkpoint. - */ - maxPageSearchSize: z.number().int().optional().default(500), -}); export type InitEntityEngineRequestBodyInput = z.input; +export const InitEntityEngineResponse = lazySchema(() => EngineDescriptor); export type InitEntityEngineResponse = z.infer; -export const InitEntityEngineResponse = EngineDescriptor; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts index 5e91cbf673267..2103a56911f90 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts @@ -14,18 +14,20 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EngineDescriptor } from '../common.gen'; +export const ListEntityEnginesResponse = lazySchema(() => + z.object({ + /** + * The total number of entity engines. + */ + count: z.number().int().optional(), + /** + * An array of engine descriptors. + */ + engines: z.array(EngineDescriptor).optional(), + }) +); export type ListEntityEnginesResponse = z.infer; -export const ListEntityEnginesResponse = z.object({ - /** - * The total number of entity engines. - */ - count: z.number().int().optional(), - /** - * An array of engine descriptors. - */ - engines: z.array(EngineDescriptor).optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts index 69b819d9e2ce9..daba5f702fda2 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts @@ -14,23 +14,27 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntityType } from '../common.gen'; +export const StartEntityEngineRequestParams = lazySchema(() => + z.object({ + /** + * The entity type of the engine to start. + */ + entityType: EntityType, + }) +); export type StartEntityEngineRequestParams = z.infer; -export const StartEntityEngineRequestParams = z.object({ - /** - * The entity type of the engine to start. - */ - entityType: EntityType, -}); export type StartEntityEngineRequestParamsInput = z.input; +export const StartEntityEngineResponse = lazySchema(() => + z.object({ + /** + * Whether the engine was successfully started. + */ + started: z.boolean().optional(), + }) +); export type StartEntityEngineResponse = z.infer; -export const StartEntityEngineResponse = z.object({ - /** - * Whether the engine was successfully started. - */ - started: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts index 6a17b64d7f964..bcab55b881425 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts @@ -14,23 +14,27 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntityType } from '../common.gen'; +export const StopEntityEngineRequestParams = lazySchema(() => + z.object({ + /** + * The entity type of the engine to stop. + */ + entityType: EntityType, + }) +); export type StopEntityEngineRequestParams = z.infer; -export const StopEntityEngineRequestParams = z.object({ - /** - * The entity type of the engine to stop. - */ - entityType: EntityType, -}); export type StopEntityEngineRequestParamsInput = z.input; +export const StopEntityEngineResponse = lazySchema(() => + z.object({ + /** + * Whether the engine was successfully stopped. + */ + stopped: z.boolean().optional(), + }) +); export type StopEntityEngineResponse = z.infer; -export const StopEntityEngineResponse = z.object({ - /** - * Whether the engine was successfully stopped. - */ - stopped: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/common.gen.ts index bbf12d31ed24d..29c3d706ec22c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/common.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntityRiskLevels, EntityRiskScoreRecord } from '../../common/common.gen'; import { AssetCriticalityLevel } from '../../asset_criticality/common.gen'; @@ -22,422 +22,438 @@ import { AssetCriticalityLevel } from '../../asset_criticality/common.gen'; /** * Internal metadata attached to an entity by the engine that produced it. */ +export const EngineMetadata = lazySchema(() => + z + .object({ + /** + * The engine type that produced this entity record. + */ + Type: z.string(), + }) + .strict() +); export type EngineMetadata = z.infer; -export const EngineMetadata = z - .object({ - /** - * The engine type that produced this entity record. - */ - Type: z.string(), - }) - .strict(); /** * Core entity fields shared across all entity types. The `entity` namespace is a root-level field in the Entity Store latest index. */ +export const EntityField = lazySchema(() => + z + .object({ + /** + * Unique identifier for this entity. + */ + id: z.string(), + /** + * Human-readable name of the entity. + */ + name: z.string().optional(), + /** + * The entity type. + */ + type: z.string().optional(), + /** + * Optional sub-type classification for the entity. + */ + sub_type: z.string().optional(), + /** + * The source that produced this entity record. + */ + source: z.string().optional(), + EngineMetadata: EngineMetadata.optional(), + /** + * Boolean flags describing characteristics of the entity. + */ + attributes: z + .object({ + /** + * Whether the entity has elevated privileges. + */ + privileged: z.boolean().optional(), + /** + * Whether the entity is classified as an asset. + */ + asset: z.boolean().optional(), + /** + * Whether the entity is managed (for example, via a directory service). + */ + managed: z.boolean().optional(), + /** + * Whether multi-factor authentication is enabled for the entity. + */ + mfa_enabled: z.boolean().optional(), + }) + .strict() + .optional(), + /** + * Boolean flags indicating observed behavioral signals. + */ + behaviors: z + .object({ + /** + * Whether the entity has been targeted by brute-force attacks. + */ + brute_force_victim: z.boolean().optional(), + /** + * Whether the entity has logged in from a new country. + */ + new_country_login: z.boolean().optional(), + /** + * Whether the entity has used a USB device. + */ + used_usb_device: z.boolean().optional(), + }) + .strict() + .optional(), + /** + * Timestamps tracking the entity lifecycle. + */ + lifecycle: z + .object({ + /** + * When the entity was first observed. + */ + first_seen: z.string().datetime().optional(), + /** + * When the entity was last observed. + */ + last_seen: z.string().datetime().optional(), + /** + * When the entity last generated activity. + */ + last_activity: z.string().datetime().optional(), + }) + .strict() + .optional(), + /** + * Connections between this entity and other entities. + */ + relationships: z + .object({ + /** + * Entity IDs this entity communicates with. + */ + communicates_with: z.array(z.string()).optional(), + /** + * Entity IDs this entity depends on. + */ + depends_on: z.array(z.string()).optional(), + /** + * Entity IDs that depend on this entity. + */ + dependent_of: z.array(z.string()).optional(), + /** + * Entity IDs owned by this entity. + */ + owns: z.array(z.string()).optional(), + /** + * Entity IDs that own this entity. + */ + owned_by: z.array(z.string()).optional(), + /** + * Entity IDs this entity accesses frequently. + */ + accesses_frequently: z.array(z.string()).optional(), + /** + * Entity IDs this entity accesses infrequently. + */ + accesses_infrequently: z.array(z.string()).optional(), + /** + * Entity IDs that frequently access this entity. + */ + accessed_frequently_by: z.array(z.string()).optional(), + /** + * Entity IDs supervised by this entity. + */ + supervises: z.array(z.string()).optional(), + /** + * Entity IDs that supervise this entity. + */ + supervised_by: z.array(z.string()).optional(), + }) + .strict() + .optional(), + /** + * Risk scoring information for the entity. + */ + risk: z + .object({ + /** + * Lexical description of the entity's risk. + */ + calculated_level: EntityRiskLevels.optional(), + /** + * The raw numeric value of the given entity's risk score. + */ + calculated_score: z.number().optional(), + /** + * The normalized numeric value of the given entity's risk score. Useful for comparing with other entities. + */ + calculated_score_norm: z.number().min(0).max(100).optional(), + }) + .strict() + .optional(), + }) + .strict() +); export type EntityField = z.infer; -export const EntityField = z - .object({ - /** - * Unique identifier for this entity. - */ - id: z.string(), - /** - * Human-readable name of the entity. - */ - name: z.string().optional(), - /** - * The entity type. - */ - type: z.string().optional(), - /** - * Optional sub-type classification for the entity. - */ - sub_type: z.string().optional(), - /** - * The source that produced this entity record. - */ - source: z.string().optional(), - EngineMetadata: EngineMetadata.optional(), - /** - * Boolean flags describing characteristics of the entity. - */ - attributes: z - .object({ - /** - * Whether the entity has elevated privileges. - */ - privileged: z.boolean().optional(), - /** - * Whether the entity is classified as an asset. - */ - asset: z.boolean().optional(), - /** - * Whether the entity is managed (for example, via a directory service). - */ - managed: z.boolean().optional(), - /** - * Whether multi-factor authentication is enabled for the entity. - */ - mfa_enabled: z.boolean().optional(), - }) - .strict() - .optional(), - /** - * Boolean flags indicating observed behavioral signals. - */ - behaviors: z - .object({ - /** - * Whether the entity has been targeted by brute-force attacks. - */ - brute_force_victim: z.boolean().optional(), - /** - * Whether the entity has logged in from a new country. - */ - new_country_login: z.boolean().optional(), - /** - * Whether the entity has used a USB device. - */ - used_usb_device: z.boolean().optional(), - }) - .strict() - .optional(), - /** - * Timestamps tracking the entity lifecycle. - */ - lifecycle: z - .object({ - /** - * When the entity was first observed. - */ - first_seen: z.string().datetime().optional(), - /** - * When the entity was last observed. - */ - last_seen: z.string().datetime().optional(), - /** - * When the entity last generated activity. - */ - last_activity: z.string().datetime().optional(), - }) - .strict() - .optional(), - /** - * Connections between this entity and other entities. - */ - relationships: z - .object({ - /** - * Entity IDs this entity communicates with. - */ - communicates_with: z.array(z.string()).optional(), - /** - * Entity IDs this entity depends on. - */ - depends_on: z.array(z.string()).optional(), - /** - * Entity IDs that depend on this entity. - */ - dependent_of: z.array(z.string()).optional(), - /** - * Entity IDs owned by this entity. - */ - owns: z.array(z.string()).optional(), - /** - * Entity IDs that own this entity. - */ - owned_by: z.array(z.string()).optional(), - /** - * Entity IDs this entity accesses frequently. - */ - accesses_frequently: z.array(z.string()).optional(), - /** - * Entity IDs this entity accesses infrequently. - */ - accesses_infrequently: z.array(z.string()).optional(), - /** - * Entity IDs that frequently access this entity. - */ - accessed_frequently_by: z.array(z.string()).optional(), - /** - * Entity IDs supervised by this entity. - */ - supervises: z.array(z.string()).optional(), - /** - * Entity IDs that supervise this entity. - */ - supervised_by: z.array(z.string()).optional(), - }) - .strict() - .optional(), - /** - * Risk scoring information for the entity. - */ - risk: z - .object({ - /** - * Lexical description of the entity's risk. - */ - calculated_level: EntityRiskLevels.optional(), - /** - * The raw numeric value of the given entity's risk score. - */ - calculated_score: z.number().optional(), - /** - * The normalized numeric value of the given entity's risk score. Useful for comparing with other entities. - */ - calculated_score_norm: z.number().min(0).max(100).optional(), - }) - .strict() - .optional(), - }) - .strict(); /** * Asset metadata associated with the entity. */ +export const Asset = lazySchema(() => + z + .object({ + /** + * Unique identifier for the asset. + */ + id: z.string().optional(), + /** + * Human-readable asset name. + */ + name: z.string().optional(), + /** + * The owner of the asset. + */ + owner: z.string().optional(), + /** + * Serial number of the asset. + */ + serial_number: z.string().optional(), + /** + * Model name or number. + */ + model: z.string().optional(), + /** + * Vendor or manufacturer. + */ + vendor: z.string().optional(), + /** + * Deployment environment (for example, production, staging). + */ + environment: z.string().optional(), + /** + * The criticality level assigned to this asset. + */ + criticality: AssetCriticalityLevel.nullable().optional(), + /** + * Business unit the asset belongs to. + */ + business_unit: z.string().optional(), + }) + .strict() +); export type Asset = z.infer; -export const Asset = z - .object({ - /** - * Unique identifier for the asset. - */ - id: z.string().optional(), - /** - * Human-readable asset name. - */ - name: z.string().optional(), - /** - * The owner of the asset. - */ - owner: z.string().optional(), - /** - * Serial number of the asset. - */ - serial_number: z.string().optional(), - /** - * Model name or number. - */ - model: z.string().optional(), - /** - * Vendor or manufacturer. - */ - vendor: z.string().optional(), - /** - * Deployment environment (for example, production, staging). - */ - environment: z.string().optional(), - /** - * The criticality level assigned to this asset. - */ - criticality: AssetCriticalityLevel.nullable().optional(), - /** - * Business unit the asset belongs to. - */ - business_unit: z.string().optional(), - }) - .strict(); /** * An entity record representing a user, stored in the Entity Store latest index. */ +export const UserEntity = lazySchema(() => + z + .object({ + /** + * The time the entity record was last updated. + */ + '@timestamp': z.string().datetime().optional(), + entity: EntityField, + /** + * Elastic Common Schema (ECS) user fields collected on the entity. + */ + user: z + .object({ + /** + * Observed full names of the user. + */ + full_name: z.array(z.string()).optional(), + /** + * Observed user domains. + */ + domain: z.array(z.string()).optional(), + /** + * Observed roles assigned to the user. + */ + roles: z.array(z.string()).optional(), + /** + * Primary user name. + */ + name: z.string(), + /** + * Observed user IDs. + */ + id: z.array(z.string()).optional(), + /** + * Observed email addresses. + */ + email: z.array(z.string()).optional(), + /** + * Observed user hashes. + */ + hash: z.array(z.string()).optional(), + risk: EntityRiskScoreRecord.optional(), + }) + .strict() + .optional(), + asset: Asset.optional(), + event: z + .object({ + /** + * When the event was ingested into Elasticsearch. + */ + ingested: z.string().datetime().optional(), + }) + .strict() + .optional(), + }) + .strict() +); export type UserEntity = z.infer; -export const UserEntity = z - .object({ - /** - * The time the entity record was last updated. - */ - '@timestamp': z.string().datetime().optional(), - entity: EntityField, - /** - * Elastic Common Schema (ECS) user fields collected on the entity. - */ - user: z - .object({ - /** - * Observed full names of the user. - */ - full_name: z.array(z.string()).optional(), - /** - * Observed user domains. - */ - domain: z.array(z.string()).optional(), - /** - * Observed roles assigned to the user. - */ - roles: z.array(z.string()).optional(), - /** - * Primary user name. - */ - name: z.string(), - /** - * Observed user IDs. - */ - id: z.array(z.string()).optional(), - /** - * Observed email addresses. - */ - email: z.array(z.string()).optional(), - /** - * Observed user hashes. - */ - hash: z.array(z.string()).optional(), - risk: EntityRiskScoreRecord.optional(), - }) - .strict() - .optional(), - asset: Asset.optional(), - event: z - .object({ - /** - * When the event was ingested into Elasticsearch. - */ - ingested: z.string().datetime().optional(), - }) - .strict() - .optional(), - }) - .strict(); /** * An entity record representing a host, stored in the Entity Store latest index. */ +export const HostEntity = lazySchema(() => + z + .object({ + /** + * The time the entity record was last updated. + */ + '@timestamp': z.string().datetime().optional(), + entity: EntityField, + /** + * Elastic Common Schema (ECS) host fields collected on the entity. + */ + host: z + .object({ + /** + * Observed hostnames. + */ + hostname: z.array(z.string()).optional(), + /** + * Observed host domains. + */ + domain: z.array(z.string()).optional(), + /** + * Observed IP addresses. + */ + ip: z.array(z.string()).optional(), + /** + * Primary host name. + */ + name: z.string(), + /** + * Observed host IDs. + */ + id: z.array(z.string()).optional(), + /** + * Observed host types. + */ + type: z.array(z.string()).optional(), + /** + * Observed MAC addresses. + */ + mac: z.array(z.string()).optional(), + /** + * Observed CPU architectures. + */ + architecture: z.array(z.string()).optional(), + /** + * Elastic Common Schema (ECS) host.os fields collected on the entity latest index. + */ + os: z + .object({ + name: z.union([z.string(), z.array(z.string())]).optional(), + type: z.union([z.string(), z.array(z.string())]).optional(), + family: z.string().optional(), + full: z.string().optional(), + kernel: z.string().optional(), + platform: z.string().optional(), + version: z.string().optional(), + }) + .strict() + .optional(), + risk: EntityRiskScoreRecord.optional(), + entity: EntityField.optional(), + }) + .strict() + .optional(), + asset: Asset.optional(), + event: z + .object({ + /** + * When the event was ingested into Elasticsearch. + */ + ingested: z.string().datetime().optional(), + }) + .strict() + .optional(), + }) + .strict() +); export type HostEntity = z.infer; -export const HostEntity = z - .object({ - /** - * The time the entity record was last updated. - */ - '@timestamp': z.string().datetime().optional(), - entity: EntityField, - /** - * Elastic Common Schema (ECS) host fields collected on the entity. - */ - host: z - .object({ - /** - * Observed hostnames. - */ - hostname: z.array(z.string()).optional(), - /** - * Observed host domains. - */ - domain: z.array(z.string()).optional(), - /** - * Observed IP addresses. - */ - ip: z.array(z.string()).optional(), - /** - * Primary host name. - */ - name: z.string(), - /** - * Observed host IDs. - */ - id: z.array(z.string()).optional(), - /** - * Observed host types. - */ - type: z.array(z.string()).optional(), - /** - * Observed MAC addresses. - */ - mac: z.array(z.string()).optional(), - /** - * Observed CPU architectures. - */ - architecture: z.array(z.string()).optional(), - /** - * Elastic Common Schema (ECS) host.os fields collected on the entity latest index. - */ - os: z - .object({ - name: z.union([z.string(), z.array(z.string())]).optional(), - type: z.union([z.string(), z.array(z.string())]).optional(), - family: z.string().optional(), - full: z.string().optional(), - kernel: z.string().optional(), - platform: z.string().optional(), - version: z.string().optional(), - }) - .strict() - .optional(), - risk: EntityRiskScoreRecord.optional(), - entity: EntityField.optional(), - }) - .strict() - .optional(), - asset: Asset.optional(), - event: z - .object({ - /** - * When the event was ingested into Elasticsearch. - */ - ingested: z.string().datetime().optional(), - }) - .strict() - .optional(), - }) - .strict(); /** * An entity record representing a service, stored in the Entity Store latest index. */ +export const ServiceEntity = lazySchema(() => + z + .object({ + /** + * The time the entity record was last updated. + */ + '@timestamp': z.string().datetime().optional(), + entity: EntityField, + /** + * Elastic Common Schema (ECS) service fields collected on the entity. + */ + service: z + .object({ + /** + * Primary service name. + */ + name: z.string(), + risk: EntityRiskScoreRecord.optional(), + entity: EntityField.optional(), + }) + .strict() + .optional(), + asset: Asset.optional(), + event: z + .object({ + /** + * When the event was ingested into Elasticsearch. + */ + ingested: z.string().datetime().optional(), + }) + .strict() + .optional(), + }) + .strict() +); export type ServiceEntity = z.infer; -export const ServiceEntity = z - .object({ - /** - * The time the entity record was last updated. - */ - '@timestamp': z.string().datetime().optional(), - entity: EntityField, - /** - * Elastic Common Schema (ECS) service fields collected on the entity. - */ - service: z - .object({ - /** - * Primary service name. - */ - name: z.string(), - risk: EntityRiskScoreRecord.optional(), - entity: EntityField.optional(), - }) - .strict() - .optional(), - asset: Asset.optional(), - event: z - .object({ - /** - * When the event was ingested into Elasticsearch. - */ - ingested: z.string().datetime().optional(), - }) - .strict() - .optional(), - }) - .strict(); /** * A generic entity record. Maps only the `entity` and `asset` namespaces. Add additional field mappings here as needed. */ +export const GenericEntity = lazySchema(() => + z + .object({ + /** + * The time the entity record was last updated. + */ + '@timestamp': z.string().datetime().optional(), + entity: EntityField, + asset: Asset.optional(), + }) + .strict() +); export type GenericEntity = z.infer; -export const GenericEntity = z - .object({ - /** - * The time the entity record was last updated. - */ - '@timestamp': z.string().datetime().optional(), - entity: EntityField, - asset: Asset.optional(), - }) - .strict(); /** * An entity record from the Entity Store. The `entity` namespace is a root-level field in the latest index, unlike source logs where it is nested under `host`, `user`, or `service`. */ -export const EntityInternal = z.union([UserEntity, HostEntity, ServiceEntity, GenericEntity]); +export const EntityInternal = lazySchema(() => + z.union([UserEntity, HostEntity, ServiceEntity, GenericEntity]) +); export type Entity = z.infer; export const Entity = EntityInternal as z.ZodType; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/delete_entity.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/delete_entity.gen.ts index bc9f40edf1905..8bbae748cd993 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/delete_entity.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/delete_entity.gen.ts @@ -14,29 +14,35 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntityType } from '../common.gen'; +export const DeleteSingleEntityRequestParams = lazySchema(() => + z.object({ + entityType: EntityType, + }) +); export type DeleteSingleEntityRequestParams = z.infer; -export const DeleteSingleEntityRequestParams = z.object({ - entityType: EntityType, -}); export type DeleteSingleEntityRequestParamsInput = z.input; +export const DeleteSingleEntityRequestBody = lazySchema(() => + z.object({ + /** + * Identifier of the entity to be deleted, commonly entity.id value. + */ + id: z.string(), + }) +); export type DeleteSingleEntityRequestBody = z.infer; -export const DeleteSingleEntityRequestBody = z.object({ - /** - * Identifier of the entity to be deleted, commonly entity.id value. - */ - id: z.string(), -}); export type DeleteSingleEntityRequestBodyInput = z.input; +export const DeleteSingleEntityResponse = lazySchema(() => + z.object({ + /** + * Whether the entity was successfully deleted. + */ + deleted: z.boolean().optional(), + }) +); export type DeleteSingleEntityResponse = z.infer; -export const DeleteSingleEntityResponse = z.object({ - /** - * Whether the entity was successfully deleted. - */ - deleted: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/list_entities.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/list_entities.gen.ts index 2a97b6ebe0d80..cbd2f951ae1df 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/list_entities.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/list_entities.gen.ts @@ -14,58 +14,62 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString } from '@kbn/zod-helpers/v4'; import { EntityType, InspectQuery } from '../common.gen'; import { Entity } from './common.gen'; +export const ListEntitiesRequestQuery = lazySchema(() => + z.object({ + /** + * Field to sort results by. + */ + sort_field: z.string().optional(), + /** + * Sort order. + */ + sort_order: z.enum(['asc', 'desc']).optional(), + /** + * Page number to return (1-indexed). + */ + page: z.coerce.number().int().min(1).optional(), + /** + * Number of entities per page. + */ + per_page: z.coerce.number().int().min(1).max(10000).optional(), + /** + * An ES query to filter by. + */ + filterQuery: z.string().optional(), + /** + * Entity types to include in the results. + */ + entity_types: ArrayFromString(EntityType), + }) +); export type ListEntitiesRequestQuery = z.infer; -export const ListEntitiesRequestQuery = z.object({ - /** - * Field to sort results by. - */ - sort_field: z.string().optional(), - /** - * Sort order. - */ - sort_order: z.enum(['asc', 'desc']).optional(), - /** - * Page number to return (1-indexed). - */ - page: z.coerce.number().int().min(1).optional(), - /** - * Number of entities per page. - */ - per_page: z.coerce.number().int().min(1).max(10000).optional(), - /** - * An ES query to filter by. - */ - filterQuery: z.string().optional(), - /** - * Entity types to include in the results. - */ - entity_types: ArrayFromString(EntityType), -}); export type ListEntitiesRequestQueryInput = z.input; +export const ListEntitiesResponse = lazySchema(() => + z.object({ + /** + * The entity records for this page. + */ + records: z.array(Entity), + /** + * Current page number. + */ + page: z.number().int().min(1), + /** + * Number of entities per page. + */ + per_page: z.number().int().min(1).max(1000), + /** + * Total number of entities matching the query. + */ + total: z.number().int().min(0), + inspect: InspectQuery.optional(), + }) +); export type ListEntitiesResponse = z.infer; -export const ListEntitiesResponse = z.object({ - /** - * The entity records for this page. - */ - records: z.array(Entity), - /** - * Current page number. - */ - page: z.number().int().min(1), - /** - * Number of entities per page. - */ - per_page: z.number().int().min(1).max(1000), - /** - * Total number of entities matching the query. - */ - total: z.number().int().min(0), - inspect: InspectQuery.optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entities_bulk.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entities_bulk.gen.ts index b1c0a5923d334..a31990d18c732 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entities_bulk.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entities_bulk.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { EntityType } from '../common.gen'; @@ -23,38 +23,44 @@ import { Entity } from './common.gen'; /** * A wrapper that pairs an entity type with the entity record to upsert. */ +export const EntityContainer = lazySchema(() => + z.object({ + /** + * The entity type of the record. + */ + type: EntityType, + /** + * The entity record to create or update. + */ + record: Entity, + }) +); export type EntityContainer = z.infer; -export const EntityContainer = z.object({ - /** - * The entity type of the record. - */ - type: EntityType, - /** - * The entity record to create or update. - */ - record: Entity, -}); /** * A collection of entities to upsert in bulk. */ +export const EntitiesContainer = lazySchema(() => + z.object({ + /** + * The entities to create or update. + */ + entities: z.array(EntityContainer), + }) +); export type EntitiesContainer = z.infer; -export const EntitiesContainer = z.object({ - /** - * The entities to create or update. - */ - entities: z.array(EntityContainer), -}); +export const UpsertEntitiesBulkRequestQuery = lazySchema(() => + z.object({ + /** + * When true, allows updating protected fields. + */ + force: BooleanFromString.optional().default(false), + }) +); export type UpsertEntitiesBulkRequestQuery = z.infer; -export const UpsertEntitiesBulkRequestQuery = z.object({ - /** - * When true, allows updating protected fields. - */ - force: BooleanFromString.optional().default(false), -}); export type UpsertEntitiesBulkRequestQueryInput = z.input; +export const UpsertEntitiesBulkRequestBody = lazySchema(() => EntitiesContainer); export type UpsertEntitiesBulkRequestBody = z.infer; -export const UpsertEntitiesBulkRequestBody = EntitiesContainer; export type UpsertEntitiesBulkRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entity.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entity.gen.ts index f35b6fd4cf473..a8fa3a3279bd0 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entity.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/entities/upsert_entity.gen.ts @@ -14,30 +14,34 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { EntityType } from '../common.gen'; import { Entity } from './common.gen'; +export const UpsertEntityRequestQuery = lazySchema(() => + z.object({ + /** + * When true, allows updating protected fields. + */ + force: BooleanFromString.optional().default(false), + }) +); export type UpsertEntityRequestQuery = z.infer; -export const UpsertEntityRequestQuery = z.object({ - /** - * When true, allows updating protected fields. - */ - force: BooleanFromString.optional().default(false), -}); export type UpsertEntityRequestQueryInput = z.input; +export const UpsertEntityRequestParams = lazySchema(() => + z.object({ + entityType: EntityType, + }) +); export type UpsertEntityRequestParams = z.infer; -export const UpsertEntityRequestParams = z.object({ - entityType: EntityType, -}); export type UpsertEntityRequestParamsInput = z.input; +export const UpsertEntityRequestBody = lazySchema(() => Entity); export type UpsertEntityRequestBody = z.infer; -export const UpsertEntityRequestBody = Entity; export type UpsertEntityRequestBodyInput = z.input; +export const UpsertEntityResponse = lazySchema(() => Entity); export type UpsertEntityResponse = z.infer; -export const UpsertEntityResponse = Entity; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts index da6502a59ea2b..165fb4dd34b95 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts @@ -14,39 +14,43 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { StoreStatus, EngineDescriptor, EngineComponentStatus } from './common.gen'; +export const GetEntityStoreStatusRequestQuery = lazySchema(() => + z.object({ + /** + * If true, returns a detailed status of each engine including all its components. + */ + include_components: BooleanFromString.optional(), + }) +); export type GetEntityStoreStatusRequestQuery = z.infer; -export const GetEntityStoreStatusRequestQuery = z.object({ - /** - * If true, returns a detailed status of each engine including all its components. - */ - include_components: BooleanFromString.optional(), -}); export type GetEntityStoreStatusRequestQueryInput = z.input< typeof GetEntityStoreStatusRequestQuery >; +export const GetEntityStoreStatusResponse = lazySchema(() => + z.object({ + /** + * The overall status of the Entity Store. + */ + status: StoreStatus, + /** + * Per-engine status information. + */ + engines: z.array( + EngineDescriptor.merge( + z.object({ + /** + * Detailed component-level status. Only included when include_components is true. + */ + components: z.array(EngineComponentStatus).optional(), + }) + ) + ), + }) +); export type GetEntityStoreStatusResponse = z.infer; -export const GetEntityStoreStatusResponse = z.object({ - /** - * The overall status of the Entity Store. - */ - status: StoreStatus, - /** - * Per-engine status information. - */ - engines: z.array( - EngineDescriptor.extend( - z.object({ - /** - * Detailed component-level status. Only included when include_components is true. - */ - components: z.array(EngineComponentStatus).optional(), - }) - ) - ), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/migrations/run_migrations_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/migrations/run_migrations_route.gen.ts index 9a96ba62427dd..448fe5486a029 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/migrations/run_migrations_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/migrations/run_migrations_route.gen.ts @@ -14,11 +14,13 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const RunEntityAnalyticsMigrationsResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + }) +); export type RunEntityAnalyticsMigrationsResponse = z.infer< typeof RunEntityAnalyticsMigrationsResponse >; -export const RunEntityAnalyticsMigrationsResponse = z.object({ - success: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/common.gen.ts index 623fe13049457..7bd13c43f3b86 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/common.gen.ts @@ -14,51 +14,54 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The status of the Privilege Monitoring Engine */ +export const PrivilegeMonitoringEngineStatus = lazySchema(() => + z.enum(['started', 'error', 'disabled', 'not_installed']) +); export type PrivilegeMonitoringEngineStatus = z.infer; -export const PrivilegeMonitoringEngineStatus = z.enum([ - 'started', - 'error', - 'disabled', - 'not_installed', -]); export type PrivilegeMonitoringEngineStatusEnum = typeof PrivilegeMonitoringEngineStatus.enum; export const PrivilegeMonitoringEngineStatusEnum = PrivilegeMonitoringEngineStatus.enum; +export const MonitoringEngineDescriptor = lazySchema(() => + z.object({ + status: PrivilegeMonitoringEngineStatus, + error: z + .object({ + /** + * Error message typically only present if the engine is in error state + */ + message: z.string().optional(), + }) + .optional(), + }) +); export type MonitoringEngineDescriptor = z.infer; -export const MonitoringEngineDescriptor = z.object({ - status: PrivilegeMonitoringEngineStatus, - error: z - .object({ - /** - * Error message typically only present if the engine is in error state - */ - message: z.string().optional(), - }) - .optional(), -}); +export const MonitoringEngineComponentResource = lazySchema(() => + z.enum(['privmon_engine', 'index', 'task']) +); export type MonitoringEngineComponentResource = z.infer; -export const MonitoringEngineComponentResource = z.enum(['privmon_engine', 'index', 'task']); export type MonitoringEngineComponentResourceEnum = typeof MonitoringEngineComponentResource.enum; export const MonitoringEngineComponentResourceEnum = MonitoringEngineComponentResource.enum; +export const MonitoringEngineComponentStatus = lazySchema(() => + z.object({ + id: z.string(), + installed: z.boolean(), + resource: MonitoringEngineComponentResource, + health: z.enum(['green', 'yellow', 'red', 'unknown']).optional(), + errors: z + .array( + z.object({ + title: z.string().optional(), + message: z.string().optional(), + }) + ) + .optional(), + }) +); export type MonitoringEngineComponentStatus = z.infer; -export const MonitoringEngineComponentStatus = z.object({ - id: z.string(), - installed: z.boolean(), - resource: MonitoringEngineComponentResource, - health: z.enum(['green', 'yellow', 'red', 'unknown']).optional(), - errors: z - .array( - z.object({ - title: z.string().optional(), - message: z.string().optional(), - }) - ) - .optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/create_index.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/create_index.gen.ts index e18f1c58a032d..7c56eb61ab4bf 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/create_index.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/create_index.gen.ts @@ -14,28 +14,32 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const CreatePrivilegesImportIndexRequestBody = lazySchema(() => + z.object({ + /** + * The index name to create + */ + name: z.string(), + /** + * The mode of index creation, either 'standard' or 'lookup' + */ + mode: z.enum(['standard', 'lookup']), + }) +); export type CreatePrivilegesImportIndexRequestBody = z.infer< typeof CreatePrivilegesImportIndexRequestBody >; -export const CreatePrivilegesImportIndexRequestBody = z.object({ - /** - * The index name to create - */ - name: z.string(), - /** - * The mode of index creation, either 'standard' or 'lookup' - */ - mode: z.enum(['standard', 'lookup']), -}); export type CreatePrivilegesImportIndexRequestBodyInput = z.input< typeof CreatePrivilegesImportIndexRequestBody >; +export const CreatePrivilegesImportIndexResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + }) +); export type CreatePrivilegesImportIndexResponse = z.infer< typeof CreatePrivilegesImportIndexResponse >; -export const CreatePrivilegesImportIndexResponse = z.object({ - success: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/delete.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/delete.gen.ts index 9f9af4dbfc988..8659fdc6cdbb1 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/delete.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/delete.gen.ts @@ -14,21 +14,25 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; +export const DeleteMonitoringEngineRequestQuery = lazySchema(() => + z.object({ + /** + * Whether to delete all the privileged user data + */ + data: BooleanFromString.optional().default(false), + }) +); export type DeleteMonitoringEngineRequestQuery = z.infer; -export const DeleteMonitoringEngineRequestQuery = z.object({ - /** - * Whether to delete all the privileged user data - */ - data: BooleanFromString.optional().default(false), -}); export type DeleteMonitoringEngineRequestQueryInput = z.input< typeof DeleteMonitoringEngineRequestQuery >; +export const DeleteMonitoringEngineResponse = lazySchema(() => + z.object({ + deleted: z.boolean(), + }) +); export type DeleteMonitoringEngineResponse = z.infer; -export const DeleteMonitoringEngineResponse = z.object({ - deleted: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/disable.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/disable.gen.ts index 7232cbd2c9d9a..75326555f36e7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/disable.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/disable.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { MonitoringEngineDescriptor } from '../common.gen'; +export const DisableMonitoringEngineResponse = lazySchema(() => MonitoringEngineDescriptor); export type DisableMonitoringEngineResponse = z.infer; -export const DisableMonitoringEngineResponse = MonitoringEngineDescriptor; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/init.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/init.gen.ts index 439c84495fc61..b780a8729a300 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/init.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/init.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { MonitoringEngineDescriptor } from '../common.gen'; +export const InitMonitoringEngineResponse = lazySchema(() => MonitoringEngineDescriptor); export type InitMonitoringEngineResponse = z.infer; -export const InitMonitoringEngineResponse = MonitoringEngineDescriptor; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/schedule_now.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/schedule_now.gen.ts index c6113744d5a62..a2cb3c5d7b81e 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/schedule_now.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/engine/schedule_now.gen.ts @@ -14,12 +14,14 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ScheduleMonitoringEngineResponse = lazySchema(() => + z.object({ + /** + * Indicates the scheduling was successful + */ + success: z.boolean().optional(), + }) +); export type ScheduleMonitoringEngineResponse = z.infer; -export const ScheduleMonitoringEngineResponse = z.object({ - /** - * Indicates the scheduling was successful - */ - success: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/health.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/health.gen.ts index 656a29bc724c3..c61d8208893fa 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/health.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/health.gen.ts @@ -14,31 +14,33 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PrivilegeMonitoringEngineStatus } from './common.gen'; +export const PrivMonHealthResponse = lazySchema(() => + z.object({ + status: PrivilegeMonitoringEngineStatus, + error: z + .object({ + message: z.string().optional(), + }) + .optional(), + /** + * User statistics for privilege monitoring + */ + users: z + .object({ + /** + * Current number of privileged users being monitored + */ + current_count: z.number().int(), + /** + * Maximum number of privileged users allowed to be monitored + */ + max_allowed: z.number().int(), + }) + .optional(), + }) +); export type PrivMonHealthResponse = z.infer; -export const PrivMonHealthResponse = z.object({ - status: PrivilegeMonitoringEngineStatus, - error: z - .object({ - message: z.string().optional(), - }) - .optional(), - /** - * User statistics for privilege monitoring - */ - users: z - .object({ - /** - * Current number of privileged users being monitored - */ - current_count: z.number().int(), - /** - * Maximum number of privileged users allowed to be monitored - */ - max_allowed: z.number().int(), - }) - .optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts index cf52621a00b30..f5fddf547716c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/monitoring_entity_source/monitoring_entity_source.gen.ts @@ -14,152 +14,179 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; +export const MonitoringEntitySourceType = lazySchema(() => + z.enum(['index', 'entity_analytics_integration']) +); export type MonitoringEntitySourceType = z.infer; -export const MonitoringEntitySourceType = z.enum(['index', 'entity_analytics_integration']); export type MonitoringEntitySourceTypeEnum = typeof MonitoringEntitySourceType.enum; export const MonitoringEntitySourceTypeEnum = MonitoringEntitySourceType.enum; -export type Matcher = z.infer; -export const Matcher = z.object({ - fields: z.array(z.string()), - /** +export const Matcher = lazySchema(() => + z.object({ + fields: z.array(z.string()), + /** * Matcher values. Must be either an array of strings (e.g. group or role names) or an array of booleans (e.g. integration-derived flags like privileged_group_member). Mixed types are intentionally not supported for simplicity and predictability. */ - values: z.union([z.array(z.string()), z.array(z.boolean())]), -}); + values: z.union([z.array(z.string()), z.array(z.boolean())]), + }) +); +export type Matcher = z.infer; +export const Filter = lazySchema(() => + z.object({ + kuery: z.union([z.string(), z.object({})]).optional(), + }) +); export type Filter = z.infer; -export const Filter = z.object({ - kuery: z.union([z.string(), z.object({})]).optional(), -}); +export const Integrations = lazySchema(() => + z.object({ + /** + * Index to read latest sync markers from + */ + syncMarkerIndex: z.string().optional(), + /** + * integrations latest full sync and update syncData + */ + syncData: z + .object({ + /** + * Timestamp of the last full sync from integrations + */ + lastFullSync: z.string().datetime().optional(), + /** + * Timestamp of the last update processed from integrations + */ + lastUpdateProcessed: z.string().datetime().optional(), + }) + .optional(), + }) +); export type Integrations = z.infer; -export const Integrations = z.object({ - /** - * Index to read latest sync markers from - */ - syncMarkerIndex: z.string().optional(), - /** - * integrations latest full sync and update syncData - */ - syncData: z - .object({ - /** - * Timestamp of the last full sync from integrations - */ - lastFullSync: z.string().datetime().optional(), - /** - * Timestamp of the last update processed from integrations - */ - lastUpdateProcessed: z.string().datetime().optional(), - }) - .optional(), -}); +export const UpdateableMonitoringEntitySourceProperties = lazySchema(() => + z.object({ + name: z.string().optional(), + indexPattern: z.string().optional(), + integrationName: z.string().optional(), + enabled: z.boolean().optional(), + matchers: z.array(Matcher).optional(), + filter: Filter.optional(), + integrations: Integrations.optional(), + }) +); export type UpdateableMonitoringEntitySourceProperties = z.infer< typeof UpdateableMonitoringEntitySourceProperties >; -export const UpdateableMonitoringEntitySourceProperties = z.object({ - name: z.string().optional(), - indexPattern: z.string().optional(), - integrationName: z.string().optional(), - enabled: z.boolean().optional(), - matchers: z.array(Matcher).optional(), - filter: Filter.optional(), - integrations: Integrations.optional(), -}); +export const UpdateEntitySourceNoadditionalProps = lazySchema(() => + UpdateableMonitoringEntitySourceProperties.merge(z.object({}).strict()) +); export type UpdateEntitySourceNoadditionalProps = z.infer< typeof UpdateEntitySourceNoadditionalProps >; -export const UpdateEntitySourceNoadditionalProps = - UpdateableMonitoringEntitySourceProperties.extend(z.object({}).strict()); -export type MonitoringEntitySourceProperties = z.infer; -export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySourceProperties.extend( - z.object({ - type: MonitoringEntitySourceType.optional(), - managed: z.boolean().optional(), - managedVersion: z.number().int().optional(), - matchersModifiedByUser: z.boolean().optional(), - }) +export const MonitoringEntitySourceProperties = lazySchema(() => + UpdateableMonitoringEntitySourceProperties.merge( + z.object({ + type: MonitoringEntitySourceType.optional(), + managed: z.boolean().optional(), + managedVersion: z.number().int().optional(), + matchersModifiedByUser: z.boolean().optional(), + }) + ) ); +export type MonitoringEntitySourceProperties = z.infer; -export type MonitoringEntitySourceAttributes = z.infer; -export const MonitoringEntitySourceAttributes = MonitoringEntitySourceProperties.extend( - z.object({}) +export const MonitoringEntitySourceAttributes = lazySchema(() => + MonitoringEntitySourceProperties.merge(z.object({})) ); +export type MonitoringEntitySourceAttributes = z.infer; -export type MonitoringEntitySource = z.infer; -export const MonitoringEntitySource = MonitoringEntitySourceProperties.extend( - z.object({ - id: z.string(), - }) +export const MonitoringEntitySource = lazySchema(() => + MonitoringEntitySourceProperties.merge( + z.object({ + id: z.string(), + }) + ) ); +export type MonitoringEntitySource = z.infer; +export const CreateEntitySourceRequestBody = lazySchema(() => + z + .object({ + type: MonitoringEntitySourceType, + name: z.string(), + indexPattern: z.string().optional(), + enabled: z.boolean().optional(), + matchers: z.array(Matcher).optional(), + filter: Filter.optional(), + }) + .strict() +); export type CreateEntitySourceRequestBody = z.infer; -export const CreateEntitySourceRequestBody = z - .object({ - type: MonitoringEntitySourceType, - name: z.string(), - indexPattern: z.string().optional(), - enabled: z.boolean().optional(), - matchers: z.array(Matcher).optional(), - filter: Filter.optional(), - }) - .strict(); export type CreateEntitySourceRequestBodyInput = z.input; +export const CreateEntitySourceResponse = lazySchema(() => MonitoringEntitySource); export type CreateEntitySourceResponse = z.infer; -export const CreateEntitySourceResponse = MonitoringEntitySource; +export const DeleteEntitySourceRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type DeleteEntitySourceRequestParams = z.infer; -export const DeleteEntitySourceRequestParams = z.object({ - id: z.string(), -}); export type DeleteEntitySourceRequestParamsInput = z.input; +export const GetEntitySourceRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type GetEntitySourceRequestParams = z.infer; -export const GetEntitySourceRequestParams = z.object({ - id: z.string(), -}); export type GetEntitySourceRequestParamsInput = z.input; +export const GetEntitySourceResponse = lazySchema(() => MonitoringEntitySource); export type GetEntitySourceResponse = z.infer; -export const GetEntitySourceResponse = MonitoringEntitySource; +export const ListEntitySourcesRequestQuery = lazySchema(() => + z.object({ + type: z.string().optional(), + managed: BooleanFromString.optional(), + name: z.string().optional(), + page: z.coerce.number().int().min(1).optional(), + per_page: z.coerce.number().int().min(1).max(10000).optional(), + sort_field: z.string().optional(), + sort_order: z.enum(['asc', 'desc']).optional(), + }) +); export type ListEntitySourcesRequestQuery = z.infer; -export const ListEntitySourcesRequestQuery = z.object({ - type: z.string().optional(), - managed: BooleanFromString.optional(), - name: z.string().optional(), - page: z.coerce.number().int().min(1).optional(), - per_page: z.coerce.number().int().min(1).max(10000).optional(), - sort_field: z.string().optional(), - sort_order: z.enum(['asc', 'desc']).optional(), -}); export type ListEntitySourcesRequestQueryInput = z.input; +export const ListEntitySourcesResponse = lazySchema(() => + z.object({ + sources: z.array(MonitoringEntitySource), + page: z.number().int().min(1), + per_page: z.number().int().min(1).max(10000), + total: z.number().int().min(0), + }) +); export type ListEntitySourcesResponse = z.infer; -export const ListEntitySourcesResponse = z.object({ - sources: z.array(MonitoringEntitySource), - page: z.number().int().min(1), - per_page: z.number().int().min(1).max(10000), - total: z.number().int().min(0), -}); +export const UpdateEntitySourceRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type UpdateEntitySourceRequestParams = z.infer; -export const UpdateEntitySourceRequestParams = z.object({ - id: z.string(), -}); export type UpdateEntitySourceRequestParamsInput = z.input; +export const UpdateEntitySourceRequestBody = lazySchema(() => UpdateEntitySourceNoadditionalProps); export type UpdateEntitySourceRequestBody = z.infer; -export const UpdateEntitySourceRequestBody = UpdateEntitySourceNoadditionalProps; export type UpdateEntitySourceRequestBodyInput = z.input; +export const UpdateEntitySourceResponse = lazySchema(() => MonitoringEntitySource); export type UpdateEntitySourceResponse = z.infer; -export const UpdateEntitySourceResponse = MonitoringEntitySource; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/install.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/install.gen.ts index c4880d88b40f5..795ac72a35ca4 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/install.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/install.gen.ts @@ -14,11 +14,13 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const InstallPrivilegedAccessDetectionPackageResponse = lazySchema(() => + z.object({ + message: z.string(), + }) +); export type InstallPrivilegedAccessDetectionPackageResponse = z.infer< typeof InstallPrivilegedAccessDetectionPackageResponse >; -export const InstallPrivilegedAccessDetectionPackageResponse = z.object({ - message: z.string(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/status.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/status.gen.ts index 18f99b685b0e9..4dcd0026741f6 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/status.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileged_access_detection/status.gen.ts @@ -14,19 +14,21 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const GetPrivilegedAccessDetectionPackageStatusResponse = lazySchema(() => + z.object({ + package_installation_status: z.enum(['complete', 'incomplete']), + ml_module_setup_status: z.enum(['complete', 'incomplete']), + jobs: z.array( + z.object({ + job_id: z.string(), + description: z.string().optional(), + state: z.enum(['closing', 'closed', 'opened', 'failed', 'opening']), + }) + ), + }) +); export type GetPrivilegedAccessDetectionPackageStatusResponse = z.infer< typeof GetPrivilegedAccessDetectionPackageStatusResponse >; -export const GetPrivilegedAccessDetectionPackageStatusResponse = z.object({ - package_installation_status: z.enum(['complete', 'incomplete']), - ml_module_setup_status: z.enum(['complete', 'incomplete']), - jobs: z.array( - z.object({ - job_id: z.string(), - description: z.string().optional(), - state: z.enum(['closing', 'closed', 'opened', 'failed', 'opening']), - }) - ), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileges.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileges.gen.ts index bb857b38e2a8f..4c367dda9d8fe 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileges.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/privileges.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { EntityAnalyticsPrivileges } from '../common/common.gen'; +export const PrivMonPrivilegesResponse = lazySchema(() => EntityAnalyticsPrivileges); export type PrivMonPrivilegesResponse = z.infer; -export const PrivMonPrivilegesResponse = EntityAnalyticsPrivileges; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/search_indices.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/search_indices.gen.ts index 9d71eb1f92b00..f65a81af053c4 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/search_indices.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/search_indices.gen.ts @@ -14,17 +14,19 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const SearchPrivilegesIndicesRequestQuery = lazySchema(() => + z.object({ + searchQuery: z.string().optional(), + }) +); export type SearchPrivilegesIndicesRequestQuery = z.infer< typeof SearchPrivilegesIndicesRequestQuery >; -export const SearchPrivilegesIndicesRequestQuery = z.object({ - searchQuery: z.string().optional(), -}); export type SearchPrivilegesIndicesRequestQueryInput = z.input< typeof SearchPrivilegesIndicesRequestQuery >; +export const SearchPrivilegesIndicesResponse = lazySchema(() => z.array(z.string())); export type SearchPrivilegesIndicesResponse = z.infer; -export const SearchPrivilegesIndicesResponse = z.array(z.string()); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts index 529cedba693c2..3cdd72b28a902 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/common.gen.ts @@ -14,91 +14,62 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const UserName = lazySchema(() => + z.object({ + user: z + .object({ + /** + * The name of the user. + */ + name: z.string().optional(), + }) + .optional(), + /** + * Entity analytics monitoring configuration for the user + */ + entity_analytics_monitoring: z + .object({ + /** + * Array of labels associated with the user + */ + labels: z + .array( + z.object({ + /** + * The field name for the label + */ + field: z.string().optional(), + /** + * The value of the label + */ + value: z.string().optional(), + /** + * The source where this label was created (api, csv, or index_sync) + */ + source: z.enum(['api', 'csv', 'index_sync']).optional(), + }) + ) + .optional(), + }) + .optional(), + }) +); export type UserName = z.infer; -export const UserName = z.object({ - user: z - .object({ - /** - * The name of the user. - */ - name: z.string().optional(), - }) - .optional(), - /** - * Entity analytics monitoring configuration for the user - */ - entity_analytics_monitoring: z - .object({ - /** - * Array of labels associated with the user - */ - labels: z - .array( - z.object({ - /** - * The field name for the label - */ - field: z.string().optional(), - /** - * The value of the label - */ - value: z.string().optional(), - /** - * The source where this label was created (api, csv, or index_sync) - */ - source: z.enum(['api', 'csv', 'index_sync']).optional(), - }) - ) - .optional(), - }) - .optional(), -}); +export const MonitoringLabel = lazySchema(() => + z.object({ + field: z.string(), + value: z.string(), + source: z.string(), + }) +); export type MonitoringLabel = z.infer; -export const MonitoringLabel = z.object({ - field: z.string(), - value: z.string(), - source: z.string(), -}); -export type MonitoredUserUpdateDoc = z.infer; -export const MonitoredUserUpdateDoc = z.object({ - id: z.string().optional(), - user: z - .object({ - name: z.string().optional(), - /** - * Indicates if the user is privileged. - */ - is_privileged: z.boolean().optional(), - }) - .optional(), - labels: z - .object({ - sources: z.array(z.unknown()).optional(), - source_ids: z.array(z.string()).optional(), - source_integrations: z.array(z.string()).optional(), - }) - .optional(), - entity_analytics_monitoring: z - .object({ - labels: z.array(MonitoringLabel).optional(), - }) - .optional(), -}); - -export type MonitoredUserDoc = z.infer; -export const MonitoredUserDoc = MonitoredUserUpdateDoc.extend( +export const MonitoredUserUpdateDoc = lazySchema(() => z.object({ - event: z - .object({ - ingested: z.string().datetime().optional(), - '@timestamp': z.string().datetime().optional(), - }) - .optional(), - '@timestamp': z.string().datetime().optional(), + id: z.string().optional(), user: z .object({ name: z.string().optional(), @@ -106,19 +77,56 @@ export const MonitoredUserDoc = MonitoredUserUpdateDoc.extend( * Indicates if the user is privileged. */ is_privileged: z.boolean().optional(), - entity: z - .object({ - attributes: z - .object({ - /** - * Indicates if the user is privileged. - */ - Privileged: z.boolean().optional(), - }) - .optional(), - }) - .optional(), + }) + .optional(), + labels: z + .object({ + sources: z.array(z.unknown()).optional(), + source_ids: z.array(z.string()).optional(), + source_integrations: z.array(z.string()).optional(), + }) + .optional(), + entity_analytics_monitoring: z + .object({ + labels: z.array(MonitoringLabel).optional(), }) .optional(), }) ); +export type MonitoredUserUpdateDoc = z.infer; + +export const MonitoredUserDoc = lazySchema(() => + MonitoredUserUpdateDoc.merge( + z.object({ + event: z + .object({ + ingested: z.string().datetime().optional(), + '@timestamp': z.string().datetime().optional(), + }) + .optional(), + '@timestamp': z.string().datetime().optional(), + user: z + .object({ + name: z.string().optional(), + /** + * Indicates if the user is privileged. + */ + is_privileged: z.boolean().optional(), + entity: z + .object({ + attributes: z + .object({ + /** + * Indicates if the user is privileged. + */ + Privileged: z.boolean().optional(), + }) + .optional(), + }) + .optional(), + }) + .optional(), + }) + ) +); +export type MonitoredUserDoc = z.infer; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/create.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/create.gen.ts index 5f2543df8a572..604fffe34370f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/create.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/create.gen.ts @@ -15,12 +15,13 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { UserName, MonitoredUserDoc } from './common.gen'; +export const CreatePrivMonUserRequestBody = lazySchema(() => UserName); export type CreatePrivMonUserRequestBody = z.infer; -export const CreatePrivMonUserRequestBody = UserName; export type CreatePrivMonUserRequestBodyInput = z.input; +export const CreatePrivMonUserResponse = lazySchema(() => MonitoredUserDoc); export type CreatePrivMonUserResponse = z.infer; -export const CreatePrivMonUserResponse = MonitoredUserDoc; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/delete.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/delete.gen.ts index 9a28bedffa377..15c705fdfb764 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/delete.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/delete.gen.ts @@ -14,22 +14,26 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const DeletePrivMonUserRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type DeletePrivMonUserRequestParams = z.infer; -export const DeletePrivMonUserRequestParams = z.object({ - id: z.string(), -}); export type DeletePrivMonUserRequestParamsInput = z.input; +export const DeletePrivMonUserResponse = lazySchema(() => + z.object({ + /** + * Indicates if the deletion was successful + */ + acknowledged: z.boolean().optional(), + /** + * A message providing additional information about the deletion status + */ + message: z.string().optional(), + }) +); export type DeletePrivMonUserResponse = z.infer; -export const DeletePrivMonUserResponse = z.object({ - /** - * Indicates if the deletion was successful - */ - acknowledged: z.boolean().optional(), - /** - * A message providing additional information about the deletion status - */ - message: z.string().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/list.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/list.gen.ts index 98b74397a5061..34b7cdec8a565 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/list.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/list.gen.ts @@ -14,18 +14,20 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { MonitoredUserDoc } from './common.gen'; +export const ListPrivMonUsersRequestQuery = lazySchema(() => + z.object({ + /** + * KQL query to filter the list of monitored users + */ + kql: z.string().optional(), + }) +); export type ListPrivMonUsersRequestQuery = z.infer; -export const ListPrivMonUsersRequestQuery = z.object({ - /** - * KQL query to filter the list of monitored users - */ - kql: z.string().optional(), -}); export type ListPrivMonUsersRequestQueryInput = z.input; +export const ListPrivMonUsersResponse = lazySchema(() => z.array(MonitoredUserDoc)); export type ListPrivMonUsersResponse = z.infer; -export const ListPrivMonUsersResponse = z.array(MonitoredUserDoc); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/update.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/update.gen.ts index 89521d820a526..1f08a69e77f33 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/update.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/update.gen.ts @@ -14,19 +14,21 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { MonitoredUserUpdateDoc, MonitoredUserDoc } from './common.gen'; +export const UpdatePrivMonUserRequestParams = lazySchema(() => + z.object({ + id: z.string(), + }) +); export type UpdatePrivMonUserRequestParams = z.infer; -export const UpdatePrivMonUserRequestParams = z.object({ - id: z.string(), -}); export type UpdatePrivMonUserRequestParamsInput = z.input; +export const UpdatePrivMonUserRequestBody = lazySchema(() => MonitoredUserUpdateDoc); export type UpdatePrivMonUserRequestBody = z.infer; -export const UpdatePrivMonUserRequestBody = MonitoredUserUpdateDoc; export type UpdatePrivMonUserRequestBodyInput = z.input; +export const UpdatePrivMonUserResponse = lazySchema(() => MonitoredUserDoc); export type UpdatePrivMonUserResponse = z.infer; -export const UpdatePrivMonUserResponse = MonitoredUserDoc; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/upload_csv.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/upload_csv.gen.ts index ab40e4830f88c..129d0c51fcbd9 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/upload_csv.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/monitoring/users/upload_csv.gen.ts @@ -14,25 +14,31 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const PrivmonUserCsvUploadErrorItem = lazySchema(() => + z.object({ + message: z.string(), + username: z.string().nullable(), + index: z.number().int().nullable(), + }) +); export type PrivmonUserCsvUploadErrorItem = z.infer; -export const PrivmonUserCsvUploadErrorItem = z.object({ - message: z.string(), - username: z.string().nullable(), - index: z.number().int().nullable(), -}); +export const PrivmonUserCsvUploadStats = lazySchema(() => + z.object({ + successfulOperations: z.number().int(), + uploaded: z.number().int(), + failedOperations: z.number().int(), + totalOperations: z.number().int(), + }) +); export type PrivmonUserCsvUploadStats = z.infer; -export const PrivmonUserCsvUploadStats = z.object({ - successfulOperations: z.number().int(), - uploaded: z.number().int(), - failedOperations: z.number().int(), - totalOperations: z.number().int(), -}); +export const PrivmonBulkUploadUsersCSVResponse = lazySchema(() => + z.object({ + errors: z.array(PrivmonUserCsvUploadErrorItem), + stats: PrivmonUserCsvUploadStats, + }) +); export type PrivmonBulkUploadUsersCSVResponse = z.infer; -export const PrivmonBulkUploadUsersCSVResponse = z.object({ - errors: z.array(PrivmonUserCsvUploadErrorItem), - stats: PrivmonUserCsvUploadStats, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/calculation_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/calculation_route.gen.ts index 8da54486011ce..bf024e7025b9a 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/calculation_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/calculation_route.gen.ts @@ -14,46 +14,48 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AfterKeys, EntityRiskScoreRecord } from '../common/common.gen'; +export const RiskScoresCalculationResponse = lazySchema(() => + z.object({ + /** + * Used to obtain the next "page" of risk scores. See also the `after_keys` key in a risk scores request. If this key is empty, the calculation is complete. + */ + after_keys: AfterKeys, + /** + * A list of errors encountered during the calculation. + */ + errors: z.array(z.string()), + /** + * The number of risk scores persisted to elasticsearch. + */ + scores_written: z.number(), + scores: z + .object({ + /** + * A list of host risk scores + */ + host: z.array(EntityRiskScoreRecord).optional(), + /** + * A list of user risk scores + */ + user: z.array(EntityRiskScoreRecord).optional(), + /** + * A list of service risk scores + */ + service: z.array(EntityRiskScoreRecord).optional(), + /** + * A list of generic risk scores + */ + generic: z.array(EntityRiskScoreRecord).optional(), + /** + * If 'wait_for' the request will wait for the index refresh. + */ + refresh: z.literal('wait_for').optional(), + }) + .optional(), + }) +); export type RiskScoresCalculationResponse = z.infer; -export const RiskScoresCalculationResponse = z.object({ - /** - * Used to obtain the next "page" of risk scores. See also the `after_keys` key in a risk scores request. If this key is empty, the calculation is complete. - */ - after_keys: AfterKeys, - /** - * A list of errors encountered during the calculation. - */ - errors: z.array(z.string()), - /** - * The number of risk scores persisted to elasticsearch. - */ - scores_written: z.number(), - scores: z - .object({ - /** - * A list of host risk scores - */ - host: z.array(EntityRiskScoreRecord).optional(), - /** - * A list of user risk scores - */ - user: z.array(EntityRiskScoreRecord).optional(), - /** - * A list of service risk scores - */ - service: z.array(EntityRiskScoreRecord).optional(), - /** - * A list of generic risk scores - */ - generic: z.array(EntityRiskScoreRecord).optional(), - /** - * If 'wait_for' the request will wait for the index refresh. - */ - refresh: z.literal('wait_for').optional(), - }) - .optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_cleanup_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_cleanup_route.gen.ts index 51d13c7c934fd..cd67b5d2da112 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_cleanup_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_cleanup_route.gen.ts @@ -14,20 +14,24 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const CleanUpRiskEngineErrorResponse = lazySchema(() => + z.object({ + cleanup_successful: z.boolean(), + errors: z.array( + z.object({ + seq: z.number().int(), + error: z.string(), + }) + ), + }) +); export type CleanUpRiskEngineErrorResponse = z.infer; -export const CleanUpRiskEngineErrorResponse = z.object({ - cleanup_successful: z.boolean(), - errors: z.array( - z.object({ - seq: z.number().int(), - error: z.string(), - }) - ), -}); +export const CleanUpRiskEngineResponse = lazySchema(() => + z.object({ + cleanup_successful: z.boolean().optional(), + }) +); export type CleanUpRiskEngineResponse = z.infer; -export const CleanUpRiskEngineResponse = z.object({ - cleanup_successful: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_configure_saved_object_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_configure_saved_object_route.gen.ts index a9f798f6a780f..af172b6a42f4c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_configure_saved_object_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_configure_saved_object_route.gen.ts @@ -14,53 +14,59 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ConfigureRiskEngineSavedObjectErrorResponse = lazySchema(() => + z.object({ + risk_engine_saved_object_configured: z.boolean(), + errors: z.array( + z.object({ + seq: z.number().int(), + error: z.string(), + }) + ), + }) +); export type ConfigureRiskEngineSavedObjectErrorResponse = z.infer< typeof ConfigureRiskEngineSavedObjectErrorResponse >; -export const ConfigureRiskEngineSavedObjectErrorResponse = z.object({ - risk_engine_saved_object_configured: z.boolean(), - errors: z.array( - z.object({ - seq: z.number().int(), - error: z.string(), - }) - ), -}); +export const ConfigureRiskEngineSavedObjectRequestBody = lazySchema(() => + z.object({ + exclude_alert_statuses: z.array(z.string()).optional(), + range: z + .object({ + start: z.string().optional(), + end: z.string().optional(), + }) + .optional(), + exclude_alert_tags: z.array(z.string()).optional(), + enable_reset_to_zero: z.boolean().optional(), + filters: z + .array( + z.object({ + entity_types: z.array(z.enum(['host', 'user', 'service'])), + /** + * KQL filter string + */ + filter: z.string(), + }) + ) + .optional(), + }) +); export type ConfigureRiskEngineSavedObjectRequestBody = z.infer< typeof ConfigureRiskEngineSavedObjectRequestBody >; -export const ConfigureRiskEngineSavedObjectRequestBody = z.object({ - exclude_alert_statuses: z.array(z.string()).optional(), - range: z - .object({ - start: z.string().optional(), - end: z.string().optional(), - }) - .optional(), - exclude_alert_tags: z.array(z.string()).optional(), - enable_reset_to_zero: z.boolean().optional(), - filters: z - .array( - z.object({ - entity_types: z.array(z.enum(['host', 'user', 'service'])), - /** - * KQL filter string - */ - filter: z.string(), - }) - ) - .optional(), -}); export type ConfigureRiskEngineSavedObjectRequestBodyInput = z.input< typeof ConfigureRiskEngineSavedObjectRequestBody >; +export const ConfigureRiskEngineSavedObjectResponse = lazySchema(() => + z.object({ + risk_engine_saved_object_configured: z.boolean().optional(), + }) +); export type ConfigureRiskEngineSavedObjectResponse = z.infer< typeof ConfigureRiskEngineSavedObjectResponse >; -export const ConfigureRiskEngineSavedObjectResponse = z.object({ - risk_engine_saved_object_configured: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_disable_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_disable_route.gen.ts index ccfd4e4895a4a..3634f0bb866e9 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_disable_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_disable_route.gen.ts @@ -14,15 +14,19 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const RiskEngineDisableErrorResponse = lazySchema(() => + z.object({ + message: z.string(), + full_error: z.string(), + }) +); export type RiskEngineDisableErrorResponse = z.infer; -export const RiskEngineDisableErrorResponse = z.object({ - message: z.string(), - full_error: z.string(), -}); +export const DisableRiskEngineResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + }) +); export type DisableRiskEngineResponse = z.infer; -export const DisableRiskEngineResponse = z.object({ - success: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_enable_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_enable_route.gen.ts index 448682e4fb1a2..ecfb237ce795d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_enable_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_enable_route.gen.ts @@ -14,15 +14,19 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const EnableRiskEngineErrorResponse = lazySchema(() => + z.object({ + message: z.string(), + full_error: z.string(), + }) +); export type EnableRiskEngineErrorResponse = z.infer; -export const EnableRiskEngineErrorResponse = z.object({ - message: z.string(), - full_error: z.string(), -}); +export const EnableRiskEngineResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + }) +); export type EnableRiskEngineResponse = z.infer; -export const EnableRiskEngineResponse = z.object({ - success: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts index f699ebd2178b9..2a875c3c7f391 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts @@ -14,23 +14,29 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const InitRiskEngineResult = lazySchema(() => + z.object({ + risk_engine_enabled: z.boolean(), + risk_engine_resources_installed: z.boolean(), + risk_engine_configuration_created: z.boolean(), + errors: z.array(z.string()), + }) +); export type InitRiskEngineResult = z.infer; -export const InitRiskEngineResult = z.object({ - risk_engine_enabled: z.boolean(), - risk_engine_resources_installed: z.boolean(), - risk_engine_configuration_created: z.boolean(), - errors: z.array(z.string()), -}); +export const InitRiskEngineErrorResponse = lazySchema(() => + z.object({ + message: z.string(), + full_error: z.string(), + }) +); export type InitRiskEngineErrorResponse = z.infer; -export const InitRiskEngineErrorResponse = z.object({ - message: z.string(), - full_error: z.string(), -}); +export const InitRiskEngineResponse = lazySchema(() => + z.object({ + result: InitRiskEngineResult, + }) +); export type InitRiskEngineResponse = z.infer; -export const InitRiskEngineResponse = z.object({ - result: InitRiskEngineResult, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_schedule_now_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_schedule_now_route.gen.ts index 931e07a500351..2cd3b4aca94a7 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_schedule_now_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_schedule_now_route.gen.ts @@ -14,18 +14,22 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const RiskEngineScheduleNowResponse = lazySchema(() => + z.object({ + success: z.boolean().optional(), + }) +); export type RiskEngineScheduleNowResponse = z.infer; -export const RiskEngineScheduleNowResponse = z.object({ - success: z.boolean().optional(), -}); +export const RiskEngineScheduleNowErrorResponse = lazySchema(() => + z.object({ + message: z.string(), + full_error: z.string(), + }) +); export type RiskEngineScheduleNowErrorResponse = z.infer; -export const RiskEngineScheduleNowErrorResponse = z.object({ - message: z.string(), - full_error: z.string(), -}); +export const ScheduleRiskEngineNowResponse = lazySchema(() => RiskEngineScheduleNowResponse); export type ScheduleRiskEngineNowResponse = z.infer; -export const ScheduleRiskEngineNowResponse = RiskEngineScheduleNowResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_settings_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_settings_route.gen.ts index df8371c214a37..08f9e951944b3 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_settings_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_settings_route.gen.ts @@ -14,30 +14,32 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { DateRange } from '../common/common.gen'; +export const ReadRiskEngineSettingsResponse = lazySchema(() => + z.object({ + range: DateRange.optional(), + /** + * Include closed alerts in the risk score calculation + */ + includeClosedAlerts: z.boolean().optional(), + /** + * Whether to enable resetting risk scores to zero when there are no alerts in the selected date range + */ + enableResetToZero: z.boolean().optional(), + filters: z + .array( + z.object({ + entity_types: z.array(z.enum(['host', 'user', 'service'])), + /** + * KQL filter string + */ + filter: z.string(), + }) + ) + .optional(), + }) +); export type ReadRiskEngineSettingsResponse = z.infer; -export const ReadRiskEngineSettingsResponse = z.object({ - range: DateRange.optional(), - /** - * Include closed alerts in the risk score calculation - */ - includeClosedAlerts: z.boolean().optional(), - /** - * Whether to enable resetting risk scores to zero when there are no alerts in the selected date range - */ - enableResetToZero: z.boolean().optional(), - filters: z - .array( - z.object({ - entity_types: z.array(z.enum(['host', 'user', 'service'])), - /** - * KQL filter string - */ - filter: z.string(), - }) - ) - .optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts index 33721f9a9c48d..4a809afeea708 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts @@ -14,38 +14,36 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const RiskEngineStatus = lazySchema(() => z.enum(['NOT_INSTALLED', 'DISABLED', 'ENABLED'])); export type RiskEngineStatus = z.infer; -export const RiskEngineStatus = z.enum(['NOT_INSTALLED', 'DISABLED', 'ENABLED']); export type RiskEngineStatusEnum = typeof RiskEngineStatus.enum; export const RiskEngineStatusEnum = RiskEngineStatus.enum; +export const RiskEngineTaskStatusValues = lazySchema(() => + z.enum(['idle', 'claiming', 'running', 'failed', 'should_delete', 'unrecognized', 'dead_letter']) +); export type RiskEngineTaskStatusValues = z.infer; -export const RiskEngineTaskStatusValues = z.enum([ - 'idle', - 'claiming', - 'running', - 'failed', - 'should_delete', - 'unrecognized', - 'dead_letter', -]); export type RiskEngineTaskStatusValuesEnum = typeof RiskEngineTaskStatusValues.enum; export const RiskEngineTaskStatusValuesEnum = RiskEngineTaskStatusValues.enum; +export const RiskEngineTaskStatus = lazySchema(() => + z.object({ + status: RiskEngineTaskStatusValues, + runAt: z.string().datetime(), + startedAt: z.string().datetime().optional(), + }) +); export type RiskEngineTaskStatus = z.infer; -export const RiskEngineTaskStatus = z.object({ - status: RiskEngineTaskStatusValues, - runAt: z.string().datetime(), - startedAt: z.string().datetime().optional(), -}); +export const RiskEngineStatusResponse = lazySchema(() => + z.object({ + risk_engine_status: RiskEngineStatus, + risk_engine_task_status: RiskEngineTaskStatus.optional(), + }) +); export type RiskEngineStatusResponse = z.infer; -export const RiskEngineStatusResponse = z.object({ - risk_engine_status: RiskEngineStatus, - risk_engine_task_status: RiskEngineTaskStatus.optional(), -}); +export const GetRiskEngineStatusResponse = lazySchema(() => RiskEngineStatusResponse); export type GetRiskEngineStatusResponse = z.infer; -export const GetRiskEngineStatusResponse = RiskEngineStatusResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/entity_calculation_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/entity_calculation_route.gen.ts index 1c58623cbe25b..6b7b23c14c642 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/entity_calculation_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/entity_calculation_route.gen.ts @@ -14,56 +14,68 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { IdentifierType, EntityRiskScoreRecord } from '../common/common.gen'; +export const RiskScoresEntityCalculationRequest = lazySchema(() => + z.object({ + /** + * Used to identify the entity. + */ + identifier: z.string(), + /** + * Used to define the type of entity. + */ + identifier_type: IdentifierType, + /** + * If 'wait_for' the request will wait for the index refresh. + */ + refresh: z.literal('wait_for').optional(), + }) +); export type RiskScoresEntityCalculationRequest = z.infer; -export const RiskScoresEntityCalculationRequest = z.object({ - /** - * Used to identify the entity. - */ - identifier: z.string(), - /** - * Used to define the type of entity. - */ - identifier_type: IdentifierType, - /** - * If 'wait_for' the request will wait for the index refresh. - */ - refresh: z.literal('wait_for').optional(), -}); +export const RiskScoresEntityCalculationResponse = lazySchema(() => + z.object({ + success: z.boolean(), + score: EntityRiskScoreRecord.optional(), + }) +); export type RiskScoresEntityCalculationResponse = z.infer< typeof RiskScoresEntityCalculationResponse >; -export const RiskScoresEntityCalculationResponse = z.object({ - success: z.boolean(), - score: EntityRiskScoreRecord.optional(), -}); +export const DeprecatedTriggerRiskScoreCalculationRequestBody = lazySchema( + () => RiskScoresEntityCalculationRequest +); export type DeprecatedTriggerRiskScoreCalculationRequestBody = z.infer< typeof DeprecatedTriggerRiskScoreCalculationRequestBody >; -export const DeprecatedTriggerRiskScoreCalculationRequestBody = RiskScoresEntityCalculationRequest; export type DeprecatedTriggerRiskScoreCalculationRequestBodyInput = z.input< typeof DeprecatedTriggerRiskScoreCalculationRequestBody >; +export const DeprecatedTriggerRiskScoreCalculationResponse = lazySchema( + () => RiskScoresEntityCalculationResponse +); export type DeprecatedTriggerRiskScoreCalculationResponse = z.infer< typeof DeprecatedTriggerRiskScoreCalculationResponse >; -export const DeprecatedTriggerRiskScoreCalculationResponse = RiskScoresEntityCalculationResponse; +export const TriggerRiskScoreCalculationRequestBody = lazySchema( + () => RiskScoresEntityCalculationRequest +); export type TriggerRiskScoreCalculationRequestBody = z.infer< typeof TriggerRiskScoreCalculationRequestBody >; -export const TriggerRiskScoreCalculationRequestBody = RiskScoresEntityCalculationRequest; export type TriggerRiskScoreCalculationRequestBodyInput = z.input< typeof TriggerRiskScoreCalculationRequestBody >; +export const TriggerRiskScoreCalculationResponse = lazySchema( + () => RiskScoresEntityCalculationResponse +); export type TriggerRiskScoreCalculationResponse = z.infer< typeof TriggerRiskScoreCalculationResponse >; -export const TriggerRiskScoreCalculationResponse = RiskScoresEntityCalculationResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/get_risk_engine_privileges.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/get_risk_engine_privileges.gen.ts index c90a87f210e97..5a925fa5dab3c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/get_risk_engine_privileges.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/get_risk_engine_privileges.gen.ts @@ -15,8 +15,9 @@ */ import type { z } from '@kbn/zod/v4'; +import { lazySchema } from '@kbn/zod/v4'; import { EntityAnalyticsPrivileges } from '../common/common.gen'; +export const RiskEngineGetPrivilegesResponse = lazySchema(() => EntityAnalyticsPrivileges); export type RiskEngineGetPrivilegesResponse = z.infer; -export const RiskEngineGetPrivilegesResponse = EntityAnalyticsPrivileges; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/preview_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/preview_route.gen.ts index 451f80133dce5..bc42fedbd7a40 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/preview_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/risk_engine/preview_route.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { DataViewId, @@ -27,99 +27,103 @@ import { EntityRiskScoreRecord, } from '../common/common.gen'; -export type RiskScoresPreviewRequest = z.infer; -export const RiskScoresPreviewRequest = z.object({ - /** - * The identifier of the Kibana data view to be used when generating risk scores. If a data view is not found, the provided ID will be used as the query's index pattern instead. - */ - data_view_id: DataViewId, - /** - * Used to retrieve a specific "page" of risk scores. If unspecified, the first "page" of scores is returned. See also the `after_keys` key in a risk scores response. - */ - after_keys: AfterKeys.optional(), - /** - * If set to `true`, a `debug` key is added to the response, containing both the internal request and response with elasticsearch. - */ - debug: z.boolean().optional(), - /** - * An elasticsearch DSL filter object. Used to filter the data being scored, which implicitly filters the risk scores returned. - */ - filter: Filter.optional(), - page_size: PageSize.optional(), - /** - * Used to restrict the type of risk scores involved. If unspecified, both `host` and `user` scores will be returned. - */ - identifier_type: IdentifierType.optional(), - /** - * Defines the time period over which scores will be evaluated. If unspecified, a range of `[now, now-30d]` will be used. - */ - range: DateRange.optional(), - weights: RiskScoreWeights.optional(), - /** - * A list of alert statuses to exclude from the risk score calculation. If unspecified, all alert statuses are included. - */ - exclude_alert_statuses: z.array(z.string()).optional(), - /** - * A list of alert tags to exclude from the risk score calculation. If unspecified, all alert tags are included. - */ - exclude_alert_tags: z.array(z.string()).optional(), - /** - * Custom KQL filters to exclude from risk scoring queries, allowing more targeted risk analysis by filtering out specific alerts. - */ - filters: z - .array( - z.object({ - /** - * The entity types this filter applies to - */ - entity_types: z.array(z.enum(['host', 'user', 'service'])), - /** - * KQL filter expression to exclude (alerts matching this filter will be excluded from risk score calculation) - */ - filter: z.string(), - }) - ) - .optional(), -}); - -export type RiskScoresPreviewResponse = z.infer; -export const RiskScoresPreviewResponse = z.object({ - /** - * Used to obtain the next "page" of risk scores. See also the `after_keys` key in a risk scores request. If this key is empty, the calculation is complete. - */ - after_keys: AfterKeys, - /** - * Object containing debug information, particularly the internal request and response from elasticsearch - */ - debug: z - .object({ - request: z.string().optional(), - response: z.string().optional(), - }) - .optional(), - scores: z.object({ +export const RiskScoresPreviewRequest = lazySchema(() => + z.object({ + /** + * The identifier of the Kibana data view to be used when generating risk scores. If a data view is not found, the provided ID will be used as the query's index pattern instead. + */ + data_view_id: DataViewId, + /** + * Used to retrieve a specific "page" of risk scores. If unspecified, the first "page" of scores is returned. See also the `after_keys` key in a risk scores response. + */ + after_keys: AfterKeys.optional(), + /** + * If set to `true`, a `debug` key is added to the response, containing both the internal request and response with elasticsearch. + */ + debug: z.boolean().optional(), + /** + * An elasticsearch DSL filter object. Used to filter the data being scored, which implicitly filters the risk scores returned. + */ + filter: Filter.optional(), + page_size: PageSize.optional(), + /** + * Used to restrict the type of risk scores involved. If unspecified, both `host` and `user` scores will be returned. + */ + identifier_type: IdentifierType.optional(), /** - * A list of host risk scores + * Defines the time period over which scores will be evaluated. If unspecified, a range of `[now, now-30d]` will be used. */ - host: z.array(EntityRiskScoreRecord).optional(), + range: DateRange.optional(), + weights: RiskScoreWeights.optional(), /** - * A list of user risk scores + * A list of alert statuses to exclude from the risk score calculation. If unspecified, all alert statuses are included. */ - user: z.array(EntityRiskScoreRecord).optional(), + exclude_alert_statuses: z.array(z.string()).optional(), /** - * A list of service risk scores + * A list of alert tags to exclude from the risk score calculation. If unspecified, all alert tags are included. */ - service: z.array(EntityRiskScoreRecord).optional(), + exclude_alert_tags: z.array(z.string()).optional(), /** - * A list of generic entities risk scores + * Custom KQL filters to exclude from risk scoring queries, allowing more targeted risk analysis by filtering out specific alerts. */ - generic: z.array(EntityRiskScoreRecord).optional(), - }), -}); + filters: z + .array( + z.object({ + /** + * The entity types this filter applies to + */ + entity_types: z.array(z.enum(['host', 'user', 'service'])), + /** + * KQL filter expression to exclude (alerts matching this filter will be excluded from risk score calculation) + */ + filter: z.string(), + }) + ) + .optional(), + }) +); +export type RiskScoresPreviewRequest = z.infer; + +export const RiskScoresPreviewResponse = lazySchema(() => + z.object({ + /** + * Used to obtain the next "page" of risk scores. See also the `after_keys` key in a risk scores request. If this key is empty, the calculation is complete. + */ + after_keys: AfterKeys, + /** + * Object containing debug information, particularly the internal request and response from elasticsearch + */ + debug: z + .object({ + request: z.string().optional(), + response: z.string().optional(), + }) + .optional(), + scores: z.object({ + /** + * A list of host risk scores + */ + host: z.array(EntityRiskScoreRecord).optional(), + /** + * A list of user risk scores + */ + user: z.array(EntityRiskScoreRecord).optional(), + /** + * A list of service risk scores + */ + service: z.array(EntityRiskScoreRecord).optional(), + /** + * A list of generic entities risk scores + */ + generic: z.array(EntityRiskScoreRecord).optional(), + }), + }) +); +export type RiskScoresPreviewResponse = z.infer; +export const PreviewRiskScoreRequestBody = lazySchema(() => RiskScoresPreviewRequest); export type PreviewRiskScoreRequestBody = z.infer; -export const PreviewRiskScoreRequestBody = RiskScoresPreviewRequest; export type PreviewRiskScoreRequestBodyInput = z.input; +export const PreviewRiskScoreResponse = lazySchema(() => RiskScoresPreviewResponse); export type PreviewRiskScoreResponse = z.infer; -export const PreviewRiskScoreResponse = RiskScoresPreviewResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/csv_upload/csv_upload.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/csv_upload/csv_upload.gen.ts index a9c811031756c..d31581bdf76d9 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/csv_upload/csv_upload.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/csv_upload/csv_upload.gen.ts @@ -14,47 +14,53 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const WatchlistCsvUploadResponseItem = lazySchema(() => + z.object({ + status: z.enum(['success', 'failure', 'unmatched']), + /** + * Number of entities matched for this row + */ + matchedEntities: z.number().int(), + /** + * Error message if the row failed to process + */ + error: z.string().optional(), + }) +); export type WatchlistCsvUploadResponseItem = z.infer; -export const WatchlistCsvUploadResponseItem = z.object({ - status: z.enum(['success', 'failure', 'unmatched']), - /** - * Number of entities matched for this row - */ - matchedEntities: z.number().int(), - /** - * Error message if the row failed to process - */ - error: z.string().optional(), -}); +export const UploadWatchlistCsvRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the watchlist to add entities to + */ + watchlist_id: z.string(), + }) +); export type UploadWatchlistCsvRequestParams = z.infer; -export const UploadWatchlistCsvRequestParams = z.object({ - /** - * The ID of the watchlist to add entities to - */ - watchlist_id: z.string(), -}); export type UploadWatchlistCsvRequestParamsInput = z.input; +export const UploadWatchlistCsvResponse = lazySchema(() => + z.object({ + /** + * Number of rows that matched at least one entity + */ + successful: z.number().int(), + /** + * Number of rows that failed to process + */ + failed: z.number().int(), + /** + * Total number of rows processed + */ + total: z.number().int(), + /** + * Number of rows that matched no entities + */ + unmatched: z.number().int(), + items: z.array(WatchlistCsvUploadResponseItem), + }) +); export type UploadWatchlistCsvResponse = z.infer; -export const UploadWatchlistCsvResponse = z.object({ - /** - * Number of rows that matched at least one entity - */ - successful: z.number().int(), - /** - * Number of rows that failed to process - */ - failed: z.number().int(), - /** - * Total number of rows processed - */ - total: z.number().int(), - /** - * Number of rows that matched no entities - */ - unmatched: z.number().int(), - items: z.array(WatchlistCsvUploadResponseItem), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts index 3a27d348f6f56..db4e090a8145c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/common.gen.ts @@ -14,94 +14,109 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const EntitySourceType = lazySchema(() => + z.enum(['index', 'entity_analytics_integration', 'store']) +); export type EntitySourceType = z.infer; -export const EntitySourceType = z.enum(['index', 'entity_analytics_integration', 'store']); export type EntitySourceTypeEnum = typeof EntitySourceType.enum; export const EntitySourceTypeEnum = EntitySourceType.enum; -export type Matcher = z.infer; -export const Matcher = z.object({ - fields: z.array(z.string()), - /** +export const Matcher = lazySchema(() => + z.object({ + fields: z.array(z.string()), + /** * Matcher values. Must be either an array of strings (e.g. group or role names) or an array of booleans (e.g. integration-derived flags like privileged_group_member). Mixed types are intentionally not supported for simplicity and predictability. */ - values: z.union([z.array(z.string()), z.array(z.boolean())]), -}); + values: z.union([z.array(z.string()), z.array(z.boolean())]), + }) +); +export type Matcher = z.infer; +export const Filter = lazySchema(() => + z.object({ + kuery: z.union([z.string(), z.object({})]).optional(), + }) +); export type Filter = z.infer; -export const Filter = z.object({ - kuery: z.union([z.string(), z.object({})]).optional(), -}); +export const Integrations = lazySchema(() => + z.object({ + /** + * Index to read latest sync markers from + */ + syncMarkerIndex: z.string().optional(), + /** + * integrations latest full sync and update syncData + */ + syncData: z + .object({ + /** + * Timestamp of the last full sync from integrations + */ + lastFullSync: z.string().datetime().optional(), + /** + * Timestamp of the last update processed from integrations + */ + lastUpdateProcessed: z.string().datetime().optional(), + }) + .optional(), + }) +); export type Integrations = z.infer; -export const Integrations = z.object({ - /** - * Index to read latest sync markers from - */ - syncMarkerIndex: z.string().optional(), - /** - * integrations latest full sync and update syncData - */ - syncData: z - .object({ - /** - * Timestamp of the last full sync from integrations - */ - lastFullSync: z.string().datetime().optional(), - /** - * Timestamp of the last update processed from integrations - */ - lastUpdateProcessed: z.string().datetime().optional(), - }) - .optional(), -}); +export const UpdateableMonitoringEntitySourceProperties = lazySchema(() => + z.object({ + name: z.string().optional(), + indexPattern: z.string().optional(), + integrationName: z.string().optional(), + enabled: z.boolean().optional(), + /** + * Field used to query the entity store for index-type sources + */ + identifierField: z.string().optional(), + /** + * KQL query used to filter data from the provided index patterns + */ + queryRule: z.string().optional(), + matchers: z.array(Matcher).optional(), + filter: Filter.optional(), + integrations: Integrations.optional(), + }) +); export type UpdateableMonitoringEntitySourceProperties = z.infer< typeof UpdateableMonitoringEntitySourceProperties >; -export const UpdateableMonitoringEntitySourceProperties = z.object({ - name: z.string().optional(), - indexPattern: z.string().optional(), - integrationName: z.string().optional(), - enabled: z.boolean().optional(), - /** - * Field used to query the entity store for index-type sources - */ - identifierField: z.string().optional(), - /** - * KQL query used to filter data from the provided index patterns - */ - queryRule: z.string().optional(), - matchers: z.array(Matcher).optional(), - filter: Filter.optional(), - integrations: Integrations.optional(), -}); +export const UpdateEntitySourceNoadditionalProps = lazySchema(() => + UpdateableMonitoringEntitySourceProperties.merge(z.object({}).strict()) +); export type UpdateEntitySourceNoadditionalProps = z.infer< typeof UpdateEntitySourceNoadditionalProps >; -export const UpdateEntitySourceNoadditionalProps = - UpdateableMonitoringEntitySourceProperties.extend(z.object({}).strict()); -export type MonitoringEntitySourceProperties = z.infer; -export const MonitoringEntitySourceProperties = UpdateableMonitoringEntitySourceProperties.extend( - z.object({ - type: EntitySourceType.optional(), - managed: z.boolean().optional(), - }) +export const MonitoringEntitySourceProperties = lazySchema(() => + UpdateableMonitoringEntitySourceProperties.merge( + z.object({ + type: EntitySourceType.optional(), + managed: z.boolean().optional(), + }) + ) ); +export type MonitoringEntitySourceProperties = z.infer; -export type MonitoringEntitySourceAttributes = z.infer; -export const MonitoringEntitySourceAttributes = MonitoringEntitySourceProperties.extend( - z.object({}) +export const MonitoringEntitySourceAttributes = lazySchema(() => + MonitoringEntitySourceProperties.merge(z.object({})) ); +export type MonitoringEntitySourceAttributes = z.infer; -export type MonitoringEntitySource = z.infer; -export const MonitoringEntitySource = MonitoringEntitySourceProperties.extend( - z.object({ - id: z.string(), - }) +export const MonitoringEntitySource = lazySchema(() => + MonitoringEntitySourceProperties.merge( + z.object({ + id: z.string(), + }) + ) ); +export type MonitoringEntitySource = z.infer; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/create.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/create.gen.ts index 7fcbd5af6b607..08b3d8afd92c8 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/create.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/create.gen.ts @@ -14,50 +14,54 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntitySourceType, Matcher, Filter, MonitoringEntitySource } from './common.gen'; +export const CreateWatchlistEntitySourceRequestParams = lazySchema(() => + z.object({ + watchlist_id: z.string(), + }) +); export type CreateWatchlistEntitySourceRequestParams = z.infer< typeof CreateWatchlistEntitySourceRequestParams >; -export const CreateWatchlistEntitySourceRequestParams = z.object({ - watchlist_id: z.string(), -}); export type CreateWatchlistEntitySourceRequestParamsInput = z.input< typeof CreateWatchlistEntitySourceRequestParams >; +export const CreateWatchlistEntitySourceRequestBody = lazySchema(() => + z + .object({ + type: EntitySourceType, + name: z.string(), + indexPattern: z.string().optional(), + /** + * Required when type is entity_analytics_integration. One of entityanalytics_okta, entityanalytics_ad. + */ + integrationName: z.string().optional(), + enabled: z.boolean().optional(), + /** + * Field used to query the entity store for index-type sources + */ + identifierField: z.string().optional(), + /** + * KQL query used to filter data from the provided index patterns + */ + queryRule: z.string().optional(), + matchers: z.array(Matcher).optional(), + filter: Filter.optional(), + }) + .strict() +); export type CreateWatchlistEntitySourceRequestBody = z.infer< typeof CreateWatchlistEntitySourceRequestBody >; -export const CreateWatchlistEntitySourceRequestBody = z - .object({ - type: EntitySourceType, - name: z.string(), - indexPattern: z.string().optional(), - /** - * Required when type is entity_analytics_integration. One of entityanalytics_okta, entityanalytics_ad. - */ - integrationName: z.string().optional(), - enabled: z.boolean().optional(), - /** - * Field used to query the entity store for index-type sources - */ - identifierField: z.string().optional(), - /** - * KQL query used to filter data from the provided index patterns - */ - queryRule: z.string().optional(), - matchers: z.array(Matcher).optional(), - filter: Filter.optional(), - }) - .strict(); export type CreateWatchlistEntitySourceRequestBodyInput = z.input< typeof CreateWatchlistEntitySourceRequestBody >; +export const CreateWatchlistEntitySourceResponse = lazySchema(() => MonitoringEntitySource); export type CreateWatchlistEntitySourceResponse = z.infer< typeof CreateWatchlistEntitySourceResponse >; -export const CreateWatchlistEntitySourceResponse = MonitoringEntitySource; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/delete.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/delete.gen.ts index b0c202c5cbb9d..3c6c3d87b9e4d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/delete.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/delete.gen.ts @@ -14,15 +14,17 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const DeleteWatchlistEntitySourceRequestParams = lazySchema(() => + z.object({ + watchlist_id: z.string(), + id: z.string(), + }) +); export type DeleteWatchlistEntitySourceRequestParams = z.infer< typeof DeleteWatchlistEntitySourceRequestParams >; -export const DeleteWatchlistEntitySourceRequestParams = z.object({ - watchlist_id: z.string(), - id: z.string(), -}); export type DeleteWatchlistEntitySourceRequestParamsInput = z.input< typeof DeleteWatchlistEntitySourceRequestParams >; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/get.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/get.gen.ts index 2bfa50e007fd4..a0156c7697044 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/get.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/get.gen.ts @@ -14,20 +14,22 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { MonitoringEntitySource } from './common.gen'; +export const GetWatchlistEntitySourceRequestParams = lazySchema(() => + z.object({ + watchlist_id: z.string(), + id: z.string(), + }) +); export type GetWatchlistEntitySourceRequestParams = z.infer< typeof GetWatchlistEntitySourceRequestParams >; -export const GetWatchlistEntitySourceRequestParams = z.object({ - watchlist_id: z.string(), - id: z.string(), -}); export type GetWatchlistEntitySourceRequestParamsInput = z.input< typeof GetWatchlistEntitySourceRequestParams >; +export const GetWatchlistEntitySourceResponse = lazySchema(() => MonitoringEntitySource); export type GetWatchlistEntitySourceResponse = z.infer; -export const GetWatchlistEntitySourceResponse = MonitoringEntitySource; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/list.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/list.gen.ts index b35a48c3585c0..7c3eead851eb5 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/list.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/list.gen.ts @@ -14,41 +14,47 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BooleanFromString } from '@kbn/zod-helpers/v4'; import { MonitoringEntitySource } from './common.gen'; +export const ListWatchlistEntitySourcesRequestQuery = lazySchema(() => + z.object({ + type: z.string().optional(), + managed: BooleanFromString.optional(), + name: z.string().optional(), + page: z.coerce.number().int().min(1).optional(), + per_page: z.coerce.number().int().min(1).max(10000).optional(), + sort_field: z.string().optional(), + sort_order: z.enum(['asc', 'desc']).optional(), + }) +); export type ListWatchlistEntitySourcesRequestQuery = z.infer< typeof ListWatchlistEntitySourcesRequestQuery >; -export const ListWatchlistEntitySourcesRequestQuery = z.object({ - type: z.string().optional(), - managed: BooleanFromString.optional(), - name: z.string().optional(), - page: z.coerce.number().int().min(1).optional(), - per_page: z.coerce.number().int().min(1).max(10000).optional(), - sort_field: z.string().optional(), - sort_order: z.enum(['asc', 'desc']).optional(), -}); export type ListWatchlistEntitySourcesRequestQueryInput = z.input< typeof ListWatchlistEntitySourcesRequestQuery >; +export const ListWatchlistEntitySourcesRequestParams = lazySchema(() => + z.object({ + watchlist_id: z.string(), + }) +); export type ListWatchlistEntitySourcesRequestParams = z.infer< typeof ListWatchlistEntitySourcesRequestParams >; -export const ListWatchlistEntitySourcesRequestParams = z.object({ - watchlist_id: z.string(), -}); export type ListWatchlistEntitySourcesRequestParamsInput = z.input< typeof ListWatchlistEntitySourcesRequestParams >; +export const ListWatchlistEntitySourcesResponse = lazySchema(() => + z.object({ + sources: z.array(MonitoringEntitySource), + page: z.number().int().min(1), + per_page: z.number().int().min(1).max(10000), + total: z.number().int().min(0), + }) +); export type ListWatchlistEntitySourcesResponse = z.infer; -export const ListWatchlistEntitySourcesResponse = z.object({ - sources: z.array(MonitoringEntitySource), - page: z.number().int().min(1), - per_page: z.number().int().min(1).max(10000), - total: z.number().int().min(0), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/update.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/update.gen.ts index 2397d3117f61f..ba9468a589985 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/update.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/data_source/update.gen.ts @@ -14,30 +14,34 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { UpdateEntitySourceNoadditionalProps, MonitoringEntitySource } from './common.gen'; +export const UpdateWatchlistEntitySourceRequestParams = lazySchema(() => + z.object({ + watchlist_id: z.string(), + id: z.string(), + }) +); export type UpdateWatchlistEntitySourceRequestParams = z.infer< typeof UpdateWatchlistEntitySourceRequestParams >; -export const UpdateWatchlistEntitySourceRequestParams = z.object({ - watchlist_id: z.string(), - id: z.string(), -}); export type UpdateWatchlistEntitySourceRequestParamsInput = z.input< typeof UpdateWatchlistEntitySourceRequestParams >; +export const UpdateWatchlistEntitySourceRequestBody = lazySchema( + () => UpdateEntitySourceNoadditionalProps +); export type UpdateWatchlistEntitySourceRequestBody = z.infer< typeof UpdateWatchlistEntitySourceRequestBody >; -export const UpdateWatchlistEntitySourceRequestBody = UpdateEntitySourceNoadditionalProps; export type UpdateWatchlistEntitySourceRequestBodyInput = z.input< typeof UpdateWatchlistEntitySourceRequestBody >; +export const UpdateWatchlistEntitySourceResponse = lazySchema(() => MonitoringEntitySource); export type UpdateWatchlistEntitySourceResponse = z.infer< typeof UpdateWatchlistEntitySourceResponse >; -export const UpdateWatchlistEntitySourceResponse = MonitoringEntitySource; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/assign.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/assign.gen.ts index 8c0a8c05c0cff..5259d2395efc8 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/assign.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/assign.gen.ts @@ -14,62 +14,70 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const WatchlistEntityAssignResponseItem = lazySchema(() => + z.object({ + /** + * The EUID of the entity + */ + euid: z.string(), + status: z.enum(['success', 'failure', 'not_found']), + /** + * Error message if the entity failed to process + */ + error: z.string().optional(), + }) +); export type WatchlistEntityAssignResponseItem = z.infer; -export const WatchlistEntityAssignResponseItem = z.object({ - /** - * The EUID of the entity - */ - euid: z.string(), - status: z.enum(['success', 'failure', 'not_found']), - /** - * Error message if the entity failed to process - */ - error: z.string().optional(), -}); +export const AssignWatchlistEntitiesRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the watchlist to add entities to + */ + watchlist_id: z.string(), + }) +); export type AssignWatchlistEntitiesRequestParams = z.infer< typeof AssignWatchlistEntitiesRequestParams >; -export const AssignWatchlistEntitiesRequestParams = z.object({ - /** - * The ID of the watchlist to add entities to - */ - watchlist_id: z.string(), -}); export type AssignWatchlistEntitiesRequestParamsInput = z.input< typeof AssignWatchlistEntitiesRequestParams >; +export const AssignWatchlistEntitiesRequestBody = lazySchema(() => + z.object({ + /** + * The EUIDs of the entities to assign + */ + euids: z.array(z.string()), + }) +); export type AssignWatchlistEntitiesRequestBody = z.infer; -export const AssignWatchlistEntitiesRequestBody = z.object({ - /** - * The EUIDs of the entities to assign - */ - euids: z.array(z.string()), -}); export type AssignWatchlistEntitiesRequestBodyInput = z.input< typeof AssignWatchlistEntitiesRequestBody >; +export const AssignWatchlistEntitiesResponse = lazySchema(() => + z.object({ + /** + * Number of entities successfully assigned + */ + successful: z.number().int(), + /** + * Number of entities that failed to process + */ + failed: z.number().int(), + /** + * Number of entities not found in the entity store + */ + not_found: z.number().int(), + /** + * Total number of entities processed + */ + total: z.number().int(), + items: z.array(WatchlistEntityAssignResponseItem), + }) +); export type AssignWatchlistEntitiesResponse = z.infer; -export const AssignWatchlistEntitiesResponse = z.object({ - /** - * Number of entities successfully assigned - */ - successful: z.number().int(), - /** - * Number of entities that failed to process - */ - failed: z.number().int(), - /** - * Number of entities not found in the entity store - */ - not_found: z.number().int(), - /** - * Total number of entities processed - */ - total: z.number().int(), - items: z.array(WatchlistEntityAssignResponseItem), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/unassign.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/unassign.gen.ts index d3f3b9e579482..7e1c0fc51b5b9 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/unassign.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/entities/unassign.gen.ts @@ -14,66 +14,74 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const WatchlistEntityUnassignResponseItem = lazySchema(() => + z.object({ + /** + * The EUID of the entity + */ + euid: z.string(), + status: z.enum(['success', 'failure', 'not_found']), + /** + * Error message if the entity failed to process + */ + error: z.string().optional(), + }) +); export type WatchlistEntityUnassignResponseItem = z.infer< typeof WatchlistEntityUnassignResponseItem >; -export const WatchlistEntityUnassignResponseItem = z.object({ - /** - * The EUID of the entity - */ - euid: z.string(), - status: z.enum(['success', 'failure', 'not_found']), - /** - * Error message if the entity failed to process - */ - error: z.string().optional(), -}); +export const UnassignWatchlistEntitiesRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the watchlist to remove entities from + */ + watchlist_id: z.string(), + }) +); export type UnassignWatchlistEntitiesRequestParams = z.infer< typeof UnassignWatchlistEntitiesRequestParams >; -export const UnassignWatchlistEntitiesRequestParams = z.object({ - /** - * The ID of the watchlist to remove entities from - */ - watchlist_id: z.string(), -}); export type UnassignWatchlistEntitiesRequestParamsInput = z.input< typeof UnassignWatchlistEntitiesRequestParams >; +export const UnassignWatchlistEntitiesRequestBody = lazySchema(() => + z.object({ + /** + * The EUIDs of the entities to unassign + */ + euids: z.array(z.string()), + }) +); export type UnassignWatchlistEntitiesRequestBody = z.infer< typeof UnassignWatchlistEntitiesRequestBody >; -export const UnassignWatchlistEntitiesRequestBody = z.object({ - /** - * The EUIDs of the entities to unassign - */ - euids: z.array(z.string()), -}); export type UnassignWatchlistEntitiesRequestBodyInput = z.input< typeof UnassignWatchlistEntitiesRequestBody >; +export const UnassignWatchlistEntitiesResponse = lazySchema(() => + z.object({ + /** + * Number of entities successfully unassigned + */ + successful: z.number().int(), + /** + * Number of entities that failed to process + */ + failed: z.number().int(), + /** + * Number of entities not found in the manual watchlist assignment + */ + not_found: z.number().int(), + /** + * Total number of entities processed + */ + total: z.number().int(), + items: z.array(WatchlistEntityUnassignResponseItem), + }) +); export type UnassignWatchlistEntitiesResponse = z.infer; -export const UnassignWatchlistEntitiesResponse = z.object({ - /** - * Number of entities successfully unassigned - */ - successful: z.number().int(), - /** - * Number of entities that failed to process - */ - failed: z.number().int(), - /** - * Number of entities not found in the manual watchlist assignment - */ - not_found: z.number().int(), - /** - * Total number of entities processed - */ - total: z.number().int(), - items: z.array(WatchlistEntityUnassignResponseItem), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/common.gen.ts index f3f3f99bdd86c..a5c84ab2d3801 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/common.gen.ts @@ -14,44 +14,46 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const WatchlistObject = lazySchema(() => + z.object({ + /** + * The unique ID of the watchlist + */ + id: z.string().optional(), + /** + * The name of the watchlist + */ + name: z.string(), + /** + * Description of the watchlist + */ + description: z.string().optional(), + /** + * Indicates if the watchlist is managed by the system + */ + managed: z.boolean(), + /** + * Risk score modifier associated with the watchlist + */ + riskModifier: z.number(), + /** + * List of entity source IDs associated with the watchlist + */ + entitySourceIds: z.array(z.string()).optional(), + /** + * Number of entities in the watchlist + */ + entityCount: z.number().optional(), + /** + * Timestamp indicating when the watchlist was created + */ + createdAt: z.string().datetime().optional(), + /** + * Timestamp indicating when the watchlist was last updated + */ + updatedAt: z.string().datetime().optional(), + }) +); export type WatchlistObject = z.infer; -export const WatchlistObject = z.object({ - /** - * The unique ID of the watchlist - */ - id: z.string().optional(), - /** - * The name of the watchlist - */ - name: z.string(), - /** - * Description of the watchlist - */ - description: z.string().optional(), - /** - * Indicates if the watchlist is managed by the system - */ - managed: z.boolean(), - /** - * Risk score modifier associated with the watchlist - */ - riskModifier: z.number(), - /** - * List of entity source IDs associated with the watchlist - */ - entitySourceIds: z.array(z.string()).optional(), - /** - * Number of entities in the watchlist - */ - entityCount: z.number().optional(), - /** - * Timestamp indicating when the watchlist was created - */ - createdAt: z.string().datetime().optional(), - /** - * Timestamp indicating when the watchlist was last updated - */ - updatedAt: z.string().datetime().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts index 159f2c29a9497..a777f88fcfefe 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/create.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { EntitySourceType, @@ -24,59 +24,63 @@ import { } from '../data_source/common.gen'; import { WatchlistObject } from './common.gen'; +export const CreateWatchlistRequestBody = lazySchema(() => + z.object({ + /** + * Unique name for the watchlist + */ + name: z.string(), + /** + * Description of the watchlist + */ + description: z.string().optional(), + /** + * Risk score modifier associated with the watchlist + */ + riskModifier: z.number().min(0).max(2), + /** + * Indicates if the watchlist is managed by the system + */ + managed: z.boolean().optional(), + /** + * Optional entity sources to create and link to the watchlist + */ + entitySources: z + .array( + z + .object({ + type: EntitySourceType, + name: z.string(), + indexPattern: z.string().optional(), + /** + * Required when type is entity_analytics_integration. One of entityanalytics_okta, entityanalytics_ad. + */ + integrationName: z.string().optional(), + enabled: z.boolean().optional(), + /** + * Field used to query the entity store for index-type sources + */ + identifierField: z.string().optional(), + /** + * KQL query used to filter data from the provided index patterns + */ + queryRule: z.string().optional(), + matchers: z.array(Matcher).optional(), + filter: Filter.optional(), + }) + .strict() + ) + .optional(), + }) +); export type CreateWatchlistRequestBody = z.infer; -export const CreateWatchlistRequestBody = z.object({ - /** - * Unique name for the watchlist - */ - name: z.string(), - /** - * Description of the watchlist - */ - description: z.string().optional(), - /** - * Risk score modifier associated with the watchlist - */ - riskModifier: z.number().min(0).max(2), - /** - * Indicates if the watchlist is managed by the system - */ - managed: z.boolean().optional(), - /** - * Optional entity sources to create and link to the watchlist - */ - entitySources: z - .array( - z - .object({ - type: EntitySourceType, - name: z.string(), - indexPattern: z.string().optional(), - /** - * Required when type is entity_analytics_integration. One of entityanalytics_okta, entityanalytics_ad. - */ - integrationName: z.string().optional(), - enabled: z.boolean().optional(), - /** - * Field used to query the entity store for index-type sources - */ - identifierField: z.string().optional(), - /** - * KQL query used to filter data from the provided index patterns - */ - queryRule: z.string().optional(), - matchers: z.array(Matcher).optional(), - filter: Filter.optional(), - }) - .strict() - ) - .optional(), -}); export type CreateWatchlistRequestBodyInput = z.input; -export type CreateWatchlistResponse = z.infer; -export const CreateWatchlistResponse = WatchlistObject.extend( - z.object({ - entitySources: z.array(MonitoringEntitySource).optional(), - }) +export const CreateWatchlistResponse = lazySchema(() => + WatchlistObject.merge( + z.object({ + entitySources: z.array(MonitoringEntitySource).optional(), + }) + ) ); +export type CreateWatchlistResponse = z.infer; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/get.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/get.gen.ts index 35489f2bd6480..6644b6898a6ac 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/get.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/get.gen.ts @@ -14,18 +14,20 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { WatchlistObject } from './common.gen'; +export const GetWatchlistRequestParams = lazySchema(() => + z.object({ + /** + * Unique ID of the watchlist + */ + id: z.string(), + }) +); export type GetWatchlistRequestParams = z.infer; -export const GetWatchlistRequestParams = z.object({ - /** - * Unique ID of the watchlist - */ - id: z.string(), -}); export type GetWatchlistRequestParamsInput = z.input; +export const GetWatchlistResponse = lazySchema(() => WatchlistObject); export type GetWatchlistResponse = z.infer; -export const GetWatchlistResponse = WatchlistObject; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/list.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/list.gen.ts index da88e4d5e42a8..c9f30b728ae32 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/list.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/list.gen.ts @@ -14,9 +14,9 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { WatchlistObject } from './common.gen'; +export const ListWatchlistsResponse = lazySchema(() => z.array(WatchlistObject)); export type ListWatchlistsResponse = z.infer; -export const ListWatchlistsResponse = z.array(WatchlistObject); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/update.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/update.gen.ts index 1b5341ee5ba56..6602fb8144206 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/update.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/management/update.gen.ts @@ -14,39 +14,43 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { WatchlistObject } from './common.gen'; +export const UpdateWatchlistRequestParams = lazySchema(() => + z.object({ + /** + * The ID of the watchlist to update + */ + id: z.string(), + }) +); export type UpdateWatchlistRequestParams = z.infer; -export const UpdateWatchlistRequestParams = z.object({ - /** - * The ID of the watchlist to update - */ - id: z.string(), -}); export type UpdateWatchlistRequestParamsInput = z.input; +export const UpdateWatchlistRequestBody = lazySchema(() => + z.object({ + /** + * Unique name of the watchlist + */ + name: z.string(), + /** + * Description of the watchlist + */ + description: z.string().optional(), + /** + * Risk score modifier associated with the watchlist + */ + riskModifier: z.number().min(0).max(2), + /** + * Indicates if the watchlist is managed by the system + */ + managed: z.boolean().optional(), + }) +); export type UpdateWatchlistRequestBody = z.infer; -export const UpdateWatchlistRequestBody = z.object({ - /** - * Unique name of the watchlist - */ - name: z.string(), - /** - * Description of the watchlist - */ - description: z.string().optional(), - /** - * Risk score modifier associated with the watchlist - */ - riskModifier: z.number().min(0).max(2), - /** - * Indicates if the watchlist is managed by the system - */ - managed: z.boolean().optional(), -}); export type UpdateWatchlistRequestBodyInput = z.input; +export const UpdateWatchlistResponse = lazySchema(() => WatchlistObject); export type UpdateWatchlistResponse = z.infer; -export const UpdateWatchlistResponse = WatchlistObject; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/sync/sync.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/sync/sync.gen.ts index 949828cbbaee8..17db624d4162a 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/sync/sync.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/entity_analytics/watchlists/sync/sync.gen.ts @@ -14,15 +14,19 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const SyncWatchlistRequestParams = lazySchema(() => + z.object({ + watchlist_id: z.string().min(1), + }) +); export type SyncWatchlistRequestParams = z.infer; -export const SyncWatchlistRequestParams = z.object({ - watchlist_id: z.string().min(1), -}); export type SyncWatchlistRequestParamsInput = z.input; +export const SyncWatchlistResponse = lazySchema(() => + z.object({ + acknowledged: z.boolean(), + }) +); export type SyncWatchlistResponse = z.infer; -export const SyncWatchlistResponse = z.object({ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/initialization/initialization.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/initialization/initialization.gen.ts index fcb320402d9a3..879d3ea50f690 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/initialization/initialization.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/initialization/initialization.gen.ts @@ -14,70 +14,86 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Identifier for an initialization flow. */ +export const InitializationFlowId = lazySchema(() => + z.enum(['create-list-indices', 'security-data-views']) +); export type InitializationFlowId = z.infer; -export const InitializationFlowId = z.enum(['create-list-indices', 'security-data-views']); export type InitializationFlowIdEnum = typeof InitializationFlowId.enum; export const InitializationFlowIdEnum = InitializationFlowId.enum; +export const CreateListIndicesReadyResult = lazySchema(() => + z.object({ + status: z.literal('ready'), + }) +); export type CreateListIndicesReadyResult = z.infer; -export const CreateListIndicesReadyResult = z.object({ - status: z.literal('ready'), -}); +export const InitializationFlowErrorResult = lazySchema(() => + z.object({ + status: z.literal('error'), + error: z.string().nullable(), + }) +); export type InitializationFlowErrorResult = z.infer; -export const InitializationFlowErrorResult = z.object({ - status: z.literal('error'), - error: z.string().nullable(), -}); +export const DataViewPayload = lazySchema(() => + z.object({ + id: z.string(), + title: z.string(), + patternList: z.array(z.string()), + }) +); export type DataViewPayload = z.infer; -export const DataViewPayload = z.object({ - id: z.string(), - title: z.string(), - patternList: z.array(z.string()), -}); +export const SecurityDataViewsReadyResult = lazySchema(() => + z.object({ + status: z.literal('ready'), + payload: z.object({ + defaultDataView: DataViewPayload, + alertDataView: DataViewPayload, + attackDataView: DataViewPayload.optional(), + kibanaDataViews: z.array(DataViewPayload), + signalIndexName: z.string(), + }), + }) +); export type SecurityDataViewsReadyResult = z.infer; -export const SecurityDataViewsReadyResult = z.object({ - status: z.literal('ready'), - payload: z.object({ - defaultDataView: DataViewPayload, - alertDataView: DataViewPayload, - attackDataView: DataViewPayload.optional(), - kibanaDataViews: z.array(DataViewPayload), - signalIndexName: z.string(), - }), -}); /** * Per-flow results. Only requested flows appear in the response, so all properties are optional. Each flow is either a typed ready result or an error result. */ +export const InitializationFlowsResult = lazySchema(() => + z.object({ + 'create-list-indices': z + .union([CreateListIndicesReadyResult, InitializationFlowErrorResult]) + .optional(), + 'security-data-views': z + .union([SecurityDataViewsReadyResult, InitializationFlowErrorResult]) + .optional(), + }) +); export type InitializationFlowsResult = z.infer; -export const InitializationFlowsResult = z.object({ - 'create-list-indices': z - .union([CreateListIndicesReadyResult, InitializationFlowErrorResult]) - .optional(), - 'security-data-views': z - .union([SecurityDataViewsReadyResult, InitializationFlowErrorResult]) - .optional(), -}); +export const InitializeSecuritySolutionRequestBody = lazySchema(() => + z.object({ + flows: z.array(InitializationFlowId).min(1), + }) +); export type InitializeSecuritySolutionRequestBody = z.infer< typeof InitializeSecuritySolutionRequestBody >; -export const InitializeSecuritySolutionRequestBody = z.object({ - flows: z.array(InitializationFlowId).min(1), -}); export type InitializeSecuritySolutionRequestBodyInput = z.input< typeof InitializeSecuritySolutionRequestBody >; +export const InitializeSecuritySolutionResponse = lazySchema(() => + z.object({ + flows: InitializationFlowsResult, + }) +); export type InitializeSecuritySolutionResponse = z.infer; -export const InitializeSecuritySolutionResponse = z.object({ - flows: InitializationFlowsResult, -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/model/alert.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/model/alert.gen.ts index 110548a25c9cb..377ab3b44ca41 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/model/alert.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/model/alert.gen.ts @@ -14,39 +14,45 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; /** * A list of alerts `id`s. */ +export const AlertIds = lazySchema(() => + z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1) +); export type AlertIds = z.infer; -export const AlertIds = z.array(z.string().min(1).superRefine(isNonEmptyString)).min(1); /** * Use alert tags to organize related alerts into categories that you can filter and group. */ +export const AlertTag = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type AlertTag = z.infer; -export const AlertTag = z.string().min(1).superRefine(isNonEmptyString); /** * List of keywords to organize related alerts into categories that you can filter and group. */ +export const AlertTags = lazySchema(() => z.array(AlertTag)); export type AlertTags = z.infer; -export const AlertTags = z.array(AlertTag); /** * The status of an alert, which can be `open`, `acknowledged`, `in-progress`, or `closed`. */ +export const AlertStatus = lazySchema(() => + z.enum(['open', 'closed', 'acknowledged', 'in-progress']) +); export type AlertStatus = z.infer; -export const AlertStatus = z.enum(['open', 'closed', 'acknowledged', 'in-progress']); export type AlertStatusEnum = typeof AlertStatus.enum; export const AlertStatusEnum = AlertStatus.enum; /** * The status of an alert, which can be `open`, `acknowledged`, `in-progress`, or `closed`. */ +export const AlertStatusExceptClosed = lazySchema(() => + z.enum(['open', 'acknowledged', 'in-progress']) +); export type AlertStatusExceptClosed = z.infer; -export const AlertStatusExceptClosed = z.enum(['open', 'acknowledged', 'in-progress']); export type AlertStatusExceptClosedEnum = typeof AlertStatusExceptClosed.enum; export const AlertStatusExceptClosedEnum = AlertStatusExceptClosed.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/model/error_responses.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/model/error_responses.gen.ts index 9808c23af99d8..cf47a0a1b9690 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/model/error_responses.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/model/error_responses.gen.ts @@ -14,17 +14,21 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const PlatformErrorResponse = lazySchema(() => + z.object({ + statusCode: z.number().int(), + error: z.string(), + message: z.string(), + }) +); export type PlatformErrorResponse = z.infer; -export const PlatformErrorResponse = z.object({ - statusCode: z.number().int(), - error: z.string(), - message: z.string(), -}); +export const SiemErrorResponse = lazySchema(() => + z.object({ + status_code: z.number().int(), + message: z.string(), + }) +); export type SiemErrorResponse = z.infer; -export const SiemErrorResponse = z.object({ - status_code: z.number().int(), - message: z.string(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/model/primitives.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/model/primitives.gen.ts index 7b5ce75077a7b..8a9280a9a957f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/model/primitives.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/model/primitives.gen.ts @@ -14,17 +14,17 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isNonEmptyString } from '@kbn/zod-helpers/v4'; /** * A string that does not contain only whitespace characters */ +export const NonEmptyString = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString)); export type NonEmptyString = z.infer; -export const NonEmptyString = z.string().min(1).superRefine(isNonEmptyString); /** * A universally unique identifier */ +export const UUID = lazySchema(() => z.string().uuid()); export type UUID = z.infer; -export const UUID = z.string().uuid(); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.gen.ts index 6d618e0ee7698..7bafbba3c03e3 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/clean_draft_timelines/clean_draft_timelines_route.gen.ts @@ -14,15 +14,17 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { TimelineType, PersistTimelineResponse } from '../model/components.gen'; +export const CleanDraftTimelinesRequestBody = lazySchema(() => + z.object({ + timelineType: TimelineType, + }) +); export type CleanDraftTimelinesRequestBody = z.infer; -export const CleanDraftTimelinesRequestBody = z.object({ - timelineType: TimelineType, -}); export type CleanDraftTimelinesRequestBodyInput = z.input; +export const CleanDraftTimelinesResponse = lazySchema(() => PersistTimelineResponse); export type CleanDraftTimelinesResponse = z.infer; -export const CleanDraftTimelinesResponse = PersistTimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/copy_timeline/copy_timeline_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/copy_timeline/copy_timeline_route.gen.ts index 69de6fafc036c..c1c67d88b8e84 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/copy_timeline/copy_timeline_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/copy_timeline/copy_timeline_route.gen.ts @@ -14,16 +14,18 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedTimeline, PersistTimelineResponse } from '../model/components.gen'; +export const CopyTimelineRequestBody = lazySchema(() => + z.object({ + timeline: SavedTimeline, + timelineIdToCopy: z.string(), + }) +); export type CopyTimelineRequestBody = z.infer; -export const CopyTimelineRequestBody = z.object({ - timeline: SavedTimeline, - timelineIdToCopy: z.string(), -}); export type CopyTimelineRequestBodyInput = z.input; +export const CopyTimelineResponse = lazySchema(() => PersistTimelineResponse); export type CopyTimelineResponse = z.infer; -export const CopyTimelineResponse = PersistTimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.gen.ts index d9da8fc0657d2..2844874288c42 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/create_timelines/create_timelines_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedTimeline, @@ -23,26 +23,28 @@ import { PersistTimelineResponse, } from '../model/components.gen'; +export const CreateTimelinesRequestBody = lazySchema(() => + z.object({ + timeline: SavedTimeline, + status: TimelineStatus.nullable().optional(), + /** + * A unique identifier for the Timeline template. + */ + templateTimelineId: z.string().nullable().optional(), + /** + * Timeline template version number. + */ + templateTimelineVersion: z.number().nullable().optional(), + /** + * A unique identifier for the Timeline. + */ + timelineId: z.string().nullable().optional(), + timelineType: TimelineType.nullable().optional(), + version: z.string().nullable().optional(), + }) +); export type CreateTimelinesRequestBody = z.infer; -export const CreateTimelinesRequestBody = z.object({ - timeline: SavedTimeline, - status: TimelineStatus.nullable().optional(), - /** - * A unique identifier for the Timeline template. - */ - templateTimelineId: z.string().nullable().optional(), - /** - * Timeline template version number. - */ - templateTimelineVersion: z.number().nullable().optional(), - /** - * A unique identifier for the Timeline. - */ - timelineId: z.string().nullable().optional(), - timelineType: TimelineType.nullable().optional(), - version: z.string().nullable().optional(), -}); export type CreateTimelinesRequestBodyInput = z.input; +export const CreateTimelinesResponse = lazySchema(() => PersistTimelineResponse); export type CreateTimelinesResponse = z.infer; -export const CreateTimelinesResponse = PersistTimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.gen.ts index d8ba12a91eab9..a2883830cb086 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_note/delete_note_route.gen.ts @@ -14,19 +14,21 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const DeleteNoteRequestBody = lazySchema(() => + z.union([ + z + .object({ + noteId: z.string(), + }) + .nullable(), + z + .object({ + noteIds: z.array(z.string()).nullable(), + }) + .nullable(), + ]) +); export type DeleteNoteRequestBody = z.infer; -export const DeleteNoteRequestBody = z.union([ - z - .object({ - noteId: z.string(), - }) - .nullable(), - z - .object({ - noteIds: z.array(z.string()).nullable(), - }) - .nullable(), -]); export type DeleteNoteRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.gen.ts index b6b1688ae162f..b440be48b9817 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.gen.ts @@ -14,17 +14,19 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const DeleteTimelinesRequestBody = lazySchema(() => + z.object({ + /** + * The list of IDs of the Timelines or Timeline templates to delete + */ + savedObjectIds: z.array(z.string()).max(100), + /** + * Saved search IDs that should be deleted alongside the timelines + */ + searchIds: z.array(z.string()).max(100).optional(), + }) +); export type DeleteTimelinesRequestBody = z.infer; -export const DeleteTimelinesRequestBody = z.object({ - /** - * The list of IDs of the Timelines or Timeline templates to delete - */ - savedObjectIds: z.array(z.string()).max(100), - /** - * Saved search IDs that should be deleted alongside the timelines - */ - searchIds: z.array(z.string()).max(100).optional(), -}); export type DeleteTimelinesRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.gen.ts index 4d0ebbd7f8c13..a037ed9c1e126 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/export_timelines/export_timelines_route.gen.ts @@ -14,19 +14,23 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const ExportTimelinesRequestQuery = lazySchema(() => + z.object({ + /** + * The name of the file to export + */ + file_name: z.string(), + }) +); export type ExportTimelinesRequestQuery = z.infer; -export const ExportTimelinesRequestQuery = z.object({ - /** - * The name of the file to export - */ - file_name: z.string(), -}); export type ExportTimelinesRequestQueryInput = z.input; +export const ExportTimelinesRequestBody = lazySchema(() => + z.object({ + ids: z.array(z.string()).min(1).max(1000).nullable().optional(), + }) +); export type ExportTimelinesRequestBody = z.infer; -export const ExportTimelinesRequestBody = z.object({ - ids: z.array(z.string()).min(1).max(1000).nullable().optional(), -}); export type ExportTimelinesRequestBodyInput = z.input; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.gen.ts index 28e54933efd6e..cd6a93b064235 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.gen.ts @@ -14,15 +14,17 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { TimelineType, PersistTimelineResponse } from '../model/components.gen'; +export const GetDraftTimelinesRequestQuery = lazySchema(() => + z.object({ + timelineType: TimelineType, + }) +); export type GetDraftTimelinesRequestQuery = z.infer; -export const GetDraftTimelinesRequestQuery = z.object({ - timelineType: TimelineType, -}); export type GetDraftTimelinesRequestQueryInput = z.input; +export const GetDraftTimelinesResponse = lazySchema(() => PersistTimelineResponse); export type GetDraftTimelinesResponse = z.infer; -export const GetDraftTimelinesResponse = PersistTimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_notes/get_notes_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_notes/get_notes_route.gen.ts index 7f7603c585722..d18c79e0989db 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_notes/get_notes_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_notes/get_notes_route.gen.ts @@ -14,50 +14,50 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Note } from '../model/components.gen'; /** * Filter notes based on their association with a document or saved object. */ +export const AssociatedFilterType = lazySchema(() => + z.enum(['all', 'document_only', 'saved_object_only', 'document_and_saved_object', 'orphan']) +); export type AssociatedFilterType = z.infer; -export const AssociatedFilterType = z.enum([ - 'all', - 'document_only', - 'saved_object_only', - 'document_and_saved_object', - 'orphan', -]); export type AssociatedFilterTypeEnum = typeof AssociatedFilterType.enum; export const AssociatedFilterTypeEnum = AssociatedFilterType.enum; +export const DocumentIds = lazySchema(() => z.union([z.array(z.string()), z.string()])); export type DocumentIds = z.infer; -export const DocumentIds = z.union([z.array(z.string()), z.string()]); +export const SavedObjectIds = lazySchema(() => z.union([z.array(z.string()), z.string()])); export type SavedObjectIds = z.infer; -export const SavedObjectIds = z.union([z.array(z.string()), z.string()]); +export const GetNotesResult = lazySchema(() => + z.object({ + totalCount: z.number(), + notes: z.array(Note), + }) +); export type GetNotesResult = z.infer; -export const GetNotesResult = z.object({ - totalCount: z.number(), - notes: z.array(Note), -}); +export const GetNotesRequestQuery = lazySchema(() => + z.object({ + documentIds: DocumentIds.optional(), + savedObjectIds: SavedObjectIds.optional(), + page: z.string().nullable().optional(), + perPage: z.string().nullable().optional(), + search: z.string().nullable().optional(), + sortField: z.string().nullable().optional(), + sortOrder: z.string().nullable().optional(), + filter: z.string().nullable().optional(), + createdByFilter: z.string().nullable().optional(), + associatedFilter: AssociatedFilterType.optional(), + }) +); export type GetNotesRequestQuery = z.infer; -export const GetNotesRequestQuery = z.object({ - documentIds: DocumentIds.optional(), - savedObjectIds: SavedObjectIds.optional(), - page: z.string().nullable().optional(), - perPage: z.string().nullable().optional(), - search: z.string().nullable().optional(), - sortField: z.string().nullable().optional(), - sortOrder: z.string().nullable().optional(), - filter: z.string().nullable().optional(), - createdByFilter: z.string().nullable().optional(), - associatedFilter: AssociatedFilterType.optional(), -}); export type GetNotesRequestQueryInput = z.input; +export const GetNotesResponse = lazySchema(() => GetNotesResult); export type GetNotesResponse = z.infer; -export const GetNotesResponse = GetNotesResult; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.gen.ts index 030f562223bd2..48aae29399aee 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.gen.ts @@ -14,22 +14,24 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { TimelineResponse } from '../model/components.gen'; +export const GetTimelineRequestQuery = lazySchema(() => + z.object({ + /** + * The `savedObjectId` of the template timeline to retrieve + */ + template_timeline_id: z.string().optional(), + /** + * The `savedObjectId` of the Timeline to retrieve. + */ + id: z.string().optional(), + }) +); export type GetTimelineRequestQuery = z.infer; -export const GetTimelineRequestQuery = z.object({ - /** - * The `savedObjectId` of the template timeline to retrieve - */ - template_timeline_id: z.string().optional(), - /** - * The `savedObjectId` of the Timeline to retrieve. - */ - id: z.string().optional(), -}); export type GetTimelineRequestQueryInput = z.input; +export const GetTimelineResponse = lazySchema(() => TimelineResponse); export type GetTimelineResponse = z.infer; -export const GetTimelineResponse = TimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.gen.ts index 4e445021419f6..d5cda5cb3c0ec 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { TimelineType, @@ -23,59 +23,63 @@ import { TimelineResponse, } from '../model/components.gen'; +export const GetTimelinesRequestQuery = lazySchema(() => + z.object({ + /** + * If true, only timelines that are marked as favorites by the user are returned. + */ + only_user_favorite: z.enum(['true', 'false']).nullable().optional(), + timeline_type: TimelineType.nullable().optional(), + sort_field: SortFieldTimeline.optional(), + /** + * Whether to sort the results `ascending` or `descending` + */ + sort_order: z.enum(['asc', 'desc']).optional(), + /** + * How many results should returned at once + */ + page_size: z.string().nullable().optional(), + /** + * How many pages should be skipped + */ + page_index: z.string().nullable().optional(), + /** + * Allows to search for timelines by their title + */ + search: z.string().nullable().optional(), + status: TimelineStatus.nullable().optional(), + }) +); export type GetTimelinesRequestQuery = z.infer; -export const GetTimelinesRequestQuery = z.object({ - /** - * If true, only timelines that are marked as favorites by the user are returned. - */ - only_user_favorite: z.enum(['true', 'false']).nullable().optional(), - timeline_type: TimelineType.nullable().optional(), - sort_field: SortFieldTimeline.optional(), - /** - * Whether to sort the results `ascending` or `descending` - */ - sort_order: z.enum(['asc', 'desc']).optional(), - /** - * How many results should returned at once - */ - page_size: z.string().nullable().optional(), - /** - * How many pages should be skipped - */ - page_index: z.string().nullable().optional(), - /** - * Allows to search for timelines by their title - */ - search: z.string().nullable().optional(), - status: TimelineStatus.nullable().optional(), -}); export type GetTimelinesRequestQueryInput = z.input; +export const GetTimelinesResponse = lazySchema(() => + z.object({ + timeline: z.array(TimelineResponse), + /** + * The total amount of results + */ + totalCount: z.number(), + /** + * The amount of `default` type Timelines in the results + */ + defaultTimelineCount: z.number().optional(), + /** + * The amount of Timeline templates in the results + */ + templateTimelineCount: z.number().optional(), + /** + * The amount of favorited Timelines + */ + favoriteCount: z.number().optional(), + /** + * The amount of Elastic's Timeline templates in the results + */ + elasticTemplateTimelineCount: z.number().optional(), + /** + * The amount of custom Timeline templates in the results + */ + customTemplateTimelineCount: z.number().optional(), + }) +); export type GetTimelinesResponse = z.infer; -export const GetTimelinesResponse = z.object({ - timeline: z.array(TimelineResponse), - /** - * The total amount of results - */ - totalCount: z.number(), - /** - * The amount of `default` type Timelines in the results - */ - defaultTimelineCount: z.number().optional(), - /** - * The amount of Timeline templates in the results - */ - templateTimelineCount: z.number().optional(), - /** - * The amount of favorited Timelines - */ - favoriteCount: z.number().optional(), - /** - * The amount of Elastic's Timeline templates in the results - */ - elasticTemplateTimelineCount: z.number().optional(), - /** - * The amount of custom Timeline templates in the results - */ - customTemplateTimelineCount: z.number().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.gen.ts index faf6bbe00d00d..eb343771adb7d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/import_timelines/import_timelines_route.gen.ts @@ -14,19 +14,21 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ImportTimelineResult } from '../model/components.gen'; +export const ImportTimelinesRequestBody = lazySchema(() => + z.object({ + /** + * Whether the Timeline should be immutable + */ + isImmutable: z.enum(['true', 'false']).optional(), + file: z.unknown(), + }) +); export type ImportTimelinesRequestBody = z.infer; -export const ImportTimelinesRequestBody = z.object({ - /** - * Whether the Timeline should be immutable - */ - isImmutable: z.enum(['true', 'false']).optional(), - file: z.unknown(), -}); export type ImportTimelinesRequestBodyInput = z.input; +export const ImportTimelinesResponse = lazySchema(() => ImportTimelineResult); export type ImportTimelinesResponse = z.infer; -export const ImportTimelinesResponse = ImportTimelineResult; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen.ts index 1c56564d17d2c..5777f25fd371e 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen.ts @@ -14,7 +14,7 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ImportTimelines, @@ -22,17 +22,19 @@ import { ImportTimelineResult, } from '../model/components.gen'; +export const InstallPrepackedTimelinesRequestBody = lazySchema(() => + z.object({ + timelinesToInstall: z.array(ImportTimelines.nullable()), + timelinesToUpdate: z.array(ImportTimelines.nullable()), + prepackagedTimelines: z.array(TimelineSavedToReturnObject.nullable()), + }) +); export type InstallPrepackedTimelinesRequestBody = z.infer< typeof InstallPrepackedTimelinesRequestBody >; -export const InstallPrepackedTimelinesRequestBody = z.object({ - timelinesToInstall: z.array(ImportTimelines.nullable()), - timelinesToUpdate: z.array(ImportTimelines.nullable()), - prepackagedTimelines: z.array(TimelineSavedToReturnObject.nullable()), -}); export type InstallPrepackedTimelinesRequestBodyInput = z.input< typeof InstallPrepackedTimelinesRequestBody >; +export const InstallPrepackedTimelinesResponse = lazySchema(() => ImportTimelineResult); export type InstallPrepackedTimelinesResponse = z.infer; -export const InstallPrepackedTimelinesResponse = ImportTimelineResult; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts index a79160cab7e3a..2c5bb8bf7d6f0 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/model/components.gen.ts @@ -14,576 +14,629 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The type of Timeline. */ +export const TimelineType = lazySchema(() => z.enum(['default', 'template'])); export type TimelineType = z.infer; -export const TimelineType = z.enum(['default', 'template']); export type TimelineTypeEnum = typeof TimelineType.enum; export const TimelineTypeEnum = TimelineType.enum; /** * The type of data provider. */ +export const DataProviderType = lazySchema(() => z.enum(['default', 'template'])); export type DataProviderType = z.infer; -export const DataProviderType = z.enum(['default', 'template']); export type DataProviderTypeEnum = typeof DataProviderType.enum; export const DataProviderTypeEnum = DataProviderType.enum; /** * The type of the timeline template. */ +export const TemplateTimelineType = lazySchema(() => z.enum(['elastic', 'custom'])); export type TemplateTimelineType = z.infer; -export const TemplateTimelineType = z.enum(['elastic', 'custom']); export type TemplateTimelineTypeEnum = typeof TemplateTimelineType.enum; export const TemplateTimelineTypeEnum = TemplateTimelineType.enum; +export const ColumnHeaderResult = lazySchema(() => + z.object({ + aggregatable: z.boolean().nullable().optional(), + category: z.string().nullable().optional(), + columnHeaderType: z.string().nullable().optional(), + description: z.string().nullable().optional(), + example: z.string().nullable().optional(), + indexes: z.array(z.string()).nullable().optional(), + id: z.string().nullable().optional(), + name: z.string().nullable().optional(), + placeholder: z.string().nullable().optional(), + searchable: z.boolean().nullable().optional(), + type: z.string().nullable().optional(), + }) +); export type ColumnHeaderResult = z.infer; -export const ColumnHeaderResult = z.object({ - aggregatable: z.boolean().nullable().optional(), - category: z.string().nullable().optional(), - columnHeaderType: z.string().nullable().optional(), - description: z.string().nullable().optional(), - example: z.string().nullable().optional(), - indexes: z.array(z.string()).nullable().optional(), - id: z.string().nullable().optional(), - name: z.string().nullable().optional(), - placeholder: z.string().nullable().optional(), - searchable: z.boolean().nullable().optional(), - type: z.string().nullable().optional(), -}); +export const QueryMatchResult = lazySchema(() => + z.object({ + field: z.string().nullable().optional(), + displayField: z.string().nullable().optional(), + value: z.union([z.string().nullable(), z.array(z.string()).nullable()]).optional(), + displayValue: z.string().nullable().optional(), + operator: z.string().nullable().optional(), + }) +); export type QueryMatchResult = z.infer; -export const QueryMatchResult = z.object({ - field: z.string().nullable().optional(), - displayField: z.string().nullable().optional(), - value: z.union([z.string().nullable(), z.array(z.string()).nullable()]).optional(), - displayValue: z.string().nullable().optional(), - operator: z.string().nullable().optional(), -}); +export const DataProviderQueryMatch = lazySchema(() => + z.object({ + enabled: z.boolean().nullable().optional(), + excluded: z.boolean().nullable().optional(), + id: z.string().nullable().optional(), + kqlQuery: z.string().nullable().optional(), + name: z.string().nullable().optional(), + queryMatch: QueryMatchResult.nullable().optional(), + type: DataProviderType.nullable().optional(), + }) +); export type DataProviderQueryMatch = z.infer; -export const DataProviderQueryMatch = z.object({ - enabled: z.boolean().nullable().optional(), - excluded: z.boolean().nullable().optional(), - id: z.string().nullable().optional(), - kqlQuery: z.string().nullable().optional(), - name: z.string().nullable().optional(), - queryMatch: QueryMatchResult.nullable().optional(), - type: DataProviderType.nullable().optional(), -}); +export const DataProviderResult = lazySchema(() => + z.object({ + and: z.array(DataProviderQueryMatch).nullable().optional(), + enabled: z.boolean().nullable().optional(), + excluded: z.boolean().nullable().optional(), + id: z.string().nullable().optional(), + kqlQuery: z.string().nullable().optional(), + name: z.string().nullable().optional(), + queryMatch: QueryMatchResult.nullable().optional(), + type: DataProviderType.nullable().optional(), + }) +); export type DataProviderResult = z.infer; -export const DataProviderResult = z.object({ - and: z.array(DataProviderQueryMatch).nullable().optional(), - enabled: z.boolean().nullable().optional(), - excluded: z.boolean().nullable().optional(), - id: z.string().nullable().optional(), - kqlQuery: z.string().nullable().optional(), - name: z.string().nullable().optional(), - queryMatch: QueryMatchResult.nullable().optional(), - type: DataProviderType.nullable().optional(), -}); /** * Identifies the available row renderers */ +export const RowRendererId = lazySchema(() => + z.enum([ + 'alert', + 'alerts', + 'auditd', + 'auditd_file', + 'library', + 'netflow', + 'plain', + 'registry', + 'suricata', + 'system', + 'system_dns', + 'system_endgame_process', + 'system_file', + 'system_fim', + 'system_security_event', + 'system_socket', + 'threat_match', + 'zeek', + ]) +); export type RowRendererId = z.infer; -export const RowRendererId = z.enum([ - 'alert', - 'alerts', - 'auditd', - 'auditd_file', - 'library', - 'netflow', - 'plain', - 'registry', - 'suricata', - 'system', - 'system_dns', - 'system_endgame_process', - 'system_file', - 'system_fim', - 'system_security_event', - 'system_socket', - 'threat_match', - 'zeek', -]); export type RowRendererIdEnum = typeof RowRendererId.enum; export const RowRendererIdEnum = RowRendererId.enum; /** * Indicates when and who marked a Timeline as a favorite. */ +export const FavoriteTimelineResult = lazySchema(() => + z.object({ + fullName: z.string().nullable().optional(), + userName: z.string().nullable().optional(), + favoriteDate: z.number().nullable().optional(), + }) +); export type FavoriteTimelineResult = z.infer; -export const FavoriteTimelineResult = z.object({ - fullName: z.string().nullable().optional(), - userName: z.string().nullable().optional(), - favoriteDate: z.number().nullable().optional(), -}); +export const FilterTimelineResult = lazySchema(() => + z.object({ + exists: z.string().nullable().optional(), + meta: z + .object({ + alias: z.string().nullable().optional(), + controlledBy: z.string().nullable().optional(), + disabled: z.boolean().nullable().optional(), + field: z.string().nullable().optional(), + formattedValue: z.string().nullable().optional(), + index: z.string().nullable().optional(), + key: z.string().nullable().optional(), + negate: z.boolean().nullable().optional(), + params: z.string().nullable().optional(), + type: z.string().nullable().optional(), + value: z.string().nullable().optional(), + }) + .nullable() + .optional(), + match_all: z.string().nullable().optional(), + missing: z.string().nullable().optional(), + query: z.string().nullable().optional(), + range: z.string().nullable().optional(), + script: z.string().nullable().optional(), + }) +); export type FilterTimelineResult = z.infer; -export const FilterTimelineResult = z.object({ - exists: z.string().nullable().optional(), - meta: z - .object({ - alias: z.string().nullable().optional(), - controlledBy: z.string().nullable().optional(), - disabled: z.boolean().nullable().optional(), - field: z.string().nullable().optional(), - formattedValue: z.string().nullable().optional(), - index: z.string().nullable().optional(), - key: z.string().nullable().optional(), - negate: z.boolean().nullable().optional(), - params: z.string().nullable().optional(), - type: z.string().nullable().optional(), - value: z.string().nullable().optional(), - }) - .nullable() - .optional(), - match_all: z.string().nullable().optional(), - missing: z.string().nullable().optional(), - query: z.string().nullable().optional(), - range: z.string().nullable().optional(), - script: z.string().nullable().optional(), -}); /** * KQL bar query. */ +export const SerializedFilterQueryResult = lazySchema(() => + z.object({ + filterQuery: z + .object({ + kuery: z + .object({ + kind: z.string().nullable().optional(), + expression: z.string().nullable().optional(), + }) + .nullable() + .optional(), + serializedQuery: z.string().nullable().optional(), + }) + .nullable() + .optional(), + }) +); export type SerializedFilterQueryResult = z.infer; -export const SerializedFilterQueryResult = z.object({ - filterQuery: z - .object({ - kuery: z - .object({ - kind: z.string().nullable().optional(), - expression: z.string().nullable().optional(), - }) - .nullable() - .optional(), - serializedQuery: z.string().nullable().optional(), - }) - .nullable() - .optional(), -}); /** * Object indicating how rows are sorted in the Timeline's grid */ +export const SortObject = lazySchema(() => + z.object({ + columnId: z.string().nullable().optional(), + columnType: z.string().nullable().optional(), + sortDirection: z.string().nullable().optional(), + }) +); export type SortObject = z.infer; -export const SortObject = z.object({ - columnId: z.string().nullable().optional(), - columnType: z.string().nullable().optional(), - sortDirection: z.string().nullable().optional(), -}); +export const Sort = lazySchema(() => z.union([SortObject, z.array(SortObject)])); export type Sort = z.infer; -export const Sort = z.union([SortObject, z.array(SortObject)]); /** * The status of the Timeline. */ +export const TimelineStatus = lazySchema(() => z.enum(['active', 'draft', 'immutable'])); export type TimelineStatus = z.infer; -export const TimelineStatus = z.enum(['active', 'draft', 'immutable']); export type TimelineStatusEnum = typeof TimelineStatus.enum; export const TimelineStatusEnum = TimelineStatus.enum; -export type SavedTimeline = z.infer; -export const SavedTimeline = z.object({ - /** - * The Timeline's columns - */ - columns: z.array(ColumnHeaderResult).nullable().optional(), - /** - * The time the Timeline was created, using a 13-digit Epoch timestamp. - */ - created: z.number().nullable().optional(), - /** - * The user who created the Timeline. - */ - createdBy: z.string().nullable().optional(), - /** - * Object containing query clauses - */ - dataProviders: z.array(DataProviderResult).nullable().optional(), - /** - * ID of the Timeline's Data View - */ - dataViewId: z.string().nullable().optional(), - /** - * The Timeline's search period. - */ - dateRange: z - .object({ - end: z.union([z.string().nullable(), z.number().nullable()]).optional(), - start: z.union([z.string().nullable(), z.number().nullable()]).optional(), - }) - .nullable() - .optional(), - /** - * The Timeline's description - */ - description: z.string().nullable().optional(), - /** - * EQL query that is used in the correlation tab - */ - eqlOptions: z - .object({ - eventCategoryField: z.string().nullable().optional(), - query: z.string().nullable().optional(), - size: z.union([z.string().nullable(), z.number().nullable()]).optional(), - tiebreakerField: z.string().nullable().optional(), - timestampField: z.string().nullable().optional(), - }) - .nullable() - .optional(), - /** - * Event types displayed in the Timeline - */ - eventType: z.string().nullable().optional(), - /** - * A list of row renderers that should not be used when in `Event renderers` mode - */ - excludedRowRendererIds: z.array(RowRendererId).nullable().optional(), - favorite: z.array(FavoriteTimelineResult).nullable().optional(), - /** - * A list of filters that should be applied to the query - */ - filters: z.array(FilterTimelineResult).nullable().optional(), - /** - * Indicates whether the KQL bar filters the query results or searches for additional results, where: - * `filter`: filters query results - * `search`: displays additional search results - */ - kqlMode: z.string().nullable().optional(), - kqlQuery: SerializedFilterQueryResult.nullable().optional(), - /** - * A list of index names to use in the query (e.g. when the default data view has been modified) - */ - indexNames: z.array(z.string()).nullable().optional(), - /** - * The ID of the saved search that is used in the ES|QL tab - */ - savedSearchId: z.string().nullable().optional(), - /** - * The ID of the saved query that might be used in the Query tab - */ - savedQueryId: z.string().nullable().optional(), - sort: Sort.nullable().optional(), - status: TimelineStatus.nullable().optional(), - /** - * The Timeline's title. - */ - title: z.string().nullable().optional(), - /** - * A unique ID (UUID) for Timeline templates. For Timelines, the value is `null`. - */ - templateTimelineId: z.string().nullable().optional(), - /** - * Timeline template version number. For Timelines, the value is `null`. - */ - templateTimelineVersion: z.number().nullable().optional(), - timelineType: TimelineType.nullable().optional(), - /** - * The last time the Timeline was updated, using a 13-digit Epoch timestamp - */ - updated: z.number().nullable().optional(), - /** - * The user who last updated the Timeline - */ - updatedBy: z.string().nullable().optional(), -}); - -export type SavedTimelineWithSavedObjectId = z.infer; -export const SavedTimelineWithSavedObjectId = SavedTimeline.extend( +export const SavedTimeline = lazySchema(() => z.object({ /** - * The `savedObjectId` of the Timeline or Timeline template + * The Timeline's columns */ - savedObjectId: z.string(), + columns: z.array(ColumnHeaderResult).nullable().optional(), /** - * The version of the Timeline or Timeline template + * The time the Timeline was created, using a 13-digit Epoch timestamp. */ - version: z.string(), - }) -); - -export type NoteCreatedAndUpdatedMetadata = z.infer; -export const NoteCreatedAndUpdatedMetadata = z.object({ - /** - * The time the note was created, using a 13-digit Epoch timestamp. - */ - created: z.number().nullable().optional(), - /** - * The user who created the note. - */ - createdBy: z.string().nullable().optional(), - /** - * The last time the note was updated, using a 13-digit Epoch timestamp - */ - updated: z.number().nullable().optional(), - /** - * The user who last updated the note - */ - updatedBy: z.string().nullable().optional(), -}); - -export type BareNote = z.infer; -export const BareNote = NoteCreatedAndUpdatedMetadata.extend( - z.object({ + created: z.number().nullable().optional(), /** - * The `_id` of the associated event for this note. + * The user who created the Timeline. */ - eventId: z.string().nullable().optional(), + createdBy: z.string().nullable().optional(), /** - * The text of the note + * Object containing query clauses */ - note: z.string().nullable().optional(), + dataProviders: z.array(DataProviderResult).nullable().optional(), /** - * The `savedObjectId` of the Timeline that this note is associated with + * ID of the Timeline's Data View */ - timelineId: z.string(), - }) -); - -export type Note = z.infer; -export const Note = BareNote.extend( - z.object({ + dataViewId: z.string().nullable().optional(), /** - * The `savedObjectId` of the note + * The Timeline's search period. */ - noteId: z.string(), + dateRange: z + .object({ + end: z.union([z.string().nullable(), z.number().nullable()]).optional(), + start: z.union([z.string().nullable(), z.number().nullable()]).optional(), + }) + .nullable() + .optional(), /** - * The version of the note + * The Timeline's description */ - version: z.string(), + description: z.string().nullable().optional(), + /** + * EQL query that is used in the correlation tab + */ + eqlOptions: z + .object({ + eventCategoryField: z.string().nullable().optional(), + query: z.string().nullable().optional(), + size: z.union([z.string().nullable(), z.number().nullable()]).optional(), + tiebreakerField: z.string().nullable().optional(), + timestampField: z.string().nullable().optional(), + }) + .nullable() + .optional(), + /** + * Event types displayed in the Timeline + */ + eventType: z.string().nullable().optional(), + /** + * A list of row renderers that should not be used when in `Event renderers` mode + */ + excludedRowRendererIds: z.array(RowRendererId).nullable().optional(), + favorite: z.array(FavoriteTimelineResult).nullable().optional(), + /** + * A list of filters that should be applied to the query + */ + filters: z.array(FilterTimelineResult).nullable().optional(), + /** + * Indicates whether the KQL bar filters the query results or searches for additional results, where: + * `filter`: filters query results + * `search`: displays additional search results + */ + kqlMode: z.string().nullable().optional(), + kqlQuery: SerializedFilterQueryResult.nullable().optional(), + /** + * A list of index names to use in the query (e.g. when the default data view has been modified) + */ + indexNames: z.array(z.string()).nullable().optional(), + /** + * The ID of the saved search that is used in the ES|QL tab + */ + savedSearchId: z.string().nullable().optional(), + /** + * The ID of the saved query that might be used in the Query tab + */ + savedQueryId: z.string().nullable().optional(), + sort: Sort.nullable().optional(), + status: TimelineStatus.nullable().optional(), + /** + * The Timeline's title. + */ + title: z.string().nullable().optional(), + /** + * A unique ID (UUID) for Timeline templates. For Timelines, the value is `null`. + */ + templateTimelineId: z.string().nullable().optional(), + /** + * Timeline template version number. For Timelines, the value is `null`. + */ + templateTimelineVersion: z.number().nullable().optional(), + timelineType: TimelineType.nullable().optional(), + /** + * The last time the Timeline was updated, using a 13-digit Epoch timestamp + */ + updated: z.number().nullable().optional(), + /** + * The user who last updated the Timeline + */ + updatedBy: z.string().nullable().optional(), }) ); +export type SavedTimeline = z.infer; -export type PinnedEventCreatedAndUpdatedMetadata = z.infer< - typeof PinnedEventCreatedAndUpdatedMetadata ->; -export const PinnedEventCreatedAndUpdatedMetadata = z.object({ - /** - * The time the pinned event was created, using a 13-digit Epoch timestamp. - */ - created: z.number().nullable().optional(), - /** - * The user who created the pinned event. - */ - createdBy: z.string().nullable().optional(), - /** - * The last time the pinned event was updated, using a 13-digit Epoch timestamp - */ - updated: z.number().nullable().optional(), - /** - * The user who last updated the pinned event - */ - updatedBy: z.string().nullable().optional(), -}); +export const SavedTimelineWithSavedObjectId = lazySchema(() => + SavedTimeline.merge( + z.object({ + /** + * The `savedObjectId` of the Timeline or Timeline template + */ + savedObjectId: z.string(), + /** + * The version of the Timeline or Timeline template + */ + version: z.string(), + }) + ) +); +export type SavedTimelineWithSavedObjectId = z.infer; -export type BarePinnedEvent = z.infer; -export const BarePinnedEvent = PinnedEventCreatedAndUpdatedMetadata.extend( +export const NoteCreatedAndUpdatedMetadata = lazySchema(() => z.object({ /** - * The `_id` of the associated event for this pinned event. + * The time the note was created, using a 13-digit Epoch timestamp. */ - eventId: z.string(), + created: z.number().nullable().optional(), /** - * The `savedObjectId` of the timeline that this pinned event is associated with + * The user who created the note. */ - timelineId: z.string(), - }) -); - -export type PinnedEvent = z.infer; -export const PinnedEvent = BarePinnedEvent.extend( - z.object({ + createdBy: z.string().nullable().optional(), /** - * The `savedObjectId` of this pinned event + * The last time the note was updated, using a 13-digit Epoch timestamp */ - pinnedEventId: z.string(), + updated: z.number().nullable().optional(), /** - * The version of this pinned event + * The user who last updated the note */ - version: z.string(), + updatedBy: z.string().nullable().optional(), }) ); +export type NoteCreatedAndUpdatedMetadata = z.infer; -export type TimelineResponse = z.infer; -export const TimelineResponse = SavedTimeline.extend(SavedTimelineWithSavedObjectId).extend( +export const BareNote = lazySchema(() => + NoteCreatedAndUpdatedMetadata.merge( + z.object({ + /** + * The `_id` of the associated event for this note. + */ + eventId: z.string().nullable().optional(), + /** + * The text of the note + */ + note: z.string().nullable().optional(), + /** + * The `savedObjectId` of the Timeline that this note is associated with + */ + timelineId: z.string(), + }) + ) +); +export type BareNote = z.infer; + +export const Note = lazySchema(() => + BareNote.merge( + z.object({ + /** + * The `savedObjectId` of the note + */ + noteId: z.string(), + /** + * The version of the note + */ + version: z.string(), + }) + ) +); +export type Note = z.infer; + +export const PinnedEventCreatedAndUpdatedMetadata = lazySchema(() => z.object({ /** - * A list of all the notes that are associated to this Timeline. - */ - eventIdToNoteIds: z.array(Note).nullable().optional(), - /** - * A list of all the notes that are associated to this Timeline. + * The time the pinned event was created, using a 13-digit Epoch timestamp. */ - notes: z.array(Note).nullable().optional(), + created: z.number().nullable().optional(), /** - * A list of all the ids of notes that are associated to this Timeline. + * The user who created the pinned event. */ - noteIds: z.array(z.string()).nullable().optional(), + createdBy: z.string().nullable().optional(), /** - * A list of all the ids of pinned events that are associated to this Timeline. + * The last time the pinned event was updated, using a 13-digit Epoch timestamp */ - pinnedEventIds: z.array(z.string()).nullable().optional(), + updated: z.number().nullable().optional(), /** - * A list of all the pinned events that are associated to this Timeline. + * The user who last updated the pinned event */ - pinnedEventsSaveObject: z.array(PinnedEvent).nullable().optional(), + updatedBy: z.string().nullable().optional(), }) ); +export type PinnedEventCreatedAndUpdatedMetadata = z.infer< + typeof PinnedEventCreatedAndUpdatedMetadata +>; -export type TimelineSavedToReturnObject = z.infer; -export const TimelineSavedToReturnObject = SavedTimeline.extend( - z.object({ - savedObjectId: z.string(), - version: z.string(), - eventIdToNoteIds: z.array(Note).nullable().optional(), - notes: z.array(Note).nullable().optional(), - noteIds: z.array(z.string()).nullable().optional(), - pinnedEventIds: z.array(z.string()).nullable().optional(), - pinnedEventsSaveObject: z.array(PinnedEvent).nullable().optional(), - }) +export const BarePinnedEvent = lazySchema(() => + PinnedEventCreatedAndUpdatedMetadata.merge( + z.object({ + /** + * The `_id` of the associated event for this pinned event. + */ + eventId: z.string(), + /** + * The `savedObjectId` of the timeline that this pinned event is associated with + */ + timelineId: z.string(), + }) + ) ); +export type BarePinnedEvent = z.infer; +export const PinnedEvent = lazySchema(() => + BarePinnedEvent.merge( + z.object({ + /** + * The `savedObjectId` of this pinned event + */ + pinnedEventId: z.string(), + /** + * The version of this pinned event + */ + version: z.string(), + }) + ) +); +export type PinnedEvent = z.infer; + +export const TimelineResponse = lazySchema(() => + SavedTimeline.merge(SavedTimelineWithSavedObjectId).merge( + z.object({ + /** + * A list of all the notes that are associated to this Timeline. + */ + eventIdToNoteIds: z.array(Note).nullable().optional(), + /** + * A list of all the notes that are associated to this Timeline. + */ + notes: z.array(Note).nullable().optional(), + /** + * A list of all the ids of notes that are associated to this Timeline. + */ + noteIds: z.array(z.string()).nullable().optional(), + /** + * A list of all the ids of pinned events that are associated to this Timeline. + */ + pinnedEventIds: z.array(z.string()).nullable().optional(), + /** + * A list of all the pinned events that are associated to this Timeline. + */ + pinnedEventsSaveObject: z.array(PinnedEvent).nullable().optional(), + }) + ) +); +export type TimelineResponse = z.infer; + +export const TimelineSavedToReturnObject = lazySchema(() => + SavedTimeline.merge( + z.object({ + savedObjectId: z.string(), + version: z.string(), + eventIdToNoteIds: z.array(Note).nullable().optional(), + notes: z.array(Note).nullable().optional(), + noteIds: z.array(z.string()).nullable().optional(), + pinnedEventIds: z.array(z.string()).nullable().optional(), + pinnedEventsSaveObject: z.array(PinnedEvent).nullable().optional(), + }) + ) +); +export type TimelineSavedToReturnObject = z.infer; + +export const SavedObjectResolveOutcome = lazySchema(() => + z.enum(['exactMatch', 'aliasMatch', 'conflict']) +); export type SavedObjectResolveOutcome = z.infer; -export const SavedObjectResolveOutcome = z.enum(['exactMatch', 'aliasMatch', 'conflict']); export type SavedObjectResolveOutcomeEnum = typeof SavedObjectResolveOutcome.enum; export const SavedObjectResolveOutcomeEnum = SavedObjectResolveOutcome.enum; +export const SavedObjectResolveAliasPurpose = lazySchema(() => + z.enum(['savedObjectConversion', 'savedObjectImport']) +); export type SavedObjectResolveAliasPurpose = z.infer; -export const SavedObjectResolveAliasPurpose = z.enum([ - 'savedObjectConversion', - 'savedObjectImport', -]); export type SavedObjectResolveAliasPurposeEnum = typeof SavedObjectResolveAliasPurpose.enum; export const SavedObjectResolveAliasPurposeEnum = SavedObjectResolveAliasPurpose.enum; +export const ResolvedTimeline = lazySchema(() => + z.object({ + timeline: TimelineSavedToReturnObject, + outcome: SavedObjectResolveOutcome, + alias_target_id: z.string().optional(), + alias_purpose: SavedObjectResolveAliasPurpose.optional(), + }) +); export type ResolvedTimeline = z.infer; -export const ResolvedTimeline = z.object({ - timeline: TimelineSavedToReturnObject, - outcome: SavedObjectResolveOutcome, - alias_target_id: z.string().optional(), - alias_purpose: SavedObjectResolveAliasPurpose.optional(), -}); +export const FavoriteTimelineResponse = lazySchema(() => + z.object({ + savedObjectId: z.string(), + version: z.string(), + templateTimelineId: z.string().nullable().optional(), + templateTimelineVersion: z.number().nullable().optional(), + timelineType: TimelineType.optional(), + favorite: z.array(FavoriteTimelineResult).optional(), + }) +); export type FavoriteTimelineResponse = z.infer; -export const FavoriteTimelineResponse = z.object({ - savedObjectId: z.string(), - version: z.string(), - templateTimelineId: z.string().nullable().optional(), - templateTimelineVersion: z.number().nullable().optional(), - timelineType: TimelineType.optional(), - favorite: z.array(FavoriteTimelineResult).optional(), -}); +export const PersistTimelineResponse = lazySchema(() => TimelineResponse); export type PersistTimelineResponse = z.infer; -export const PersistTimelineResponse = TimelineResponse; -export type BareNoteWithoutExternalRefs = z.infer; -export const BareNoteWithoutExternalRefs = NoteCreatedAndUpdatedMetadata.extend( - z.object({ - /** - * The `_id` of the associated event for this note. - */ - eventId: z.string().nullable().optional(), - /** - * The text of the note - */ - note: z.string().nullable().optional(), - /** - * The `savedObjectId` of the timeline that this note is associated with - */ - timelineId: z.string().optional(), - }) +export const BareNoteWithoutExternalRefs = lazySchema(() => + NoteCreatedAndUpdatedMetadata.merge( + z.object({ + /** + * The `_id` of the associated event for this note. + */ + eventId: z.string().nullable().optional(), + /** + * The text of the note + */ + note: z.string().nullable().optional(), + /** + * The `savedObjectId` of the timeline that this note is associated with + */ + timelineId: z.string().optional(), + }) + ) ); +export type BareNoteWithoutExternalRefs = z.infer; /** * The field to sort the timelines by. */ +export const SortFieldTimeline = lazySchema(() => + z.enum(['title', 'description', 'updated', 'created']) +); export type SortFieldTimeline = z.infer; -export const SortFieldTimeline = z.enum(['title', 'description', 'updated', 'created']); export type SortFieldTimelineEnum = typeof SortFieldTimeline.enum; export const SortFieldTimelineEnum = SortFieldTimeline.enum; +export const SortDirection = lazySchema(() => z.enum(['asc', 'desc'])); export type SortDirection = z.infer; -export const SortDirection = z.enum(['asc', 'desc']); export type SortDirectionEnum = typeof SortDirection.enum; export const SortDirectionEnum = SortDirection.enum; +export const ImportTimelines = lazySchema(() => + SavedTimeline.merge( + z.object({ + savedObjectId: z.string().nullable(), + version: z.string().nullable(), + pinnedEventIds: z.array(z.string()).nullable(), + eventNotes: z.array(BareNote).nullable(), + globalNotes: z.array(BareNote).nullable(), + }) + ) +); export type ImportTimelines = z.infer; -export const ImportTimelines = SavedTimeline.extend( + +export const ImportTimelineResult = lazySchema(() => z.object({ - savedObjectId: z.string().nullable(), - version: z.string().nullable(), - pinnedEventIds: z.array(z.string()).nullable(), - eventNotes: z.array(BareNote).nullable(), - globalNotes: z.array(BareNote).nullable(), + /** + * Indicates whether any of the Timelines were successfully imports + */ + success: z.boolean().optional(), + /** + * The amount of successfully imported/updated Timelines + */ + success_count: z.number().optional(), + /** + * The amount of successfully installed Timelines + */ + timelines_installed: z.number().optional(), + /** + * The amount of successfully updated Timelines + */ + timelines_updated: z.number().optional(), + /** + * The list of failed Timeline imports + */ + errors: z + .array( + z.object({ + /** + * The ID of the timeline that failed to import + */ + id: z.string().optional(), + /** + * The error containing the reason why the timeline could not be imported + */ + error: z + .object({ + /** + * The reason why the timeline could not be imported + */ + message: z.string().optional(), + /** + * The HTTP status code of the error + */ + status_code: z.number().optional(), + }) + .optional(), + }) + ) + .optional(), }) ); - export type ImportTimelineResult = z.infer; -export const ImportTimelineResult = z.object({ - /** - * Indicates whether any of the Timelines were successfully imports - */ - success: z.boolean().optional(), - /** - * The amount of successfully imported/updated Timelines - */ - success_count: z.number().optional(), - /** - * The amount of successfully installed Timelines - */ - timelines_installed: z.number().optional(), - /** - * The amount of successfully updated Timelines - */ - timelines_updated: z.number().optional(), - /** - * The list of failed Timeline imports - */ - errors: z - .array( - z.object({ - /** - * The ID of the timeline that failed to import - */ - id: z.string().optional(), - /** - * The error containing the reason why the timeline could not be imported - */ - error: z - .object({ - /** - * The reason why the timeline could not be imported - */ - message: z.string().optional(), - /** - * The HTTP status code of the error - */ - status_code: z.number().optional(), - }) - .optional(), - }) - ) - .optional(), -}); +export const TimelineErrorResponse = lazySchema(() => + z.union([ + z.object({ + message: z.string(), + status_code: z.number(), + }), + z.object({ + message: z.string(), + statusCode: z.number(), + }), + ]) +); export type TimelineErrorResponse = z.infer; -export const TimelineErrorResponse = z.union([ - z.object({ - message: z.string(), - status_code: z.number(), - }), - z.object({ - message: z.string(), - statusCode: z.number(), - }), -]); diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/patch_timelines/patch_timeline_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/patch_timelines/patch_timeline_route.gen.ts index 21cd1e0d5bf49..3b8205797ef6f 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/patch_timelines/patch_timeline_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/patch_timelines/patch_timeline_route.gen.ts @@ -14,26 +14,28 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SavedTimeline, PersistTimelineResponse } from '../model/components.gen'; +export const PatchTimelineRequestBody = lazySchema(() => + z.object({ + /** + * The `savedObjectId` of the Timeline or Timeline template that you’re updating. + */ + timelineId: z.string().nullable(), + /** + * The version of the Timeline or Timeline template that you’re updating. + */ + version: z.string().nullable(), + /** + * The timeline object of the Timeline or Timeline template that you’re updating. + */ + timeline: SavedTimeline, + }) +); export type PatchTimelineRequestBody = z.infer; -export const PatchTimelineRequestBody = z.object({ - /** - * The `savedObjectId` of the Timeline or Timeline template that you’re updating. - */ - timelineId: z.string().nullable(), - /** - * The version of the Timeline or Timeline template that you’re updating. - */ - version: z.string().nullable(), - /** - * The timeline object of the Timeline or Timeline template that you’re updating. - */ - timeline: SavedTimeline, -}); export type PatchTimelineRequestBodyInput = z.input; +export const PatchTimelineResponse = lazySchema(() => PersistTimelineResponse); export type PatchTimelineResponse = z.infer; -export const PatchTimelineResponse = PersistTimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_favorite/persist_favorite_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_favorite/persist_favorite_route.gen.ts index cd64049649e0f..73bc07ddfb82c 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_favorite/persist_favorite_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_favorite/persist_favorite_route.gen.ts @@ -14,18 +14,20 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { TimelineType, FavoriteTimelineResponse } from '../model/components.gen'; +export const PersistFavoriteRouteRequestBody = lazySchema(() => + z.object({ + timelineId: z.string().nullable(), + templateTimelineId: z.string().nullable(), + templateTimelineVersion: z.number().nullable(), + timelineType: TimelineType.nullable(), + }) +); export type PersistFavoriteRouteRequestBody = z.infer; -export const PersistFavoriteRouteRequestBody = z.object({ - timelineId: z.string().nullable(), - templateTimelineId: z.string().nullable(), - templateTimelineVersion: z.number().nullable(), - timelineType: TimelineType.nullable(), -}); export type PersistFavoriteRouteRequestBodyInput = z.input; +export const PersistFavoriteRouteResponse = lazySchema(() => FavoriteTimelineResponse); export type PersistFavoriteRouteResponse = z.infer; -export const PersistFavoriteRouteResponse = FavoriteTimelineResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_note/persist_note_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_note/persist_note_route.gen.ts index 239674a8b5d7c..56312e21cf3d3 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_note/persist_note_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/persist_note/persist_note_route.gen.ts @@ -14,31 +14,35 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { BareNote, Note } from '../model/components.gen'; +export const ResponseNote = lazySchema(() => + z.object({ + note: Note, + }) +); export type ResponseNote = z.infer; -export const ResponseNote = z.object({ - note: Note, -}); +export const PersistNoteRouteRequestBody = lazySchema(() => + z.object({ + /** + * The note to add or update. + */ + note: BareNote, + /** + * The `savedObjectId` of the note + */ + noteId: z.string().nullable().optional(), + /** + * The version of the note + */ + version: z.string().nullable().optional(), + }) +); export type PersistNoteRouteRequestBody = z.infer; -export const PersistNoteRouteRequestBody = z.object({ - /** - * The note to add or update. - */ - note: BareNote, - /** - * The `savedObjectId` of the note - */ - noteId: z.string().nullable().optional(), - /** - * The version of the note - */ - version: z.string().nullable().optional(), -}); export type PersistNoteRouteRequestBodyInput = z.input; +export const PersistNoteRouteResponse = lazySchema(() => ResponseNote); export type PersistNoteRouteResponse = z.infer; -export const PersistNoteRouteResponse = ResponseNote; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/pinned_events/pinned_events_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/pinned_events/pinned_events_route.gen.ts index 8f9195db54e9a..4fefb75161da5 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/pinned_events/pinned_events_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/pinned_events/pinned_events_route.gen.ts @@ -14,39 +14,43 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { PinnedEvent } from '../model/components.gen'; +export const PersistPinnedEventResponse = lazySchema(() => + z.union([ + PinnedEvent, + z.object({ + /** + * Indicates whether the event was successfully unpinned + */ + unpinned: z.boolean(), + }), + ]) +); export type PersistPinnedEventResponse = z.infer; -export const PersistPinnedEventResponse = z.union([ - PinnedEvent, + +export const PersistPinnedEventRouteRequestBody = lazySchema(() => z.object({ /** - * Indicates whether the event was successfully unpinned + * The `_id` of the associated event for this pinned event. */ - unpinned: z.boolean(), - }), -]); - + eventId: z.string(), + /** + * The `savedObjectId` of the timeline that you want this pinned event unpinned from. + */ + timelineId: z.string(), + /** + * The `savedObjectId` of the pinned event you want to unpin. + */ + pinnedEventId: z.string().nullable().optional(), + }) +); export type PersistPinnedEventRouteRequestBody = z.infer; -export const PersistPinnedEventRouteRequestBody = z.object({ - /** - * The `_id` of the associated event for this pinned event. - */ - eventId: z.string(), - /** - * The `savedObjectId` of the timeline that you want this pinned event unpinned from. - */ - timelineId: z.string(), - /** - * The `savedObjectId` of the pinned event you want to unpin. - */ - pinnedEventId: z.string().nullable().optional(), -}); export type PersistPinnedEventRouteRequestBodyInput = z.input< typeof PersistPinnedEventRouteRequestBody >; +export const PersistPinnedEventRouteResponse = lazySchema(() => PersistPinnedEventResponse); export type PersistPinnedEventRouteResponse = z.infer; -export const PersistPinnedEventRouteResponse = PersistPinnedEventResponse; diff --git a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/resolve_timeline/resolve_timeline_route.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/resolve_timeline/resolve_timeline_route.gen.ts index b5cda673a4537..05a96d10da5dc 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/api/timeline/resolve_timeline/resolve_timeline_route.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/api/timeline/resolve_timeline/resolve_timeline_route.gen.ts @@ -14,22 +14,24 @@ * version: 2023-10-31 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ResolvedTimeline } from '../model/components.gen'; +export const ResolveTimelineRequestQuery = lazySchema(() => + z.object({ + /** + * The ID of the template timeline to resolve + */ + template_timeline_id: z.string().optional(), + /** + * The ID of the timeline to resolve + */ + id: z.string().optional(), + }) +); export type ResolveTimelineRequestQuery = z.infer; -export const ResolveTimelineRequestQuery = z.object({ - /** - * The ID of the template timeline to resolve - */ - template_timeline_id: z.string().optional(), - /** - * The ID of the timeline to resolve - */ - id: z.string().optional(), -}); export type ResolveTimelineRequestQueryInput = z.input; +export const ResolveTimelineResponse = lazySchema(() => ResolvedTimeline); export type ResolveTimelineResponse = z.infer; -export const ResolveTimelineResponse = ResolvedTimeline; diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/dashboards/dashboard_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/dashboards/dashboard_migration.gen.ts index 1181bf92496fc..69afbc75443ce 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/dashboards/dashboard_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/dashboards/dashboard_migration.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; import { NonEmptyString } from '../../../../api/model/primitives.gen'; @@ -35,159 +35,191 @@ import { SiemMigrationResourceBase, } from '../../common.gen'; +export const CreateDashboardMigrationRequestBody = lazySchema(() => + z.object({ + /** + * The dashboard migration name + */ + name: NonEmptyString, + }) +); export type CreateDashboardMigrationRequestBody = z.infer< typeof CreateDashboardMigrationRequestBody >; -export const CreateDashboardMigrationRequestBody = z.object({ - /** - * The dashboard migration name - */ - name: NonEmptyString, -}); export type CreateDashboardMigrationRequestBodyInput = z.input< typeof CreateDashboardMigrationRequestBody >; +export const CreateDashboardMigrationResponse = lazySchema(() => + z.object({ + /** + * The migration id created. + */ + migration_id: NonEmptyString, + }) +); export type CreateDashboardMigrationResponse = z.infer; -export const CreateDashboardMigrationResponse = z.object({ - /** - * The migration id created. - */ - migration_id: NonEmptyString, -}); +export const CreateDashboardMigrationDashboardsRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type CreateDashboardMigrationDashboardsRequestParams = z.infer< typeof CreateDashboardMigrationDashboardsRequestParams >; -export const CreateDashboardMigrationDashboardsRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type CreateDashboardMigrationDashboardsRequestParamsInput = z.input< typeof CreateDashboardMigrationDashboardsRequestParams >; +export const CreateDashboardMigrationDashboardsRequestBody = lazySchema(() => + z.array(SplunkOriginalDashboardExport) +); export type CreateDashboardMigrationDashboardsRequestBody = z.infer< typeof CreateDashboardMigrationDashboardsRequestBody >; -export const CreateDashboardMigrationDashboardsRequestBody = z.array(SplunkOriginalDashboardExport); export type CreateDashboardMigrationDashboardsRequestBodyInput = z.input< typeof CreateDashboardMigrationDashboardsRequestBody >; +export const DeleteDashboardMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type DeleteDashboardMigrationRequestParams = z.infer< typeof DeleteDashboardMigrationRequestParams >; -export const DeleteDashboardMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type DeleteDashboardMigrationRequestParamsInput = z.input< typeof DeleteDashboardMigrationRequestParams >; +export const GetAllDashboardMigrationsStatsResponse = lazySchema(() => + z.array(DashboardMigrationTaskStats) +); export type GetAllDashboardMigrationsStatsResponse = z.infer< typeof GetAllDashboardMigrationsStatsResponse >; -export const GetAllDashboardMigrationsStatsResponse = z.array(DashboardMigrationTaskStats); +export const GetAllTranslationStatsDashboardMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetAllTranslationStatsDashboardMigrationRequestParams = z.infer< typeof GetAllTranslationStatsDashboardMigrationRequestParams >; -export const GetAllTranslationStatsDashboardMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetAllTranslationStatsDashboardMigrationRequestParamsInput = z.input< typeof GetAllTranslationStatsDashboardMigrationRequestParams >; +export const GetAllTranslationStatsDashboardMigrationResponse = lazySchema( + () => DashboardMigrationTranslationStats +); export type GetAllTranslationStatsDashboardMigrationResponse = z.infer< typeof GetAllTranslationStatsDashboardMigrationResponse >; -export const GetAllTranslationStatsDashboardMigrationResponse = DashboardMigrationTranslationStats; +export const GetDashboardMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetDashboardMigrationRequestParams = z.infer; -export const GetDashboardMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetDashboardMigrationRequestParamsInput = z.input< typeof GetDashboardMigrationRequestParams >; +export const GetDashboardMigrationResponse = lazySchema(() => DashboardMigration); export type GetDashboardMigrationResponse = z.infer; -export const GetDashboardMigrationResponse = DashboardMigration; +export const GetDashboardMigrationDashboardsRequestQuery = lazySchema(() => + z.object({ + page: z.coerce.number().optional(), + per_page: z.coerce.number().optional(), + sort_field: NonEmptyString.optional(), + sort_direction: z.enum(['asc', 'desc']).optional(), + search_term: z.string().optional(), + ids: ArrayFromString(NonEmptyString).optional(), + is_installed: BooleanFromString.optional(), + is_fully_translated: BooleanFromString.optional(), + is_partially_translated: BooleanFromString.optional(), + is_untranslatable: BooleanFromString.optional(), + is_failed: BooleanFromString.optional(), + }) +); export type GetDashboardMigrationDashboardsRequestQuery = z.infer< typeof GetDashboardMigrationDashboardsRequestQuery >; -export const GetDashboardMigrationDashboardsRequestQuery = z.object({ - page: z.coerce.number().optional(), - per_page: z.coerce.number().optional(), - sort_field: NonEmptyString.optional(), - sort_direction: z.enum(['asc', 'desc']).optional(), - search_term: z.string().optional(), - ids: ArrayFromString(NonEmptyString).optional(), - is_installed: BooleanFromString.optional(), - is_fully_translated: BooleanFromString.optional(), - is_partially_translated: BooleanFromString.optional(), - is_untranslatable: BooleanFromString.optional(), - is_failed: BooleanFromString.optional(), -}); export type GetDashboardMigrationDashboardsRequestQueryInput = z.input< typeof GetDashboardMigrationDashboardsRequestQuery >; +export const GetDashboardMigrationDashboardsRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetDashboardMigrationDashboardsRequestParams = z.infer< typeof GetDashboardMigrationDashboardsRequestParams >; -export const GetDashboardMigrationDashboardsRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetDashboardMigrationDashboardsRequestParamsInput = z.input< typeof GetDashboardMigrationDashboardsRequestParams >; +export const GetDashboardMigrationDashboardsResponse = lazySchema(() => + z.object({ + /** + * The total number of rules in migration. + */ + total: z.number(), + data: z.array(DashboardMigrationDashboard), + }) +); export type GetDashboardMigrationDashboardsResponse = z.infer< typeof GetDashboardMigrationDashboardsResponse >; -export const GetDashboardMigrationDashboardsResponse = z.object({ - /** - * The total number of rules in migration. - */ - total: z.number(), - data: z.array(DashboardMigrationDashboard), -}); +export const GetDashboardMigrationResourcesRequestQuery = lazySchema(() => + z.object({ + type: SiemMigrationResourceType.optional(), + names: ArrayFromString(z.string()).optional(), + from: z.coerce.number().optional(), + size: z.coerce.number().optional(), + }) +); export type GetDashboardMigrationResourcesRequestQuery = z.infer< typeof GetDashboardMigrationResourcesRequestQuery >; -export const GetDashboardMigrationResourcesRequestQuery = z.object({ - type: SiemMigrationResourceType.optional(), - names: ArrayFromString(z.string()).optional(), - from: z.coerce.number().optional(), - size: z.coerce.number().optional(), -}); export type GetDashboardMigrationResourcesRequestQueryInput = z.input< typeof GetDashboardMigrationResourcesRequestQuery >; +export const GetDashboardMigrationResourcesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetDashboardMigrationResourcesRequestParams = z.infer< typeof GetDashboardMigrationResourcesRequestParams >; -export const GetDashboardMigrationResourcesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetDashboardMigrationResourcesRequestParamsInput = z.input< typeof GetDashboardMigrationResourcesRequestParams >; +export const GetDashboardMigrationResourcesResponse = lazySchema(() => + z.array(SiemMigrationResource) +); export type GetDashboardMigrationResourcesResponse = z.infer< typeof GetDashboardMigrationResourcesResponse >; -export const GetDashboardMigrationResourcesResponse = z.array(SiemMigrationResource); +export const GetDashboardMigrationResourcesMissingRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetDashboardMigrationResourcesMissingRequestParams = z.infer< typeof GetDashboardMigrationResourcesMissingRequestParams >; -export const GetDashboardMigrationResourcesMissingRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetDashboardMigrationResourcesMissingRequestParamsInput = z.input< typeof GetDashboardMigrationResourcesMissingRequestParams >; @@ -195,158 +227,188 @@ export type GetDashboardMigrationResourcesMissingRequestParamsInput = z.input< /** * The identified resources missing */ +export const GetDashboardMigrationResourcesMissingResponse = lazySchema(() => + z.array(SiemMigrationResourceBase) +); export type GetDashboardMigrationResourcesMissingResponse = z.infer< typeof GetDashboardMigrationResourcesMissingResponse >; -export const GetDashboardMigrationResourcesMissingResponse = z.array(SiemMigrationResourceBase); +export const GetDashboardMigrationStatsRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetDashboardMigrationStatsRequestParams = z.infer< typeof GetDashboardMigrationStatsRequestParams >; -export const GetDashboardMigrationStatsRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetDashboardMigrationStatsRequestParamsInput = z.input< typeof GetDashboardMigrationStatsRequestParams >; +export const GetDashboardMigrationStatsResponse = lazySchema(() => DashboardMigrationTaskStats); export type GetDashboardMigrationStatsResponse = z.infer; -export const GetDashboardMigrationStatsResponse = DashboardMigrationTaskStats; +export const InstallMigrationDashboardsRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type InstallMigrationDashboardsRequestParams = z.infer< typeof InstallMigrationDashboardsRequestParams >; -export const InstallMigrationDashboardsRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type InstallMigrationDashboardsRequestParamsInput = z.input< typeof InstallMigrationDashboardsRequestParams >; +export const InstallMigrationDashboardsRequestBody = lazySchema(() => + z.object({ + /** + * The list of dashboard migration ids to install + */ + ids: z.array(NonEmptyString).optional(), + }) +); export type InstallMigrationDashboardsRequestBody = z.infer< typeof InstallMigrationDashboardsRequestBody >; -export const InstallMigrationDashboardsRequestBody = z.object({ - /** - * The list of dashboard migration ids to install - */ - ids: z.array(NonEmptyString).optional(), -}); export type InstallMigrationDashboardsRequestBodyInput = z.input< typeof InstallMigrationDashboardsRequestBody >; +export const InstallMigrationDashboardsResponse = lazySchema(() => + z.object({ + /** + * The number of dashboards that were installed. + */ + installed: z.number(), + }) +); export type InstallMigrationDashboardsResponse = z.infer; -export const InstallMigrationDashboardsResponse = z.object({ - /** - * The number of dashboards that were installed. - */ - installed: z.number(), -}); +export const StartDashboardsMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type StartDashboardsMigrationRequestParams = z.infer< typeof StartDashboardsMigrationRequestParams >; -export const StartDashboardsMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type StartDashboardsMigrationRequestParamsInput = z.input< typeof StartDashboardsMigrationRequestParams >; +export const StartDashboardsMigrationRequestBody = lazySchema(() => + z.object({ + /** + * Settings applicable to current dashboard migration task execution. + */ + settings: DashboardMigrationTaskExecutionSettings, + langsmith_options: LangSmithOptions.optional(), + /** + * The optional indicator to retry the dashboard translation based on this filter criteria. + */ + retry: DashboardMigrationRetryFilter.optional(), + }) +); export type StartDashboardsMigrationRequestBody = z.infer< typeof StartDashboardsMigrationRequestBody >; -export const StartDashboardsMigrationRequestBody = z.object({ - /** - * Settings applicable to current dashboard migration task execution. - */ - settings: DashboardMigrationTaskExecutionSettings, - langsmith_options: LangSmithOptions.optional(), - /** - * The optional indicator to retry the dashboard translation based on this filter criteria. - */ - retry: DashboardMigrationRetryFilter.optional(), -}); export type StartDashboardsMigrationRequestBodyInput = z.input< typeof StartDashboardsMigrationRequestBody >; +export const StartDashboardsMigrationResponse = lazySchema(() => + z.object({ + /** + * Indicates the migration has been started. `false` means the migration does not need to be started. + */ + started: z.boolean(), + }) +); export type StartDashboardsMigrationResponse = z.infer; -export const StartDashboardsMigrationResponse = z.object({ - /** - * Indicates the migration has been started. `false` means the migration does not need to be started. - */ - started: z.boolean(), -}); +export const StopDashboardsMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type StopDashboardsMigrationRequestParams = z.infer< typeof StopDashboardsMigrationRequestParams >; -export const StopDashboardsMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type StopDashboardsMigrationRequestParamsInput = z.input< typeof StopDashboardsMigrationRequestParams >; +export const StopDashboardsMigrationResponse = lazySchema(() => + z.object({ + /** + * Indicates the migration has been stopped. + */ + stopped: z.boolean(), + }) +); export type StopDashboardsMigrationResponse = z.infer; -export const StopDashboardsMigrationResponse = z.object({ - /** - * Indicates the migration has been stopped. - */ - stopped: z.boolean(), -}); +export const UpdateDashboardMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type UpdateDashboardMigrationRequestParams = z.infer< typeof UpdateDashboardMigrationRequestParams >; -export const UpdateDashboardMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type UpdateDashboardMigrationRequestParamsInput = z.input< typeof UpdateDashboardMigrationRequestParams >; +export const UpdateDashboardMigrationRequestBody = lazySchema(() => + z + .object({ + /** + * The dashboard migration name + */ + name: NonEmptyString.optional(), + }) + .strict() +); export type UpdateDashboardMigrationRequestBody = z.infer< typeof UpdateDashboardMigrationRequestBody >; -export const UpdateDashboardMigrationRequestBody = z - .object({ - /** - * The dashboard migration name - */ - name: NonEmptyString.optional(), - }) - .strict(); export type UpdateDashboardMigrationRequestBodyInput = z.input< typeof UpdateDashboardMigrationRequestBody >; +export const UpsertDashboardMigrationResourcesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type UpsertDashboardMigrationResourcesRequestParams = z.infer< typeof UpsertDashboardMigrationResourcesRequestParams >; -export const UpsertDashboardMigrationResourcesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type UpsertDashboardMigrationResourcesRequestParamsInput = z.input< typeof UpsertDashboardMigrationResourcesRequestParams >; +export const UpsertDashboardMigrationResourcesRequestBody = lazySchema(() => + z.array(SiemMigrationResourceData) +); export type UpsertDashboardMigrationResourcesRequestBody = z.infer< typeof UpsertDashboardMigrationResourcesRequestBody >; -export const UpsertDashboardMigrationResourcesRequestBody = z.array(SiemMigrationResourceData); export type UpsertDashboardMigrationResourcesRequestBodyInput = z.input< typeof UpsertDashboardMigrationResourcesRequestBody >; +export const UpsertDashboardMigrationResourcesResponse = lazySchema(() => + z.object({ + /** + * The request has been processed correctly. + */ + acknowledged: z.boolean(), + }) +); export type UpsertDashboardMigrationResourcesResponse = z.infer< typeof UpsertDashboardMigrationResourcesResponse >; -export const UpsertDashboardMigrationResourcesResponse = z.object({ - /** - * The request has been processed correctly. - */ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts index 793a215684b66..94023c8d2208a 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts @@ -14,7 +14,7 @@ * version: 1 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4'; import { @@ -40,103 +40,123 @@ import { SiemMigrationResourceBase, } from '../../common.gen'; +export const CreateQRadarRuleMigrationRulesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type CreateQRadarRuleMigrationRulesRequestParams = z.infer< typeof CreateQRadarRuleMigrationRulesRequestParams >; -export const CreateQRadarRuleMigrationRulesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type CreateQRadarRuleMigrationRulesRequestParamsInput = z.input< typeof CreateQRadarRuleMigrationRulesRequestParams >; +export const CreateQRadarRuleMigrationRulesRequestBody = lazySchema(() => + z.object({ + /** + * The QRadar rules XML export content + */ + xml: z.string().min(1), + }) +); export type CreateQRadarRuleMigrationRulesRequestBody = z.infer< typeof CreateQRadarRuleMigrationRulesRequestBody >; -export const CreateQRadarRuleMigrationRulesRequestBody = z.object({ - /** - * The QRadar rules XML export content - */ - xml: z.string().min(1), -}); export type CreateQRadarRuleMigrationRulesRequestBodyInput = z.input< typeof CreateQRadarRuleMigrationRulesRequestBody >; +export const CreateRuleMigrationRequestBody = lazySchema(() => + z.object({ + /** + * The rule migration name + */ + name: NonEmptyString, + }) +); export type CreateRuleMigrationRequestBody = z.infer; -export const CreateRuleMigrationRequestBody = z.object({ - /** - * The rule migration name - */ - name: NonEmptyString, -}); export type CreateRuleMigrationRequestBodyInput = z.input; +export const CreateRuleMigrationResponse = lazySchema(() => + z.object({ + /** + * The migration id created. + */ + migration_id: NonEmptyString, + }) +); export type CreateRuleMigrationResponse = z.infer; -export const CreateRuleMigrationResponse = z.object({ - /** - * The migration id created. - */ - migration_id: NonEmptyString, -}); +export const CreateRuleMigrationRulesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type CreateRuleMigrationRulesRequestParams = z.infer< typeof CreateRuleMigrationRulesRequestParams >; -export const CreateRuleMigrationRulesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type CreateRuleMigrationRulesRequestParamsInput = z.input< typeof CreateRuleMigrationRulesRequestParams >; +export const CreateRuleMigrationRulesRequestBody = lazySchema(() => z.array(OriginalRule)); export type CreateRuleMigrationRulesRequestBody = z.infer< typeof CreateRuleMigrationRulesRequestBody >; -export const CreateRuleMigrationRulesRequestBody = z.array(OriginalRule); export type CreateRuleMigrationRulesRequestBodyInput = z.input< typeof CreateRuleMigrationRulesRequestBody >; +export const DeleteRuleMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type DeleteRuleMigrationRequestParams = z.infer; -export const DeleteRuleMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type DeleteRuleMigrationRequestParamsInput = z.input< typeof DeleteRuleMigrationRequestParams >; +export const GetAllStatsRuleMigrationResponse = lazySchema(() => z.array(RuleMigrationTaskStats)); export type GetAllStatsRuleMigrationResponse = z.infer; -export const GetAllStatsRuleMigrationResponse = z.array(RuleMigrationTaskStats); +export const GetRuleMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationRequestParams = z.infer; -export const GetRuleMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationRequestParamsInput = z.input; +export const GetRuleMigrationResponse = lazySchema(() => RuleMigration); export type GetRuleMigrationResponse = z.infer; -export const GetRuleMigrationResponse = RuleMigration; /** * The map of related integrations, with the integration id as a key */ +export const GetRuleMigrationIntegrationsResponse = lazySchema(() => + z.object({}).catchall(RelatedIntegration) +); export type GetRuleMigrationIntegrationsResponse = z.infer< typeof GetRuleMigrationIntegrationsResponse >; -export const GetRuleMigrationIntegrationsResponse = z.object({}).catchall(RelatedIntegration); +export const GetRuleMigrationIntegrationsStatsResponse = lazySchema( + () => RuleMigrationAllIntegrationsStats +); export type GetRuleMigrationIntegrationsStatsResponse = z.infer< typeof GetRuleMigrationIntegrationsStatsResponse >; -export const GetRuleMigrationIntegrationsStatsResponse = RuleMigrationAllIntegrationsStats; +export const GetRuleMigrationPrebuiltRulesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationPrebuiltRulesRequestParams = z.infer< typeof GetRuleMigrationPrebuiltRulesRequestParams >; -export const GetRuleMigrationPrebuiltRulesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationPrebuiltRulesRequestParamsInput = z.input< typeof GetRuleMigrationPrebuiltRulesRequestParams >; @@ -144,59 +164,69 @@ export type GetRuleMigrationPrebuiltRulesRequestParamsInput = z.input< /** * The map of prebuilt rules, with the rules id as a key */ +export const GetRuleMigrationPrebuiltRulesResponse = lazySchema(() => + z.object({}).catchall(PrebuiltRuleVersion) +); export type GetRuleMigrationPrebuiltRulesResponse = z.infer< typeof GetRuleMigrationPrebuiltRulesResponse >; -export const GetRuleMigrationPrebuiltRulesResponse = z.object({}).catchall(PrebuiltRuleVersion); /** * The missing index privileges required for the migration */ +export const GetRuleMigrationPrivilegesResponse = lazySchema(() => + z.array( + z.object({ + /** + * The index name of the privilege missing + */ + indexName: z.string(), + /** + * The index privileges level missing + */ + privileges: z.array(z.string()), + }) + ) +); export type GetRuleMigrationPrivilegesResponse = z.infer; -export const GetRuleMigrationPrivilegesResponse = z.array( +export const GetRuleMigrationResourcesRequestQuery = lazySchema(() => z.object({ - /** - * The index name of the privilege missing - */ - indexName: z.string(), - /** - * The index privileges level missing - */ - privileges: z.array(z.string()), + type: SiemMigrationResourceType.optional(), + names: ArrayFromString(z.string()).optional(), + from: z.coerce.number().optional(), + size: z.coerce.number().optional(), }) ); export type GetRuleMigrationResourcesRequestQuery = z.infer< typeof GetRuleMigrationResourcesRequestQuery >; -export const GetRuleMigrationResourcesRequestQuery = z.object({ - type: SiemMigrationResourceType.optional(), - names: ArrayFromString(z.string()).optional(), - from: z.coerce.number().optional(), - size: z.coerce.number().optional(), -}); export type GetRuleMigrationResourcesRequestQueryInput = z.input< typeof GetRuleMigrationResourcesRequestQuery >; +export const GetRuleMigrationResourcesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationResourcesRequestParams = z.infer< typeof GetRuleMigrationResourcesRequestParams >; -export const GetRuleMigrationResourcesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationResourcesRequestParamsInput = z.input< typeof GetRuleMigrationResourcesRequestParams >; +export const GetRuleMigrationResourcesResponse = lazySchema(() => z.array(SiemMigrationResource)); export type GetRuleMigrationResourcesResponse = z.infer; -export const GetRuleMigrationResourcesResponse = z.array(SiemMigrationResource); +export const GetRuleMigrationResourcesMissingRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationResourcesMissingRequestParams = z.infer< typeof GetRuleMigrationResourcesMissingRequestParams >; -export const GetRuleMigrationResourcesMissingRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationResourcesMissingRequestParamsInput = z.input< typeof GetRuleMigrationResourcesMissingRequestParams >; @@ -204,115 +234,137 @@ export type GetRuleMigrationResourcesMissingRequestParamsInput = z.input< /** * The identified resources missing */ +export const GetRuleMigrationResourcesMissingResponse = lazySchema(() => + z.array(SiemMigrationResourceBase) +); export type GetRuleMigrationResourcesMissingResponse = z.infer< typeof GetRuleMigrationResourcesMissingResponse >; -export const GetRuleMigrationResourcesMissingResponse = z.array(SiemMigrationResourceBase); +export const GetRuleMigrationRulesRequestQuery = lazySchema(() => + z.object({ + page: z.coerce.number().optional(), + per_page: z.coerce.number().optional(), + sort_field: NonEmptyString.optional(), + sort_direction: z.enum(['asc', 'desc']).optional(), + search_term: z.string().optional(), + ids: ArrayFromString(NonEmptyString).optional(), + is_prebuilt: BooleanFromString.optional(), + is_installed: BooleanFromString.optional(), + is_fully_translated: BooleanFromString.optional(), + is_partially_translated: BooleanFromString.optional(), + is_untranslatable: BooleanFromString.optional(), + is_failed: BooleanFromString.optional(), + is_missing_index: BooleanFromString.optional(), + }) +); export type GetRuleMigrationRulesRequestQuery = z.infer; -export const GetRuleMigrationRulesRequestQuery = z.object({ - page: z.coerce.number().optional(), - per_page: z.coerce.number().optional(), - sort_field: NonEmptyString.optional(), - sort_direction: z.enum(['asc', 'desc']).optional(), - search_term: z.string().optional(), - ids: ArrayFromString(NonEmptyString).optional(), - is_prebuilt: BooleanFromString.optional(), - is_installed: BooleanFromString.optional(), - is_fully_translated: BooleanFromString.optional(), - is_partially_translated: BooleanFromString.optional(), - is_untranslatable: BooleanFromString.optional(), - is_failed: BooleanFromString.optional(), - is_missing_index: BooleanFromString.optional(), -}); export type GetRuleMigrationRulesRequestQueryInput = z.input< typeof GetRuleMigrationRulesRequestQuery >; +export const GetRuleMigrationRulesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationRulesRequestParams = z.infer; -export const GetRuleMigrationRulesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationRulesRequestParamsInput = z.input< typeof GetRuleMigrationRulesRequestParams >; +export const GetRuleMigrationRulesResponse = lazySchema(() => + z.object({ + /** + * The total number of rules in migration. + */ + total: z.number(), + data: z.array(RuleMigrationRule), + }) +); export type GetRuleMigrationRulesResponse = z.infer; -export const GetRuleMigrationRulesResponse = z.object({ - /** - * The total number of rules in migration. - */ - total: z.number(), - data: z.array(RuleMigrationRule), -}); +export const GetRuleMigrationStatsRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationStatsRequestParams = z.infer; -export const GetRuleMigrationStatsRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationStatsRequestParamsInput = z.input< typeof GetRuleMigrationStatsRequestParams >; +export const GetRuleMigrationStatsResponse = lazySchema(() => RuleMigrationTaskStats); export type GetRuleMigrationStatsResponse = z.infer; -export const GetRuleMigrationStatsResponse = RuleMigrationTaskStats; +export const GetRuleMigrationTranslationStatsRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type GetRuleMigrationTranslationStatsRequestParams = z.infer< typeof GetRuleMigrationTranslationStatsRequestParams >; -export const GetRuleMigrationTranslationStatsRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type GetRuleMigrationTranslationStatsRequestParamsInput = z.input< typeof GetRuleMigrationTranslationStatsRequestParams >; +export const GetRuleMigrationTranslationStatsResponse = lazySchema( + () => RuleMigrationTranslationStats +); export type GetRuleMigrationTranslationStatsResponse = z.infer< typeof GetRuleMigrationTranslationStatsResponse >; -export const GetRuleMigrationTranslationStatsResponse = RuleMigrationTranslationStats; +export const InstallMigrationRulesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type InstallMigrationRulesRequestParams = z.infer; -export const InstallMigrationRulesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type InstallMigrationRulesRequestParamsInput = z.input< typeof InstallMigrationRulesRequestParams >; +export const InstallMigrationRulesRequestBody = lazySchema(() => + z.object({ + ids: z.array(NonEmptyString).optional(), + /** + * Indicates whether installed rules should be enabled + */ + enabled: z.boolean().optional(), + }) +); export type InstallMigrationRulesRequestBody = z.infer; -export const InstallMigrationRulesRequestBody = z.object({ - ids: z.array(NonEmptyString).optional(), - /** - * Indicates whether installed rules should be enabled - */ - enabled: z.boolean().optional(), -}); export type InstallMigrationRulesRequestBodyInput = z.input< typeof InstallMigrationRulesRequestBody >; +export const InstallMigrationRulesResponse = lazySchema(() => + z.object({ + /** + * Indicates the number of successfully installed migration rules. + */ + installed: z.number(), + }) +); export type InstallMigrationRulesResponse = z.infer; -export const InstallMigrationRulesResponse = z.object({ - /** - * Indicates the number of successfully installed migration rules. - */ - installed: z.number(), -}); +export const RuleMigrationEnhanceRuleRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type RuleMigrationEnhanceRuleRequestParams = z.infer< typeof RuleMigrationEnhanceRuleRequestParams >; -export const RuleMigrationEnhanceRuleRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type RuleMigrationEnhanceRuleRequestParamsInput = z.input< typeof RuleMigrationEnhanceRuleRequestParams >; +export const RuleMigrationEnhanceRuleRequestBody = lazySchema(() => EnhanceQRadarRule); export type RuleMigrationEnhanceRuleRequestBody = z.infer< typeof RuleMigrationEnhanceRuleRequestBody >; -export const RuleMigrationEnhanceRuleRequestBody = EnhanceQRadarRule; export type RuleMigrationEnhanceRuleRequestBodyInput = z.input< typeof RuleMigrationEnhanceRuleRequestBody >; @@ -320,169 +372,203 @@ export type RuleMigrationEnhanceRuleRequestBodyInput = z.input< /** * Response from rule enhancement operation */ +export const RuleMigrationEnhanceRuleResponse = lazySchema(() => + z.object({ + /** + * whether the update was applied successfully + */ + updated: z.boolean(), + }) +); export type RuleMigrationEnhanceRuleResponse = z.infer; -export const RuleMigrationEnhanceRuleResponse = z.object({ - /** - * whether the update was applied successfully - */ - updated: z.boolean(), -}); +export const StartRuleMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type StartRuleMigrationRequestParams = z.infer; -export const StartRuleMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type StartRuleMigrationRequestParamsInput = z.input; +export const StartRuleMigrationRequestBody = lazySchema(() => + z.object({ + /** + * Settings applicable to current rule migration task execution. + */ + settings: RuleMigrationTaskExecutionSettings, + langsmith_options: LangSmithOptions.optional(), + /** + * The optional indicator to retry the rule translation based on this filter criteria. + */ + retry: RuleMigrationRetryFilter.optional(), + /** + * Selected rules to retry migration on. + */ + selection: z + .object({ + ids: z.array(NonEmptyString), + }) + .optional(), + }) +); export type StartRuleMigrationRequestBody = z.infer; -export const StartRuleMigrationRequestBody = z.object({ - /** - * Settings applicable to current rule migration task execution. - */ - settings: RuleMigrationTaskExecutionSettings, - langsmith_options: LangSmithOptions.optional(), - /** - * The optional indicator to retry the rule translation based on this filter criteria. - */ - retry: RuleMigrationRetryFilter.optional(), - /** - * Selected rules to retry migration on. - */ - selection: z - .object({ - ids: z.array(NonEmptyString), - }) - .optional(), -}); export type StartRuleMigrationRequestBodyInput = z.input; +export const StartRuleMigrationResponse = lazySchema(() => + z.object({ + /** + * Indicates the migration has been started. `false` means the migration does not need to be started. + */ + started: z.boolean(), + }) +); export type StartRuleMigrationResponse = z.infer; -export const StartRuleMigrationResponse = z.object({ - /** - * Indicates the migration has been started. `false` means the migration does not need to be started. - */ - started: z.boolean(), -}); +export const StopRuleMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type StopRuleMigrationRequestParams = z.infer; -export const StopRuleMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type StopRuleMigrationRequestParamsInput = z.input; +export const StopRuleMigrationResponse = lazySchema(() => + z.object({ + /** + * Indicates the migration has been stopped. + */ + stopped: z.boolean(), + }) +); export type StopRuleMigrationResponse = z.infer; -export const StopRuleMigrationResponse = z.object({ - /** - * Indicates the migration has been stopped. - */ - stopped: z.boolean(), -}); +export const UpdateRuleMigrationRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type UpdateRuleMigrationRequestParams = z.infer; -export const UpdateRuleMigrationRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type UpdateRuleMigrationRequestParamsInput = z.input< typeof UpdateRuleMigrationRequestParams >; +export const UpdateRuleMigrationRequestBody = lazySchema(() => + z.object({ + /** + * The rule migration name + */ + name: NonEmptyString.optional(), + /** + * The index pattern to update + */ + index_pattern: NonEmptyString.optional(), + }) +); export type UpdateRuleMigrationRequestBody = z.infer; -export const UpdateRuleMigrationRequestBody = z.object({ - /** - * The rule migration name - */ - name: NonEmptyString.optional(), - /** - * The index pattern to update - */ - index_pattern: NonEmptyString.optional(), -}); export type UpdateRuleMigrationRequestBodyInput = z.input; +export const UpdateRuleMigrationIndexPatternRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type UpdateRuleMigrationIndexPatternRequestParams = z.infer< typeof UpdateRuleMigrationIndexPatternRequestParams >; -export const UpdateRuleMigrationIndexPatternRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type UpdateRuleMigrationIndexPatternRequestParamsInput = z.input< typeof UpdateRuleMigrationIndexPatternRequestParams >; +export const UpdateRuleMigrationIndexPatternRequestBody = lazySchema(() => + z.object({ + ids: z.array(NonEmptyString).optional(), + /** + * The index pattern to update + */ + index_pattern: NonEmptyString, + }) +); export type UpdateRuleMigrationIndexPatternRequestBody = z.infer< typeof UpdateRuleMigrationIndexPatternRequestBody >; -export const UpdateRuleMigrationIndexPatternRequestBody = z.object({ - ids: z.array(NonEmptyString).optional(), - /** - * The index pattern to update - */ - index_pattern: NonEmptyString, -}); export type UpdateRuleMigrationIndexPatternRequestBodyInput = z.input< typeof UpdateRuleMigrationIndexPatternRequestBody >; +export const UpdateRuleMigrationIndexPatternResponse = lazySchema(() => + z.object({ + /** + * Indicates the number of rules that have been updated. + */ + updated: z.number(), + }) +); export type UpdateRuleMigrationIndexPatternResponse = z.infer< typeof UpdateRuleMigrationIndexPatternResponse >; -export const UpdateRuleMigrationIndexPatternResponse = z.object({ - /** - * Indicates the number of rules that have been updated. - */ - updated: z.number(), -}); +export const UpdateRuleMigrationRulesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type UpdateRuleMigrationRulesRequestParams = z.infer< typeof UpdateRuleMigrationRulesRequestParams >; -export const UpdateRuleMigrationRulesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type UpdateRuleMigrationRulesRequestParamsInput = z.input< typeof UpdateRuleMigrationRulesRequestParams >; +export const UpdateRuleMigrationRulesRequestBody = lazySchema(() => + z.array(UpdateRuleMigrationRule) +); export type UpdateRuleMigrationRulesRequestBody = z.infer< typeof UpdateRuleMigrationRulesRequestBody >; -export const UpdateRuleMigrationRulesRequestBody = z.array(UpdateRuleMigrationRule); export type UpdateRuleMigrationRulesRequestBodyInput = z.input< typeof UpdateRuleMigrationRulesRequestBody >; +export const UpdateRuleMigrationRulesResponse = lazySchema(() => + z.object({ + /** + * Indicates rules migrations have been updated. + */ + updated: z.boolean(), + }) +); export type UpdateRuleMigrationRulesResponse = z.infer; -export const UpdateRuleMigrationRulesResponse = z.object({ - /** - * Indicates rules migrations have been updated. - */ - updated: z.boolean(), -}); +export const UpsertRuleMigrationResourcesRequestParams = lazySchema(() => + z.object({ + migration_id: NonEmptyString, + }) +); export type UpsertRuleMigrationResourcesRequestParams = z.infer< typeof UpsertRuleMigrationResourcesRequestParams >; -export const UpsertRuleMigrationResourcesRequestParams = z.object({ - migration_id: NonEmptyString, -}); export type UpsertRuleMigrationResourcesRequestParamsInput = z.input< typeof UpsertRuleMigrationResourcesRequestParams >; +export const UpsertRuleMigrationResourcesRequestBody = lazySchema(() => + z.array(SiemMigrationResourceData) +); export type UpsertRuleMigrationResourcesRequestBody = z.infer< typeof UpsertRuleMigrationResourcesRequestBody >; -export const UpsertRuleMigrationResourcesRequestBody = z.array(SiemMigrationResourceData); export type UpsertRuleMigrationResourcesRequestBodyInput = z.input< typeof UpsertRuleMigrationResourcesRequestBody >; +export const UpsertRuleMigrationResourcesResponse = lazySchema(() => + z.object({ + /** + * The request has been processed correctly. + */ + acknowledged: z.boolean(), + }) +); export type UpsertRuleMigrationResourcesResponse = z.infer< typeof UpsertRuleMigrationResourcesResponse >; -export const UpsertRuleMigrationResourcesResponse = z.object({ - /** - * The request has been processed correctly. - */ - acknowledged: z.boolean(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts index c1b4bdbffff69..8dda73050eeef 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/common.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../../api/model/primitives.gen'; import { SplunkResourceType } from './vendor/common/splunk.gen'; @@ -23,309 +23,329 @@ import { QradarResourceType } from './vendor/common/qradar.gen'; /** * The GenAI connector id to use. */ +export const ConnectorId = lazySchema(() => z.string()); export type ConnectorId = z.infer; -export const ConnectorId = z.string(); /** * The LangSmith options object. */ +export const LangSmithOptions = lazySchema(() => + z.object({ + /** + * The project name. + */ + project_name: z.string(), + /** + * The API key to use for tracing. + */ + api_key: z.string(), + }) +); export type LangSmithOptions = z.infer; -export const LangSmithOptions = z.object({ - /** - * The project name. - */ - project_name: z.string(), - /** - * The API key to use for tracing. - */ - api_key: z.string(), -}); /** * The LangSmith settings object for evaluations. */ -export type LangSmithEvaluationOptions = z.infer; -export const LangSmithEvaluationOptions = LangSmithOptions.extend( - z.object({ - /** - * The dataset name to use for evaluations. - */ - dataset: z.string(), - }) +export const LangSmithEvaluationOptions = lazySchema(() => + LangSmithOptions.merge( + z.object({ + /** + * The dataset name to use for evaluations. + */ + dataset: z.string(), + }) + ) ); +export type LangSmithEvaluationOptions = z.infer; /** * The vendor identifier. */ +export const SiemMigrationVendor = lazySchema(() => z.enum(['splunk', 'qradar'])); export type SiemMigrationVendor = z.infer; -export const SiemMigrationVendor = z.enum(['splunk', 'qradar']); export type SiemMigrationVendorEnum = typeof SiemMigrationVendor.enum; export const SiemMigrationVendorEnum = SiemMigrationVendor.enum; /** * A comment for the migration process */ +export const MigrationComment = lazySchema(() => + z.object({ + /** + * The message of the migration comment + */ + message: z.string(), + /** + * The moment of creation of the comment + */ + created_at: z.string(), + /** + * The user profile ID of the user who created the comment, or `assistant` if it was generated by the LLM + */ + created_by: z.string(), + }) +); export type MigrationComment = z.infer; -export const MigrationComment = z.object({ - /** - * The message of the migration comment - */ - message: z.string(), - /** - * The moment of creation of the comment - */ - created_at: z.string(), - /** - * The user profile ID of the user who created the comment, or `assistant` if it was generated by the LLM - */ - created_by: z.string(), -}); /** * The comments for the migration including a summary from the LLM in markdown. */ +export const MigrationComments = lazySchema(() => z.array(MigrationComment)); export type MigrationComments = z.infer; -export const MigrationComments = z.array(MigrationComment); /** * The status of migration. */ +export const MigrationStatus = lazySchema(() => + z.enum(['pending', 'processing', 'completed', 'failed']) +); export type MigrationStatus = z.infer; -export const MigrationStatus = z.enum(['pending', 'processing', 'completed', 'failed']); export type MigrationStatusEnum = typeof MigrationStatus.enum; export const MigrationStatusEnum = MigrationStatus.enum; /** * The status of the migration task. */ +export const MigrationTaskStatus = lazySchema(() => + z.enum(['ready', 'running', 'stopped', 'finished', 'interrupted']) +); export type MigrationTaskStatus = z.infer; -export const MigrationTaskStatus = z.enum([ - 'ready', - 'running', - 'stopped', - 'finished', - 'interrupted', -]); export type MigrationTaskStatusEnum = typeof MigrationTaskStatus.enum; export const MigrationTaskStatusEnum = MigrationTaskStatus.enum; /** * The last execution of a migration task. */ +export const MigrationLastExecution = lazySchema(() => + z.object({ + /** + * The total execution time in milliseconds for the migration. This includes duration of last_execution and any previous executions. + */ + total_execution_time_ms: z.number().int().optional(), + /** + * The moment the last execution started. + */ + started_at: z.string().optional(), + /** + * The moment the last execution finished. + */ + finished_at: z.string().nullable().optional(), + /** + * The connector ID used for the last execution. + */ + connector_id: z.string().optional(), + /** + * The error message if the last execution failed. + */ + error: z.string().nullable().optional(), + /** + * Indicates if the last execution was stopped by the user. + */ + is_stopped: z.boolean().optional(), + }) +); export type MigrationLastExecution = z.infer; -export const MigrationLastExecution = z.object({ - /** - * The total execution time in milliseconds for the migration. This includes duration of last_execution and any previous executions. - */ - total_execution_time_ms: z.number().int().optional(), - /** - * The moment the last execution started. - */ - started_at: z.string().optional(), - /** - * The moment the last execution finished. - */ - finished_at: z.string().nullable().optional(), - /** - * The connector ID used for the last execution. - */ - connector_id: z.string().optional(), - /** - * The error message if the last execution failed. - */ - error: z.string().nullable().optional(), - /** - * Indicates if the last execution was stopped by the user. - */ - is_stopped: z.boolean().optional(), -}); /** * The items migration translation stats object. */ -export type MigrationTranslationStats = z.infer; -export const MigrationTranslationStats = z.object({ - /** - * The migration id - */ - id: NonEmptyString, - /** - * The items migration translation stats. - */ - items: z.object({ +export const MigrationTranslationStats = lazySchema(() => + z.object({ /** - * The total number of items in the migration. + * The migration id */ - total: z.number().int(), + id: NonEmptyString, /** - * The number of items that have been successfully translated. + * The items migration translation stats. */ - success: z.object({ + items: z.object({ /** - * The total number of items that have been successfully translated. + * The total number of items in the migration. */ total: z.number().int(), /** - * The translation results + * The number of items that have been successfully translated. */ - result: z.object({ + success: z.object({ /** - * The number of items that have been fully translated. + * The total number of items that have been successfully translated. */ - full: z.number().int(), + total: z.number().int(), /** - * The number of items that have been partially translated. + * The translation results */ - partial: z.number().int(), + result: z.object({ + /** + * The number of items that have been fully translated. + */ + full: z.number().int(), + /** + * The number of items that have been partially translated. + */ + partial: z.number().int(), + /** + * The number of items that could not be translated. + */ + untranslatable: z.number().int(), + }), /** - * The number of items that could not be translated. + * The number of items that have been successfully translated and can be installed. */ - untranslatable: z.number().int(), + installable: z.number().int(), }), /** - * The number of items that have been successfully translated and can be installed. + * The number of items that have failed translation. */ - installable: z.number().int(), + failed: z.number().int(), }), - /** - * The number of items that have failed translation. - */ - failed: z.number().int(), - }), -}); + }) +); +export type MigrationTranslationStats = z.infer; /** * The migration translation result. */ +export const MigrationTranslationResult = lazySchema(() => + z.enum(['full', 'partial', 'untranslatable']) +); export type MigrationTranslationResult = z.infer; -export const MigrationTranslationResult = z.enum(['full', 'partial', 'untranslatable']); export type MigrationTranslationResultEnum = typeof MigrationTranslationResult.enum; export const MigrationTranslationResultEnum = MigrationTranslationResult.enum; /** * The migration items stats. */ +export const MigrationTaskItemsStats = lazySchema(() => + z.object({ + /** + * The total number of items to migrate. + */ + total: z.number().int(), + /** + * The number of items that are pending migration. + */ + pending: z.number().int(), + /** + * The number of items that are being migrated. + */ + processing: z.number().int(), + /** + * The number of items that have been migrated successfully. + */ + completed: z.number().int(), + /** + * The number of items that have failed migration. + */ + failed: z.number().int(), + }) +); export type MigrationTaskItemsStats = z.infer; -export const MigrationTaskItemsStats = z.object({ - /** - * The total number of items to migrate. - */ - total: z.number().int(), - /** - * The number of items that are pending migration. - */ - pending: z.number().int(), - /** - * The number of items that are being migrated. - */ - processing: z.number().int(), - /** - * The number of items that have been migrated successfully. - */ - completed: z.number().int(), - /** - * The number of items that have failed migration. - */ - failed: z.number().int(), -}); /** * The migration task stats object. */ +export const MigrationTaskStats = lazySchema(() => + z.object({ + /** + * The migration id + */ + id: NonEmptyString, + /** + * The migration name + */ + name: NonEmptyString, + /** + * Indicates if the migration task status. + */ + status: MigrationTaskStatus, + /** + * The migration items stats. + */ + items: MigrationTaskItemsStats, + /** + * The moment the migration was created. + */ + created_at: z.string(), + /** + * The moment of the last update. + */ + last_updated_at: z.string(), + /** + * The last execution of the migration task. + */ + last_execution: MigrationLastExecution.optional(), + /** + * The migration vendor. + */ + vendor: SiemMigrationVendor.optional(), + }) +); export type MigrationTaskStats = z.infer; -export const MigrationTaskStats = z.object({ - /** - * The migration id - */ - id: NonEmptyString, - /** - * The migration name - */ - name: NonEmptyString, - /** - * Indicates if the migration task status. - */ - status: MigrationTaskStatus, - /** - * The migration items stats. - */ - items: MigrationTaskItemsStats, - /** - * The moment the migration was created. - */ - created_at: z.string(), - /** - * The moment of the last update. - */ - last_updated_at: z.string(), - /** - * The last execution of the migration task. - */ - last_execution: MigrationLastExecution.optional(), - /** - * The migration vendor. - */ - vendor: SiemMigrationVendor.optional(), -}); +export const SiemMigrationResourceType = lazySchema(() => + z.union([SplunkResourceType, QradarResourceType]) +); export type SiemMigrationResourceType = z.infer; -export const SiemMigrationResourceType = z.union([SplunkResourceType, QradarResourceType]); /** * A resource of a migration */ +export const SiemMigrationResourceBase = lazySchema(() => + z.object({ + type: SiemMigrationResourceType, + /** + * The name of the resource + */ + name: NonEmptyString, + }) +); export type SiemMigrationResourceBase = z.infer; -export const SiemMigrationResourceBase = z.object({ - type: SiemMigrationResourceType, - /** - * The name of the resource - */ - name: NonEmptyString, -}); +export const SiemMigrationResourceContent = lazySchema(() => + z.object({ + /** + * The resource content value. Can be an empty string. + */ + content: z.string(), + /** + * The resource arbitrary metadata. + */ + metadata: z.object({}).catchall(z.unknown()).optional(), + }) +); export type SiemMigrationResourceContent = z.infer; -export const SiemMigrationResourceContent = z.object({ - /** - * The resource content value. Can be an empty string. - */ - content: z.string(), - /** - * The resource arbitrary metadata. - */ - metadata: z.object({}).catchall(z.unknown()).optional(), -}); /** * The rule migration resource data. */ -export type SiemMigrationResourceData = z.infer; -export const SiemMigrationResourceData = SiemMigrationResourceBase.extend( - SiemMigrationResourceContent +export const SiemMigrationResourceData = lazySchema(() => + SiemMigrationResourceBase.merge(SiemMigrationResourceContent) ); +export type SiemMigrationResourceData = z.infer; /** * The rule migration resource document object. */ -export type SiemMigrationResource = z.infer; -export const SiemMigrationResource = SiemMigrationResourceBase.extend( - SiemMigrationResourceContent.partial() -).extend( - z.object({ - /** - * The rule resource migration id - */ - id: NonEmptyString, - /** - * The migration id - */ - migration_id: NonEmptyString, - /** - * The moment of the last update - */ - updated_at: z.string().optional(), - /** - * The user who last updated the resource - */ - updated_by: z.string().optional(), - }) +export const SiemMigrationResource = lazySchema(() => + SiemMigrationResourceBase.merge(SiemMigrationResourceContent.partial()).merge( + z.object({ + /** + * The rule resource migration id + */ + id: NonEmptyString, + /** + * The migration id + */ + migration_id: NonEmptyString, + /** + * The moment of the last update + */ + updated_at: z.string().optional(), + /** + * The user who last updated the resource + */ + updated_by: z.string().optional(), + }) + ) ); +export type SiemMigrationResource = z.infer; diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts index e5e191795fc1b..e0c06490c3f37 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/dashboard_migration.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../../api/model/primitives.gen'; import { @@ -29,269 +29,289 @@ import { SplunkOriginalDashboardProperties } from './vendor/dashboards/splunk.ge /** * The original dashboard vendor identifier. */ +export const OriginalDashboardVendor = lazySchema(() => z.literal('splunk')); export type OriginalDashboardVendor = z.infer; -export const OriginalDashboardVendor = z.literal('splunk'); /** * The dashboard migration object ( without Id ) with its settings. */ +export const DashboardMigrationData = lazySchema(() => + z.object({ + /** + * The dashboard migration name + */ + name: NonEmptyString, + /** + * The user profile ID of the user who created the migration. + */ + created_by: NonEmptyString, + /** + * The moment migration was created + */ + created_at: NonEmptyString, + /** + * The last execution of the dashboard migration task. + */ + last_execution: MigrationLastExecution.optional(), + }) +); export type DashboardMigrationData = z.infer; -export const DashboardMigrationData = z.object({ - /** - * The dashboard migration name - */ - name: NonEmptyString, - /** - * The user profile ID of the user who created the migration. - */ - created_by: NonEmptyString, - /** - * The moment migration was created - */ - created_at: NonEmptyString, - /** - * The last execution of the dashboard migration task. - */ - last_execution: MigrationLastExecution.optional(), -}); /** * The dashboard migration object with its settings. */ +export const DashboardMigration = lazySchema(() => + z + .object({ + /** + * The dashboard migration id + */ + id: NonEmptyString, + }) + .merge(DashboardMigrationData) +); export type DashboardMigration = z.infer; -export const DashboardMigration = z - .object({ - /** - * The dashboard migration id - */ - id: NonEmptyString, - }) - .extend(DashboardMigrationData); /** * The dashboard migration translation stats object. */ -export type DashboardMigrationTranslationStats = z.infer; -export const DashboardMigrationTranslationStats = z.object({ - /** - * The migration id - */ - id: NonEmptyString, - /** - * The dashboards migration translation stats. - */ - dashboards: z.object({ +export const DashboardMigrationTranslationStats = lazySchema(() => + z.object({ /** - * The total number of dashboards in the migration. + * The migration id */ - total: z.number().int(), + id: NonEmptyString, /** - * The number of dashboards that have been successfully translated. + * The dashboards migration translation stats. */ - success: z.object({ + dashboards: z.object({ /** - * The total number of dashboards that have been successfully translated. + * The total number of dashboards in the migration. */ total: z.number().int(), /** - * The translation results + * The number of dashboards that have been successfully translated. */ - result: z.object({ + success: z.object({ /** - * The number of dashboards that have been fully translated. + * The total number of dashboards that have been successfully translated. */ - full: z.number().int(), + total: z.number().int(), /** - * The number of dashboards that have been partially translated. + * The translation results */ - partial: z.number().int(), + result: z.object({ + /** + * The number of dashboards that have been fully translated. + */ + full: z.number().int(), + /** + * The number of dashboards that have been partially translated. + */ + partial: z.number().int(), + /** + * The number of dashboards that could not be translated. + */ + untranslatable: z.number().int(), + }), /** - * The number of dashboards that could not be translated. + * The number of dashboards that have been successfully translated and can be installed. */ - untranslatable: z.number().int(), + installable: z.number().int(), }), /** - * The number of dashboards that have been successfully translated and can be installed. + * The number of dashboards that have failed translation. */ - installable: z.number().int(), + failed: z.number().int(), }), - /** - * The number of dashboards that have failed translation. - */ - failed: z.number().int(), - }), -}); + }) +); +export type DashboardMigrationTranslationStats = z.infer; /** * The raw dashboard object from different vendors */ +export const OriginalDashboard = lazySchema(() => + z.object({ + /** + * The unique identifier for the dashboard + */ + id: z.string(), + /** + * The original dashboard vendor identifier. + */ + vendor: OriginalDashboardVendor, + /** + * The title of the dashboard + */ + title: z.string(), + /** + * The description of the dashboard + */ + description: z.string(), + /** + * The data of the dashboard in the specified format + */ + data: z.string(), + /** + * The last updated timestamp of the dashboard + */ + last_updated: z.string().optional(), + /** + * The format of the dashboard data (e.g., 'json', 'xml') + */ + format: z.string(), + /** + * Additional properties specific to the splunk + */ + splunk_properties: SplunkOriginalDashboardProperties.optional(), + }) +); export type OriginalDashboard = z.infer; -export const OriginalDashboard = z.object({ - /** - * The unique identifier for the dashboard - */ - id: z.string(), - /** - * The original dashboard vendor identifier. - */ - vendor: OriginalDashboardVendor, - /** - * The title of the dashboard - */ - title: z.string(), - /** - * The description of the dashboard - */ - description: z.string(), - /** - * The data of the dashboard in the specified format - */ - data: z.string(), - /** - * The last updated timestamp of the dashboard - */ - last_updated: z.string().optional(), - /** - * The format of the dashboard data (e.g., 'json', 'xml') - */ - format: z.string(), - /** - * Additional properties specific to the splunk - */ - splunk_properties: SplunkOriginalDashboardProperties.optional(), -}); /** * The elastic dashboard translation. */ +export const ElasticDashboard = lazySchema(() => + z.object({ + /** + * The unique identifier for the dashboard installed Saved Object + */ + id: z.string().optional(), + /** + * The title of the dashboard + */ + title: z.string(), + /** + * The description of the dashboard + */ + description: z.string().optional(), + /** + * The data of the dashboard, format could depend on the vendor + */ + data: z.string().optional(), + }) +); export type ElasticDashboard = z.infer; -export const ElasticDashboard = z.object({ - /** - * The unique identifier for the dashboard installed Saved Object - */ - id: z.string().optional(), - /** - * The title of the dashboard - */ - title: z.string(), - /** - * The description of the dashboard - */ - description: z.string().optional(), - /** - * The data of the dashboard, format could depend on the vendor - */ - data: z.string().optional(), -}); /** * The dashboard migration document object. */ +export const DashboardMigrationDashboardData = lazySchema(() => + z.object({ + /** + * The moment of creation + */ + '@timestamp': z.string(), + /** + * The migration id. + */ + migration_id: NonEmptyString, + /** + * The user profile ID of the user who created the migration. + */ + created_by: NonEmptyString, + /** + * The original dashboard to migrate. + */ + original_dashboard: OriginalDashboard, + /** + * The translated elastic dashboard. + */ + elastic_dashboard: ElasticDashboard.optional(), + /** + * The rule translation result. + */ + translation_result: MigrationTranslationResult.optional(), + /** + * The status of the dashboard migration process. + */ + status: MigrationStatus.default('pending'), + /** + * The comments for the migration including a summary from the LLM in markdown. + */ + comments: MigrationComments.optional(), + /** + * The moment of the last update + */ + updated_at: z.string().optional(), + /** + * The user who last updated the migration + */ + updated_by: z.string().optional(), + }) +); export type DashboardMigrationDashboardData = z.infer; -export const DashboardMigrationDashboardData = z.object({ - /** - * The moment of creation - */ - '@timestamp': z.string(), - /** - * The migration id. - */ - migration_id: NonEmptyString, - /** - * The user profile ID of the user who created the migration. - */ - created_by: NonEmptyString, - /** - * The original dashboard to migrate. - */ - original_dashboard: OriginalDashboard, - /** - * The translated elastic dashboard. - */ - elastic_dashboard: ElasticDashboard.optional(), - /** - * The rule translation result. - */ - translation_result: MigrationTranslationResult.optional(), - /** - * The status of the dashboard migration process. - */ - status: MigrationStatus.default('pending'), - /** - * The comments for the migration including a summary from the LLM in markdown. - */ - comments: MigrationComments.optional(), - /** - * The moment of the last update - */ - updated_at: z.string().optional(), - /** - * The user who last updated the migration - */ - updated_by: z.string().optional(), -}); /** * The dashboard migration document object. */ +export const DashboardMigrationDashboard = lazySchema(() => + z + .object({ + /** + * The dashboard migration id + */ + id: NonEmptyString, + }) + .merge(DashboardMigrationDashboardData) +); export type DashboardMigrationDashboard = z.infer; -export const DashboardMigrationDashboard = z - .object({ - /** - * The dashboard migration id - */ - id: NonEmptyString, - }) - .extend(DashboardMigrationDashboardData); /** * The partial version of the migrated elastic dashboard. */ +export const ElasticDashboardPartial = lazySchema(() => ElasticDashboard.partial()); export type ElasticDashboardPartial = z.infer; -export const ElasticDashboardPartial = ElasticDashboard.partial(); /** * The dashboard migration data object for dashboard update operation */ +export const UpdateMigrationDashboard = lazySchema(() => + z.object({ + /** + * The dashboard migration id + */ + id: NonEmptyString, + /** + * The migrated elastic dashboard attributes to update. + */ + elastic_dashboard: ElasticDashboardPartial.optional(), + /** + * The comments for the migration including a summary from the LLM in markdown. + */ + comments: MigrationComments.optional(), + }) +); export type UpdateMigrationDashboard = z.infer; -export const UpdateMigrationDashboard = z.object({ - /** - * The dashboard migration id - */ - id: NonEmptyString, - /** - * The migrated elastic dashboard attributes to update. - */ - elastic_dashboard: ElasticDashboardPartial.optional(), - /** - * The comments for the migration including a summary from the LLM in markdown. - */ - comments: MigrationComments.optional(), -}); /** * The dashboard migration task stats object. */ +export const DashboardMigrationTaskStats = lazySchema(() => MigrationTaskStats); export type DashboardMigrationTaskStats = z.infer; -export const DashboardMigrationTaskStats = MigrationTaskStats; /** * The dashboard migration task execution settings. */ +export const DashboardMigrationTaskExecutionSettings = lazySchema(() => + z.object({ + /** + * The connector ID used in the last execution. + */ + connector_id: z.string(), + }) +); export type DashboardMigrationTaskExecutionSettings = z.infer< typeof DashboardMigrationTaskExecutionSettings >; -export const DashboardMigrationTaskExecutionSettings = z.object({ - /** - * The connector ID used in the last execution. - */ - connector_id: z.string(), -}); /** * Indicates the filter to retry the migrations dashboards translation */ +export const DashboardMigrationRetryFilter = lazySchema(() => + z.enum(['failed', 'not_fully_translated']) +); export type DashboardMigrationRetryFilter = z.infer; -export const DashboardMigrationRetryFilter = z.enum(['failed', 'not_fully_translated']); export type DashboardMigrationRetryFilterEnum = typeof DashboardMigrationRetryFilter.enum; export const DashboardMigrationRetryFilterEnum = DashboardMigrationRetryFilter.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts index 01bd9084aa952..49124fba2154a 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts @@ -14,7 +14,7 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { NonEmptyString } from '../../api/model/primitives.gen'; import { Threat } from '../../api/detection_engine/model/rule_schema/common_attributes.gen'; @@ -30,378 +30,410 @@ import { /** * The original rule vendor identifier. */ +export const OriginalRuleVendor = lazySchema(() => z.enum(['splunk', 'qradar'])); export type OriginalRuleVendor = z.infer; -export const OriginalRuleVendor = z.enum(['splunk', 'qradar']); export type OriginalRuleVendorEnum = typeof OriginalRuleVendor.enum; export const OriginalRuleVendorEnum = OriginalRuleVendor.enum; /** * The original rule annotations containing additional information. */ +export const OriginalRuleAnnotations = lazySchema(() => + z + .object({ + /** + * The original rule Mitre Attack IDs. + */ + mitre_attack: z.array(z.string()).optional(), + }) + .catchall(z.unknown()) +); export type OriginalRuleAnnotations = z.infer; -export const OriginalRuleAnnotations = z - .object({ - /** - * The original rule Mitre Attack IDs. - */ - mitre_attack: z.array(z.string()).optional(), - }) - .catchall(z.unknown()); /** * The original rule to migrate. */ +export const OriginalRule = lazySchema(() => + z.object({ + /** + * The original rule id. + */ + id: NonEmptyString, + /** + * The original rule vendor identifier. + */ + vendor: OriginalRuleVendor, + /** + * The original rule name. + */ + title: NonEmptyString, + /** + * The original rule description. + */ + description: z.string(), + /** + * The original rule query. + */ + query: z.string().min(1), + /** + * The original rule query language. + */ + query_language: z.string(), + /** + * The original rule annotations containing additional information. + */ + annotations: OriginalRuleAnnotations.optional(), + /** + * The original rule's severity or some representation of it. + */ + severity: z.string().optional(), + /** + * The MITRE ATT&CK threat information for this rule. + */ + threat: z.array(Threat).optional(), + }) +); export type OriginalRule = z.infer; -export const OriginalRule = z.object({ - /** - * The original rule id. - */ - id: NonEmptyString, - /** - * The original rule vendor identifier. - */ - vendor: OriginalRuleVendor, - /** - * The original rule name. - */ - title: NonEmptyString, - /** - * The original rule description. - */ - description: z.string(), - /** - * The original rule query. - */ - query: z.string().min(1), - /** - * The original rule query language. - */ - query_language: z.string(), - /** - * The original rule annotations containing additional information. - */ - annotations: OriginalRuleAnnotations.optional(), - /** - * The original rule's severity or some representation of it. - */ - severity: z.string().optional(), - /** - * The MITRE ATT&CK threat information for this rule. - */ - threat: z.array(Threat).optional(), -}); /** * The migrated elastic rule. */ +export const ElasticRule = lazySchema(() => + z.object({ + /** + * The migrated rule title. + */ + title: z.string(), + /** + * The migrated rule description. + */ + description: z.string().optional(), + /** + * The migrated rule severity. + */ + severity: z.string().optional(), + /** + * The migrated rule risk_score value, integer between 0 and 100. + */ + risk_score: z.number().optional(), + /** + * The translated elastic query. + */ + query: z.string().optional(), + /** + * The translated elastic query language. + */ + query_language: z.literal('esql').optional(), + /** + * The Elastic prebuilt rule id matched. + */ + prebuilt_rule_id: NonEmptyString.nullable().optional(), + /** + * The IDs of the Elastic integrations suggested to be installed for this rule. + */ + integration_ids: z.array(z.string()).optional(), + /** + * The Elastic rule id installed as a result. + */ + id: NonEmptyString.optional(), + /** + * The MITRE ATT&CK threat information for this rule. + */ + threat: z.array(Threat).optional(), + }) +); export type ElasticRule = z.infer; -export const ElasticRule = z.object({ - /** - * The migrated rule title. - */ - title: z.string(), - /** - * The migrated rule description. - */ - description: z.string().optional(), - /** - * The migrated rule severity. - */ - severity: z.string().optional(), - /** - * The migrated rule risk_score value, integer between 0 and 100. - */ - risk_score: z.number().optional(), - /** - * The translated elastic query. - */ - query: z.string().optional(), - /** - * The translated elastic query language. - */ - query_language: z.literal('esql').optional(), - /** - * The Elastic prebuilt rule id matched. - */ - prebuilt_rule_id: NonEmptyString.nullable().optional(), - /** - * The IDs of the Elastic integrations suggested to be installed for this rule. - */ - integration_ids: z.array(z.string()).optional(), - /** - * The Elastic rule id installed as a result. - */ - id: NonEmptyString.optional(), - /** - * The MITRE ATT&CK threat information for this rule. - */ - threat: z.array(Threat).optional(), -}); /** * The partial version of the migrated elastic rule. */ +export const ElasticRulePartial = lazySchema(() => ElasticRule.partial()); export type ElasticRulePartial = z.infer; -export const ElasticRulePartial = ElasticRule.partial(); /** * The prebuilt rule version. */ +export const PrebuiltRuleVersion = lazySchema(() => + z.object({ + /** + * The latest available version of prebuilt rule. + */ + target: RuleResponse, + /** + * The currently installed version of prebuilt rule. + */ + current: RuleResponse.optional(), + }) +); export type PrebuiltRuleVersion = z.infer; -export const PrebuiltRuleVersion = z.object({ - /** - * The latest available version of prebuilt rule. - */ - target: RuleResponse, - /** - * The currently installed version of prebuilt rule. - */ - current: RuleResponse.optional(), -}); /** * The last execution of the rule migration task. */ +export const RuleMigrationLastExecution = lazySchema(() => + MigrationLastExecution.merge( + z.object({ + /** + * Indicates if the last execution skipped matching prebuilt rules. + */ + skip_prebuilt_rules_matching: z.boolean().optional(), + }) + ) +); export type RuleMigrationLastExecution = z.infer; -export const RuleMigrationLastExecution = MigrationLastExecution.extend( + +/** + * The rule migration object ( without Id ) with its settings. + */ +export const RuleMigrationData = lazySchema(() => z.object({ /** - * Indicates if the last execution skipped matching prebuilt rules. + * The user profile ID of the user who created the migration. */ - skip_prebuilt_rules_matching: z.boolean().optional(), + created_by: NonEmptyString, + /** + * The moment migration was created + */ + created_at: NonEmptyString, + /** + * The last execution details of a rule migration task. + */ + last_execution: RuleMigrationLastExecution.optional(), }) ); - -/** - * The rule migration object ( without Id ) with its settings. - */ export type RuleMigrationData = z.infer; -export const RuleMigrationData = z.object({ - /** - * The user profile ID of the user who created the migration. - */ - created_by: NonEmptyString, - /** - * The moment migration was created - */ - created_at: NonEmptyString, - /** - * The last execution details of a rule migration task. - */ - last_execution: RuleMigrationLastExecution.optional(), -}); /** * The rule migration object with its settings. */ +export const RuleMigration = lazySchema(() => + z + .object({ + /** + * The rule migration id + */ + id: NonEmptyString, + /** + * The rule migration name + */ + name: NonEmptyString, + }) + .merge(RuleMigrationData) +); export type RuleMigration = z.infer; -export const RuleMigration = z - .object({ + +/** + * The rule migration document object. + */ +export const RuleMigrationRuleData = lazySchema(() => + z.object({ /** - * The rule migration id + * The moment of creation */ - id: NonEmptyString, + '@timestamp': z.string(), + /** + * The migration id. + */ + migration_id: NonEmptyString, + /** + * The user profile ID of the user who created the migration. + */ + created_by: NonEmptyString, + /** + * The original rule to migrate. + */ + original_rule: OriginalRule, + /** + * The migrated elastic rule. + */ + elastic_rule: ElasticRule.optional(), + /** + * The rule translation result. + */ + translation_result: MigrationTranslationResult.optional(), + /** + * The status of the rule migration process. + */ + status: MigrationStatus.default('pending'), /** - * The rule migration name + * The comments for the migration including a summary from the LLM in markdown. */ - name: NonEmptyString, + comments: MigrationComments.optional(), + /** + * The moment of the last update + */ + updated_at: z.string().optional(), + /** + * The user who last updated the migration + */ + updated_by: z.string().optional(), }) - .extend(RuleMigrationData); - -/** - * The rule migration document object. - */ +); export type RuleMigrationRuleData = z.infer; -export const RuleMigrationRuleData = z.object({ - /** - * The moment of creation - */ - '@timestamp': z.string(), - /** - * The migration id. - */ - migration_id: NonEmptyString, - /** - * The user profile ID of the user who created the migration. - */ - created_by: NonEmptyString, - /** - * The original rule to migrate. - */ - original_rule: OriginalRule, - /** - * The migrated elastic rule. - */ - elastic_rule: ElasticRule.optional(), - /** - * The rule translation result. - */ - translation_result: MigrationTranslationResult.optional(), - /** - * The status of the rule migration process. - */ - status: MigrationStatus.default('pending'), - /** - * The comments for the migration including a summary from the LLM in markdown. - */ - comments: MigrationComments.optional(), - /** - * The moment of the last update - */ - updated_at: z.string().optional(), - /** - * The user who last updated the migration - */ - updated_by: z.string().optional(), -}); /** * The rule migration document object. */ +export const RuleMigrationRule = lazySchema(() => + z + .object({ + /** + * The rule migration id + */ + id: NonEmptyString, + }) + .merge(RuleMigrationRuleData) +); export type RuleMigrationRule = z.infer; -export const RuleMigrationRule = z - .object({ - /** - * The rule migration id - */ - id: NonEmptyString, - }) - .extend(RuleMigrationRuleData); /** * The rule migration task stats object. */ -export type RuleMigrationTaskStats = z.infer; -export const RuleMigrationTaskStats = MigrationTaskStats.extend( - z.object({ - /** - * The last execution of the rule migration task. - */ - last_execution: RuleMigrationLastExecution.optional(), - }) +export const RuleMigrationTaskStats = lazySchema(() => + MigrationTaskStats.merge( + z.object({ + /** + * The last execution of the rule migration task. + */ + last_execution: RuleMigrationLastExecution.optional(), + }) + ) ); +export type RuleMigrationTaskStats = z.infer; /** * The rule migration translation stats object. */ -export type RuleMigrationTranslationStats = z.infer; -export const RuleMigrationTranslationStats = z.object({ - /** - * The migration id - */ - id: NonEmptyString, - /** - * The rules migration translation stats. - */ - rules: z.object({ +export const RuleMigrationTranslationStats = lazySchema(() => + z.object({ /** - * The total number of rules in the migration. + * The migration id */ - total: z.number().int(), + id: NonEmptyString, /** - * The number of rules that have been successfully translated. + * The rules migration translation stats. */ - success: z.object({ + rules: z.object({ /** - * The total number of rules that have been successfully translated. + * The total number of rules in the migration. */ total: z.number().int(), /** - * The translation results + * The number of rules that have been successfully translated. */ - result: z.object({ + success: z.object({ /** - * The number of rules that have been fully translated. + * The total number of rules that have been successfully translated. */ - full: z.number().int(), + total: z.number().int(), /** - * The number of rules that have been partially translated. + * The translation results */ - partial: z.number().int(), + result: z.object({ + /** + * The number of rules that have been fully translated. + */ + full: z.number().int(), + /** + * The number of rules that have been partially translated. + */ + partial: z.number().int(), + /** + * The number of rules that could not be translated. + */ + untranslatable: z.number().int(), + }), /** - * The number of rules that could not be translated. + * The number of rules that have been successfully translated and can be installed. */ - untranslatable: z.number().int(), + installable: z.number().int(), + /** + * The number of rules that have been successfully translated and matched Elastic prebuilt rules. + */ + prebuilt: z.number().int(), + /** + * The number of rules that have the placeholder for the missing index pattern in the query. + */ + missing_index: z.number().int(), }), /** - * The number of rules that have been successfully translated and can be installed. - */ - installable: z.number().int(), - /** - * The number of rules that have been successfully translated and matched Elastic prebuilt rules. + * The number of rules that have failed translation. */ - prebuilt: z.number().int(), - /** - * The number of rules that have the placeholder for the missing index pattern in the query. - */ - missing_index: z.number().int(), + failed: z.number().int(), }), - /** - * The number of rules that have failed translation. - */ - failed: z.number().int(), - }), -}); + }) +); +export type RuleMigrationTranslationStats = z.infer; /** * The rule migration data object for rule update operation */ +export const UpdateRuleMigrationRule = lazySchema(() => + z.object({ + /** + * The rule migration id + */ + id: NonEmptyString, + /** + * The migrated elastic rule attributes to update. + */ + elastic_rule: ElasticRulePartial.optional(), + /** + * The comments for the migration including a summary from the LLM in markdown. + */ + comments: MigrationComments.optional(), + }) +); export type UpdateRuleMigrationRule = z.infer; -export const UpdateRuleMigrationRule = z.object({ - /** - * The rule migration id - */ - id: NonEmptyString, - /** - * The migrated elastic rule attributes to update. - */ - elastic_rule: ElasticRulePartial.optional(), - /** - * The comments for the migration including a summary from the LLM in markdown. - */ - comments: MigrationComments.optional(), -}); /** * Indicates the filter to retry the migrations rules translation */ +export const RuleMigrationRetryFilter = lazySchema(() => + z.enum(['failed', 'not_fully_translated', 'selected']) +); export type RuleMigrationRetryFilter = z.infer; -export const RuleMigrationRetryFilter = z.enum(['failed', 'not_fully_translated', 'selected']); export type RuleMigrationRetryFilterEnum = typeof RuleMigrationRetryFilter.enum; export const RuleMigrationRetryFilterEnum = RuleMigrationRetryFilter.enum; /** * The migration rules integration stats object. */ +export const RuleMigrationIntegrationStats = lazySchema(() => + z.object({ + /** + * The integration id + */ + id: NonEmptyString, + /** + * The number of rules that are associated with the integration. + */ + total_rules: z.number().int(), + }) +); export type RuleMigrationIntegrationStats = z.infer; -export const RuleMigrationIntegrationStats = z.object({ - /** - * The integration id - */ - id: NonEmptyString, - /** - * The number of rules that are associated with the integration. - */ - total_rules: z.number().int(), -}); /** * The integrations stats objects of all the rule of all the migrations. */ +export const RuleMigrationAllIntegrationsStats = lazySchema(() => + z.array(RuleMigrationIntegrationStats) +); export type RuleMigrationAllIntegrationsStats = z.infer; -export const RuleMigrationAllIntegrationsStats = z.array(RuleMigrationIntegrationStats); /** * The rule migration task execution settings. */ +export const RuleMigrationTaskExecutionSettings = lazySchema(() => + z.object({ + /** + * The connector ID used for the last execution. + */ + connector_id: z.string(), + /** + * Indicates if the current execution should skip matching prebuilt rules. + */ + skip_prebuilt_rules_matching: z.boolean().optional(), + }) +); export type RuleMigrationTaskExecutionSettings = z.infer; -export const RuleMigrationTaskExecutionSettings = z.object({ - /** - * The connector ID used for the last execution. - */ - connector_id: z.string(), - /** - * Indicates if the current execution should skip matching prebuilt rules. - */ - skip_prebuilt_rules_matching: z.boolean().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/qradar.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/qradar.gen.ts index 8f48c69d78d9e..a40dd187bb7da 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/qradar.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/qradar.gen.ts @@ -14,23 +14,25 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The type of the resource */ +export const QradarResourceType = lazySchema(() => + z.enum([ + 'qidmap', + 'reference_data_rules', + 'sensordevicetype', + 'sensordeviceprotocols', + 'sensordevicecategory', + 'ariel_property_expression', + 'ariel_regex_property', + 'reference_data', + 'offense_type', + 'lookup', + ]) +); export type QradarResourceType = z.infer; -export const QradarResourceType = z.enum([ - 'qidmap', - 'reference_data_rules', - 'sensordevicetype', - 'sensordeviceprotocols', - 'sensordevicecategory', - 'ariel_property_expression', - 'ariel_regex_property', - 'reference_data', - 'offense_type', - 'lookup', -]); export type QradarResourceTypeEnum = typeof QradarResourceType.enum; export const QradarResourceTypeEnum = QradarResourceType.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/splunk.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/splunk.gen.ts index 4c35112568211..d99f1b36f1d09 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/splunk.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/common/splunk.gen.ts @@ -14,12 +14,12 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * The type of the resource */ +export const SplunkResourceType = lazySchema(() => z.enum(['lookup', 'macro'])); export type SplunkResourceType = z.infer; -export const SplunkResourceType = z.enum(['lookup', 'macro']); export type SplunkResourceTypeEnum = typeof SplunkResourceType.enum; export const SplunkResourceTypeEnum = SplunkResourceType.enum; diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/dashboards/splunk.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/dashboards/splunk.gen.ts index 52e8265448c34..2c974e0bc21b4 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/dashboards/splunk.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/dashboards/splunk.gen.ts @@ -14,83 +14,89 @@ * version: not applicable */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Properties of the original dashboard */ +export const SplunkOriginalDashboardExportProperties = lazySchema(() => + z.object({ + /** + * The unique identifier for the dashboard + */ + id: z.string(), + /** + * The label of the dashboard + */ + label: z.string().optional(), + /** + * The title of the dashboard + */ + title: z.string(), + /** + * The description of the dashboard + */ + description: z.string().optional(), + /** + * The EAI data of the dashboard, typically in XML format + */ + 'eai:data': z.string(), + /** + * The application associated with the EAI ACL + */ + 'eai:acl.app': z.string().optional(), + /** + * The sharing model of the EAI ACL (e.g., app, global) + */ + 'eai:acl.sharing': z.string().optional(), + /** + * The owner of the EAI ACL + */ + 'eai:acl.owner': z.string().optional(), + /** + * The last updated timestamp of the dashboard + */ + updated: z.string().optional(), + /** + * The version of the dashboard + */ + version: z.string().optional(), + }) +); export type SplunkOriginalDashboardExportProperties = z.infer< typeof SplunkOriginalDashboardExportProperties >; -export const SplunkOriginalDashboardExportProperties = z.object({ - /** - * The unique identifier for the dashboard - */ - id: z.string(), - /** - * The label of the dashboard - */ - label: z.string().optional(), - /** - * The title of the dashboard - */ - title: z.string(), - /** - * The description of the dashboard - */ - description: z.string().optional(), - /** - * The EAI data of the dashboard, typically in XML format - */ - 'eai:data': z.string(), - /** - * The application associated with the EAI ACL - */ - 'eai:acl.app': z.string().optional(), - /** - * The sharing model of the EAI ACL (e.g., app, global) - */ - 'eai:acl.sharing': z.string().optional(), - /** - * The owner of the EAI ACL - */ - 'eai:acl.owner': z.string().optional(), - /** - * The last updated timestamp of the dashboard - */ - updated: z.string().optional(), - /** - * The version of the dashboard - */ - version: z.string().optional(), -}); /** * Data Model for Splunk's original dashboard */ +export const SplunkOriginalDashboardExport = lazySchema(() => + z.object({ + /** + * The result object in Splunk file containing the dashboard's properties + */ + result: SplunkOriginalDashboardExportProperties, + }) +); export type SplunkOriginalDashboardExport = z.infer; -export const SplunkOriginalDashboardExport = z.object({ - /** - * The result object in Splunk file containing the dashboard's properties - */ - result: SplunkOriginalDashboardExportProperties, -}); /** * Properties of the original dashboard */ +export const SplunkOriginalDashboardProperties = lazySchema(() => + z.object({ + /** + * The application associated with the EAI ACL + */ + app: z.string().optional(), + /** + * The sharing model of the EAI ACL (e.g., app, global) + */ + sharing: z.string().optional(), + /** + * The owner of the EAI ACL + */ + owner: z.string().optional(), + }) +); export type SplunkOriginalDashboardProperties = z.infer; -export const SplunkOriginalDashboardProperties = z.object({ - /** - * The application associated with the EAI ACL - */ - app: z.string().optional(), - /** - * The sharing model of the EAI ACL (e.g., app, global) - */ - sharing: z.string().optional(), - /** - * The owner of the EAI ACL - */ - owner: z.string().optional(), -}); diff --git a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/rules/qradar.gen.ts b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/rules/qradar.gen.ts index 987d16fdcb7f4..33e394594af88 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/rules/qradar.gen.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/vendor/rules/qradar.gen.ts @@ -14,61 +14,71 @@ * version: 1.0.0 */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; +export const QRadarMitreMappingTechnique = lazySchema(() => + z.object({ + confidence: z.string().optional(), + enabled: z.boolean(), + id: z.string(), + }) +); export type QRadarMitreMappingTechnique = z.infer; -export const QRadarMitreMappingTechnique = z.object({ - confidence: z.string().optional(), - enabled: z.boolean(), - id: z.string(), -}); +export const QRadarMitreMappingTactic = lazySchema(() => + z.object({ + confidence: z.string().optional(), + user_override: z.boolean().optional(), + enabled: z.boolean(), + ibm_default: z.boolean().optional(), + name: z.string(), + techniques: z.object({}).catchall(QRadarMitreMappingTechnique).optional(), + }) +); export type QRadarMitreMappingTactic = z.infer; -export const QRadarMitreMappingTactic = z.object({ - confidence: z.string().optional(), - user_override: z.boolean().optional(), - enabled: z.boolean(), - ibm_default: z.boolean().optional(), - name: z.string(), - techniques: z.object({}).catchall(QRadarMitreMappingTechnique).optional(), -}); +export const QRadarMitreMappingRule = lazySchema(() => + z.object({ + id: z.string(), + has_ibm_default: z.boolean().optional(), + last_updated: z.number().optional(), + mapping: z.object({}).catchall(QRadarMitreMappingTactic), + 'min-mitre-version': z.number().optional(), + }) +); export type QRadarMitreMappingRule = z.infer; -export const QRadarMitreMappingRule = z.object({ - id: z.string(), - has_ibm_default: z.boolean().optional(), - last_updated: z.number().optional(), - mapping: z.object({}).catchall(QRadarMitreMappingTactic), - 'min-mitre-version': z.number().optional(), -}); /** * QRadar MITRE mappings data keyed by rule name */ +export const QRadarMitreMappingsData = lazySchema(() => + z.object({}).catchall(QRadarMitreMappingRule) +); export type QRadarMitreMappingsData = z.infer; -export const QRadarMitreMappingsData = z.object({}).catchall(QRadarMitreMappingRule); /** * Request to enhance rules with QRadar MITRE mappings */ +export const QRadarMitreRequest = lazySchema(() => + z.object({ + /** + * The vendor identifier + */ + vendor: z.literal('qradar'), + /** + * The type of enhancement data + */ + type: z.literal('mitre'), + /** + * QRadar MITRE mappings data keyed by rule name + */ + data: QRadarMitreMappingsData, + }) +); export type QRadarMitreRequest = z.infer; -export const QRadarMitreRequest = z.object({ - /** - * The vendor identifier - */ - vendor: z.literal('qradar'), - /** - * The type of enhancement data - */ - type: z.literal('mitre'), - /** - * QRadar MITRE mappings data keyed by rule name - */ - data: QRadarMitreMappingsData, -}); /** * Union type for QRadar rule enhancements */ +export const EnhanceQRadarRule = lazySchema(() => QRadarMitreRequest); export type EnhanceQRadarRule = z.infer; -export const EnhanceQRadarRule = QRadarMitreRequest; From ec22bebb35c275ab899deb3bd08bcd858b9c6a79 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 17 Apr 2026 19:46:37 +0200 Subject: [PATCH 4/6] use WeakMap to make Zod schemas GCable --- .../shared/kbn-zod/v4/lazy_schema.test.ts | 44 ++++++++++++++++++- .../packages/shared/kbn-zod/v4/lazy_schema.ts | 23 ++++++++-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts index 7c3d933e6af63..040ee402b5495 100644 --- a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts +++ b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts @@ -22,17 +22,57 @@ describe('lazySchema', () => { expect(factory).toHaveBeenCalledTimes(1); }); - it('memoizes the materialized schema', () => { + it('caches the materialized schema while it is still reachable', () => { const factory = jest.fn(() => z.object({ id: z.string() })); const schema = lazySchema(factory); - schema.parse({ id: 'a' }); + // A single retained reference pins the instance, so all calls reuse it. + const pinned = schema.safeParse({ id: 'a' }); + expect(pinned.success).toBe(true); schema.parse({ id: 'b' }); schema.safeParse({ id: 'c' }); expect(factory).toHaveBeenCalledTimes(1); }); + // The materialized schema is held via `WeakRef`, so if the GC reclaims it + // between turns (under memory pressure), the next access rebuilds it from + // the factory. We verify the rebuild path by simulating cache eviction — + // V8's heuristics are not deterministic enough to assert collection itself. + it('rebuilds the schema after the WeakRef is cleared', () => { + const factory = jest.fn(() => z.object({ id: z.string() })); + const RealWeakRef = globalThis.WeakRef; + let onlyRef: WeakRef | undefined; + class EvictableWeakRef { + private target: T | undefined; + constructor(target: T) { + this.target = target; + onlyRef = this as unknown as WeakRef; + } + deref(): T | undefined { + return this.target; + } + evict(): void { + this.target = undefined; + } + } + (globalThis as { WeakRef: unknown }).WeakRef = EvictableWeakRef; + try { + const schema = lazySchema(factory); + + schema.parse({ id: 'a' }); + expect(factory).toHaveBeenCalledTimes(1); + + // Simulate the GC reclaiming the schema. + (onlyRef as unknown as EvictableWeakRef).evict(); + + schema.parse({ id: 'b' }); + expect(factory).toHaveBeenCalledTimes(2); + } finally { + (globalThis as { WeakRef: unknown }).WeakRef = RealWeakRef; + } + }); + it('forwards parse/safeParse and applies validation', () => { const schema = lazySchema(() => z.object({ id: z.string(), count: z.number().int().min(0) }).strict() diff --git a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts index 58b7353e4ef98..2a5e993b0dd7d 100644 --- a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts +++ b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts @@ -13,12 +13,19 @@ import type * as z4 from 'zod/v4'; * Wraps a Zod schema factory in a Proxy that defers construction of the * underlying schema until any property (including `.parse`, `.safeParse`, * `.extend`, `.optional`, etc.) is first accessed. The materialized schema - * is memoized, so subsequent accesses reuse it. + * is cached behind a `WeakRef`, so once no external consumer keeps it alive + * the GC is free to reclaim it; the next access rebuilds it from the factory. * * Intended for generated schemas (e.g. from `@kbn/openapi-generator`) where * many schemas are declared at module-load time but only a subset is used * at runtime. Unused schemas stay as a single Proxy instance plus a closure, - * keeping baseline heap low. + * keeping baseline heap low; transiently-used schemas are collectible after + * their last reference is dropped. + * + * Trade-off: if the same schema is used repeatedly across GC cycles without + * callers retaining a reference, each cycle pays the cost of rebuilding it. + * Hold on to a reference (e.g. `const s = LazySchema; s.parse(...)` inside a + * hot path) if that matters. * * Caveat: `instanceof z.ZodObject` / `instanceof z.ZodType` on the returned * value will be `false` because the Proxy target is an empty object. Zod's @@ -26,8 +33,16 @@ import type * as z4 from 'zod/v4'; * rather than `instanceof`, so this is safe in practice. */ export function lazySchema(factory: () => T): T { - let instance: T | undefined; - const materialize = (): T => (instance ??= factory()); + let ref: WeakRef | undefined; + const materialize = (): T => { + const cached = ref?.deref(); + if (cached) { + return cached; + } + const fresh = factory(); + ref = new WeakRef(fresh); + return fresh; + }; return new Proxy({} as T, { get(_target, prop) { From 0e71ca4fa0f615304fae2a4fb80bdcfa0f35c0d7 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 20 Apr 2026 09:31:16 +0200 Subject: [PATCH 5/6] extract generic lazyGCableObject utility function --- .../packages/shared/kbn-lazy-object/README.md | 50 +++++++++- .../packages/shared/kbn-lazy-object/index.ts | 1 + .../src/lazy_gcable_object.test.ts | 99 +++++++++++++++++++ .../kbn-lazy-object/src/lazy_gcable_object.ts | 57 +++++++++++ .../shared/kbn-zod/v4/lazy_schema.test.ts | 65 +----------- .../packages/shared/kbn-zod/v4/lazy_schema.ts | 58 +++-------- 6 files changed, 220 insertions(+), 110 deletions(-) create mode 100644 src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.test.ts create mode 100644 src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.ts diff --git a/src/platform/packages/shared/kbn-lazy-object/README.md b/src/platform/packages/shared/kbn-lazy-object/README.md index 740db0853224e..f25fd796e4bf7 100644 --- a/src/platform/packages/shared/kbn-lazy-object/README.md +++ b/src/platform/packages/shared/kbn-lazy-object/README.md @@ -1,3 +1,51 @@ # @kbn/lazy-object -Empty package generated by @kbn/generate +Utilities for deferring the construction of objects until they are first used, +so that modules that declare many objects at load-time don't pay the +construction cost (time and memory) for the ones that are never touched. + +The package offers several variants that differ in granularity, caching, and +how they're authored: + +## `lazyObject(obj)` + Babel plugin + +Author object literals normally; a Babel plugin rewrites `lazyObject({ ... })` +call sites into `createLazyObjectFromFactories({ key: () => expr, ... })` so +each property is built on first access and cached forever. At runtime without +the Babel plugin this is an identity function. + +Use when: you want ergonomic lazy fields on an object without changing source +style. Requires the Babel plugin in the build. + +## `createLazyObjectFromFactories(factories)` + +Runtime-only version of the above. Takes an object whose values are factory +functions and returns an object whose properties materialize on first read +(cached forever). No build-time support needed. + +Use when: you want per-property laziness without the Babel plugin. + +## `createLazyObjectFromAnnotations(obj)` + `annotateLazy(fn)` + +Like `createLazyObjectFromFactories`, but you mark individual factory values +with `annotateLazy(...)` so an object can mix eagerly-defined fields with +lazily-computed ones. + +Use when: only some fields of an object benefit from laziness. + +## `lazyGCableObject(factory)` + +Whole-object lazy with GC-reclaimable caching. Returns a Proxy that builds the +underlying object on first property access, caches it behind a `WeakRef`, and +lets the GC reclaim it once no consumer is holding a reference. The next access +rebuilds it. + +Use when: you declare many similar objects at module-load time, expect only a +subset to be used, and want transiently-used ones to be collectible rather than +pinned for the process lifetime. + +## Metrics + +`getLazyObjectMetrics()` returns a `{ count, called }` snapshot for the +annotation-based variants (how many lazy keys were registered vs. materialized), +useful when evaluating whether laziness is paying off in a given module graph. diff --git a/src/platform/packages/shared/kbn-lazy-object/index.ts b/src/platform/packages/shared/kbn-lazy-object/index.ts index 160fd801aaafc..4af100b97c1bd 100644 --- a/src/platform/packages/shared/kbn-lazy-object/index.ts +++ b/src/platform/packages/shared/kbn-lazy-object/index.ts @@ -10,6 +10,7 @@ export { createLazyObjectFromFactories } from './src/create_lazy_object_from_factories'; export { getLazyObjectMetrics } from './src/metrics'; export { lazyObject } from './src/lazy_object'; +export { lazyGCableObject } from './src/lazy_gcable_object'; export { createLazyObjectFromAnnotations, annotateLazy, diff --git a/src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.test.ts b/src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.test.ts new file mode 100644 index 0000000000000..f13b47987229d --- /dev/null +++ b/src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.test.ts @@ -0,0 +1,99 @@ +/* + * 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 { lazyGCableObject } from './lazy_gcable_object'; + +describe('lazyGCableObject', () => { + it('defers factory invocation until first property access', () => { + const factory = jest.fn(() => ({ value: 1 })); + const obj = lazyGCableObject(factory); + + expect(factory).not.toHaveBeenCalled(); + + // Access a property to trigger materialization. + void obj.value; + + expect(factory).toHaveBeenCalledTimes(1); + }); + + it('caches the materialized object while it is still reachable', () => { + const factory = jest.fn(() => ({ value: 1 })); + const obj = lazyGCableObject(factory); + + // A single retained reference pins the instance, so all reads reuse it. + expect(obj.value).toBe(1); + expect(obj.value).toBe(1); + expect(obj.value).toBe(1); + + expect(factory).toHaveBeenCalledTimes(1); + }); + + // The materialized object is held via `WeakRef`, so if the GC reclaims it + // between turns (under memory pressure), the next access rebuilds it from + // the factory. We verify the rebuild path by simulating cache eviction — + // V8's heuristics are not deterministic enough to assert collection itself. + it('rebuilds the object after the WeakRef is cleared', () => { + const factory = jest.fn(() => ({ value: 1 })); + const RealWeakRef = globalThis.WeakRef; + + let onlyRef: WeakRef | undefined; + + class EvictableWeakRef { + private target: T | undefined; + constructor(target: T) { + this.target = target; + onlyRef = this as unknown as WeakRef; + } + deref(): T | undefined { + return this.target; + } + evict(): void { + this.target = undefined; + } + } + (globalThis as { WeakRef: unknown }).WeakRef = EvictableWeakRef; + + try { + const obj = lazyGCableObject(factory); + + void obj.value; + expect(factory).toHaveBeenCalledTimes(1); + + // Simulate the GC reclaiming the object. + (onlyRef as unknown as EvictableWeakRef).evict(); + + void obj.value; + expect(factory).toHaveBeenCalledTimes(2); + } finally { + (globalThis as { WeakRef: unknown }).WeakRef = RealWeakRef; + } + }); + + it('binds function-valued properties to the materialized object', () => { + const obj = lazyGCableObject(() => ({ + value: 42, + getValue() { + return this.value; + }, + })); + + // Destructuring loses the original `this`; the Proxy must bind the method + // to the materialized target so the call still resolves correctly. + const { getValue } = obj; + expect(getValue()).toBe(42); + expect(obj.getValue()).toBe(42); + }); + + it('supports the `in` operator via the has trap', () => { + const obj = lazyGCableObject(() => ({ a: 1, b: 2 })); + + expect('a' in obj).toBe(true); + expect('missing' in obj).toBe(false); + }); +}); diff --git a/src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.ts b/src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.ts new file mode 100644 index 0000000000000..709eb2da57515 --- /dev/null +++ b/src/platform/packages/shared/kbn-lazy-object/src/lazy_gcable_object.ts @@ -0,0 +1,57 @@ +/* + * 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". + */ + +/** + * Wraps an object factory in a Proxy that defers construction of the underlying + * object until any property is first accessed. The materialized object is cached + * behind a `WeakRef`, so once no external consumer keeps it alive the GC is free + * to reclaim it; the next access rebuilds it from the factory. Function-valued + * properties are bound to the materialized object so methods observe a stable + * `this`. + * + * Intended for cases where many objects are declared at module-load time but + * only a subset is used at runtime. Unused entries stay as a single Proxy + * instance plus a closure, keeping baseline heap low; transiently-used entries + * are collectible after their last reference is dropped. + * + * Trade-off: if the same object is used repeatedly across GC cycles without + * callers retaining a reference, each cycle pays the cost of rebuilding it. + * Hold on to a reference (e.g. `const o = LazyThing; o.method(...)` inside a + * hot path) if that matters. + * + * Caveat: `instanceof` checks on the returned value will be `false` because the + * Proxy target is an empty object. Structural checks on properties of the + * materialized object work as expected. + */ +export function lazyGCableObject(factory: () => T): T { + let ref: WeakRef | undefined; + const materialize = (): T => { + const cached = ref?.deref(); + if (cached) { + return cached; + } + const fresh = factory(); + ref = new WeakRef(fresh); + return fresh; + }; + + return new Proxy({} as T, { + get(_target, prop) { + const real = materialize() as unknown as Record; + const value = real[prop]; + if (typeof value === 'function') { + return (value as (...args: unknown[]) => unknown).bind(real); + } + return value; + }, + has(_target, prop) { + return prop in (materialize() as unknown as object); + }, + }); +} diff --git a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts index 040ee402b5495..ed3ff9a49c795 100644 --- a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts +++ b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.test.ts @@ -10,69 +10,10 @@ import { z } from '.'; import { lazySchema } from './lazy_schema'; +/** + * Test Zod specific patters + */ describe('lazySchema', () => { - it('defers factory invocation until first property access', () => { - const factory = jest.fn(() => z.object({ id: z.string() })); - const schema = lazySchema(factory); - - expect(factory).not.toHaveBeenCalled(); - - schema.parse({ id: 'a' }); - - expect(factory).toHaveBeenCalledTimes(1); - }); - - it('caches the materialized schema while it is still reachable', () => { - const factory = jest.fn(() => z.object({ id: z.string() })); - const schema = lazySchema(factory); - - // A single retained reference pins the instance, so all calls reuse it. - const pinned = schema.safeParse({ id: 'a' }); - expect(pinned.success).toBe(true); - schema.parse({ id: 'b' }); - schema.safeParse({ id: 'c' }); - - expect(factory).toHaveBeenCalledTimes(1); - }); - - // The materialized schema is held via `WeakRef`, so if the GC reclaims it - // between turns (under memory pressure), the next access rebuilds it from - // the factory. We verify the rebuild path by simulating cache eviction — - // V8's heuristics are not deterministic enough to assert collection itself. - it('rebuilds the schema after the WeakRef is cleared', () => { - const factory = jest.fn(() => z.object({ id: z.string() })); - const RealWeakRef = globalThis.WeakRef; - let onlyRef: WeakRef | undefined; - class EvictableWeakRef { - private target: T | undefined; - constructor(target: T) { - this.target = target; - onlyRef = this as unknown as WeakRef; - } - deref(): T | undefined { - return this.target; - } - evict(): void { - this.target = undefined; - } - } - (globalThis as { WeakRef: unknown }).WeakRef = EvictableWeakRef; - try { - const schema = lazySchema(factory); - - schema.parse({ id: 'a' }); - expect(factory).toHaveBeenCalledTimes(1); - - // Simulate the GC reclaiming the schema. - (onlyRef as unknown as EvictableWeakRef).evict(); - - schema.parse({ id: 'b' }); - expect(factory).toHaveBeenCalledTimes(2); - } finally { - (globalThis as { WeakRef: unknown }).WeakRef = RealWeakRef; - } - }); - it('forwards parse/safeParse and applies validation', () => { const schema = lazySchema(() => z.object({ id: z.string(), count: z.number().int().min(0) }).strict() diff --git a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts index 2a5e993b0dd7d..4fb80d02fa9af 100644 --- a/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts +++ b/src/platform/packages/shared/kbn-zod/v4/lazy_schema.ts @@ -7,54 +7,18 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import type * as z4 from 'zod/v4'; +import { lazyGCableObject } from '@kbn/lazy-object/src/lazy_gcable_object'; /** - * Wraps a Zod schema factory in a Proxy that defers construction of the - * underlying schema until any property (including `.parse`, `.safeParse`, - * `.extend`, `.optional`, etc.) is first accessed. The materialized schema - * is cached behind a `WeakRef`, so once no external consumer keeps it alive - * the GC is free to reclaim it; the next access rebuilds it from the factory. + * Zod-typed wrapper around `lazyGCableObject` for generated schemas + * (e.g. from `@kbn/openapi-generator`). Defers construction of the schema + * until any property (`.parse`, `.safeParse`, `.extend`, `.optional`, ...) + * is first accessed, and lets the GC reclaim the materialized schema once no + * consumer is holding a reference. * - * Intended for generated schemas (e.g. from `@kbn/openapi-generator`) where - * many schemas are declared at module-load time but only a subset is used - * at runtime. Unused schemas stay as a single Proxy instance plus a closure, - * keeping baseline heap low; transiently-used schemas are collectible after - * their last reference is dropped. - * - * Trade-off: if the same schema is used repeatedly across GC cycles without - * callers retaining a reference, each cycle pays the cost of rebuilding it. - * Hold on to a reference (e.g. `const s = LazySchema; s.parse(...)` inside a - * hot path) if that matters. - * - * Caveat: `instanceof z.ZodObject` / `instanceof z.ZodType` on the returned - * value will be `false` because the Proxy target is an empty object. Zod's - * own internals and typical consumers use structural `_zod` / `.def` checks - * rather than `instanceof`, so this is safe in practice. + * Zod-specific caveat: `instanceof z.ZodObject` / `instanceof z.ZodType` on + * the returned value will be `false` because the Proxy target is an empty + * object. Zod's own internals and typical consumers use structural `_zod` / + * `.def` checks rather than `instanceof`, so this is safe in practice. */ -export function lazySchema(factory: () => T): T { - let ref: WeakRef | undefined; - const materialize = (): T => { - const cached = ref?.deref(); - if (cached) { - return cached; - } - const fresh = factory(); - ref = new WeakRef(fresh); - return fresh; - }; - - return new Proxy({} as T, { - get(_target, prop) { - const real = materialize() as unknown as Record; - const value = real[prop]; - if (typeof value === 'function') { - return (value as (...args: unknown[]) => unknown).bind(real); - } - return value; - }, - has(_target, prop) { - return prop in (materialize() as unknown as object); - }, - }); -} +export { lazyGCableObject as lazySchema }; From 817fcf4b91d4f833f1b62070d828d989db697156 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 17 Apr 2026 16:57:11 +0200 Subject: [PATCH 6/6] use local patched Zod v4 version --- local_deps/zod_4.3.6.tgz | Bin 0 -> 730165 bytes package.json | 5 +++-- yarn.lock | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 local_deps/zod_4.3.6.tgz diff --git a/local_deps/zod_4.3.6.tgz b/local_deps/zod_4.3.6.tgz new file mode 100644 index 0000000000000000000000000000000000000000..03a25bf1fffd05a8916544971b48cfc70d017eb1 GIT binary patch literal 730165 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∫!jEh}^wCx5F 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

uZ6*SXLaDtwK{x70Kcs_=5 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�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 |-vj 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 qg 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

    f8`{!&VA#PqBaH0DUf%pW*1ax&PKd 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�_aB(7kXvyGa!m7D9(E%t5G zc)^3%@BtoL-{{ESHMHM^)(FeLU1_{&^oi*2`-1Nr6=`&43uOBa=W}BMoYMx*c>(7{ zfOAuTua7F-z!wVe^PHp?iu(I;&+BmudY|W*wYa0owI}2$ki85Laj4C)ktDjAh8!C4 z@gTilkSC@9JpKrItq*{V4LCAGRSE?n3d7gt7)YYsutC5bL6Wb~moxb2!>u-z8pF6L-Q z-xJ?x$G{WOE()`6=)KXXZ~qhAt~|?H?-TYP+l$D^&GxXqYa2??m$ob~$d{)qFW{G+ zsV|}TkfX$g&#x{AQePtPF-CI?+r#ev*pW17|F(F*m_nQC8*+b}`r>ylFnVhA40aik z3g~`f*##IpLtW}I`v%`*{o(W5k|%>ICb}eM>4>=(9VIqu|91bRm3YmN(mwD6JDQ{a z{Q6RE)K?gPx#vmZXHBS}TLRo|`jbzT2`_K8SJn(FiinvzLjI*t4)Y7HV_SPss;%KO z0%*r=zAE}L70~;Hwkyy4vsq&Ux2P`yy}l^tE22E0GZO{sdIWl1QFc~Ey>1nrW8UmZ z(7%u;KcZc?#9Tdw>I`@hn=B7F+*YqXYBy1*g8qr?@p^1p?7y!6G*DhK0=ez&=Ribq z0vq}W{{7?jICG@{*CV39&9#PCsK-7_{-aVuTSbp(;&rS{46|?Kz5HLgizyZGYqy?v z)wSlR6T}gr6C4&kG%K#mA!xne@xZ0#G9OfcK`c^RNvd>$eo-CqGlA| zZV#W$;X`MEt|yw^jGuaWGTtnDEcryP<3wAd`mSvI=z%}C^qp#R%19$7 zNv`*6SR*IeJXK1zLHo!18%M{{=|>!aU8l8|fK*@Mrw;ulGmUqrmpOSlIeD38=Hq5> z_HdI|M1W3usyP|fk6NS7Ru2nh1KgTxXLm2p$F+R1&)^n>Qv&>}$>uR2U+YIT^fBD0 z(>Sx1EzFQWZv!7Up(t!#zFY2_c1oXg!Gq=LYO|QKSb^z`5oG83b*i;O*H0J7ls#jo zRp#vqvQ(}L!50YuN@-=Wx-`Z2B4!feL&nNs(V*j@?l5Dq$4xJwVad5~c*S+@MHrKQ z{8-*H+~eij?DHaBI#qCNvZ@F))PLQ!>U6Q)=VV{yc_*gFdL?`(v|fA}IIR{592nER z=^w7Xs`o=g)H0UYuI zxmfAsBHcx3dOg=7bg0ZKxi9+Mw7=~YM1P7OD?|REUlJRUeyFNWo5NIkAG4g(_>dPg zRe)|0BFI2%LD%y>l=%Z7S*nQj;725D?CCcw-WP}?~?2XEKWy(%1y3JPAGM_(&nOs3mu~ST!bP5i&ou=^zX${c^LXpc#KTU`sIzY zpriR;8_peu-jQdE4Q{zS@Nf7{7c>WsrIt2k3HN1O1w#n>3ON_ppjW!Wwzd7K1ID}EgZJP+aw3w9m6Z8PZ{KfFBfE_!zGXxPS*52Gi}NZEyr#c8=-jNO#)*I zBK0BZ$K9bZWIlY&ob|?}48e!2gfGKm`T4w42 z-)5CffhM3wA zoIIQ5b*{4b-S)HCipKBdvv|Gk0`<2g*X?e3Mg(KAtXmI-gpX>LrVrm3*Pe=qiBif5 zIlI~=N$M+fX1nldS>2*q4Y0a%B*7-(- zNX=sL97U@>!JsJ(@$ifBf)z!aPshRWcvA#T4xU}yHl7^3o`Sc+8R2GlI&~88F@?;|01T+~ z*LOL4_7d-hu%k`T&k#n-u;{(AVs1-;;oRvzh@QE@xjo&eS!`D0h$>MkNRLm=fiHTo zY|TVAnMsOo%ydw*rA5b5n}%>HUs(s-dXLp0X4cc$yBF)LLcCi_%B{52ATOv4(MUNk zP+U|fmdLJQ7k4P&Wf(?$a8;#kEK|zMO71qh$10@HZtcj0-r_XDJGtRlt*c?&{`&Rp z_kQ(@j{+dq6T4MdMvn!aPQnI;BiLFngXaq|yEu~qlR?gswzyUyegv`>9i3hg#~2WQ z#4f=_Cb0zcKXnOsOSlr`+=l!Z7mX3_({`&h*Lt-JA&;#(Ro?3vky5>{v_;eDNnh#A z)cY$cK3~6H6eS;Nj-4Zo>@2A8p|t5kF5>I0=l~@7r)^dhNKle{xA)w}h4C&erGjerm>8J=j8S*luYd5^33uO~bzMD};wZOKo&+e%%nir7aGIly8(OAM&lx87<)37R9n#fe6?zV)f}&$1bhn z*5VvW4Bt*g7KEG^4s*tkOPU}j%(ZYyA1lTz@(%^Q&#G|j?!~5D2!^sLW0J(+%E74p z!(Nl@PWNT2IDCQ@+Gc%AOd0K(Ilem;*8j#8x%zTW0pFO1KsG&a$dOxDgDj~bM*5Mk zZ9i^D(LS*TBWx_CfGNrO$IhSwZx&*Df`8!C&bnhO#h#Ku<;mlU<;(fr+Do-#Oq7Bs zmF1>ANP@coVSP&sV^Lc-}PysJ*ol)#prNtuz|J> zppUB6xz{fq0vKbctF%aoIC8~j_4x_p-bnM~o!uEJqTEYdL$6GVffiesp4B^>J_+<^ zbAI$!;y_(jR=igqdlWmyvBSg-+cjnmZ-WZ*gq9n$en=~*=95sZ$I$vW;zix*5V>|j zujJ9ySw`H6J{!*vqdev-b{x1$VEVpEmlcOlbmh-GQZw(~ixOK=v?bY%p)w><45Q$; z>n1*jDY*LDpaZW4+$bK%f-1Tvk1LkH4lXDKU`0}?P@-PLlCPTg8lAS^*m)Y3>IG+q zhVUbLQ*1_w9!uBcp+Bsb5N<)uD6nr|3sF`paN}LSUG6gH&V?xe*W)KbY7%C#EuXwO z9!8-Kj5B8^f)5g65AvjVt&)e;u~ust2ky%cbB=aFSrFz2tG#~#lgj`D0z~F?f8@g4a^)Ldh*aLIT!&tPADhh()N=g3iwvKb3^n8TlQqZhMp{F(US#jT2b&N zP6ch{zStblR_v}Of40(gHS4pLw(IGht;83b=h=#lM%x+!gfd>Y8|Hs8n5gZpsGF1x z2NWN*1p6nfc-5%e7jj2KK3`kos12kYj%|`L$fA;$AtFu{^M>vGOb0m_+?@T&zX)n?^!nV~nyp-zzd+9HD0bnb57c+lbS-YC@w=J#p zT;IOmZZ-pLS$bzfwNSJN`dSD^ug@P11ViDMGJFR0;nN#{{yYepg@{e;#>f-h2bvF& z{YspUko2*kI4+X17NHNE!X(cf^>jzQ`=h=CQUAec;84pxK@xEIa8&$%rveB956mB; zK3~)irfxmBNdme((f!`&0blf>KYAz-J={3aX(7M^Lzz43gYnA^vzKVF_3$ODpg`vl zh5o^pfZ;V7XzU|eApq@3ltrO?h;&EyA879aVh1jEQWra|UEI(Vng+?gzPOX(cT)U2 zFYa-AeNKPC84NkY5oh;)I|;^@EH(m^q*6>5>_f5J zxqrX&zyasMgU&;ToEDAY<<)iYkhA-sbN?adp~FtH$keuLeF=3%!p>088Sp!OUZ=*^)-NJlQdV7x)VM~@uYu@KVv`vcKnC>oALyZ1*A>?&}bEjrisRCx&^m<0GAe!!u{ z6rJ~ADzA`-J&r?Xk2!<>rlJ)pI!?iPKB_6 z@l7GGQ$W-d3yy3YO5|Y_1R*1ioSIZ~Y9>w=YOBL8M{l7pkdJnC4Gj&s2D14=5A=zj zrd`=wPgf!v&v$u3T`-0!g^>Z(nNbT)@+0r+E%c{px6-@3LHk>HTwipE+?H$J6OnZZCyV_txVRO1Besr#18g$#pkMa{ z=wFkT$8GU)$dJKpY+{I@dyn*|GENrij?R!Hk?Kjoh1BbgKfL~jJtBKR-+jtBVR6Rl zl;t_=lQw7VPIKqocIVyVd8)E9Y^dxBH0b=vn+==8SlW@>AO>q=XXtC*1LJ4j@LazoSsl15#pc?u#w${JEj(f zR5jzsFoikp*G&k;bRjj6R!yNgpRrXL-PuP~=)3%M9YZ`@%oND_hHOIBnaK@ua(_Hx z!B4HwpM}eL<{|44KtP3TmhK~@GkF5gCF{gYmTIHsQgQO~XHJQeRWGE2V>&tp!0e)U zN2C21uMr^FOy&5{ciCawY-4GwmW*^^6CSIFXbl0l%L*KO_wHre9Y|Gi-B)imU&tu^ zR;#Ra6796~19|SGpC_);e;XTHXX8qmoMi9B%4Bs|>4$i7#k2j^4EbWr)sjhZ#+>oi zY~(q3OD1G+66Us;NGw}(CBS9r>;Sl@KRcRArxkK<$(ohEJnW(`54VO$ZdmnXvpr39 z)gPX@Jk|`u8K*PhQR0_M$j658U`v+Ld})eZ+%V|7DCyjJNvGhL z-Jpen&Rvzf^deP8!|t&BPECu_Wj>zlro+E#Lq7VX}Dz`x(y9SZIzMGvx~2gFKRa?-0W ze%nB^MrH`T(hFw~cfXSxe)pY>5{O^)o;tKYdAP4m9b1j1x#%a9ieYl*lIg14<&1Y9h9!^(`cWX$`r|@TZS< zd!&Y&?^Qfv%Oz*{rb~_++Ad{k-gwP&V(YamYT0}#Tsc4xurZfYlKyzmlSstl0kTF{;)Tmh$yNO@%#J(g5`J$u?2h>3e#NVLFAza~{ z6s~Z_DqIPpb-0>_q1qS~83RQ`^@RN4P$=a0hvUIWLJh{kZg(Q2_QA(2`2nOCE-&QUn1o5c_QGrxHlYe#}y@^ zsNO^}8S(}^kzmLdS3+K&*BAFCB9Ryj=^jra6b~u!cu@8DW8rupp}6DzV9@6e1>#;c z5ceqwHR%r~L&WcD-0ks2DWpNsFFkzmTwo~#q%#q7k8e3V>ZS&zE<8xtnu zZ+m>>bmw255%w80ZxDhy=Yi`4J8yAOXKuVGUnWRzcHs4`C{Q;Q-bvsm#f|dtn)iSG z`>*xifD-Qm`*!7X@vcFCSAQy#>Y}}H7kf74A_uNQ{zd9=yWK&*-|@fLvjI8xc>+GK z!|e+M-5yUc==M9@kcEOke_2X4`zw;CE&%04<;cqY5BW>=50LLYT*21&2Igl*2GsYG zZ_okRan+H`LCfzLOp(KmH($X*e{{f==qM6Lvk4kKKz@bw35UCny$c;d<9^G=?I`^L zD0C1?ek2obcTp?^n!a4-y4M($mn50gHE9LR}n%-aISk1>K95ZZNj3K; zaw3~_C~ujfm=XV^ywz!7!&6M7w;K2K(3NFfZbHq+bEyIQ{XGQxT;chR?Op{Tw5O%z z71t#giNpow?3{}$z}eJ7+8%j@xrko)=uP7@B?-IAHfm>F9s9cvO2fh^_izjS*Um2T zM38t7l)8(&|4Xh#=+-j%R_M$vXviBJ8MTu<_oD?M$Ia8&H#hjWymaYO^B8P=*nuBE zda=4=E$fci*ByVcy5lYDj@#EQf9z<7bthWZooKAvDtc*OWYH%6ogRM8Z zAthDN5q6UzX7F%vY$(R~t<*CMlae`=>~^2mb*0}yXi(VZ)16GOqVb&oP@L94KZPen zc_83c!+y8hsd^(ZrypjVP9@|CI{k1B5eWGGY)!A+HpEgv+fuA@{S%JO+LF~abq@1J zEa{$iG8{;aQQy#4ZfEUlZ_$l43a~Q-fyRHsfDEm|3)CjaU}r;vY}eS9AR7hPY1s;7 z!UP%WY-qV+9ig3pY!t9VkZnrcp?`$7#P1WeG^%c(sa0? zvp1Vrk2Ji}5Blkd<-ysc!4TcfAZ!+BY*|ckk;S&Pa9q2uH_p{-s3t1aq%FJ@2nj0) zR@QA2nJ)rF90YRqVM(`g$Bq=gQgrHF?q0pp>Qw=KMs7iV(?(3bg`5Vum7ru(I2Kep zG{D#J@=>E=mhUIEpj&%7S-IyUKoRZm&_?W{c5JrN@@FYP4wVi!fMn&dPB<& zySS`gW zt9?-~4^vA}U8eo??=6dc0_#bPS~A&!Q*qLdKQvCxtc$Q(+kO|uD7TY$mE@poliOZ? ztJ$V5qSc)TosaGj-VS3ilb{zIi6&PzMhv>uFbRS|Av&CN6|!CA*i{%7dv|*#%aIqk4@BFOYRR`l!7WBm z_FQC#<=ImZ;wAe=G?2>{vhi%Xtwy9XgPZkg>;3u=rLNi>2dI&FJi zpNg<=iQzZQcHnL0b=k)N+3>KW2YwbpK8t^Cn4WU&%H-{v4nctdEsWT_ki}Eh#=9Bh zGh6m|Gw9d3Z0=?}zrCypG0aXhy?4>#D-@&nK`UEC`uDDEAcYSfy*O}eIISLf$EOT` zaBBa_lb25l7;QM3f~M<2?IFjT-F=N0o4}2yhV!8jH`z?joeT~8VxG}pzi%j*6CgL? zdQsR`pPn~yd;fcYH_WWXuEP2Yc>KZ< zzZfCS*j~im)?a*PxQCm-w*K5R2iX35(7T0d_ZeaamizLs1zc}NQBPeylgk}F-rbi> z_zLe84_zLLxX&Nx7Em|k+YNZ`;cIH3*>hI*-30!LDKFjQ4beRpJknQfjI;Jd+ur<> zH$%H+#A@5Iiu_QQezeWbsrnA#+$}AZ;Cf4L`01? zh(sbTE;S!4MNmN(m)bAL?P}R>k(d00OLlRvnTvysE)Lqb>DP^A%R1>^y_`IH+!zAE zrk*rbe6c+YXw@RxwgN&I!!(Jy4M9CSl=N%5n|u?{&fB;jDCcZAV>2)|ZnngahmBOp zCu9p!x`kBhJ^%JJGnK_YjqO_50Ld%RZb5}^jTv|126n#@&$hkSndxtvy|(xWK&fQ2 ztY0q}*jrB!5X~*$urXJ&NB2#3LTl7dtebz*Z&RzGUIW!mJ;{WPZ|2w-vQfX5d!><& zUXj|IbW;k;W*pzG=WJi@Y2_XvT=AuRyV%sf%_}&IowN?Z(?`zbV@JY032$U1c0^xW zgPJrFZN`(c-bmr%>HUL=BfaT(YX4~B=<$JAe_WJi&m?(X#@iUt60r7r5*rNvyJ}*P9AyaJ+oU zK)=6idw0mw(5A^L>$dp1u}O^hY*#pM(~e*FM8ct9!0+>VbQ=sGWAk z(Ec{22$zQnwypu1iDskJuy5#CYA6-!KMdU&Wgb+H z_34>QP8~meLVf3*!`=_h_>)5e zC)DFfU-13+`hp|J&s|ayALR2xfw;JmihnBf8wV{1r{IppxY2jo05;IGPtE)`LXPe` z(L=s7nTq3nb=F^_6_-sJPXU6#fZ`8Cyl%hOn~Ws9XOX@S%Wi+hDzAmwyA9ptTkXPRvDgD;djI@L_Rm{T2v zUe%E%(=sKEdg~v5PUYEBGPue~Whh@xEfjMZYH0Inhb?mLKs&QjJhsn6DLxc z)B!r@XG7^>THBvUiA%leaK~G3@&1>@vb_OzB$pIvOR)87awU)b&eeu$v6E?DH%PsN zvfhFMEihOu5vEJhUlaxizGR9sko?bCekQE{@^!_)LcRS;uFqWm^+HR(=wI{oUv952 z;E~pU1wuaGzt?~LEB16kb zLokgn*LA&#zvHEV{=KN4HfZl1vF?+ZS?%{xD9HJzL0Gl6Sar z>VT>gI-zgaqcij?8EDeL(g~2Fj$)=SlO4(!15YaH=){#lcdx!~s$&mja6s1# zBN|1{)=+euq`R}~T%_B%O2z{0zTrHye*-qrZ3%=8Wd^#@>fDTzd92eWowzD}d7x;fD}8dGkj_8vn7b5FY>D7P$vy0Tpfgjp6~ zyp>}q#LCc3gz4sLF3idU?FeNr_w8CXEiK8$nP1dFh>}RM@8%VprCS)&5C;Msak7lT z(RoSD<)8&z6)VBkM2kUdqODG>igC!=XEU80@sW6%?k%ZCxjx{~pqeRgYgf$9;cC?J+7;CWopp~|xcV0q4zUblK8ZbjeLfLG!#f{!d_;eI@&;*-|J@z! zZ}d-E{~b@0FQvqVCE&4aHvK}&z*~&}!I0N2j{jb_*YE!K`2Vl?d#UTc2mKult0_tJ zv{+wDSYF1eY9dEfGH>y+F2ThW6E{#SG!qAmP1k8#-(e!V=<;`#Ta7en@qM3pl!}XD&JtW zrUednzkB+S6*tc=F3HOldevOxTEoWu6~sD4Aum{7Tx+mvF;}j>Sa}*`FC@X-)S;ya z?oJjyRHgUqtzIsT$-SCB|0))GM_@hzt?(0eyOfBhXHK#+SFHji)^58cj32hk*j`i< z&XX-T#l@LsU${H3#KaC_*M4z09b^wxM_$e3Q{-zjR$qkKwWAzVIN4sq6mRFhcx(TO zi%UP;x&6$V+V@u6jDp>{DlT;V?RiRHZ)dfSRNi9JV882BtNl8tLp$hg>sLF3E>(Kl znY-JK*Y;*1i;W>DDssy3DARip*@M zd$YxKLcht9Oy!6b(<)i1izU9ElGWm&*tIe(K*kcKTko`8SVNMP?n<2l| z6cF#`WlVvRdG)fKIOOI`ZdOWkIxPF18IAeAVb?lpE*816f`@7UWTmBHP75_@Da&b_ zpsXp}TI0iV|IC-;bT=oK*2**enC`oI>Y!i$!?izMC9T3$|DY@JGH&}De=V;6-JXzq z|KAV)|NHv?U-5^R^7LYvUeD8!HjfweE>~APn^U{kN!R5(T;EIg+mgjhoPJ@ob59iS z;jutE#CEm7qOV=dCg_j9d#e~%j)zTEzO!GGWX`Vciy=7r}qTx{RY+(?7Z*bZyXj2skFpOPBBLPIUv6?jzv#Gp6f}|tJA4b zGGIm>r(mGXCGZv=dH7$o@SmRAcqEp(MmNsP|9 zM=gM1$V0(wF4dFD=$h||wlIw2f71s_XdIk=qm4gevOaOV{WfJX9);rmpEQIHrYHg> zH=+*@AN7$pUK&H~f755Qq}Jb)8$_SHZD1mD4F}N`zMwYb#q{O>DnmRK3x(WBybr(o zM|U{_2GvPE=dRGNjv}d;BZRZ3-ZfaWms5n5t!8CBMe-D_AC4@mGr}Pz4J-uoH8OZ7? zLVSPF?@VP1Y7VB`X_FRYv|s~`ee+r`ng4(6z5SCL$#E#?pZQnxLcA5QJHP;#FB1G( za(5+B){?v>SNqH%G}8n0%rpsf!)Rd0;S63#zIRWuaj$Hz0WJECNf#b zjSS_fKMVVAAGzhLzrsDaQihGV{A?_V@y9!2-d8Y!x2_k!h)~F(_dV;ubU4K06s+oV zoRQ!C{E;A_HyjOswmUrN3o?h$;X40XiKix;Bj{(a%@9T2@hh&e^vASafZbHV=>mKR zNZfPp2?nKy0a0uO6IYA`mrIp_4--Z~lF#=lT`Z=041z%h!50wQ?SJ*p<0D|XiHpJ< zMj_~-r|R;F4sf;t3r_DDqzi;*yD>VmOC?*nd{PAP%s8?vqQ0Zif+5T7MEtT-dU>){ zD^G>XCp46dr~Uoo2V*?o0+?y7Y&W|#l>`akWK>h(_C464JMNJH|1|W2?-L{q?21!4 zttfz5*C%1Pv*#Ze_}T401tt=_)*DPCdTG(^`Bbm^;qhT(<6Dlyp|Jz8rCaKN3wYsr1YwuX=Y_U?_bXq8j?mq((_FX4{EzQ6klVDaynS#Iq83a!lq+wU$l^(RPin*>>QZj~xHD44pZlJXHl(6B&XH4atrQ->8`)00f z6EyFWSaG)5L#s8eW6v(y4r;LfPuvT)|F3Ory|w?H%g&>Ps0{O|evytV)5+5caC@qfJf;-6mq{f}OK@mH_@{(q<6@cF0o`KPbG_(%8<8{;YC zk6wN8bIShNt1tfT)ffMuR&ZW@@#|NA|Kqp>=6!)MEFOhdU;N#xzyAr9l;zK&*`#mc z)fa#G>Wg1exxb@2e|Kh0>;8>%YxwK$BOy}$BlRAB|B%rj;U+=iv8`YFaDf9 z{MoB7egz*Kq8KCpuaUlA{M&D_FU6tR|6~09#lOLqzo9Sxz_}{vTG2|UJS?{AnzzLv z!v8Cb1$_EnaTJlIf0TB-*vConz}O3Et{6w;ej%ry$thzmmUPdE05IYzy}M>FO-6;Z zv&K|P_1HKh!GErR$amVXo$71ktx5Jlcx;F(ejX1b${0!pHu3!8eS&KhV&#*|KB*l!t|6*Mqi(BT)NgbiebJmx z^P#>B&(t~hc@d{p8pB^JT90fJ<=}Gg%=V5!6F-((!v7^S2oyPQgx^dkK0lSr_Yd^_ z?->mireMlONewc1v0_`9&EIRfF0A=Uyte=|IZax75sp~?4W z^!=A-HXRjL3t17oZHS$t!#7P6zRBvOT)d2vWRHQTP#FE|yfeSJ zqnI{$oL8yAe`KK8WK-ASe-(ts?;s$5lHp^HH3eL(&cvadl%%?tFsZSKb4kx~A)URn z$GHsZ1}!Du1zia3-*(sZ+n;mz$-MtZ7{)~S@|?E-W%~c{_|N8M;{Ko3T6^oQ|L;70 z&fxwZ{R+RA4Z%g!&abzGay zCR-{}UaFz^)N)Qs?AUW$AI;7Kb4AQbHH4SjWwnEqstSC0?~H{5WPYlp&qPjEbF#YH zrW+iyO;uJ+an)j6ZQ#BvP!CJVTa*P5z43cw`_HBlmPp`yH<%Qu16z;@t4Xg!@XFtU z4erD%-g0A~Dx?A3^A23JYnA{N@G5Cw4?=d+N(o>iUL^tSr8f@mOec4P+aE#6&s~dz zN@5lUF>?6L0-X_~Jp7>_R5xm9%&NAU%4pJ+5*Yya9S$l3?D+>)X{S%&JN^N%O0|{X zx;v=yW^<m8d3WKRUaAFH?ld8%PyVeT-Lpr2*y79|f3U_J}()f6sFd3oRMPP_Uxj zm)ealqt$N?Eg}pOaFVyS7G`1-80@$o9o`vFi}h>|3Rc+luTaeZsYJI7K+wZps4jcY zQm^><@#7M8VG9ZsDmsXEVE}Elb>Y@8R9h5Q0Z{Zrq1se3At?M&p{n@cVB92n`wLdX zC;7CBn?);bsul6gqKtaV8nLI;}^^ z>fiGUR%fOr3j)xGR^OX3YK^9n$aT^c$$e{<<#!1!ZMhxuoFJLq&^hT3G{t zNDaf_AnflE6%Y@yW*Lj(Po*Lrsj(2O(f6X>*x&Q2m1*RS@lo(fO+IYXDN%joMiETk zzEb@IUcJjs!D^i^0urAoXW%#{hQVO!yrTB1DB+FywIXC%&F!diqkP-|H%PkE$zgvl z?)Xb-_q4W1t=^KY>b0n*KtoRzq8yOA0spJ-@(;E5K&GXWf(5= zFm~hn;6zvDyDtGv0V4a12?A!6 zzy$3!i-3vkIP-FL(yTK-9B!pC08p;|&IS_OdKQ5qZ9S>s~p4epawku%|Bs26U4g zNUAMpNg#Er(2{`a)}dtpO<9SS0n}g|T6nzC0Av+W&Z$#eKrp+J86jryDawG%fV42A z*rsFxbsSRnii#cGuC&NpRV_Z znsgSe|M>A^GpQJq8RQq~6IquQ!9^ID7J)%#raS;SBFY~vf&rSH7OcOyNd2MPTckQ# zr538cAVbE+ti_?k#*xKg2@}@hkkC-G1So#61Sn|CS`IE`&|2n@ElMWMgq0=VoOfZH zj|XoXm#NNmX}!A1m*_(J7g@HG3>s5HEY7r3 z(vE({?Tp6Z(2u;c;J-25HBv>XMehrr$#_KGq2-CyB6R9nhGI=iRw`Ca-kuJ+NL}_%3iq!b!IK|nS&SWl3kuKkk zb2P`KA)DNdBAp&2S8JgYF`XH^21TAs(P~T2pS2iw$%*{EfqN+aTZ*vc*qdjsnl2+j zGTXbPdwb26)39bWE$Q`)I(69+2&Gi+-GKZ~$MzC+y$Ew5rh36@Dmlq!Rd1oCwy{Vf zzf3c)K)nc*6rD6*WZ6=ULd8tf*WHyCQdtT$ij+zQE%^(dS5gkUn|>N%EX&DnaMg;y=vjqLnpR%Sh~wl+b{MN$*M0!c5YxI3lz zr`UN*rarETOqPL;L6OpXI_S51$J5`(2{l<84+B5!xAw#1xai}@k8?|71iY-!mUH9f zx_kA?ix=+X>ZboZy83dsH$Hf}=CY!~y~s-k-gD<8GI)WKa`)l=heDGlB^up`0;~_3 z><8Wp7xWyw4{Rt2>W`%2(OPS?w$>Z%_02}RxnU^LTidwW+27deb=oa&qqBC^+v~Ji zSGGFdMzht~zq+>B*<0V>3Jm%XGeM)1a4yJ0w-?K_PV083eW$bbVQ2lL&c?@F0U5-j z)ogwH^R+XKL zzPH)js&B1rt+m(O*4E}e7aOsQPtL+<+COlkXNUOvu&)-29YUIt=qM_o?x4#lhHfQ; zx*0pNteNO5%dAN*uyph0-dOO^yjJl9q(lxQ@$hbjF24^>@=~}we#t@Iux~4Xm7!Jv+$?*<91Qi%V}2`o`Bs767`CUysHW{(3-@2E zRRlllE;$EFZTn36PT|t{r4)3g#uVs1n1<`!qrp*Xd_=d>t@lC74oIGhE7^m%K*K&g30`8?R>%dcA^&q0P9>@CKasf znifezU9%asIe*pk;1sS}hF)evZXvwQRqKTix700+xz%c%-@3JG0n9T@$AwYPfKj~v zSwPZ4twilsGk>aNRCilx*3s&!7W7>GQ@5+~Bqat!qeM_i@dY`5#p z7W{LX%?|y`29W8U`yf|P8Qpdr@~suFiB7jh5vN;LKU6ngE9K`aTC=eKF9%>*hhh%f zst`-{Ez3pO*}UD^x-(Dx9D8OVr)Lgdm-U9`%vKfL<6_>`EN~{TYoGng8Oe0bmaJN& zX4-}87V!U>y}IPq%Mnp&N3RH4DNsxC0AsBpbyUZ2@s^UciejgEnHQ?KvAK2SYBM?b zmqb{vco~BppK!t>Z#?$cV31#59vXOMifrRJr7}h;!b*pcY^_Fat{M{6di_>>Tcx+mn*v}O3dwD4g}Rn zz+ukqa&TCsS^^U8OUuD&B_N=?xFja+Bo@riTMi1=Nq|vZvL#WX6KDx=+>=@k5>+ze z#ax~x5o4E1Cjc^UWjRP#$BY-b78eGlI04JSk`>L^#V)#KffcdJ<=|~Uc@jN&^00f- zT$v?6D)G-tgBcs@%Ym%ldh(?Ie)U%8$&&_ts@+NhM%(#3Pz9t|#3xPD%feM_Az?~B zlQt4o-{rTFw(Tyz4U_eA$=pLm(vl+VRtKf)sZo+~(`ZSEtt6P(m^n{>gJdriYhp>v zs>fmN6swy=wi3u(609mHjNmonVriVAQY|&qi5TbwFt&o8YqnL>OqyyyHMEtbMip&_ zd=PDb=c9>X7*h?9@vG!2()+Nx{R049@19&qEhNHVv=B@HU;x`L3$$6k%C4E#VM!BE z32>M2&?1vA#0h=)x7}Xfywcrnu3zb%@|4!v#@5yDc6(E#G`BH#yBQa4Hcype&1S9M zY}eaYvHZ#Utj-!}QW2=xf~wtGoh8+;0;pEI3q?=YwwtYP?UXXsHzA|dG8SvHGHo@p zg*j~?&y{YiR(r&nM0g^7ty_cd^$kpbEcLT83E~7`hs5rCH6``^diMjRR5$(zrMn2H_C8PRp0tTy1-|i8=8sC^ z3so7)oFm#BL?fc!dKWp5#t!jmvhj#N;_n*bb+R^_r|M-GQk>mxegAg-TbOjxT3MfU zYA0K>(@w{f(OlV_otiRQGfVjmbNRNd{JOdPnyvhrx%|4VeA`@p!&bgEtEDndLE3U^ z0|^y+!#758=pTIE<~87p9H-J1VVD@J0jsF9gRG}>OP+J(v((Hcv+6v!SD7rv(NLH* znRsd{)>_$`bu2lXvra)68?$PvXpKh7QeoXvVa--y%~HXNQrl7iW?rg%)m(HFn9i1m zvcM#r(Ly~R`(Z28M4Qb#<@@DRQ2@};3h?h~Jjm)@enG!o|IT-R_mg`M>W{vUGX3!B zvtcl*PmV~sZzi>oX-V})_Ex3nm04Z=3X3#Ml`CB}Z4J_{Ty^(u-$^B_Lj&B_;)l7ocZP{}IZl%aD9hcqGvx^3wJXxiG&p{1rRD0p@ zH1HUgmlEuoqlvKkqgO?y^7vtpg)r8C6&byH5mp4YVI)a{k( zSrA*J7g?BORA=**>GFlFbkuM+-62zJ*#3p8*XcyjZ#*2Gb^*6S+$-6x^;Az zg;hpwGb68_Rk5B8w{`S96C-S-^|RdXIHN0L2uD(Ntw81 zO>)Dm-3UnxuT3~pw_^MQVqo~82^4H2$SS?>8@!rrv)o`f1Ltx*py)78VI2ALU`mewris>B;yplTx=AIx1Bbl`@c z3?)j|H!nDioB$?6tzuE|rX^_Zn)lp$rR%i*ryPQ0bH2U;W`+^x&Y-0LL2Q-VzLf zQ_tBC$3u5w(k9e^!pPnC9=OSqQAS%IDS#)J*lqn4x|6ulakd|a{g3f8eB^ne43z4H zeGdv%{NTtP`28J$R9u3mKpD}u9o{#!6c=Jxj7K%!A`Pd6UegJ0e=e_{x4Uql-?h%Mfkyn8E1-Lsv_y&}(v47xP z$22)X62~mmSrQ+$c&!IZdO6RPj<}Hi&fA}_$O95-@EoJG$5I2<~aMq?G<2V7-|ji*uN+9eR8Sc9*0j(FAyG~^B! zc#M&_EaX)$3+ecYI|3QpkO=puFthHK_1(;tvu{_U$Te_mPPFrdVLq3oZ(`tmPcefjH(Gh-UlzK?jsfPMqT{tUtW z=6}ntOph#TXh4Zyz54Pm34vb~LLl-c3qhEX)+{Cbfj0r_;$89K7*8Mx^3^&y)OAkj zIv7sju{W8H12ItB3|7~f=A&o5b`!}z?{Oea={s|D^)o*_C>dXHovi_87*mSsnYRNMH zo#^=+@fi|-NTB|jSDB8n!e^g;Pl5=a`UC<>|I@4A`~j7Q%Ks!PO#MFA`0VaSO3KkX zPdi#yQ#VEGCQl9AAf)>215Z6*Fuxtc?6DO5qolNXQd_h!V7Pow)_Xw-|4Dv-7BN7- z`!I$rj<`@Se?e2`Ph*N9eSSf7{?)7B{D>yRpE-9Q-d8GHDy9pIR`Os@$7JUxxPL@L z1*LzSR}F*ZZG-LHeIQ2y1Jkq0iLvSV{V|6aBLM{*rSTXlmEO!NEnx4tk+-?7Gc=pg zzd{C+RqjwZtrFwVLiLzFaPn?m;WzGieF+*%-T<*FxU~|GY{Z*AKt$wrbLTj zj>GY1RN?0!A!%y-3AOV#)YPBjS4hW{e;^coL3H^Q4kgT0mX1K6*55eQj~f8DCUASs zBrw6mGJw;cI^X^Lk>I4nmb;{Am|cq{7QU@)lUK?T#&_aa`eQOnc>SWn3+6W9hh9!T z>B$SGEmhb>!1oU-+G4__&aVW4e@Ha@OZeslN4f?%6exwGNOqB$t!f$z6)54LCd6R;eW$wm13U@VU2TvPLdUgM zQ+h7RxvR7F|3mzjV#;`s{%=b85os8#%#S-xys{$<;M*S~=f@A`I+ss$TxLwd{FG!a z)cs=uCZ_x46Vb!jZrs1wrSn7m^2z*|&WyYVzo)=_+GsJFP)^if7rr<*ZrpHMHKmJu zKFr$>VnH^+{r%$y_(C)JuGO};o86j9>A3O4RR8~|wI9ue3rSP>{m)bn7RLWYLGWql z2j3@LG{jb%%4tPGjgfQ`hC6%yfng@Q{iiT}#4PI#rV%>uZ>drSG5Qf|MIcojl2(5z zFlRa|7x98>g#cNBL$1uUC&L}c%m`!8k{kAPfE2uVm!M5oCuSz*!!s}IWzoBQk~EQQ zYh+L~W0qi>^g%e;5f4xAg!_sbj0)nFP)4Q!Xn^5C;J@_xJI}o1$k?YpCp!NZ+Ti>pZ7`+9L3WM?1)KW` zvjBFi$`LjLsuBE4=|)1TLJ=b(3JRHImFk%${4I^aauWvW=1jZWys?b)i%bGGd4EWw zOWo3jS(_OI8JOx1E9O3U0}9nO60KY>a!AL0T8p>CA)dcP-)n=?&Z{@_VbeM~zk|VI7S+^{98~4c+?Cn;eGyh&Hfg+(X&^pZ40u z=DP0xX+zrDTmR2_{BV!V35HPj#{QnS!fh@q4i2;Q{~Y=FHQ~Z}$unPuePAAR+pMlS zpMhNTC&!Y-qf3(68RSohjVQ9F$~ddzyleosqs?RmgE8G zFlCNHzpprbA`Im2ed2;Ml@|1U62}6WF{{5*t zsHzxXkj$k^f}quk3Xr#{MU=)RN5Td`PBr}$i{r59RsI&Lp5+*5`;yxh_{+W^8CVpQ z0L09Og#fXlHb8h$p63RIAn~$RP;|3hF-TMtWF9%6#vZ8X5v&r-`B!m+;|c*cG!h*T z_rgIj3R2N|8lgDgVzeC$Y~+YvOeg|LmYxUSBXSoNXax(-MG)_(D7Rrr8%eNps|vyC(}UY{P_5v+3UE#p1TPzj1rK*SupNR~?vV4d5H3{GO8jv# zAW+T)J>Iw;z`gN*L=iUR570BIM7(zcG*py+rF z?6~Z4&t;L7fr{DyppZ7r65uj;dOie@~Vvj+~gsT_!VeH?hjuomP*;OnwCPs zn29&uDVY|nMaHX_qeEPeKSEHkP{QLEW0eChYVj8;Y`~>Su@rDo3(su9?jvU&F)g*o zJSwI1=1riIz_MmeQQemmUo!}C0=67h@wr)>^2ScwmV+v4*`SKKcYnVm4Q0J*+qQ@n zT#O}5s9+uBL0Mo>!9K_b#l~2{ECaE!cqPy>%p!UE*$w)R2UX3pNSvK4u^r`Aa>S4T zTw;4F0I%D)LBK4tQx!nzxr{ti3-0vy8DF9~6SmidM}XvD&cEuUE{11trUpsqdpW1cBmW z@MY1);(bv=1MnH4P@x#l6?rZIDg~P*xM`&zfISU>B2r=i-RwOV z=-J*lVh6yBD(13+Iw#y@7gWUek`ga_fqFi6MU_ZS>f6yO$!L1He+3q^0j&v1?Vl(l9c}B6I;+4IQ-*1v<74c!iu1I?!$`rwz z65OiP7ARppQ!}vvm56canH16Fa@JA0W*r&=XyN^E=tsrG7%!Wzwv7By5r{F(6lxeP zhm)}zMCgyHR)LfR7XETOsa6u3R(-UYE1CpbZaJ51o{d&KYIa9dCVF^eve3X_LE9Y0 zJh7K5=-^@C8dx4y{UJugjDmwagChk8c(~#lr|!fZA9xd|KX&&g^{rCk1U-4II?zo3 zu=xnJc8d8nGTK?sYbP9efjjc+YmMgoZK*(P?fD_Ur(~gZ9Gmq+x_Sj+*&6E|_XhOF z?>Ky(YLG{nun3MDCV`jQP0Ac3Sv1{)CCxhs$G#U;jSaWKIH^T^8o>qw z)Cn8S58W}@hhoxRD?BKmb+h{MXzV4EW;Od75>trb*+DDSey%g!>mPXR8d@%eyouX) zC$2f1hv82J{l2ZNJX)bqqJgD>?sNqA(63~6#x;*XqJ7|^z;XM1pDn}-;nP+TV&(Us zyeo>aIfJjU?`NaFXLCwKxI5K*U_sOm0@yNHk)`Z3y5V%fYst+T*J~KOETpM!icwy- z+mn?0f9MJZJ>+va7Xjtm|Iyys+(_L2v9YnX@izYRJbqGlcpw)fuI2Dyv+%-l<%bg4 z$SbX?{G(Q478<&<;ZyIxhk1A$UoWycW=XIv86?Ylisf%9z- zM3y@V$E*?;kR#EZD0O9u>?z-7t-kl3bK4n8LT)Pkd34A~R!Km_y6nr4 z3$9K|v?%8*QFe%8MhOxZ#hW5K^1_Kz?r*PccZJFl3l-7j&ksGk^BB9tXDan+mv60h z9hmsQhSLfAhE#5VP#JhfZZM%KC9DV0iZ}`bpL(G;?g2$)^gE<^lb*&95~#)zATxnt z3=395$Q-q#cq`s3BCoTC84=h9=a$$9oC@w>xonf5=K6GVD9^^l zVhlRP<+#H$z4TadT{ zXqLnX9{~s)ylEb(?8<@BFpZa0F;WJ!g;HS1V#CTu$T&bq%T#09V$Xp@94=1cq(BgJ zIAe+%T6u^O7bkMEtBcK;9g$%K^dkq_5eqt>Hc`INVd_H<6a$#+Vx0~5nc;!~BjMQ( zy(swRgbXJr5TB3z2~ZTTal&rE+(LZ9!IXxLw-2m%E3F0geqwH0%oOlsO_)qQglYgZ>aD2MvfUh$**>!;{9&$H9k13Ci;r zCUXz?cuml929nyJXv4_$Ezq%0UwVbMK=j!;TPI1dd$HL|7_ zPBw4!c@cT&0s6!pT~DIBLc-{#y69%ExxbZ5t~^rQ8@RY<7Yi9an&i6!|E0%gMpbMY ztt)BGxD~x-ZGum-j2-aJVtd^kdD>Io&{}!Zh7s3CK{L$8%8rV}mme>+w*@0W&w_NZ#0;0R_U?h(rBP%|@d$0<5L;x+45 z#-c?sr793%T6%I!g{+g~@C{I(Sa>~2@$l@GtMg{pgVyV*_6 zbah;9NE9Dk^SU_asAtoJ3TI2s6aDV>68ArpzV|`=WZM7RYpwN-#Qopx=2mO{t^NNz zexz;w`|Q*d%zI%A{~&@5L^zFx-m1`D`9&Z{qO5A%U+@A6$XQ)=w9F4teb1i821}a;60D~g3e;xnm|`PN4$f101MA_4`1#Cc%UpE!W4*Bu?4ynCR*KS zt#6?aVy*DbdiOACc2I%N^a`6mV?%h0H3?Q zsap+!1NUw7;Q+A$n+c4;vqfyd3)r`!xC(uM*K!(mhbEV5kQoI zPCh>Jd-2H%zE6jOEu|?QlR!r$0@$uZc!>=cg7^`Ky5nes0Y>1pa9e?;*cIckY0{ z@##Q^zl#&$&Ahysi1$lrQ-ne73S+uh6(c7IIeR$nfs3o8bNR$HdW?p%T|rc&N__EW z75mLD{aK+c^@`JGL0rshtX!~*oWt%DGT$zuIlo1;Th^5#Jg6fP8KOqJWj=zWJ#loI z5eAriGJ;L$9D(#9_`L39I@YL6f_$|QljuR21L4S8^*D`UABjzszXK`Mw6wdK= zC>MjYJP=os(sX6XMbUXMD2Z>;i&4(8L&XqhmzcbEXvLSJymqLGyJOCmH(?>Dh!w3k zt{%T9<$Q6C-Mcgb~7&8Y@RB`n$23h*{-**V)>KxS)Db|q#{tW z1y#GXI!l5Pfx7K36g^$rZnnC$Q_5K1gp5|pSggs)wAIWO=Crq)^($Q<^&{3K!V~Fh z-5PwaZ(ssssh^3L`tRcdknrtst+sp~xZv^sEgJgej@^aK-NXo$=i)P?;bd*ut2uwQ=^~{$N5Mv&2Pkn-4t$Q15)`G+ zL0`Io#Cin3YLxYR^d@ru{ZIJckKpekR*Dt)PNG0{yRp(`!sQ`7l)OZ;vK!4Vik$4` zwXDUly+KSxytdw@d$DjCLrt>DmZtb4{;r`$37j`i)uobk^J2-mX(ekFJL}f>Z`Z%o zJ!!41&pNe}tywbh)KsjsvNh{iayDn3f-p8_)l^YTZ`&%YTPm#CDy&&5SW#+QDs0S7 zQ{}7XqMNhYsV#47cG_8{YBY3v7sy@EdgkI#ze=5NBWX8g%J<8sq5u#`E5N@mmqO@( z7@(<>UP9|s&VSu}(`i1{jPM? zv^7Y(a@F0teJ7QyiZqbY;+6Kg;g|S1-RD1b!!Pl(M3H##<_<*RuR!}HQjA@vd|?C| z`%CMIyxsSFJ43N7!Q|th7xocpbe^b>sU~`y&QqC0m02%u*B`&Xio;)fPgv5_^!Dt= z4Kl>&$!oJ4wPhL~dKWvTdKpt{yZ2#t`v*^+M0J=^^B9d+SFPRVcktpFnrSZq3>=K@%(-CClmATC6|$obT^_M1tP?h;3uU)_FT3(O#6lu1|o&Ub(JlY0;9 zkG_xIr^BbuhQX*lIU+yQ=5j>}zTBNbimzc51G|p;d=chPl>&&X&E{6?>ecqf`qp~$ z>eZH7h&_1;h3XllMBg#``Cy*Tubux)kGtP)L65GiZLV*bJ1+CDEUnA?gV4R$POmlA zo9!#@we`)-wJRI#D_1tX_t&nN36NWMA>JoiT!20r)1uYby1KP_b*;6wer2=0*4o&D z{xvPc$S=GQHJ&~{e@PIp0?>L%LC(Vu#ht3rbcFGz@ue~uF>}T{mEvcql&g;_cl?99 z0i6oRh`~M2k?}{+k{_ri=PEjZEsa16lI6~-4e|7q+Q>sniGHolKfyDhH) zCH6~g~W+9PrA041=HYk3y|E3V%SWw_>$9S&}c+;QZ=Or!Jy{Yo^Wc1dDY zzC#b`xj}Y8H@lK5Qo6<-Bm59EO`T)6tMaQ`LF833g?b9uIg593nQw>TT1LJLYJGGZ zxI;U+`Ybz-UcJc+BH8Zc6ZqI*hXwe}m$TghtdMR;lNAOe9XySMj1ezPrkSO!Vwq35 z<;8oyjY(Xh4L}n0t>54^@f*C268-In5-r38Z^K02hKUv)yVopC^lfn5+`(}fmfQH< z!BH+@0gRw6ebjot`s4|q`vdxoTtI)?8&94fZ#;PdJveRCmv#EGP09$Swv;b%DtvC4 z62<4*6Z&b;r<1iOPiE)Q6vLn>K&Qhn+akAc%tCeZ==wHR_ie21BC)!e{Pi|i_ieE5 z+hE=E3f9de+S@?EGYJ&@`b3hxjUt}gqFpR(^2|*!^mNPu9)IpD;Sep(5)LFm4B2Sz zOKy0<*d)U14&|FvYPKKr2GhP5RV%&m)En3``|kKz1#d5*$EoRTXsa1Njz^{OE;`oE z^Kd-q>!A3MMU&}1j2X}2_Y9ru__>3@{e1witzdVed`?USB3a`-1%mP>R(4%R&^app zpmEY_&KSwd*KWK=H7n4s9F39vYp078zIJ!5;^;R$um-)c6Qz3t6phGi>oW)04Cmq1Yo z=#IzkaZw{M6;2(-JipC?Kk*8t{Shi|cVlocLuTPXm6p3cGg{5>Bdh}V!E!obU82e;oRN2xn_AfN7q8vE`bN-iTK zwSW%Bp#w**Aw8Sp66~W_Fn}V~AXt1%lXXism-t#4d%r*R$6nvC40E0{c07A|7AP?e zD?I0xHa47X&u@6xgn11HNA!Fdc0rJ7o}sz{%}9i{|~DxJ9e5vvgH z%`#mP7qbxMM{lRkIC83h z_(YDJvPB03>sPlc0HFnS@Nc`))o%lO4VRn}q)&;y!gI%HqT!TErM0y*O%@iLgcf0& zZZFxIDT1sdC++(KR8SZ*@ylW+p~LWvnA?WP7|~na7AB+G>|&#j@uMK-V{aS+(@As3 z{lJ5-+|Ds8!k;lv;!J6=c(XY(lO4))W>aU%Rz5#wP7Mn`YOS=E!-YtQ9zI(fi!}<) zMY-loBVb0I8f6z75$gMcfxG7oI@|1Wp4sKqx7L3oMgNct%fwR#RXJVExq#Tv_ltKE8fgJ16 z*xUDC?5w7&7i_@&;42mpS3S!|JgiRmZr5GPzVVvMh9yDXjE)Yd95pgZ!&(ExpT~)EDk$E${Xwf(w;8nk+az4TMpBtxc+# z0R?$W+}C2TOITzJO~*IPB5Py-Q=CL{eDWk|LU39u8{I5g<*u3khOT5j^|;m04@}96 z34$eZiA^ZH<(p;mO-ALkWJ}eyab3(_ro(XM*{f{8XeN8T@xh~SCRItCG!95NYt0YWZh_F&Mz8XZSO8dt|y@_6r&m|3) z?ur6k7_r1LEjlN-?_;OK=>%p5nrWxK$#m>Fx9@#qA&G)O&mCdm{sYL5I^4*+-34s6 zyNM1?2a~j}5O-ijGN$#upYX^VkNv*aapcP_TKkRBG&;nr2BO<|8u~%CvRbKe_rgr+ z{rA1GzklqAp%)Ah_ntXWfczM43esjWcF7W|3Ln;~*F}(AhV3&#{>Cc3gGEK7Rc3WC z$`qwo${WeqH06Ns(M~6`EvBqI3B*|00y}}Q2DrG}qkz0L)63MgIptu2*R;9B-T@Nq zSDm16d+vgOJMFXI?`VA;x{eP|fJ~A^plzFp2(14+%+JLbzdiibt7Pv`&b#M^ZD&P4 zYk_#HU)4*4=eWxdBh>E5PTW=l)b7OLX^!(DeBs8o*(HUpdof+_WKweP;wfnh+HzF0 zqKSt22M^Kf&dyH7^O1ee;6{1cieLZuIx(U=*urot%~&dTh<pZ?$h}l{b|w&H5KV2UGl%wy13w zCZll#JPR!&orPAkhrLUYTei@#B&0Ac5&8>;jE z$cq(Bf0U2(~6$UkNhFIXDQAiH`-A|Cvm9BLxQ5U z#Noh%pWc1|O8OfYdou6Tev{We_gAn6yA z2rY_&VKQV|AR%+P7+;Yz2UGn@x=8Cc`Z^3+FPj5Iud7go;5}rcexDjFDW%gaQ zmt6n!_F*oeg%`9G2DPyR9~+QyO)2f~J5@+(AkNN>8#g4@&b#kA?_dtS$?XmXwFE86 ze5`o4-3WTo3&&m~?nvW40TaGx(<}ijX_lx+&C(+=yO7r!zTUH1lhIrPlq}VvCz{UN^swv$ZEu)_P=>k}pCl+W?{g-2 z?=>07H-C&0Qal{7ZaVwEH|R%B-O13l?VC7(scHU-Ce*x!NQ{dGVUSa@p%h8+O|~;U z(tPwwax!0xh7i+WUKVql$`U{*%z0*v9-qXwkzhHqVC?m#W4Z#;$o=GB-gkSR^PxNO z4#M%Vqf0Z^Q=ySY)4d)m2jka~bwt>P=4Rmqc|-{^{^PL!2++SSs@*JOG)Xia--4(( z2=yjYAspEgDN)(r*?rUI(*m;E!Q0yuf*S%a4B;fK>mo!VJABm=36Ur{pH8QvzMP4~ zErD{v7?+W0_9zTng$`V5Bj z^EZXo#YT);8bYixtCdS}vY*&V%EpY$owe)=j$t)zKF#42vOiV9!gWrMznhI>={J3CQ97Zlsbz(w7?b&?uPK8i#*3n@MPVcYfj4QMRSmzvZ zjJ(YJrXiKe3px7Dp&5|JZZWN=Gzrg|u_Sy&p_l(>q(mhu2wE9Ov>?N*~8i4E;RXz--0gB(|HNzNDd+A3-8hGlws@(`hNfUo)O+Il3cp(%! zPz}WHvJIFxq36mBmaIhE0W88C-`x8M8^#2^_FkekkG*4P>P35rqI+Y!tqLDS@a_gI zP||iLmMTnxu{VMx1SU705bw}ocs??zkPI1)u@kS68sXo6Kf!@93u@)~Ih$77JnrJu z=6+X!;&D`UL{$M%tb$T8$*ra7IB_-p zshb|lR3tc~^-wv1&K3wQ4%`$44u2a1FE{`~X{(PG`3+l_$6@~g#-b+#vo=~o)#b*C zeC}$9HZ{aFpe`V(_-j+56mxW{=Y@0ucMa$YlUJ44ReB(yZcF09(-o#K$jet$|u4>adpf;)IlMt=G}dn2Lft zn@n)x=xrj81Q_wXY)-GP;cHVjL_dV28haqU*wqdDm6VQNZt3r%a-?n#D?2-E{F*60 zO2Ionvo^UEcBI9+Z!U7H5i(#FjQrb&tg#&1X=Dv;t4Z3<)xQ0YBXi}XTX@zM84uf7 zRFZGJDc2SdPprmlV78anT-sJ z7r#D42wbLr`F(@nMLocNdkkp_T#96iBElqP4Bhv~(PW2darj$wWZ-Ja$~(-W#L(~e z2cB9c9UGU7eNZt+tw_GyNPE|1io&$#m|rH6d?2gXs~ZO69*37UMdd5-uZ<*06Dc{5 zbaJUAi8&_^MuJ2t5Xok#6|2~Nd^t@enlplk$A6H#Si0C{jdB{yONTshq)^&Oy1cDM zVWE_;1c@62#M47~KaGD7gvlp{th#^3xp4gmx^hSzAGtcQ*rarA>D+b^sl&XfqrCcw zapk-?_Rg{kzm&1ZPzaZQdOzQecQIR&6xkM{Qm+`5N|U2^F61yww!Vi?D(`t2OaIew z?{43|_EUCZ<7AkH=7qmE9iuy^!y0J_Y^s$HSq7$8hi+)k)n z?>nHJy8SR196R-!jvoZx7z5vHtcAU)h$5id+qj5GrQe$v87 z0gJrQhH5dvQKVTji@Y{61YHQv$DmHkwGz9oyPS2{w%)3Z?d|PlY@8RET-Xcqp4oNF zF0&59GjDg91kBpQns5GO)H^rNyvn7+na_}{P0F(Px!3Ed{Jf&^Y06;EaGPsGbLJe6 zJ(-W=vF2Njk5+T(a4~CwvX+^AV{`^tUmarI$gQZ~_Ox%k%3Ny(%m->xfz*!`H7}j( zEv}1QDF3AtzJzj7dKYMNAtYcfVAVA<>0-Wv@{)KFE;&yjZ1q|u2BbItfV^hhTf|wF z&EyOF!m|1OoOoK1wUcmEA9zRJK<*C=a`tu{!%`xqf6o-of9IOsLlHa~Z@SrcRZ+QJ zkueO=)WIO!a|fS#2R<}c)#w! z5Ny(5A(hk1}ftM(U=*n{VrJ($a!AKX?*zY)1zfZ%pD`t=P!o|xd z8ohA1dilif&nO&uS0Fy02o-^S+FT*zlhcLGG!rsdoN&=)=i*1l%82hwNln9_C9X}~ z!l6!gD=o@7=Pf49u`n|Ba@Pc#+-FT$`jK1@81WWa6dXQpinElN_OB63ExvwZ11KC# zP;7@0b2!#K5e+RXh?)*V&KFr}&?Q(0m!MA=R<|A6bn0$A)n1Z*I!8CYD2tjgL?yTW zg_uhco3o-3-OfRbWdW2BeHt1VQsIs9N|G9RFmCeI$#q| zWVaz2)}FtJdEaet6sxWF+Imeq6yaW)_a><2v3t%DoF!eizI=RblMq8Zta#^Lq;$b# z-Mcula{eR$TJU6n6HGm8hw|<_It%=9hAlP>z1Nhx6^TcP(W$ZQ1HQ?lS;Wg8P!UvFwg@ephE9FqP3Xdpz^4bUc6Q_*VX9RDLV}^z@}42ewN_8uF52Qad$FM&JlfI9RUxh?R2!lCVW^ z^N@f8-K-$wO4o2r6?+SkC8N)u+bB{63_#Zrp0!EJRV-S*?cIxn>bp|tSfGDy=i7LX zbY>xP+DF*3%VmTJa|yxM!eW#NFO(9t6MZ!Fz)y^$nVfL|VDFh~Rf7UH^+4Hz`FK}n zhFU;S9087S9l9_4AstM-+H7vMu3l|#tZ%J1uU>7fsHOaXm#SwK6QhckqaKjB@ahPL?*h@ppt`olYNGkJ!gWVu!**w#wsI)!d|AZT5!P z*!A_nj~)qqgNo`41S8Aj1<{3``nAiwj4EfgxX+ zAh`AvH=o_U;2r=HGug}dqpI1di55(?GD%cKCjXG?luB#vLN~W!=>NQwb5$>8CPsVq z%Rmz__Y5>wA@y`f2A^93U@r$?>P$!uyuO(!6p^t%a3>QlaMbsTBB*USnDQ;WIpm?m zT#pd%rSERjRP%=({OxB!cxb-pO+t8d=#Mi2+zCT^IByUBdTw9<@f{?W1fle)ffwDX zDAp)NX;O85x7uqJ>BD;*_MNp$GMEIKZVbYM!ADlkYwmD6q*W;n54qiO@t>iB3vMN#guoPX!W zRq?>+IF=*yac_W!#3xJ>ck0eK3@0TbXYA){w8u{E=W96Cu3eHWsuNiR{aS3x)PV?k ziuXW27p8zm_~qmAI2_YR0A}WU(5Xnr`B0$(o)-SbYODaPYW-NHxcAlTNTr+XA*6>M z-pk}UPj(qDPj>MZB_IoIaPZosC%bg`7?R-&=)~dR$Ro7`Fb>|FPyIqniZeJWjye9neJ72e-k=uKQD_Jz|tsbqfqM>Yc z64q5oIf)i*0~V;w^>qjT!cX$=`c|{G?ljjnHk+;1=4KNFzw8<4-09_IYOLgkVEo_*eGeZ#sa(61Dz2>hypp!cs+HJN z1J32gVLv|YsGlo$W)ccNi3(HP(z2MSq5}V(E`8!W1l6VQj{7mP-*2tRRF?8N%y-Pk zjccUf5%E%5k1m0fl<*&jD*>-R!aM!Epf8bYU}qn(7k`pTH&IQJT2#k*ghIGCc>$jk znfoCskS`{fhji^I1aI7NBmR~lW|NEqxy;ddKwmF0vufz~W2EEf8e>@B_5yG0PQo#( zMhk|#>JWf_>H#P8ud|hACGPS~io<^IJy;CI(P4ZOrjMd^5Qfj3>BvDZKWI=cIWau9 zC!UgMIJbjiq4$uubpvPD@9#QX*dIgcVBqX|%2kOj-noc}J{lN$;&f z0nzlWj>dM^6WxLR!%f+fM~93s4rl8lj}!px5wpkfmg~+gx65$_va;*^k01WA^AW?R zp#k{_3p%`DvVL=mS54R0N|jx=mR*m_0{LLw_3LYmCNF*;Qf@!E>p+UA#a2EJEMX3o3(%y~me zd@D5w5BwgxKePvk0Mm+jFodn&{xPW}2W*-_x-xtX*0gx3=oWheP#C}DgH@fB1c{jT z7QaYkkq)dFK5k@uPw5&df3cik9sK;z1B^*w5)Tq!4|cgraMyv!yeooEc8Q)15EBFM z$PFemS%iBhT5-fFsTEjWym1fuKN|Z(iVJ`=Z_-nSU4qoc9poU;hvC2-qg;x_H3eo^ zQ7z9-EJP}?{qR=o-8_}SGZb$_N+V{YmWY{*12B)>cBJO{q~%ta6@)$La;ro1KGm*a zVS*%|kzBe@Z>TTa#%M#$FDjwt)d}WwZ?0cg^!g;KjlZ2^)V%>w_OjO#`o94tn^| zq&KF^mkA1pE9?a900{-k?{Ml0ux!_gBftyc_glu%NMhyVD8s4(rMd6Igf|}>ke+@3 z!q=Z@Ll*CWnRZ%@@CvJARYCJ-qbT!0_W0mFy;F z@yI#}Q)Qw^O(#o3I4cD~jSWhyo@`#JGbaKO)Nwv>N7s|+t&n)S8Lzq-i|%jJn!6e= zUi9X>JMdq6e6nP0GH+ICNTQB?V|V@0&6;t82^k`CiW>=K_?w)W9i~Y|4VfY%+0v7e z7nPg8TelKBG+9^7OkRV1#qx;>DJ!IA9j}?(P#_4#M!f2b#mq>lWT$df?53@hG?P)> zLUIp%2MAC0uE!P9aL{*xFsL6Mk3cV>y#QZ4Bib9KlP|HCa0MVktJ@WpS;3c48Roa_ zbfgKq?^JmKdij=>Sg+I^k*Wwvdxb4ig{=x1k|i5yJOm_V2*yklA&%k{Oq!8If3i3! zW+V1F#UTPn7K>m-MOcd}@*P|>Jp{)!ti#RYC*n3#l!v0c9}-j%j!*egDsoR96N&i7 zH;6@fDkVDaUuLKuod>^l|WVv&^-f-x>BQm}0Na?mB36^1FnhbL3ql(Amz z80}NQHYa@H+3v1r>Mtl0vr9G0ilw+=peNG0CLeWH421D^dAowymF_kkbEyF&!gG#}(d+jF;n96`1sgurU#HFcOvo(3|kJ z6w-kB0U2IIx}a^|>01pJQG+DZD+x+6R2tGFn*hz^01?gc29d{WF*HV!t@)rd8VybX z;XBrtJkC}IT}%WSN06o@cQ|wIA_i3Y%O`K#X@yC$ilK(OqW6D=cS*Pk)h>%p@1TYW zeby>o(~87<6gH1y>Ax-BVDE|=*qe7`0rfgtX6Hk>Nq)rY?zTFz-43j~K|O8gQ}=tI z4xWe>XS+3B6H^u{$(TeE>S2-;m-KN*eO+feo(K%{NEs-W8g~o0{q`UV@j)Tl4g32F zwfcS^H_ufRPkc{^VHh=)RGjQkx8}s3nJNG+UDLb9+vgqAdgSOLjwAX`Lu_6FBt}__ z?#EI?tj%&ZVgeuObsfd)e2pASxQbqVaNRs~u)yE2Rbl261Exv|hUaKH7~l?RAIcpvdxKyOTp)X}6gxh9$V##5 zNCw!EAz7LD^DTG(m|xM!n?>dl8=Y}M7Ya3w8s@{JiQ?Z zw89=TEnw)5uEi^37}|O$IrSYZR7**&%4Y$ek6vGzrXQi9#YYd<-t+*e3>|C4f$6~9 zs6g~-qrhS(oc?r#aSIcCgR?gdqeyv>jMGP=>-QhUvGQE`lpEDFF==+9+^Mqa0CIec z(?a$aQz*csrmcZ~KWpj}nC)h_2C8yj(PsL!#H!-GfJ(@MHx$eX1e8_R3Rw`Qiv0Wz zOd;7+#u6ek9B20@u5_* zkmA$L0G^D~d~ZnZq62cfG9D5sEuk}RTO4NsUf(twi06!O@nI$>=~O>@yz!wUzT zchqLI3bS|?#hnRpsy+83Z^d!@x&liA^$-_ZK1uneABYloUSDD>NkMfw4oU{1%I@V8jWF@R*Jj^XC4E>h z?2O$jzAFeei}hB4C9yGE)lQNvQ*)JXR1(#xFN6I$hC{n#Y?Ts7VUPz<+s6Z&yWilX zk@M*@HJ5tBzRr@^Co2*;4FiOulELt4a&l5?xV+C>pw7<3G7TG7^eZJiV=zm0p>!PF zBE<6$lncj&fsNfeD>U+W$>}9!o}&izDEx>t`?=&RX*Q}5^)+uDDjoxTs^FL{7Px}- zU~2S32iGnU1>jFo93kj>nYJK0Q^YG$!kQu~s{=+1v?8bqh4_lXTB>nDM7jqv`<&qZ zS}|n^zKhqj5Vue0WdVw&`y2Puyut}!xcf?0rWF!3K&2>Bg&M9&EQtf@uSD%R>?<7i zxqF-#cWAxmjpWFuLcVaU#x`g&7x(GXADb;Zv14F$YC;P|ZS$hKuG@)l*cC z^(*GCP#7FL@{O1`W1ABVdRo_3MV6SrjIChu9O4Q&@_IfHgW|zxugT*$lCz3E?coQp z=|R!OG=fmX0qWS9N=X5ws)RPBawemPy7yq4l8MTxCc?-}y{9n~*m_JHL{XEt+gj!> zECWs3a3o}deY)Ze)WPxm4GAi6O(@>!s!ig8?%Z@*akFCJc{LJNI7thS4))Q9eMQ|r z2ry6@*mly%9XtGQuxfy=PnP!Om^5I4hf3*C=LhcbAawi8!CT03v2??QxS9Y+9XWLw z+meiD;pWn$*@D;plqo(L(GIm(xv~3gWPNUgV!X)p9@#UUlW2JaUcr!=n$&BoD>SMm zpkJm|Yi=3iilI_Aqy4{6Y&GuH+u1TrC4p(bh4P1lrDF6 zve}0Ql3~eruBA$fKJ!|#tML>cda&({RV*1`M#~m|m{pmX5-3whKyX&gn`esGIkoJp zDY7S>sfO~@)cKCu-JlOkHdQB64QPzLaJUB>64A-8233|^>q)6lQ4_N{<2iXnDC%);3foi>;9ns&B%d$fI8c%ln&hrBH>6d zH^O-}$tS`ez^0^}QJT|(Hi^i)F;?HgON>}OcsB38IgHu@Cd znF~}Rq7G@kS}XuyHnGQL7F=}d$P{+zMJ*-NMb&qz9JU~m4&APL>!THaQY{moA2M;t zq7~)o2chk)ND9S+N~+Hg58sjI6PuDUXPB70{R^NVhpeE07$xpmQOH*#u!(%7HY>FF zFerloLveRsFs(ioRa9YV$Gbwq;2xmi__DOJ%9u$3=n>O<@$5rH{*wsQhi6{LiC^L5 zH)8sI^=TG)&E|6uK%U|oge`3(th#;>cw>ql+?z^oWONu#VSeqYGFVwb!Ept(yru$vj)3m2GC)-OF7@ z!i&iCt4I$p(al~O17Ze~-+$=`_=(lzeHUjy92z%;AxBzr)L_y-3v1 zdyVv$(}(n~imV$jurYD)K)qu&}Jcx{y+DDJ+st8a^~E!jfOH zc3hQ^R-DRz7U$I~E0UxnLDb9Cq}gFxDX(04rY?w@zK;<}9j6Bh>%>c2nm(amO}TlL zSF`K!ezg?^A`7@G4pLrnZiSh?y59??LvPIDz_pv`FlH&0JQJH;?*5a+Wh(?d5#>~O zK<5zrof3ldM_ABN2FCVt8r=$)ZNRa;zMV#39v_Z<02rEYf4NyK&sZbY9ppONgUAIs~oLbO%e!chwaE>_!9PxDvs4a zZINTt$Z9fxTQ)9YHMwU=5UC>DXAz0U((GYdSu#OmEDJj7Py|Ct%cl+mBx)uInqBNP zlN|^KkYqvu89JeBRyhz3rjI&?(iL!t<<^U zJl~e^pxKWLDY{N46Lt0CgAYkDK?AjRxd1-OjD23vb4Q@R5d>5S z*(D(`=<=8iss}yp&J!jxipS-KM$BgxUsPVXG6IR(?FD>6Csb8GA=93m8_@YoAER_4 zt`s|lO(qBQwgF&qPOf9P7NLMkGU2gfN=f=SCb`P^F&YI&ZiR`@HV8#gNHIqZ9cQOo z6gOu|$xD@(U3)_~f##!4f0k$M;yW|0o9@KYwgcOhcpHG~lNO9>P1qwCBk`MFc~zA5{Ce0C=vQxr&1>>wy#Ez;36Uxe zFku0SkTd@`*S0nj^M7l7eeLc1KaU@IH!HjMd4=BHk=LId`SfO`yib)R#7my}GVBA( zsQ0^)1)JSrG>at&{F_ev0lztwUAP^W)GpTMmruvJRdK;OT{3+~`F_nkKR6HhPDN9j*G1$StR#0AjAWO>>Tb1puEX$3R=5i-9Sx#7BEXaD#9lW5QKaGVI z@M~6ax`ITO{sgU8_QGTvmW3aBnTRlZcwC&mS5%uYk`om8NyrQ)!ok6I6pZrrL6H>= zw27_G;dF1{-OFsp(5j_b12l8v>8k8by2d^CUd&94>6DA;xzKg$4nEAI%nW?P4v!jE zUp9D|#$+sB@#6-i;0RQEaow=;6l&z|dk@IDRB^T8Qff44oyMd7(bS7zj|c7bJ%K1M zxI?cV6oxQ_eG05C0?4<$uYQ4tp>0X9F+r0)AN->}&`B{!1W=6Hjte z@7ns?X>s>j7S!5{_s#&Kc=zOGbi8}9Y)W?T`)Ki{?xEMJx{VJ^;|uWJylzs(V%;RG zvZvY6Z;6cY>$iw7}yZ|G+r^m#b zb}~E!#c&d#T{t0cWID)GfLWP~ATjjiP$dhVbp~_Nux>aob)7w!$^(}uqfOQzoP5HM z&r_7U%I`A0x~9!s?Qtj#Kz5g*=#Buo6Yf_^fUz<`PTV|QhBoVNa! zW3tI?3aO=cFi@vb4pxF89=QQ5Ohfk=)+RS_4}p~c-JUM4Ik$a=UN#~K`P-`7DlK9{ zXbTp9nl;I|1gaSKbKhQJ7&&XR(7G;q_jU00g=!Fnj;sYPL7qN&Da0X7la- z|2%&5hf*$+yAEeFTT~)-A5XTS9^U_9dy*yBcBq;W&?b;5s+b9Qa3!-LvTcyTk|qKZke0%#y*zPk>xAT+_C#?g741qIu)+fRz!#y zKA)&m*mI93_QJHyS4w~N&mfTO#Us4(wOC;ui!SW32j1i%IS8xa*gwE!p5I8)$)N?m z8(fbj;bh%ru)6525*LUof$EHFKJrn47@*&M7{kVA3Gsp>NWS~ON-eeUbnN25iJY(gWh}0f z^+!aQyAO`mbxK3VCd=5=GkSi1tkfAJqv94(&5mm(v-jM{+gzu~gda$2`;VXb`(qFG zF+=}9e#TT+tuz~S`8lT!I=6SkWUtU|UVV%hmi*PC_CIdGU#2}q61%6*aWa1Q^GAZ5 z-f)Dj{ha|_7>8*5$DhM=fmx`)oT*QrgUqx|6GhJ5jSUbVliK6;i_RI~OF-kEdrxVb z&*duVNy=&I=($f(t(4C6ulPm;yy#Cik*Gnz;=%-u+>J!fwi!r~PjW*~x|RS1s;lQ8 zdBTiEOM+rWW0fgFpk}L@#zF;3IH(CR7>uA={lWI_`s3~@IX$X6u8C7loSeHEmY?|9 zROj-E4r~_NgD#&4eBwKy)I(7P8oGQ^5bn%4uFNLX(I~;tWyep%5daKnYt@P&L_;Sd z*&m1pe>Avw*h%ek8gL0C6K@jlZXr`vq&2nTR8A{OV~ha8Sd`{zxBnD_H#oob22*;5 z;g(ameuM66yIx81U&MlVZYWDHtIih9n$Bpfbj`p|7AursAO?+H?9O&GGspvUXQIT= zec=zML)iR0#smsifVdJ+)3aR=L4|^C)>TKkeXQ*osL$2usuD z6JB}5?r%$3opy7Z!YHy54Mo#^r6GTU)}H)E#I@_i+7P9&6)aS&4N_~f8i?PhBuVgGAmg}3&<^Y}@{|FFNfFS@@!S2PfhWRSc= z=K|e+pA-psTSlY@{&4keGDcs^c4a>d$?pxan+{4RZrM_tak80e74Nv?=bIA2+ddwd z2G|XH$@>026;)qSq4l_~Tok9`T#a=negKwQQWPqDFQ~#^EUCol+y_C|?_!M^9s|bv z0K$M?7YL_gd7_{7C)$;VSCyN*rEo+be08I}{{PS3o3FQ#BZ-6ix1S=-sjenn6fMa| zcT+M|@=?>Cs2L+g{R)>~ zpW-t^uln(Dd^(s^DNy;omgvoBpSxhGRsjlCLL{m%jUW^7oJ}EF8A5VY;GrN#X=%gf zJJ+pdCNu7i&-+J;AIA0gAmgFVW-0)b;;G*oV7!DXkJNXA zC>&%kHJ3V-5bGGGVKQW}lxkkH68wv2QA`mvd5)9OHYBN0Q;97r+h~2;hQz9ofSgD) zl+@a#=l*7#$%kpm_y@^0P+DOhbvqc|Sf=qF^>Q zAt9jgqB_QpUe21*NLnYiG_m;Ibsdok)=)TA9*pc0firvHF@X}mu(q(jzM{1bRw2la zzDAlU4#AO0RtS{x1qU{QsOHZkQ?5?U0LTo!Aw?5b`*RNG725pR-Hp?2e33`-dNasm z@RB8Wc&H&#SF5@y#+4x7_Qi&Qc)eC_SWkjT%v=m&Tp!jtqIZD zp5W0_4fGltL}J2slBUDqU`zo|50hw05t(@)2%sGb4NB0R2ngB$uxD_isWSEk{7!t< zj#91KSdm@#5%ZsVgBaIy$M=4+ksdg=5lvOCq;L%ifxtS-WTR!2mBGNNsw03GV1 z$cvW;W zV?(2J{Y{N_-X)OUK2Um*r1v?bCT22MhH2(%S&S5QP2*wwzmmmLL@3Q->7ol0LA$>| zzgR7;r%B}aG0jP+rgeAH&ZWllh;MdLAx&Pn=! zhq0>Wn19M|SP2+h8izJaY%tWzjO~*>Zq%qL=-$8~((iDb5Co4FeBi67O0}8xyGj*L zIQF&O@#+V$scnq-XW~w_fg!%#wY$cDj{nac-|r_`IQ9?x&A9(}XZ`+P{P;hVzpPH? z{rxZZ|G9lT`f)PW&l&E$y1#Mf&W(aWfwKL8?#QS>c+pSXBRoxdYL7im-}YOUm5iP* zr4u^ucnb2Q>Y$c9yY|)m+|UW-@=m{&? zWKqWx*MA^&e>B*d9jf5yTpPcq*)M~LGf4!>`lzFh@;z$fQh?i$<~3yA81JR(?E=@o)Msbc z+&L=O`N?y6x&lupTwmkyI2lclKfv3m9%=6;6O-echtoF?r*9rkPVc{YC4KWs`sS7N z%`54Oy^^lji72HXOg11)PPXHaQ5n)TH$ye8!w}c}<}_5sY3Q4e&uV;p9RHSF_m*s&6P98mo{5}`&-gq`1}XntXsy(5B<$}|KZ-|`W^55 z=ia?<@gJ||?+VU;v^7tj0qHa+EM$qJBEVn|xD=H&w5Wix%ce?%6YyPo(0NdBA6On>g;tM~Tsc97 zFiTsJ(aS`LlpF`Gu--$+(VFg|NMyLbiwDsTaaBs1zF2G~iLq31Dr0fR$DuVz zCA1nX=e|qEhFZ=eBi~$*?HNW8RXHq@z{bI_+QOodZ7s=$w5cGGER&GzOxDw^0_uFF zEjHWxcRe{HD2uQ6(q14y*t7E)tDcCz4v?zCo+i;_I0i))jDTsK90>XN5I-E;XO@-b z$((jFfw~Zg0=f9oSG(rf(NFQuQ93E`^XWJUd z6?f;%PBF0e&f_R?VA`&kDpqpt{~3ni&uwzR2?Xxop>~RW+e?1ozx?=L%h?Cc@c-Mq zf9J06|F^mEZU1*Ae=CdsRaBQRu#>ZEnq9%%J&2W>Z%NXp?=yQ6y^Xh+XY43a%Tjn> z0Uy%+X~O{}B%}tX7c9pGp-4ckjU@!*k{9Lpy4oBUEL@UXu^qvz z{M=)hbg9FW0$Wo@67pe)FAnv&iG)DM<5E-0D%5rlUsCxi7Oy!rkp(1e=3d@|{7vXC zEOd*K`kVY+f&868{BNRowkXcqBrjrY5nJQBGCM)Oil?q|6kO ziB1Lsb0EPpwOx-~!Rvh+p_!2$GXG$_-s8b2stVUR)hpe+XC8G8JLt`3Io7!Oi(_+f ztU}!B$@jXO>Y`hujMF7iA**BBV(j)SWVSNB6Go~m18a&uRnzQTe|WAq|6kMYDCnxV zDATTzQ=<#(Wmz}DGYax-_L!9zPh`=&(OfZ`hEV;Zuq-@;Ttuv@a?iO~4y$_XnZdQz zSyal}EPnM{p2@g7LdJ4aJBCGX-;SPu>nX45Z2CP+NY{_5Ko4Br4OMD(?MF z-Zl-Xg?`diWW}b&ep|D_R!$QoJ={YGleSg3em%Oo8G=FS8rh$~O*u%EQVoU99@4qG z(OpulPUFd+$M7(B)Eo3qq&@zI$LNJIsDqL-8O8ny!?*LBYjJ)vGZx~kvmEcpU!K=c zV60rP_`()Tri9~fZcleM1E)JzVgJ?k{||SJvkee=x7Urw$+*#3h6C6P|F8AUb^reV zz5Dm?f3yEz#UDT3gLBP1(Pv!F@hMo=+{Wi;hl8H_aR~e23H+c*q~D7b%H7rt3HQ}e z+>7zbux;VO{@!nYI|KY;f1dwmNCqq{0m{$+`pzUul2&~8 zFL(ZL+`V`AFTVfxosG?J?|)s%pE>`>nTq#59%Cd9nz<+i-k7s1PX5QB^9b*>VEMXn zH?-N}bw76I4!e9~`Oi_Jq|9r__uH&QI?MAEN5gei6`kkR!N$;9j&}2x=z0sAgnIP! z*_+*8o<8OdVD_Uyf1>t%GU+L72V{c!Pkc6(DH13qyqd(5sV?#=-F5(f+#96uXHpHx z5|Gh#ksGRP1rv}ZIv&1hATpx=o{omaT^d9xv^jyY?Mw?$Z+*N!d( zo;!|@lISI_Dqv4~H2K6vD;;*D8G*}s)3Ppkln%Q5vN(kuse0>K4HlhCXO&X?`7-|a z>NLi8$ElHhDA>dRh2)s6?kj9r}l;uc+WPYQVX6k z->L zFIDLDsMQKE1Y`L)Io2jjmNz?1NBTG_36$$3kFucr;4lNn-FW z*PcB1dW)4ZnuWsJsz0+JACcvhDA3PreeK0)04Ik@XQ8eaK*3WJ^?~LqI=S3_PR3c& zvWaX2b}DW}P55R+1-C4Es=0C=mAgw$Y7!qygiJ|Zw`-Ab3o7*jhQ-`>@ieR5$1h= z@KGtDL+rMq94;PD`^hIYpn5?Oidn1XvZQrfTL9qfd94|geZG>4+gvTcuP@O{Ud(>Q zz-QfYvOS}uq!N*Nfu89$oo;w;CQAT6n}FQ(?OV4Z)JWmX(#0dXb(^poDs1LQ3RK0? zXp#5aHYueYmb6;Da?vW@-O{=#CDN(W=mdfeIhE_71wE}ZT}0IsxKycHjn=B;W2L8$ zw%80%oDhG!+cVDXo>2Y)uS20@2x=4{*i_9yDL!mB*M!e)03GB+Z z4?EF0$WXo^Jwc(tR?!ymICC^TnhZu&t%~tgTkBAPu=H6u0^`~?&>0qa#-DzX?)cOP zk}9pWGdv8X!gw$$VGXH=oUQvS3Me%>wUbqQ@>Z4l(v0?~>g&Gx+TJI!?6q~<{Z2;p zZvRNN)ju%+p2ALaOtJ8px_b=8TyNcemVA5;ENfB<4kXnRB9{S$#+0-4j*H@@;XvZr z*B`vr$|P?f2*_h9DQV|arlabzAPz@B!iR>0S!W2XDwb3W$3uek5Iz-r>eEBbo8Xa3 z_{eGd2$E&9qFfb8YE@rv^JdlF^p@ljyPVq)?Mx1p_Gq^#CbEIrm8z1=s9mKygjs2# zI3SrAMtY%2g3GPPM0$V3tp1WeB{JRdb1^}AjnG-o#KbgNu4Uut@Qq?&h=utes(iRx zQKM7&aKDnWYmo`~5v)ySpZvbthaj73N>r#t3?HZiz7?@ifc3$J6@OY9EV@d*G;m7q z?)EBkRh^FJteBh)e(TQJ=Cs?HuVz2)59Y0VG`lJsga?Y(`4^k}pvyQQ~E(07uD5q9-E$h6U>6$*195&{UbT`Dis6{4)4R z;ojy2VB*Ei2jI7l6RsHdPIeX|D%b!f-7}5I;P`k9OMoM@dxN96=cNrt$x(NVi;UrW z(5L1`Vop+8)R&9VbVL{8<`Wx3&GfX4sd{!vTUb7HJEIkXKU7?K|L%PKrn-d}mhj;T zE$SI&VQLO{qvNKh0_?Y0%T;BcVcZ~<|5JA~M*GS+fcRPA*)X;AHX|7wB_Ulz+p%^0 zsYp+jmmqyG8kJV)4D;;-xsRsRPH0}q#LJo$X&w&7gw7$){WCG`M=A-ZuQ6zQc?qjB zS2TN@30-b_i*mQ>NZ-1+KiUkO%3CI|XWvTW{gvbI2R076FAfrK<4y;MS=%Dq!LNw~ zs(`9dwMgr-mSW!0bxf@6x zc13*(A;_vnX`T+s=CVNaj;HGA>-8u!S$qnJUi-VE%--6Khu>mpDa`wgMd6%v73sVE zUvQ(|G#4{UgNZ*?)&Ca-L-vBI`e%L^w{P8|k+~H;`Pa0o=#%s(aMSx;13J4=d&k*y zZq*<3@!5jX3cy=lm4&A%s$6Cnv)+C#qk+qjoOV6`#_7hYe!g;S> z{*qY>RDq0Iub)27$a=Q>?0IJ9qwIQ+wVBo2FPYVzzQ}_2^zqA#tcSEj=Vih|9LhJd z333BM5XyY3bArPf|x9dNN)*!i9ao) zFTI8PVmIkZLH-3?sjEV2!3hdTmU`qhla?rH=ZSPD#9DUIbTDVRYYkviqFC- z%1_jz>_bO5>+PN>0L7Mmx@orBrGFJ|WUSz_skv5RqFvEdSWvpeDonLXufkLkjgDCd3@8Fjr&&shExXkrr0BT2dD3I$`P3IMjGYwb`JUVQ=W zqHC||qF#AZOi+-M08k#sKz@o{Ah9k`u1D}=4laSSLUHXc=a|rRxMn^bQ}1JBEJCcv zWETL)$U8p(mKEB9i4+S6ip=~~Ob%~Y-NSiwl3Y{-5tKaEp%Up+ZcMH_nAElB=CW9* zC{2we(eI5zG2@}SDA8UEA&^NoQz%6`5!}$js&3`W(rB1Pv-v0->bhqF>@Ccc&)lUq zV9V>J8IoSJwiwiLZhkRVe3qj=?Do$WB@taO&!iAsF%RC=Hm%c*ZA~5ZTbkytoLX*o zyjhDki58!;2qu5V(k-U+eB~Qs4mNdt>&Xz2zrQFU)7^AuC)`0^czW_h=Ir?i1=14~ zQtJ|nI^Bu>a&y${h(oG3gYLo$#T$$-kxeMbPtgf(=F|lSb-Wz(#faqf!4+h1_eP-@ zyv1NIj>DCPd^$Fxy~4UKHcF-O%BDWow^~&|m7lH7qvGW{s#@2B<-@lA2up?S?xK)X zkK$3M+mCzQ2@Hwa@$}Epm=RBu#yOr0`iXa)18-N+6&K{A(BRf130CK4wg*8BLKP$u z(N454qlaJwPMNUZZb!|?P09AoqvUrw%;j%mtC#YfVP>g2qY@UF+fP!uCtlg2&_vDX zNw1!%a~pLBn|lIJMy8z}27Qbdoz1^3lB`)cOL(jf{G6PR5d&cAp_(9*)6rmha*A>Q zgv!yx{2YctE2-w5V@#)%uouCQ#8+LmY>Ef4@snV#OpZ?Dw1Qu9MVYaPP;YpE0b_le zkte_rW6?DDQ2Ny3+my)r19_H=P7-KvyuAx|6-BHlMb_wjay~eYb`{O(*TZ%*dT%M(D2%0@gV0#S>L`TO`Gu&i|Pv zV{rTWH6FbmZ-WQ%^B~%-RxA46ph>yg`V+EVSdPY80vm5WWH%C`O?cEWON|%)s|LXd zcoiH6l*rd;7%UY$%p5{v-okV)(032Z6lW9~0u#6F(nH1Lo0LFpS*c>O_SF2+F)f;g z1w@dyy}Utp3AnrlZ5O>jT;8zkWwHncXtNrKvl8rtnw^^MWF$UhK`aMyj591TwT z-QSbWwt{BxB{r@{F0WH+SemHX0ohOWcOW-I%%}8S?o@DbzJldg2aYgv+1HN=jDtzb zh76&xH^hc%L3C)8vXewR(e~<34}%Jz@FWJy~ov_CWSt!akq2eWbgN`A25s<#Q?y1G#w|=yN1)tcWP#jCrNC88b^L2sa7*f z(1Q4Vdv|&Qn>2Kk53ZusSd?f+vb;llvD6Y6tPXg{Dy^&ulsiDLks<`vkU|&K#9%zt zR%)R>xnx{+uU?G0gAs7S?}N^d8;$kG#-`$hMDftaSn*PHI6VO&u99>OT%Shp?i^}< z$Fv8~&(4h-(F@q6nc~yo$tdn5QJ0twxD#Fg8FiEX5g2*85QJ&$vJpbue#&uXtm&eE zZV2J_*A&rp_A4kLl*p(8FpO5C^XB6c3mKv`R+KI#_DEpMNEgtXD{GTXCaUzd`o9+y zMy;guhDvD1twd=vQg!N)-g{GFSJXJ?t+ev0I&EE;C2&4pXoMB%JISYv;6EL>?1cq< zS?7Sp5?VlZkKS+p8jtPrkHK`FfLXJ5zU|{py1`!Cy+%=w076R*sQRag9}WU9pb>?| zlTR4Ya+{&l85~v4@BaV-@2(n8jPC2AHIEE(CQK(uh8)rlR-mDXd;QpEInkqRX^UD` z2i<5@drDPn72+puWaT6klej;?(~g|3_&O*ex0CK6nj+t8)n&#Q>0rf0=_$7pg~_QK z`6}q?_plT>5fan#Nq>5_ZQ|Zzu(G`YzIa6!s`Nx}8QsmbV`lHitE{&2-eHzClZnHn zjWQ_r24Q=YTZSvP>S3!%xUkzd(y<<0MGuvB?6%#De?KolTT%lTp>WE0EY$#Kqnj6E z{vRCYj^;ST?>1q?_9ej^jfVY%2hqY-VuY145*KPAx3wH=FW-kQbA*WaGdFJ{O1{pDo|L_n_qpKu;uW$wyY%Z9AD(r^B-kU8sQwKAJ@qVBI#JG)%YMCnNMnl6pD+^NL4I;p?LLs$}r+va(YdM--%B1CZy))bgrf7Vp# zRS@3+8KUhrKa9c9_3UnC5GKVV2Cr6~pXu-+Emb@?41i9oX%_Irh{FgXPw@d{&&Liz zao;;lWOP~BHmfbQ#8mB|rvOGji5WeejHAQkH2%;XOh;h;QEJ$EG*+b*kHC%{UU$`i z`h(F~+>3s1APlwWipGrH=kJ4$tSeuH@8>*KIP5l|2O~(`6wCV;`JU&iF5DNl*K=3u@Bvvg@yKHG7bPU=* zqTKZw#ZIfK7NDd+$pe7`T`33ro~h|C(|qg|CwcE|w48Nj#$3c>(ezB*H=1002Fyq6qLjGi#+o}8+$ z*M;S^L^e-SJ28;M-Z-I7gfuKG)6@$7+E=tv)Kh>_nW_GBPdO< zM=Kt^)z%<%c7=$4Y{>P)coe$u^_o}l~PYB;+9 zAFKAw4VG8k-;>o`-C6gK>(2O!x7zL{Bigj-BC|T1*Dth@sOrMDVZ89rXu|f7s@gBvzS+_^ zMhre^kaCS9{T1PE+AW5>F79EUvhHMwu;pMM*vSXUW1x_z^VwWxXHnRenL`TF#tkar zOijQp3+jZ=1z8Gk}XQu?ysx;xEeV&1R)HPN~UZ6 z2K*l;V1Olk%bAGqs-W%K47(o~Aav1YOFY_uC$uijUCl(Ap5QOqVXe7C#=e=OM5+UrQOMS-O$BUEp4)8+^T#9_5`1>M|jG zW^ICfOv6gWFY)gSM}$yYF$K}Pky}6qfVT5AX~@sGrIz8?u}2JNI%WJc_M9E%*lZd1 zR{y_(X%y6W0cVxx~rlmtx&ax}%f#6Q2j7oI+0$Lf`yB_cf9GKvOOhA<(ddix?cATbJ=HgK)+VeKrw(|S z04Vp%*u-JI-3Oi8&!GFSe^-s;K+q=~=|BxgHbo75l_8pkvQFd8Xy1U#DVMQ3f&U!E z;|T;fK=SNb1Ry?vt(AJck7f}Qefzb?e|6zeVEt2HBbu+t1Jw-gtVIhOki*zo2px$< zNhJ1i4l$^JZACY%n$kB#1I~wLHr1V3BmIosYpzYS^N7rpJ!(Z>$atWjS~W)1@%Emm zKuH;yPr~&QzRd(|ioXI5Wr9E`xwP}OGkCf_1S9*X2w0SpbiI~Ah$OF_eDfoO^$Q_n zCZWYl%;Y^Wjjc;*J%ho*st4~lojH;jUJe63hvoM#-S-JgZ}_=X*=^hPCAer=FGM1| zfp6{8-Y8O~l^AUu6-?jrM7z)4Ti45jA@ZE45p zUK;k*MP{o$f^51{rZW0sG&t*y170=dHWrifa-rt9**q; zx=+NXuDqNjb~H^Dprn6TBe zM+xtYy|uo|z33b#I!^zp8KdWwY}ME^%DjQXqma*m7$;--{D*;mH22{` zZ~KZ~KxB!5U)Jr5N6dsvwB2!{I2L47>{%Y0Vu3kCSKXysEB&Csau^VsxEl7u;j+vp zgmhILk4c9XkJ*TpGnT~o*}^X<#LsfyPl%tTMovCdj0i07O0jiNDg9!CgSh)9no>SH z_=-(2UYy@5!!3m<2$#Dfyng`muluiQ!nY3GjVRqvNS%A7?mjW+azNbGW+9ewRF4d6U3ZxDlyFCns~LSQD43hkE;T;@ zR38?%;4vz>COj^)2(H@?eaY$&0YZS+qunJ9f$JZ#n{(gzVa{bSwI$uvE~SS}U6jri zEJ<{Uhr*eZ=Fqg;n>_78-Qvcc>Br6C@a5ap5wD;B=m+?V=|zdAbatN zw8Ex{G&6yy8oDgJ01W%^PQvN zvFMZ_?ltHIlBgBkt4E)SEKT)KZ=5KNkpU6N+c!L-)tYvVu8TSL(1*z6mvT9mzHBxwC6ot0Z3aJj$ynlt&9pB&Qoi|?9qIKj&f600DVKddj%sJ|p7{WyNQ2nyW+KZL*^rtNVu92Jx zKSc()>ghcCve|Hu&3W)sWU!5%^XN;mwLS(n+^rMDh_SU+j~Rcu3fYm&M;f6B3C%}0+eeOA&oUn^EfDuQqs z%RAm`9kD{>Ld%Q`Atf%PP`EH6;KH5O7iJ1y=s9~KXX%BVlNV+VUYJQIu1#GC0qWkB z&=7TKG{z8QQLX^`6Xh9=32-*~~+SqTs4X`PC=j~x(wmB)9u}&pO#AXD&*2RZoayuja z^b!7-Ryh%34mLh-^{xjrF?aa}y(I1*K|m2y`GjfKBNs1F0&u7Hjh`6{lgg1Uh!tlg-y1M(y*-(YR@FdSIYw*_h-O% zY*=pPLzE6nz>UOA3Otot27I03HUM{lmH?fe8~0cO`Mw}&{YgR~%*jSUDB_K2pM`ow zF`?&|-Rf!<7OcGs&MST=Q1%z@0^9z*4#1jGv+YC8?Gj`*OuLg~>f z<@JoR=;A#Ag^UsYGO@K>d`2b)ksJon5Hm=B77w`tUwy<9ZvrQJ-hQE=3@$p_qUH~d zR>m`i2VNb}47S26f?lJf`AhOG|0bNQ(s=g~d}UDYF3e)La>sQSgCT7}W)97Q z{?s0kXv3u&{Zc-bo-QCf`&Q__mev%td)NxSq5Lt|KBBoJaBW;kJ?wce>8&}ZGqb4*je>&^lQsrtL_SxF#Irwoqk zDcz9rZCc%|k&pww>v93ZMEb02We3vK&$>1$z;_>r;jSx`tW)ZCcZV7DqJZAAViG!v zO3|cK;kzy@B$Q4LKXxw#srrH0ff=BIDJTRj7Ul1{o}+bVjzbasUH4=c=9!ebT+Jv8 zKkGuDgk<`vYt0Ih)X#cqtArUMtuE|NIuEe5rUy*rsHPr6O{~v*-Rj$zL-9Bq>jR_< z|L&>e-YGGx*yvL#%U-?phD7*X&pecS_TG|Mf@s8^%ZP zQEW`cOKoF)ef|F3yAk}W{=9$h{$*ohV?A2GbMOB8#>V~o>vyB|jXQVm{YB+36^o3& zsS-FNh03CE{LXzPf88@$U~WVla{?YGRVz_k*D17ozM;TGFp+cy*yqt$jddXTAM7zJ zi(rDQ%84ncYNMI@;peO(~qCN-1{H+@$}i7-Cv$Q zhM&)WHuS+7j|OU?`!sPA(Vpcdk!t9tO-|huw|z`{HHjxvTk%yG)wo0Bvo{b3b;rAh zs-sHG(g$>tem?GwCg=1M`2~KS#qSdy?=%I`^Cm?>9;~5#(=$MPksGRPcB_G^P-M5) zg{P*y(FPxO^6>-2a8*Dilb_gteJ?Tqf0}`lqItg)kJ$C&&4#Et=Bzb-3khrAxLxdT zj&f1@FQ*)Da%PsB4R1O9NV~Z?TPvJ`nsxP7%m_AfRT$Lpp_(hIgy)xAgGfB7Q)+GW z1=nFW+JLYrc^6|t)~4K78==7SfS;ZpkPkc@#qQ4q!uLlD!Z7z1BnW*gbs;=Hb9YE{ zKc>rzPKmUy+5;0O9;Xq$9qg?%QRPUj7nN3qzazA%y%rN*9d?>>E%L)FbQ0L!pjMp` z()aSl4LT0Cf*8zbAZl%3Lz#=MD;b5?#-&Kd_Ov4%e7q$dG@={R@CEF&w|J0Ibrgxt z3l|W)5rEn9*gAw#T}S!CVfE0#XPXP+Qqz9_r`>UbT2e^Rk1d-6-B;-!MEqw+MnYhD zB7#namme`o79?KYpm-KgsH)rR9!J%iRM=92o&0neDuoAI4Yg>&zf}XjW=rW-1)$+{ zd3t>r60XTH!;08NT!-|{&MZ^HU#I4DxT0eSf^&XQe&^GA` ze9OF51ug&+l&@TjutGDm{_|b)){RFRVv(|_w+824wCN3463t@qrutPpsxm7$&7J|8z!ft z!AA(hL;mK~iq&vc54ydi6CJ9)^#>6FP(os&mi(mCsOY;z&iH7!E*bPQb{K*M+mW0G zs3H@xS*O-`i-l?$Xebjty?beFB*xqa*e6Z(YKjmwTP+Cv0l~4Qa!@h+TGw}EkS9GE z@B1q}P^B&m6^cn{q*foJqrL^8)P7F~+-&8MtyMEF+kvlp5Ia3nZw}cAt=aw3tSow$ggdhIAl1E*sLNh}IADwS7Pq8f zMc;p~1Vjp4baCMUtl4G9ozm|f#r;1|qNx%Ml{BDAq<~diP!+iNr8@PSCgI1fT9U|v zoafhBJZ!wH>7_^_Y-wZY(G-+%dTohEz_F|x_y-^y$9Qm1(-PCtn;F)jo)LbkUIP@Q z=)r>rw&SqBeTy=)VnvWam;p8oPmgtcCspe21`2L*9WhXxHZ7H!8Jf?_S3 zKHijl1biyBKx#r0zd+aowuZNVpZDM7Vm0YBIB<7hx=I8=hmP-jJ9;I;g#7 zT;P2mK5U#F-Sp=h;+`6g_f1J#n?>84j7;1|-Q@QK-7Lj0Dnqr6(-dE9w%h=hdD5cX zRfS0VQ&|mBk%W-?Pvzg*eo$$qtPBk$*oR|pAP^5j&=NPGWc{}%bRH0_$USm;;aF0r z77C7<=?Q>*KBD&2PCgA8CE|{&$V#%+yey~vDvKip0+tbRy&N^9CT*N~=fY}}eTbN* zoW;6+!($5qQz3^<@HY{pe!FVB)`S@dEXV>-wN|&o(EMW$f}IS=L5~EwEkc^CL%^j|7b7;n~IV{d?qNiJz}g0xYs{w zH`Kw9NqoK@a{KHy(@^CHy$^}*tU-t>64RIiKjUG67N)2DhN#_uP)iR zjrF31t!Ut49C*9R%WTc195SUgcEGT3ve{l?FWfff>`8&uS@tqD(@n$#J5$9@7WbA- zcplcI#W2`Sjbj5pL4$HO#@HNypT<2q6?GkdB3|krG#_;_G#p)Ah}MhGZ9RYS3}5f{ z`1~ths<1pUGdz!Xams&=G>ZW8ph%JdNTUGD(q(PSF)K*B4s7P@kDlU7} z0=fVJ5;~XmJDX8*MZ9tIW|gi~TLq?VYz(nJSPG2%mmFy`vu7eNWbWwPS?Nmf2|NPg zbBG4SOyZf*Om-CQh*s&3O})~HR(FbAimzs>x*p7wUC9GtO`;gO2Y1PQ2i&uNsSIP% zs_itiEv7LU{4)5Mj2^{G?5Xr_AA?Y+utPLW}M# zux4rLl&d1dALH)CTa0bXt67n$lU{RJ$?YvB74ESrEjm4W!CtmhF0&K|IsY23&w@~A z@%bSQ*~^fcS#+7sWJRNT`wi99)J!$rOewLcYOc;ZTP3)C>sEvg4$RzLfHC|D-@)4h!i{O65p{qiFA-ul~l8zKoa}ZDI!RnMK5r-G~;Vy>L zl01`TE3&q{q7j)8uYk}9Wru9cX=|?3Lhyhvt2KRM5`xABF?>wsIj>vRTl}5LOM=G6 zl*hOZFI0h9#RUJ{{raMS*l*4_o4&J(Ofabj9lG@YJK0A&s2I@EExGIaLNL6Ub032U4ox!7xO`Kv;BeoP$^edU;jjuU1|A#$ZKvPUwuBVc&;yPfhxD~7_8`J&0D zm$iz?B6};J^hiBd!INfRz68=POJMDTK^2Sy*4MlcfHn=B7k!07*U;DdJ_p_`sS8pX z`?ICO*uJY$L}sMlKAFLlAz@N>>I)pJr4azf&SLX+p=O*nX3DoWA91sl(`ASN`_rmvY*M(+z{V1DzQd*aHn5oUon5*+K9z;l zXSi(40qX2W#(0|eWAZbjZzI#IQAVr%j%ibg&0raGr%abL3E}dGBLNjZ!sR+92Alj0 zmp$TuZ1y7yCLHu1CKf1tXV9`cw1iZ@v-r@2WOKg5rMu&29*@|RtQyZf9<(XJ8m_I@ z+N(Y!qj47uRvUGb((iy*O6B)~4nilNOSjtu25SyQ+NpyY6m5EP@cZQE!ZB3$M5V~) zyV6yXuSNvc*m6wJBXjkWft%~)Vc>?Q#eu82=OdnKCnWGKVhu|G4H%~?gQW;SVSLGn zS|Dp6@DyekdX)-8(N?dFPTPSRh2sKOsRQPLcZylFPjKuDi?%@-ho;Kq2u3@T+CY_l zIIerE+U*~yF2HSbM!|_8!-%Bukfq$-Yk)yI7*VzTEcy7{sA#E|+h!;cR9WZ{3@t;2 z;M_vmZKKf$xt!X*xYpmLtHJgiy}BifRf7G2WhqUHP2lws(3yxNIxrzJ@|IsU^ZApa z0K};n2Urr1<3N}g5T>-nLUqgES3#miqr*OC{#fb9VoHydi25yu%YDDcN4UhGGGbYS zgp2NWffp32SaPQsJtUIrz>vho50UD{frViNX8{*7lr7L_t|F=AQn%pfh>aa862wky zbHMf~fTm$PQHmeENj-L>AGskPNs1s?3}T9n?HfBwVq$u5W?3vOp8#@EEy2EsQnrL4 zm8~kAHnmZ{M#wk>+k=D$-c<{+2ix*#0u>}ZOyBJ^H4Ud&2Gqoim2IL{l4N4mH4{xW zb4~MN$>`M_!5Hm8Ynwc~OeDLoexS1hipC8%zI-keIJN=?6dvn3WnDz|$*;!CYPCgS zfg0t3xh#BLxA;ZZSyyalUE1Z~$+Jopfw{aMNssZT!#AYpLyYJTcPmN)S3caYr0&pC zM;?JCQePj6-m4j?7Ja2JRkpN?1Hbm2d!dK#=vV;pr^Nu!&9cQ{D0QgYtCXuV9hI$- zoDF{KmThI)?Ubz2kNbntm5$1{qg{e5>G?I8XgC;m`I3}b+U+H&(s*r_rCG0ZUmyy} zWDIZCrh8Lrh?OW`9Lgv;NnlpszfJwrPAL$oz*$Ke2#>GQHD3>hbJhIq<3!bndnY^P zD8=h5Ljgm>qG0ZXL&%U0RiIhP| z$$GfU_85&N@}Oi+;7)Is)&Yb1bc8o?%L;@cusy9Ps)Aiz=AZrD&S=>%4;7c*zgx0v zRH=x_-wK4sFiU98`-XVVH*R{%EkzJ0pa|>O@H!5;3`4Fjse>$i2_i);_qYFfwExe8 z@ml-yU+b6O-R^FQGMl#0{`%VA;$4YYdvDhM(f+)7 zp8zVJ=Nh)%8>sZ${%3VRUOQG*Rr8l?=J#Fodt>ch+a%oaGWG9`&C82*{#y(DNB`AC z&!$r!Zv}04?I%Ft;BZYQ+%2D=FcNLi5-eI%G*pG(Dspdb$bw4#iBh|3|Db|vZ`(f{ zG;+Uh*%8sxRnr&P}Pr4-*bLKm1SaLVWEv>TO8;u2$P|%l#TE z_iMV`e}~Hbce>o;P`SrkZm+uYU|)T&wLNVA9;)^ClGy5G_(?gnomaJ;+RhHp5Lgo9 z0G&=I!*TOA1OqyHKTtB~xHtF+j<>ht+jsA8{B`5@#=U#%>i5wBKZBK+RIIOtsL-~5k*@BZ}tpAT*w{BW>#aQnf* z&cQ$5zWaP|ary7|#s0x`eSLR*?O^)&FF*ZsF#YLo>+tc@<45rE_$U1M>B&#++7H!( z#tNX;ZYdI14?b;f))dz8WBuab)B4|Px76?Tj{1KL)VAr0$f|eh=f;})&tKL557qyV z)c+HeuyK6w=`Y6$#ZQ|X3XM;jcU0oNLqO@%y^i|*m!u4O7uACU+t}YkV+iZG3@r6` zt8fpIAhp_$&PbL(d!Aah&f3L6s^9c;qpm)HchpKgM?IX^`%hndxZkW=jbWpH_p(|0 z{Flp%W;2z#UcY~NkxJdT43)eWD7hIdc{fnvoltg52`95fDY9;nso;77D zKiqz>0}HEKR~3e)&8z~oTNf38k+(i>ZkTmZFN&~Y9t799gtBY5Dr%mRZlnjy{Dkq+ zgSCTlC%?#rn(hdSndU;U%*FotMtcW;;(vBDhZQS*k#4U!n;t-mSpEM_Fv=+va~2Bi=$9?&7AW?rnOqcwNUv|Ih#H@x+gYCJz4`AiE&+l&(5CP2MLTy8ZFdV1l>xZ=;cMyw>fn{T6?S>G@?V|aKJe$jexi#&63Q&2}?To%CItRC_chs*<$lBzoQ`7qugXew0 zVYs}1TO_~8BIz*CeTQ+Xj+uamrT&*oKlvh5a6=VrX5`$zY!-xZ@3NXIT0_(`D%{Pe za3`z6os0^ZC~am`Q0$f}Ukw+%uSOv&5BR=zah&{hz3CQM#{%%*Ke25K#kbP7VWJ$X zziM-x!2nY+ZyA=*9C5LM>BJb~Cvp&wqhR^W0cftQNsn1mlI|PBeq-3{#jt8E+<+o~ z#Wiz7E}7oKm~F%R*EAX9dwRG3^4I(8cmB3{8zPF1&eWcHt$Vyiru;S1oXFb0HXTEf zRik*)P_9rT?YR7K8%)DsK62AGFCRQGl+%fKE+5otJ3i(Fy>T)fO-)$x@ojVd;NYOX zgJ`V1O``#6iiZ^*I}Rq0u7(1VEi$B`Sxp1ZvaqFBgX!o9{E^=s9CW}W5C3fHf8L?~ z+aE-|BpycRNj%an!k}grfL5)p?{D0>_ZJxG^^1+o+S;9s3ry4c(q>zwtz()@GT#c& z#isgCtwzXT1j!&enYdJy=G#&K+uyu<|F4SI?*0`v8khpODK%~LzD`-+hur;jTXcQ> zLKItHudS_bu5JG9BG5xsO`r~H9$4*8pYw{eElu;*UqI4mtG zL=3+eI_n-G_d-Tdgm14Ma_7OT|c54D|l z?j;=!echVg=W zR|VG4Lw%=RYigQSn?ZDICe`8v#JLQOv>xLd`uKduIVs1pb2llI8Sv@j&o>-jIl+4& z=Bg0~q8nGV+lhyhq%-?i=FZ05JDYbl^ogtKly(U4JC=iS!CnhCAL*@fdN%E4b@JVo zWtqWnGS+9v`)w009+D|gIr0x;pm^uqKX%?J=6UxIihgU@ny{{kYKl#MSZk9+Ztl>( zHL4|0#-Eqf?>=M2-v-@&wQ^CZUDn=hWeyzG(F0|u&4F;9zNmJGxHn zj%N?F>)Azg^Mfw-{rA=$(3q%&TS4~2lWQ-E%P`3ML6G+gg1q5heGT;Yzy5o#`rF5e z?Xh%Y@jMyvDz855rRLRFtrqzgY;B|}Vv_ySB<>_5U=LNHF&_51lWN6814Ot~Bn=DQ zP96>ViUvYsh$aL65Y146YJ^~Em)21-?8S?ClQ3Kzou>(%pTbo;Ox zPX>ooLcb=6Vtk#c3PwbrS7VSb3@Eb}q=^S$DhduprPdV`8}ZMbhRP$riW4eX5N>ku zhT@K_GAc^|hLQ+3qlV9{9OBF2WK;Yy#JRBLTlQQv+sNh4*AieubCwqd6SA0Ha{X6T zG##X)j($ClT%$|G=#|x&8MR+{gPe23qZlSMD#T{Sihf{TeVLwL6Ey*rOxPqR3~)^Z z$P;COot$@-8Z4%~kS7paNx)6T0yd!mQcqJ+C?pLn80kbt^tO>q)DYpr4$UBfwwzkJ zlkNv7M=_zylTcj31_fa*;P<^W4FwS?G%hQ}PHbE%468fd&#-=77k+3j;X#LWjt8Tt z%0xs*X(fHcxTANM`xpwQHNe4)rU1B7`{DU4FKCguP2eexoEv^+*5FaNhb>WK<|t;2 zM;8y$EoO~!@Mp=89qAvHqrrvf9?x-KJh*gf$`6@U6ej}Ko3Z~~>^j8xQk z*ga9CpD|in>3Xk#&4V?!!!=RhQ+p6TiyHV~Yi8y(onOa;}J^yH+$>&h(;NGQI%3X-~RYN3;6Nl}JBp(=#`DTw>&?BEFJQ zjJ`_~Sac&OKv8{w?h?>Bp%;5|adfZtQPWBQi4^2(F;>v~uVt+8CRS>wj92+JpeJJZ zwUCom$zlH->2A3DTywv_>GjAyKydYAE-tSZ8hZJ>NdXR! zSKN!iH{}b#7Xb*0@|dk6x$G<8DvP+oS6`5OOxT8^wAU5BGRkYTuM6Ex;D)rxR=X;= zt{ezJpK+N%3a_8neK>6IzbO4@&>rdj2O{{FBlZkN|AR957iMrB$s{G%ouCQVVBcvl z{aUo_?l4VM;R$A+h}CNidv;tsX%(hl3sE5+QWjOg-z-g5a1y$Dk^-Jz3r#VIP!>_i z73vx>D`NY#kd|X9rHCu8NL&Na%2<9~MDb$+JXF zZlhz#dhR=+pUn&E+!`A{IIf@A7uu-y!_i=Z&TR1B4XAQX1i!jNJM#8>V^ZoOuoy-K zehoN38I69WWZ&=6ea1pO)Fl)}3cYXWV4F8Vc#DoxqtUQPsb718=ZC*l8RK+3Y}_}Mm@3aG22r0vU0_O4^u-A*BcJ^|J8)U}=P0)^IRkV7`E z=EicG#z|J9VLV-5Rg3|)DoVK-|P`35rQ~dUAaSsC?((ZsaIz$_f&eZSY?h#67@EztG z8I#i(BDwc5Rz~kUI!vPJSgkMJJ{;gdjPg!&-0da(SYeRYNfw}~c$RYtc(noG7eL@; z<t45Kw6D5$;MoD_!#9+%@ za>2NmPpKQujx$Stxwr82U+6ZT{tMhiw0fK-jJO5Fy>Q;PwYqZtgh>Y(wrZ&pcvm`! z>iEN+J2b~1_EL@V%V_!+8ZL`ZYk}j96pAh}cAN{b?t8I2bfvc$D65gvJv1dKA==q- zyT@HN#rQg-S1Ol1cN&>e2>M&~*{m=3M=adxI0?z8*=9z@HAGX8~rdVs1B#7ly`~ zTX($gt#5*56;4`|Q^bM0*Y72cm2d>e>t@LTGw0Q-L)@I9FA?ptu9}wJ{x5jpMsv+l zv4%@`9>S)QN3_LS;Ztvej6%+&4X<%d~;Z zab{XI62j3cjEiu5S~)J(DJz7_iBd?r5LixZ=$%AJ^AU zA1{V1Uf^(t?b+_L=L>?>mu+0Yj~2!DNMP$g-CP*#rjP9FUlt{8FHM1`FBSp`E)X6` zpFV!MSl{um+6DTMY@CaL)d#g9z+k@o0tU)C@J~-=qpO)7^eEL2Pxe6Uu$@p1MdCEf z2-2X^OduJ!^Q|h7V`U34sYRG?QvEYWK@wHa?VVQY+}_2XR@S>ffCH5l?%g(EQj0LZ zQ19YTaw|3I9!2!FB)qvf#MeWWcJ?y(FX}7srXfDFu`aqfoT9 zic$DYC3{p#?DR-Ayx1E?f(6{f4zJAZX>hEm)Wn*Lg&fWjeKWywO)oeU@ zr52f&peHIUM_|mbyVda|8R{>RVI%}qp~uP5qrtQf7p|aAV=`dzP!j>w_BYxf-YS(E z2l&`BAON(40pF#8bSwagQp<(D<776S%q`icrwEBA0!2eoDcrlCx}TCxRX12O!P*pt zb-=CWb}bBwJ6Q-8%ib#E^(PIs7Tu0E)}vduOz&k>F6V(fYQES5d1Cq(ejtzPP{-2` zOXdj^2FphJ1~u5H)P6=GcjB_fm%bq2j-oq~&=~cat3o*A)~%ja5tKf*}=m+n)%Fe4dRIT+aNE9 zSni;=vIo7DKj^90USCVJxIe&vTgBQJtpT+&a9w~x{lW6N{-wsSKbXAL{dhY#_GoE3 zm@}MLNO0bPq}DN3Lc8Oiu)uX#$bhbd?jO@5N<`Zy=iB}o=*b5*An6OK!O@st(aZQ_&>M7ey_%PL* zS-FR)MzVxXRZXT8h=9A4XsJabxTqV+m_ssK-b5crpWlXVk%+zj;uI-!i$v{J7IP81 zVQI?NKaEduf(d-ctLa0sOr!$dFzfnT@TenV=R&@poWx5dq)!jhc%87~2OdK4th*Y~TCL_`!@K4Zq+T(rvHW48r@NiiYdM16LoYZe z(z37`&dzFKmF(qPKM+4P{;Bl%6Oa6LbRc-xJ%K~OStX0WTwaen2Li%zwgbUo_e8Pk zk{t+^1~lLfpkdEE*$<+w!3qi%K7*w?MbBWFkNh)O>S5i%x6b`8eFiJ5%{qg1 zgX=mcvV=$|cxyVCuA?I;pJ4N`G<&5TqIl-t{kfI&>{h-LCu`DZFer z>n|f!%7t>7}9=2OFTzor6=PYjoE#nb2NgnO0VV{&N-Ua z*RI<++S2iw^Bip{c&y+YZRvQe@ElF!I{!JEH?#iu=V)U8wm3z~oTFXQxs}ljzUK3* z6?fvw&av|P@fDqCt+X5IbFKL$aOrcc6`o;GFaDrs7%S@Bm7HOeu^pE%wU)5-hRw&U z5PN0kgIWUDnMH#ZQ$jY!WLiWcw_(f**+rQ^DZ{ANcpSXy8diDRsH|7&f(o~OMK9Si zp4a$}iXItLaM4RDBIo(fKAD%f8|BZe?I@44v5*($^;NoY7ME*tl*^SpA#n!rL1vbl z4R1O9@J_)1x8j#*7rrn%>r5&nU;)Kq2U4apbR3nEq=ncMfCPmu4x=w|A+av7tVi&p zw4enUwO@HVm`+rFr9Fqhh53kqXs$-$LdcqHEN%h4C0_^xl9*HYXYn&Z=myXb!}Zj@ z2u);f3-x98K^&ASdBT_0d6#l_=NoP>?n{6u`prV)NmNP($o$}m}ZFy%suI0llFy4EJkX92CkX5l<%cEJS!*)k( zX6aT(jwA`dn-Q(sD~}=x%~;wjW*nlJlB+^L7*BGE=(B~$iIw-&Ik|ckBBd7*pdC9q z5K7bZKpK$JegB$#U_Ap;u-%zcp{RRjY(X7qkvfc|2azMHU$4z3@hg%e2I<8_$!og{4oDMA z8DF57-E-YXrfzrE*Hf|>^scdRvE*Hve3>C$q9{w4Y|SBhEaPNIA5)-=0DA3H$cH)q`rww6d5K1czo#typ_>a(=G0+fd4OaIdD@hqBKPe^c|Rfu=u&-UABR9FJ*+Z!JX-EpsLT4KpT^$|^ID zRPoj8^-FZanW@pg?+-qfcEg!Zn_tuohml=Wk4GRGT0BuBt;1t_-9-ZQcl>Rp-YEIk zv^z>V!2g_g<#S^m6_hc}Qa~}gocc-hTJc1gr(pRhg6AwHC&*$r&L|kvK>^7Hl~4c? z)#}jBh{CVsYNFTT0ulAqD1YgJRolYyQUQ4&LnuIA z8JX}#boJ|Ar*}uAxZM8m3#`+Kq?)1Id;TQGEsFSPwaE*9@}E&#;7n>jBKD;m+w6}$N;9;wZ&n&%TBW#vq5P4N<8Jn1FzcrxfGl`W@M z47Hx4xI+P`Pz#L$8+)OZ|B#yF+IQ!Bow%%fU_Y{pTX<|eGa1{-lE2#(?pO_(1Pek!WFj$ zRs;X#6XASVHHgg%ioFz(M;tfB9KT5Riu99>$C!^x%I{LTK!zP4FGI{`R-OQ>>8Y3I z4^u1cpjvqRON?)z$tBS{<%Q}H+_t$ia_cp^Ah~Hen_9~xx98bw_&?C#)ezgXxeQ_h zA&&-UXM=tt9-sG*QsKH@j0R`jv6AGyUey4vf?up2gEq`=wSw=rYYMqxwc4E|XZ5IC zv%3TbB6I?%)1c*a7n-e_8v?la{SyCv{vw{7(jXB$S}`W409iUK*Z60xF*!~8)#@l2 zPkR%uaorhv2SHJ9bdsRvP$gQ`Bd%(Q<;EkUHG#^&HmNiX!u@|WclR%~UQoJs#%VO^ zC1*)Gyr}g91w>5^c5p8F>U@*Vb%Mtqh@hrV$PqiF@td@IAx~i)wc@hIgJk*wTrjKc*x>!I4EPfkaJ z>B%V?BfzS0G%-Jim5eB@)LYn6`&J3X=&w#=w8M%o;0V#asSv=)Pof<=AMnpGOMz)) zezP`p3Yc~bIIArTF3)Jp(k=!~gA1fiEv`+8c#7w7xrMgI+q?DXA#gV!wf`Pm7Tzc4 zgX3sd5uJWLY&WC#rXQT9_E8V_--G4B&)QX4yOh=EQ?f0$^#OLwH6_s?1qN;gy%!ou z=rm zspU~AyQL7BLPLldYVh!1H6p^mlQk%)&t1ncvDC0AGTEc=4KkP~Nj`(%VS0NlWRW|M zO$rPJTkF(F_#^LeP-;DDSs`Px_SCG?UKF6*?7!DG;kIiPjr@UkX}6rlxNoVp{L$FU zxty2s~6HMM9fMHGDGph?*7Qvu_e zr*C{`5i!0N~Iac>JG%vdi=`)zXoYc4V0ppejyuxhn7qw;5C z^(0FMwJ0pij`fRjw}ea_^S;Mg$1p`(SB+4Fh$k2-foKW6u99@5f==rXG|qLZdg(ZD z`KVC9gKOqgGjP_AYv@tK3$m~VFX0$cALVNED)hJPQLZ!eP5MCja4AWr*;}%iBGV}T z+2!yD5uVWNF}o=vJ6R8UM`)vm-}m1OmKIxHy68`K0ugs8tpR8&cQq; zsfG=C0~AoSG#&M4fy#daoElG5od=OseQvr(&2(mJ&zT+d2zyG@v4q3^+93KBoDeo# zH6V6rS>C1^bol%s_w0egYTLsH96k%y5UlC*f3Ahe8ZTb{&Tg+}f9+>0$My-~>LJq=I$WX=lz*y?5p3jfXT98>6=% z+3G&EREJITO9>#ACAAE)saQt92_I2Ce*z~9)pzjn-AF0L!q|&v4)7EO4vxctI82Rq z{=ur-3S7#V_U-kh4>a|Z?(MFWI$yH&kugJt#cmdx77!X}8zG<-n9wi=kcCDTH-Rv{sYI%@$3P-{wCUA0^{K?}O3;4OBXa##+3oblnV4 zmsFWAXaU1xW3jrVh8so;#v4bimYRQ>BOXNY$GA(y8!BNdP)_rODCxaM1b+s(kg!8G zse4I*7-Y@}U`yuPE$B}AOYvK8y)-(3Q-4kEswtG^c91$9r%8^-?^=hmK(Iin9aBG^C_X zgPp??)1IxMF~%K)@eMO{-tib4@%l9$Hlr%u1*Ld>{@}u&af^(ny$MQlN0MqlI}Hg) zd(Xf#G$j{V^JMm1Z~Tozq|plTL#gdU_n452n$_xIe-B+F-(BECb-`(Nu}OcMXS%?@(h; zVg`Bp2KsE!oY#|2R6r$0X+tzqcc&*{%={@nQoE3Ij0=s&=iA<`C1XNrflpvFQomsS zo8k-y6{_HwQdJjKYmq41jATt+#^DTGk>Db{ZLw=qxa?O@GFRHIx&si+XgVY z#>E*DaXKi+WX~slhOu$p37sZnx~!yRCJ`d68bB1{M{UwmC=t;Mf#`6Jqyb&rbC%ExW#b&pDJIcxiiQCDfDYO(!&(D`wrvEJC& zj36RPqE=yrM07Yk0TxwBR2~n!N2+mhB{?PsqYj_Wj2qDl@RsAk)8WY|?w}zA)^%9^ z!4f{|CjBG0!$zT0>`INWwx9OZ_7<|u&8+^p8K8Pt{^&Y(=_4r)5LI&16qs9h+ZJGS zD{X)E3>2^{sC&FYB-01jVTtdkYut;JSy4-G>m%lrJQ9;*p%ue{>J_*&zY06L1(q5c zUl(a3Rv+RCJvZ`sBX@~Pu}IEB^@m%VvX`bm)N14}Mxp6na19bFb$VuNA!8S(S>hqP zoRt#uEMmnZ3RA4GP~q|gE8>Xc9aq!hCJM>dl>1PrkSeJ*5%avEVMa5vhku` z1waUc{ZK-xdw~VD$Yi;F+wFs3Vl7Lv@P80h8E#GN9b>?3UDyOE0+m`?_f@}}nBvQ!7XV-N>3}Pv} zjWyb+57}Xq06XjkE4jI-%Xd+R4taok+-vP{M!Krdkxf9jNKbN;4oPu6|>v#C!;+M5uhhgCMh()FEHPb z_js~B=}*tL6ZIeD-`9QBtGxl<9H9H@T2E_vYZP58U;xz|c7ewC^~M(Nda#3Td-j#{ z?E7&vFS*mAuUR+HgY#C@bI#1&8w64M>HuGm66G|2maO4j^b1$GA&xj_jC+<|l6U?u z)qm|vs;`91YeX%2AzqHJe2;?;#vfh5Ff-k?`^_o{ExdZJAEkTo@8_kb6Lot*Y7fg1 z`)gukKir|PYdM!G@nHb{pE6M#t|mq&iu#!a3qV{}XS}Exh#xJp;Nt!=i93V7(%JT< z6jkGAKh>Jj3cqQNuu`Eu3$>8j8c6Sq2n?jqjf+PIMQk!c;j5f%)PtcS_x35|jXdW8 zc6Nw?tCcLN&q-Dg;IY_kAX{l*#>HCpI87_9`r7Yl-0$=hHW1Kh%n`5PDh$1*{X)E; zy~Sal)MA3Zt?9cjaJR)Of%uL9%C2J=Gdeq7J02y8@LmTsxC>`n-SK416@^00A+nSX z#hCe54=B08|L9l3!K;!y&Rw09@o_3ieN+FtR7CL7frp5qP2B0|mr3vq6D-CfcS95v z-s61wj-J$NI&oX60*(`O$u8SL4-uieI;gLVL_$t5sqkwR(H!UI8^h)ZojJxlE zOVpN+%raTrPbICA{=|*+gvA29we01U7L^E)MLL&kJr_4Q$R4$>Z zspz}^djtbAhl+|``9c32c^LNBhb=SCRuPvpx=^{BT1Qj)8!tRv)|85S-O7HMwhzxT(XF zHv6uQ(buvJJX-nI3hX>8IIUx#V5{lN01NJ0NwGF+bmpT=D%;Fmqt|1LB{rU~CGA)F z4srRdS5~cP)?ZF7)#JzA@zJPz*6qWw*gV_K*=^0&uQIi6(7aXrF1mwvs=}e3s{AGd zY?7e#r28R(6|iNZ4&esZH9x~eP;VCb4PrG8l;a152|#>udI0_ zUhCgh|Ch}PgY_FgdQ7AMLwEriJf`bng{bQu4HN+W+JBWtlh|ln1t|PX1PRymL2)Ti zH6v2ezIZ)biLY>HP28e_Cj+oC-Ag1Hu`nQ>`t7t|`pE&x!tI!aCU+H$-?j$BvgqnuD_D zAq}v7MPtMxm`e%n^FGI5n_Vs^AZte=*mUuQF*0h!b1MQl4R8Ib|7@G}q@IfoY}#4{ zjgDy`K?`KM*vg3R01eZ0o6L+_antt8Rt8ysMI5MgjhU)}hQ}17FJ}LAEIFmZOnudH zqdJ~yg>>q;b0n+y8w$I@FI0&jA5N*Z1Aq+=+>o7Tu;f(J(B;6~)TXgz5FR&RZ=D7$ zeT_)KaET4DuvUG1;i`RAh9Dy2f!Fut+YxhZWLc(-EW?H|YgmhhcTXoAZ6eRWvH~3B z*4LqL_6E4)i~0HY&Z5$JvzlJ{?Oj|6mImzp2*+}`sWSRM}?&RjLxRx z2{o*`K-JX72!@)2zkoF|i4}Zmm9HHVGK}(%xGVP>#O|uKH9$jwjspM<28y5P88_Qg zruEni)uPS;G*#ztbLr3AP+yO-97^hZ@pe}~6jq1RcC2)@NvZ30WjLx}n zVgA;)SyRUEtW^$7h8cDN^el6wz7h7gYz3eNEUSJTFq08Q?{-5p!v4S(;NabNpPl^6 zgLkSU(_Tl3g^7|O6rc+f3py+W^7AbsCcrz>n&*V-P>q^ZWDE4jKhYE`w@<;V`mCeilYqY<@1A1encyL&+$+?M* zn(Gx9R?1VNK~G-Ag^yDd)0xP__`6l+#o9Cq8emYT8A$7_?EV~P(K)Q53zUzt|8mNM z&IjAqaYBv?v&t8TUl#vj-WdlU%Y6$vv7MYU*~#@q3H)#u%*@7d8_gq2r**B!*&+6zm4!BhxIE zI1H9Jq*Vc=Q;f%Hhn_0uAXL`~(Xp8@A94E``$9OJJIpQNdWIkV91hfc==kKI?$yaC z8rK@f-JTkQDn=;;i#I}T;H|Ug$CL^i*|iNf?yr((&kuhyPU#r10u6wN`mitc{>iu$4byCp;z#I1lN4~{i~DLmk$ zP3DZZ^UN(m(lJh9Fb-2%KyGg@y@A8Msd*M79TylJ4Uhp;#`+fj+>SH~obtmD{wPBH z`CSOjxQ_*l_khiPsB#a3x!D|mQ0Wc9hc)N6&4LVIIe<3ncy#P@K&=c5&=cxKnV{4j^m36~d?2)+a$rE3WaGxL4)I_=t+TC5awc5<|@#!$^w zxjL2(fNm?3-wur$TsdK;BFow@xG)CX7VA#2m$YaG%3-lu*z*zY*S~H_Z!Ze+xO=Du zGwD<<3N?7a+0Vd6Yk>*l*q2hi5FEwFoualWennPxj9;>KXD)$BPulq&xz(n*u3)9N z&RM^-qs{Co(eW_`ZB9{9CZ}nb^=7RvrgeZ~F3(icuW1r-U_u)azE#4|Cmja&4Qkfh z1o~R0tK339POf`XJ=n!;O)SK>ucy~U7eGp$YTlEzgvj7%>gS<8@-P(n`8 zJV6-YKP8-tB=lAL7+uZv6ug2svtR*;%j%4GevbG(h1Zlo<;`OFDIBy)$`;A#ecOrO%JV2%v4hmEg{ZJ#Lx)LhwIZK#p zoL_|OT5HXux{ux$A$pod4$Zj}MDjq{40jLAP8*%vez0Z9B-V@dD#r$eZ=`7>l!Dbn zhy~41h)BjIL6T_}-~795G)n0XC~Cop!u)c`Y|aRY8GMqWZyCM`KZzFN);$_Ga^kQ9 zZ&EYaTo<_(8@WQR8;(KdDm*u0`Iz~V95-}NLHE=4q-~)((nEv3ZE2pqP6mUw291)# zQ0yia`2PFICtYi0q&w`M2*Smmu9k50E3}n$=+X+S@2I{SSw>X>~1 z$ac|g{|za$v7P#V^X8}87M$@>G9o*kbDxid(pz0~SJWYL)_X7Xva1%IBj*a5Wr%{0 z$GE_VMZ$#NZ~I$EaF@Xv*`6|(ZJcCa{I_8t$=OC)Wq{w>ZQ50omm$3i3~d3iU~Uu_ zXuv(?4DEtxZPp0R)**Cw2XZq}3YcET3v70&bF5gQ_F)+TCkffRyJH?KYD3tu{PXq7 z{|u(+mP0RXNOu^njDf)$6C~C?^eAfADmkwjyJThMjbWA8LL(SC5bjOCmEG8xt7H`V z%PEOY>qmo8XJ*MFFqhY(kk(I#g7zmv!8 z)F|a=dN!;8^AOG{wckS;*9dl01yvb5hSZPo`Pt#1=fnz;KnOP0{n_*L3PE`TyEP8D zWVf07KSQk99R{}jGnBgl!K}68l2C(aSSmWW#-Di(8d)*3w$^Zu7bkszd z-AeClboR0sD0Cbp$0a$JhfxGn?k)Iy%3*CT)~bhK@s8Po;)E6-Si$=CUiT<_jbm1( zwS;OR$Iq%~riHHgHSDYYP%iPSe9t%YIbYE}bB?1y3vP0rP)rpR?1N>CJd&LKtS>iP zM1zLM7_;B!Wf~dmia>PU3|;oyzq8fy@PmqU+U2~cxbk-ylU{-$;ET!(Uvu5glC-U= zzX;be^-@wwS-SgD92wnh6MdCZD?ql?xAFB~aZr65ZZm~tF%8--MdM67s~BF0UDL*@ zLcg=aUy8mX{&3(~Q?XUXsit?S5HL>h6|2q!%bjo3Lqy1%Ig~?| zYZ=oe7jc8OVTn{|IMD;AZ>7=CK%U4lua9c^Vo~ZZrxDYohVv1)G4w6I>2hVn0HPCpS?@ZXP8P0uW^XP(8wt5h=2tbhDcHO!@I zctU9fT@oHR*7^_V6u@xoBU;zaqODp(=@X-FGOpIzWZB(E{f(kX)X6o}F+8TCcP*$N zlKW^qs;Klzdr?&}^?;#mG$(yhO7I~}?%=O=T4}0Dbo9DO30jz?pg+d)>`QnKw#U$k+!s|TH zs&vLP&WmX@i}~^y2C$CDVXc2QzZ4mJIr4hUGwknMUM0;4mIY>3Tozwsam8hBOJzAC ziys6xl;MR-cN&-EgG*jJQwIgswQKm>LU3cESU0-FL;JFp3mG{-bq z*i-nw1_fM6)T>m$RdcI}dZM^l=+r_L1PzfMEVq(KPbarMP7Ghj$htNm$ZtqYv$zn6Tal=-OcFc(Il@CH z)!bDOnA=;Fz@^Rx^fg^nYgFq>I91u$JkAc(F2l5IMHc2FEPkZ$0-TV-%dkP`)y?>E z12{cH-ON%kvubJuGD~SRh&L1$83>DLh?W$gYn!^)p^ZAM40eA`VKB`0oE@+DMNarD zwLea|H`U0Qsn{ks;HYGVkA0Qwa4KCf#7_AaaY8i;I~*z5R5gkPDFbz(3?$(Ef=?_x z8I69W@E z0YbYvUbGj8FAVKiqErJx=_UE?_XqvtY^Wys%vPo97kYacn%~H7D7EYR|Ji%L_qd8H zQS?6huh{g*A>AOiep)7NTZ(N=;uvfnTPAZO6nU$)C2iE|7QMS=%d)-?5=fXkWRjW5 zB$JuUJuq`-NOD2~Nk{+_^5FBGr+F}MHhE$$hVV51!d*Y=_paT&yVaHrs1vNcYgesW zwW?~>s#R;P>U}G>qb-}ly~{q$90{p?nlW>x zWKxlUbM6~uYf|=IXWA`}z3A&Mjki8w6o^|ENpU$*D+q2w`k`-9DY0mOoK} z*Ky17AFAKkHmLgZH9}^0T9NXDO6{K&_T5nLfVg*S?dxT%LjjWeY;)A7Gx!K?=jwe6 zZWsXcb=Oj^?Y5NAcXQ7z>m2aLTgL5{(ltx@Y1M!oSO|RrVw_vrR&>xt~;tCzz1bN@F9LVcubNjF=BhT*b2o);$8^ z=b(qUrOuR-6vD~VTPLY~c1X@TTZ%xHpd$cXK%&2SeYB5OF z#dd=E*(ITINsq}(@bMDHIjx3mjLkAOd0@0u)(|o;9{3Vc9s}X6xAt?U;d)~~BD9~X zwDcEiQcvRWu`{Q{0j|P_NF^qOT0YrPDs_HGT_iLja@G`Q=M43OsXd{kQy$>1i8%8J zzidR=AoeDPL8(mFa>Cv_by*nIT$W2kG0kydHkYikRQ462a>kKb3RQK(5~F!8TB^Ys zQV!SGYn#QTI@!!6LuQLCt46oYQW}u(in85u7(!{G5)qd_i;;NPkQ>Am(AeKbgG{Q) z+mHm^%v_ly^b*nGjtteIWCkt0p=&HEbU9i6{7kvNCYv>htm%`4OB~|Go;|km@IGC> zoV2SbxMc+^)l=CwuM9Xe0!njUvjb;3b)QIP7_;nYUjs;E)i7@s`wvAgTHlM=HP%gdM1)6#)QW*r`IQ^Yf^&X}Gz{1oQH#()+ z0_%bbb5pY;()kZYuJDW_KuUX~b|S8?-`DXX8rB2r4T@K>BSCc3^YOHil}PJc;c1HA zc12yGvfY(LPq{=23LQQjUDBJOE+I9hikkM7z$)pGf;VMWjvcgI$*;QlRD0sJb=Ef@ zepI!h`*u-uEpn<#@F;hwu{V5FZ)VfV04kYFg&<&2fl7|Ou(ciC;9GJdB9+{f^7a)y|w!bK+g=CnceZ-0JQ`D&@&^hj5l3B@orkhf<2$V%BsNAwcw8G+qw5P>et+ zSrJEUa8qLIJL6P8(@#Aap&VruLwYJ)NLP1Z0Ilg1dRXS+IU`ZpXU)(HIaS_W@TLYs zaf>vfl4E{NTSW zG3#ol8D?~sxNb zMOSZSMpx_{Kmr#;FRQjYp7M2b#-q-qoS8>|m__j{Sq1;?fsr7TJAba%Uslhg@6Jc~ zBF)}dNnhNg$E;qS!pJgPIl`xQos2Up`MCx|_A?IthJg}YM!^z_i5BpPnL*hwQrKQB z!iF(;CgNByxzb*3&#x{<40^jOZ`%>R!a4nf~;q#ptjIzB!~p zxKTc_(Hw%@kW|#Ag8KSXeT~)(=>umdvZ4hl1xCY02sq9-Brz#aC&wwa4(&Gl#aU)G*3v_ zf6p{T2O&VwAQcXV1J=-=O6p@=Ujh;4D}Vs?0>5GaE~(kTPb#~rM@-IX6B#UJq9XEC zf>{N=L+&}D81b1_;6K$cX&pXFOVg3ysKy9zIBFDA>Sktvq7M#VaE9WL5vo((LVS4k z0wH+;Mk4EkRCf>U>#&<;9!b@hT?-SV4`fUnin{(T44S~sWY(wv&B_X)3Vwuoy6v8A zE>G~7#WPf9!8s?xkW`{};pxcHJ#q}UQxnVA9FK@2*~5^<1yIh>*Ugc&#K)>CX4j9Ts&X7~=DePlUQS z(nhZjS@+B-lUSBa+x6B~JxF!j9ArGDijoR!Jwl`wZ*~7w`pzqW%J+;qy{;&!q0GW3 zjOMfv);vwq`79L0#JIPSJaKQ+G2+`T52Iv2Po9fc4TesVqj;k=(^#1*fdazA7p6UM z{?syOPCccYcGq(WY0BCBh^$hhE7n9s3ExQ;q%kI0HusT`wv}|WQyLJEK53wYFHHk<8#X)a40lUyNmjiYyZ3sT zWS*-nJLCo|PlveQ?|m!UA$ML8otTeStUJ3BUKul&4=wy4spFp?I=`3}vYK2^XI{=;k=rJ0$X@E`5^ zr6#&7WX;CbrV-!uE*+-lT13~y=o71`=~GT#`4k9YH$9pJLU$%uG{KISV!BS%p-uWW zU`d;4wLoBGbtiV5iqL#$pToxmRz{`5|6X05?!PU>9z~{YJexD<0-dgq%;|IDi(Rp; z;tlj}8Ig#1z`1N9ty#c`%H!}KjMaUX$fXj zk}G>o=sn_|E4y=P18!5uq?b;9&_<6AL}1WXjIXdkpvgizcN4(*_IlLp6$-gwTvhxX zU)^&~U5Lpl4)fINRcNXV1so*$wUVz9+jcuu*^F7<&nQLsYG(F+=sthDdvvou_7DFmkIdJx41~g1@C<6 zA0TTO_tDx8N!qHw9VAPQ!}gsA(3=dhP^X2 zCM!{O^>}KsiTR2@DU->`c~bhnI^so!>;`2V4>^p}?)CTd1bYc*LqcJ20_Mb{!z;Rs$o#Rku)FMp3V?XnJBBQm9$6 z^c7dA4Ot(v#nX&C&TY?2ZW!a%W00}TqB6>uDEP?9b2I<9%xA|E%O-4ZFhnl?Zp;NO zZ@Uwy*Y3>d%Zy&kxS`(Lg*{(UZ*!8qx^4g+xASiEcA5;{C#y*D5JMoTKiyA^3B zPI79sT9J!fNu0>0FX>brD(cgzuDRfoEBmG-*5&Ze|VdB>B95b0wsrORbST2#egqo^JCVEV*K5HHsoP34>(q{p+U zCu1UYiNt7>HNv*Ld@)n(G*_n{-9Lm*h7jUPPuJP9vM1Ap?UxyddvZWK)Uo&UCU$UzuMm zD=SV}cp2Z=*2#Nje8kLWX`Gc7SAWfW>TI4io7P!EWoyxj_@!~;Y~~;E-4o{Fr?$x= zovM3|-0_@L;g^a+e&$qBfAm(R`w7PUwvVnqvcRBT)WIK%79bX1^$&4E*dmN(^_s;%zifh-bKE_YD4wmgxaAwK$ zNprR3Mxj3x2;L~odbT-knw|+cmjXiHyAaTq{^VD|^fhUS& zN)fseLoz@Pqa}B5P1why3Yi4j3B^f3k)d0SpxyvVHEI~Vn1kde!BVraCQdk!?ifoR zYcgtPFalj+IAjhws$-VL0X_6IkT990v|8bW);nyuH+dna9JRNEjG_HN5j-EcI}kfJsk;$+2W0jTxjTt9fvroll}JY1@*We&h`?GLGxQThBVMC&{xj%zz(`Qx}VOIGY`zcwJ5{0 z{WJ?%3Z9up6+i zS%0x0UB+1K=7W1W+vWDOFw0)M`X^%BS*k>>H$|&yqKFrH21h!dQu>rZzidrnD zLi6z0xud5a!TnhLbUO-?&9#L_4aVMidMFmIG#2LjvNhNa>- zQh~V&#nzyZj&pqVHVq`tQG~!a!&By1j*7dTRy-gYaZGCa%&u^?eY=0-AQ$rL_55z4 z1J$?XcW=ITmGa2uq01K%J>&YX5aN8;QZ2IH+xh$8P zxSr{5a|dn9&-Lr7;Vmi+ozp6gv{RVkFYJ(^;JKFM9zU}bV}jAt)mO=`V4x05%D>GK z6OD0E^lK+lqrx*D924lQ!I0Gk5B?hWz6U`MLm+DabW(>gl(af5vln}?F4lu3!?-+q zr1U-AvOXum^E!Iqgqh#uT|L0&%^T?#Dzc2yYiPbLGRhnoffqz}L(5SK)Ig)< zWTBS;3<8`jZQQ%2NiuMB*Sz`Q_JVKsyex*d<67%vJvaiCMD3Qorc7MC$PW1>{D^&; z^}R&pw~X+UyaOn=8s|yCo(YXec-xfw5g4%aKuSn@`f^l9Ujp$aqbo?mVoE$0EuXl& z4gx>n|2SPqD8h47cmOT$KOU|h=5Xbw@KPImcmiQetAO5^1HMse#VCp4@Qeax5&ZOo zyrazsH0=$OJ`={ZIWfGa4ce$|W(E@+U)*k?V57kqj8A51(WwSYnGR-*w@P4;EF&O- z%(3f6YO-Rl*r@T&DdzWM;tnk5n*Ul1V~lnyWvcF z2d&vuZ+BMM%WMPC*-KD6F=NQF%XUsrdRQs@$(VZ~<4;%0)ppWq^cr?{XE=7rsINz; zMPc3Q1;ed|XP)%BCgKZ)H_m4B)Ftb@MGX9kFSm%~33<1IH5d`$GK?gVVLOnI)c>N^ zF{9c}Ft|951u;_A$B@m^N_w37;;fAI%&)XE>*KM2VtT+VT4*$oK7kI?qX|a^ft8|6 zNxo~4-w9YI?04oRVU-TfLIULx!DMAY^LvRxk0YGn2Oq@Y|6uT?#b~`5Rq>WkO5oJ9 zxOiM7)Gy*9*MJEUNrG}HQ0b^xF^XNhc#(t4JP0F|F)WtEkS$`wOAZ7T*2=Z0zT8>~ zrh)@Ql13GFQ5AvE2$%*v4F5Wm6nBKM_4SakjH;`)NO^$dESXasG6J(xw?&o{9n7jI zg1uFR)0e$ZY|2aTQFZk`)Fi;4cvL- z>;?Rgv8D2lt&|%a9oE5$BzJ;F5+>gmQJ?S#jMKx@GVxfve3D{o6x56QB-oz##&7cDBiyip zc$CTK<&j81y~t0>oKt*N?;7=5O(9-WDnHZhwEPJlRkFBjQhebz z`H`aR^A~(n$-<#jeBn1eNL74(IaXzY>J{nRDf&gcn!|`Zr1Vh2SJgk#9+x|X-{eQO zN##%UEI-Jg!~99Ssfi+vP{l;yH&s%esfeQDRrj6PCd=OASNOc`IxT5_z}#kr3=mnD zq4e1@s0^U>r}xp2bC7o26P2yNm~7@})F zWin4Im2Q8eX>!<1NzbA*NOSU}zw#B|sbrov>2%bZnD3|(G2hjt-KmmvgRPYy?u|6l zC@Q#>ARNy91TjL1TSSyzmR4TrwPevxSjwAeY`$ftNL`efCXbj?I4Lcuho)kuX%UcC z1#%sSwfE_E47=W7=6o?CXPXDSMN3&gRHJYfEn^!8iE!^nI(*PFa z&MXNd97Ay;HVg!igmtLBd#MgeK$iGx_H}p_cVoe_lG>A8n}hD(0zl4$|Po$+VokH?)h0+%sch+%M?eoOIZqZd=(oWilexOFj;ojV0u$jfz3V(m_r zCh>KhhxxpdX)RpWIe_E4go+IMzyjcWmf8TFM=lCZMilsUCR`uf47@@Zc{stzhC2kE z$G9^}PgJ=~nDbSpIhjS+cAZlO>~SjPg~_Ow6Woz!#Eh_`LwF{f^ue~htyB2P5GYx7 z+W}-$Ik7Go4HGFY%IZE|wmr}cvsfz2_TZLKWUtFT7H8M2)1Q4o?V~uq!2z8D_TI7D zh?-Todt{s{K@nr#5Ez$}!@ihTsv%KQT8#0vVDf@ZRjf2y;DT&R!mV&BuvUTm6>u@9 z0?}-v23i|aD}d5Bi^`NDM^`B|#BRL;kXv!Q98;Kavt`!Wl)q(M%&7p^DhIr=VC4sn zg)Gp9QUHk}S0L>Zs8<3^!xzzDxeh}zH{a+1^?_ey3uN*l=_7(HPL4TJUogMPA0U&C z52d&jri#mGES3rB@*Tf90$G?C5)OZNRtd_X(=d*Z7Ku zx+aq_cy?GSeK4=r(F;3%!WW)ZHC3UE_FyqSkuH7x4Ka+qkg>W_9?5im<8Sivx%2;#ZZz-}S0NAJuIU#)=yz;tkW~Dhi44I3$>wC4hv9 zl_v8D=`~b0L}R*^|1h22Jj1Z1<5l5TEim9We8E&(Or$vKM#Q1EIriIfxSR5xj=YXv zl>7$C_-xH%X6>g>JaOV2aCTuEq=w9)egD_q?^F3(538%N#T(w37_K#{VJ%9A+hKXJ z+)4&l$H>UYEL!ms!FFG{pmWuD>oDt{ROYv{@rf^Fg-;_$P*$|s(8n~I;_pKtwN-R1Rv z^x&vF|A8s&&Hvr_^*;aimiEumFKhi@-L>_9bZl(oU~2t8us8pAAv8Wqq{K zTnk%h%4l-}vPQEdf!<{Y%8b#{oUD9Bfmti8W&Xl@&)#_R#ydBDedFC5*WUZ#jbEdGKb0*& z>TBsk*@tAugCJe&nrd&_h zl{`H*uj1uTRO)dt`q%G04`lc)kmH8|{CN!@gv(j97REKq z^V*HyzW2({9I$nD@fTM~sw>36ZujVWv*X)Jc(A59n=&{xMR< zMADe7qsF*ArpjHWguhVls|f=-bzZ|pHG3;Yv-twj5XkUa!2f&)-kuFko=N*eWf$)?QWUp;^3v>bw?gcXihoa6636PzfIs_LJ*gbd=VUz?Hr5v{GG z#pk>@Tj)4hwhfzhGJnpPuLiq5$&p$x_X!c6CGX^|t&f4x8f^O=DpKB^=BI+rfMI8?#6Ee|>Ja+=`M`(Z;pp zy;SbvjeiCn_eYpwufceI6K3j*JYIZ*rxF0${0=0){oc3U`vJ~pnAP7it$^;|vMb#l z!XnHF-l6I6F65C7*uI$d#~vtV_iy!z$hLRnkVjUbV$qr#N?#J`nSd@Kqoq4T<@>j2 zIPnaNmp0GhIVc_jTA0j^%#}>Cc0vHx$9Ey|+rXW_mr*M%et)>}MsVZz5`(82ah(F6 zC05NtLE&n_sGBL+YBc5-;$_dY3m2b)u`Z`Xwbo9cEx~k9IDDiK024S|aHmK@(hL;R zk_{JUnZ&(Rl5%)E<3}_AaAo->3=~X7yegwJxl0 zi6nJT7tY7xCTISu_Ksy&$|u*E#O@z1TxQ_XlP+wwl6hFoS9AmmKi_)u##@0FnkppD z)8{|n_+{z-JM>ChBxYp44+{5hiF()Zdeh6>g^OLWLR;K{;PiXQ{Wf&oAD|0KG}M?O zBi6Vj?WLT!(ZpGdlAWUV4ol~N4*X|eBH`!3g?4B=Mda7C7E&TT5siZPUH~AkqnHT9 z`&OVkF>HaTThG1PVeR*CxjWQZt1*U*#|c@}quyxEueEEfc)b?QHnYK6R(U`GLTfk(P<^*jAcXS%iMgKoOF*)Ms{|}Ch9N5$U@5WDPaNq?ZiDNuZ2^7KvV>iKR_kOHriX{Z%v z4Ilod@Q>%fBXpJY5M*QpkpDYJ_;%v9h`WW8a4DiFEX6{YEH3eV^4!>>jQifMqLpX~ z1l$u(x5HYIp#py@sa6r5!I-BpszReN64{}kbHnCJ7JmIAr|)u)7lQ^m6N@D%7ww5l zUn#SZuCitqnsEbvN-3&vCqtr~{EqK)W&=bAteeEw%}Do#m48dA<{@8g^{J&V)mFo& zpa{liETA#Eg0y96@_pH9x$%lXWzSK3@;lla)rRC@=S(Rf2-Ky)B^X6ZUD2I5cEtVH!cEStB)Y-fXZL zz)6=nl+GvhZJ4*NV*oh0gjXVF5{hMc!GTi7%4q3IFPi9J0}eEd>sK%@D3L$s9tG$7 z9cuN05v`#2W=o^`JJxRNB@-ii*mx>ZRd7_bi!wx@o|bI*pP;^`g`*%9W7Tl%^RFM~ zTEXmyr5OQvc4W@xNa-A-GRNrH_ym3D2(ErO96-we=F2>4WfpKPZX~?w#q`T)wxrIH zAgjT+FjL+`nY0o>jD}~>LlVKa5K{2FCSE&)PW>KMNdm+XV_DfQ!4{@?rA)^)MKis` zm+z1{!Hg*f@&f)Kw7 zB4SwPOiJ1un-eJCitBBP=OScF;_D#NwN|1{AYKeRseD{SNt4Jj&@hCbp1Ra3`ng7G zt8+&>C`(fG%ZawU+X0wdgZcI6U6~aDxW%7 zDYV*j_m(pxPR&B{zvDw9^T$>zD~gF=>CW2%(QVxd-#jt!qH=? zWaD*oZ2PLT;NI`~NB*uZiQj(DKk`?)e|U#INhVbT>80NL0H)#&u}52+Y~;P%%>zGM zBJZECfvk0q)Bc-5VbTVx}%$=~>0@l{314E@aR0K3y>>?#$`Hu3sSADP&)oKmq zXvg$xR`!W8nRCJsUp4+$qGp2;$9povxVBTgyXl|Mi@viW0Pyu_cQnfK>}ZE*gZP{m zXAhw}qTQ$R0(VnngeAJyUSq^Dy(pehUPKuvY0H2VYTG`l;xVm=T*NE3jDFPrXc!6# z%G}MIC9shZrf*P-&~praYQ)K6kQd=&nbvy zN<~&cBdQ|u7D_sZRedvGNz7T$0ph~*nrRsOe-0_{XkTdZsu*KOg?%w+C56eh0=tkC z>_Q6cF&pfH1-6yfnCfAc2R=0dd%EuhB8F3Ai$i}L!ELC$;J&ybZB2{ z3<|&q10fgrip)w7T1!A6un|%lb`UQmCAZu{mvYD4azcV&{f1Mx)!bClzXb^Ms_UEh z&fVfXERqzp(GUJovjGc7vJ$RGd27L*?OF?vyHMS%)(9%}sGb}rHln(D;W%~`tX1V& zW4UUjGk{AKY92cjE`!`!BVU{qb_W(Tswb^OK|F$hIG^{kGb^QULw{o6NR$%^@N^QSjox%uz6-n#jl4rSbEKR5pci`;tt=C3;xvLpQD zDDv5l>T~mzTi*_Dy?g5|Cz8+2SN`;3aO?R$y?E=n0H5D~;pXdqdJ(&XvT^Jc`1(Qs zWPF{n+|TepY>ga~J$CxQdr{7vU9V_A6uCw>rre}xI10>vSPr~`g>^EaLhGRDyRKl{_) z5*WypftC?^NPHCeVGO)L8E?H6z_i23_q-j1$dmu(&mkiYiC@}Li9A_hN`3R@&(lGQ zd|98r`74!GL@5&4ZoR8|-!~#f%%W80Nnd6a!N>>ubsQcyf8oY4@R5Paq>*$emW*px6dThHD6eV_(QrDGH$%~v`` zHcD4+1S;A=U4sZ-)Dg+t5s1=_@I+~lHT=u1cW?go*0-~R3s?b$NFsRuZQvz>$Grcu z4z=C8QHX%oK6~@$!Ofq(|2H>ZsrZ8OActp`SJ)0{aqTCV(9O3{n7sK0FrV#!WlMnM zQ0z~C>+7FhF}(Ro4h*Gu+o97w9dU#NdEWo_`|mi?!T)WgX5|5pS}CvcIT&- zB;fqbD8S*LtfL1r9nT2USe(j7lO$@kXtEui8451oiAnMB6H`2$o={iM&wvau3IfDf zNhNu5U68rpFWo9D91xXQ!0N#s5(K0)rODL<%FAe`CYm@D=U?eTCGIbJK~F8AW6ke`As zk(p&RUZ^M7i44F01wxpCg5s>sM(ZzzR7ElrZ?NwR--vv zpdE#;9MEhLsWDXq@*p+mh5|YfrW?4$)DRWZ-dIYdJBXIXewV6ZqZDAbqJ@pg5E_L zqlr3*sEI0l7)VL99yUXOIBlHG>eB)TB|JDeFEy&?qV*bZZtRKqiW;Y+{0?cWC(k!1zJ5Ar72r8*rYES+Pa`Hbh z1(W6iOk3%70i_S=Wl4s2VXmhtW4t>tgNo7bYVAVqFdeK07O&o(m1T^2o6*zlxEU=D zvR*m(R{iywqz@Mt|2vE%Z2RNrt(ih$D40J3SU`6>$ecoCZ0wQ3Gqa}*3cLAjDo-&d z%_!iqT;Vw5JQg|JqaDYnC3rRJ9TV;Ajm5L- z%uyn#PNYS&mP5udE&MCrrg6Gs&E)@mwB+{2^jS!Ee>90r=KITT~8%`It3;0Lo zL>(0t=LeC>m&hZY^dM^z3lCN%9>o{MfXJ;)Jge5wIWjrnaf&={roSSMJ024GLBXY& zZaB+v`g*gm7AM#g@g&kW*qjCb$l9^Dv3mR~($>OtNP&N4YtaU(0RI+9sb-E_s~6R% z6iNf@<01br04dBI1{BmwubmEryS;TA$j`9<)+Ts^HUI9i{~tRze!$iLjZaRF?(P3~ zw_L%EDYeP*FLFDv+TX7O$rpi^$V@=Q$j%-9{$ zcJZppJ&SulX}}Y0N?{q64w)mxTE6pAuHg!+0yeLbPRo>gDZs;_5t*~LfBA1$~hMK-Qq36m8I*|o(3R5)1) zN9BX81RiBA@QBre59Y6{mf8&|=}WJC%2Y ztCHtex)hLYxer&8qb-<91 z8*z_AtVB_3tyZSLDJW~nrA9N2e0Shj43=heB!r#-`0`6u zE7lvAqUL%d&dAZZHfTu#eCA_#93l4ESut^mO1fFh>(PylvC*?u0`}f@-I<{ zBv3*hwa!>jX7p~-;=K7a z?gLU|4^D->BlWeTOSZJwF5q)QgOU%j%AE;wXIgO+(&?Txoo4B;t-x%QnIgZ{dr=}%8G9$#7>b~XB-9; zF8OLeh9>a$%TYZdEj2u!WmbDw^dW{-KNl^ZxV-M0G+d!OE*}rq57PmEaB7Hc22hzi z9mxFn{S+yfD@LjFQR}cLGbTGZXF1zfAO{`Q@as$%*HD|M$)GauCldrmiuY8SQorKWicyEN(V&lqv5_tCI^YL;$Y_*%|GTtoykx%LjmZ&BA zr%c2h5eGh`h zP(-MJH)0g#W()9Mm@AR^;!;PRpr>_0>5PxXtC2CV-K#(pELU7(!vF()ozs}pCV!ck zV+NHTeTf4~lT_4_5_Nem<>G{(cxL)wNt}vuSUe!lmuKf3K##FIoL{F#yE~t9%@A`u zzz8vb$OwwWDR&hSEGBU?<<6s0U@u1KRpj#$i-TqU08;7^!(Ri~1WmY#KU&_7rL} z2(oO{>s|(AS#cV!VW5S8r)^s(zr{1PASGus*4c(4Eia?or@J(3XyHXUN1VK=!yw0! z%diwHZlEby+JMZH)(xss38VnqUrPSuZs7gqYF$vuGFj_fj4I+|vWiGbg83j$4EZ!w zbUA8iTc;ujWX%{4tR+(}RWwVToy!K}wW?8F+koT(RJV9V*Aq=gjkTu66(Ncm! zG!QOH1vbGw;_O`4v4>;;I3lcKMaf&pZ&BXr1_0+PJJB3%oef(n%Fu8~1OY5MOLmD) z+1!=6TQx#)d$d;LEmB&RDT*w~8AJf*j+E^E+s309wGXEq?A@j;0W4K{GpsK*)`TY` zujA9kxb8MhqNIvM=wV_dwKlR9IhDJW6M@9Tb(E{mx5Db`3~U6@P=N>F88L6poqD)c<5)9oA}%OUVi18y2%uoT~%Ni<7f> zm?JQ1NOT%K;P9F#-daPH*9mdo;tfWLl02c#Y7+Ne_!sN=Z$6 z(-~8xBYCTVO-zDwQ6*1C2o|N(t0%5 zh81Ow^g^*^iQjS`2sGppb3=jZ+wDN9(MwaQgPrtXmJ~Qkrq9rbJu(PmzTG;mh_TS=CAAJS@S$PrYum$6w>&43& zPm-3-hMTYxT^!;oYDvv(%I978z>r>xt8uHgdGrp|z@b4n3`vpqMV4U7&cT+l>s)w= z^3xv9o1R@=yMCz|u0PIVMNx%oS35Cg%}zR>=(-2{C8JnckD68q#B~x62t^DF;l&-c zAT5`~Fmlk`3caP80K=?~b}UQra>Xz%wTVJdJ8n`%P|7nD&cW7^D03lcKBP>Hw7q%< z$gJnh1g@=<47;fAfQ?XRyg!gaT%}7`xlX$!?2~!w6uEY2T!#V{$r)`=r{x3eDcCDG zQc0nfk97%|XD@kmfoz95)3^Yu@57|yFUp99YD05U1ZqP{%5VZYe}^TztuoCtjuF)2 z!X{m{ql@Q|O_i;z2Tcm2cqcH$@CN-LyAoZt&|JZYtAj=GE3oD40kv=;p|j6`0+j@` z+8K8#i4_SKn|brZId3$S&)?6v|H+C0F(@aHF7dx7Mh;H8@gEM3@5TS#m7kbjp12RY zYB9TS2SFc1!BofxDBLOL18d&NO@G?}lj9hT?|Sp+&p1Mpku+ACjY}jCpWs+cSn;;o z`W*#?7@RHboe2gpIHT7bfgrjEfC#qJLr6z{z#-Io=!c3w@B@bWH81|7FbuRpk+H4t z+H5p~qKG#D@bH>tf~&(6LZMkq!Yvm56`robqLX5SK^7WV=Df-ZGl3IY#f+%P&6|xU z$)03}d&CGGfyGK?kfA}4FBVs|W?RSth$#MtMtk>Rv_JEf=s-o3z~bnNnn{OMB!WUg z6G9fn9wofA-?u{y6(6H0%ak(cV`lD584J252W%~hIBRHa> z5umo2vQcC{4y~wtDTarGD5-&PwSO^AaQm_!ULuf0>%;J$KyTWK9AdzuhUJ68@ki(k zN&?bu+Oo?T$3O-q5uIuDceF_{2UsOz0pLKA0=M;Mqt(FXmsi5%%%!^AXqT&DtyYw0 zU;wS;0tpC*@_IX2L360mA?xe*KL4}mK`g2ZczO?mq!8oC6(yx&$4Jp6^KgQYE*jmZ zDIuT|>nW))ni*Wdio>#bo;d^gIAo zL%rh`;17A{frKJz-#~f9V1mH|59kUWjq7;PH5GyM$HUeNkg(AZRbn}KFe%Y*R2g*J zLcN66_E_AEN)QiI_!r#CB9QV+lp+2si{82FX&0r?JqJ!KIa` z4w4@%J9u1OZ!iPI+a+t^`aZ#pIt9&9Lz6=1s3B(Zv|d8!5CJ%h&c5EF==2vs#}1Fu zOZ1%nBInrkncdY_)SPY+b6ku14zY45Yi5L;t~`0BBm33CWxPHc6f7piiwEX-VUyio zk2eU;4g%oVElNed!8JHL{7r>}-=qXOIjcadr(#3;oeK})?B++B#Fx;sED0#{J|PnL z*4M!Y)#;JT2oI8dF8A0$9G?7cTVm;=@fiHxS{0zQ@?79y|eQ9B_S0bbHZ1|k>y z%K~3EWPYQt=+2HMr2^h4COX_Hrli=@;c04U3D|`V3x-Tkanpq5oB>}BmX3I-BUq!L z8a5qE%3OAxJQ6!sNqKAv@}TWZLCRwl6QflYLs6CvJb-$9!b0>jx2s;rH2xJ|HGq+Q zCd$KfqT3COysXa$rQE{x1U4hac;qxky8v0}TQ$UC>J;EayF^#C#LV?!CSYSQe9|Zx zkt75j=1okHt!rg#cpYtKMd&S(qaw)GwIX0L9V#OK>Krv;zOGd*k{gj-mp3C1M=?U3 zdkr$!iHha8y?2T4XW{4G|Da;P4KM;+=kvdVqX!PA?*APd-;4jgE5A=+{I`9u??Dxk zC9Lfv5L{LexS(SUIN*U-WgIy9jFHsjGlo**=W|A$b4H$XMxGN!o)bo%6Goo1MxL`q zp0g$#iVsK6P9P`OZT0gPB91AP3KN%3#$aBaRBxy_4^SOjEd3F~#idg*U|c%Y3K{4B z+k^PI=p`QAZbqYHM&5r!Ix4@FFCHCfG&ocW zJ&++CJ*l8{^yY@8qr`y(rrQ_zLeuRFGK15RM#T+KM~OLu)CrYLcBnd$Av<85QW&KJ z*QrmQ0Cwsd7MwBO?tW0a>_bkwbB%a*8AZBP% zYj(?g625^^B^x7*vM9JjYe=`6rYUOM`4eC zPe<5uqU)*1dUjMjmqb}X_0l2r+<suV@a6kZ&+}&v&e>J8f_UylZCEwJF%b%FbW(AWD4f&>QFGxf|G?!83Wc`KC@JO zXq8Q=_m7H_Wam6PKNM_mu??!*veyXpTV4A@;P?!zefaenvXGGJ zVprY4p4zsf_8`Yx#Z?y#XAd!~ zc;%B@)M9HTPKJU46)Ox${DiZPWgDRk$4x_v)D-5%3n*a?xA2?TJn09ujW%f8Ub=OP z^k@zs`mXGLf~!}J6jR^h>6xxkA4KwP|h;FCSQwNE5*V$3MHZY9nteQB0m_B z8z%|py`S=mWM2G({Z!UUGrCm5}+7sCvB7u47xVtTEin z$$Bkr6$|A;X?AoDDP1U(41^`2qIE7o@>sO)Oqg24dCYornQnF9P`67TL3Q{84+O(c zE>1`LpIm%sxZH}8mH|`QlnEMB#8o>ha+Evsx1=USpbT0eWdBeoG&e*ok(|GA{ zNCsMRanVR0N_}$|9>*llSVgwk*#H&?l#paCxv8oug&rL;DaTQD+D$xa;BAQftXDP2 z#voDChz_+I7EXQ;+kO_D6?xZOvqY;nf}nKiM8j$6)d>eTt+Ep}X{4)FkOGiF3}G2R!aEA#+&O%6ux+|a2uE_$Rowt=tm`tBwXg|q zwPc&jGPn|;lub=69WsWBK(LIi<+4DD4C0H$CTWh6k{dPw(i^pnXz@%&mKV>D$r z1b+@QYC_Bl;)fnGeOVPC#4MSO=k7xmEh>grEo3Q-jY5aAnSv+eH2@wR@yY+ym9WV- ztu9nyR4uQ>Pp#J0>W%fMn@Ov^aq05rm4X&;X~)ZcQl7?o+KELTI>NQg8a~kU$asR# z@E~UpgetLLrLk3LHNEZ3ip_0KOtkwftDQGy_tUI%)b7;AjFklbhefM@23%S18UFzGPXEK2y;X;vtHqtC5Dqa&Scp#@BXJ+9NvbVkNm%r|Gq zIE@U2TULmFwLOOQS86Us)Z%6Zu3;a@Eu}okMPV%D2CI=(J@k;NLoox$_Cl)$f7ugaRrTulkUabAAM7&1`YSj?e1xoOz84IKKq zDaNs|>~>YmzCae=XB*MF*TvA>m^N)A`KKpdA2-Ozf}L)XG2l;Iwc#(m1 znzn-5&pOuSsUiaRX@8)3GqV|WPX|O7iPCaf7`&uqxE^k{F@~(n!g?A}LP`4f@w*m0 zx7CQVI4)a}i>gd7DNI>0esZ;3VVZ9Dp4CWG>FmYQe z!9`KWMW}xtjqlh6%jTXPF@C zI2SF|gd*HIGf)uK>MT!m60>4HRM>I-NveJqa0(6B<4836trbC-wWcfKai@+|c37VS zt#j4DkZ7kk-*0Ua0GCNukahU6(^h7}?M7k1knfPLaK^7x z$aRO<4h)}yhd?+i9Lg;3a<_{G3YOW9whI>xHgZv>Ui6=&_IQ<<=Y(}t6*Yo2mr`-> zC1+*QXr%L{j~hsmy4NpOy9cjTyF-_%*_)z4-KHijl*6Tn z!spEjoz3GXPtTt}`sj)Ilc#4+eEGz=A*sxH{ODg;ALejoL(%auD7=4cbmHK|!{d_^ z4-W5P$!Hv4 zd6RWnye(#SzkwlIcAT(qrW7cVqU4}1juVuGXToOq!Qe~t^Jg!dJ25~1;BdgDi-rAP z92*-SKR7lrKKby0iGv3ZJUsGnp)?d^WKZWlSSTrScBp718|LW46BCmMCniP?jvpNP z;(-IBlcNU+=(a~NAH=11<{q=%Y~rI>m}!Wb-P!TmeJW=EIK^SYtEjZ-VglyNleQ)y$*nCm-jiHhQ*q%E&8cC2-e z9tdQ{#&R9@UyE#%2J0gHg;miI5w`7`uzEg{C$hzLZFU=|21>gn3mrFr=WB*b619E$zqCJLo1`{U!4W&Ac$jp|JrIX-=Bqm^unP-eAg;j-}+$S?uHr z$9sQjP@_JTQ-h-a+TeM71^4cxDPsM$L5neaR9>-nw`P&6^1Uafi{Gqcr`LySgDCru z(e9VjSQhv32|N2%Lm*NKl)FwCQ0O2rwo`*wO+R;74SE_vx17O<0o(-0g00}OE8MP= z;8F}gqRVlDrpEkHmc5WfnOjk8Hz7hJp30L|E`q~dL0A=mp@cKdK0WnhWz-WMDkOTa zq$d{ljb%RE#bU5%)hF!PyqYy{Zwuv_iuNtM)^jqhG7<4&*|_eubdglpQMgzxlS@x7?fZZnieBw;^ZPPZsx5aQE_XH1WqHAQjPWHV%-1%k9 zhE(H{v40ABiMNosv=5w)j42(9qwPoP(h>s|nJH`G#G1ttt{6Cf&R9}&^p(8k8jALM z(>3n@v#033AoGsteZ2^=cXN9uXmbyVv5nedj%8H&IOUgk72s_pFS0Y3E!TFJd>z?W z!cE=F)u-TV9~kBkesyM;J(yo&#M{Me4X7W8-f05mXp&g1nx+;}deJ?64TLR(u3{*a zBd*t@<_u-C@pQ9pm#hRgdwQp^9Yh$UuTxj5zOuUNb56GIYJ^rQQt4;O4bz2nr>pM0f>y*mTRVMdo&e0;Xj{_ z2Hqh~(FbSXBRFmAj)p}jURier21mr*fr45(D%m3l6%8XexJ%62qIrUP74}7q`Gt5{ zJSA%(`JTy49LgC*#71kL0|D2f`Nk5l4?Pv;X;-a_wd=^p^gE6S{T8uLoRPwZuUA1B zOj?b#v@hrayaGeKtT`K*LZ1ycYYhyhNPz_?HW%7hxf~}6MkMh#KQVm%J{!+Xm*u=BH3iq@>=I<1DZ_AKe$TdnLjFa>fFiZH8n>7f zG|{*UZO1=^Bd4*x-bmPmI$rBgL@Q6q`&d;(WttIM8MT6oREFJBQQv`%N|+t^e6$hO z2_+$vw^l;os}KekF-G7;)o*2w&W~}bZ65uUc4^9QqL)5RyITTPFQ24pitG_;dC)Kd zRzRq8;U&sXzP{dc%ZZI!NKTXRY?uz@W3UX;i1PhOj_PKx1Gx5iZW!>mTtZdj)Q(<+d3DDbS%P&un<;PFNMuT+}*B0!FVCA#jQ=PT2tnKPQVdKQ!(7_9>rp) z51m#5o-k{iF3Um0v9d~lrxyYcu;(H~wlc34Cv?%SC2EaoSc@`B*a|~oJYOX0%c-Df z5m;uFOk|Ea)&dm#G2K}`7#E!^h}jn1b*-1qQW@WUr&4;Q z6w;;qVU}|z9zA*b#Ca;Dzjz#gaXp-;)lk~_=*cn^up0``8_#N)cC9f1dJ6OgM(uZI zm8jrbvJt;&{x?H}GUmiAt+&)hZXRv3pcZ#7C$8hbmMJ31zEq+Pf>i@<5qGe>mZ{Av zSE*j)UB=rkOP4}HMie@V5l45yQsj}$7{8w2khUeNjNgc3n=tXkZj{Z0L1oCqNGD(j z7?vd@je6Yr0>%%Ajfo2E)>>)9!X<|>>=rvP7B{{Z)IT~>lCjFn_>d6?WQ=MY%S>#l zfZptB1;S5Wie0;j=n$) zeL?$j06Kv6;(65V6vv={MhYcSfWqw-w5P4!F-Szig@o=J0Ahu(gpz()j|7&o(y?x~ zwgKSXzWWn@^8VM2iDBN?Cd2J3<;6i>|JvpL*O8IYgQM>KuOnk)d-uQY#;?mYt$d@a zby=$z_rl>{Pt;;bZoUi!NjeVw<9Olr-qq3f%FlQIGsX^1Om=_?JKzYN=l|%~*u+6+ z{vVu}nB1HHyYUnAe@oah!Y&H>T3zV85#wt?-Ox-N;)?iqrLhP@1_OXlu<3#rFd#>^ zuM~y?9qsH&nKh@yD?)dgl-pN|rIO)|5NoXxND^1dyr;u>+wvZaVj*M+hY>9rC0Ox$ zpFCn@rB2SjfTmAihYrPO|3L*-3F zSIQW`wm1u&hyhdzbKM$D1@kqSBlYKpVYm1Tc8fQ{W*nmT;?wQTcrjd#YhiN{TDTA+ zIV2gN8CRhdUoczTYBY|;%l7D93ojQ(N36CUFcIZ4otr7n)(d&cIi2~{_F@>UhAmX) zD%?dpv%^P5M+y%9=jq_yZUM-@b_?7FP@(QkAfo`c5gBE@&4{Zj@oKsqQ*Jv%=d*Vu zMclC`T9bnC3}Xz_VT-?rg8TKfbqACIGvCl;%ZHvp8SOvLMx;fw7g?w^>hW?ItTiyQ z3*HO?Lo#ZHtJ&>8ukL7YxQ%gl15%>U7bP_G!H}a9JP%F2z^KFAtl?9$r<7*y*O@7)e#d>3qa@QI%Y0~9>Dl|emo$J=PDjHK&QvhQs7lt-EUgd zoZBd_4pU?cb)?NcL)#4WF!foy>#@Pk3DMFHvby0EFq=qJiwLFnkNP5T;sC?s| z>hcZy3>Z1qWS4cra-fu<#yrOb=zul1Aunvu(9J77xlK6zE=pOYeIt7zsx8Mmh0$p; z$R$QzUw5TUCw4_mAztCEd2a|Qp4EyqOFLNZG64A6CT!ex3Z^58ECzf+T+(9?B7Joa zM)>Y)rI3IJvrc3~^R5zzwOAxt?d8zFKv)%=6cLqeI_Nmdv@7b15EAlW2$2oVO9(<6 zR+9h+#FYRgDi9|cwTv~>rukYJ*PL;INkuOi=u?Ld#Loj73w}@;(`mKUL`#Q8b)^Mz zR9L?PJDBY0aG~k67*8y`?S&87C<2(lwABm9*U}5;9_uI+ND%~E$BOQ}5(4LzVuE<< zC@TyFiaF-5@QX4#zV`;=RAEWVC-x+p9#d* zxb*g1t|AyuSB(KY9kJyh)ijZTmP)tN@qh{76le9qIal&6S&(Tb3#YfZueqCzEA5S) zf#@bxfRNH7=|B)0OOZ}kC@2ala~(~}AtSAdX^VCm`VbVBblMzOk`}6RQQt4q?Tqrh z0PxWrImg{rlYVA@j{e_N`VZ^`u#5hGW#}=gRGqm8=1~zmiLlbhK-`fW*OETx+2uu9Pz+#lji~XNK6=n%}sgO z%pnrf1NW-B7wv&yYr8b3!cG%h)!n2GhK38RinweK_Y_Q2?}mYMkp<+OkyRsTfP) zUzw*JFJh((Cm%6VHYP;c#)O$VDN`p!YCWtss60Q2)MbYGWeu~+Dfq`o852okvW^<# z@|Y@jnG*g&y{{$==+t=)8}A)x#b_T~IC=g|kc9Ox*ueik-HMGY#%Gag6vE6hZ@U>{ z4~j2~;YMRE-mJx|;(NSK#5s9(V?vNyf0*PCllF(T5Ox`b$B!PjldJJ!Q-fNJ!}ah= zqi%jw;GB=rLbD+3+EyEjwU7_=!dBDD#6v(m`?KP8-1CyH6!4NU^J_Fpb)6`~UvZ8m zie19_`PHw@NP0$V>ouVCJnT+jYS!#QyKTs)c+!_OQMy?2=bSY#9-;cv;b}QgX@dw! zW&;FkE3BdO>xO})v_&UT&@lRyo&uE4qN(->Co6wzSEOzIbyO+Qj3W*WW*MaXPCUj= zI^=*7k*(#4G_6dAg9I057mci4fa8iuQ${qNA1&p_ zjXKp6DB6S#8BOoDwsBVrMqNw;xhYEz_HYs1OXNVT*4i-1 zBJ`Cxe1u$O4j0^knb4ZeHxi5Wn~U?xTe3$W=Pr2$n)g^)jwyzPgS+r_you_pZTJSr zZp$376^_^1Yep<>%)!;+u}sT&Me)H${=uV=F$T3tqK6)s;vSe9Ob>V`yZ=nwra-FI zalLQCr>FjaFz7P(g-SF{{CR>X>F@ZhnxY_kM%$F-!etSdKsept+4DRGlPF~I5L~t? zScfRjuGia{C(swW)`~|fz15ktm&`h?1C8$W$s>&1)yV?eozD%r*Gz(TmufX(@rIlx z44+O`4_&$P{afy)Vb(&-5Cb?NYcRS8`jsvflN3}@b73*wh?7QhyW2Uw!}`O;8KM1)2&V!qcQ^1RaLe06#th2BqN^P@nYlJ=b+ede`jRqmxaAU}_r!JO+G`(Xd z0!#llE=+%kqO?s*c53^Jzb^Lw2gfJJ9R1(q!2=U}`oG=ySnN5l&I)%tc?B`d2q`0pLkCPE zoXT=$mHg)pC!TJHwPJzIL)O|!O9pKWVA-lgAtX!$g0mEpl60}6@Jm+n!pr?OkIsdx z<`u$ZaS3^_^>>#V4XbP`7|YXU;dRzuv$^oS)AHzYSZ&ody)7R=lkRpCjLx%t2J`fu zvVIUPv}YqWurTQ62~#$2`z8YPGlu7=*{zehV;+Y00PgAD$;&RaonMMe?pnVXoHA$Q zaxzQHh|z5vPAmHVZncpZW7j4Mqx8J}r)-dyTM-%|8ciGLG+FZ75PaR0$4uc0C++sbELzn>QkK^S7B^F`As%^^21?fHYyHvr-%@5S}a6R}2kXkk=9LPu&PTM}IHgx&8M&+`)Jv zKZx$-W9U?;INiR0k$$r}{cwj)A5`ah6%@n0@8f$^Qe+N*jw*+{HpM?9Gx_c*Y&!LK zruyYBP595+yzWIDXyr0dsIVxDrd7GCbVJ!=kj>g1Rl@mRT1TQV7QRT# zi#l?zSMOS{_S&gVpN@a_`joE8=)Y6%dY|^JVaKI5uZG>%s~z>__x9R4o_}q%dik(B zb?;nv)_P^Uy&RbAb?5GPXRp1vBaVBocczEg?z}g5tuuG^;IF3zb>tpeP; zkl}?G1k&jaxZ`4@UPCkYr_cpu;*gUZ*D-nANnS_RSP?8~FXsQf`SZp9S3F=q9H8s` z9~*b(|AEnwz4^Z@KQaHUc`w2|$k~pIy`19sEavqj-LcAdukE9YV+qLKEdNyfJoo=> z#P`7cKO=kh|Ln?d@BW|9_b(&jQY1pCw`ucZlJ&Ql@H#2rH+ta^%te7zyAgZ&<-}PztnJ| z^ud>Fe-#GRl@G4{B`1Df1N7CGufMbzEXN;Q`{&@~`7?HSKK`haMVVA?9iVS@rSZYr z|B5zgK-zzf0dQD1a*9xW7WpyQo*l5y{VYkR;`1#+9kE$Z1?N*=WEmBiue#Fy;M$Mk zVD0+91}oQp6N)dM*nAl|(RGD0+tK-Cc8tFGB zk2-oUM&F%|(f7Z& z|9K5^S91sK>j42Pcwe6S1`)k)XEfVcOuw1yZ*3Bz`fj~jMQa~i`!Ps9O-!m@f4K_0 z@%qc~4!rI&6Xx%~x1mYU^na?mL{5d-)2%PKG30s;{zvdkX~)-7{iF8TiULSMm)9X%I#^(TK>@qh zzWTx2e*~7aa{cXUx^fvcu&)S#Ia(ezg5?jc{oR^3a$xVl0duq#(*9{Z*noeL8^8U( z+Ue+l9>&poNWe4>eFq6Vk0NAtlWNyrf{wfP<2WE$v--icSHe^b!9HRHo+7zd)T~NBvG?P@lXzL3e^J?S zW+`jpcMJycDV)q^n-6bH6;+fYnM4!&(=(}i_<7F%HyiiB`TywN`oAl`z4QOi_b=o8 zA9%p-o&QgcdG7z)JOAI6-`@FuxAXt&FRdBZ|JAR*+Ue{+@#l08|Ldz^-JjDw_0P)p z*+1_8;O)2mJ5pv<*NyL&^%^ z`b*0T*MExtc})TA&nbHVY#5D}|9A$_d^HGzRc09G*`zG2XWQhCh<@>Xuy3goCu9U~6proa4H?!-Lc`ZEamrOoRv)vZc4!+JpN zg~b}{YKFN@0PcAkfEncZ+?h{Zf6FH5Q^e3|N${Mz$D2`3TYwIy%{`#u2c0$G?tue+ z54BHS|5+2L`BXb6q4OQ==b&%riv3W#&E>m%T>rtf7uAw&&er7xTG1B8vM*L({1-+T z{;6Gmdtj&b`H+AG2uSX$eMiUk`6|cW9?YSAPKsZD85Rg^Ec_n{AFSm&x<6`w+|kW` zJ)YX1*3w;etHeyX{!>^TV4}VX|F461?K{5j`TYJERMEQri#qObUcx;N)|mUmzK0`w zqaxi>93XWVl<6bzo{sD@mgqtTnC#Q~lbca5*kzs2cR+|o$vtp3zZ*Y~{{PC#{^O^2 z)&D=O{~sUO)Bo?vZ%_aK`Tk|-|CtBuivR!U$k@cBJO3y5?*H7K-=6-zoBsdyt3Ueq z7yquc@V8%l{`U9(SJoi_h!FFyVKA8j>1>g8|$7&1Yfrra~z4MPa zMSt>79aZ)J_0Eg8fBFA@^5f?}`s;uD=m)>ct*Q6dWa#Dd03L(~UssHFqJw9cpFH!I zupBCwA71;n58wQ&58wK$58r&|Gvj@S6Z)BV{`|-9-2R`hnAA%t+96jS&o+;j-G^`f z{Py$T`uMjmd422#jlieOwN5wxweMv$e}|rQcc{vH+l`KAuv(0vowxt^{3kD8gGuaB zy9c-5dFJ;2{B3{Q_k2}J9eeQcwZFUl+Pi(J+Ouk6IekF-^{h%hy7uy)fA^b@Uj5hG zFZ>uJ-9Nwk?(KKJmrJG25O<_ZH%C}^T{>6DvWmw4AAXh6lLsIF<8!y4`7Y$_!{P1r zci#T^uV4GNlRtERZ?^cR z*_~5>PMJRk2LbQAnLY^k%n{P6EmM*u;_89-p? zw+;aUD4@R?rvL$ta^Eq4{lPj12tNMRbGLu;UEe`~{mD5A2tNM(Pe1;bcVHHFIS24% zOrHV-)_3y^Ao%F--$Yeb{zCvg81LpGz@Gm84(jhee(q)11;d`6I~&Hwf4%dMpS<*a zm>C~`^X+bm{15-|?T>!&yW20kmRpP8r9NAo-x>Tsb@^TK+KEzM0srLLH(`M@A+u`# z_Vd5{@Xc30a|(WBH=jKF*Q{UXCTHu{Kl;vJGNpUh^WT2vuR7}a?+6~BI(5IK0_onp zRLE-lPPP7ntohzl{&!@pydn#A@Jlab90Yvw!@v6ErB}U_?BPftU#0p;;EnJ1dnAxm z(?E{|vMNDSm+!yu(M#{-Jqb{Nc4k^{4!Q290jg4*0_s2ju>a=U*#`n|_HiJ975(P# z|NQDd+_STpRW49iHXq(NB=i|U@!jH?)+^1 zpOV|P-cN<=!z@Q@F)$Nbna2VCh8P5lp|fg7=K-QMe0Ie$-WZg3O2+lY=&}eCh+jZ- zJO!Nh@C>T#W?*~T!gW3f>zly2f#1SbYzBCDJ=(xa2L-R8k`(ys(Hbs-^@xW$fKd=c z)rSGnP$2)A8VW8zJ-o5O8WGY=!-jHLgbAC$+*5X?{`@XfW@EUXGFp}3!tC53px&l>(8LjtfN7OtZmp|TEj3m4&%z?%lsig2hEF7j@pyH?rIEUC( zRrLN!r;Cee4SAoxIZ{C-Ehlik)UsajE%i30v^G}UwbIU`)i+Lx57zu*oK$g2)Wa4o zErkwWo$^t=y~dkuqnJ)~a)-_3Hm=Hvky)iVd3oh?yTwR#@(UfH`Re3Q3Nkyv$raau zPDw;-HPvGxoBn9@_Y!PV_zDvBQZPrT$i1|cw%Y%E_oJ5R_)aO)e)_F*% zy;-S~`ncT*$H#a;4**RuHC#;F_0@XgQr*Q-CHt|vV9Z`*T06im#RwP`W)s}0*x4Pa zbOERE0BA(4K=Lejl&o4xQ~3~i#AGFd!pde)jALURrzqg3min#;o`Cs7JD;w2>9OF< zy+b+C)(q0Y);pOyVtrJy&jCidpQp!^xm*~1lEHA z;DgJGQ4=v|RvSHm-|18-K&1@b&jtNhz*tN8m(S!V1rN#aL7b`KBWpbHsVcwn!5I~( zi6nUvre5elr-)-MdWqK=O1#*l2N50$AD_C^GLi&>TVfStEsc3111n7r)2^JcSS`^mh+7wn>(@vt0km$Ufx>blZG{Oivr$#M%*l>k~4sAXb z?}Ye5SQhPN&G|jtUNPoQ8WJ9InL+T?wA7e|#OX%saj{1@v$TVnoy~^m0|nXB4Vm~n zN`mYTabamVtCr)mAKO6{yrC1kDr|;p$+WeJT$LPWu7bN=y?eCy_#;srHN7Bs!!h#2N4 zcda+S=@s{C22a15=B-y<)^oM{+`O7GbFO+u@KtBL`Fl%rkFVn%kV=fO71lIsvKK^S z`{i5fY*oe6?M5rALGG_6xF!`F3s2D~CF=%Rn9zgnZ#R)m0&;wM(Nd}wTTL`eik)(~ z41Z_m=7MQCkWZmHMW~NZm*Rmmdunb9SM7?ecA7PytV#wl=Z7FZrocecp!fR3M(w+t z9&=0hl}_`Ksd3tde(XTa(~bJ+cCChnU_jX^pMK4$v`6)t2W_uzO^p=1uR@8sP~8y% zt7>IFBt$qmxvZ!WEcF4)kuWq&@C3sBN@KCvt^#u?rXh$EWNz`o!I!mSsgWGk)))n-JB9UoE%N6`f7VU^@tONv4{B}Na_%IQf!AAnlM z4uZrBb;xYXz(_tZr+uH|dc~tlE5GMB zi@v*Ol`2u3YW@H1U2SvJHW2=vUtuzQ2yo;e1wJGJhK7`;P?8~m(q`y!1c#V9cd73# zyd?SW)xPLmvgNyj&M>(dh`rM8O0u+C`B}-G1@H)`#I>4$ty);C5!9Ly)k?>-Y7ng& zJZpA9s}-CT1haxr);zGRmPnS5W6cU=wSci|K&-iL0X56sKv%7St6JDk6XjUSYRflASah(9FGY3p(dJroK!m0zX{`YE5iCs;LT+Iw!wF0gh zV5^yMt5no#de|xjw9=532UQVD)eKXmLsX`Xs)wl1$OXJ-hi8!i6RtxyY`09Y45>ksCdZKw9-cCjKYol9qccmY1!7HyVl`k` zq1TA^qT7P5;H{;FT~YUkd><(pHYV%MlaRTCo9jE-$~EmIVeaKBKPkmHTk0+@?f<>_ z=Ek+f)$WH*ws`gS>f$vj%50dJ(Dx9=O(F(`bG`?O;hTzwJp7U%G2T7oqhbq$Rktn^ zNmDDiY0$CRu(9tCj;T(VjEec-k;n^`U9fR6`z(m@Q88L3R($QGHowPlG8qRoIms*j zCb!!5c`%;z%bjXC9t!1y{L`{@Mx#_)+ad3M@#e}}Ae(T6z_r87 z*aCjL+{|vPuN&!3cSUl#>NBk5eqMrQSC{AK?jTunxP&PMx$K}r@o8H(uFHHSBKr)Q zjE>+amje`?*(@}YmCGE#j4qeJ0l4TVnwYe9N!OHF{hlIt+Q|mlx1cS8k6)z2+Py5;b_BD8Xl2oNAQP?=GDUk&s>?jvu3Xc_M9%u zR*lA+FzLzc`?t*b(J1>q=Y3<(*qSU%scF$ec`Vy0G-}J~nQYw#HB5%1FOMZK7&~Se z$grznW(JN02AJxV#B{OnZ34$;j~uIy8*7RhYX}>Q1&!GuW8WZV%ze?5{eUrI&iSu+ z4CmL;;dhMxx_$T7%3Ux1>(1r*&)?AZ74(uwF#Kg~yBABj9?h5vgJrNSMCOB?jN>95XyiF&#dquQ2I{aJ z_QyZb9!gO{zMAMu%)px>1(mNR`jUY+zI>k_6vudkLb%?fK3Z>HV!SUEq8<~VrpX#9axyb~0Tgo||2&Aw z9x~q|0ks2gJojoU3a&!DrjS}w$Vb8xiSddFoH)DJuV=fH6JQ@@*Sld!fNrgC(iv7G zCDVcVAS0u1bZlx(a=e8gng?5lkIWKouvA=AQ+PG7zJsUMZH@EektH6zXu9ZResbeO zBY+%-yw(7bQ0fMsCQwClP&J`s|KwjxTg$6$ zV6(>aq6{Pjlfm{1D>AI!=fG?Z*9U>!&$=M%MoG+u3KTO$t{D=Tlbcs&ht`$XvN3~& z+nWfxv%Y}SVf~Y*JTG!QUDtd1nCul2S)5*gH2YyAsS=V`Q9csfq1CV672~R3eaZNl z&_j!lIUXx*EsS}v&gkGMKklQ2QGKLwxsXxJ;U3?@!1^^VJ5oTPI4LmWOUk<9H4Z}|2^8u!oiH3^5GW2BQL{PxG5 z%MMZ1X}r7J&w2IliqM~^NE1cQzAJ{-14geAcde$LT|D#J6-y^!OR;p^#_rntJq<2@ff#7v{1HPVTGbPd&7$AHBaSF z5VxvAmHj|Tc6}r9_*1HkRN2(**Ln^`2=^Sj)9?ao1}!?`)*AuVQLR)hFA&|=pXCqoQ~0QH9SN$SK@bKc{drg2dB1Ve&nXOfI5FeiD+r5hJen+MWfn zz7EjPRr08Y0~AXO(S!M=kKi-x1W19FgK63$((LPz#gyvP)Kuvu(bVUWY3lL|!c)px zupeR;yX*N~)04?Fj!&oQ!Y`V#^