@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.
@@ -5559,6 +5559,10 @@ var SchemaFieldType = /* @__PURE__ */ ((SchemaFieldType2) => {
5559
5559
  SchemaFieldType2["Unknown"] = "unknown";
5560
5560
  return SchemaFieldType2;
5561
5561
  })(SchemaFieldType || {});
5562
+ function isSpatialIndexFilter(spatialFilter) {
5563
+ const filter = spatialFilter;
5564
+ return Array.isArray(filter?.indexes) && ["h3", "h3int", "quadbin"].includes(filter?.type);
5565
+ }
5562
5566
 
5563
5567
  // src/utils.ts
5564
5568
  var FILTER_TYPES = new Set(Object.values(FilterType));
@@ -5737,6 +5741,41 @@ function getFilterValue(filtersWithoutTimeType, timeColumn, timeFilter, filterSi
5737
5741
  };
5738
5742
  }
5739
5743
 
5744
+ // src/api/auth.ts
5745
+ function buildAuthHeaders(options) {
5746
+ if (options.authMode === "session") {
5747
+ if (options.accessToken) {
5748
+ throw new Error(
5749
+ `accessToken must not be provided with authMode: 'session' \u2014 authentication is delegated to the server behind apiBaseUrl`
5750
+ );
5751
+ }
5752
+ return {};
5753
+ }
5754
+ if (!options.accessToken) {
5755
+ throw new Error(
5756
+ `accessToken is required (or pass authMode: 'session' to authenticate via a same-origin session instead)`
5757
+ );
5758
+ }
5759
+ return { Authorization: `Bearer ${options.accessToken}` };
5760
+ }
5761
+ function getAuthCredentials(authMode) {
5762
+ return authMode === "session" ? "same-origin" : void 0;
5763
+ }
5764
+ function rewriteUrlForSessionMode(url, apiBaseUrl) {
5765
+ let origin;
5766
+ try {
5767
+ const parsed = new URL(url);
5768
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
5769
+ return url;
5770
+ }
5771
+ origin = parsed.origin;
5772
+ } catch {
5773
+ return url;
5774
+ }
5775
+ const base = apiBaseUrl.replace(/\/+$/, "");
5776
+ return base + url.slice(origin.length);
5777
+ }
5778
+
5740
5779
  // src/api/carto-api-error.ts
5741
5780
  var CartoAPIError = class extends Error {
5742
5781
  constructor(error, errorContext, response, responseJson) {
@@ -5843,7 +5882,8 @@ async function requestWithParameters({
5843
5882
  errorContext,
5844
5883
  maxLengthURL = DEFAULT_MAX_LENGTH_URL,
5845
5884
  localCache,
5846
- signal
5885
+ signal,
5886
+ credentials
5847
5887
  }) {
5848
5888
  parameters = {
5849
5889
  v: V3_MINOR_VERSION,
@@ -5867,8 +5907,9 @@ async function requestWithParameters({
5867
5907
  method: "POST",
5868
5908
  body: JSON.stringify(parameters),
5869
5909
  headers,
5870
- signal
5871
- }) : fetch(url, { headers, signal });
5910
+ signal,
5911
+ ...credentials && { credentials }
5912
+ }) : fetch(url, { headers, signal, ...credentials && { credentials } });
5872
5913
  let response;
5873
5914
  let responseJson;
5874
5915
  const jsonPromise = fetchPromise.then((_response) => {
@@ -5914,8 +5955,19 @@ function createCacheKey(baseUrl, parameters, headers) {
5914
5955
  headers: headerEntries
5915
5956
  });
5916
5957
  }
5958
+ var RELATIVE_ORIGIN = "https://relative.invalid";
5959
+ function parseBaseUrl(baseUrlString) {
5960
+ const isRelative = baseUrlString.startsWith("/") && !baseUrlString.startsWith("//");
5961
+ return {
5962
+ url: new URL(baseUrlString, isRelative ? RELATIVE_ORIGIN : void 0),
5963
+ isRelative
5964
+ };
5965
+ }
5966
+ function serializeBaseUrl(url, isRelative) {
5967
+ return isRelative ? `${url.pathname}${url.search}` : url.toString();
5968
+ }
5917
5969
  function createURLWithParameters(baseUrlString, parameters) {
5918
- const baseUrl = new URL(baseUrlString);
5970
+ const { url: baseUrl, isRelative } = parseBaseUrl(baseUrlString);
5919
5971
  for (const [key, value] of Object.entries(parameters)) {
5920
5972
  if (isPureObject(value) || Array.isArray(value)) {
5921
5973
  baseUrl.searchParams.set(key, JSON.stringify(value));
@@ -5928,16 +5980,16 @@ function createURLWithParameters(baseUrlString, parameters) {
5928
5980
  }
5929
5981
  }
5930
5982
  }
5931
- return baseUrl.toString();
5983
+ return serializeBaseUrl(baseUrl, isRelative);
5932
5984
  }
5933
5985
  function excludeURLParameters(baseUrlString, parameters) {
5934
- const baseUrl = new URL(baseUrlString);
5986
+ const { url: baseUrl, isRelative } = parseBaseUrl(baseUrlString);
5935
5987
  for (const param of parameters) {
5936
5988
  if (baseUrl.searchParams.has(param)) {
5937
5989
  baseUrl.searchParams.delete(param);
5938
5990
  }
5939
5991
  }
5940
- return baseUrl.toString();
5992
+ return serializeBaseUrl(baseUrl, isRelative);
5941
5993
  }
5942
5994
  function clearDefaultRequestCache() {
5943
5995
  DEFAULT_REQUEST_CACHE.clear();
@@ -5965,10 +6017,12 @@ async function baseSource(endpoint, options, urlParameters) {
5965
6017
  }
5966
6018
  const baseUrl = buildSourceUrl(mergedOptions);
5967
6019
  const { clientId, maxLengthURL, localCache } = mergedOptions;
6020
+ const sessionMode = options.authMode === "session";
5968
6021
  const headers = {
5969
- Authorization: `Bearer ${options.accessToken}`,
6022
+ ...buildAuthHeaders(options),
5970
6023
  ...options.headers
5971
6024
  };
6025
+ const credentials = getAuthCredentials(options.authMode);
5972
6026
  const parameters = { client: clientId, ...options.tags, ...urlParameters };
5973
6027
  const errorContext = {
5974
6028
  requestType: "Map instantiation",
@@ -5982,15 +6036,19 @@ async function baseSource(endpoint, options, urlParameters) {
5982
6036
  headers,
5983
6037
  errorContext,
5984
6038
  maxLengthURL,
5985
- localCache
6039
+ localCache,
6040
+ credentials
5986
6041
  });
5987
- const dataUrl = tilejson.url[0];
6042
+ let dataUrl = tilejson.url[0];
5988
6043
  if (cache) {
5989
6044
  cache.value = parseInt(
5990
6045
  new URL(dataUrl).searchParams.get("cache") || "",
5991
6046
  10
5992
6047
  );
5993
6048
  }
6049
+ if (sessionMode) {
6050
+ dataUrl = rewriteUrlForSessionMode(dataUrl, mergedOptions.apiBaseUrl);
6051
+ }
5994
6052
  errorContext.requestType = "Map data";
5995
6053
  const json = await requestWithParameters({
5996
6054
  baseUrl: dataUrl,
@@ -5998,9 +6056,14 @@ async function baseSource(endpoint, options, urlParameters) {
5998
6056
  headers,
5999
6057
  errorContext,
6000
6058
  maxLengthURL,
6001
- localCache
6059
+ localCache,
6060
+ credentials
6002
6061
  });
6003
- if (accessToken) {
6062
+ if (sessionMode) {
6063
+ json.tiles = json.tiles?.map(
6064
+ (template) => rewriteUrlForSessionMode(template, mergedOptions.apiBaseUrl)
6065
+ );
6066
+ } else if (accessToken) {
6004
6067
  json.accessToken = accessToken;
6005
6068
  }
6006
6069
  if (schema) {
@@ -6105,6 +6168,7 @@ function dealWithApiError({
6105
6168
  async function makeCall({
6106
6169
  url,
6107
6170
  accessToken,
6171
+ authMode,
6108
6172
  opts
6109
6173
  }) {
6110
6174
  let response;
@@ -6113,10 +6177,13 @@ async function makeCall({
6113
6177
  try {
6114
6178
  response = await fetch(url.toString(), {
6115
6179
  headers: {
6116
- Authorization: `Bearer ${accessToken}`,
6180
+ ...buildAuthHeaders({ accessToken, authMode }),
6117
6181
  ...isPost && { "Content-Type": "application/json" },
6118
6182
  ...opts.headers
6119
6183
  },
6184
+ ...getAuthCredentials(authMode) && {
6185
+ credentials: getAuthCredentials(authMode)
6186
+ },
6120
6187
  ...isPost && {
6121
6188
  method: opts?.method,
6122
6189
  body: opts?.body
@@ -6160,9 +6227,8 @@ function executeModel(props) {
6160
6227
  )}`
6161
6228
  );
6162
6229
  const { model, source, params, opts } = props;
6163
- const { type, apiVersion, apiBaseUrl, accessToken, connectionName, clientId } = source;
6230
+ const { type, apiVersion, apiBaseUrl, connectionName, clientId } = source;
6164
6231
  assert2(apiBaseUrl, "executeModel: missing apiBaseUrl");
6165
- assert2(accessToken, "executeModel: missing accessToken");
6166
6232
  assert2(apiVersion === V3, "executeModel: SQL Model API requires CARTO 3+");
6167
6233
  assert2(type !== "tileset", "executeModel: Tilesets not supported");
6168
6234
  let url = `${apiBaseUrl}/v3/sql/${connectionName}/model/${model}`;
@@ -6201,6 +6267,7 @@ function executeModel(props) {
6201
6267
  return makeCall({
6202
6268
  url,
6203
6269
  accessToken: source.accessToken,
6270
+ authMode: source.authMode,
6204
6271
  opts: {
6205
6272
  ...opts,
6206
6273
  method: isGet ? "GET" : "POST",
@@ -6325,6 +6392,7 @@ var WidgetRemoteSource = class extends WidgetSource {
6325
6392
  apiBaseUrl: props.apiBaseUrl,
6326
6393
  clientId: props.clientId,
6327
6394
  accessToken: props.accessToken,
6395
+ authMode: props.authMode,
6328
6396
  connectionName: props.connectionName,
6329
6397
  filters: getApplicableFilters(filterOwner, filters || props.filters),
6330
6398
  filtersLogicalOperator: props.filtersLogicalOperator,
@@ -6654,7 +6722,7 @@ var WidgetRemoteSource = class extends WidgetSource {
6654
6722
  url = `${apiBaseUrl}/${apiVersion}/stats/${connectionName}/${data}/${spatialDataColumn}`;
6655
6723
  }
6656
6724
  const headers = {
6657
- Authorization: `Bearer ${this.props.accessToken}`,
6725
+ ...buildAuthHeaders(this.props),
6658
6726
  ...this.props.headers
6659
6727
  };
6660
6728
  const errorContext = {
@@ -6667,7 +6735,8 @@ var WidgetRemoteSource = class extends WidgetSource {
6667
6735
  headers,
6668
6736
  signal,
6669
6737
  errorContext,
6670
- parameters
6738
+ parameters,
6739
+ credentials: getAuthCredentials(this.props.authMode)
6671
6740
  }).then(({ extent: { xmin, ymin, xmax, ymax } }) => ({
6672
6741
  bbox: [xmin, ymin, xmax, ymax]
6673
6742
  }));
@@ -7376,16 +7445,17 @@ var WidgetTilesetSourceImpl = class extends WidgetSource {
7376
7445
  this._features.length = 0;
7377
7446
  }
7378
7447
  _extractTileFeatures(spatialFilter) {
7448
+ const geometryFilter = spatialFilter && !isSpatialIndexFilter(spatialFilter) ? spatialFilter : void 0;
7379
7449
  const prevInputs = this._tileFeatureExtractPreviousInputs;
7380
- if (this._features.length && spatialFilterEquals(prevInputs.spatialFilter, spatialFilter)) {
7450
+ if (this._features.length && spatialFilterEquals(prevInputs.spatialFilter, geometryFilter)) {
7381
7451
  return;
7382
7452
  }
7383
7453
  this._features = tileFeatures({
7384
7454
  ...assignOptional({}, this.props, this._tileFeatureExtractOptions),
7385
7455
  tiles: this._tiles,
7386
- spatialFilter
7456
+ spatialFilter: geometryFilter
7387
7457
  });
7388
- prevInputs.spatialFilter = spatialFilter;
7458
+ prevInputs.spatialFilter = geometryFilter;
7389
7459
  }
7390
7460
  /**
7391
7461
  * Loads features as GeoJSON (used for testing).
@@ -8409,7 +8479,7 @@ var query = async function(options) {
8409
8479
  }
8410
8480
  const baseUrl = buildQueryUrl({ apiBaseUrl, connectionName });
8411
8481
  const headers = {
8412
- Authorization: `Bearer ${options.accessToken}`,
8482
+ ...buildAuthHeaders(options),
8413
8483
  ...options.headers
8414
8484
  };
8415
8485
  const parameters = {
@@ -8431,7 +8501,8 @@ var query = async function(options) {
8431
8501
  errorContext,
8432
8502
  maxLengthURL,
8433
8503
  localCache,
8434
- signal: options.signal
8504
+ signal: options.signal,
8505
+ credentials: getAuthCredentials(options.authMode)
8435
8506
  });
8436
8507
  };
8437
8508
 
@@ -10761,6 +10832,9 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
10761
10832
  };
10762
10833
  }
10763
10834
  function createLoadOptions(accessToken) {
10835
+ if (!accessToken) {
10836
+ return { loadOptions: { fetch: { credentials: "same-origin" } } };
10837
+ }
10764
10838
  return {
10765
10839
  loadOptions: { fetch: { headers: { Authorization: `Bearer ${accessToken}` } } }
10766
10840
  };
@@ -11350,6 +11424,20 @@ function _getHexagonResolution(viewport, tileSize) {
11350
11424
  Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS)
11351
11425
  );
11352
11426
  }
11427
+ var DYNAMIC_TILES_POINTS_AGGREGATION_LEVEL = 8;
11428
+ var AGG_LEVEL_CORRECTION_BY_TILE_RESOLUTION = {
11429
+ 0.25: -1,
11430
+ 0.5: 0,
11431
+ 1: 1,
11432
+ 2: 2,
11433
+ 4: 3
11434
+ };
11435
+ function getPointsAggregationLevel({
11436
+ tileResolution,
11437
+ zoomLevel
11438
+ }) {
11439
+ return zoomLevel + DYNAMIC_TILES_POINTS_AGGREGATION_LEVEL + AGG_LEVEL_CORRECTION_BY_TILE_RESOLUTION[tileResolution];
11440
+ }
11353
11441
 
11354
11442
  // src/utils/CellSet.ts
11355
11443
  var EMPTY_U32 = 2 ** 32 - 1;
@@ -11445,6 +11533,7 @@ export {
11445
11533
  fillInTileStats as _fillInTileStats,
11446
11534
  _getHexagonResolution,
11447
11535
  getLog10ScaleSteps as _getLog10ScaleSteps,
11536
+ getPointsAggregationLevel as _getPointsAggregationLevel,
11448
11537
  getRasterTileLayerStyleProps as _getRasterTileLayerStyleProps,
11449
11538
  validateVecExprSyntax as _validateVecExprSyntax,
11450
11539
  addFilter,
@@ -11454,6 +11543,7 @@ export {
11454
11543
  applySorting,
11455
11544
  boundaryQuerySource,
11456
11545
  boundaryTableSource,
11546
+ buildAuthHeaders,
11457
11547
  buildBinaryFeatureFilter,
11458
11548
  buildPublicMapUrl,
11459
11549
  buildStatsUrl,
@@ -11472,6 +11562,7 @@ export {
11472
11562
  filterFunctions,
11473
11563
  geojsonFeatures,
11474
11564
  getApplicableFilters,
11565
+ getAuthCredentials,
11475
11566
  getClient,
11476
11567
  getColorAccessor,
11477
11568
  getColumnNameFromGeoColumn,
@@ -11493,6 +11584,7 @@ export {
11493
11584
  h3TilesetSource,
11494
11585
  hasFilter,
11495
11586
  histogram,
11587
+ isSpatialIndexFilter,
11496
11588
  makeIntervalComplete,
11497
11589
  negateAccessor,
11498
11590
  opacityToAlpha,
@@ -11504,6 +11596,7 @@ export {
11504
11596
  rasterSource,
11505
11597
  removeFilter,
11506
11598
  requestWithParameters,
11599
+ rewriteUrlForSessionMode,
11507
11600
  scaleAggregationResLevel,
11508
11601
  scatterPlot,
11509
11602
  setClient,