import { asStringArray, clean, datadogRequest, mutationPreview, positiveInt } from './core.ts' import type { DatadogIncidentInput } from './types.ts' function incidentId(params: DatadogIncidentInput): string { const id = clean(params.incidentId ?? params.id) if (!id) throw new Error('incidentId is required.') return id } function summarizeIncident(item: any) { const attributes = item?.attributes ?? item ?? {} return { id: item?.id ?? attributes.id ?? null, title: attributes.title ?? null, publicId: attributes.public_id ?? attributes.publicId ?? null, state: attributes.state ?? null, severity: attributes.fields?.severity?.value ?? attributes.severity ?? null, customerImpacted: attributes.customer_impacted ?? attributes.customerImpacted ?? null, created: attributes.created ?? attributes.created_at ?? null, modified: attributes.modified ?? attributes.modified_at ?? null, resolved: attributes.resolved ?? attributes.resolved_at ?? null, } } function incidentPayload(params: DatadogIncidentInput, type = 'incidents') { if (params.body && typeof params.body === 'object') return params.body const attributes: Record = { ...(params.attributes ?? {}) } if (clean(params.title)) attributes.title = clean(params.title) if (params.customerImpacted != null) attributes.customer_impacted = params.customerImpacted if (params.fields && typeof params.fields === 'object') attributes.fields = params.fields return { data: { type, attributes, }, } } /** List incidents. GET /api/v2/incidents */ export async function listIncidents(params: DatadogIncidentInput = {}) { const query: Record = {} if (params.pageSize != null || params.perPage != null) { query['page[size]'] = positiveInt(params.pageSize ?? params.perPage, 10, 100) } if (params.page != null) query['page[offset]'] = positiveInt(params.page, 0, 10_000) const include = asStringArray(params.include) if (include.length) query.include = include.join(',') const body = await datadogRequest('/api/v2/incidents', { ...params, query }) const incidents = Array.isArray(body?.data) ? body.data : [] return { count: incidents.length, incidents: incidents.map(summarizeIncident), meta: body?.meta ?? null, } } /** Get one incident. GET /api/v2/incidents/{incident_id} */ export async function getIncident(params: DatadogIncidentInput = {}) { const id = incidentId(params) const include = asStringArray(params.include) const query = include.length ? { include: include.join(',') } : undefined const body = await datadogRequest('/api/v2/incidents/' + encodeURIComponent(id), { ...params, query, }) return { incident: summarizeIncident(body?.data ?? body), raw: body } } /** Search incidents. GET /api/v2/incidents/search */ export async function searchIncidents(params: DatadogIncidentInput = {}) { const query: Record = {} if (clean(params.query)) query.query = clean(params.query) if (params.pageSize != null || params.perPage != null) { query['page[size]'] = positiveInt(params.pageSize ?? params.perPage, 10, 100) } if (params.page != null) query['page[offset]'] = positiveInt(params.page, 0, 10_000) const include = asStringArray(params.include) if (include.length) query.include = include.join(',') const body = await datadogRequest('/api/v2/incidents/search', { ...params, query }) const incidents = Array.isArray(body?.data) ? body.data : [] return { count: incidents.length, incidents: incidents.map(summarizeIncident), meta: body?.meta ?? null, } } /** Create an incident. Requires confirm. Pass dryRun: true to preview. */ export async function createIncident(params: DatadogIncidentInput = {}) { const payload = incidentPayload(params) const title = clean((payload as any)?.data?.attributes?.title) if (!title) throw new Error('Creating an incident requires title (or a full body).') const preview = mutationPreview(params, { action: 'create incident ' + title, method: 'POST', path: '/api/v2/incidents', body: payload, }) if (preview) return preview const created = await datadogRequest('/api/v2/incidents', { ...params, method: 'POST', body: payload, }) return { ok: true, action: 'create', incident: summarizeIncident(created?.data ?? created), raw: created } } /** Update an incident. Requires confirm. Pass dryRun: true to preview. */ export async function updateIncident(params: DatadogIncidentInput = {}) { const id = incidentId(params) const payload = incidentPayload(params) ;(payload as any).data.id = id const preview = mutationPreview(params, { action: 'update incident ' + id, method: 'PATCH', path: '/api/v2/incidents/' + encodeURIComponent(id), body: payload, }) if (preview) return preview const updated = await datadogRequest('/api/v2/incidents/' + encodeURIComponent(id), { ...params, method: 'PATCH', body: payload, }) return { ok: true, action: 'update', incident: summarizeIncident(updated?.data ?? updated), raw: updated } } /** Delete an incident. Requires confirm. Pass dryRun: true to preview. */ export async function deleteIncident(params: DatadogIncidentInput = {}) { const id = incidentId(params) const preview = mutationPreview(params, { action: 'delete incident ' + id, method: 'DELETE', path: '/api/v2/incidents/' + encodeURIComponent(id), }) if (preview) return preview const deleted = await datadogRequest('/api/v2/incidents/' + encodeURIComponent(id), { ...params, method: 'DELETE', }) return { ok: true, action: 'delete', incidentId: id, raw: deleted } } /** * List, search, or get Datadog incidents. Mutations live on named exports. * @example * import { listIncidents } from 'kody:@kody/datadog/incidents' * const result = await listIncidents({ pageSize: 10 }) */ export default async function incidents(params: DatadogIncidentInput = {}) { if (params.incidentId || params.id) return await getIncident(params) if (clean(params.query)) return await searchIncidents(params) return await listIncidents(params) }