@querypanel/node-sdk 1.0.42 → 1.0.43

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/index.cjs CHANGED
@@ -1164,6 +1164,9 @@ function buildSchemaRequest(databaseName, adapter, introspection, metadata) {
1164
1164
  return request;
1165
1165
  }
1166
1166
 
1167
+ // src/routes/modify.ts
1168
+ var import_node_crypto4 = __toESM(require("crypto"), 1);
1169
+
1167
1170
  // src/routes/query.ts
1168
1171
  var import_node_crypto3 = __toESM(require("crypto"), 1);
1169
1172
  async function ask(client, queryEngine, question, options, signal) {
@@ -1325,11 +1328,216 @@ function anonymizeResults(rows) {
1325
1328
  });
1326
1329
  }
1327
1330
 
1328
- // src/routes/vizspec.ts
1329
- var import_node_crypto4 = __toESM(require("crypto"), 1);
1330
- async function generateVizSpec(client, input, options, signal) {
1331
+ // src/routes/modify.ts
1332
+ function buildModifiedQuestion(originalQuestion, modifications) {
1333
+ const hints = [];
1334
+ if (modifications.timeGranularity) {
1335
+ hints.push(`group results by ${modifications.timeGranularity}`);
1336
+ }
1337
+ if (modifications.dateRange) {
1338
+ const parts = [];
1339
+ if (modifications.dateRange.from) {
1340
+ parts.push(`from ${modifications.dateRange.from}`);
1341
+ }
1342
+ if (modifications.dateRange.to) {
1343
+ parts.push(`to ${modifications.dateRange.to}`);
1344
+ }
1345
+ if (parts.length > 0) {
1346
+ hints.push(`filter date range ${parts.join(" ")}`);
1347
+ }
1348
+ }
1349
+ if (modifications.additionalInstructions) {
1350
+ hints.push(modifications.additionalInstructions);
1351
+ }
1352
+ if (hints.length === 0) {
1353
+ return originalQuestion;
1354
+ }
1355
+ return `${originalQuestion} (${hints.join(", ")})`;
1356
+ }
1357
+ function buildVizHints(modifications) {
1358
+ const hints = {};
1359
+ if (modifications.chartType) {
1360
+ hints.chartType = modifications.chartType;
1361
+ }
1362
+ if (modifications.xAxis) {
1363
+ hints.xAxis = modifications.xAxis;
1364
+ }
1365
+ if (modifications.yAxis) {
1366
+ hints.yAxis = modifications.yAxis;
1367
+ }
1368
+ if (modifications.series) {
1369
+ hints.series = modifications.series;
1370
+ }
1371
+ if (modifications.stacking) {
1372
+ hints.stacking = modifications.stacking;
1373
+ }
1374
+ if (modifications.limit !== void 0) {
1375
+ hints.limit = modifications.limit;
1376
+ }
1377
+ return hints;
1378
+ }
1379
+ function resolveTenantId5(client, tenantId) {
1380
+ const resolved = tenantId ?? client.getDefaultTenantId();
1381
+ if (!resolved) {
1382
+ throw new Error(
1383
+ "tenantId is required. Provide it per request or via defaultTenantId option."
1384
+ );
1385
+ }
1386
+ return resolved;
1387
+ }
1388
+ async function modifyChart(client, queryEngine, input, options, signal) {
1331
1389
  const tenantId = resolveTenantId5(client, options?.tenantId);
1332
1390
  const sessionId = import_node_crypto4.default.randomUUID();
1391
+ const chartType = options?.chartType ?? "vega-lite";
1392
+ const hasSqlMods = !!input.sqlModifications;
1393
+ const hasVizMods = !!input.vizModifications;
1394
+ const hasCustomSql = !!input.sqlModifications?.customSql;
1395
+ let finalSql = input.sql;
1396
+ let finalParams = input.params ?? {};
1397
+ let paramMetadata = [];
1398
+ let rationale;
1399
+ let queryId;
1400
+ let sqlChanged = false;
1401
+ const databaseName = input.database ?? queryEngine.getDefaultDatabase();
1402
+ if (!databaseName) {
1403
+ throw new Error(
1404
+ "No database specified. Provide database in input or attach a default database."
1405
+ );
1406
+ }
1407
+ const metadata = queryEngine.getDatabaseMetadata(databaseName);
1408
+ let tenantSettings;
1409
+ if (metadata?.tenantFieldName) {
1410
+ tenantSettings = {
1411
+ tenantFieldName: metadata.tenantFieldName,
1412
+ tenantFieldType: metadata.tenantFieldType,
1413
+ enforceTenantIsolation: metadata.enforceTenantIsolation
1414
+ };
1415
+ }
1416
+ if (hasCustomSql) {
1417
+ finalSql = input.sqlModifications.customSql;
1418
+ finalParams = {};
1419
+ paramMetadata = [];
1420
+ sqlChanged = true;
1421
+ } else if (hasSqlMods && !hasCustomSql) {
1422
+ const modifiedQuestion = buildModifiedQuestion(
1423
+ input.question,
1424
+ input.sqlModifications
1425
+ );
1426
+ const queryResponse = await client.post(
1427
+ "/query",
1428
+ {
1429
+ question: modifiedQuestion,
1430
+ previous_sql: input.sql,
1431
+ ...options?.maxRetry ? { max_retry: options.maxRetry } : {},
1432
+ ...tenantSettings ? { tenant_settings: tenantSettings } : {},
1433
+ ...databaseName ? { database: databaseName } : {},
1434
+ ...metadata?.dialect ? { dialect: metadata.dialect } : {}
1435
+ },
1436
+ tenantId,
1437
+ options?.userId,
1438
+ options?.scopes,
1439
+ signal,
1440
+ sessionId
1441
+ );
1442
+ finalSql = queryResponse.sql;
1443
+ paramMetadata = Array.isArray(queryResponse.params) ? queryResponse.params : [];
1444
+ finalParams = queryEngine.mapGeneratedParams(paramMetadata);
1445
+ rationale = queryResponse.rationale;
1446
+ queryId = queryResponse.queryId;
1447
+ sqlChanged = finalSql !== input.sql;
1448
+ }
1449
+ const execution = await queryEngine.validateAndExecute(
1450
+ finalSql,
1451
+ finalParams,
1452
+ databaseName,
1453
+ tenantId
1454
+ );
1455
+ const rows = execution.rows ?? [];
1456
+ let chart = {
1457
+ specType: chartType,
1458
+ notes: rows.length === 0 ? "Query returned no rows." : null
1459
+ };
1460
+ if (rows.length > 0) {
1461
+ const vizHints = hasVizMods ? buildVizHints(input.vizModifications) : {};
1462
+ if (chartType === "vizspec") {
1463
+ const vizspecResponse = await client.post(
1464
+ "/vizspec",
1465
+ {
1466
+ question: input.question,
1467
+ sql: finalSql,
1468
+ rationale,
1469
+ fields: execution.fields,
1470
+ rows: anonymizeResults(rows),
1471
+ max_retries: options?.chartMaxRetries ?? 3,
1472
+ query_id: queryId,
1473
+ // Include viz hints for the chart generator
1474
+ ...hasVizMods ? { encoding_hints: vizHints } : {}
1475
+ },
1476
+ tenantId,
1477
+ options?.userId,
1478
+ options?.scopes,
1479
+ signal,
1480
+ sessionId
1481
+ );
1482
+ chart = {
1483
+ vizSpec: vizspecResponse.spec,
1484
+ specType: "vizspec",
1485
+ notes: vizspecResponse.notes
1486
+ };
1487
+ } else {
1488
+ const chartResponse = await client.post(
1489
+ "/chart",
1490
+ {
1491
+ question: input.question,
1492
+ sql: finalSql,
1493
+ rationale,
1494
+ fields: execution.fields,
1495
+ rows: anonymizeResults(rows),
1496
+ max_retries: options?.chartMaxRetries ?? 3,
1497
+ query_id: queryId,
1498
+ // Include viz hints for the chart generator
1499
+ ...hasVizMods ? { encoding_hints: vizHints } : {}
1500
+ },
1501
+ tenantId,
1502
+ options?.userId,
1503
+ options?.scopes,
1504
+ signal,
1505
+ sessionId
1506
+ );
1507
+ chart = {
1508
+ vegaLiteSpec: chartResponse.chart ? {
1509
+ ...chartResponse.chart,
1510
+ data: { values: rows }
1511
+ } : null,
1512
+ specType: "vega-lite",
1513
+ notes: chartResponse.notes
1514
+ };
1515
+ }
1516
+ }
1517
+ return {
1518
+ sql: finalSql,
1519
+ params: finalParams,
1520
+ paramMetadata,
1521
+ rationale,
1522
+ dialect: metadata?.dialect ?? "unknown",
1523
+ queryId,
1524
+ rows,
1525
+ fields: execution.fields,
1526
+ chart,
1527
+ attempts: 1,
1528
+ target_db: databaseName,
1529
+ modified: {
1530
+ sqlChanged,
1531
+ vizChanged: hasVizMods
1532
+ }
1533
+ };
1534
+ }
1535
+
1536
+ // src/routes/vizspec.ts
1537
+ var import_node_crypto5 = __toESM(require("crypto"), 1);
1538
+ async function generateVizSpec(client, input, options, signal) {
1539
+ const tenantId = resolveTenantId6(client, options?.tenantId);
1540
+ const sessionId = import_node_crypto5.default.randomUUID();
1333
1541
  const response = await client.post(
1334
1542
  "/vizspec",
1335
1543
  {
@@ -1349,7 +1557,7 @@ async function generateVizSpec(client, input, options, signal) {
1349
1557
  );
1350
1558
  return response;
1351
1559
  }
1352
- function resolveTenantId5(client, tenantId) {
1560
+ function resolveTenantId6(client, tenantId) {
1353
1561
  const resolved = tenantId ?? client.getDefaultTenantId();
1354
1562
  if (!resolved) {
1355
1563
  throw new Error(
@@ -1406,6 +1614,30 @@ var QueryPanelSdkAPI = class {
1406
1614
  const adapter = this.queryEngine.getDatabase(databaseName);
1407
1615
  return await adapter.introspect(tables ? { tables } : void 0);
1408
1616
  }
1617
+ /**
1618
+ * Syncs the database schema to QueryPanel for natural language query generation.
1619
+ *
1620
+ * This method introspects your database schema and uploads it to QueryPanel's
1621
+ * vector store. The schema is used by the LLM to generate accurate SQL queries.
1622
+ * Schema embedding is skipped if no changes are detected (drift detection).
1623
+ *
1624
+ * @param databaseName - Name of the attached database to sync
1625
+ * @param options - Sync options including tenantId and forceReindex
1626
+ * @param signal - Optional AbortSignal for cancellation
1627
+ * @returns Response with sync status and chunk counts
1628
+ *
1629
+ * @example
1630
+ * ```typescript
1631
+ * // Basic schema sync (skips if no changes)
1632
+ * await qp.syncSchema("analytics", { tenantId: "tenant_123" });
1633
+ *
1634
+ * // Force re-embedding even if schema hasn't changed
1635
+ * await qp.syncSchema("analytics", {
1636
+ * tenantId: "tenant_123",
1637
+ * forceReindex: true,
1638
+ * });
1639
+ * ```
1640
+ */
1409
1641
  async syncSchema(databaseName, options, signal) {
1410
1642
  return await syncSchema(
1411
1643
  this.client,
@@ -1416,6 +1648,36 @@ var QueryPanelSdkAPI = class {
1416
1648
  );
1417
1649
  }
1418
1650
  // Natural language query
1651
+ /**
1652
+ * Generates SQL from a natural language question and executes it.
1653
+ *
1654
+ * This is the primary method for converting user questions into data.
1655
+ * It handles the complete flow: SQL generation → validation → execution → chart generation.
1656
+ *
1657
+ * @param question - Natural language question (e.g., "Show revenue by country")
1658
+ * @param options - Query options including tenantId, database, and retry settings
1659
+ * @param signal - Optional AbortSignal for cancellation
1660
+ * @returns Response with SQL, executed data rows, and generated chart
1661
+ * @throws {Error} When SQL generation or execution fails after all retries
1662
+ *
1663
+ * @example
1664
+ * ```typescript
1665
+ * // Basic query
1666
+ * const result = await qp.ask("Top 10 customers by revenue", {
1667
+ * tenantId: "tenant_123",
1668
+ * database: "analytics",
1669
+ * });
1670
+ * console.log(result.sql); // Generated SQL
1671
+ * console.log(result.rows); // Query results
1672
+ * console.log(result.chart); // Vega-Lite chart spec
1673
+ *
1674
+ * // With automatic SQL repair on failure
1675
+ * const result = await qp.ask("Show monthly trends", {
1676
+ * tenantId: "tenant_123",
1677
+ * maxRetry: 3, // Retry up to 3 times if SQL fails
1678
+ * });
1679
+ * ```
1680
+ */
1419
1681
  async ask(question, options, signal) {
1420
1682
  return await ask(
1421
1683
  this.client,
@@ -1426,6 +1688,28 @@ var QueryPanelSdkAPI = class {
1426
1688
  );
1427
1689
  }
1428
1690
  // VizSpec generation
1691
+ /**
1692
+ * Generates a VizSpec visualization specification from query results.
1693
+ *
1694
+ * Use this when you have raw SQL results and want to generate a chart
1695
+ * specification without going through the full ask() flow. Useful for
1696
+ * re-generating charts with different settings.
1697
+ *
1698
+ * @param input - VizSpec generation input with question, SQL, and result data
1699
+ * @param options - Optional settings for tenant and retries
1700
+ * @param signal - Optional AbortSignal for cancellation
1701
+ * @returns VizSpec specification for chart, table, or metric visualization
1702
+ *
1703
+ * @example
1704
+ * ```typescript
1705
+ * const vizspec = await qp.generateVizSpec({
1706
+ * question: "Revenue by country",
1707
+ * sql: "SELECT country, SUM(revenue) FROM orders GROUP BY country",
1708
+ * fields: ["country", "revenue"],
1709
+ * rows: queryResults,
1710
+ * }, { tenantId: "tenant_123" });
1711
+ * ```
1712
+ */
1429
1713
  async generateVizSpec(input, options, signal) {
1430
1714
  return await generateVizSpec(
1431
1715
  this.client,
@@ -1434,10 +1718,125 @@ var QueryPanelSdkAPI = class {
1434
1718
  signal
1435
1719
  );
1436
1720
  }
1721
+ // Chart modification
1722
+ /**
1723
+ * Modifies a chart by regenerating SQL and/or applying visualization changes.
1724
+ *
1725
+ * This method supports three modes of operation:
1726
+ *
1727
+ * 1. **SQL Modifications**: When `sqlModifications` is provided, the SQL is
1728
+ * regenerated using the query endpoint with modification hints. If `customSql`
1729
+ * is set, it's used directly without regeneration.
1730
+ *
1731
+ * 2. **Visualization Modifications**: When only `vizModifications` is provided,
1732
+ * the existing SQL is re-executed and a new chart is generated with the
1733
+ * specified encoding preferences.
1734
+ *
1735
+ * 3. **Combined**: Both SQL and visualization modifications can be applied
1736
+ * together. SQL is regenerated first, then viz modifications are applied.
1737
+ *
1738
+ * @param input - Chart modification input with source data and modifications
1739
+ * @param options - Optional settings for tenant, user, and chart generation
1740
+ * @param signal - Optional AbortSignal for cancellation
1741
+ * @returns Modified chart response with SQL, data, and chart specification
1742
+ *
1743
+ * @example
1744
+ * ```typescript
1745
+ * // Change chart type and axis from an ask() response
1746
+ * const modified = await qp.modifyChart({
1747
+ * sql: response.sql,
1748
+ * question: "revenue by country",
1749
+ * database: "analytics",
1750
+ * vizModifications: {
1751
+ * chartType: "bar",
1752
+ * xAxis: { field: "country" },
1753
+ * yAxis: { field: "revenue", aggregate: "sum" },
1754
+ * },
1755
+ * }, { tenantId: "tenant_123" });
1756
+ *
1757
+ * // Change time granularity (triggers SQL regeneration)
1758
+ * const monthly = await qp.modifyChart({
1759
+ * sql: response.sql,
1760
+ * question: "revenue over time",
1761
+ * database: "analytics",
1762
+ * sqlModifications: {
1763
+ * timeGranularity: "month",
1764
+ * dateRange: { from: "2024-01-01", to: "2024-12-31" },
1765
+ * },
1766
+ * }, { tenantId: "tenant_123" });
1767
+ *
1768
+ * // Direct SQL edit with chart regeneration
1769
+ * const customized = await qp.modifyChart({
1770
+ * sql: response.sql,
1771
+ * question: "revenue by country",
1772
+ * database: "analytics",
1773
+ * sqlModifications: {
1774
+ * customSql: "SELECT country, SUM(revenue) FROM orders GROUP BY country",
1775
+ * },
1776
+ * }, { tenantId: "tenant_123" });
1777
+ * ```
1778
+ */
1779
+ async modifyChart(input, options, signal) {
1780
+ return await modifyChart(
1781
+ this.client,
1782
+ this.queryEngine,
1783
+ input,
1784
+ options,
1785
+ signal
1786
+ );
1787
+ }
1437
1788
  // Chart CRUD operations
1789
+ /**
1790
+ * Saves a chart to the QueryPanel system for later retrieval.
1791
+ *
1792
+ * Charts store the SQL query, parameters, and visualization spec - never the actual data.
1793
+ * Data is fetched live when the chart is rendered or refreshed.
1794
+ *
1795
+ * @param body - Chart data including title, SQL, and Vega-Lite spec
1796
+ * @param options - Tenant, user, and scope options
1797
+ * @param signal - Optional AbortSignal for cancellation
1798
+ * @returns The saved chart with its generated ID
1799
+ *
1800
+ * @example
1801
+ * ```typescript
1802
+ * const savedChart = await qp.createChart({
1803
+ * title: "Revenue by Country",
1804
+ * sql: response.sql,
1805
+ * sql_params: response.params,
1806
+ * vega_lite_spec: response.chart.vegaLiteSpec,
1807
+ * target_db: "analytics",
1808
+ * }, { tenantId: "tenant_123", userId: "user_456" });
1809
+ * ```
1810
+ */
1438
1811
  async createChart(body, options, signal) {
1439
1812
  return await createChart(this.client, body, options, signal);
1440
1813
  }
1814
+ /**
1815
+ * Lists saved charts with optional filtering and pagination.
1816
+ *
1817
+ * Use `includeData: true` to execute each chart's SQL and include live data.
1818
+ *
1819
+ * @param options - Filtering, pagination, and data options
1820
+ * @param signal - Optional AbortSignal for cancellation
1821
+ * @returns Paginated list of charts
1822
+ *
1823
+ * @example
1824
+ * ```typescript
1825
+ * // List charts with pagination
1826
+ * const charts = await qp.listCharts({
1827
+ * tenantId: "tenant_123",
1828
+ * pagination: { page: 1, limit: 10 },
1829
+ * sortBy: "created_at",
1830
+ * sortDir: "desc",
1831
+ * });
1832
+ *
1833
+ * // List with live data
1834
+ * const chartsWithData = await qp.listCharts({
1835
+ * tenantId: "tenant_123",
1836
+ * includeData: true,
1837
+ * });
1838
+ * ```
1839
+ */
1441
1840
  async listCharts(options, signal) {
1442
1841
  return await listCharts(
1443
1842
  this.client,
@@ -1446,6 +1845,24 @@ var QueryPanelSdkAPI = class {
1446
1845
  signal
1447
1846
  );
1448
1847
  }
1848
+ /**
1849
+ * Retrieves a single chart by ID with live data.
1850
+ *
1851
+ * The chart's SQL is automatically executed and data is included in the response.
1852
+ *
1853
+ * @param id - Chart ID
1854
+ * @param options - Tenant, user, and scope options
1855
+ * @param signal - Optional AbortSignal for cancellation
1856
+ * @returns Chart with live data populated
1857
+ *
1858
+ * @example
1859
+ * ```typescript
1860
+ * const chart = await qp.getChart("chart_123", {
1861
+ * tenantId: "tenant_123",
1862
+ * });
1863
+ * console.log(chart.vega_lite_spec.data.values); // Live data
1864
+ * ```
1865
+ */
1449
1866
  async getChart(id, options, signal) {
1450
1867
  return await getChart(
1451
1868
  this.client,
@@ -1455,6 +1872,23 @@ var QueryPanelSdkAPI = class {
1455
1872
  signal
1456
1873
  );
1457
1874
  }
1875
+ /**
1876
+ * Updates an existing chart's metadata or configuration.
1877
+ *
1878
+ * @param id - Chart ID to update
1879
+ * @param body - Fields to update (partial update supported)
1880
+ * @param options - Tenant, user, and scope options
1881
+ * @param signal - Optional AbortSignal for cancellation
1882
+ * @returns Updated chart
1883
+ *
1884
+ * @example
1885
+ * ```typescript
1886
+ * const updated = await qp.updateChart("chart_123", {
1887
+ * title: "Updated Chart Title",
1888
+ * description: "New description",
1889
+ * }, { tenantId: "tenant_123" });
1890
+ * ```
1891
+ */
1458
1892
  async updateChart(id, body, options, signal) {
1459
1893
  return await updateChart(
1460
1894
  this.client,
@@ -1464,10 +1898,42 @@ var QueryPanelSdkAPI = class {
1464
1898
  signal
1465
1899
  );
1466
1900
  }
1901
+ /**
1902
+ * Deletes a chart permanently.
1903
+ *
1904
+ * @param id - Chart ID to delete
1905
+ * @param options - Tenant, user, and scope options
1906
+ * @param signal - Optional AbortSignal for cancellation
1907
+ *
1908
+ * @example
1909
+ * ```typescript
1910
+ * await qp.deleteChart("chart_123", { tenantId: "tenant_123" });
1911
+ * ```
1912
+ */
1467
1913
  async deleteChart(id, options, signal) {
1468
1914
  await deleteChart(this.client, id, options, signal);
1469
1915
  }
1470
- // Active Chart CRUD operations
1916
+ // Active Chart CRUD operations (Dashboard)
1917
+ /**
1918
+ * Pins a saved chart to the dashboard (Active Charts).
1919
+ *
1920
+ * Active Charts are used for building dashboards. Unlike the chart history,
1921
+ * active charts are meant to be displayed together with layout metadata.
1922
+ *
1923
+ * @param body - Active chart config with chart_id, order, and optional meta
1924
+ * @param options - Tenant, user, and scope options
1925
+ * @param signal - Optional AbortSignal for cancellation
1926
+ * @returns Created active chart entry
1927
+ *
1928
+ * @example
1929
+ * ```typescript
1930
+ * const pinned = await qp.createActiveChart({
1931
+ * chart_id: savedChart.id,
1932
+ * order: 1,
1933
+ * meta: { width: "full", variant: "dark" },
1934
+ * }, { tenantId: "tenant_123" });
1935
+ * ```
1936
+ */
1471
1937
  async createActiveChart(body, options, signal) {
1472
1938
  return await createActiveChart(
1473
1939
  this.client,
@@ -1476,6 +1942,30 @@ var QueryPanelSdkAPI = class {
1476
1942
  signal
1477
1943
  );
1478
1944
  }
1945
+ /**
1946
+ * Lists all active charts (dashboard items) with optional live data.
1947
+ *
1948
+ * Use `withData: true` to execute each chart's SQL and include results.
1949
+ * This is the primary method for loading a complete dashboard.
1950
+ *
1951
+ * @param options - Filtering and data options including withData
1952
+ * @param signal - Optional AbortSignal for cancellation
1953
+ * @returns Paginated list of active charts with optional live data
1954
+ *
1955
+ * @example
1956
+ * ```typescript
1957
+ * // Load dashboard with live data
1958
+ * const dashboard = await qp.listActiveCharts({
1959
+ * tenantId: "tenant_123",
1960
+ * withData: true,
1961
+ * });
1962
+ *
1963
+ * dashboard.data.forEach(item => {
1964
+ * console.log(item.chart?.title);
1965
+ * console.log(item.chart?.vega_lite_spec.data.values);
1966
+ * });
1967
+ * ```
1968
+ */
1479
1969
  async listActiveCharts(options, signal) {
1480
1970
  return await listActiveCharts(
1481
1971
  this.client,
@@ -1484,6 +1974,22 @@ var QueryPanelSdkAPI = class {
1484
1974
  signal
1485
1975
  );
1486
1976
  }
1977
+ /**
1978
+ * Retrieves a single active chart by ID.
1979
+ *
1980
+ * @param id - Active chart ID
1981
+ * @param options - Options including withData for live data
1982
+ * @param signal - Optional AbortSignal for cancellation
1983
+ * @returns Active chart with associated chart data
1984
+ *
1985
+ * @example
1986
+ * ```typescript
1987
+ * const activeChart = await qp.getActiveChart("active_123", {
1988
+ * tenantId: "tenant_123",
1989
+ * withData: true,
1990
+ * });
1991
+ * ```
1992
+ */
1487
1993
  async getActiveChart(id, options, signal) {
1488
1994
  return await getActiveChart(
1489
1995
  this.client,
@@ -1493,6 +1999,25 @@ var QueryPanelSdkAPI = class {
1493
1999
  signal
1494
2000
  );
1495
2001
  }
2002
+ /**
2003
+ * Updates an active chart's order or metadata.
2004
+ *
2005
+ * Use this to reorder dashboard items or update layout hints.
2006
+ *
2007
+ * @param id - Active chart ID to update
2008
+ * @param body - Fields to update (order, meta)
2009
+ * @param options - Tenant, user, and scope options
2010
+ * @param signal - Optional AbortSignal for cancellation
2011
+ * @returns Updated active chart
2012
+ *
2013
+ * @example
2014
+ * ```typescript
2015
+ * const updated = await qp.updateActiveChart("active_123", {
2016
+ * order: 5,
2017
+ * meta: { width: "half" },
2018
+ * }, { tenantId: "tenant_123" });
2019
+ * ```
2020
+ */
1496
2021
  async updateActiveChart(id, body, options, signal) {
1497
2022
  return await updateActiveChart(
1498
2023
  this.client,
@@ -1502,6 +2027,20 @@ var QueryPanelSdkAPI = class {
1502
2027
  signal
1503
2028
  );
1504
2029
  }
2030
+ /**
2031
+ * Removes a chart from the dashboard (unpins it).
2032
+ *
2033
+ * This only removes the active chart entry, not the underlying saved chart.
2034
+ *
2035
+ * @param id - Active chart ID to delete
2036
+ * @param options - Tenant, user, and scope options
2037
+ * @param signal - Optional AbortSignal for cancellation
2038
+ *
2039
+ * @example
2040
+ * ```typescript
2041
+ * await qp.deleteActiveChart("active_123", { tenantId: "tenant_123" });
2042
+ * ```
2043
+ */
1505
2044
  async deleteActiveChart(id, options, signal) {
1506
2045
  await deleteActiveChart(this.client, id, options, signal);
1507
2046
  }