@claryai/cli 0.1.0

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 (237) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +197 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/ajv.d.ts +3 -0
  5. package/dist/ajv.d.ts.map +1 -0
  6. package/dist/ajv.js +13 -0
  7. package/dist/analytics/analytics.d.ts +370 -0
  8. package/dist/analytics/analytics.d.ts.map +1 -0
  9. package/dist/analytics/analytics.js +143 -0
  10. package/dist/config.d.ts +34 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +134 -0
  13. package/dist/dbt/context.d.ts +14 -0
  14. package/dist/dbt/context.d.ts.map +1 -0
  15. package/dist/dbt/context.js +76 -0
  16. package/dist/dbt/context.test.d.ts +2 -0
  17. package/dist/dbt/context.test.d.ts.map +1 -0
  18. package/dist/dbt/context.test.js +152 -0
  19. package/dist/dbt/manifest.d.ts +7 -0
  20. package/dist/dbt/manifest.d.ts.map +1 -0
  21. package/dist/dbt/manifest.js +23 -0
  22. package/dist/dbt/models.d.ts +43 -0
  23. package/dist/dbt/models.d.ts.map +1 -0
  24. package/dist/dbt/models.js +256 -0
  25. package/dist/dbt/models.test.d.ts +2 -0
  26. package/dist/dbt/models.test.d.ts.map +1 -0
  27. package/dist/dbt/models.test.js +19 -0
  28. package/dist/dbt/profile.d.ts +9 -0
  29. package/dist/dbt/profile.d.ts.map +1 -0
  30. package/dist/dbt/profile.js +86 -0
  31. package/dist/dbt/profiles.test.d.ts +2 -0
  32. package/dist/dbt/profiles.test.d.ts.map +1 -0
  33. package/dist/dbt/profiles.test.js +50 -0
  34. package/dist/dbt/schema.d.ts +31 -0
  35. package/dist/dbt/schema.d.ts.map +1 -0
  36. package/dist/dbt/schema.js +49 -0
  37. package/dist/dbt/targets/Bigquery/index.d.ts +18 -0
  38. package/dist/dbt/targets/Bigquery/index.d.ts.map +1 -0
  39. package/dist/dbt/targets/Bigquery/index.js +105 -0
  40. package/dist/dbt/targets/Bigquery/oauth.d.ts +2 -0
  41. package/dist/dbt/targets/Bigquery/oauth.d.ts.map +1 -0
  42. package/dist/dbt/targets/Bigquery/oauth.js +43 -0
  43. package/dist/dbt/targets/Bigquery/serviceAccount.d.ts +35 -0
  44. package/dist/dbt/targets/Bigquery/serviceAccount.d.ts.map +1 -0
  45. package/dist/dbt/targets/Bigquery/serviceAccount.js +149 -0
  46. package/dist/dbt/targets/Databricks/oauth.d.ts +21 -0
  47. package/dist/dbt/targets/Databricks/oauth.d.ts.map +1 -0
  48. package/dist/dbt/targets/Databricks/oauth.js +184 -0
  49. package/dist/dbt/targets/athena.d.ts +21 -0
  50. package/dist/dbt/targets/athena.d.ts.map +1 -0
  51. package/dist/dbt/targets/athena.js +91 -0
  52. package/dist/dbt/targets/athena.test.d.ts +2 -0
  53. package/dist/dbt/targets/athena.test.d.ts.map +1 -0
  54. package/dist/dbt/targets/athena.test.js +60 -0
  55. package/dist/dbt/targets/clickhouse.d.ts +24 -0
  56. package/dist/dbt/targets/clickhouse.d.ts.map +1 -0
  57. package/dist/dbt/targets/clickhouse.js +90 -0
  58. package/dist/dbt/targets/databricks.d.ts +27 -0
  59. package/dist/dbt/targets/databricks.d.ts.map +1 -0
  60. package/dist/dbt/targets/databricks.js +138 -0
  61. package/dist/dbt/targets/duckdb.d.ts +16 -0
  62. package/dist/dbt/targets/duckdb.d.ts.map +1 -0
  63. package/dist/dbt/targets/duckdb.js +63 -0
  64. package/dist/dbt/targets/duckdb.test.d.ts +2 -0
  65. package/dist/dbt/targets/duckdb.test.d.ts.map +1 -0
  66. package/dist/dbt/targets/duckdb.test.js +37 -0
  67. package/dist/dbt/targets/postgres.d.ts +26 -0
  68. package/dist/dbt/targets/postgres.d.ts.map +1 -0
  69. package/dist/dbt/targets/postgres.js +142 -0
  70. package/dist/dbt/targets/redshift.d.ts +23 -0
  71. package/dist/dbt/targets/redshift.d.ts.map +1 -0
  72. package/dist/dbt/targets/redshift.js +96 -0
  73. package/dist/dbt/targets/snowflake.d.ts +4 -0
  74. package/dist/dbt/targets/snowflake.d.ts.map +1 -0
  75. package/dist/dbt/targets/snowflake.js +134 -0
  76. package/dist/dbt/targets/trino.d.ts +16 -0
  77. package/dist/dbt/targets/trino.d.ts.map +1 -0
  78. package/dist/dbt/targets/trino.js +65 -0
  79. package/dist/dbt/templating.d.ts +15 -0
  80. package/dist/dbt/templating.d.ts.map +1 -0
  81. package/dist/dbt/templating.js +50 -0
  82. package/dist/dbt/templating.test.d.ts +2 -0
  83. package/dist/dbt/templating.test.d.ts.map +1 -0
  84. package/dist/dbt/templating.test.js +51 -0
  85. package/dist/dbt/types.d.ts +17 -0
  86. package/dist/dbt/types.d.ts.map +1 -0
  87. package/dist/dbt/types.js +2 -0
  88. package/dist/dbt/validation.d.ts +9 -0
  89. package/dist/dbt/validation.d.ts.map +1 -0
  90. package/dist/dbt/validation.js +54 -0
  91. package/dist/env.d.ts +12 -0
  92. package/dist/env.d.ts.map +1 -0
  93. package/dist/env.js +40 -0
  94. package/dist/error.d.ts +2 -0
  95. package/dist/error.d.ts.map +1 -0
  96. package/dist/error.js +12 -0
  97. package/dist/globalState.d.ts +29 -0
  98. package/dist/globalState.d.ts.map +1 -0
  99. package/dist/globalState.js +67 -0
  100. package/dist/handlers/asyncQuery.d.ts +7 -0
  101. package/dist/handlers/asyncQuery.d.ts.map +1 -0
  102. package/dist/handlers/asyncQuery.js +50 -0
  103. package/dist/handlers/compile.d.ts +16 -0
  104. package/dist/handlers/compile.d.ts.map +1 -0
  105. package/dist/handlers/compile.js +277 -0
  106. package/dist/handlers/compile.test.d.ts +2 -0
  107. package/dist/handlers/compile.test.d.ts.map +1 -0
  108. package/dist/handlers/compile.test.js +201 -0
  109. package/dist/handlers/createProject.d.ts +37 -0
  110. package/dist/handlers/createProject.d.ts.map +1 -0
  111. package/dist/handlers/createProject.js +272 -0
  112. package/dist/handlers/dbt/apiClient.d.ts +14 -0
  113. package/dist/handlers/dbt/apiClient.d.ts.map +1 -0
  114. package/dist/handlers/dbt/apiClient.js +167 -0
  115. package/dist/handlers/dbt/compile.d.ts +35 -0
  116. package/dist/handlers/dbt/compile.d.ts.map +1 -0
  117. package/dist/handlers/dbt/compile.js +220 -0
  118. package/dist/handlers/dbt/getDbtProfileTargetName.d.ts +9 -0
  119. package/dist/handlers/dbt/getDbtProfileTargetName.d.ts.map +1 -0
  120. package/dist/handlers/dbt/getDbtProfileTargetName.js +44 -0
  121. package/dist/handlers/dbt/getDbtVersion.d.ts +16 -0
  122. package/dist/handlers/dbt/getDbtVersion.d.ts.map +1 -0
  123. package/dist/handlers/dbt/getDbtVersion.js +141 -0
  124. package/dist/handlers/dbt/getDbtVersion.mocks.d.ts +11 -0
  125. package/dist/handlers/dbt/getDbtVersion.mocks.d.ts.map +1 -0
  126. package/dist/handlers/dbt/getDbtVersion.mocks.js +70 -0
  127. package/dist/handlers/dbt/getDbtVersion.test.d.ts +2 -0
  128. package/dist/handlers/dbt/getDbtVersion.test.d.ts.map +1 -0
  129. package/dist/handlers/dbt/getDbtVersion.test.js +97 -0
  130. package/dist/handlers/dbt/getWarehouseClient.d.ts +24 -0
  131. package/dist/handlers/dbt/getWarehouseClient.d.ts.map +1 -0
  132. package/dist/handlers/dbt/getWarehouseClient.js +312 -0
  133. package/dist/handlers/dbt/refresh.d.ts +11 -0
  134. package/dist/handlers/dbt/refresh.d.ts.map +1 -0
  135. package/dist/handlers/dbt/refresh.js +114 -0
  136. package/dist/handlers/dbt/run.d.ts +14 -0
  137. package/dist/handlers/dbt/run.d.ts.map +1 -0
  138. package/dist/handlers/dbt/run.js +67 -0
  139. package/dist/handlers/deploy.d.ts +26 -0
  140. package/dist/handlers/deploy.d.ts.map +1 -0
  141. package/dist/handlers/deploy.js +377 -0
  142. package/dist/handlers/diagnostics.d.ts +11 -0
  143. package/dist/handlers/diagnostics.d.ts.map +1 -0
  144. package/dist/handlers/diagnostics.js +194 -0
  145. package/dist/handlers/download.d.ts +29 -0
  146. package/dist/handlers/download.d.ts.map +1 -0
  147. package/dist/handlers/download.js +955 -0
  148. package/dist/handlers/exportChartImage.d.ts +7 -0
  149. package/dist/handlers/exportChartImage.d.ts.map +1 -0
  150. package/dist/handlers/exportChartImage.js +33 -0
  151. package/dist/handlers/generate.d.ts +13 -0
  152. package/dist/handlers/generate.d.ts.map +1 -0
  153. package/dist/handlers/generate.js +159 -0
  154. package/dist/handlers/generateExposures.d.ts +8 -0
  155. package/dist/handlers/generateExposures.d.ts.map +1 -0
  156. package/dist/handlers/generateExposures.js +100 -0
  157. package/dist/handlers/getProject.d.ts +6 -0
  158. package/dist/handlers/getProject.d.ts.map +1 -0
  159. package/dist/handlers/getProject.js +43 -0
  160. package/dist/handlers/installSkills.d.ts +12 -0
  161. package/dist/handlers/installSkills.d.ts.map +1 -0
  162. package/dist/handlers/installSkills.js +321 -0
  163. package/dist/handlers/lint/ajvToSarif.d.ts +66 -0
  164. package/dist/handlers/lint/ajvToSarif.d.ts.map +1 -0
  165. package/dist/handlers/lint/ajvToSarif.js +222 -0
  166. package/dist/handlers/lint/sarifFormatter.d.ts +14 -0
  167. package/dist/handlers/lint/sarifFormatter.d.ts.map +1 -0
  168. package/dist/handlers/lint/sarifFormatter.js +111 -0
  169. package/dist/handlers/lint.d.ts +8 -0
  170. package/dist/handlers/lint.d.ts.map +1 -0
  171. package/dist/handlers/lint.js +308 -0
  172. package/dist/handlers/listProjects.d.ts +6 -0
  173. package/dist/handlers/listProjects.d.ts.map +1 -0
  174. package/dist/handlers/listProjects.js +53 -0
  175. package/dist/handlers/login/oauth.d.ts +2 -0
  176. package/dist/handlers/login/oauth.d.ts.map +1 -0
  177. package/dist/handlers/login/oauth.js +27 -0
  178. package/dist/handlers/login/pat.d.ts +2 -0
  179. package/dist/handlers/login/pat.d.ts.map +1 -0
  180. package/dist/handlers/login/pat.js +31 -0
  181. package/dist/handlers/login.d.ts +15 -0
  182. package/dist/handlers/login.d.ts.map +1 -0
  183. package/dist/handlers/login.js +239 -0
  184. package/dist/handlers/metadataFile.d.ts +9 -0
  185. package/dist/handlers/metadataFile.d.ts.map +1 -0
  186. package/dist/handlers/metadataFile.js +34 -0
  187. package/dist/handlers/oauthLogin.d.ts +6 -0
  188. package/dist/handlers/oauthLogin.d.ts.map +1 -0
  189. package/dist/handlers/oauthLogin.js +191 -0
  190. package/dist/handlers/preview.d.ts +29 -0
  191. package/dist/handlers/preview.d.ts.map +1 -0
  192. package/dist/handlers/preview.js +415 -0
  193. package/dist/handlers/renameHandler.d.ts +16 -0
  194. package/dist/handlers/renameHandler.d.ts.map +1 -0
  195. package/dist/handlers/renameHandler.js +160 -0
  196. package/dist/handlers/runChart.d.ts +10 -0
  197. package/dist/handlers/runChart.d.ts.map +1 -0
  198. package/dist/handlers/runChart.js +105 -0
  199. package/dist/handlers/selectProject.d.ts +20 -0
  200. package/dist/handlers/selectProject.d.ts.map +1 -0
  201. package/dist/handlers/selectProject.js +91 -0
  202. package/dist/handlers/setProject.d.ts +14 -0
  203. package/dist/handlers/setProject.d.ts.map +1 -0
  204. package/dist/handlers/setProject.js +131 -0
  205. package/dist/handlers/setWarehouse.d.ts +14 -0
  206. package/dist/handlers/setWarehouse.d.ts.map +1 -0
  207. package/dist/handlers/setWarehouse.js +94 -0
  208. package/dist/handlers/sql.d.ts +9 -0
  209. package/dist/handlers/sql.d.ts.map +1 -0
  210. package/dist/handlers/sql.js +89 -0
  211. package/dist/handlers/utils.d.ts +11 -0
  212. package/dist/handlers/utils.d.ts.map +1 -0
  213. package/dist/handlers/utils.js +36 -0
  214. package/dist/handlers/validate.d.ts +22 -0
  215. package/dist/handlers/validate.d.ts.map +1 -0
  216. package/dist/handlers/validate.js +201 -0
  217. package/dist/index.d.ts +3 -0
  218. package/dist/index.d.ts.map +1 -0
  219. package/dist/index.js +581 -0
  220. package/dist/lightdash/loader.d.ts +21 -0
  221. package/dist/lightdash/loader.d.ts.map +1 -0
  222. package/dist/lightdash/loader.js +122 -0
  223. package/dist/lightdash/projectType.d.ts +84 -0
  224. package/dist/lightdash/projectType.d.ts.map +1 -0
  225. package/dist/lightdash/projectType.js +75 -0
  226. package/dist/lightdash-config/index.d.ts +2 -0
  227. package/dist/lightdash-config/index.d.ts.map +1 -0
  228. package/dist/lightdash-config/index.js +41 -0
  229. package/dist/lightdash-config/lightdash-config.test.d.ts +2 -0
  230. package/dist/lightdash-config/lightdash-config.test.d.ts.map +1 -0
  231. package/dist/lightdash-config/lightdash-config.test.js +70 -0
  232. package/dist/styles.d.ts +10 -0
  233. package/dist/styles.d.ts.map +1 -0
  234. package/dist/styles.js +14 -0
  235. package/entitlements.plist +33 -0
  236. package/package.json +71 -0
  237. package/track.sh +116 -0
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runChartHandler = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@lightdash/common");
6
+ const fs_1 = require("fs");
7
+ const yaml = tslib_1.__importStar(require("js-yaml"));
8
+ const config_1 = require("../config");
9
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
10
+ const styles = tslib_1.__importStar(require("../styles"));
11
+ const asyncQuery_1 = require("./asyncQuery");
12
+ const apiClient_1 = require("./dbt/apiClient");
13
+ const DEFAULT_PAGE_SIZE = 500;
14
+ const runChartHandler = async (options) => {
15
+ globalState_1.default.setVerbose(options.verbose ?? false);
16
+ // Read and parse YAML
17
+ let fileContent;
18
+ try {
19
+ fileContent = await fs_1.promises.readFile(options.path, 'utf-8');
20
+ }
21
+ catch (err) {
22
+ throw new Error(`Cannot read file: ${options.path}`);
23
+ }
24
+ let chart;
25
+ try {
26
+ chart = yaml.load(fileContent);
27
+ }
28
+ catch (err) {
29
+ throw new Error(`Invalid YAML in ${options.path}`);
30
+ }
31
+ // Validate it's a metric query chart (not SQL)
32
+ const typedChart = chart;
33
+ if ('sql' in typedChart && !('tableName' in typedChart)) {
34
+ throw new Error('SQL charts are not supported. Only metric query charts (with tableName + metricQuery) can be run.');
35
+ }
36
+ if (!typedChart.tableName || !typedChart.metricQuery) {
37
+ throw new Error(`File is not a valid metric query chart. Expected 'tableName' and 'metricQuery' fields.`);
38
+ }
39
+ const chartAsCode = chart;
40
+ // Get project UUID
41
+ const config = await (0, config_1.getConfig)();
42
+ const projectUuid = config.context?.project;
43
+ if (!projectUuid) {
44
+ throw new Error(`No project selected. Run 'clary config set-project' first.`);
45
+ }
46
+ const chartName = chartAsCode.name ?? chartAsCode.slug ?? options.path;
47
+ globalState_1.default.debug(`> Running chart: ${chartName}`);
48
+ globalState_1.default.debug(`> Table: ${chartAsCode.tableName}`);
49
+ globalState_1.default.debug(`> Project: ${projectUuid}`);
50
+ const spinner = globalState_1.default.startSpinner(`Executing query for '${chartName}'...`);
51
+ const { metricQuery } = chartAsCode;
52
+ // Build request body: convert MetricQuery to MetricQueryRequest shape
53
+ const queryBody = {
54
+ exploreName: chartAsCode.tableName,
55
+ dimensions: metricQuery.dimensions,
56
+ metrics: metricQuery.metrics,
57
+ filters: metricQuery.filters,
58
+ sorts: metricQuery.sorts,
59
+ limit: options.limit ?? metricQuery.limit,
60
+ tableCalculations: metricQuery.tableCalculations,
61
+ additionalMetrics: metricQuery.additionalMetrics,
62
+ customDimensions: metricQuery.customDimensions,
63
+ };
64
+ // Submit metric query
65
+ const submitResult = await (0, apiClient_1.lightdashApi)({
66
+ method: 'POST',
67
+ url: `/api/v2/projects/${projectUuid}/query/metric-query`,
68
+ body: JSON.stringify({
69
+ query: queryBody,
70
+ context: 'cli',
71
+ }),
72
+ });
73
+ globalState_1.default.debug(`> Query UUID: ${submitResult.queryUuid}`);
74
+ spinner.text = 'Waiting for query results...';
75
+ // Poll for completion
76
+ const result = await (0, asyncQuery_1.pollForResults)(projectUuid, submitResult.queryUuid, {
77
+ pageSize: options.output
78
+ ? (options.pageSize ?? DEFAULT_PAGE_SIZE)
79
+ : undefined,
80
+ });
81
+ if (result.status === common_1.QueryHistoryStatus.ERROR) {
82
+ spinner.fail(`Query failed for '${chartName}'\n Make sure all semantic layer fields referenced in the metric query (dimensions, metrics, custom dimensions, etc.) are deployed to the Clary project.`);
83
+ throw new Error(result.error ?? 'Query execution failed');
84
+ }
85
+ if (result.status === common_1.QueryHistoryStatus.CANCELLED) {
86
+ spinner.fail(`Query cancelled for '${chartName}'`);
87
+ throw new Error('Query was cancelled');
88
+ }
89
+ if (result.status !== common_1.QueryHistoryStatus.READY) {
90
+ spinner.fail('Unexpected query status');
91
+ throw new Error(`Unexpected query status: ${result.status}`);
92
+ }
93
+ const durationMs = result.initialQueryExecutionMs;
94
+ const durationStr = durationMs ? ` (${durationMs}ms)` : '';
95
+ if (options.output) {
96
+ const columns = Object.keys(result.columns);
97
+ const csv = (0, asyncQuery_1.resultsToCsv)(columns, result.rows);
98
+ await fs_1.promises.writeFile(options.output, csv, 'utf8');
99
+ spinner.succeed(`${styles.success('Success!')} Wrote ${result.rows.length} rows to ${options.output}${durationStr}`);
100
+ }
101
+ else {
102
+ spinner.succeed(`${styles.success('Success!')} '${chartName}' query succeeded${durationStr}`);
103
+ }
104
+ };
105
+ exports.runChartHandler = runChartHandler;
@@ -0,0 +1,20 @@
1
+ import { Config } from '../config';
2
+ export type ProjectSelection = {
3
+ projectUuid: string;
4
+ isPreview: boolean;
5
+ };
6
+ /**
7
+ * Resolves which project to use, prompting the user if there's an active preview.
8
+ *
9
+ * Priority:
10
+ * 1. If `explicitProject` is provided (via --project flag), use it
11
+ * 2. If there's an active preview and we're in interactive mode, ask the user
12
+ * 3. In non-interactive mode with active preview, use preview project
13
+ * 4. Fall back to the main project
14
+ */
15
+ export declare const selectProject: (config: Config, explicitProject?: string) => Promise<ProjectSelection | undefined>;
16
+ /**
17
+ * Logs which project is being used
18
+ */
19
+ export declare const logSelectedProject: (selection: ProjectSelection, config: Config, action: string) => void;
20
+ //# sourceMappingURL=selectProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectProject.d.ts","sourceRoot":"","sources":["../../src/handlers/selectProject.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAInC,MAAM,MAAM,gBAAgB,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACtB,QAAQ,MAAM,EACd,kBAAkB,MAAM,KACzB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAsEtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAC3B,WAAW,gBAAgB,EAC3B,QAAQ,MAAM,EACd,QAAQ,MAAM,KACf,IAcF,CAAC"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logSelectedProject = exports.selectProject = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
6
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
7
+ const styles = tslib_1.__importStar(require("../styles"));
8
+ /**
9
+ * Resolves which project to use, prompting the user if there's an active preview.
10
+ *
11
+ * Priority:
12
+ * 1. If `explicitProject` is provided (via --project flag), use it
13
+ * 2. If there's an active preview and we're in interactive mode, ask the user
14
+ * 3. In non-interactive mode with active preview, use preview project
15
+ * 4. Fall back to the main project
16
+ */
17
+ const selectProject = async (config, explicitProject) => {
18
+ // If explicit project provided via --project flag, use it
19
+ if (explicitProject) {
20
+ return { projectUuid: explicitProject, isPreview: false };
21
+ }
22
+ const mainProject = config.context?.project;
23
+ const previewProject = config.context?.previewProject;
24
+ const previewName = config.context?.previewName;
25
+ const mainProjectName = config.context?.projectName;
26
+ // No projects configured at all
27
+ if (!mainProject && !previewProject) {
28
+ return undefined;
29
+ }
30
+ // Only preview project available (edge case, but handle it)
31
+ if (!mainProject && previewProject) {
32
+ return { projectUuid: previewProject, isPreview: true };
33
+ }
34
+ // Only main project available (no active preview)
35
+ if (mainProject && !previewProject) {
36
+ return { projectUuid: mainProject, isPreview: false };
37
+ }
38
+ // Both are available - need to choose
39
+ if (mainProject && previewProject) {
40
+ // In non-interactive mode, default to preview project
41
+ if (globalState_1.default.isNonInteractive()) {
42
+ globalState_1.default.debug('> Non-interactive mode with active preview, using preview project');
43
+ return { projectUuid: previewProject, isPreview: true };
44
+ }
45
+ // Interactive mode - ask the user
46
+ const spinner = globalState_1.default.getActiveSpinner();
47
+ spinner?.stop();
48
+ const previewLabel = previewName
49
+ ? `Preview: "${previewName}"`
50
+ : `Preview: ${previewProject}`;
51
+ const mainLabel = mainProjectName
52
+ ? `Production: "${mainProjectName}"`
53
+ : `Production: ${mainProject}`;
54
+ const { selectedProject } = await inquirer_1.default.prompt([
55
+ {
56
+ type: 'list',
57
+ name: 'selectedProject',
58
+ message: 'You have an active preview. Which project do you want to use?',
59
+ choices: [
60
+ { name: previewLabel, value: 'preview' },
61
+ { name: mainLabel, value: 'production' },
62
+ ],
63
+ default: 'preview',
64
+ },
65
+ ]);
66
+ spinner?.start();
67
+ if (selectedProject === 'preview') {
68
+ return { projectUuid: previewProject, isPreview: true };
69
+ }
70
+ return { projectUuid: mainProject, isPreview: false };
71
+ }
72
+ return undefined;
73
+ };
74
+ exports.selectProject = selectProject;
75
+ /**
76
+ * Logs which project is being used
77
+ */
78
+ const logSelectedProject = (selection, config, action) => {
79
+ const { projectUuid, isPreview } = selection;
80
+ const previewName = config.context?.previewName;
81
+ const mainProjectName = config.context?.projectName;
82
+ if (isPreview) {
83
+ const name = previewName ? `"${previewName}"` : projectUuid;
84
+ globalState_1.default.log(`\n${styles.success(`${action} preview project:`)} ${name}\n`);
85
+ }
86
+ else {
87
+ const name = mainProjectName ? `"${mainProjectName}"` : projectUuid;
88
+ globalState_1.default.log(`\n${styles.success(`${action} project:`)} ${name}\n`);
89
+ }
90
+ };
91
+ exports.logSelectedProject = logSelectedProject;
@@ -0,0 +1,14 @@
1
+ type SetProjectOptions = {
2
+ verbose: boolean;
3
+ name: string;
4
+ uuid: string;
5
+ };
6
+ export declare const setProjectCommand: (name?: string, uuid?: string) => Promise<"selected" | "skipped" | "empty">;
7
+ export declare const setFirstProject: () => Promise<void>;
8
+ export declare const setProjectHandler: (options: SetProjectOptions) => Promise<void>;
9
+ export declare const unsetProjectCommand: () => Promise<void>;
10
+ export declare const unsetProjectHandler: (options: {
11
+ verbose: boolean;
12
+ }) => Promise<void>;
13
+ export {};
14
+ //# sourceMappingURL=setProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setProject.d.ts","sourceRoot":"","sources":["../../src/handlers/setProject.ts"],"names":[],"mappings":"AAQA,KAAK,iBAAiB,GAAG;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC1B,OAAO,MAAM,EACb,OAAO,MAAM,KACd,OAAO,CAAC,UAAU,GAAG,SAAS,GAAG,OAAO,CAmE1C,CAAC;AAEF,eAAO,MAAM,eAAe,qBAmB3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,SAAS,iBAAiB,kBAsBjE,CAAC;AAEF,eAAO,MAAM,mBAAmB,qBAG/B,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,SAAS;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,kBAmBtE,CAAC"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unsetProjectHandler = exports.unsetProjectCommand = exports.setProjectHandler = exports.setFirstProject = exports.setProjectCommand = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
6
+ const url_1 = require("url");
7
+ const analytics_1 = require("../analytics/analytics");
8
+ const config_1 = require("../config");
9
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
10
+ const apiClient_1 = require("./dbt/apiClient");
11
+ const setProjectCommand = async (name, uuid) => {
12
+ const projects = await (0, apiClient_1.lightdashApi)({
13
+ method: 'GET',
14
+ url: `/api/v1/org/projects`,
15
+ body: undefined,
16
+ });
17
+ globalState_1.default.debug(`> Set project returned response: ${JSON.stringify(projects)}`);
18
+ if (projects.length === 0)
19
+ return 'empty';
20
+ let selectedProject;
21
+ // --uuid or --name options
22
+ if (uuid !== undefined || name !== undefined) {
23
+ selectedProject = projects.find((project) => project.name === name || project.projectUuid === uuid);
24
+ }
25
+ else if (globalState_1.default.isNonInteractive()) {
26
+ globalState_1.default.debug('> Non-interactive mode: selecting first project');
27
+ [selectedProject] = projects;
28
+ }
29
+ else {
30
+ const SKIP_VALUE = '__skip__';
31
+ const answers = await inquirer_1.default.prompt([
32
+ {
33
+ type: 'list',
34
+ name: 'project',
35
+ choices: [
36
+ {
37
+ name: "Don't select a project",
38
+ value: SKIP_VALUE,
39
+ },
40
+ ...projects.map((project) => ({
41
+ name: project.name,
42
+ value: project.projectUuid,
43
+ })),
44
+ ],
45
+ },
46
+ ]);
47
+ if (answers.project === SKIP_VALUE) {
48
+ await (0, config_1.unsetProject)();
49
+ return 'skipped';
50
+ }
51
+ selectedProject = projects.find((project) => project.projectUuid === answers.project);
52
+ }
53
+ if (selectedProject !== undefined) {
54
+ await (0, config_1.setProject)(selectedProject.projectUuid, selectedProject.name);
55
+ const config = await (0, config_1.getConfig)();
56
+ const projectUrl = config.context?.serverUrl &&
57
+ new url_1.URL(`/projects/${selectedProject.projectUuid}/home`, config.context.serverUrl);
58
+ console.error(`\n ✅️ Connected to Clary project: ${projectUrl || ''}\n`);
59
+ return 'selected';
60
+ }
61
+ throw new Error(`Project not found.`);
62
+ };
63
+ exports.setProjectCommand = setProjectCommand;
64
+ const setFirstProject = async () => {
65
+ const projects = await (0, apiClient_1.lightdashApi)({
66
+ method: 'GET',
67
+ url: `/api/v1/org/projects`,
68
+ body: undefined,
69
+ });
70
+ const firstProject = projects[0];
71
+ await (0, config_1.setProject)(firstProject.projectUuid, firstProject.name);
72
+ const config = await (0, config_1.getConfig)();
73
+ const projectUrl = config.context?.serverUrl &&
74
+ new url_1.URL(`/projects/${firstProject.name}/home`, config.context.serverUrl);
75
+ console.error(`\n ✅️ Connected to Clary project: ${projectUrl || ''}\n`);
76
+ };
77
+ exports.setFirstProject = setFirstProject;
78
+ const setProjectHandler = async (options) => {
79
+ const startTime = Date.now();
80
+ let success = true;
81
+ globalState_1.default.setVerbose(options.verbose);
82
+ try {
83
+ const result = await (0, exports.setProjectCommand)(options.name, options.uuid);
84
+ if (result === 'skipped') {
85
+ console.error(`\n Project unset.\n`);
86
+ }
87
+ }
88
+ catch (e) {
89
+ success = false;
90
+ throw e;
91
+ }
92
+ finally {
93
+ await analytics_1.LightdashAnalytics.track({
94
+ event: 'command.executed',
95
+ properties: {
96
+ command: 'set-project',
97
+ durationMs: Date.now() - startTime,
98
+ success,
99
+ },
100
+ });
101
+ }
102
+ };
103
+ exports.setProjectHandler = setProjectHandler;
104
+ const unsetProjectCommand = async () => {
105
+ await (0, config_1.unsetProject)();
106
+ console.error(`\n Project unset.\n`);
107
+ };
108
+ exports.unsetProjectCommand = unsetProjectCommand;
109
+ const unsetProjectHandler = async (options) => {
110
+ const startTime = Date.now();
111
+ let success = true;
112
+ globalState_1.default.setVerbose(options.verbose);
113
+ try {
114
+ await (0, exports.unsetProjectCommand)();
115
+ }
116
+ catch (e) {
117
+ success = false;
118
+ throw e;
119
+ }
120
+ finally {
121
+ await analytics_1.LightdashAnalytics.track({
122
+ event: 'command.executed',
123
+ properties: {
124
+ command: 'unset-project',
125
+ durationMs: Date.now() - startTime,
126
+ success,
127
+ },
128
+ });
129
+ }
130
+ };
131
+ exports.unsetProjectHandler = unsetProjectHandler;
@@ -0,0 +1,14 @@
1
+ type SetWarehouseHandlerOptions = {
2
+ projectDir: string;
3
+ profilesDir: string;
4
+ target?: string;
5
+ profile?: string;
6
+ targetPath?: string;
7
+ project?: string;
8
+ startOfWeek?: number;
9
+ assumeYes: boolean;
10
+ verbose: boolean;
11
+ };
12
+ export declare const setWarehouseHandler: (options: SetWarehouseHandlerOptions) => Promise<void>;
13
+ export {};
14
+ //# sourceMappingURL=setWarehouse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setWarehouse.d.ts","sourceRoot":"","sources":["../../src/handlers/setWarehouse.ts"],"names":[],"mappings":"AAaA,KAAK,0BAA0B,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAeF,eAAO,MAAM,mBAAmB,GAC5B,SAAS,0BAA0B,kBAyFtC,CAAC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setWarehouseHandler = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@lightdash/common");
6
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
7
+ const config_1 = require("../config");
8
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
9
+ const styles = tslib_1.__importStar(require("../styles"));
10
+ const createProject_1 = require("./createProject");
11
+ const apiClient_1 = require("./dbt/apiClient");
12
+ const refresh_1 = require("./dbt/refresh");
13
+ const resolveProjectUuid = async (projectOption) => {
14
+ if (projectOption) {
15
+ return projectOption;
16
+ }
17
+ const config = await (0, config_1.getConfig)();
18
+ if (!config.context?.project) {
19
+ throw new common_1.AuthorizationError(`No project selected. Run 'clary config set-project' first or pass '--project <uuid>'.`);
20
+ }
21
+ return config.context.project;
22
+ };
23
+ const setWarehouseHandler = async (options) => {
24
+ globalState_1.default.setVerbose(options.verbose);
25
+ await (0, apiClient_1.checkLightdashVersion)();
26
+ const projectUuid = await resolveProjectUuid(options.project);
27
+ // Load credentials from profiles.yml
28
+ const loaded = await (0, createProject_1.loadWarehouseCredentialsFromProfiles)({
29
+ projectDir: options.projectDir,
30
+ profilesDir: options.profilesDir,
31
+ target: options.target,
32
+ profile: options.profile,
33
+ startOfWeek: options.startOfWeek,
34
+ assumeYes: options.assumeYes,
35
+ targetPath: options.targetPath,
36
+ });
37
+ if (!loaded) {
38
+ console.error(styles.warning('User declined to store warehouse credentials. Use --assume-yes to bypass.'));
39
+ return;
40
+ }
41
+ const { credentials } = loaded;
42
+ // Fetch existing project to preserve its settings
43
+ const existingProject = await (0, refresh_1.getProject)(projectUuid);
44
+ // Confirmation prompt
45
+ if (!options.assumeYes && !globalState_1.default.isNonInteractive()) {
46
+ const spinner = globalState_1.default.getActiveSpinner();
47
+ spinner?.stop();
48
+ const answers = await inquirer_1.default.prompt([
49
+ {
50
+ type: 'confirm',
51
+ name: 'isConfirm',
52
+ message: `This will update the warehouse connection on project '${existingProject.name}' to ${credentials.type} and trigger a recompile. Continue?`,
53
+ default: false,
54
+ },
55
+ ]);
56
+ if (!answers.isConfirm) {
57
+ console.error(styles.warning('Aborted.'));
58
+ return;
59
+ }
60
+ spinner?.start();
61
+ }
62
+ const spinner = globalState_1.default.startSpinner(' Updating warehouse connection...');
63
+ try {
64
+ // Build UpdateProject body — preserve existing fields, override warehouseConnection.
65
+ // Note: dbtConnection from GET response may have stripped secrets, but the backend's
66
+ // mergeMissingProjectConfigSecrets fills them back in from the saved project before persisting.
67
+ const updateBody = {
68
+ name: existingProject.name,
69
+ dbtConnection: existingProject.dbtConnection,
70
+ dbtVersion: existingProject.dbtVersion,
71
+ warehouseConnection: credentials,
72
+ };
73
+ // PATCH project — triggers adaptor test + recompile
74
+ const result = await (0, apiClient_1.lightdashApi)({
75
+ method: 'PATCH',
76
+ url: `/api/v1/projects/${projectUuid}`,
77
+ body: JSON.stringify(updateBody),
78
+ });
79
+ // Poll until job completes (custom spinner prefix)
80
+ await (0, refresh_1.getFinalJobState)(result.jobUuid, 'Updating warehouse connection');
81
+ spinner.stop();
82
+ }
83
+ catch (e) {
84
+ spinner.fail();
85
+ throw e;
86
+ }
87
+ const config = await (0, config_1.getConfig)();
88
+ const displayUrl = `${config.context?.serverUrl}/projects/${projectUuid}/home`;
89
+ console.error(`${styles.bold('Successfully updated warehouse connection:')}`);
90
+ console.error('');
91
+ console.error(` ${styles.bold(`⚡️ ${displayUrl}`)}`);
92
+ console.error('');
93
+ };
94
+ exports.setWarehouseHandler = setWarehouseHandler;
@@ -0,0 +1,9 @@
1
+ type SqlHandlerOptions = {
2
+ output: string;
3
+ limit?: number;
4
+ pageSize?: number;
5
+ verbose?: boolean;
6
+ };
7
+ export declare const sqlHandler: (sql: string, options: SqlHandlerOptions) => Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/handlers/sql.ts"],"names":[],"mappings":"AAcA,KAAK,iBAAiB,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAKF,eAAO,MAAM,UAAU,GACnB,KAAK,MAAM,EACX,SAAS,iBAAiB,KAC3B,OAAO,CAAC,IAAI,CAqGd,CAAC"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sqlHandler = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@lightdash/common");
6
+ const fs_1 = require("fs");
7
+ const uuid_1 = require("uuid");
8
+ const analytics_1 = require("../analytics/analytics");
9
+ const config_1 = require("../config");
10
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
11
+ const styles = tslib_1.__importStar(require("../styles"));
12
+ const asyncQuery_1 = require("./asyncQuery");
13
+ const apiClient_1 = require("./dbt/apiClient");
14
+ const DEFAULT_PAGE_SIZE = 500;
15
+ const DEFAULT_LIMIT = 50000;
16
+ const sqlHandler = async (sql, options) => {
17
+ globalState_1.default.setVerbose(options.verbose ?? false);
18
+ const executionId = (0, uuid_1.v4)();
19
+ const startTime = Date.now();
20
+ const config = await (0, config_1.getConfig)();
21
+ const projectUuid = config.context?.project;
22
+ if (!projectUuid) {
23
+ throw new Error(`No project selected. Run 'clary config set-project' first.`);
24
+ }
25
+ globalState_1.default.debug(`> Running SQL query against project: ${projectUuid}`);
26
+ globalState_1.default.debug(`> SQL: ${sql}`);
27
+ const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;
28
+ try {
29
+ await analytics_1.LightdashAnalytics.track({
30
+ event: 'sql.started',
31
+ properties: {
32
+ executionId,
33
+ projectId: projectUuid,
34
+ },
35
+ });
36
+ const spinner = globalState_1.default.startSpinner('Submitting SQL query...');
37
+ const limit = options.limit ?? DEFAULT_LIMIT;
38
+ const submitResult = await (0, apiClient_1.lightdashApi)({
39
+ method: 'POST',
40
+ url: `/api/v2/projects/${projectUuid}/query/sql`,
41
+ body: JSON.stringify({
42
+ sql,
43
+ limit,
44
+ context: 'cli',
45
+ }),
46
+ });
47
+ globalState_1.default.debug(`> Query UUID: ${submitResult.queryUuid}`);
48
+ spinner.text = 'Waiting for query results...';
49
+ const result = await (0, asyncQuery_1.pollForResults)(projectUuid, submitResult.queryUuid, {
50
+ pageSize,
51
+ });
52
+ if (result.status === common_1.QueryHistoryStatus.ERROR) {
53
+ spinner.fail('Query failed');
54
+ throw new Error(result.error ?? 'Query execution failed');
55
+ }
56
+ if (result.status !== common_1.QueryHistoryStatus.READY) {
57
+ spinner.fail('Unexpected query status');
58
+ throw new Error(`Unexpected query status: ${result.status}`);
59
+ }
60
+ const columns = Object.keys(result.columns);
61
+ const rowCount = result.rows.length;
62
+ spinner.text = `Writing ${rowCount} rows to ${options.output}...`;
63
+ const csv = (0, asyncQuery_1.resultsToCsv)(columns, result.rows);
64
+ await fs_1.promises.writeFile(options.output, csv, 'utf8');
65
+ spinner.succeed(`${styles.success('Success!')} Wrote ${rowCount} rows to ${options.output}`);
66
+ await analytics_1.LightdashAnalytics.track({
67
+ event: 'sql.completed',
68
+ properties: {
69
+ executionId,
70
+ projectId: projectUuid,
71
+ rowCount,
72
+ columnCount: columns.length,
73
+ durationMs: Date.now() - startTime,
74
+ },
75
+ });
76
+ }
77
+ catch (e) {
78
+ await analytics_1.LightdashAnalytics.track({
79
+ event: 'sql.error',
80
+ properties: {
81
+ executionId,
82
+ error: (0, common_1.getErrorMessage)(e),
83
+ errorCategory: (0, analytics_1.categorizeError)(e),
84
+ },
85
+ });
86
+ throw e;
87
+ }
88
+ };
89
+ exports.sqlHandler = sqlHandler;
@@ -0,0 +1,11 @@
1
+ import { LightdashRequestMethodHeader, RequestMethod } from '@lightdash/common';
2
+ type RequestHeader = {
3
+ 'Content-Type': 'application/json';
4
+ 'Content-Encoding'?: string;
5
+ Authorization: string;
6
+ 'Proxy-Authorization'?: string;
7
+ [LightdashRequestMethodHeader]: RequestMethod;
8
+ };
9
+ export declare function buildRequestHeaders(token: string): RequestHeader;
10
+ export {};
11
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/handlers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,4BAA4B,EAC5B,aAAa,EAChB,MAAM,mBAAmB,CAAC;AAO3B,KAAK,aAAa,GAAG;IACjB,cAAc,EAAE,kBAAkB,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,CAAC,4BAA4B,CAAC,EAAE,aAAa,CAAC;CACjD,CAAC;AAgBF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAgBhD"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildRequestHeaders = buildRequestHeaders;
4
+ const common_1 = require("@lightdash/common");
5
+ var TokenType;
6
+ (function (TokenType) {
7
+ TokenType["ApiKey"] = "ApiKey";
8
+ TokenType["Bearer"] = "Bearer";
9
+ })(TokenType || (TokenType = {}));
10
+ /**
11
+ * We initially used personal access tokens (PATs) for CLI authentication without any prefix.
12
+ * Service account tokens are launching with a prefix, so we'll check them first.
13
+ * We assume a missing prefix is a personal access token, although new PATs will be created with a prefix.
14
+ *
15
+ * See {@link AuthTokenPrefix} for the available token prefixes
16
+ */
17
+ function getAuthHeader(token) {
18
+ const authType = token?.startsWith(common_1.AuthTokenPrefix.SERVICE_ACCOUNT)
19
+ ? TokenType.Bearer
20
+ : TokenType.ApiKey;
21
+ return `${authType} ${token}`;
22
+ }
23
+ function buildRequestHeaders(token) {
24
+ const headers = {
25
+ 'Content-Type': 'application/json',
26
+ Authorization: getAuthHeader(token),
27
+ [common_1.LightdashRequestMethodHeader]: process.env.CI === 'true'
28
+ ? common_1.RequestMethod.CLI_CI
29
+ : common_1.RequestMethod.CLI,
30
+ };
31
+ if (process.env.CLARY_PROXY_AUTHORIZATION) {
32
+ headers['Proxy-Authorization'] =
33
+ process.env.CLARY_PROXY_AUTHORIZATION;
34
+ }
35
+ return headers;
36
+ }
@@ -0,0 +1,22 @@
1
+ import { Explore, ExploreError, SchedulerJobStatus, ValidationTarget } from '@lightdash/common';
2
+ import { CompileHandlerOptions } from './compile';
3
+ export declare const requestValidation: (projectUuid: string, explores: (Explore | ExploreError)[], validationTargets: ValidationTarget[]) => Promise<{
4
+ jobId: string;
5
+ }>;
6
+ export declare const getJobState: (jobUuid: string) => Promise<{
7
+ status: SchedulerJobStatus;
8
+ details: Record<string, import("@lightdash/common").AnyType> | null;
9
+ }>;
10
+ export declare const getValidation: (projectUuid: string, jobId: string) => Promise<import("@lightdash/common").ValidationResponse[]>;
11
+ export declare function delay(ms: number): Promise<unknown>;
12
+ type ValidateHandlerOptions = CompileHandlerOptions & {
13
+ project?: string;
14
+ verbose: boolean;
15
+ preview: boolean;
16
+ only: ValidationTarget[];
17
+ showChartConfigurationWarnings: boolean;
18
+ };
19
+ export declare const waitUntilFinished: (jobUuid: string) => Promise<string>;
20
+ export declare const validateHandler: (options: ValidateHandlerOptions) => Promise<void>;
21
+ export {};
22
+ //# sourceMappingURL=validate.d.ts.map