@datachonk/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 (86) hide show
  1. package/README.md +200 -0
  2. package/dist/__tests__/cache.test.d.ts +2 -0
  3. package/dist/__tests__/cache.test.d.ts.map +1 -0
  4. package/dist/__tests__/cache.test.js +40 -0
  5. package/dist/__tests__/cache.test.js.map +1 -0
  6. package/dist/__tests__/config.test.d.ts +2 -0
  7. package/dist/__tests__/config.test.d.ts.map +1 -0
  8. package/dist/__tests__/config.test.js +113 -0
  9. package/dist/__tests__/config.test.js.map +1 -0
  10. package/dist/__tests__/templates.test.d.ts +2 -0
  11. package/dist/__tests__/templates.test.d.ts.map +1 -0
  12. package/dist/__tests__/templates.test.js +51 -0
  13. package/dist/__tests__/templates.test.js.map +1 -0
  14. package/dist/commands/analyze.d.ts +10 -0
  15. package/dist/commands/analyze.d.ts.map +1 -0
  16. package/dist/commands/analyze.js +156 -0
  17. package/dist/commands/analyze.js.map +1 -0
  18. package/dist/commands/chat.d.ts +3 -0
  19. package/dist/commands/chat.d.ts.map +1 -0
  20. package/dist/commands/chat.js +121 -0
  21. package/dist/commands/chat.js.map +1 -0
  22. package/dist/commands/config.d.ts +2 -0
  23. package/dist/commands/config.d.ts.map +1 -0
  24. package/dist/commands/config.js +287 -0
  25. package/dist/commands/config.js.map +1 -0
  26. package/dist/commands/docs.d.ts +7 -0
  27. package/dist/commands/docs.d.ts.map +1 -0
  28. package/dist/commands/docs.js +208 -0
  29. package/dist/commands/docs.js.map +1 -0
  30. package/dist/commands/generate.d.ts +9 -0
  31. package/dist/commands/generate.d.ts.map +1 -0
  32. package/dist/commands/generate.js +130 -0
  33. package/dist/commands/generate.js.map +1 -0
  34. package/dist/commands/init.d.ts +7 -0
  35. package/dist/commands/init.d.ts.map +1 -0
  36. package/dist/commands/init.js +149 -0
  37. package/dist/commands/init.js.map +1 -0
  38. package/dist/commands/lineage.d.ts +9 -0
  39. package/dist/commands/lineage.d.ts.map +1 -0
  40. package/dist/commands/lineage.js +186 -0
  41. package/dist/commands/lineage.js.map +1 -0
  42. package/dist/commands/migrate.d.ts +3 -0
  43. package/dist/commands/migrate.d.ts.map +1 -0
  44. package/dist/commands/migrate.js +213 -0
  45. package/dist/commands/migrate.js.map +1 -0
  46. package/dist/commands/review.d.ts +8 -0
  47. package/dist/commands/review.d.ts.map +1 -0
  48. package/dist/commands/review.js +215 -0
  49. package/dist/commands/review.js.map +1 -0
  50. package/dist/commands/scan.d.ts +18 -0
  51. package/dist/commands/scan.d.ts.map +1 -0
  52. package/dist/commands/scan.js +335 -0
  53. package/dist/commands/scan.js.map +1 -0
  54. package/dist/commands/test.d.ts +3 -0
  55. package/dist/commands/test.d.ts.map +1 -0
  56. package/dist/commands/test.js +244 -0
  57. package/dist/commands/test.js.map +1 -0
  58. package/dist/index.d.ts +3 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +232 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/utils/analyzer.d.ts +39 -0
  63. package/dist/utils/analyzer.d.ts.map +1 -0
  64. package/dist/utils/analyzer.js +310 -0
  65. package/dist/utils/analyzer.js.map +1 -0
  66. package/dist/utils/cache.d.ts +98 -0
  67. package/dist/utils/cache.d.ts.map +1 -0
  68. package/dist/utils/cache.js +253 -0
  69. package/dist/utils/cache.js.map +1 -0
  70. package/dist/utils/config.d.ts +56 -0
  71. package/dist/utils/config.d.ts.map +1 -0
  72. package/dist/utils/config.js +108 -0
  73. package/dist/utils/config.js.map +1 -0
  74. package/dist/utils/generators.d.ts +8 -0
  75. package/dist/utils/generators.d.ts.map +1 -0
  76. package/dist/utils/generators.js +265 -0
  77. package/dist/utils/generators.js.map +1 -0
  78. package/dist/utils/plugins.d.ts +94 -0
  79. package/dist/utils/plugins.d.ts.map +1 -0
  80. package/dist/utils/plugins.js +164 -0
  81. package/dist/utils/plugins.js.map +1 -0
  82. package/dist/utils/templates.d.ts +57 -0
  83. package/dist/utils/templates.d.ts.map +1 -0
  84. package/dist/utils/templates.js +458 -0
  85. package/dist/utils/templates.js.map +1 -0
  86. package/package.json +69 -0
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # @datachonk/cli
2
+
3
+ AI-powered dbt expert CLI - analyze, generate, and optimize your dbt projects.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @datachonk/cli
9
+ # or
10
+ npx @datachonk/cli
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ # Initialize DataChonk in your dbt project
17
+ cd your-dbt-project
18
+ datachonk init
19
+
20
+ # Analyze your project for issues
21
+ datachonk analyze
22
+
23
+ # Generate a new staging model
24
+ datachonk generate staging --name customers --source raw.stripe.customers
25
+
26
+ # Review code before committing
27
+ datachonk review
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ ### `datachonk init`
33
+
34
+ Initialize DataChonk in your dbt project. Creates a `.datachonk.yml` configuration file.
35
+
36
+ ```bash
37
+ datachonk init
38
+ datachonk init --warehouse snowflake
39
+ ```
40
+
41
+ ### `datachonk analyze`
42
+
43
+ Analyze your dbt project for anti-patterns, issues, and optimization opportunities.
44
+
45
+ ```bash
46
+ datachonk analyze # Analyze entire project
47
+ datachonk analyze --model stg_users # Analyze specific model
48
+ datachonk analyze --fix # Auto-fix issues where possible
49
+ datachonk analyze --json # Output as JSON
50
+ datachonk analyze --verbose # Show all details
51
+ ```
52
+
53
+ ### `datachonk generate`
54
+
55
+ Generate dbt models, tests, and documentation.
56
+
57
+ ```bash
58
+ datachonk generate staging --name customers --source raw.stripe.customers
59
+ datachonk generate intermediate --name customer_orders --source stg_orders
60
+ datachonk generate mart --name customer_360 --source int_customer_orders
61
+ datachonk generate dim --name customers --source int_customers
62
+ datachonk generate fct --name orders --source int_orders
63
+ datachonk generate snapshot --name customers --source raw.crm.customers
64
+ datachonk generate source --name stripe --source raw.stripe
65
+ datachonk generate test --name validate_orders --source fct_orders
66
+ datachonk generate docs --name fct_orders
67
+ ```
68
+
69
+ Options:
70
+ - `--name, -n`: Name for the generated model
71
+ - `--source, -s`: Source table or model
72
+ - `--output, -o`: Custom output path
73
+ - `--dry-run`: Preview without writing files
74
+
75
+ ### `datachonk review`
76
+
77
+ Get AI-powered code review of your dbt models.
78
+
79
+ ```bash
80
+ datachonk review # Review staged git changes
81
+ datachonk review models/staging/*.sql # Review specific files
82
+ datachonk review --strict # Enable strict mode
83
+ datachonk review --json # Output as JSON
84
+ ```
85
+
86
+ ### `datachonk lineage`
87
+
88
+ Analyze and visualize model lineage.
89
+
90
+ ```bash
91
+ datachonk lineage # Show project overview
92
+ datachonk lineage fct_orders # Show lineage for specific model
93
+ datachonk lineage fct_orders --upstream # Show only upstream
94
+ datachonk lineage fct_orders --downstream # Show only downstream
95
+ datachonk lineage fct_orders --depth 5 # Limit depth
96
+ datachonk lineage --json # Output as JSON
97
+ ```
98
+
99
+ ### `datachonk docs`
100
+
101
+ Generate or enhance dbt documentation.
102
+
103
+ ```bash
104
+ datachonk docs # Document all models
105
+ datachonk docs stg_customers # Document specific model
106
+ datachonk docs --missing-only # Only document undocumented models
107
+ datachonk docs --enhance # Use AI to improve descriptions
108
+ ```
109
+
110
+ ### `datachonk config`
111
+
112
+ Manage DataChonk configuration.
113
+
114
+ ```bash
115
+ datachonk config list # Show all configuration
116
+ datachonk config get warehouse # Get specific value
117
+ datachonk config set warehouse bigquery # Set value
118
+ datachonk config reset # Reset to defaults
119
+ ```
120
+
121
+ ## Configuration
122
+
123
+ DataChonk stores configuration in `.datachonk.yml`:
124
+
125
+ ```yaml
126
+ version: 1
127
+ warehouse: snowflake
128
+ modeling:
129
+ approach: kimball
130
+ conventions:
131
+ - stg_prefix
132
+ - int_prefix
133
+ - fct_prefix
134
+ - dim_prefix
135
+ - snake_case
136
+ ai:
137
+ enabled: true
138
+ apiKey: your-api-key
139
+ analysis:
140
+ ignorePaths:
141
+ - target/**
142
+ - dbt_packages/**
143
+ ignoreRules: []
144
+ generation:
145
+ defaultMaterialization: view
146
+ addDescriptions: true
147
+ addTests: true
148
+ ```
149
+
150
+ ## CI/CD Integration
151
+
152
+ ### GitHub Actions
153
+
154
+ ```yaml
155
+ name: dbt CI
156
+
157
+ on: [pull_request]
158
+
159
+ jobs:
160
+ lint:
161
+ runs-on: ubuntu-latest
162
+ steps:
163
+ - uses: actions/checkout@v3
164
+ - uses: actions/setup-node@v3
165
+ with:
166
+ node-version: '18'
167
+ - run: npm install -g datachonk
168
+ - run: datachonk analyze --json > analysis.json
169
+ - run: datachonk review --strict
170
+ ```
171
+
172
+ ### Pre-commit Hook
173
+
174
+ Add to `.pre-commit-config.yaml`:
175
+
176
+ ```yaml
177
+ repos:
178
+ - repo: local
179
+ hooks:
180
+ - id: datachonk-lint
181
+ name: DataChonk Lint
182
+ entry: datachonk analyze
183
+ language: system
184
+ types: [sql]
185
+ pass_filenames: false
186
+ ```
187
+
188
+ ## Exit Codes
189
+
190
+ - `0`: Success / No critical issues
191
+ - `1`: Critical issues found / Command failed
192
+
193
+ ## Environment Variables
194
+
195
+ - `DATACHONK_API_KEY`: API key for AI features (alternative to config file)
196
+ - `DATACHONK_API_URL`: Custom API URL (default: https://datachonk.dev)
197
+
198
+ ## License
199
+
200
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/cache.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { existsSync, mkdirSync, rmSync } from "fs";
3
+ import { join } from "path";
4
+ // Mock the cache module with test directory
5
+ const TEST_CACHE_DIR = join(process.cwd(), ".test-cache");
6
+ describe("Cache Utils", () => {
7
+ beforeEach(() => {
8
+ if (!existsSync(TEST_CACHE_DIR)) {
9
+ mkdirSync(TEST_CACHE_DIR, { recursive: true });
10
+ }
11
+ });
12
+ afterEach(() => {
13
+ if (existsSync(TEST_CACHE_DIR)) {
14
+ rmSync(TEST_CACHE_DIR, { recursive: true, force: true });
15
+ }
16
+ });
17
+ describe("cache operations", () => {
18
+ it("should handle cache directory creation", () => {
19
+ expect(existsSync(TEST_CACHE_DIR)).toBe(true);
20
+ });
21
+ it("should handle missing cache gracefully", () => {
22
+ // Cache operations should not throw when cache doesn't exist
23
+ rmSync(TEST_CACHE_DIR, { recursive: true, force: true });
24
+ expect(existsSync(TEST_CACHE_DIR)).toBe(false);
25
+ });
26
+ });
27
+ describe("cache key generation", () => {
28
+ it("generates consistent keys for same input", () => {
29
+ const input1 = JSON.stringify({ query: "test", version: 1 });
30
+ const input2 = JSON.stringify({ query: "test", version: 1 });
31
+ expect(input1).toBe(input2);
32
+ });
33
+ it("generates different keys for different input", () => {
34
+ const input1 = JSON.stringify({ query: "test1" });
35
+ const input2 = JSON.stringify({ query: "test2" });
36
+ expect(input1).not.toBe(input2);
37
+ });
38
+ });
39
+ });
40
+ //# sourceMappingURL=cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.js","sourceRoot":"","sources":["../../src/__tests__/cache.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,4CAA4C;AAC5C,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;AAE1D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,6DAA6D;YAC7D,MAAM,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
3
+ import { join } from "path";
4
+ import { loadConfig, saveConfig, getApiUrl, DEFAULT_API_URL, } from "../utils/config.js";
5
+ const TEST_DIR = join(process.cwd(), ".test-config");
6
+ const CONFIG_PATH = join(TEST_DIR, ".datachonk.yml");
7
+ describe("Config Utils", () => {
8
+ beforeEach(() => {
9
+ // Create test directory
10
+ if (!existsSync(TEST_DIR)) {
11
+ mkdirSync(TEST_DIR, { recursive: true });
12
+ }
13
+ // Clear env vars
14
+ delete process.env.DATACHONK_API_URL;
15
+ delete process.env.DATACHONK_API_KEY;
16
+ });
17
+ afterEach(() => {
18
+ // Clean up test directory
19
+ if (existsSync(TEST_DIR)) {
20
+ rmSync(TEST_DIR, { recursive: true, force: true });
21
+ }
22
+ });
23
+ describe("loadConfig", () => {
24
+ it("returns default config when no file exists", () => {
25
+ const config = loadConfig(TEST_DIR);
26
+ expect(config.version).toBe(1);
27
+ expect(config.warehouse).toBe("snowflake");
28
+ expect(config.modeling.approach).toBe("kimball");
29
+ });
30
+ it("loads config from YAML file", () => {
31
+ const yamlContent = `
32
+ version: 1
33
+ warehouse: bigquery
34
+ modeling:
35
+ approach: data_vault
36
+ conventions:
37
+ - snake_case
38
+ `;
39
+ writeFileSync(CONFIG_PATH, yamlContent);
40
+ const config = loadConfig(TEST_DIR);
41
+ expect(config.warehouse).toBe("bigquery");
42
+ expect(config.modeling.approach).toBe("data_vault");
43
+ });
44
+ it("merges with defaults for missing fields", () => {
45
+ const yamlContent = `
46
+ version: 1
47
+ warehouse: redshift
48
+ `;
49
+ writeFileSync(CONFIG_PATH, yamlContent);
50
+ const config = loadConfig(TEST_DIR);
51
+ expect(config.warehouse).toBe("redshift");
52
+ expect(config.modeling.approach).toBe("kimball"); // default
53
+ expect(config.ai.enabled).toBe(false); // default
54
+ });
55
+ });
56
+ describe("saveConfig", () => {
57
+ it("saves config to YAML file", () => {
58
+ const config = {
59
+ version: 1,
60
+ warehouse: "databricks",
61
+ modeling: {
62
+ approach: "obt",
63
+ conventions: ["snake_case"],
64
+ },
65
+ ai: {
66
+ enabled: true,
67
+ apiKey: "test-key",
68
+ },
69
+ analysis: {
70
+ ignorePaths: [],
71
+ ignoreRules: [],
72
+ },
73
+ generation: {
74
+ defaultMaterialization: "table",
75
+ addDescriptions: true,
76
+ addTests: true,
77
+ },
78
+ connections: {},
79
+ };
80
+ saveConfig(config, TEST_DIR);
81
+ expect(existsSync(CONFIG_PATH)).toBe(true);
82
+ const loaded = loadConfig(TEST_DIR);
83
+ expect(loaded.warehouse).toBe("databricks");
84
+ expect(loaded.modeling.approach).toBe("obt");
85
+ expect(loaded.ai.enabled).toBe(true);
86
+ });
87
+ });
88
+ describe("getApiUrl", () => {
89
+ it("returns default URL when no config or env var", () => {
90
+ const url = getApiUrl();
91
+ expect(url).toBe(DEFAULT_API_URL);
92
+ });
93
+ it("respects DATACHONK_API_URL env var", () => {
94
+ process.env.DATACHONK_API_URL = "https://custom.example.com";
95
+ const url = getApiUrl();
96
+ expect(url).toBe("https://custom.example.com");
97
+ });
98
+ it("config apiUrl takes precedence", () => {
99
+ const yamlContent = `
100
+ version: 1
101
+ apiUrl: https://config.example.com
102
+ `;
103
+ writeFileSync(CONFIG_PATH, yamlContent);
104
+ process.env.DATACHONK_API_URL = "https://env.example.com";
105
+ // Note: This test would need the config to be loaded from TEST_DIR
106
+ // which requires modifying getApiUrl to accept a path parameter
107
+ // For now, just verify the env var works
108
+ const url = getApiUrl();
109
+ expect(url).toBe("https://env.example.com");
110
+ });
111
+ });
112
+ });
113
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=templates.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/templates.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { initTemplates, getTemplate, listTemplates, renderTemplate, } from "../utils/templates.js";
3
+ describe("Template Utils", () => {
4
+ beforeEach(() => {
5
+ initTemplates();
6
+ });
7
+ describe("listTemplates", () => {
8
+ it("returns staging templates", () => {
9
+ const templates = listTemplates("staging");
10
+ expect(templates.length).toBeGreaterThan(0);
11
+ });
12
+ it("returns mart templates", () => {
13
+ const templates = listTemplates("mart");
14
+ expect(templates.length).toBeGreaterThan(0);
15
+ });
16
+ it("returns test templates", () => {
17
+ const templates = listTemplates("test");
18
+ expect(templates.length).toBeGreaterThan(0);
19
+ });
20
+ it("returns empty array for unknown category", () => {
21
+ const templates = listTemplates("unknown-category");
22
+ expect(templates).toEqual([]);
23
+ });
24
+ });
25
+ describe("getTemplate", () => {
26
+ it("returns template by name", () => {
27
+ const template = getTemplate("staging-model");
28
+ expect(template).toBeDefined();
29
+ expect(template?.name).toBe("staging-model");
30
+ });
31
+ it("returns null for unknown template", () => {
32
+ const template = getTemplate("nonexistent-template");
33
+ expect(template).toBeNull();
34
+ });
35
+ });
36
+ describe("renderTemplate", () => {
37
+ it("renders staging template with variables", () => {
38
+ const rendered = renderTemplate("staging-model", {
39
+ source_name: "raw_data",
40
+ source_table: "users",
41
+ columns: ["user_id", "email", "created_at"],
42
+ });
43
+ expect(rendered).toContain("raw_data");
44
+ expect(rendered).toContain("users");
45
+ });
46
+ it("throws for unknown template", () => {
47
+ expect(() => renderTemplate("nonexistent", {})).toThrow("Template not found");
48
+ });
49
+ });
50
+ });
51
+ //# sourceMappingURL=templates.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../src/__tests__/templates.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,UAAU,CAAC,GAAG,EAAE;QACd,aAAa,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,SAAS,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;YAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/B,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,QAAQ,GAAG,WAAW,CAAC,sBAAsB,CAAC,CAAC;YACrD,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,QAAQ,GAAG,cAAc,CAAC,eAAe,EAAE;gBAC/C,WAAW,EAAE,UAAU;gBACvB,YAAY,EAAE,OAAO;gBACrB,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC;aAC5C,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ interface AnalyzeOptions {
2
+ path: string;
3
+ model?: string;
4
+ fix?: boolean;
5
+ json?: boolean;
6
+ verbose?: boolean;
7
+ }
8
+ export declare function analyzeCommand(options: AnalyzeOptions): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=analyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AASA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAqK3E"}
@@ -0,0 +1,156 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { glob } from "glob";
4
+ import { readFileSync, existsSync } from "fs";
5
+ import { join, basename } from "path";
6
+ import { table } from "table";
7
+ import { loadConfig } from "../utils/config.js";
8
+ import { parseModel, detectAntiPatterns } from "../utils/analyzer.js";
9
+ export async function analyzeCommand(options) {
10
+ const spinner = ora("Analyzing dbt project...").start();
11
+ try {
12
+ const config = loadConfig(options.path);
13
+ const projectPath = options.path;
14
+ // Find all SQL files
15
+ const pattern = options.model
16
+ ? `**/${options.model}.sql`
17
+ : "**/*.sql";
18
+ const files = await glob(pattern, {
19
+ cwd: projectPath,
20
+ ignore: ["**/target/**", "**/dbt_packages/**", "**/node_modules/**"],
21
+ });
22
+ if (files.length === 0) {
23
+ spinner.fail("No SQL files found");
24
+ return;
25
+ }
26
+ spinner.text = `Found ${files.length} SQL files. Analyzing...`;
27
+ const allIssues = [];
28
+ const modelStats = {
29
+ total: files.length,
30
+ staging: 0,
31
+ intermediate: 0,
32
+ mart: 0,
33
+ other: 0,
34
+ withTests: 0,
35
+ withDocs: 0,
36
+ };
37
+ for (const file of files) {
38
+ const filePath = join(projectPath, file);
39
+ const content = readFileSync(filePath, "utf-8");
40
+ const fileName = basename(file, ".sql");
41
+ // Categorize model
42
+ if (fileName.startsWith("stg_"))
43
+ modelStats.staging++;
44
+ else if (fileName.startsWith("int_"))
45
+ modelStats.intermediate++;
46
+ else if (fileName.startsWith("fct_") || fileName.startsWith("dim_"))
47
+ modelStats.mart++;
48
+ else
49
+ modelStats.other++;
50
+ // Parse and analyze
51
+ const model = parseModel(content, fileName);
52
+ const issues = detectAntiPatterns(model, config.warehouse);
53
+ for (const issue of issues) {
54
+ allIssues.push({ ...issue, file });
55
+ }
56
+ // Check for tests
57
+ const schemaPath = join(projectPath, file.replace(".sql", ".yml"));
58
+ const schemaPath2 = join(projectPath, "models", "schema.yml");
59
+ if (existsSync(schemaPath) || existsSync(schemaPath2)) {
60
+ modelStats.withTests++;
61
+ }
62
+ }
63
+ spinner.succeed(`Analyzed ${files.length} models`);
64
+ // Group issues by severity
65
+ const critical = allIssues.filter(i => i.severity === "critical");
66
+ const high = allIssues.filter(i => i.severity === "high");
67
+ const medium = allIssues.filter(i => i.severity === "medium");
68
+ const low = allIssues.filter(i => i.severity === "low");
69
+ if (options.json) {
70
+ console.log(JSON.stringify({
71
+ summary: {
72
+ totalModels: modelStats.total,
73
+ issues: {
74
+ critical: critical.length,
75
+ high: high.length,
76
+ medium: medium.length,
77
+ low: low.length,
78
+ },
79
+ modelTypes: modelStats,
80
+ },
81
+ issues: allIssues,
82
+ }, null, 2));
83
+ return;
84
+ }
85
+ // Print summary
86
+ console.log("\n" + chalk.bold("Project Summary"));
87
+ console.log(chalk.gray("─".repeat(50)));
88
+ const summaryData = [
89
+ ["Total Models", modelStats.total.toString()],
90
+ ["Staging (stg_)", chalk.cyan(modelStats.staging.toString())],
91
+ ["Intermediate (int_)", chalk.blue(modelStats.intermediate.toString())],
92
+ ["Marts (fct_/dim_)", chalk.green(modelStats.mart.toString())],
93
+ ["Other", chalk.gray(modelStats.other.toString())],
94
+ ];
95
+ console.log(table(summaryData, {
96
+ border: {
97
+ topBody: "", topJoin: "", topLeft: "", topRight: "",
98
+ bottomBody: "", bottomJoin: "", bottomLeft: "", bottomRight: "",
99
+ bodyLeft: "", bodyRight: "", bodyJoin: chalk.gray("│"),
100
+ joinBody: "", joinLeft: "", joinRight: "", joinJoin: "",
101
+ },
102
+ }));
103
+ // Print issues
104
+ console.log(chalk.bold("\nIssues Found"));
105
+ console.log(chalk.gray("─".repeat(50)));
106
+ const issuesSummary = [
107
+ [chalk.red("Critical"), critical.length.toString()],
108
+ [chalk.hex("#FFA500")("High"), high.length.toString()],
109
+ [chalk.yellow("Medium"), medium.length.toString()],
110
+ [chalk.gray("Low"), low.length.toString()],
111
+ ];
112
+ console.log(table(issuesSummary, {
113
+ border: {
114
+ topBody: "", topJoin: "", topLeft: "", topRight: "",
115
+ bottomBody: "", bottomJoin: "", bottomLeft: "", bottomRight: "",
116
+ bodyLeft: "", bodyRight: "", bodyJoin: chalk.gray("│"),
117
+ joinBody: "", joinLeft: "", joinRight: "", joinJoin: "",
118
+ },
119
+ }));
120
+ if (allIssues.length > 0) {
121
+ console.log(chalk.bold("\nDetailed Issues"));
122
+ console.log(chalk.gray("─".repeat(50)));
123
+ // Show critical and high issues
124
+ const importantIssues = [...critical, ...high];
125
+ for (const issue of importantIssues.slice(0, options.verbose ? undefined : 10)) {
126
+ const severityColor = issue.severity === "critical" ? chalk.red : chalk.hex("#FFA500");
127
+ console.log(`\n${severityColor(`[${issue.severity.toUpperCase()}]`)} ${chalk.bold(issue.pattern)}`);
128
+ console.log(chalk.gray(` File: ${issue.file}`));
129
+ console.log(chalk.gray(` ${issue.explanation}`));
130
+ console.log(chalk.cyan(` Fix: ${issue.fix}`));
131
+ }
132
+ if (!options.verbose && importantIssues.length > 10) {
133
+ console.log(chalk.gray(`\n ... and ${importantIssues.length - 10} more issues. Use --verbose to see all.`));
134
+ }
135
+ }
136
+ // Exit code based on issues
137
+ if (critical.length > 0) {
138
+ console.log(chalk.red("\n✖ Analysis failed with critical issues"));
139
+ process.exit(1);
140
+ }
141
+ else if (high.length > 0) {
142
+ console.log(chalk.yellow("\n⚠ Analysis completed with warnings"));
143
+ process.exit(0);
144
+ }
145
+ else {
146
+ console.log(chalk.green("\n✓ Analysis passed"));
147
+ process.exit(0);
148
+ }
149
+ }
150
+ catch (error) {
151
+ spinner.fail("Analysis failed");
152
+ console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
153
+ process.exit(1);
154
+ }
155
+ }
156
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const chatCommand: Command;
3
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,WAAW,SAwHpB,CAAC"}