@mapbox/mapbox-gl-style-spec 14.15.0-beta.2 → 14.16.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 (76) hide show
  1. package/deref.ts +3 -0
  2. package/diff.ts +63 -0
  3. package/dist/index.cjs +741 -54
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +205 -40
  6. package/dist/index.es.js +741 -54
  7. package/dist/index.es.js.map +1 -1
  8. package/expression/compound_expression.ts +4 -0
  9. package/expression/definitions/assertion.ts +7 -0
  10. package/expression/definitions/case.ts +2 -1
  11. package/expression/definitions/coalesce.ts +4 -0
  12. package/expression/definitions/coercion.ts +12 -0
  13. package/expression/definitions/collator.ts +8 -5
  14. package/expression/definitions/comparison.ts +12 -5
  15. package/expression/definitions/config.ts +12 -0
  16. package/expression/definitions/distance.ts +13 -2
  17. package/expression/definitions/format.ts +10 -0
  18. package/expression/definitions/image.ts +3 -0
  19. package/expression/definitions/in.ts +5 -0
  20. package/expression/definitions/index.ts +62 -10
  21. package/expression/definitions/index_of.ts +6 -0
  22. package/expression/definitions/interpolate.ts +5 -1
  23. package/expression/definitions/length.ts +2 -0
  24. package/expression/definitions/let.ts +1 -0
  25. package/expression/definitions/match.ts +5 -0
  26. package/expression/definitions/number_format.ts +7 -0
  27. package/expression/definitions/slice.ts +4 -0
  28. package/expression/definitions/within.ts +1 -0
  29. package/expression/index.ts +28 -19
  30. package/expression/parsing_context.ts +2 -0
  31. package/expression/types/image_variant.ts +3 -0
  32. package/expression/types.ts +1 -2
  33. package/expression/values.ts +1 -0
  34. package/feature_filter/convert.ts +9 -1
  35. package/feature_filter/index.ts +41 -1
  36. package/format.ts +5 -0
  37. package/function/convert.ts +5 -0
  38. package/function/index.ts +79 -25
  39. package/group_by_layout.ts +4 -5
  40. package/migrate/v8.ts +42 -3
  41. package/migrate/v9.ts +5 -0
  42. package/migrate.ts +1 -0
  43. package/package.json +1 -1
  44. package/read_style.ts +2 -0
  45. package/reference/v8.json +463 -18
  46. package/rollup.config.js +1 -0
  47. package/style-spec.ts +187 -74
  48. package/test.js +4 -0
  49. package/types.ts +74 -5
  50. package/util/geometry_util.ts +4 -0
  51. package/validate/validate.ts +3 -8
  52. package/validate/validate_appearance.ts +101 -0
  53. package/validate/validate_array.ts +6 -4
  54. package/validate/validate_enum.ts +2 -7
  55. package/validate/validate_expression.ts +48 -3
  56. package/validate/validate_filter.ts +5 -3
  57. package/validate/validate_fog.ts +6 -0
  58. package/validate/validate_function.ts +2 -0
  59. package/validate/validate_iconset.ts +1 -0
  60. package/validate/validate_import.ts +2 -2
  61. package/validate/validate_layer.ts +37 -4
  62. package/validate/validate_light.ts +6 -0
  63. package/validate/validate_lights.ts +9 -0
  64. package/validate/validate_model.ts +1 -2
  65. package/validate/validate_number.ts +4 -4
  66. package/validate/validate_object.ts +7 -0
  67. package/validate/validate_projection.ts +2 -0
  68. package/validate/validate_property.ts +15 -4
  69. package/validate/validate_rain.ts +5 -0
  70. package/validate/validate_snow.ts +5 -0
  71. package/validate/validate_source.ts +13 -3
  72. package/validate/validate_style.ts +1 -0
  73. package/validate/validate_terrain.ts +6 -0
  74. package/validate_mapbox_api_supported.ts +1 -0
  75. package/visit.ts +2 -0
  76. package/util/extend.ts +0 -9
@@ -4,10 +4,10 @@ import {deepUnbundle} from '../util/unbundle_jsonlint';
4
4
  import {isStateConstant, isGlobalPropertyConstant, isFeatureConstant} from '../expression/is_constant';
5
5
  import CompoundExpression from '../expression/compound_expression';
6
6
 
7
+ import type {StylePropertySpecification} from '../../style-spec/style-spec';
7
8
  import type {Expression} from '../expression/expression';
8
9
  import type {StyleReference} from '../reference/latest';
9
10
  import type {StyleSpecification} from '../types';
10
- import type {StylePropertySpecification} from '../style-spec';
11
11
 
12
12
  export type ExpressionValidatorOptions = {
13
13
  key: string;
@@ -17,7 +17,7 @@ export type ExpressionValidatorOptions = {
17
17
  propertyType?: 'layout' | 'paint' | 'filter';
18
18
  style?: Partial<StyleSpecification>;
19
19
  styleSpec?: StyleReference;
20
- expressionContext?: 'property' | 'filter' | 'cluster-initial' | 'cluster-reduce' | 'cluster-map';
20
+ expressionContext?: 'property' | 'filter' | 'cluster-initial' | 'cluster-reduce' | 'cluster-map' | 'appearance';
21
21
  };
22
22
 
23
23
  export default function validateExpression(options: ExpressionValidatorOptions): ValidationError[] {
@@ -28,27 +28,37 @@ export default function validateExpression(options: ExpressionValidatorOptions):
28
28
  });
29
29
  }
30
30
 
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
32
32
  const expressionObj = (expression.value as any).expression || (expression.value as any)._styleExpression.expression;
33
33
 
34
34
  if (options.expressionContext === 'property' && (options.propertyKey === 'text-font') &&
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
35
36
  !expressionObj.outputDefined()) {
36
37
  return [new ValidationError(options.key, options.value, `Invalid data expression for "${options.propertyKey}". Output values must be contained as literals within the expression.`)];
37
38
  }
38
39
 
39
40
  if (options.expressionContext === 'property' && options.propertyType === 'layout' &&
41
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
40
42
  (!isStateConstant(expressionObj))) {
41
43
  return [new ValidationError(options.key, options.value, '"feature-state" data expressions are not supported with layout properties.')];
42
44
  }
43
45
 
44
46
  if (options.expressionContext === 'filter') {
47
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
45
48
  return disallowedFilterParameters(expressionObj, options);
46
49
  }
47
50
 
51
+ if (options.expressionContext === 'appearance') {
52
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
53
+ return checkDisallowedParameters(expressionObj, options);
54
+ }
55
+
48
56
  if (options.expressionContext && options.expressionContext.indexOf('cluster') === 0) {
57
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
49
58
  if (!isGlobalPropertyConstant(expressionObj, ['zoom', 'feature-state'])) {
50
59
  return [new ValidationError(options.key, options.value, '"zoom" and "feature-state" expressions are not supported with cluster properties.')];
51
60
  }
61
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
52
62
  if (options.expressionContext === 'cluster-initial' && !isFeatureConstant(expressionObj)) {
53
63
  return [new ValidationError(options.key, options.value, 'Feature data expressions are not supported with initial expression part of cluster properties.')];
54
64
  }
@@ -66,8 +76,11 @@ export function disallowedFilterParameters(e: Expression, options: any): Validat
66
76
  'distance-from-center'
67
77
  ]);
68
78
 
79
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
69
80
  if (options.valueSpec && options.valueSpec.expression) {
81
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
70
82
  for (const param of options.valueSpec.expression.parameters) {
83
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
71
84
  disallowedParameters.delete(param);
72
85
  }
73
86
  }
@@ -79,6 +92,7 @@ export function disallowedFilterParameters(e: Expression, options: any): Validat
79
92
 
80
93
  if (e instanceof CompoundExpression) {
81
94
  if (disallowedParameters.has(e.name)) {
95
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
82
96
  return [new ValidationError(options.key, options.value, `["${e.name}"] expression is not supported in a filter for a ${options.object.type} layer with id: ${options.object.id}`)];
83
97
  }
84
98
  }
@@ -88,3 +102,34 @@ export function disallowedFilterParameters(e: Expression, options: any): Validat
88
102
 
89
103
  return errors;
90
104
  }
105
+
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
+ function checkDisallowedParameters(e: Expression, options: any): ValidationError[] {
108
+ const allowedParameters = new Set<string>();
109
+
110
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
111
+ if (options.valueSpec && options.valueSpec.expression) {
112
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
113
+ for (const param of options.valueSpec.expression.parameters) {
114
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
115
+ allowedParameters.add(param);
116
+ }
117
+ }
118
+
119
+ if (allowedParameters.size === 0) {
120
+ return [];
121
+ }
122
+ const errors: ValidationError[] = [];
123
+
124
+ if (e instanceof CompoundExpression) {
125
+ if (!allowedParameters.has(e.name)) {
126
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
127
+ return [new ValidationError(options.key, options.value, `["${e.name}"] is not an allowed parameter`)];
128
+ }
129
+ }
130
+ e.eachChild((arg) => {
131
+ errors.push(...checkDisallowedParameters(arg, options));
132
+ });
133
+
134
+ return errors;
135
+ }
@@ -3,7 +3,6 @@ import validateExpression from './validate_expression';
3
3
  import validateEnum from './validate_enum';
4
4
  import {getType, isString, isNumber, isBoolean} from '../util/get_type';
5
5
  import {unbundle, deepUnbundle} from '../util/unbundle_jsonlint';
6
- import extend from '../util/extend';
7
6
  import {isExpressionFilter} from '../feature_filter/index';
8
7
 
9
8
  import type {StyleReference} from '../reference/latest';
@@ -26,8 +25,9 @@ export default function validateFilter(options: FilterValidatorOptions): Validat
26
25
  // We default to a layerType of `fill` because that points to a non-dynamic filter definition within the style-spec.
27
26
  const layerType = options.layerType || 'fill';
28
27
 
29
- return validateExpression(extend({}, options, {
30
- expressionContext: 'filter',
28
+ return validateExpression(Object.assign({}, options, {
29
+ expressionContext: 'filter' as const,
30
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
31
31
  valueSpec: options.styleSpec[`filter_${layerType}`]
32
32
  }));
33
33
  } else {
@@ -51,6 +51,7 @@ function validateNonExpressionFilter(options: FilterValidatorOptions): Validatio
51
51
  let errors: ValidationError[] = validateEnum({
52
52
  key: `${key}[0]`,
53
53
  value: value[0],
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
54
55
  valueSpec: styleSpec.filter_operator
55
56
  });
56
57
 
@@ -83,6 +84,7 @@ function validateNonExpressionFilter(options: FilterValidatorOptions): Validatio
83
84
  errors = errors.concat(validateEnum({
84
85
  key: `${key}[${i}]`,
85
86
  value: value[i],
87
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
86
88
  valueSpec: styleSpec.geometry_type
87
89
  }));
88
90
  } else if (!isString(value[i]) && !isNumber(value[i]) && !isBoolean(value[i])) {
@@ -16,6 +16,7 @@ export default function validateFog(options: FogValidatorOptions): ValidationErr
16
16
  const fog = options.value;
17
17
  const style = options.style;
18
18
  const styleSpec = options.styleSpec;
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
19
20
  const fogSpec = styleSpec.fog;
20
21
 
21
22
  if (fog === undefined) {
@@ -31,6 +32,7 @@ export default function validateFog(options: FogValidatorOptions): ValidationErr
31
32
  const transitionMatch = key.match(/^(.*)-transition$/);
32
33
  const useThemeMatch = key.match(/^(.*)-use-theme$/);
33
34
 
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
34
36
  if (useThemeMatch && fogSpec[useThemeMatch[1]]) {
35
37
  errors = errors.concat(validate({
36
38
  key,
@@ -39,18 +41,22 @@ export default function validateFog(options: FogValidatorOptions): ValidationErr
39
41
  style,
40
42
  styleSpec
41
43
  }));
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
42
45
  } else if (transitionMatch && fogSpec[transitionMatch[1]] && fogSpec[transitionMatch[1]].transition) {
43
46
  errors = errors.concat(validate({
44
47
  key,
45
48
  value: fog[key],
49
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
46
50
  valueSpec: styleSpec.transition,
47
51
  style,
48
52
  styleSpec
49
53
  }));
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
50
55
  } else if (fogSpec[key]) {
51
56
  errors = errors.concat(validate({
52
57
  key,
53
58
  value: fog[key],
59
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
54
60
  valueSpec: fogSpec[key],
55
61
  style,
56
62
  styleSpec
@@ -17,6 +17,7 @@ import type {StyleSpecification} from '../types';
17
17
  import type {StylePropertySpecification} from '../style-spec';
18
18
 
19
19
  function hasObjectStops(value: object): value is {stops: Array<Record<PropertyKey, unknown>>} {
20
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
20
21
  const stops = value['stops'];
21
22
  return Array.isArray(stops) && Array.isArray(stops[0]) && isObject(stops[0][0]);
22
23
  }
@@ -51,6 +52,7 @@ export default function validateFunction(options: FunctionValidatorOptions): Val
51
52
  const errors = validateObject({
52
53
  key: options.key,
53
54
  value: options.value,
55
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
54
56
  valueSpec: options.styleSpec.function,
55
57
  style: options.style,
56
58
  styleSpec: options.styleSpec,
@@ -38,6 +38,7 @@ export default function validateIconset(options: IconsetValidatorOptions): Valid
38
38
  errors = errors.concat(validateObject({
39
39
  key,
40
40
  value: iconset,
41
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
41
42
  valueSpec: styleSpec[`iconset_${type}`],
42
43
  style,
43
44
  styleSpec
@@ -1,4 +1,3 @@
1
- import extend from '../util/extend';
2
1
  import validateStyle from './validate_style';
3
2
  import validateObject from './validate_object';
4
3
  import ValidationError from '../error/validation_error';
@@ -31,8 +30,9 @@ export default function validateImport(options: ImportValidatorOptions): Validat
31
30
  enumerable: false
32
31
  });
33
32
 
34
- let errors = validateObject(extend({}, options, {
33
+ let errors = validateObject(Object.assign({}, options, {
35
34
  value: importSpec,
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
36
36
  valueSpec: styleSpec.import
37
37
  }));
38
38
 
@@ -1,11 +1,12 @@
1
1
  import ValidationError from '../error/validation_error';
2
2
  import {unbundle} from '../util/unbundle_jsonlint';
3
+ import validateArray from './validate_array';
3
4
  import validateObject from './validate_object';
4
5
  import validateFilter from './validate_filter';
6
+ import validateAppearance, {type AppearanceValidatorOptions} from './validate_appearance';
5
7
  import validatePaintProperty from './validate_paint_property';
6
8
  import validateLayoutProperty from './validate_layout_property';
7
9
  import validateSpec from './validate';
8
- import extend from '../util/extend';
9
10
  import {isObject, isString} from '../util/get_type';
10
11
 
11
12
  import type {StyleReference} from '../reference/latest';
@@ -64,9 +65,11 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
64
65
  if (!parent) {
65
66
  if (typeof ref === 'string')
66
67
  errors.push(new ValidationError(key, layer.ref, `ref layer "${ref}" not found`));
68
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
67
69
  } else if (parent.ref) {
68
70
  errors.push(new ValidationError(key, layer.ref, 'ref cannot reference another ref layer'));
69
71
  } else {
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
70
73
  type = unbundle(parent.type) as string;
71
74
  }
72
75
  } else if (!(type === 'background' || type === 'sky' || type === 'slot')) {
@@ -101,6 +104,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
101
104
  errors = errors.concat(validateObject({
102
105
  key,
103
106
  value: layer,
107
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
104
108
  valueSpec: styleSpec.layer,
105
109
  style: options.style,
106
110
  styleSpec: options.styleSpec,
@@ -114,6 +118,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
114
118
  return validateSpec({
115
119
  key: `${key}.type`,
116
120
  value: layer.type,
121
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
117
122
  valueSpec: styleSpec.layer.type,
118
123
  style: options.style,
119
124
  styleSpec: options.styleSpec,
@@ -122,7 +127,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
122
127
  });
123
128
  },
124
129
  filter(options) {
125
- return validateFilter(extend({layerType: type}, options));
130
+ return validateFilter(Object.assign({layerType: type}, options));
126
131
  },
127
132
  layout(options) {
128
133
  return validateObject({
@@ -134,7 +139,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
134
139
  styleSpec: options.styleSpec,
135
140
  objectElementValidators: {
136
141
  '*'(options) {
137
- return validateLayoutProperty(extend({layerType: type}, options));
142
+ return validateLayoutProperty(Object.assign({layerType: type}, options));
138
143
  }
139
144
  }
140
145
  });
@@ -149,10 +154,38 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
149
154
  styleSpec: options.styleSpec,
150
155
  objectElementValidators: {
151
156
  '*'(options) {
152
- return validatePaintProperty(extend({layerType: type, layer}, options));
157
+ return validatePaintProperty(Object.assign({layerType: type, layer}, options));
153
158
  }
154
159
  }
155
160
  });
161
+ },
162
+ appearances(options) {
163
+ const validationErrors = validateArray({
164
+ key: options.key,
165
+ value: options.value,
166
+
167
+ valueSpec: options.valueSpec,
168
+ style: options.style,
169
+ styleSpec: options.styleSpec,
170
+ arrayElementValidator: (options) => validateAppearance(Object.assign({layerType: type, layer}, options) as AppearanceValidatorOptions)
171
+ });
172
+ // Check non-repeated names on a given layer
173
+ const appearances = Array.isArray(options.value) ? options.value : [];
174
+ const dedupedNames = new Set<string>();
175
+ appearances.forEach((a, index) => {
176
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
177
+ const name: string | undefined = unbundle(a.name) as string | undefined;
178
+ if (name) {
179
+ if (dedupedNames.has(name)) {
180
+ const layerId = unbundle((layer as LayerSpecification).id) as string;
181
+ validationErrors.push(new ValidationError(options.key, name, `Duplicated appearance name "${name}" for layer "${layerId}"`));
182
+ } else {
183
+ dedupedNames.add(name);
184
+ }
185
+ }
186
+ });
187
+
188
+ return validationErrors;
156
189
  }
157
190
  }
158
191
  }));
@@ -15,6 +15,7 @@ type LightValidatorOptions = {
15
15
  export default function validateLight(options: LightValidatorOptions): ValidationError[] {
16
16
  const light = options.value;
17
17
  const styleSpec = options.styleSpec;
18
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
18
19
  const lightSpec = styleSpec.light;
19
20
  const style = options.style;
20
21
 
@@ -31,6 +32,7 @@ export default function validateLight(options: LightValidatorOptions): Validatio
31
32
  const transitionMatch = key.match(/^(.*)-transition$/);
32
33
  const useThemeMatch = key.match(/^(.*)-use-theme$/);
33
34
 
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
34
36
  if (useThemeMatch && lightSpec[useThemeMatch[1]]) {
35
37
  errors = errors.concat(validate({
36
38
  key,
@@ -39,18 +41,22 @@ export default function validateLight(options: LightValidatorOptions): Validatio
39
41
  style,
40
42
  styleSpec
41
43
  }));
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
42
45
  } else if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
43
46
  errors = errors.concat(validate({
44
47
  key,
45
48
  value: light[key],
49
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
46
50
  valueSpec: styleSpec.transition,
47
51
  style,
48
52
  styleSpec
49
53
  }));
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
50
55
  } else if (lightSpec[key]) {
51
56
  errors = errors.concat(validate({
52
57
  key,
53
58
  value: light[key],
59
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
54
60
  valueSpec: lightSpec[key],
55
61
  style,
56
62
  styleSpec
@@ -28,6 +28,7 @@ export default function validateLights(options: LightsValidatorOptions): Validat
28
28
 
29
29
  let errors: ValidationError[] = [];
30
30
  const styleSpec = options.styleSpec;
31
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
31
32
  const lightSpec = styleSpec['light-3d'];
32
33
  const style = options.style;
33
34
  const lights = options.style.lights;
@@ -60,6 +61,7 @@ export default function validateLights(options: LightsValidatorOptions): Validat
60
61
  return errors;
61
62
  }
62
63
 
64
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
63
65
  const lightPropertySpec = styleSpec[lightType];
64
66
 
65
67
  for (const key in light) {
@@ -73,6 +75,7 @@ export default function validateLights(options: LightsValidatorOptions): Validat
73
75
  const transitionMatch = propertyKey.match(/^(.*)-transition$/);
74
76
  const useThemeMatch = propertyKey.match(/^(.*)-use-theme$/);
75
77
 
78
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
76
79
  if (useThemeMatch && lightPropertySpec[useThemeMatch[1]]) {
77
80
  errors = errors.concat(validate({
78
81
  key,
@@ -81,20 +84,24 @@ export default function validateLights(options: LightsValidatorOptions): Validat
81
84
  style,
82
85
  styleSpec
83
86
  }));
87
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
84
88
  } else if (transitionMatch && lightPropertySpec[transitionMatch[1]] && lightPropertySpec[transitionMatch[1]].transition) {
85
89
  errors = errors.concat(validate({
86
90
  key,
87
91
  value: light[key],
92
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
88
93
  valueSpec: styleSpec.transition,
89
94
  style,
90
95
  styleSpec
91
96
  }));
97
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
92
98
  } else if (!lightPropertySpec[propertyKey]) {
93
99
  errors = errors.concat([new ValidationWarning(options.key, properties[propertyKey], `unknown property "${propertyKey}"`)]);
94
100
  } else {
95
101
  errors = errors.concat(validate({
96
102
  key: propertyKey,
97
103
  value: properties[propertyKey],
104
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
98
105
  valueSpec: lightPropertySpec[propertyKey],
99
106
  style,
100
107
  styleSpec
@@ -102,10 +109,12 @@ export default function validateLights(options: LightsValidatorOptions): Validat
102
109
  }
103
110
  }
104
111
  } else {
112
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
105
113
  if (lightSpec[key]) {
106
114
  errors = errors.concat(validate({
107
115
  key,
108
116
  value: light[key],
117
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
109
118
  valueSpec: lightSpec[key],
110
119
  style,
111
120
  styleSpec
@@ -10,8 +10,7 @@ export function isValidUrl(str: string, allowRelativeUrls: boolean): boolean {
10
10
  try {
11
11
  new URL(str, isRelative && allowRelativeUrls ? 'http://example.com' : undefined);
12
12
  return true;
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- } catch (_: any) {
13
+ } catch (_: unknown) {
15
14
  return false;
16
15
  }
17
16
  }
@@ -3,14 +3,12 @@ import ValidationError from '../error/validation_error';
3
3
 
4
4
  import type {StyleReference} from '../reference/latest';
5
5
  import type {StyleSpecification} from '../types';
6
+ import type {NumberPropertySpecification} from '../style-spec';
6
7
 
7
8
  type NumberValidatorOptions = {
8
9
  key: string;
9
10
  value: unknown;
10
- valueSpec: {
11
- minimum?: number;
12
- maximum?: number
13
- };
11
+ valueSpec: NumberPropertySpecification;
14
12
  style: Partial<StyleSpecification>;
15
13
  styleSpec: StyleReference;
16
14
  arrayIndex: number;
@@ -34,6 +32,7 @@ export default function validateNumber(options: NumberValidatorOptions): Validat
34
32
  let specMin = valueSpec.minimum;
35
33
  if (Array.isArray(valueSpec.minimum)) {
36
34
  const i = options.arrayIndex;
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
37
36
  specMin = valueSpec.minimum[i];
38
37
  }
39
38
  if (value < specMin) {
@@ -45,6 +44,7 @@ export default function validateNumber(options: NumberValidatorOptions): Validat
45
44
  let specMax = valueSpec.maximum;
46
45
  if (Array.isArray(valueSpec.maximum)) {
47
46
  const i = options.arrayIndex;
47
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
48
48
  specMax = valueSpec.maximum[i];
49
49
  }
50
50
  if (value > specMax) {
@@ -8,8 +8,11 @@ import type {StyleSpecification, LayerSpecification} from '../types';
8
8
  type ObjectElementValidatorOptions = {
9
9
  key: string;
10
10
  value: unknown;
11
+ valueSpec?: unknown;
11
12
  style: Partial<StyleSpecification>;
12
13
  styleSpec: StyleReference;
14
+ object?: object;
15
+ objectKey?: string;
13
16
  };
14
17
 
15
18
  type ObjectValidatorOptions = {
@@ -39,6 +42,7 @@ export default function validateObject(options: ObjectValidatorOptions): Validat
39
42
  let errors: ValidationError[] = [];
40
43
  for (const objectKey in object) {
41
44
  const elementSpecKey = objectKey.split('.')[0]; // treat 'paint.*' as 'paint'
45
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
42
46
  const elementSpec = elementSpecs[elementSpecKey] || elementSpecs['*'];
43
47
 
44
48
  let validateElement;
@@ -57,9 +61,11 @@ export default function validateObject(options: ObjectValidatorOptions): Validat
57
61
  continue;
58
62
  }
59
63
 
64
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call
60
65
  errors = errors.concat(validateElement({
61
66
  key: (key ? `${key}.` : key) + objectKey,
62
67
  value: object[objectKey],
68
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
63
69
  valueSpec: elementSpec,
64
70
  style,
65
71
  styleSpec,
@@ -74,6 +80,7 @@ export default function validateObject(options: ObjectValidatorOptions): Validat
74
80
  continue;
75
81
  }
76
82
 
83
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
77
84
  if (elementSpecs[elementSpecKey].required && elementSpecs[elementSpecKey]['default'] === undefined && object[elementSpecKey] === undefined) {
78
85
  errors.push(new ValidationError(key, object, `missing required property "${elementSpecKey}"`));
79
86
  }
@@ -15,6 +15,7 @@ type ProjectionValidatorOptions = {
15
15
  export default function validateProjection(options: ProjectionValidatorOptions): ValidationError[] {
16
16
  const projection = options.value;
17
17
  const styleSpec = options.styleSpec;
18
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
18
19
  const projectionSpec = styleSpec.projection;
19
20
  const style = options.style;
20
21
 
@@ -25,6 +26,7 @@ export default function validateProjection(options: ProjectionValidatorOptions):
25
26
  errors = errors.concat(validate({
26
27
  key,
27
28
  value: projection[key],
29
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
28
30
  valueSpec: projectionSpec[key],
29
31
  style,
30
32
  styleSpec
@@ -13,12 +13,12 @@ import type {StyleSpecification, LayerSpecification} from '../types';
13
13
  export type PropertyValidatorOptions = {
14
14
  key: string;
15
15
  value: unknown;
16
- valueSpec: unknown;
16
+ valueSpec?: unknown;
17
17
  style: Partial<StyleSpecification>;
18
18
  styleSpec: StyleReference;
19
- objectKey: string;
19
+ objectKey?: string;
20
20
  layerType: string;
21
- layer: LayerSpecification;
21
+ layer?: Partial<LayerSpecification>;
22
22
  };
23
23
 
24
24
  export default function validateProperty(options: PropertyValidatorOptions, propertyType: string): ValidationError[] {
@@ -28,11 +28,13 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
28
28
  const styleSpec = options.styleSpec;
29
29
  const value = options.value;
30
30
  const propertyKey = options.objectKey;
31
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
31
32
  const layerSpec = styleSpec[`${propertyType}_${options.layerType}`];
32
33
 
33
34
  if (!layerSpec) return [];
34
35
 
35
36
  const useThemeMatch = propertyKey.match(/^(.*)-use-theme$/);
37
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
36
38
  if (useThemeMatch && layerSpec[useThemeMatch[1]]) {
37
39
  if (isExpression(value)) {
38
40
  const errors: ValidationError[] = [];
@@ -67,22 +69,26 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
67
69
  }
68
70
 
69
71
  const transitionMatch = propertyKey.match(/^(.*)-transition$/);
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
70
73
  if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) {
71
74
  return validate({
72
75
  key,
73
76
  value,
77
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
74
78
  valueSpec: styleSpec.transition,
75
79
  style,
76
80
  styleSpec
77
81
  });
78
82
  }
79
83
 
84
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
80
85
  const valueSpec = options.valueSpec || layerSpec[propertyKey];
81
86
  if (!valueSpec) {
82
87
  return [new ValidationWarning(key, value, `unknown property "${propertyKey}"`)];
83
88
  }
84
89
 
85
90
  let tokenMatch: RegExpExecArray | undefined;
91
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
86
92
  if (isString(value) && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) {
87
93
  const example = `\`{ "type": "identity", "property": ${tokenMatch ? JSON.stringify(tokenMatch[1]) : '"_"'} }\``;
88
94
  return [new ValidationError(
@@ -101,13 +107,17 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
101
107
  errors.push(new ValidationError(key, value, '"text-font" does not support identity functions'));
102
108
  }
103
109
  } else if (options.layerType === 'model' && propertyType === 'paint' && layer && layer.layout && layer.layout.hasOwnProperty('model-id')) {
110
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
104
111
  if (supportsPropertyExpression(valueSpec) && (supportsLightExpression(valueSpec) || supportsZoomExpression(valueSpec))) {
105
112
  // Performance related style spec limitation: zoom and light expressions are not allowed for e.g. trees.
113
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
106
114
  const expression = createPropertyExpression(deepUnbundle(value), valueSpec);
107
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
108
116
  const expressionObj = (expression.value as any).expression || (expression.value as any)._styleExpression.expression;
109
117
 
118
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
110
119
  if (expressionObj && !isGlobalPropertyConstant(expressionObj, ['measure-light'])) {
120
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
111
121
  if (propertyKey !== 'model-emissive-strength' || (!isFeatureConstant(expressionObj) || !isStateConstant(expressionObj))) {
112
122
  errors.push(new ValidationError(key, value, `${propertyKey} does not support measure-light expressions when the model layer source is vector tile or GeoJSON.`));
113
123
  }
@@ -118,6 +128,7 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
118
128
  return errors.concat(validate({
119
129
  key: options.key,
120
130
  value,
131
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
121
132
  valueSpec,
122
133
  style,
123
134
  styleSpec,
@@ -16,6 +16,7 @@ export default function validateRain(options: RainValidatorOptions): ValidationE
16
16
  const rain = options.value;
17
17
  const style = options.style;
18
18
  const styleSpec = options.styleSpec;
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
19
20
  const rainSpec = styleSpec.rain;
20
21
 
21
22
  if (rain === undefined) {
@@ -30,18 +31,22 @@ export default function validateRain(options: RainValidatorOptions): ValidationE
30
31
  for (const key in rain) {
31
32
  const transitionMatch = key.match(/^(.*)-transition$/);
32
33
 
34
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
33
35
  if (transitionMatch && rainSpec[transitionMatch[1]] && rainSpec[transitionMatch[1]].transition) {
34
36
  errors = errors.concat(validate({
35
37
  key,
36
38
  value: rain[key],
39
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
37
40
  valueSpec: styleSpec.transition,
38
41
  style,
39
42
  styleSpec
40
43
  }));
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
41
45
  } else if (rainSpec[key]) {
42
46
  errors = errors.concat(validate({
43
47
  key,
44
48
  value: rain[key],
49
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
45
50
  valueSpec: rainSpec[key],
46
51
  style,
47
52
  styleSpec