@carto/api-client 0.0.1-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/README.md +24 -0
- package/build/api-client.cjs +1202 -0
- package/build/api-client.cjs.map +1 -0
- package/build/api-client.modern.js +1089 -0
- package/build/api-client.modern.js.map +1 -0
- package/build/client.d.ts +4 -0
- package/build/constants-internal.d.ts +21 -0
- package/build/constants.d.ts +33 -0
- package/build/index.d.ts +5 -0
- package/build/models/common.d.ts +25 -0
- package/build/models/index.d.ts +3 -0
- package/build/models/model.d.ts +17 -0
- package/build/sources/index.d.ts +5 -0
- package/build/sources/types.d.ts +80 -0
- package/build/sources/widget-base-source.d.ts +32 -0
- package/build/sources/widget-query-source.d.ts +8 -0
- package/build/sources/widget-table-source.d.ts +8 -0
- package/build/sources/wrappers.d.ts +47 -0
- package/build/types-internal.d.ts +7 -0
- package/build/types.d.ts +73 -0
- package/build/utils.d.ts +27 -0
- package/package.json +89 -0
- package/src/client.ts +17 -0
- package/src/constants-internal.ts +24 -0
- package/src/constants.ts +37 -0
- package/src/index.ts +5 -0
- package/src/models/common.ts +93 -0
- package/src/models/index.ts +3 -0
- package/src/models/model.ts +112 -0
- package/src/sources/index.ts +5 -0
- package/src/sources/types.ts +90 -0
- package/src/sources/widget-base-source.ts +255 -0
- package/src/sources/widget-query-source.ts +25 -0
- package/src/sources/widget-table-source.ts +25 -0
- package/src/sources/wrappers.ts +114 -0
- package/src/types-internal.ts +9 -0
- package/src/types.ts +76 -0
- package/src/utils.ts +84 -0
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@carto/api-client",
|
|
3
|
+
"version": "0.0.1-0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"tag": "alpha"
|
|
7
|
+
},
|
|
8
|
+
"packageManager": "yarn@4.2.2",
|
|
9
|
+
"author": "Don McCurdy <donmccurdy@carto.com>",
|
|
10
|
+
"license": "UNLICENSED",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"source": "src/index.ts",
|
|
14
|
+
"types": "./build/index.d.ts",
|
|
15
|
+
"main": "./build/api-client.cjs",
|
|
16
|
+
"module": "./build/api-client.modern.js",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./build/index.d.ts",
|
|
20
|
+
"require": "./build/api-client.cjs",
|
|
21
|
+
"default": "./build/api-client.modern.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"browserslist": [
|
|
25
|
+
"defaults",
|
|
26
|
+
"not IE 11",
|
|
27
|
+
"node >= 18"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "microbundle --format cjs,modern --no-compress --define VERSION=$npm_package_version",
|
|
31
|
+
"build:watch": "microbundle watch --format cjs,modern --no-compress --define VERSION=$npm_package_version",
|
|
32
|
+
"dev": "concurrently \"yarn build:watch\" \"vite --config examples/vite.config.ts --open\"",
|
|
33
|
+
"test": "vitest run --typecheck",
|
|
34
|
+
"test:watch": "vitest watch --typecheck",
|
|
35
|
+
"coverage": "vitest run --coverage",
|
|
36
|
+
"lint": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --ignore-path ./.eslintignore --check",
|
|
37
|
+
"format": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --ignore-path ./.eslintignore --write",
|
|
38
|
+
"clean": "rimraf build/*",
|
|
39
|
+
"version": "git add -u",
|
|
40
|
+
"prepack": "yarn clean && yarn build",
|
|
41
|
+
"prepublish": "yarn lint && yarn test",
|
|
42
|
+
"postpublish": "git push && git push --tags"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"build",
|
|
46
|
+
"src",
|
|
47
|
+
"README.md"
|
|
48
|
+
],
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@deck.gl/aggregation-layers": "^9.0.14",
|
|
51
|
+
"@deck.gl/carto": "^9.0.14",
|
|
52
|
+
"@deck.gl/core": "^9.0.14",
|
|
53
|
+
"@deck.gl/extensions": "^9.0.14",
|
|
54
|
+
"@deck.gl/geo-layers": "^9.0.14",
|
|
55
|
+
"@deck.gl/layers": "^9.0.12",
|
|
56
|
+
"@deck.gl/mesh-layers": "^9.0.12",
|
|
57
|
+
"@deck.gl/react": "^9.0.17",
|
|
58
|
+
"@lit/react": "^1.0.5",
|
|
59
|
+
"@lit/task": "^1.0.1",
|
|
60
|
+
"@loaders.gl/core": "^4.2.1",
|
|
61
|
+
"@luma.gl/core": "^9.0.12",
|
|
62
|
+
"@luma.gl/engine": "^9.0.12",
|
|
63
|
+
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
|
64
|
+
"@types/json-schema": "^7.0.15",
|
|
65
|
+
"@types/react": "^18.3.3",
|
|
66
|
+
"@types/react-dom": "^18.3.0",
|
|
67
|
+
"@types/semver": "^7.5.8",
|
|
68
|
+
"@vitejs/plugin-vue": "^5.0.5",
|
|
69
|
+
"@vitest/coverage-istanbul": "^1.6.0",
|
|
70
|
+
"@webcomponents/webcomponentsjs": "^2.8.0",
|
|
71
|
+
"concurrently": "^8.2.2",
|
|
72
|
+
"echarts": "^5.5.0",
|
|
73
|
+
"lit": "^3.1.4",
|
|
74
|
+
"lit-analyzer": "^1.2.1",
|
|
75
|
+
"maplibre-gl": "^4.1.3",
|
|
76
|
+
"microbundle": "^0.15.1",
|
|
77
|
+
"prettier": "^2.6.2",
|
|
78
|
+
"react": "^18.3.1",
|
|
79
|
+
"react-dom": "^18.3.1",
|
|
80
|
+
"react-map-gl": "^7.1.7",
|
|
81
|
+
"rimraf": "^3.0.2",
|
|
82
|
+
"svelte": "^4.2.17",
|
|
83
|
+
"typescript": "~5.3.3",
|
|
84
|
+
"vite": "^5.2.10",
|
|
85
|
+
"vitest": "1.6.0",
|
|
86
|
+
"vue": "^3.4.27"
|
|
87
|
+
},
|
|
88
|
+
"stableVersion": "0.0.0"
|
|
89
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {CLIENT_ID} from './constants.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default client
|
|
5
|
+
* @internalRemarks Source: @carto/react-core
|
|
6
|
+
*/
|
|
7
|
+
let client = CLIENT_ID;
|
|
8
|
+
|
|
9
|
+
/** @internalRemarks Source: @carto/react-core */
|
|
10
|
+
export function getClient() {
|
|
11
|
+
return client;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** @internalRemarks Source: @carto/react-core */
|
|
15
|
+
export function setClient(c: string) {
|
|
16
|
+
client = c;
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threshold to use GET requests, vs POST
|
|
3
|
+
* @internalRemarks Source: @carto/constants
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export const REQUEST_GET_MAX_URL_LENGTH = 2048;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @internalRemarks Source: @carto/constants
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_API_BASE_URL = 'https://gcp-us-east1.api.carto.com';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @internalRemarks Source: @carto/constants
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export const DEFAULT_CLIENT = 'deck-gl-carto';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @internalRemarks Source: @carto/react-api
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_GEO_COLUMN = 'geom';
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const CLIENT_ID = 'carto-api-client';
|
|
2
|
+
|
|
3
|
+
/** @internalRemarks Source: @carto/constants */
|
|
4
|
+
export enum MapType {
|
|
5
|
+
TABLE = 'table',
|
|
6
|
+
QUERY = 'query',
|
|
7
|
+
TILESET = 'tileset',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** @internalRemarks Source: @carto/constants */
|
|
11
|
+
export enum ApiVersion {
|
|
12
|
+
V1 = 'v1',
|
|
13
|
+
V2 = 'v2',
|
|
14
|
+
V3 = 'v3',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** @internalRemarks Source: @carto/react-core */
|
|
18
|
+
export enum GroupDateType {
|
|
19
|
+
YEARS = 'year',
|
|
20
|
+
MONTHS = 'month',
|
|
21
|
+
WEEKS = 'week',
|
|
22
|
+
DAYS = 'day',
|
|
23
|
+
HOURS = 'hour',
|
|
24
|
+
MINUTES = 'minute',
|
|
25
|
+
SECONDS = 'second',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @internalRemarks Source: @carto/react-api, @deck.gl/carto */
|
|
29
|
+
export enum FilterType {
|
|
30
|
+
IN = 'in',
|
|
31
|
+
/** [a, b] both are included. */
|
|
32
|
+
BETWEEN = 'between',
|
|
33
|
+
/** [a, b) a is included, b is not. */
|
|
34
|
+
CLOSED_OPEN = 'closed_open',
|
|
35
|
+
TIME = 'time',
|
|
36
|
+
STRING_SEARCH = 'stringSearch',
|
|
37
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import {$TODO} from '../types-internal.js';
|
|
2
|
+
import {Credentials} from '../types.js';
|
|
3
|
+
import {InvalidColumnError} from '../utils.js';
|
|
4
|
+
|
|
5
|
+
/** @internalRemarks Source: @carto/react-api */
|
|
6
|
+
export interface ModelRequestOptions {
|
|
7
|
+
method: 'GET' | 'POST';
|
|
8
|
+
abortController?: AbortController;
|
|
9
|
+
otherOptions?: Record<string, unknown>;
|
|
10
|
+
body?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Return more descriptive error from API
|
|
15
|
+
* @internalRemarks Source: @carto/react-api
|
|
16
|
+
*/
|
|
17
|
+
export function dealWithApiError({
|
|
18
|
+
response,
|
|
19
|
+
data,
|
|
20
|
+
}: {
|
|
21
|
+
response: Response;
|
|
22
|
+
data: $TODO;
|
|
23
|
+
}) {
|
|
24
|
+
if (data.error === 'Column not found') {
|
|
25
|
+
throw new InvalidColumnError(`${data.error} ${data.column_name}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (data.error?.includes('Missing columns')) {
|
|
29
|
+
throw new InvalidColumnError(data.error);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
switch (response.status) {
|
|
33
|
+
case 401:
|
|
34
|
+
throw new Error('Unauthorized access. Invalid credentials');
|
|
35
|
+
case 403:
|
|
36
|
+
throw new Error('Forbidden access to the requested data');
|
|
37
|
+
default:
|
|
38
|
+
const msg =
|
|
39
|
+
data && data.error && typeof data.error === 'string'
|
|
40
|
+
? data.error
|
|
41
|
+
: JSON.stringify(data?.hint || data.error?.[0]);
|
|
42
|
+
throw new Error(msg);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @internalRemarks Source: @carto/react-api */
|
|
47
|
+
export function checkCredentials(credentials: Credentials) {
|
|
48
|
+
if (!credentials || !credentials.apiBaseUrl || !credentials.accessToken) {
|
|
49
|
+
throw new Error('Missing or bad credentials provided');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** @internalRemarks Source: @carto/react-api */
|
|
54
|
+
export async function makeCall({
|
|
55
|
+
url,
|
|
56
|
+
credentials,
|
|
57
|
+
opts,
|
|
58
|
+
}: {
|
|
59
|
+
url: string;
|
|
60
|
+
credentials: Credentials;
|
|
61
|
+
opts: ModelRequestOptions;
|
|
62
|
+
}) {
|
|
63
|
+
let response;
|
|
64
|
+
let data;
|
|
65
|
+
const isPost = opts?.method === 'POST';
|
|
66
|
+
try {
|
|
67
|
+
response = await fetch(url.toString(), {
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: `Bearer ${credentials.accessToken}`,
|
|
70
|
+
...(isPost ? {'Content-Type': 'application/json'} : {}),
|
|
71
|
+
},
|
|
72
|
+
...(isPost
|
|
73
|
+
? {
|
|
74
|
+
method: opts?.method,
|
|
75
|
+
body: opts?.body,
|
|
76
|
+
}
|
|
77
|
+
: {}),
|
|
78
|
+
signal: opts?.abortController?.signal,
|
|
79
|
+
...opts?.otherOptions,
|
|
80
|
+
});
|
|
81
|
+
data = await response.json();
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if ((error as Error).name === 'AbortError') throw error;
|
|
84
|
+
|
|
85
|
+
throw new Error(`Failed request: ${error}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
dealWithApiError({response, data});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {getClient} from '../client';
|
|
2
|
+
import {ApiVersion, MapType} from '../constants';
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_GEO_COLUMN,
|
|
5
|
+
REQUEST_GET_MAX_URL_LENGTH,
|
|
6
|
+
} from '../constants-internal';
|
|
7
|
+
import {Source, SpatialFilter} from '../types';
|
|
8
|
+
import {$TODO} from '../types-internal';
|
|
9
|
+
import {assert} from '../utils';
|
|
10
|
+
import {ModelRequestOptions, checkCredentials, makeCall} from './common';
|
|
11
|
+
|
|
12
|
+
/** @internalRemarks Source: @carto/react-api */
|
|
13
|
+
const AVAILABLE_MODELS = [
|
|
14
|
+
'category',
|
|
15
|
+
'histogram',
|
|
16
|
+
'formula',
|
|
17
|
+
'timeseries',
|
|
18
|
+
'range',
|
|
19
|
+
'scatterplot',
|
|
20
|
+
'table',
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export type Model = (typeof AVAILABLE_MODELS)[number];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Execute a SQL model request.
|
|
27
|
+
* @internalRemarks Source: @carto/react-api
|
|
28
|
+
*/
|
|
29
|
+
export function executeModel(props: {
|
|
30
|
+
model: Model;
|
|
31
|
+
source: Source;
|
|
32
|
+
params: Record<string, unknown>;
|
|
33
|
+
spatialFilter?: SpatialFilter;
|
|
34
|
+
opts?: Partial<ModelRequestOptions>;
|
|
35
|
+
}) {
|
|
36
|
+
assert(props.source, 'executeModel: missing source');
|
|
37
|
+
assert(props.model, 'executeModel: missing model');
|
|
38
|
+
assert(props.params, 'executeModel: missing params');
|
|
39
|
+
|
|
40
|
+
assert(
|
|
41
|
+
AVAILABLE_MODELS.indexOf(props.model) !== -1,
|
|
42
|
+
`executeModel: model provided isn't valid. Available models: ${AVAILABLE_MODELS.join(
|
|
43
|
+
', '
|
|
44
|
+
)}`
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const {source, model, params, spatialFilter, opts} = props;
|
|
48
|
+
|
|
49
|
+
checkCredentials(source.credentials);
|
|
50
|
+
|
|
51
|
+
assert(
|
|
52
|
+
source.credentials.apiVersion === ApiVersion.V3,
|
|
53
|
+
'SQL Model API is a feature only available in CARTO 3.'
|
|
54
|
+
);
|
|
55
|
+
assert(
|
|
56
|
+
source.type !== MapType.TILESET,
|
|
57
|
+
'executeModel: Tileset not supported'
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
let url = `${source.credentials.apiBaseUrl}/v3/sql/${source.connection}/model/${model}`;
|
|
61
|
+
|
|
62
|
+
const {filters, filtersLogicalOperator = 'and', data, type} = source;
|
|
63
|
+
const queryParameters = source.queryParameters
|
|
64
|
+
? JSON.stringify(source.queryParameters)
|
|
65
|
+
: '';
|
|
66
|
+
|
|
67
|
+
const queryParams: Record<string, string> = {
|
|
68
|
+
type,
|
|
69
|
+
client: getClient(),
|
|
70
|
+
source: data,
|
|
71
|
+
params: JSON.stringify(params),
|
|
72
|
+
queryParameters,
|
|
73
|
+
filters: JSON.stringify(filters),
|
|
74
|
+
filtersLogicalOperator,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// API supports multiple filters, we apply it only to geoColumn
|
|
78
|
+
const spatialFilters = spatialFilter
|
|
79
|
+
? {
|
|
80
|
+
[source.geoColumn ? source.geoColumn : DEFAULT_GEO_COLUMN]:
|
|
81
|
+
spatialFilter,
|
|
82
|
+
}
|
|
83
|
+
: undefined;
|
|
84
|
+
|
|
85
|
+
if (spatialFilters) {
|
|
86
|
+
queryParams.spatialFilters = JSON.stringify(spatialFilters);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const urlWithSearchParams =
|
|
90
|
+
url + '?' + new URLSearchParams(queryParams).toString();
|
|
91
|
+
const isGet = urlWithSearchParams.length <= REQUEST_GET_MAX_URL_LENGTH;
|
|
92
|
+
if (isGet) {
|
|
93
|
+
url = urlWithSearchParams;
|
|
94
|
+
} else {
|
|
95
|
+
// undo the JSON.stringify, @TODO find a better pattern
|
|
96
|
+
queryParams.params = params as $TODO;
|
|
97
|
+
queryParams.filters = filters as $TODO;
|
|
98
|
+
queryParams.queryParameters = source.queryParameters as $TODO;
|
|
99
|
+
if (spatialFilters) {
|
|
100
|
+
queryParams.spatialFilters = spatialFilters as $TODO;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return makeCall({
|
|
104
|
+
url,
|
|
105
|
+
credentials: source.credentials,
|
|
106
|
+
opts: {
|
|
107
|
+
...opts,
|
|
108
|
+
method: isGet ? 'GET' : 'POST',
|
|
109
|
+
...(!isGet && {body: JSON.stringify(queryParams)}),
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AggregationType,
|
|
3
|
+
SortColumnType,
|
|
4
|
+
SortDirection,
|
|
5
|
+
SpatialFilter,
|
|
6
|
+
} from '../types';
|
|
7
|
+
|
|
8
|
+
/******************************************************************************
|
|
9
|
+
* WIDGET API REQUESTS
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface BaseRequestOptions {
|
|
13
|
+
spatialFilter?: SpatialFilter;
|
|
14
|
+
abortController?: AbortController;
|
|
15
|
+
filterOwner?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface FormulaRequestOptions extends BaseRequestOptions {
|
|
19
|
+
column: string;
|
|
20
|
+
operation?: AggregationType;
|
|
21
|
+
operationExp?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CategoryRequestOptions extends BaseRequestOptions {
|
|
25
|
+
column: string;
|
|
26
|
+
operation?: AggregationType;
|
|
27
|
+
operationColumn?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface RangeRequestOptions extends BaseRequestOptions {
|
|
31
|
+
column: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface TableRequestOptions extends BaseRequestOptions {
|
|
35
|
+
columns: string[];
|
|
36
|
+
sortBy?: string;
|
|
37
|
+
sortDirection?: SortDirection;
|
|
38
|
+
sortByColumnType?: SortColumnType;
|
|
39
|
+
page?: number;
|
|
40
|
+
rowsPerPage?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ScatterRequestOptions extends BaseRequestOptions {
|
|
44
|
+
xAxisColumn: string;
|
|
45
|
+
xAxisJoinOperation?: AggregationType;
|
|
46
|
+
yAxisColumn: string;
|
|
47
|
+
yAxisJoinOperation?: AggregationType;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface TimeSeriesRequestOptions extends BaseRequestOptions {
|
|
51
|
+
column: string;
|
|
52
|
+
stepSize?: number;
|
|
53
|
+
stepMultiplier?: number;
|
|
54
|
+
operation?: AggregationType;
|
|
55
|
+
operationColumn?: string;
|
|
56
|
+
joinOperation?: AggregationType;
|
|
57
|
+
splitByCategory?: string;
|
|
58
|
+
splitByCategoryLimit?: number;
|
|
59
|
+
splitByCategoryValues?: string[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface HistogramRequestOptions extends BaseRequestOptions {
|
|
63
|
+
column: string;
|
|
64
|
+
ticks: number[];
|
|
65
|
+
operation?: AggregationType;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/******************************************************************************
|
|
69
|
+
* WIDGET API RESPONSES
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
export type FormulaResponse = {value: number};
|
|
73
|
+
|
|
74
|
+
export type CategoryResponse = {name: string; value: number}[];
|
|
75
|
+
|
|
76
|
+
export type RangeResponse = {min: number; max: number};
|
|
77
|
+
|
|
78
|
+
export type TableResponse = {
|
|
79
|
+
totalCount: number;
|
|
80
|
+
rows: Record<string, number | string>[];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type ScatterResponse = [number, number][];
|
|
84
|
+
|
|
85
|
+
export type TimeSeriesResponse = {
|
|
86
|
+
rows: {name: string; value: number}[];
|
|
87
|
+
categories: string[];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type HistogramResponse = number[];
|