@cubejs-client/core 1.3.15 → 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
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/* eslint-disable import/first */
|
|
2
|
+
/* globals describe,test,expect,jest,afterEach,beforeAll,beforeEach */
|
|
3
|
+
import fetch from 'cross-fetch';
|
|
4
|
+
jest.mock('cross-fetch');
|
|
5
|
+
import HttpTransport from '../src/HttpTransport';
|
|
6
|
+
const mockedFetch = fetch;
|
|
7
|
+
describe('HttpTransport', () => {
|
|
8
|
+
const apiUrl = 'http://localhost:3000/cubejs-api/v1';
|
|
9
|
+
const query = {
|
|
10
|
+
measures: ['Orders.count'],
|
|
11
|
+
dimensions: ['Users.country']
|
|
12
|
+
};
|
|
13
|
+
const queryUrlEncoded = '%7B%22measures%22%3A%5B%22Orders.count%22%5D%2C%22dimensions%22%3A%5B%22Users.country%22%5D%7D';
|
|
14
|
+
const queryJson = '{"query":{"measures":["Orders.count"],"dimensions":["Users.country"]}}';
|
|
15
|
+
const ids = [];
|
|
16
|
+
for (let i = 0; i < 40; i++)
|
|
17
|
+
ids.push('a40b2052-4137-11eb-b378-0242ac130002');
|
|
18
|
+
const LargeQuery = {
|
|
19
|
+
measures: ['Orders.count'],
|
|
20
|
+
dimensions: ['Users.country'],
|
|
21
|
+
filters: [
|
|
22
|
+
{
|
|
23
|
+
member: 'Users.id',
|
|
24
|
+
operator: 'equals',
|
|
25
|
+
values: ids
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
};
|
|
29
|
+
const largeQueryJson = `{"query":{"measures":["Orders.count"],"dimensions":["Users.country"],"filters":[{"member":"Users.id","operator":"equals","values":${JSON.stringify(ids)}}]}}`;
|
|
30
|
+
beforeAll(() => {
|
|
31
|
+
mockedFetch.mockReturnValue(Promise.resolve({ ok: true }));
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
mockedFetch.mockClear();
|
|
35
|
+
});
|
|
36
|
+
test('it serializes the query object and sends it in the query string', async () => {
|
|
37
|
+
const transport = new HttpTransport({
|
|
38
|
+
authorization: 'token',
|
|
39
|
+
apiUrl,
|
|
40
|
+
});
|
|
41
|
+
const req = transport.request('load', { query });
|
|
42
|
+
await req.subscribe(() => { console.log('subscribe cb'); });
|
|
43
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
44
|
+
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load?query=${queryUrlEncoded}`, {
|
|
45
|
+
method: 'GET',
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: 'token',
|
|
48
|
+
},
|
|
49
|
+
body: null
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
test('it passes extra headers and serializes extra params', async () => {
|
|
53
|
+
const extraParams = { foo: 'bar' };
|
|
54
|
+
const serializedExtraParams = encodeURIComponent(JSON.stringify(extraParams));
|
|
55
|
+
const transport = new HttpTransport({
|
|
56
|
+
authorization: 'token',
|
|
57
|
+
apiUrl,
|
|
58
|
+
headers: {
|
|
59
|
+
'X-Extra-Header': '42'
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const req = transport.request('meta', { extraParams });
|
|
63
|
+
await req.subscribe(() => { console.log('subscribe cb'); });
|
|
64
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
65
|
+
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/meta?extraParams=${serializedExtraParams}`, {
|
|
66
|
+
method: 'GET',
|
|
67
|
+
headers: {
|
|
68
|
+
Authorization: 'token',
|
|
69
|
+
'X-Extra-Header': '42'
|
|
70
|
+
},
|
|
71
|
+
body: null
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
test('it serializes the query object and sends it in the body', async () => {
|
|
75
|
+
const transport = new HttpTransport({
|
|
76
|
+
authorization: 'token',
|
|
77
|
+
apiUrl,
|
|
78
|
+
method: 'POST'
|
|
79
|
+
});
|
|
80
|
+
const req = transport.request('load', { query });
|
|
81
|
+
await req.subscribe(() => { console.log('subscribe cb'); });
|
|
82
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
83
|
+
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load`, {
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: {
|
|
86
|
+
Authorization: 'token',
|
|
87
|
+
'Content-Type': 'application/json'
|
|
88
|
+
},
|
|
89
|
+
body: queryJson
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
test('it use POST over GET if url length is more than 2000 characters', async () => {
|
|
93
|
+
const transport = new HttpTransport({
|
|
94
|
+
authorization: 'token',
|
|
95
|
+
apiUrl
|
|
96
|
+
});
|
|
97
|
+
const req = transport.request('load', { query: LargeQuery });
|
|
98
|
+
await req.subscribe(() => { console.log('subscribe cb'); });
|
|
99
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
100
|
+
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load`, {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers: {
|
|
103
|
+
Authorization: 'token',
|
|
104
|
+
'Content-Type': 'application/json'
|
|
105
|
+
},
|
|
106
|
+
body: largeQueryJson
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
// Signal tests from src/tests/HttpTransport.test.js
|
|
110
|
+
describe('Signal functionality', () => {
|
|
111
|
+
beforeEach(() => {
|
|
112
|
+
// Default mock implementation for signal tests
|
|
113
|
+
mockedFetch.mockImplementation(() => Promise.resolve({
|
|
114
|
+
json: () => Promise.resolve({ data: 'test data' }),
|
|
115
|
+
ok: true,
|
|
116
|
+
status: 200
|
|
117
|
+
}));
|
|
118
|
+
});
|
|
119
|
+
afterEach(() => {
|
|
120
|
+
mockedFetch.mockClear();
|
|
121
|
+
});
|
|
122
|
+
test('should pass the signal to fetch when provided in constructor', async () => {
|
|
123
|
+
const controller = new AbortController();
|
|
124
|
+
const { signal } = controller;
|
|
125
|
+
const transport = new HttpTransport({
|
|
126
|
+
authorization: 'token',
|
|
127
|
+
apiUrl: 'http://localhost:4000/cubejs-api/v1',
|
|
128
|
+
signal
|
|
129
|
+
});
|
|
130
|
+
const request = transport.request('load', { query: { measures: ['Orders.count'] } });
|
|
131
|
+
// Start the request
|
|
132
|
+
const promise = request.subscribe((result) => result);
|
|
133
|
+
// Wait for fetch to be called
|
|
134
|
+
await Promise.resolve();
|
|
135
|
+
// Ensure fetch was called with the signal
|
|
136
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
137
|
+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(signal);
|
|
138
|
+
await promise;
|
|
139
|
+
});
|
|
140
|
+
test('should pass the signal to fetch when provided in request method', async () => {
|
|
141
|
+
const controller = new AbortController();
|
|
142
|
+
const { signal } = controller;
|
|
143
|
+
const transport = new HttpTransport({
|
|
144
|
+
authorization: 'token',
|
|
145
|
+
apiUrl: 'http://localhost:4000/cubejs-api/v1'
|
|
146
|
+
});
|
|
147
|
+
const request = transport.request('load', {
|
|
148
|
+
query: { measures: ['Orders.count'] },
|
|
149
|
+
signal
|
|
150
|
+
});
|
|
151
|
+
// Start the request
|
|
152
|
+
const promise = request.subscribe((result) => result);
|
|
153
|
+
// Wait for fetch to be called
|
|
154
|
+
await Promise.resolve();
|
|
155
|
+
// Ensure fetch was called with the signal
|
|
156
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
157
|
+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(signal);
|
|
158
|
+
await promise;
|
|
159
|
+
});
|
|
160
|
+
test('should prioritize request signal over constructor signal', async () => {
|
|
161
|
+
const controller1 = new AbortController();
|
|
162
|
+
const controller2 = new AbortController();
|
|
163
|
+
const transport = new HttpTransport({
|
|
164
|
+
authorization: 'token',
|
|
165
|
+
apiUrl: 'http://localhost:4000/cubejs-api/v1',
|
|
166
|
+
signal: controller1.signal
|
|
167
|
+
});
|
|
168
|
+
const request = transport.request('load', {
|
|
169
|
+
query: { measures: ['Orders.count'] },
|
|
170
|
+
signal: controller2.signal
|
|
171
|
+
});
|
|
172
|
+
// Start the request
|
|
173
|
+
const promise = request.subscribe((result) => result);
|
|
174
|
+
// Wait for fetch to be called
|
|
175
|
+
await Promise.resolve();
|
|
176
|
+
// Ensure fetch was called with the request signal, not the constructor signal
|
|
177
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
178
|
+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(controller2.signal);
|
|
179
|
+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).not.toBe(controller1.signal);
|
|
180
|
+
await promise;
|
|
181
|
+
});
|
|
182
|
+
test('should create AbortSignal.timeout from fetchTimeout if signal not provided', async () => {
|
|
183
|
+
// Mock AbortSignal.timeout
|
|
184
|
+
const originalTimeout = AbortSignal.timeout;
|
|
185
|
+
const mockTimeoutSignal = {};
|
|
186
|
+
AbortSignal.timeout = jest.fn().mockReturnValue(mockTimeoutSignal);
|
|
187
|
+
const transport = new HttpTransport({
|
|
188
|
+
authorization: 'token',
|
|
189
|
+
apiUrl: 'http://localhost:4000/cubejs-api/v1',
|
|
190
|
+
fetchTimeout: 5000
|
|
191
|
+
});
|
|
192
|
+
const request = transport.request('load', {
|
|
193
|
+
query: { measures: ['Orders.count'] }
|
|
194
|
+
});
|
|
195
|
+
// Start the request
|
|
196
|
+
const promise = request.subscribe((result) => result);
|
|
197
|
+
// Wait for fetch to be called
|
|
198
|
+
await Promise.resolve();
|
|
199
|
+
// Ensure fetch was called with the timeout signal
|
|
200
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
201
|
+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(mockTimeoutSignal);
|
|
202
|
+
expect(AbortSignal.timeout).toHaveBeenCalledWith(5000);
|
|
203
|
+
// Restore original implementation
|
|
204
|
+
AbortSignal.timeout = originalTimeout;
|
|
205
|
+
await promise;
|
|
206
|
+
});
|
|
207
|
+
test('should handle request abortion', async () => {
|
|
208
|
+
// Create a mock Promise and resolver function to control Promise completion
|
|
209
|
+
let resolveFetch;
|
|
210
|
+
const fetchPromise = new Promise(resolve => {
|
|
211
|
+
resolveFetch = resolve;
|
|
212
|
+
});
|
|
213
|
+
// Mock fetch to return our controlled Promise
|
|
214
|
+
mockedFetch.mockImplementationOnce(() => fetchPromise);
|
|
215
|
+
const controller = new AbortController();
|
|
216
|
+
const { signal } = controller;
|
|
217
|
+
const transport = new HttpTransport({
|
|
218
|
+
authorization: 'token',
|
|
219
|
+
apiUrl: 'http://localhost:4000/cubejs-api/v1'
|
|
220
|
+
});
|
|
221
|
+
const request = transport.request('load', {
|
|
222
|
+
query: { measures: ['Orders.count'] },
|
|
223
|
+
signal
|
|
224
|
+
});
|
|
225
|
+
// Start the request but don't wait for it to complete
|
|
226
|
+
const requestPromise = request.subscribe((result) => result);
|
|
227
|
+
// Wait for fetch to be called
|
|
228
|
+
await Promise.resolve();
|
|
229
|
+
// Ensure fetch was called with the signal
|
|
230
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
231
|
+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(signal);
|
|
232
|
+
// Abort the request
|
|
233
|
+
controller.abort();
|
|
234
|
+
// Resolve the fetch Promise, simulating request completion
|
|
235
|
+
resolveFetch({
|
|
236
|
+
json: () => Promise.resolve({ data: 'aborted data' }),
|
|
237
|
+
ok: true,
|
|
238
|
+
status: 200
|
|
239
|
+
});
|
|
240
|
+
// Wait for the request Promise to complete
|
|
241
|
+
await requestPromise;
|
|
242
|
+
}, 10000); // Set 10-second timeout
|
|
243
|
+
});
|
|
244
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResultSet.test.d.ts","sourceRoot":"","sources":["../../test/ResultSet.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,MAAM,CAAC"}
|