@mapbox/mapbox-gl-style-spec 14.5.2 → 14.6.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.
@@ -34,9 +34,8 @@ class Assertion implements Expression {
34
34
  this.args = args;
35
35
  }
36
36
 
37
- static parse(args: ReadonlyArray<unknown>, context: ParsingContext): Expression | null | undefined {
37
+ static parse(args: ReadonlyArray<unknown>, context: ParsingContext): Expression | void {
38
38
  if (args.length < 2)
39
- // @ts-expect-error - TS2322 - Type 'void' is not assignable to type 'Expression'.
40
39
  return context.error(`Expected at least one argument.`);
41
40
 
42
41
  let i = 1;
@@ -48,7 +47,6 @@ class Assertion implements Expression {
48
47
  if (args.length > 2) {
49
48
  const type = args[1];
50
49
  if (typeof type !== 'string' || !(type in types) || type === 'object')
51
- // @ts-expect-error - TS2322 - Type 'void' is not assignable to type 'Expression'.
52
50
  return context.error('The item type argument of "array" must be one of string, number, boolean', 1);
53
51
  itemType = types[type];
54
52
  i++;
@@ -63,7 +61,6 @@ class Assertion implements Expression {
63
61
  args[2] < 0 ||
64
62
  args[2] !== Math.floor(args[2]))
65
63
  ) {
66
- // @ts-expect-error - TS2322 - Type 'void' is not assignable to type 'Expression'.
67
64
  return context.error('The length argument to "array" must be a positive integer literal', 2);
68
65
  }
69
66
  N = (args[2] as number);
@@ -93,7 +90,7 @@ class Assertion implements Expression {
93
90
  if (!error) {
94
91
  return value;
95
92
  } else if (i === this.args.length - 1) {
96
- throw new RuntimeError(`Expected value to be of type ${toString(this.type)}, but found ${toString(typeOf(value))} instead.`);
93
+ throw new RuntimeError(`The expression ${JSON.stringify(this.args[i].serialize())} evaluated to ${toString(typeOf(value))} but was expected to be of type ${toString(this.type)}.`);
97
94
  }
98
95
  }
99
96
 
@@ -133,7 +133,7 @@ export class StyleExpression {
133
133
  if (!this._warningHistory[e.message]) {
134
134
  this._warningHistory[e.message] = true;
135
135
  if (typeof console !== 'undefined') {
136
- console.warn(e.message);
136
+ console.warn(`Failed to evaluate expression "${JSON.stringify(this.expression.serialize())}". ${e.message}`);
137
137
  }
138
138
  }
139
139
  return this._defaultValue;
@@ -178,7 +178,7 @@ export function createExpression(
178
178
  export class ZoomConstantExpression<Kind extends EvaluationKind> {
179
179
  kind: Kind;
180
180
  isStateDependent: boolean;
181
- isConfigDependent: boolean;
181
+ configDependencies: Set<string>;
182
182
  _styleExpression: StyleExpression;
183
183
  isLightConstant: boolean | null | undefined;
184
184
 
@@ -187,7 +187,7 @@ export class ZoomConstantExpression<Kind extends EvaluationKind> {
187
187
  this._styleExpression = expression;
188
188
  this.isLightConstant = isLightConstant;
189
189
  this.isStateDependent = kind !== ('constant' as EvaluationKind) && !isConstant.isStateConstant(expression.expression);
190
- this.isConfigDependent = !isConstant.isConfigConstant(expression.expression);
190
+ this.configDependencies = isConstant.getConfigDependencies(expression.expression);
191
191
  }
192
192
 
193
193
  evaluateWithoutErrorHandling(
@@ -218,7 +218,7 @@ export class ZoomDependentExpression<Kind extends EvaluationKind> {
218
218
  zoomStops: Array<number>;
219
219
  isStateDependent: boolean;
220
220
  isLightConstant: boolean | null | undefined;
221
- isConfigDependent: boolean;
221
+ configDependencies: Set<string>;
222
222
 
223
223
  _styleExpression: StyleExpression;
224
224
  interpolationType: InterpolationType | null | undefined;
@@ -229,7 +229,7 @@ export class ZoomDependentExpression<Kind extends EvaluationKind> {
229
229
  this._styleExpression = expression;
230
230
  this.isStateDependent = kind !== ('camera' as EvaluationKind) && !isConstant.isStateConstant(expression.expression);
231
231
  this.isLightConstant = isLightConstant;
232
- this.isConfigDependent = !isConstant.isConfigConstant(expression.expression);
232
+ this.configDependencies = isConstant.getConfigDependencies(expression.expression);
233
233
  this.interpolationType = interpolationType;
234
234
  }
235
235
 
@@ -266,7 +266,7 @@ export class ZoomDependentExpression<Kind extends EvaluationKind> {
266
266
 
267
267
  export type ConstantExpression = {
268
268
  kind: 'constant';
269
- isConfigDependent: boolean;
269
+ configDependencies: Set<string>;
270
270
  readonly evaluate: (
271
271
  globals: GlobalProperties,
272
272
  feature?: Feature,
@@ -280,7 +280,7 @@ export type SourceExpression = {
280
280
  kind: 'source';
281
281
  isStateDependent: boolean;
282
282
  isLightConstant: boolean | null | undefined;
283
- isConfigDependent: boolean;
283
+ configDependencies: Set<string>;
284
284
  readonly evaluate: (
285
285
  globals: GlobalProperties,
286
286
  feature?: Feature,
@@ -294,7 +294,7 @@ export type SourceExpression = {
294
294
  export type CameraExpression = {
295
295
  kind: 'camera';
296
296
  isStateDependent: boolean;
297
- isConfigDependent: boolean;
297
+ configDependencies: Set<string>;
298
298
  readonly evaluate: (
299
299
  globals: GlobalProperties,
300
300
  feature?: Feature,
@@ -311,7 +311,7 @@ export interface CompositeExpression {
311
311
  kind: 'composite';
312
312
  isStateDependent: boolean;
313
313
  isLightConstant: boolean | null | undefined;
314
- isConfigDependent: boolean;
314
+ configDependencies: Set<string>;
315
315
  readonly evaluate: (
316
316
  globals: GlobalProperties,
317
317
  feature?: Feature,
@@ -449,7 +449,7 @@ export function normalizePropertyExpression<T>(
449
449
  }
450
450
  return {
451
451
  kind: 'constant',
452
- isConfigDependent: false,
452
+ configDependencies: new Set(),
453
453
  evaluate: () => constant
454
454
  };
455
455
  }
@@ -51,14 +51,15 @@ function isStateConstant(e: Expression): boolean {
51
51
  return result;
52
52
  }
53
53
 
54
- function isConfigConstant(e: Expression): boolean {
54
+ function getConfigDependencies(e: Expression): Set<string> {
55
55
  if (e instanceof Config) {
56
- return false;
56
+ const singleConfig = new Set([e.key]);
57
+ return singleConfig;
57
58
  }
58
59
 
59
- let result = true;
60
+ let result = new Set<string>();
60
61
  e.eachChild(arg => {
61
- if (result && !isConfigConstant(arg)) { result = false; }
62
+ result = new Set([...result, ...getConfigDependencies(arg)]);
62
63
  });
63
64
  return result;
64
65
  }
@@ -72,4 +73,4 @@ function isGlobalPropertyConstant(e: Expression, properties: Array<string>): boo
72
73
  return result;
73
74
  }
74
75
 
75
- export {isFeatureConstant, isGlobalPropertyConstant, isStateConstant, isConfigConstant};
76
+ export {isFeatureConstant, isGlobalPropertyConstant, isStateConstant, getConfigDependencies};
@@ -91,18 +91,18 @@ function _convertFilter(filter: FilterSpecification, expectedTypes: ExpectedType
91
91
  });
92
92
  return ['any'].concat(children);
93
93
  } else if (op === 'all') {
94
- const children = (filter as any).slice(1).map(f => _convertFilter(f, expectedTypes));
94
+ const children: any[] = (filter).slice(1).map(f => _convertFilter(f, expectedTypes));
95
95
  return children.length > 1 ? ['all'].concat(children) : [].concat(...children);
96
96
  } else if (op === 'none') {
97
- return ['!', _convertFilter(['any'].concat((filter as any).slice(1)), {})];
97
+ return ['!', _convertFilter(['any'].concat((filter).slice(1)), {})];
98
98
  } else if (op === 'in') {
99
- converted = convertInOp((filter[1] as any), filter.slice(2));
99
+ converted = convertInOp((filter[1]), filter.slice(2));
100
100
  } else if (op === '!in') {
101
- converted = convertInOp((filter[1] as any), filter.slice(2), true);
101
+ converted = convertInOp((filter[1]), filter.slice(2), true);
102
102
  } else if (op === 'has') {
103
- converted = convertHasOp((filter[1] as any));
103
+ converted = convertHasOp((filter[1]));
104
104
  } else if (op === '!has') {
105
- converted = ['!', convertHasOp((filter[1] as any))];
105
+ converted = ['!', convertHasOp((filter[1]))];
106
106
  } else {
107
107
  converted = true;
108
108
  }
@@ -164,7 +164,7 @@ function convertComparisonOp(property: string, value: any, op: string, expectedT
164
164
  function convertInOp(property: string, values: Array<any>, negate: boolean = false) {
165
165
  if (values.length === 0) return negate;
166
166
 
167
- let get;
167
+ let get: string[];
168
168
  if (property === '$type') {
169
169
  get = ['geometry-type'];
170
170
  } else if (property === '$id') {
@@ -192,9 +192,8 @@ function convertInOp(property: string, values: Array<any>, negate: boolean = fal
192
192
  return ['match', get, uniqueValues, !negate, negate];
193
193
  }
194
194
 
195
- return [ negate ? 'all' : 'any' ].concat(
196
- // @ts-expect-error - TS2769 - No overload matches this call.
197
- values.map(v => [negate ? '!=' : '==', get, v])
195
+ return [negate ? 'all' : 'any'].concat(
196
+ values.map(v => [negate ? '!=' : '==', get, v]) as any[]
198
197
  );
199
198
  }
200
199
 
@@ -82,7 +82,7 @@ function isExpressionFilter(filter: unknown): boolean {
82
82
  * @param {string} layerType the type of the layer this filter will be applied to.
83
83
  * @returns {Function} filter-evaluating function
84
84
  */
85
- function createFilter(filter?: FilterSpecification | ExpressionSpecification, layerType: string = 'fill'): FeatureFilter {
85
+ function createFilter(filter?: FilterSpecification, layerType: string = 'fill'): FeatureFilter {
86
86
  if (filter === null || filter === undefined) {
87
87
  return {filter: () => true, needGeometry: false, needFeature: false};
88
88
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapbox/mapbox-gl-style-spec",
3
- "version": "14.5.2",
3
+ "version": "14.6.0",
4
4
  "description": "a specification for mapbox gl styles",
5
5
  "author": "Mapbox",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
package/reference/v8.json CHANGED
@@ -1485,6 +1485,24 @@
1485
1485
  },
1486
1486
  "property-type": "data-constant",
1487
1487
  "experimental": true
1488
+ },
1489
+ "clip-layer-scope": {
1490
+ "type": "array",
1491
+ "value": "string",
1492
+ "default": [],
1493
+ "doc": "Removes content from layers with the specified scope. By default all layers are affected. For example specifying `basemap` will only remove content from the Mapbox Standard style layers which have the same scope",
1494
+ "sdk-support": {
1495
+ "basic functionality": {
1496
+ "js": "3.6.0",
1497
+ "android": "11.7.0",
1498
+ "ios": "11.7.0"
1499
+ }
1500
+ },
1501
+ "expression": {
1502
+ "interpolated": false
1503
+ },
1504
+ "property-type": "data-constant",
1505
+ "experimental": true
1488
1506
  }
1489
1507
  },
1490
1508
  "layout_fill": {
@@ -5968,7 +5986,58 @@
5968
5986
  ]
5969
5987
  },
5970
5988
  "property-type": "data-constant"
5971
- }
5989
+ },
5990
+ "fill-extrusion-line-width": {
5991
+ "type": "number",
5992
+ "default": 0,
5993
+ "minimum": 0,
5994
+ "transition": true,
5995
+ "units": "meters",
5996
+ "doc": "If a non-zero value is provided, it sets the fill-extrusion layer into wall rendering mode. The value is used to render the feature with the given width over the outlines of the geometry. Note: This property is experimental and some other fill-extrusion properties might not be supported with non-zero line width.",
5997
+ "sdk-support": {
5998
+ "basic functionality": {
5999
+ "js": "3.7.0"
6000
+ },
6001
+ "data-driven styling": {
6002
+ "js": "3.7.0"
6003
+ }
6004
+ },
6005
+ "expression": {
6006
+ "interpolated": true,
6007
+ "parameters": [
6008
+ "zoom",
6009
+ "feature",
6010
+ "feature-state",
6011
+ "measure-light"
6012
+ ]
6013
+ },
6014
+ "property-type": "data-driven"
6015
+ },
6016
+ "fill-extrusion-line-alignment": {
6017
+ "type": "enum",
6018
+ "values": {
6019
+ "inside": {
6020
+ "doc": "Aligns the wall inside of the outline."
6021
+ },
6022
+ "outside": {
6023
+ "doc": "Aligns the wall outside of the outline."
6024
+ },
6025
+ "center": {
6026
+ "doc": "Aligns the wall relative to the center of the outline."
6027
+ }
6028
+ },
6029
+ "default": "center",
6030
+ "doc": "Specifies the alignment for offset of the walls relative to the outlines of the geometry. For open-ended line string geometries the positioning is considered based on the ordering of the points, where inside is in clockwise order and outside is counter-clockwise. This property only has an effect if a non-zero fill-extrusion-line-width is used. Center alignment is automatically used for non-closed lines.",
6031
+ "requires": [
6032
+ "fill-extrusion-line-width"
6033
+ ],
6034
+ "sdk-support": {
6035
+ "basic functionality": {
6036
+ "js": "3.7.0"
6037
+ }
6038
+ },
6039
+ "property-type": "data-constant"
6040
+ }
5972
6041
  },
5973
6042
  "paint_line": {
5974
6043
  "line-opacity": {
@@ -6493,7 +6562,6 @@
6493
6562
  "default": 0,
6494
6563
  "minimum": 0,
6495
6564
  "maximum": 1,
6496
- "experimental": true,
6497
6565
  "doc": "Opacity multiplier (multiplies line-opacity value) of the line part that is occluded by 3D objects. Value 0 hides occluded part, value 1 means the same opacity as non-occluded part. The property is not supported when `line-opacity` has data-driven styling.",
6498
6566
  "sdk-support": {
6499
6567
  "basic functionality": {
@@ -6574,7 +6642,7 @@
6574
6642
  "circle-blur": {
6575
6643
  "type": "number",
6576
6644
  "default": 0,
6577
- "doc": "Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.",
6645
+ "doc": "Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity. Setting a negative value renders the blur as an inner glow effect.",
6578
6646
  "transition": true,
6579
6647
  "sdk-support": {
6580
6648
  "basic functionality": {
@@ -7034,11 +7102,11 @@
7034
7102
  "property-type": "data-driven"
7035
7103
  },
7036
7104
  "icon-occlusion-opacity": {
7037
- "doc": "The opacity at which the icon will be drawn in case of being depth occluded. Not supported on globe zoom levels. Absent value means behavior prior to this property introduction.",
7105
+ "doc": "The opacity at which the icon will be drawn in case of being depth occluded. Absent value means full occlusion against terrain only.",
7038
7106
  "type": "number",
7039
7107
  "minimum": 0,
7040
7108
  "maximum": 1,
7041
- "default": 1,
7109
+ "default": 0,
7042
7110
  "transition": true,
7043
7111
  "requires": [
7044
7112
  "icon-image"
@@ -7384,10 +7452,10 @@
7384
7452
  },
7385
7453
  "text-occlusion-opacity": {
7386
7454
  "type": "number",
7387
- "doc": "The opacity at which the text will be drawn in case of being depth occluded. Not supported on globe zoom levels. Absent value means behavior prior to this property introduction.",
7455
+ "doc": "The opacity at which the text will be drawn in case of being depth occluded. Absent value means full occlusion against terrain only.",
7388
7456
  "minimum": 0,
7389
7457
  "maximum": 1,
7390
- "default": 1,
7458
+ "default": 0,
7391
7459
  "transition": true,
7392
7460
  "requires": [
7393
7461
  "text-field"
@@ -8142,6 +8210,27 @@
8142
8210
  }
8143
8211
  },
8144
8212
  "property-type": "data-constant"
8213
+ },
8214
+ "raster-particle-elevation": {
8215
+ "type": "number",
8216
+ "doc": "Specifies an uniform elevation from the ground, in meters.",
8217
+ "default": 0,
8218
+ "minimum": 0,
8219
+ "transition": true,
8220
+ "sdk-support": {
8221
+ "basic functionality": {
8222
+ "js": "3.7.0",
8223
+ "android": "11.7.0",
8224
+ "ios": "11.7.0"
8225
+ }
8226
+ },
8227
+ "expression": {
8228
+ "interpolated": true,
8229
+ "parameters": [
8230
+ "zoom"
8231
+ ]
8232
+ },
8233
+ "property-type": "data-constant"
8145
8234
  }
8146
8235
  },
8147
8236
  "paint_hillshade": {
@@ -8809,9 +8898,6 @@
8809
8898
  "default": true,
8810
8899
  "doc": "Enable/Disable shadow casting for this layer",
8811
8900
  "transition": false,
8812
- "expression": {
8813
- "interpolated": false
8814
- },
8815
8901
  "sdk-support": {
8816
8902
  "basic functionality": {
8817
8903
  "js": "3.0.0",
@@ -8826,9 +8912,6 @@
8826
8912
  "default": true,
8827
8913
  "doc": "Enable/Disable shadow receiving for this layer",
8828
8914
  "transition": false,
8829
- "expression": {
8830
- "interpolated": false
8831
- },
8832
8915
  "sdk-support": {
8833
8916
  "basic functionality": {
8834
8917
  "js": "3.0.0",
package/types.ts CHANGED
@@ -10,6 +10,7 @@ export type ResolvedImageSpecification = string;
10
10
  export type PromoteIdSpecification = {[_: string]: string} | string;
11
11
 
12
12
  export type FilterSpecification =
13
+ | ExpressionSpecification
13
14
  | ['has', string]
14
15
  | ['!has', string]
15
16
  | ['==', string, string | number | boolean]
@@ -70,7 +71,8 @@ export type DataDrivenPropertyValueSpecification<T> =
70
71
  | CameraFunctionSpecification<T>
71
72
  | SourceFunctionSpecification<T>
72
73
  | CompositeFunctionSpecification<T>
73
- | ExpressionSpecification;
74
+ | ExpressionSpecification
75
+ | (T extends Array<infer U> ? Array<U | ExpressionSpecification> : never);
74
76
 
75
77
  export type StyleSpecification = {
76
78
  "version": 8,
@@ -698,7 +700,10 @@ export type FillExtrusionLayerSpecification = {
698
700
  "fill-extrusion-rounded-roof"?: PropertyValueSpecification<boolean>,
699
701
  "fill-extrusion-cutoff-fade-range"?: ExpressionSpecification,
700
702
  "fill-extrusion-emissive-strength"?: PropertyValueSpecification<number>,
701
- "fill-extrusion-emissive-strength-transition"?: TransitionSpecification
703
+ "fill-extrusion-emissive-strength-transition"?: TransitionSpecification,
704
+ "fill-extrusion-line-width"?: DataDrivenPropertyValueSpecification<number>,
705
+ "fill-extrusion-line-width-transition"?: TransitionSpecification,
706
+ "fill-extrusion-line-alignment"?: "inside" | "outside" | "center"
702
707
  }
703
708
  }
704
709
 
@@ -788,7 +793,9 @@ export type RasterParticleLayerSpecification = {
788
793
  "raster-particle-speed-factor-transition"?: TransitionSpecification,
789
794
  "raster-particle-fade-opacity-factor"?: PropertyValueSpecification<number>,
790
795
  "raster-particle-fade-opacity-factor-transition"?: TransitionSpecification,
791
- "raster-particle-reset-rate-factor"?: number
796
+ "raster-particle-reset-rate-factor"?: number,
797
+ "raster-particle-elevation"?: PropertyValueSpecification<number>,
798
+ "raster-particle-elevation-transition"?: TransitionSpecification
792
799
  }
793
800
  }
794
801
 
@@ -869,8 +876,8 @@ export type ModelLayerSpecification = {
869
876
  "model-color-mix-intensity"?: DataDrivenPropertyValueSpecification<number>,
870
877
  "model-color-mix-intensity-transition"?: TransitionSpecification,
871
878
  "model-type"?: "common-3d" | "location-indicator",
872
- "model-cast-shadows"?: ExpressionSpecification,
873
- "model-receive-shadows"?: ExpressionSpecification,
879
+ "model-cast-shadows"?: boolean,
880
+ "model-receive-shadows"?: boolean,
874
881
  "model-ambient-occlusion-intensity"?: PropertyValueSpecification<number>,
875
882
  "model-ambient-occlusion-intensity-transition"?: TransitionSpecification,
876
883
  "model-emissive-strength"?: DataDrivenPropertyValueSpecification<number>,
@@ -993,7 +1000,11 @@ export type ClipLayerSpecification = {
993
1000
  /**
994
1001
  * @experimental This property is experimental and subject to change in future versions.
995
1002
  */
996
- "clip-layer-types"?: ExpressionSpecification
1003
+ "clip-layer-types"?: ExpressionSpecification,
1004
+ /**
1005
+ * @experimental This property is experimental and subject to change in future versions.
1006
+ */
1007
+ "clip-layer-scope"?: ExpressionSpecification
997
1008
  },
998
1009
  "paint"?: never
999
1010
  }