yamchart 0.3.6 → 0.3.9
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.
- package/dist/{chunk-7HKIUUVE.js → chunk-ENOTMVPI.js} +27 -4
- package/dist/{chunk-7HKIUUVE.js.map → chunk-ENOTMVPI.js.map} +1 -1
- package/dist/{chunk-3CLMQNNR.js → chunk-G7246EH3.js} +3 -3
- package/dist/chunk-G7246EH3.js.map +1 -0
- package/dist/{dev-PWY7UVIO.js → dev-CPZ3M5EE.js} +134 -70
- package/dist/dev-CPZ3M5EE.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/public/assets/{index-DY3hJB9N.js → index-D9hfHuVH.js} +99 -99
- package/dist/public/assets/{index-ogBV05Wr.css → index-xXsNnf9d.css} +1 -1
- package/dist/public/assets/{index.es-DTRIdI7C.js → index.es-B4AYqvku.js} +1 -1
- package/dist/public/index.html +2 -2
- package/dist/{update-GWPF5AS6.js → update-VUUPJBZ7.js} +3 -3
- package/dist/update-VUUPJBZ7.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-3CLMQNNR.js.map +0 -1
- package/dist/dev-PWY7UVIO.js.map +0 -1
- package/dist/update-GWPF5AS6.js.map +0 -1
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ScheduleSchema,
|
|
7
7
|
loadEnvFile,
|
|
8
8
|
validateProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ENOTMVPI.js";
|
|
10
10
|
import {
|
|
11
11
|
AuthDatabase,
|
|
12
12
|
generateSessionToken,
|
|
@@ -289,6 +289,10 @@ var ConfigLoader = class {
|
|
|
289
289
|
return this.models.get(name);
|
|
290
290
|
}
|
|
291
291
|
getDefaultConnection() {
|
|
292
|
+
const envConnection = process.env.YAMCHART_CONNECTION;
|
|
293
|
+
if (envConnection) {
|
|
294
|
+
return this.connections.get(envConnection);
|
|
295
|
+
}
|
|
292
296
|
const defaultName = this.project?.defaults?.connection;
|
|
293
297
|
if (defaultName) {
|
|
294
298
|
return this.connections.get(defaultName);
|
|
@@ -529,6 +533,49 @@ function createConnectorFromConfig(connection, options) {
|
|
|
529
533
|
throw new Error(`Unsupported connection type: ${connection.type}`);
|
|
530
534
|
}
|
|
531
535
|
}
|
|
536
|
+
function buildConnectionInfo(connection) {
|
|
537
|
+
const info2 = {
|
|
538
|
+
name: connection.name,
|
|
539
|
+
type: connection.type
|
|
540
|
+
};
|
|
541
|
+
switch (connection.type) {
|
|
542
|
+
case "duckdb": {
|
|
543
|
+
const c = connection;
|
|
544
|
+
info2.path = c.config.path;
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case "postgres": {
|
|
548
|
+
const c = connection;
|
|
549
|
+
info2.host = c.config.host;
|
|
550
|
+
info2.port = c.config.port;
|
|
551
|
+
info2.database = c.config.database;
|
|
552
|
+
info2.schema = c.config.schema;
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
case "mysql": {
|
|
556
|
+
const c = connection;
|
|
557
|
+
info2.host = c.config.host;
|
|
558
|
+
info2.port = c.config.port;
|
|
559
|
+
info2.database = c.config.database;
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
case "sqlite": {
|
|
563
|
+
const c = connection;
|
|
564
|
+
info2.path = c.config.path;
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
567
|
+
case "snowflake": {
|
|
568
|
+
const c = connection;
|
|
569
|
+
info2.account = c.config.account;
|
|
570
|
+
info2.warehouse = c.config.warehouse;
|
|
571
|
+
info2.database = c.config.database;
|
|
572
|
+
info2.schema = c.config.schema;
|
|
573
|
+
info2.role = c.config.role;
|
|
574
|
+
break;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return info2;
|
|
578
|
+
}
|
|
532
579
|
async function testConnection(connection, options) {
|
|
533
580
|
const start = performance.now();
|
|
534
581
|
let connector = null;
|
|
@@ -799,12 +846,30 @@ async function dashboardRoutes(fastify, options) {
|
|
|
799
846
|
});
|
|
800
847
|
fastify.post("/api/dashboards/:id", async (request, reply) => {
|
|
801
848
|
const { id } = request.params;
|
|
802
|
-
const { layout, message } = request.body;
|
|
849
|
+
const { layout, tab, tabLayout, message } = request.body;
|
|
803
850
|
const dashboard = configLoader.getDashboardByName(id);
|
|
804
851
|
if (!dashboard) {
|
|
805
852
|
return reply.status(404).send({ error: `Dashboard not found: ${id}` });
|
|
806
853
|
}
|
|
807
|
-
|
|
854
|
+
let updated;
|
|
855
|
+
if (dashboard.tabs) {
|
|
856
|
+
if (!tab || !tabLayout) {
|
|
857
|
+
return reply.status(400).send({ error: 'Tabbed dashboard requires "tab" and "tabLayout" fields' });
|
|
858
|
+
}
|
|
859
|
+
const tabIndex = dashboard.tabs.findIndex((t) => t.name === tab);
|
|
860
|
+
if (tabIndex === -1) {
|
|
861
|
+
return reply.status(400).send({ error: `Tab not found: ${tab}` });
|
|
862
|
+
}
|
|
863
|
+
const existingTab = dashboard.tabs[tabIndex];
|
|
864
|
+
const newTabs = [...dashboard.tabs];
|
|
865
|
+
newTabs[tabIndex] = { ...existingTab, layout: tabLayout };
|
|
866
|
+
updated = { ...dashboard, tabs: newTabs };
|
|
867
|
+
} else {
|
|
868
|
+
if (!layout) {
|
|
869
|
+
return reply.status(400).send({ error: 'Non-tabbed dashboard requires "layout" field' });
|
|
870
|
+
}
|
|
871
|
+
updated = { ...dashboard, layout };
|
|
872
|
+
}
|
|
808
873
|
const filePath = join3(projectDir, "dashboards", `${id}.yaml`);
|
|
809
874
|
await writeFile(filePath, stringifyYaml(updated));
|
|
810
875
|
await configLoader.load();
|
|
@@ -818,7 +883,7 @@ async function dashboardRoutes(fastify, options) {
|
|
|
818
883
|
});
|
|
819
884
|
fastify.post("/api/dashboards/:id/warm-cache", async (request, reply) => {
|
|
820
885
|
const { id } = request.params;
|
|
821
|
-
const { params = {} } = request.body;
|
|
886
|
+
const { params = {}, tab } = request.body;
|
|
822
887
|
const dashboard = configLoader.getDashboardByName(id);
|
|
823
888
|
if (!dashboard) {
|
|
824
889
|
return reply.status(404).send({ error: `Dashboard not found: ${id}` });
|
|
@@ -827,12 +892,28 @@ async function dashboardRoutes(fastify, options) {
|
|
|
827
892
|
return reply.status(500).send({ error: "Query service not available" });
|
|
828
893
|
}
|
|
829
894
|
const chartRefs = [];
|
|
830
|
-
|
|
831
|
-
for (const
|
|
832
|
-
|
|
833
|
-
|
|
895
|
+
const extractFromLayout = (layout) => {
|
|
896
|
+
for (const row of layout.rows) {
|
|
897
|
+
for (const widget of row.widgets) {
|
|
898
|
+
if (widget.type === "chart" && widget.ref) {
|
|
899
|
+
chartRefs.push(widget.ref);
|
|
900
|
+
}
|
|
834
901
|
}
|
|
835
902
|
}
|
|
903
|
+
};
|
|
904
|
+
if (dashboard.tabs) {
|
|
905
|
+
if (tab) {
|
|
906
|
+
const matchingTab = dashboard.tabs.find((t) => t.name === tab);
|
|
907
|
+
if (matchingTab) {
|
|
908
|
+
extractFromLayout(matchingTab.layout);
|
|
909
|
+
}
|
|
910
|
+
} else {
|
|
911
|
+
for (const t of dashboard.tabs) {
|
|
912
|
+
extractFromLayout(t.layout);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
} else if (dashboard.layout) {
|
|
916
|
+
extractFromLayout(dashboard.layout);
|
|
836
917
|
}
|
|
837
918
|
const results = await Promise.all(chartRefs.map(async (chartRef) => {
|
|
838
919
|
const chart = configLoader.getChartByName(chartRef);
|
|
@@ -13326,32 +13407,8 @@ async function createServer(options) {
|
|
|
13326
13407
|
if (!defaultConnection) {
|
|
13327
13408
|
throw new Error("No connection configured");
|
|
13328
13409
|
}
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
const duckdbConfig = defaultConnection;
|
|
13332
|
-
const dbPath = duckdbConfig.config.path.startsWith("/") ? duckdbConfig.config.path : join4(projectDir, duckdbConfig.config.path);
|
|
13333
|
-
connector = new DuckDBConnector({ path: dbPath });
|
|
13334
|
-
await connector.connect();
|
|
13335
|
-
} else if (defaultConnection.type === "postgres") {
|
|
13336
|
-
const pgConnection = defaultConnection;
|
|
13337
|
-
const credentials = resolvePostgresAuth(pgConnection);
|
|
13338
|
-
connector = new PostgresConnector({
|
|
13339
|
-
host: pgConnection.config.host,
|
|
13340
|
-
port: pgConnection.config.port,
|
|
13341
|
-
database: pgConnection.config.database,
|
|
13342
|
-
schema: pgConnection.config.schema,
|
|
13343
|
-
ssl: pgConnection.config.ssl,
|
|
13344
|
-
user: credentials.user,
|
|
13345
|
-
password: credentials.password,
|
|
13346
|
-
min: pgConnection.pool?.min_connections,
|
|
13347
|
-
max: pgConnection.pool?.max_connections,
|
|
13348
|
-
idleTimeoutMillis: pgConnection.pool?.idle_timeout,
|
|
13349
|
-
statementTimeout: pgConnection.query?.timeout
|
|
13350
|
-
});
|
|
13351
|
-
await connector.connect();
|
|
13352
|
-
} else {
|
|
13353
|
-
throw new Error(`Unsupported connection type: ${defaultConnection.type}`);
|
|
13354
|
-
}
|
|
13410
|
+
const connector = createConnectorFromConfig(defaultConnection, { projectDir });
|
|
13411
|
+
await connector.connect();
|
|
13355
13412
|
const project = configLoader.getProject();
|
|
13356
13413
|
const cacheTtl = project.defaults?.cache_ttl ? parseTtl2(project.defaults.cache_ttl) : 5 * 60 * 1e3;
|
|
13357
13414
|
const cache = new MemoryCache({
|
|
@@ -13383,26 +13440,16 @@ async function createServer(options) {
|
|
|
13383
13440
|
if (schedules.length > 0) {
|
|
13384
13441
|
schedulerService.start(schedules);
|
|
13385
13442
|
}
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
schema: defaultConnection.config.schema
|
|
13397
|
-
}
|
|
13398
|
-
};
|
|
13399
|
-
fastify.get("/api/health", async () => ({
|
|
13400
|
-
status: "ok",
|
|
13401
|
-
version: VERSION,
|
|
13402
|
-
project: project.name,
|
|
13403
|
-
environment: process.env.NODE_ENV || "development",
|
|
13404
|
-
connection: connectionInfo
|
|
13405
|
-
}));
|
|
13443
|
+
fastify.get("/api/health", async () => {
|
|
13444
|
+
const currentConnection = configLoader.getDefaultConnection();
|
|
13445
|
+
return {
|
|
13446
|
+
status: "ok",
|
|
13447
|
+
version: VERSION,
|
|
13448
|
+
project: configLoader.getProject().name,
|
|
13449
|
+
environment: process.env.NODE_ENV || "development",
|
|
13450
|
+
connection: currentConnection ? buildConnectionInfo(currentConnection) : void 0
|
|
13451
|
+
};
|
|
13452
|
+
});
|
|
13406
13453
|
if (authDb) {
|
|
13407
13454
|
const secureCookies = process.env.NODE_ENV === "production";
|
|
13408
13455
|
const sessionTtlMs = options.localAuth.sessionTtlMs;
|
|
@@ -13554,24 +13601,41 @@ async function runDevServer(projectDir, options) {
|
|
|
13554
13601
|
}
|
|
13555
13602
|
success(`Validation passed (${validation.stats.passed} files)`);
|
|
13556
13603
|
newline();
|
|
13557
|
-
|
|
13558
|
-
let
|
|
13604
|
+
let usesBrowserAuth = false;
|
|
13605
|
+
let localAuth;
|
|
13559
13606
|
try {
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13607
|
+
const { readFileSync } = await import("fs");
|
|
13608
|
+
const { parse } = await import("yaml");
|
|
13609
|
+
const raw = readFileSync(resolve(projectDir, "yamchart.yaml"), "utf-8");
|
|
13610
|
+
const projectConfig = parse(raw);
|
|
13611
|
+
if (projectConfig?.auth?.enabled) {
|
|
13612
|
+
localAuth = {
|
|
13613
|
+
enabled: true,
|
|
13614
|
+
dbPath: projectConfig.auth.db_path ? resolve(projectConfig.auth.db_path.replace(/^~/, homedir())) : resolve(homedir(), ".yamchart", "auth.db"),
|
|
13615
|
+
sessionTtlMs: projectConfig.auth.session_ttl ? parseTtl(projectConfig.auth.session_ttl) : 30 * 24 * 60 * 60 * 1e3
|
|
13616
|
+
};
|
|
13617
|
+
}
|
|
13618
|
+
const connectionDir = resolve(projectDir, "connections");
|
|
13619
|
+
const targetConn = process.env.YAMCHART_CONNECTION || projectConfig?.defaults?.connection;
|
|
13620
|
+
if (targetConn) {
|
|
13621
|
+
try {
|
|
13622
|
+
const connRaw = readFileSync(resolve(connectionDir, `${targetConn}.yaml`), "utf-8");
|
|
13623
|
+
const connConfig = parse(connRaw);
|
|
13624
|
+
if (connConfig?.auth?.type === "externalbrowser") {
|
|
13625
|
+
usesBrowserAuth = true;
|
|
13626
|
+
}
|
|
13627
|
+
} catch {
|
|
13572
13628
|
}
|
|
13573
|
-
} catch {
|
|
13574
13629
|
}
|
|
13630
|
+
} catch {
|
|
13631
|
+
}
|
|
13632
|
+
if (usesBrowserAuth) {
|
|
13633
|
+
info("Snowflake SSO \u2014 opening browser for authentication...");
|
|
13634
|
+
newline();
|
|
13635
|
+
}
|
|
13636
|
+
const spinner2 = spinner("Starting server...");
|
|
13637
|
+
let server;
|
|
13638
|
+
try {
|
|
13575
13639
|
server = await createServer({
|
|
13576
13640
|
projectDir,
|
|
13577
13641
|
port: options.port,
|
|
@@ -13621,4 +13685,4 @@ async function runDevServer(projectDir, options) {
|
|
|
13621
13685
|
export {
|
|
13622
13686
|
runDevServer
|
|
13623
13687
|
};
|
|
13624
|
-
//# sourceMappingURL=dev-
|
|
13688
|
+
//# sourceMappingURL=dev-CPZ3M5EE.js.map
|