@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.
- package/README.md +85 -0
- package/dist/bin/bon.mjs +142 -65
- package/dist/docs/_index.md +17 -6
- package/dist/docs/topics/catalog.md +36 -0
- package/dist/docs/topics/cli.deploy.md +193 -0
- package/dist/docs/topics/cli.md +113 -0
- package/dist/docs/topics/cli.validate.md +125 -0
- package/dist/docs/topics/cubes.data-source.md +1 -1
- package/dist/docs/topics/getting-started.md +2 -2
- package/dist/docs/topics/governance.md +83 -0
- package/dist/docs/topics/overview.md +49 -0
- package/dist/docs/topics/querying.mcp.md +200 -0
- package/dist/docs/topics/querying.md +11 -0
- package/dist/docs/topics/querying.rest-api.md +198 -0
- package/dist/docs/topics/querying.sdk.md +53 -0
- package/dist/docs/topics/slack-teams.md +18 -0
- package/package.json +2 -2
|
@@ -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.
|
|
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
|
},
|