@bonnard/cli 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,198 @@
1
+ # REST API
2
+
3
+ > Query your deployed semantic layer using the Bonnard REST API. Send JSON query objects or SQL strings to retrieve measures and dimensions with filtering, grouping, and time ranges.
4
+
5
+ ## Overview
6
+
7
+ After deploying with `bon deploy`, you can query the semantic layer using `bon query`. This tests that your cubes and views work correctly and returns data from your warehouse through Bonnard.
8
+
9
+ ## Query Formats
10
+
11
+ Bonnard supports two query formats:
12
+
13
+ ### JSON Format (Default)
14
+
15
+ The JSON format uses the REST API structure:
16
+
17
+ ```bash
18
+ bon query '{"measures": ["orders.count"]}'
19
+
20
+ bon query '{
21
+ "measures": ["orders.total_revenue"],
22
+ "dimensions": ["orders.status"],
23
+ "filters": [{
24
+ "member": "orders.created_at",
25
+ "operator": "inDateRange",
26
+ "values": ["2024-01-01", "2024-12-31"]
27
+ }]
28
+ }'
29
+ ```
30
+
31
+ **JSON Query Properties:**
32
+
33
+ | Property | Description |
34
+ |----------|-------------|
35
+ | `measures` | Array of measures to calculate (e.g., `["orders.count"]`) |
36
+ | `dimensions` | Array of dimensions to group by (e.g., `["orders.status"]`) |
37
+ | `filters` | Array of filter objects |
38
+ | `timeDimensions` | Time-based grouping with granularity |
39
+ | `segments` | Named filters defined in cubes |
40
+ | `limit` | Max rows to return |
41
+ | `offset` | Skip rows (pagination) |
42
+ | `order` | Sort specification |
43
+
44
+ **Filter Operators:**
45
+
46
+ | Operator | Use Case |
47
+ |----------|----------|
48
+ | `equals`, `notEquals` | Exact match |
49
+ | `contains`, `notContains` | String contains |
50
+ | `startsWith`, `endsWith` | String prefix/suffix |
51
+ | `gt`, `gte`, `lt`, `lte` | Numeric comparison |
52
+ | `inDateRange`, `beforeDate`, `afterDate` | Time filtering |
53
+ | `set`, `notSet` | NULL checks |
54
+
55
+ ### SQL Format
56
+
57
+ The SQL format uses the SQL API, where cubes are tables:
58
+
59
+ ```bash
60
+ bon query --sql "SELECT status, MEASURE(count) FROM orders GROUP BY 1"
61
+
62
+ bon query --sql "SELECT
63
+ city,
64
+ MEASURE(total_revenue),
65
+ MEASURE(avg_order_value)
66
+ FROM orders
67
+ WHERE status = 'completed'
68
+ GROUP BY 1
69
+ ORDER BY 2 DESC
70
+ LIMIT 10"
71
+ ```
72
+
73
+ **SQL Syntax Rules:**
74
+
75
+ 1. **Cubes/views are tables** — `FROM orders` references the `orders` cube
76
+ 2. **Dimensions are columns** — Include in `SELECT` and `GROUP BY`
77
+ 3. **Measures use `MEASURE()`** — Or matching aggregates (`SUM`, `COUNT`, etc.)
78
+ 4. **Segments are boolean** — Filter with `WHERE is_completed IS TRUE`
79
+
80
+ **Examples:**
81
+
82
+ ```sql
83
+ -- Count orders by status
84
+ SELECT status, MEASURE(count) FROM orders GROUP BY 1
85
+
86
+ -- Revenue by city with filter
87
+ SELECT city, SUM(amount) FROM orders WHERE status = 'shipped' GROUP BY 1
88
+
89
+ -- Using time dimension with granularity
90
+ SELECT DATE_TRUNC('month', created_at), MEASURE(total_revenue)
91
+ FROM orders
92
+ GROUP BY 1
93
+ ORDER BY 1
94
+ ```
95
+
96
+ ## CLI Usage
97
+
98
+ ```bash
99
+ # JSON format (default)
100
+ bon query '{"measures": ["orders.count"]}'
101
+
102
+ # SQL format
103
+ bon query --sql "SELECT MEASURE(count) FROM orders"
104
+
105
+ # Limit rows
106
+ bon query '{"measures": ["orders.count"], "dimensions": ["orders.city"]}' --limit 10
107
+
108
+ # JSON output (instead of table)
109
+ bon query '{"measures": ["orders.count"]}' --format json
110
+ ```
111
+
112
+ ## Output Formats
113
+
114
+ ### Table Format (Default)
115
+
116
+ ```
117
+ ┌─────────┬───────────────┐
118
+ │ status │ orders.count │
119
+ ├─────────┼───────────────┤
120
+ │ pending │ 42 │
121
+ │ shipped │ 156 │
122
+ │ done │ 892 │
123
+ └─────────┴───────────────┘
124
+ ```
125
+
126
+ ### JSON Format
127
+
128
+ ```bash
129
+ bon query '{"measures": ["orders.count"]}' --format json
130
+ ```
131
+
132
+ ```json
133
+ [
134
+ { "orders.status": "pending", "orders.count": 42 },
135
+ { "orders.status": "shipped", "orders.count": 156 },
136
+ { "orders.status": "done", "orders.count": 892 }
137
+ ]
138
+ ```
139
+
140
+ ## Common Patterns
141
+
142
+ ### Time Series Analysis
143
+
144
+ ```bash
145
+ bon query '{
146
+ "measures": ["orders.total_revenue"],
147
+ "timeDimensions": [{
148
+ "dimension": "orders.created_at",
149
+ "granularity": "month",
150
+ "dateRange": ["2024-01-01", "2024-12-31"]
151
+ }]
152
+ }'
153
+ ```
154
+
155
+ ### Filtering by Dimension
156
+
157
+ ```bash
158
+ bon query '{
159
+ "measures": ["orders.count"],
160
+ "dimensions": ["orders.city"],
161
+ "filters": [{
162
+ "member": "orders.status",
163
+ "operator": "equals",
164
+ "values": ["completed"]
165
+ }]
166
+ }'
167
+ ```
168
+
169
+ ### Multiple Measures
170
+
171
+ ```bash
172
+ bon query '{
173
+ "measures": ["orders.count", "orders.total_revenue", "orders.avg_order_value"],
174
+ "dimensions": ["orders.category"]
175
+ }'
176
+ ```
177
+
178
+ ## Error Handling
179
+
180
+ ### Common Errors
181
+
182
+ **"Projection references non-aggregate values"**
183
+ - All dimensions must be in `GROUP BY`
184
+ - All measures must use `MEASURE()` or matching aggregate
185
+
186
+ **"Cube not found"**
187
+ - Check cube name matches deployed cube
188
+ - Run `bon deploy` if cubes changed
189
+
190
+ **"Not logged in"**
191
+ - Run `bon login` first
192
+
193
+ ## See Also
194
+
195
+ - [cli.deploy](cli.deploy) - Deploy before querying
196
+ - [cubes.measures](cubes.measures) - Define measures
197
+ - [cubes.dimensions](cubes.dimensions) - Define dimensions
198
+ - [views](views) - Create focused query interfaces
@@ -0,0 +1,53 @@
1
+ # SDK
2
+
3
+ > Build custom data apps on top of your semantic layer.
4
+
5
+ The Bonnard SDK (`@bonnard/sdk`) is a lightweight TypeScript client for querying your deployed semantic layer programmatically. Build dashboards, embedded analytics, internal tools, or data pipelines — all backed by your governed metrics.
6
+
7
+ ## Quick start
8
+
9
+ ```bash
10
+ npm install @bonnard/sdk
11
+ ```
12
+
13
+ ```typescript
14
+ import { createClient } from '@bonnard/sdk';
15
+
16
+ const bonnard = createClient({
17
+ apiKey: 'your-api-key',
18
+ });
19
+
20
+ const result = await bonnard.query({
21
+ cube: 'orders',
22
+ measures: ['revenue', 'count'],
23
+ dimensions: ['status'],
24
+ timeDimension: {
25
+ dimension: 'created_at',
26
+ granularity: 'month',
27
+ dateRange: ['2025-01-01', '2025-12-31'],
28
+ },
29
+ });
30
+ ```
31
+
32
+ ## Type-safe queries
33
+
34
+ Full TypeScript support with inference. Measures, dimensions, filters, time dimensions, and sort orders are all typed. Query results include field annotations with titles and types.
35
+
36
+ ```typescript
37
+ const result = await bonnard.sql<OrderRow>(
38
+ `SELECT status, MEASURE(revenue) FROM orders GROUP BY 1`
39
+ );
40
+ // result.data is OrderRow[]
41
+ ```
42
+
43
+ ## What you can build
44
+
45
+ - **Custom dashboards** — Query your semantic layer from Next.js, React, or any frontend
46
+ - **Embedded analytics** — Add governed metrics to your product
47
+ - **Data pipelines** — Consume semantic layer data in ETL workflows
48
+ - **Internal tools** — Build admin panels backed by consistent metrics
49
+
50
+ ## See Also
51
+
52
+ - [Overview](/docs/overview) — Platform overview
53
+ - [querying.rest-api](querying.rest-api) — Query format reference
@@ -0,0 +1,18 @@
1
+ # Slack & Teams (Coming Soon)
2
+
3
+ > AI agents in your team chat. Coming soon.
4
+
5
+ Bonnard will bring semantic layer queries directly into Slack and Microsoft Teams — so anyone on your team can ask questions about data without leaving the conversation.
6
+
7
+ ## Planned capabilities
8
+
9
+ - **Natural language queries** — Ask "what was revenue last month?" in a channel and get an answer with a chart
10
+ - **Governed responses** — Every answer goes through your semantic layer, so metrics are always consistent
11
+ - **Shared context** — Results posted in channels are visible to the whole team, not siloed in individual AI chats
12
+ - **Proactive alerts** — Get notified when key metrics change beyond thresholds you define
13
+
14
+ ## Why it matters
15
+
16
+ Your team already lives in Slack and Teams. Instead of asking analysts or switching to a BI tool, anyone can get instant, governed answers right where they work. The same semantic layer that powers your AI agents and dashboards powers your team chat.
17
+
18
+ Interested in early access? Reach out at [hello@bonnard.dev](mailto:hello@bonnard.dev).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bonnard/cli",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "bon": "./dist/bin/bon.mjs"
@@ -9,7 +9,7 @@
9
9
  "dist"
10
10
  ],
11
11
  "scripts": {
12
- "build": "tsdown src/bin/bon.ts --format esm --out-dir dist/bin && cp -r src/templates dist/ && mkdir -p dist/docs/topics dist/docs/schemas && cp ../content/index.md dist/docs/_index.md && cp ../content/getting-started.md dist/docs/topics/ && cp ../content/modeling/*.md dist/docs/topics/",
12
+ "build": "tsdown src/bin/bon.ts --format esm --out-dir dist/bin && cp -r src/templates dist/ && mkdir -p dist/docs/topics dist/docs/schemas && cp ../content/index.md dist/docs/_index.md && cp ../content/overview.md ../content/getting-started.md dist/docs/topics/ && cp ../content/modeling/*.md dist/docs/topics/",
13
13
  "dev": "tsdown src/bin/bon.ts --format esm --out-dir dist/bin --watch",
14
14
  "test": "vitest run"
15
15
  },