1/**
2 * Typed view of the Axiom dashboard chart-JSON subset.
3 *
4 * Axiom's `CreateDashboardInput` declares
5 * `dashboard.charts: ReadonlyArray<unknown>` (see
6 * `@distilled.cloud/axiom/.../v2/createDashboard.ts`); these
7 * interfaces give callers compile-time safety when building the
8 * payload by hand.
9 *
10 * `chart.id` is a free-form string the author picks — Axiom
11 * doesn't validate the format. It joins to the matching
12 * `LayoutCell.i` in `dashboard.layout`.
13 */
14
15/**
16 * Axiom-validated chart kinds. Discovered by probing
17 * `POST /v2/dashboards`: anything else returns
18 * `dashboard validation failed at [charts N type]: Invalid input`.
19 */
20export type ChartKind =
21 | "TimeSeries"
22 | "Table"
23 | "Pie"
24 | "Statistic"
25 | "Heatmap"
26 | "LogStream"
27 | "Note"
28 | "SmartFilter";
29
30/**
31 * Minimum chart payload Axiom's `POST /v2/dashboards` accepts.
32 * Any unknown keys (e.g. `dataset`, `description`) trigger
33 * `Unrecognized keys: "<name>"`, so this struct is intentionally
34 * narrow. The dataset is implicit via the APL query.
35 */
36export interface BaseChart {
37 readonly id: string;
38 readonly name: string;
39 readonly type: ChartKind;
40 readonly query: { readonly apl: string };
41}
42
43export interface TimeSeriesChart extends BaseChart {
44 readonly type: "TimeSeries";
45}
46
47export interface TableChart extends BaseChart {
48 readonly type: "Table";
49}
50
51export interface PieChart extends BaseChart {
52 readonly type: "Pie";
53}
54
55export interface StatisticChart extends BaseChart {
56 readonly type: "Statistic";
57}
58
59export interface HeatmapChart extends BaseChart {
60 readonly type: "Heatmap";
61}
62
63export interface LogStreamChart extends BaseChart {
64 readonly type: "LogStream";
65}
66
67/**
68 * A free-form markdown note. Unlike data charts, `Note` has no `query`
69 * or `name` — Axiom's payload is strictly `{ id, type, text, variant? }`.
70 */
71export interface NoteChart {
72 readonly id: string;
73 readonly type: "Note";
74 /** Markdown body rendered in the note cell. */
75 readonly text: string;
76 readonly variant?: "default";
77}
78
79/**
80 * A dashboard filter bar (Axiom calls it `SmartFilter` on the wire,
81 * `Filter bar` in the UI). Holds one or more filters whose IDs can
82 * be referenced from other charts' APL via
83 * `declare query_parameters (<filter-id>:string = "")`.
84 *
85 * Unlike data charts, `SmartFilter` has no top-level `query` field —
86 * each filter inside `filters` may carry its own option-source APL.
87 */
88export interface SmartFilterChart {
89 readonly id: string;
90 readonly type: "SmartFilter";
91 /** Optional display name for the filter bar element. */
92 readonly name?: string;
93 readonly filters: readonly SmartFilter[];
94}
95
96/**
97 * One filter inside a {@link SmartFilterChart}. Either a free-text
98 * `search` filter or a dropdown `select` filter. Select filters draw
99 * their options from either an inline `list` or an APL `query`.
100 */
101export type SmartFilter = SmartFilterSearch | SmartFilterSelect;
102
103export interface SmartFilterSearch {
104 readonly id: string;
105 readonly type: "search";
106 readonly name?: string;
107 readonly active?: boolean;
108}
109
110export interface SmartFilterSelect {
111 readonly id: string;
112 readonly type: "select";
113 readonly name?: string;
114 readonly active?: boolean;
115 /** `"list"` for inline `options`, `"apl"` for a query-driven dropdown. */
116 readonly selectType?: "list" | "apl";
117 /**
118 * APL query that returns rows shaped `{ key, value }`. Axiom shows
119 * `key` in the dropdown and substitutes `value` into chart queries.
120 */
121 readonly apl?: { readonly apl: string };
122 /** Inline key/value options when `selectType === "list"`. */
123 readonly options?: readonly {
124 readonly id?: string;
125 readonly key: string;
126 readonly value: string;
127 readonly default?: boolean;
128 }[];
129}
130
131export type Chart =
132 | TimeSeriesChart
133 | TableChart
134 | PieChart
135 | StatisticChart
136 | HeatmapChart
137 | LogStreamChart
138 | NoteChart
139 | SmartFilterChart;
140
141/**
142 * Mirrors Axiom's `CreateDashboardInput.dashboard.layout` cell schema.
143 * `i` references a chart by its `id`.
144 */
145export interface LayoutCell {
146 readonly i: string;
147 readonly x: number;
148 readonly y: number | null;
149 readonly w: number;
150 readonly h: number;
151 readonly minW?: number;
152 readonly minH?: number;
153 readonly maxW?: number;
154 readonly maxH?: number;
155 readonly static?: boolean;
156}