@bonnard/cli 0.1.3 → 0.1.5

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.
Files changed (50) hide show
  1. package/dist/bin/bon.mjs +1919 -100
  2. package/dist/bin/models-IsV2sX74.mjs +76 -0
  3. package/dist/bin/{validate-Bd1D39Bj.mjs → validate-C4EHvJzJ.mjs} +47 -4
  4. package/dist/docs/README.md +78 -0
  5. package/dist/docs/_index.md +70 -0
  6. package/dist/docs/topics/cubes.data-source.md +92 -0
  7. package/dist/docs/topics/cubes.dimensions.format.md +195 -0
  8. package/dist/docs/topics/cubes.dimensions.md +184 -0
  9. package/dist/docs/topics/cubes.dimensions.primary-key.md +106 -0
  10. package/dist/docs/topics/cubes.dimensions.sub-query.md +174 -0
  11. package/dist/docs/topics/cubes.dimensions.time.md +111 -0
  12. package/dist/docs/topics/cubes.dimensions.types.md +107 -0
  13. package/dist/docs/topics/cubes.extends.md +149 -0
  14. package/dist/docs/topics/cubes.hierarchies.md +174 -0
  15. package/dist/docs/topics/cubes.joins.md +115 -0
  16. package/dist/docs/topics/cubes.md +117 -0
  17. package/dist/docs/topics/cubes.measures.calculated.md +99 -0
  18. package/dist/docs/topics/cubes.measures.drill-members.md +158 -0
  19. package/dist/docs/topics/cubes.measures.filters.md +86 -0
  20. package/dist/docs/topics/cubes.measures.format.md +153 -0
  21. package/dist/docs/topics/cubes.measures.md +162 -0
  22. package/dist/docs/topics/cubes.measures.rolling.md +119 -0
  23. package/dist/docs/topics/cubes.measures.types.md +122 -0
  24. package/dist/docs/topics/cubes.public.md +172 -0
  25. package/dist/docs/topics/cubes.refresh-key.md +153 -0
  26. package/dist/docs/topics/cubes.segments.md +121 -0
  27. package/dist/docs/topics/cubes.sql.md +61 -0
  28. package/dist/docs/topics/pre-aggregations.md +126 -0
  29. package/dist/docs/topics/pre-aggregations.rollup.md +162 -0
  30. package/dist/docs/topics/syntax.context-variables.md +153 -0
  31. package/dist/docs/topics/syntax.md +133 -0
  32. package/dist/docs/topics/syntax.references.md +174 -0
  33. package/dist/docs/topics/views.cubes.md +162 -0
  34. package/dist/docs/topics/views.folders.md +154 -0
  35. package/dist/docs/topics/views.includes.md +139 -0
  36. package/dist/docs/topics/views.md +138 -0
  37. package/dist/docs/topics/workflow.deploy.md +128 -0
  38. package/dist/docs/topics/workflow.mcp.md +100 -0
  39. package/dist/docs/topics/workflow.md +147 -0
  40. package/dist/docs/topics/workflow.query.md +198 -0
  41. package/dist/docs/topics/workflow.validate.md +152 -0
  42. package/dist/templates/claude/rules/bonnard.md +15 -0
  43. package/dist/templates/claude/settings.json +7 -0
  44. package/dist/templates/claude/skills/bonnard-cli/SKILL.md +59 -0
  45. package/dist/templates/claude/skills/bonnard-queries/SKILL.md +68 -0
  46. package/dist/templates/cursor/rules/bonnard-cli.mdc +47 -0
  47. package/dist/templates/cursor/rules/bonnard-queries.mdc +49 -0
  48. package/dist/templates/cursor/rules/bonnard.mdc +20 -0
  49. package/dist/templates/shared/bonnard.md +81 -0
  50. package/package.json +13 -8
@@ -0,0 +1,126 @@
1
+ # pre-aggregations
2
+
3
+ > Materialize query results for faster analytics performance.
4
+
5
+ ## Overview
6
+
7
+ Pre-aggregations are materialized tables that store pre-computed query results. They dramatically improve query performance by avoiding repeated aggregation of raw data.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql_table: orders
15
+
16
+ measures:
17
+ - name: count
18
+ type: count
19
+
20
+ - name: total_revenue
21
+ type: sum
22
+ sql: amount
23
+
24
+ dimensions:
25
+ - name: status
26
+ type: string
27
+ sql: status
28
+
29
+ - name: created_at
30
+ type: time
31
+ sql: created_at
32
+
33
+ pre_aggregations:
34
+ - name: orders_by_day
35
+ measures:
36
+ - count
37
+ - total_revenue
38
+ dimensions:
39
+ - status
40
+ time_dimension: created_at
41
+ granularity: day
42
+ ```
43
+
44
+ ## Pre-Aggregation Types
45
+
46
+ ### rollup (default)
47
+ Summarizes data into aggregated form. Most effective for performance.
48
+
49
+ ```yaml
50
+ pre_aggregations:
51
+ - name: main
52
+ type: rollup
53
+ measures:
54
+ - count
55
+ - total_revenue
56
+ dimensions:
57
+ - status
58
+ time_dimension: created_at
59
+ granularity: day
60
+ ```
61
+
62
+ ### original_sql
63
+ Persists the cube's SQL query without aggregation. Useful for complex SQL.
64
+
65
+ ```yaml
66
+ pre_aggregations:
67
+ - name: base_data
68
+ type: original_sql
69
+ ```
70
+
71
+ ### rollup_join
72
+ Joins pre-aggregations from different data sources (preview feature).
73
+
74
+ ### rollup_lambda
75
+ Combines real-time and historical data (advanced).
76
+
77
+ ## Key Properties
78
+
79
+ | Property | Description |
80
+ |----------|-------------|
81
+ | `name` | Unique identifier |
82
+ | `type` | `rollup`, `original_sql`, `rollup_join`, `rollup_lambda` |
83
+ | `measures` | Measures to include |
84
+ | `dimensions` | Dimensions to include |
85
+ | `time_dimension` | Time dimension for partitioning |
86
+ | `granularity` | Time granularity: `day`, `week`, `month`, etc. |
87
+ | `partition_granularity` | How to partition data |
88
+ | `refresh_key` | When to refresh |
89
+ | `scheduled_refresh` | Auto-refresh (default: true) |
90
+
91
+ ## Additive vs Non-Additive
92
+
93
+ **Additive measures** (count, sum, min, max) can be combined from pre-aggregated data:
94
+
95
+ ```yaml
96
+ # These work efficiently with rollups
97
+ measures:
98
+ - name: count
99
+ type: count
100
+ - name: total
101
+ type: sum
102
+ sql: amount
103
+ ```
104
+
105
+ **Non-additive measures** (count_distinct, avg) may require the original data:
106
+
107
+ ```yaml
108
+ # count_distinct needs special handling
109
+ measures:
110
+ - name: unique_users
111
+ type: count_distinct
112
+ sql: user_id
113
+ ```
114
+
115
+ ## Best Practices
116
+
117
+ 1. **Start with common queries** — pre-aggregate your most frequent access patterns
118
+ 2. **Include all needed members** — queries must match the pre-aggregation exactly
119
+ 3. **Use partitioning** — for large datasets, partition by time
120
+ 4. **Monitor refresh** — ensure data stays current
121
+
122
+ ## See Also
123
+
124
+ - pre-aggregations.rollup
125
+ - cubes.measures
126
+ - cubes.dimensions.time
@@ -0,0 +1,162 @@
1
+ # pre-aggregations.rollup
2
+
3
+ > Create summarized data tables for high-performance queries.
4
+
5
+ ## Overview
6
+
7
+ Rollup pre-aggregations summarize raw data into aggregated tables, grouped by specified dimensions. They're the most effective way to improve query performance.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ pre_aggregations:
13
+ - name: orders_daily
14
+ type: rollup
15
+ measures:
16
+ - count
17
+ - total_revenue
18
+ dimensions:
19
+ - status
20
+ - category
21
+ time_dimension: created_at
22
+ granularity: day
23
+ partition_granularity: month
24
+ ```
25
+
26
+ ## Time-Based Rollups
27
+
28
+ ### Basic Time Rollup
29
+
30
+ ```yaml
31
+ - name: daily_orders
32
+ measures:
33
+ - count
34
+ time_dimension: created_at
35
+ granularity: day
36
+ ```
37
+
38
+ ### Partitioned Rollup
39
+
40
+ Partition large datasets for efficient refreshes:
41
+
42
+ ```yaml
43
+ - name: orders_monthly_partitioned
44
+ measures:
45
+ - count
46
+ - total_revenue
47
+ time_dimension: created_at
48
+ granularity: day
49
+ partition_granularity: month
50
+ ```
51
+
52
+ ### Granularity Options
53
+
54
+ | Granularity | Description |
55
+ |-------------|-------------|
56
+ | `second` | Per-second aggregation |
57
+ | `minute` | Per-minute aggregation |
58
+ | `hour` | Hourly aggregation |
59
+ | `day` | Daily aggregation |
60
+ | `week` | Weekly aggregation |
61
+ | `month` | Monthly aggregation |
62
+ | `quarter` | Quarterly aggregation |
63
+ | `year` | Yearly aggregation |
64
+
65
+ ## Refresh Strategies
66
+
67
+ ### Time-Based Refresh
68
+
69
+ ```yaml
70
+ - name: orders_hourly
71
+ measures:
72
+ - count
73
+ time_dimension: created_at
74
+ granularity: hour
75
+ refresh_key:
76
+ every: 1 hour
77
+ ```
78
+
79
+ ### Incremental Refresh
80
+
81
+ Only refresh recent partitions:
82
+
83
+ ```yaml
84
+ - name: orders_incremental
85
+ measures:
86
+ - count
87
+ - total_revenue
88
+ time_dimension: created_at
89
+ granularity: day
90
+ partition_granularity: month
91
+ refresh_key:
92
+ every: 1 day
93
+ incremental: true
94
+ update_window: 7 day
95
+ ```
96
+
97
+ ### SQL-Based Refresh
98
+
99
+ Refresh when data changes:
100
+
101
+ ```yaml
102
+ - name: orders_on_change
103
+ measures:
104
+ - count
105
+ refresh_key:
106
+ sql: SELECT MAX(updated_at) FROM orders
107
+ ```
108
+
109
+ ## Indexes
110
+
111
+ Add indexes for better query performance:
112
+
113
+ ```yaml
114
+ - name: orders_by_status
115
+ measures:
116
+ - count
117
+ dimensions:
118
+ - status
119
+ - category
120
+ indexes:
121
+ - name: status_idx
122
+ columns:
123
+ - status
124
+ ```
125
+
126
+ ## Query Matching
127
+
128
+ A query uses a rollup if:
129
+ 1. All requested measures are in the rollup
130
+ 2. All requested dimensions are in the rollup
131
+ 3. Time dimension granularity is compatible
132
+ 4. Filters match the rollup's data
133
+
134
+ ```yaml
135
+ # This rollup...
136
+ - name: orders_daily
137
+ measures:
138
+ - count
139
+ - total_revenue
140
+ dimensions:
141
+ - status
142
+ time_dimension: created_at
143
+ granularity: day
144
+
145
+ # ...matches queries like:
146
+ # - orders.count by day
147
+ # - orders.total_revenue by status by week (day rolls up to week)
148
+ # - orders.count where status = 'completed' by month
149
+ ```
150
+
151
+ ## Best Practices
152
+
153
+ 1. **Match your queries** — design rollups around common access patterns
154
+ 2. **Use incremental refresh** — for large time-series data
155
+ 3. **Partition wisely** — monthly partitions work well for most cases
156
+ 4. **Add indexes** — for high-cardinality dimension filters
157
+
158
+ ## See Also
159
+
160
+ - pre-aggregations
161
+ - cubes.dimensions.time
162
+ - cubes.measures
@@ -0,0 +1,153 @@
1
+ # syntax.context-variables
2
+
3
+ > Access runtime context in SQL expressions.
4
+
5
+ ## Overview
6
+
7
+ Context variables provide access to runtime information within cube definitions. Use them for dynamic SQL generation, filter handling, and security context.
8
+
9
+ ## Context Variables
10
+
11
+ ### {CUBE}
12
+
13
+ References the current cube without repeating its name:
14
+
15
+ ```yaml
16
+ cubes:
17
+ - name: orders
18
+ dimensions:
19
+ - name: status
20
+ type: string
21
+ sql: "{CUBE}.status" # Same as "{orders}.status"
22
+
23
+ measures:
24
+ - name: completed_count
25
+ type: count
26
+ filters:
27
+ - sql: "{CUBE}.status = 'completed'"
28
+ ```
29
+
30
+ Essential when using `extends` so SQL works in child cubes.
31
+
32
+ ### FILTER_PARAMS
33
+
34
+ Access filter values from queries during SQL generation:
35
+
36
+ ```yaml
37
+ cubes:
38
+ - name: orders
39
+ sql: >
40
+ SELECT * FROM orders
41
+ WHERE {FILTER_PARAMS.orders.created_at.filter('created_at')}
42
+ ```
43
+
44
+ Useful for:
45
+ - Partition pruning in data warehouses
46
+ - Predicate pushdown optimization
47
+ - Dynamic table selection
48
+
49
+ Syntax: `{FILTER_PARAMS.cube_name.member_name.filter('sql_expression')}`
50
+
51
+ ### FILTER_GROUP
52
+
53
+ Wraps multiple FILTER_PARAMS when combining with OR:
54
+
55
+ ```yaml
56
+ sql: >
57
+ SELECT * FROM orders
58
+ WHERE {FILTER_GROUP(
59
+ FILTER_PARAMS.orders.status.filter('status'),
60
+ FILTER_PARAMS.orders.type.filter('type')
61
+ )}
62
+ ```
63
+
64
+ Prevents incorrect SQL when filters use OR logic.
65
+
66
+ ### COMPILE_CONTEXT
67
+
68
+ Evaluated once per deployment context. Access via Jinja syntax:
69
+
70
+ ```yaml
71
+ cubes:
72
+ - name: orders
73
+ sql_table: "{{ COMPILE_CONTEXT.schema }}.orders"
74
+
75
+ public: "{{ 'true' if COMPILE_CONTEXT.role == 'admin' else 'false' }}"
76
+ ```
77
+
78
+ Common uses:
79
+ - Multi-tenant table names
80
+ - Environment-specific configuration
81
+ - Role-based visibility
82
+
83
+ ### SQL_UTILS
84
+
85
+ Helper functions for SQL generation:
86
+
87
+ ```yaml
88
+ dimensions:
89
+ - name: created_at_local
90
+ type: time
91
+ sql: "{SQL_UTILS.convertTz('created_at', 'UTC', 'America/New_York')}"
92
+ ```
93
+
94
+ **convertTz()**: Converts timestamps between timezones.
95
+
96
+ Note: Don't use SQL_UTILS dimensions as `timeDimensions` in queries to avoid double conversion.
97
+
98
+ ## Examples
99
+
100
+ ### Partition Filtering (Snowflake/BigQuery)
101
+
102
+ ```yaml
103
+ cubes:
104
+ - name: events
105
+ sql: >
106
+ SELECT * FROM events
107
+ WHERE {FILTER_PARAMS.events.timestamp.filter('timestamp')}
108
+ ```
109
+
110
+ When querying with a date filter, this pushes the filter to the partition column for efficient pruning.
111
+
112
+ ### Multi-Tenant Tables
113
+
114
+ ```yaml
115
+ cubes:
116
+ - name: orders
117
+ sql_table: "{{ COMPILE_CONTEXT.tenant_schema }}.orders"
118
+ ```
119
+
120
+ ### Dynamic Visibility
121
+
122
+ ```yaml
123
+ cubes:
124
+ - name: sensitive_data
125
+ public: "{{ 'true' if COMPILE_CONTEXT.user_role in ['admin', 'analyst'] else 'false' }}"
126
+ ```
127
+
128
+ ### Timezone Conversion
129
+
130
+ ```yaml
131
+ dimensions:
132
+ - name: created_at_et
133
+ type: time
134
+ sql: "{SQL_UTILS.convertTz('created_at', 'UTC', 'America/New_York')}"
135
+ title: "Created At (ET)"
136
+ ```
137
+
138
+ ## Best Practices
139
+
140
+ 1. **Use {CUBE}** in extendable cubes — never hardcode cube names
141
+ 2. **Use FILTER_PARAMS** for partition pruning — improves query performance
142
+ 3. **Use COMPILE_CONTEXT** for deployment config — not for per-query logic
143
+ 4. **Test filter pushdown** — verify FILTER_PARAMS generates expected SQL
144
+
145
+ ## Deprecated: SECURITY_CONTEXT
146
+
147
+ `SECURITY_CONTEXT` is deprecated. Use `query_rewrite` for security filtering instead.
148
+
149
+ ## See Also
150
+
151
+ - syntax
152
+ - syntax.references
153
+ - cubes.extends
@@ -0,0 +1,133 @@
1
+ # syntax
2
+
3
+ > YAML syntax and conventions for Cube data models.
4
+
5
+ ## Overview
6
+
7
+ Cube data models are defined in YAML files. Understanding the syntax conventions helps you write correct and maintainable models.
8
+
9
+ ## File Structure
10
+
11
+ ### Cubes File
12
+
13
+ ```yaml
14
+ cubes:
15
+ - name: orders
16
+ sql_table: public.orders
17
+
18
+ measures:
19
+ - name: count
20
+ type: count
21
+
22
+ dimensions:
23
+ - name: id
24
+ type: number
25
+ sql: id
26
+ primary_key: true
27
+ ```
28
+
29
+ ### Views File
30
+
31
+ ```yaml
32
+ views:
33
+ - name: orders_overview
34
+ cubes:
35
+ - join_path: orders
36
+ includes:
37
+ - count
38
+ - status
39
+ ```
40
+
41
+ ## Naming Conventions
42
+
43
+ ### Cube and View Names
44
+
45
+ - Use `snake_case`
46
+ - Be descriptive: `user_orders`, not `uo`
47
+ - Use plural for collections: `orders`, `users`
48
+
49
+ ```yaml
50
+ cubes:
51
+ - name: orders # Good
52
+ - name: user_activity # Good
53
+ - name: Orders # Bad - use lowercase
54
+ - name: userOrders # Bad - use snake_case
55
+ ```
56
+
57
+ ### Member Names
58
+
59
+ - Use `snake_case`
60
+ - Be descriptive but concise
61
+
62
+ ```yaml
63
+ measures:
64
+ - name: count # Good
65
+ - name: total_revenue # Good
66
+ - name: average_order_value # Good
67
+ - name: aov # Bad - unclear abbreviation
68
+ ```
69
+
70
+ ## SQL Expressions
71
+
72
+ ### Inline SQL
73
+
74
+ ```yaml
75
+ dimensions:
76
+ - name: full_name
77
+ type: string
78
+ sql: "CONCAT(first_name, ' ', last_name)"
79
+ ```
80
+
81
+ ### Multi-line SQL
82
+
83
+ Use YAML block scalar for complex SQL:
84
+
85
+ ```yaml
86
+ cubes:
87
+ - name: orders
88
+ sql: >
89
+ SELECT
90
+ o.*,
91
+ u.name as user_name
92
+ FROM orders o
93
+ LEFT JOIN users u ON o.user_id = u.id
94
+ ```
95
+
96
+ ## Common Patterns
97
+
98
+ ### Quoting
99
+
100
+ Quote SQL expressions with special characters:
101
+
102
+ ```yaml
103
+ # Quoted - required for expressions
104
+ sql: "{CUBE}.amount * 0.1"
105
+
106
+ # Unquoted - simple column reference
107
+ sql: amount
108
+ ```
109
+
110
+ ### Arrays
111
+
112
+ ```yaml
113
+ # Inline array
114
+ includes: [count, total_revenue]
115
+
116
+ # Block array
117
+ includes:
118
+ - count
119
+ - total_revenue
120
+ ```
121
+
122
+ ### Booleans
123
+
124
+ ```yaml
125
+ primary_key: true
126
+ public: false
127
+ ```
128
+
129
+ ## See Also
130
+
131
+ - syntax.references
132
+ - cubes
133
+ - views