import {z} from 'zod' export type ProductAnalyticsRetentionIndexTargetType = 'index'; export type ProductAnalyticsRetentionIndexTarget = {type: ProductAnalyticsRetentionIndexTargetType, value: number}; export type ProductAnalyticsRetentionAggregationTargetType = 'aggregation'; export type ProductAnalyticsRetentionAggregationTarget = {type: ProductAnalyticsRetentionAggregationTargetType, value: string}; export type ProductAnalyticsRetentionCohortTarget = ProductAnalyticsRetentionIndexTarget | ProductAnalyticsRetentionAggregationTarget; export type ProductAnalyticsRetentionCohortScopeType = 'cohort'; export type ProductAnalyticsRetentionCohortScope = {target: ProductAnalyticsRetentionCohortTarget, type: ProductAnalyticsRetentionCohortScopeType}; export type ProductAnalyticsRetentionReturnPeriodScopeType = 'return_period'; export type ProductAnalyticsRetentionReturnPeriodScope = {target: ProductAnalyticsRetentionIndexTarget, type: ProductAnalyticsRetentionReturnPeriodScopeType}; export type ProductAnalyticsRetentionCellScopeType = 'cell'; export type ProductAnalyticsRetentionCellScope = {cohort_target: ProductAnalyticsRetentionCohortTarget, return_period_target: ProductAnalyticsRetentionIndexTarget, type: ProductAnalyticsRetentionCellScopeType}; export type ProductAnalyticsRetentionScope = ProductAnalyticsRetentionCohortScope | ProductAnalyticsRetentionReturnPeriodScope | ProductAnalyticsRetentionCellScope; export type ProductAnalyticsRetentionComputeMetric = '__dd.retention' | '__dd.retention_rate'; export type ProductAnalyticsRetentionCompute = {aggregation: string, metric: ProductAnalyticsRetentionComputeMetric}; export type QuerySortOrder = 'asc' | 'desc'; export type ProductAnalyticsGroupBySort = {aggregation?: string | undefined, metric?: string | undefined, order?: QuerySortOrder | undefined}; export type ProductAnalyticsRetentionGroupByTarget = 'cohort' | 'return_period'; export type ProductAnalyticsRetentionGroupBy = {facet: string, limit?: number | undefined, should_exclude_missing?: boolean | undefined, sort?: ProductAnalyticsGroupBySort | undefined, source?: string | undefined, target: ProductAnalyticsRetentionGroupByTarget}; export type ProductAnalyticsEventQueryDataSource = 'product_analytics'; export type ProductAnalyticsEventSearch = {query?: string | undefined}; export type ProductAnalyticsEventQuery = {data_source: ProductAnalyticsEventQueryDataSource, search: ProductAnalyticsEventSearch}; export type ProductAnalyticsOccurrenceQueryDataSource = 'product_analytics_occurrence'; export type ProductAnalyticsOccurrenceFilter = {meta?: {[key: string]: string} | undefined, operator: string, value: string}; export type ProductAnalyticsOccurrenceSearch = {occurrences?: ProductAnalyticsOccurrenceFilter | undefined, query?: string | undefined}; export type ProductAnalyticsOccurrenceQuery = {data_source: ProductAnalyticsOccurrenceQueryDataSource, search: ProductAnalyticsOccurrenceSearch}; export type ProductAnalyticsBaseQuery = ProductAnalyticsEventQuery | ProductAnalyticsOccurrenceQuery; export type ProductAnalyticsRetentionCalendarTimeIntervalType = 'calendar'; export type ProductAnalyticsCalendarIntervalType = 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'; export type ProductAnalyticsCalendarInterval = {alignment?: string | undefined, quantity?: number | undefined, timezone?: string | undefined, type: ProductAnalyticsCalendarIntervalType}; export type ProductAnalyticsRetentionCalendarTimeInterval = {type: ProductAnalyticsRetentionCalendarTimeIntervalType, value: ProductAnalyticsCalendarInterval}; export type ProductAnalyticsRetentionFixedTimeIntervalType = 'fixed'; export type ProductAnalyticsRetentionFixedTimeIntervalUnit = 'day' | 'week' | 'month'; export type ProductAnalyticsRetentionFixedTimeInterval = {type: ProductAnalyticsRetentionFixedTimeIntervalType, unit: ProductAnalyticsRetentionFixedTimeIntervalUnit, value: number}; export type ProductAnalyticsRetentionTimeInterval = ProductAnalyticsRetentionCalendarTimeInterval | ProductAnalyticsRetentionFixedTimeInterval; export type ProductAnalyticsRetentionCohortCriteria = {base_query: ProductAnalyticsBaseQuery, time_interval: ProductAnalyticsRetentionTimeInterval}; export type ProductAnalyticsAudienceAccountSubquery = {name: string, query?: string | undefined}; export type ProductAnalyticsAudienceSegmentSubquery = {name: string, segment_id: string}; export type ProductAnalyticsAudienceUserSubquery = {name: string, query?: string | undefined}; export type ProductAnalyticsAudienceFilters = {accounts?: Array | undefined, formula?: string | undefined, segments?: Array | undefined, users?: Array | undefined}; export type ProductAnalyticsRetentionFilters = {audience_filters?: ProductAnalyticsAudienceFilters | undefined, string_filter?: string | undefined}; export type ProductAnalyticsRetentionEntity = '@usr.id' | '@account.id'; export type ProductAnalyticsRetentionReturnCondition = 'conversion_on' | 'conversion_on_or_after'; export type ProductAnalyticsRetentionReturnCriteria = {base_query: ProductAnalyticsBaseQuery, time_interval?: ProductAnalyticsRetentionTimeInterval | undefined}; export type ProductAnalyticsRetentionSearch = {cohort_criteria: ProductAnalyticsRetentionCohortCriteria, filters?: ProductAnalyticsRetentionFilters | undefined, retention_entity: ProductAnalyticsRetentionEntity, return_condition: ProductAnalyticsRetentionReturnCondition, return_criteria?: ProductAnalyticsRetentionReturnCriteria | undefined}; export type ProductAnalyticsFormulaRetentionQuery = {computation_scope?: ProductAnalyticsRetentionScope | undefined, compute: ProductAnalyticsRetentionCompute, group_by?: Array | undefined, search: ProductAnalyticsRetentionSearch}; export type ProductAnalyticsFormulaRetentionRequestAttributes = {exclude_anonymous_traffic?: boolean | undefined, from: number, query: ProductAnalyticsFormulaRetentionQuery, to: number}; export type ProductAnalyticsFormulaRetentionRequestType = 'formula_retention_request'; export type ProductAnalyticsFormulaRetentionRequestData = {attributes: ProductAnalyticsFormulaRetentionRequestAttributes, type: ProductAnalyticsFormulaRetentionRequestType}; export type ProductAnalyticsFormulaRetentionRequest = {data: ProductAnalyticsFormulaRetentionRequestData}; export type CreateApiApiV2ProductAnalyticsRetentionTimeseriesArgs = {body: ProductAnalyticsFormulaRetentionRequest}; export type CreateApiApiV2ProductAnalyticsRetentionTimeseriesOptions = {baseUrl?: string | undefined, apiKeyAuth?: string | undefined, appKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const productAnalyticsInterval = z.object({milliseconds: z.number().int().optional(), start_time: z.number().int().optional(), times: z.array(z.number().int()).optional(), type: z.string().optional()}); export const productAnalyticsUnit = z.object({family: z.string().optional(), id: z.number().int().optional(), name: z.string().optional(), plural: z.string().optional(), scale_factor: z.number().optional(), short_name: z.string().optional()}); export const productAnalyticsSerie = z.object({group_tags: z.array(z.string()).optional(), query_index: z.number().int().optional(), unit: z.array(productAnalyticsUnit).optional()}); export const productAnalyticsTimeseriesResponseAttributes = z.object({intervals: z.array(productAnalyticsInterval).optional(), series: z.array(productAnalyticsSerie).optional(), times: z.array(z.number().int()).optional(), values: z.array(z.array(z.number().nullable())).optional()}); export const productAnalyticsTimeseriesResponseType = z.literal("timeseries_response"); export const productAnalyticsTimeseriesResponseData = z.object({attributes: productAnalyticsTimeseriesResponseAttributes.optional(), id: z.string().optional(), type: productAnalyticsTimeseriesResponseType.optional()}); export const productAnalyticsResponseMetaStatus = z.enum(["done", "running", "timeout"]); export const productAnalyticsResponseMeta = z.object({request_id: z.string().optional(), status: productAnalyticsResponseMetaStatus.optional()}); export const productAnalyticsTimeseriesResponse = z.object({data: productAnalyticsTimeseriesResponseData.optional(), meta: productAnalyticsResponseMeta.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 }; /** * Compute retention timeseries * * POST /api/v2/product-analytics/retention/timeseries * * Also accepts auth: AuthZ */ export const createApiApiV2ProductAnalyticsRetentionTimeseries = async (args: CreateApiApiV2ProductAnalyticsRetentionTimeseriesArgs, options?: CreateApiApiV2ProductAnalyticsRetentionTimeseriesOptions) => { 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/product-analytics/retention/timeseries${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", 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(productAnalyticsTimeseriesResponse, await res.json()) };