import {z} from 'zod' export type ExperimentsDatadogEntryPointFilterColumnType = 'varchar' | 'int' | 'double' | 'boolean' | 'varchar_array' | 'int_array' | 'double_array' | 'raw'; export type ExperimentsDatadogEntryPointFilterOperation = 'eq' | 'in' | 'neq' | 'not_in' | 'gte' | 'lte' | 'gt' | 'lt'; export type ExperimentsDatadogEntryPointFilter = {column: string, column_type: ExperimentsDatadogEntryPointFilterColumnType, operation: ExperimentsDatadogEntryPointFilterOperation, values: Array}; export type ExperimentsDatadogEntryPointFilterGroup = Array; export type ExperimentsPatchExperimentV2ResponseDataAttributesDatadogFlagConfigurationEntryPoint = {filters: Array, measure_id: string} | null; export type ExperimentsSavedFilterCondition = {saved_filter_id: string}; export type ExperimentsTargetingRuleOperator = 'LT' | 'LTE' | 'GT' | 'GTE' | 'MATCHES' | 'NOT_MATCHES' | 'ONE_OF' | 'NOT_ONE_OF' | 'IS_NULL' | 'EQUALS' | 'SEMVER_EQ' | 'SEMVER_NEQ' | 'SEMVER_LT' | 'SEMVER_LTE' | 'SEMVER_GT' | 'SEMVER_GTE'; export type ExperimentsInlineCondition = {attribute: string, operator: ExperimentsTargetingRuleOperator, value: Array}; export type ExperimentsTargetingRuleCondition = ExperimentsSavedFilterCondition | ExperimentsInlineCondition; export type ExperimentsTargetingRule = {conditions: Array}; export type ExperimentsPatchExperimentV2RequestDataAttributesDatadogFlagConfiguration = {entry_point?: ExperimentsPatchExperimentV2ResponseDataAttributesDatadogFlagConfigurationEntryPoint | undefined, environment_id?: string | undefined, feature_flag_id?: string | undefined, reset_on_feature_flag_change?: boolean | undefined, targeting_rules?: Array | undefined} | null; export type ExperimentsCreateExperimentV2RequestDataAttributesDecisionMetricsItems = {is_primary: boolean, metric_id: string}; export type ExperimentsCreateExperimentV2RequestDataAttributesRelatedLinksItems = {id?: (string | null) | undefined, title?: (string | null) | undefined, url: string}; export type ExperimentsCreateExperimentV2RequestDataAttributesSplitByPropertiesItems = {column_name: string, column_type?: ExperimentsDatadogEntryPointFilterColumnType | undefined, name?: string | undefined}; export type ExperimentsCreateExperimentV2RequestDataAttributesStructuredMetadataItems = {enum_values?: Array | undefined, field_key: string, freetext_value?: string | undefined}; export type ExperimentsCreateExperimentV2RequestDataAttributesTrafficExposureMode = 'STATIC' | 'STEPS'; export type ExperimentsCreateExperimentV2RequestDataAttributesTrafficExposureStepsItems = {duration_ms: number | null, fraction: number}; export type ExperimentsPatchExperimentV2ResponseDataAttributesTrafficExposure = {fraction?: number | undefined, mode: ExperimentsCreateExperimentV2RequestDataAttributesTrafficExposureMode, steps?: Array | undefined}; export type ExperimentsCreateExperimentV2RequestDataAttributesVariantsItems = {feature_flag_variant_id?: string | undefined, is_active?: boolean | undefined, is_control: boolean, key: string, name?: (string | null) | undefined, weight: number}; export type ExperimentsWarehouseEntryPointFilterOperation = 'IS' | 'IS_NOT'; export type ExperimentsWarehouseExposureFilter = {operation: ExperimentsWarehouseEntryPointFilterOperation, property_id: string, values: Array}; export type ExperimentsWarehouseEntryPoint = {filters: Array, measure_id: string} | null; export type ExperimentsCreateExperimentV2RequestDataAttributesWarehouseExposureConfiguration = {entry_point: ExperimentsWarehouseEntryPoint, experiment_key: string, exposure_sql_model_id: string} | null; export type ExperimentsPatchExperimentV2RequestDataAttributes = {assignments_end_date?: (string | null) | undefined, assignments_start_date?: (string | null) | undefined, datadog_flag_configuration?: ExperimentsPatchExperimentV2RequestDataAttributesDatadogFlagConfiguration | undefined, decision_metrics?: Array | undefined, events_end_date?: (string | null) | undefined, events_start_date?: (string | null) | undefined, hypothesis?: string | undefined, migration_metadata: unknown, name?: string | undefined, related_links?: Array | undefined, split_by_properties?: Array | undefined, structured_metadata?: (Array | null) | undefined, subject_type_id?: string | undefined, summary?: (string | null) | undefined, tags?: Array | undefined, teams?: Array | undefined, traffic_exposure?: ExperimentsPatchExperimentV2ResponseDataAttributesTrafficExposure | undefined, variants?: Array | undefined, warehouse_exposure_configuration?: ExperimentsCreateExperimentV2RequestDataAttributesWarehouseExposureConfiguration | undefined}; export type ExperimentsPatchExperimentV2ResponseDataType = 'experiments'; export type ExperimentsPatchExperimentV2RequestData = {attributes?: ExperimentsPatchExperimentV2RequestDataAttributes | undefined, id?: string | undefined, type: ExperimentsPatchExperimentV2ResponseDataType}; export type ExperimentsPatchExperimentV2Request = {data: ExperimentsPatchExperimentV2RequestData}; export type PatchApiApiV2ExperimentsExperimentIdArgs = {experiment_id: string, body: ExperimentsPatchExperimentV2Request}; export type PatchApiApiV2ExperimentsExperimentIdOptions = {baseUrl?: string | undefined, apiKeyAuth?: string | undefined, appKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const experimentsExperimentV2DTODataAttributesConclusionOutcome = z.enum(["POSITIVE", "NEGATIVE", "NEUTRAL", "INCONCLUSIVE", "MISCONFIGURED", "UNKNOWN"]).nullable(); export const experimentsPatchExperimentV2ResponseDataAttributesConclusion = z.object({decision_reason: z.string().nullable().optional(), outcome: experimentsExperimentV2DTODataAttributesConclusionOutcome.optional(), summary: z.string().nullable().optional()}); export const experimentsDatadogEntryPointFilterColumnType = z.enum(["varchar", "int", "double", "boolean", "varchar_array", "int_array", "double_array", "raw"]); export const experimentsDatadogEntryPointFilterOperation = z.enum(["eq", "in", "neq", "not_in", "gte", "lte", "gt", "lt"]); export const experimentsDatadogEntryPointFilter = z.object({column: z.string(), column_type: experimentsDatadogEntryPointFilterColumnType, operation: experimentsDatadogEntryPointFilterOperation, values: z.array(z.string())}); export const experimentsDatadogEntryPointFilterGroup = z.array(experimentsDatadogEntryPointFilter); export const experimentsPatchExperimentV2ResponseDataAttributesDatadogFlagConfigurationEntryPoint = z.object({filters: z.array(experimentsDatadogEntryPointFilterGroup), measure_id: z.string()}).nullable(); export const experimentsSavedFilterCondition = z.object({saved_filter_id: z.string()}); export const experimentsTargetingRuleOperator = z.enum(["LT", "LTE", "GT", "GTE", "MATCHES", "NOT_MATCHES", "ONE_OF", "NOT_ONE_OF", "IS_NULL", "EQUALS", "SEMVER_EQ", "SEMVER_NEQ", "SEMVER_LT", "SEMVER_LTE", "SEMVER_GT", "SEMVER_GTE"]); export const experimentsInlineCondition = z.object({attribute: z.string().min(1), operator: experimentsTargetingRuleOperator, value: z.array(z.string())}); export const experimentsTargetingRuleCondition = z.union([experimentsSavedFilterCondition, experimentsInlineCondition]); export const experimentsTargetingRule = z.object({conditions: z.array(experimentsTargetingRuleCondition)}); export const experimentsPatchExperimentV2ResponseDataAttributesDatadogFlagConfiguration = z.object({allocation_key: z.string().optional(), entry_point: experimentsPatchExperimentV2ResponseDataAttributesDatadogFlagConfigurationEntryPoint, environment_id: z.string().optional(), feature_flag_id: z.string().optional(), targeting_rules: z.array(experimentsTargetingRule).optional()}).nullable(); export const experimentsCreateExperimentV2RequestDataAttributesDecisionMetricsItems = z.object({is_primary: z.boolean(), metric_id: z.string()}); export const experimentsCreateExperimentV2RequestDataAttributesRelatedLinksItems = z.object({id: z.string().nullable().optional(), title: z.string().nullable().optional(), url: z.string()}); export const experimentsPatchExperimentV2ResponseDataAttributesSplitByPropertiesItemsColumnType = z.enum(["varchar", "int", "double", "boolean", "varchar_array", "int_array", "double_array", "raw", "STRING", "INTEGER", "FLOAT", "BOOLEAN", "DATE", "TIMESTAMP"]); export const experimentsExperimentV2DTODataAttributesSplitByPropertiesItems = z.object({column_name: z.string(), column_type: experimentsPatchExperimentV2ResponseDataAttributesSplitByPropertiesItemsColumnType, id: z.string(), name: z.string()}); export const experimentsExperimentV2DTODataAttributesStatus = z.enum(["DRAFT", "SCHEDULED", "IN_PROGRESS", "READY_FOR_DECISION", "DECISION_MADE", "CANCELLED", "UNKNOWN"]); export const experimentsPatchExperimentV2ResponseDataAttributesStructuredMetadataItemsFieldType = z.enum(["FREETEXT", "ENUM"]); export const experimentsStructuredMetadataResponse = z.object({enum_values: z.array(z.string()).optional(), field_display_name: z.string().optional(), field_key: z.string(), field_type: experimentsPatchExperimentV2ResponseDataAttributesStructuredMetadataItemsFieldType.optional(), freetext_value: z.string().optional()}); export const experimentsCreateExperimentV2RequestDataAttributesTrafficExposureMode = z.enum(["STATIC", "STEPS"]); export const experimentsCreateExperimentV2RequestDataAttributesTrafficExposureStepsItems = z.object({duration_ms: z.number().int().nullable(), fraction: z.number()}); export const experimentsPatchExperimentV2ResponseDataAttributesTrafficExposure = z.object({fraction: z.number().optional(), mode: experimentsCreateExperimentV2RequestDataAttributesTrafficExposureMode, steps: z.array(experimentsCreateExperimentV2RequestDataAttributesTrafficExposureStepsItems).optional()}); export const experimentsExperimentV2DTODataAttributesVariantsItems = z.object({feature_flag_variant_id: z.string().optional(), is_active: z.boolean(), is_control: z.boolean(), key: z.string(), name: z.string().nullable().optional(), weight: z.number()}); export const experimentsWarehouseEntryPointFilterOperation = z.enum(["IS", "IS_NOT"]); export const experimentsWarehouseExposureFilter = z.object({operation: experimentsWarehouseEntryPointFilterOperation, property_id: z.string(), values: z.array(z.string())}); export const experimentsWarehouseEntryPoint = z.object({filters: z.array(experimentsWarehouseExposureFilter), measure_id: z.string()}).nullable(); export const experimentsPatchExperimentV2ResponseDataAttributesWarehouseExposureConfiguration = z.object({entry_point: experimentsWarehouseEntryPoint, experiment_key: z.string().nullable(), exposure_sql_model_id: z.string()}).nullable(); export const experimentsPatchExperimentV2ResponseDataAttributes = z.object({assignments_end_date: z.string().nullable().optional(), assignments_start_date: z.string().nullable().optional(), concluded_at: z.string().nullable().optional(), conclusion: experimentsPatchExperimentV2ResponseDataAttributesConclusion.optional(), created_at: z.string().optional(), datadog_flag_configuration: experimentsPatchExperimentV2ResponseDataAttributesDatadogFlagConfiguration.optional(), decision_metrics: z.array(experimentsCreateExperimentV2RequestDataAttributesDecisionMetricsItems).optional(), decision_variant_key: z.string().optional(), events_end_date: z.string().nullable().optional(), events_start_date: z.string().nullable().optional(), experiment_type: z.string().optional(), hypothesis: z.string().optional(), migration_metadata: z.unknown(), name: z.string().optional(), pipeline_table_suffix: z.string().optional(), protocol_id: z.string().optional(), related_links: z.array(experimentsCreateExperimentV2RequestDataAttributesRelatedLinksItems).optional(), results_last_updated: z.string().nullable().optional(), split_by_properties: z.array(experimentsExperimentV2DTODataAttributesSplitByPropertiesItems).optional(), status: experimentsExperimentV2DTODataAttributesStatus.optional(), structured_metadata: z.array(experimentsStructuredMetadataResponse).optional(), subject_type_id: z.string().nullable().optional(), summary: z.string().optional(), tags: z.array(z.string()).optional(), teams: z.array(z.string()).optional(), traffic_exposure: experimentsPatchExperimentV2ResponseDataAttributesTrafficExposure.optional(), updated_at: z.string().optional(), variants: z.array(experimentsExperimentV2DTODataAttributesVariantsItems).optional(), warehouse_exposure_configuration: experimentsPatchExperimentV2ResponseDataAttributesWarehouseExposureConfiguration.optional()}); export const experimentsPatchExperimentV2ResponseDataType = z.literal("experiments"); export const experimentsExperimentV2DTOData = z.object({attributes: experimentsPatchExperimentV2ResponseDataAttributes.optional(), id: z.string(), type: experimentsPatchExperimentV2ResponseDataType}); export const experimentsPatchExperimentV2MetaDTOWarningsItems = z.object({code: z.string(), detail: z.string()}); export const experimentsPatchExperimentV2MetaDTO = z.object({needs_pipeline_refresh: z.boolean(), refresh_endpoint: z.string().optional(), warnings: z.array(experimentsPatchExperimentV2MetaDTOWarningsItems).optional()}); export const experimentsPatchExperimentV2Response = z.object({data: experimentsExperimentV2DTOData, meta: experimentsPatchExperimentV2MetaDTO.optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Patch experiment * * PATCH /api/v2/experiments/{experiment_id} * * Also accepts auth: AuthZ */ export const patchApiApiV2ExperimentsExperimentId = async (args: PatchApiApiV2ExperimentsExperimentIdArgs, options?: PatchApiApiV2ExperimentsExperimentIdOptions) => { const {baseUrl = "https://api.datadoghq.com", fetch: fetchFn = fetch, apiKeyAuth, appKeyAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (apiKeyAuth !== undefined) headers.set("DD-API-KEY", apiKeyAuth) if (appKeyAuth !== undefined) headers.set("DD-APPLICATION-KEY", appKeyAuth) const url = `${baseUrl.replace(/\/+$/, '')}/api/v2/experiments/${encodeURIComponent(String(args.experiment_id))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "PATCH", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(experimentsPatchExperimentV2Response, await res.json()) };