@carto/api-client 0.5.26 → 0.5.27-alpha.dd7e837.114

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,6 +2,9 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - feat(parseMap): custom aggregation support on spatial-index and geometry-aggregated layers. Adds `compileCustomAggregation(expression, { provider })` helper, `VisualChannelField.accessorKey`, and `{channel}AggregationExp` / `{channel}AggregationDomain` on `VisConfig` for all 6 channels.
6
+ - chore(ci): add prerelease support to release workflow (#274)
7
+
5
8
  ### 0.5.26
6
9
 
7
10
  - fix(widgetSources): add offset request option and total for pagination (#273)
@@ -154,6 +154,7 @@ __export(src_exports, {
154
154
  calculateLayerScale: () => calculateLayerScale,
155
155
  clearDefaultRequestCache: () => clearDefaultRequestCache,
156
156
  clearFilters: () => clearFilters,
157
+ compileCustomAggregation: () => compileCustomAggregation,
157
158
  configureSource: () => configureSource,
158
159
  createColorScale: () => createColorScale,
159
160
  createPolygonSpatialFilter: () => createPolygonSpatialFilter,
@@ -9936,15 +9937,22 @@ function findAccessorKey(keys, properties) {
9936
9937
  }
9937
9938
  return keys;
9938
9939
  }
9939
- function getColorAccessor({ name, colorColumn }, scaleType, { aggregation, range }, opacity, data) {
9940
+ function getColorAccessor({ name, colorColumn, accessorKey }, scaleType, {
9941
+ aggregation,
9942
+ range,
9943
+ domainOverride
9944
+ }, opacity, data) {
9945
+ const effectiveName = accessorKey ?? colorColumn ?? name;
9946
+ const effectiveScaleType = colorColumn && !accessorKey ? "identity" : scaleType;
9940
9947
  const { scale: scale2, domain } = calculateLayerScale(
9941
- colorColumn || name,
9942
- colorColumn ? "identity" : scaleType,
9948
+ effectiveName,
9949
+ effectiveScaleType,
9943
9950
  range,
9944
- data
9951
+ data,
9952
+ domainOverride
9945
9953
  );
9946
9954
  const alpha = opacityToAlpha(opacity);
9947
- let accessorKeys = getAccessorKeys(colorColumn || name, aggregation);
9955
+ let accessorKeys = accessorKey ? [accessorKey] : getAccessorKeys(colorColumn || name, aggregation);
9948
9956
  const accessor = (properties) => {
9949
9957
  if (!(accessorKeys[0] in properties)) {
9950
9958
  accessorKeys = findAccessorKey(accessorKeys, properties);
@@ -9961,11 +9969,11 @@ function getColorAccessor({ name, colorColumn }, scaleType, { aggregation, range
9961
9969
  range: (scale2.range() || []).map(rgbToHex)
9962
9970
  };
9963
9971
  }
9964
- function calculateLayerScale(name, scaleType, range, data) {
9972
+ function calculateLayerScale(name, scaleType, range, data, domainOverride) {
9965
9973
  let scaleDomain;
9966
9974
  let scaleColors = [];
9967
9975
  const { colors } = range;
9968
- const domain = calculateDomain(data, name, scaleType, colors.length);
9976
+ const domain = domainOverride && !range.colorMap ? domainOverride : calculateDomain(data, name, scaleType, colors.length);
9969
9977
  if (scaleType !== "identity") {
9970
9978
  if (range.colorMap) {
9971
9979
  const { colorMap } = range;
@@ -10050,19 +10058,20 @@ function negateAccessor(accessor) {
10050
10058
  }
10051
10059
  return -accessor;
10052
10060
  }
10053
- function getSizeAccessor({ name }, scaleType, aggregation, range, data) {
10061
+ function getSizeAccessor({ name, accessorKey }, scaleType, aggregation, range, data, domainOverride) {
10054
10062
  const scale2 = scaleType ? SCALE_FUNCS[scaleType]() : identity2;
10055
10063
  let domain = [];
10056
10064
  if (scaleType && range) {
10057
10065
  if (aggregation !== AggregationTypes.Count) {
10058
- domain = calculateDomain(data, name, scaleType);
10066
+ const source = accessorKey ?? name;
10067
+ domain = domainOverride ?? calculateDomain(data, source, scaleType);
10059
10068
  scale2.domain(domain);
10060
10069
  } else {
10061
10070
  domain = scale2.domain();
10062
10071
  }
10063
10072
  scale2.range(range);
10064
10073
  }
10065
- let accessorKeys = getAccessorKeys(name, aggregation);
10074
+ let accessorKeys = accessorKey ? [accessorKey] : getAccessorKeys(name, aggregation);
10066
10075
  const accessor = (properties) => {
10067
10076
  if (!(accessorKeys[0] in properties)) {
10068
10077
  accessorKeys = findAccessorKey(accessorKeys, properties);
@@ -10109,9 +10118,30 @@ function getDefaultAggregationExpColumnAliasForLayerType(layerType, provider, sc
10109
10118
  return DEFAULT_AGGREGATION_EXP_ALIAS;
10110
10119
  }
10111
10120
  }
10121
+ function hashString(input) {
10122
+ let h = 2166136261;
10123
+ for (let i = 0; i < input.length; i++) {
10124
+ h ^= input.charCodeAt(i);
10125
+ h = Math.imul(h, 16777619);
10126
+ }
10127
+ return (h >>> 0).toString(16).padStart(8, "0");
10128
+ }
10129
+ function normalizeExpression(exp) {
10130
+ return exp.trim().replace(/\s+/g, " ");
10131
+ }
10132
+ function applyProviderCase(alias, provider) {
10133
+ return provider === "snowflake" ? alias.toUpperCase() : alias;
10134
+ }
10112
10135
  function getColumnAliasForAggregationExp(name, aggregation, provider) {
10113
- const columnAlias = `${name}_${aggregation}`;
10114
- return provider === "snowflake" ? columnAlias.toUpperCase() : columnAlias;
10136
+ return applyProviderCase(`${name}_${aggregation}`, provider);
10137
+ }
10138
+ function compileCustomAggregation(exp, opts) {
10139
+ const normalized = normalizeExpression(exp);
10140
+ if (!normalized) {
10141
+ throw new Error("Custom aggregation expression must not be empty");
10142
+ }
10143
+ const hash2 = hashString(normalized);
10144
+ return applyProviderCase("custom_agg_" + hash2, opts.provider);
10115
10145
  }
10116
10146
  function getDefaultColumnFromSchemaForAggregationExp(schema) {
10117
10147
  return schema ? schema[0].name : "";
@@ -10639,6 +10669,26 @@ function createStyleProps(config2, mapping) {
10639
10669
  result.highlightColor = config2.visConfig.enable3d ? [255, 255, 255, 60] : [252, 242, 26, 255];
10640
10670
  return result;
10641
10671
  }
10672
+ function resolveCustomAggregation({
10673
+ field,
10674
+ aggregation,
10675
+ expression,
10676
+ domain,
10677
+ providerId
10678
+ }) {
10679
+ if (aggregation !== "custom") {
10680
+ return { field, aggregation, domainOverride: void 0 };
10681
+ }
10682
+ if (!field || !expression?.trim()) {
10683
+ return { field, aggregation: void 0, domainOverride: void 0 };
10684
+ }
10685
+ const alias = compileCustomAggregation(expression, { provider: providerId });
10686
+ return {
10687
+ field: { ...field, accessorKey: alias },
10688
+ aggregation: void 0,
10689
+ domainOverride: domain
10690
+ };
10691
+ }
10642
10692
  function createChannelProps(id, layerType, config2, visualChannels, data, dataset) {
10643
10693
  if (layerType === "raster") {
10644
10694
  const rasterMetadata = data.raster_metadata;
@@ -10687,18 +10737,25 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
10687
10737
  const scales = {};
10688
10738
  {
10689
10739
  const { colorField, colorScale } = visualChannels;
10690
- const { colorRange, colorAggregation } = visConfig;
10691
- if (colorField && colorScale && colorRange) {
10740
+ const { colorRange } = visConfig;
10741
+ const { field, aggregation, domainOverride } = resolveCustomAggregation({
10742
+ field: colorField,
10743
+ aggregation: visConfig.colorAggregation,
10744
+ expression: visConfig.colorAggregationExp,
10745
+ domain: visConfig.colorAggregationDomain,
10746
+ providerId: dataset.providerId
10747
+ });
10748
+ if (field && colorScale && colorRange) {
10692
10749
  const { accessor, ...scaleProps } = getColorAccessor(
10693
- colorField,
10750
+ field,
10694
10751
  colorScale,
10695
- { aggregation: colorAggregation, range: colorRange },
10752
+ { aggregation, range: colorRange, domainOverride },
10696
10753
  visConfig.opacity,
10697
10754
  data
10698
10755
  );
10699
10756
  result.getFillColor = accessor;
10700
10757
  scales.fillColor = updateTriggers.getFillColor = {
10701
- field: colorField,
10758
+ field,
10702
10759
  type: colorScale,
10703
10760
  ...scaleProps
10704
10761
  };
@@ -10758,40 +10815,54 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
10758
10815
  };
10759
10816
  }
10760
10817
  {
10761
- const radiusRange = visConfig.radiusRange;
10762
10818
  const { radiusField, radiusScale } = visualChannels;
10763
- if (radiusField && radiusRange && radiusScale) {
10819
+ const { radiusRange } = visConfig;
10820
+ const { field, aggregation, domainOverride } = resolveCustomAggregation({
10821
+ field: radiusField,
10822
+ aggregation: visConfig.radiusAggregation,
10823
+ expression: visConfig.radiusAggregationExp,
10824
+ domain: visConfig.radiusAggregationDomain,
10825
+ providerId: dataset.providerId
10826
+ });
10827
+ if (field && radiusRange && radiusScale) {
10764
10828
  const { accessor, ...scaleProps } = getSizeAccessor(
10765
- radiusField,
10829
+ field,
10766
10830
  radiusScale,
10767
- visConfig.radiusAggregation,
10831
+ aggregation,
10768
10832
  radiusRange,
10769
- data
10833
+ data,
10834
+ domainOverride
10770
10835
  );
10771
10836
  result.getPointRadius = accessor;
10772
10837
  scales.pointRadius = updateTriggers.getPointRadius = {
10773
- field: radiusField,
10838
+ field,
10774
10839
  type: radiusScale,
10775
10840
  ...scaleProps
10776
10841
  };
10777
10842
  }
10778
10843
  }
10779
10844
  {
10780
- const strokeColorRange = visConfig.strokeColorRange;
10781
10845
  const { strokeColorScale, strokeColorField } = visualChannels;
10782
- if (strokeColorField && strokeColorRange && strokeColorScale) {
10783
- const { strokeColorAggregation: aggregation } = visConfig;
10846
+ const { strokeColorRange } = visConfig;
10847
+ const { field, aggregation, domainOverride } = resolveCustomAggregation({
10848
+ field: strokeColorField,
10849
+ aggregation: visConfig.strokeColorAggregation,
10850
+ expression: visConfig.strokeColorAggregationExp,
10851
+ domain: visConfig.strokeColorAggregationDomain,
10852
+ providerId: dataset.providerId
10853
+ });
10854
+ if (field && strokeColorRange && strokeColorScale) {
10784
10855
  const opacity = visConfig.strokeOpacity !== void 0 ? visConfig.strokeOpacity : 1;
10785
10856
  const { accessor, ...scaleProps } = getColorAccessor(
10786
- strokeColorField,
10857
+ field,
10787
10858
  strokeColorScale,
10788
- { aggregation, range: strokeColorRange },
10859
+ { aggregation, range: strokeColorRange, domainOverride },
10789
10860
  opacity,
10790
10861
  data
10791
10862
  );
10792
10863
  result.getLineColor = accessor;
10793
10864
  scales.lineColor = updateTriggers.getLineColor = {
10794
- field: strokeColorField,
10865
+ field,
10795
10866
  type: strokeColorScale,
10796
10867
  ...scaleProps
10797
10868
  };
@@ -10799,37 +10870,53 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
10799
10870
  }
10800
10871
  {
10801
10872
  const { sizeField: strokeWidthField, sizeScale: strokeWidthScale } = visualChannels;
10802
- const { sizeRange, sizeAggregation } = visConfig;
10803
- if (strokeWidthField && sizeRange) {
10873
+ const { sizeRange } = visConfig;
10874
+ const { field, aggregation, domainOverride } = resolveCustomAggregation({
10875
+ field: strokeWidthField,
10876
+ aggregation: visConfig.sizeAggregation,
10877
+ expression: visConfig.sizeAggregationExp,
10878
+ domain: visConfig.sizeAggregationDomain,
10879
+ providerId: dataset.providerId
10880
+ });
10881
+ if (field && sizeRange) {
10804
10882
  const { accessor, ...scaleProps } = getSizeAccessor(
10805
- strokeWidthField,
10883
+ field,
10806
10884
  strokeWidthScale,
10807
- sizeAggregation,
10885
+ aggregation,
10808
10886
  sizeRange,
10809
- data
10887
+ data,
10888
+ domainOverride
10810
10889
  );
10811
10890
  result.getLineWidth = accessor;
10812
10891
  scales.lineWidth = updateTriggers.getLineWidth = {
10813
- field: strokeWidthField,
10892
+ field,
10814
10893
  type: strokeWidthScale || "identity",
10815
10894
  ...scaleProps
10816
10895
  };
10817
10896
  }
10818
10897
  }
10819
10898
  {
10820
- const { enable3d, heightRange } = visConfig;
10821
10899
  const { heightField, heightScale } = visualChannels;
10822
- if (heightField && heightRange && enable3d) {
10900
+ const { enable3d, heightRange } = visConfig;
10901
+ const { field, aggregation, domainOverride } = resolveCustomAggregation({
10902
+ field: heightField,
10903
+ aggregation: visConfig.heightAggregation,
10904
+ expression: visConfig.heightAggregationExp,
10905
+ domain: visConfig.heightAggregationDomain,
10906
+ providerId: dataset.providerId
10907
+ });
10908
+ if (field && heightRange && enable3d) {
10823
10909
  const { accessor, ...scaleProps } = getSizeAccessor(
10824
- heightField,
10910
+ field,
10825
10911
  heightScale,
10826
- visConfig.heightAggregation,
10912
+ aggregation,
10827
10913
  heightRange,
10828
- data
10914
+ data,
10915
+ domainOverride
10829
10916
  );
10830
10917
  result.getElevation = accessor;
10831
10918
  scales.elevation = updateTriggers.getElevation = {
10832
- field: heightField,
10919
+ field,
10833
10920
  type: heightScale || "identity",
10834
10921
  ...scaleProps
10835
10922
  };
@@ -10837,18 +10924,25 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
10837
10924
  }
10838
10925
  {
10839
10926
  const { weightField } = visualChannels;
10840
- const { weightAggregation } = visConfig;
10841
- if (weightField && weightAggregation) {
10927
+ const { field, aggregation, domainOverride } = resolveCustomAggregation({
10928
+ field: weightField,
10929
+ aggregation: visConfig.weightAggregation,
10930
+ expression: visConfig.weightAggregationExp,
10931
+ domain: visConfig.weightAggregationDomain,
10932
+ providerId: dataset.providerId
10933
+ });
10934
+ if (field && (aggregation || visConfig.weightAggregation === "custom")) {
10842
10935
  const { accessor, ...scaleProps } = getSizeAccessor(
10843
- weightField,
10936
+ field,
10844
10937
  void 0,
10845
- weightAggregation,
10938
+ aggregation,
10846
10939
  void 0,
10847
- data
10940
+ data,
10941
+ domainOverride
10848
10942
  );
10849
10943
  result.getWeight = accessor;
10850
10944
  scales.weight = updateTriggers.getWeight = {
10851
- field: weightField,
10945
+ field,
10852
10946
  type: "identity",
10853
10947
  ...scaleProps
10854
10948
  };
@@ -11653,6 +11747,7 @@ function hashBuckets(initialCount) {
11653
11747
  calculateLayerScale,
11654
11748
  clearDefaultRequestCache,
11655
11749
  clearFilters,
11750
+ compileCustomAggregation,
11656
11751
  configureSource,
11657
11752
  createColorScale,
11658
11753
  createPolygonSpatialFilter,