yamchart 0.8.1 → 0.8.3

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 (68) hide show
  1. package/dist/{advisor-57BOMUUF.js → advisor-JMWAAWJO.js} +10 -10
  2. package/dist/chunk-4W6IVOKO.js +362 -0
  3. package/dist/chunk-4W6IVOKO.js.map +1 -0
  4. package/dist/{chunk-JYQKDWLG.js → chunk-5N3FYFBV.js} +72 -1
  5. package/dist/chunk-5N3FYFBV.js.map +1 -0
  6. package/dist/{chunk-OTAUP5RC.js → chunk-7AVPKKYY.js} +5 -5
  7. package/dist/chunk-7AVPKKYY.js.map +1 -0
  8. package/dist/{chunk-X6LQGWUX.js → chunk-KP4CYPBL.js} +9 -2
  9. package/dist/chunk-KP4CYPBL.js.map +1 -0
  10. package/dist/{chunk-E2UZXDF6.js → chunk-N6PUISAQ.js} +4 -4
  11. package/dist/compare-ZN6RUOOQ.js +87 -0
  12. package/dist/compare-ZN6RUOOQ.js.map +1 -0
  13. package/dist/{connection-utils-FTSZU2VF.js → connection-utils-VEKXRCOM.js} +4 -4
  14. package/dist/describe-X55JPLES.js +29 -0
  15. package/dist/describe-X55JPLES.js.map +1 -0
  16. package/dist/{dev-MRZ76V74.js → dev-NZLS72PG.js} +9 -7
  17. package/dist/dev-NZLS72PG.js.map +1 -0
  18. package/dist/{dist-PVHFUYP2.js → dist-E2PVGIPT.js} +4 -2
  19. package/dist/{dist-WDTDQDTX.js → dist-GVNWQXFR.js} +2 -2
  20. package/dist/index.js +314 -32
  21. package/dist/index.js.map +1 -1
  22. package/dist/{lineage-XSITWW2O.js → lineage-T5NRHHZN.js} +32 -5
  23. package/dist/{lineage-XSITWW2O.js.map → lineage-T5NRHHZN.js.map} +1 -1
  24. package/dist/public/assets/{EventManagement-BlxJ2TFw.js → EventManagement-7MyQq5KD.js} +1 -1
  25. package/dist/public/assets/{LoginPage-BT8ikmPn.js → LoginPage-BypxvDY2.js} +1 -1
  26. package/dist/public/assets/{PublicViewer-B4uFxgbt.js → PublicViewer-CdDaYqTc.js} +1 -1
  27. package/dist/public/assets/{SetupWizard-njrOhCzw.js → SetupWizard-CEGLuSGr.js} +1 -1
  28. package/dist/public/assets/{ShareManagement-Bg16oJhW.js → ShareManagement-DcPZNRdx.js} +1 -1
  29. package/dist/public/assets/{UserManagement-tiCIT4UY.js → UserManagement-VZ9Qvds0.js} +1 -1
  30. package/dist/public/assets/{index-BZ25r23j.css → index-B_fusLA_.css} +1 -1
  31. package/dist/public/assets/index-Cxn1i3jV.js +187 -0
  32. package/dist/public/assets/{index.es-BuktD_R2.js → index.es-06ls9Fpg.js} +1 -1
  33. package/dist/public/assets/{jspdf.es.min-DFRl2hZQ.js → jspdf.es.min-DER4Hnpt.js} +3 -3
  34. package/dist/public/index.html +3 -3
  35. package/dist/{query-JRMMNXX6.js → query-3F5V5CZH.js} +4 -4
  36. package/dist/{sample-VGIY4U4J.js → sample-SWYXGWOM.js} +4 -4
  37. package/dist/search-ARIDL6DA.js +28 -0
  38. package/dist/search-ARIDL6DA.js.map +1 -0
  39. package/dist/source-resolver-UHKZVOOC.js +18 -0
  40. package/dist/source-resolver-UHKZVOOC.js.map +1 -0
  41. package/dist/{sync-warehouse-XHTBZH25.js → sync-warehouse-J4E2R2PW.js} +4 -4
  42. package/dist/tables-VAR2ZKUA.js +30 -0
  43. package/dist/tables-VAR2ZKUA.js.map +1 -0
  44. package/dist/templates/default/docs/yamchart-reference.md +23 -4
  45. package/dist/templates/default/yamchart.yaml +1 -1
  46. package/dist/templates/empty/yamchart.yaml +1 -1
  47. package/dist/{test-TXRZWNXK.js → test-SV5SLSLM.js} +4 -4
  48. package/package.json +1 -1
  49. package/dist/chunk-JYQKDWLG.js.map +0 -1
  50. package/dist/chunk-OTAUP5RC.js.map +0 -1
  51. package/dist/chunk-X6LQGWUX.js.map +0 -1
  52. package/dist/describe-TGIOBNJB.js +0 -44
  53. package/dist/describe-TGIOBNJB.js.map +0 -1
  54. package/dist/dev-MRZ76V74.js.map +0 -1
  55. package/dist/public/assets/index-B41yj3io.js +0 -187
  56. package/dist/search-QSYNG4SR.js +0 -39
  57. package/dist/search-QSYNG4SR.js.map +0 -1
  58. package/dist/tables-UOO342TA.js +0 -40
  59. package/dist/tables-UOO342TA.js.map +0 -1
  60. /package/dist/{advisor-57BOMUUF.js.map → advisor-JMWAAWJO.js.map} +0 -0
  61. /package/dist/{chunk-E2UZXDF6.js.map → chunk-N6PUISAQ.js.map} +0 -0
  62. /package/dist/{connection-utils-FTSZU2VF.js.map → connection-utils-VEKXRCOM.js.map} +0 -0
  63. /package/dist/{dist-PVHFUYP2.js.map → dist-E2PVGIPT.js.map} +0 -0
  64. /package/dist/{dist-WDTDQDTX.js.map → dist-GVNWQXFR.js.map} +0 -0
  65. /package/dist/{query-JRMMNXX6.js.map → query-3F5V5CZH.js.map} +0 -0
  66. /package/dist/{sample-VGIY4U4J.js.map → sample-SWYXGWOM.js.map} +0 -0
  67. /package/dist/{sync-warehouse-XHTBZH25.js.map → sync-warehouse-J4E2R2PW.js.map} +0 -0
  68. /package/dist/{test-TXRZWNXK.js.map → test-SV5SLSLM.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createConnector,
3
3
  resolveConnection
4
- } from "./chunk-OTAUP5RC.js";
4
+ } from "./chunk-7AVPKKYY.js";
5
5
  import {
6
6
  detail,
7
7
  error,
@@ -10,8 +10,8 @@ import {
10
10
  success,
11
11
  warning
12
12
  } from "./chunk-HJVVHYVN.js";
13
- import "./chunk-X6LQGWUX.js";
14
- import "./chunk-JYQKDWLG.js";
13
+ import "./chunk-KP4CYPBL.js";
14
+ import "./chunk-5N3FYFBV.js";
15
15
  import "./chunk-UND73EOB.js";
16
16
  import "./chunk-DGUM43GV.js";
17
17
 
@@ -44,7 +44,7 @@ async function getDbtProjectPath(projectDir, override) {
44
44
  return null;
45
45
  }
46
46
  async function buildContext(projectDir, options) {
47
- const { parseModelMetadata } = await import("./dist-PVHFUYP2.js");
47
+ const { parseModelMetadata } = await import("./dist-E2PVGIPT.js");
48
48
  const modelsDir = join(projectDir, "models");
49
49
  const yamchartModels = [];
50
50
  try {
@@ -140,7 +140,7 @@ async function buildContext(projectDir, options) {
140
140
  };
141
141
  if (dbtPath) {
142
142
  try {
143
- const { detectConventions, listDbtModels } = await import("./dist-WDTDQDTX.js");
143
+ const { detectConventions, listDbtModels } = await import("./dist-GVNWQXFR.js");
144
144
  const dbtProjectYml = await readFile(join(dbtPath, "dbt_project.yml"), "utf-8");
145
145
  const dbtConfig = parseYaml(dbtProjectYml);
146
146
  const conventions = await detectConventions(dbtPath);
@@ -236,7 +236,7 @@ async function runAdvisor(projectDir, questionOrMode, options) {
236
236
  `warehouse: ${context.warehouse ? `connected (${context.warehouse.connectionType})` : "not connected"}`
237
237
  );
238
238
  console.log("");
239
- const { AdvisorAgent, AnthropicProvider, buildModelPath } = await import("./dist-WDTDQDTX.js");
239
+ const { AdvisorAgent, AnthropicProvider, buildModelPath } = await import("./dist-GVNWQXFR.js");
240
240
  const provider = new AnthropicProvider(apiKey);
241
241
  const agent = new AdvisorAgent(provider);
242
242
  const isAudit = questionOrMode === "audit";
@@ -281,7 +281,7 @@ ${pc.bold(`[${i + 1}]`)} ${formatProposal(proposal, context.dbt.conventions, bui
281
281
  spin2.stop();
282
282
  console.log(result.response);
283
283
  if (result.proposals.length > 0) {
284
- const { buildModelPath: bmp } = await import("./dist-WDTDQDTX.js");
284
+ const { buildModelPath: bmp } = await import("./dist-GVNWQXFR.js");
285
285
  for (const proposal of result.proposals) {
286
286
  console.log(
287
287
  `
@@ -322,7 +322,7 @@ ${formatProposal(proposal, context.dbt.conventions, bmp)}`
322
322
  conversationHistory.length = 0;
323
323
  conversationHistory.push(...result.messages);
324
324
  if (result.proposals.length > 0) {
325
- const { buildModelPath: bmp } = await import("./dist-WDTDQDTX.js");
325
+ const { buildModelPath: bmp } = await import("./dist-GVNWQXFR.js");
326
326
  for (const proposal of result.proposals) {
327
327
  console.log(
328
328
  `
@@ -340,7 +340,7 @@ async function offerApply(context, proposals) {
340
340
  return;
341
341
  }
342
342
  const { confirm } = await import("@inquirer/prompts");
343
- const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } = await import("./dist-WDTDQDTX.js");
343
+ const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } = await import("./dist-GVNWQXFR.js");
344
344
  for (const proposal of proposals) {
345
345
  console.log("");
346
346
  const shouldApply = await confirm({
@@ -379,4 +379,4 @@ async function offerApply(context, proposals) {
379
379
  export {
380
380
  runAdvisor
381
381
  };
382
- //# sourceMappingURL=advisor-57BOMUUF.js.map
382
+ //# sourceMappingURL=advisor-JMWAAWJO.js.map
@@ -0,0 +1,362 @@
1
+ import {
2
+ resolveTableName
3
+ } from "./chunk-VJC24RKT.js";
4
+ import {
5
+ getDescribeQuery,
6
+ getSearchQuery,
7
+ getTablesQuery
8
+ } from "./chunk-EHM6AMMA.js";
9
+ import {
10
+ createConnector,
11
+ resolveConnection
12
+ } from "./chunk-7AVPKKYY.js";
13
+
14
+ // src/commands/source-resolver.ts
15
+ import { readFile as readFile2, access as access2 } from "fs/promises";
16
+ import { join as join2 } from "path";
17
+ import { performance } from "perf_hooks";
18
+
19
+ // src/commands/model-parser.ts
20
+ import { readFile, readdir, access } from "fs/promises";
21
+ import { join, extname } from "path";
22
+ function parseModelReturns(sql) {
23
+ const nameMatch = sql.match(/--\s*@name:\s*(.+)/);
24
+ if (!nameMatch?.[1]) return null;
25
+ const name = nameMatch[1].trim();
26
+ const descMatch = sql.match(/--\s*@description:\s*(.+)/);
27
+ const description = descMatch?.[1]?.trim();
28
+ const columns = [];
29
+ const returnsMatch = sql.match(/--\s*@returns:\s*\n((?:\s*--\s+-\s+.+\n?)*)/);
30
+ if (returnsMatch?.[1]) {
31
+ const lines = returnsMatch[1].split("\n");
32
+ for (const line of lines) {
33
+ const colMatch = line.match(/--\s+-\s+(\w+)(?:\s*:\s*(\w+))?/);
34
+ if (colMatch?.[1]) {
35
+ columns.push({
36
+ name: colMatch[1],
37
+ type: colMatch[2] || "unknown",
38
+ nullable: "YES"
39
+ });
40
+ }
41
+ }
42
+ }
43
+ return { name, description, columns };
44
+ }
45
+ async function findSqlFiles(dir) {
46
+ const files = [];
47
+ const entries = await readdir(dir, { withFileTypes: true });
48
+ for (const entry of entries) {
49
+ const fullPath = join(dir, entry.name);
50
+ if (entry.isDirectory()) {
51
+ files.push(...await findSqlFiles(fullPath));
52
+ } else if (extname(entry.name) === ".sql") {
53
+ files.push(fullPath);
54
+ }
55
+ }
56
+ return files;
57
+ }
58
+ async function scanModels(projectDir) {
59
+ const modelsDir = join(projectDir, "models");
60
+ try {
61
+ await access(modelsDir);
62
+ } catch {
63
+ return [];
64
+ }
65
+ const sqlFiles = await findSqlFiles(modelsDir);
66
+ const models = [];
67
+ for (const filePath of sqlFiles) {
68
+ const content = await readFile(filePath, "utf-8");
69
+ const parsed = parseModelReturns(content);
70
+ if (parsed) {
71
+ models.push(parsed);
72
+ }
73
+ }
74
+ return models;
75
+ }
76
+
77
+ // src/commands/source-resolver.ts
78
+ async function loadCatalog(projectDir) {
79
+ try {
80
+ const catalogPath = join2(projectDir, ".yamchart", "catalog.json");
81
+ await access2(catalogPath);
82
+ const content = await readFile2(catalogPath, "utf-8");
83
+ return JSON.parse(content);
84
+ } catch {
85
+ return null;
86
+ }
87
+ }
88
+ function findCatalogModel(catalog, tableName) {
89
+ return catalog.models?.find(
90
+ (m) => m.name.toLowerCase() === tableName.toLowerCase()
91
+ );
92
+ }
93
+ function catalogColumnsToNormalized(columns) {
94
+ return columns.map((c) => ({
95
+ name: c.name,
96
+ type: c.data_type,
97
+ nullable: "YES"
98
+ }));
99
+ }
100
+ async function describeFromCatalog(projectDir, table) {
101
+ const catalog = await loadCatalog(projectDir);
102
+ if (!catalog) return null;
103
+ const model = findCatalogModel(catalog, table);
104
+ if (!model?.columns?.length) return null;
105
+ return {
106
+ source: "catalog",
107
+ table: model.table || table,
108
+ columns: catalogColumnsToNormalized(model.columns),
109
+ durationMs: 0,
110
+ ...model.table ? { resolvedFrom: table } : {}
111
+ };
112
+ }
113
+ async function describeFromModel(projectDir, table) {
114
+ const models = await scanModels(projectDir);
115
+ const match = models.find(
116
+ (m) => m.name.toLowerCase() === table.toLowerCase()
117
+ );
118
+ if (!match || match.columns.length === 0) return null;
119
+ return {
120
+ source: "model",
121
+ table: match.name,
122
+ columns: match.columns,
123
+ durationMs: 0
124
+ };
125
+ }
126
+ async function describeFromDb(projectDir, table, connectionName) {
127
+ const resolved = await resolveTableName(projectDir, table);
128
+ const connection = await resolveConnection(projectDir, connectionName);
129
+ const connector = createConnector(connection, projectDir);
130
+ try {
131
+ await connector.connect();
132
+ const query = getDescribeQuery(connection.type, resolved.tableName);
133
+ const startTime = performance.now();
134
+ const result = await connector.execute(query.sql);
135
+ const durationMs = performance.now() - startTime;
136
+ const columns = query.normalize(result.rows);
137
+ return {
138
+ source: "db",
139
+ table: resolved.tableName,
140
+ columns,
141
+ connectionName: connection.name,
142
+ connectionType: connection.type,
143
+ durationMs,
144
+ ...resolved.source === "catalog" ? { resolvedFrom: table } : {}
145
+ };
146
+ } finally {
147
+ await connector.disconnect();
148
+ }
149
+ }
150
+ async function resolveDescribeSource(projectDir, table, source, connectionName) {
151
+ switch (source) {
152
+ case "catalog": {
153
+ const catalog = await loadCatalog(projectDir);
154
+ if (!catalog) throw new Error("No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.");
155
+ const model = findCatalogModel(catalog, table);
156
+ if (!model) throw new Error(`Table "${table}" not found in catalog.`);
157
+ if (!model.columns?.length) throw new Error(`Catalog has no column metadata for "${table}". Run sync to populate.`);
158
+ return {
159
+ source: "catalog",
160
+ table: model.table || table,
161
+ columns: catalogColumnsToNormalized(model.columns),
162
+ durationMs: 0,
163
+ ...model.table ? { resolvedFrom: table } : {}
164
+ };
165
+ }
166
+ case "model": {
167
+ const models = await scanModels(projectDir);
168
+ const match = models.find((m) => m.name.toLowerCase() === table.toLowerCase());
169
+ if (!match) throw new Error(`No model found matching "${table}". Check your models/ directory.`);
170
+ return {
171
+ source: "model",
172
+ table: match.name,
173
+ columns: match.columns,
174
+ durationMs: 0
175
+ };
176
+ }
177
+ case "db":
178
+ return describeFromDb(projectDir, table, connectionName);
179
+ case "auto": {
180
+ const catalogResult = await describeFromCatalog(projectDir, table);
181
+ if (catalogResult) return catalogResult;
182
+ const modelResult = await describeFromModel(projectDir, table);
183
+ if (modelResult) return modelResult;
184
+ return describeFromDb(projectDir, table, connectionName);
185
+ }
186
+ }
187
+ }
188
+ async function tablesFromCatalog(projectDir) {
189
+ const catalog = await loadCatalog(projectDir);
190
+ if (!catalog?.models?.length) return null;
191
+ const tables = catalog.models.map((m) => {
192
+ const parts = (m.table || m.name).split(".");
193
+ return {
194
+ schema: parts.length > 1 ? parts.slice(0, -1).join(".") : "",
195
+ name: parts[parts.length - 1],
196
+ type: m.source === "dbt-source" ? "SOURCE" : "TABLE"
197
+ };
198
+ });
199
+ return { source: "catalog", tables, durationMs: 0 };
200
+ }
201
+ async function tablesFromModel(projectDir) {
202
+ const models = await scanModels(projectDir);
203
+ if (models.length === 0) return null;
204
+ const tables = models.map((m) => ({
205
+ schema: "",
206
+ name: m.name,
207
+ type: "MODEL"
208
+ }));
209
+ return { source: "model", tables, durationMs: 0 };
210
+ }
211
+ async function tablesFromDb(projectDir, connectionName, options) {
212
+ const connection = await resolveConnection(projectDir, connectionName);
213
+ const connector = createConnector(connection, projectDir);
214
+ try {
215
+ await connector.connect();
216
+ const query = getTablesQuery(connection.type, options);
217
+ const start = performance.now();
218
+ const result = await connector.execute(query.sql);
219
+ const tables = query.normalize(result.rows);
220
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
221
+ return {
222
+ source: "db",
223
+ tables,
224
+ connectionName: connection.name,
225
+ connectionType: connection.type,
226
+ durationMs
227
+ };
228
+ } finally {
229
+ await connector.disconnect();
230
+ }
231
+ }
232
+ async function resolveTablesSource(projectDir, source, connectionName, options) {
233
+ switch (source) {
234
+ case "catalog": {
235
+ const catalog = await loadCatalog(projectDir);
236
+ if (!catalog) throw new Error("No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.");
237
+ const result = await tablesFromCatalog(projectDir);
238
+ return result || { source: "catalog", tables: [], durationMs: 0 };
239
+ }
240
+ case "model": {
241
+ const result = await tablesFromModel(projectDir);
242
+ return result || { source: "model", tables: [], durationMs: 0 };
243
+ }
244
+ case "db":
245
+ return tablesFromDb(projectDir, connectionName, options);
246
+ case "auto": {
247
+ const catalogResult = await tablesFromCatalog(projectDir);
248
+ if (catalogResult) return catalogResult;
249
+ const modelResult = await tablesFromModel(projectDir);
250
+ if (modelResult) return modelResult;
251
+ return tablesFromDb(projectDir, connectionName, options);
252
+ }
253
+ }
254
+ }
255
+ function searchCatalog(catalog, keyword) {
256
+ const results = [];
257
+ const lower = keyword.toLowerCase();
258
+ for (const model of catalog.models || []) {
259
+ const tableParts = (model.table || model.name).split(".");
260
+ const schema = tableParts.length > 1 ? tableParts.slice(0, -1).join(".") : "";
261
+ const tableName = tableParts[tableParts.length - 1];
262
+ if (model.name.toLowerCase().includes(lower) || tableName.toLowerCase().includes(lower)) {
263
+ results.push({ type: "table", schema, table: model.name });
264
+ }
265
+ for (const col of model.columns || []) {
266
+ if (col.name.toLowerCase().includes(lower)) {
267
+ results.push({
268
+ type: "column",
269
+ schema,
270
+ table: model.name,
271
+ column: col.name,
272
+ columnType: col.data_type
273
+ });
274
+ }
275
+ }
276
+ }
277
+ return results;
278
+ }
279
+ async function searchFromDb(projectDir, keyword, connectionName) {
280
+ const connection = await resolveConnection(projectDir, connectionName);
281
+ const connector = createConnector(connection, projectDir);
282
+ try {
283
+ await connector.connect();
284
+ const query = getSearchQuery(connection.type, keyword);
285
+ const startTime = performance.now();
286
+ const result = await connector.execute(query.sql);
287
+ const durationMs = performance.now() - startTime;
288
+ const results = query.normalize(result.rows);
289
+ return {
290
+ source: "db",
291
+ keyword,
292
+ results,
293
+ connectionName: connection.name,
294
+ connectionType: connection.type,
295
+ durationMs
296
+ };
297
+ } finally {
298
+ await connector.disconnect();
299
+ }
300
+ }
301
+ async function resolveSearchSource(projectDir, keyword, source, connectionName) {
302
+ switch (source) {
303
+ case "catalog": {
304
+ const catalog = await loadCatalog(projectDir);
305
+ if (!catalog) throw new Error("No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.");
306
+ return { source: "catalog", keyword, results: searchCatalog(catalog, keyword), durationMs: 0 };
307
+ }
308
+ case "model": {
309
+ const models = await scanModels(projectDir);
310
+ const lower = keyword.toLowerCase();
311
+ const results = [];
312
+ for (const model of models) {
313
+ if (model.name.toLowerCase().includes(lower)) {
314
+ results.push({ type: "table", schema: "", table: model.name });
315
+ }
316
+ for (const col of model.columns) {
317
+ if (col.name.toLowerCase().includes(lower)) {
318
+ results.push({ type: "column", schema: "", table: model.name, column: col.name, columnType: col.type });
319
+ }
320
+ }
321
+ }
322
+ return { source: "model", keyword, results, durationMs: 0 };
323
+ }
324
+ case "db":
325
+ return searchFromDb(projectDir, keyword, connectionName);
326
+ case "auto": {
327
+ const catalog = await loadCatalog(projectDir);
328
+ if (catalog?.models?.length) {
329
+ const results = searchCatalog(catalog, keyword);
330
+ if (results.length > 0) {
331
+ return { source: "catalog", keyword, results, durationMs: 0 };
332
+ }
333
+ }
334
+ const models = await scanModels(projectDir);
335
+ if (models.length > 0) {
336
+ const lower = keyword.toLowerCase();
337
+ const results = [];
338
+ for (const model of models) {
339
+ if (model.name.toLowerCase().includes(lower)) {
340
+ results.push({ type: "table", schema: "", table: model.name });
341
+ }
342
+ for (const col of model.columns) {
343
+ if (col.name.toLowerCase().includes(lower)) {
344
+ results.push({ type: "column", schema: "", table: model.name, column: col.name, columnType: col.type });
345
+ }
346
+ }
347
+ }
348
+ if (results.length > 0) {
349
+ return { source: "model", keyword, results, durationMs: 0 };
350
+ }
351
+ }
352
+ return searchFromDb(projectDir, keyword, connectionName);
353
+ }
354
+ }
355
+ }
356
+
357
+ export {
358
+ resolveDescribeSource,
359
+ resolveTablesSource,
360
+ resolveSearchSource
361
+ };
362
+ //# sourceMappingURL=chunk-4W6IVOKO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/source-resolver.ts","../src/commands/model-parser.ts"],"sourcesContent":["import { readFile, access } from 'fs/promises';\nimport { join } from 'path';\nimport { performance } from 'node:perf_hooks';\nimport type { NormalizedColumn, NormalizedTable, SearchResult } from './introspection.js';\nimport { getDescribeQuery, getTablesQuery, getSearchQuery } from './introspection.js';\nimport { resolveConnection, createConnector } from './connection-utils.js';\nimport { scanModels } from './model-parser.js';\nimport { resolveTableName } from './model-resolver.js';\n\nexport type SourceType = 'auto' | 'catalog' | 'model' | 'db';\n\ninterface CatalogColumn {\n name: string;\n data_type: string;\n description?: string;\n}\n\ninterface CatalogModel {\n name: string;\n table?: string;\n columns?: CatalogColumn[];\n source?: string;\n dependsOn?: string[];\n}\n\ninterface CatalogFile {\n models?: CatalogModel[];\n}\n\nexport interface DescribeSourceResult {\n source: 'catalog' | 'model' | 'db';\n table: string;\n columns: NormalizedColumn[];\n connectionName?: string;\n connectionType?: string;\n durationMs: number;\n resolvedFrom?: string;\n}\n\nexport interface TablesSourceResult {\n source: 'catalog' | 'model' | 'db';\n tables: NormalizedTable[];\n connectionName?: string;\n connectionType?: string;\n durationMs: number;\n}\n\nexport interface SearchSourceResult {\n source: 'catalog' | 'model' | 'db';\n keyword: string;\n results: SearchResult[];\n connectionName?: string;\n connectionType?: string;\n durationMs: number;\n}\n\nasync function loadCatalog(projectDir: string): Promise<CatalogFile | null> {\n try {\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n await access(catalogPath);\n const content = await readFile(catalogPath, 'utf-8');\n return JSON.parse(content) as CatalogFile;\n } catch {\n return null;\n }\n}\n\nfunction findCatalogModel(catalog: CatalogFile, tableName: string): CatalogModel | undefined {\n return catalog.models?.find(\n (m) => m.name.toLowerCase() === tableName.toLowerCase(),\n );\n}\n\nfunction catalogColumnsToNormalized(columns: CatalogColumn[]): NormalizedColumn[] {\n return columns.map((c) => ({\n name: c.name,\n type: c.data_type,\n nullable: 'YES',\n }));\n}\n\n// --- DESCRIBE ---\n\nasync function describeFromCatalog(\n projectDir: string,\n table: string,\n): Promise<DescribeSourceResult | null> {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) return null;\n\n const model = findCatalogModel(catalog, table);\n if (!model?.columns?.length) return null;\n\n return {\n source: 'catalog',\n table: model.table || table,\n columns: catalogColumnsToNormalized(model.columns),\n durationMs: 0,\n ...(model.table ? { resolvedFrom: table } : {}),\n };\n}\n\nasync function describeFromModel(\n projectDir: string,\n table: string,\n): Promise<DescribeSourceResult | null> {\n const models = await scanModels(projectDir);\n const match = models.find(\n (m) => m.name.toLowerCase() === table.toLowerCase(),\n );\n if (!match || match.columns.length === 0) return null;\n\n return {\n source: 'model',\n table: match.name,\n columns: match.columns,\n durationMs: 0,\n };\n}\n\nasync function describeFromDb(\n projectDir: string,\n table: string,\n connectionName?: string,\n): Promise<DescribeSourceResult> {\n const resolved = await resolveTableName(projectDir, table);\n const connection = await resolveConnection(projectDir, connectionName);\n const connector = createConnector(connection, projectDir);\n\n try {\n await connector.connect();\n const query = getDescribeQuery(connection.type, resolved.tableName);\n const startTime = performance.now();\n const result = await connector.execute(query.sql);\n const durationMs = performance.now() - startTime;\n const columns = query.normalize(result.rows as Record<string, unknown>[]);\n\n return {\n source: 'db',\n table: resolved.tableName,\n columns,\n connectionName: connection.name,\n connectionType: connection.type,\n durationMs,\n ...(resolved.source === 'catalog' ? { resolvedFrom: table } : {}),\n };\n } finally {\n await connector.disconnect();\n }\n}\n\nexport async function resolveDescribeSource(\n projectDir: string,\n table: string,\n source: SourceType,\n connectionName?: string,\n): Promise<DescribeSourceResult> {\n switch (source) {\n case 'catalog': {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n const model = findCatalogModel(catalog, table);\n if (!model) throw new Error(`Table \"${table}\" not found in catalog.`);\n if (!model.columns?.length) throw new Error(`Catalog has no column metadata for \"${table}\". Run sync to populate.`);\n return {\n source: 'catalog',\n table: model.table || table,\n columns: catalogColumnsToNormalized(model.columns),\n durationMs: 0,\n ...(model.table ? { resolvedFrom: table } : {}),\n };\n }\n\n case 'model': {\n const models = await scanModels(projectDir);\n const match = models.find((m) => m.name.toLowerCase() === table.toLowerCase());\n if (!match) throw new Error(`No model found matching \"${table}\". Check your models/ directory.`);\n return {\n source: 'model',\n table: match.name,\n columns: match.columns,\n durationMs: 0,\n };\n }\n\n case 'db':\n return describeFromDb(projectDir, table, connectionName);\n\n case 'auto': {\n const catalogResult = await describeFromCatalog(projectDir, table);\n if (catalogResult) return catalogResult;\n\n const modelResult = await describeFromModel(projectDir, table);\n if (modelResult) return modelResult;\n\n return describeFromDb(projectDir, table, connectionName);\n }\n }\n}\n\n// --- TABLES ---\n\nasync function tablesFromCatalog(projectDir: string): Promise<TablesSourceResult | null> {\n const catalog = await loadCatalog(projectDir);\n if (!catalog?.models?.length) return null;\n\n const tables: NormalizedTable[] = catalog.models.map((m) => {\n const parts = (m.table || m.name).split('.');\n return {\n schema: parts.length > 1 ? parts.slice(0, -1).join('.') : '',\n name: parts[parts.length - 1],\n type: m.source === 'dbt-source' ? 'SOURCE' : 'TABLE',\n };\n });\n\n return { source: 'catalog', tables, durationMs: 0 };\n}\n\nasync function tablesFromModel(projectDir: string): Promise<TablesSourceResult | null> {\n const models = await scanModels(projectDir);\n if (models.length === 0) return null;\n\n const tables: NormalizedTable[] = models.map((m) => ({\n schema: '',\n name: m.name,\n type: 'MODEL',\n }));\n\n return { source: 'model', tables, durationMs: 0 };\n}\n\nasync function tablesFromDb(\n projectDir: string,\n connectionName?: string,\n options?: { schema?: string; database?: string },\n): Promise<TablesSourceResult> {\n const connection = await resolveConnection(projectDir, connectionName);\n const connector = createConnector(connection, projectDir);\n\n try {\n await connector.connect();\n const query = getTablesQuery(connection.type, options);\n const start = performance.now();\n const result = await connector.execute(query.sql);\n const tables = query.normalize(result.rows);\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n\n return {\n source: 'db',\n tables,\n connectionName: connection.name,\n connectionType: connection.type,\n durationMs,\n };\n } finally {\n await connector.disconnect();\n }\n}\n\nexport async function resolveTablesSource(\n projectDir: string,\n source: SourceType,\n connectionName?: string,\n options?: { schema?: string; database?: string },\n): Promise<TablesSourceResult> {\n switch (source) {\n case 'catalog': {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n const result = await tablesFromCatalog(projectDir);\n return result || { source: 'catalog', tables: [], durationMs: 0 };\n }\n\n case 'model': {\n const result = await tablesFromModel(projectDir);\n return result || { source: 'model', tables: [], durationMs: 0 };\n }\n\n case 'db':\n return tablesFromDb(projectDir, connectionName, options);\n\n case 'auto': {\n const catalogResult = await tablesFromCatalog(projectDir);\n if (catalogResult) return catalogResult;\n\n const modelResult = await tablesFromModel(projectDir);\n if (modelResult) return modelResult;\n\n return tablesFromDb(projectDir, connectionName, options);\n }\n }\n}\n\n// --- SEARCH ---\n\nfunction searchCatalog(catalog: CatalogFile, keyword: string): SearchResult[] {\n const results: SearchResult[] = [];\n const lower = keyword.toLowerCase();\n\n for (const model of catalog.models || []) {\n const tableParts = (model.table || model.name).split('.');\n const schema = tableParts.length > 1 ? tableParts.slice(0, -1).join('.') : '';\n const tableName = tableParts[tableParts.length - 1];\n\n if (model.name.toLowerCase().includes(lower) || tableName.toLowerCase().includes(lower)) {\n results.push({ type: 'table', schema, table: model.name });\n }\n\n for (const col of model.columns || []) {\n if (col.name.toLowerCase().includes(lower)) {\n results.push({\n type: 'column',\n schema,\n table: model.name,\n column: col.name,\n columnType: col.data_type,\n });\n }\n }\n }\n\n return results;\n}\n\nasync function searchFromDb(\n projectDir: string,\n keyword: string,\n connectionName?: string,\n): Promise<SearchSourceResult> {\n const connection = await resolveConnection(projectDir, connectionName);\n const connector = createConnector(connection, projectDir);\n\n try {\n await connector.connect();\n const query = getSearchQuery(connection.type, keyword);\n const startTime = performance.now();\n const result = await connector.execute(query.sql);\n const durationMs = performance.now() - startTime;\n const results = query.normalize(result.rows as Record<string, unknown>[]);\n\n return {\n source: 'db',\n keyword,\n results,\n connectionName: connection.name,\n connectionType: connection.type,\n durationMs,\n };\n } finally {\n await connector.disconnect();\n }\n}\n\nexport async function resolveSearchSource(\n projectDir: string,\n keyword: string,\n source: SourceType,\n connectionName?: string,\n): Promise<SearchSourceResult> {\n switch (source) {\n case 'catalog': {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n return { source: 'catalog', keyword, results: searchCatalog(catalog, keyword), durationMs: 0 };\n }\n\n case 'model': {\n const models = await scanModels(projectDir);\n const lower = keyword.toLowerCase();\n const results: SearchResult[] = [];\n\n for (const model of models) {\n if (model.name.toLowerCase().includes(lower)) {\n results.push({ type: 'table', schema: '', table: model.name });\n }\n for (const col of model.columns) {\n if (col.name.toLowerCase().includes(lower)) {\n results.push({ type: 'column', schema: '', table: model.name, column: col.name, columnType: col.type });\n }\n }\n }\n\n return { source: 'model', keyword, results, durationMs: 0 };\n }\n\n case 'db':\n return searchFromDb(projectDir, keyword, connectionName);\n\n case 'auto': {\n const catalog = await loadCatalog(projectDir);\n if (catalog?.models?.length) {\n const results = searchCatalog(catalog, keyword);\n if (results.length > 0) {\n return { source: 'catalog', keyword, results, durationMs: 0 };\n }\n }\n\n const models = await scanModels(projectDir);\n if (models.length > 0) {\n const lower = keyword.toLowerCase();\n const results: SearchResult[] = [];\n for (const model of models) {\n if (model.name.toLowerCase().includes(lower)) {\n results.push({ type: 'table', schema: '', table: model.name });\n }\n for (const col of model.columns) {\n if (col.name.toLowerCase().includes(lower)) {\n results.push({ type: 'column', schema: '', table: model.name, column: col.name, columnType: col.type });\n }\n }\n }\n if (results.length > 0) {\n return { source: 'model', keyword, results, durationMs: 0 };\n }\n }\n\n return searchFromDb(projectDir, keyword, connectionName);\n }\n }\n}\n","import { readFile, readdir, access } from 'fs/promises';\nimport { join, extname } from 'path';\nimport type { NormalizedColumn } from './introspection.js';\n\nexport interface ParsedModel {\n name: string;\n description?: string;\n columns: NormalizedColumn[];\n}\n\n/**\n * Parse @name, @description, and @returns from a SQL model file's content.\n * Returns null if no @name annotation is found.\n */\nexport function parseModelReturns(sql: string): ParsedModel | null {\n const nameMatch = sql.match(/--\\s*@name:\\s*(.+)/);\n if (!nameMatch?.[1]) return null;\n\n const name = nameMatch[1].trim();\n\n const descMatch = sql.match(/--\\s*@description:\\s*(.+)/);\n const description = descMatch?.[1]?.trim();\n\n const columns: NormalizedColumn[] = [];\n\n // Find @returns: block and parse each -- - name: type line\n const returnsMatch = sql.match(/--\\s*@returns:\\s*\\n((?:\\s*--\\s+-\\s+.+\\n?)*)/);\n if (returnsMatch?.[1]) {\n const lines = returnsMatch[1].split('\\n');\n for (const line of lines) {\n const colMatch = line.match(/--\\s+-\\s+(\\w+)(?:\\s*:\\s*(\\w+))?/);\n if (colMatch?.[1]) {\n columns.push({\n name: colMatch[1],\n type: colMatch[2] || 'unknown',\n nullable: 'YES',\n });\n }\n }\n }\n\n return { name, description, columns };\n}\n\n/**\n * Recursively find all .sql files in a directory.\n */\nasync function findSqlFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...await findSqlFiles(fullPath));\n } else if (extname(entry.name) === '.sql') {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\n/**\n * Scan models/ directory for SQL files, parse @name and @returns annotations.\n * Returns array of ParsedModel for files that have @name.\n */\nexport async function scanModels(projectDir: string): Promise<ParsedModel[]> {\n const modelsDir = join(projectDir, 'models');\n\n try {\n await access(modelsDir);\n } catch {\n return [];\n }\n\n const sqlFiles = await findSqlFiles(modelsDir);\n const models: ParsedModel[] = [];\n\n for (const filePath of sqlFiles) {\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseModelReturns(content);\n if (parsed) {\n models.push(parsed);\n }\n }\n\n return models;\n}\n"],"mappings":"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","names":["readFile","access","join","join","access","readFile"]}
@@ -1329,6 +1329,76 @@ function resolveSnowflakeAuth(connection) {
1329
1329
  throw new Error(`Auth type "${auth.type}" not yet implemented for Snowflake`);
1330
1330
  }
1331
1331
 
1332
+ // ../../packages/query/dist/connectors/reconnecting.js
1333
+ var CONNECTION_ERROR_PATTERNS = [
1334
+ "terminated connection",
1335
+ "socket hang up",
1336
+ "connection reset",
1337
+ "ECONNRESET",
1338
+ "ECONNREFUSED",
1339
+ "ETIMEDOUT",
1340
+ "connection lost",
1341
+ "gone away",
1342
+ // MySQL: "server has gone away"
1343
+ "not connected"
1344
+ ];
1345
+ function isConnectionError(error) {
1346
+ const message = error instanceof Error ? error.message : String(error);
1347
+ const lower = message.toLowerCase();
1348
+ return CONNECTION_ERROR_PATTERNS.some((pattern) => lower.includes(pattern.toLowerCase()));
1349
+ }
1350
+ var ReconnectingConnector = class {
1351
+ inner;
1352
+ constructor(inner) {
1353
+ this.inner = inner;
1354
+ }
1355
+ async connect() {
1356
+ return this.inner.connect();
1357
+ }
1358
+ async disconnect() {
1359
+ return this.inner.disconnect();
1360
+ }
1361
+ isConnected() {
1362
+ return this.inner.isConnected();
1363
+ }
1364
+ async execute(sql) {
1365
+ await this.ensureConnected();
1366
+ try {
1367
+ return await this.inner.execute(sql);
1368
+ } catch (err) {
1369
+ if (isConnectionError(err)) {
1370
+ await this.reconnect();
1371
+ return this.inner.execute(sql);
1372
+ }
1373
+ throw err;
1374
+ }
1375
+ }
1376
+ async explain(sql) {
1377
+ await this.ensureConnected();
1378
+ try {
1379
+ return await this.inner.explain(sql);
1380
+ } catch (err) {
1381
+ if (isConnectionError(err)) {
1382
+ await this.reconnect();
1383
+ return this.inner.explain(sql);
1384
+ }
1385
+ throw err;
1386
+ }
1387
+ }
1388
+ async ensureConnected() {
1389
+ if (!this.inner.isConnected()) {
1390
+ await this.reconnect();
1391
+ }
1392
+ }
1393
+ async reconnect() {
1394
+ try {
1395
+ await this.inner.disconnect();
1396
+ } catch {
1397
+ }
1398
+ await this.inner.connect();
1399
+ }
1400
+ };
1401
+
1332
1402
  // ../../packages/query/dist/connectors/index.js
1333
1403
  function serializeDateValue(value) {
1334
1404
  if (value.getUTCHours() === 0 && value.getUTCMinutes() === 0 && value.getUTCSeconds() === 0 && value.getUTCMilliseconds() === 0) {
@@ -1516,6 +1586,7 @@ export {
1516
1586
  resolvePostgresAuth,
1517
1587
  resolveMySQLAuth,
1518
1588
  resolveSnowflakeAuth,
1589
+ ReconnectingConnector,
1519
1590
  serializeDateValue,
1520
1591
  expandThis,
1521
1592
  runAssertion,
@@ -1524,4 +1595,4 @@ export {
1524
1595
  checkSchema,
1525
1596
  VERSION
1526
1597
  };
1527
- //# sourceMappingURL=chunk-JYQKDWLG.js.map
1598
+ //# sourceMappingURL=chunk-5N3FYFBV.js.map