@mapbox/mapbox-gl-style-spec 13.24.0-alpha.6 → 13.25.0-beta.1

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.
Files changed (74) hide show
  1. package/.eslintrc +10 -0
  2. package/CHANGELOG.md +23 -4
  3. package/bin/gl-style-composite.js +6 -2
  4. package/bin/gl-style-format.js +6 -2
  5. package/bin/gl-style-migrate.js +6 -2
  6. package/bin/gl-style-validate.js +5 -1
  7. package/dist/index.cjs +435 -225
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.es.js +427 -217
  10. package/dist/index.es.js.map +1 -1
  11. package/expression/compound_expression.js +2 -2
  12. package/expression/definitions/assertion.js +3 -3
  13. package/expression/definitions/at.js +5 -5
  14. package/expression/definitions/case.js +4 -4
  15. package/expression/definitions/coalesce.js +4 -4
  16. package/expression/definitions/coercion.js +3 -3
  17. package/expression/definitions/collator.js +4 -4
  18. package/expression/definitions/comparison.js +22 -22
  19. package/expression/definitions/format.js +4 -4
  20. package/expression/definitions/image.js +4 -4
  21. package/expression/definitions/in.js +5 -5
  22. package/expression/definitions/index_of.js +5 -5
  23. package/expression/definitions/interpolate.js +6 -5
  24. package/expression/definitions/length.js +5 -5
  25. package/expression/definitions/let.js +5 -5
  26. package/expression/definitions/literal.js +5 -5
  27. package/expression/definitions/match.js +4 -4
  28. package/expression/definitions/number_format.js +4 -4
  29. package/expression/definitions/slice.js +5 -5
  30. package/expression/definitions/step.js +4 -4
  31. package/expression/definitions/var.js +4 -4
  32. package/expression/definitions/within.js +16 -8
  33. package/expression/evaluation_context.js +8 -8
  34. package/expression/expression.js +1 -1
  35. package/expression/index.js +5 -5
  36. package/expression/is_constant.js +3 -3
  37. package/expression/parsing_context.js +1 -1
  38. package/expression/runtime_error.js +1 -1
  39. package/expression/scope.js +1 -1
  40. package/expression/stops.js +1 -1
  41. package/expression/values.js +1 -1
  42. package/feature_filter/index.js +1 -1
  43. package/flow-typed/gl-matrix.js +8 -1
  44. package/function/convert.js +4 -4
  45. package/migrate/expressions.js +1 -1
  46. package/package.json +1 -1
  47. package/reference/latest.js +4 -0
  48. package/reference/v8.json +144 -7
  49. package/types.js +6 -2
  50. package/util/color.js +35 -0
  51. package/validate/validate.js +13 -1
  52. package/validate/validate_array.js +10 -2
  53. package/validate/validate_boolean.js +4 -1
  54. package/validate/validate_color.js +4 -1
  55. package/validate/validate_enum.js +4 -1
  56. package/validate/validate_expression.js +5 -2
  57. package/validate/validate_filter.js +12 -4
  58. package/validate/validate_fog.js +4 -1
  59. package/validate/validate_formatted.js +5 -1
  60. package/validate/validate_function.js +24 -15
  61. package/validate/validate_glyphs_url.js +4 -1
  62. package/validate/validate_image.js +5 -1
  63. package/validate/validate_layer.js +17 -2
  64. package/validate/validate_layout_property.js +5 -1
  65. package/validate/validate_light.js +4 -1
  66. package/validate/validate_number.js +8 -1
  67. package/validate/validate_object.js +12 -2
  68. package/validate/validate_paint_property.js +5 -1
  69. package/validate/validate_projection.js +5 -1
  70. package/validate/validate_property.js +9 -1
  71. package/validate/validate_source.js +4 -1
  72. package/validate/validate_string.js +4 -1
  73. package/validate/validate_terrain.js +5 -2
  74. package/validate_style.min.js +1 -1
package/reference/v8.json CHANGED
@@ -63,7 +63,7 @@
63
63
  },
64
64
  "fog": {
65
65
  "type": "fog",
66
- "doc": "A global effect that fades layers and markers based on their distance to the camera. The fog can be used to approximate the effect of atmosphere on distant objects and enhance the depth perception of the map when used with terrain or 3D features."
66
+ "doc": "A global effect that fades layers and markers based on their distance to the camera. The fog can be used to approximate the effect of atmosphere on distant objects and enhance the depth perception of the map when used with terrain or 3D features. Note: fog is renamed to atmosphere in the Android and iOS SDKs and planned to be changed in GL-JS v.3.0.0."
67
67
  },
68
68
  "sources": {
69
69
  "required": true,
@@ -3816,7 +3816,9 @@
3816
3816
  ],
3817
3817
  "sdk-support": {
3818
3818
  "basic functionality": {
3819
- "js": "2.3.0"
3819
+ "js": "2.3.0",
3820
+ "android": "10.6.0",
3821
+ "ios": "10.6.0"
3820
3822
  }
3821
3823
  }
3822
3824
  },
@@ -3831,17 +3833,86 @@
3831
3833
  ]
3832
3834
  },
3833
3835
  "transition": true,
3834
- "doc": "The color of the fog. Using opacity is recommended only for smoothly transitioning fog on/off as anything less than 100% opacity results in more tiles loaded and drawn.",
3836
+ "doc": "The color of the atmosphere region immediately below the horizon and within the `range` and above the horizon and within `horizon-blend`. Using opacity is recommended only for smoothly transitioning fog on/off as anything less than 100% opacity results in more tiles loaded and drawn.",
3835
3837
  "sdk-support": {
3836
3838
  "basic functionality": {
3837
- "js": "2.3.0"
3839
+ "js": "2.3.0",
3840
+ "android": "10.6.0",
3841
+ "ios": "10.6.0"
3842
+ }
3843
+ }
3844
+ },
3845
+ "high-color": {
3846
+ "type": "color",
3847
+ "property-type": "data-constant",
3848
+ "default": "#245cdf",
3849
+ "expression": {
3850
+ "interpolated": true,
3851
+ "parameters": [
3852
+ "zoom"
3853
+ ]
3854
+ },
3855
+ "transition": true,
3856
+ "doc": "The color of the atmosphere region above the horizon, `high-color` extends further above the horizon than the `color` property and its spread can be controlled with `horizon-blend`. The opacity can be set to `0` to remove the high atmosphere color contribution.",
3857
+ "sdk-support": {
3858
+ "basic functionality": {
3859
+ "js": "2.9.0",
3860
+ "android": "10.6.0",
3861
+ "ios": "10.6.0"
3862
+ }
3863
+ }
3864
+ },
3865
+ "space-color": {
3866
+ "type": "color",
3867
+ "property-type": "data-constant",
3868
+
3869
+ "default":
3870
+ [
3871
+ "interpolate",
3872
+ [
3873
+ "linear"
3874
+ ],
3875
+ [
3876
+ "zoom"
3877
+ ],
3878
+ 4,
3879
+ "#010b19",
3880
+ 7,
3881
+ "#367ab9"
3882
+ ],
3883
+ "expression": {
3884
+ "interpolated": true,
3885
+ "parameters": [
3886
+ "zoom"
3887
+ ]
3888
+ },
3889
+ "transition": true,
3890
+ "doc": "The color of the region above the horizon and after the end of the `horizon-blend` contribution. The opacity can be set to `0` to have a transparent background.",
3891
+ "sdk-support": {
3892
+ "basic functionality": {
3893
+ "js": "2.9.0",
3894
+ "android": "10.6.0",
3895
+ "ios": "10.6.0"
3838
3896
  }
3839
3897
  }
3840
3898
  },
3841
3899
  "horizon-blend": {
3842
3900
  "type": "number",
3843
3901
  "property-type": "data-constant",
3844
- "default": 0.1,
3902
+ "default":
3903
+ [
3904
+ "interpolate",
3905
+ [
3906
+ "linear"
3907
+ ],
3908
+ [
3909
+ "zoom"
3910
+ ],
3911
+ 4,
3912
+ 0.2,
3913
+ 7,
3914
+ 0.1
3915
+ ],
3845
3916
  "minimum": 0,
3846
3917
  "maximum": 1,
3847
3918
  "expression": {
@@ -3851,10 +3922,47 @@
3851
3922
  ]
3852
3923
  },
3853
3924
  "transition": true,
3854
- "doc": "Horizon blend applies a smooth fade from the color of the fog to the color of the sky. A value of zero leaves a sharp transition from fog to sky. Increasing the value blends the color of fog into increasingly high angles of the sky.",
3925
+ "doc": "Horizon blend applies a smooth fade from the color of the atmosphere to the color of space. A value of zero leaves a sharp transition from atmosphere to space. Increasing the value blends the color of atmosphere into increasingly high angles of the sky.",
3855
3926
  "sdk-support": {
3856
3927
  "basic functionality": {
3857
- "js": "2.3.0"
3928
+ "js": "2.3.0",
3929
+ "android": "10.6.0",
3930
+ "ios": "10.6.0"
3931
+ }
3932
+ }
3933
+ },
3934
+ "star-intensity": {
3935
+ "type": "number",
3936
+ "property-type": "data-constant",
3937
+ "default":
3938
+ [
3939
+ "interpolate",
3940
+ [
3941
+ "linear"
3942
+ ],
3943
+ [
3944
+ "zoom"
3945
+ ],
3946
+ 5,
3947
+ 0.35,
3948
+ 6,
3949
+ 0
3950
+ ],
3951
+ "minimum": 0,
3952
+ "maximum": 1,
3953
+ "expression": {
3954
+ "interpolated": true,
3955
+ "parameters": [
3956
+ "zoom"
3957
+ ]
3958
+ },
3959
+ "transition": true,
3960
+ "doc": "A value controlling the star intensity where `0` will show no stars and `1` will show stars at their maximum intensity.",
3961
+ "sdk-support": {
3962
+ "basic functionality": {
3963
+ "js": "2.9.0",
3964
+ "android": "10.6.0",
3965
+ "ios": "10.6.0"
3858
3966
  }
3859
3967
  }
3860
3968
  }
@@ -4083,6 +4191,9 @@
4083
4191
  },
4084
4192
  "transition": true,
4085
4193
  "doc": "Exaggerates the elevation of the terrain by multiplying the data from the DEM with this value.",
4194
+ "requires": [
4195
+ "source"
4196
+ ],
4086
4197
  "sdk-support": {
4087
4198
  "basic functionality": {
4088
4199
  "js": "2.0.0",
@@ -4879,6 +4990,32 @@
4879
4990
  ]
4880
4991
  },
4881
4992
  "property-type": "color-ramp"
4993
+ },
4994
+ "line-trim-offset": {
4995
+ "type": "array",
4996
+ "value": "number",
4997
+ "doc": "The line part between [trim-start, trim-end] will be marked as transparent to make a route vanishing effect. The line trim-off offset is based on the whole line gradient range [0.0, 1.0]. If either 'trim-start' or 'trim-end' offset is out of valid range, the default range will be set.",
4998
+ "length": 2,
4999
+ "default": [0.0, 0.0],
5000
+ "transition": false,
5001
+ "requires": [
5002
+ "line-gradient",
5003
+ {
5004
+ "source": "geojson",
5005
+ "has": {
5006
+ "lineMetrics": true
5007
+ }
5008
+ }
5009
+ ],
5010
+ "sdk-support": {
5011
+ "basic functionality": {
5012
+ "js": "2.3.0",
5013
+ "android": "10.5.0",
5014
+ "ios": "10.5.0",
5015
+ "macos": "10.5.0"
5016
+ }
5017
+ },
5018
+ "property-type": "constant"
4882
5019
  }
4883
5020
  },
4884
5021
  "paint_circle": {
package/types.js CHANGED
@@ -91,7 +91,10 @@ export type TerrainSpecification = {|
91
91
  export type FogSpecification = {|
92
92
  "range"?: PropertyValueSpecification<[number, number]>,
93
93
  "color"?: PropertyValueSpecification<ColorSpecification>,
94
- "horizon-blend"?: PropertyValueSpecification<number>
94
+ "high-color"?: PropertyValueSpecification<ColorSpecification>,
95
+ "space-color"?: PropertyValueSpecification<ColorSpecification>,
96
+ "horizon-blend"?: PropertyValueSpecification<number>,
97
+ "star-intensity"?: PropertyValueSpecification<number>
95
98
  |}
96
99
 
97
100
  export type ProjectionSpecification = {|
@@ -229,7 +232,8 @@ export type LineLayerSpecification = {|
229
232
  "line-blur"?: DataDrivenPropertyValueSpecification<number>,
230
233
  "line-dasharray"?: DataDrivenPropertyValueSpecification<Array<number>>,
231
234
  "line-pattern"?: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>,
232
- "line-gradient"?: ExpressionSpecification
235
+ "line-gradient"?: ExpressionSpecification,
236
+ "line-trim-offset"?: [number, number]
233
237
  |}
234
238
  |}
235
239
 
package/util/color.js CHANGED
@@ -77,6 +77,11 @@ class Color {
77
77
  return `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},${a})`;
78
78
  }
79
79
 
80
+ /**
81
+ * Returns an RGBA array of values representing the color, unpremultiplied by A.
82
+ *
83
+ * @returns An array of RGBA color values in the range [0, 255].
84
+ */
80
85
  toArray(): [number, number, number, number] {
81
86
  const {r, g, b, a} = this;
82
87
  return a === 0 ? [0, 0, 0, 0] : [
@@ -86,6 +91,36 @@ class Color {
86
91
  a
87
92
  ];
88
93
  }
94
+
95
+ /**
96
+ * Returns a RGBA array of float values representing the color, unpremultiplied by A.
97
+ *
98
+ * @returns An array of RGBA color values in the range [0, 1].
99
+ */
100
+ toArray01(): [number, number, number, number] {
101
+ const {r, g, b, a} = this;
102
+ return a === 0 ? [0, 0, 0, 0] : [
103
+ r / a,
104
+ g / a,
105
+ b / a,
106
+ a
107
+ ];
108
+ }
109
+
110
+ /**
111
+ * Returns an RGBA array of values representing the color, premultiplied by A.
112
+ *
113
+ * @returns An array of RGBA color values in the range [0, 1].
114
+ */
115
+ toArray01PremultipliedAlpha(): [number, number, number, number] {
116
+ const {r, g, b, a} = this;
117
+ return [
118
+ r,
119
+ g,
120
+ b,
121
+ a
122
+ ];
123
+ }
89
124
  }
90
125
 
91
126
  Color.black = new Color(0, 0, 0, 1);
@@ -1,3 +1,4 @@
1
+ // @flow
1
2
 
2
3
  import extend from '../util/extend.js';
3
4
  import {unbundle, deepUnbundle} from '../util/unbundle_jsonlint.js';
@@ -23,6 +24,10 @@ import validateFormatted from './validate_formatted.js';
23
24
  import validateImage from './validate_image.js';
24
25
  import validateProjection from './validate_projection.js';
25
26
 
27
+ import type {StyleReference} from '../reference/latest.js';
28
+ import type {StyleSpecification} from '../types.js';
29
+ import type ValidationError from '../error/validation_error.js';
30
+
26
31
  const VALIDATORS = {
27
32
  '*'() {
28
33
  return [];
@@ -55,8 +60,15 @@ const VALIDATORS = {
55
60
  // scalar value.
56
61
  // - valueSpec: current spec being evaluated. Tracks value.
57
62
  // - styleSpec: current full spec being evaluated.
63
+ export type ValidationOptions = {
64
+ key: string;
65
+ value: Object;
66
+ valueSpec: Object;
67
+ style: $Shape<StyleSpecification>;
68
+ styleSpec: StyleReference;
69
+ }
58
70
 
59
- export default function validate(options) {
71
+ export default function validate(options: ValidationOptions): Array<ValidationError> {
60
72
  const value = options.value;
61
73
  const valueSpec = options.valueSpec;
62
74
  const styleSpec = options.styleSpec;
@@ -1,9 +1,16 @@
1
+ // @flow
1
2
 
2
3
  import getType from '../util/get_type.js';
3
4
  import validate from './validate.js';
4
5
  import ValidationError from '../error/validation_error.js';
5
6
 
6
- export default function validateArray(options) {
7
+ import type {ValidationOptions} from './validate.js';
8
+
9
+ type Options = ValidationOptions & {
10
+ arrayElementValidator: Function;
11
+ };
12
+
13
+ export default function validateArray(options: Options): Array<ValidationError> {
7
14
  const array = options.value;
8
15
  const arraySpec = options.valueSpec;
9
16
  const style = options.style;
@@ -27,7 +34,8 @@ export default function validateArray(options) {
27
34
  "type": arraySpec.value,
28
35
  "values": arraySpec.values,
29
36
  "minimum": arraySpec.minimum,
30
- "maximum": arraySpec.maximum
37
+ "maximum": arraySpec.maximum,
38
+ function: undefined
31
39
  };
32
40
 
33
41
  if (styleSpec.$version < 7) {
@@ -1,8 +1,11 @@
1
+ // @flow
1
2
 
2
3
  import getType from '../util/get_type.js';
3
4
  import ValidationError from '../error/validation_error.js';
4
5
 
5
- export default function validateBoolean(options) {
6
+ import type {ValidationOptions} from './validate.js';
7
+
8
+ export default function validateBoolean(options: ValidationOptions): Array<ValidationError> {
6
9
  const value = options.value;
7
10
  const key = options.key;
8
11
  const type = getType(value);
@@ -1,9 +1,12 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import getType from '../util/get_type.js';
4
5
  import {parseCSSColor} from 'csscolorparser';
5
6
 
6
- export default function validateColor(options) {
7
+ import type {ValidationOptions} from './validate.js';
8
+
9
+ export default function validateColor(options: ValidationOptions): Array<ValidationError> {
7
10
  const key = options.key;
8
11
  const value = options.value;
9
12
  const type = getType(value);
@@ -1,8 +1,11 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import {unbundle} from '../util/unbundle_jsonlint.js';
4
5
 
5
- export default function validateEnum(options) {
6
+ import type {ValidationOptions} from './validate.js';
7
+
8
+ export default function validateEnum(options: ValidationOptions): Array<ValidationError> {
6
9
  const key = options.key;
7
10
  const value = options.value;
8
11
  const valueSpec = options.valueSpec;
@@ -52,8 +52,11 @@ export function disallowedFilterParameters(e: Expression, options: any): Array<V
52
52
  'pitch',
53
53
  'distance-from-center'
54
54
  ]);
55
- for (const param of options.valueSpec.expression.parameters) {
56
- disallowedParameters.delete(param);
55
+
56
+ if (options.valueSpec && options.valueSpec.expression) {
57
+ for (const param of options.valueSpec.expression.parameters) {
58
+ disallowedParameters.delete(param);
59
+ }
57
60
  }
58
61
 
59
62
  if (disallowedParameters.size === 0) {
@@ -1,3 +1,4 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import validateExpression from './validate_expression.js';
@@ -7,13 +8,20 @@ import {unbundle, deepUnbundle} from '../util/unbundle_jsonlint.js';
7
8
  import extend from '../util/extend.js';
8
9
  import {isExpressionFilter} from '../feature_filter/index.js';
9
10
 
10
- export default function validateFilter(options) {
11
+ import type {ValidationOptions} from './validate.js';
12
+
13
+ type Options = ValidationOptions & {
14
+ layerType: string;
15
+ }
16
+
17
+ export default function validateFilter(options: Options): Array<ValidationError> {
11
18
  if (isExpressionFilter(deepUnbundle(options.value))) {
12
- const layerType = deepUnbundle(options.layerType);
19
+ // We default to a layerType of `fill` because that points to a non-dynamic filter definition within the style-spec.
20
+ const layerType = options.layerType || 'fill';
21
+
13
22
  return validateExpression(extend({}, options, {
14
23
  expressionContext: 'filter',
15
- // We default to a layerType of `fill` because that points to a non-dynamic filter definition within the style-spec.
16
- valueSpec: options.styleSpec[`filter_${layerType || 'fill'}`]
24
+ valueSpec: options.styleSpec[`filter_${layerType}`]
17
25
  }));
18
26
  } else {
19
27
  return validateNonExpressionFilter(options);
@@ -1,9 +1,12 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import validate from './validate.js';
4
5
  import getType from '../util/get_type.js';
5
6
 
6
- export default function validateFog(options) {
7
+ import type {ValidationOptions} from './validate.js';
8
+
9
+ export default function validateFog(options: ValidationOptions): Array<ValidationError> {
7
10
  const fog = options.value;
8
11
  const style = options.style;
9
12
  const styleSpec = options.styleSpec;
@@ -1,8 +1,12 @@
1
1
  // @flow
2
+
2
3
  import validateExpression from './validate_expression.js';
3
4
  import validateString from './validate_string.js';
4
5
 
5
- export default function validateFormatted(options: any) {
6
+ import type {ValidationOptions} from './validate.js';
7
+ import type ValidationError from '../error/validation_error.js';
8
+
9
+ export default function validateFormatted(options: ValidationOptions): Array<ValidationError> {
6
10
  if (validateString(options).length === 0) {
7
11
  return [];
8
12
  }
@@ -1,3 +1,4 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import getType from '../util/get_type.js';
@@ -13,11 +14,13 @@ import {
13
14
  supportsInterpolation
14
15
  } from '../util/properties.js';
15
16
 
16
- export default function validateFunction(options) {
17
+ import type {ValidationOptions} from './validate.js';
18
+
19
+ export default function validateFunction(options: ValidationOptions): any {
17
20
  const functionValueSpec = options.valueSpec;
18
21
  const functionType = unbundle(options.value.type);
19
22
  let stopKeyType;
20
- let stopDomainValues = {};
23
+ let stopDomainValues: {[string | number]: boolean} = {};
21
24
  let previousStopDomainValue;
22
25
  let previousStopDomainZoom;
23
26
 
@@ -66,7 +69,7 @@ export default function validateFunction(options) {
66
69
 
67
70
  return errors;
68
71
 
69
- function validateFunctionStops(options) {
72
+ function validateFunctionStops(options: ValidationOptions) {
70
73
  if (functionType === 'identity') {
71
74
  return [new ValidationError(options.key, options.value, 'identity function may not have a "stops" property')];
72
75
  }
@@ -90,7 +93,7 @@ export default function validateFunction(options) {
90
93
  return errors;
91
94
  }
92
95
 
93
- function validateFunctionStop(options) {
96
+ function validateFunctionStop(options: ValidationOptions) {
94
97
  let errors = [];
95
98
  const value = options.value;
96
99
  const key = options.key;
@@ -113,11 +116,17 @@ export default function validateFunction(options) {
113
116
  if (value[0].value === undefined) {
114
117
  return [new ValidationError(key, value, 'object stop key must have value')];
115
118
  }
116
- if (previousStopDomainZoom && previousStopDomainZoom > unbundle(value[0].zoom)) {
119
+
120
+ const nextStopDomainZoom = unbundle(value[0].zoom);
121
+ if (typeof nextStopDomainZoom !== 'number') {
122
+ return [new ValidationError(key, value[0].zoom, 'stop zoom values must be numbers')];
123
+ }
124
+
125
+ if (previousStopDomainZoom && previousStopDomainZoom > nextStopDomainZoom) {
117
126
  return [new ValidationError(key, value[0].zoom, 'stop zoom values must appear in ascending order')];
118
127
  }
119
- if (unbundle(value[0].zoom) !== previousStopDomainZoom) {
120
- previousStopDomainZoom = unbundle(value[0].zoom);
128
+ if (nextStopDomainZoom !== previousStopDomainZoom) {
129
+ previousStopDomainZoom = nextStopDomainZoom;
121
130
  previousStopDomainValue = undefined;
122
131
  stopDomainValues = {};
123
132
  }
@@ -152,7 +161,7 @@ export default function validateFunction(options) {
152
161
  }));
153
162
  }
154
163
 
155
- function validateStopDomainValue(options, stop) {
164
+ function validateStopDomainValue(options: ValidationOptions, stop) {
156
165
  const type = getType(options.value);
157
166
  const value = unbundle(options.value);
158
167
 
@@ -164,7 +173,7 @@ export default function validateFunction(options) {
164
173
  return [new ValidationError(options.key, reportValue, `${type} stop domain type must match previous stop domain type ${stopKeyType}`)];
165
174
  }
166
175
 
167
- if (type !== 'number' && type !== 'string' && type !== 'boolean') {
176
+ if (type !== 'number' && type !== 'string' && type !== 'boolean' && typeof value !== 'number' && typeof value !== 'string' && typeof value !== 'boolean') {
168
177
  return [new ValidationError(options.key, reportValue, 'stop domain value must be a number, string, or boolean')];
169
178
  }
170
179
 
@@ -176,26 +185,26 @@ export default function validateFunction(options) {
176
185
  return [new ValidationError(options.key, reportValue, message)];
177
186
  }
178
187
 
179
- if (functionType === 'categorical' && type === 'number' && (!isFinite(value) || Math.floor(value) !== value)) {
180
- return [new ValidationError(options.key, reportValue, `integer expected, found ${value}`)];
188
+ if (functionType === 'categorical' && type === 'number' && (typeof value !== 'number' || !isFinite(value) || Math.floor(value) !== value)) {
189
+ return [new ValidationError(options.key, reportValue, `integer expected, found ${String(value)}`)];
181
190
  }
182
191
 
183
- if (functionType !== 'categorical' && type === 'number' && previousStopDomainValue !== undefined && value < previousStopDomainValue) {
192
+ if (functionType !== 'categorical' && type === 'number' && typeof value === 'number' && typeof previousStopDomainValue === 'number' && previousStopDomainValue !== undefined && value < previousStopDomainValue) {
184
193
  return [new ValidationError(options.key, reportValue, 'stop domain values must appear in ascending order')];
185
194
  } else {
186
195
  previousStopDomainValue = value;
187
196
  }
188
197
 
189
- if (functionType === 'categorical' && value in stopDomainValues) {
198
+ if (functionType === 'categorical' && (value: any) in stopDomainValues) {
190
199
  return [new ValidationError(options.key, reportValue, 'stop domain values must be unique')];
191
200
  } else {
192
- stopDomainValues[value] = true;
201
+ stopDomainValues[(value: any)] = true;
193
202
  }
194
203
 
195
204
  return [];
196
205
  }
197
206
 
198
- function validateFunctionDefault(options) {
207
+ function validateFunctionDefault(options: ValidationOptions) {
199
208
  return validate({
200
209
  key: options.key,
201
210
  value: options.value,
@@ -1,8 +1,11 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import validateString from './validate_string.js';
4
5
 
5
- export default function(options) {
6
+ import type {ValidationOptions} from './validate.js';
7
+
8
+ export default function(options: ValidationOptions): Array<ValidationError> {
6
9
  const value = options.value;
7
10
  const key = options.key;
8
11
 
@@ -1,8 +1,12 @@
1
1
  // @flow
2
+
2
3
  import validateExpression from './validate_expression.js';
3
4
  import validateString from './validate_string.js';
4
5
 
5
- export default function validateImage(options: any) {
6
+ import type {ValidationOptions} from './validate.js';
7
+ import type ValidationError from '../error/validation_error.js';
8
+
9
+ export default function validateImage(options: ValidationOptions): Array<ValidationError> {
6
10
  if (validateString(options).length === 0) {
7
11
  return [];
8
12
  }
@@ -1,3 +1,4 @@
1
+ // @flow
1
2
 
2
3
  import ValidationError from '../error/validation_error.js';
3
4
  import {unbundle} from '../util/unbundle_jsonlint.js';
@@ -8,7 +9,15 @@ import validateLayoutProperty from './validate_layout_property.js';
8
9
  import validateSpec from './validate.js';
9
10
  import extend from '../util/extend.js';
10
11
 
11
- export default function validateLayer(options) {
12
+ import type {ValidationOptions} from './validate.js';
13
+ import type {LayerSpecification} from '../types.js';
14
+
15
+ type Options = ValidationOptions & {
16
+ value: LayerSpecification;
17
+ arrayIndex: number;
18
+ }
19
+
20
+ export default function validateLayer(options: Options): Array<ValidationError> {
12
21
  let errors = [];
13
22
 
14
23
  const layer = options.value;
@@ -27,6 +36,7 @@ export default function validateLayer(options) {
27
36
  for (let i = 0; i < options.arrayIndex; i++) {
28
37
  const otherLayer = style.layers[i];
29
38
  if (unbundle(otherLayer.id) === layerId) {
39
+ // $FlowFixMe[prop-missing] - id.__line__ is added dynamically during the readStyle step
30
40
  errors.push(new ValidationError(key, layer.id, `duplicate layer id "${layer.id}", previously used at line ${otherLayer.id.__line__}`));
31
41
  }
32
42
  }
@@ -46,7 +56,8 @@ export default function validateLayer(options) {
46
56
  });
47
57
 
48
58
  if (!parent) {
49
- errors.push(new ValidationError(key, layer.ref, `ref layer "${ref}" not found`));
59
+ if (typeof ref === 'string')
60
+ errors.push(new ValidationError(key, layer.ref, `ref layer "${ref}" not found`));
50
61
  } else if (parent.ref) {
51
62
  errors.push(new ValidationError(key, layer.ref, 'ref cannot reference another ref layer'));
52
63
  } else {
@@ -71,6 +82,8 @@ export default function validateLayer(options) {
71
82
  } else if (type === 'line' && layer.paint && layer.paint['line-gradient'] &&
72
83
  (sourceType !== 'geojson' || !source.lineMetrics)) {
73
84
  errors.push(new ValidationError(key, layer, `layer "${layer.id}" specifies a line-gradient, which requires a GeoJSON source with \`lineMetrics\` enabled.`));
85
+ } else if (type === 'line' && layer.paint && layer.paint['line-trim-offset'] && !layer.paint['line-gradient']) {
86
+ errors.push(new ValidationError(key, layer, `layer "${layer.id}" specifies a line-trim-offset, which requires line-gradient enabled.`));
74
87
  }
75
88
  }
76
89
  }
@@ -106,6 +119,7 @@ export default function validateLayer(options) {
106
119
  layer,
107
120
  key: options.key,
108
121
  value: options.value,
122
+ valueSpec: {},
109
123
  style: options.style,
110
124
  styleSpec: options.styleSpec,
111
125
  objectElementValidators: {
@@ -120,6 +134,7 @@ export default function validateLayer(options) {
120
134
  layer,
121
135
  key: options.key,
122
136
  value: options.value,
137
+ valueSpec: {},
123
138
  style: options.style,
124
139
  styleSpec: options.styleSpec,
125
140
  objectElementValidators: {
@@ -1,6 +1,10 @@
1
+ // @flow
1
2
 
2
3
  import validateProperty from './validate_property.js';
3
4
 
4
- export default function validateLayoutProperty(options) {
5
+ import type ValidationError from '../error/validation_error.js';
6
+ import type {PropertyValidationOptions} from './validate_property.js';
7
+
8
+ export default function validateLayoutProperty(options: PropertyValidationOptions): Array<ValidationError> {
5
9
  return validateProperty(options, 'layout');
6
10
  }