diff --git a/src/platform/packages/shared/kbn-connector-schemas/bedrock/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/bedrock/schemas/v1.ts index c0cea8f42b435..87a06adca166c 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/bedrock/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/bedrock/schemas/v1.ts @@ -7,230 +7,264 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { DEFAULT_MODEL } from '../constants'; -export const TelemetryMetadataSchema = z - .object({ - pluginId: z.string().optional(), - aggregateBy: z.string().optional(), - }) - .strict(); +export const TelemetryMetadataSchema = lazySchema(() => + z + .object({ + pluginId: z.string().optional(), + aggregateBy: z.string().optional(), + }) + .strict() +); // Connector schema -export const ConfigSchema = z - .object({ - apiUrl: z.string(), - region: z.string().optional(), - defaultModel: z.string().default(DEFAULT_MODEL), - contextWindowLength: z.coerce.number().optional(), - temperature: z.coerce.number().optional(), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + apiUrl: z.string(), + region: z.string().optional(), + defaultModel: z.string().default(DEFAULT_MODEL), + contextWindowLength: z.coerce.number().optional(), + temperature: z.coerce.number().optional(), + }) + .strict() +); -export const SecretsSchema = z - .object({ - accessKey: z.string(), - secret: z.string(), - }) - .strict(); - -export const RunActionParamsSchema = z - .object({ - body: z.string(), - model: z.string().optional(), - // abort signal from client - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - raw: z.boolean().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); +export const SecretsSchema = lazySchema(() => + z + .object({ + accessKey: z.string(), + secret: z.string(), + }) + .strict() +); -export const BedrockMessageSchema = z - .object({ - role: z.string(), - content: z.string().optional(), - rawContent: z.array(z.any()).optional(), - }) - .strict() - .superRefine((value, ctx) => { - if (value.content === undefined && value.rawContent === undefined) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: 'Must specify either content or rawContent', - }); - } else if (value.content !== undefined && value.rawContent !== undefined) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: 'content and rawContent can not be used at the same time', - }); - } - }); - -export const BedrockToolChoiceSchema = z - .object({ - type: z.enum(['auto', 'any', 'tool']), - name: z.string().optional(), - }) - .strict(); - -export const BedrockUsageSchema = z - .object({ - input_tokens: z.coerce.number(), - output_tokens: z.coerce.number(), - // added with Sonnet 3.7 - cache_creation_input_tokens: z.coerce.number().optional(), - }) - .passthrough() - .optional(); - -export const InvokeAIActionParamsSchema = z - .object({ - messages: z.array(BedrockMessageSchema), - model: z.string().optional(), - temperature: z.coerce.number().optional(), - stopSequences: z.array(z.string()).optional(), - system: z.string().optional(), - maxTokens: z.coerce.number().optional(), - // abort signal from client - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - anthropicVersion: z.string().optional(), - tools: z - .array( +export const RunActionParamsSchema = lazySchema(() => + z + .object({ + body: z.string(), + model: z.string().optional(), + // abort signal from client + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + raw: z.boolean().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); + +export const BedrockMessageSchema = lazySchema(() => + z + .object({ + role: z.string(), + content: z.string().optional(), + rawContent: z.array(z.any()).optional(), + }) + .strict() + .superRefine((value, ctx) => { + if (value.content === undefined && value.rawContent === undefined) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Must specify either content or rawContent', + }); + } else if (value.content !== undefined && value.rawContent !== undefined) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'content and rawContent can not be used at the same time', + }); + } + }) +); + +export const BedrockToolChoiceSchema = lazySchema(() => + z + .object({ + type: z.enum(['auto', 'any', 'tool']), + name: z.string().optional(), + }) + .strict() +); + +export const BedrockUsageSchema = lazySchema(() => + z + .object({ + input_tokens: z.coerce.number(), + output_tokens: z.coerce.number(), + // added with Sonnet 3.7 + cache_creation_input_tokens: z.coerce.number().optional(), + }) + .passthrough() + .optional() +); + +export const InvokeAIActionParamsSchema = lazySchema(() => + z + .object({ + messages: z.array(BedrockMessageSchema), + model: z.string().optional(), + temperature: z.coerce.number().optional(), + stopSequences: z.array(z.string()).optional(), + system: z.string().optional(), + maxTokens: z.coerce.number().optional(), + // abort signal from client + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + anthropicVersion: z.string().optional(), + tools: z + .array( + z + .object({ + name: z.string(), + description: z.string(), + input_schema: z.object({}).passthrough(), + }) + .strict() + ) + .optional(), + toolChoice: BedrockToolChoiceSchema.optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); + +export const InvokeAIActionResponseSchema = lazySchema(() => + z + .object({ + message: z.string(), + usage: BedrockUsageSchema, + }) + .strict() +); + +export const InvokeAIRawActionParamsSchema = lazySchema(() => + z + .object({ + messages: z.array( z .object({ - name: z.string(), - description: z.string(), - input_schema: z.object({}).passthrough(), + role: z.string(), + content: z.any(), }) .strict() - ) - .optional(), - toolChoice: BedrockToolChoiceSchema.optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); + ), + model: z.string().optional(), + temperature: z.coerce.number().optional(), + stopSequences: z.array(z.string()).optional(), + system: z.string().optional(), + maxTokens: z.coerce.number().optional(), + // abort signal from client + signal: z.any().optional(), + anthropicVersion: z.string().optional(), + timeout: z.coerce.number().optional(), + tools: z + .array( + z + .object({ + name: z.string(), + description: z.string(), + input_schema: z.object({}).passthrough(), + }) + .strict() + ) + .optional(), + toolChoice: BedrockToolChoiceSchema.optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); -export const InvokeAIActionResponseSchema = z - .object({ - message: z.string(), - usage: BedrockUsageSchema, - }) - .strict(); +export const InvokeAIRawActionResponseSchema = lazySchema(() => z.object({}).passthrough()); -export const InvokeAIRawActionParamsSchema = z - .object({ - messages: z.array( - z +export const ConverseResponseSchema = lazySchema(() => + z + .object({ + output: z.object({ + message: z.object({}).passthrough().optional(), + }), + stopReason: z.string().optional(), + usage: z .object({ - role: z.string(), - content: z.any(), + inputToken: z.number().optional(), + outputTokens: z.number().optional(), + totalTokens: z.number().optional(), }) - .strict() - ), - model: z.string().optional(), - temperature: z.coerce.number().optional(), - stopSequences: z.array(z.string()).optional(), - system: z.string().optional(), - maxTokens: z.coerce.number().optional(), - // abort signal from client - signal: z.any().optional(), - anthropicVersion: z.string().optional(), - timeout: z.coerce.number().optional(), - tools: z - .array( - z - .object({ - name: z.string(), - description: z.string(), - input_schema: z.object({}).passthrough(), - }) - .strict() - ) - .optional(), - toolChoice: BedrockToolChoiceSchema.optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); - -export const InvokeAIRawActionResponseSchema = z.object({}).passthrough(); - -export const ConverseResponseSchema = z - .object({ - output: z.object({ - message: z.object({}).passthrough().optional(), - }), - stopReason: z.string().optional(), - usage: z - .object({ - inputToken: z.number().optional(), - outputTokens: z.number().optional(), - totalTokens: z.number().optional(), - }) - .passthrough(), - }) - .passthrough(); + .passthrough(), + }) + .passthrough() +); -export const RunApiLatestResponseSchema = z - .object({ +export const RunApiLatestResponseSchema = lazySchema(() => + z + .object({ + stop_reason: z.string().optional(), + usage: BedrockUsageSchema, + content: z.array(z.object({ type: z.string(), text: z.string().optional() }).passthrough()), + }) + .passthrough() +); + +export const RunActionResponseSchema = lazySchema(() => + z.object({ + completion: z.string(), stop_reason: z.string().optional(), usage: BedrockUsageSchema, - content: z.array(z.object({ type: z.string(), text: z.string().optional() }).passthrough()), }) - .passthrough(); - -export const RunActionResponseSchema = z.object({ - completion: z.string(), - stop_reason: z.string().optional(), - usage: BedrockUsageSchema, -}); +); -export const StreamingResponseSchema = z.any(); +export const StreamingResponseSchema = lazySchema(() => z.any()); // Run action schema -export const DashboardActionParamsSchema = z - .object({ - dashboardId: z.string(), - }) - .strict(); +export const DashboardActionParamsSchema = lazySchema(() => + z + .object({ + dashboardId: z.string(), + }) + .strict() +); -export const DashboardActionResponseSchema = z - .object({ - available: z.boolean(), - }) - .strict(); - -export const BedrockClientSendParamsSchema = z - .object({ - // ConverseCommand | ConverseStreamCommand from @aws-sdk/client-bedrock-runtime - command: z.any(), - // Kibana related properties - signal: z.any().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); - -export const BedrockClientSendResponseSchema = z.object({}).passthrough(); - -export const ConverseActionParamsSchema = z - .object({ - // Converse API will already be validating, no need for us to strictly validate again - messages: z.array(z.any()), - model: z.string().optional(), - system: z.array(z.any()).optional(), - temperature: z.coerce.number().optional(), - maxTokens: z.coerce.number().optional(), - stopSequences: z.array(z.string()).optional(), - tools: z.array(z.any()).optional(), - toolChoice: z.any().optional(), - // Kibana related properties - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - connectorUsageCollector: z.any().optional(), - }) - .passthrough(); +export const DashboardActionResponseSchema = lazySchema(() => + z + .object({ + available: z.boolean(), + }) + .strict() +); + +export const BedrockClientSendParamsSchema = lazySchema(() => + z + .object({ + // ConverseCommand | ConverseStreamCommand from @aws-sdk/client-bedrock-runtime + command: z.any(), + // Kibana related properties + signal: z.any().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); + +export const BedrockClientSendResponseSchema = lazySchema(() => z.object({}).passthrough()); + +export const ConverseActionParamsSchema = lazySchema(() => + z + .object({ + // Converse API will already be validating, no need for us to strictly validate again + messages: z.array(z.any()), + model: z.string().optional(), + system: z.array(z.any()).optional(), + temperature: z.coerce.number().optional(), + maxTokens: z.coerce.number().optional(), + stopSequences: z.array(z.string()).optional(), + tools: z.array(z.any()).optional(), + toolChoice: z.any().optional(), + // Kibana related properties + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + connectorUsageCollector: z.any().optional(), + }) + .passthrough() +); export const ConverseStreamActionParamsSchema = ConverseActionParamsSchema; diff --git a/src/platform/packages/shared/kbn-connector-schemas/cases_webhook/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/cases_webhook/schemas/v1.ts index f6a6823f671dd..bf80032aa392a 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/cases_webhook/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/cases_webhook/schemas/v1.ts @@ -6,10 +6,10 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AuthConfiguration, SecretConfigurationSchema, WebhookMethods } from '../../common/auth'; -const HeadersSchema = z.record(z.string(), z.string()); +const HeadersSchema = lazySchema(() => z.record(z.string(), z.string())); export const ExternalIncidentServiceConfiguration = { createIncidentUrl: z.string(), @@ -46,44 +46,48 @@ export const ExternalIncidentServiceConfiguration = { additionalFields: AuthConfiguration.additionalFields, }; -export const ExternalIncidentServiceConfigurationSchema = z - .object(ExternalIncidentServiceConfiguration) - .strict(); +export const ExternalIncidentServiceConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceConfiguration).strict() +); -export const ExecutorSubActionPushParamsSchema = z - .object({ - incident: z - .object({ - title: z.string(), - description: z.string().nullable().default(null), - id: z.string().nullable().default(null), - severity: z.string().nullable().default(null), - status: z.string().nullable().default(null), - externalId: z.string().nullable().default(null), - tags: z.array(z.string()).nullable().default(null), - }) - .strict(), - comments: z - .array( - z - .object({ - comment: z.string(), - commentId: z.string(), - }) - .strict() - ) - .nullable() - .default(null), - }) - .strict(); - -export const ExecutorParamsSchema = z.discriminatedUnion('subAction', [ +export const ExecutorSubActionPushParamsSchema = lazySchema(() => z .object({ - subAction: z.literal('pushToService'), - subActionParams: ExecutorSubActionPushParamsSchema, + incident: z + .object({ + title: z.string(), + description: z.string().nullable().default(null), + id: z.string().nullable().default(null), + severity: z.string().nullable().default(null), + status: z.string().nullable().default(null), + externalId: z.string().nullable().default(null), + tags: z.array(z.string()).nullable().default(null), + }) + .strict(), + comments: z + .array( + z + .object({ + comment: z.string(), + commentId: z.string(), + }) + .strict() + ) + .nullable() + .default(null), }) - .strict(), -]); + .strict() +); + +export const ExecutorParamsSchema = lazySchema(() => + z.discriminatedUnion('subAction', [ + z + .object({ + subAction: z.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchema, + }) + .strict(), + ]) +); export const ExternalIncidentServiceSecretConfigurationSchema = SecretConfigurationSchema; diff --git a/src/platform/packages/shared/kbn-connector-schemas/common/auth/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/common/auth/schemas/v1.ts index dcc324e941df9..ca8f2688f668d 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/common/auth/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/common/auth/schemas/v1.ts @@ -7,22 +7,24 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ import { i18n } from '@kbn/i18n'; -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AuthType, SSLCertType } from '../constants'; -export const authTypeSchema = z - .union([ - z.literal(AuthType.Basic), - z.literal(AuthType.SSL), - z.literal(AuthType.OAuth2ClientCredentials), - z.literal(null), - ]) - .default(AuthType.Basic) - .optional(); +export const authTypeSchema = lazySchema(() => + z + .union([ + z.literal(AuthType.Basic), + z.literal(AuthType.SSL), + z.literal(AuthType.OAuth2ClientCredentials), + z.literal(null), + ]) + .default(AuthType.Basic) + .optional() +); -export const hasAuthSchema = z.boolean().default(true); +export const hasAuthSchema = lazySchema(() => z.boolean().default(true)); -const HeadersSchema = z.record(z.string(), z.string()); +const HeadersSchema = lazySchema(() => z.record(z.string(), z.string())); export const AuthConfiguration = { hasAuth: hasAuthSchema, @@ -97,15 +99,17 @@ export const SecretConfigurationSchemaValidation = { }, }; -export const SecretConfigurationSchema = z - .object(SecretConfiguration) - .strict() - .superRefine((secrets, ctx) => { - const errorMessage = SecretConfigurationSchemaValidation.validate(secrets); - if (errorMessage) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: errorMessage, - }); - } - }); +export const SecretConfigurationSchema = lazySchema(() => + z + .object(SecretConfiguration) + .strict() + .superRefine((secrets, ctx) => { + const errorMessage = SecretConfigurationSchemaValidation.validate(secrets); + if (errorMessage) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: errorMessage, + }); + } + }) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/crowdstrike/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/crowdstrike/schemas/v1.ts index 9afb66cc587d4..acfbc0ad54582 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/crowdstrike/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/crowdstrike/schemas/v1.ts @@ -6,366 +6,396 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SUB_ACTION } from '../constants'; // Connector schema -export const CrowdstrikeConfigSchema = z - .object({ - url: z.string(), - }) - .strict(); -export const CrowdstrikeSecretsSchema = z - .object({ - clientId: z.string(), - clientSecret: z.string(), - }) - .strict(); +export const CrowdstrikeConfigSchema = lazySchema(() => + z + .object({ + url: z.string(), + }) + .strict() +); +export const CrowdstrikeSecretsSchema = lazySchema(() => + z + .object({ + clientId: z.string(), + clientSecret: z.string(), + }) + .strict() +); -export const CrowdstrikeApiDoNotValidateResponsesSchema = z.any(); +export const CrowdstrikeApiDoNotValidateResponsesSchema = lazySchema(() => z.any()); -export const RelaxedCrowdstrikeBaseApiResponseSchema = z.object({}).passthrough().optional(); +export const RelaxedCrowdstrikeBaseApiResponseSchema = lazySchema(() => + z.object({}).passthrough().optional() +); -export const CrowdstrikeBaseApiResponseSchema = z - .object({ - resources: z.array(z.any()), - errors: z.array(z.any()).nullable().default(null), - meta: z - .object({ - query_time: z.coerce.number().optional(), - powered_by: z.string().optional(), - trace_id: z.string().optional(), - }) - .passthrough(), - }) - .passthrough(); +export const CrowdstrikeBaseApiResponseSchema = lazySchema(() => + z + .object({ + resources: z.array(z.any()), + errors: z.array(z.any()).nullable().default(null), + meta: z + .object({ + query_time: z.coerce.number().optional(), + powered_by: z.string().optional(), + trace_id: z.string().optional(), + }) + .passthrough(), + }) + .passthrough() +); -export const CrowdstrikeGetAgentOnlineStatusResponseSchema = z - .object({ - resources: z.array( - z +export const CrowdstrikeGetAgentOnlineStatusResponseSchema = lazySchema(() => + z + .object({ + resources: z.array( + z + .object({ + state: z.string().optional(), + id: z.string().optional(), + last_seen: z.string().optional(), + }) + .passthrough() + ), + errors: z.array(z.any()).nullable().default(null), + meta: z .object({ - state: z.string().optional(), - id: z.string().optional(), - last_seen: z.string().optional(), + query_time: z.coerce.number().optional(), + powered_by: z.string().optional(), + trace_id: z.string().optional(), }) - .passthrough() - ), - errors: z.array(z.any()).nullable().default(null), - meta: z - .object({ - query_time: z.coerce.number().optional(), - powered_by: z.string().optional(), - trace_id: z.string().optional(), - }) - .passthrough(), - }) - .passthrough(); + .passthrough(), + }) + .passthrough() +); -export const CrowdstrikeGetAgentsResponseSchema = z - .object({ - resources: z.array( - z +export const CrowdstrikeGetAgentsResponseSchema = lazySchema(() => + z + .object({ + resources: z.array( + z + .object({ + device_id: z.string().optional(), + cid: z.string().optional(), + agent_load_flags: z.string().optional(), + agent_local_time: z.string().optional(), + agent_version: z.string().optional(), + bios_manufacturer: z.string().optional(), + bios_version: z.string().optional(), + config_id_base: z.string().optional(), + config_id_build: z.string().optional(), + config_id_platform: z.string().optional(), + cpu_signature: z.string().optional(), + cpu_vendor: z.string().optional(), + external_ip: z.string().optional(), + mac_address: z.string().optional(), + instance_id: z.string().optional(), + service_provider: z.string().optional(), + service_provider_account_id: z.string().optional(), + hostname: z.string().optional(), + first_seen: z.string().optional(), + last_login_timestamp: z.string().optional(), + last_login_user: z.string().optional(), + last_login_uid: z.string().optional(), + last_seen: z.string().optional(), + local_ip: z.string().optional(), + major_version: z.string().optional(), + minor_version: z.string().optional(), + os_version: z.string().optional(), + platform_id: z.string().optional(), + platform_name: z.string().optional(), + policies: z + .array( + z + .object({ + policy_type: z.string().optional(), + policy_id: z.string().optional(), + applied: z.boolean().optional(), + settings_hash: z.string().optional(), + assigned_date: z.string().optional(), + applied_date: z.string().optional(), + rule_groups: z.any().optional(), + }) + .passthrough() + ) + .optional(), + reduced_functionality_mode: z.string().optional(), + device_policies: z + .object({ + prevention: z + .object({ + policy_type: z.string().optional(), + policy_id: z.string().optional(), + applied: z.boolean().optional(), + settings_hash: z.string().optional(), + assigned_date: z.string().optional(), + applied_date: z.string().optional(), + rule_groups: z.any().optional(), + }) + .passthrough(), + sensor_update: z + .object({ + policy_type: z.string().optional(), + policy_id: z.string().optional(), + applied: z.boolean().optional(), + settings_hash: z.string().optional(), + assigned_date: z.string().optional(), + applied_date: z.string().optional(), + uninstall_protection: z.string().optional(), + }) + .passthrough(), + global_config: z + .object({ + policy_type: z.string().optional(), + policy_id: z.string().optional(), + applied: z.boolean().optional(), + settings_hash: z.string().optional(), + assigned_date: z.string().optional(), + applied_date: z.string().optional(), + }) + .passthrough(), + remote_response: z + .object({ + policy_type: z.string().optional(), + policy_id: z.string().optional(), + applied: z.boolean().optional(), + settings_hash: z.string().optional(), + assigned_date: z.string().optional(), + applied_date: z.string().optional(), + }) + .passthrough(), + }) + .passthrough() + .optional(), + groups: z.array(z.any()).optional(), + group_hash: z.string().optional(), + product_type_desc: z.string().optional(), + provision_status: z.string().optional(), + serial_number: z.string().optional(), + status: z.string().optional(), + system_manufacturer: z.string().optional(), + system_product_name: z.string().optional(), + tags: z.array(z.any()).optional(), + modified_timestamp: z.any(), + meta: z + .object({ + version: z.string().optional(), + version_string: z.string().optional(), + }) + .passthrough() + .optional(), + zone_group: z.string().optional(), + kernel_version: z.string().optional(), + chassis_type: z.string().optional(), + chassis_type_desc: z.string().optional(), + connection_ip: z.string().optional(), + default_gateway_ip: z.string().optional(), + connection_mac_address: z.string().optional(), + linux_sensor_mode: z.string().optional(), + deployment_type: z.string().optional(), + }) + .passthrough() + ), + errors: z.array(z.any()).nullable().default(null), + meta: z .object({ - device_id: z.string().optional(), - cid: z.string().optional(), - agent_load_flags: z.string().optional(), - agent_local_time: z.string().optional(), - agent_version: z.string().optional(), - bios_manufacturer: z.string().optional(), - bios_version: z.string().optional(), - config_id_base: z.string().optional(), - config_id_build: z.string().optional(), - config_id_platform: z.string().optional(), - cpu_signature: z.string().optional(), - cpu_vendor: z.string().optional(), - external_ip: z.string().optional(), - mac_address: z.string().optional(), - instance_id: z.string().optional(), - service_provider: z.string().optional(), - service_provider_account_id: z.string().optional(), - hostname: z.string().optional(), - first_seen: z.string().optional(), - last_login_timestamp: z.string().optional(), - last_login_user: z.string().optional(), - last_login_uid: z.string().optional(), - last_seen: z.string().optional(), - local_ip: z.string().optional(), - major_version: z.string().optional(), - minor_version: z.string().optional(), - os_version: z.string().optional(), - platform_id: z.string().optional(), - platform_name: z.string().optional(), - policies: z - .array( - z - .object({ - policy_type: z.string().optional(), - policy_id: z.string().optional(), - applied: z.boolean().optional(), - settings_hash: z.string().optional(), - assigned_date: z.string().optional(), - applied_date: z.string().optional(), - rule_groups: z.any().optional(), - }) - .passthrough() - ) - .optional(), - reduced_functionality_mode: z.string().optional(), - device_policies: z - .object({ - prevention: z - .object({ - policy_type: z.string().optional(), - policy_id: z.string().optional(), - applied: z.boolean().optional(), - settings_hash: z.string().optional(), - assigned_date: z.string().optional(), - applied_date: z.string().optional(), - rule_groups: z.any().optional(), - }) - .passthrough(), - sensor_update: z - .object({ - policy_type: z.string().optional(), - policy_id: z.string().optional(), - applied: z.boolean().optional(), - settings_hash: z.string().optional(), - assigned_date: z.string().optional(), - applied_date: z.string().optional(), - uninstall_protection: z.string().optional(), - }) - .passthrough(), - global_config: z - .object({ - policy_type: z.string().optional(), - policy_id: z.string().optional(), - applied: z.boolean().optional(), - settings_hash: z.string().optional(), - assigned_date: z.string().optional(), - applied_date: z.string().optional(), - }) - .passthrough(), - remote_response: z - .object({ - policy_type: z.string().optional(), - policy_id: z.string().optional(), - applied: z.boolean().optional(), - settings_hash: z.string().optional(), - assigned_date: z.string().optional(), - applied_date: z.string().optional(), - }) - .passthrough(), - }) - .passthrough() - .optional(), - groups: z.array(z.any()).optional(), - group_hash: z.string().optional(), - product_type_desc: z.string().optional(), - provision_status: z.string().optional(), - serial_number: z.string().optional(), - status: z.string().optional(), - system_manufacturer: z.string().optional(), - system_product_name: z.string().optional(), - tags: z.array(z.any()).optional(), - modified_timestamp: z.any(), - meta: z - .object({ - version: z.string().optional(), - version_string: z.string().optional(), - }) - .passthrough() - .optional(), - zone_group: z.string().optional(), - kernel_version: z.string().optional(), - chassis_type: z.string().optional(), - chassis_type_desc: z.string().optional(), - connection_ip: z.string().optional(), - default_gateway_ip: z.string().optional(), - connection_mac_address: z.string().optional(), - linux_sensor_mode: z.string().optional(), - deployment_type: z.string().optional(), + query_time: z.coerce.number().optional(), + powered_by: z.string().optional(), + trace_id: z.string().optional(), }) - .passthrough() - ), - errors: z.array(z.any()).nullable().default(null), - meta: z - .object({ - query_time: z.coerce.number().optional(), - powered_by: z.string().optional(), - trace_id: z.string().optional(), - }) - .passthrough(), - }) - .passthrough(); -export const CrowdstrikeHostActionsResponseSchema = z - .object({ - resources: z.array( - z + .passthrough(), + }) + .passthrough() +); +export const CrowdstrikeHostActionsResponseSchema = lazySchema(() => + z + .object({ + resources: z.array( + z + .object({ + id: z.string().optional(), + path: z.string().optional(), + }) + .passthrough() + ), + meta: z .object({ - id: z.string().optional(), - path: z.string().optional(), + query_time: z.coerce.number().optional(), + powered_by: z.string().optional(), + trace_id: z.string().optional(), }) - .passthrough() - ), - meta: z - .object({ - query_time: z.coerce.number().optional(), - powered_by: z.string().optional(), - trace_id: z.string().optional(), - }) - .passthrough(), - errors: z.array(z.any()).nullable().default(null), - }) - .passthrough(); + .passthrough(), + errors: z.array(z.any()).nullable().default(null), + }) + .passthrough() +); // TODO temporary any value -export const CrowdstrikeRTRCommandParamsSchema = z.any(); -export const CrowdstrikeHostActionsParamsSchema = z - .object({ - command: z.enum(['contain', 'lift_containment']), - actionParameters: z.object({}).passthrough().optional(), - ids: z.array(z.string()), - alertIds: z.array(z.string()).optional(), - comment: z.string().optional(), - }) - .strict(); +export const CrowdstrikeRTRCommandParamsSchema = lazySchema(() => z.any()); +export const CrowdstrikeHostActionsParamsSchema = lazySchema(() => + z + .object({ + command: z.enum(['contain', 'lift_containment']), + actionParameters: z.object({}).passthrough().optional(), + ids: z.array(z.string()), + alertIds: z.array(z.string()).optional(), + comment: z.string().optional(), + }) + .strict() +); -export const CrowdstrikeGetAgentsParamsSchema = z - .object({ - ids: z.array(z.string()), - }) - .strict(); -export const CrowdstrikeGetTokenResponseSchema = z - .object({ - access_token: z.string(), - expires_in: z.coerce.number(), - token_type: z.string(), - id_token: z.string().optional(), - issued_token_type: z.string().optional(), - refresh_token: z.string().optional(), - scope: z.string().optional(), - }) - .passthrough(); +export const CrowdstrikeGetAgentsParamsSchema = lazySchema(() => + z + .object({ + ids: z.array(z.string()), + }) + .strict() +); +export const CrowdstrikeGetTokenResponseSchema = lazySchema(() => + z + .object({ + access_token: z.string(), + expires_in: z.coerce.number(), + token_type: z.string(), + id_token: z.string().optional(), + issued_token_type: z.string().optional(), + refresh_token: z.string().optional(), + scope: z.string().optional(), + }) + .passthrough() +); -export const CrowdstrikeHostActionsSchema = z - .object({ - subAction: z.literal(SUB_ACTION.HOST_ACTIONS), - subActionParams: CrowdstrikeHostActionsParamsSchema, - }) - .strict(); +export const CrowdstrikeHostActionsSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.HOST_ACTIONS), + subActionParams: CrowdstrikeHostActionsParamsSchema, + }) + .strict() +); export const CrowdstrikeActionParamsSchema = CrowdstrikeHostActionsSchema; -export const CrowdstrikeInitRTRResponseSchema = z - .object({ - meta: z - .object({ - query_time: z.coerce.number().optional(), - powered_by: z.string().optional(), - trace_id: z.string().optional(), - }) - .passthrough() - .optional(), - batch_id: z.string().optional(), - resources: z - .record( - z.string(), - z - .object({ - session_id: z.string().optional(), - task_id: z.string().optional(), - complete: z.boolean().optional(), - stdout: z.string().optional(), - stderr: z.string().optional(), - base_command: z.string().optional(), - aid: z.string().optional(), - errors: z.array(z.any()).optional(), - query_time: z.coerce.number().optional(), - offline_queued: z.boolean().optional(), - }) - .passthrough() - ) - .optional(), - errors: z.array(z.any()).optional(), - }) - .passthrough(); - -export const CrowdstrikeInitRTRParamsSchema = z - .object({ - endpoint_ids: z.array(z.string()), - }) - .strict(); - -export const CrowdstrikeExecuteRTRResponseSchema = z - .object({ - combined: z - .object({ - resources: z.record( +export const CrowdstrikeInitRTRResponseSchema = lazySchema(() => + z + .object({ + meta: z + .object({ + query_time: z.coerce.number().optional(), + powered_by: z.string().optional(), + trace_id: z.string().optional(), + }) + .passthrough() + .optional(), + batch_id: z.string().optional(), + resources: z + .record( z.string(), z .object({ - session_id: z.string(), - task_id: z.string(), - complete: z.boolean(), - stdout: z.string(), - stderr: z.string(), - base_command: z.string(), - aid: z.string(), - errors: z.array(z.any()), - query_time: z.coerce.number(), - offline_queued: z.boolean(), + session_id: z.string().optional(), + task_id: z.string().optional(), + complete: z.boolean().optional(), + stdout: z.string().optional(), + stderr: z.string().optional(), + base_command: z.string().optional(), + aid: z.string().optional(), + errors: z.array(z.any()).optional(), + query_time: z.coerce.number().optional(), + offline_queued: z.boolean().optional(), }) .passthrough() - ), - }) - .passthrough(), - meta: z - .object({ - query_time: z.coerce.number(), - powered_by: z.string(), - trace_id: z.string(), - }) - .passthrough(), - errors: z.array(z.any()).nullable().default(null), - }) - .passthrough(); + ) + .optional(), + errors: z.array(z.any()).optional(), + }) + .passthrough() +); -export const CrowdstrikeGetScriptsResponseSchema = z - .object({ - meta: z - .object({ - query_time: z.coerce.number().optional(), - powered_by: z.string().optional(), - trace_id: z.string().optional(), - }) - .passthrough() - .optional(), - resources: z - .array( - z - .object({ - content: z.string().optional(), - created_by: z.string().optional(), - created_by_uuid: z.string().optional(), - created_timestamp: z.string().optional(), - file_type: z.string().optional(), - id: z.string().optional(), - description: z.string().optional(), - modified_by: z.string().optional(), - modified_timestamp: z.string().optional(), - name: z.string().optional(), - permission_type: z.string().optional(), - platform: z.array(z.string()).optional(), - run_attempt_count: z.coerce.number().optional(), - run_success_count: z.coerce.number().optional(), - sha256: z.string().optional(), - size: z.coerce.number().optional(), - write_access: z.boolean().optional(), - }) - .passthrough() - ) - .optional(), - errors: z.array(z.any()).optional(), - }) - .passthrough(); +export const CrowdstrikeInitRTRParamsSchema = lazySchema(() => + z + .object({ + endpoint_ids: z.array(z.string()), + }) + .strict() +); + +export const CrowdstrikeExecuteRTRResponseSchema = lazySchema(() => + z + .object({ + combined: z + .object({ + resources: z.record( + z.string(), + z + .object({ + session_id: z.string(), + task_id: z.string(), + complete: z.boolean(), + stdout: z.string(), + stderr: z.string(), + base_command: z.string(), + aid: z.string(), + errors: z.array(z.any()), + query_time: z.coerce.number(), + offline_queued: z.boolean(), + }) + .passthrough() + ), + }) + .passthrough(), + meta: z + .object({ + query_time: z.coerce.number(), + powered_by: z.string(), + trace_id: z.string(), + }) + .passthrough(), + errors: z.array(z.any()).nullable().default(null), + }) + .passthrough() +); + +export const CrowdstrikeGetScriptsResponseSchema = lazySchema(() => + z + .object({ + meta: z + .object({ + query_time: z.coerce.number().optional(), + powered_by: z.string().optional(), + trace_id: z.string().optional(), + }) + .passthrough() + .optional(), + resources: z + .array( + z + .object({ + content: z.string().optional(), + created_by: z.string().optional(), + created_by_uuid: z.string().optional(), + created_timestamp: z.string().optional(), + file_type: z.string().optional(), + id: z.string().optional(), + description: z.string().optional(), + modified_by: z.string().optional(), + modified_timestamp: z.string().optional(), + name: z.string().optional(), + permission_type: z.string().optional(), + platform: z.array(z.string()).optional(), + run_attempt_count: z.coerce.number().optional(), + run_success_count: z.coerce.number().optional(), + sha256: z.string().optional(), + size: z.coerce.number().optional(), + write_access: z.boolean().optional(), + }) + .passthrough() + ) + .optional(), + errors: z.array(z.any()).optional(), + }) + .passthrough() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/d3security/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/d3security/schemas/v1.ts index 4cb8a0501138d..53821b4bebd43 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/d3security/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/d3security/schemas/v1.ts @@ -7,27 +7,33 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { D3SecuritySeverity } from '../constants'; // Connector schema -export const D3SecurityConfigSchema = z - .object({ - url: z.string(), - }) - .strict(); +export const D3SecurityConfigSchema = lazySchema(() => + z + .object({ + url: z.string(), + }) + .strict() +); -export const D3SecuritySecretsSchema = z.object({ token: z.string() }).strict(); +export const D3SecuritySecretsSchema = lazySchema(() => z.object({ token: z.string() }).strict()); // Run action schema -export const D3SecurityRunActionParamsSchema = z - .object({ - body: z.string().optional(), - severity: z.string().default(D3SecuritySeverity.EMPTY).optional(), - eventType: z.string().default('').optional(), - }) - .strict(); +export const D3SecurityRunActionParamsSchema = lazySchema(() => + z + .object({ + body: z.string().optional(), + severity: z.string().default(D3SecuritySeverity.EMPTY).optional(), + eventType: z.string().default('').optional(), + }) + .strict() +); -export const D3SecurityRunActionResponseSchema = z.object({ - refid: z.string(), -}); +export const D3SecurityRunActionResponseSchema = lazySchema(() => + z.object({ + refid: z.string(), + }) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/email/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/email/schemas/v1.ts index cd044cd4bd808..65d00f97d4a9e 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/email/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/email/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { defaultFooterText } from '../constants'; const PORT_MAX = 256 * 256 - 1; @@ -24,7 +24,7 @@ const ConfigSchemaProps = { oauthTokenUrl: z.string().nullable().default(null), }; -export const ConfigSchema = z.object(ConfigSchemaProps).strict(); +export const ConfigSchema = lazySchema(() => z.object(ConfigSchemaProps).strict()); const SecretsSchemaProps = { user: z.string().nullable().default(null), @@ -32,7 +32,7 @@ const SecretsSchemaProps = { clientSecret: z.string().nullable().default(null), }; -export const SecretsSchema = z.object(SecretsSchemaProps).strict(); +export const SecretsSchema = lazySchema(() => z.object(SecretsSchemaProps).strict()); const AttachmentSchemaProps = { content: z.string(), @@ -40,9 +40,9 @@ const AttachmentSchemaProps = { filename: z.string(), encoding: z.string().optional(), }; -export const AttachmentSchema = z.object(AttachmentSchemaProps).strict(); +export const AttachmentSchema = lazySchema(() => z.object(AttachmentSchemaProps).strict()); -export const emailSchema = z.array(z.string().max(512)).max(100); +export const emailSchema = lazySchema(() => z.array(z.string().max(512)).max(100)); export const ParamsSchemaProps = { to: emailSchema.default([]), @@ -67,4 +67,4 @@ export const ParamsSchemaProps = { attachments: z.array(AttachmentSchema).optional(), }; -export const ParamsSchema = z.object(ParamsSchemaProps).strict(); +export const ParamsSchema = lazySchema(() => z.object(ParamsSchemaProps).strict()); diff --git a/src/platform/packages/shared/kbn-connector-schemas/es_index/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/es_index/schemas/v1.ts index 5b25be9d1ef57..138db171085bf 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/es_index/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/es_index/schemas/v1.ts @@ -6,34 +6,38 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { ALERT_HISTORY_PREFIX } from '../constants'; -export const ConfigSchema = z - .object({ - index: z.string(), - refresh: z.boolean().default(false), - executionTimeField: z.string().nullable().default(null), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + index: z.string(), + refresh: z.boolean().default(false), + executionTimeField: z.string().nullable().default(null), + }) + .strict() +); -export const SecretsSchema = z.object({}).strict().default({}); +export const SecretsSchema = lazySchema(() => z.object({}).strict().default({})); // see: https://www.elastic.co/guide/en/elasticsearch/reference/current/actions-index.html // - timeout not added here, as this seems to be a generic thing we want to do // eventually: https://github.com/elastic/kibana/projects/26#card-24087404 -export const ParamsSchema = z - .object({ - documents: z.array(z.record(z.string(), z.any())), - indexOverride: z - .string() - .nullable() - .default(null) - .refine( - (pattern) => pattern === null || (pattern && pattern.startsWith(ALERT_HISTORY_PREFIX)), - { - message: `index must start with "${ALERT_HISTORY_PREFIX}"`, - } - ), - }) - .strict(); +export const ParamsSchema = lazySchema(() => + z + .object({ + documents: z.array(z.record(z.string(), z.any())), + indexOverride: z + .string() + .nullable() + .default(null) + .refine( + (pattern) => pattern === null || (pattern && pattern.startsWith(ALERT_HISTORY_PREFIX)), + { + message: `index must start with "${ALERT_HISTORY_PREFIX}"`, + } + ), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/gemini/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/gemini/schemas/v1.ts index 3678c42760480..7914db6db0254 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/gemini/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/gemini/schemas/v1.ts @@ -6,114 +6,134 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { DEFAULT_MODEL } from '../constants'; -export const TelemetryMetadataSchema = z - .object({ - pluginId: z.string().optional(), - aggregateBy: z.string().optional(), - }) - .strict(); +export const TelemetryMetadataSchema = lazySchema(() => + z + .object({ + pluginId: z.string().optional(), + aggregateBy: z.string().optional(), + }) + .strict() +); -export const ConfigSchema = z - .object({ - apiUrl: z.string(), - defaultModel: z.string().default(DEFAULT_MODEL), - gcpRegion: z.string(), - gcpProjectID: z.string(), - contextWindowLength: z.coerce.number().optional(), - temperature: z.coerce.number().optional(), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + apiUrl: z.string(), + defaultModel: z.string().default(DEFAULT_MODEL), + gcpRegion: z.string(), + gcpProjectID: z.string(), + contextWindowLength: z.coerce.number().optional(), + temperature: z.coerce.number().optional(), + }) + .strict() +); -export const SecretsSchema = z - .object({ - credentialsJson: z.string(), +export const SecretsSchema = lazySchema(() => + z + .object({ + credentialsJson: z.string(), + }) + .strict() +); + +export const RunActionParamsSchema = lazySchema(() => + z + .object({ + body: z.any(), + model: z.string().optional(), + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + temperature: z.coerce.number().optional(), + stopSequences: z.array(z.string()).optional(), + raw: z.boolean().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); + +export const RunApiResponseSchema = lazySchema(() => + z.object({ + candidates: z.any(), + usageMetadata: z.object({ + promptTokenCount: z.coerce.number(), + candidatesTokenCount: z.coerce.number(), + totalTokenCount: z.coerce.number(), + }), }) - .strict(); +); -export const RunActionParamsSchema = z - .object({ - body: z.any(), - model: z.string().optional(), - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - temperature: z.coerce.number().optional(), - stopSequences: z.array(z.string()).optional(), - raw: z.boolean().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), +export const RunActionResponseSchema = lazySchema(() => + z.object({ + completion: z.string(), + stop_reason: z.string().optional(), + usageMetadata: z + .object({ + promptTokenCount: z.coerce.number(), + candidatesTokenCount: z.coerce.number(), + totalTokenCount: z.coerce.number(), + }) + .optional(), }) - .strict(); +); -export const RunApiResponseSchema = z.object({ - candidates: z.any(), - usageMetadata: z.object({ - promptTokenCount: z.coerce.number(), - candidatesTokenCount: z.coerce.number(), - totalTokenCount: z.coerce.number(), - }), -}); +export const RunActionRawResponseSchema = lazySchema(() => z.any()); -export const RunActionResponseSchema = z.object({ - completion: z.string(), - stop_reason: z.string().optional(), - usageMetadata: z +export const InvokeAIActionParamsSchema = lazySchema(() => + z .object({ - promptTokenCount: z.coerce.number(), - candidatesTokenCount: z.coerce.number(), - totalTokenCount: z.coerce.number(), + maxOutputTokens: z.coerce.number().optional(), + messages: z.any(), + systemInstruction: z.string().optional(), + model: z.string().optional(), + temperature: z.coerce.number().optional(), + stopSequences: z.array(z.string()).optional(), + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + tools: z.array(z.any()).optional(), + toolConfig: z + .object({ + mode: z.enum(['AUTO', 'ANY', 'NONE']), + allowedFunctionNames: z.array(z.string()).optional(), + }) + .strict() + .optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), }) - .optional(), -}); + .strict() +); -export const RunActionRawResponseSchema = z.any(); +export const InvokeAIRawActionParamsSchema = InvokeAIActionParamsSchema; -export const InvokeAIActionParamsSchema = z - .object({ - maxOutputTokens: z.coerce.number().optional(), - messages: z.any(), - systemInstruction: z.string().optional(), - model: z.string().optional(), - temperature: z.coerce.number().optional(), - stopSequences: z.array(z.string()).optional(), - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - tools: z.array(z.any()).optional(), - toolConfig: z +export const InvokeAIActionResponseSchema = lazySchema(() => + z.object({ + message: z.string(), + usageMetadata: z .object({ - mode: z.enum(['AUTO', 'ANY', 'NONE']), - allowedFunctionNames: z.array(z.string()).optional(), + promptTokenCount: z.coerce.number(), + candidatesTokenCount: z.coerce.number(), + totalTokenCount: z.coerce.number(), }) - .strict() .optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), }) - .strict(); +); -export const InvokeAIRawActionParamsSchema = InvokeAIActionParamsSchema; +export const InvokeAIRawActionResponseSchema = lazySchema(() => z.any()); -export const InvokeAIActionResponseSchema = z.object({ - message: z.string(), - usageMetadata: z +export const StreamingResponseSchema = lazySchema(() => z.any()); + +export const DashboardActionParamsSchema = lazySchema(() => + z .object({ - promptTokenCount: z.coerce.number(), - candidatesTokenCount: z.coerce.number(), - totalTokenCount: z.coerce.number(), + dashboardId: z.string(), }) - .optional(), -}); + .strict() +); -export const InvokeAIRawActionResponseSchema = z.any(); - -export const StreamingResponseSchema = z.any(); - -export const DashboardActionParamsSchema = z - .object({ - dashboardId: z.string(), +export const DashboardActionResponseSchema = lazySchema(() => + z.object({ + available: z.boolean(), }) - .strict(); - -export const DashboardActionResponseSchema = z.object({ - available: z.boolean(), -}); +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/http/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/http/schemas/v1.ts index 233a75b87bc3e..2d4cb48790885 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/http/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/http/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SecretConfiguration, SecretConfigurationSchemaValidation, @@ -15,68 +15,72 @@ import { AuthConfiguration } from '../../common/auth'; export const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] as const; -export const HeadersSchema = z.record(z.string(), z.string()); +export const HeadersSchema = lazySchema(() => z.record(z.string(), z.string())); -export const ConfigSchema = z - .object({ - url: z.string().url(), - headers: HeadersSchema.nullable().default(null), - hasAuth: AuthConfiguration.hasAuth, - authType: AuthConfiguration.authType, - certType: AuthConfiguration.certType, - ca: AuthConfiguration.ca, - verificationMode: AuthConfiguration.verificationMode, - accessTokenUrl: AuthConfiguration.accessTokenUrl, - clientId: AuthConfiguration.clientId, - scope: AuthConfiguration.scope, - additionalFields: AuthConfiguration.additionalFields, - proxyUrl: z.string().url().nullable().default(null), - proxyVerificationMode: z.enum(['none', 'certificate', 'full']).optional(), - hasProxyAuth: z.boolean().default(false), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + url: z.string().url(), + headers: HeadersSchema.nullable().default(null), + hasAuth: AuthConfiguration.hasAuth, + authType: AuthConfiguration.authType, + certType: AuthConfiguration.certType, + ca: AuthConfiguration.ca, + verificationMode: AuthConfiguration.verificationMode, + accessTokenUrl: AuthConfiguration.accessTokenUrl, + clientId: AuthConfiguration.clientId, + scope: AuthConfiguration.scope, + additionalFields: AuthConfiguration.additionalFields, + proxyUrl: z.string().url().nullable().default(null), + proxyVerificationMode: z.enum(['none', 'certificate', 'full']).optional(), + hasProxyAuth: z.boolean().default(false), + }) + .strict() +); -export const SecretsSchema = z - .object({ - ...SecretConfiguration, - proxyUsername: z.string().nullable().default(null), - proxyPassword: z.string().nullable().default(null), - }) - .strict() - .superRefine((secrets, ctx) => { - const errorMessage = SecretConfigurationSchemaValidation.validate(secrets); - if (errorMessage) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: errorMessage, - }); - } - }); +export const SecretsSchema = lazySchema(() => + z + .object({ + ...SecretConfiguration, + proxyUsername: z.string().nullable().default(null), + proxyPassword: z.string().nullable().default(null), + }) + .strict() + .superRefine((secrets, ctx) => { + const errorMessage = SecretConfigurationSchemaValidation.validate(secrets); + if (errorMessage) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: errorMessage, + }); + } + }) +); -export const HttpMethodSchema = z.enum(HTTP_METHODS).default('GET'); +export const HttpMethodSchema = lazySchema(() => z.enum(HTTP_METHODS).default('GET')); -export const HttpRequestBodySchema = z.union([ - z.string(), - z.array(z.unknown()), - z.record(z.string(), z.unknown()), -]); +export const HttpRequestBodySchema = lazySchema(() => + z.union([z.string(), z.array(z.unknown()), z.record(z.string(), z.unknown())]) +); -export const ParamsSchema = z - .object({ - url: z.string().url().optional(), - path: z.string().optional(), - method: HttpMethodSchema, - body: HttpRequestBodySchema.optional(), - query: z.record(z.string(), z.string()).optional(), - headers: z.record(z.string(), z.string()).optional(), - fetcher: z - .object({ - skip_ssl_verification: z.boolean().optional(), - follow_redirects: z.boolean().optional(), - max_redirects: z.number().optional(), - keep_alive: z.boolean().optional(), - max_content_length: z.number().positive().finite().optional(), - }) - .optional(), - }) - .strict(); +export const ParamsSchema = lazySchema(() => + z + .object({ + url: z.string().url().optional(), + path: z.string().optional(), + method: HttpMethodSchema, + body: HttpRequestBodySchema.optional(), + query: z.record(z.string(), z.string()).optional(), + headers: z.record(z.string(), z.string()).optional(), + fetcher: z + .object({ + skip_ssl_verification: z.boolean().optional(), + follow_redirects: z.boolean().optional(), + max_redirects: z.number().optional(), + keep_alive: z.boolean().optional(), + max_content_length: z.number().positive().finite().optional(), + }) + .optional(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/inference/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/inference/schemas/v1.ts index 17b612f3f30a3..b8852a044abaa 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/inference/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/inference/schemas/v1.ts @@ -6,295 +6,329 @@ * 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 '@kbn/zod/v4'; -export const TelemetryMetadataSchema = z - .object({ - pluginId: z.string().optional(), - aggregateBy: z.string().optional(), - }) - .strict(); +import { z, lazySchema } from '@kbn/zod/v4'; +export const TelemetryMetadataSchema = lazySchema(() => + z + .object({ + pluginId: z.string().optional(), + aggregateBy: z.string().optional(), + }) + .strict() +); -export const ConfigSchema = z - .object({ - provider: z.string(), - taskType: z.string(), - inferenceId: z.string(), - providerConfig: z.object({}).passthrough().default({}), - taskTypeConfig: z.object({}).passthrough().default({}).optional(), - contextWindowLength: z.coerce.number().optional(), - headers: z.record(z.string(), z.string()).optional(), - temperature: z.coerce.number().optional(), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + provider: z.string(), + taskType: z.string(), + inferenceId: z.string(), + providerConfig: z.object({}).passthrough().default({}), + taskTypeConfig: z.object({}).passthrough().default({}).optional(), + contextWindowLength: z.coerce.number().optional(), + headers: z.record(z.string(), z.string()).optional(), + temperature: z.coerce.number().optional(), + }) + .strict() +); -export const SecretsSchema = z - .object({ - providerSecrets: z.object({}).passthrough().default({}), - }) - .strict(); +export const SecretsSchema = lazySchema(() => + z + .object({ + providerSecrets: z.object({}).passthrough().default({}), + }) + .strict() +); -export const ChatCompleteParamsSchema = z - .object({ - input: z.string(), - }) - .strict(); +export const ChatCompleteParamsSchema = lazySchema(() => + z + .object({ + input: z.string(), + }) + .strict() +); // subset of OpenAI.ChatCompletionMessageParam https://github.com/openai/openai-node/blob/master/src/resources/chat/completions.ts -const AIMessage = z - .object({ - role: z.string(), - content: z.string().nullish(), - name: z.string().optional(), - tool_calls: z - .array( - z - .object({ - id: z.string(), - function: z - .object({ - arguments: z.string().optional(), - name: z.string().optional(), - }) - .strict(), - type: z.string(), - }) - .strict() - ) - .optional(), - tool_call_id: z.string().optional(), - }) - .strict(); +const AIMessage = lazySchema(() => + z + .object({ + role: z.string(), + content: z.string().nullish(), + name: z.string().optional(), + tool_calls: z + .array( + z + .object({ + id: z.string(), + function: z + .object({ + arguments: z.string().optional(), + name: z.string().optional(), + }) + .strict(), + type: z.string(), + }) + .strict() + ) + .optional(), + tool_call_id: z.string().optional(), + }) + .strict() +); -const AITool = z - .object({ - type: z.string(), - function: z - .object({ - name: z.string(), - description: z.string().optional(), - parameters: z.record(z.string(), z.any()).optional(), - }) - .strict(), - }) - .strict(); +const AITool = lazySchema(() => + z + .object({ + type: z.string(), + function: z + .object({ + name: z.string(), + description: z.string().optional(), + parameters: z.record(z.string(), z.any()).optional(), + }) + .strict(), + }) + .strict() +); // subset of OpenAI.ChatCompletionCreateParamsBase https://github.com/openai/openai-node/blob/master/src/resources/chat/completions.ts -export const UnifiedChatCompleteParamsSchema = z - .object({ - body: z - .object({ - messages: z.array(AIMessage).default([]), - model: z.string().optional(), - /** - * The maximum number of [tokens](/tokenizer) that can be generated in the chat - * completion. This value can be used to control - * [costs](https://openai.com/api/pricing/) for text generated via API. - * - * This value is now deprecated in favor of `max_completion_tokens`, and is not - * compatible with - * [o1 series models](https://platform.openai.com/docs/guides/reasoning). - */ - max_tokens: z.coerce.number().optional(), - /** - * Developer-defined tags and values used for filtering completions in the - * [dashboard](https://platform.openai.com/chat-completions). - */ - metadata: z.record(z.string(), z.string()).optional(), - /** - * How many chat completion choices to generate for each input message. Note that - * you will be charged based on the number of generated tokens across all of the - * choices. Keep `n` as `1` to minimize costs. - */ - n: z.coerce.number().optional(), - /** - * Up to 4 sequences where the API will stop generating further tokens. - */ - stop: z.union([z.string(), z.array(z.string())]).nullish(), - /** - * The maximum number of tokens to generate in the completion. Requests can use - z.union([z.string(), z.array(z.string)]).optional(), - /** - * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will - * make the output more random, while lower values like 0.2 will make it more - * focused and deterministic. - * - * We generally recommend altering this or `top_p` but not both. - */ - temperature: z.coerce.number().optional(), - /** - * Controls which (if any) tool is called by the model. `none` means the model will - * not call any tool and instead generates a message. `auto` means the model can - * pick between generating a message or calling one or more tools. `required` means - * the model must call one or more tools. Specifying a particular tool via - * `{"type": "function", "function": {"name": "my_function"}}` forces the model to - * call that tool. - * - * `none` is the default when no tools are present. `auto` is the default if tools - * are present. - */ - tool_choice: z - .union([ - z.string(), - z - .object({ - type: z.string(), - function: z - .object({ - name: z.string(), - }) - .strict(), - }) - .strict(), - ]) - .optional(), - /** - * A list of tools the model may call. Currently, only functions are supported as a - * tool. Use this to provide a list of functions the model may generate JSON inputs - * for. A max of 128 functions are supported. - */ - tools: z.array(AITool).optional(), - /** - * An alternative to sampling with temperature, called nucleus sampling, where the - * model considers the results of the tokens with top_p probability mass. So 0.1 - * means only the tokens comprising the top 10% probability mass are considered. - * - * We generally recommend altering this or `temperature` but not both. - */ - top_p: z.coerce.number().optional(), - /** - * A unique identifier representing your end-user, which can help OpenAI to monitor - * and detect abuse. - * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices/end-user-ids). - */ - user: z.string().optional(), - }) - .strict(), - // abort signal from client - signal: z.any().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); +export const UnifiedChatCompleteParamsSchema = lazySchema(() => + z + .object({ + body: z + .object({ + messages: z.array(AIMessage).default([]), + model: z.string().optional(), + /** + * The maximum number of [tokens](/tokenizer) that can be generated in the chat + * completion. This value can be used to control + * [costs](https://openai.com/api/pricing/) for text generated via API. + * + * This value is now deprecated in favor of `max_completion_tokens`, and is not + * compatible with + * [o1 series models](https://platform.openai.com/docs/guides/reasoning). + */ + max_tokens: z.coerce.number().optional(), + /** + * Developer-defined tags and values used for filtering completions in the + * [dashboard](https://platform.openai.com/chat-completions). + */ + metadata: z.record(z.string(), z.string()).optional(), + /** + * How many chat completion choices to generate for each input message. Note that + * you will be charged based on the number of generated tokens across all of the + * choices. Keep `n` as `1` to minimize costs. + */ + n: z.coerce.number().optional(), + /** + * Up to 4 sequences where the API will stop generating further tokens. + */ + stop: z.union([z.string(), z.array(z.string())]).nullish(), + /** + * The maximum number of tokens to generate in the completion. Requests can use + z.union([z.string(), z.array(z.string)]).optional(), + /** + * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will + * make the output more random, while lower values like 0.2 will make it more + * focused and deterministic. + * + * We generally recommend altering this or `top_p` but not both. + */ + temperature: z.coerce.number().optional(), + /** + * Controls which (if any) tool is called by the model. `none` means the model will + * not call any tool and instead generates a message. `auto` means the model can + * pick between generating a message or calling one or more tools. `required` means + * the model must call one or more tools. Specifying a particular tool via + * `{"type": "function", "function": {"name": "my_function"}}` forces the model to + * call that tool. + * + * `none` is the default when no tools are present. `auto` is the default if tools + * are present. + */ + tool_choice: z + .union([ + z.string(), + z + .object({ + type: z.string(), + function: z + .object({ + name: z.string(), + }) + .strict(), + }) + .strict(), + ]) + .optional(), + /** + * A list of tools the model may call. Currently, only functions are supported as a + * tool. Use this to provide a list of functions the model may generate JSON inputs + * for. A max of 128 functions are supported. + */ + tools: z.array(AITool).optional(), + /** + * An alternative to sampling with temperature, called nucleus sampling, where the + * model considers the results of the tokens with top_p probability mass. So 0.1 + * means only the tokens comprising the top 10% probability mass are considered. + * + * We generally recommend altering this or `temperature` but not both. + */ + top_p: z.coerce.number().optional(), + /** + * A unique identifier representing your end-user, which can help OpenAI to monitor + * and detect abuse. + * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices/end-user-ids). + */ + user: z.string().optional(), + }) + .strict(), + // abort signal from client + signal: z.any().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); -export const UnifiedChatCompleteResponseSchema = z - .object({ - id: z.string(), - choices: z - .array( - z - .object({ - finish_reason: z - .enum(['stop', 'length', 'tool_calls', 'content_filter', 'function_call']) - .nullish(), - index: z.coerce.number().optional(), - message: z - .object({ - content: z.string().nullish(), - refusal: z.string().nullish(), - role: z.string().optional(), - tool_calls: z - .array( - z - .object({ - id: z.string().optional(), - index: z.coerce.number().optional(), - function: z - .object({ - arguments: z.string().optional(), - name: z.string().optional(), - }) - .strict() - .optional(), - type: z.string().optional(), - }) - .strict() - ) - .default([]) - .optional(), - }) - .strict(), - }) - .strict() - ) - .default([]), - created: z.coerce.number().optional(), - model: z.string().optional(), - object: z.string().optional(), - usage: z - .object({ - completion_tokens: z.coerce.number().optional(), - prompt_tokens: z.coerce.number().optional(), - total_tokens: z.coerce.number().optional(), - }) - .strict() - .nullish(), - }) - .strict(); +export const UnifiedChatCompleteResponseSchema = lazySchema(() => + z + .object({ + id: z.string(), + choices: z + .array( + z + .object({ + finish_reason: z + .enum(['stop', 'length', 'tool_calls', 'content_filter', 'function_call']) + .nullish(), + index: z.coerce.number().optional(), + message: z + .object({ + content: z.string().nullish(), + refusal: z.string().nullish(), + role: z.string().optional(), + tool_calls: z + .array( + z + .object({ + id: z.string().optional(), + index: z.coerce.number().optional(), + function: z + .object({ + arguments: z.string().optional(), + name: z.string().optional(), + }) + .strict() + .optional(), + type: z.string().optional(), + }) + .strict() + ) + .default([]) + .optional(), + }) + .strict(), + }) + .strict() + ) + .default([]), + created: z.coerce.number().optional(), + model: z.string().optional(), + object: z.string().optional(), + usage: z + .object({ + completion_tokens: z.coerce.number().optional(), + prompt_tokens: z.coerce.number().optional(), + total_tokens: z.coerce.number().optional(), + }) + .strict() + .nullish(), + }) + .strict() +); -export const ChatCompleteResponseSchema = z - .array( - z - .object({ - result: z.string(), - }) - .strict() - ) - .default([]); +export const ChatCompleteResponseSchema = lazySchema(() => + z + .array( + z + .object({ + result: z.string(), + }) + .strict() + ) + .default([]) +); -export const RerankParamsSchema = z - .object({ - input: z.array(z.string()).default([]), - query: z.string(), - }) - .strict(); +export const RerankParamsSchema = lazySchema(() => + z + .object({ + input: z.array(z.string()).default([]), + query: z.string(), + }) + .strict() +); -export const RerankResponseSchema = z - .array( - z - .object({ - text: z.string().optional(), - index: z.coerce.number(), - score: z.coerce.number(), - }) - .strict() - ) - .default([]); +export const RerankResponseSchema = lazySchema(() => + z + .array( + z + .object({ + text: z.string().optional(), + index: z.coerce.number(), + score: z.coerce.number(), + }) + .strict() + ) + .default([]) +); -export const SparseEmbeddingParamsSchema = z - .object({ - input: z.string(), - }) - .strict(); +export const SparseEmbeddingParamsSchema = lazySchema(() => + z + .object({ + input: z.string(), + }) + .strict() +); -export const SparseEmbeddingResponseSchema = z.array(z.object({}).passthrough()).default([]); +export const SparseEmbeddingResponseSchema = lazySchema(() => + z.array(z.object({}).passthrough()).default([]) +); -export const TextEmbeddingParamsSchema = z - .object({ - input: z.string(), - inputType: z.string(), - }) - .strict(); +export const TextEmbeddingParamsSchema = lazySchema(() => + z + .object({ + input: z.string(), + inputType: z.string(), + }) + .strict() +); -export const TextEmbeddingResponseSchema = z - .array( - z - .object({ - embedding: z.array(z.any()).default([]), - }) - .strict() - ) - .default([]); +export const TextEmbeddingResponseSchema = lazySchema(() => + z + .array( + z + .object({ + embedding: z.array(z.any()).default([]), + }) + .strict() + ) + .default([]) +); -export const StreamingResponseSchema = z.any(); +export const StreamingResponseSchema = lazySchema(() => z.any()); // Run action schema -export const DashboardActionParamsSchema = z - .object({ - dashboardId: z.string(), - }) - .strict(); +export const DashboardActionParamsSchema = lazySchema(() => + z + .object({ + dashboardId: z.string(), + }) + .strict() +); -export const DashboardActionResponseSchema = z - .object({ - available: z.boolean(), - }) - .strict(); +export const DashboardActionResponseSchema = lazySchema(() => + z + .object({ + available: z.boolean(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/jira-service-management/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/jira-service-management/schemas/v1.ts index 38f96d5e5f8d4..aedcd1e3af2e5 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/jira-service-management/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/jira-service-management/schemas/v1.ts @@ -7,112 +7,124 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isEmpty } from 'lodash'; import { MESSAGE_NON_EMPTY } from '../constants'; -export const ConfigSchema = z - .object({ - apiUrl: z.string(), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + apiUrl: z.string(), + }) + .strict() +); -export const SecretsSchema = z - .object({ - apiKey: z.string(), - }) - .strict(); +export const SecretsSchema = lazySchema(() => + z + .object({ + apiKey: z.string(), + }) + .strict() +); -const SuccessfulResponse = z - .object({ - took: z.coerce.number(), - requestId: z.string(), - result: z.string(), - }) - .passthrough(); +const SuccessfulResponse = lazySchema(() => + z + .object({ + took: z.coerce.number(), + requestId: z.string(), + result: z.string(), + }) + .passthrough() +); -export const FailureResponse = z - .object({ - code: z.coerce.number().optional(), - message: z.string().optional(), - result: z.string().optional(), - errors: z.array(z.object({ title: z.string(), code: z.string() }).strict()).optional(), - took: z.coerce.number().optional(), - requestId: z.string().optional(), - }) - .passthrough(); +export const FailureResponse = lazySchema(() => + z + .object({ + code: z.coerce.number().optional(), + message: z.string().optional(), + result: z.string().optional(), + errors: z.array(z.object({ title: z.string(), code: z.string() }).strict()).optional(), + took: z.coerce.number().optional(), + requestId: z.string().optional(), + }) + .passthrough() +); -export const Response = z.union([SuccessfulResponse, FailureResponse]); +export const Response = lazySchema(() => z.union([SuccessfulResponse, FailureResponse])); -const responderTypes = z.enum(['team', 'user', 'escalation', 'schedule']); +const responderTypes = lazySchema(() => z.enum(['team', 'user', 'escalation', 'schedule'])); /** * For more information on the JiraServiceManagement create alert schema see: https://developer.atlassian.com/cloud/jira/service-desk-ops/rest/v1/api-group-integration-events/#api-jsm-ops-integration-v2-alerts-post */ -export const CreateAlertParamsSchema = z - .object({ - message: z - .string() - .min(1) - .max(130) - .superRefine((message, ctx) => { - if (isEmpty(message.trim())) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: MESSAGE_NON_EMPTY, - }); - } - }), - /** - * The max length here should be 512 according to JiraServiceManagement's docs but we will sha256 hash the alias if it is longer than 512 - * so we'll not impose a limit on the schema otherwise it'll get rejected prematurely. - */ - alias: z.string().optional(), - description: z.string().max(15000).optional(), - responders: z - .array(z.object({ id: z.string(), type: responderTypes }).strict()) - .max(50) - .optional(), - visibleTo: z - .array( - z.union([ - z - .object({ - id: z.string(), - type: z.literal('team'), - }) - .strict(), - z - .object({ - id: z.string(), - type: z.literal('user'), - }) - .strict(), - ]) - ) - .max(50) - .optional(), - actions: z.array(z.string().max(50)).max(10).optional(), - tags: z.array(z.string().max(50)).max(20).optional(), - /** - * The validation requirement here is that the total characters between the key and value do not exceed 8000. JiraServiceManagement - * will truncate the value if it would exceed the 8000 but it doesn't throw an error. Because of this I'm intentionally - * not validating the length of the keys and values here. - */ - details: z.record(z.string(), z.string()).optional(), - entity: z.string().max(512).optional(), - source: z.string().max(100).optional(), - priority: z.enum(['P1', 'P2', 'P3', 'P4', 'P5']).optional(), - note: z.string().max(25000).optional(), - user: z.string().max(100).optional(), - }) - .strict(); +export const CreateAlertParamsSchema = lazySchema(() => + z + .object({ + message: z + .string() + .min(1) + .max(130) + .superRefine((message, ctx) => { + if (isEmpty(message.trim())) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: MESSAGE_NON_EMPTY, + }); + } + }), + /** + * The max length here should be 512 according to JiraServiceManagement's docs but we will sha256 hash the alias if it is longer than 512 + * so we'll not impose a limit on the schema otherwise it'll get rejected prematurely. + */ + alias: z.string().optional(), + description: z.string().max(15000).optional(), + responders: z + .array(z.object({ id: z.string(), type: responderTypes }).strict()) + .max(50) + .optional(), + visibleTo: z + .array( + z.union([ + z + .object({ + id: z.string(), + type: z.literal('team'), + }) + .strict(), + z + .object({ + id: z.string(), + type: z.literal('user'), + }) + .strict(), + ]) + ) + .max(50) + .optional(), + actions: z.array(z.string().max(50)).max(10).optional(), + tags: z.array(z.string().max(50)).max(20).optional(), + /** + * The validation requirement here is that the total characters between the key and value do not exceed 8000. JiraServiceManagement + * will truncate the value if it would exceed the 8000 but it doesn't throw an error. Because of this I'm intentionally + * not validating the length of the keys and values here. + */ + details: z.record(z.string(), z.string()).optional(), + entity: z.string().max(512).optional(), + source: z.string().max(100).optional(), + priority: z.enum(['P1', 'P2', 'P3', 'P4', 'P5']).optional(), + note: z.string().max(25000).optional(), + user: z.string().max(100).optional(), + }) + .strict() +); -export const CloseAlertParamsSchema = z - .object({ - alias: z.string(), - user: z.string().max(100).optional(), - source: z.string().max(100).optional(), - note: z.string().max(25000).optional(), - }) - .strict(); +export const CloseAlertParamsSchema = lazySchema(() => + z + .object({ + alias: z.string(), + user: z.string().max(100).optional(), + source: z.string().max(100).optional(), + note: z.string().max(25000).optional(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/jira/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/jira/schemas/v1.ts index d01f6df9aee75..d99c42c555591 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/jira/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/jira/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Coerced, validateRecordKeysAllowed, validateRecordMaxKeys } from '../../common/utils'; import { MAX_OTHER_FIELDS_LENGTH } from '../constants'; @@ -15,18 +15,18 @@ export const ExternalIncidentServiceConfiguration = { projectKey: z.string(), }; -export const ExternalIncidentServiceConfigurationSchema = z - .object(ExternalIncidentServiceConfiguration) - .strict(); +export const ExternalIncidentServiceConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceConfiguration).strict() +); export const ExternalIncidentServiceSecretConfiguration = { email: z.string(), apiToken: z.string(), }; -export const ExternalIncidentServiceSecretConfigurationSchema = z - .object(ExternalIncidentServiceSecretConfiguration) - .strict(); +export const ExternalIncidentServiceSecretConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceSecretConfiguration).strict() +); const incidentSchemaObject = { summary: z.string(), @@ -75,87 +75,99 @@ const incidentSchemaObject = { export const incidentSchemaObjectProperties = Object.keys(incidentSchemaObject); -export const ExecutorSubActionPushParamsSchema = z.object({ - incident: z.object(incidentSchemaObject).strict(), - comments: z - .array( - z - .object({ - comment: z.string(), - commentId: z.string(), - }) - .strict() - ) - .nullable() - .default(null), -}); - -export const ExecutorSubActionGetIncidentParamsSchema = z - .object({ - externalId: z.string(), - }) - .strict(); - -// Reserved for future implementation -export const ExecutorSubActionCommonFieldsParamsSchema = z.object({}).strict(); -export const ExecutorSubActionHandshakeParamsSchema = z.object({}).strict(); -export const ExecutorSubActionGetCapabilitiesParamsSchema = z.object({}).strict(); -export const ExecutorSubActionGetIssueTypesParamsSchema = z.object({}).strict(); -export const ExecutorSubActionGetFieldsByIssueTypeParamsSchema = z - .object({ - id: z.string(), +export const ExecutorSubActionPushParamsSchema = lazySchema(() => + z.object({ + incident: z.object(incidentSchemaObject).strict(), + comments: z + .array( + z + .object({ + comment: z.string(), + commentId: z.string(), + }) + .strict() + ) + .nullable() + .default(null), }) - .strict(); -export const ExecutorSubActionGetIssuesParamsSchema = z.object({ title: z.string() }).strict(); -export const ExecutorSubActionGetIssueParamsSchema = z.object({ id: z.string() }).strict(); +); -export const ExecutorParamsSchema = z.discriminatedUnion('subAction', [ - z - .object({ - subAction: z.literal('getFields'), - subActionParams: ExecutorSubActionCommonFieldsParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('getIncident'), - subActionParams: ExecutorSubActionGetIncidentParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('handshake'), - subActionParams: ExecutorSubActionHandshakeParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('pushToService'), - subActionParams: ExecutorSubActionPushParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('issueTypes'), - subActionParams: ExecutorSubActionGetIssueTypesParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('fieldsByIssueType'), - subActionParams: ExecutorSubActionGetFieldsByIssueTypeParamsSchema, - }) - .strict(), +export const ExecutorSubActionGetIncidentParamsSchema = lazySchema(() => z .object({ - subAction: z.literal('issues'), - subActionParams: ExecutorSubActionGetIssuesParamsSchema, + externalId: z.string(), }) - .strict(), + .strict() +); + +// Reserved for future implementation +export const ExecutorSubActionCommonFieldsParamsSchema = lazySchema(() => z.object({}).strict()); +export const ExecutorSubActionHandshakeParamsSchema = lazySchema(() => z.object({}).strict()); +export const ExecutorSubActionGetCapabilitiesParamsSchema = lazySchema(() => z.object({}).strict()); +export const ExecutorSubActionGetIssueTypesParamsSchema = lazySchema(() => z.object({}).strict()); +export const ExecutorSubActionGetFieldsByIssueTypeParamsSchema = lazySchema(() => z .object({ - subAction: z.literal('issue'), - subActionParams: ExecutorSubActionGetIssueParamsSchema, + id: z.string(), }) - .strict(), -]); + .strict() +); +export const ExecutorSubActionGetIssuesParamsSchema = lazySchema(() => + z.object({ title: z.string() }).strict() +); +export const ExecutorSubActionGetIssueParamsSchema = lazySchema(() => + z.object({ id: z.string() }).strict() +); + +export const ExecutorParamsSchema = lazySchema(() => + z.discriminatedUnion('subAction', [ + z + .object({ + subAction: z.literal('getFields'), + subActionParams: ExecutorSubActionCommonFieldsParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('getIncident'), + subActionParams: ExecutorSubActionGetIncidentParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('handshake'), + subActionParams: ExecutorSubActionHandshakeParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('issueTypes'), + subActionParams: ExecutorSubActionGetIssueTypesParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('fieldsByIssueType'), + subActionParams: ExecutorSubActionGetFieldsByIssueTypeParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('issues'), + subActionParams: ExecutorSubActionGetIssuesParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('issue'), + subActionParams: ExecutorSubActionGetIssueParamsSchema, + }) + .strict(), + ]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/mcp/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/mcp/schemas/v1.ts index d9c2e3af24237..20b2604462a83 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/mcp/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/mcp/schemas/v1.ts @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; /** * Authentication types supported by the MCP connector. @@ -27,75 +27,83 @@ export const API_KEY_PLACEHOLDER = '{{apiKey}}'; * * Flat structure following standard Kibana connector patterns. */ -export const MCPConnectorConfigSchema = z.object({ - /** - * The URL of the MCP server endpoint. - */ - serverUrl: z.string(), - /** - * Whether authentication is required. Defaults to true. - */ - hasAuth: z.boolean().default(true), - /** - * Authentication type to use when hasAuth is true. - */ - authType: z - .enum([MCPAuthType.None, MCPAuthType.Bearer, MCPAuthType.ApiKey, MCPAuthType.Basic]) - .optional(), - /** - * Custom header name for API key authentication. - * Defaults to 'X-API-Key' if not specified. - * Only used when authType is 'apiKey'. - */ - apiKeyHeaderName: z.string().min(1).optional(), - /** - * When authType is 'apiKey': optional value template. {{apiKey}} is replaced by secrets.apiKey. - * When omitted, the header value is the raw apiKey. - */ - apiKeyHeaderValue: z.string().optional(), - /** - * Non-sensitive HTTP headers to include in requests. - */ - headers: z.record(z.string(), z.string()).optional(), -}); +export const MCPConnectorConfigSchema = lazySchema(() => + z.object({ + /** + * The URL of the MCP server endpoint. + */ + serverUrl: z.string(), + /** + * Whether authentication is required. Defaults to true. + */ + hasAuth: z.boolean().default(true), + /** + * Authentication type to use when hasAuth is true. + */ + authType: z + .enum([MCPAuthType.None, MCPAuthType.Bearer, MCPAuthType.ApiKey, MCPAuthType.Basic]) + .optional(), + /** + * Custom header name for API key authentication. + * Defaults to 'X-API-Key' if not specified. + * Only used when authType is 'apiKey'. + */ + apiKeyHeaderName: z.string().min(1).optional(), + /** + * When authType is 'apiKey': optional value template. {{apiKey}} is replaced by secrets.apiKey. + * When omitted, the header value is the raw apiKey. + */ + apiKeyHeaderValue: z.string().optional(), + /** + * Non-sensitive HTTP headers to include in requests. + */ + headers: z.record(z.string(), z.string()).optional(), + }) +); /** * Schema for MCP connector secrets. * * Flat structure with optional fields based on auth type. */ -export const MCPConnectorSecretsSchema = z.object({ - /** - * Bearer token for 'bearer' auth type. - */ - token: z.string().optional(), - /** - * API key for 'apiKey' auth type. - */ - apiKey: z.string().optional(), - /** - * Username for 'basic' auth type. - */ - user: z.string().optional(), - /** - * Password for 'basic' auth type. - */ - password: z.string().optional(), - /** - * Sensitive HTTP headers to include in requests. - */ - secretHeaders: z.record(z.string(), z.string()).optional(), -}); +export const MCPConnectorSecretsSchema = lazySchema(() => + z.object({ + /** + * Bearer token for 'bearer' auth type. + */ + token: z.string().optional(), + /** + * API key for 'apiKey' auth type. + */ + apiKey: z.string().optional(), + /** + * Username for 'basic' auth type. + */ + user: z.string().optional(), + /** + * Password for 'basic' auth type. + */ + password: z.string().optional(), + /** + * Sensitive HTTP headers to include in requests. + */ + secretHeaders: z.record(z.string(), z.string()).optional(), + }) +); // Sub-action schemas -export const TestConnectorRequestSchema = z.object({}).strict(); +export const TestConnectorRequestSchema = lazySchema(() => z.object({}).strict()); -export const ListToolsRequestSchema = z.object({ - forceRefresh: z.boolean().optional(), -}); +export const ListToolsRequestSchema = lazySchema(() => + z.object({ + forceRefresh: z.boolean().optional(), + }) +); -export const CallToolRequestSchema = z.object({ - name: z.string(), - arguments: z.record(z.string(), z.any()).optional(), -}); +export const CallToolRequestSchema = lazySchema(() => + z.object({ + name: z.string(), + arguments: z.record(z.string(), z.any()).optional(), + }) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/microsoft_defender_endpoint/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/microsoft_defender_endpoint/schemas/v1.ts index 9a432a6a87715..d55423bc2f93c 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/microsoft_defender_endpoint/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/microsoft_defender_endpoint/schemas/v1.ts @@ -6,210 +6,242 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SUB_ACTION } from '../constants'; // ---------------------------------- // Connector setup schemas // ---------------------------------- -export const MicrosoftDefenderEndpointConfigSchema = z - .object({ - clientId: z.string().min(1), - tenantId: z.string().min(1), - oAuthServerUrl: z.string().min(1), - oAuthScope: z.string().min(1), - apiUrl: z.string().min(1), - }) - .strict(); -export const MicrosoftDefenderEndpointSecretsSchema = z - .object({ - clientSecret: z.string().min(1), - }) - .strict(); +export const MicrosoftDefenderEndpointConfigSchema = lazySchema(() => + z + .object({ + clientId: z.string().min(1), + tenantId: z.string().min(1), + oAuthServerUrl: z.string().min(1), + oAuthScope: z.string().min(1), + apiUrl: z.string().min(1), + }) + .strict() +); +export const MicrosoftDefenderEndpointSecretsSchema = lazySchema(() => + z + .object({ + clientSecret: z.string().min(1), + }) + .strict() +); // ---------------------------------- // Connector Methods // ---------------------------------- -export const MicrosoftDefenderEndpointDoNotValidateResponseSchema = z.any(); - -export const MicrosoftDefenderEndpointBaseApiResponseSchema = z.object({}).passthrough().optional(); - -export const MicrosoftDefenderEndpointEmptyParamsSchema = z.object({}).strict(); - -export const TestConnectorParamsSchema = z.object({}).strict(); - -export const AgentDetailsParamsSchema = z - .object({ - id: z.string().min(1), - }) - .strict(); - -const MachineHealthStatusSchema = z.enum([ - 'Active', - 'Inactive', - 'ImpairedCommunication', - 'NoSensorData', - 'NoSensorDataImpairedCommunication', - 'Unknown', -]); - -export const AgentListParamsSchema = z - .object({ - computerDnsName: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - id: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - version: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - deviceValue: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - aaDeviceId: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - machineTags: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - lastSeen: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - exposureLevel: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - onboardingStatus: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - lastIpAddress: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - healthStatus: z - .union([MachineHealthStatusSchema, z.array(MachineHealthStatusSchema).min(1)]) - .optional(), - osPlatform: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - riskScore: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - rbacGroupId: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - page: z.coerce.number().min(1).optional(), - pageSize: z.coerce.number().min(1).max(1000).optional(), - }) - .strict(); - -export const IsolateHostParamsSchema = z - .object({ - id: z.string().min(1), - comment: z.string().min(1), - }) - .strict(); - -export const ReleaseHostParamsSchema = z - .object({ - id: z.string().min(1), - comment: z.string().min(1), - }) - .strict(); - -export const RunScriptParamsSchema = z - .object({ - id: z.string().min(1), - comment: z.string().min(1).optional(), - parameters: z - .object({ - scriptName: z.string().min(1), - args: z.string().min(1).optional(), - }) - .strict(), - }) - .strict(); - -export const CancelParamsSchema = z - .object({ - comment: z.string().min(1), - actionId: z.string().min(1), - }) - .strict(); - -const MachineActionTypeSchema = z.enum([ - 'RunAntiVirusScan', - 'Offboard', - 'LiveResponse', - 'CollectInvestigationPackage', - 'Isolate', - 'Unisolate', - 'StopAndQuarantineFile', - 'RestrictCodeExecution', - 'UnrestrictCodeExecution', -]); - -const MachineActionStatusSchema = z.enum([ - 'Pending', - 'InProgress', - 'Succeeded', - 'Failed', - 'TimeOut', - 'Cancelled', -]); - -export const GetActionsParamsSchema = z - .object({ - id: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - status: z - .union([MachineActionStatusSchema, z.array(MachineActionStatusSchema).min(1)]) - .optional(), - machineId: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - type: z.union([MachineActionTypeSchema, z.array(MachineActionTypeSchema).min(1)]).optional(), - requestor: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - creationDateTimeUtc: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), - page: z.coerce.number().min(1).optional(), - pageSize: z.coerce.number().min(1).max(1000).optional(), - sortField: z.string().min(1).optional(), - sortDirection: z.enum(['asc', 'desc']).optional(), - }) - .strict(); - -export const GetActionResultsParamsSchema = z - .object({ - id: z.string().min(1), - }) - .strict(); - -export const MSDefenderLibraryFileSchema = z - .object({ - fileName: z.string().optional(), - sha256: z.string().optional(), - description: z.string().optional(), - creationTime: z.string().optional(), - lastUpdatedTime: z.string().optional(), - createdBy: z.string().optional(), - hasParameters: z.boolean().optional(), - parametersDescription: z.string().nullish(), - }) - .passthrough(); - -export const GetLibraryFilesResponse = z - .object({ - '@odata.context': z.string().optional(), - value: z.array(MSDefenderLibraryFileSchema).optional(), - }) - .passthrough(); - -export const DownloadActionResultsResponseSchema = z.any(); +export const MicrosoftDefenderEndpointDoNotValidateResponseSchema = lazySchema(() => z.any()); + +export const MicrosoftDefenderEndpointBaseApiResponseSchema = lazySchema(() => + z.object({}).passthrough().optional() +); + +export const MicrosoftDefenderEndpointEmptyParamsSchema = lazySchema(() => z.object({}).strict()); + +export const TestConnectorParamsSchema = lazySchema(() => z.object({}).strict()); + +export const AgentDetailsParamsSchema = lazySchema(() => + z + .object({ + id: z.string().min(1), + }) + .strict() +); + +const MachineHealthStatusSchema = lazySchema(() => + z.enum([ + 'Active', + 'Inactive', + 'ImpairedCommunication', + 'NoSensorData', + 'NoSensorDataImpairedCommunication', + 'Unknown', + ]) +); + +export const AgentListParamsSchema = lazySchema(() => + z + .object({ + computerDnsName: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + id: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + version: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + deviceValue: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + aaDeviceId: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + machineTags: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + lastSeen: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + exposureLevel: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + onboardingStatus: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + lastIpAddress: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + healthStatus: z + .union([MachineHealthStatusSchema, z.array(MachineHealthStatusSchema).min(1)]) + .optional(), + osPlatform: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + riskScore: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + rbacGroupId: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + page: z.coerce.number().min(1).optional(), + pageSize: z.coerce.number().min(1).max(1000).optional(), + }) + .strict() +); + +export const IsolateHostParamsSchema = lazySchema(() => + z + .object({ + id: z.string().min(1), + comment: z.string().min(1), + }) + .strict() +); + +export const ReleaseHostParamsSchema = lazySchema(() => + z + .object({ + id: z.string().min(1), + comment: z.string().min(1), + }) + .strict() +); + +export const RunScriptParamsSchema = lazySchema(() => + z + .object({ + id: z.string().min(1), + comment: z.string().min(1).optional(), + parameters: z + .object({ + scriptName: z.string().min(1), + args: z.string().min(1).optional(), + }) + .strict(), + }) + .strict() +); + +export const CancelParamsSchema = lazySchema(() => + z + .object({ + comment: z.string().min(1), + actionId: z.string().min(1), + }) + .strict() +); + +const MachineActionTypeSchema = lazySchema(() => + z.enum([ + 'RunAntiVirusScan', + 'Offboard', + 'LiveResponse', + 'CollectInvestigationPackage', + 'Isolate', + 'Unisolate', + 'StopAndQuarantineFile', + 'RestrictCodeExecution', + 'UnrestrictCodeExecution', + ]) +); + +const MachineActionStatusSchema = lazySchema(() => + z.enum(['Pending', 'InProgress', 'Succeeded', 'Failed', 'TimeOut', 'Cancelled']) +); + +export const GetActionsParamsSchema = lazySchema(() => + z + .object({ + id: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + status: z + .union([MachineActionStatusSchema, z.array(MachineActionStatusSchema).min(1)]) + .optional(), + machineId: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + type: z.union([MachineActionTypeSchema, z.array(MachineActionTypeSchema).min(1)]).optional(), + requestor: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(), + creationDateTimeUtc: z + .union([z.string().min(1), z.array(z.string().min(1)).min(1)]) + .optional(), + page: z.coerce.number().min(1).optional(), + pageSize: z.coerce.number().min(1).max(1000).optional(), + sortField: z.string().min(1).optional(), + sortDirection: z.enum(['asc', 'desc']).optional(), + }) + .strict() +); + +export const GetActionResultsParamsSchema = lazySchema(() => + z + .object({ + id: z.string().min(1), + }) + .strict() +); + +export const MSDefenderLibraryFileSchema = lazySchema(() => + z + .object({ + fileName: z.string().optional(), + sha256: z.string().optional(), + description: z.string().optional(), + creationTime: z.string().optional(), + lastUpdatedTime: z.string().optional(), + createdBy: z.string().optional(), + hasParameters: z.boolean().optional(), + parametersDescription: z.string().nullish(), + }) + .passthrough() +); + +export const GetLibraryFilesResponse = lazySchema(() => + z + .object({ + '@odata.context': z.string().optional(), + value: z.array(MSDefenderLibraryFileSchema).optional(), + }) + .passthrough() +); + +export const DownloadActionResultsResponseSchema = lazySchema(() => z.any()); // ---------------------------------- // Connector Sub-Actions // ---------------------------------- -const TestConnectorSchema = z - .object({ - subAction: z.literal(SUB_ACTION.TEST_CONNECTOR), - subActionParams: TestConnectorParamsSchema, - }) - .strict(); - -const IsolateHostSchema = z - .object({ - subAction: z.literal(SUB_ACTION.ISOLATE_HOST), - subActionParams: IsolateHostParamsSchema, - }) - .strict(); - -const ReleaseHostSchema = z - .object({ - subAction: z.literal(SUB_ACTION.RELEASE_HOST), - subActionParams: ReleaseHostParamsSchema, - }) - .strict(); -const RunScriptSchema = z - .object({ - subAction: z.literal(SUB_ACTION.RUN_SCRIPT), - subActionParams: RunScriptParamsSchema, - }) - .strict(); - -export const MicrosoftDefenderEndpointActionParamsSchema = z.union([ - TestConnectorSchema, - IsolateHostSchema, - ReleaseHostSchema, - RunScriptSchema, -]); +const TestConnectorSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.TEST_CONNECTOR), + subActionParams: TestConnectorParamsSchema, + }) + .strict() +); + +const IsolateHostSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.ISOLATE_HOST), + subActionParams: IsolateHostParamsSchema, + }) + .strict() +); + +const ReleaseHostSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.RELEASE_HOST), + subActionParams: ReleaseHostParamsSchema, + }) + .strict() +); +const RunScriptSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.RUN_SCRIPT), + subActionParams: RunScriptParamsSchema, + }) + .strict() +); + +export const MicrosoftDefenderEndpointActionParamsSchema = lazySchema(() => + z.union([TestConnectorSchema, IsolateHostSchema, ReleaseHostSchema, RunScriptSchema]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/openai/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/openai/schemas/v1.ts index f51dcf4a92675..83401f6f20a81 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/openai/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/openai/schemas/v1.ts @@ -6,243 +6,265 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { DEFAULT_MODEL, OpenAiProviderType } from '../constants'; -export const TelemetryMetadataSchema = z - .object({ - pluginId: z.string().optional(), - aggregateBy: z.string().optional(), - }) - .strict(); +export const TelemetryMetadataSchema = lazySchema(() => + z + .object({ + pluginId: z.string().optional(), + aggregateBy: z.string().optional(), + }) + .strict() +); // Connector schema -export const ConfigSchema = z.discriminatedUnion( - 'apiProvider', - [ - z - .object({ - apiProvider: z.enum([OpenAiProviderType.AzureAi]), - apiUrl: z.string(), - defaultModel: z.string().optional(), - headers: z.record(z.string(), z.string()).optional(), - contextWindowLength: z.coerce.number().optional(), - temperature: z.coerce.number().optional(), - }) - .strict(), - z - .object({ - apiProvider: z.enum([OpenAiProviderType.OpenAi]), - apiUrl: z.string(), - organizationId: z.string().optional(), - projectId: z.string().optional(), - defaultModel: z.string().default(DEFAULT_MODEL), - headers: z.record(z.string(), z.string()).optional(), - contextWindowLength: z.coerce.number().optional(), - temperature: z.coerce.number().optional(), - }) - .strict(), +export const ConfigSchema = lazySchema(() => + z.discriminatedUnion( + 'apiProvider', + [ + z + .object({ + apiProvider: z.enum([OpenAiProviderType.AzureAi]), + apiUrl: z.string(), + defaultModel: z.string().optional(), + headers: z.record(z.string(), z.string()).optional(), + contextWindowLength: z.coerce.number().optional(), + temperature: z.coerce.number().optional(), + }) + .strict(), + z + .object({ + apiProvider: z.enum([OpenAiProviderType.OpenAi]), + apiUrl: z.string(), + organizationId: z.string().optional(), + projectId: z.string().optional(), + defaultModel: z.string().default(DEFAULT_MODEL), + headers: z.record(z.string(), z.string()).optional(), + contextWindowLength: z.coerce.number().optional(), + temperature: z.coerce.number().optional(), + }) + .strict(), + z + .object({ + apiProvider: z.enum([OpenAiProviderType.Other]), + apiUrl: z.string(), + defaultModel: z.string(), + verificationMode: z.enum(['full', 'certificate', 'none']).default('full').optional(), + headers: z.record(z.string(), z.string()).optional(), + contextWindowLength: z.coerce.number().optional(), + temperature: z.coerce.number().optional(), + enableNativeFunctionCalling: z.boolean().optional(), + }) + .strict(), + ], + { + error: 'Invalid or missing apiProvider: expected one of "Azure OpenAI", "OpenAI", or "Other"', + } + ) +); + +export const SecretsSchema = lazySchema(() => + z.union([ + z.object({ apiKey: z.string() }).strict(), z .object({ - apiProvider: z.enum([OpenAiProviderType.Other]), - apiUrl: z.string(), - defaultModel: z.string(), - verificationMode: z.enum(['full', 'certificate', 'none']).default('full').optional(), - headers: z.record(z.string(), z.string()).optional(), - contextWindowLength: z.coerce.number().optional(), - temperature: z.coerce.number().optional(), - enableNativeFunctionCalling: z.boolean().optional(), + apiKey: z.string().min(1).optional(), + certificateData: z.string().min(1).optional(), + privateKeyData: z.string().min(1).optional(), + caData: z.string().min(1).optional(), }) .strict(), - ], - { - error: 'Invalid or missing apiProvider: expected one of "Azure OpenAI", "OpenAI", or "Other"', - } + ]) ); -export const SecretsSchema = z.union([ - z.object({ apiKey: z.string() }).strict(), +// Run action schema +export const RunActionParamsSchema = lazySchema(() => z .object({ - apiKey: z.string().min(1).optional(), - certificateData: z.string().min(1).optional(), - privateKeyData: z.string().min(1).optional(), - caData: z.string().min(1).optional(), + body: z.string(), + // abort signal from client + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), }) - .strict(), -]); - -// Run action schema -export const RunActionParamsSchema = z - .object({ - body: z.string(), - // abort signal from client - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); + .strict() +); -const AIMessage = z - .object({ - role: z.string(), - content: z.string(), - name: z.string().optional(), - function_call: z - .object({ - arguments: z.string(), - name: z.string(), - }) - .strict() - .optional(), - tool_calls: z - .array( - z - .object({ - id: z.string(), - function: z - .object({ - arguments: z.string(), - name: z.string(), - }) - .strict(), - type: z.string(), - }) - .strict() - ) - .optional(), - tool_call_id: z.string().optional(), - }) - .strict(); +const AIMessage = lazySchema(() => + z + .object({ + role: z.string(), + content: z.string(), + name: z.string().optional(), + function_call: z + .object({ + arguments: z.string(), + name: z.string(), + }) + .strict() + .optional(), + tool_calls: z + .array( + z + .object({ + id: z.string(), + function: z + .object({ + arguments: z.string(), + name: z.string(), + }) + .strict(), + type: z.string(), + }) + .strict() + ) + .optional(), + tool_call_id: z.string().optional(), + }) + .strict() +); // Run action schema -export const InvokeAIActionParamsSchema = z - .object({ - messages: z.array(AIMessage), - model: z.string().optional(), - tools: z - .array( - z - .object({ +export const InvokeAIActionParamsSchema = lazySchema(() => + z + .object({ + messages: z.array(AIMessage), + model: z.string().optional(), + tools: z + .array( + z + .object({ + type: z.literal('function'), + function: z + .object({ + description: z.string().optional(), + name: z.string(), + parameters: z.object({}).passthrough(), + strict: z.boolean().optional(), + }) + .passthrough(), + }) + // Not sure if this will include other properties, we should pass them if it does + .passthrough() + ) + .optional(), + tool_choice: z + .union([ + z.literal('none'), + z.literal('auto'), + z.literal('required'), + z.object({ type: z.literal('function'), - function: z - .object({ - description: z.string().optional(), - name: z.string(), - parameters: z.object({}).passthrough(), - strict: z.boolean().optional(), - }) - .passthrough(), - }) - // Not sure if this will include other properties, we should pass them if it does - .passthrough() - ) - .optional(), - tool_choice: z - .union([ - z.literal('none'), - z.literal('auto'), - z.literal('required'), - z.object({ - type: z.literal('function'), - function: z.object({ name: z.string() }).passthrough(), - }), - ]) - .optional(), - // Deprecated in favor of tools - functions: z - .array( - z - .object({ + function: z.object({ name: z.string() }).passthrough(), + }), + ]) + .optional(), + // Deprecated in favor of tools + functions: z + .array( + z + .object({ + name: z.string(), + description: z.string(), + parameters: z + .object({ + type: z.string(), + properties: z.object({}).passthrough(), + additionalProperties: z.boolean(), + $schema: z.string(), + }) + .passthrough(), + }) + // Not sure if this will include other properties, we should pass them if it does + .passthrough() + ) + .optional(), + // Deprecated in favor of tool_choice + function_call: z + .union([ + z.literal('none'), + z.literal('auto'), + z.object({ name: z.string(), - description: z.string(), - parameters: z - .object({ - type: z.string(), - properties: z.object({}).passthrough(), - additionalProperties: z.boolean(), - $schema: z.string(), - }) - .passthrough(), - }) - // Not sure if this will include other properties, we should pass them if it does - .passthrough() - ) - .optional(), - // Deprecated in favor of tool_choice - function_call: z - .union([ - z.literal('none'), - z.literal('auto'), - z.object({ - name: z.string(), - }), - ]) - .optional(), - n: z.coerce.number().optional(), - stop: z.union([z.string(), z.array(z.string())]).nullish(), - temperature: z.coerce.number().optional(), - response_format: z.any().optional(), - // abort signal from client - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); + }), + ]) + .optional(), + n: z.coerce.number().optional(), + stop: z.union([z.string(), z.array(z.string())]).nullish(), + temperature: z.coerce.number().optional(), + response_format: z.any().optional(), + // abort signal from client + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); -export const InvokeAIActionResponseSchema = z.object({ - message: z.string(), - usage: z.object({ - prompt_tokens: z.coerce.number(), - completion_tokens: z.coerce.number(), - total_tokens: z.coerce.number(), - }), -}); +export const InvokeAIActionResponseSchema = lazySchema(() => + z.object({ + message: z.string(), + usage: z.object({ + prompt_tokens: z.coerce.number(), + completion_tokens: z.coerce.number(), + total_tokens: z.coerce.number(), + }), + }) +); // Execute action schema -export const StreamActionParamsSchema = z - .object({ - body: z.string(), - stream: z.boolean().default(false), - // abort signal from client - signal: z.any().optional(), - timeout: z.coerce.number().optional(), - telemetryMetadata: TelemetryMetadataSchema.optional(), - }) - .strict(); +export const StreamActionParamsSchema = lazySchema(() => + z + .object({ + body: z.string(), + stream: z.boolean().default(false), + // abort signal from client + signal: z.any().optional(), + timeout: z.coerce.number().optional(), + telemetryMetadata: TelemetryMetadataSchema.optional(), + }) + .strict() +); -export const StreamingResponseSchema = z.any(); +export const StreamingResponseSchema = lazySchema(() => z.any()); -export const RunActionResponseSchema = z.object({ - id: z.string().optional(), - object: z.string().optional(), - created: z.coerce.number().optional(), - model: z.string().optional(), - usage: z.object({ - prompt_tokens: z.coerce.number(), - completion_tokens: z.coerce.number(), - total_tokens: z.coerce.number(), - }), - choices: z.array( - z.object({ - message: z.object({ - role: z.string(), - // nullable because message can contain function calls instead of final response when used with RAG - content: z.string().nullish(), - }), - finish_reason: z.string().optional(), - index: z.coerce.number().optional(), - }) - ), -}); +export const RunActionResponseSchema = lazySchema(() => + z.object({ + id: z.string().optional(), + object: z.string().optional(), + created: z.coerce.number().optional(), + model: z.string().optional(), + usage: z.object({ + prompt_tokens: z.coerce.number(), + completion_tokens: z.coerce.number(), + total_tokens: z.coerce.number(), + }), + choices: z.array( + z.object({ + message: z.object({ + role: z.string(), + // nullable because message can contain function calls instead of final response when used with RAG + content: z.string().nullish(), + }), + finish_reason: z.string().optional(), + index: z.coerce.number().optional(), + }) + ), + }) +); // Run action schema -export const DashboardActionParamsSchema = z - .object({ - dashboardId: z.string(), - }) - .strict(); +export const DashboardActionParamsSchema = lazySchema(() => + z + .object({ + dashboardId: z.string(), + }) + .strict() +); -export const DashboardActionResponseSchema = z.object({ - available: z.boolean(), -}); +export const DashboardActionResponseSchema = lazySchema(() => + z.object({ + available: z.boolean(), + }) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/opsgenie/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/opsgenie/schemas/v1.ts index c26e5b0092d19..3bef639d52fb0 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/opsgenie/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/opsgenie/schemas/v1.ts @@ -6,164 +6,176 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { isEmpty } from 'lodash'; import { MESSAGE_NON_EMPTY } from '../constants'; -export const ConfigSchema = z - .object({ - apiUrl: z.string(), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + apiUrl: z.string(), + }) + .strict() +); -export const SecretsSchema = z - .object({ - apiKey: z.string(), - }) - .strict(); +export const SecretsSchema = lazySchema(() => + z + .object({ + apiKey: z.string(), + }) + .strict() +); -const SuccessfulResponse = z - .object({ - took: z.coerce.number(), - requestId: z.string(), - result: z.string(), - }) - .passthrough(); +const SuccessfulResponse = lazySchema(() => + z + .object({ + took: z.coerce.number(), + requestId: z.string(), + result: z.string(), + }) + .passthrough() +); -export const FailureResponse = z - .object({ - took: z.coerce.number(), - requestId: z.string(), - message: z.string().optional(), - result: z.string().optional(), - /** - * When testing invalid requests with Opsgenie the response seems to take the form: - * { - * ['field that is invalid']: 'message about what the issue is' - * } - * - * e.g. - * - * { - * "message": "Message can not be empty.", - * "username": "must be a well-formed email address" - * } - */ - errors: z.any().optional(), - }) - .passthrough(); +export const FailureResponse = lazySchema(() => + z + .object({ + took: z.coerce.number(), + requestId: z.string(), + message: z.string().optional(), + result: z.string().optional(), + /** + * When testing invalid requests with Opsgenie the response seems to take the form: + * { + * ['field that is invalid']: 'message about what the issue is' + * } + * + * e.g. + * + * { + * "message": "Message can not be empty.", + * "username": "must be a well-formed email address" + * } + */ + errors: z.any().optional(), + }) + .passthrough() +); -export const Response = z.union([SuccessfulResponse, FailureResponse]); +export const Response = lazySchema(() => z.union([SuccessfulResponse, FailureResponse])); -export const CloseAlertParamsSchema = z - .object({ - alias: z.string(), - user: z.string().max(100).optional(), - source: z.string().max(100).optional(), - note: z.string().max(25000).optional(), - }) - .strict(); +export const CloseAlertParamsSchema = lazySchema(() => + z + .object({ + alias: z.string(), + user: z.string().max(100).optional(), + source: z.string().max(100).optional(), + note: z.string().max(25000).optional(), + }) + .strict() +); -const responderTypes = z.enum(['team', 'user', 'escalation', 'schedule']); +const responderTypes = lazySchema(() => z.enum(['team', 'user', 'escalation', 'schedule'])); /** * For more information on the Opsgenie create alert schema see: https://docs.opsgenie.com/docs/alert-api#create-alert */ -export const CreateAlertParamsSchema = z - .object({ - message: z - .string() - .min(1) - .max(130) - .superRefine((message, ctx) => { - if (isEmpty(message.trim())) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: MESSAGE_NON_EMPTY, - }); - } - }), - /** - * The max length here should be 512 according to Opsgenie's docs but we will sha256 hash the alias if it is longer than 512 - * so we'll not impose a limit on the schema otherwise it'll get rejected prematurely. - */ - alias: z.string().optional(), - description: z.string().max(15000).optional(), - responders: z - .array( - z.union( - [ - z - .object({ - name: z.string(), - type: responderTypes, - }) - .strict(), - z.object({ id: z.string(), type: responderTypes }).strict(), - /** - * This field is not explicitly called out in the description of responders within Opsgenie's API docs but it is - * shown in an example and when I tested it, it seems to work as they throw an error if you try to specify a username - * without a valid email - */ - z.object({ username: z.string(), type: z.literal('user') }).strict(), - ], - { - error: - 'Each responder must have a "type" (team|user|escalation|schedule) and one of "name", "id", or "username"', +export const CreateAlertParamsSchema = lazySchema(() => + z + .object({ + message: z + .string() + .min(1) + .max(130) + .superRefine((message, ctx) => { + if (isEmpty(message.trim())) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: MESSAGE_NON_EMPTY, + }); } + }), + /** + * The max length here should be 512 according to Opsgenie's docs but we will sha256 hash the alias if it is longer than 512 + * so we'll not impose a limit on the schema otherwise it'll get rejected prematurely. + */ + alias: z.string().optional(), + description: z.string().max(15000).optional(), + responders: z + .array( + z.union( + [ + z + .object({ + name: z.string(), + type: responderTypes, + }) + .strict(), + z.object({ id: z.string(), type: responderTypes }).strict(), + /** + * This field is not explicitly called out in the description of responders within Opsgenie's API docs but it is + * shown in an example and when I tested it, it seems to work as they throw an error if you try to specify a username + * without a valid email + */ + z.object({ username: z.string(), type: z.literal('user') }).strict(), + ], + { + error: + 'Each responder must have a "type" (team|user|escalation|schedule) and one of "name", "id", or "username"', + } + ) ) - ) - .max(50) - .optional(), - visibleTo: z - .array( - z.union( - [ - z - .object({ - name: z.string(), - type: z.literal('team'), - }) - .strict(), - z - .object({ - id: z.string(), - type: z.literal('team'), - }) - .strict(), - z - .object({ - id: z.string(), - type: z.literal('user'), - }) - .strict(), - z - .object({ - username: z.string(), - type: z.literal('user'), - }) - .strict(), - ], - { - error: - 'Each visible target must have a "type" (team|user) and one of "name", "id", or "username"', - } + .max(50) + .optional(), + visibleTo: z + .array( + z.union( + [ + z + .object({ + name: z.string(), + type: z.literal('team'), + }) + .strict(), + z + .object({ + id: z.string(), + type: z.literal('team'), + }) + .strict(), + z + .object({ + id: z.string(), + type: z.literal('user'), + }) + .strict(), + z + .object({ + username: z.string(), + type: z.literal('user'), + }) + .strict(), + ], + { + error: + 'Each visible target must have a "type" (team|user) and one of "name", "id", or "username"', + } + ) ) - ) - .max(50) - .optional(), - actions: z.array(z.string().max(50)).max(10).optional(), - tags: z.array(z.string().max(50)).max(20).optional(), - /** - * The validation requirement here is that the total characters between the key and value do not exceed 8000. Opsgenie - * will truncate the value if it would exceed the 8000 but it doesn't throw an error. Because of this I'm intentionally - * not validating the length of the keys and values here. - */ - details: z.record(z.string(), z.string()).optional(), - entity: z.string().max(512).optional(), - source: z.string().max(100).optional(), - priority: z.enum(['P1', 'P2', 'P3', 'P4', 'P5']).optional(), - user: z.string().max(100).optional(), - note: z.string().max(25000).optional(), - }) - .strict(); + .max(50) + .optional(), + actions: z.array(z.string().max(50)).max(10).optional(), + tags: z.array(z.string().max(50)).max(20).optional(), + /** + * The validation requirement here is that the total characters between the key and value do not exceed 8000. Opsgenie + * will truncate the value if it would exceed the 8000 but it doesn't throw an error. Because of this I'm intentionally + * not validating the length of the keys and values here. + */ + details: z.record(z.string(), z.string()).optional(), + entity: z.string().max(512).optional(), + source: z.string().max(100).optional(), + priority: z.enum(['P1', 'P2', 'P3', 'P4', 'P5']).optional(), + user: z.string().max(100).optional(), + note: z.string().max(25000).optional(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/pagerduty/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/pagerduty/schemas/v1.ts index 97f9d76c0f77d..c2fe56f27fcb4 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/pagerduty/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/pagerduty/schemas/v1.ts @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ import { i18n } from '@kbn/i18n'; -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import moment from 'moment'; import { convertTimestamp, Coerced } from '../../common/utils'; @@ -21,83 +21,87 @@ import { const configSchemaProps = { apiUrl: z.string().nullable().default(null), }; -export const ConfigSchema = z.object(configSchemaProps).strict(); +export const ConfigSchema = lazySchema(() => z.object(configSchemaProps).strict()); -export const SecretsSchema = z - .object({ - routingKey: z.string(), - }) - .strict(); +export const SecretsSchema = lazySchema(() => + z + .object({ + routingKey: z.string(), + }) + .strict() +); -const EventActionSchema = z.enum([ - EVENT_ACTION_TRIGGER, - EVENT_ACTION_RESOLVE, - EVENT_ACTION_ACKNOWLEDGE, -]); +const EventActionSchema = lazySchema(() => + z.enum([EVENT_ACTION_TRIGGER, EVENT_ACTION_RESOLVE, EVENT_ACTION_ACKNOWLEDGE]) +); -const PayloadSeveritySchema = z.enum(['critical', 'error', 'warning', 'info']); -const LinksSchema = z.array(z.object({ href: z.string(), text: z.string() }).strict()); -const customDetailsSchema = Coerced(z.record(z.string(), z.any())); +const PayloadSeveritySchema = lazySchema(() => z.enum(['critical', 'error', 'warning', 'info'])); +const LinksSchema = lazySchema(() => + z.array(z.object({ href: z.string(), text: z.string() }).strict()) +); +const customDetailsSchema = lazySchema(() => Coerced(z.record(z.string(), z.any()))); -export const ParamsSchema = z - .object({ - eventAction: EventActionSchema.optional(), - dedupKey: z.string().max(255).optional(), - summary: z.string().max(1024).optional(), - source: z.string().optional(), - severity: PayloadSeveritySchema.optional(), - timestamp: z.string().optional(), - component: z.string().optional(), - group: z.string().optional(), - class: z.string().optional(), - links: LinksSchema.optional(), - customDetails: customDetailsSchema.optional(), - }) - .strict() - .superRefine((paramsObject, ctx) => { - const { timestamp, eventAction, dedupKey } = paramsObject; - const convertedTimestamp = convertTimestamp(timestamp); - if (convertedTimestamp != null) { - try { - const date = moment(convertedTimestamp); - if (!date.isValid()) { +export const ParamsSchema = lazySchema(() => + z + .object({ + eventAction: EventActionSchema.optional(), + dedupKey: z.string().max(255).optional(), + summary: z.string().max(1024).optional(), + source: z.string().optional(), + severity: PayloadSeveritySchema.optional(), + timestamp: z.string().optional(), + component: z.string().optional(), + group: z.string().optional(), + class: z.string().optional(), + links: LinksSchema.optional(), + customDetails: customDetailsSchema.optional(), + }) + .strict() + .superRefine((paramsObject, ctx) => { + const { timestamp, eventAction, dedupKey } = paramsObject; + const convertedTimestamp = convertTimestamp(timestamp); + if (convertedTimestamp != null) { + try { + const date = moment(convertedTimestamp); + if (!date.isValid()) { + ctx.addIssue({ + code: 'custom', + message: i18n.translate( + 'xpack.stackConnectors.pagerduty.invalidTimestampErrorMessage', + { + defaultMessage: `error parsing timestamp "{timestamp}"`, + values: { + timestamp, + }, + } + ), + }); + return; + } + } catch (err) { ctx.addIssue({ code: 'custom', message: i18n.translate( - 'xpack.stackConnectors.pagerduty.invalidTimestampErrorMessage', + 'xpack.stackConnectors.pagerduty.timestampParsingFailedErrorMessage', { - defaultMessage: `error parsing timestamp "{timestamp}"`, + defaultMessage: `error parsing timestamp "{timestamp}": {message}`, values: { timestamp, + message: err.message, }, } ), }); - return; } - } catch (err) { + } + if (eventAction && EVENT_ACTIONS_WITH_REQUIRED_DEDUPKEY.has(eventAction) && !dedupKey) { ctx.addIssue({ code: 'custom', - message: i18n.translate( - 'xpack.stackConnectors.pagerduty.timestampParsingFailedErrorMessage', - { - defaultMessage: `error parsing timestamp "{timestamp}": {message}`, - values: { - timestamp, - message: err.message, - }, - } - ), + message: i18n.translate('xpack.stackConnectors.pagerduty.missingDedupkeyErrorMessage', { + defaultMessage: `DedupKey is required when eventAction is "{eventAction}"`, + values: { eventAction }, + }), }); } - } - if (eventAction && EVENT_ACTIONS_WITH_REQUIRED_DEDUPKEY.has(eventAction) && !dedupKey) { - ctx.addIssue({ - code: 'custom', - message: i18n.translate('xpack.stackConnectors.pagerduty.missingDedupkeyErrorMessage', { - defaultMessage: `DedupKey is required when eventAction is "{eventAction}"`, - values: { eventAction }, - }), - }); - } - }); + }) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/resilient/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/resilient/schemas/v1.ts index 08721f1408cd9..35342660e9e1c 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/resilient/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/resilient/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Coerced, validateRecordKeysAllowed, validateRecordMaxKeys } from '../../common/utils'; export const ExternalIncidentServiceConfiguration = { @@ -14,18 +14,18 @@ export const ExternalIncidentServiceConfiguration = { orgId: z.string(), }; -export const ExternalIncidentServiceConfigurationSchema = z - .object(ExternalIncidentServiceConfiguration) - .strict(); +export const ExternalIncidentServiceConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceConfiguration).strict() +); export const ExternalIncidentServiceSecretConfiguration = { apiKeyId: z.string(), apiKeySecret: z.string(), }; -export const ExternalIncidentServiceSecretConfigurationSchema = z - .object(ExternalIncidentServiceSecretConfiguration) - .strict(); +export const ExternalIncidentServiceSecretConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceSecretConfiguration).strict() +); const MAX_ADDITIONAL_FIELDS_LENGTH = 50; @@ -65,24 +65,26 @@ const CommonIncidentAttributes = { export const commonIncidentSchemaObjectProperties = Object.keys(CommonIncidentAttributes); -export const ExecutorSubActionPushParamsSchema = z.object({ - incident: z - .object({ - ...CommonIncidentAttributes, - }) - .strict(), - comments: z - .array( - z - .object({ - comment: z.string(), - commentId: z.string(), - }) - .strict() - ) - .nullable() - .default(null), -}); +export const ExecutorSubActionPushParamsSchema = lazySchema(() => + z.object({ + incident: z + .object({ + ...CommonIncidentAttributes, + }) + .strict(), + comments: z + .array( + z + .object({ + comment: z.string(), + commentId: z.string(), + }) + .strict() + ) + .nullable() + .default(null), + }) +); export const PushToServiceIncidentSchema = { name: z.string(), @@ -93,67 +95,83 @@ export const PushToServiceIncidentSchema = { }; // Reserved for future implementation -export const ExecutorSubActionCommonFieldsParamsSchema = z.object({}).strict(); -export const ExecutorSubActionGetIncidentTypesParamsSchema = z.object({}).strict(); -export const ExecutorSubActionGetSeverityParamsSchema = z.object({}).strict(); +export const ExecutorSubActionCommonFieldsParamsSchema = lazySchema(() => z.object({}).strict()); +export const ExecutorSubActionGetIncidentTypesParamsSchema = lazySchema(() => + z.object({}).strict() +); +export const ExecutorSubActionGetSeverityParamsSchema = lazySchema(() => z.object({}).strict()); + +const ArrayOfValuesSchema = lazySchema(() => + z.array( + z + .object({ + value: z.coerce.number(), + label: z.string(), + }) + .passthrough() + ) +); -const ArrayOfValuesSchema = z.array( +export const GetIncidentTypesResponseSchema = lazySchema(() => z .object({ - value: z.coerce.number(), - label: z.string(), + values: ArrayOfValuesSchema, }) .passthrough() ); -export const GetIncidentTypesResponseSchema = z - .object({ - values: ArrayOfValuesSchema, - }) - .passthrough(); +export const GetSeverityResponseSchema = lazySchema(() => + z + .object({ + values: ArrayOfValuesSchema, + }) + .passthrough() +); -export const GetSeverityResponseSchema = z - .object({ - values: ArrayOfValuesSchema, - }) - .passthrough(); - -const ValuesItemSchema = z - .object({ - value: z.union([z.coerce.number(), z.string()]), - label: z.string(), - enabled: z.boolean(), - hidden: z.boolean(), - default: z.boolean(), - }) - .passthrough(); - -export const ExternalServiceFieldsSchema = z - .object({ - input_type: z.string(), - name: z.string(), - read_only: z.boolean(), - required: z.string().nullable().default(null), - text: z.string(), - prefix: z.string().nullable().default(null), - values: z.array(ValuesItemSchema).nullable().default(null), - }) - .passthrough(); +const ValuesItemSchema = lazySchema(() => + z + .object({ + value: z.union([z.coerce.number(), z.string()]), + label: z.string(), + enabled: z.boolean(), + hidden: z.boolean(), + default: z.boolean(), + }) + .passthrough() +); + +export const ExternalServiceFieldsSchema = lazySchema(() => + z + .object({ + input_type: z.string(), + name: z.string(), + read_only: z.boolean(), + required: z.string().nullable().default(null), + text: z.string(), + prefix: z.string().nullable().default(null), + values: z.array(ValuesItemSchema).nullable().default(null), + }) + .passthrough() +); -export const GetCommonFieldsResponseSchema = z.array(ExternalServiceFieldsSchema); +export const GetCommonFieldsResponseSchema = lazySchema(() => z.array(ExternalServiceFieldsSchema)); -export const ExternalServiceIncidentResponseSchema = z - .object({ - id: z.string(), - title: z.string(), - url: z.string(), - pushedDate: z.string(), - }) - .strict(); +export const ExternalServiceIncidentResponseSchema = lazySchema(() => + z + .object({ + id: z.string(), + title: z.string(), + url: z.string(), + pushedDate: z.string(), + }) + .strict() +); -export const GetIncidentResponseSchema = z - .object({ - id: z.coerce.number(), - inc_last_modified_date: z.coerce.number(), - }) - .passthrough(); +export const GetIncidentResponseSchema = lazySchema(() => + z + .object({ + id: z.coerce.number(), + inc_last_modified_date: z.coerce.number(), + }) + .passthrough() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/sentinelone/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/sentinelone/schemas/v1.ts index eaa047b89cf30..f8f1119045e39 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/sentinelone/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/sentinelone/schemas/v1.ts @@ -7,659 +7,712 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ /* eslint-disable @typescript-eslint/naming-convention */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SUB_ACTION } from '../constants'; // Connector schema -export const SentinelOneConfigSchema = z.object({ url: z.string() }).strict(); -export const SentinelOneSecretsSchema = z - .object({ - token: z.string(), - }) - .strict(); +export const SentinelOneConfigSchema = lazySchema(() => z.object({ url: z.string() }).strict()); +export const SentinelOneSecretsSchema = lazySchema(() => + z + .object({ + token: z.string(), + }) + .strict() +); -export const SentinelOneApiDoNotValidateResponsesSchema = z.any(); +export const SentinelOneApiDoNotValidateResponsesSchema = lazySchema(() => z.any()); -export const SentinelOneBaseApiResponseSchema = z.object({}).passthrough().optional(); +export const SentinelOneBaseApiResponseSchema = lazySchema(() => + z.object({}).passthrough().optional() +); -export const SentinelOneGetAgentsResponseSchema = z - .object({ - pagination: z - .object({ - totalItems: z.coerce.number(), - nextCursor: z.string().nullable().default(null), - }) - .strict(), - errors: z.array(z.string()).nullable().default(null), - data: z.array( - z +export const SentinelOneGetAgentsResponseSchema = lazySchema(() => + z + .object({ + pagination: z .object({ - modelName: z.string(), - firewallEnabled: z.boolean(), - totalMemory: z.coerce.number(), - osName: z.string(), - cloudProviders: z.record(z.string(), z.any()), - siteName: z.string(), - cpuId: z.string(), - isPendingUninstall: z.boolean(), - isUpToDate: z.boolean(), - osArch: z.string(), - accountId: z.string(), - locationEnabled: z.boolean(), - consoleMigrationStatus: z.string(), - scanFinishedAt: z.string().nullable().default(null), - operationalStateExpiration: z.string().nullable().default(null), - agentVersion: z.string(), - isActive: z.boolean(), - locationType: z.string(), - activeThreats: z.coerce.number(), - inRemoteShellSession: z.boolean(), - allowRemoteShell: z.boolean(), - serialNumber: z.string().nullable().default(null), - updatedAt: z.string(), - lastActiveDate: z.string(), - firstFullModeTime: z.string().nullable().default(null), - operationalState: z.string(), - externalId: z.string(), - mitigationModeSuspicious: z.string(), - licenseKey: z.string(), - cpuCount: z.coerce.number(), - mitigationMode: z.string(), - networkStatus: z.string(), - installerType: z.string(), - uuid: z.string(), - detectionState: z.string().nullable().default(null), - infected: z.boolean(), - registeredAt: z.string(), - lastIpToMgmt: z.string(), - storageName: z.string().nullable().default(null), - osUsername: z.string().nullable().default(null), - groupIp: z.string(), - createdAt: z.string(), - remoteProfilingState: z.string(), - groupUpdatedAt: z.string().nullable().default(null), - scanAbortedAt: z.string().nullable().default(null), - isUninstalled: z.boolean(), - networkQuarantineEnabled: z.boolean(), - tags: z - .object({ - sentinelone: z.array( - z - .object({ - assignedBy: z.string(), - assignedAt: z.string(), - assignedById: z.string(), - key: z.string(), - value: z.string(), - id: z.string(), - }) - .strict() - ), - }) - .strict(), - externalIp: z.string(), - siteId: z.string(), - machineType: z.string(), - domain: z.string(), - scanStatus: z.string(), - osStartTime: z.string(), - accountName: z.string(), - lastLoggedInUserName: z.string(), - showAlertIcon: z.boolean(), - rangerStatus: z.string(), - groupName: z.string(), - threatRebootRequired: z.boolean(), - remoteProfilingStateExpiration: z.string().nullable().default(null), - policyUpdatedAt: z.string().nullable().default(null), - activeDirectory: z - .object({ - userPrincipalName: z.string().nullable().default(null), - lastUserDistinguishedName: z.string().nullable().default(null), - computerMemberOf: z.array(z.object({ type: z.string() }).passthrough()), - lastUserMemberOf: z.array(z.object({ type: z.string() }).passthrough()), - mail: z.string().nullable().default(null), - computerDistinguishedName: z.string().nullable().default(null), - }) - .passthrough(), - isDecommissioned: z.boolean(), - rangerVersion: z.string(), - userActionsNeeded: z.array( - z + totalItems: z.coerce.number(), + nextCursor: z.string().nullable().default(null), + }) + .strict(), + errors: z.array(z.string()).nullable().default(null), + data: z.array( + z + .object({ + modelName: z.string(), + firewallEnabled: z.boolean(), + totalMemory: z.coerce.number(), + osName: z.string(), + cloudProviders: z.record(z.string(), z.any()), + siteName: z.string(), + cpuId: z.string(), + isPendingUninstall: z.boolean(), + isUpToDate: z.boolean(), + osArch: z.string(), + accountId: z.string(), + locationEnabled: z.boolean(), + consoleMigrationStatus: z.string(), + scanFinishedAt: z.string().nullable().default(null), + operationalStateExpiration: z.string().nullable().default(null), + agentVersion: z.string(), + isActive: z.boolean(), + locationType: z.string(), + activeThreats: z.coerce.number(), + inRemoteShellSession: z.boolean(), + allowRemoteShell: z.boolean(), + serialNumber: z.string().nullable().default(null), + updatedAt: z.string(), + lastActiveDate: z.string(), + firstFullModeTime: z.string().nullable().default(null), + operationalState: z.string(), + externalId: z.string(), + mitigationModeSuspicious: z.string(), + licenseKey: z.string(), + cpuCount: z.coerce.number(), + mitigationMode: z.string(), + networkStatus: z.string(), + installerType: z.string(), + uuid: z.string(), + detectionState: z.string().nullable().default(null), + infected: z.boolean(), + registeredAt: z.string(), + lastIpToMgmt: z.string(), + storageName: z.string().nullable().default(null), + osUsername: z.string().nullable().default(null), + groupIp: z.string(), + createdAt: z.string(), + remoteProfilingState: z.string(), + groupUpdatedAt: z.string().nullable().default(null), + scanAbortedAt: z.string().nullable().default(null), + isUninstalled: z.boolean(), + networkQuarantineEnabled: z.boolean(), + tags: z .object({ - type: z.string(), - example: z.string(), - enum: z.array(z.string()), + sentinelone: z.array( + z + .object({ + assignedBy: z.string(), + assignedAt: z.string(), + assignedById: z.string(), + key: z.string(), + value: z.string(), + id: z.string(), + }) + .strict() + ), }) - .passthrough() - ), - locations: z - .array(z.object({ name: z.string(), scope: z.string(), id: z.string() }).passthrough()) - .nullable() - .default(null), - id: z.string(), - coreCount: z.coerce.number(), - osRevision: z.string(), - osType: z.string(), - groupId: z.string(), - computerName: z.string(), - scanStartedAt: z.string(), - encryptedApplications: z.boolean(), - storageType: z.string().nullable().default(null), - networkInterfaces: z.array( - z + .strict(), + externalIp: z.string(), + siteId: z.string(), + machineType: z.string(), + domain: z.string(), + scanStatus: z.string(), + osStartTime: z.string(), + accountName: z.string(), + lastLoggedInUserName: z.string(), + showAlertIcon: z.boolean(), + rangerStatus: z.string(), + groupName: z.string(), + threatRebootRequired: z.boolean(), + remoteProfilingStateExpiration: z.string().nullable().default(null), + policyUpdatedAt: z.string().nullable().default(null), + activeDirectory: z .object({ - gatewayMacAddress: z.string().nullable().default(null), - inet6: z.array(z.string()), - name: z.string(), - inet: z.array(z.string()), - physical: z.string(), - gatewayIp: z.string().nullable().default(null), - id: z.string(), + userPrincipalName: z.string().nullable().default(null), + lastUserDistinguishedName: z.string().nullable().default(null), + computerMemberOf: z.array(z.object({ type: z.string() }).passthrough()), + lastUserMemberOf: z.array(z.object({ type: z.string() }).passthrough()), + mail: z.string().nullable().default(null), + computerDistinguishedName: z.string().nullable().default(null), }) - .passthrough() - ), - fullDiskScanLastUpdatedAt: z.string(), - appsVulnerabilityStatus: z.string(), - }) - .passthrough() - ), - }) - .passthrough(); + .passthrough(), + isDecommissioned: z.boolean(), + rangerVersion: z.string(), + userActionsNeeded: z.array( + z + .object({ + type: z.string(), + example: z.string(), + enum: z.array(z.string()), + }) + .passthrough() + ), + locations: z + .array( + z.object({ name: z.string(), scope: z.string(), id: z.string() }).passthrough() + ) + .nullable() + .default(null), + id: z.string(), + coreCount: z.coerce.number(), + osRevision: z.string(), + osType: z.string(), + groupId: z.string(), + computerName: z.string(), + scanStartedAt: z.string(), + encryptedApplications: z.boolean(), + storageType: z.string().nullable().default(null), + networkInterfaces: z.array( + z + .object({ + gatewayMacAddress: z.string().nullable().default(null), + inet6: z.array(z.string()), + name: z.string(), + inet: z.array(z.string()), + physical: z.string(), + gatewayIp: z.string().nullable().default(null), + id: z.string(), + }) + .passthrough() + ), + fullDiskScanLastUpdatedAt: z.string(), + appsVulnerabilityStatus: z.string(), + }) + .passthrough() + ), + }) + .passthrough() +); -export const SentinelOneIsolateHostResponseSchema = z - .object({ - errors: z.array(z.string()).nullable().default(null), - data: z.object({ affected: z.coerce.number() }).passthrough(), - }) - .strict(); +export const SentinelOneIsolateHostResponseSchema = lazySchema(() => + z + .object({ + errors: z.array(z.string()).nullable().default(null), + data: z.object({ affected: z.coerce.number() }).passthrough(), + }) + .strict() +); -export const SentinelOneGetRemoteScriptsParamsSchema = z - .object({ - query: z.string().nullable().default(null), - // Possible values (multiples comma delimiter): `linux` or `macos` or `windows` - osTypes: z.string().nullable().default(null), - // possible values (multiples comma delimiter): `action` or `artifactCollection` or `dataCollection` - scriptType: z.string().nullable().default(null), - // Cursor position returned by the last request. Use to iterate over more than 1000 items. Example: "YWdlbnRfaWQ6NTgwMjkzODE=". - cursor: z.string().nullable().default(null), - // List of group IDs to filter by. Example: "225494730938493804,225494730938493915". - groupIds: z.string().nullable().default(null), - // A list of script IDs. Example: "225494730938493804,225494730938493915". - ids: z.string().nullable().default(null), - // Is the script runnable in Advanced Response Scripts - isAvailableForArs: z.boolean().nullable().default(null), - // Limit number of returned items (1-1000). Example: "10". - limit: z.coerce.number().max(1000).min(1).default(10).nullable().default(null), - // List of Site IDs to filter by. Example: "225494730938493804,225494730938493915". - siteIds: z.string().nullable().default(null), - // Skip first number of items (0-1000). To iterate over more than 1000 items, use "cursor". Example: "150". - skip: z.coerce.number().nullable().default(null), - // If true, total number of items will not be calculated, which speeds up execution time. - skipCount: z.boolean().nullable().default(null), - // The column to sort the results by. Example: "id". - sortBy: z.string().nullable().default(null), - // Sort direction. Example: "asc" or "desc" - sortOrder: z.string().nullable().default(null), - }) - .strict(); +export const SentinelOneGetRemoteScriptsParamsSchema = lazySchema(() => + z + .object({ + query: z.string().nullable().default(null), + // Possible values (multiples comma delimiter): `linux` or `macos` or `windows` + osTypes: z.string().nullable().default(null), + // possible values (multiples comma delimiter): `action` or `artifactCollection` or `dataCollection` + scriptType: z.string().nullable().default(null), + // Cursor position returned by the last request. Use to iterate over more than 1000 items. Example: "YWdlbnRfaWQ6NTgwMjkzODE=". + cursor: z.string().nullable().default(null), + // List of group IDs to filter by. Example: "225494730938493804,225494730938493915". + groupIds: z.string().nullable().default(null), + // A list of script IDs. Example: "225494730938493804,225494730938493915". + ids: z.string().nullable().default(null), + // Is the script runnable in Advanced Response Scripts + isAvailableForArs: z.boolean().nullable().default(null), + // Limit number of returned items (1-1000). Example: "10". + limit: z.coerce.number().max(1000).min(1).default(10).nullable().default(null), + // List of Site IDs to filter by. Example: "225494730938493804,225494730938493915". + siteIds: z.string().nullable().default(null), + // Skip first number of items (0-1000). To iterate over more than 1000 items, use "cursor". Example: "150". + skip: z.coerce.number().nullable().default(null), + // If true, total number of items will not be calculated, which speeds up execution time. + skipCount: z.boolean().nullable().default(null), + // The column to sort the results by. Example: "id". + sortBy: z.string().nullable().default(null), + // Sort direction. Example: "asc" or "desc" + sortOrder: z.string().nullable().default(null), + }) + .strict() +); -export const SentinelOneFetchAgentFilesParamsSchema = z - .object({ - agentId: z.string().min(1), - zipPassCode: z.string().min(10), - files: z.array(z.string().min(1)), - }) - .strict(); +export const SentinelOneFetchAgentFilesParamsSchema = lazySchema(() => + z + .object({ + agentId: z.string().min(1), + zipPassCode: z.string().min(10), + files: z.array(z.string().min(1)), + }) + .strict() +); -export const SentinelOneFetchAgentFilesResponseSchema = z - .object({ - errors: z.array(z.string()).nullable().default(null), - data: z - .object({ - success: z.boolean(), - }) - .passthrough() - .optional(), - }) - .passthrough(); +export const SentinelOneFetchAgentFilesResponseSchema = lazySchema(() => + z + .object({ + errors: z.array(z.string()).nullable().default(null), + data: z + .object({ + success: z.boolean(), + }) + .passthrough() + .optional(), + }) + .passthrough() +); -export const SentinelOneDownloadAgentFileParamsSchema = z - .object({ - agentId: z.string().min(1), - activityId: z.string().min(1), - }) - .strict(); +export const SentinelOneDownloadAgentFileParamsSchema = lazySchema(() => + z + .object({ + agentId: z.string().min(1), + activityId: z.string().min(1), + }) + .strict() +); -export const SentinelOneDownloadAgentFileResponseSchema = z.any(); +export const SentinelOneDownloadAgentFileResponseSchema = lazySchema(() => z.any()); -export const SentinelOneGetActivitiesParamsSchema = z - .object({ - accountIds: z.string().min(1).optional(), - activityTypes: z.string().optional(), - activityUuids: z.string().min(1).optional(), - agentIds: z.string().min(1).optional(), - alertIds: z.string().min(1).optional(), - countOnly: z.boolean().optional(), - createdAt__between: z.string().min(1).optional(), - createdAt__gt: z.string().min(1).optional(), - createdAt__gte: z.string().min(1).optional(), - createdAt__lt: z.string().min(1).optional(), - createdAt__lte: z.string().min(1).optional(), - cursor: z.string().min(1).optional(), - groupIds: z.string().min(1).optional(), - ids: z.string().min(1).optional(), - includeHidden: z.boolean().optional(), - limit: z.coerce.number().optional(), - ruleIds: z.string().min(1).optional(), - siteIds: z.string().min(1).optional(), - skip: z.coerce.number().optional(), - skipCount: z.boolean().optional(), - sortBy: z.string().min(1).optional(), - sortOrder: z.string().min(1).optional(), - threatIds: z.string().min(1).optional(), - userEmails: z.string().min(1).optional(), - userIds: z.string().min(1).optional(), - }) - .strict() - .optional(); +export const SentinelOneGetActivitiesParamsSchema = lazySchema(() => + z + .object({ + accountIds: z.string().min(1).optional(), + activityTypes: z.string().optional(), + activityUuids: z.string().min(1).optional(), + agentIds: z.string().min(1).optional(), + alertIds: z.string().min(1).optional(), + countOnly: z.boolean().optional(), + createdAt__between: z.string().min(1).optional(), + createdAt__gt: z.string().min(1).optional(), + createdAt__gte: z.string().min(1).optional(), + createdAt__lt: z.string().min(1).optional(), + createdAt__lte: z.string().min(1).optional(), + cursor: z.string().min(1).optional(), + groupIds: z.string().min(1).optional(), + ids: z.string().min(1).optional(), + includeHidden: z.boolean().optional(), + limit: z.coerce.number().optional(), + ruleIds: z.string().min(1).optional(), + siteIds: z.string().min(1).optional(), + skip: z.coerce.number().optional(), + skipCount: z.boolean().optional(), + sortBy: z.string().min(1).optional(), + sortOrder: z.string().min(1).optional(), + threatIds: z.string().min(1).optional(), + userEmails: z.string().min(1).optional(), + userIds: z.string().min(1).optional(), + }) + .strict() + .optional() +); -export const SentinelOneGetActivitiesResponseDataSchema = z - .object({ - accountId: z.string(), - accountName: z.string(), - activityType: z.coerce.number(), - activityUuid: z.string(), - agentId: z.string().nullable().default(null), - agentUpdatedVersion: z.string().nullable().default(null), - comments: z.string().nullable().default(null), - createdAt: z.string(), - data: z - .object({ - // Empty by design. - // The SentinelOne Activity Log can place any (unknown) data here - }) - .passthrough(), - description: z.string().nullable().default(null), - groupId: z.string().nullable().default(null), - groupName: z.string().nullable().default(null), - hash: z.string().nullable().default(null), - id: z.string(), - osFamily: z.string().nullable().default(null), - primaryDescription: z.string().nullable().default(null), - secondaryDescription: z.string().nullable().default(null), - siteId: z.string(), - siteName: z.string(), - threatId: z.string().nullable().default(null), - updatedAt: z.string(), - userId: z.string().nullable().default(null), - }) - .passthrough(); +export const SentinelOneGetActivitiesResponseDataSchema = lazySchema(() => + z + .object({ + accountId: z.string(), + accountName: z.string(), + activityType: z.coerce.number(), + activityUuid: z.string(), + agentId: z.string().nullable().default(null), + agentUpdatedVersion: z.string().nullable().default(null), + comments: z.string().nullable().default(null), + createdAt: z.string(), + data: z + .object({ + // Empty by design. + // The SentinelOne Activity Log can place any (unknown) data here + }) + .passthrough(), + description: z.string().nullable().default(null), + groupId: z.string().nullable().default(null), + groupName: z.string().nullable().default(null), + hash: z.string().nullable().default(null), + id: z.string(), + osFamily: z.string().nullable().default(null), + primaryDescription: z.string().nullable().default(null), + secondaryDescription: z.string().nullable().default(null), + siteId: z.string(), + siteName: z.string(), + threatId: z.string().nullable().default(null), + updatedAt: z.string(), + userId: z.string().nullable().default(null), + }) + .passthrough() +); -export const SentinelOneGetActivitiesResponseNoDataSchema = - SentinelOneGetActivitiesResponseDataSchema.omit({ data: true }); +export const SentinelOneGetActivitiesResponseNoDataSchema = lazySchema(() => + SentinelOneGetActivitiesResponseDataSchema.omit({ data: true }) +); -export const SentinelOneGetActivitiesResponseSchema = z - .object({ - errors: z.array(z.string()).optional(), - pagination: z - .object({ - nextCursor: z.string().nullable().default(null), - totalItems: z.coerce.number(), - }) - .strict(), - data: z.array(SentinelOneGetActivitiesResponseDataSchema), - }) - .passthrough(); +export const SentinelOneGetActivitiesResponseSchema = lazySchema(() => + z + .object({ + errors: z.array(z.string()).optional(), + pagination: z + .object({ + nextCursor: z.string().nullable().default(null), + totalItems: z.coerce.number(), + }) + .strict(), + data: z.array(SentinelOneGetActivitiesResponseDataSchema), + }) + .passthrough() +); -export const AlertIds = z.array(z.string()).optional(); +export const AlertIds = lazySchema(() => z.array(z.string()).optional()); -export const SentinelOneGetRemoteScriptsResponseSchema = z - .object({ - errors: z.array(z.string()).nullable().default(null), - pagination: z - .object({ - nextCursor: z.string().nullable().default(null), - totalItems: z.coerce.number(), - }) - .strict(), - data: z.array( - z +export const SentinelOneGetRemoteScriptsResponseSchema = lazySchema(() => + z + .object({ + errors: z.array(z.string()).nullable().default(null), + pagination: z .object({ - id: z.string(), - updater: z.string().nullable().default(null), - isAvailableForLite: z.boolean(), - isAvailableForArs: z.boolean(), - fileSize: z.coerce.number(), - mgmtId: z.coerce.number(), - scopeLevel: z.string(), - shortFileName: z.string(), - scriptName: z.string(), - creator: z.string(), - package: z + nextCursor: z.string().nullable().default(null), + totalItems: z.coerce.number(), + }) + .strict(), + data: z.array( + z + .object({ + id: z.string(), + updater: z.string().nullable().default(null), + isAvailableForLite: z.boolean(), + isAvailableForArs: z.boolean(), + fileSize: z.coerce.number(), + mgmtId: z.coerce.number(), + scopeLevel: z.string(), + shortFileName: z.string(), + scriptName: z.string(), + creator: z.string(), + package: z + .object({ + id: z.string(), + bucketName: z.string(), + endpointExpiration: z.string(), + fileName: z.string(), + endpointExpirationSeconds: z.coerce.number().nullable().default(null), + fileSize: z.coerce.number(), + signatureType: z.string(), + signature: z.string(), + }) + .passthrough() + .nullable() + .default(null), + bucketName: z.string(), + inputRequired: z.boolean(), + fileName: z.string(), + supportedDestinations: z.array(z.string()).nullable().default(null), + scopeName: z.string().nullable().default(null), + signatureType: z.string(), + outputFilePaths: z.array(z.string()).nullable().default(null), + scriptDescription: z.string().nullable().default(null), + createdByUserId: z.string(), + scopeId: z.string(), + updatedAt: z.string(), + scriptType: z.string(), + scopePath: z.string(), + creatorId: z.string(), + osTypes: z.array(z.string()), + scriptRuntimeTimeoutSeconds: z.coerce.number(), + version: z.string(), + updaterId: z.string().nullable().default(null), + createdAt: z.string(), + inputExample: z.string().nullable().default(null), + inputInstructions: z.string().nullable().default(null), + signature: z.string(), + createdByUser: z.string(), + requiresApproval: z.boolean().optional(), + }) + .passthrough() + ), + }) + .passthrough() +); + +export const SentinelOneExecuteScriptParamsSchema = lazySchema(() => + z + .object({ + // Only a sub-set of filters are defined below. This API, however, support many more filters + // which can be added in the future if needed. + filter: z + .object({ + uuids: z.string().min(1).optional(), + ids: z.string().min(1).optional(), + }) + .strict(), + script: z + .object({ + apiKey: z.string().optional(), + inputParams: z.string().optional(), + outputDirectory: z.string().optional(), + outputDestination: z + .enum(['Local', 'None', 'SentinelCloud', 'SingularityXDR']) + .optional(), + passwordFromScope: z .object({ - id: z.string(), - bucketName: z.string(), - endpointExpiration: z.string(), - fileName: z.string(), - endpointExpirationSeconds: z.coerce.number().nullable().default(null), - fileSize: z.coerce.number(), - signatureType: z.string(), - signature: z.string(), + scopeLevel: z.string().optional(), + scopeId: z.string().optional(), }) - .passthrough() - .nullable() - .default(null), - bucketName: z.string(), - inputRequired: z.boolean(), - fileName: z.string(), - supportedDestinations: z.array(z.string()).nullable().default(null), - scopeName: z.string().nullable().default(null), - signatureType: z.string(), - outputFilePaths: z.array(z.string()).nullable().default(null), - scriptDescription: z.string().nullable().default(null), - createdByUserId: z.string(), - scopeId: z.string(), - updatedAt: z.string(), - scriptType: z.string(), - scopePath: z.string(), - creatorId: z.string(), - osTypes: z.array(z.string()), - scriptRuntimeTimeoutSeconds: z.coerce.number(), - version: z.string(), - updaterId: z.string().nullable().default(null), - createdAt: z.string(), - inputExample: z.string().nullable().default(null), - inputInstructions: z.string().nullable().default(null), - signature: z.string(), - createdByUser: z.string(), + .strict() + .optional(), + password: z.string().optional(), requiresApproval: z.boolean().optional(), + scriptId: z.string(), + scriptName: z.string().optional(), + scriptRuntimeTimeoutSeconds: z.coerce.number().optional(), + singularityxdrKeyword: z.string().optional(), + singularityxdrUrl: z.string().optional(), + taskDescription: z.string().optional(), }) - .passthrough() - ), - }) - .passthrough(); + .strict(), + alertIds: AlertIds, + }) + .strict() +); -export const SentinelOneExecuteScriptParamsSchema = z - .object({ - // Only a sub-set of filters are defined below. This API, however, support many more filters - // which can be added in the future if needed. - filter: z - .object({ - uuids: z.string().min(1).optional(), - ids: z.string().min(1).optional(), - }) - .strict(), - script: z - .object({ - apiKey: z.string().optional(), - inputParams: z.string().optional(), - outputDirectory: z.string().optional(), - outputDestination: z.enum(['Local', 'None', 'SentinelCloud', 'SingularityXDR']).optional(), - passwordFromScope: z - .object({ - scopeLevel: z.string().optional(), - scopeId: z.string().optional(), - }) - .strict() - .optional(), - password: z.string().optional(), - requiresApproval: z.boolean().optional(), - scriptId: z.string(), - scriptName: z.string().optional(), - scriptRuntimeTimeoutSeconds: z.coerce.number().optional(), - singularityxdrKeyword: z.string().optional(), - singularityxdrUrl: z.string().optional(), - taskDescription: z.string().optional(), - }) - .strict(), - alertIds: AlertIds, - }) - .strict(); - -export const SentinelOneExecuteScriptResponseSchema = z - .object({ - errors: z.array(z.object({}).passthrough()).nullable().default(null), - data: z - .object({ - pendingExecutionId: z.string().nullable().default(null), - affected: z.coerce.number().nullable().default(null), - parentTaskId: z.string().nullable().default(null), - pending: z.boolean().nullable().default(null), - }) - .passthrough() - .nullable() - .default(null), - }) - .passthrough(); +export const SentinelOneExecuteScriptResponseSchema = lazySchema(() => + z + .object({ + errors: z.array(z.object({}).passthrough()).nullable().default(null), + data: z + .object({ + pendingExecutionId: z.string().nullable().default(null), + affected: z.coerce.number().nullable().default(null), + parentTaskId: z.string().nullable().default(null), + pending: z.boolean().nullable().default(null), + }) + .passthrough() + .nullable() + .default(null), + }) + .passthrough() +); -export const SentinelOneGetRemoteScriptResultsParamsSchema = z - .object({ - taskIds: z.array(z.string()), - }) - .strict(); +export const SentinelOneGetRemoteScriptResultsParamsSchema = lazySchema(() => + z + .object({ + taskIds: z.array(z.string()), + }) + .strict() +); -export const SentinelOneGetRemoteScriptResultsResponseSchema = z - .object({ - errors: z - .array(z.object({ type: z.string() }).passthrough()) - .nullable() - .default(null), - data: z.any(), - }) - .passthrough(); +export const SentinelOneGetRemoteScriptResultsResponseSchema = lazySchema(() => + z + .object({ + errors: z + .array(z.object({ type: z.string() }).passthrough()) + .nullable() + .default(null), + data: z.any(), + }) + .passthrough() +); -export const SentinelOneDownloadRemoteScriptResultsParamsSchema = z - .object({ - taskId: z.string().min(1), - }) - .strict(); +export const SentinelOneDownloadRemoteScriptResultsParamsSchema = lazySchema(() => + z + .object({ + taskId: z.string().min(1), + }) + .strict() +); -export const SentinelOneDownloadRemoteScriptResultsResponseSchema = z.any(); +export const SentinelOneDownloadRemoteScriptResultsResponseSchema = lazySchema(() => z.any()); -export const SentinelOneGetRemoteScriptStatusParamsSchema = z - .object({ - parentTaskId: z.string(), - }) - .passthrough(); +export const SentinelOneGetRemoteScriptStatusParamsSchema = lazySchema(() => + z + .object({ + parentTaskId: z.string(), + }) + .passthrough() +); -export const SentinelOneGetRemoteScriptStatusResponseSchema = z - .object({ - pagination: z - .object({ - totalItems: z.coerce.number(), - nextCursor: z.string().nullable().default(null), - }) - .strict(), - errors: z - .array(z.object({ type: z.string() }).passthrough()) - .nullable() - .default(null), - data: z.array(z.map(z.string(), z.any())), - }) - .passthrough(); +export const SentinelOneGetRemoteScriptStatusResponseSchema = lazySchema(() => + z + .object({ + pagination: z + .object({ + totalItems: z.coerce.number(), + nextCursor: z.string().nullable().default(null), + }) + .strict(), + errors: z + .array(z.object({ type: z.string() }).passthrough()) + .nullable() + .default(null), + data: z.array(z.map(z.string(), z.any())), + }) + .passthrough() +); -export const SentinelOneBaseFilterSchema = z - .object({ - K8SNodeName__contains: z.string().nullable().default(null), - coreCount__lt: z.string().nullable().default(null), - rangerStatuses: z.string().nullable().default(null), - adUserQuery__contains: z.string().nullable().default(null), - rangerVersionsNin: z.string().nullable().default(null), - rangerStatusesNin: z.string().nullable().default(null), - coreCount__gte: z.string().nullable().default(null), - threatCreatedAt__gte: z.string().nullable().default(null), - decommissionedAt__lte: z.string().nullable().default(null), - operationalStatesNin: z.string().nullable().default(null), - appsVulnerabilityStatusesNin: z.string().nullable().default(null), - mitigationMode: z.string().nullable().default(null), - createdAt__gte: z.string().nullable().default(null), - gatewayIp: z.string().nullable().default(null), - cloudImage__contains: z.string().nullable().default(null), - registeredAt__between: z.string().nullable().default(null), - threatMitigationStatus: z.string().nullable().default(null), - installerTypesNin: z.string().nullable().default(null), - appsVulnerabilityStatuses: z.string().nullable().default(null), - threatResolved: z.string().nullable().default(null), - mitigationModeSuspicious: z.string().nullable().default(null), - isUpToDate: z.string().nullable().default(null), - adComputerQuery__contains: z.string().nullable().default(null), - updatedAt__gte: z.string().nullable().default(null), - azureResourceGroup__contains: z.string().nullable().default(null), - scanStatus: z.string().nullable().default(null), - threatContentHash: z.string().nullable().default(null), - osTypesNin: z.string().nullable().default(null), - threatRebootRequired: z.string().nullable().default(null), - totalMemory__between: z.string().nullable().default(null), - firewallEnabled: z.string().nullable().default(null), - gcpServiceAccount__contains: z.string().nullable().default(null), - updatedAt__gt: z.string().nullable().default(null), - remoteProfilingStates: z.string().nullable().default(null), - filteredGroupIds: z.string().nullable().default(null), - agentVersions: z.string().nullable().default(null), - activeThreats: z.string().nullable().default(null), - machineTypesNin: z.string().nullable().default(null), - lastActiveDate__gt: z.string().nullable().default(null), - awsSubnetIds__contains: z.string().nullable().default(null), - installerTypes: z.string().nullable().default(null), - registeredAt__gte: z.string().nullable().default(null), - migrationStatus: z.string().nullable().default(null), - cloudTags__contains: z.string().nullable().default(null), - totalMemory__gte: z.string().nullable().default(null), - decommissionedAt__lt: z.string().nullable().default(null), - threatCreatedAt__lt: z.string().nullable().default(null), - updatedAt__lte: z.string().nullable().default(null), - osArch: z.string().nullable().default(null), - registeredAt__gt: z.string().nullable().default(null), - registeredAt__lt: z.string().nullable().default(null), - siteIds: z.string().nullable().default(null), - networkInterfaceInet__contains: z.string().nullable().default(null), - groupIds: z.string().nullable().default(null), - uuids: z.string().nullable().default(null), - accountIds: z.string().nullable().default(null), - scanStatusesNin: z.string().nullable().default(null), - cpuCount__lte: z.string().nullable().default(null), - locationIds: z.string().nullable().default(null), - awsSecurityGroups__contains: z.string().nullable().default(null), - networkStatusesNin: z.string().nullable().default(null), - activeThreats__gt: z.string().nullable().default(null), - infected: z.string().nullable().default(null), - osVersion__contains: z.string().nullable().default(null), - machineTypes: z.string().nullable().default(null), - agentPodName__contains: z.string().nullable().default(null), - computerName__like: z.string().nullable().default(null), - threatCreatedAt__gt: z.string().nullable().default(null), - consoleMigrationStatusesNin: z.string().nullable().default(null), - computerName: z.string().nullable().default(null), - decommissionedAt__between: z.string().nullable().default(null), - cloudInstanceId__contains: z.string().nullable().default(null), - createdAt__lte: z.string().nullable().default(null), - coreCount__between: z.string().nullable().default(null), - totalMemory__lte: z.string().nullable().default(null), - remoteProfilingStatesNin: z.string().nullable().default(null), - adComputerMember__contains: z.string().nullable().default(null), - threatCreatedAt__between: z.string().nullable().default(null), - totalMemory__gt: z.string().nullable().default(null), - ids: z.string().nullable().default(null), - agentVersionsNin: z.string().nullable().default(null), - updatedAt__between: z.string().nullable().default(null), - locationEnabled: z.string().nullable().default(null), - locationIdsNin: z.string().nullable().default(null), - osTypes: z.string().nullable().default(null), - encryptedApplications: z.string().nullable().default(null), - filterId: z.string().nullable().default(null), - decommissionedAt__gt: z.string().nullable().default(null), - adUserMember__contains: z.string().nullable().default(null), - uuid: z.string().nullable().default(null), - coreCount__lte: z.string().nullable().default(null), - coreCount__gt: z.string().nullable().default(null), - cloudNetwork__contains: z.string().nullable().default(null), - clusterName__contains: z.string().nullable().default(null), - cpuCount__gte: z.string().nullable().default(null), - query: z.string().nullable().default(null), - lastActiveDate__between: z.string().nullable().default(null), - rangerStatus: z.string().nullable().default(null), - domains: z.string().nullable().default(null), - cloudProvider: z.string().nullable().default(null), - lastActiveDate__lt: z.string().nullable().default(null), - scanStatuses: z.string().nullable().default(null), - hasLocalConfiguration: z.string().nullable().default(null), - networkStatuses: z.string().nullable().default(null), - isPendingUninstall: z.string().nullable().default(null), - createdAt__gt: z.string().nullable().default(null), - cpuCount__lt: z.string().nullable().default(null), - consoleMigrationStatuses: z.string().nullable().default(null), - adQuery: z.string().nullable().default(null), - updatedAt__lt: z.string().nullable().default(null), - createdAt__lt: z.string().nullable().default(null), - adComputerName__contains: z.string().nullable().default(null), - cloudInstanceSize__contains: z.string().nullable().default(null), - registeredAt__lte: z.string().nullable().default(null), - networkQuarantineEnabled: z.string().nullable().default(null), - cloudAccount__contains: z.string().nullable().default(null), - cloudLocation__contains: z.string().nullable().default(null), - rangerVersions: z.string().nullable().default(null), - networkInterfaceGatewayMacAddress__contains: z.string().nullable().default(null), - uuid__contains: z.string().nullable().default(null), - agentNamespace__contains: z.string().nullable().default(null), - K8SNodeLabels__contains: z.string().nullable().default(null), - adQuery__contains: z.string().nullable().default(null), - K8SType__contains: z.string().nullable().default(null), - countsFor: z.string().nullable().default(null), - totalMemory__lt: z.string().nullable().default(null), - externalId__contains: z.string().nullable().default(null), - filteredSiteIds: z.string().nullable().default(null), - decommissionedAt__gte: z.string().nullable().default(null), - cpuCount__gt: z.string().nullable().default(null), - threatHidden: z.string().nullable().default(null), - isUninstalled: z.string().nullable().default(null), - computerName__contains: z.string().nullable().default(null), - lastActiveDate__lte: z.string().nullable().default(null), - adUserName__contains: z.string().nullable().default(null), - isActive: z.string().nullable().default(null), - userActionsNeeded: z.string().nullable().default(null), - threatCreatedAt__lte: z.string().nullable().default(null), - domainsNin: z.string().nullable().default(null), - operationalStates: z.string().nullable().default(null), - externalIp__contains: z.string().nullable().default(null), - isDecommissioned: z.string().nullable().default(null), - networkInterfacePhysical__contains: z.string().nullable().default(null), - lastActiveDate__gte: z.string().nullable().default(null), - createdAt__between: z.string().nullable().default(null), - cpuCount__between: z.string().nullable().default(null), - lastLoggedInUserName__contains: z.string().nullable().default(null), - awsRole__contains: z.string().nullable().default(null), - K8SVersion__contains: z.string().nullable().default(null), - alertIds: AlertIds, - }) - .strict(); +export const SentinelOneBaseFilterSchema = lazySchema(() => + z + .object({ + K8SNodeName__contains: z.string().nullable().default(null), + coreCount__lt: z.string().nullable().default(null), + rangerStatuses: z.string().nullable().default(null), + adUserQuery__contains: z.string().nullable().default(null), + rangerVersionsNin: z.string().nullable().default(null), + rangerStatusesNin: z.string().nullable().default(null), + coreCount__gte: z.string().nullable().default(null), + threatCreatedAt__gte: z.string().nullable().default(null), + decommissionedAt__lte: z.string().nullable().default(null), + operationalStatesNin: z.string().nullable().default(null), + appsVulnerabilityStatusesNin: z.string().nullable().default(null), + mitigationMode: z.string().nullable().default(null), + createdAt__gte: z.string().nullable().default(null), + gatewayIp: z.string().nullable().default(null), + cloudImage__contains: z.string().nullable().default(null), + registeredAt__between: z.string().nullable().default(null), + threatMitigationStatus: z.string().nullable().default(null), + installerTypesNin: z.string().nullable().default(null), + appsVulnerabilityStatuses: z.string().nullable().default(null), + threatResolved: z.string().nullable().default(null), + mitigationModeSuspicious: z.string().nullable().default(null), + isUpToDate: z.string().nullable().default(null), + adComputerQuery__contains: z.string().nullable().default(null), + updatedAt__gte: z.string().nullable().default(null), + azureResourceGroup__contains: z.string().nullable().default(null), + scanStatus: z.string().nullable().default(null), + threatContentHash: z.string().nullable().default(null), + osTypesNin: z.string().nullable().default(null), + threatRebootRequired: z.string().nullable().default(null), + totalMemory__between: z.string().nullable().default(null), + firewallEnabled: z.string().nullable().default(null), + gcpServiceAccount__contains: z.string().nullable().default(null), + updatedAt__gt: z.string().nullable().default(null), + remoteProfilingStates: z.string().nullable().default(null), + filteredGroupIds: z.string().nullable().default(null), + agentVersions: z.string().nullable().default(null), + activeThreats: z.string().nullable().default(null), + machineTypesNin: z.string().nullable().default(null), + lastActiveDate__gt: z.string().nullable().default(null), + awsSubnetIds__contains: z.string().nullable().default(null), + installerTypes: z.string().nullable().default(null), + registeredAt__gte: z.string().nullable().default(null), + migrationStatus: z.string().nullable().default(null), + cloudTags__contains: z.string().nullable().default(null), + totalMemory__gte: z.string().nullable().default(null), + decommissionedAt__lt: z.string().nullable().default(null), + threatCreatedAt__lt: z.string().nullable().default(null), + updatedAt__lte: z.string().nullable().default(null), + osArch: z.string().nullable().default(null), + registeredAt__gt: z.string().nullable().default(null), + registeredAt__lt: z.string().nullable().default(null), + siteIds: z.string().nullable().default(null), + networkInterfaceInet__contains: z.string().nullable().default(null), + groupIds: z.string().nullable().default(null), + uuids: z.string().nullable().default(null), + accountIds: z.string().nullable().default(null), + scanStatusesNin: z.string().nullable().default(null), + cpuCount__lte: z.string().nullable().default(null), + locationIds: z.string().nullable().default(null), + awsSecurityGroups__contains: z.string().nullable().default(null), + networkStatusesNin: z.string().nullable().default(null), + activeThreats__gt: z.string().nullable().default(null), + infected: z.string().nullable().default(null), + osVersion__contains: z.string().nullable().default(null), + machineTypes: z.string().nullable().default(null), + agentPodName__contains: z.string().nullable().default(null), + computerName__like: z.string().nullable().default(null), + threatCreatedAt__gt: z.string().nullable().default(null), + consoleMigrationStatusesNin: z.string().nullable().default(null), + computerName: z.string().nullable().default(null), + decommissionedAt__between: z.string().nullable().default(null), + cloudInstanceId__contains: z.string().nullable().default(null), + createdAt__lte: z.string().nullable().default(null), + coreCount__between: z.string().nullable().default(null), + totalMemory__lte: z.string().nullable().default(null), + remoteProfilingStatesNin: z.string().nullable().default(null), + adComputerMember__contains: z.string().nullable().default(null), + threatCreatedAt__between: z.string().nullable().default(null), + totalMemory__gt: z.string().nullable().default(null), + ids: z.string().nullable().default(null), + agentVersionsNin: z.string().nullable().default(null), + updatedAt__between: z.string().nullable().default(null), + locationEnabled: z.string().nullable().default(null), + locationIdsNin: z.string().nullable().default(null), + osTypes: z.string().nullable().default(null), + encryptedApplications: z.string().nullable().default(null), + filterId: z.string().nullable().default(null), + decommissionedAt__gt: z.string().nullable().default(null), + adUserMember__contains: z.string().nullable().default(null), + uuid: z.string().nullable().default(null), + coreCount__lte: z.string().nullable().default(null), + coreCount__gt: z.string().nullable().default(null), + cloudNetwork__contains: z.string().nullable().default(null), + clusterName__contains: z.string().nullable().default(null), + cpuCount__gte: z.string().nullable().default(null), + query: z.string().nullable().default(null), + lastActiveDate__between: z.string().nullable().default(null), + rangerStatus: z.string().nullable().default(null), + domains: z.string().nullable().default(null), + cloudProvider: z.string().nullable().default(null), + lastActiveDate__lt: z.string().nullable().default(null), + scanStatuses: z.string().nullable().default(null), + hasLocalConfiguration: z.string().nullable().default(null), + networkStatuses: z.string().nullable().default(null), + isPendingUninstall: z.string().nullable().default(null), + createdAt__gt: z.string().nullable().default(null), + cpuCount__lt: z.string().nullable().default(null), + consoleMigrationStatuses: z.string().nullable().default(null), + adQuery: z.string().nullable().default(null), + updatedAt__lt: z.string().nullable().default(null), + createdAt__lt: z.string().nullable().default(null), + adComputerName__contains: z.string().nullable().default(null), + cloudInstanceSize__contains: z.string().nullable().default(null), + registeredAt__lte: z.string().nullable().default(null), + networkQuarantineEnabled: z.string().nullable().default(null), + cloudAccount__contains: z.string().nullable().default(null), + cloudLocation__contains: z.string().nullable().default(null), + rangerVersions: z.string().nullable().default(null), + networkInterfaceGatewayMacAddress__contains: z.string().nullable().default(null), + uuid__contains: z.string().nullable().default(null), + agentNamespace__contains: z.string().nullable().default(null), + K8SNodeLabels__contains: z.string().nullable().default(null), + adQuery__contains: z.string().nullable().default(null), + K8SType__contains: z.string().nullable().default(null), + countsFor: z.string().nullable().default(null), + totalMemory__lt: z.string().nullable().default(null), + externalId__contains: z.string().nullable().default(null), + filteredSiteIds: z.string().nullable().default(null), + decommissionedAt__gte: z.string().nullable().default(null), + cpuCount__gt: z.string().nullable().default(null), + threatHidden: z.string().nullable().default(null), + isUninstalled: z.string().nullable().default(null), + computerName__contains: z.string().nullable().default(null), + lastActiveDate__lte: z.string().nullable().default(null), + adUserName__contains: z.string().nullable().default(null), + isActive: z.string().nullable().default(null), + userActionsNeeded: z.string().nullable().default(null), + threatCreatedAt__lte: z.string().nullable().default(null), + domainsNin: z.string().nullable().default(null), + operationalStates: z.string().nullable().default(null), + externalIp__contains: z.string().nullable().default(null), + isDecommissioned: z.string().nullable().default(null), + networkInterfacePhysical__contains: z.string().nullable().default(null), + lastActiveDate__gte: z.string().nullable().default(null), + createdAt__between: z.string().nullable().default(null), + cpuCount__between: z.string().nullable().default(null), + lastLoggedInUserName__contains: z.string().nullable().default(null), + awsRole__contains: z.string().nullable().default(null), + K8SVersion__contains: z.string().nullable().default(null), + alertIds: AlertIds, + }) + .strict() +); export const SentinelOneIsolateHostParamsSchema = SentinelOneBaseFilterSchema; export const SentinelOneGetAgentsParamsSchema = SentinelOneBaseFilterSchema; -export const SentinelOneIsolateHostSchema = z - .object({ - subAction: z.literal(SUB_ACTION.ISOLATE_HOST), - subActionParams: SentinelOneIsolateHostParamsSchema, - }) - .strict(); +export const SentinelOneIsolateHostSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.ISOLATE_HOST), + subActionParams: SentinelOneIsolateHostParamsSchema, + }) + .strict() +); -export const SentinelOneReleaseHostSchema = z - .object({ - subAction: z.literal(SUB_ACTION.RELEASE_HOST), - subActionParams: SentinelOneIsolateHostParamsSchema, - }) - .strict(); +export const SentinelOneReleaseHostSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.RELEASE_HOST), + subActionParams: SentinelOneIsolateHostParamsSchema, + }) + .strict() +); -export const SentinelOneExecuteScriptSchema = z - .object({ - subAction: z.literal(SUB_ACTION.EXECUTE_SCRIPT), - subActionParams: SentinelOneExecuteScriptParamsSchema, - }) - .strict(); +export const SentinelOneExecuteScriptSchema = lazySchema(() => + z + .object({ + subAction: z.literal(SUB_ACTION.EXECUTE_SCRIPT), + subActionParams: SentinelOneExecuteScriptParamsSchema, + }) + .strict() +); -export const SentinelOneActionParamsSchema = z.union([ - SentinelOneIsolateHostSchema, - SentinelOneReleaseHostSchema, - SentinelOneExecuteScriptSchema, -]); +export const SentinelOneActionParamsSchema = lazySchema(() => + z.union([ + SentinelOneIsolateHostSchema, + SentinelOneReleaseHostSchema, + SentinelOneExecuteScriptSchema, + ]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/server_log/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/server_log/schemas/v1.ts index 121e0155ccd54..aa88a544dfdb4 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/server_log/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/server_log/schemas/v1.ts @@ -6,13 +6,15 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; -export const ConfigSchema = z.object({}).strict().default({}); -export const SecretsSchema = z.object({}).strict().default({}); -export const ParamsSchema = z - .object({ - message: z.string(), - level: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'), - }) - .strict(); +export const ConfigSchema = lazySchema(() => z.object({}).strict().default({})); +export const SecretsSchema = lazySchema(() => z.object({}).strict().default({})); +export const ParamsSchema = lazySchema(() => + z + .object({ + message: z.string(), + level: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/servicenow/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/servicenow/schemas/v1.ts index dcb17ecdc785b..8627fb9ae5e89 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/servicenow/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/servicenow/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { Coerced, validateRecordKeysAllowed, validateRecordMaxKeys } from '../../common/utils'; import { DEFAULT_ALERTS_GROUPING_KEY, MAX_ADDITIONAL_FIELDS_LENGTH } from '../constants'; @@ -23,13 +23,13 @@ export const ExternalIncidentServiceConfiguration = { usesTableApi: z.boolean().default(true), }; -export const ExternalIncidentServiceConfigurationBaseSchema = z - .object(ExternalIncidentServiceConfigurationBase) - .strict(); +export const ExternalIncidentServiceConfigurationBaseSchema = lazySchema(() => + z.object(ExternalIncidentServiceConfigurationBase).strict() +); -export const ExternalIncidentServiceConfigurationSchema = z - .object(ExternalIncidentServiceConfiguration) - .strict(); +export const ExternalIncidentServiceConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceConfiguration).strict() +); export const ExternalIncidentServiceSecretConfiguration = { password: z.string().nullable().default(null), // required if isOAuth = false @@ -39,21 +39,23 @@ export const ExternalIncidentServiceSecretConfiguration = { privateKeyPassword: z.string().nullable().default(null), }; -export const ExternalIncidentServiceSecretConfigurationSchema = z - .object(ExternalIncidentServiceSecretConfiguration) - .strict(); +export const ExternalIncidentServiceSecretConfigurationSchema = lazySchema(() => + z.object(ExternalIncidentServiceSecretConfiguration).strict() +); -export const CommentsSchema = z - .array( - z - .object({ - comment: z.string(), - commentId: z.string(), - }) - .strict() - ) - .nullable() - .default(null); +export const CommentsSchema = lazySchema(() => + z + .array( + z + .object({ + comment: z.string(), + commentId: z.string(), + }) + .strict() + ) + .nullable() + .default(null) +); export const CommonAttributes = { short_description: z.string(), @@ -89,29 +91,35 @@ export const CommonAttributes = { export const commonIncidentSchemaObjectProperties = Object.keys(CommonAttributes); -export const ExecutorSubActionGetChoicesParamsSchema = z - .object({ - fields: z.array(z.string()), - }) - .strict(); +export const ExecutorSubActionGetChoicesParamsSchema = lazySchema(() => + z + .object({ + fields: z.array(z.string()), + }) + .strict() +); -export const ExecutorSubActionGetIncidentParamsSchema = z - .object({ - externalId: z.string(), - }) - .strict(); +export const ExecutorSubActionGetIncidentParamsSchema = lazySchema(() => + z + .object({ + externalId: z.string(), + }) + .strict() +); -export const ExecutorSubActionCloseIncidentParamsSchema = z - .object({ - incident: z - .object({ - externalId: z.string().nullable().default(null), - correlation_id: z.string().default(DEFAULT_ALERTS_GROUPING_KEY).nullable(), - }) - .strict(), - }) - .strict(); +export const ExecutorSubActionCloseIncidentParamsSchema = lazySchema(() => + z + .object({ + incident: z + .object({ + externalId: z.string().nullable().default(null), + correlation_id: z.string().default(DEFAULT_ALERTS_GROUPING_KEY).nullable(), + }) + .strict(), + }) + .strict() +); // Reserved for future implementation -export const ExecutorSubActionHandshakeParamsSchema = z.object({}).strict(); -export const ExecutorSubActionCommonFieldsParamsSchema = z.object({}).strict(); +export const ExecutorSubActionHandshakeParamsSchema = lazySchema(() => z.object({}).strict()); +export const ExecutorSubActionCommonFieldsParamsSchema = lazySchema(() => z.object({}).strict()); diff --git a/src/platform/packages/shared/kbn-connector-schemas/servicenow_itom/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/servicenow_itom/schemas/v1.ts index c2fe5bf5ebf02..02c23a3484c38 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/servicenow_itom/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/servicenow_itom/schemas/v1.ts @@ -6,39 +6,43 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { DEFAULT_ALERTS_GROUPING_KEY, ExecutorSubActionGetChoicesParamsSchema, } from '../../servicenow'; -export const ExecutorSubActionAddEventParamsSchema = z - .object({ - source: z.string().nullable().default(null), - event_class: z.string().nullable().default(null), - resource: z.string().nullable().default(null), - node: z.string().nullable().default(null), - metric_name: z.string().nullable().default(null), - type: z.string().nullable().default(null), - severity: z.string().nullable().default(null), - description: z.string().nullable().default(null), - additional_info: z.string().nullable().default(null), - message_key: z.string().nullable().default(DEFAULT_ALERTS_GROUPING_KEY), - time_of_event: z.string().nullable().default(null), - }) - .strict(); - -export const ExecutorParamsSchemaITOM = z.discriminatedUnion('subAction', [ +export const ExecutorSubActionAddEventParamsSchema = lazySchema(() => z .object({ - subAction: z.literal('addEvent'), - subActionParams: ExecutorSubActionAddEventParamsSchema, + source: z.string().nullable().default(null), + event_class: z.string().nullable().default(null), + resource: z.string().nullable().default(null), + node: z.string().nullable().default(null), + metric_name: z.string().nullable().default(null), + type: z.string().nullable().default(null), + severity: z.string().nullable().default(null), + description: z.string().nullable().default(null), + additional_info: z.string().nullable().default(null), + message_key: z.string().nullable().default(DEFAULT_ALERTS_GROUPING_KEY), + time_of_event: z.string().nullable().default(null), }) - .strict(), - z - .object({ - subAction: z.literal('getChoices'), - subActionParams: ExecutorSubActionGetChoicesParamsSchema, - }) - .strict(), -]); + .strict() +); + +export const ExecutorParamsSchemaITOM = lazySchema(() => + z.discriminatedUnion('subAction', [ + z + .object({ + subAction: z.literal('addEvent'), + subActionParams: ExecutorSubActionAddEventParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('getChoices'), + subActionParams: ExecutorSubActionGetChoicesParamsSchema, + }) + .strict(), + ]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/servicenow_itsm/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/servicenow_itsm/schemas/v1.ts index adcc0b95caee7..ae04329a1c556 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/servicenow_itsm/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/servicenow_itsm/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { CommentsSchema, CommonAttributes, @@ -17,55 +17,59 @@ import { ExecutorSubActionHandshakeParamsSchema, } from '../../servicenow'; -export const ExecutorSubActionPushParamsSchemaITSM = z - .object({ - incident: z - .object({ - ...CommonAttributes, - severity: z.string().nullable().default(null), - urgency: z.string().nullable().default(null), - impact: z.string().nullable().default(null), - }) - .strict(), - comments: CommentsSchema, - }) - .strict(); - -export const ExecutorParamsSchemaITSM = z.discriminatedUnion('subAction', [ - z - .object({ - subAction: z.literal('getFields'), - subActionParams: ExecutorSubActionCommonFieldsParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('getIncident'), - subActionParams: ExecutorSubActionGetIncidentParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('handshake'), - subActionParams: ExecutorSubActionHandshakeParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('pushToService'), - subActionParams: ExecutorSubActionPushParamsSchemaITSM, - }) - .strict(), - z - .object({ - subAction: z.literal('getChoices'), - subActionParams: ExecutorSubActionGetChoicesParamsSchema, - }) - .strict(), +export const ExecutorSubActionPushParamsSchemaITSM = lazySchema(() => z .object({ - subAction: z.literal('closeIncident'), - subActionParams: ExecutorSubActionCloseIncidentParamsSchema, + incident: z + .object({ + ...CommonAttributes, + severity: z.string().nullable().default(null), + urgency: z.string().nullable().default(null), + impact: z.string().nullable().default(null), + }) + .strict(), + comments: CommentsSchema, }) - .strict(), -]); + .strict() +); + +export const ExecutorParamsSchemaITSM = lazySchema(() => + z.discriminatedUnion('subAction', [ + z + .object({ + subAction: z.literal('getFields'), + subActionParams: ExecutorSubActionCommonFieldsParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('getIncident'), + subActionParams: ExecutorSubActionGetIncidentParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('handshake'), + subActionParams: ExecutorSubActionHandshakeParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchemaITSM, + }) + .strict(), + z + .object({ + subAction: z.literal('getChoices'), + subActionParams: ExecutorSubActionGetChoicesParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('closeIncident'), + subActionParams: ExecutorSubActionCloseIncidentParamsSchema, + }) + .strict(), + ]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/servicenow_sir/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/servicenow_sir/schemas/v1.ts index 3e8f6a27e3265..11558857650b1 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/servicenow_sir/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/servicenow_sir/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { CommentsSchema, CommonAttributes, @@ -17,72 +17,76 @@ import { } from '../../servicenow'; // Schema for ServiceNow Security Incident Response (SIR) -export const ExecutorSubActionPushParamsSchemaSIR = z - .object({ - incident: z - .object({ - ...CommonAttributes, - dest_ip: z - .union([ - z.string().nullable().default(null), - z.array(z.string()).nullable().default(null), - ]) - .default(null), - malware_hash: z - .union([ - z.string().nullable().default(null), - z.array(z.string()).nullable().default(null), - ]) - .default(null), - malware_url: z - .union([ - z.string().nullable().default(null), - z.array(z.string()).nullable().default(null), - ]) - .default(null), - source_ip: z - .union([ - z.string().nullable().default(null), - z.array(z.string()).nullable().default(null), - ]) - .default(null), - priority: z.string().nullable().default(null), - }) - .strict(), - comments: CommentsSchema, - }) - .strict(); - -// Executor parameters for ServiceNow Security Incident Response (SIR) -export const ExecutorParamsSchemaSIR = z.discriminatedUnion('subAction', [ - z - .object({ - subAction: z.literal('getFields'), - subActionParams: ExecutorSubActionCommonFieldsParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('getIncident'), - subActionParams: ExecutorSubActionGetIncidentParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('handshake'), - subActionParams: ExecutorSubActionHandshakeParamsSchema, - }) - .strict(), - z - .object({ - subAction: z.literal('pushToService'), - subActionParams: ExecutorSubActionPushParamsSchemaSIR, - }) - .strict(), +export const ExecutorSubActionPushParamsSchemaSIR = lazySchema(() => z .object({ - subAction: z.literal('getChoices'), - subActionParams: ExecutorSubActionGetChoicesParamsSchema, + incident: z + .object({ + ...CommonAttributes, + dest_ip: z + .union([ + z.string().nullable().default(null), + z.array(z.string()).nullable().default(null), + ]) + .default(null), + malware_hash: z + .union([ + z.string().nullable().default(null), + z.array(z.string()).nullable().default(null), + ]) + .default(null), + malware_url: z + .union([ + z.string().nullable().default(null), + z.array(z.string()).nullable().default(null), + ]) + .default(null), + source_ip: z + .union([ + z.string().nullable().default(null), + z.array(z.string()).nullable().default(null), + ]) + .default(null), + priority: z.string().nullable().default(null), + }) + .strict(), + comments: CommentsSchema, }) - .strict(), -]); + .strict() +); + +// Executor parameters for ServiceNow Security Incident Response (SIR) +export const ExecutorParamsSchemaSIR = lazySchema(() => + z.discriminatedUnion('subAction', [ + z + .object({ + subAction: z.literal('getFields'), + subActionParams: ExecutorSubActionCommonFieldsParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('getIncident'), + subActionParams: ExecutorSubActionGetIncidentParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('handshake'), + subActionParams: ExecutorSubActionHandshakeParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchemaSIR, + }) + .strict(), + z + .object({ + subAction: z.literal('getChoices'), + subActionParams: ExecutorSubActionGetChoicesParamsSchema, + }) + .strict(), + ]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/slack/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/slack/schemas/v1.ts index 8ead0726d0270..38095583cdb4d 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/slack/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/slack/schemas/v1.ts @@ -6,17 +6,19 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; -export const ConfigSchema = z.object({}).strict().default({}); +export const ConfigSchema = lazySchema(() => z.object({}).strict().default({})); const secretsSchemaProps = { webhookUrl: z.string(), }; -export const SecretsSchema = z.object(secretsSchemaProps).strict(); +export const SecretsSchema = lazySchema(() => z.object(secretsSchemaProps).strict()); -export const ParamsSchema = z - .object({ - message: z.string().min(1), - }) - .strict(); +export const ParamsSchema = lazySchema(() => + z + .object({ + message: z.string().min(1), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/slack_api/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/slack_api/schemas/v1.ts index 3bc8944ed5113..539e10be0fa0f 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/slack_api/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/slack_api/schemas/v1.ts @@ -6,61 +6,71 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; export const MAX_ALLOWED_CHANNELS = 500; -export const SlackApiSecretsSchema = z - .object({ - token: z.string().min(1), - }) - .strict(); +export const SlackApiSecretsSchema = lazySchema(() => + z + .object({ + token: z.string().min(1), + }) + .strict() +); -export const SlackApiConfigSchema = z - .object({ - allowedChannels: z - .array( - z - .object({ - id: z.string().min(1).optional(), - name: z.string().min(1), - }) - .strict() - ) - .max(MAX_ALLOWED_CHANNELS) - .optional(), - }) - .strict(); +export const SlackApiConfigSchema = lazySchema(() => + z + .object({ + allowedChannels: z + .array( + z + .object({ + id: z.string().min(1).optional(), + name: z.string().min(1), + }) + .strict() + ) + .max(MAX_ALLOWED_CHANNELS) + .optional(), + }) + .strict() +); -export const ValidChannelIdSubActionParamsSchema = z - .object({ - channelId: z.string().optional(), - }) - .strict(); +export const ValidChannelIdSubActionParamsSchema = lazySchema(() => + z + .object({ + channelId: z.string().optional(), + }) + .strict() +); -export const ValidChannelIdParamsSchema = z - .object({ - subAction: z.literal('validChannelId'), - subActionParams: ValidChannelIdSubActionParamsSchema, - }) - .strict(); +export const ValidChannelIdParamsSchema = lazySchema(() => + z + .object({ + subAction: z.literal('validChannelId'), + subActionParams: ValidChannelIdSubActionParamsSchema, + }) + .strict() +); -export const PostMessageSubActionParamsSchema = z - .object({ - /** - * @deprecated Use `channelNames` or `channelIds` instead - * `channelNames` takes priority over `channelIds` and `channels` - */ - channels: z.array(z.string()).max(1).optional(), - channelIds: z.array(z.string()).max(1).optional(), - channelNames: z - // min of two characters to account for '#' prefix - .array(z.string().min(2).max(200).superRefine(validateChannelName)) - .max(1) - .optional(), - text: z.string().min(1), - }) - .strict(); +export const PostMessageSubActionParamsSchema = lazySchema(() => + z + .object({ + /** + * @deprecated Use `channelNames` or `channelIds` instead + * `channelNames` takes priority over `channelIds` and `channels` + */ + channels: z.array(z.string()).max(1).optional(), + channelIds: z.array(z.string()).max(1).optional(), + channelNames: z + // min of two characters to account for '#' prefix + .array(z.string().min(2).max(200).superRefine(validateChannelName)) + .max(1) + .optional(), + text: z.string().min(1), + }) + .strict() +); export function validateBlockkit(text: string, ctx: z.RefinementCtx) { try { @@ -97,35 +107,39 @@ export function validateChannelName(value: string | undefined, ctx: z.Refinement } } -export const PostBlockkitSubActionParamsSchema = z - .object({ - /** - * @deprecated Use `channelNames` or `channelIds` instead - * `channelNames` takes priority over `channelIds` and `channels` - */ - channels: z.array(z.string()).max(1).optional(), - channelIds: z.array(z.string()).max(1).optional(), - channelNames: z.array(z.string().superRefine(validateChannelName)).max(1).optional(), - text: z.string().superRefine(validateBlockkit), - }) - .strict(); +export const PostBlockkitSubActionParamsSchema = lazySchema(() => + z + .object({ + /** + * @deprecated Use `channelNames` or `channelIds` instead + * `channelNames` takes priority over `channelIds` and `channels` + */ + channels: z.array(z.string()).max(1).optional(), + channelIds: z.array(z.string()).max(1).optional(), + channelNames: z.array(z.string().superRefine(validateChannelName)).max(1).optional(), + text: z.string().superRefine(validateBlockkit), + }) + .strict() +); -export const PostMessageParamsSchema = z - .object({ - subAction: z.literal('postMessage'), - subActionParams: PostMessageSubActionParamsSchema, - }) - .strict(); +export const PostMessageParamsSchema = lazySchema(() => + z + .object({ + subAction: z.literal('postMessage'), + subActionParams: PostMessageSubActionParamsSchema, + }) + .strict() +); -export const PostBlockkitParamsSchema = z - .object({ - subAction: z.literal('postBlockkit'), - subActionParams: PostBlockkitSubActionParamsSchema, - }) - .strict(); +export const PostBlockkitParamsSchema = lazySchema(() => + z + .object({ + subAction: z.literal('postBlockkit'), + subActionParams: PostBlockkitSubActionParamsSchema, + }) + .strict() +); -export const SlackApiParamsSchema = z.union([ - ValidChannelIdParamsSchema, - PostMessageParamsSchema, - PostBlockkitParamsSchema, -]); +export const SlackApiParamsSchema = lazySchema(() => + z.union([ValidChannelIdParamsSchema, PostMessageParamsSchema, PostBlockkitParamsSchema]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/swimlane/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/swimlane/schemas/v1.ts index fcc247b52e21d..6c955c8f9635e 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/swimlane/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/swimlane/schemas/v1.ts @@ -6,7 +6,7 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; export const ConfigMap = { id: z.string(), @@ -15,7 +15,7 @@ export const ConfigMap = { fieldType: z.string(), }; -export const ConfigMapSchema = z.object(ConfigMap).strict(); +export const ConfigMapSchema = lazySchema(() => z.object(ConfigMap).strict()); export const ConfigMapping = { ruleNameConfig: ConfigMapSchema.nullable().default(null), @@ -27,7 +27,7 @@ export const ConfigMapping = { descriptionConfig: ConfigMapSchema.nullable().default(null), }; -export const ConfigMappingSchema = z.object(ConfigMapping).strict(); +export const ConfigMappingSchema = lazySchema(() => z.object(ConfigMapping).strict()); export const SwimlaneServiceConfiguration = { apiUrl: z.string(), @@ -36,13 +36,17 @@ export const SwimlaneServiceConfiguration = { mappings: ConfigMappingSchema, }; -export const SwimlaneServiceConfigurationSchema = z.object(SwimlaneServiceConfiguration).strict(); +export const SwimlaneServiceConfigurationSchema = lazySchema(() => + z.object(SwimlaneServiceConfiguration).strict() +); export const SwimlaneSecretsConfiguration = { apiToken: z.string(), }; -export const SwimlaneSecretsConfigurationSchema = z.object(SwimlaneSecretsConfiguration).strict(); +export const SwimlaneSecretsConfigurationSchema = lazySchema(() => + z.object(SwimlaneSecretsConfiguration).strict() +); const SwimlaneFields = { alertId: z.string().nullable().default(null), @@ -53,26 +57,30 @@ const SwimlaneFields = { description: z.string().nullable().default(null), }; -export const ExecutorSubActionPushParamsSchema = z - .object({ - incident: z - .object({ - ...SwimlaneFields, - externalId: z.string().nullable().default(null), - }) - .strict(), - comments: z - .array(z.object({ comment: z.string(), commentId: z.string() }).strict()) - .nullable() - .default(null), - }) - .strict(); - -export const ExecutorParamsSchema = z.discriminatedUnion('subAction', [ +export const ExecutorSubActionPushParamsSchema = lazySchema(() => z .object({ - subAction: z.literal('pushToService'), - subActionParams: ExecutorSubActionPushParamsSchema, + incident: z + .object({ + ...SwimlaneFields, + externalId: z.string().nullable().default(null), + }) + .strict(), + comments: z + .array(z.object({ comment: z.string(), commentId: z.string() }).strict()) + .nullable() + .default(null), }) - .strict(), -]); + .strict() +); + +export const ExecutorParamsSchema = lazySchema(() => + z.discriminatedUnion('subAction', [ + z + .object({ + subAction: z.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchema, + }) + .strict(), + ]) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/teams/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/teams/schemas/v1.ts index a27f89b9148b0..8b702ea99ef88 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/teams/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/teams/schemas/v1.ts @@ -6,15 +6,17 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; -export const ConfigSchema = z.object({}).strict().default({}); +export const ConfigSchema = lazySchema(() => z.object({}).strict().default({})); const secretsSchemaProps = { webhookUrl: z.string(), }; -export const SecretsSchema = z.object(secretsSchemaProps).strict(); -export const ParamsSchema = z - .object({ - message: z.string().min(1), - }) - .strict(); +export const SecretsSchema = lazySchema(() => z.object(secretsSchemaProps).strict()); +export const ParamsSchema = lazySchema(() => + z + .object({ + message: z.string().min(1), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/thehive/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/thehive/schemas/v1.ts index 6b0f2881c7a7d..dd5a43adee506 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/thehive/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/thehive/schemas/v1.ts @@ -7,47 +7,53 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { z } from '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { TheHiveSeverity, TheHiveTLP, SUB_ACTION } from '../constants'; -export const TheHiveConfigSchema = z - .object({ - url: z.string(), - organisation: z.string().nullable().default(null), - }) - .strict(); +export const TheHiveConfigSchema = lazySchema(() => + z + .object({ + url: z.string(), + organisation: z.string().nullable().default(null), + }) + .strict() +); -export const TheHiveSecretsSchema = z - .object({ - apiKey: z.string(), - }) - .strict(); +export const TheHiveSecretsSchema = lazySchema(() => + z + .object({ + apiKey: z.string(), + }) + .strict() +); -export const ExecutorSubActionPushParamsSchema = z - .object({ - incident: z - .object({ - title: z.string(), - description: z.string(), - externalId: z.string().nullable().default(null), - severity: z.coerce.number().default(TheHiveSeverity.MEDIUM).nullable().default(null), - tlp: z.coerce.number().default(TheHiveTLP.AMBER).nullable().default(null), - tags: z.array(z.string()).nullable().default(null), - }) - .strict(), - comments: z - .array( - z - .object({ - comment: z.string(), - commentId: z.string(), - }) - .strict() - ) - .nullable() - .default(null), - }) - .strict(); +export const ExecutorSubActionPushParamsSchema = lazySchema(() => + z + .object({ + incident: z + .object({ + title: z.string(), + description: z.string(), + externalId: z.string().nullable().default(null), + severity: z.coerce.number().default(TheHiveSeverity.MEDIUM).nullable().default(null), + tlp: z.coerce.number().default(TheHiveTLP.AMBER).nullable().default(null), + tags: z.array(z.string()).nullable().default(null), + }) + .strict(), + comments: z + .array( + z + .object({ + comment: z.string(), + commentId: z.string(), + }) + .strict() + ) + .nullable() + .default(null), + }) + .strict() +); export const PushToServiceIncidentSchema = { title: z.string(), @@ -57,141 +63,155 @@ export const PushToServiceIncidentSchema = { tags: z.array(z.string()).nullable().default(null), }; -export const ExecutorSubActionGetIncidentParamsSchema = z - .object({ - externalId: z.string(), - }) - .strict(); - -export const ExecutorSubActionCreateAlertParamsSchema = z - .object({ - title: z.string(), - description: z.string(), - type: z.string(), - source: z.string(), - sourceRef: z.string(), - severity: z.coerce.number().default(TheHiveSeverity.MEDIUM).nullable().default(null), - isRuleSeverity: z.boolean().default(false).nullable(), - tlp: z.coerce.number().default(TheHiveTLP.AMBER).nullable().default(null), - tags: z.array(z.string()).nullable().default(null), - body: z.string().nullable().default(null), - }) - .strict(); - -export const ExecutorParamsSchema = z.union([ +export const ExecutorSubActionGetIncidentParamsSchema = lazySchema(() => z .object({ - subAction: z.literal(SUB_ACTION.PUSH_TO_SERVICE), - subActionParams: ExecutorSubActionPushParamsSchema, + externalId: z.string(), }) - .strict(), + .strict() +); + +export const ExecutorSubActionCreateAlertParamsSchema = lazySchema(() => z .object({ - subAction: z.literal(SUB_ACTION.CREATE_ALERT), - subActionParams: ExecutorSubActionCreateAlertParamsSchema, + title: z.string(), + description: z.string(), + type: z.string(), + source: z.string(), + sourceRef: z.string(), + severity: z.coerce.number().default(TheHiveSeverity.MEDIUM).nullable().default(null), + isRuleSeverity: z.boolean().default(false).nullable(), + tlp: z.coerce.number().default(TheHiveTLP.AMBER).nullable().default(null), + tags: z.array(z.string()).nullable().default(null), + body: z.string().nullable().default(null), }) - .strict(), -]); + .strict() +); -export const TheHiveIncidentResponseSchema = z.object({ - _id: z.string(), - _type: z.string(), - _createdBy: z.string(), - _updatedBy: z.string().nullable().default(null), - _createdAt: z.coerce.number(), - _updatedAt: z.coerce.number().nullable().default(null), - number: z.coerce.number(), - title: z.string(), - description: z.string(), - severity: z.coerce.number(), - severityLabel: z.string(), - startDate: z.coerce.number(), - endDate: z.coerce.number().nullable().default(null), - tags: z.array(z.string()).nullable().default(null), - flag: z.boolean(), - tlp: z.coerce.number(), - tlpLabel: z.string(), - pap: z.coerce.number(), - papLabel: z.string(), - status: z.string(), - stage: z.string(), - summary: z.string().nullable().default(null), - impactStatus: z.string().nullable().default(null), - assignee: z.string().nullable().default(null), - customFields: z.array(z.record(z.string(), z.any())).nullable().default(null), - userPermissions: z.array(z.string()).nullable().default(null), - extraData: z.object({}).passthrough(), - newDate: z.coerce.number(), - inProgressDate: z.coerce.number().nullable().default(null), - closedDate: z.coerce.number().nullable().default(null), - alertDate: z.coerce.number().nullable().default(null), - alertNewDate: z.coerce.number().nullable().default(null), - alertInProgressDate: z.coerce.number().nullable().default(null), - alertImportedDate: z.coerce.number().nullable().default(null), - timeToDetect: z.coerce.number(), - timeToTriage: z.coerce.number().nullable().default(null), - timeToQualify: z.coerce.number().nullable().default(null), - timeToAcknowledge: z.coerce.number().nullable().default(null), - timeToResolve: z.coerce.number().nullable().default(null), - handlingDuration: z.coerce.number().nullable().default(null), -}); +export const ExecutorParamsSchema = lazySchema(() => + z.union([ + z + .object({ + subAction: z.literal(SUB_ACTION.PUSH_TO_SERVICE), + subActionParams: ExecutorSubActionPushParamsSchema, + }) + .strict(), + z + .object({ + subAction: z.literal(SUB_ACTION.CREATE_ALERT), + subActionParams: ExecutorSubActionCreateAlertParamsSchema, + }) + .strict(), + ]) +); + +export const TheHiveIncidentResponseSchema = lazySchema(() => + z.object({ + _id: z.string(), + _type: z.string(), + _createdBy: z.string(), + _updatedBy: z.string().nullable().default(null), + _createdAt: z.coerce.number(), + _updatedAt: z.coerce.number().nullable().default(null), + number: z.coerce.number(), + title: z.string(), + description: z.string(), + severity: z.coerce.number(), + severityLabel: z.string(), + startDate: z.coerce.number(), + endDate: z.coerce.number().nullable().default(null), + tags: z.array(z.string()).nullable().default(null), + flag: z.boolean(), + tlp: z.coerce.number(), + tlpLabel: z.string(), + pap: z.coerce.number(), + papLabel: z.string(), + status: z.string(), + stage: z.string(), + summary: z.string().nullable().default(null), + impactStatus: z.string().nullable().default(null), + assignee: z.string().nullable().default(null), + customFields: z.array(z.record(z.string(), z.any())).nullable().default(null), + userPermissions: z.array(z.string()).nullable().default(null), + extraData: z.object({}).passthrough(), + newDate: z.coerce.number(), + inProgressDate: z.coerce.number().nullable().default(null), + closedDate: z.coerce.number().nullable().default(null), + alertDate: z.coerce.number().nullable().default(null), + alertNewDate: z.coerce.number().nullable().default(null), + alertInProgressDate: z.coerce.number().nullable().default(null), + alertImportedDate: z.coerce.number().nullable().default(null), + timeToDetect: z.coerce.number(), + timeToTriage: z.coerce.number().nullable().default(null), + timeToQualify: z.coerce.number().nullable().default(null), + timeToAcknowledge: z.coerce.number().nullable().default(null), + timeToResolve: z.coerce.number().nullable().default(null), + handlingDuration: z.coerce.number().nullable().default(null), + }) +); -export const TheHiveUpdateIncidentResponseSchema = z.any(); +export const TheHiveUpdateIncidentResponseSchema = lazySchema(() => z.any()); -export const TheHiveAddCommentResponseSchema = z.object({ - _id: z.string(), - _type: z.string(), - createdBy: z.string(), - createdAt: z.coerce.number(), - updatedAt: z.coerce.number().nullable().default(null), - updatedBy: z.string().nullable().default(null), - message: z.string(), - isEdited: z.boolean(), - extraData: z.object({}).passthrough(), -}); +export const TheHiveAddCommentResponseSchema = lazySchema(() => + z.object({ + _id: z.string(), + _type: z.string(), + createdBy: z.string(), + createdAt: z.coerce.number(), + updatedAt: z.coerce.number().nullable().default(null), + updatedBy: z.string().nullable().default(null), + message: z.string(), + isEdited: z.boolean(), + extraData: z.object({}).passthrough(), + }) +); -export const TheHiveCreateAlertResponseSchema = z.object({ - _id: z.string(), - _type: z.string(), - _createdBy: z.string(), - _updatedBy: z.string().nullable().default(null), - _createdAt: z.coerce.number(), - _updatedAt: z.coerce.number().nullable().default(null), - type: z.string(), - source: z.string(), - sourceRef: z.string(), - externalLink: z.string().nullable().default(null), - title: z.string(), - description: z.string(), - severity: z.coerce.number(), - severityLabel: z.string(), - date: z.coerce.number(), - tags: z.array(z.string()).nullable().default(null), - tlp: z.coerce.number(), - tlpLabel: z.string(), - pap: z.coerce.number(), - papLabel: z.string(), - follow: z.boolean().nullable().default(null), - customFields: z.array(z.object({}).passthrough()).nullable().default(null), - caseTemplate: z.string().nullable().default(null), - observableCount: z.coerce.number(), - caseId: z.string().nullable().default(null), - status: z.string(), - stage: z.string(), - assignee: z.string().nullable().default(null), - summary: z.string().nullable().default(null), - extraData: z.object({}).passthrough(), - newDate: z.coerce.number(), - inProgressDate: z.coerce.number().nullable().default(null), - closedDate: z.coerce.number().nullable().default(null), - importedDate: z.coerce.number().nullable().default(null), - timeToDetect: z.coerce.number(), - timeToTriage: z.coerce.number().nullable().default(null), - timeToQualify: z.coerce.number().nullable().default(null), - timeToAcknowledge: z.coerce.number().nullable().default(null), -}); +export const TheHiveCreateAlertResponseSchema = lazySchema(() => + z.object({ + _id: z.string(), + _type: z.string(), + _createdBy: z.string(), + _updatedBy: z.string().nullable().default(null), + _createdAt: z.coerce.number(), + _updatedAt: z.coerce.number().nullable().default(null), + type: z.string(), + source: z.string(), + sourceRef: z.string(), + externalLink: z.string().nullable().default(null), + title: z.string(), + description: z.string(), + severity: z.coerce.number(), + severityLabel: z.string(), + date: z.coerce.number(), + tags: z.array(z.string()).nullable().default(null), + tlp: z.coerce.number(), + tlpLabel: z.string(), + pap: z.coerce.number(), + papLabel: z.string(), + follow: z.boolean().nullable().default(null), + customFields: z.array(z.object({}).passthrough()).nullable().default(null), + caseTemplate: z.string().nullable().default(null), + observableCount: z.coerce.number(), + caseId: z.string().nullable().default(null), + status: z.string(), + stage: z.string(), + assignee: z.string().nullable().default(null), + summary: z.string().nullable().default(null), + extraData: z.object({}).passthrough(), + newDate: z.coerce.number(), + inProgressDate: z.coerce.number().nullable().default(null), + closedDate: z.coerce.number().nullable().default(null), + importedDate: z.coerce.number().nullable().default(null), + timeToDetect: z.coerce.number(), + timeToTriage: z.coerce.number().nullable().default(null), + timeToQualify: z.coerce.number().nullable().default(null), + timeToAcknowledge: z.coerce.number().nullable().default(null), + }) +); -export const TheHiveFailureResponseSchema = z.object({ - type: z.coerce.number(), - message: z.string(), -}); +export const TheHiveFailureResponseSchema = lazySchema(() => + z.object({ + type: z.coerce.number(), + message: z.string(), + }) +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/tines/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/tines/schemas/v1.ts index d5afb65f81110..08ccfd07dbfa6 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/tines/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/tines/schemas/v1.ts @@ -6,57 +6,73 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; // Connector schema -export const TinesConfigSchema = z.object({ url: z.string() }).strict(); -export const TinesSecretsSchema = z.object({ email: z.string(), token: z.string() }).strict(); +export const TinesConfigSchema = lazySchema(() => z.object({ url: z.string() }).strict()); +export const TinesSecretsSchema = lazySchema(() => + z.object({ email: z.string(), token: z.string() }).strict() +); // Stories action schema export const TinesStoriesActionParamsSchema = null; -export const TinesStoryObjectSchema = z - .object({ +export const TinesStoryObjectSchema = lazySchema(() => + z + .object({ + id: z.coerce.number(), + name: z.string(), + published: z.boolean(), + }) + .strict() +); +export const TinesStoriesActionResponseSchema = lazySchema(() => + z + .object({ + stories: z.array(TinesStoryObjectSchema), + incompleteResponse: z.boolean(), + }) + .strict() +); + +// Webhooks action schema +export const TinesWebhooksActionParamsSchema = lazySchema(() => + z.object({ storyId: z.coerce.number() }).strict() +); +export const TinesWebhookObjectSchema = lazySchema(() => + z.object({ id: z.coerce.number(), name: z.string(), - published: z.boolean(), + storyId: z.coerce.number(), }) - .strict(); -export const TinesStoriesActionResponseSchema = z - .object({ - stories: z.array(TinesStoryObjectSchema), - incompleteResponse: z.boolean(), - }) - .strict(); - -// Webhooks action schema -export const TinesWebhooksActionParamsSchema = z.object({ storyId: z.coerce.number() }).strict(); -export const TinesWebhookObjectSchema = z.object({ - id: z.coerce.number(), - name: z.string(), - storyId: z.coerce.number(), -}); +); // Webhooks action configuration schema -export const TinesWebhookActionConfigSchema = z - .object({ - path: z.string(), - secret: z.string(), - }) - .strict(); +export const TinesWebhookActionConfigSchema = lazySchema(() => + z + .object({ + path: z.string(), + secret: z.string(), + }) + .strict() +); -export const TinesWebhooksActionResponseSchema = z - .object({ - webhooks: z.array(TinesWebhookObjectSchema), - incompleteResponse: z.boolean(), - }) - .strict(); +export const TinesWebhooksActionResponseSchema = lazySchema(() => + z + .object({ + webhooks: z.array(TinesWebhookObjectSchema), + incompleteResponse: z.boolean(), + }) + .strict() +); // Run action schema -export const TinesRunActionParamsSchema = z - .object({ - webhook: TinesWebhookObjectSchema.optional(), - webhookUrl: z.string().optional(), - body: z.string(), - }) - .strict(); -export const TinesRunActionResponseSchema = z.object({}); +export const TinesRunActionParamsSchema = lazySchema(() => + z + .object({ + webhook: TinesWebhookObjectSchema.optional(), + webhookUrl: z.string().optional(), + body: z.string(), + }) + .strict() +); +export const TinesRunActionResponseSchema = lazySchema(() => z.object({})); diff --git a/src/platform/packages/shared/kbn-connector-schemas/torq/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/torq/schemas/v1.ts index e8a063f4a274c..a4b32f62f58ed 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/torq/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/torq/schemas/v1.ts @@ -6,20 +6,22 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; const configSchemaProps = { webhookIntegrationUrl: z.string(), }; -export const ConfigSchema = z.object(configSchemaProps).strict(); +export const ConfigSchema = lazySchema(() => z.object(configSchemaProps).strict()); const secretSchemaProps = { token: z.string(), }; -export const SecretsSchema = z.object(secretSchemaProps).strict(); +export const SecretsSchema = lazySchema(() => z.object(secretSchemaProps).strict()); -export const ParamsSchema = z - .object({ - body: z.string(), - }) - .strict(); +export const ParamsSchema = lazySchema(() => + z + .object({ + body: z.string(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/webhook/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/webhook/schemas/v1.ts index aa081031154fb..8bd95aa979d94 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/webhook/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/webhook/schemas/v1.ts @@ -6,10 +6,10 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { AuthConfiguration, WebhookMethods } from '../../common/auth'; -export const HeadersSchema = z.record(z.string(), z.string()); +export const HeadersSchema = lazySchema(() => z.record(z.string(), z.string())); const configSchemaProps = { url: z.string(), @@ -47,13 +47,14 @@ function normalizeAuthTypeForUnauthenticatedConnectors(value: unknown): unknown return value; } -export const ConfigSchema = z.preprocess( - normalizeAuthTypeForUnauthenticatedConnectors, - z.object(configSchemaProps).strict() +export const ConfigSchema = lazySchema(() => + z.preprocess(normalizeAuthTypeForUnauthenticatedConnectors, z.object(configSchemaProps).strict()) ); -export const ParamsSchema = z - .object({ - body: z.string().optional(), - }) - .strict(); +export const ParamsSchema = lazySchema(() => + z + .object({ + body: z.string().optional(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/xmatters/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/xmatters/schemas/v1.ts index 4ba1b46921518..9c1c1d248165e 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/xmatters/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/xmatters/schemas/v1.ts @@ -6,29 +6,31 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; const configSchemaProps = { configUrl: z.string().nullable().default(null), usesBasic: z.boolean().default(true), }; -export const ConfigSchema = z.object(configSchemaProps).strict(); +export const ConfigSchema = lazySchema(() => z.object(configSchemaProps).strict()); const secretSchemaProps = { user: z.string().nullable().default(null), password: z.string().nullable().default(null), secretsUrl: z.string().nullable().default(null), }; -export const SecretsSchema = z.object(secretSchemaProps).strict(); +export const SecretsSchema = lazySchema(() => z.object(secretSchemaProps).strict()); -export const ParamsSchema = z - .object({ - alertActionGroupName: z.string().optional(), - signalId: z.string().optional(), - ruleName: z.string().optional(), - date: z.string().optional(), - severity: z.string(), - spaceId: z.string().optional(), - tags: z.string().optional(), - }) - .strict(); +export const ParamsSchema = lazySchema(() => + z + .object({ + alertActionGroupName: z.string().optional(), + signalId: z.string().optional(), + ruleName: z.string().optional(), + date: z.string().optional(), + severity: z.string(), + spaceId: z.string().optional(), + tags: z.string().optional(), + }) + .strict() +); diff --git a/src/platform/packages/shared/kbn-connector-schemas/xsoar/schemas/v1.ts b/src/platform/packages/shared/kbn-connector-schemas/xsoar/schemas/v1.ts index 1d851f66fe8cf..174d007993470 100644 --- a/src/platform/packages/shared/kbn-connector-schemas/xsoar/schemas/v1.ts +++ b/src/platform/packages/shared/kbn-connector-schemas/xsoar/schemas/v1.ts @@ -6,54 +6,66 @@ * 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 '@kbn/zod/v4'; +import { z, lazySchema } from '@kbn/zod/v4'; import { SUB_ACTION } from '../constants'; -export const ConfigSchema = z - .object({ - url: z.string(), - }) - .strict(); +export const ConfigSchema = lazySchema(() => + z + .object({ + url: z.string(), + }) + .strict() +); -export const SecretsSchema = z - .object({ - apiKey: z.string(), - apiKeyID: z.string().nullable().default(null), - }) - .strict(); +export const SecretsSchema = lazySchema(() => + z + .object({ + apiKey: z.string(), + apiKeyID: z.string().nullable().default(null), + }) + .strict() +); export const XSOARPlaybooksActionParamsSchema = null; -export const XSOARPlaybooksObjectSchema = z.object({ - id: z.string(), - name: z.string(), -}); -export const XSOARPlaybooksActionResponseSchema = z.object({ - playbooks: z.array(XSOARPlaybooksObjectSchema), -}); - -export const XSOARRunActionParamsSchema = z - .object({ +export const XSOARPlaybooksObjectSchema = lazySchema(() => + z.object({ + id: z.string(), name: z.string(), - playbookId: z.string().nullable().default(null), - createInvestigation: z.boolean(), - severity: z.coerce.number(), - isRuleSeverity: z.boolean().default(false).nullable(), - body: z.string().nullable().default(null), }) - .strict(); -export const XSOARRunActionResponseSchema = z.object({}); +); +export const XSOARPlaybooksActionResponseSchema = lazySchema(() => + z.object({ + playbooks: z.array(XSOARPlaybooksObjectSchema), + }) +); -export const ExecutorParamsSchema = z.union([ +export const XSOARRunActionParamsSchema = lazySchema(() => z .object({ - subAction: z.literal(SUB_ACTION.PLAYBOOKS), - subActionParams: z.literal(null), // this subaction not required any value as params + name: z.string(), + playbookId: z.string().nullable().default(null), + createInvestigation: z.boolean(), + severity: z.coerce.number(), + isRuleSeverity: z.boolean().default(false).nullable(), + body: z.string().nullable().default(null), }) - .strict(), - z - .object({ - subAction: z.literal(SUB_ACTION.RUN), - subActionParams: XSOARRunActionParamsSchema, - }) - .strict(), -]); + .strict() +); +export const XSOARRunActionResponseSchema = lazySchema(() => z.object({})); + +export const ExecutorParamsSchema = lazySchema(() => + z.union([ + z + .object({ + subAction: z.literal(SUB_ACTION.PLAYBOOKS), + subActionParams: z.literal(null), // this subaction not required any value as params + }) + .strict(), + z + .object({ + subAction: z.literal(SUB_ACTION.RUN), + subActionParams: XSOARRunActionParamsSchema, + }) + .strict(), + ]) +); diff --git a/x-pack/platform/plugins/shared/actions/server/integration_tests/connector_types.test.ts b/x-pack/platform/plugins/shared/actions/server/integration_tests/connector_types.test.ts index 3b2d74d609be1..35f6a0b8c7293 100644 --- a/x-pack/platform/plugins/shared/actions/server/integration_tests/connector_types.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/integration_tests/connector_types.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { z } from '@kbn/zod'; +import { z, setLazySchemaDisabled } from '@kbn/zod'; import type { TestElasticsearchUtils, TestKibanaUtils } from '@kbn/core-test-helpers-kbn-server'; import type { ActionTypeRegistry } from '../action_type_registry'; import { setupTestServers } from './lib'; @@ -49,6 +49,7 @@ describe('Connector type config checks', () => { let actionTypeRegistry: ActionTypeRegistry; beforeAll(async () => { + setLazySchemaDisabled(true); const setupResult = await setupTestServers(); esServer = setupResult.esServer; kibanaServer = setupResult.kibanaServer; @@ -59,6 +60,7 @@ describe('Connector type config checks', () => { }); afterAll(async () => { + setLazySchemaDisabled(false); if (kibanaServer) { await kibanaServer.stop(); }