@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,153 @@
1
+ # cubes.extends
2
+
3
+ > Reuse members from other cubes to reduce duplication.
4
+
5
+ ## Overview
6
+
7
+ The `extends` property allows a cube to inherit measures, dimensions, segments, and joins from another cube. This promotes code reusability and keeps your data model DRY.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ # Base cube with shared members
14
+ - name: base_events
15
+ sql_table: events
16
+
17
+ measures:
18
+ - name: count
19
+ type: count
20
+
21
+ dimensions:
22
+ - name: id
23
+ type: number
24
+ sql: "{CUBE}.id"
25
+ primary_key: true
26
+
27
+ - name: created_at
28
+ type: time
29
+ sql: "{CUBE}.created_at"
30
+
31
+ # Child cube extends base
32
+ - name: page_views
33
+ extends: base_events
34
+ sql_table: page_view_events
35
+
36
+ dimensions:
37
+ - name: page_url
38
+ type: string
39
+ sql: "{CUBE}.url"
40
+
41
+ # Another child cube
42
+ - name: purchases
43
+ extends: base_events
44
+ sql_table: purchase_events
45
+
46
+ measures:
47
+ - name: total_revenue
48
+ type: sum
49
+ sql: "{CUBE}.amount"
50
+ ```
51
+
52
+ ## How It Works
53
+
54
+ When a cube extends another:
55
+
56
+ 1. **Measures merge** — child gets all parent measures plus its own
57
+ 2. **Dimensions merge** — child gets all parent dimensions plus its own
58
+ 3. **Segments merge** — child gets all parent segments plus its own
59
+ 4. **Joins merge** — child gets all parent joins plus its own
60
+
61
+ ## Important: Use {CUBE}
62
+
63
+ Always use `{CUBE}` when referencing columns in extendable cubes:
64
+
65
+ ```yaml
66
+ # Good - works in parent and child cubes
67
+ dimensions:
68
+ - name: created_at
69
+ type: time
70
+ sql: "{CUBE}.created_at"
71
+
72
+ # Bad - breaks in child cubes
73
+ dimensions:
74
+ - name: created_at
75
+ type: time
76
+ sql: "{base_events}.created_at"
77
+ ```
78
+
79
+ ## Overriding Members
80
+
81
+ Child cubes can override parent members by defining them with the same name:
82
+
83
+ ```yaml
84
+ cubes:
85
+ - name: base_orders
86
+ measures:
87
+ - name: count
88
+ type: count
89
+ description: "Total orders"
90
+
91
+ - name: completed_orders
92
+ extends: base_orders
93
+ measures:
94
+ - name: count
95
+ type: count
96
+ description: "Completed orders only"
97
+ filters:
98
+ - sql: "{CUBE}.status = 'completed'"
99
+ ```
100
+
101
+ ## Common Patterns
102
+
103
+ ### Event Tables
104
+
105
+ ```yaml
106
+ cubes:
107
+ - name: base_event
108
+ dimensions:
109
+ - name: id
110
+ sql: "{CUBE}.id"
111
+ primary_key: true
112
+ - name: user_id
113
+ sql: "{CUBE}.user_id"
114
+ - name: timestamp
115
+ type: time
116
+ sql: "{CUBE}.timestamp"
117
+
118
+ - name: clicks
119
+ extends: base_event
120
+ sql_table: click_events
121
+
122
+ - name: impressions
123
+ extends: base_event
124
+ sql_table: impression_events
125
+ ```
126
+
127
+ ### Multi-Tenant Tables
128
+
129
+ ```yaml
130
+ cubes:
131
+ - name: base_orders
132
+ sql: "SELECT * FROM orders WHERE tenant_id = '{{COMPILE_CONTEXT.tenant}}'"
133
+
134
+ - name: tenant_orders
135
+ extends: base_orders
136
+ ```
137
+
138
+ ## Best Practices
139
+
140
+ 1. **Use {CUBE} everywhere** — never hardcode cube names in SQL
141
+ 2. **Keep base cubes focused** — only include truly shared members
142
+ 3. **Don't over-extend** — deep inheritance chains are hard to maintain
143
+ 4. **Document inheritance** — make it clear which cubes extend others
144
+
145
+ ## See Also
146
+
147
+ - cubes
148
+ - syntax.references
149
+ - syntax.context-variables
150
+
151
+ ## More Information
152
+
153
+ https://cube.dev/docs/product/data-modeling/concepts/code-reusability-extending-cubes
@@ -0,0 +1,178 @@
1
+ # cubes.hierarchies
2
+
3
+ > Define drill-down paths for dimensional analysis.
4
+
5
+ ## Overview
6
+
7
+ Hierarchies group dimensions into levels of granularity, enabling drill-down and roll-up analysis. Users can navigate from high-level summaries (e.g., country) down to details (e.g., city).
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql_table: orders
15
+
16
+ dimensions:
17
+ - name: country
18
+ type: string
19
+ sql: country
20
+
21
+ - name: state
22
+ type: string
23
+ sql: state
24
+
25
+ - name: city
26
+ type: string
27
+ sql: city
28
+
29
+ hierarchies:
30
+ - name: location
31
+ title: "Geographic Location"
32
+ levels:
33
+ - country
34
+ - state
35
+ - city
36
+ ```
37
+
38
+ ## Properties
39
+
40
+ | Property | Required | Description |
41
+ |----------|----------|-------------|
42
+ | `name` | Yes | Unique identifier |
43
+ | `levels` | Yes | Ordered list of dimensions (least to most granular) |
44
+ | `title` | No | Human-readable display name |
45
+ | `public` | No | API visibility (default: true) |
46
+
47
+ ## Syntax
48
+
49
+ ### Basic Hierarchy
50
+
51
+ ```yaml
52
+ hierarchies:
53
+ - name: time_hierarchy
54
+ levels:
55
+ - year
56
+ - quarter
57
+ - month
58
+ - day
59
+ ```
60
+
61
+ ### With Title
62
+
63
+ ```yaml
64
+ hierarchies:
65
+ - name: product_category
66
+ title: "Product Categories"
67
+ levels:
68
+ - department
69
+ - category
70
+ - subcategory
71
+ ```
72
+
73
+ ### Multiple Hierarchies
74
+
75
+ A dimension can appear in multiple hierarchies:
76
+
77
+ ```yaml
78
+ hierarchies:
79
+ - name: fiscal_time
80
+ levels:
81
+ - fiscal_year
82
+ - fiscal_quarter
83
+ - fiscal_month
84
+
85
+ - name: calendar_time
86
+ levels:
87
+ - calendar_year
88
+ - calendar_quarter
89
+ - calendar_month
90
+ ```
91
+
92
+ ## Cross-Cube Hierarchies
93
+
94
+ Include dimensions from joined cubes using dot notation:
95
+
96
+ ```yaml
97
+ cubes:
98
+ - name: orders
99
+ joins:
100
+ - name: users
101
+ relationship: many_to_one
102
+ sql: "{CUBE}.user_id = {users.id}"
103
+
104
+ hierarchies:
105
+ - name: customer_location
106
+ levels:
107
+ - users.country
108
+ - users.state
109
+ - users.city
110
+ ```
111
+
112
+ ## Common Patterns
113
+
114
+ ### Geographic Hierarchy
115
+
116
+ ```yaml
117
+ hierarchies:
118
+ - name: geography
119
+ title: "Location"
120
+ levels:
121
+ - continent
122
+ - country
123
+ - region
124
+ - city
125
+ ```
126
+
127
+ ### Time Hierarchy
128
+
129
+ ```yaml
130
+ hierarchies:
131
+ - name: time
132
+ title: "Time Period"
133
+ levels:
134
+ - year
135
+ - quarter
136
+ - month
137
+ - week
138
+ - day
139
+ ```
140
+
141
+ ### Organizational Hierarchy
142
+
143
+ ```yaml
144
+ hierarchies:
145
+ - name: organization
146
+ title: "Org Structure"
147
+ levels:
148
+ - division
149
+ - department
150
+ - team
151
+ ```
152
+
153
+ ### Product Hierarchy
154
+
155
+ ```yaml
156
+ hierarchies:
157
+ - name: product
158
+ title: "Product Categories"
159
+ levels:
160
+ - brand
161
+ - category
162
+ - product_line
163
+ - sku
164
+ ```
165
+
166
+ ## BI Tool Support
167
+
168
+ Hierarchy support varies by visualization tool. Check your specific tool's documentation for compatibility.
169
+
170
+ ## See Also
171
+
172
+ - cubes.dimensions
173
+ - cubes.joins
174
+ - views.folders
175
+
176
+ ## More Information
177
+
178
+ https://cube.dev/docs/reference/data-model/hierarchies
@@ -0,0 +1,119 @@
1
+ # cubes.joins
2
+
3
+ > Connect cubes together to enable cross-cube analysis.
4
+
5
+ ## Overview
6
+
7
+ Joins define relationships between cubes, allowing queries to combine measures and dimensions from multiple cubes. Cube automatically generates the appropriate SQL JOINs.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql: SELECT * FROM orders
15
+
16
+ joins:
17
+ - name: users
18
+ relationship: many_to_one
19
+ sql: "{CUBE}.user_id = {users.id}"
20
+
21
+ - name: products
22
+ relationship: many_to_one
23
+ sql: "{CUBE}.product_id = {products.id}"
24
+ ```
25
+
26
+ ## Relationship Types
27
+
28
+ ### many_to_one
29
+ Many rows in this cube relate to one row in the joined cube.
30
+
31
+ ```yaml
32
+ # Many orders belong to one user
33
+ - name: users
34
+ relationship: many_to_one
35
+ sql: "{CUBE}.user_id = {users.id}"
36
+ ```
37
+
38
+ ### one_to_many
39
+ One row in this cube relates to many rows in the joined cube.
40
+
41
+ ```yaml
42
+ # One user has many orders
43
+ - name: orders
44
+ relationship: one_to_many
45
+ sql: "{CUBE}.id = {orders.user_id}"
46
+ ```
47
+
48
+ ### one_to_one
49
+ One row in this cube relates to exactly one row in the joined cube.
50
+
51
+ ```yaml
52
+ # One user has one profile
53
+ - name: profiles
54
+ relationship: one_to_one
55
+ sql: "{CUBE}.id = {profiles.user_id}"
56
+ ```
57
+
58
+ ## Join Properties
59
+
60
+ | Property | Required | Description |
61
+ |----------|----------|-------------|
62
+ | `name` | Yes | Name of the cube to join |
63
+ | `relationship` | Yes | `many_to_one`, `one_to_many`, or `one_to_one` |
64
+ | `sql` | Yes | Join condition |
65
+
66
+ ## Syntax
67
+
68
+ ### {CUBE} Reference
69
+ Use `{CUBE}` to reference the current cube:
70
+
71
+ ```yaml
72
+ sql: "{CUBE}.user_id = {users.id}"
73
+ ```
74
+
75
+ ### Referencing Joined Cube
76
+ Use `{cube_name}` to reference the joined cube:
77
+
78
+ ```yaml
79
+ sql: "{CUBE}.product_id = {products.id}"
80
+ ```
81
+
82
+ ## Multi-hop Joins
83
+
84
+ Cubes can access data through transitive joins:
85
+
86
+ ```yaml
87
+ # orders -> users -> countries
88
+ # Query can use countries.name with orders.count
89
+
90
+ cubes:
91
+ - name: orders
92
+ joins:
93
+ - name: users
94
+ relationship: many_to_one
95
+ sql: "{CUBE}.user_id = {users.id}"
96
+
97
+ - name: users
98
+ joins:
99
+ - name: countries
100
+ relationship: many_to_one
101
+ sql: "{CUBE}.country_id = {countries.id}"
102
+ ```
103
+
104
+ ## Best Practices
105
+
106
+ 1. **Define joins on the "many" side** — put the join in orders, not users
107
+ 2. **Use primary keys** — ensure joined cubes have `primary_key` defined
108
+ 3. **Keep joins simple** — avoid complex conditions
109
+ 4. **Consider views** for specific join paths
110
+
111
+ ## See Also
112
+
113
+ - cubes
114
+ - cubes.dimensions.primary-key
115
+ - views
116
+
117
+ ## More Information
118
+
119
+ https://cube.dev/docs/reference/data-model/joins
@@ -0,0 +1,121 @@
1
+ # cubes
2
+
3
+ > Define data models that map to your database tables.
4
+
5
+ ## Overview
6
+
7
+ Cubes are the foundational building blocks of your semantic layer. Each cube represents a dataset (typically a database table or SQL query) and defines the measures (metrics) and dimensions (attributes) available for analysis.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ cubes:
13
+ - name: orders
14
+ sql_table: public.orders
15
+
16
+ measures:
17
+ - name: count
18
+ type: count
19
+
20
+ - name: total_revenue
21
+ type: sum
22
+ sql: amount
23
+
24
+ - name: average_order_value
25
+ type: number
26
+ sql: "{total_revenue} / NULLIF({count}, 0)"
27
+
28
+ dimensions:
29
+ - name: id
30
+ type: number
31
+ sql: id
32
+ primary_key: true
33
+
34
+ - name: status
35
+ type: string
36
+ sql: status
37
+
38
+ - name: created_at
39
+ type: time
40
+ sql: created_at
41
+
42
+ joins:
43
+ - name: users
44
+ relationship: many_to_one
45
+ sql: "{CUBE}.user_id = {users.id}"
46
+ ```
47
+
48
+ ## Core Properties
49
+
50
+ | Property | Required | Description |
51
+ |----------|----------|-------------|
52
+ | `name` | Yes | Unique identifier in snake_case |
53
+ | `sql` or `sql_table` | Yes | Data source query or table |
54
+ | `measures` | No | Aggregations (count, sum, avg, etc.) |
55
+ | `dimensions` | No | Attributes for grouping/filtering |
56
+ | `joins` | No | Relationships to other cubes |
57
+ | `segments` | No | Predefined filters |
58
+ | `pre_aggregations` | No | Materialized query results |
59
+
60
+ ## Data Source
61
+
62
+ ### sql_table (recommended)
63
+
64
+ For simple table references:
65
+
66
+ ```yaml
67
+ cubes:
68
+ - name: orders
69
+ sql_table: public.orders
70
+ ```
71
+
72
+ ### sql
73
+
74
+ For complex queries:
75
+
76
+ ```yaml
77
+ cubes:
78
+ - name: orders
79
+ sql: >
80
+ SELECT o.*, u.name as user_name
81
+ FROM orders o
82
+ LEFT JOIN users u ON o.user_id = u.id
83
+ ```
84
+
85
+ ## Naming Conventions
86
+
87
+ - Use `snake_case` for names
88
+ - Use plural nouns: `orders`, `users`, `products`
89
+ - Be descriptive: `order_line_items` not `oli`
90
+
91
+ ## File Organization
92
+
93
+ One cube per file in the `models/` directory:
94
+
95
+ ```
96
+ models/
97
+ ├── orders.yaml
98
+ ├── users.yaml
99
+ ├── products.yaml
100
+ └── line_items.yaml
101
+ ```
102
+
103
+ ## Best Practices
104
+
105
+ 1. **Define a primary key** — required for joins and count_distinct
106
+ 2. **Start with basic measures** — count, sum of key metrics
107
+ 3. **Add dimensions for common filters** — status, dates, categories
108
+ 4. **Use joins sparingly** — define on the "many" side
109
+ 5. **Document with descriptions** — help consumers understand the data
110
+
111
+ ## See Also
112
+
113
+ - cubes.sql
114
+ - cubes.measures
115
+ - cubes.dimensions
116
+ - cubes.joins
117
+ - cubes.segments
118
+
119
+ ## More Information
120
+
121
+ https://cube.dev/docs/reference/data-model/cube
@@ -0,0 +1,103 @@
1
+ # cubes.measures.calculated
2
+
3
+ > Build complex metrics from other measures.
4
+
5
+ ## Overview
6
+
7
+ Calculated measures combine existing measures to create derived metrics. Use the `number` type and reference other measures with `{measure_name}` syntax.
8
+
9
+ ## Example
10
+
11
+ ```yaml
12
+ measures:
13
+ - name: total_orders
14
+ type: count
15
+
16
+ - name: total_revenue
17
+ type: sum
18
+ sql: amount
19
+
20
+ - name: average_order_value
21
+ type: number
22
+ sql: "{total_revenue} / NULLIF({total_orders}, 0)"
23
+ ```
24
+
25
+ ## Syntax
26
+
27
+ ### Referencing Measures
28
+
29
+ Use curly braces to reference other measures:
30
+
31
+ ```yaml
32
+ - name: profit_margin
33
+ type: number
34
+ sql: "({revenue} - {cost}) / NULLIF({revenue}, 0)"
35
+ ```
36
+
37
+ ### Handling Division by Zero
38
+
39
+ Always use `NULLIF` to prevent division by zero:
40
+
41
+ ```yaml
42
+ - name: conversion_rate
43
+ type: number
44
+ sql: "{conversions} / NULLIF({visits}, 0)"
45
+ ```
46
+
47
+ ## Common Patterns
48
+
49
+ ### Percentages
50
+
51
+ ```yaml
52
+ - name: completion_rate
53
+ type: number
54
+ sql: "100.0 * {completed} / NULLIF({total}, 0)"
55
+ format: percent
56
+ ```
57
+
58
+ ### Ratios
59
+
60
+ ```yaml
61
+ - name: orders_per_user
62
+ type: number
63
+ sql: "{order_count} / NULLIF({user_count}, 0)"
64
+ ```
65
+
66
+ ### Profit Calculations
67
+
68
+ ```yaml
69
+ - name: gross_profit
70
+ type: number
71
+ sql: "{revenue} - {cost_of_goods}"
72
+
73
+ - name: gross_margin
74
+ type: number
75
+ sql: "{gross_profit} / NULLIF({revenue}, 0)"
76
+ format: percent
77
+ ```
78
+
79
+ ### Year-over-Year
80
+
81
+ ```yaml
82
+ - name: yoy_growth
83
+ type: number
84
+ sql: "({revenue_this_year} - {revenue_last_year}) / NULLIF({revenue_last_year}, 0)"
85
+ format: percent
86
+ ```
87
+
88
+ ## Best Practices
89
+
90
+ 1. **Build on base measures** — don't duplicate aggregation logic
91
+ 2. **Use descriptive names** — `conversion_rate` not `calc1`
92
+ 3. **Add format** — helps consumers understand the value
93
+ 4. **Document complex formulas** with `description`
94
+
95
+ ## See Also
96
+
97
+ - cubes.measures
98
+ - cubes.measures.types
99
+ - cubes.measures.rolling
100
+
101
+ ## More Information
102
+
103
+ https://cube.dev/docs/reference/data-model/measures#calculated-measures