@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
package/src/HttpTransport.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import fetch from 'cross-fetch';
|
|
2
|
-
import 'url-search-params-polyfill';
|
|
3
|
-
|
|
4
|
-
class HttpTransport {
|
|
5
|
-
constructor({ authorization, apiUrl, method, headers = {}, credentials, fetchTimeout }) {
|
|
6
|
-
this.authorization = authorization;
|
|
7
|
-
this.apiUrl = apiUrl;
|
|
8
|
-
this.method = method;
|
|
9
|
-
this.headers = headers;
|
|
10
|
-
this.credentials = credentials;
|
|
11
|
-
this.fetchTimeout = fetchTimeout;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
request(method, { baseRequestId, ...params }) {
|
|
15
|
-
let spanCounter = 1;
|
|
16
|
-
const searchParams = new URLSearchParams(
|
|
17
|
-
params && Object.keys(params)
|
|
18
|
-
.map(k => ({ [k]: typeof params[k] === 'object' ? JSON.stringify(params[k]) : params[k] }))
|
|
19
|
-
.reduce((a, b) => ({ ...a, ...b }), {})
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
let url = `${this.apiUrl}/${method}${searchParams.toString().length ? `?${searchParams}` : ''}`;
|
|
23
|
-
|
|
24
|
-
const requestMethod = this.method || (url.length < 2000 ? 'GET' : 'POST');
|
|
25
|
-
if (requestMethod === 'POST') {
|
|
26
|
-
url = `${this.apiUrl}/${method}`;
|
|
27
|
-
this.headers['Content-Type'] = 'application/json';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Currently, all methods make GET requests. If a method makes a request with a body payload,
|
|
31
|
-
// remember to add {'Content-Type': 'application/json'} to the header.
|
|
32
|
-
const runRequest = () => fetch(url, {
|
|
33
|
-
method: requestMethod,
|
|
34
|
-
headers: {
|
|
35
|
-
Authorization: this.authorization,
|
|
36
|
-
'x-request-id': baseRequestId && `${baseRequestId}-span-${spanCounter++}`,
|
|
37
|
-
...this.headers
|
|
38
|
-
},
|
|
39
|
-
credentials: this.credentials,
|
|
40
|
-
body: requestMethod === 'POST' ? JSON.stringify(params) : null,
|
|
41
|
-
signal: this.fetchTimeout ? AbortSignal.timeout(this.fetchTimeout) : undefined,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
/* eslint no-unsafe-finally: off */
|
|
46
|
-
async subscribe(callback) {
|
|
47
|
-
let result = {
|
|
48
|
-
error: 'network Error' // add default error message
|
|
49
|
-
};
|
|
50
|
-
try {
|
|
51
|
-
result = await runRequest();
|
|
52
|
-
} finally {
|
|
53
|
-
return callback(result, () => this.subscribe(callback));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default HttpTransport;
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/first */
|
|
2
|
-
/* eslint-disable import/newline-after-import */
|
|
3
|
-
/* globals describe,test,expect,jest,afterEach,beforeAll */
|
|
4
|
-
import '@babel/runtime/regenerator';
|
|
5
|
-
jest.mock('cross-fetch');
|
|
6
|
-
import fetch from 'cross-fetch';
|
|
7
|
-
import HttpTransport from './HttpTransport';
|
|
8
|
-
|
|
9
|
-
describe('HttpTransport', () => {
|
|
10
|
-
const apiUrl = 'http://localhost:3000/cubejs-api/v1';
|
|
11
|
-
const query = {
|
|
12
|
-
measures: ['Orders.count'],
|
|
13
|
-
dimensions: ['Users.country']
|
|
14
|
-
};
|
|
15
|
-
const queryUrlEncoded = '%7B%22measures%22%3A%5B%22Orders.count%22%5D%2C%22dimensions%22%3A%5B%22Users.country%22%5D%7D';
|
|
16
|
-
const queryJson = '{"query":{"measures":["Orders.count"],"dimensions":["Users.country"]}}';
|
|
17
|
-
|
|
18
|
-
const ids = [];
|
|
19
|
-
for (let i = 0; i < 40; i++) ids.push('a40b2052-4137-11eb-b378-0242ac130002');
|
|
20
|
-
const LargeQuery = {
|
|
21
|
-
measures: ['Orders.count'],
|
|
22
|
-
dimensions: ['Users.country'],
|
|
23
|
-
filters: [
|
|
24
|
-
{
|
|
25
|
-
member: 'Users.id',
|
|
26
|
-
operator: 'equals',
|
|
27
|
-
values: ids
|
|
28
|
-
}
|
|
29
|
-
]
|
|
30
|
-
};
|
|
31
|
-
const largeQueryJson = `{"query":{"measures":["Orders.count"],"dimensions":["Users.country"],"filters":[{"member":"Users.id","operator":"equals","values":${JSON.stringify(ids)}}]}}`;
|
|
32
|
-
|
|
33
|
-
beforeAll(() => {
|
|
34
|
-
fetch.mockReturnValue(Promise.resolve({ ok: true }));
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
afterEach(() => {
|
|
38
|
-
fetch.mockClear();
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('it serializes the query object and sends it in the query string', async () => {
|
|
42
|
-
const transport = new HttpTransport({
|
|
43
|
-
authorization: 'token',
|
|
44
|
-
apiUrl,
|
|
45
|
-
});
|
|
46
|
-
const req = transport.request('load', { query });
|
|
47
|
-
await req.subscribe(() => { });
|
|
48
|
-
expect(fetch).toHaveBeenCalledTimes(1);
|
|
49
|
-
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load?query=${queryUrlEncoded}`, {
|
|
50
|
-
method: 'GET',
|
|
51
|
-
headers: {
|
|
52
|
-
Authorization: 'token',
|
|
53
|
-
},
|
|
54
|
-
body: null
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test('it passes extra headers and serializes extra params', async () => {
|
|
59
|
-
const extraParams = { foo: 'bar' };
|
|
60
|
-
const serializedExtraParams = encodeURIComponent(JSON.stringify(extraParams));
|
|
61
|
-
const transport = new HttpTransport({
|
|
62
|
-
authorization: 'token',
|
|
63
|
-
apiUrl,
|
|
64
|
-
headers: {
|
|
65
|
-
'X-Extra-Header': '42'
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
const req = transport.request('meta', { extraParams });
|
|
69
|
-
await req.subscribe(() => { });
|
|
70
|
-
expect(fetch).toHaveBeenCalledTimes(1);
|
|
71
|
-
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/meta?extraParams=${serializedExtraParams}`, {
|
|
72
|
-
method: 'GET',
|
|
73
|
-
headers: {
|
|
74
|
-
Authorization: 'token',
|
|
75
|
-
'X-Extra-Header': '42'
|
|
76
|
-
},
|
|
77
|
-
body: null
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('it serializes the query object and sends it in the body', async () => {
|
|
82
|
-
const transport = new HttpTransport({
|
|
83
|
-
authorization: 'token',
|
|
84
|
-
apiUrl,
|
|
85
|
-
method: 'POST'
|
|
86
|
-
});
|
|
87
|
-
const req = transport.request('load', { query });
|
|
88
|
-
await req.subscribe(() => { });
|
|
89
|
-
expect(fetch).toHaveBeenCalledTimes(1);
|
|
90
|
-
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load`, {
|
|
91
|
-
method: 'POST',
|
|
92
|
-
headers: {
|
|
93
|
-
Authorization: 'token',
|
|
94
|
-
'Content-Type': 'application/json'
|
|
95
|
-
},
|
|
96
|
-
body: queryJson
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test('it use POST over GET if url length is more than 2000 characters', async () => {
|
|
101
|
-
const transport = new HttpTransport({
|
|
102
|
-
authorization: 'token',
|
|
103
|
-
apiUrl
|
|
104
|
-
});
|
|
105
|
-
const req = transport.request('load', { query: LargeQuery });
|
|
106
|
-
await req.subscribe(() => { });
|
|
107
|
-
expect(fetch).toHaveBeenCalledTimes(1);
|
|
108
|
-
expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load`, {
|
|
109
|
-
method: 'POST',
|
|
110
|
-
headers: {
|
|
111
|
-
Authorization: 'token',
|
|
112
|
-
'Content-Type': 'application/json'
|
|
113
|
-
},
|
|
114
|
-
body: largeQueryJson
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
});
|
package/src/Meta.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @cubejs-client/core
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { unnest, fromPairs } from 'ramda';
|
|
6
|
-
|
|
7
|
-
const memberMap = (memberArray) => fromPairs(memberArray.map((m) => [m.name, m]));
|
|
8
|
-
|
|
9
|
-
const operators = {
|
|
10
|
-
string: [
|
|
11
|
-
{ name: 'contains', title: 'contains' },
|
|
12
|
-
{ name: 'notContains', title: 'does not contain' },
|
|
13
|
-
{ name: 'equals', title: 'equals' },
|
|
14
|
-
{ name: 'notEquals', title: 'does not equal' },
|
|
15
|
-
{ name: 'set', title: 'is set' },
|
|
16
|
-
{ name: 'notSet', title: 'is not set' },
|
|
17
|
-
{ name: 'startsWith', title: 'starts with' },
|
|
18
|
-
{ name: 'notStartsWith', title: 'does not start with' },
|
|
19
|
-
{ name: 'endsWith', title: 'ends with' },
|
|
20
|
-
{ name: 'notEndsWith', title: 'does not end with' },
|
|
21
|
-
],
|
|
22
|
-
number: [
|
|
23
|
-
{ name: 'equals', title: 'equals' },
|
|
24
|
-
{ name: 'notEquals', title: 'does not equal' },
|
|
25
|
-
{ name: 'set', title: 'is set' },
|
|
26
|
-
{ name: 'notSet', title: 'is not set' },
|
|
27
|
-
{ name: 'gt', title: '>' },
|
|
28
|
-
{ name: 'gte', title: '>=' },
|
|
29
|
-
{ name: 'lt', title: '<' },
|
|
30
|
-
{ name: 'lte', title: '<=' },
|
|
31
|
-
],
|
|
32
|
-
time: [
|
|
33
|
-
{ name: 'equals', title: 'equals' },
|
|
34
|
-
{ name: 'notEquals', title: 'does not equal' },
|
|
35
|
-
{ name: 'inDateRange', title: 'in date range' },
|
|
36
|
-
{ name: 'notInDateRange', title: 'not in date range' },
|
|
37
|
-
{ name: 'afterDate', title: 'after date' },
|
|
38
|
-
{ name: 'afterOrOnDate', title: 'after or on date' },
|
|
39
|
-
{ name: 'beforeDate', title: 'before date' },
|
|
40
|
-
{ name: 'beforeOrOnDate', title: 'before or on date' },
|
|
41
|
-
],
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Contains information about available cubes and it's members.
|
|
46
|
-
*/
|
|
47
|
-
class Meta {
|
|
48
|
-
constructor(metaResponse) {
|
|
49
|
-
this.meta = metaResponse;
|
|
50
|
-
const { cubes } = this.meta;
|
|
51
|
-
this.cubes = cubes;
|
|
52
|
-
this.cubesMap = fromPairs(
|
|
53
|
-
cubes.map((c) => [
|
|
54
|
-
c.name,
|
|
55
|
-
{
|
|
56
|
-
measures: memberMap(c.measures),
|
|
57
|
-
dimensions: memberMap(c.dimensions),
|
|
58
|
-
segments: memberMap(c.segments),
|
|
59
|
-
},
|
|
60
|
-
])
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
membersForQuery(query, memberType) {
|
|
65
|
-
return unnest(this.cubes.map((c) => c[memberType])).sort((a, b) => (a.title > b.title ? 1 : -1));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
membersGroupedByCube() {
|
|
69
|
-
const memberKeys = ['measures', 'dimensions', 'segments', 'timeDimensions'];
|
|
70
|
-
|
|
71
|
-
return this.cubes.reduce(
|
|
72
|
-
(memo, cube) => {
|
|
73
|
-
memberKeys.forEach((key) => {
|
|
74
|
-
let members = cube[key];
|
|
75
|
-
|
|
76
|
-
if (key === 'timeDimensions') {
|
|
77
|
-
members = cube.dimensions.filter((m) => m.type === 'time');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
memo[key] = [
|
|
81
|
-
...memo[key],
|
|
82
|
-
{
|
|
83
|
-
cubeName: cube.name,
|
|
84
|
-
cubeTitle: cube.title,
|
|
85
|
-
type: cube.type,
|
|
86
|
-
public: cube.public,
|
|
87
|
-
members
|
|
88
|
-
},
|
|
89
|
-
];
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
return memo;
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
measures: [],
|
|
96
|
-
dimensions: [],
|
|
97
|
-
segments: [],
|
|
98
|
-
timeDimensions: [],
|
|
99
|
-
}
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
resolveMember(memberName, memberType) {
|
|
104
|
-
const [cube] = memberName.split('.');
|
|
105
|
-
|
|
106
|
-
if (!this.cubesMap[cube]) {
|
|
107
|
-
return { title: memberName, error: `Cube not found ${cube} for path '${memberName}'` };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const memberTypes = Array.isArray(memberType) ? memberType : [memberType];
|
|
111
|
-
const member = memberTypes
|
|
112
|
-
.map((type) => this.cubesMap[cube][type] && this.cubesMap[cube][type][memberName])
|
|
113
|
-
.find((m) => m);
|
|
114
|
-
|
|
115
|
-
if (!member) {
|
|
116
|
-
return {
|
|
117
|
-
title: memberName,
|
|
118
|
-
error: `Path not found '${memberName}'`,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return member;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
defaultTimeDimensionNameFor(memberName) {
|
|
126
|
-
const [cube] = memberName.split('.');
|
|
127
|
-
if (!this.cubesMap[cube]) {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
return Object.keys(this.cubesMap[cube].dimensions || {}).find(
|
|
131
|
-
(d) => this.cubesMap[cube].dimensions[d].type === 'time'
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
filterOperatorsForMember(memberName, memberType) {
|
|
136
|
-
const member = this.resolveMember(memberName, memberType);
|
|
137
|
-
|
|
138
|
-
return operators[member.type] || operators.string;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export default Meta;
|
package/src/ProgressResult.js
DELETED