@mapbox/mapbox-gl-style-spec 14.15.0-beta.1 → 14.15.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.
- package/deref.ts +3 -0
- package/diff.ts +63 -0
- package/dist/index.cjs +743 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +85 -6
- package/dist/index.es.js +743 -65
- package/dist/index.es.js.map +1 -1
- package/expression/compound_expression.ts +4 -0
- package/expression/definitions/assertion.ts +7 -0
- package/expression/definitions/case.ts +2 -1
- package/expression/definitions/coalesce.ts +4 -0
- package/expression/definitions/coercion.ts +12 -0
- package/expression/definitions/collator.ts +8 -5
- package/expression/definitions/comparison.ts +12 -5
- package/expression/definitions/config.ts +12 -0
- package/expression/definitions/distance.ts +13 -2
- package/expression/definitions/format.ts +10 -0
- package/expression/definitions/image.ts +3 -0
- package/expression/definitions/in.ts +5 -0
- package/expression/definitions/index.ts +62 -10
- package/expression/definitions/index_of.ts +6 -0
- package/expression/definitions/interpolate.ts +5 -1
- package/expression/definitions/length.ts +2 -0
- package/expression/definitions/let.ts +1 -0
- package/expression/definitions/match.ts +5 -0
- package/expression/definitions/number_format.ts +7 -0
- package/expression/definitions/slice.ts +4 -0
- package/expression/definitions/within.ts +1 -0
- package/expression/index.ts +28 -19
- package/expression/parsing_context.ts +2 -0
- package/expression/types/image_variant.ts +3 -0
- package/expression/types.ts +1 -2
- package/expression/values.ts +1 -0
- package/feature_filter/convert.ts +9 -1
- package/feature_filter/index.ts +41 -1
- package/format.ts +5 -0
- package/function/convert.ts +5 -0
- package/function/index.ts +79 -25
- package/group_by_layout.ts +4 -5
- package/migrate/v8.ts +42 -3
- package/migrate/v9.ts +5 -0
- package/migrate.ts +1 -0
- package/package.json +1 -1
- package/read_style.ts +2 -0
- package/reference/v8.json +457 -12
- package/rollup.config.js +1 -0
- package/test.js +4 -0
- package/types.ts +74 -5
- package/util/color.ts +21 -26
- package/util/geometry_util.ts +4 -0
- package/validate/validate.ts +1 -0
- package/validate/validate_appearance.ts +101 -0
- package/validate/validate_array.ts +1 -0
- package/validate/validate_expression.ts +48 -3
- package/validate/validate_filter.ts +5 -3
- package/validate/validate_fog.ts +6 -0
- package/validate/validate_function.ts +2 -0
- package/validate/validate_iconset.ts +1 -0
- package/validate/validate_import.ts +2 -2
- package/validate/validate_layer.ts +37 -4
- package/validate/validate_light.ts +6 -0
- package/validate/validate_lights.ts +9 -0
- package/validate/validate_model.ts +1 -2
- package/validate/validate_number.ts +2 -0
- package/validate/validate_object.ts +7 -0
- package/validate/validate_projection.ts +2 -0
- package/validate/validate_property.ts +15 -4
- package/validate/validate_rain.ts +5 -0
- package/validate/validate_snow.ts +5 -0
- package/validate/validate_source.ts +12 -0
- package/validate/validate_style.ts +1 -0
- package/validate/validate_terrain.ts +6 -0
- package/validate_mapbox_api_supported.ts +1 -0
- package/visit.ts +2 -0
- package/util/extend.ts +0 -9
package/types.ts
CHANGED
|
@@ -130,6 +130,35 @@ export type ModelsSpecification = {
|
|
|
130
130
|
[_: string]: ModelSpecification
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
+
export type ModelNodeOverrideSpecification = {
|
|
134
|
+
"orientation"?: [number, number, number]
|
|
135
|
+
};
|
|
136
|
+
export type ModelNodeOverridesSpecification = {
|
|
137
|
+
[_: string]: ModelNodeOverrideSpecification
|
|
138
|
+
};
|
|
139
|
+
export type ModelMaterialOverrideSpecification = {
|
|
140
|
+
"model-color"?: ColorSpecification,
|
|
141
|
+
"model-color-mix-intensity"?: number,
|
|
142
|
+
"model-opacity"?: number,
|
|
143
|
+
"model-emissive-strength"?: number
|
|
144
|
+
};
|
|
145
|
+
export type ModelMaterialOverridesSpecification = {
|
|
146
|
+
[_: string]: ModelMaterialOverrideSpecification
|
|
147
|
+
};
|
|
148
|
+
export type ModelSourceModelsSpecification = {
|
|
149
|
+
[_: string]: ModelSourceModelSpecification
|
|
150
|
+
};
|
|
151
|
+
export type ModelSourceModelSpecification = {
|
|
152
|
+
"uri": string,
|
|
153
|
+
"position"?: [number, number],
|
|
154
|
+
"orientation"?: [number, number, number],
|
|
155
|
+
"nodeOverrides"?: ModelNodeOverridesSpecification,
|
|
156
|
+
"materialOverrides"?: ModelMaterialOverridesSpecification,
|
|
157
|
+
"nodeOverrideNames"?: Array<string>,
|
|
158
|
+
"materialOverrideNames"?: Array<string>,
|
|
159
|
+
"featureProperties"?: unknown
|
|
160
|
+
};
|
|
161
|
+
|
|
133
162
|
export type IconsetsSpecification = {
|
|
134
163
|
[_: string]: IconsetSpecification
|
|
135
164
|
};
|
|
@@ -383,7 +412,7 @@ export type SelectorPropertySpecification = {
|
|
|
383
412
|
};
|
|
384
413
|
|
|
385
414
|
export type AppearanceSpecification = {
|
|
386
|
-
"condition"?:
|
|
415
|
+
"condition"?: DataDrivenPropertyValueSpecification<boolean>,
|
|
387
416
|
"name"?: string,
|
|
388
417
|
"properties"?: unknown
|
|
389
418
|
};
|
|
@@ -499,7 +528,8 @@ export type ModelSourceSpecification = {
|
|
|
499
528
|
"type": "model" | "batched-model",
|
|
500
529
|
"maxzoom"?: number,
|
|
501
530
|
"minzoom"?: number,
|
|
502
|
-
"tiles"?: Array<string
|
|
531
|
+
"tiles"?: Array<string>,
|
|
532
|
+
"models"?: ModelSourceModelsSpecification
|
|
503
533
|
};
|
|
504
534
|
|
|
505
535
|
export type SourceSpecification =
|
|
@@ -1099,6 +1129,10 @@ export type BuildingLayerSpecification = {
|
|
|
1099
1129
|
* @experimental This property is experimental and subject to change in future versions.
|
|
1100
1130
|
*/
|
|
1101
1131
|
"building-facade-floors"?: DataDrivenPropertyValueSpecification<number>,
|
|
1132
|
+
/**
|
|
1133
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1134
|
+
*/
|
|
1135
|
+
"building-facade-unit-width"?: DataDrivenPropertyValueSpecification<number>,
|
|
1102
1136
|
/**
|
|
1103
1137
|
* @experimental This property is experimental and subject to change in future versions.
|
|
1104
1138
|
*/
|
|
@@ -1116,7 +1150,22 @@ export type BuildingLayerSpecification = {
|
|
|
1116
1150
|
* @experimental This property is experimental and subject to change in future versions.
|
|
1117
1151
|
*/
|
|
1118
1152
|
"building-base"?: DataDrivenPropertyValueSpecification<number>,
|
|
1119
|
-
"building-base-transition"?: TransitionSpecification
|
|
1153
|
+
"building-base-transition"?: TransitionSpecification,
|
|
1154
|
+
/**
|
|
1155
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1156
|
+
*/
|
|
1157
|
+
"building-flood-light-wall-radius"?: DataDrivenPropertyValueSpecification<number>,
|
|
1158
|
+
"building-flood-light-wall-radius-transition"?: TransitionSpecification,
|
|
1159
|
+
/**
|
|
1160
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1161
|
+
*/
|
|
1162
|
+
"building-flood-light-ground-radius"?: DataDrivenPropertyValueSpecification<number>,
|
|
1163
|
+
"building-flood-light-ground-radius-transition"?: TransitionSpecification,
|
|
1164
|
+
/**
|
|
1165
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1166
|
+
*/
|
|
1167
|
+
"building-flip-roof-orientation"?: DataDrivenPropertyValueSpecification<boolean>,
|
|
1168
|
+
"building-flip-roof-orientation-transition"?: TransitionSpecification
|
|
1120
1169
|
},
|
|
1121
1170
|
"paint"?: {
|
|
1122
1171
|
/**
|
|
@@ -1166,7 +1215,23 @@ export type BuildingLayerSpecification = {
|
|
|
1166
1215
|
* @experimental This property is experimental and subject to change in future versions.
|
|
1167
1216
|
*/
|
|
1168
1217
|
"building-facade-emissive-chance"?: PropertyValueSpecification<number>,
|
|
1169
|
-
"building-cutoff-fade-range"?: ExpressionSpecification
|
|
1218
|
+
"building-cutoff-fade-range"?: ExpressionSpecification,
|
|
1219
|
+
/**
|
|
1220
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1221
|
+
*/
|
|
1222
|
+
"building-flood-light-color"?: PropertyValueSpecification<ColorSpecification>,
|
|
1223
|
+
"building-flood-light-color-transition"?: TransitionSpecification,
|
|
1224
|
+
"building-flood-light-color-use-theme"?: PropertyValueSpecification<string>,
|
|
1225
|
+
/**
|
|
1226
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1227
|
+
*/
|
|
1228
|
+
"building-flood-light-intensity"?: PropertyValueSpecification<number>,
|
|
1229
|
+
"building-flood-light-intensity-transition"?: TransitionSpecification,
|
|
1230
|
+
/**
|
|
1231
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1232
|
+
*/
|
|
1233
|
+
"building-flood-light-ground-attenuation"?: PropertyValueSpecification<number>,
|
|
1234
|
+
"building-flood-light-ground-attenuation-transition"?: TransitionSpecification
|
|
1170
1235
|
},
|
|
1171
1236
|
"appearances"?: Array<AppearanceSpecification>
|
|
1172
1237
|
};
|
|
@@ -1363,7 +1428,11 @@ export type ModelLayerSpecification = {
|
|
|
1363
1428
|
"model-height-based-emissive-strength-multiplier"?: DataDrivenPropertyValueSpecification<[number, number, number, number, number]>,
|
|
1364
1429
|
"model-height-based-emissive-strength-multiplier-transition"?: TransitionSpecification,
|
|
1365
1430
|
"model-cutoff-fade-range"?: ExpressionSpecification,
|
|
1366
|
-
"model-front-cutoff"?: PropertyValueSpecification<[number, number, number]
|
|
1431
|
+
"model-front-cutoff"?: PropertyValueSpecification<[number, number, number]>,
|
|
1432
|
+
/**
|
|
1433
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
1434
|
+
*/
|
|
1435
|
+
"model-elevation-reference"?: "sea" | "ground" | "hd-road-markup" | ExpressionSpecification
|
|
1367
1436
|
},
|
|
1368
1437
|
"appearances"?: Array<AppearanceSpecification>
|
|
1369
1438
|
};
|
package/util/color.ts
CHANGED
|
@@ -206,46 +206,41 @@ export abstract class RenderColor {
|
|
|
206
206
|
|
|
207
207
|
if (this.premultiplied) {
|
|
208
208
|
if (a === 0) return [0, 0, 0, 0];
|
|
209
|
-
|
|
210
|
-
r
|
|
211
|
-
g
|
|
212
|
-
b
|
|
209
|
+
const invA = 1 / a; // Single division, then multiply
|
|
210
|
+
r *= invA;
|
|
211
|
+
g *= invA;
|
|
212
|
+
b *= invA;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
const red = Math.min(Math.max(r, 0
|
|
216
|
-
const green = Math.min(Math.max(g, 0
|
|
217
|
-
const blue = Math.min(Math.max(b, 0
|
|
215
|
+
const red = Math.min(Math.max(r, 0), 1);
|
|
216
|
+
const green = Math.min(Math.max(g, 0), 1);
|
|
217
|
+
const blue = Math.min(Math.max(b, 0), 1);
|
|
218
218
|
|
|
219
219
|
const min = Math.min(red, green, blue);
|
|
220
220
|
const max = Math.max(red, green, blue);
|
|
221
|
+
const delta = max - min;
|
|
221
222
|
|
|
222
|
-
const l = (min + max)
|
|
223
|
+
const l = (min + max) * 0.5;
|
|
223
224
|
|
|
224
|
-
if (
|
|
225
|
+
if (delta === 0) {
|
|
225
226
|
return [0, 0, l * 100, a];
|
|
226
227
|
}
|
|
227
228
|
|
|
228
|
-
const delta = max - min;
|
|
229
|
-
|
|
230
229
|
const s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
|
231
230
|
|
|
232
|
-
let h
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
h = (
|
|
231
|
+
let h: number;
|
|
232
|
+
switch (max) {
|
|
233
|
+
case red:
|
|
234
|
+
h = ((green - blue) / delta + (green < blue ? 6 : 0)) * 60;
|
|
235
|
+
break;
|
|
236
|
+
case green:
|
|
237
|
+
h = ((blue - red) / delta + 2) * 60;
|
|
238
|
+
break;
|
|
239
|
+
default: // blue
|
|
240
|
+
h = ((red - green) / delta + 4) * 60;
|
|
239
241
|
}
|
|
240
242
|
|
|
241
|
-
h
|
|
242
|
-
|
|
243
|
-
return [
|
|
244
|
-
Math.min(Math.max(h, 0), 360),
|
|
245
|
-
Math.min(Math.max(s * 100, 0), 100),
|
|
246
|
-
Math.min(Math.max(l * 100, 0), 100),
|
|
247
|
-
a
|
|
248
|
-
];
|
|
243
|
+
return [h, s * 100, l * 100, a];
|
|
249
244
|
}
|
|
250
245
|
|
|
251
246
|
/**
|
package/util/geometry_util.ts
CHANGED
|
@@ -16,6 +16,7 @@ function calculateSignedArea(ring: Ring): number {
|
|
|
16
16
|
for (let i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
|
|
17
17
|
p1 = ring[i];
|
|
18
18
|
p2 = ring[j];
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
19
20
|
sum += (p2.x - p1.x) * (p1.y + p2.y);
|
|
20
21
|
}
|
|
21
22
|
return sum;
|
|
@@ -44,13 +45,16 @@ export function classifyRings(rings: Array<Ring>, maxRings: number): Array<Array
|
|
|
44
45
|
if (ccw === undefined) ccw = area < 0;
|
|
45
46
|
|
|
46
47
|
if (ccw === area < 0) {
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
47
49
|
if (polygon) polygons.push(polygon);
|
|
48
50
|
polygon = [rings[i]];
|
|
49
51
|
|
|
50
52
|
} else {
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
51
54
|
(polygon).push(rings[i]);
|
|
52
55
|
}
|
|
53
56
|
}
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
54
58
|
if (polygon) polygons.push(polygon);
|
|
55
59
|
|
|
56
60
|
// Earcut performance degrades with the # of rings in a polygon. For this
|
package/validate/validate.ts
CHANGED
|
@@ -122,6 +122,7 @@ export default function validate(options: ValidatorOptions, arrayAsExpression: b
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
const errors = validateObject(Object.assign({}, options, {
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
125
126
|
valueSpec: valueSpec.type ? styleSpec[valueSpec.type] : valueSpec
|
|
126
127
|
}));
|
|
127
128
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import validateObject from './validate_object';
|
|
2
|
+
import ValidationError from '../error/validation_error';
|
|
3
|
+
import validateProperty from './validate_property';
|
|
4
|
+
import {unbundle} from '../util/unbundle_jsonlint';
|
|
5
|
+
import validateExpression from './validate_expression';
|
|
6
|
+
import latest from '../reference/latest';
|
|
7
|
+
|
|
8
|
+
import type {StyleSpecification, LayerSpecification, AppearanceSpecification} from '../types';
|
|
9
|
+
import type {StyleReference} from '../reference/latest';
|
|
10
|
+
|
|
11
|
+
export type AppearanceValidatorOptions = {
|
|
12
|
+
key: string;
|
|
13
|
+
value: unknown;
|
|
14
|
+
style: Partial<StyleSpecification>;
|
|
15
|
+
styleSpec: StyleReference;
|
|
16
|
+
object?: object;
|
|
17
|
+
objectKey?: string;
|
|
18
|
+
layer: LayerSpecification;
|
|
19
|
+
layerType: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default function validateAppearance(options: AppearanceValidatorOptions): Array<ValidationError> {
|
|
23
|
+
const {key, layer, layerType} = options;
|
|
24
|
+
const value = unbundle(options.value) as AppearanceSpecification;
|
|
25
|
+
const name = unbundle(value.name);
|
|
26
|
+
const condition = unbundle(value.condition);
|
|
27
|
+
|
|
28
|
+
const errors = validateObject({
|
|
29
|
+
key,
|
|
30
|
+
value,
|
|
31
|
+
valueSpec: options.styleSpec.appearance as object,
|
|
32
|
+
style: options.style,
|
|
33
|
+
styleSpec: options.styleSpec,
|
|
34
|
+
objectElementValidators: {
|
|
35
|
+
condition: (options) => validateCondition(Object.assign({layer, layerType}, options)),
|
|
36
|
+
properties: (options) => validateProperties(Object.assign({layer, layerType}, options)),
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (name !== 'hidden' && !condition) {
|
|
41
|
+
errors.push(new ValidationError(options.key, 'name', `Appearance with name different than "hidden" must have a condition`));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return errors;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function validateProperties(options: AppearanceValidatorOptions): Array<ValidationError> {
|
|
48
|
+
const errors: Array<ValidationError> = [];
|
|
49
|
+
|
|
50
|
+
const {styleSpec, layer, layerType} = options;
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
53
|
+
const paintProperties = styleSpec[`paint_${layerType}`];
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
55
|
+
const layoutProperties = styleSpec[`layout_${layerType}`];
|
|
56
|
+
const properties = options.object[options.objectKey] as object;
|
|
57
|
+
|
|
58
|
+
for (const propertyKey in properties) {
|
|
59
|
+
const propertyType =
|
|
60
|
+
propertyKey in paintProperties ? 'paint' :
|
|
61
|
+
propertyKey in layoutProperties ? 'layout' :
|
|
62
|
+
undefined;
|
|
63
|
+
|
|
64
|
+
if (!propertyType) {
|
|
65
|
+
errors.push(new ValidationError(options.key, propertyKey, `unknown property "${propertyKey}" for layer type "${layerType}"`));
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const propertyValidationOptions = Object.assign({}, options, {
|
|
70
|
+
key: `${options.key}.${propertyKey}`,
|
|
71
|
+
object: properties,
|
|
72
|
+
objectKey: propertyKey,
|
|
73
|
+
layer,
|
|
74
|
+
layerType,
|
|
75
|
+
value: properties[propertyKey] as unknown,
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
77
|
+
valueSpec: (propertyType === 'paint' ? paintProperties[propertyKey] : layoutProperties[propertyKey]) as object,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
errors.push(...validateProperty(propertyValidationOptions, propertyType));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return errors;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function validateCondition(options: AppearanceValidatorOptions): Array<ValidationError> {
|
|
87
|
+
const errors: Array<ValidationError> = [];
|
|
88
|
+
|
|
89
|
+
const appearance = options.object as AppearanceSpecification;
|
|
90
|
+
const condition = appearance.condition;
|
|
91
|
+
|
|
92
|
+
errors.push(...validateExpression({
|
|
93
|
+
key: options.key,
|
|
94
|
+
value: condition,
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
96
|
+
valueSpec: latest['appearance']['condition'],
|
|
97
|
+
expressionContext: 'appearance'
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
return errors;
|
|
101
|
+
}
|
|
@@ -72,6 +72,7 @@ export default function validateArray(options: ArrayValidatorOptions): Validatio
|
|
|
72
72
|
errors = errors.concat(validateArrayElement({
|
|
73
73
|
array,
|
|
74
74
|
arrayIndex: i,
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
75
76
|
value: array[i],
|
|
76
77
|
valueSpec: arrayElementSpec,
|
|
77
78
|
style,
|
|
@@ -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(
|
|
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])) {
|
package/validate/validate_fog.ts
CHANGED
|
@@ -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(
|
|
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
|
|