@cubejs-client/core 1.3.14 → 1.3.16
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/{cubejs-client-core.js → cubejs-client-core.cjs.js} +1016 -411
- package/dist/cubejs-client-core.cjs.js.map +1 -0
- package/dist/cubejs-client-core.umd.js +2901 -12088
- package/dist/cubejs-client-core.umd.js.map +1 -1
- package/dist/src/HttpTransport.d.ts +54 -0
- package/dist/src/HttpTransport.d.ts.map +1 -0
- package/dist/src/HttpTransport.js +55 -0
- package/dist/src/Meta.d.ts +62 -0
- package/dist/src/Meta.d.ts.map +1 -0
- package/dist/src/Meta.js +150 -0
- package/dist/src/ProgressResult.d.ts +8 -0
- package/dist/src/ProgressResult.d.ts.map +1 -0
- package/dist/src/ProgressResult.js +11 -0
- package/dist/src/RequestError.d.ts +6 -0
- package/dist/src/RequestError.d.ts.map +1 -0
- package/dist/src/RequestError.js +7 -0
- package/dist/src/ResultSet.d.ts +430 -0
- package/dist/src/ResultSet.d.ts.map +1 -0
- package/dist/src/ResultSet.js +952 -0
- package/dist/src/SqlQuery.d.ts +17 -0
- package/dist/src/SqlQuery.d.ts.map +1 -0
- package/dist/src/SqlQuery.js +11 -0
- package/dist/src/index.d.ts +194 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +411 -0
- package/dist/src/index.umd.d.ts +3 -0
- package/dist/src/index.umd.d.ts.map +1 -0
- package/dist/src/index.umd.js +6 -0
- package/dist/src/time.d.ts +70 -0
- package/dist/src/time.d.ts.map +1 -0
- package/dist/src/time.js +249 -0
- package/dist/src/types.d.ts +424 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +1 -0
- package/dist/src/utils.d.ts +19 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +294 -0
- package/dist/test/CubeApi.test.d.ts +7 -0
- package/dist/test/CubeApi.test.d.ts.map +1 -0
- package/dist/test/CubeApi.test.js +279 -0
- package/dist/test/HttpTransport.test.d.ts +2 -0
- package/dist/test/HttpTransport.test.d.ts.map +1 -0
- package/dist/test/HttpTransport.test.js +244 -0
- package/dist/test/ResultSet.test.d.ts +7 -0
- package/dist/test/ResultSet.test.d.ts.map +1 -0
- package/dist/test/ResultSet.test.js +1725 -0
- package/dist/test/compare-date-range.test.d.ts +2 -0
- package/dist/test/compare-date-range.test.d.ts.map +1 -0
- package/dist/test/compare-date-range.test.js +742 -0
- package/dist/test/data-blending.test.d.ts +2 -0
- package/dist/test/data-blending.test.d.ts.map +1 -0
- package/dist/test/data-blending.test.js +423 -0
- package/dist/test/default-heuristics.test.d.ts +2 -0
- package/dist/test/default-heuristics.test.d.ts.map +1 -0
- package/dist/test/default-heuristics.test.js +108 -0
- package/dist/test/drill-down.test.d.ts +2 -0
- package/dist/test/drill-down.test.d.ts.map +1 -0
- package/dist/test/drill-down.test.js +373 -0
- package/dist/test/fixtures/datablending/load-responses.json +261 -0
- package/dist/test/granularity.test.d.ts +2 -0
- package/dist/test/granularity.test.d.ts.map +1 -0
- package/dist/test/granularity.test.js +218 -0
- package/dist/test/helpers.d.ts +283 -0
- package/dist/test/helpers.d.ts.map +1 -0
- package/dist/test/helpers.js +974 -0
- package/dist/test/index.test.d.ts +7 -0
- package/dist/test/index.test.d.ts.map +1 -0
- package/dist/test/index.test.js +370 -0
- package/dist/test/table.test.d.ts +2 -0
- package/dist/test/table.test.d.ts.map +1 -0
- package/dist/test/table.test.js +757 -0
- package/dist/test/utils.test.d.ts +2 -0
- package/dist/test/utils.test.d.ts.map +1 -0
- package/dist/test/utils.test.js +32 -0
- package/package.json +26 -21
- package/dist/cubejs-client-core.esm.js +0 -1639
- package/dist/cubejs-client-core.esm.js.map +0 -1
- package/dist/cubejs-client-core.js.map +0 -1
- package/index.d.ts +0 -1338
- package/src/HttpTransport.js +0 -60
- package/src/HttpTransport.test.js +0 -117
- package/src/Meta.js +0 -142
- package/src/ProgressResult.js +0 -13
- package/src/RequestError.js +0 -7
- package/src/ResultSet.js +0 -746
- package/src/SqlQuery.js +0 -13
- package/src/index.js +0 -398
- package/src/index.test.js +0 -454
- package/src/index.umd.js +0 -8
- package/src/tests/ResultSet.test.js +0 -1655
- package/src/tests/compare-date-range.test.js +0 -753
- package/src/tests/data-blending.test.js +0 -432
- package/src/tests/default-heuristics.test.js +0 -118
- package/src/tests/drill-down.test.js +0 -402
- package/src/tests/fixtures/datablending/load-responses.json +0 -261
- package/src/tests/granularity.test.js +0 -225
- package/src/tests/table.test.js +0 -791
- package/src/tests/utils.test.js +0 -35
- package/src/time.js +0 -296
- package/src/utils.js +0 -368
package/src/SqlQuery.js
DELETED
package/src/index.js
DELETED
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import ResultSet from './ResultSet';
|
|
3
|
-
import SqlQuery from './SqlQuery';
|
|
4
|
-
import Meta from './Meta';
|
|
5
|
-
import ProgressResult from './ProgressResult';
|
|
6
|
-
import HttpTransport from './HttpTransport';
|
|
7
|
-
import RequestError from './RequestError';
|
|
8
|
-
|
|
9
|
-
let mutexCounter = 0;
|
|
10
|
-
|
|
11
|
-
const MUTEX_ERROR = 'Mutex has been changed';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Query result dataset formats enum.
|
|
15
|
-
*/
|
|
16
|
-
const ResultType = {
|
|
17
|
-
DEFAULT: 'default',
|
|
18
|
-
COMPACT: 'compact'
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
function mutexPromise(promise) {
|
|
22
|
-
return new Promise(async (resolve, reject) => {
|
|
23
|
-
try {
|
|
24
|
-
resolve(await promise);
|
|
25
|
-
} catch (error) {
|
|
26
|
-
if (error !== MUTEX_ERROR) {
|
|
27
|
-
reject(error);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
class CubeApi {
|
|
34
|
-
constructor(apiToken, options) {
|
|
35
|
-
if (apiToken !== null && !Array.isArray(apiToken) && typeof apiToken === 'object') {
|
|
36
|
-
options = apiToken;
|
|
37
|
-
apiToken = undefined;
|
|
38
|
-
}
|
|
39
|
-
options = options || {};
|
|
40
|
-
|
|
41
|
-
if (!options.transport && !options.apiUrl) {
|
|
42
|
-
throw new Error('The `apiUrl` option is required');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
this.apiToken = apiToken;
|
|
46
|
-
this.apiUrl = options.apiUrl;
|
|
47
|
-
this.method = options.method;
|
|
48
|
-
this.headers = options.headers || {};
|
|
49
|
-
this.credentials = options.credentials;
|
|
50
|
-
this.transport = options.transport || new HttpTransport({
|
|
51
|
-
authorization: typeof apiToken === 'function' ? undefined : apiToken,
|
|
52
|
-
apiUrl: this.apiUrl,
|
|
53
|
-
method: this.method,
|
|
54
|
-
headers: this.headers,
|
|
55
|
-
credentials: this.credentials
|
|
56
|
-
});
|
|
57
|
-
this.pollInterval = options.pollInterval || 5;
|
|
58
|
-
this.parseDateMeasures = options.parseDateMeasures;
|
|
59
|
-
this.castNumerics = typeof options.castNumerics === 'boolean' ? options.castNumerics : false;
|
|
60
|
-
this.networkErrorRetries = options.networkErrorRetries || 0;
|
|
61
|
-
|
|
62
|
-
this.updateAuthorizationPromise = null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
request(method, params) {
|
|
66
|
-
return this.transport.request(method, {
|
|
67
|
-
baseRequestId: uuidv4(),
|
|
68
|
-
...params
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
loadMethod(request, toResult, options, callback) {
|
|
73
|
-
const mutexValue = ++mutexCounter;
|
|
74
|
-
if (typeof options === 'function' && !callback) {
|
|
75
|
-
callback = options;
|
|
76
|
-
options = undefined;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
options = options || {};
|
|
80
|
-
|
|
81
|
-
const mutexKey = options.mutexKey || 'default';
|
|
82
|
-
if (options.mutexObj) {
|
|
83
|
-
options.mutexObj[mutexKey] = mutexValue;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const requestPromise = this
|
|
87
|
-
.updateTransportAuthorization()
|
|
88
|
-
.then(() => request());
|
|
89
|
-
|
|
90
|
-
let skipAuthorizationUpdate = true;
|
|
91
|
-
let unsubscribed = false;
|
|
92
|
-
|
|
93
|
-
const checkMutex = async () => {
|
|
94
|
-
const requestInstance = await requestPromise;
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
options.mutexObj &&
|
|
98
|
-
options.mutexObj[mutexKey] !== mutexValue
|
|
99
|
-
) {
|
|
100
|
-
unsubscribed = true;
|
|
101
|
-
if (requestInstance.unsubscribe) {
|
|
102
|
-
await requestInstance.unsubscribe();
|
|
103
|
-
}
|
|
104
|
-
throw MUTEX_ERROR;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
let networkRetries = this.networkErrorRetries;
|
|
109
|
-
|
|
110
|
-
const loadImpl = async (response, next) => {
|
|
111
|
-
const requestInstance = await requestPromise;
|
|
112
|
-
|
|
113
|
-
const subscribeNext = async () => {
|
|
114
|
-
if (options.subscribe && !unsubscribed) {
|
|
115
|
-
if (requestInstance.unsubscribe) {
|
|
116
|
-
return next();
|
|
117
|
-
} else {
|
|
118
|
-
await new Promise(resolve => setTimeout(() => resolve(), this.pollInterval * 1000));
|
|
119
|
-
return next();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return null;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const continueWait = async (wait) => {
|
|
126
|
-
if (!unsubscribed) {
|
|
127
|
-
if (wait) {
|
|
128
|
-
await new Promise(resolve => setTimeout(() => resolve(), this.pollInterval * 1000));
|
|
129
|
-
}
|
|
130
|
-
return next();
|
|
131
|
-
}
|
|
132
|
-
return null;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
if (options.subscribe && !skipAuthorizationUpdate) {
|
|
136
|
-
await this.updateTransportAuthorization();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
skipAuthorizationUpdate = false;
|
|
140
|
-
|
|
141
|
-
if (response.status === 502 ||
|
|
142
|
-
response.error &&
|
|
143
|
-
response.error.toLowerCase() === 'network error' &&
|
|
144
|
-
--networkRetries >= 0
|
|
145
|
-
) {
|
|
146
|
-
await checkMutex();
|
|
147
|
-
return continueWait(true);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
let body = {};
|
|
151
|
-
let text = '';
|
|
152
|
-
try {
|
|
153
|
-
text = await response.text();
|
|
154
|
-
body = JSON.parse(text);
|
|
155
|
-
} catch (_) {
|
|
156
|
-
body.error = text;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (body.error === 'Continue wait') {
|
|
160
|
-
await checkMutex();
|
|
161
|
-
if (options.progressCallback) {
|
|
162
|
-
options.progressCallback(new ProgressResult(body));
|
|
163
|
-
}
|
|
164
|
-
return continueWait();
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (response.status !== 200) {
|
|
168
|
-
await checkMutex();
|
|
169
|
-
if (!options.subscribe && requestInstance.unsubscribe) {
|
|
170
|
-
await requestInstance.unsubscribe();
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const error = new RequestError(body.error, body, response.status); // TODO error class
|
|
174
|
-
if (callback) {
|
|
175
|
-
callback(error);
|
|
176
|
-
} else {
|
|
177
|
-
throw error;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return subscribeNext();
|
|
181
|
-
}
|
|
182
|
-
await checkMutex();
|
|
183
|
-
if (!options.subscribe && requestInstance.unsubscribe) {
|
|
184
|
-
await requestInstance.unsubscribe();
|
|
185
|
-
}
|
|
186
|
-
const result = toResult(body);
|
|
187
|
-
if (callback) {
|
|
188
|
-
callback(null, result);
|
|
189
|
-
} else {
|
|
190
|
-
return result;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return subscribeNext();
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const promise = requestPromise.then(requestInstance => mutexPromise(requestInstance.subscribe(loadImpl)));
|
|
197
|
-
|
|
198
|
-
if (callback) {
|
|
199
|
-
return {
|
|
200
|
-
unsubscribe: async () => {
|
|
201
|
-
const requestInstance = await requestPromise;
|
|
202
|
-
|
|
203
|
-
unsubscribed = true;
|
|
204
|
-
if (requestInstance.unsubscribe) {
|
|
205
|
-
return requestInstance.unsubscribe();
|
|
206
|
-
}
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
} else {
|
|
211
|
-
return promise;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async updateTransportAuthorization() {
|
|
216
|
-
if (this.updateAuthorizationPromise) {
|
|
217
|
-
await this.updateAuthorizationPromise;
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (typeof this.apiToken === 'function') {
|
|
222
|
-
this.updateAuthorizationPromise = new Promise(async (resolve, reject) => {
|
|
223
|
-
try {
|
|
224
|
-
const token = await this.apiToken();
|
|
225
|
-
if (this.transport.authorization !== token) {
|
|
226
|
-
this.transport.authorization = token;
|
|
227
|
-
}
|
|
228
|
-
resolve();
|
|
229
|
-
} catch (error) {
|
|
230
|
-
reject(error);
|
|
231
|
-
} finally {
|
|
232
|
-
this.updateAuthorizationPromise = null;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
await this.updateAuthorizationPromise;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Add system properties to a query object.
|
|
242
|
-
* @param {Query} query
|
|
243
|
-
* @param {string} responseFormat
|
|
244
|
-
* @returns {void}
|
|
245
|
-
* @private
|
|
246
|
-
*/
|
|
247
|
-
patchQueryInternal(query, responseFormat) {
|
|
248
|
-
if (
|
|
249
|
-
responseFormat === ResultType.COMPACT &&
|
|
250
|
-
query.responseFormat !== ResultType.COMPACT
|
|
251
|
-
) {
|
|
252
|
-
return {
|
|
253
|
-
...query,
|
|
254
|
-
responseFormat: ResultType.COMPACT,
|
|
255
|
-
};
|
|
256
|
-
} else {
|
|
257
|
-
return query;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Process result fetched from the gateway#load method according
|
|
263
|
-
* to the network protocol.
|
|
264
|
-
* @param {*} response
|
|
265
|
-
* @returns ResultSet
|
|
266
|
-
* @private
|
|
267
|
-
*/
|
|
268
|
-
loadResponseInternal(response, options = {}) {
|
|
269
|
-
if (
|
|
270
|
-
response.results.length
|
|
271
|
-
) {
|
|
272
|
-
if (options.castNumerics) {
|
|
273
|
-
response.results.forEach((result) => {
|
|
274
|
-
const numericMembers = Object.entries({
|
|
275
|
-
...result.annotation.measures,
|
|
276
|
-
...result.annotation.dimensions,
|
|
277
|
-
}).map(([k, v]) => {
|
|
278
|
-
if (v.type === 'number') {
|
|
279
|
-
return k;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return undefined;
|
|
283
|
-
}).filter(Boolean);
|
|
284
|
-
|
|
285
|
-
result.data = result.data.map((row) => {
|
|
286
|
-
numericMembers.forEach((key) => {
|
|
287
|
-
if (row[key] != null) {
|
|
288
|
-
row[key] = Number(row[key]);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
return row;
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (response.results[0].query.responseFormat &&
|
|
298
|
-
response.results[0].query.responseFormat === ResultType.COMPACT) {
|
|
299
|
-
response.results.forEach((result, j) => {
|
|
300
|
-
const data = [];
|
|
301
|
-
result.data.dataset.forEach((r) => {
|
|
302
|
-
const row = {};
|
|
303
|
-
result.data.members.forEach((m, i) => {
|
|
304
|
-
row[m] = r[i];
|
|
305
|
-
});
|
|
306
|
-
data.push(row);
|
|
307
|
-
});
|
|
308
|
-
response.results[j].data = data;
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return new ResultSet(response, {
|
|
314
|
-
parseDateMeasures: this.parseDateMeasures
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
load(query, options, callback, responseFormat = ResultType.DEFAULT) {
|
|
319
|
-
options = {
|
|
320
|
-
castNumerics: this.castNumerics,
|
|
321
|
-
...options
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
if (responseFormat === ResultType.COMPACT) {
|
|
325
|
-
if (Array.isArray(query)) {
|
|
326
|
-
query = query.map((q) => this.patchQueryInternal(q, ResultType.COMPACT));
|
|
327
|
-
} else {
|
|
328
|
-
query = this.patchQueryInternal(query, ResultType.COMPACT);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return this.loadMethod(
|
|
332
|
-
() => this.request('load', {
|
|
333
|
-
query,
|
|
334
|
-
queryType: 'multi',
|
|
335
|
-
}),
|
|
336
|
-
(response) => this.loadResponseInternal(response, options),
|
|
337
|
-
options,
|
|
338
|
-
callback
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
subscribe(query, options, callback, responseFormat = ResultType.DEFAULT) {
|
|
343
|
-
options = {
|
|
344
|
-
castNumerics: this.castNumerics,
|
|
345
|
-
...options
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
if (responseFormat === ResultType.COMPACT) {
|
|
349
|
-
if (Array.isArray(query)) {
|
|
350
|
-
query = query.map((q) => this.patchQueryInternal(q, ResultType.COMPACT));
|
|
351
|
-
} else {
|
|
352
|
-
query = this.patchQueryInternal(query, ResultType.COMPACT);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return this.loadMethod(
|
|
356
|
-
() => this.request('subscribe', {
|
|
357
|
-
query,
|
|
358
|
-
queryType: 'multi',
|
|
359
|
-
}),
|
|
360
|
-
(response) => this.loadResponseInternal(response, options),
|
|
361
|
-
{ ...options, subscribe: true },
|
|
362
|
-
callback
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
sql(query, options, callback) {
|
|
367
|
-
return this.loadMethod(
|
|
368
|
-
() => this.request('sql', { query }),
|
|
369
|
-
(response) => (Array.isArray(response) ? response.map((body) => new SqlQuery(body)) : new SqlQuery(response)),
|
|
370
|
-
options,
|
|
371
|
-
callback
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
meta(options, callback) {
|
|
376
|
-
return this.loadMethod(
|
|
377
|
-
() => this.request('meta'),
|
|
378
|
-
(body) => new Meta(body),
|
|
379
|
-
options,
|
|
380
|
-
callback
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
dryRun(query, options, callback) {
|
|
385
|
-
return this.loadMethod(
|
|
386
|
-
() => this.request('dry-run', { query }),
|
|
387
|
-
(response) => response,
|
|
388
|
-
options,
|
|
389
|
-
callback
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
export default (apiToken, options) => new CubeApi(apiToken, options);
|
|
395
|
-
|
|
396
|
-
export { CubeApi, HttpTransport, ResultSet, RequestError, Meta };
|
|
397
|
-
export * from './utils';
|
|
398
|
-
export * from './time';
|