@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,37 @@
1
+ import { CreateProjectTableConfiguration, ProjectType, type ApiCreateProjectResults, type CreateWarehouseCredentials, type DbtVersionOption } from '@lightdash/common';
2
+ export declare const resolveOrganizationCredentialsName: (name: string) => Promise<string>;
3
+ type CreateProjectOptions = {
4
+ name: string;
5
+ projectDir: string;
6
+ profilesDir: string;
7
+ target: string | undefined;
8
+ profile: string | undefined;
9
+ type: ProjectType;
10
+ startOfWeek?: number;
11
+ upstreamProjectUuid?: string;
12
+ tableConfiguration?: CreateProjectTableConfiguration;
13
+ copyContent?: boolean;
14
+ warehouseCredentials?: boolean;
15
+ organizationCredentials?: string;
16
+ targetPath?: string;
17
+ assumeYes?: boolean;
18
+ };
19
+ type LoadWarehouseCredentialsOptions = {
20
+ projectDir: string;
21
+ profilesDir: string;
22
+ target?: string;
23
+ profile?: string;
24
+ startOfWeek?: number;
25
+ assumeYes?: boolean;
26
+ targetPath?: string;
27
+ };
28
+ type LoadWarehouseCredentialsResult = {
29
+ credentials: CreateWarehouseCredentials;
30
+ targetName: string;
31
+ dbtVersionOption: DbtVersionOption;
32
+ isDbtCloudCLI: boolean;
33
+ };
34
+ export declare const loadWarehouseCredentialsFromProfiles: (options: LoadWarehouseCredentialsOptions) => Promise<LoadWarehouseCredentialsResult | null>;
35
+ export declare const createProject: (options: CreateProjectOptions) => Promise<ApiCreateProjectResults | undefined>;
36
+ export {};
37
+ //# sourceMappingURL=createProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createProject.d.ts","sourceRoot":"","sources":["../../src/handlers/createProject.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,+BAA+B,EAI/B,WAAW,EAGX,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EAExB,MAAM,mBAAmB,CAAC;AAgE3B,eAAO,MAAM,kCAAkC,GAC3C,MAAM,MAAM,KACb,OAAO,CAAC,MAAM,CAyChB,CAAC;AAEF,KAAK,oBAAoB,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,+BAA+B,CAAC;IACrD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAqDF,KAAK,+BAA+B,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,8BAA8B,GAAG;IAClC,WAAW,EAAE,0BAA0B,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oCAAoC,GAC7C,SAAS,+BAA+B,KACzC,OAAO,CAAC,8BAA8B,GAAG,IAAI,CA2F/C,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,SAAS,oBAAoB,KAC9B,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAsG7C,CAAC"}
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createProject = exports.loadWarehouseCredentialsFromProfiles = exports.resolveOrganizationCredentialsName = 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 path_1 = tslib_1.__importDefault(require("path"));
8
+ const config_1 = require("../config");
9
+ const context_1 = require("../dbt/context");
10
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
11
+ const styles = tslib_1.__importStar(require("../styles"));
12
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
13
+ const apiClient_1 = require("./dbt/apiClient");
14
+ const getDbtProfileTargetName_1 = tslib_1.__importDefault(require("./dbt/getDbtProfileTargetName"));
15
+ const getDbtVersion_1 = require("./dbt/getDbtVersion");
16
+ const getWarehouseClient_1 = tslib_1.__importStar(require("./dbt/getWarehouseClient"));
17
+ const askToRememberAnswer = async () => {
18
+ const answers = await inquirer_1.default.prompt([
19
+ {
20
+ type: 'confirm',
21
+ name: 'isConfirm',
22
+ message: 'Do you want to save this answer for next time?',
23
+ },
24
+ ]);
25
+ if (answers.isConfirm) {
26
+ await (0, config_1.setAnswer)({
27
+ permissionToStoreWarehouseCredentials: true,
28
+ });
29
+ }
30
+ };
31
+ const askPermissionToStoreWarehouseCredentials = async (assumeYes = false) => {
32
+ if (globalState_1.default.isNonInteractive() || assumeYes) {
33
+ globalState_1.default.debug('> Auto-accepting warehouse credentials storage');
34
+ return true;
35
+ }
36
+ const config = await (0, config_1.getConfig)();
37
+ const savedAnswer = config.answers?.permissionToStoreWarehouseCredentials;
38
+ if (!savedAnswer) {
39
+ const spinner = globalState_1.default.getActiveSpinner();
40
+ if (spinner) {
41
+ spinner.stop();
42
+ }
43
+ const answers = await inquirer_1.default.prompt([
44
+ {
45
+ type: 'confirm',
46
+ name: 'isConfirm',
47
+ message: 'Do you confirm Clary can store your warehouse credentials so you can run queries in Clary?',
48
+ },
49
+ ]);
50
+ if (answers.isConfirm) {
51
+ await askToRememberAnswer();
52
+ }
53
+ if (spinner) {
54
+ spinner.start();
55
+ }
56
+ return answers.isConfirm;
57
+ }
58
+ return savedAnswer;
59
+ };
60
+ const resolveOrganizationCredentialsName = async (name) => {
61
+ globalState_1.default.debug(`> Resolving organization warehouse credentials: ${name}`);
62
+ try {
63
+ const credentialsList = await (0, apiClient_1.lightdashApi)({
64
+ method: 'GET',
65
+ url: '/api/v1/org/warehouse-credentials?summary=true',
66
+ body: undefined,
67
+ });
68
+ const credential = credentialsList.find((cred) => cred.name === name);
69
+ if (!credential) {
70
+ const availableNames = credentialsList.length > 0
71
+ ? credentialsList
72
+ .map((c) => ` - ${c.name} (${c.warehouseType})`)
73
+ .join('\n')
74
+ : ' (none available)';
75
+ throw new Error(`Organization warehouse credentials "${name}" not found.\n\nAvailable credentials:\n${availableNames}`);
76
+ }
77
+ globalState_1.default.debug(`> Resolved "${name}" to UUID: ${credential.organizationWarehouseCredentialsUuid}`);
78
+ return credential.organizationWarehouseCredentialsUuid;
79
+ }
80
+ catch (error) {
81
+ if (error instanceof Error) {
82
+ throw error;
83
+ }
84
+ throw new Error('Failed to resolve organization warehouse credentials. This may be an Enterprise Edition feature that is not available.');
85
+ }
86
+ };
87
+ exports.resolveOrganizationCredentialsName = resolveOrganizationCredentialsName;
88
+ const isSnowflakeSsoEnabled = async () => {
89
+ const response = await (0, apiClient_1.lightdashApi)({
90
+ method: 'GET',
91
+ url: `/api/v1/health`,
92
+ body: undefined,
93
+ });
94
+ return response?.auth?.snowflake?.enabled ?? false;
95
+ };
96
+ const applySnowflakeSsoHandling = async (credentials) => {
97
+ if (credentials.type !== common_1.WarehouseTypes.SNOWFLAKE ||
98
+ credentials.authenticationType !==
99
+ common_1.SnowflakeAuthenticationType.EXTERNAL_BROWSER) {
100
+ return credentials;
101
+ }
102
+ const snowflakeSsoEnabled = await isSnowflakeSsoEnabled();
103
+ if (snowflakeSsoEnabled) {
104
+ console.error(styles.info(`\nClary server has Snowflake OAuth authentication enabled.
105
+ We will ask for user credentials again on the Clary UI.\n`));
106
+ return {
107
+ ...credentials,
108
+ requireUserCredentials: true,
109
+ };
110
+ }
111
+ console.error(styles.warning(`\nUser has externalbrowser snowflake authentication.
112
+ We will generate programatically a temporary PAT to enable access on Clary which expires in 1 day.
113
+ For a better user experience, we recommend enabling Snowflake OAuth authentication on the server.\n`));
114
+ const patToken = await (0, getWarehouseClient_1.createProgramaticallySnowflakePat)(credentials);
115
+ return {
116
+ ...credentials,
117
+ authenticationType: common_1.SnowflakeAuthenticationType.PASSWORD,
118
+ password: patToken,
119
+ };
120
+ };
121
+ const loadWarehouseCredentialsFromProfiles = async (options) => {
122
+ const absoluteProjectPath = path_1.default.resolve(options.projectDir);
123
+ const dbtVersionResult = await (0, getDbtVersion_1.tryGetDbtVersion)();
124
+ if (!dbtVersionResult.success) {
125
+ throw dbtVersionResult.error;
126
+ }
127
+ const { isDbtCloudCLI } = dbtVersionResult.version;
128
+ const dbtVersionOption = dbtVersionResult.version.versionOption;
129
+ const context = await (0, context_1.getDbtContext)({
130
+ projectDir: absoluteProjectPath,
131
+ targetPath: options.targetPath,
132
+ });
133
+ globalState_1.default.debug(`> Using profiles dir ${options.profilesDir} and profile ${options.profile || context.profileName}`);
134
+ const targetName = await (0, getDbtProfileTargetName_1.default)({
135
+ isDbtCloudCLI,
136
+ profilesDir: options.profilesDir,
137
+ profile: options.profile || context.profileName,
138
+ target: options.target,
139
+ });
140
+ globalState_1.default.debug(`> Using target name ${targetName}`);
141
+ const canStoreWarehouseCredentials = await askPermissionToStoreWarehouseCredentials(options.assumeYes);
142
+ if (!canStoreWarehouseCredentials) {
143
+ return null;
144
+ }
145
+ const result = await (0, getWarehouseClient_1.default)({
146
+ isDbtCloudCLI,
147
+ profilesDir: options.profilesDir,
148
+ profile: options.profile || context.profileName,
149
+ target: options.target,
150
+ startOfWeek: options.startOfWeek,
151
+ });
152
+ const { credentials } = result;
153
+ if (credentials.type === common_1.WarehouseTypes.BIGQUERY &&
154
+ credentials.keyfileContents.project_id &&
155
+ credentials.keyfileContents.project_id !== credentials.project) {
156
+ if (globalState_1.default.isNonInteractive() && !options.assumeYes) {
157
+ throw new Error(`BigQuery project mismatch: credentials file uses "${credentials.keyfileContents.project_id}" ` +
158
+ `but profiles.yml specifies "${credentials.project}". ` +
159
+ 'This may cause permission issues. Use --assume-yes to bypass this warning.');
160
+ }
161
+ if (options.assumeYes) {
162
+ globalState_1.default.debug(`> Auto-accepting BigQuery project mismatch (credentials: ${credentials.keyfileContents.project_id}, profiles: ${credentials.project})`);
163
+ }
164
+ else {
165
+ const spinner = globalState_1.default.getActiveSpinner();
166
+ spinner?.stop();
167
+ const answers = await inquirer_1.default.prompt([
168
+ {
169
+ type: 'confirm',
170
+ name: 'isConfirm',
171
+ message: `${styles.title('Warning')}: Your project on your credentials file ${styles.title(credentials.keyfileContents.project_id)} does not match your project on your profiles.yml ${styles.title(credentials.project)}, this might cause permission issues when accessing data on the warehouse. Are you sure you want to continue?`,
172
+ },
173
+ ]);
174
+ if (!answers.isConfirm) {
175
+ process.exit(1);
176
+ }
177
+ spinner?.start();
178
+ }
179
+ }
180
+ const finalCredentials = await applySnowflakeSsoHandling(credentials);
181
+ return {
182
+ credentials: finalCredentials,
183
+ targetName,
184
+ dbtVersionOption,
185
+ isDbtCloudCLI,
186
+ };
187
+ };
188
+ exports.loadWarehouseCredentialsFromProfiles = loadWarehouseCredentialsFromProfiles;
189
+ const createProject = async (options) => {
190
+ await (0, apiClient_1.checkProjectCreationPermission)(options.upstreamProjectUuid, options.type);
191
+ // Resolve organization credentials early before doing any heavy work
192
+ let organizationWarehouseCredentialsUuid;
193
+ if (options.organizationCredentials) {
194
+ organizationWarehouseCredentialsUuid =
195
+ await (0, exports.resolveOrganizationCredentialsName)(options.organizationCredentials);
196
+ }
197
+ const absoluteProjectPath = path_1.default.resolve(options.projectDir);
198
+ let targetName;
199
+ let credentials;
200
+ let isDbtCloudCLI = false;
201
+ let dbtVersionOption = (0, common_1.getLatestSupportDbtVersion)();
202
+ // If using organization credentials, don't load warehouse credentials from profiles
203
+ if (organizationWarehouseCredentialsUuid) {
204
+ globalState_1.default.debug(`> Using organization warehouse credentials: ${options.organizationCredentials}`);
205
+ const dbtVersionResult = await (0, getDbtVersion_1.tryGetDbtVersion)();
206
+ if (!dbtVersionResult.success) {
207
+ throw dbtVersionResult.error;
208
+ }
209
+ isDbtCloudCLI = dbtVersionResult.version.isDbtCloudCLI;
210
+ dbtVersionOption = dbtVersionResult.version.versionOption;
211
+ // Still need to get target name for dbt connection
212
+ const context = await (0, context_1.getDbtContext)({
213
+ projectDir: absoluteProjectPath,
214
+ targetPath: options.targetPath,
215
+ });
216
+ globalState_1.default.debug(`> Using profiles dir ${options.profilesDir} and profile ${options.profile || context.profileName}`);
217
+ targetName = await (0, getDbtProfileTargetName_1.default)({
218
+ isDbtCloudCLI,
219
+ profilesDir: options.profilesDir,
220
+ profile: options.profile || context.profileName,
221
+ target: options.target,
222
+ });
223
+ globalState_1.default.debug(`> Using target name ${targetName}`);
224
+ }
225
+ else if (options.warehouseCredentials === false) {
226
+ globalState_1.default.debug('> Creating project without warehouse credentials');
227
+ // No dbt needed - use defaults set above
228
+ }
229
+ else {
230
+ const loaded = await (0, exports.loadWarehouseCredentialsFromProfiles)({
231
+ projectDir: options.projectDir,
232
+ profilesDir: options.profilesDir,
233
+ target: options.target,
234
+ profile: options.profile,
235
+ startOfWeek: options.startOfWeek,
236
+ assumeYes: options.assumeYes,
237
+ targetPath: options.targetPath,
238
+ });
239
+ if (!loaded) {
240
+ // User declined to store warehouse credentials
241
+ globalState_1.default.debug('> User declined to store warehouse credentials use --no-warehouse-credentials to create a project without warehouse credentials');
242
+ return undefined;
243
+ }
244
+ credentials = loaded.credentials;
245
+ targetName = loaded.targetName;
246
+ isDbtCloudCLI = loaded.isDbtCloudCLI;
247
+ dbtVersionOption = loaded.dbtVersionOption;
248
+ }
249
+ const project = {
250
+ name: options.name,
251
+ type: options.type,
252
+ warehouseConnection: credentials,
253
+ copyWarehouseConnectionFromUpstreamProject: isDbtCloudCLI ||
254
+ (options.warehouseCredentials === false &&
255
+ options.upstreamProjectUuid !== undefined),
256
+ dbtConnection: {
257
+ type: common_1.DbtProjectType.NONE,
258
+ target: targetName,
259
+ },
260
+ upstreamProjectUuid: options.upstreamProjectUuid,
261
+ dbtVersion: dbtVersionOption,
262
+ tableConfiguration: options.tableConfiguration,
263
+ copyContent: options.copyContent,
264
+ organizationWarehouseCredentialsUuid,
265
+ };
266
+ return (0, apiClient_1.lightdashApi)({
267
+ method: 'POST',
268
+ url: `/api/v1/org/projects`,
269
+ body: JSON.stringify(project),
270
+ });
271
+ };
272
+ exports.createProject = createProject;
@@ -0,0 +1,14 @@
1
+ import { ApiResponse, ProjectType, type LightdashUserWithAbilityRules } from '@lightdash/common';
2
+ import { BodyInit } from 'node-fetch';
3
+ type LightdashApiProps = {
4
+ method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT';
5
+ url: string;
6
+ body: BodyInit | undefined;
7
+ };
8
+ export declare const setGzipEnabled: (enabled: boolean) => void;
9
+ export declare const lightdashApi: <T extends ApiResponse["results"]>({ method, url, body, }: LightdashApiProps) => Promise<T>;
10
+ export declare const getUserContext: () => Promise<LightdashUserWithAbilityRules>;
11
+ export declare const checkProjectCreationPermission: (upstreamProjectUuid: string | undefined, projectType: ProjectType) => Promise<void>;
12
+ export declare const checkLightdashVersion: () => Promise<void>;
13
+ export {};
14
+ //# sourceMappingURL=apiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/apiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,WAAW,EAIX,WAAW,EACX,KAAK,6BAA6B,EAErC,MAAM,mBAAmB,CAAC;AAC3B,OAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS7C,KAAK,iBAAiB,GAAG;IACrB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC9B,CAAC;AAKF,eAAO,MAAM,cAAc,GAAI,SAAS,OAAO,SAE9C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,EAAE,wBAIlE,iBAAiB,KAAG,OAAO,CAAC,CAAC,CAqE/B,CAAC;AAEF,eAAO,MAAM,cAAc,QACb,OAAO,CAAC,6BAA6B,CAKzC,CAAC;AAEX,eAAO,MAAM,8BAA8B,GACvC,qBAAqB,MAAM,GAAG,SAAS,EACvC,aAAa,WAAW,KACzB,OAAO,CAAC,IAAI,CAkGd,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,IAAI,CAyB1D,CAAC"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkLightdashVersion = exports.checkProjectCreationPermission = exports.getUserContext = exports.lightdashApi = exports.setGzipEnabled = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const ability_1 = require("@casl/ability");
6
+ const common_1 = require("@lightdash/common");
7
+ const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
8
+ const url_1 = require("url");
9
+ const zlib_1 = require("zlib");
10
+ const config_1 = require("../../config");
11
+ const env_1 = require("../../env");
12
+ const globalState_1 = tslib_1.__importDefault(require("../../globalState"));
13
+ const styles = tslib_1.__importStar(require("../../styles"));
14
+ const utils_1 = require("../utils");
15
+ const MIN_GZIP_SIZE = 1024;
16
+ let gzipEnabled = false;
17
+ const setGzipEnabled = (enabled) => {
18
+ gzipEnabled = enabled;
19
+ };
20
+ exports.setGzipEnabled = setGzipEnabled;
21
+ const lightdashApi = async ({ method, url, body, }) => {
22
+ const config = await (0, config_1.getConfig)();
23
+ if (!(config.context?.apiKey && config.context.serverUrl)) {
24
+ throw new common_1.AuthorizationError(`Not logged in. Run 'clary login --help'`);
25
+ }
26
+ const headers = (0, utils_1.buildRequestHeaders)(config.context.apiKey);
27
+ const fullUrl = new url_1.URL(url, config.context.serverUrl).href;
28
+ globalState_1.default.debug(`> Making HTTP ${method} request to: ${fullUrl}`);
29
+ let requestBody = body;
30
+ if (gzipEnabled &&
31
+ body &&
32
+ typeof body === 'string' &&
33
+ Buffer.byteLength(body) > MIN_GZIP_SIZE) {
34
+ try {
35
+ const uncompressedSize = Buffer.byteLength(body);
36
+ const compressed = (0, zlib_1.gzipSync)(body);
37
+ globalState_1.default.debug(`> Compressed request body: ${uncompressedSize} bytes → ${compressed.byteLength} bytes (${Math.round((1 - compressed.byteLength / uncompressedSize) * 100)}% reduction)`);
38
+ requestBody = compressed;
39
+ headers['Content-Encoding'] = 'gzip';
40
+ }
41
+ catch (err) {
42
+ globalState_1.default.debug(`> Gzip compression failed, sending uncompressed: ${err}`);
43
+ }
44
+ }
45
+ return (0, node_fetch_1.default)(fullUrl, { method, headers, body: requestBody })
46
+ .then((r) => {
47
+ globalState_1.default.debug(`> HTTP request returned status: ${r.status}`);
48
+ if (!r.ok) {
49
+ const contentType = r.headers.get('content-type');
50
+ if (contentType && contentType.includes('application/json')) {
51
+ return r.json().then((d) => {
52
+ throw new common_1.LightdashError(d.error);
53
+ });
54
+ }
55
+ return r.text().then((text) => {
56
+ throw new Error(`Received non-JSON response from server (status ${r.status}): ${text}`);
57
+ });
58
+ }
59
+ return r;
60
+ })
61
+ .then((r) => r.json())
62
+ .then((d) => {
63
+ globalState_1.default.debug(`> HTTP request returned status: ${d.status}`);
64
+ switch (d.status) {
65
+ case 'ok':
66
+ return d.results;
67
+ case 'error':
68
+ throw new common_1.LightdashError(d.error);
69
+ default:
70
+ throw new Error(d);
71
+ }
72
+ })
73
+ .catch((err) => {
74
+ // ApiErrorResponse
75
+ throw err;
76
+ });
77
+ };
78
+ exports.lightdashApi = lightdashApi;
79
+ const getUserContext = async () => (0, exports.lightdashApi)({
80
+ method: 'GET',
81
+ url: `/api/v1/user`,
82
+ body: undefined,
83
+ });
84
+ exports.getUserContext = getUserContext;
85
+ const checkProjectCreationPermission = async (upstreamProjectUuid, projectType) => {
86
+ try {
87
+ const user = await (0, exports.getUserContext)();
88
+ // Build CASL ability from user's ability rules (same as backend)
89
+ const ability = new ability_1.Ability(user.abilityRules);
90
+ if (!user.organizationUuid) {
91
+ throw new common_1.ForbiddenError(`You don't have permission to create projects. Please ensure you're a member of an organization.`);
92
+ }
93
+ // Replicates logic from ProjectService.validateProjectCreationPermissions
94
+ switch (projectType) {
95
+ case common_1.ProjectType.DEFAULT:
96
+ if (ability.can('create', (0, ability_1.subject)('Project', {
97
+ organizationUuid: user.organizationUuid,
98
+ type: common_1.ProjectType.DEFAULT,
99
+ }))) {
100
+ return;
101
+ }
102
+ throw new common_1.ForbiddenError(`You don't have permission to create projects in this organization.\n` +
103
+ `This typically requires the 'admin' or 'developer' role.\n` +
104
+ `Contact your organization admin to request access.`);
105
+ case common_1.ProjectType.PREVIEW:
106
+ if (upstreamProjectUuid) {
107
+ if (
108
+ // checks if user has permission to access upstream project
109
+ ability.cannot('view', (0, ability_1.subject)('Project', {
110
+ organizationUuid: user.organizationUuid,
111
+ projectUuid: upstreamProjectUuid,
112
+ }))) {
113
+ throw new common_1.ForbiddenError(`Unable to create preview project: you don't have permission to access the upstream project.\n` +
114
+ `You need 'view' access to the project you're trying to preview from.\n` +
115
+ `Contact your admin to request access.`);
116
+ }
117
+ if (
118
+ // checks if user has permission to create project from an upstream project on a project level
119
+ ability.can('create', (0, ability_1.subject)('Project', {
120
+ upstreamProjectUuid,
121
+ type: common_1.ProjectType.PREVIEW,
122
+ }))) {
123
+ return;
124
+ }
125
+ }
126
+ if (
127
+ // checks if user has permission to create project on an organization level
128
+ ability.can('create', (0, ability_1.subject)('Project', {
129
+ organizationUuid: user.organizationUuid,
130
+ type: common_1.ProjectType.PREVIEW,
131
+ }))) {
132
+ return;
133
+ }
134
+ throw new common_1.ForbiddenError(`You don't have permission to create preview projects in this organization.\n` +
135
+ `This typically requires the 'developer' or 'admin' role.\n` +
136
+ `Contact your organization admin to request access.`);
137
+ default:
138
+ throw new Error(`Unknown project type: ${projectType}`);
139
+ }
140
+ }
141
+ catch (err) {
142
+ if (err instanceof common_1.ForbiddenError ||
143
+ err instanceof common_1.AuthorizationError) {
144
+ throw err;
145
+ }
146
+ globalState_1.default.debug(`Failed to check permissions: ${err}`);
147
+ // If we can't check permissions, we'll let the API call fail with proper error
148
+ }
149
+ };
150
+ exports.checkProjectCreationPermission = checkProjectCreationPermission;
151
+ const checkLightdashVersion = async () => {
152
+ try {
153
+ const health = await (0, exports.lightdashApi)({
154
+ method: 'GET',
155
+ url: `/api/v1/health`,
156
+ body: undefined,
157
+ });
158
+ if (health.version !== env_1.CLI_VERSION) {
159
+ const config = await (0, config_1.getConfig)();
160
+ console.error(`${styles.title('Warning')}: CLI (${env_1.CLI_VERSION}) is running a different version than Clary (${health.version}) on ${config.context?.serverUrl}.\n Some commands may fail, consider upgrading your CLI by ${styles.secondary((0, env_1.getUpdateInstructions)(health.version))}`);
161
+ }
162
+ }
163
+ catch (err) {
164
+ globalState_1.default.debug(`> Health check failed: ${err}`);
165
+ }
166
+ };
167
+ exports.checkLightdashVersion = checkLightdashVersion;
@@ -0,0 +1,35 @@
1
+ import { LoadManifestArgs } from '../../dbt/manifest';
2
+ export type DbtCompileOptions = {
3
+ profilesDir: string | undefined;
4
+ projectDir: string | undefined;
5
+ target: string | undefined;
6
+ profile: string | undefined;
7
+ select: string[] | undefined;
8
+ models: string[] | undefined;
9
+ vars: string | undefined;
10
+ threads: string | undefined;
11
+ noVersionCheck: boolean | undefined;
12
+ exclude: string[] | undefined;
13
+ selector: string | undefined;
14
+ state: string | undefined;
15
+ fullRefresh: boolean | undefined;
16
+ skipDbtCompile: boolean | undefined;
17
+ skipWarehouseCatalog: boolean | undefined;
18
+ useDbtList: boolean | undefined;
19
+ defer: boolean | undefined;
20
+ targetPath: string | undefined;
21
+ favorState: boolean | undefined;
22
+ };
23
+ export declare const dbtCompile: (options: DbtCompileOptions) => Promise<void>;
24
+ export declare function dbtList(options: DbtCompileOptions): Promise<string[]>;
25
+ export type CompileModelsResult = {
26
+ compiledModelIds: string[] | undefined;
27
+ /**
28
+ * The model IDs from the user's original selection (e.g. --select "tag:lightdash").
29
+ * When --defer is used, models NOT in this list were pulled in via joins
30
+ * and should use the production schema from the state manifest.
31
+ */
32
+ originallySelectedModelIds: string[] | undefined;
33
+ };
34
+ export declare function maybeCompileModelsAndJoins(loadManifestOpts: LoadManifestArgs, initialOptions: DbtCompileOptions): Promise<CompileModelsResult>;
35
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/compile.ts"],"names":[],"mappings":"AAYA,OAAO,EAAgB,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAIpE,MAAM,MAAM,iBAAiB,GAAG;IAC5B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,oBAAoB,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;CACnC,CAAC;AAwCF,eAAO,MAAM,UAAU,GAAU,SAAS,iBAAiB,kBAW1D,CAAC;AAsEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyC3E;AAED,MAAM,MAAM,mBAAmB,GAAG;IAC9B,gBAAgB,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACvC;;;;OAIG;IACH,0BAA0B,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACpD,CAAC;AAEF,wBAAsB,0BAA0B,CAC5C,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,iBAAiB,GAClC,OAAO,CAAC,mBAAmB,CAAC,CA0G9B"}