import {z} from 'zod' export type GetApiApiV1LiveTrackingHeatmapsGridArgs = {access_key?: string | undefined, type: 'npc_death' | 'player_death' | 'player_spell', challengeModeId: number, season: 'season-mn-2' | 'season-mn-2-tr' | 'season-mn-1' | 'season-mn-1-cutoffs' | 'season-mn-1-break-the-meta' | 'season-mn-1-tr' | 'season-mn-2-ptr' | 'season-tww-3' | 'season-tww-3-cutoffs' | 'season-mn-1-beta' | 'season-tww-3-legion-remix' | 'season-tww-3-legion-remix-1-player' | 'season-tww-3-break-the-meta' | 'season-tww-3-tr' | 'season-tww-2' | 'season-tww-2-break-the-meta' | 'season-tww-2-meta-vs-meta' | 'season-tww-2-tr' | 'season-tww-1' | 'season-tww-3-ptr' | 'season-tww-1-post' | 'season-tww-1-cutoffs' | 'season-tww-1-break-the-meta' | 'season-tww-1-tr' | 'season-tww-2-ptr' | 'season-df-4' | 'season-df-4-post' | 'season-df-4-cutoffs' | 'season-df-4-break-the-meta' | 'season-tww-1-beta' | 'season-df-4-tr' | 'season-df-3' | 'season-df-4-ptr' | 'season-df-3-meta-vs-meta' | 'season-df-3-break-the-meta' | 'season-df-3-tr' | 'season-df-2' | 'season-df-2-post' | 'season-df-2-cutoffs' | 'season-df-3-ptr' | 'season-df-2-break-the-meta' | 'season-df-2-tgp' | 'season-df-2-post-1017' | 'season-df-2-post-1015' | 'season-df-1' | 'season-df-1-post' | 'season-df-1-cutoffs' | 'season-df-1-break-the-meta' | 'season-sl-4' | 'season-sl-4-post' | 'season-sl-4-patch-10-0' | 'season-sl-4-break-the-meta' | 'season-sl-4-legion-timewalking' | 'season-sl-3' | 'season-sl-3-post-925' | 'season-sl-3-legion-timewalking' | 'season-sl-2' | 'season-sl-2-post' | 'season-sl-2-tormented-hero' | 'season-sl-2-post-915' | 'season-sl-2-legion-timewalking' | 'season-sl-1' | 'season-sl-1-post' | 'season-bfa-4-post' | 'season-bfa-4' | 'season-bfa-3-post' | 'season-bfa-3' | 'season-bfa-2-post' | 'season-bfa-2' | 'season-bfa-1' | 'season-pre-bfa' | 'season-post-legion' | 'season-7.3.2' | 'season-7.3.0' | 'season-7.2.5' | 'season-7.2.0', dataType?: ('player_position' | 'enemy_position') | undefined, region?: string | undefined, minMythicLevel?: number | undefined, maxMythicLevel?: number | undefined, minItemLevel?: number | undefined, maxItemLevel?: number | undefined, minPeriod?: number | undefined, maxPeriod?: number | undefined, minTimerFraction?: number | undefined, maxTimerFraction?: number | undefined, minPlayerDeaths?: number | undefined, maxPlayerDeaths?: number | undefined, includeSpecIds?: string | undefined, excludeSpecIds?: string | undefined, includeClassIds?: string | undefined, excludeClassIds?: string | undefined, excludePlayerDeathSpecIds?: string | undefined, includePlayerDeathSpecIds?: string | undefined, excludePlayerDeathClassIds?: string | undefined, includePlayerDeathClassIds?: string | undefined, includePlayerSpellIds?: string | undefined, includeAffixIds?: string | undefined, excludeAffixIds?: string | undefined, minRequiredSamplesFactor?: number | undefined, floorsAsArray?: boolean | undefined, token?: string | undefined}; export type GetApiApiV1LiveTrackingHeatmapsGridOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const viewHeatmapGridResponse = z.object({}); 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 }; /** * Query aggregated spatial heatmap data for Mythic+ dungeons. Returns density data (deaths, spell casts) bucketed into a floor grid. Supports filtering by key level, item level, specs, classes, affixes, and more. * * GET /api/v1/live-tracking/heatmaps/grid */ export const getApiApiV1LiveTrackingHeatmapsGrid = async (args: GetApiApiV1LiveTrackingHeatmapsGridArgs, options?: GetApiApiV1LiveTrackingHeatmapsGridOptions) => { const {baseUrl = "http://raider.io", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.access_key != null) query.append("access_key", String(args.access_key)) if (args.type != null) query.append("type", String(args.type)) if (args.challengeModeId != null) query.append("challengeModeId", String(args.challengeModeId)) if (args.season != null) query.append("season", String(args.season)) if (args.dataType != null) query.append("dataType", String(args.dataType)) if (args.region != null) query.append("region", String(args.region)) if (args.minMythicLevel != null) query.append("minMythicLevel", String(args.minMythicLevel)) if (args.maxMythicLevel != null) query.append("maxMythicLevel", String(args.maxMythicLevel)) if (args.minItemLevel != null) query.append("minItemLevel", String(args.minItemLevel)) if (args.maxItemLevel != null) query.append("maxItemLevel", String(args.maxItemLevel)) if (args.minPeriod != null) query.append("minPeriod", String(args.minPeriod)) if (args.maxPeriod != null) query.append("maxPeriod", String(args.maxPeriod)) if (args.minTimerFraction != null) query.append("minTimerFraction", String(args.minTimerFraction)) if (args.maxTimerFraction != null) query.append("maxTimerFraction", String(args.maxTimerFraction)) if (args.minPlayerDeaths != null) query.append("minPlayerDeaths", String(args.minPlayerDeaths)) if (args.maxPlayerDeaths != null) query.append("maxPlayerDeaths", String(args.maxPlayerDeaths)) if (args.includeSpecIds != null) query.append("includeSpecIds", String(args.includeSpecIds)) if (args.excludeSpecIds != null) query.append("excludeSpecIds", String(args.excludeSpecIds)) if (args.includeClassIds != null) query.append("includeClassIds", String(args.includeClassIds)) if (args.excludeClassIds != null) query.append("excludeClassIds", String(args.excludeClassIds)) if (args.excludePlayerDeathSpecIds != null) query.append("excludePlayerDeathSpecIds", String(args.excludePlayerDeathSpecIds)) if (args.includePlayerDeathSpecIds != null) query.append("includePlayerDeathSpecIds", String(args.includePlayerDeathSpecIds)) if (args.excludePlayerDeathClassIds != null) query.append("excludePlayerDeathClassIds", String(args.excludePlayerDeathClassIds)) if (args.includePlayerDeathClassIds != null) query.append("includePlayerDeathClassIds", String(args.includePlayerDeathClassIds)) if (args.includePlayerSpellIds != null) query.append("includePlayerSpellIds", String(args.includePlayerSpellIds)) if (args.includeAffixIds != null) query.append("includeAffixIds", String(args.includeAffixIds)) if (args.excludeAffixIds != null) query.append("excludeAffixIds", String(args.excludeAffixIds)) if (args.minRequiredSamplesFactor != null) query.append("minRequiredSamplesFactor", String(args.minRequiredSamplesFactor)) if (args.floorsAsArray != null) query.append("floorsAsArray", String(args.floorsAsArray)) if (args.token != null) query.append("token", String(args.token)) const url = `${baseUrl.replace(/\/+$/, '')}/api/v1/live-tracking/heatmaps/grid${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(viewHeatmapGridResponse, await res.json()) };