@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,122 @@
1
+ "use strict";
2
+ /**
3
+ * Loader for Lightdash YAML model files
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loadLightdashModel = loadLightdashModel;
7
+ exports.findLightdashModelFiles = findLightdashModelFiles;
8
+ exports.loadLightdashModels = loadLightdashModels;
9
+ const tslib_1 = require("tslib");
10
+ const common_1 = require("@lightdash/common");
11
+ const fs = tslib_1.__importStar(require("fs"));
12
+ const yaml = tslib_1.__importStar(require("js-yaml"));
13
+ const path = tslib_1.__importStar(require("path"));
14
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
15
+ /**
16
+ * Load a single Lightdash YAML model file
17
+ */
18
+ async function loadLightdashModel(filePath) {
19
+ try {
20
+ const fileContents = await fs.promises.readFile(filePath, 'utf8');
21
+ const parsed = yaml.load(fileContents);
22
+ // Basic validation
23
+ if (!parsed.type || !parsed.name || !parsed.dimensions) {
24
+ throw new common_1.ParseError(`Invalid Lightdash model in ${filePath}: must have type, name, and dimensions`);
25
+ }
26
+ if (!parsed.sql_from) {
27
+ throw new common_1.ParseError(`Invalid Lightdash model in ${filePath}: must have sql_from`);
28
+ }
29
+ return parsed;
30
+ }
31
+ catch (error) {
32
+ if (error instanceof common_1.ParseError) {
33
+ throw error;
34
+ }
35
+ throw new common_1.ParseError(`Failed to load Lightdash model from ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
36
+ }
37
+ }
38
+ /**
39
+ * Check if a YAML file contains a Lightdash model definition
40
+ * A valid model file must have a `type` field with value 'model', 'model/v1beta', or 'model/v1'
41
+ */
42
+ async function isLightdashModelFile(filePath) {
43
+ try {
44
+ const fileContents = await fs.promises.readFile(filePath, 'utf8');
45
+ const parsed = yaml.load(fileContents);
46
+ if (!parsed || typeof parsed !== 'object') {
47
+ return false;
48
+ }
49
+ // Check for valid model type values
50
+ const validModelTypes = ['model', 'model/v1beta', 'model/v1'];
51
+ return validModelTypes.includes(parsed.type ?? '');
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ /**
58
+ * Find all Lightdash YAML model files in a directory
59
+ * Looks for files in models/ or lightdash/models/ directory that contain `type: model`
60
+ *
61
+ * This explicitly checks the YAML content for `type: model` (or versioned variants)
62
+ * to avoid false positives from other YAML files (e.g., content-as-code spaces).
63
+ */
64
+ async function findLightdashModelFiles(projectDir) {
65
+ // Check both possible model locations: models/ (preferred) and lightdash/models/ (legacy)
66
+ const possibleDirs = [
67
+ path.join(projectDir, 'models'),
68
+ path.join(projectDir, 'lightdash', 'models'),
69
+ ];
70
+ const lightdashModelsDir = possibleDirs.find((dir) => fs.existsSync(dir));
71
+ if (!lightdashModelsDir) {
72
+ globalState_1.default.debug(`No models directory found at ${possibleDirs.join(' or ')}`);
73
+ return [];
74
+ }
75
+ globalState_1.default.debug(`Using models directory: ${lightdashModelsDir}`);
76
+ const yamlFiles = [];
77
+ async function walkDir(dir) {
78
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
79
+ for await (const entry of entries) {
80
+ const fullPath = path.join(dir, entry.name);
81
+ if (entry.isDirectory()) {
82
+ await walkDir(fullPath);
83
+ }
84
+ else if (entry.isFile() &&
85
+ (entry.name.endsWith('.yml') || entry.name.endsWith('.yaml'))) {
86
+ yamlFiles.push(fullPath);
87
+ }
88
+ }
89
+ }
90
+ await walkDir(lightdashModelsDir);
91
+ // Filter to only include files that actually contain `type: model`
92
+ const modelFiles = [];
93
+ for await (const filePath of yamlFiles) {
94
+ const isModel = await isLightdashModelFile(filePath);
95
+ if (isModel) {
96
+ modelFiles.push(filePath);
97
+ }
98
+ else {
99
+ globalState_1.default.debug(`Skipping ${filePath}: not a valid Lightdash model file (missing type: model)`);
100
+ }
101
+ }
102
+ return modelFiles;
103
+ }
104
+ /**
105
+ * Load all Lightdash YAML models from a project directory
106
+ */
107
+ async function loadLightdashModels(projectDir) {
108
+ const modelFiles = await findLightdashModelFiles(projectDir);
109
+ globalState_1.default.debug(`Found ${modelFiles.length} Lightdash model files in ${projectDir}`);
110
+ const models = [];
111
+ for await (const filePath of modelFiles) {
112
+ try {
113
+ const model = await loadLightdashModel(filePath);
114
+ models.push(model);
115
+ globalState_1.default.debug(`Loaded Lightdash model: ${model.name}`);
116
+ }
117
+ catch (error) {
118
+ console.error(`Warning: Failed to load ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
119
+ }
120
+ }
121
+ return models;
122
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Project type detection utilities
3
+ *
4
+ * Determines whether a project is:
5
+ * - A Lightdash YAML-only project (no dbt required)
6
+ * - A dbt project (requires dbt)
7
+ *
8
+ * Detection order:
9
+ * 1. If ANY Lightdash YAML models exist (with `type: model`) → YAML-only project
10
+ * 2. Otherwise → dbt project
11
+ *
12
+ * For YAML-only projects:
13
+ * - warehouseCredentials, skipDbtCompile, skipWarehouseCatalog are fixed
14
+ * - dbt is never checked (user may not have it installed)
15
+ *
16
+ * For dbt projects:
17
+ * - User controls warehouseCredentials, skipDbtCompile, skipWarehouseCatalog
18
+ */
19
+ /**
20
+ * Enum for project types to ensure type safety
21
+ */
22
+ export declare enum CliProjectType {
23
+ LightdashYaml = "lightdash-yaml",
24
+ Dbt = "dbt"
25
+ }
26
+ export type LightdashYamlProjectConfig = {
27
+ type: CliProjectType.LightdashYaml;
28
+ /**
29
+ * YAML-only projects don't load warehouse credentials from dbt profiles
30
+ */
31
+ warehouseCredentials: false;
32
+ /**
33
+ * YAML-only projects skip dbt compilation
34
+ */
35
+ skipDbtCompile: true;
36
+ /**
37
+ * YAML-only projects skip warehouse catalog (types are in YAML)
38
+ */
39
+ skipWarehouseCatalog: true;
40
+ };
41
+ export type DbtProjectConfig = {
42
+ type: CliProjectType.Dbt;
43
+ /**
44
+ * User-controlled: whether to load warehouse credentials from dbt profiles
45
+ */
46
+ warehouseCredentials: boolean | undefined;
47
+ /**
48
+ * User-controlled: whether to skip dbt compilation
49
+ */
50
+ skipDbtCompile: boolean | undefined;
51
+ /**
52
+ * User-controlled: whether to skip warehouse catalog fetch
53
+ */
54
+ skipWarehouseCatalog: boolean | undefined;
55
+ };
56
+ export type ProjectTypeConfig = LightdashYamlProjectConfig | DbtProjectConfig;
57
+ export declare function isLightdashYamlProject(config: ProjectTypeConfig): config is LightdashYamlProjectConfig;
58
+ export declare function isDbtProject(config: ProjectTypeConfig): config is DbtProjectConfig;
59
+ type DetectProjectTypeOptions = {
60
+ /**
61
+ * Path to the project directory
62
+ */
63
+ projectDir: string;
64
+ /**
65
+ * User-specified options (only used for dbt projects)
66
+ */
67
+ userOptions?: {
68
+ warehouseCredentials?: boolean;
69
+ skipDbtCompile?: boolean;
70
+ skipWarehouseCatalog?: boolean;
71
+ };
72
+ };
73
+ /**
74
+ * Detect project type based on project contents
75
+ *
76
+ * Detection is based on YAML files containing `type: model` (or versioned variants).
77
+ * This ensures we don't get false positives from other YAML files like content-as-code spaces.
78
+ *
79
+ * If ANY Lightdash YAML models exist → YAML-only project (dbt options ignored)
80
+ * Otherwise → dbt project (user controls dbt options)
81
+ */
82
+ export declare function detectProjectType(options: DetectProjectTypeOptions): Promise<ProjectTypeConfig>;
83
+ export {};
84
+ //# sourceMappingURL=projectType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectType.d.ts","sourceRoot":"","sources":["../../src/lightdash/projectType.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH;;GAEG;AACH,oBAAY,cAAc;IACtB,aAAa,mBAAmB;IAChC,GAAG,QAAQ;CACd;AAED,MAAM,MAAM,0BAA0B,GAAG;IACrC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC;IACnC;;OAEG;IACH,oBAAoB,EAAE,KAAK,CAAC;IAC5B;;OAEG;IACH,cAAc,EAAE,IAAI,CAAC;IACrB;;OAEG;IACH,oBAAoB,EAAE,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,cAAc,CAAC,GAAG,CAAC;IACzB;;OAEG;IACH,oBAAoB,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C;;OAEG;IACH,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC;;OAEG;IACH,oBAAoB,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,0BAA0B,GAAG,gBAAgB,CAAC;AAE9E,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,iBAAiB,GAC1B,MAAM,IAAI,0BAA0B,CAEtC;AAED,wBAAgB,YAAY,CACxB,MAAM,EAAE,iBAAiB,GAC1B,MAAM,IAAI,gBAAgB,CAE5B;AAED,KAAK,wBAAwB,GAAG;IAC5B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,WAAW,CAAC,EAAE;QACV,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAClC,CAAC;CACL,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,wBAAwB,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAiC5B"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ /**
3
+ * Project type detection utilities
4
+ *
5
+ * Determines whether a project is:
6
+ * - A Lightdash YAML-only project (no dbt required)
7
+ * - A dbt project (requires dbt)
8
+ *
9
+ * Detection order:
10
+ * 1. If ANY Lightdash YAML models exist (with `type: model`) → YAML-only project
11
+ * 2. Otherwise → dbt project
12
+ *
13
+ * For YAML-only projects:
14
+ * - warehouseCredentials, skipDbtCompile, skipWarehouseCatalog are fixed
15
+ * - dbt is never checked (user may not have it installed)
16
+ *
17
+ * For dbt projects:
18
+ * - User controls warehouseCredentials, skipDbtCompile, skipWarehouseCatalog
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.CliProjectType = void 0;
22
+ exports.isLightdashYamlProject = isLightdashYamlProject;
23
+ exports.isDbtProject = isDbtProject;
24
+ exports.detectProjectType = detectProjectType;
25
+ const tslib_1 = require("tslib");
26
+ const path_1 = tslib_1.__importDefault(require("path"));
27
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
28
+ const loader_1 = require("./loader");
29
+ /**
30
+ * Enum for project types to ensure type safety
31
+ */
32
+ var CliProjectType;
33
+ (function (CliProjectType) {
34
+ CliProjectType["LightdashYaml"] = "lightdash-yaml";
35
+ CliProjectType["Dbt"] = "dbt";
36
+ })(CliProjectType || (exports.CliProjectType = CliProjectType = {}));
37
+ function isLightdashYamlProject(config) {
38
+ return config.type === CliProjectType.LightdashYaml;
39
+ }
40
+ function isDbtProject(config) {
41
+ return config.type === CliProjectType.Dbt;
42
+ }
43
+ /**
44
+ * Detect project type based on project contents
45
+ *
46
+ * Detection is based on YAML files containing `type: model` (or versioned variants).
47
+ * This ensures we don't get false positives from other YAML files like content-as-code spaces.
48
+ *
49
+ * If ANY Lightdash YAML models exist → YAML-only project (dbt options ignored)
50
+ * Otherwise → dbt project (user controls dbt options)
51
+ */
52
+ async function detectProjectType(options) {
53
+ const absoluteProjectPath = path_1.default.resolve(options.projectDir);
54
+ // Check for Lightdash YAML models (files with `type: model`)
55
+ const yamlModelFiles = await (0, loader_1.findLightdashModelFiles)(absoluteProjectPath);
56
+ if (yamlModelFiles.length > 0) {
57
+ globalState_1.default.debug(`> Found ${yamlModelFiles.length} Lightdash YAML model(s), using YAML-only project mode`);
58
+ return {
59
+ type: CliProjectType.LightdashYaml,
60
+ warehouseCredentials: false,
61
+ skipDbtCompile: true,
62
+ skipWarehouseCatalog: true,
63
+ };
64
+ }
65
+ // No YAML models found → dbt project
66
+ globalState_1.default.debug('> No Lightdash YAML models found, using dbt project mode');
67
+ // For dbt projects, --no-warehouse-credentials implies skip dbt compile and warehouse catalog
68
+ const noCredentials = options.userOptions?.warehouseCredentials === false;
69
+ return {
70
+ type: CliProjectType.Dbt,
71
+ warehouseCredentials: options.userOptions?.warehouseCredentials,
72
+ skipDbtCompile: noCredentials || options.userOptions?.skipDbtCompile,
73
+ skipWarehouseCatalog: noCredentials || options.userOptions?.skipWarehouseCatalog,
74
+ };
75
+ }
@@ -0,0 +1,2 @@
1
+ export declare const readAndLoadLightdashProjectConfig: (projectDir: string, projectUuid?: string) => Promise<import("@lightdash/common").LightdashProjectConfig>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lightdash-config/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iCAAiC,GAC1C,YAAY,MAAM,EAClB,cAAc,MAAM,gEAsCvB,CAAC"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readAndLoadLightdashProjectConfig = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@lightdash/common");
6
+ const promises_1 = tslib_1.__importDefault(require("fs/promises"));
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const analytics_1 = require("../analytics/analytics");
9
+ const config_1 = require("../config");
10
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
11
+ const readAndLoadLightdashProjectConfig = async (projectDir, projectUuid) => {
12
+ const { user, context } = await (0, config_1.getConfig)();
13
+ const configPath = path_1.default.join(projectDir, 'lightdash.config.yml');
14
+ try {
15
+ const fileContents = await promises_1.default.readFile(configPath, 'utf8');
16
+ const config = await (0, common_1.loadLightdashProjectConfig)(fileContents, async (lightdashConfig) => {
17
+ void analytics_1.LightdashAnalytics.track({
18
+ event: 'lightdashconfig.loaded',
19
+ properties: {
20
+ projectId: projectUuid ?? context?.project ?? '',
21
+ userId: user?.userUuid,
22
+ organizationId: user?.organizationUuid,
23
+ categories_count: Number(Object.keys(lightdashConfig.spotlight.categories ?? {}).length),
24
+ default_visibility: lightdashConfig.spotlight.default_visibility,
25
+ },
26
+ });
27
+ });
28
+ return config;
29
+ }
30
+ catch (e) {
31
+ globalState_1.default.debug(`No lightdash.config.yml found in ${configPath}`);
32
+ if (e instanceof Error && 'code' in e && e.code === 'ENOENT') {
33
+ // Return default config if file doesn't exist
34
+ return {
35
+ spotlight: common_1.DEFAULT_SPOTLIGHT_CONFIG,
36
+ };
37
+ }
38
+ throw e;
39
+ }
40
+ };
41
+ exports.readAndLoadLightdashProjectConfig = readAndLoadLightdashProjectConfig;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lightdash-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightdash-config.test.d.ts","sourceRoot":"","sources":["../../src/lightdash-config/lightdash-config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const common_1 = require("@lightdash/common");
5
+ const promises_1 = tslib_1.__importDefault(require("fs/promises"));
6
+ const _1 = require(".");
7
+ const VALID_CONFIG_CONTENTS = 'spotlight:\n' +
8
+ ' default_visibility: show # Optional, defaults to "show"\n' +
9
+ ' categories:\n' +
10
+ ' core:\n' +
11
+ ' label: "Core Metrics"\n' +
12
+ ' color: blue\n' +
13
+ ' experimental:\n' +
14
+ ' label: "Experimental Metrics"\n' +
15
+ ' color: orange\n' +
16
+ ' sales:\n' +
17
+ ' label: "Sales"\n' +
18
+ ' color: green\n';
19
+ const VALID_CONFIG = {
20
+ spotlight: {
21
+ default_visibility: 'show',
22
+ categories: {
23
+ core: { label: 'Core Metrics', color: 'blue' },
24
+ experimental: { label: 'Experimental Metrics', color: 'orange' },
25
+ sales: { label: 'Sales', color: 'green' },
26
+ },
27
+ },
28
+ };
29
+ const INVALID_CONFIG_CONTENTS = 'spotlight:\n default_visibility: invalid_value';
30
+ const readFileSpy = jest.spyOn(promises_1.default, 'readFile');
31
+ // Mock getConfig
32
+ jest.mock('../config', () => ({
33
+ getConfig: jest.fn().mockResolvedValue({ user: null, context: null }),
34
+ }));
35
+ describe('Existing lightdash.config.yml file', () => {
36
+ describe('when valid', () => {
37
+ it('should load the config file', async () => {
38
+ readFileSpy.mockResolvedValueOnce(VALID_CONFIG_CONTENTS);
39
+ const config = await (0, _1.readAndLoadLightdashProjectConfig)('');
40
+ expect(config).toEqual(VALID_CONFIG);
41
+ });
42
+ });
43
+ describe('when invalid', () => {
44
+ it('should throw an error', async () => {
45
+ readFileSpy.mockResolvedValueOnce(INVALID_CONFIG_CONTENTS);
46
+ await expect((0, _1.readAndLoadLightdashProjectConfig)('')).rejects.toThrow(/Invalid lightdash.config.yml with errors/);
47
+ });
48
+ });
49
+ });
50
+ class MockedFSError extends Error {
51
+ code;
52
+ constructor(message, code) {
53
+ super(message);
54
+ this.code = code;
55
+ }
56
+ }
57
+ describe('Missing lightdash.config.yml file', () => {
58
+ it('should load the default config', async () => {
59
+ // ! Throwing a mock error, not something we should rely on but when running the test in jest `e instanceof Error` is false, but when running the code in node it is true
60
+ // ! Check: https://github.com/jestjs/jest/issues/11808
61
+ readFileSpy.mockRejectedValueOnce(new MockedFSError('file not found', 'ENOENT'));
62
+ const config = await (0, _1.readAndLoadLightdashProjectConfig)('./some/path/to/nonexisting/file');
63
+ expect(config).toEqual({
64
+ spotlight: common_1.DEFAULT_SPOTLIGHT_CONFIG,
65
+ });
66
+ });
67
+ });
68
+ afterAll(() => {
69
+ jest.restoreAllMocks();
70
+ });
@@ -0,0 +1,10 @@
1
+ import chalk from 'chalk';
2
+ export declare const error: chalk.Chalk;
3
+ export declare const title: chalk.Chalk;
4
+ export declare const info: (s: string) => string;
5
+ export declare const bold: chalk.Chalk;
6
+ export declare const secondary: chalk.Chalk;
7
+ export declare const success: chalk.Chalk;
8
+ export declare const warning: chalk.Chalk;
9
+ export declare const debug: chalk.Chalk;
10
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,KAAK,aAAY,CAAC;AAC/B,eAAO,MAAM,KAAK,aAA0B,CAAC;AAC7C,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,WAAM,CAAC;AACrC,eAAO,MAAQ,IAAI,aAAU,CAAC;AAC9B,eAAO,MAAM,SAAS,aAAY,CAAC;AACnC,eAAO,MAAM,OAAO,aAAmB,CAAC;AACxC,eAAO,MAAM,OAAO,aAAe,CAAC;AACpC,eAAO,MAAM,KAAK,aAAa,CAAC"}
package/dist/styles.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.debug = exports.warning = exports.success = exports.secondary = exports.bold = exports.info = exports.title = exports.error = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
+ exports.error = chalk_1.default.red;
7
+ exports.title = chalk_1.default.bold.yellowBright;
8
+ const info = (s) => s;
9
+ exports.info = info;
10
+ exports.bold = chalk_1.default.bold;
11
+ exports.secondary = chalk_1.default.dim;
12
+ exports.success = chalk_1.default.bold.green;
13
+ exports.warning = chalk_1.default.yellow;
14
+ exports.debug = chalk_1.default.grey;
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <!-- Allow JIT compilation for V8 JavaScript engine -->
6
+ <key>com.apple.security.cs.allow-jit</key>
7
+ <true/>
8
+
9
+ <!-- Allow unsigned executable memory for V8 -->
10
+ <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
11
+ <true/>
12
+
13
+ <!-- Allow DYLD environment variables -->
14
+ <key>com.apple.security.cs.allow-dyld-environment-variables</key>
15
+ <true/>
16
+
17
+ <!-- Disable library validation to allow loading of unsigned libraries -->
18
+ <key>com.apple.security.cs.disable-library-validation</key>
19
+ <true/>
20
+
21
+ <!-- Disable executable memory protection -->
22
+ <key>com.apple.security.cs.disable-executable-page-protection</key>
23
+ <true/>
24
+
25
+ <!-- Network client for API calls -->
26
+ <key>com.apple.security.network.client</key>
27
+ <true/>
28
+
29
+ <!-- File system access for dbt projects -->
30
+ <key>com.apple.security.files.user-selected.read-write</key>
31
+ <true/>
32
+ </dict>
33
+ </plist>
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@claryai/cli",
3
+ "version": "0.1.0",
4
+ "description": "Clary CLI tool",
5
+ "bin": {
6
+ "clary": "dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist/**/*",
10
+ "track.sh",
11
+ "entitlements.plist"
12
+ ],
13
+ "dependencies": {
14
+ "@actions/core": "1.11.1",
15
+ "@casl/ability": "6.8.0",
16
+ "@types/columnify": "1.5.1",
17
+ "ajv": "8.18.0",
18
+ "ajv-formats": "2.1.1",
19
+ "better-ajv-errors": "1.2.0",
20
+ "chalk": "4.1.2",
21
+ "chokidar": "3.6.0",
22
+ "columnify": "1.6.0",
23
+ "commander": "9.5.0",
24
+ "execa": "5.1.1",
25
+ "google-auth-library": "9.15.1",
26
+ "inquirer": "8.2.4",
27
+ "js-yaml": "4.1.1",
28
+ "lodash": "4.17.23",
29
+ "node-fetch": "2.7.0",
30
+ "nunjucks": "3.2.3",
31
+ "openid-client": "5.6.4",
32
+ "ora": "5.4.1",
33
+ "p-limit": "3.1.0",
34
+ "parse-node-version": "2.0.0",
35
+ "unique-names-generator": "4.7.1",
36
+ "uuid": "11.0.3",
37
+ "yaml": "2.7.0",
38
+ "@lightdash/common": "0.2712.0",
39
+ "@lightdash/warehouses": "0.2712.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/inquirer": "8.2.4",
43
+ "@types/js-yaml": "4.0.9",
44
+ "@types/lodash": "4.14.202",
45
+ "@types/node-fetch": "2.6.13",
46
+ "@types/nunjucks": "3.2.1",
47
+ "@types/parse-node-version": "1.0.0",
48
+ "@types/uuid": "10.0.0",
49
+ "@vercel/ncc": "0.38.4",
50
+ "@yao-pkg/pkg": "6.7.0",
51
+ "ts-node": "10.9.2",
52
+ "typescript": "6.0.0-beta"
53
+ },
54
+ "scripts": {
55
+ "test": "jest",
56
+ "dev": "ts-node src/index.ts",
57
+ "build": "tsc --build tsconfig.json",
58
+ "bundle": "ncc build dist/index.js -o bundle -e @duckdb/node-api -e @duckdb/node-bindings -e @duckdb/node-bindings-darwin-arm64 -e @duckdb/node-bindings-darwin-x64 -e @duckdb/node-bindings-linux-arm64 -e @duckdb/node-bindings-linux-x64 -e @duckdb/node-bindings-win32-x64 && bash ./scripts/copy-bundle-assets.sh",
59
+ "build:binary": "DUCKDB_BINDINGS=node-bindings-darwin-x64,node-bindings-darwin-arm64 pnpm bundle && npx @yao-pkg/pkg bundle/index.js --config pkg.config.json --targets node20-macos-x64,node20-macos-arm64 --output bin/clary --compress Brotli",
60
+ "typecheck": "tsc --project tsconfig.json --noEmit",
61
+ "linter": "eslint -c .eslintrc.js --ignore-path ./../../.gitignore",
62
+ "formatter": "oxfmt",
63
+ "lint": "pnpm run linter ./src",
64
+ "fix-lint": "pnpm run linter ./src --fix",
65
+ "format": "oxfmt ./src --check",
66
+ "fix-format": "oxfmt ./src",
67
+ "preinstall": "bash track.sh started || echo 'skipping preinstall'",
68
+ "postinstall": "bash track.sh completed || echo 'skipping postinstall'",
69
+ "release": "pnpm publish --no-git-checks --access public"
70
+ }
71
+ }
package/track.sh ADDED
@@ -0,0 +1,116 @@
1
+ #!/bin/bash
2
+ # Send anonymous tracking events to rudderstack so we can monitor installations and errors
3
+
4
+ INSTALLATION_ID=$(curl -s 'https://www.uuidgenerator.net/api/version4')
5
+
6
+ os=""
7
+
8
+ is_mac() {
9
+ [[ $OSTYPE == darwin* ]]
10
+ }
11
+
12
+ is_windows() {
13
+ [[ $OSTYPE == msys* ]]
14
+ }
15
+
16
+ check_os() {
17
+ if is_mac; then
18
+ os="Mac"
19
+ return
20
+ fi
21
+
22
+ if is_windows; then
23
+ os="Windows"
24
+ return
25
+ fi
26
+
27
+ os_name="$(cat /etc/*-release | awk -F= '$1 == "NAME" { gsub(/"/, ""); print $2; exit }')"
28
+
29
+ case "$os_name" in
30
+ Ubuntu*)
31
+ os="ubuntu"
32
+ ;;
33
+ Amazon\ Linux*)
34
+ os="amazon linux"
35
+ ;;
36
+ Debian*)
37
+ os="debian"
38
+ ;;
39
+ Linux\ Mint*)
40
+ os="linux mint"
41
+ ;;
42
+ Red\ Hat*)
43
+ os="red hat"
44
+ ;;
45
+ CentOS*)
46
+ os="centos"
47
+ ;;
48
+ SLES*)
49
+ os="sles"
50
+ ;;
51
+ openSUSE*)
52
+ os="opensuse"
53
+ ;;
54
+ *)
55
+ os="Not Found: $os_name"
56
+ esac
57
+ }
58
+
59
+ # Check whether the given command exists.
60
+ has_cmd() {
61
+ command -v "$1" > /dev/null 2>&1
62
+ }
63
+ # Check whether 'wget' command exists.
64
+ has_wget() {
65
+ has_cmd wget
66
+ }
67
+
68
+ # Check whether 'curl' command exists.
69
+ has_curl() {
70
+ has_cmd curl
71
+ }
72
+
73
+ inform_macos_xcrun_requirement() {
74
+ # Check if xcrun is installed
75
+ if ! command -v xcrun >/dev/null 2>&1; then
76
+ echo "⚠️ macOS users: Before installing the Clary CLI, make sure you have 'xcrun' installed."
77
+ echo " You can install it by running the following command:"
78
+ echo " xcode-select --install"
79
+ echo " After installing 'xcrun', you can proceed with the Clary CLI installation."
80
+ echo ""
81
+ fi
82
+ }
83
+
84
+ if [[ $NODE_ENV == "development" || "$CI" == "true" ]]; then
85
+ echo "Do not send tracking on NODE_ENV=$NODE_ENV or CI=$CI mode"
86
+ exit 0
87
+ fi
88
+
89
+ if is_mac; then
90
+ inform_macos_xcrun_requirement
91
+ fi
92
+
93
+ track() {
94
+
95
+ check_os
96
+
97
+ DATA='{
98
+ "anonymousId":"'"$INSTALLATION_ID"'",
99
+ "event": "lightdash_cli.install.'"$1"'",
100
+ "properties": { "os": "'"$os"'"}
101
+ }'
102
+ echo $DATA
103
+ URL="https://analytics.getclary.com/v1/track"
104
+ HEADER='Content-Type: application/json'
105
+ HEADER_AUTH='Authorization: Basic MXZxa1NsV01WdFlPbDcwcmszUVNFMHYxZnFZOg=='
106
+
107
+ if has_curl; then
108
+ curl -sfL -d "$DATA" --header "$HEADER" --header "$HEADER_AUTH" "$URL" > /dev/null 2>&1
109
+ elif has_wget; then
110
+ wget -q --post-data="$DATA" --header="$HEADER" --header "$HEADER_AUTH" "$URL" > /dev/null 2>&1
111
+ fi
112
+ }
113
+
114
+ track $1
115
+
116
+ exit 0