@carto/api-client 0.5.9-alpha.PR193.3 → 0.5.9

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/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "homepage": "https://github.com/CartoDB/carto-api-client#readme",
9
9
  "author": "Don McCurdy <donmccurdy@carto.com>",
10
10
  "packageManager": "yarn@4.3.1",
11
- "version": "0.5.9-alpha.PR193.3",
11
+ "version": "0.5.9",
12
12
  "license": "MIT",
13
13
  "publishConfig": {
14
14
  "access": "public"
package/src/api/query.ts CHANGED
@@ -13,17 +13,7 @@ import {requestWithParameters} from './request-with-parameters.js';
13
13
  import type {APIErrorContext} from './carto-api-error.js';
14
14
  import {getClient} from '../client.js';
15
15
 
16
- export type QueryOptions = SourceOptions &
17
- QuerySourceOptions & {
18
- /**
19
- * @internal
20
- * @experimental
21
- * Used to append additional parameters to the SQL API request for features specific to providers or integrations.
22
- */
23
- internalParameters?: Record<string, string | boolean | number>;
24
- /** Used to abort the request. */
25
- signal?: AbortSignal;
26
- };
16
+ export type QueryOptions = SourceOptions & QuerySourceOptions;
27
17
  type UrlParameters = {q: string; queryParameters?: string};
28
18
 
29
19
  export const query = async function (
@@ -37,7 +27,6 @@ export const query = async function (
37
27
  connectionName,
38
28
  sqlQuery,
39
29
  queryParameters,
40
- internalParameters,
41
30
  } = options;
42
31
  const urlParameters: UrlParameters = {q: sqlQuery};
43
32
 
@@ -50,12 +39,7 @@ export const query = async function (
50
39
  Authorization: `Bearer ${options.accessToken}`,
51
40
  ...options.headers,
52
41
  };
53
- const parameters = {
54
- client: clientId,
55
- ...options.tags,
56
- ...internalParameters,
57
- ...urlParameters,
58
- };
42
+ const parameters = {client: clientId, ...urlParameters};
59
43
 
60
44
  const errorContext: APIErrorContext = {
61
45
  requestType: 'SQL',
@@ -70,6 +54,5 @@ export const query = async function (
70
54
  errorContext,
71
55
  maxLengthURL,
72
56
  localCache,
73
- signal: options.signal,
74
57
  });
75
58
  };
@@ -23,7 +23,6 @@ export async function requestWithParameters<T = any>({
23
23
  errorContext,
24
24
  maxLengthURL = DEFAULT_MAX_LENGTH_URL,
25
25
  localCache,
26
- signal,
27
26
  }: {
28
27
  baseUrl: string;
29
28
  parameters?: Record<string, unknown>;
@@ -31,7 +30,6 @@ export async function requestWithParameters<T = any>({
31
30
  errorContext: APIErrorContext;
32
31
  maxLengthURL?: number;
33
32
  localCache?: LocalCacheOptions;
34
- signal?: AbortSignal;
35
33
  }): Promise<T> {
36
34
  // Parameters added to all requests issued with `requestWithParameters()`.
37
35
  // These parameters override parameters already in the base URL, but not
@@ -67,9 +65,8 @@ export async function requestWithParameters<T = any>({
67
65
  method: 'POST',
68
66
  body: JSON.stringify(parameters),
69
67
  headers,
70
- signal,
71
68
  })
72
- : fetch(url, {headers, signal});
69
+ : fetch(url, {headers});
73
70
 
74
71
  let response: Response | undefined;
75
72
  let responseJson: unknown;
@@ -146,12 +143,10 @@ function createURLWithParameters(
146
143
  if (isPureObject(value) || Array.isArray(value)) {
147
144
  baseUrl.searchParams.set(key, JSON.stringify(value));
148
145
  } else {
149
- if (value !== null && value !== undefined) {
150
- baseUrl.searchParams.set(
151
- key,
152
- (value as string | boolean | number).toString()
153
- );
154
- }
146
+ baseUrl.searchParams.set(
147
+ key,
148
+ (value as string | boolean | number).toString()
149
+ );
155
150
  }
156
151
  }
157
152
  return baseUrl.toString();
@@ -43,7 +43,6 @@ export interface ModelSource {
43
43
  spatialDataColumn?: string;
44
44
  spatialDataType?: SpatialDataType;
45
45
  spatialFiltersMode?: SpatialFilterPolyfillMode;
46
- tags?: Record<string, string>;
47
46
  }
48
47
 
49
48
  const {V3} = ApiVersion;
@@ -88,7 +87,6 @@ export function executeModel(props: {
88
87
  spatialDataType = 'geo',
89
88
  spatialDataColumn = DEFAULT_GEO_COLUMN,
90
89
  spatialFiltersMode = 'intersects',
91
- tags,
92
90
  } = source;
93
91
 
94
92
  const queryParams: Record<string, unknown> = {
@@ -99,7 +97,6 @@ export function executeModel(props: {
99
97
  queryParameters: source.queryParameters || '',
100
98
  filters,
101
99
  filtersLogicalOperator,
102
- ...(tags ?? {}),
103
100
  };
104
101
 
105
102
  queryParams.spatialDataType = spatialDataType;
@@ -1,7 +1,11 @@
1
1
  import {aggregationFunctions, aggregate} from './aggregation.js';
2
2
  import type {AggregationType} from '../types.js';
3
3
  import type {FeatureData} from '../types-internal.js';
4
- import type {CategoryResponseRaw} from '../widget-sources/types.js';
4
+ import type {
5
+ CategoryOrderBy,
6
+ CategoryResponseEntry,
7
+ CategoryResponseRaw,
8
+ } from '../widget-sources/types.js';
5
9
 
6
10
  /** @privateRemarks Source: @carto/react-core */
7
11
  export function groupValuesByColumn({
@@ -11,6 +15,7 @@ export function groupValuesByColumn({
11
15
  keysColumn,
12
16
  operation,
13
17
  othersThreshold,
18
+ orderBy = 'frequency_desc',
14
19
  }: {
15
20
  data: FeatureData[];
16
21
  valuesColumns?: string[];
@@ -18,6 +23,7 @@ export function groupValuesByColumn({
18
23
  keysColumn: string;
19
24
  operation: AggregationType;
20
25
  othersThreshold?: number;
26
+ orderBy?: CategoryOrderBy;
21
27
  }): CategoryResponseRaw | null {
22
28
  if (Array.isArray(data) && data.length === 0) {
23
29
  return {rows: null};
@@ -54,7 +60,7 @@ export function groupValuesByColumn({
54
60
  name,
55
61
  value: targetOperation(value),
56
62
  }))
57
- .sort((a, b) => b.value - a.value);
63
+ .sort(getSorter(orderBy));
58
64
 
59
65
  if (othersThreshold && allCategories.length > othersThreshold) {
60
66
  const otherValue = allCategories
@@ -72,3 +78,26 @@ export function groupValuesByColumn({
72
78
  rows: allCategories,
73
79
  };
74
80
  }
81
+
82
+ export function getSorter(
83
+ orderBy: CategoryOrderBy
84
+ ): (a: CategoryResponseEntry, b: CategoryResponseEntry) => number {
85
+ switch (orderBy) {
86
+ case 'frequency_asc':
87
+ // 'value ASC, name ASC'
88
+ return (a, b) => a.value - b.value || localeCompare(a.name, b.name);
89
+ case 'frequency_desc':
90
+ // 'value DESC, name ASC'
91
+ return (a, b) => b.value - a.value || localeCompare(a.name, b.name);
92
+ case 'alphabetical_asc':
93
+ // 'name ASC, value DESC'
94
+ return (a, b) => localeCompare(a.name, b.name) || b.value - a.value;
95
+ case 'alphabetical_desc':
96
+ // 'name DESC, value DESC'
97
+ return (a, b) => localeCompare(b.name, a.name) || b.value - a.value;
98
+ }
99
+ }
100
+
101
+ function localeCompare(a?: string | null, b?: string | null) {
102
+ return (a ?? 'null').localeCompare(b ?? 'null');
103
+ }
@@ -47,7 +47,7 @@ export async function baseSource<UrlParameters extends Record<string, unknown>>(
47
47
  Authorization: `Bearer ${options.accessToken}`,
48
48
  ...options.headers,
49
49
  };
50
- const parameters = {client: clientId, ...options.tags, ...urlParameters};
50
+ const parameters = {client: clientId, ...urlParameters};
51
51
 
52
52
  const errorContext: APIErrorContext = {
53
53
  requestType: 'Map instantiation',
@@ -75,9 +75,6 @@ export type SourceOptionalOptions = {
75
75
  * By default, local in-memory caching is enabled.
76
76
  */
77
77
  localCache?: LocalCacheOptions;
78
-
79
- /** Additional tags appended to HTTP requests, available for analytics and audits. */
80
- tags?: Record<string, string>;
81
78
  };
82
79
 
83
80
  export type LocalCacheOptions = {
@@ -31,6 +31,12 @@ export interface BaseRequestOptions {
31
31
  filterOwner?: string;
32
32
  }
33
33
 
34
+ export type CategoryOrderBy =
35
+ | 'frequency_asc' // sort by aggregate value ascending, then by name ascending
36
+ | 'frequency_desc' // sort by aggregate value descending, then by name ascending
37
+ | 'alphabetical_asc' // sort by category name ascending, then by value descending
38
+ | 'alphabetical_desc'; // sort by category name descending, then by value descending
39
+
34
40
  /**
35
41
  * Examples:
36
42
  * * population by state
@@ -61,6 +67,11 @@ export interface CategoryRequestOptions extends BaseRequestOptions {
61
67
  joinOperation?: 'count' | 'avg' | 'min' | 'max' | 'sum';
62
68
  /** Calculate `_carto_others` category for all categories after first N (N is threshold). */
63
69
  othersThreshold?: number;
70
+ /**
71
+ * Order categories by frequency or alphabetically.
72
+ * @default 'frequency_desc'
73
+ */
74
+ orderBy?: CategoryOrderBy;
64
75
  /** Return raw result (CategoryResponseRaw). */
65
76
  rawResult?: boolean;
66
77
  }
@@ -209,6 +220,7 @@ export type FeaturesResponse = {rows: Record<string, unknown>[]};
209
220
  /** Response from {@link WidgetRemoteSource#getFormula}. */
210
221
  export type FormulaResponse = {value: number | null};
211
222
 
223
+ /** Entry in the category widget response, see {@link WidgetRemoteSource#getCategories}. */
212
224
  export type CategoryResponseEntry = {name: string | null; value: number};
213
225
  /** Response from {@link WidgetRemoteSource#getCategories}. */
214
226
  export type CategoryResponse = CategoryResponseEntry[];
@@ -61,7 +61,6 @@ export abstract class WidgetRemoteSource<
61
61
  filtersLogicalOperator: props.filtersLogicalOperator,
62
62
  spatialDataType: props.spatialDataType,
63
63
  spatialDataColumn: props.spatialDataColumn,
64
- tags: props.tags,
65
64
  };
66
65
  }
67
66
 
@@ -77,8 +76,14 @@ export abstract class WidgetRemoteSource<
77
76
  rawResult,
78
77
  ...params
79
78
  } = options;
80
- const {column, operation, operationColumn, operationExp, othersThreshold} =
81
- params;
79
+ const {
80
+ column,
81
+ operation,
82
+ operationColumn,
83
+ operationExp,
84
+ othersThreshold,
85
+ orderBy,
86
+ } = params;
82
87
 
83
88
  if (operation === AggregationTypes.Custom) {
84
89
  assert(operationExp, 'operationExp is required for custom operation');
@@ -97,6 +102,7 @@ export abstract class WidgetRemoteSource<
97
102
  operationExp,
98
103
  operationColumn: operationColumn || column,
99
104
  othersThreshold,
105
+ orderBy,
100
106
  },
101
107
  opts: {signal, headers: this.props.headers},
102
108
  });
@@ -191,6 +191,7 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
191
191
  filterOwner,
192
192
  spatialFilter,
193
193
  othersThreshold,
194
+ orderBy = 'frequency_desc',
194
195
  rawResult,
195
196
  }: CategoryRequestOptions): Promise<CategoryResponse> {
196
197
  const filteredFeatures = this._getFilteredFeatures(
@@ -212,6 +213,7 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
212
213
  keysColumn: column,
213
214
  operation,
214
215
  othersThreshold,
216
+ orderBy,
215
217
  });
216
218
 
217
219
  if (rawResult) {