@lightdash/query-sdk 1.85.1 → 1.86.1
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/README.md +8 -0
- package/dist/apiTransport.js +26 -19
- package/dist/features.js +6 -0
- package/dist/generated/sdkVersion.d.ts +1 -1
- package/dist/generated/sdkVersion.js +1 -1
- package/dist/query.d.ts +5 -1
- package/dist/query.js +13 -1
- package/dist/savedChart.d.ts +2 -1
- package/dist/savedChart.js +1 -0
- package/dist/types.d.ts +3 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -92,10 +92,18 @@ lightdash
|
|
|
92
92
|
{ field: 'amount', operator: 'greaterThan', value: 1000 },
|
|
93
93
|
{ field: 'order_date', operator: 'inThePast', value: 90, unit: 'days' },
|
|
94
94
|
])
|
|
95
|
+
.metricFilters([
|
|
96
|
+
{ field: 'total_revenue', operator: 'greaterThanOrEqual', value: 5000 },
|
|
97
|
+
])
|
|
95
98
|
.sorts([{ field: 'total_revenue', direction: 'desc' }])
|
|
96
99
|
.limit(100);
|
|
97
100
|
```
|
|
98
101
|
|
|
102
|
+
`.filters()` accepts dimensions and serializes them as WHERE filters.
|
|
103
|
+
`.metricFilters()` accepts metrics and serializes them as HAVING filters. A
|
|
104
|
+
metric can be used only as a filter and does not need to be selected with
|
|
105
|
+
`.metrics()`.
|
|
106
|
+
|
|
99
107
|
Supported filter operators: `equals`, `notEquals`, `greaterThan`, `lessThan`, `greaterThanOrEqual`, `lessThanOrEqual`, `inThePast`, `notInThePast`, `inTheNext`, `inTheCurrent`, `notInTheCurrent`, `inBetween`, `notInBetween`, `isNull`, `notNull`, `startsWith`, `endsWith`, `include`, `doesNotInclude`.
|
|
100
108
|
|
|
101
109
|
## Parameters
|
package/dist/apiTransport.js
CHANGED
|
@@ -20,27 +20,31 @@ const sleep = (ms) => new Promise((resolve) => {
|
|
|
20
20
|
setTimeout(resolve, ms);
|
|
21
21
|
});
|
|
22
22
|
/**
|
|
23
|
-
* Convert SDK filter definitions into the Lightdash API
|
|
24
|
-
*
|
|
23
|
+
* Convert SDK dimension and metric filter definitions into the Lightdash API
|
|
24
|
+
* filter format.
|
|
25
25
|
*/
|
|
26
|
-
function buildApiFilters(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
...(f.settings ? { settings: f.settings } : {}),
|
|
38
|
-
}));
|
|
26
|
+
function buildApiFilters(dimensionFilters, metricFilters = []) {
|
|
27
|
+
const buildGroup = (filters, rootId, ruleIdPrefix) => ({
|
|
28
|
+
id: rootId,
|
|
29
|
+
and: filters.map((filter, index) => ({
|
|
30
|
+
id: `${ruleIdPrefix}-${index}`,
|
|
31
|
+
target: { fieldId: filter.fieldId },
|
|
32
|
+
operator: filter.operator,
|
|
33
|
+
values: filter.values,
|
|
34
|
+
...(filter.settings ? { settings: filter.settings } : {}),
|
|
35
|
+
})),
|
|
36
|
+
});
|
|
39
37
|
return {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
...(dimensionFilters.length > 0
|
|
39
|
+
? {
|
|
40
|
+
dimensions: buildGroup(dimensionFilters, 'sdk-root', 'sdk-filter'),
|
|
41
|
+
}
|
|
42
|
+
: {}),
|
|
43
|
+
...(metricFilters.length > 0
|
|
44
|
+
? {
|
|
45
|
+
metrics: buildGroup(metricFilters, 'sdk-metric-root', 'sdk-metric-filter'),
|
|
46
|
+
}
|
|
47
|
+
: {}),
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
50
|
const createFieldQualifier = (table) => (fieldId) => {
|
|
@@ -123,6 +127,9 @@ function buildMetricQueryBody(query, qualify, limit = query.limit) {
|
|
|
123
127
|
filters: buildApiFilters(query.filters.map((f) => ({
|
|
124
128
|
...f,
|
|
125
129
|
fieldId: qualify(f.fieldId),
|
|
130
|
+
})), (query.metricFilters ?? []).map((f) => ({
|
|
131
|
+
...f,
|
|
132
|
+
fieldId: qualify(f.fieldId),
|
|
126
133
|
}))),
|
|
127
134
|
sorts: query.sorts.map((s) => ({
|
|
128
135
|
fieldId: qualify(s.fieldId),
|
package/dist/features.js
CHANGED
|
@@ -13,6 +13,12 @@ export const SDK_FEATURES = [
|
|
|
13
13
|
label: 'Semantic layer queries',
|
|
14
14
|
description: 'Run metric and dimension queries against the Lightdash semantic layer.',
|
|
15
15
|
},
|
|
16
|
+
{
|
|
17
|
+
key: 'metric-filters',
|
|
18
|
+
label: 'Metric filters',
|
|
19
|
+
description: 'Filter grouped query results by metric values, including metrics used only as filters.',
|
|
20
|
+
wiring: 'Pass metric filter rules to query(...).metricFilters([...]); keep dimension filter rules in .filters([...]).',
|
|
21
|
+
},
|
|
16
22
|
{
|
|
17
23
|
key: 'saved-chart',
|
|
18
24
|
label: 'Saved chart queries',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "1.
|
|
1
|
+
export declare const SDK_VERSION = "1.86.1";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by scripts/generateSdkVersion.mjs (prebuild) — do not edit.
|
|
2
|
-
export const SDK_VERSION = '1.
|
|
2
|
+
export const SDK_VERSION = '1.86.1';
|
package/dist/query.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* .dimensions(['customer_segment', 'order_date'])
|
|
7
7
|
* .metrics(['total_revenue', 'order_count'])
|
|
8
8
|
* .filters([{ field: 'order_date', operator: 'inThePast', value: 90, unit: 'days' }])
|
|
9
|
+
* .metricFilters([{ field: 'total_revenue', operator: 'greaterThan', value: 1000 }])
|
|
9
10
|
* .sorts([{ field: 'total_revenue', direction: 'desc' }])
|
|
10
11
|
* .limit(100)
|
|
11
12
|
*
|
|
@@ -17,6 +18,7 @@ type BuilderState = {
|
|
|
17
18
|
dimensions: string[];
|
|
18
19
|
metrics: string[];
|
|
19
20
|
filters: InternalFilterDefinition[];
|
|
21
|
+
metricFilters: InternalFilterDefinition[];
|
|
20
22
|
sorts: {
|
|
21
23
|
fieldId: string;
|
|
22
24
|
descending: boolean;
|
|
@@ -49,8 +51,10 @@ export declare class QueryBuilder {
|
|
|
49
51
|
dimensions(fields: string[]): QueryBuilder;
|
|
50
52
|
/** Set metric fields (aggregations) */
|
|
51
53
|
metrics(fields: string[]): QueryBuilder;
|
|
52
|
-
/** Add filters */
|
|
54
|
+
/** Add dimension (WHERE) filters */
|
|
53
55
|
filters(filters: Filter[]): QueryBuilder;
|
|
56
|
+
/** Add metric (HAVING) filters. The metrics do not need to be selected. */
|
|
57
|
+
metricFilters(filters: Filter[]): QueryBuilder;
|
|
54
58
|
/** Add sorts */
|
|
55
59
|
sorts(sorts: Sort[]): QueryBuilder;
|
|
56
60
|
/** Add table calculations (computed columns evaluated after the query) */
|
package/dist/query.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* .dimensions(['customer_segment', 'order_date'])
|
|
7
7
|
* .metrics(['total_revenue', 'order_count'])
|
|
8
8
|
* .filters([{ field: 'order_date', operator: 'inThePast', value: 90, unit: 'days' }])
|
|
9
|
+
* .metricFilters([{ field: 'total_revenue', operator: 'greaterThan', value: 1000 }])
|
|
9
10
|
* .sorts([{ field: 'total_revenue', direction: 'desc' }])
|
|
10
11
|
* .limit(100)
|
|
11
12
|
*
|
|
@@ -32,6 +33,7 @@ export class QueryBuilder {
|
|
|
32
33
|
dimensions: [],
|
|
33
34
|
metrics: [],
|
|
34
35
|
filters: [],
|
|
36
|
+
metricFilters: [],
|
|
35
37
|
sorts: [],
|
|
36
38
|
tableCalculations: [],
|
|
37
39
|
additionalMetrics: [],
|
|
@@ -73,12 +75,21 @@ export class QueryBuilder {
|
|
|
73
75
|
metrics: [...this._state.metrics, ...fields],
|
|
74
76
|
});
|
|
75
77
|
}
|
|
76
|
-
/** Add filters */
|
|
78
|
+
/** Add dimension (WHERE) filters */
|
|
77
79
|
filters(filters) {
|
|
78
80
|
return this._clone({
|
|
79
81
|
filters: [...this._state.filters, ...toInternalFilters(filters)],
|
|
80
82
|
});
|
|
81
83
|
}
|
|
84
|
+
/** Add metric (HAVING) filters. The metrics do not need to be selected. */
|
|
85
|
+
metricFilters(filters) {
|
|
86
|
+
return this._clone({
|
|
87
|
+
metricFilters: [
|
|
88
|
+
...this._state.metricFilters,
|
|
89
|
+
...toInternalFilters(filters),
|
|
90
|
+
],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
82
93
|
/** Add sorts */
|
|
83
94
|
sorts(sorts) {
|
|
84
95
|
const converted = sorts.map((s) => ({
|
|
@@ -135,6 +146,7 @@ export class QueryBuilder {
|
|
|
135
146
|
dimensions: this._state.dimensions,
|
|
136
147
|
metrics: this._state.metrics,
|
|
137
148
|
filters: this._state.filters,
|
|
149
|
+
metricFilters: this._state.metricFilters,
|
|
138
150
|
sorts: this._state.sorts,
|
|
139
151
|
tableCalculations: this._state.tableCalculations,
|
|
140
152
|
additionalMetrics: this._state.additionalMetrics,
|
package/dist/savedChart.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { AdditionalMetric, CustomDimension, Filter, InternalFilterDefinitio
|
|
|
6
6
|
*
|
|
7
7
|
* CRITICAL: this mirrors the ENTIRE chainable `QueryBuilder` surface. Generated
|
|
8
8
|
* apps chain builder methods on every query (`.dimensions().metrics().filters()
|
|
9
|
-
* .sorts().label().limit()…`); calling a method that doesn't exist on a plain
|
|
9
|
+
* .metricFilters().sorts().label().limit()…`); calling a method that doesn't exist on a plain
|
|
10
10
|
* object throws `TypeError: X is not a function` and crashes the whole app. So a
|
|
11
11
|
* linked chart must be exactly as crash-safe as a normal query — every method
|
|
12
12
|
* below exists and is chainable.
|
|
@@ -41,6 +41,7 @@ export type SavedChartQuery = {
|
|
|
41
41
|
tableCalculations: (calcs: TableCalculation[]) => SavedChartQuery;
|
|
42
42
|
additionalMetrics: (metrics: AdditionalMetric[]) => SavedChartQuery;
|
|
43
43
|
customDimensions: (dims: CustomDimension[]) => SavedChartQuery;
|
|
44
|
+
metricFilters: (filters: Filter[]) => SavedChartQuery;
|
|
44
45
|
};
|
|
45
46
|
export declare function savedChart(chartUuid: string, label?: string): SavedChartQuery;
|
|
46
47
|
/** Identity key for a saved-chart query — anything that changes the run must change the key. */
|
package/dist/savedChart.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -73,7 +73,10 @@ export type QueryDefinition = {
|
|
|
73
73
|
exploreName: string;
|
|
74
74
|
dimensions: string[];
|
|
75
75
|
metrics: string[];
|
|
76
|
+
/** Dimension (WHERE) filters added with `.filters()`. */
|
|
76
77
|
filters: InternalFilterDefinition[];
|
|
78
|
+
/** Metric (HAVING) filters added with `.metricFilters()`. Optional for definitions built by older SDK versions. */
|
|
79
|
+
metricFilters?: InternalFilterDefinition[];
|
|
77
80
|
sorts: {
|
|
78
81
|
fieldId: string;
|
|
79
82
|
descending: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/query-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.86.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "SDK for building custom data apps against the Lightdash semantic layer",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"jsdom": "26.1.0",
|
|
35
35
|
"typescript": "7.0.2",
|
|
36
36
|
"vitest": "4.1.6",
|
|
37
|
-
"@lightdash/common": "1.
|
|
37
|
+
"@lightdash/common": "1.86.1"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"prebuild": "node ./scripts/generateSdkVersion.mjs",
|