@metabase/cli 0.1.0 → 0.1.1

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 (187) hide show
  1. package/README.md +972 -57
  2. package/dist/add-collection--zwkmE1S.mjs +11 -0
  3. package/dist/add-collection-B1qe0D1U.mjs +54 -0
  4. package/dist/api-key-gzCbKDjL.mjs +13 -0
  5. package/dist/archive-CitmlD1e.mjs +39 -0
  6. package/dist/{archive-CsWeHXle.mjs → archive-CnhWegtR.mjs} +7 -4
  7. package/dist/archive-DQjBOXnx.mjs +44 -0
  8. package/dist/archive-Ni8-lQ1Y.mjs +44 -0
  9. package/dist/auth-BPjsrFxM.mjs +19 -0
  10. package/dist/{body-Dv9hQ0Qk.mjs → body-DRBgxS6-.mjs} +3 -2
  11. package/dist/{branches-BujtceGr.mjs → branches-C5Jcw8wu.mjs} +8 -6
  12. package/dist/cancel-Ca3r7Y6v.mjs +56 -0
  13. package/dist/{cancel-task-CT2xUMRg.mjs → cancel-task-C1-8vDKS.mjs} +9 -7
  14. package/dist/card-BGAy3eIb.mjs +20 -0
  15. package/dist/{card-CsXk8T6A.mjs → card-CAEZWixN.mjs} +34 -15
  16. package/dist/cards-CILfMPUP.mjs +37 -0
  17. package/dist/cli.mjs +33 -14
  18. package/dist/collection-B3sPXRLs.mjs +163 -0
  19. package/dist/collection-D8cnCB98.mjs +19 -0
  20. package/dist/create-3Z6rm-4O.mjs +44 -0
  21. package/dist/create-BsY5RrVY.mjs +44 -0
  22. package/dist/create-C4OCclBD.mjs +48 -0
  23. package/dist/create-COsD7Vzm.mjs +48 -0
  24. package/dist/create-CP8ou91U.mjs +125 -0
  25. package/dist/create-CeIi_QLj.mjs +66 -0
  26. package/dist/create-CqNw6PmR.mjs +50 -0
  27. package/dist/create-DE_5NrFy.mjs +48 -0
  28. package/dist/{create-B8ektf-R.mjs → create-MEhhhgMC.mjs} +8 -6
  29. package/dist/create-QxDmleKJ.mjs +48 -0
  30. package/dist/{create-branch-goZBTNnr.mjs → create-branch-CKMYaAHk.mjs} +9 -7
  31. package/dist/credentials-CwRKvdP2.mjs +85 -0
  32. package/dist/{current-task-DBjRNCFq.mjs → current-task-Dutjys16.mjs} +9 -7
  33. package/dist/dashboard-B4fVp392.mjs +20 -0
  34. package/dist/dashboard-CnMD04PQ.mjs +163 -0
  35. package/dist/database-BMTb0CzV.mjs +17 -0
  36. package/dist/database-Dvkfy3JM.mjs +51 -0
  37. package/dist/db-ACuuaEok.mjs +22 -0
  38. package/dist/{delete-8vGU35r3.mjs → delete-BMQZuVXZ.mjs} +7 -5
  39. package/dist/{delete-B27KLF5X.mjs → delete-BvcA4jPj.mjs} +7 -5
  40. package/dist/{delete-runtime-Byr60cR3.mjs → delete-runtime-BMzvfj_B.mjs} +4 -4
  41. package/dist/{delete-table-BNaJ_gA4.mjs → delete-table-DUPjHKk4.mjs} +7 -5
  42. package/dist/deprovision-Bsc1S15j.mjs +61 -0
  43. package/dist/{dirty-aNUuph4I.mjs → dirty-CXcdoUhY.mjs} +8 -6
  44. package/dist/docker-D-ieBsP7.mjs +612 -0
  45. package/dist/eid-pvOsEMPZ.mjs +13 -0
  46. package/dist/{export-QDkuuzSE.mjs → export-BjGhLEOi.mjs} +30 -23
  47. package/dist/field-BI2bt8e9.mjs +18 -0
  48. package/dist/field-DciLbuv-.mjs +276 -0
  49. package/dist/fields-Do8HHm_T.mjs +38 -0
  50. package/dist/flag-pair-DtR1AiBQ.mjs +17 -0
  51. package/dist/{get-BGBIzMKY.mjs → get-BGFGWkH0.mjs} +6 -4
  52. package/dist/get-BmE_VHdl.mjs +36 -0
  53. package/dist/{get-DI_IJvgk.mjs → get-C7sshmqF.mjs} +6 -4
  54. package/dist/get-CObKBj2J.mjs +36 -0
  55. package/dist/get-Cq5U_Eep.mjs +40 -0
  56. package/dist/get-D4GUJBiX.mjs +41 -0
  57. package/dist/{get-COXHplHP.mjs → get-DFrsi77F.mjs} +7 -5
  58. package/dist/get-DczxeETg.mjs +53 -0
  59. package/dist/{get-Cl8-IauC.mjs → get-DeQa3ThJ.mjs} +7 -4
  60. package/dist/get-DhZ_dGUb.mjs +36 -0
  61. package/dist/{get-i6LWOByV.mjs → get-DzCVafyO.mjs} +6 -4
  62. package/dist/get-YCnVqq-z.mjs +49 -0
  63. package/dist/get-run-CTyW29s3.mjs +36 -0
  64. package/dist/git-sync-BOmT8HEU.mjs +28 -0
  65. package/dist/{has-remote-changes-hjKoQuRy.mjs → has-remote-changes-xX8vMVsX.mjs} +8 -6
  66. package/dist/{import-HJsSKRYx.mjs → import-CaAUNtXz.mjs} +11 -9
  67. package/dist/{input-Dojr-RTw.mjs → input-ikCiip6x.mjs} +2 -1
  68. package/dist/is-dirty-CPu-xqkW.mjs +10 -0
  69. package/dist/{is-dirty-1Qy7hiHB.mjs → is-dirty-mgxEwEk4.mjs} +5 -4
  70. package/dist/items-Cg67tdto.mjs +77 -0
  71. package/dist/{key-DBxPSFwi.mjs → key-NDEARu2L.mjs} +1 -1
  72. package/dist/{license-MoWse3ZI.mjs → license-CwKzVMD0.mjs} +3 -3
  73. package/dist/list-BqdNQ1nU.mjs +47 -0
  74. package/dist/list-BwGdD45N.mjs +32 -0
  75. package/dist/list-CfOVsAZz.mjs +55 -0
  76. package/dist/list-CpyNn1Zn.mjs +32 -0
  77. package/dist/list-CwwOoGLK.mjs +40 -0
  78. package/dist/{list-C_PRdL5e.mjs → list-DD8CQx8l.mjs} +7 -5
  79. package/dist/{list-Bk6RsbJl.mjs → list-DL-RWpIE.mjs} +5 -3
  80. package/dist/list-DLlq3FyS.mjs +61 -0
  81. package/dist/list-DdQ4jmUQ.mjs +52 -0
  82. package/dist/{list-C4Ajrw8f.mjs → list-DshbLoqR.mjs} +6 -3
  83. package/dist/{list-C8tdLOH5.mjs → list-DzTMpoBs.mjs} +5 -3
  84. package/dist/list-JgRtCzz3.mjs +32 -0
  85. package/dist/{list-CWt3fqrZ.mjs → list-WzgJcwB5.mjs} +5 -3
  86. package/dist/{login-C9WTwNn6.mjs → login-DJnmR2wX.mjs} +14 -5
  87. package/dist/{logout-oLszGCOg.mjs → logout-BMe_1Zp8.mjs} +7 -6
  88. package/dist/logs-CQxKJ3HG.mjs +58 -0
  89. package/dist/{manifest-CAdjQYH8.mjs → manifest-Dv5B9Blc.mjs} +3 -7
  90. package/dist/measure-BEQfnLdN.mjs +67 -0
  91. package/dist/measure-BGyYbtqO.mjs +19 -0
  92. package/dist/metadata-CLIALntn.mjs +37 -0
  93. package/dist/metadata-T-fNUWg_.mjs +38 -0
  94. package/dist/{package-BGfw4ZWJ.mjs → package-DBsS7a5x.mjs} +7 -1
  95. package/dist/paginate-CTSfuYiF.mjs +49 -0
  96. package/dist/parse-id-BUOZQqjp.mjs +12 -0
  97. package/dist/parse-ref-DGvh4aDn.mjs +17 -0
  98. package/dist/parse-schemas-BnW4T1_I.mjs +12 -0
  99. package/dist/{poll-ILanYysl.mjs → poll-DMmmZWvi.mjs} +2 -1
  100. package/dist/{poll-task-DbpsiQhl.mjs → poll-task-2Ckiwp8U.mjs} +8 -7
  101. package/dist/predicates-DiIiS3k7.mjs +153 -0
  102. package/dist/preflight-CC_g6EWU.mjs +91 -0
  103. package/dist/{prompt-DpT8yAVy.mjs → prompt-Bf3DQ-qE.mjs} +1 -1
  104. package/dist/provision-BUgWJWAV.mjs +77 -0
  105. package/dist/ps-BUNHygf-.mjs +10 -0
  106. package/dist/ps-Yv0JjLVN.mjs +78 -0
  107. package/dist/{query-PihYi-UZ.mjs → query-CzfbuG8a.mjs} +38 -13
  108. package/dist/query-UIebHmbT.mjs +90 -0
  109. package/dist/remove-BAUbcwuF.mjs +98 -0
  110. package/dist/{remove-B2hVYn1v.mjs → remove-CN2PNGTR.mjs} +6 -5
  111. package/dist/remove-collection-C6NxEh53.mjs +38 -0
  112. package/dist/render-DXv-D6fU.mjs +182 -0
  113. package/dist/rescan-values-CcB4F9qa.mjs +43 -0
  114. package/dist/revision-message-flag-CWQbKhdl.mjs +11 -0
  115. package/dist/{run-C2so6Qp6.mjs → run-BjXZtu_6.mjs} +27 -36
  116. package/dist/runs-CXx7l1NY.mjs +54 -0
  117. package/dist/{runtime-C9CEZhcn.mjs → runtime-D7jihh81.mjs} +425 -442
  118. package/dist/schema-tables-BCJT2DM_.mjs +45 -0
  119. package/dist/schemas-DlNpbn4H.mjs +47 -0
  120. package/dist/{search-CopOytXY.mjs → search-Dt-6mdHZ.mjs} +6 -19
  121. package/dist/segment-BMrUBz94.mjs +70 -0
  122. package/dist/segment-C52QNnSs.mjs +19 -0
  123. package/dist/{set-BcF7M1GQ.mjs → set-DCESWpi3.mjs} +6 -4
  124. package/dist/{set-CbibegpA.mjs → set-L7cuHjVZ.mjs} +8 -6
  125. package/dist/{setting-U3NtBMFo.mjs → setting-DysGAuYS.mjs} +3 -3
  126. package/dist/setup-_ypJDPAY.mjs +71 -0
  127. package/dist/snippet-Dw0Sjzkr.mjs +64 -0
  128. package/dist/snippet-vb3G9R8a.mjs +19 -0
  129. package/dist/start-BokXnb0V.mjs +350 -0
  130. package/dist/{stash-DOBbYozC.mjs → stash-CaGX6PfX.mjs} +9 -7
  131. package/dist/{status-Buf1ZbNR.mjs → status-BaX9vedb.mjs} +10 -8
  132. package/dist/{status-CUcs8XBH.mjs → status-CyecXzN4.mjs} +4 -2
  133. package/dist/{status-D1F5XHae.mjs → status-RpVyPEty.mjs} +4 -2
  134. package/dist/stop-BRuF_Cg1.mjs +81 -0
  135. package/dist/summary-CpEOiOlZ.mjs +41 -0
  136. package/dist/sync-schema-4Cl4h8Jn.mjs +43 -0
  137. package/dist/table-BeMWuvzO.mjs +19 -0
  138. package/dist/{table-Cfk7oSvw.mjs → table-jljEqZ0R.mjs} +22 -9
  139. package/dist/transform-DwRc-w6y.mjs +24 -0
  140. package/dist/{transform-B5uRpg1G.mjs → transform-IEX4Mx3X.mjs} +56 -2
  141. package/dist/transform-job-BigWrctt.mjs +19 -0
  142. package/dist/{transform-job-C7QXWTVE.mjs → transform-job-Csr86muI.mjs} +7 -0
  143. package/dist/translate-DqLlXXUx.mjs +111 -0
  144. package/dist/tree-BT24nkLM.mjs +32 -0
  145. package/dist/update-BCXKQi2n.mjs +52 -0
  146. package/dist/{update-CL8tRbxr.mjs → update-BXbLmC2b.mjs} +9 -7
  147. package/dist/update-C1Frz9GR.mjs +52 -0
  148. package/dist/update-C5goGhNr.mjs +56 -0
  149. package/dist/update-CCOyB0iT.mjs +73 -0
  150. package/dist/update-D04NMueX.mjs +59 -0
  151. package/dist/update-D6WVtNV1.mjs +57 -0
  152. package/dist/update-DFR46LsB.mjs +56 -0
  153. package/dist/update-DyLItrpV.mjs +56 -0
  154. package/dist/update-dashcard-av0_PYeg.mjs +71 -0
  155. package/dist/update-mrgvQF4i.mjs +51 -0
  156. package/dist/url-x4wn_l3k.mjs +54 -0
  157. package/dist/uuid-BZHbti8B.mjs +47 -0
  158. package/dist/validate-DCYx6jdL.mjs +1496 -0
  159. package/dist/validate-query-B07oGG4K.mjs +37 -0
  160. package/dist/values-Be6i0Fs9.mjs +36 -0
  161. package/dist/{wait-Bugr9eXD.mjs → wait-BMqQD8k_.mjs} +10 -8
  162. package/dist/wait-CWizX_sR.mjs +19 -0
  163. package/dist/wait-flags-DO3ar2tf.mjs +35 -0
  164. package/dist/workspace-CG1xyJ86.mjs +24 -0
  165. package/dist/workspace-DVuqKJGG.mjs +72 -0
  166. package/dist/workspace-credentials-B6BL-X0d.mjs +139 -0
  167. package/package.json +7 -1
  168. package/dist/auth-BF7IjZIH.mjs +0 -18
  169. package/dist/card-_Ta7zdYe.mjs +0 -19
  170. package/dist/create-CI2Cunq5.mjs +0 -38
  171. package/dist/create-DdbU3TLX.mjs +0 -42
  172. package/dist/database-PA9Goi25.mjs +0 -33
  173. package/dist/db-DMghzgb6.mjs +0 -17
  174. package/dist/field-C8IVs6rp.mjs +0 -76
  175. package/dist/field-DaYo_90x.mjs +0 -13
  176. package/dist/get-Cwpj7lDe.mjs +0 -35
  177. package/dist/get-Dh_acl8q.mjs +0 -34
  178. package/dist/is-dirty-DpKn9HJp.mjs +0 -8
  179. package/dist/list-CBSBHtK-.mjs +0 -38
  180. package/dist/parse-id-BhmmfyCP.mjs +0 -14
  181. package/dist/sync-BPyGXfUk.mjs +0 -26
  182. package/dist/table-D7nJt7JO.mjs +0 -16
  183. package/dist/transform-UbyewMxY.mjs +0 -21
  184. package/dist/transform-job-CrYkr-Ma.mjs +0 -19
  185. package/dist/update-DU2oU2j-.mjs +0 -49
  186. /package/dist/{body-flags-BUA9XV1u.mjs → body-flags-BK7J6Daz.mjs} +0 -0
  187. /package/dist/{setting-26ckqHAP.mjs → setting-CTaAeMci.mjs} +0 -0
@@ -0,0 +1,1496 @@
1
+ import { ConfigError, escapeJsonPointerSegment, isPlainObject } from "./predicates-DiIiS3k7.mjs";
2
+ import { z } from "zod";
3
+ import Ajv2020 from "ajv/dist/2020.js";
4
+ import addFormats from "ajv-formats";
5
+
6
+ //#region src/core/schema/data/schemas/common/parameter.json
7
+ var title$3 = "Parameter";
8
+ var description$3 = "A filter control parameter for cards and dashboards. Parameters allow users to interactively filter data via UI controls.\n";
9
+ var type$1 = "object";
10
+ var required$1 = [
11
+ "id",
12
+ "name",
13
+ "slug",
14
+ "type"
15
+ ];
16
+ var properties$1 = {
17
+ "id": {
18
+ "type": "string",
19
+ "minLength": 1,
20
+ "description": "Unique identifier within the dashboard or card. UUIDs are recommended, but Metabase accepts any unique non-empty string.\n"
21
+ },
22
+ "name": {
23
+ "type": "string",
24
+ "description": "Display name"
25
+ },
26
+ "slug": {
27
+ "type": "string",
28
+ "description": "URL-friendly identifier"
29
+ },
30
+ "type": {
31
+ "type": "string",
32
+ "description": "Filter widget type: string/=, string/!=, string/contains, string/starts-with, string/ends-with, number/=, number/!=, number/>=, number/<=, number/between, date/single, date/range, date/month-year, date/quarter-year, date/relative, date/all-options, boolean/=, temporal-unit\n"
33
+ },
34
+ "default": { "description": "Default value (type depends on filter type)" },
35
+ "required": {
36
+ "type": "boolean",
37
+ "description": "Whether a value is required"
38
+ },
39
+ "sectionId": {
40
+ "type": "string",
41
+ "description": "UI section grouping. Restricts which columns are available for mapping. For id — only PK and FK columns. For location — only location columns (country, city, etc.). Normally matches the first part of the parameter type.\n",
42
+ "enum": [
43
+ "string",
44
+ "number",
45
+ "date",
46
+ "boolean",
47
+ "temporal-unit",
48
+ "id",
49
+ "location"
50
+ ]
51
+ },
52
+ "temporal_units": {
53
+ "type": "array",
54
+ "description": "Allowed temporal units (for temporal-unit type)",
55
+ "items": {
56
+ "type": "string",
57
+ "enum": [
58
+ "minute",
59
+ "hour",
60
+ "day",
61
+ "week",
62
+ "month",
63
+ "quarter",
64
+ "year"
65
+ ]
66
+ }
67
+ },
68
+ "values_query_type": {
69
+ "type": "string",
70
+ "enum": [
71
+ "list",
72
+ "search",
73
+ "none"
74
+ ]
75
+ },
76
+ "values_source_type": {
77
+ "type": ["string", "null"],
78
+ "enum": [
79
+ null,
80
+ "card",
81
+ "static-list"
82
+ ]
83
+ },
84
+ "values_source_config": {
85
+ "type": "object",
86
+ "description": "Source configuration. For static-list: {values: [[val, label], ...]}. For card: {card_id, value_field, label_field}.\n",
87
+ "properties": {
88
+ "values": {
89
+ "type": "array",
90
+ "description": "Static list of [value, label] pairs"
91
+ },
92
+ "card_id": {
93
+ "type": "string",
94
+ "description": "Card entity_id to source values from"
95
+ },
96
+ "value_field": { "description": "Field clause for extracting values from card results" },
97
+ "label_field": { "description": "Field clause for extracting labels from card results" }
98
+ },
99
+ "additionalProperties": true
100
+ }
101
+ };
102
+ var $defs$3 = { "parameter_target": {
103
+ "description": "Parameter target for dashboard parameter mappings. Uses legacy MBQL format: [field, Field-FK, null-or-options].\n",
104
+ "type": "array",
105
+ "minItems": 2,
106
+ "allOf": [
107
+ {
108
+ "if": { "prefixItems": [{ "const": "dimension" }] },
109
+ "then": {
110
+ "prefixItems": [{ "const": "dimension" }, {
111
+ "type": "array",
112
+ "minItems": 2,
113
+ "allOf": [
114
+ {
115
+ "if": { "prefixItems": [{ "const": "field" }] },
116
+ "then": { "$ref": "ref.yaml#/$defs/legacy_field_ref" }
117
+ },
118
+ {
119
+ "if": { "prefixItems": [{ "const": "expression" }] },
120
+ "then": { "$ref": "ref.yaml#/$defs/legacy_expression_ref" }
121
+ },
122
+ {
123
+ "if": { "prefixItems": [{ "const": "template-tag" }] },
124
+ "then": {
125
+ "prefixItems": [{ "const": "template-tag" }, { "type": "string" }],
126
+ "minItems": 2,
127
+ "maxItems": 2
128
+ }
129
+ }
130
+ ]
131
+ }],
132
+ "items": { "anyOf": [{
133
+ "type": "object",
134
+ "properties": { "stage-number": { "type": "integer" } }
135
+ }, { "type": "null" }] },
136
+ "maxItems": 3
137
+ }
138
+ },
139
+ {
140
+ "if": { "prefixItems": [{ "const": "variable" }] },
141
+ "then": {
142
+ "prefixItems": [{ "const": "variable" }, {
143
+ "type": "array",
144
+ "prefixItems": [{ "const": "template-tag" }, { "type": "string" }],
145
+ "minItems": 2,
146
+ "maxItems": 2
147
+ }],
148
+ "minItems": 2,
149
+ "maxItems": 2
150
+ }
151
+ },
152
+ {
153
+ "if": { "prefixItems": [{ "const": "text-tag" }] },
154
+ "then": {
155
+ "prefixItems": [{ "const": "text-tag" }, { "type": "string" }],
156
+ "minItems": 2,
157
+ "maxItems": 2
158
+ }
159
+ }
160
+ ]
161
+ } };
162
+ var parameter_default = {
163
+ title: title$3,
164
+ description: description$3,
165
+ type: type$1,
166
+ required: required$1,
167
+ properties: properties$1,
168
+ $defs: $defs$3
169
+ };
170
+
171
+ //#endregion
172
+ //#region src/core/schema/data/schemas/common/query.json
173
+ var title$2 = "Query";
174
+ var description$2 = "A query definition in serialized pMBQL format. Contains a flat list of stages (no recursive source-query nesting). Each stage is either an MBQL structured stage or a native SQL stage.\n";
175
+ var type = "object";
176
+ var required = [
177
+ "lib/type",
178
+ "database",
179
+ "stages"
180
+ ];
181
+ var properties = {
182
+ "lib/type": {
183
+ "type": "string",
184
+ "const": "mbql/query"
185
+ },
186
+ "database": { "$ref": "id.yaml#/$defs/database_id" },
187
+ "stages": {
188
+ "type": "array",
189
+ "minItems": 1,
190
+ "items": { "$ref": "#/$defs/stage" }
191
+ }
192
+ };
193
+ var $defs$2 = {
194
+ "options": {
195
+ "description": "Base options object for pMBQL clauses. Always present as the second element of every clause array. Empty {} when no options apply.\n",
196
+ "type": "object",
197
+ "properties": {
198
+ "base-type": { "type": "string" },
199
+ "effective-type": { "type": "string" },
200
+ "lib/uuid": {
201
+ "type": "string",
202
+ "format": "uuid"
203
+ },
204
+ "lib/expression-name": { "type": "string" }
205
+ }
206
+ },
207
+ "case_sensitive_options": {
208
+ "description": "Options for string filter operators.",
209
+ "allOf": [{ "$ref": "#/$defs/options" }, {
210
+ "type": "object",
211
+ "properties": { "case-sensitive": { "type": "boolean" } }
212
+ }]
213
+ },
214
+ "time_interval_options": {
215
+ "description": "Options for the time-interval operator.",
216
+ "allOf": [{ "$ref": "#/$defs/options" }, {
217
+ "type": "object",
218
+ "properties": { "include-current": { "type": "boolean" } }
219
+ }]
220
+ },
221
+ "datetime_parse_options": {
222
+ "description": "Options for the datetime parsing operator.",
223
+ "allOf": [{ "$ref": "#/$defs/options" }, {
224
+ "type": "object",
225
+ "properties": { "mode": {
226
+ "type": "string",
227
+ "enum": [
228
+ "iso",
229
+ "simple",
230
+ "unix-seconds",
231
+ "unix-milliseconds",
232
+ "unix-microseconds",
233
+ "unix-nanoseconds",
234
+ "iso-bytes",
235
+ "simple-bytes"
236
+ ]
237
+ } }
238
+ }]
239
+ },
240
+ "stage": {
241
+ "type": "object",
242
+ "required": ["lib/type"],
243
+ "allOf": [{
244
+ "if": { "properties": { "lib/type": { "const": "mbql.stage/mbql" } } },
245
+ "then": { "$ref": "#/$defs/mbql_stage" }
246
+ }, {
247
+ "if": { "properties": { "lib/type": { "const": "mbql.stage/native" } } },
248
+ "then": { "$ref": "#/$defs/native_stage" }
249
+ }]
250
+ },
251
+ "mbql_stage": {
252
+ "type": "object",
253
+ "properties": {
254
+ "lib/type": { "const": "mbql.stage/mbql" },
255
+ "source-table": { "$ref": "id.yaml#/$defs/table_id" },
256
+ "source-card": { "$ref": "id.yaml#/$defs/entity_id" },
257
+ "joins": {
258
+ "type": "array",
259
+ "items": { "$ref": "#/$defs/join" }
260
+ },
261
+ "expressions": {
262
+ "type": "array",
263
+ "items": { "$ref": "#/$defs/expression" }
264
+ },
265
+ "fields": {
266
+ "type": "array",
267
+ "items": {
268
+ "type": "array",
269
+ "allOf": [{
270
+ "if": { "prefixItems": [{ "const": "field" }] },
271
+ "then": { "$ref": "ref.yaml#/$defs/field_ref" }
272
+ }, {
273
+ "if": { "prefixItems": [{ "const": "expression" }] },
274
+ "then": { "$ref": "ref.yaml#/$defs/expression_ref" }
275
+ }]
276
+ }
277
+ },
278
+ "filters": {
279
+ "type": "array",
280
+ "items": { "$ref": "#/$defs/expression" }
281
+ },
282
+ "aggregation": {
283
+ "type": "array",
284
+ "items": { "$ref": "#/$defs/expression" }
285
+ },
286
+ "breakout": {
287
+ "type": "array",
288
+ "items": { "$ref": "#/$defs/expression" }
289
+ },
290
+ "order-by": {
291
+ "type": "array",
292
+ "items": { "$ref": "#/$defs/expression" }
293
+ },
294
+ "limit": { "type": ["integer", "null"] }
295
+ }
296
+ },
297
+ "expression": {
298
+ "description": "An MBQL expression clause. Either a literal value or an array [operator, options, ...args] where options is always an object.\n",
299
+ "type": [
300
+ "string",
301
+ "number",
302
+ "boolean",
303
+ "null",
304
+ "array"
305
+ ],
306
+ "if": { "type": "array" },
307
+ "then": {
308
+ "minItems": 1,
309
+ "allOf": [
310
+ {
311
+ "if": { "prefixItems": [{ "const": "field" }] },
312
+ "then": { "$ref": "ref.yaml#/$defs/field_ref" }
313
+ },
314
+ {
315
+ "if": { "prefixItems": [{ "const": "expression" }] },
316
+ "then": { "$ref": "ref.yaml#/$defs/expression_ref" }
317
+ },
318
+ {
319
+ "if": { "prefixItems": [{ "const": "aggregation" }] },
320
+ "then": { "$ref": "ref.yaml#/$defs/aggregation_ref" }
321
+ },
322
+ {
323
+ "if": { "prefixItems": [{ "const": "metric" }] },
324
+ "then": { "$ref": "ref.yaml#/$defs/metric_ref" }
325
+ },
326
+ {
327
+ "if": { "prefixItems": [{ "const": "measure" }] },
328
+ "then": { "$ref": "ref.yaml#/$defs/measure_ref" }
329
+ },
330
+ {
331
+ "if": { "prefixItems": [{ "const": "segment" }] },
332
+ "then": { "$ref": "ref.yaml#/$defs/segment_ref" }
333
+ },
334
+ {
335
+ "if": { "prefixItems": [{ "const": "value" }] },
336
+ "then": {
337
+ "prefixItems": [
338
+ { "const": "value" },
339
+ { "$ref": "#/$defs/options" },
340
+ { "type": [
341
+ "string",
342
+ "number",
343
+ "boolean"
344
+ ] }
345
+ ],
346
+ "minItems": 3,
347
+ "maxItems": 3
348
+ }
349
+ },
350
+ {
351
+ "if": { "prefixItems": [{ "enum": [
352
+ "+",
353
+ "-",
354
+ "*",
355
+ "/"
356
+ ] }] },
357
+ "then": {
358
+ "prefixItems": [
359
+ { "enum": [
360
+ "+",
361
+ "-",
362
+ "*",
363
+ "/"
364
+ ] },
365
+ { "$ref": "#/$defs/options" },
366
+ { "$ref": "#/$defs/expression" }
367
+ ],
368
+ "items": { "$ref": "#/$defs/expression" },
369
+ "minItems": 3
370
+ }
371
+ },
372
+ {
373
+ "if": { "prefixItems": [{ "enum": ["and", "or"] }] },
374
+ "then": {
375
+ "prefixItems": [
376
+ { "enum": ["and", "or"] },
377
+ { "$ref": "#/$defs/options" },
378
+ { "$ref": "#/$defs/expression" },
379
+ { "$ref": "#/$defs/expression" }
380
+ ],
381
+ "items": { "$ref": "#/$defs/expression" },
382
+ "minItems": 4
383
+ }
384
+ },
385
+ {
386
+ "if": { "prefixItems": [{ "const": "not" }] },
387
+ "then": {
388
+ "prefixItems": [
389
+ { "const": "not" },
390
+ { "$ref": "#/$defs/options" },
391
+ { "$ref": "#/$defs/expression" }
392
+ ],
393
+ "minItems": 3,
394
+ "maxItems": 3
395
+ }
396
+ },
397
+ {
398
+ "if": { "prefixItems": [{ "enum": [
399
+ "=",
400
+ "!=",
401
+ "<",
402
+ ">",
403
+ "<=",
404
+ ">="
405
+ ] }] },
406
+ "then": {
407
+ "prefixItems": [
408
+ { "enum": [
409
+ "=",
410
+ "!=",
411
+ "<",
412
+ ">",
413
+ "<=",
414
+ ">="
415
+ ] },
416
+ { "$ref": "#/$defs/options" },
417
+ { "$ref": "#/$defs/expression" },
418
+ { "$ref": "#/$defs/expression" }
419
+ ],
420
+ "items": { "$ref": "#/$defs/expression" },
421
+ "minItems": 4
422
+ }
423
+ },
424
+ {
425
+ "if": { "prefixItems": [{ "enum": ["in", "not-in"] }] },
426
+ "then": {
427
+ "prefixItems": [
428
+ { "enum": ["in", "not-in"] },
429
+ { "$ref": "#/$defs/options" },
430
+ { "$ref": "#/$defs/expression" },
431
+ { "$ref": "#/$defs/expression" }
432
+ ],
433
+ "items": { "$ref": "#/$defs/expression" },
434
+ "minItems": 4
435
+ }
436
+ },
437
+ {
438
+ "if": { "prefixItems": [{ "const": "between" }] },
439
+ "then": {
440
+ "prefixItems": [
441
+ { "const": "between" },
442
+ { "$ref": "#/$defs/options" },
443
+ { "$ref": "#/$defs/expression" },
444
+ { "$ref": "#/$defs/expression" },
445
+ { "$ref": "#/$defs/expression" }
446
+ ],
447
+ "minItems": 5,
448
+ "maxItems": 5
449
+ }
450
+ },
451
+ {
452
+ "if": { "prefixItems": [{ "const": "inside" }] },
453
+ "then": {
454
+ "prefixItems": [
455
+ { "const": "inside" },
456
+ { "$ref": "#/$defs/options" },
457
+ { "$ref": "#/$defs/expression" },
458
+ { "$ref": "#/$defs/expression" },
459
+ { "type": "number" },
460
+ { "type": "number" },
461
+ { "type": "number" },
462
+ { "type": "number" }
463
+ ],
464
+ "minItems": 8,
465
+ "maxItems": 8
466
+ }
467
+ },
468
+ {
469
+ "if": { "prefixItems": [{ "enum": [
470
+ "is-null",
471
+ "not-null",
472
+ "is-empty",
473
+ "not-empty"
474
+ ] }] },
475
+ "then": {
476
+ "prefixItems": [
477
+ { "enum": [
478
+ "is-null",
479
+ "not-null",
480
+ "is-empty",
481
+ "not-empty"
482
+ ] },
483
+ { "$ref": "#/$defs/options" },
484
+ { "$ref": "#/$defs/expression" }
485
+ ],
486
+ "minItems": 3,
487
+ "maxItems": 3
488
+ }
489
+ },
490
+ {
491
+ "if": { "prefixItems": [{ "enum": [
492
+ "contains",
493
+ "does-not-contain",
494
+ "starts-with",
495
+ "ends-with"
496
+ ] }] },
497
+ "then": {
498
+ "prefixItems": [
499
+ { "enum": [
500
+ "contains",
501
+ "does-not-contain",
502
+ "starts-with",
503
+ "ends-with"
504
+ ] },
505
+ { "$ref": "#/$defs/case_sensitive_options" },
506
+ { "$ref": "#/$defs/expression" },
507
+ { "$ref": "#/$defs/expression" }
508
+ ],
509
+ "items": { "$ref": "#/$defs/expression" },
510
+ "minItems": 4
511
+ }
512
+ },
513
+ {
514
+ "if": { "prefixItems": [{ "const": "time-interval" }] },
515
+ "then": {
516
+ "prefixItems": [
517
+ { "const": "time-interval" },
518
+ { "$ref": "#/$defs/time_interval_options" },
519
+ { "$ref": "#/$defs/expression" },
520
+ {
521
+ "if": { "type": "integer" },
522
+ "then": { "type": "integer" },
523
+ "else": { "enum": [
524
+ "current",
525
+ "last",
526
+ "next"
527
+ ] }
528
+ },
529
+ { "$ref": "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" }
530
+ ],
531
+ "minItems": 5,
532
+ "maxItems": 5
533
+ }
534
+ },
535
+ {
536
+ "if": { "prefixItems": [{ "const": "relative-time-interval" }] },
537
+ "then": {
538
+ "prefixItems": [
539
+ { "const": "relative-time-interval" },
540
+ { "$ref": "#/$defs/options" },
541
+ { "$ref": "#/$defs/expression" },
542
+ { "type": "integer" },
543
+ { "$ref": "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" },
544
+ { "type": "integer" },
545
+ { "$ref": "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" }
546
+ ],
547
+ "minItems": 7,
548
+ "maxItems": 7
549
+ }
550
+ },
551
+ {
552
+ "if": { "prefixItems": [{ "enum": ["now", "today"] }] },
553
+ "then": {
554
+ "prefixItems": [{ "enum": ["now", "today"] }, { "$ref": "#/$defs/options" }],
555
+ "minItems": 2,
556
+ "maxItems": 2
557
+ }
558
+ },
559
+ {
560
+ "if": { "prefixItems": [{ "const": "interval" }] },
561
+ "then": {
562
+ "prefixItems": [
563
+ { "const": "interval" },
564
+ { "$ref": "#/$defs/options" },
565
+ { "type": "integer" },
566
+ { "$ref": "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" }
567
+ ],
568
+ "minItems": 4,
569
+ "maxItems": 4
570
+ }
571
+ },
572
+ {
573
+ "if": { "prefixItems": [{ "enum": [
574
+ "abs",
575
+ "ceil",
576
+ "floor",
577
+ "round",
578
+ "sqrt",
579
+ "exp",
580
+ "log",
581
+ "length",
582
+ "trim",
583
+ "ltrim",
584
+ "rtrim",
585
+ "upper",
586
+ "lower",
587
+ "host",
588
+ "domain",
589
+ "subdomain",
590
+ "path",
591
+ "get-year",
592
+ "get-quarter",
593
+ "get-month",
594
+ "get-day",
595
+ "get-hour",
596
+ "get-minute",
597
+ "get-second",
598
+ "text",
599
+ "integer",
600
+ "float",
601
+ "day-name",
602
+ "month-name",
603
+ "quarter-name",
604
+ "date"
605
+ ] }] },
606
+ "then": {
607
+ "prefixItems": [
608
+ { "enum": [
609
+ "abs",
610
+ "ceil",
611
+ "floor",
612
+ "round",
613
+ "sqrt",
614
+ "exp",
615
+ "log",
616
+ "length",
617
+ "trim",
618
+ "ltrim",
619
+ "rtrim",
620
+ "upper",
621
+ "lower",
622
+ "host",
623
+ "domain",
624
+ "subdomain",
625
+ "path",
626
+ "get-year",
627
+ "get-quarter",
628
+ "get-month",
629
+ "get-day",
630
+ "get-hour",
631
+ "get-minute",
632
+ "get-second",
633
+ "text",
634
+ "integer",
635
+ "float",
636
+ "day-name",
637
+ "month-name",
638
+ "quarter-name",
639
+ "date"
640
+ ] },
641
+ { "$ref": "#/$defs/options" },
642
+ { "$ref": "#/$defs/expression" }
643
+ ],
644
+ "minItems": 3,
645
+ "maxItems": 3
646
+ }
647
+ },
648
+ {
649
+ "if": { "prefixItems": [{ "const": "datetime" }] },
650
+ "then": {
651
+ "prefixItems": [
652
+ { "const": "datetime" },
653
+ { "$ref": "#/$defs/datetime_parse_options" },
654
+ { "$ref": "#/$defs/expression" }
655
+ ],
656
+ "minItems": 3,
657
+ "maxItems": 3
658
+ }
659
+ },
660
+ {
661
+ "if": { "prefixItems": [{ "enum": ["get-day-of-week", "get-week"] }] },
662
+ "then": {
663
+ "prefixItems": [
664
+ { "enum": ["get-day-of-week", "get-week"] },
665
+ { "$ref": "#/$defs/options" },
666
+ { "$ref": "#/$defs/expression" },
667
+ {
668
+ "type": "string",
669
+ "enum": [
670
+ "iso",
671
+ "us",
672
+ "instance"
673
+ ]
674
+ }
675
+ ],
676
+ "minItems": 3,
677
+ "maxItems": 4
678
+ }
679
+ },
680
+ {
681
+ "if": { "prefixItems": [{ "const": "power" }] },
682
+ "then": {
683
+ "prefixItems": [
684
+ { "const": "power" },
685
+ { "$ref": "#/$defs/options" },
686
+ { "$ref": "#/$defs/expression" },
687
+ { "$ref": "#/$defs/expression" }
688
+ ],
689
+ "minItems": 4,
690
+ "maxItems": 4
691
+ }
692
+ },
693
+ {
694
+ "if": { "prefixItems": [{ "enum": ["replace", "split-part"] }] },
695
+ "then": {
696
+ "prefixItems": [
697
+ { "enum": ["replace", "split-part"] },
698
+ { "$ref": "#/$defs/options" },
699
+ { "$ref": "#/$defs/expression" },
700
+ { "$ref": "#/$defs/expression" },
701
+ { "$ref": "#/$defs/expression" }
702
+ ],
703
+ "minItems": 5,
704
+ "maxItems": 5
705
+ }
706
+ },
707
+ {
708
+ "if": { "prefixItems": [{ "const": "substring" }] },
709
+ "then": {
710
+ "prefixItems": [
711
+ { "const": "substring" },
712
+ { "$ref": "#/$defs/options" },
713
+ { "$ref": "#/$defs/expression" },
714
+ { "$ref": "#/$defs/expression" },
715
+ { "$ref": "#/$defs/expression" }
716
+ ],
717
+ "minItems": 4,
718
+ "maxItems": 5
719
+ }
720
+ },
721
+ {
722
+ "if": { "prefixItems": [{ "const": "collate" }] },
723
+ "then": {
724
+ "prefixItems": [
725
+ { "const": "collate" },
726
+ { "$ref": "#/$defs/options" },
727
+ { "$ref": "#/$defs/expression" },
728
+ { "type": "string" }
729
+ ],
730
+ "minItems": 4,
731
+ "maxItems": 4
732
+ }
733
+ },
734
+ {
735
+ "if": { "prefixItems": [{ "const": "regex-match-first" }] },
736
+ "then": {
737
+ "prefixItems": [
738
+ { "const": "regex-match-first" },
739
+ { "$ref": "#/$defs/options" },
740
+ { "$ref": "#/$defs/expression" },
741
+ { "type": "string" }
742
+ ],
743
+ "minItems": 4,
744
+ "maxItems": 4
745
+ }
746
+ },
747
+ {
748
+ "if": { "prefixItems": [{ "const": "concat" }] },
749
+ "then": {
750
+ "prefixItems": [
751
+ { "const": "concat" },
752
+ { "$ref": "#/$defs/options" },
753
+ { "$ref": "#/$defs/expression" },
754
+ { "$ref": "#/$defs/expression" }
755
+ ],
756
+ "items": { "$ref": "#/$defs/expression" },
757
+ "minItems": 4
758
+ }
759
+ },
760
+ {
761
+ "if": { "prefixItems": [{ "const": "coalesce" }] },
762
+ "then": {
763
+ "prefixItems": [
764
+ { "const": "coalesce" },
765
+ { "$ref": "#/$defs/options" },
766
+ { "$ref": "#/$defs/expression" },
767
+ { "$ref": "#/$defs/expression" }
768
+ ],
769
+ "items": { "$ref": "#/$defs/expression" },
770
+ "minItems": 4
771
+ }
772
+ },
773
+ {
774
+ "if": { "prefixItems": [{ "enum": ["datetime-add", "datetime-subtract"] }] },
775
+ "then": {
776
+ "prefixItems": [
777
+ { "enum": ["datetime-add", "datetime-subtract"] },
778
+ { "$ref": "#/$defs/options" },
779
+ { "$ref": "#/$defs/expression" },
780
+ { "type": "integer" },
781
+ { "$ref": "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" }
782
+ ],
783
+ "minItems": 5,
784
+ "maxItems": 5
785
+ }
786
+ },
787
+ {
788
+ "if": { "prefixItems": [{ "const": "datetime-diff" }] },
789
+ "then": {
790
+ "prefixItems": [
791
+ { "const": "datetime-diff" },
792
+ { "$ref": "#/$defs/options" },
793
+ { "$ref": "#/$defs/expression" },
794
+ { "$ref": "#/$defs/expression" },
795
+ { "$ref": "#/$defs/datetime_diff_unit" }
796
+ ],
797
+ "minItems": 5,
798
+ "maxItems": 5
799
+ }
800
+ },
801
+ {
802
+ "if": { "prefixItems": [{ "const": "convert-timezone" }] },
803
+ "then": {
804
+ "prefixItems": [
805
+ { "const": "convert-timezone" },
806
+ { "$ref": "#/$defs/options" },
807
+ { "$ref": "#/$defs/expression" },
808
+ { "type": "string" },
809
+ { "type": "string" }
810
+ ],
811
+ "minItems": 4,
812
+ "maxItems": 5
813
+ }
814
+ },
815
+ {
816
+ "if": { "prefixItems": [{ "const": "temporal-extract" }] },
817
+ "then": {
818
+ "prefixItems": [
819
+ { "const": "temporal-extract" },
820
+ { "$ref": "#/$defs/options" },
821
+ { "$ref": "#/$defs/expression" },
822
+ { "$ref": "temporal_bucketing.yaml#/$defs/datetime_extraction_unit" },
823
+ {
824
+ "type": "string",
825
+ "enum": [
826
+ "iso",
827
+ "us",
828
+ "instance"
829
+ ]
830
+ }
831
+ ],
832
+ "minItems": 4,
833
+ "maxItems": 5
834
+ }
835
+ },
836
+ {
837
+ "if": { "prefixItems": [{ "enum": ["count", "cum-count"] }] },
838
+ "then": {
839
+ "prefixItems": [{ "enum": ["count", "cum-count"] }, { "$ref": "#/$defs/options" }],
840
+ "items": { "$ref": "#/$defs/expression" },
841
+ "minItems": 2,
842
+ "maxItems": 3
843
+ }
844
+ },
845
+ {
846
+ "if": { "prefixItems": [{ "enum": [
847
+ "sum",
848
+ "avg",
849
+ "min",
850
+ "max",
851
+ "distinct",
852
+ "stddev",
853
+ "var",
854
+ "median",
855
+ "cum-sum"
856
+ ] }] },
857
+ "then": {
858
+ "prefixItems": [
859
+ { "enum": [
860
+ "sum",
861
+ "avg",
862
+ "min",
863
+ "max",
864
+ "distinct",
865
+ "stddev",
866
+ "var",
867
+ "median",
868
+ "cum-sum"
869
+ ] },
870
+ { "$ref": "#/$defs/options" },
871
+ { "$ref": "#/$defs/expression" }
872
+ ],
873
+ "minItems": 3,
874
+ "maxItems": 3
875
+ }
876
+ },
877
+ {
878
+ "if": { "prefixItems": [{ "const": "percentile" }] },
879
+ "then": {
880
+ "prefixItems": [
881
+ { "const": "percentile" },
882
+ { "$ref": "#/$defs/options" },
883
+ { "$ref": "#/$defs/expression" },
884
+ { "type": "number" }
885
+ ],
886
+ "minItems": 4,
887
+ "maxItems": 4
888
+ }
889
+ },
890
+ {
891
+ "if": { "prefixItems": [{ "enum": ["count-where", "share"] }] },
892
+ "then": {
893
+ "prefixItems": [
894
+ { "enum": ["count-where", "share"] },
895
+ { "$ref": "#/$defs/options" },
896
+ { "$ref": "#/$defs/expression" }
897
+ ],
898
+ "minItems": 3,
899
+ "maxItems": 3
900
+ }
901
+ },
902
+ {
903
+ "if": { "prefixItems": [{ "enum": ["sum-where", "distinct-where"] }] },
904
+ "then": {
905
+ "prefixItems": [
906
+ { "enum": ["sum-where", "distinct-where"] },
907
+ { "$ref": "#/$defs/options" },
908
+ { "$ref": "#/$defs/expression" },
909
+ { "$ref": "#/$defs/expression" }
910
+ ],
911
+ "minItems": 4,
912
+ "maxItems": 4
913
+ }
914
+ },
915
+ {
916
+ "if": { "prefixItems": [{ "enum": ["case", "if"] }] },
917
+ "then": {
918
+ "prefixItems": [
919
+ { "enum": ["case", "if"] },
920
+ { "$ref": "#/$defs/options" },
921
+ {
922
+ "type": "array",
923
+ "items": {
924
+ "type": "array",
925
+ "prefixItems": [{ "$ref": "#/$defs/expression" }, { "$ref": "#/$defs/expression" }],
926
+ "minItems": 2,
927
+ "maxItems": 2
928
+ }
929
+ },
930
+ { "$ref": "#/$defs/expression" }
931
+ ],
932
+ "minItems": 3,
933
+ "maxItems": 4
934
+ }
935
+ },
936
+ {
937
+ "if": { "prefixItems": [{ "const": "offset" }] },
938
+ "then": {
939
+ "prefixItems": [
940
+ { "const": "offset" },
941
+ { "$ref": "#/$defs/options" },
942
+ { "$ref": "#/$defs/expression" },
943
+ { "type": "integer" }
944
+ ],
945
+ "minItems": 4,
946
+ "maxItems": 4
947
+ }
948
+ },
949
+ {
950
+ "if": { "prefixItems": [{ "enum": ["asc", "desc"] }] },
951
+ "then": {
952
+ "prefixItems": [
953
+ { "enum": ["asc", "desc"] },
954
+ { "$ref": "#/$defs/options" },
955
+ { "$ref": "#/$defs/expression" }
956
+ ],
957
+ "minItems": 3,
958
+ "maxItems": 3
959
+ }
960
+ }
961
+ ]
962
+ }
963
+ },
964
+ "datetime_diff_unit": {
965
+ "type": "string",
966
+ "enum": [
967
+ "second",
968
+ "minute",
969
+ "hour",
970
+ "day",
971
+ "week",
972
+ "month",
973
+ "quarter",
974
+ "year"
975
+ ]
976
+ },
977
+ "join": {
978
+ "type": "object",
979
+ "required": [
980
+ "stages",
981
+ "conditions",
982
+ "alias"
983
+ ],
984
+ "properties": {
985
+ "stages": {
986
+ "type": "array",
987
+ "minItems": 1,
988
+ "items": { "$ref": "#/$defs/stage" }
989
+ },
990
+ "conditions": {
991
+ "type": "array",
992
+ "minItems": 1,
993
+ "items": { "$ref": "#/$defs/expression" }
994
+ },
995
+ "alias": { "type": "string" },
996
+ "strategy": {
997
+ "type": "string",
998
+ "enum": [
999
+ "left-join",
1000
+ "right-join",
1001
+ "inner-join",
1002
+ "full-join"
1003
+ ]
1004
+ },
1005
+ "fields": {
1006
+ "if": { "type": "string" },
1007
+ "then": { "enum": ["all", "none"] },
1008
+ "else": {
1009
+ "type": "array",
1010
+ "items": { "$ref": "#/$defs/expression" }
1011
+ }
1012
+ }
1013
+ }
1014
+ },
1015
+ "native_stage": {
1016
+ "type": "object",
1017
+ "required": ["lib/type", "native"],
1018
+ "properties": {
1019
+ "lib/type": { "const": "mbql.stage/native" },
1020
+ "native": { "type": "string" },
1021
+ "template-tags": {
1022
+ "type": "object",
1023
+ "additionalProperties": { "$ref": "#/$defs/template_tag" }
1024
+ }
1025
+ }
1026
+ },
1027
+ "template_tag": {
1028
+ "type": "object",
1029
+ "required": [
1030
+ "type",
1031
+ "name",
1032
+ "id"
1033
+ ],
1034
+ "properties": {
1035
+ "type": {
1036
+ "type": "string",
1037
+ "enum": [
1038
+ "text",
1039
+ "number",
1040
+ "date",
1041
+ "boolean",
1042
+ "dimension",
1043
+ "temporal-unit",
1044
+ "card",
1045
+ "snippet",
1046
+ "table"
1047
+ ]
1048
+ },
1049
+ "name": { "type": "string" },
1050
+ "id": {
1051
+ "type": "string",
1052
+ "format": "uuid"
1053
+ },
1054
+ "display-name": { "type": "string" },
1055
+ "default": { "description": "Default value (type depends on tag type)" },
1056
+ "required": { "type": "boolean" }
1057
+ },
1058
+ "allOf": [
1059
+ {
1060
+ "if": { "properties": { "type": { "const": "dimension" } } },
1061
+ "then": {
1062
+ "required": ["dimension", "widget-type"],
1063
+ "properties": {
1064
+ "dimension": { "$ref": "#/$defs/expression" },
1065
+ "widget-type": { "type": "string" },
1066
+ "options": { "type": "object" },
1067
+ "alias": { "type": "string" }
1068
+ }
1069
+ }
1070
+ },
1071
+ {
1072
+ "if": { "properties": { "type": { "const": "temporal-unit" } } },
1073
+ "then": {
1074
+ "required": ["dimension"],
1075
+ "properties": {
1076
+ "dimension": { "$ref": "#/$defs/expression" },
1077
+ "alias": { "type": "string" }
1078
+ }
1079
+ }
1080
+ },
1081
+ {
1082
+ "if": { "properties": { "type": { "const": "card" } } },
1083
+ "then": {
1084
+ "required": ["card-id"],
1085
+ "properties": { "card-id": { "$ref": "id.yaml#/$defs/entity_id" } }
1086
+ }
1087
+ },
1088
+ {
1089
+ "if": { "properties": { "type": { "const": "snippet" } } },
1090
+ "then": {
1091
+ "required": ["snippet-name", "snippet-id"],
1092
+ "properties": {
1093
+ "snippet-name": { "type": "string" },
1094
+ "snippet-id": { "$ref": "id.yaml#/$defs/entity_id" }
1095
+ }
1096
+ }
1097
+ },
1098
+ {
1099
+ "if": { "properties": { "type": { "const": "table" } } },
1100
+ "then": {
1101
+ "required": ["table-id"],
1102
+ "properties": {
1103
+ "table-id": { "$ref": "id.yaml#/$defs/table_id" },
1104
+ "emit-alias": { "type": "boolean" }
1105
+ }
1106
+ }
1107
+ }
1108
+ ]
1109
+ }
1110
+ };
1111
+ var query_default = {
1112
+ title: title$2,
1113
+ description: description$2,
1114
+ type,
1115
+ required,
1116
+ properties,
1117
+ $defs: $defs$2
1118
+ };
1119
+
1120
+ //#endregion
1121
+ //#region src/core/schema/data/schemas/common/ref.json
1122
+ var title$1 = "Ref";
1123
+ var description$1 = "Column and entity reference types used in MBQL expressions, parameter mappings, and visualization settings. Options are always the second element (an object, never null).\n";
1124
+ var $defs$1 = {
1125
+ "field_options": {
1126
+ "description": "Options for field refs.",
1127
+ "allOf": [{ "$ref": "query.yaml#/$defs/options" }, {
1128
+ "type": "object",
1129
+ "properties": {
1130
+ "temporal-unit": { "$ref": "temporal_bucketing.yaml#/$defs/datetime_bucketing_unit" },
1131
+ "join-alias": { "type": "string" },
1132
+ "binning": {
1133
+ "type": "object",
1134
+ "required": ["strategy"],
1135
+ "properties": { "strategy": {
1136
+ "type": "string",
1137
+ "enum": [
1138
+ "default",
1139
+ "num-bins",
1140
+ "bin-width"
1141
+ ]
1142
+ } },
1143
+ "allOf": [{
1144
+ "if": { "properties": { "strategy": { "const": "bin-width" } } },
1145
+ "then": {
1146
+ "required": ["bin-width"],
1147
+ "properties": { "bin-width": {
1148
+ "type": "number",
1149
+ "exclusiveMinimum": 0
1150
+ } }
1151
+ }
1152
+ }, {
1153
+ "if": { "properties": { "strategy": { "const": "num-bins" } } },
1154
+ "then": {
1155
+ "required": ["num-bins"],
1156
+ "properties": { "num-bins": {
1157
+ "type": "integer",
1158
+ "minimum": 1
1159
+ } }
1160
+ }
1161
+ }]
1162
+ },
1163
+ "source-field": { "$ref": "id.yaml#/$defs/field_id" },
1164
+ "source-field-name": { "type": "string" },
1165
+ "source-field-join-alias": { "type": "string" }
1166
+ }
1167
+ }]
1168
+ },
1169
+ "field_ref": {
1170
+ "description": "[field, options, Field-FK-or-name]",
1171
+ "type": "array",
1172
+ "prefixItems": [
1173
+ { "const": "field" },
1174
+ { "$ref": "#/$defs/field_options" },
1175
+ {
1176
+ "if": { "type": "array" },
1177
+ "then": { "$ref": "id.yaml#/$defs/field_id" }
1178
+ }
1179
+ ],
1180
+ "minItems": 3,
1181
+ "maxItems": 3
1182
+ },
1183
+ "expression_ref": {
1184
+ "description": "[expression, options, name]",
1185
+ "type": "array",
1186
+ "prefixItems": [
1187
+ { "const": "expression" },
1188
+ { "$ref": "query.yaml#/$defs/options" },
1189
+ { "type": "string" }
1190
+ ],
1191
+ "minItems": 3,
1192
+ "maxItems": 3
1193
+ },
1194
+ "aggregation_ref": {
1195
+ "description": "[aggregation, options, uuid] — uuid matches the lib/uuid on the aggregation clause",
1196
+ "type": "array",
1197
+ "prefixItems": [
1198
+ { "const": "aggregation" },
1199
+ { "$ref": "query.yaml#/$defs/options" },
1200
+ {
1201
+ "type": "string",
1202
+ "format": "uuid"
1203
+ }
1204
+ ],
1205
+ "minItems": 3,
1206
+ "maxItems": 3
1207
+ },
1208
+ "metric_ref": {
1209
+ "description": "[metric, options, entity_id]",
1210
+ "type": "array",
1211
+ "prefixItems": [
1212
+ { "const": "metric" },
1213
+ { "$ref": "query.yaml#/$defs/options" },
1214
+ { "type": "string" }
1215
+ ],
1216
+ "minItems": 3,
1217
+ "maxItems": 3
1218
+ },
1219
+ "measure_ref": {
1220
+ "description": "[measure, options, entity_id]",
1221
+ "type": "array",
1222
+ "prefixItems": [
1223
+ { "const": "measure" },
1224
+ { "$ref": "query.yaml#/$defs/options" },
1225
+ { "type": "string" }
1226
+ ],
1227
+ "minItems": 3,
1228
+ "maxItems": 3
1229
+ },
1230
+ "segment_ref": {
1231
+ "description": "[segment, options, entity_id]",
1232
+ "type": "array",
1233
+ "prefixItems": [
1234
+ { "const": "segment" },
1235
+ { "$ref": "query.yaml#/$defs/options" },
1236
+ { "type": "string" }
1237
+ ],
1238
+ "minItems": 3,
1239
+ "maxItems": 3
1240
+ },
1241
+ "legacy_field_ref": {
1242
+ "description": "[field, Field-FK-or-name, null-or-options] — legacy format used in parameter targets",
1243
+ "type": "array",
1244
+ "prefixItems": [
1245
+ { "const": "field" },
1246
+ {
1247
+ "if": { "type": "array" },
1248
+ "then": { "$ref": "id.yaml#/$defs/field_id" }
1249
+ },
1250
+ { "type": ["object", "null"] }
1251
+ ],
1252
+ "minItems": 3,
1253
+ "maxItems": 3
1254
+ },
1255
+ "legacy_expression_ref": {
1256
+ "description": "[expression, name] or [expression, name, null-or-options] — legacy format used in parameter targets",
1257
+ "type": "array",
1258
+ "prefixItems": [
1259
+ { "const": "expression" },
1260
+ { "type": "string" },
1261
+ { "type": ["object", "null"] }
1262
+ ],
1263
+ "minItems": 2,
1264
+ "maxItems": 3
1265
+ }
1266
+ };
1267
+ var ref_default = {
1268
+ title: title$1,
1269
+ description: description$1,
1270
+ $defs: $defs$1
1271
+ };
1272
+
1273
+ //#endregion
1274
+ //#region src/core/schema/data/schemas/common/temporal_bucketing.json
1275
+ var title = "Temporal Bucketing";
1276
+ var description = "Datetime truncation, extraction, and bucketing unit definitions.";
1277
+ var $defs = {
1278
+ "datetime_truncation_unit": {
1279
+ "description": "Truncation units — truncate a datetime to a boundary. Also used for intervals and datetime arithmetic.\n",
1280
+ "type": "string",
1281
+ "enum": [
1282
+ "millisecond",
1283
+ "second",
1284
+ "minute",
1285
+ "hour",
1286
+ "day",
1287
+ "week",
1288
+ "month",
1289
+ "quarter",
1290
+ "year"
1291
+ ]
1292
+ },
1293
+ "datetime_extraction_unit": {
1294
+ "description": "Extraction units — extract a numeric component from a datetime.\n",
1295
+ "type": "string",
1296
+ "enum": [
1297
+ "second-of-minute",
1298
+ "minute-of-hour",
1299
+ "hour-of-day",
1300
+ "day-of-week",
1301
+ "day-of-week-iso",
1302
+ "day-of-month",
1303
+ "day-of-year",
1304
+ "week-of-year",
1305
+ "week-of-year-iso",
1306
+ "week-of-year-us",
1307
+ "week-of-year-instance",
1308
+ "month-of-year",
1309
+ "quarter-of-year",
1310
+ "year-of-era"
1311
+ ]
1312
+ },
1313
+ "datetime_bucketing_unit": {
1314
+ "description": "All datetime units — truncation + extraction + default. Used for field temporal-unit option.\n",
1315
+ "anyOf": [
1316
+ { "const": "default" },
1317
+ { "$ref": "#/$defs/datetime_truncation_unit" },
1318
+ { "$ref": "#/$defs/datetime_extraction_unit" }
1319
+ ]
1320
+ }
1321
+ };
1322
+ var temporal_bucketing_default = {
1323
+ title,
1324
+ description,
1325
+ $defs
1326
+ };
1327
+
1328
+ //#endregion
1329
+ //#region src/core/schema/validate.ts
1330
+ const ValidationIssue = z.object({
1331
+ path: z.string(),
1332
+ message: z.string()
1333
+ });
1334
+ const ValidationOutcome = z.object({
1335
+ ok: z.boolean(),
1336
+ errors: z.array(ValidationIssue)
1337
+ });
1338
+ const POSITIVE_INTEGER = {
1339
+ type: "integer",
1340
+ minimum: 1
1341
+ };
1342
+ const idSchema = {
1343
+ title: "ID",
1344
+ description: "MBQL identifier $defs — every id is a positive integer.",
1345
+ $defs: {
1346
+ entity_id: POSITIVE_INTEGER,
1347
+ user_id: POSITIVE_INTEGER,
1348
+ database_id: POSITIVE_INTEGER,
1349
+ table_id: POSITIVE_INTEGER,
1350
+ field_id: POSITIVE_INTEGER
1351
+ }
1352
+ };
1353
+ let validator = null;
1354
+ function getValidator() {
1355
+ if (validator !== null) return validator;
1356
+ const ajv = new Ajv2020({
1357
+ allErrors: true,
1358
+ strictTuples: false,
1359
+ allowUnionTypes: true
1360
+ });
1361
+ addFormats(ajv);
1362
+ ajv.addSchema(idSchema, "id.yaml");
1363
+ ajv.addSchema(parameter_default, "parameter.yaml");
1364
+ ajv.addSchema(ref_default, "ref.yaml");
1365
+ ajv.addSchema(temporal_bucketing_default, "temporal_bucketing.yaml");
1366
+ ajv.addSchema(query_default, "query.yaml");
1367
+ const compiled = ajv.getSchema("query.yaml");
1368
+ if (compiled === void 0) throw new Error("internal: query.yaml validator not registered");
1369
+ validator = compiled;
1370
+ return validator;
1371
+ }
1372
+ const UUID_HINT_MESSAGE = "must be a UUID v4 (RFC 4122) — run `metabase uuid` (or `metabase uuid --count N`) to mint one. The MBQL 5 schema rejects placeholder strings (`a1`, `uuid-1`, etc.); agents must call the CLI for UUIDs rather than authoring them.";
1373
+ const FIELD_SLOT1_HINT_MESSAGE = "must be the field options object — MBQL 5 field refs are [\"field\", {options}, fieldId]; the legacy MBQL 4 shape [\"field\", id, opts] is not accepted here. (Tip: `metabase uuid` mints `lib/uuid` strings if you need them.)";
1374
+ function clauseSlot1HintMessage(operator, slot1) {
1375
+ return `must be the clause options object — every MBQL 5 clause is ["${operator}", {options}, ...args]; got ${describeJsonValue(slot1)} at index 1`;
1376
+ }
1377
+ const FormatErrorParams = z.object({ format: z.string() });
1378
+ function isUuidFormatIssue(issue) {
1379
+ if (issue.keyword !== "format") return false;
1380
+ const parsed = FormatErrorParams.safeParse(issue.params);
1381
+ return parsed.success && parsed.data.format === "uuid";
1382
+ }
1383
+ function runValidator(validatorFn, value) {
1384
+ if (validatorFn(value)) return {
1385
+ ok: true,
1386
+ errors: []
1387
+ };
1388
+ const overrides = collectMessageOverrides(value);
1389
+ const issues = validatorFn.errors ?? [];
1390
+ const errors = issues.map((issue) => {
1391
+ if (issue.message === void 0) throw new Error(`Ajv issue at ${issue.instancePath} has no message`);
1392
+ const path = issue.instancePath === "" ? "/" : issue.instancePath;
1393
+ if (isUuidFormatIssue(issue)) return {
1394
+ path,
1395
+ message: UUID_HINT_MESSAGE
1396
+ };
1397
+ const overridden = overrides.get(path);
1398
+ return {
1399
+ path,
1400
+ message: overridden ?? issue.message
1401
+ };
1402
+ });
1403
+ return {
1404
+ ok: false,
1405
+ errors
1406
+ };
1407
+ }
1408
+ function collectMessageOverrides(root) {
1409
+ const overrides = new Map();
1410
+ visit(root, "");
1411
+ return overrides;
1412
+ function visit(node, path) {
1413
+ if (Array.isArray(node)) {
1414
+ const slot1 = clauseSlot1Message(node);
1415
+ if (slot1 !== null) overrides.set(`${path}/1`, slot1);
1416
+ const slot2 = refSlot2Message(node);
1417
+ if (slot2 !== null) overrides.set(`${path}/2`, slot2);
1418
+ for (let index = 0; index < node.length; index += 1) visit(node[index], `${path}/${index}`);
1419
+ return;
1420
+ }
1421
+ if (!isPlainObject(node)) return;
1422
+ for (const key of Object.keys(node)) visit(node[key], `${path}/${escapeJsonPointerSegment(key)}`);
1423
+ }
1424
+ }
1425
+ function clauseSlot1Message(clause) {
1426
+ if (clause.length < 2) return null;
1427
+ const operator = clause[0];
1428
+ if (typeof operator !== "string") return null;
1429
+ const slot1 = clause[1];
1430
+ if (isPlainObject(slot1)) return null;
1431
+ if (operator === "field") return FIELD_SLOT1_HINT_MESSAGE;
1432
+ return clauseSlot1HintMessage(operator, slot1);
1433
+ }
1434
+ function refSlot2Message(clause) {
1435
+ if (clause.length !== 3) return null;
1436
+ const kind = clause[0];
1437
+ if (typeof kind !== "string") return null;
1438
+ if (typeof clause[2] === "string") return null;
1439
+ return refHintForKind(kind);
1440
+ }
1441
+ function refHintForKind(kind) {
1442
+ switch (kind) {
1443
+ case "aggregation": return "must be the target aggregation's lib/uuid (string), not a numeric position";
1444
+ case "expression": return "must be the target expression's name (string), not a numeric position";
1445
+ default: return null;
1446
+ }
1447
+ }
1448
+ function describeJsonValue(value) {
1449
+ if (value === null) return "null";
1450
+ if (Array.isArray(value)) return "array";
1451
+ if (typeof value === "string") return `string ${JSON.stringify(value)}`;
1452
+ if (typeof value === "number" || typeof value === "boolean") return `${typeof value} ${String(value)}`;
1453
+ return typeof value;
1454
+ }
1455
+ function validateQuery(value) {
1456
+ return runValidator(getValidator(), value);
1457
+ }
1458
+ function isMbql5Query(value) {
1459
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1460
+ return "lib/type" in value && value["lib/type"] === "mbql/query";
1461
+ }
1462
+ function isLegacyEnvelopeWrappingMbql5(value) {
1463
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1464
+ if (!("type" in value) || value["type"] !== "query") return false;
1465
+ if (!("query" in value)) return false;
1466
+ const inner = value["query"];
1467
+ if (typeof inner !== "object" || inner === null || Array.isArray(inner)) return false;
1468
+ return "lib/type" in inner && inner["lib/type"] === "mbql/query";
1469
+ }
1470
+ function assertNotLegacyEnvelopeWrappingMbql5(value, options) {
1471
+ if (!isLegacyEnvelopeWrappingMbql5(value)) return;
1472
+ throw new ConfigError(`${options.contextLabel}: MBQL 5 query nested inside a legacy {type:"query", query:…} envelope. For MBQL 5, ${options.bodyNoun} is the mbql/query value itself: {"lib/type":"mbql/query", database:N, stages:[…]}.`);
1473
+ }
1474
+ const QuerySchemaBundle = z.object({
1475
+ schema: z.unknown(),
1476
+ defs: z.object({
1477
+ "id.yaml": z.unknown(),
1478
+ "parameter.yaml": z.unknown(),
1479
+ "ref.yaml": z.unknown(),
1480
+ "temporal_bucketing.yaml": z.unknown()
1481
+ })
1482
+ });
1483
+ function getQuerySchemaBundle() {
1484
+ return {
1485
+ schema: query_default,
1486
+ defs: {
1487
+ "id.yaml": idSchema,
1488
+ "parameter.yaml": parameter_default,
1489
+ "ref.yaml": ref_default,
1490
+ "temporal_bucketing.yaml": temporal_bucketing_default
1491
+ }
1492
+ };
1493
+ }
1494
+
1495
+ //#endregion
1496
+ export { assertNotLegacyEnvelopeWrappingMbql5, getQuerySchemaBundle, isMbql5Query, validateQuery };