@cubejs-client/core 0.29.53 → 0.30.4
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/CHANGELOG.md +30 -0
- package/dist/cubejs-client-core.esm.js +44 -9
- package/dist/cubejs-client-core.esm.js.map +1 -1
- package/dist/cubejs-client-core.js +46 -7
- package/dist/cubejs-client-core.js.map +1 -1
- package/dist/cubejs-client-core.umd.js +82 -10
- package/dist/cubejs-client-core.umd.js.map +1 -1
- package/index.d.ts +50 -6
- package/package.json +2 -2
- package/src/index.js +1 -12
- package/src/utils.js +89 -15
package/index.d.ts
CHANGED
|
@@ -808,6 +808,36 @@ declare module '@cubejs-client/core' {
|
|
|
808
808
|
total?: boolean;
|
|
809
809
|
}
|
|
810
810
|
|
|
811
|
+
export type QueryRecordType<T extends DeeplyReadonly<Query | Query[]>> =
|
|
812
|
+
T extends DeeplyReadonly<Query[]> ? QueryArrayRecordType<T> :
|
|
813
|
+
T extends DeeplyReadonly<Query> ? SingleQueryRecordType<T> :
|
|
814
|
+
never;
|
|
815
|
+
|
|
816
|
+
type QueryArrayRecordType<T extends DeeplyReadonly<Query[]>> =
|
|
817
|
+
T extends readonly [infer First, ...infer Rest]
|
|
818
|
+
? SingleQueryRecordType<First> | QueryArrayRecordType<Rest>
|
|
819
|
+
: never;
|
|
820
|
+
|
|
821
|
+
// If we can't infer any members at all, then return any.
|
|
822
|
+
type SingleQueryRecordType<T extends DeeplyReadonly<Query>> = ExtractMembers<T> extends never
|
|
823
|
+
? any
|
|
824
|
+
: { [K in string & ExtractMembers<T>]: string | number | boolean | null };
|
|
825
|
+
|
|
826
|
+
type ExtractMembers<T extends DeeplyReadonly<Query>> =
|
|
827
|
+
| ( T extends { dimensions: readonly (infer Names)[]; } ? Names : never )
|
|
828
|
+
| ( T extends { measures: readonly (infer Names)[]; } ? Names : never )
|
|
829
|
+
| ( T extends { timeDimensions: (infer U); } ? ExtractTimeMembers<U> : never );
|
|
830
|
+
|
|
831
|
+
type ExtractTimeMembers<T> =
|
|
832
|
+
T extends readonly [infer First, ...infer Rest]
|
|
833
|
+
? ExtractTimeMember<First> | ExtractTimeMembers<Rest>
|
|
834
|
+
: never;
|
|
835
|
+
|
|
836
|
+
type ExtractTimeMember<T> =
|
|
837
|
+
T extends { dimension: infer Dimension, granularity: infer Granularity }
|
|
838
|
+
? Dimension | `${Dimension & string}.${Granularity & string}`
|
|
839
|
+
: never;
|
|
840
|
+
|
|
811
841
|
export class ProgressResult {
|
|
812
842
|
stage(): string;
|
|
813
843
|
timeElapsed(): string;
|
|
@@ -983,7 +1013,10 @@ declare module '@cubejs-client/core' {
|
|
|
983
1013
|
* @order 2
|
|
984
1014
|
*/
|
|
985
1015
|
export class CubejsApi {
|
|
986
|
-
load
|
|
1016
|
+
load<QueryType extends DeeplyReadonly<Query | Query[]>>(
|
|
1017
|
+
query: QueryType,
|
|
1018
|
+
options?: LoadMethodOptions,
|
|
1019
|
+
): Promise<ResultSet<QueryRecordType<QueryType>>>;
|
|
987
1020
|
/**
|
|
988
1021
|
* Fetch data for the passed `query`.
|
|
989
1022
|
*
|
|
@@ -1008,13 +1041,18 @@ declare module '@cubejs-client/core' {
|
|
|
1008
1041
|
* ```
|
|
1009
1042
|
* @param query - [Query object](query-format)
|
|
1010
1043
|
*/
|
|
1011
|
-
load
|
|
1012
|
-
|
|
1013
|
-
|
|
1044
|
+
load<QueryType extends DeeplyReadonly<Query | Query[]>>(
|
|
1045
|
+
query: QueryType,
|
|
1046
|
+
options?: LoadMethodOptions,
|
|
1047
|
+
callback?: LoadMethodCallback<ResultSet<QueryRecordType<QueryType>>>,
|
|
1048
|
+
): void;
|
|
1049
|
+
|
|
1050
|
+
load<QueryType extends DeeplyReadonly<Query | Query[]>>(
|
|
1051
|
+
query: QueryType,
|
|
1014
1052
|
options?: LoadMethodOptions,
|
|
1015
1053
|
callback?: LoadMethodCallback<ResultSet>,
|
|
1016
1054
|
responseFormat?: string
|
|
1017
|
-
): Promise<ResultSet
|
|
1055
|
+
): Promise<ResultSet<QueryRecordType<QueryType>>>;
|
|
1018
1056
|
|
|
1019
1057
|
/**
|
|
1020
1058
|
* Allows you to fetch data and receive updates over time. See [Real-Time Data Fetch](real-time-data-fetch)
|
|
@@ -1040,7 +1078,11 @@ declare module '@cubejs-client/core' {
|
|
|
1040
1078
|
* );
|
|
1041
1079
|
* ```
|
|
1042
1080
|
*/
|
|
1043
|
-
subscribe
|
|
1081
|
+
subscribe<QueryType extends DeeplyReadonly<Query | Query[]>>(
|
|
1082
|
+
query: QueryType,
|
|
1083
|
+
options: LoadMethodOptions | null,
|
|
1084
|
+
callback: LoadMethodCallback<ResultSet<QueryRecordType<QueryType>>>,
|
|
1085
|
+
): void;
|
|
1044
1086
|
|
|
1045
1087
|
sql(query: DeeplyReadonly<Query | Query[]>, options?: LoadMethodOptions): Promise<SqlQuery>;
|
|
1046
1088
|
/**
|
|
@@ -1171,6 +1213,8 @@ declare module '@cubejs-client/core' {
|
|
|
1171
1213
|
export function getQueryMembers(query: DeeplyReadonly<Query>): string[];
|
|
1172
1214
|
|
|
1173
1215
|
export function areQueriesEqual(query1: DeeplyReadonly<Query> | null, query2: DeeplyReadonly<Query> | null): boolean;
|
|
1216
|
+
|
|
1217
|
+
export function validateQuery(query: DeeplyReadonly<Query> | null | undefined): Query;
|
|
1174
1218
|
|
|
1175
1219
|
export type ProgressResponse = {
|
|
1176
1220
|
stage: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cubejs-client/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.4",
|
|
4
4
|
"engines": {},
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"eslint-plugin-node": "^5.2.1",
|
|
47
47
|
"jest": "^26.0.1"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "b7df8f6a3cfe104e639e0f7607868afa193ed0a3"
|
|
50
50
|
}
|
package/src/index.js
CHANGED
|
@@ -368,15 +368,4 @@ class CubejsApi {
|
|
|
368
368
|
export default (apiToken, options) => new CubejsApi(apiToken, options);
|
|
369
369
|
|
|
370
370
|
export { CubejsApi, HttpTransport, ResultSet };
|
|
371
|
-
export
|
|
372
|
-
areQueriesEqual,
|
|
373
|
-
defaultHeuristics,
|
|
374
|
-
movePivotItem,
|
|
375
|
-
isQueryPresent,
|
|
376
|
-
moveItemInArray,
|
|
377
|
-
defaultOrder,
|
|
378
|
-
flattenFilters,
|
|
379
|
-
getQueryMembers,
|
|
380
|
-
getOrderMembersFromOrder,
|
|
381
|
-
GRANULARITIES
|
|
382
|
-
} from './utils';
|
|
371
|
+
export * from './utils';
|
package/src/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { indexBy, prop, clone, equals } from 'ramda';
|
|
1
|
+
import { indexBy, prop, clone, equals, fromPairs, toPairs } from 'ramda';
|
|
2
2
|
|
|
3
3
|
export const DEFAULT_GRANULARITY = 'day';
|
|
4
4
|
|
|
@@ -14,10 +14,52 @@ export const GRANULARITIES = [
|
|
|
14
14
|
{ name: 'year', title: 'Year' },
|
|
15
15
|
];
|
|
16
16
|
|
|
17
|
+
export function removeEmptyQueryFields(_query) {
|
|
18
|
+
const query = _query || {};
|
|
19
|
+
|
|
20
|
+
return fromPairs(
|
|
21
|
+
toPairs(query)
|
|
22
|
+
.map(([key, value]) => {
|
|
23
|
+
if (
|
|
24
|
+
['measures', 'dimensions', 'segments', 'timeDimensions', 'filters'].includes(key)
|
|
25
|
+
) {
|
|
26
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (key === 'order' && value) {
|
|
32
|
+
if (Array.isArray(value) && !value.length) {
|
|
33
|
+
return null;
|
|
34
|
+
} else if (!Object.keys(value).length) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return [key, value];
|
|
40
|
+
})
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function validateQuery(_query) {
|
|
46
|
+
const query = _query || {};
|
|
47
|
+
|
|
48
|
+
return removeEmptyQueryFields({
|
|
49
|
+
...query,
|
|
50
|
+
filters: (query.filters || []).filter((f) => f.operator),
|
|
51
|
+
timeDimensions: (query.timeDimensions || []).filter(
|
|
52
|
+
(td) => !(!td.dateRange && !td.granularity)
|
|
53
|
+
),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
17
57
|
export function areQueriesEqual(query1 = {}, query2 = {}) {
|
|
18
58
|
return (
|
|
19
|
-
equals(
|
|
20
|
-
|
|
59
|
+
equals(
|
|
60
|
+
Object.entries((query1 && query1.order) || {}),
|
|
61
|
+
Object.entries((query2 && query2.order) || {})
|
|
62
|
+
) && equals(query1, query2)
|
|
21
63
|
);
|
|
22
64
|
}
|
|
23
65
|
|
|
@@ -28,7 +70,10 @@ export function defaultOrder(query) {
|
|
|
28
70
|
return {
|
|
29
71
|
[granularity.dimension]: 'asc',
|
|
30
72
|
};
|
|
31
|
-
} else if (
|
|
73
|
+
} else if (
|
|
74
|
+
(query.measures || []).length > 0 &&
|
|
75
|
+
(query.dimensions || []).length > 0
|
|
76
|
+
) {
|
|
32
77
|
return {
|
|
33
78
|
[query.measures[0]]: 'desc',
|
|
34
79
|
};
|
|
@@ -65,7 +110,8 @@ export function defaultHeuristics(newState, oldQuery = {}, options) {
|
|
|
65
110
|
(oldQuery.timeDimensions || []).length === 1 &&
|
|
66
111
|
(newQuery.timeDimensions || []).length === 1 &&
|
|
67
112
|
newQuery.timeDimensions[0].granularity &&
|
|
68
|
-
oldQuery.timeDimensions[0].granularity !==
|
|
113
|
+
oldQuery.timeDimensions[0].granularity !==
|
|
114
|
+
newQuery.timeDimensions[0].granularity
|
|
69
115
|
) {
|
|
70
116
|
state = {
|
|
71
117
|
...state,
|
|
@@ -74,13 +120,16 @@ export function defaultHeuristics(newState, oldQuery = {}, options) {
|
|
|
74
120
|
}
|
|
75
121
|
|
|
76
122
|
if (
|
|
77
|
-
((oldQuery.measures || []).length === 0 &&
|
|
123
|
+
((oldQuery.measures || []).length === 0 &&
|
|
124
|
+
(newQuery.measures || []).length > 0) ||
|
|
78
125
|
((oldQuery.measures || []).length === 1 &&
|
|
79
126
|
(newQuery.measures || []).length === 1 &&
|
|
80
127
|
oldQuery.measures[0] !== newQuery.measures[0])
|
|
81
128
|
) {
|
|
82
129
|
const [td] = newQuery.timeDimensions || [];
|
|
83
|
-
const defaultTimeDimension = meta.defaultTimeDimensionNameFor(
|
|
130
|
+
const defaultTimeDimension = meta.defaultTimeDimensionNameFor(
|
|
131
|
+
newQuery.measures[0]
|
|
132
|
+
);
|
|
84
133
|
newQuery = {
|
|
85
134
|
...newQuery,
|
|
86
135
|
timeDimensions: defaultTimeDimension
|
|
@@ -103,10 +152,16 @@ export function defaultHeuristics(newState, oldQuery = {}, options) {
|
|
|
103
152
|
};
|
|
104
153
|
}
|
|
105
154
|
|
|
106
|
-
if (
|
|
155
|
+
if (
|
|
156
|
+
(oldQuery.dimensions || []).length === 0 &&
|
|
157
|
+
(newQuery.dimensions || []).length > 0
|
|
158
|
+
) {
|
|
107
159
|
newQuery = {
|
|
108
160
|
...newQuery,
|
|
109
|
-
timeDimensions: (newQuery.timeDimensions || []).map((td) => ({
|
|
161
|
+
timeDimensions: (newQuery.timeDimensions || []).map((td) => ({
|
|
162
|
+
...td,
|
|
163
|
+
granularity: undefined,
|
|
164
|
+
})),
|
|
110
165
|
};
|
|
111
166
|
|
|
112
167
|
return {
|
|
@@ -118,7 +173,10 @@ export function defaultHeuristics(newState, oldQuery = {}, options) {
|
|
|
118
173
|
};
|
|
119
174
|
}
|
|
120
175
|
|
|
121
|
-
if (
|
|
176
|
+
if (
|
|
177
|
+
(oldQuery.dimensions || []).length > 0 &&
|
|
178
|
+
(newQuery.dimensions || []).length === 0
|
|
179
|
+
) {
|
|
122
180
|
newQuery = {
|
|
123
181
|
...newQuery,
|
|
124
182
|
timeDimensions: (newQuery.timeDimensions || []).map((td) => ({
|
|
@@ -137,7 +195,8 @@ export function defaultHeuristics(newState, oldQuery = {}, options) {
|
|
|
137
195
|
}
|
|
138
196
|
|
|
139
197
|
if (
|
|
140
|
-
((oldQuery.dimensions || []).length > 0 ||
|
|
198
|
+
((oldQuery.dimensions || []).length > 0 ||
|
|
199
|
+
(oldQuery.measures || []).length > 0) &&
|
|
141
200
|
(newQuery.dimensions || []).length === 0 &&
|
|
142
201
|
(newQuery.measures || []).length === 0
|
|
143
202
|
) {
|
|
@@ -177,7 +236,9 @@ export function defaultHeuristics(newState, oldQuery = {}, options) {
|
|
|
177
236
|
}
|
|
178
237
|
|
|
179
238
|
if (
|
|
180
|
-
(newChartType === 'pie' ||
|
|
239
|
+
(newChartType === 'pie' ||
|
|
240
|
+
newChartType === 'table' ||
|
|
241
|
+
newChartType === 'number') &&
|
|
181
242
|
(oldQuery.timeDimensions || []).length === 1 &&
|
|
182
243
|
oldQuery.timeDimensions[0].granularity
|
|
183
244
|
) {
|
|
@@ -209,7 +270,13 @@ export function isQueryPresent(query) {
|
|
|
209
270
|
);
|
|
210
271
|
}
|
|
211
272
|
|
|
212
|
-
export function movePivotItem(
|
|
273
|
+
export function movePivotItem(
|
|
274
|
+
pivotConfig,
|
|
275
|
+
sourceIndex,
|
|
276
|
+
destinationIndex,
|
|
277
|
+
sourceAxis,
|
|
278
|
+
destinationAxis
|
|
279
|
+
) {
|
|
213
280
|
const nextPivotConfig = {
|
|
214
281
|
...pivotConfig,
|
|
215
282
|
x: [...pivotConfig.x],
|
|
@@ -220,7 +287,10 @@ export function movePivotItem(pivotConfig, sourceIndex, destinationIndex, source
|
|
|
220
287
|
|
|
221
288
|
if (id === 'measures') {
|
|
222
289
|
destinationIndex = lastIndex + 1;
|
|
223
|
-
} else if (
|
|
290
|
+
} else if (
|
|
291
|
+
destinationIndex >= lastIndex &&
|
|
292
|
+
nextPivotConfig[destinationAxis][lastIndex] === 'measures'
|
|
293
|
+
) {
|
|
224
294
|
destinationIndex = lastIndex - 1;
|
|
225
295
|
}
|
|
226
296
|
|
|
@@ -290,7 +360,11 @@ export function getOrderMembersFromOrder(orderMembers, order) {
|
|
|
290
360
|
export function aliasSeries(values, index, pivotConfig, duplicateMeasures) {
|
|
291
361
|
const nonNullValues = values.filter((value) => value != null);
|
|
292
362
|
|
|
293
|
-
if (
|
|
363
|
+
if (
|
|
364
|
+
pivotConfig &&
|
|
365
|
+
pivotConfig.aliasSeries &&
|
|
366
|
+
pivotConfig.aliasSeries[index]
|
|
367
|
+
) {
|
|
294
368
|
return [pivotConfig.aliasSeries[index], ...nonNullValues];
|
|
295
369
|
} else if (duplicateMeasures.has(nonNullValues[0])) {
|
|
296
370
|
return [index, ...nonNullValues];
|