@carto/api-client 0.5.30-alpha.3cf7d80.116 → 0.5.30-alpha.bdcd62f.119

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/CHANGELOG.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - feat(sources): expose `_getPointsAggregationLevel` for maps-api dynamic point-tile aggregation parity (#304)
5
6
  - feat(widgetSources): support `featureIds` / `geometryType` request options to filter widget aggregations by a feature selection without relying on the synthetic `_carto_feature_id` column (#294)
7
+ - feat(widgetSources): support `SpatialIndexFilter` (H3/Quadbin cell selection) on `spatialFilter` (#296)
6
8
 
7
9
  ### 0.5.29
8
10
 
@@ -137,6 +137,7 @@ __export(src_exports, {
137
137
  _fillInTileStats: () => fillInTileStats,
138
138
  _getHexagonResolution: () => _getHexagonResolution,
139
139
  _getLog10ScaleSteps: () => getLog10ScaleSteps,
140
+ _getPointsAggregationLevel: () => getPointsAggregationLevel,
140
141
  _getRasterTileLayerStyleProps: () => getRasterTileLayerStyleProps,
141
142
  _validateVecExprSyntax: () => validateVecExprSyntax,
142
143
  addFilter: () => addFilter,
@@ -146,6 +147,7 @@ __export(src_exports, {
146
147
  applySorting: () => applySorting,
147
148
  boundaryQuerySource: () => boundaryQuerySource,
148
149
  boundaryTableSource: () => boundaryTableSource,
150
+ buildAuthHeaders: () => buildAuthHeaders,
149
151
  buildBinaryFeatureFilter: () => buildBinaryFeatureFilter,
150
152
  buildPublicMapUrl: () => buildPublicMapUrl,
151
153
  buildStatsUrl: () => buildStatsUrl,
@@ -164,6 +166,7 @@ __export(src_exports, {
164
166
  filterFunctions: () => filterFunctions,
165
167
  geojsonFeatures: () => geojsonFeatures,
166
168
  getApplicableFilters: () => getApplicableFilters,
169
+ getAuthCredentials: () => getAuthCredentials,
167
170
  getClient: () => getClient,
168
171
  getColorAccessor: () => getColorAccessor,
169
172
  getColumnNameFromGeoColumn: () => getColumnNameFromGeoColumn,
@@ -185,6 +188,7 @@ __export(src_exports, {
185
188
  h3TilesetSource: () => h3TilesetSource,
186
189
  hasFilter: () => hasFilter,
187
190
  histogram: () => histogram,
191
+ isSpatialIndexFilter: () => isSpatialIndexFilter,
188
192
  makeIntervalComplete: () => makeIntervalComplete,
189
193
  negateAccessor: () => negateAccessor,
190
194
  opacityToAlpha: () => opacityToAlpha,
@@ -196,6 +200,7 @@ __export(src_exports, {
196
200
  rasterSource: () => rasterSource,
197
201
  removeFilter: () => removeFilter,
198
202
  requestWithParameters: () => requestWithParameters,
203
+ rewriteUrlForSessionMode: () => rewriteUrlForSessionMode,
199
204
  scaleAggregationResLevel: () => scaleAggregationResLevel,
200
205
  scatterPlot: () => scatterPlot,
201
206
  setClient: () => setClient,
@@ -5801,6 +5806,10 @@ var SchemaFieldType = /* @__PURE__ */ ((SchemaFieldType2) => {
5801
5806
  SchemaFieldType2["Unknown"] = "unknown";
5802
5807
  return SchemaFieldType2;
5803
5808
  })(SchemaFieldType || {});
5809
+ function isSpatialIndexFilter(spatialFilter) {
5810
+ const filter = spatialFilter;
5811
+ return Array.isArray(filter?.indexes) && ["h3", "h3int", "quadbin"].includes(filter?.type);
5812
+ }
5804
5813
 
5805
5814
  // src/utils.ts
5806
5815
  var FILTER_TYPES = new Set(Object.values(FilterType));
@@ -5988,6 +5997,42 @@ init_cjs_shims();
5988
5997
  // src/api/index.ts
5989
5998
  init_cjs_shims();
5990
5999
 
6000
+ // src/api/auth.ts
6001
+ init_cjs_shims();
6002
+ function buildAuthHeaders(options) {
6003
+ if (options.authMode === "session") {
6004
+ if (options.accessToken) {
6005
+ throw new Error(
6006
+ `accessToken must not be provided with authMode: 'session' \u2014 authentication is delegated to the server behind apiBaseUrl`
6007
+ );
6008
+ }
6009
+ return {};
6010
+ }
6011
+ if (!options.accessToken) {
6012
+ throw new Error(
6013
+ `accessToken is required (or pass authMode: 'session' to authenticate via a same-origin session instead)`
6014
+ );
6015
+ }
6016
+ return { Authorization: `Bearer ${options.accessToken}` };
6017
+ }
6018
+ function getAuthCredentials(authMode) {
6019
+ return authMode === "session" ? "same-origin" : void 0;
6020
+ }
6021
+ function rewriteUrlForSessionMode(url, apiBaseUrl) {
6022
+ let origin;
6023
+ try {
6024
+ const parsed = new URL(url);
6025
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
6026
+ return url;
6027
+ }
6028
+ origin = parsed.origin;
6029
+ } catch {
6030
+ return url;
6031
+ }
6032
+ const base = apiBaseUrl.replace(/\/+$/, "");
6033
+ return base + url.slice(origin.length);
6034
+ }
6035
+
5991
6036
  // src/api/carto-api-error.ts
5992
6037
  init_cjs_shims();
5993
6038
  var CartoAPIError = class extends Error {
@@ -6109,7 +6154,8 @@ async function requestWithParameters({
6109
6154
  errorContext,
6110
6155
  maxLengthURL = DEFAULT_MAX_LENGTH_URL,
6111
6156
  localCache,
6112
- signal
6157
+ signal,
6158
+ credentials
6113
6159
  }) {
6114
6160
  parameters = {
6115
6161
  v: V3_MINOR_VERSION,
@@ -6133,8 +6179,9 @@ async function requestWithParameters({
6133
6179
  method: "POST",
6134
6180
  body: JSON.stringify(parameters),
6135
6181
  headers,
6136
- signal
6137
- }) : fetch(url, { headers, signal });
6182
+ signal,
6183
+ ...credentials && { credentials }
6184
+ }) : fetch(url, { headers, signal, ...credentials && { credentials } });
6138
6185
  let response;
6139
6186
  let responseJson;
6140
6187
  const jsonPromise = fetchPromise.then((_response) => {
@@ -6180,8 +6227,19 @@ function createCacheKey(baseUrl, parameters, headers) {
6180
6227
  headers: headerEntries
6181
6228
  });
6182
6229
  }
6230
+ var RELATIVE_ORIGIN = "https://relative.invalid";
6231
+ function parseBaseUrl(baseUrlString) {
6232
+ const isRelative = baseUrlString.startsWith("/") && !baseUrlString.startsWith("//");
6233
+ return {
6234
+ url: new URL(baseUrlString, isRelative ? RELATIVE_ORIGIN : void 0),
6235
+ isRelative
6236
+ };
6237
+ }
6238
+ function serializeBaseUrl(url, isRelative) {
6239
+ return isRelative ? `${url.pathname}${url.search}` : url.toString();
6240
+ }
6183
6241
  function createURLWithParameters(baseUrlString, parameters) {
6184
- const baseUrl = new URL(baseUrlString);
6242
+ const { url: baseUrl, isRelative } = parseBaseUrl(baseUrlString);
6185
6243
  for (const [key, value] of Object.entries(parameters)) {
6186
6244
  if (isPureObject(value) || Array.isArray(value)) {
6187
6245
  baseUrl.searchParams.set(key, JSON.stringify(value));
@@ -6194,16 +6252,16 @@ function createURLWithParameters(baseUrlString, parameters) {
6194
6252
  }
6195
6253
  }
6196
6254
  }
6197
- return baseUrl.toString();
6255
+ return serializeBaseUrl(baseUrl, isRelative);
6198
6256
  }
6199
6257
  function excludeURLParameters(baseUrlString, parameters) {
6200
- const baseUrl = new URL(baseUrlString);
6258
+ const { url: baseUrl, isRelative } = parseBaseUrl(baseUrlString);
6201
6259
  for (const param of parameters) {
6202
6260
  if (baseUrl.searchParams.has(param)) {
6203
6261
  baseUrl.searchParams.delete(param);
6204
6262
  }
6205
6263
  }
6206
- return baseUrl.toString();
6264
+ return serializeBaseUrl(baseUrl, isRelative);
6207
6265
  }
6208
6266
  function clearDefaultRequestCache() {
6209
6267
  DEFAULT_REQUEST_CACHE.clear();
@@ -6231,10 +6289,12 @@ async function baseSource(endpoint, options, urlParameters) {
6231
6289
  }
6232
6290
  const baseUrl = buildSourceUrl(mergedOptions);
6233
6291
  const { clientId, maxLengthURL, localCache } = mergedOptions;
6292
+ const sessionMode = options.authMode === "session";
6234
6293
  const headers = {
6235
- Authorization: `Bearer ${options.accessToken}`,
6294
+ ...buildAuthHeaders(options),
6236
6295
  ...options.headers
6237
6296
  };
6297
+ const credentials = getAuthCredentials(options.authMode);
6238
6298
  const parameters = { client: clientId, ...options.tags, ...urlParameters };
6239
6299
  const errorContext = {
6240
6300
  requestType: "Map instantiation",
@@ -6248,15 +6308,19 @@ async function baseSource(endpoint, options, urlParameters) {
6248
6308
  headers,
6249
6309
  errorContext,
6250
6310
  maxLengthURL,
6251
- localCache
6311
+ localCache,
6312
+ credentials
6252
6313
  });
6253
- const dataUrl = tilejson.url[0];
6314
+ let dataUrl = tilejson.url[0];
6254
6315
  if (cache) {
6255
6316
  cache.value = parseInt(
6256
6317
  new URL(dataUrl).searchParams.get("cache") || "",
6257
6318
  10
6258
6319
  );
6259
6320
  }
6321
+ if (sessionMode) {
6322
+ dataUrl = rewriteUrlForSessionMode(dataUrl, mergedOptions.apiBaseUrl);
6323
+ }
6260
6324
  errorContext.requestType = "Map data";
6261
6325
  const json = await requestWithParameters({
6262
6326
  baseUrl: dataUrl,
@@ -6264,9 +6328,14 @@ async function baseSource(endpoint, options, urlParameters) {
6264
6328
  headers,
6265
6329
  errorContext,
6266
6330
  maxLengthURL,
6267
- localCache
6331
+ localCache,
6332
+ credentials
6268
6333
  });
6269
- if (accessToken) {
6334
+ if (sessionMode) {
6335
+ json.tiles = json.tiles?.map(
6336
+ (template) => rewriteUrlForSessionMode(template, mergedOptions.apiBaseUrl)
6337
+ );
6338
+ } else if (accessToken) {
6270
6339
  json.accessToken = accessToken;
6271
6340
  }
6272
6341
  if (schema) {
@@ -6389,6 +6458,7 @@ function dealWithApiError({
6389
6458
  async function makeCall({
6390
6459
  url,
6391
6460
  accessToken,
6461
+ authMode,
6392
6462
  opts
6393
6463
  }) {
6394
6464
  let response;
@@ -6397,10 +6467,13 @@ async function makeCall({
6397
6467
  try {
6398
6468
  response = await fetch(url.toString(), {
6399
6469
  headers: {
6400
- Authorization: `Bearer ${accessToken}`,
6470
+ ...buildAuthHeaders({ accessToken, authMode }),
6401
6471
  ...isPost && { "Content-Type": "application/json" },
6402
6472
  ...opts.headers
6403
6473
  },
6474
+ ...getAuthCredentials(authMode) && {
6475
+ credentials: getAuthCredentials(authMode)
6476
+ },
6404
6477
  ...isPost && {
6405
6478
  method: opts?.method,
6406
6479
  body: opts?.body
@@ -6444,9 +6517,8 @@ function executeModel(props) {
6444
6517
  )}`
6445
6518
  );
6446
6519
  const { model, source, params, opts } = props;
6447
- const { type, apiVersion, apiBaseUrl, accessToken, connectionName, clientId } = source;
6520
+ const { type, apiVersion, apiBaseUrl, connectionName, clientId } = source;
6448
6521
  assert2(apiBaseUrl, "executeModel: missing apiBaseUrl");
6449
- assert2(accessToken, "executeModel: missing accessToken");
6450
6522
  assert2(apiVersion === V3, "executeModel: SQL Model API requires CARTO 3+");
6451
6523
  assert2(type !== "tileset", "executeModel: Tilesets not supported");
6452
6524
  let url = `${apiBaseUrl}/v3/sql/${connectionName}/model/${model}`;
@@ -6485,6 +6557,7 @@ function executeModel(props) {
6485
6557
  return makeCall({
6486
6558
  url,
6487
6559
  accessToken: source.accessToken,
6560
+ authMode: source.authMode,
6488
6561
  opts: {
6489
6562
  ...opts,
6490
6563
  method: isGet ? "GET" : "POST",
@@ -6611,6 +6684,7 @@ var WidgetRemoteSource = class extends WidgetSource {
6611
6684
  apiBaseUrl: props.apiBaseUrl,
6612
6685
  clientId: props.clientId,
6613
6686
  accessToken: props.accessToken,
6687
+ authMode: props.authMode,
6614
6688
  connectionName: props.connectionName,
6615
6689
  filters: getApplicableFilters(filterOwner, filters || props.filters),
6616
6690
  filtersLogicalOperator: props.filtersLogicalOperator,
@@ -6940,7 +7014,7 @@ var WidgetRemoteSource = class extends WidgetSource {
6940
7014
  url = `${apiBaseUrl}/${apiVersion}/stats/${connectionName}/${data}/${spatialDataColumn}`;
6941
7015
  }
6942
7016
  const headers = {
6943
- Authorization: `Bearer ${this.props.accessToken}`,
7017
+ ...buildAuthHeaders(this.props),
6944
7018
  ...this.props.headers
6945
7019
  };
6946
7020
  const errorContext = {
@@ -6953,7 +7027,8 @@ var WidgetRemoteSource = class extends WidgetSource {
6953
7027
  headers,
6954
7028
  signal,
6955
7029
  errorContext,
6956
- parameters
7030
+ parameters,
7031
+ credentials: getAuthCredentials(this.props.authMode)
6957
7032
  }).then(({ extent: { xmin, ymin, xmax, ymax } }) => ({
6958
7033
  bbox: [xmin, ymin, xmax, ymax]
6959
7034
  }));
@@ -7685,16 +7760,17 @@ var WidgetTilesetSourceImpl = class extends WidgetSource {
7685
7760
  this._features.length = 0;
7686
7761
  }
7687
7762
  _extractTileFeatures(spatialFilter) {
7763
+ const geometryFilter = spatialFilter && !isSpatialIndexFilter(spatialFilter) ? spatialFilter : void 0;
7688
7764
  const prevInputs = this._tileFeatureExtractPreviousInputs;
7689
- if (this._features.length && spatialFilterEquals(prevInputs.spatialFilter, spatialFilter)) {
7765
+ if (this._features.length && spatialFilterEquals(prevInputs.spatialFilter, geometryFilter)) {
7690
7766
  return;
7691
7767
  }
7692
7768
  this._features = tileFeatures({
7693
7769
  ...assignOptional({}, this.props, this._tileFeatureExtractOptions),
7694
7770
  tiles: this._tiles,
7695
- spatialFilter
7771
+ spatialFilter: geometryFilter
7696
7772
  });
7697
- prevInputs.spatialFilter = spatialFilter;
7773
+ prevInputs.spatialFilter = geometryFilter;
7698
7774
  }
7699
7775
  /**
7700
7776
  * Loads features as GeoJSON (used for testing).
@@ -8734,7 +8810,7 @@ var query = async function(options) {
8734
8810
  }
8735
8811
  const baseUrl = buildQueryUrl({ apiBaseUrl, connectionName });
8736
8812
  const headers = {
8737
- Authorization: `Bearer ${options.accessToken}`,
8813
+ ...buildAuthHeaders(options),
8738
8814
  ...options.headers
8739
8815
  };
8740
8816
  const parameters = {
@@ -8756,7 +8832,8 @@ var query = async function(options) {
8756
8832
  errorContext,
8757
8833
  maxLengthURL,
8758
8834
  localCache,
8759
- signal: options.signal
8835
+ signal: options.signal,
8836
+ credentials: getAuthCredentials(options.authMode)
8760
8837
  });
8761
8838
  };
8762
8839
 
@@ -11113,6 +11190,9 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
11113
11190
  };
11114
11191
  }
11115
11192
  function createLoadOptions(accessToken) {
11193
+ if (!accessToken) {
11194
+ return { loadOptions: { fetch: { credentials: "same-origin" } } };
11195
+ }
11116
11196
  return {
11117
11197
  loadOptions: { fetch: { headers: { Authorization: `Bearer ${accessToken}` } } }
11118
11198
  };
@@ -11709,6 +11789,20 @@ function _getHexagonResolution(viewport, tileSize) {
11709
11789
  Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS)
11710
11790
  );
11711
11791
  }
11792
+ var DYNAMIC_TILES_POINTS_AGGREGATION_LEVEL = 8;
11793
+ var AGG_LEVEL_CORRECTION_BY_TILE_RESOLUTION = {
11794
+ 0.25: -1,
11795
+ 0.5: 0,
11796
+ 1: 1,
11797
+ 2: 2,
11798
+ 4: 3
11799
+ };
11800
+ function getPointsAggregationLevel({
11801
+ tileResolution,
11802
+ zoomLevel
11803
+ }) {
11804
+ return zoomLevel + DYNAMIC_TILES_POINTS_AGGREGATION_LEVEL + AGG_LEVEL_CORRECTION_BY_TILE_RESOLUTION[tileResolution];
11805
+ }
11712
11806
 
11713
11807
  // src/utils/CellSet.ts
11714
11808
  init_cjs_shims();
@@ -11806,6 +11900,7 @@ function hashBuckets(initialCount) {
11806
11900
  _fillInTileStats,
11807
11901
  _getHexagonResolution,
11808
11902
  _getLog10ScaleSteps,
11903
+ _getPointsAggregationLevel,
11809
11904
  _getRasterTileLayerStyleProps,
11810
11905
  _validateVecExprSyntax,
11811
11906
  addFilter,
@@ -11815,6 +11910,7 @@ function hashBuckets(initialCount) {
11815
11910
  applySorting,
11816
11911
  boundaryQuerySource,
11817
11912
  boundaryTableSource,
11913
+ buildAuthHeaders,
11818
11914
  buildBinaryFeatureFilter,
11819
11915
  buildPublicMapUrl,
11820
11916
  buildStatsUrl,
@@ -11833,6 +11929,7 @@ function hashBuckets(initialCount) {
11833
11929
  filterFunctions,
11834
11930
  geojsonFeatures,
11835
11931
  getApplicableFilters,
11932
+ getAuthCredentials,
11836
11933
  getClient,
11837
11934
  getColorAccessor,
11838
11935
  getColumnNameFromGeoColumn,
@@ -11854,6 +11951,7 @@ function hashBuckets(initialCount) {
11854
11951
  h3TilesetSource,
11855
11952
  hasFilter,
11856
11953
  histogram,
11954
+ isSpatialIndexFilter,
11857
11955
  makeIntervalComplete,
11858
11956
  negateAccessor,
11859
11957
  opacityToAlpha,
@@ -11865,6 +11963,7 @@ function hashBuckets(initialCount) {
11865
11963
  rasterSource,
11866
11964
  removeFilter,
11867
11965
  requestWithParameters,
11966
+ rewriteUrlForSessionMode,
11868
11967
  scaleAggregationResLevel,
11869
11968
  scatterPlot,
11870
11969
  setClient,