import { asStringArray, clean, datadogRequest, mutationPreview, positiveInt } from './core.ts'
import type { DatadogDashboardInput } from './types.ts'
function dashboardId(params: DatadogDashboardInput): string {
const id = clean(params.dashboardId ?? params.id)
if (!id) throw new Error('dashboardId is required.')
return id
}
function summarizeDashboard(dashboard: any) {
return {
id: dashboard?.id ?? null,
title: dashboard?.title ?? null,
description: dashboard?.description ?? null,
layoutType: dashboard?.layout_type ?? dashboard?.layoutType ?? null,
url: dashboard?.url ?? null,
authorHandle: dashboard?.author_handle ?? dashboard?.authorHandle ?? null,
createdAt: dashboard?.created_at ?? dashboard?.createdAt ?? null,
modifiedAt: dashboard?.modified_at ?? dashboard?.modifiedAt ?? null,
isReadOnly: dashboard?.is_read_only ?? dashboard?.isReadOnly ?? null,
widgetCount: Array.isArray(dashboard?.widgets) ? dashboard.widgets.length : null,
}
}
function dashboardBody(params: DatadogDashboardInput): Record<string, unknown> {
if (params.body && typeof params.body === 'object') return params.body
const body: Record<string, unknown> = {}
if (clean(params.title)) body.title = clean(params.title)
if (clean(params.description)) body.description = clean(params.description)
if (clean(params.layoutType)) body.layout_type = clean(params.layoutType)
if (Array.isArray(params.widgets)) body.widgets = params.widgets
if (Array.isArray(params.templateVariables)) body.template_variables = params.templateVariables
if (params.isReadOnly != null) body.is_read_only = params.isReadOnly
if (Array.isArray(params.notifyList)) body.notify_list = params.notifyList
if (clean(params.reflowType)) body.reflow_type = clean(params.reflowType)
const tags = asStringArray(params.tags)
if (tags.length) body.tags = tags
return body
}
/** List dashboards. GET /api/v1/dashboard */
export async function listDashboards(params: DatadogDashboardInput = {}) {
const query: Record<string, unknown> = {}
if (params.filterShared != null) query['filter[shared]'] = params.filterShared
if (params.filterDeleted != null) query['filter[deleted]'] = params.filterDeleted
if (params.count != null || params.pageSize != null) {
query.count = positiveInt(params.count ?? params.pageSize, 100, 1000)
}
if (params.start != null) query.start = positiveInt(params.start, 0, 100_000)
const body = await datadogRequest('/api/v1/dashboard', { ...params, query })
const dashboards = Array.isArray(body?.dashboards) ? body.dashboards : Array.isArray(body) ? body : []
return {
count: dashboards.length,
total: body?.total ?? dashboards.length,
dashboards: dashboards.map(summarizeDashboard),
}
}
/** Get one dashboard. GET /api/v1/dashboard/{dashboard_id} */
export async function getDashboard(params: DatadogDashboardInput = {}) {
const id = dashboardId(params)
const dashboard = await datadogRequest('/api/v1/dashboard/' + encodeURIComponent(id), params)
return { dashboard: summarizeDashboard(dashboard), raw: dashboard }
}
/** Create a dashboard. Requires confirm. Pass dryRun: true to preview. */
export async function createDashboard(params: DatadogDashboardInput = {}) {
const body = dashboardBody(params)
if (!clean(body.title) || !clean(body.layout_type)) {
throw new Error('Creating a dashboard requires title and layoutType (or a full body).')
}
if (!Array.isArray(body.widgets)) body.widgets = []
const preview = mutationPreview(params, {
action: 'create dashboard ' + clean(body.title),
method: 'POST',
path: '/api/v1/dashboard',
body,
})
if (preview) return preview
const created = await datadogRequest('/api/v1/dashboard', { ...params, method: 'POST', body })
return { ok: true, action: 'create', dashboard: summarizeDashboard(created), raw: created }
}
/** Update a dashboard. Requires confirm. Pass dryRun: true to preview. */
export async function updateDashboard(params: DatadogDashboardInput = {}) {
const id = dashboardId(params)
const body = dashboardBody(params)
const preview = mutationPreview(params, {
action: 'update dashboard ' + id,
method: 'PUT',
path: '/api/v1/dashboard/' + encodeURIComponent(id),
body,
})
if (preview) return preview
const updated = await datadogRequest('/api/v1/dashboard/' + encodeURIComponent(id), {
...params,
method: 'PUT',
body,
})
return { ok: true, action: 'update', dashboard: summarizeDashboard(updated), raw: updated }
}
/** Delete a dashboard. Requires confirm. Pass dryRun: true to preview. */
export async function deleteDashboard(params: DatadogDashboardInput = {}) {
const id = dashboardId(params)
const preview = mutationPreview(params, {
action: 'delete dashboard ' + id,
method: 'DELETE',
path: '/api/v1/dashboard/' + encodeURIComponent(id),
})
if (preview) return preview
const deleted = await datadogRequest('/api/v1/dashboard/' + encodeURIComponent(id), {
...params,
method: 'DELETE',
})
return { ok: true, action: 'delete', dashboardId: id, raw: deleted }
}
/**
* List or get Datadog dashboards. Mutations live on named exports.
* @example
* import { listDashboards } from 'kody:@kody/datadog/dashboards'
* const result = await listDashboards({ count: 20 })
*/
export default async function dashboards(params: DatadogDashboardInput = {}) {
if (params.dashboardId || params.id) return await getDashboard(params)
return await listDashboards(params)
}