crushdataai 1.2.13 → 1.2.15

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.
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueryExecutor = void 0;
4
+ const connections_1 = require("../connections");
5
+ const postgresql_1 = require("../connectors/postgresql");
6
+ const mysql_1 = require("../connectors/mysql");
7
+ // import { BigQueryConnector } from '../connectors/bigquery';
8
+ // import { SnowflakeConnector } from '../connectors/snowflake';
9
+ const shopify_1 = require("../connectors/shopify");
10
+ class QueryExecutor {
11
+ static async execute(query) {
12
+ if (!query.connection) {
13
+ throw new Error('No connection specified in query');
14
+ }
15
+ const connectionConfig = (0, connections_1.getConnection)(query.connection);
16
+ if (!connectionConfig) {
17
+ throw new Error(`Connection "${query.connection}" not found`);
18
+ }
19
+ let result;
20
+ // Execute query based on connection type
21
+ switch (connectionConfig.type) {
22
+ case 'postgresql': {
23
+ const connector = new postgresql_1.PostgreSQLConnector();
24
+ if (!query.sql)
25
+ throw new Error('SQL query required for Postgres');
26
+ result = await connector.executeQuery(connectionConfig, query.sql);
27
+ break;
28
+ }
29
+ case 'mysql': {
30
+ const connector = new mysql_1.MySQLConnector();
31
+ if (!query.sql)
32
+ throw new Error('SQL query required for MySQL');
33
+ result = await connector.executeQuery(connectionConfig, query.sql);
34
+ break;
35
+ }
36
+ // case 'bigquery': {
37
+ // const connector = new BigQueryConnector();
38
+ // if (!query.sql) throw new Error('SQL query required for BigQuery');
39
+ // result = await connector.executeQuery(connectionConfig, query.sql);
40
+ // break;
41
+ // }
42
+ // case 'snowflake': {
43
+ // const connector = new SnowflakeConnector();
44
+ // if (!query.sql) throw new Error('SQL query required for Snowflake');
45
+ // result = await connector.executeQuery(connectionConfig, query.sql);
46
+ // break;
47
+ // }
48
+ case 'shopify': {
49
+ const connector = new shopify_1.ShopifyConnector();
50
+ // For Shopify, query.sql is treated as the table name/endpoint
51
+ const tableName = query.sql?.trim() || 'orders';
52
+ // Fetch first page, limit 1000
53
+ const tableData = await connector.getData(connectionConfig, tableName, 1, 1000);
54
+ result = tableData.rows;
55
+ break;
56
+ }
57
+ default:
58
+ throw new Error(`Unsupported connection type: ${connectionConfig.type}`);
59
+ }
60
+ // Transform result to ChartData format
61
+ return this.transformToChartData(result, query);
62
+ }
63
+ static transformToChartData(data, query) {
64
+ if (!data || data.length === 0) {
65
+ return { labels: [], datasets: [] };
66
+ }
67
+ // Auto-detect labels (first string/date column)
68
+ const keys = Object.keys(data[0]);
69
+ const labelKey = keys.find(k => typeof data[0][k] === 'string' || data[0][k] instanceof Date) || keys[0];
70
+ const labels = data.map(row => String(row[labelKey]));
71
+ // Create datasets for all numeric columns
72
+ const valueKeys = keys.filter(k => k !== labelKey && typeof data[0][k] === 'number');
73
+ const datasets = valueKeys.map((key, i) => ({
74
+ label: key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, ' '),
75
+ values: data.map(row => Number(row[key]))
76
+ }));
77
+ return { labels, datasets };
78
+ }
79
+ }
80
+ exports.QueryExecutor = QueryExecutor;
@@ -0,0 +1,48 @@
1
+ export interface DashboardMetadata {
2
+ title: string;
3
+ generatedAt: string;
4
+ dataRange?: string;
5
+ recordCount?: number;
6
+ }
7
+ export interface KPI {
8
+ id: string;
9
+ label: string;
10
+ value: string;
11
+ trend?: string;
12
+ trendDirection?: 'up' | 'down' | 'neutral';
13
+ }
14
+ export interface ChartQuery {
15
+ type: 'sql' | 'api';
16
+ connection?: string;
17
+ sql?: string;
18
+ }
19
+ export interface ChartDataset {
20
+ label: string;
21
+ values: number[];
22
+ color?: string;
23
+ }
24
+ export interface ChartData {
25
+ labels: string[];
26
+ datasets: ChartDataset[];
27
+ }
28
+ export interface Chart {
29
+ id: string;
30
+ type: string;
31
+ title: string;
32
+ description?: string;
33
+ query?: ChartQuery;
34
+ data: ChartData;
35
+ lastRefreshed?: string;
36
+ }
37
+ export interface Dashboard {
38
+ metadata: DashboardMetadata;
39
+ kpis: KPI[];
40
+ charts: Chart[];
41
+ }
42
+ export interface DashboardListItem {
43
+ id: string;
44
+ title: string;
45
+ generatedAt: string;
46
+ chartCount: number;
47
+ kpiCount: number;
48
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // Dashboard types for the API layer
3
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "crushdataai",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
4
4
  "description": "CLI to install CrushData AI data analyst skill for AI coding assistants",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "crushdataai": "./dist/index.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsc && cd ui-react && npm install && npm run build",
10
+ "build": "tsc && cd ui-react && npm install && npm run build && cd ../ui-dashboard && npm install && npm run build",
11
11
  "dev": "ts-node src/index.ts",
12
12
  "prepublishOnly": "npm run build"
13
13
  },
@@ -47,7 +47,8 @@
47
47
  "files": [
48
48
  "dist",
49
49
  "assets",
50
- "ui"
50
+ "ui",
51
+ "ui-dashboard-dist"
51
52
  ],
52
53
  "repository": {
53
54
  "type": "git",