@bonnard/cli 0.1.2 → 0.1.4

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 (49) hide show
  1. package/dist/bin/bon.mjs +1892 -97
  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 +82 -0
  5. package/dist/docs/_index.md +69 -0
  6. package/dist/docs/topics/cubes.data-source.md +96 -0
  7. package/dist/docs/topics/cubes.dimensions.format.md +199 -0
  8. package/dist/docs/topics/cubes.dimensions.md +188 -0
  9. package/dist/docs/topics/cubes.dimensions.primary-key.md +110 -0
  10. package/dist/docs/topics/cubes.dimensions.sub-query.md +178 -0
  11. package/dist/docs/topics/cubes.dimensions.time.md +115 -0
  12. package/dist/docs/topics/cubes.dimensions.types.md +111 -0
  13. package/dist/docs/topics/cubes.extends.md +153 -0
  14. package/dist/docs/topics/cubes.hierarchies.md +178 -0
  15. package/dist/docs/topics/cubes.joins.md +119 -0
  16. package/dist/docs/topics/cubes.md +121 -0
  17. package/dist/docs/topics/cubes.measures.calculated.md +103 -0
  18. package/dist/docs/topics/cubes.measures.drill-members.md +162 -0
  19. package/dist/docs/topics/cubes.measures.filters.md +90 -0
  20. package/dist/docs/topics/cubes.measures.format.md +157 -0
  21. package/dist/docs/topics/cubes.measures.md +166 -0
  22. package/dist/docs/topics/cubes.measures.rolling.md +123 -0
  23. package/dist/docs/topics/cubes.measures.types.md +126 -0
  24. package/dist/docs/topics/cubes.public.md +176 -0
  25. package/dist/docs/topics/cubes.refresh-key.md +157 -0
  26. package/dist/docs/topics/cubes.segments.md +125 -0
  27. package/dist/docs/topics/cubes.sql.md +65 -0
  28. package/dist/docs/topics/pre-aggregations.md +130 -0
  29. package/dist/docs/topics/pre-aggregations.rollup.md +166 -0
  30. package/dist/docs/topics/syntax.context-variables.md +157 -0
  31. package/dist/docs/topics/syntax.md +137 -0
  32. package/dist/docs/topics/syntax.references.md +178 -0
  33. package/dist/docs/topics/views.cubes.md +166 -0
  34. package/dist/docs/topics/views.folders.md +158 -0
  35. package/dist/docs/topics/views.includes.md +143 -0
  36. package/dist/docs/topics/views.md +142 -0
  37. package/dist/docs/topics/workflow.deploy.md +132 -0
  38. package/dist/docs/topics/workflow.md +151 -0
  39. package/dist/docs/topics/workflow.query.md +203 -0
  40. package/dist/docs/topics/workflow.validate.md +156 -0
  41. package/dist/templates/claude/rules/bonnard.md +15 -0
  42. package/dist/templates/claude/settings.json +7 -0
  43. package/dist/templates/claude/skills/bonnard-cli/SKILL.md +59 -0
  44. package/dist/templates/claude/skills/bonnard-queries/SKILL.md +68 -0
  45. package/dist/templates/cursor/rules/bonnard-cli.mdc +47 -0
  46. package/dist/templates/cursor/rules/bonnard-queries.mdc +49 -0
  47. package/dist/templates/cursor/rules/bonnard.mdc +20 -0
  48. package/dist/templates/shared/bonnard.md +81 -0
  49. package/package.json +8 -3
@@ -0,0 +1,126 @@
1
+ # cubes.measures.types
2
+
3
+ > The 12 measure types available for aggregating data.
4
+
5
+ ## Overview
6
+
7
+ Cube supports 12 measure types that determine how values are aggregated. Choose the right type based on your analytical needs.
8
+
9
+ ## Measure Types
10
+
11
+ ### count
12
+ Counts the number of rows.
13
+
14
+ ```yaml
15
+ - name: count
16
+ type: count
17
+ ```
18
+
19
+ ### count_distinct
20
+ Counts unique values of a column.
21
+
22
+ ```yaml
23
+ - name: unique_users
24
+ type: count_distinct
25
+ sql: user_id
26
+ ```
27
+
28
+ ### count_distinct_approx
29
+ Approximate count distinct (faster for large datasets).
30
+
31
+ ```yaml
32
+ - name: approx_unique_users
33
+ type: count_distinct_approx
34
+ sql: user_id
35
+ ```
36
+
37
+ ### sum
38
+ Adds up numeric values.
39
+
40
+ ```yaml
41
+ - name: total_revenue
42
+ type: sum
43
+ sql: amount
44
+ ```
45
+
46
+ ### avg
47
+ Calculates the average of numeric values.
48
+
49
+ ```yaml
50
+ - name: average_order_value
51
+ type: avg
52
+ sql: amount
53
+ ```
54
+
55
+ ### min
56
+ Returns the minimum value.
57
+
58
+ ```yaml
59
+ - name: first_order_date
60
+ type: min
61
+ sql: created_at
62
+ ```
63
+
64
+ ### max
65
+ Returns the maximum value.
66
+
67
+ ```yaml
68
+ - name: last_order_date
69
+ type: max
70
+ sql: created_at
71
+ ```
72
+
73
+ ### number
74
+ A calculated number (not aggregated from rows).
75
+
76
+ ```yaml
77
+ - name: conversion_rate
78
+ type: number
79
+ sql: "{completed_orders} / NULLIF({total_orders}, 0)"
80
+ ```
81
+
82
+ ### string
83
+ A calculated string value.
84
+
85
+ ```yaml
86
+ - name: status_label
87
+ type: string
88
+ sql: "'Active'"
89
+ ```
90
+
91
+ ### time
92
+ A calculated time value.
93
+
94
+ ```yaml
95
+ - name: current_timestamp
96
+ type: time
97
+ sql: NOW()
98
+ ```
99
+
100
+ ### boolean
101
+ A calculated boolean value.
102
+
103
+ ```yaml
104
+ - name: has_orders
105
+ type: boolean
106
+ sql: "{count} > 0"
107
+ ```
108
+
109
+ ### number_agg
110
+ Custom aggregate function (advanced).
111
+
112
+ ```yaml
113
+ - name: median_price
114
+ type: number_agg
115
+ sql: "PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY {CUBE}.price)"
116
+ ```
117
+
118
+ ## See Also
119
+
120
+ - cubes.measures
121
+ - cubes.measures.calculated
122
+ - cubes.measures.filters
123
+
124
+ ## More Information
125
+
126
+ https://cube.dev/docs/reference/data-model/types-and-formats#measure-types
@@ -0,0 +1,176 @@
1
+ # cubes.public
2
+
3
+ > Control visibility of cubes, measures, and dimensions in the API.
4
+
5
+ ## Overview
6
+
7
+ The `public` property controls whether a cube or its members are exposed through the API. Set to `false` to hide internal or intermediate data from consumers.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ # Hidden cube - used for joins only
14
+ - name: internal_mappings
15
+ public: false
16
+ sql_table: internal.mappings
17
+
18
+ dimensions:
19
+ - name: id
20
+ type: number
21
+ sql: id
22
+ primary_key: true
23
+
24
+ # Public cube with some hidden members
25
+ - name: orders
26
+ sql_table: orders
27
+
28
+ measures:
29
+ - name: count
30
+ type: count
31
+
32
+ - name: internal_score
33
+ type: avg
34
+ sql: score
35
+ public: false # Hidden from API
36
+
37
+ dimensions:
38
+ - name: id
39
+ type: number
40
+ sql: id
41
+ primary_key: true
42
+ public: false # Primary keys auto-hide by default
43
+
44
+ - name: status
45
+ type: string
46
+ sql: status
47
+ ```
48
+
49
+ ## Syntax
50
+
51
+ ### Cube Level
52
+
53
+ ```yaml
54
+ cubes:
55
+ - name: internal_cube
56
+ public: false
57
+ ```
58
+
59
+ ### Measure Level
60
+
61
+ ```yaml
62
+ measures:
63
+ - name: debug_metric
64
+ type: count
65
+ public: false
66
+ ```
67
+
68
+ ### Dimension Level
69
+
70
+ ```yaml
71
+ dimensions:
72
+ - name: internal_id
73
+ type: string
74
+ sql: internal_id
75
+ public: false
76
+ ```
77
+
78
+ ### Segment Level
79
+
80
+ ```yaml
81
+ segments:
82
+ - name: test_users
83
+ sql: "{CUBE}.is_test = true"
84
+ public: false
85
+ ```
86
+
87
+ ## Default Behavior
88
+
89
+ | Member Type | Default `public` |
90
+ |-------------|------------------|
91
+ | Cube | `true` |
92
+ | Measure | `true` |
93
+ | Dimension | `true` |
94
+ | Dimension with `primary_key: true` | `false` |
95
+ | Segment | `true` |
96
+
97
+ ## Use Cases
98
+
99
+ ### Internal Cubes
100
+
101
+ Hide cubes used only for joins or intermediate calculations:
102
+
103
+ ```yaml
104
+ cubes:
105
+ - name: user_scores_internal
106
+ public: false
107
+ sql: "SELECT user_id, calculate_score() as score FROM users"
108
+ ```
109
+
110
+ ### Sensitive Fields
111
+
112
+ Hide fields that shouldn't be queried directly:
113
+
114
+ ```yaml
115
+ dimensions:
116
+ - name: password_hash
117
+ type: string
118
+ sql: password_hash
119
+ public: false
120
+
121
+ - name: api_secret
122
+ type: string
123
+ sql: api_secret
124
+ public: false
125
+ ```
126
+
127
+ ### Intermediate Measures
128
+
129
+ Hide measures used only in calculations:
130
+
131
+ ```yaml
132
+ measures:
133
+ - name: raw_numerator
134
+ type: sum
135
+ sql: value
136
+ public: false
137
+
138
+ - name: raw_denominator
139
+ type: count
140
+ public: false
141
+
142
+ - name: ratio
143
+ type: number
144
+ sql: "{raw_numerator} / NULLIF({raw_denominator}, 0)"
145
+ # This is public (default)
146
+ ```
147
+
148
+ ### Debug/Test Members
149
+
150
+ ```yaml
151
+ segments:
152
+ - name: test_data
153
+ sql: "{CUBE}.is_test = true"
154
+ public: false
155
+ ```
156
+
157
+ ## Dynamic Visibility
158
+
159
+ Use `COMPILE_CONTEXT` for dynamic visibility based on context:
160
+
161
+ ```yaml
162
+ cubes:
163
+ - name: admin_metrics
164
+ public: "{{ 'true' if COMPILE_CONTEXT.role == 'admin' else 'false' }}"
165
+ ```
166
+
167
+ ## See Also
168
+
169
+ - cubes
170
+ - cubes.measures
171
+ - cubes.dimensions
172
+ - views
173
+
174
+ ## More Information
175
+
176
+ https://cube.dev/docs/reference/data-model/cube#public
@@ -0,0 +1,157 @@
1
+ # cubes.refresh-key
2
+
3
+ > Control when cube data is refreshed in the cache.
4
+
5
+ ## Overview
6
+
7
+ The `refresh_key` property determines when Cube's cache should be invalidated. Use it to ensure queries return fresh data while optimizing performance.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql_table: orders
15
+
16
+ refresh_key:
17
+ every: 1 hour
18
+
19
+ measures:
20
+ - name: count
21
+ type: count
22
+ ```
23
+
24
+ ## Refresh Strategies
25
+
26
+ ### Time-Based Refresh
27
+
28
+ Refresh at regular intervals:
29
+
30
+ ```yaml
31
+ refresh_key:
32
+ every: 1 hour
33
+ ```
34
+
35
+ ```yaml
36
+ refresh_key:
37
+ every: 10 minute
38
+ ```
39
+
40
+ ```yaml
41
+ refresh_key:
42
+ every: 1 day
43
+ ```
44
+
45
+ ### SQL-Based Refresh
46
+
47
+ Refresh when a SQL query returns a different value:
48
+
49
+ ```yaml
50
+ refresh_key:
51
+ sql: SELECT MAX(updated_at) FROM orders
52
+ ```
53
+
54
+ This is efficient for append-only or update-tracked tables.
55
+
56
+ ### Combined Approach
57
+
58
+ Use SQL with a time-based check interval:
59
+
60
+ ```yaml
61
+ refresh_key:
62
+ sql: SELECT MAX(updated_at) FROM orders
63
+ every: 5 minute
64
+ ```
65
+
66
+ The SQL runs every 5 minutes; cache refreshes only when the result changes.
67
+
68
+ ## Syntax
69
+
70
+ ### every
71
+
72
+ Time interval format: `<number> <unit>`
73
+
74
+ | Unit | Examples |
75
+ |------|----------|
76
+ | `second` | `30 second` |
77
+ | `minute` | `5 minute`, `10 minute` |
78
+ | `hour` | `1 hour`, `6 hour` |
79
+ | `day` | `1 day` |
80
+ | `week` | `1 week` |
81
+
82
+ ### sql
83
+
84
+ Any SQL that returns a single value. Common patterns:
85
+
86
+ ```yaml
87
+ # Max timestamp (for append-only data)
88
+ sql: SELECT MAX(created_at) FROM orders
89
+
90
+ # Row count (for small tables)
91
+ sql: SELECT COUNT(*) FROM orders
92
+
93
+ # Checksum (for frequently updated data)
94
+ sql: SELECT CHECKSUM_AGG(CHECKSUM(*)) FROM orders
95
+ ```
96
+
97
+ ## Common Patterns
98
+
99
+ ### Real-Time Data
100
+
101
+ ```yaml
102
+ refresh_key:
103
+ every: 1 minute
104
+ ```
105
+
106
+ ### Daily Batch Data
107
+
108
+ ```yaml
109
+ refresh_key:
110
+ every: 1 day
111
+ sql: SELECT MAX(load_date) FROM daily_snapshot
112
+ ```
113
+
114
+ ### Event Stream Data
115
+
116
+ ```yaml
117
+ refresh_key:
118
+ sql: SELECT MAX(event_id) FROM events
119
+ every: 30 second
120
+ ```
121
+
122
+ ### Slowly Changing Data
123
+
124
+ ```yaml
125
+ refresh_key:
126
+ every: 6 hour
127
+ ```
128
+
129
+ ## Pre-Aggregation Refresh
130
+
131
+ Pre-aggregations have their own refresh_key:
132
+
133
+ ```yaml
134
+ pre_aggregations:
135
+ - name: main
136
+ measures:
137
+ - count
138
+ refresh_key:
139
+ every: 1 hour
140
+ ```
141
+
142
+ ## Best Practices
143
+
144
+ 1. **Match data freshness needs** — don't refresh more often than necessary
145
+ 2. **Use SQL-based refresh** — for tables with update timestamps
146
+ 3. **Consider pre-aggregations** — they have separate refresh cycles
147
+ 4. **Monitor performance** — frequent refreshes impact query latency
148
+
149
+ ## See Also
150
+
151
+ - cubes
152
+ - pre-aggregations
153
+ - pre-aggregations.rollup
154
+
155
+ ## More Information
156
+
157
+ https://cube.dev/docs/reference/data-model/cube#refresh-key
@@ -0,0 +1,125 @@
1
+ # cubes.segments
2
+
3
+ > Define reusable row-level filters.
4
+
5
+ ## Overview
6
+
7
+ Segments are predefined filters that can be applied to queries. They make common filtering patterns reusable and ensure consistent definitions across analyses.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql: SELECT * FROM orders
15
+
16
+ segments:
17
+ - name: completed
18
+ sql: "{CUBE}.status = 'completed'"
19
+
20
+ - name: high_value
21
+ sql: "{CUBE}.amount > 1000"
22
+
23
+ - name: this_year
24
+ sql: "YEAR({CUBE}.created_at) = YEAR(CURRENT_DATE)"
25
+ ```
26
+
27
+ ## Syntax
28
+
29
+ ### Basic Segment
30
+
31
+ ```yaml
32
+ segments:
33
+ - name: active
34
+ sql: "{CUBE}.is_active = true"
35
+ ```
36
+
37
+ ### Multiple Conditions
38
+
39
+ ```yaml
40
+ segments:
41
+ - name: premium_active
42
+ sql: "{CUBE}.is_active = true AND {CUBE}.plan = 'premium'"
43
+ ```
44
+
45
+ ### Using References
46
+
47
+ ```yaml
48
+ segments:
49
+ - name: has_recent_order
50
+ sql: "{CUBE}.last_order_date > CURRENT_DATE - INTERVAL '30 days'"
51
+ ```
52
+
53
+ ## Segments vs Filters
54
+
55
+ | Segments | Query Filters |
56
+ |----------|---------------|
57
+ | Predefined in model | Applied at query time |
58
+ | Named and reusable | Ad-hoc |
59
+ | Part of the schema | Part of the query |
60
+ | Self-documenting | Requires context |
61
+
62
+ ## Segments vs Filtered Measures
63
+
64
+ | Use Case | Solution |
65
+ |----------|----------|
66
+ | Filter all measures in a query | Segment |
67
+ | Create a specific filtered metric | Filtered measure |
68
+
69
+ ```yaml
70
+ # Segment: filters entire query
71
+ segments:
72
+ - name: completed
73
+ sql: "{CUBE}.status = 'completed'"
74
+
75
+ # Filtered measure: only this metric
76
+ measures:
77
+ - name: completed_count
78
+ type: count
79
+ filters:
80
+ - sql: "{CUBE}.status = 'completed'"
81
+ ```
82
+
83
+ ## Common Patterns
84
+
85
+ ### Status Segments
86
+
87
+ ```yaml
88
+ segments:
89
+ - name: pending
90
+ sql: "{CUBE}.status = 'pending'"
91
+ - name: completed
92
+ sql: "{CUBE}.status = 'completed'"
93
+ - name: cancelled
94
+ sql: "{CUBE}.status = 'cancelled'"
95
+ ```
96
+
97
+ ### Time-based Segments
98
+
99
+ ```yaml
100
+ segments:
101
+ - name: last_7_days
102
+ sql: "{CUBE}.created_at >= CURRENT_DATE - INTERVAL '7 days'"
103
+ - name: last_30_days
104
+ sql: "{CUBE}.created_at >= CURRENT_DATE - INTERVAL '30 days'"
105
+ ```
106
+
107
+ ### Business Logic Segments
108
+
109
+ ```yaml
110
+ segments:
111
+ - name: churned
112
+ sql: "{CUBE}.last_activity_at < CURRENT_DATE - INTERVAL '90 days'"
113
+ - name: high_value_customer
114
+ sql: "{CUBE}.lifetime_value > 10000"
115
+ ```
116
+
117
+ ## See Also
118
+
119
+ - cubes
120
+ - cubes.measures.filters
121
+ - views
122
+
123
+ ## More Information
124
+
125
+ https://cube.dev/docs/reference/data-model/segments
@@ -0,0 +1,65 @@
1
+ # cubes.sql
2
+
3
+ > Define the SQL table or subquery that powers a cube.
4
+
5
+ ## Overview
6
+
7
+ The `sql` property defines the base table or SQL subquery that a cube is built on. This is the foundation for all measures and dimensions in the cube.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql: SELECT * FROM public.orders
15
+
16
+ - name: orders_with_users
17
+ sql: >
18
+ SELECT o.*, u.name as user_name
19
+ FROM public.orders o
20
+ LEFT JOIN public.users u ON o.user_id = u.id
21
+ ```
22
+
23
+ ## Options
24
+
25
+ ### sql (required)
26
+ The SQL SELECT statement or table reference.
27
+
28
+ ```yaml
29
+ # Simple table reference
30
+ sql: SELECT * FROM orders
31
+
32
+ # Subquery with joins
33
+ sql: >
34
+ SELECT o.*, p.name as product_name
35
+ FROM orders o
36
+ JOIN products p ON o.product_id = p.id
37
+
38
+ # Using references to other cubes
39
+ sql: SELECT * FROM {users.sql()} WHERE active = true
40
+ ```
41
+
42
+ ### sql_table
43
+ Alternative to `sql` — directly reference a table without SELECT.
44
+
45
+ ```yaml
46
+ cubes:
47
+ - name: orders
48
+ sql_table: public.orders
49
+ ```
50
+
51
+ ## Best Practices
52
+
53
+ 1. **Prefer sql_table** when selecting all columns from a single table
54
+ 2. **Use subqueries** for complex joins or filtering at the cube level
55
+ 3. **Avoid aggregations** in the base SQL — let measures handle that
56
+
57
+ ## See Also
58
+
59
+ - cubes
60
+ - cubes.data-source
61
+ - syntax.references
62
+
63
+ ## More Information
64
+
65
+ https://cube.dev/docs/reference/data-model/cube#sql