@lightdash/query-sdk 0.2776.0 → 0.2778.0
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/apiTransport.js +21 -3
- package/dist/index.d.ts +1 -1
- package/dist/query.d.ts +30 -13
- package/dist/query.js +65 -24
- package/dist/types.d.ts +29 -0
- package/package.json +1 -1
package/dist/apiTransport.js
CHANGED
|
@@ -89,9 +89,21 @@ export function createApiTransport(config, adapter) {
|
|
|
89
89
|
// Lightdash field IDs are `{table}_{column}`.
|
|
90
90
|
// The SDK lets users write short names like 'driver_name'
|
|
91
91
|
// and we qualify them to 'fct_race_results_driver_name'.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
//
|
|
93
|
+
// For joined table fields, use dot notation: 'customers.name'
|
|
94
|
+
// which resolves to 'customers_name' (not 'orders_customers_name').
|
|
95
|
+
const qualify = (fieldId) => {
|
|
96
|
+
// Dot notation: 'customers.name' → 'customers_name'
|
|
97
|
+
if (fieldId.includes('.')) {
|
|
98
|
+
return fieldId.replace('.', '_');
|
|
99
|
+
}
|
|
100
|
+
// Already qualified with explore name
|
|
101
|
+
if (fieldId.startsWith(`${table}_`)) {
|
|
102
|
+
return fieldId;
|
|
103
|
+
}
|
|
104
|
+
// Short name → qualify with explore name
|
|
105
|
+
return `${table}_${fieldId}`;
|
|
106
|
+
};
|
|
95
107
|
const qualifiedDims = query.dimensions.map(qualify);
|
|
96
108
|
const qualifiedMetrics = query.metrics.map(qualify);
|
|
97
109
|
// Step 1: Execute async query
|
|
@@ -110,6 +122,12 @@ export function createApiTransport(config, adapter) {
|
|
|
110
122
|
})),
|
|
111
123
|
limit: query.limit,
|
|
112
124
|
tableCalculations: query.tableCalculations,
|
|
125
|
+
...(query.additionalMetrics.length > 0
|
|
126
|
+
? { additionalMetrics: query.additionalMetrics }
|
|
127
|
+
: {}),
|
|
128
|
+
...(query.customDimensions.length > 0
|
|
129
|
+
? { customDimensions: query.customDimensions }
|
|
130
|
+
: {}),
|
|
113
131
|
},
|
|
114
132
|
};
|
|
115
133
|
// Pass label as transport metadata (not in the API body)
|
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export { useLightdash } from './useLightdash';
|
|
|
4
4
|
export { LightdashProvider, useLightdashClient } from './LightdashProvider';
|
|
5
5
|
export { createApiTransport, type FetchAdapter } from './apiTransport';
|
|
6
6
|
export { createPostMessageTransport } from './postMessageTransport';
|
|
7
|
-
export type { Column, Filter, FilterOperator, FilterValue, FormatFunction, LightdashClientConfig, LightdashUser, QueryDefinition, QueryResult, Row, Sort, TableCalculation, Transport, UnitOfTime, } from './types';
|
|
7
|
+
export type { AdditionalMetric, Column, CustomDimension, Filter, FilterOperator, FilterValue, FormatFunction, LightdashClientConfig, LightdashUser, MetricType, QueryDefinition, QueryResult, Row, Sort, TableCalculation, Transport, UnitOfTime, } from './types';
|
|
8
8
|
export type { SdkFetchRequest, SdkFetchResponse, SdkReadyMessage, } from './postMessageTransport';
|
package/dist/query.d.ts
CHANGED
|
@@ -11,7 +11,22 @@
|
|
|
11
11
|
*
|
|
12
12
|
* The builder is immutable -- each method returns a new instance.
|
|
13
13
|
*/
|
|
14
|
-
import type { Filter, InternalFilterDefinition, QueryDefinition, Sort, TableCalculation } from './types';
|
|
14
|
+
import type { AdditionalMetric, CustomDimension, Filter, InternalFilterDefinition, QueryDefinition, Sort, TableCalculation } from './types';
|
|
15
|
+
type BuilderState = {
|
|
16
|
+
explore: string;
|
|
17
|
+
dimensions: string[];
|
|
18
|
+
metrics: string[];
|
|
19
|
+
filters: InternalFilterDefinition[];
|
|
20
|
+
sorts: {
|
|
21
|
+
fieldId: string;
|
|
22
|
+
descending: boolean;
|
|
23
|
+
}[];
|
|
24
|
+
tableCalculations: TableCalculation[];
|
|
25
|
+
additionalMetrics: AdditionalMetric[];
|
|
26
|
+
customDimensions: CustomDimension[];
|
|
27
|
+
limit: number;
|
|
28
|
+
label: string | undefined;
|
|
29
|
+
};
|
|
15
30
|
/**
|
|
16
31
|
* Create a query builder for a model.
|
|
17
32
|
*
|
|
@@ -23,18 +38,10 @@ import type { Filter, InternalFilterDefinition, QueryDefinition, Sort, TableCalc
|
|
|
23
38
|
*/
|
|
24
39
|
export declare function query(modelName: string): QueryBuilder;
|
|
25
40
|
export declare class QueryBuilder {
|
|
26
|
-
private readonly
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
private readonly _sorts;
|
|
31
|
-
private readonly _tableCalculations;
|
|
32
|
-
private readonly _limit;
|
|
33
|
-
private readonly _label;
|
|
34
|
-
constructor(explore: string, dimensions?: string[], metrics?: string[], filters?: InternalFilterDefinition[], sorts?: {
|
|
35
|
-
fieldId: string;
|
|
36
|
-
descending: boolean;
|
|
37
|
-
}[], limit?: number, label?: string, tableCalculations?: TableCalculation[]);
|
|
41
|
+
private readonly _state;
|
|
42
|
+
constructor(explore: string);
|
|
43
|
+
constructor(state: BuilderState);
|
|
44
|
+
private _clone;
|
|
38
45
|
/** Human-readable label for dev tools / query inspector */
|
|
39
46
|
label(name: string): QueryBuilder;
|
|
40
47
|
/** Set dimension fields (GROUP BY columns) */
|
|
@@ -47,8 +54,18 @@ export declare class QueryBuilder {
|
|
|
47
54
|
sorts(sorts: Sort[]): QueryBuilder;
|
|
48
55
|
/** Add table calculations (computed columns evaluated after the query) */
|
|
49
56
|
tableCalculations(calcs: TableCalculation[]): QueryBuilder;
|
|
57
|
+
/**
|
|
58
|
+
* Add additional metrics (ad-hoc aggregations defined at query time).
|
|
59
|
+
* Use this for metrics on joined tables or custom aggregations not in the YAML.
|
|
60
|
+
*/
|
|
61
|
+
additionalMetrics(metrics: AdditionalMetric[]): QueryBuilder;
|
|
62
|
+
/**
|
|
63
|
+
* Add custom dimensions (ad-hoc dimensions defined at query time).
|
|
64
|
+
*/
|
|
65
|
+
customDimensions(dims: CustomDimension[]): QueryBuilder;
|
|
50
66
|
/** Set the maximum number of rows to return (default: 500) */
|
|
51
67
|
limit(n: number): QueryBuilder;
|
|
52
68
|
/** Convert to a plain QueryDefinition object */
|
|
53
69
|
build(): QueryDefinition;
|
|
54
70
|
}
|
|
71
|
+
export {};
|
package/dist/query.js
CHANGED
|
@@ -24,27 +24,43 @@ export function query(modelName) {
|
|
|
24
24
|
return new QueryBuilder(modelName);
|
|
25
25
|
}
|
|
26
26
|
export class QueryBuilder {
|
|
27
|
-
constructor(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
constructor(exploreOrState) {
|
|
28
|
+
if (typeof exploreOrState === 'string') {
|
|
29
|
+
this._state = {
|
|
30
|
+
explore: exploreOrState,
|
|
31
|
+
dimensions: [],
|
|
32
|
+
metrics: [],
|
|
33
|
+
filters: [],
|
|
34
|
+
sorts: [],
|
|
35
|
+
tableCalculations: [],
|
|
36
|
+
additionalMetrics: [],
|
|
37
|
+
customDimensions: [],
|
|
38
|
+
limit: 500,
|
|
39
|
+
label: undefined,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
this._state = exploreOrState;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
_clone(overrides) {
|
|
47
|
+
return new QueryBuilder({ ...this._state, ...overrides });
|
|
36
48
|
}
|
|
37
49
|
/** Human-readable label for dev tools / query inspector */
|
|
38
50
|
label(name) {
|
|
39
|
-
return
|
|
51
|
+
return this._clone({ label: name });
|
|
40
52
|
}
|
|
41
53
|
/** Set dimension fields (GROUP BY columns) */
|
|
42
54
|
dimensions(fields) {
|
|
43
|
-
return
|
|
55
|
+
return this._clone({
|
|
56
|
+
dimensions: [...this._state.dimensions, ...fields],
|
|
57
|
+
});
|
|
44
58
|
}
|
|
45
59
|
/** Set metric fields (aggregations) */
|
|
46
60
|
metrics(fields) {
|
|
47
|
-
return
|
|
61
|
+
return this._clone({
|
|
62
|
+
metrics: [...this._state.metrics, ...fields],
|
|
63
|
+
});
|
|
48
64
|
}
|
|
49
65
|
/** Add filters */
|
|
50
66
|
filters(filters) {
|
|
@@ -65,7 +81,9 @@ export class QueryBuilder {
|
|
|
65
81
|
settings: f.unit ? { unitOfTime: f.unit } : null,
|
|
66
82
|
};
|
|
67
83
|
});
|
|
68
|
-
return
|
|
84
|
+
return this._clone({
|
|
85
|
+
filters: [...this._state.filters, ...converted],
|
|
86
|
+
});
|
|
69
87
|
}
|
|
70
88
|
/** Add sorts */
|
|
71
89
|
sorts(sorts) {
|
|
@@ -73,27 +91,50 @@ export class QueryBuilder {
|
|
|
73
91
|
fieldId: s.field,
|
|
74
92
|
descending: s.direction === 'desc',
|
|
75
93
|
}));
|
|
76
|
-
return
|
|
94
|
+
return this._clone({
|
|
95
|
+
sorts: [...this._state.sorts, ...converted],
|
|
96
|
+
});
|
|
77
97
|
}
|
|
78
98
|
/** Add table calculations (computed columns evaluated after the query) */
|
|
79
99
|
tableCalculations(calcs) {
|
|
80
|
-
return
|
|
100
|
+
return this._clone({
|
|
101
|
+
tableCalculations: [...this._state.tableCalculations, ...calcs],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Add additional metrics (ad-hoc aggregations defined at query time).
|
|
106
|
+
* Use this for metrics on joined tables or custom aggregations not in the YAML.
|
|
107
|
+
*/
|
|
108
|
+
additionalMetrics(metrics) {
|
|
109
|
+
return this._clone({
|
|
110
|
+
additionalMetrics: [...this._state.additionalMetrics, ...metrics],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Add custom dimensions (ad-hoc dimensions defined at query time).
|
|
115
|
+
*/
|
|
116
|
+
customDimensions(dims) {
|
|
117
|
+
return this._clone({
|
|
118
|
+
customDimensions: [...this._state.customDimensions, ...dims],
|
|
119
|
+
});
|
|
81
120
|
}
|
|
82
121
|
/** Set the maximum number of rows to return (default: 500) */
|
|
83
122
|
limit(n) {
|
|
84
|
-
return
|
|
123
|
+
return this._clone({ limit: n });
|
|
85
124
|
}
|
|
86
125
|
/** Convert to a plain QueryDefinition object */
|
|
87
126
|
build() {
|
|
88
127
|
return {
|
|
89
|
-
exploreName: this.
|
|
90
|
-
dimensions: this.
|
|
91
|
-
metrics: this.
|
|
92
|
-
filters: this.
|
|
93
|
-
sorts: this.
|
|
94
|
-
tableCalculations: this.
|
|
95
|
-
|
|
96
|
-
|
|
128
|
+
exploreName: this._state.explore,
|
|
129
|
+
dimensions: this._state.dimensions,
|
|
130
|
+
metrics: this._state.metrics,
|
|
131
|
+
filters: this._state.filters,
|
|
132
|
+
sorts: this._state.sorts,
|
|
133
|
+
tableCalculations: this._state.tableCalculations,
|
|
134
|
+
additionalMetrics: this._state.additionalMetrics,
|
|
135
|
+
customDimensions: this._state.customDimensions,
|
|
136
|
+
limit: this._state.limit,
|
|
137
|
+
...(this._state.label ? { label: this._state.label } : {}),
|
|
97
138
|
};
|
|
98
139
|
}
|
|
99
140
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -22,6 +22,33 @@ export type TableCalculation = {
|
|
|
22
22
|
/** SQL expression for the calculation */
|
|
23
23
|
sql: string;
|
|
24
24
|
};
|
|
25
|
+
export type MetricType = 'average' | 'count' | 'count_distinct' | 'sum' | 'sum_distinct' | 'min' | 'max' | 'number' | 'median' | 'percentile';
|
|
26
|
+
export type AdditionalMetric = {
|
|
27
|
+
/** Internal name of the metric (used as the field ID in results) */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Display label */
|
|
30
|
+
label?: string;
|
|
31
|
+
/** Table the metric belongs to */
|
|
32
|
+
table: string;
|
|
33
|
+
/** Aggregation type */
|
|
34
|
+
type: MetricType;
|
|
35
|
+
/** SQL expression (e.g., ${TABLE}.column_name) */
|
|
36
|
+
sql: string;
|
|
37
|
+
/** Description of what the metric measures */
|
|
38
|
+
description?: string;
|
|
39
|
+
};
|
|
40
|
+
export type CustomDimension = {
|
|
41
|
+
/** Unique ID for the custom dimension */
|
|
42
|
+
id: string;
|
|
43
|
+
/** Internal name */
|
|
44
|
+
name: string;
|
|
45
|
+
/** Table the dimension belongs to */
|
|
46
|
+
table: string;
|
|
47
|
+
/** SQL expression */
|
|
48
|
+
sql: string;
|
|
49
|
+
/** The dimension type */
|
|
50
|
+
dimensionId: string;
|
|
51
|
+
};
|
|
25
52
|
export type InternalFilterDefinition = {
|
|
26
53
|
fieldId: string;
|
|
27
54
|
operator: string;
|
|
@@ -40,6 +67,8 @@ export type QueryDefinition = {
|
|
|
40
67
|
descending: boolean;
|
|
41
68
|
}[];
|
|
42
69
|
tableCalculations: TableCalculation[];
|
|
70
|
+
additionalMetrics: AdditionalMetric[];
|
|
71
|
+
customDimensions: CustomDimension[];
|
|
43
72
|
limit: number;
|
|
44
73
|
/** Human-readable label for dev tools / query inspector (not sent to the API) */
|
|
45
74
|
label?: string;
|