@sisense/sdk-query-client 0.14.0 → 0.16.0
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/interfaces.d.ts +2 -1
- package/dist/query-api-dispatcher/query-api-dispatcher.d.ts +1 -0
- package/dist/query-api-dispatcher/query-api-dispatcher.js +19 -1
- package/dist/query-client.d.ts +5 -2
- package/dist/query-client.js +19 -2
- package/dist/query-task-manager/query-task-manager.d.ts +3 -1
- package/dist/query-task-manager/query-task-manager.js +16 -2
- package/dist/query-task-manager/query-task-passport.d.ts +1 -1
- package/dist/types.d.ts +4 -0
- package/package.json +4 -4
package/dist/interfaces.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { DataSourceField, ExecutingQueryResult, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
1
|
+
import { DataSourceField, ExecutingCsvQueryResult, ExecutingQueryResult, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
2
2
|
import { DataSource } from '@sisense/sdk-data';
|
|
3
3
|
export interface QueryClient {
|
|
4
4
|
executeQuery(params: QueryDescription, config?: QueryExecutionConfig): ExecutingQueryResult;
|
|
5
|
+
executeCsvQuery(params: QueryDescription, config?: QueryExecutionConfig): ExecutingCsvQueryResult;
|
|
5
6
|
getDataSourceFields(dataSource: DataSource): Promise<DataSourceField[]>;
|
|
6
7
|
}
|
|
@@ -10,6 +10,7 @@ export declare class QueryApiDispatcher {
|
|
|
10
10
|
constructor(httpClient: HttpClient);
|
|
11
11
|
getDataSourceFields(dataSource: DataSource, count?: number, offset?: number): Promise<DataSourceField[]>;
|
|
12
12
|
sendJaqlRequest(dataSource: DataSource, jaqlPayload: JaqlQueryPayload): RequestSendingResult<JaqlResponse>;
|
|
13
|
+
sendDownloadCsvRequest(dataSource: DataSource, jaqlPayload: JaqlQueryPayload): RequestSendingResult<ReadableStream>;
|
|
13
14
|
/**
|
|
14
15
|
* Sends a request to cancel a JAQL query.
|
|
15
16
|
*
|
|
@@ -33,6 +33,16 @@ export class QueryApiDispatcher {
|
|
|
33
33
|
abortHttpRequest: (reason) => abortController.abort(reason),
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
+
sendDownloadCsvRequest(dataSource, jaqlPayload) {
|
|
37
|
+
const url = getDownloadCsvUrl(dataSource);
|
|
38
|
+
const abortController = new AbortController();
|
|
39
|
+
const params = new URLSearchParams();
|
|
40
|
+
params.append('data', encodeURIComponent(JSON.stringify(jaqlPayload)));
|
|
41
|
+
return {
|
|
42
|
+
responsePromise: this.httpClient.post(url, params, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }, abortController.signal, { nonJSONBody: true, returnBlob: true }),
|
|
43
|
+
abortHttpRequest: (reason) => abortController.abort(reason),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
36
46
|
/**
|
|
37
47
|
* Sends a request to cancel a JAQL query.
|
|
38
48
|
*
|
|
@@ -77,7 +87,7 @@ export class QueryApiDispatcher {
|
|
|
77
87
|
*/
|
|
78
88
|
function getRegularCancelQueryUrl(dataSource) {
|
|
79
89
|
const datasourcePath = encodeURIComponent(dataSource);
|
|
80
|
-
return `${API_DATASOURCES_BASE_PATH}/${datasourcePath}/cancel_queries`;
|
|
90
|
+
return `${API_DATASOURCES_BASE_PATH}/localhost/${datasourcePath}/cancel_queries`;
|
|
81
91
|
}
|
|
82
92
|
/**
|
|
83
93
|
* Returns the URL for canceling queries for a live datasource.
|
|
@@ -98,3 +108,11 @@ function getJaqlUrl(dataSource) {
|
|
|
98
108
|
const dataSourcePath = encodeURIComponent(dataSource);
|
|
99
109
|
return `${API_DATASOURCES_BASE_PATH}/${dataSourcePath}/jaql`;
|
|
100
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Returns the URL for sending a Download CSV request.
|
|
113
|
+
*
|
|
114
|
+
* @param dataSource - The data source of the query.
|
|
115
|
+
*/
|
|
116
|
+
function getDownloadCsvUrl(dataSource) {
|
|
117
|
+
return `${getJaqlUrl(dataSource)}/csv`;
|
|
118
|
+
}
|
package/dist/query-client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataSourceField, ExecutingQueryResult, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
1
|
+
import { DataSourceField, ExecutingCsvQueryResult, ExecutingQueryResult, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
2
2
|
import { QueryClient } from './interfaces.js';
|
|
3
3
|
import { DataSource } from '@sisense/sdk-data';
|
|
4
4
|
import { HttpClient } from '@sisense/sdk-rest-client';
|
|
@@ -17,6 +17,7 @@ export declare class DimensionalQueryClient implements QueryClient {
|
|
|
17
17
|
* @throws Error if query description is invalid
|
|
18
18
|
*/
|
|
19
19
|
executeQuery(queryDescription: QueryDescription, config?: QueryExecutionConfig): ExecutingQueryResult;
|
|
20
|
+
executeCsvQuery(queryDescription: QueryDescription, config?: QueryExecutionConfig): ExecutingCsvQueryResult;
|
|
20
21
|
getDataSourceFields(dataSource: DataSource, count?: number, offset?: number): Promise<DataSourceField[]>;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
@@ -25,4 +26,6 @@ export declare class DimensionalQueryClient implements QueryClient {
|
|
|
25
26
|
* @param queryDescription - query description to validate
|
|
26
27
|
* @throws Error if query description is invalid
|
|
27
28
|
*/
|
|
28
|
-
export declare function validateQueryDescription(queryDescription: QueryDescription
|
|
29
|
+
export declare function validateQueryDescription(queryDescription: QueryDescription, config?: {
|
|
30
|
+
ignoreQueryLimit?: boolean;
|
|
31
|
+
}): void;
|
package/dist/query-client.js
CHANGED
|
@@ -46,6 +46,23 @@ export class DimensionalQueryClient {
|
|
|
46
46
|
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason || 'Unspecified reason'),
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
+
executeCsvQuery(queryDescription, config) {
|
|
50
|
+
validateQueryDescription(queryDescription, { ignoreQueryLimit: true });
|
|
51
|
+
const taskPassport = new QueryTaskPassport('SEND_DOWNLOAD_CSV_QUERY', queryDescription, Object.assign(Object.assign({}, (config ? config : {})), { shouldSkipHighlightsWithoutAttributes: this.shouldSkipHighlightsWithoutAttributes || false }));
|
|
52
|
+
return {
|
|
53
|
+
resultPromise: new Promise((resolve, reject) => {
|
|
54
|
+
void this.taskManager.executeDownloadCsvSending(taskPassport).then((executionResult) => {
|
|
55
|
+
if (executionResult.status === ExecutionResultStatus.SUCCESS) {
|
|
56
|
+
resolve(executionResult.result);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
reject(executionResult.error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}),
|
|
63
|
+
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason || 'Unspecified reason'),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
49
66
|
getDataSourceFields(dataSource, count = 9999, offset = 0) {
|
|
50
67
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
68
|
return this.queryApi.getDataSourceFields(dataSource, count, offset);
|
|
@@ -58,12 +75,12 @@ export class DimensionalQueryClient {
|
|
|
58
75
|
* @param queryDescription - query description to validate
|
|
59
76
|
* @throws Error if query description is invalid
|
|
60
77
|
*/
|
|
61
|
-
export function validateQueryDescription(queryDescription) {
|
|
78
|
+
export function validateQueryDescription(queryDescription, config) {
|
|
62
79
|
const { attributes, measures, filters, highlights, count, offset } = queryDescription;
|
|
63
80
|
if (count && count < 0) {
|
|
64
81
|
throw new TranslatableError('errors.invalidCountNegative', { count: count.toString() });
|
|
65
82
|
}
|
|
66
|
-
if (count && count > QUERY_DEFAULT_LIMIT) {
|
|
83
|
+
if (!(config === null || config === void 0 ? void 0 : config.ignoreQueryLimit) && count && count > QUERY_DEFAULT_LIMIT) {
|
|
67
84
|
throw new TranslatableError('errors.invalidCountLimit', {
|
|
68
85
|
count: count.toString(),
|
|
69
86
|
limit: QUERY_DEFAULT_LIMIT.toString(),
|
|
@@ -10,7 +10,9 @@ export declare class QueryTaskManager extends AbstractTaskManager {
|
|
|
10
10
|
constructor(queryApi: QueryApiDispatcher);
|
|
11
11
|
private prepareJaqlPayload;
|
|
12
12
|
private sendJaqlQuery;
|
|
13
|
-
private
|
|
13
|
+
private sendCsvQuery;
|
|
14
|
+
private cancelDataRetrievalQuery;
|
|
14
15
|
executeQuerySending: (passport: QueryTaskPassport) => Promise<import("@sisense/task-manager").TaskExecutionResult<QueryResultData, EmptyObject>>;
|
|
16
|
+
executeDownloadCsvSending: (passport: QueryTaskPassport) => Promise<import("@sisense/task-manager").TaskExecutionResult<Blob, EmptyObject>>;
|
|
15
17
|
}
|
|
16
18
|
export declare function validateJaqlResponse(jaqlResponse: JaqlResponse): boolean;
|
|
@@ -17,7 +17,11 @@ export class QueryTaskManager extends AbstractTaskManager {
|
|
|
17
17
|
this.sentRequestsAbortersMap = new Map();
|
|
18
18
|
this.executeQuerySending = super.createFlow([
|
|
19
19
|
new Step('PREPARE_JAQL_PAYLOAD', this.prepareJaqlPayload.bind(this), () => __awaiter(this, void 0, void 0, function* () { })),
|
|
20
|
-
new Step('SEND_JAQL_QUERY', this.sendJaqlQuery.bind(this), this.
|
|
20
|
+
new Step('SEND_JAQL_QUERY', this.sendJaqlQuery.bind(this), this.cancelDataRetrievalQuery.bind(this)),
|
|
21
|
+
]);
|
|
22
|
+
this.executeDownloadCsvSending = super.createFlow([
|
|
23
|
+
new Step('PREPARE_JAQL_PAYLOAD', this.prepareJaqlPayload.bind(this), () => __awaiter(this, void 0, void 0, function* () { })),
|
|
24
|
+
new Step('SEND_DOWNLOAD_CSV_QUERY', this.sendCsvQuery.bind(this), this.cancelDataRetrievalQuery.bind(this)),
|
|
21
25
|
]);
|
|
22
26
|
this.queryApi = queryApi;
|
|
23
27
|
}
|
|
@@ -49,7 +53,17 @@ export class QueryTaskManager extends AbstractTaskManager {
|
|
|
49
53
|
return getDataFromQueryResult(jaqlResponse, [...metadata, ...extraColumns]);
|
|
50
54
|
});
|
|
51
55
|
}
|
|
52
|
-
|
|
56
|
+
sendCsvQuery(task, jaqlPayload) {
|
|
57
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
const { taskId } = task.passport;
|
|
59
|
+
const { responsePromise, abortHttpRequest } = this.queryApi.sendDownloadCsvRequest(task.passport.queryDescription.dataSource, jaqlPayload);
|
|
60
|
+
this.sentRequestsAbortersMap.set(taskId, abortHttpRequest);
|
|
61
|
+
return responsePromise.finally(() => {
|
|
62
|
+
this.sentRequestsAbortersMap.delete(taskId);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
cancelDataRetrievalQuery(task) {
|
|
53
67
|
const taskId = task.passport.taskId;
|
|
54
68
|
const abortInitialRequest = this.sentRequestsAbortersMap.get(taskId);
|
|
55
69
|
if (abortInitialRequest) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TaskPassport } from '@sisense/task-manager';
|
|
2
2
|
import { QueryDescription, QueryExecutionConfigInternal } from '../types.js';
|
|
3
|
-
type TaskType = 'SEND_JAQL_QUERY';
|
|
3
|
+
type TaskType = 'SEND_JAQL_QUERY' | 'SEND_DOWNLOAD_CSV_QUERY';
|
|
4
4
|
export declare class QueryTaskPassport extends TaskPassport {
|
|
5
5
|
queryDescription: QueryDescription;
|
|
6
6
|
executionConfig: QueryExecutionConfigInternal;
|
package/dist/types.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export type ExecutingQueryResult = {
|
|
|
32
32
|
resultPromise: Promise<QueryResultData>;
|
|
33
33
|
cancel: (reason?: string) => Promise<void>;
|
|
34
34
|
};
|
|
35
|
+
export type ExecutingCsvQueryResult = {
|
|
36
|
+
resultPromise: Promise<Blob>;
|
|
37
|
+
cancel: (reason?: string) => Promise<void>;
|
|
38
|
+
};
|
|
35
39
|
export type MetadataItem = {
|
|
36
40
|
measure?: MetadataItemJaql;
|
|
37
41
|
jaql: MetadataItemJaql;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sisense/sdk-query-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"author": "Sisense",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@sisense/sdk-common": "^0.
|
|
13
|
-
"@sisense/sdk-data": "^0.
|
|
14
|
-
"@sisense/sdk-rest-client": "^0.
|
|
12
|
+
"@sisense/sdk-common": "^0.16.0",
|
|
13
|
+
"@sisense/sdk-data": "^0.16.0",
|
|
14
|
+
"@sisense/sdk-rest-client": "^0.16.0",
|
|
15
15
|
"@sisense/task-manager": "^0.1.0",
|
|
16
16
|
"numeral": "^2.0.6",
|
|
17
17
|
"uuid": "^9.0.0"
|