@querypanel/node-sdk 1.0.41 → 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.d.ts CHANGED
@@ -411,6 +411,158 @@ interface AskResponse {
411
411
  }
412
412
  declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
413
413
 
414
+ /**
415
+ * Simplified field reference for modification inputs.
416
+ * More ergonomic than the full AxisField type.
417
+ */
418
+ interface AxisFieldInput {
419
+ /** Column name from the SQL result */
420
+ field: string;
421
+ /** Human-friendly label for the axis */
422
+ label?: string;
423
+ /** Field data type */
424
+ type?: FieldType;
425
+ /** Aggregation operation (e.g., 'sum', 'avg') */
426
+ aggregate?: AggregateOp;
427
+ /** Time unit for temporal fields */
428
+ timeUnit?: TimeUnit;
429
+ /** Value formatting options */
430
+ format?: ValueFormat;
431
+ }
432
+ /**
433
+ * Simplified field reference for series/grouping fields.
434
+ */
435
+ interface FieldRefInput {
436
+ /** Column name from the SQL result */
437
+ field: string;
438
+ /** Human-friendly label */
439
+ label?: string;
440
+ /** Field data type */
441
+ type?: FieldType;
442
+ }
443
+ /**
444
+ * Date range specification for SQL modifications.
445
+ */
446
+ interface DateRangeInput {
447
+ /** Start date in ISO format (e.g., '2024-01-01') */
448
+ from?: string;
449
+ /** End date in ISO format (e.g., '2024-12-31') */
450
+ to?: string;
451
+ }
452
+ /**
453
+ * SQL modification options that trigger query regeneration.
454
+ * When any of these are provided, a new ask() call is made.
455
+ */
456
+ interface SqlModifications {
457
+ /**
458
+ * Direct SQL override. When provided, this SQL is executed directly
459
+ * without calling the query generation endpoint.
460
+ */
461
+ customSql?: string;
462
+ /**
463
+ * Change the time granularity of the query.
464
+ * Triggers SQL regeneration with hints about the desired grouping.
465
+ */
466
+ timeGranularity?: TimeUnit;
467
+ /**
468
+ * Filter the query to a specific date range.
469
+ * Triggers SQL regeneration with date filter hints.
470
+ */
471
+ dateRange?: DateRangeInput;
472
+ /**
473
+ * Additional natural language instructions to modify the query.
474
+ * These are appended to the original question as hints.
475
+ * Example: "exclude cancelled orders" or "only show top 10"
476
+ */
477
+ additionalInstructions?: string;
478
+ }
479
+ /**
480
+ * Visualization modification options that don't affect the SQL.
481
+ * These changes only affect how the chart is rendered.
482
+ */
483
+ interface VizModifications {
484
+ /** Change the chart type (line, bar, area, scatter, pie) */
485
+ chartType?: ChartType;
486
+ /** Configure the X axis field and settings */
487
+ xAxis?: AxisFieldInput;
488
+ /** Configure the Y axis field(s) and settings */
489
+ yAxis?: AxisFieldInput | AxisFieldInput[];
490
+ /** Configure the series/grouping field for multi-series charts */
491
+ series?: FieldRefInput;
492
+ /** Stacking mode for multi-series charts */
493
+ stacking?: StackingMode;
494
+ /** Maximum number of rows to display in the chart */
495
+ limit?: number;
496
+ }
497
+ /**
498
+ * Input for the modifyChart() method.
499
+ * Accepts chart data from either ask() responses or saved charts.
500
+ */
501
+ interface ChartModifyInput {
502
+ /**
503
+ * The SQL query to modify or re-execute.
504
+ * From ask() response: response.sql
505
+ * From saved chart: chart.sql
506
+ */
507
+ sql: string;
508
+ /**
509
+ * The original natural language question.
510
+ * Used when regenerating SQL with modifications.
511
+ */
512
+ question: string;
513
+ /**
514
+ * The database to execute the query against.
515
+ * From ask() response: response.target_db
516
+ * From saved chart: chart.target_db
517
+ */
518
+ database: string;
519
+ /**
520
+ * Query parameters (optional).
521
+ * From ask() response: response.params
522
+ * From saved chart: chart.sql_params
523
+ */
524
+ params?: ParamRecord;
525
+ /**
526
+ * SQL modifications that trigger query regeneration.
527
+ * When provided, a new ask() call is made with modification hints.
528
+ */
529
+ sqlModifications?: SqlModifications;
530
+ /**
531
+ * Visualization modifications that don't affect the SQL.
532
+ * Applied during chart generation.
533
+ */
534
+ vizModifications?: VizModifications;
535
+ }
536
+ /**
537
+ * Options for the modifyChart() method.
538
+ */
539
+ interface ChartModifyOptions {
540
+ /** Tenant ID for multi-tenant isolation */
541
+ tenantId?: string;
542
+ /** User ID for audit/tracking */
543
+ userId?: string;
544
+ /** Permission scopes */
545
+ scopes?: string[];
546
+ /** Maximum retry attempts for SQL generation */
547
+ maxRetry?: number;
548
+ /** Maximum retry attempts for chart generation */
549
+ chartMaxRetries?: number;
550
+ /** Chart generation method: 'vega-lite' or 'vizspec' */
551
+ chartType?: "vega-lite" | "vizspec";
552
+ }
553
+ /**
554
+ * Response from modifyChart(), extending AskResponse with modification metadata.
555
+ */
556
+ interface ChartModifyResponse extends AskResponse {
557
+ /** Metadata about what was modified */
558
+ modified: {
559
+ /** Whether the SQL was changed (regenerated or custom) */
560
+ sqlChanged: boolean;
561
+ /** Whether visualization settings were applied */
562
+ vizChanged: boolean;
563
+ };
564
+ }
565
+
414
566
  interface VizSpecGenerateInput {
415
567
  question: string;
416
568
  sql: string;
@@ -455,46 +607,369 @@ declare class QueryPanelSdkAPI {
455
607
  description?: string;
456
608
  tags?: string[];
457
609
  tenantFieldName?: string;
610
+ tenantFieldType?: string;
458
611
  enforceTenantIsolation?: boolean;
459
612
  }): void;
460
613
  attachDatabase(name: string, adapter: DatabaseAdapter): void;
461
614
  introspect(databaseName: string, tables?: string[]): Promise<SchemaIntrospection>;
615
+ /**
616
+ * Syncs the database schema to QueryPanel for natural language query generation.
617
+ *
618
+ * This method introspects your database schema and uploads it to QueryPanel's
619
+ * vector store. The schema is used by the LLM to generate accurate SQL queries.
620
+ * Schema embedding is skipped if no changes are detected (drift detection).
621
+ *
622
+ * @param databaseName - Name of the attached database to sync
623
+ * @param options - Sync options including tenantId and forceReindex
624
+ * @param signal - Optional AbortSignal for cancellation
625
+ * @returns Response with sync status and chunk counts
626
+ *
627
+ * @example
628
+ * ```typescript
629
+ * // Basic schema sync (skips if no changes)
630
+ * await qp.syncSchema("analytics", { tenantId: "tenant_123" });
631
+ *
632
+ * // Force re-embedding even if schema hasn't changed
633
+ * await qp.syncSchema("analytics", {
634
+ * tenantId: "tenant_123",
635
+ * forceReindex: true,
636
+ * });
637
+ * ```
638
+ */
462
639
  syncSchema(databaseName: string, options: SchemaSyncOptions, signal?: AbortSignal): Promise<IngestResponse>;
640
+ /**
641
+ * Generates SQL from a natural language question and executes it.
642
+ *
643
+ * This is the primary method for converting user questions into data.
644
+ * It handles the complete flow: SQL generation → validation → execution → chart generation.
645
+ *
646
+ * @param question - Natural language question (e.g., "Show revenue by country")
647
+ * @param options - Query options including tenantId, database, and retry settings
648
+ * @param signal - Optional AbortSignal for cancellation
649
+ * @returns Response with SQL, executed data rows, and generated chart
650
+ * @throws {Error} When SQL generation or execution fails after all retries
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * // Basic query
655
+ * const result = await qp.ask("Top 10 customers by revenue", {
656
+ * tenantId: "tenant_123",
657
+ * database: "analytics",
658
+ * });
659
+ * console.log(result.sql); // Generated SQL
660
+ * console.log(result.rows); // Query results
661
+ * console.log(result.chart); // Vega-Lite chart spec
662
+ *
663
+ * // With automatic SQL repair on failure
664
+ * const result = await qp.ask("Show monthly trends", {
665
+ * tenantId: "tenant_123",
666
+ * maxRetry: 3, // Retry up to 3 times if SQL fails
667
+ * });
668
+ * ```
669
+ */
463
670
  ask(question: string, options: AskOptions, signal?: AbortSignal): Promise<AskResponse>;
671
+ /**
672
+ * Generates a VizSpec visualization specification from query results.
673
+ *
674
+ * Use this when you have raw SQL results and want to generate a chart
675
+ * specification without going through the full ask() flow. Useful for
676
+ * re-generating charts with different settings.
677
+ *
678
+ * @param input - VizSpec generation input with question, SQL, and result data
679
+ * @param options - Optional settings for tenant and retries
680
+ * @param signal - Optional AbortSignal for cancellation
681
+ * @returns VizSpec specification for chart, table, or metric visualization
682
+ *
683
+ * @example
684
+ * ```typescript
685
+ * const vizspec = await qp.generateVizSpec({
686
+ * question: "Revenue by country",
687
+ * sql: "SELECT country, SUM(revenue) FROM orders GROUP BY country",
688
+ * fields: ["country", "revenue"],
689
+ * rows: queryResults,
690
+ * }, { tenantId: "tenant_123" });
691
+ * ```
692
+ */
464
693
  generateVizSpec(input: VizSpecGenerateInput, options?: VizSpecGenerateOptions, signal?: AbortSignal): Promise<VizSpecResponse>;
694
+ /**
695
+ * Modifies a chart by regenerating SQL and/or applying visualization changes.
696
+ *
697
+ * This method supports three modes of operation:
698
+ *
699
+ * 1. **SQL Modifications**: When `sqlModifications` is provided, the SQL is
700
+ * regenerated using the query endpoint with modification hints. If `customSql`
701
+ * is set, it's used directly without regeneration.
702
+ *
703
+ * 2. **Visualization Modifications**: When only `vizModifications` is provided,
704
+ * the existing SQL is re-executed and a new chart is generated with the
705
+ * specified encoding preferences.
706
+ *
707
+ * 3. **Combined**: Both SQL and visualization modifications can be applied
708
+ * together. SQL is regenerated first, then viz modifications are applied.
709
+ *
710
+ * @param input - Chart modification input with source data and modifications
711
+ * @param options - Optional settings for tenant, user, and chart generation
712
+ * @param signal - Optional AbortSignal for cancellation
713
+ * @returns Modified chart response with SQL, data, and chart specification
714
+ *
715
+ * @example
716
+ * ```typescript
717
+ * // Change chart type and axis from an ask() response
718
+ * const modified = await qp.modifyChart({
719
+ * sql: response.sql,
720
+ * question: "revenue by country",
721
+ * database: "analytics",
722
+ * vizModifications: {
723
+ * chartType: "bar",
724
+ * xAxis: { field: "country" },
725
+ * yAxis: { field: "revenue", aggregate: "sum" },
726
+ * },
727
+ * }, { tenantId: "tenant_123" });
728
+ *
729
+ * // Change time granularity (triggers SQL regeneration)
730
+ * const monthly = await qp.modifyChart({
731
+ * sql: response.sql,
732
+ * question: "revenue over time",
733
+ * database: "analytics",
734
+ * sqlModifications: {
735
+ * timeGranularity: "month",
736
+ * dateRange: { from: "2024-01-01", to: "2024-12-31" },
737
+ * },
738
+ * }, { tenantId: "tenant_123" });
739
+ *
740
+ * // Direct SQL edit with chart regeneration
741
+ * const customized = await qp.modifyChart({
742
+ * sql: response.sql,
743
+ * question: "revenue by country",
744
+ * database: "analytics",
745
+ * sqlModifications: {
746
+ * customSql: "SELECT country, SUM(revenue) FROM orders GROUP BY country",
747
+ * },
748
+ * }, { tenantId: "tenant_123" });
749
+ * ```
750
+ */
751
+ modifyChart(input: ChartModifyInput, options?: ChartModifyOptions, signal?: AbortSignal): Promise<ChartModifyResponse>;
752
+ /**
753
+ * Saves a chart to the QueryPanel system for later retrieval.
754
+ *
755
+ * Charts store the SQL query, parameters, and visualization spec - never the actual data.
756
+ * Data is fetched live when the chart is rendered or refreshed.
757
+ *
758
+ * @param body - Chart data including title, SQL, and Vega-Lite spec
759
+ * @param options - Tenant, user, and scope options
760
+ * @param signal - Optional AbortSignal for cancellation
761
+ * @returns The saved chart with its generated ID
762
+ *
763
+ * @example
764
+ * ```typescript
765
+ * const savedChart = await qp.createChart({
766
+ * title: "Revenue by Country",
767
+ * sql: response.sql,
768
+ * sql_params: response.params,
769
+ * vega_lite_spec: response.chart.vegaLiteSpec,
770
+ * target_db: "analytics",
771
+ * }, { tenantId: "tenant_123", userId: "user_456" });
772
+ * ```
773
+ */
465
774
  createChart(body: ChartCreateInput, options?: {
466
775
  tenantId?: string;
467
776
  userId?: string;
468
777
  scopes?: string[];
469
778
  }, signal?: AbortSignal): Promise<SdkChart>;
779
+ /**
780
+ * Lists saved charts with optional filtering and pagination.
781
+ *
782
+ * Use `includeData: true` to execute each chart's SQL and include live data.
783
+ *
784
+ * @param options - Filtering, pagination, and data options
785
+ * @param signal - Optional AbortSignal for cancellation
786
+ * @returns Paginated list of charts
787
+ *
788
+ * @example
789
+ * ```typescript
790
+ * // List charts with pagination
791
+ * const charts = await qp.listCharts({
792
+ * tenantId: "tenant_123",
793
+ * pagination: { page: 1, limit: 10 },
794
+ * sortBy: "created_at",
795
+ * sortDir: "desc",
796
+ * });
797
+ *
798
+ * // List with live data
799
+ * const chartsWithData = await qp.listCharts({
800
+ * tenantId: "tenant_123",
801
+ * includeData: true,
802
+ * });
803
+ * ```
804
+ */
470
805
  listCharts(options?: ChartListOptions, signal?: AbortSignal): Promise<PaginatedResponse<SdkChart>>;
806
+ /**
807
+ * Retrieves a single chart by ID with live data.
808
+ *
809
+ * The chart's SQL is automatically executed and data is included in the response.
810
+ *
811
+ * @param id - Chart ID
812
+ * @param options - Tenant, user, and scope options
813
+ * @param signal - Optional AbortSignal for cancellation
814
+ * @returns Chart with live data populated
815
+ *
816
+ * @example
817
+ * ```typescript
818
+ * const chart = await qp.getChart("chart_123", {
819
+ * tenantId: "tenant_123",
820
+ * });
821
+ * console.log(chart.vega_lite_spec.data.values); // Live data
822
+ * ```
823
+ */
471
824
  getChart(id: string, options?: {
472
825
  tenantId?: string;
473
826
  userId?: string;
474
827
  scopes?: string[];
475
828
  }, signal?: AbortSignal): Promise<SdkChart>;
829
+ /**
830
+ * Updates an existing chart's metadata or configuration.
831
+ *
832
+ * @param id - Chart ID to update
833
+ * @param body - Fields to update (partial update supported)
834
+ * @param options - Tenant, user, and scope options
835
+ * @param signal - Optional AbortSignal for cancellation
836
+ * @returns Updated chart
837
+ *
838
+ * @example
839
+ * ```typescript
840
+ * const updated = await qp.updateChart("chart_123", {
841
+ * title: "Updated Chart Title",
842
+ * description: "New description",
843
+ * }, { tenantId: "tenant_123" });
844
+ * ```
845
+ */
476
846
  updateChart(id: string, body: ChartUpdateInput, options?: {
477
847
  tenantId?: string;
478
848
  userId?: string;
479
849
  scopes?: string[];
480
850
  }, signal?: AbortSignal): Promise<SdkChart>;
851
+ /**
852
+ * Deletes a chart permanently.
853
+ *
854
+ * @param id - Chart ID to delete
855
+ * @param options - Tenant, user, and scope options
856
+ * @param signal - Optional AbortSignal for cancellation
857
+ *
858
+ * @example
859
+ * ```typescript
860
+ * await qp.deleteChart("chart_123", { tenantId: "tenant_123" });
861
+ * ```
862
+ */
481
863
  deleteChart(id: string, options?: {
482
864
  tenantId?: string;
483
865
  userId?: string;
484
866
  scopes?: string[];
485
867
  }, signal?: AbortSignal): Promise<void>;
868
+ /**
869
+ * Pins a saved chart to the dashboard (Active Charts).
870
+ *
871
+ * Active Charts are used for building dashboards. Unlike the chart history,
872
+ * active charts are meant to be displayed together with layout metadata.
873
+ *
874
+ * @param body - Active chart config with chart_id, order, and optional meta
875
+ * @param options - Tenant, user, and scope options
876
+ * @param signal - Optional AbortSignal for cancellation
877
+ * @returns Created active chart entry
878
+ *
879
+ * @example
880
+ * ```typescript
881
+ * const pinned = await qp.createActiveChart({
882
+ * chart_id: savedChart.id,
883
+ * order: 1,
884
+ * meta: { width: "full", variant: "dark" },
885
+ * }, { tenantId: "tenant_123" });
886
+ * ```
887
+ */
486
888
  createActiveChart(body: ActiveChartCreateInput, options?: {
487
889
  tenantId?: string;
488
890
  userId?: string;
489
891
  scopes?: string[];
490
892
  }, signal?: AbortSignal): Promise<SdkActiveChart>;
893
+ /**
894
+ * Lists all active charts (dashboard items) with optional live data.
895
+ *
896
+ * Use `withData: true` to execute each chart's SQL and include results.
897
+ * This is the primary method for loading a complete dashboard.
898
+ *
899
+ * @param options - Filtering and data options including withData
900
+ * @param signal - Optional AbortSignal for cancellation
901
+ * @returns Paginated list of active charts with optional live data
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * // Load dashboard with live data
906
+ * const dashboard = await qp.listActiveCharts({
907
+ * tenantId: "tenant_123",
908
+ * withData: true,
909
+ * });
910
+ *
911
+ * dashboard.data.forEach(item => {
912
+ * console.log(item.chart?.title);
913
+ * console.log(item.chart?.vega_lite_spec.data.values);
914
+ * });
915
+ * ```
916
+ */
491
917
  listActiveCharts(options?: ActiveChartListOptions, signal?: AbortSignal): Promise<PaginatedResponse<SdkActiveChart>>;
918
+ /**
919
+ * Retrieves a single active chart by ID.
920
+ *
921
+ * @param id - Active chart ID
922
+ * @param options - Options including withData for live data
923
+ * @param signal - Optional AbortSignal for cancellation
924
+ * @returns Active chart with associated chart data
925
+ *
926
+ * @example
927
+ * ```typescript
928
+ * const activeChart = await qp.getActiveChart("active_123", {
929
+ * tenantId: "tenant_123",
930
+ * withData: true,
931
+ * });
932
+ * ```
933
+ */
492
934
  getActiveChart(id: string, options?: ActiveChartListOptions, signal?: AbortSignal): Promise<SdkActiveChart>;
935
+ /**
936
+ * Updates an active chart's order or metadata.
937
+ *
938
+ * Use this to reorder dashboard items or update layout hints.
939
+ *
940
+ * @param id - Active chart ID to update
941
+ * @param body - Fields to update (order, meta)
942
+ * @param options - Tenant, user, and scope options
943
+ * @param signal - Optional AbortSignal for cancellation
944
+ * @returns Updated active chart
945
+ *
946
+ * @example
947
+ * ```typescript
948
+ * const updated = await qp.updateActiveChart("active_123", {
949
+ * order: 5,
950
+ * meta: { width: "half" },
951
+ * }, { tenantId: "tenant_123" });
952
+ * ```
953
+ */
493
954
  updateActiveChart(id: string, body: ActiveChartUpdateInput, options?: {
494
955
  tenantId?: string;
495
956
  userId?: string;
496
957
  scopes?: string[];
497
958
  }, signal?: AbortSignal): Promise<SdkActiveChart>;
959
+ /**
960
+ * Removes a chart from the dashboard (unpins it).
961
+ *
962
+ * This only removes the active chart entry, not the underlying saved chart.
963
+ *
964
+ * @param id - Active chart ID to delete
965
+ * @param options - Tenant, user, and scope options
966
+ * @param signal - Optional AbortSignal for cancellation
967
+ *
968
+ * @example
969
+ * ```typescript
970
+ * await qp.deleteActiveChart("active_123", { tenantId: "tenant_123" });
971
+ * ```
972
+ */
498
973
  deleteActiveChart(id: string, options?: {
499
974
  tenantId?: string;
500
975
  userId?: string;
@@ -502,4 +977,4 @@ declare class QueryPanelSdkAPI {
502
977
  }, signal?: AbortSignal): Promise<void>;
503
978
  }
504
979
 
505
- export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AskOptions, type AskResponse, type AxisField, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type FieldRef, type FieldType, type IngestResponse, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse, type PaginationInfo, type PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryPanelSdkAPI, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type TableColumn, type TableEncoding, type TableSpec, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecResponse, anonymizeResults };
980
+ export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AggregateOp, type AskOptions, type AskResponse, type AxisField, type AxisFieldInput, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartModifyInput, type ChartModifyOptions, type ChartModifyResponse, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type DateRangeInput, type FieldRef, type FieldRefInput, type FieldType, type IngestResponse, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse, type PaginationInfo, type PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryPanelSdkAPI, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type SqlModifications, type StackingMode, type TableColumn, type TableEncoding, type TableSpec, type TimeUnit, type VizModifications, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecResponse, anonymizeResults };