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 { if (params.body && typeof params.body === 'object') return params.body const body: Record = {} 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 = {} 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) }