@mapbox/mapbox-gl-style-spec 14.16.0-beta.1 → 14.16.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/dist/index.cjs +88 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.es.js +88 -42
- package/dist/index.es.js.map +1 -1
- package/expression/definitions/index.ts +13 -0
- package/expression/expression_dependencies.ts +33 -0
- package/expression/index.ts +16 -5
- package/expression/is_constant.ts +1 -14
- package/package.json +3 -2
- package/reference/v8.json +31 -14
- package/types.ts +6 -2
- package/validate/validate_appearance.ts +5 -7
- package/validate/validate_expression.ts +1 -1
- package/validate/validate_filter.ts +0 -2
- package/validate/validate_layer.ts +3 -2
- package/validate/validate_property.ts +11 -20
|
@@ -266,6 +266,19 @@ CompoundExpression.register(expressions, {
|
|
|
266
266
|
[],
|
|
267
267
|
(ctx) => ctx.globals.worldview || ""
|
|
268
268
|
],
|
|
269
|
+
'is-active-floor': [
|
|
270
|
+
BooleanType,
|
|
271
|
+
varargs(StringType),
|
|
272
|
+
(ctx, args) => {
|
|
273
|
+
const hasActiveFloors = ctx.globals.activeFloors && ctx.globals.activeFloors.size > 0;
|
|
274
|
+
if (!hasActiveFloors) { return false; }
|
|
275
|
+
const floorIds: Set<string> = ctx.globals.activeFloors;
|
|
276
|
+
return args.some(arg => {
|
|
277
|
+
const value = arg.evaluate(ctx) as string;
|
|
278
|
+
return floorIds.has(value);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
],
|
|
269
282
|
'id': [
|
|
270
283
|
ValueType,
|
|
271
284
|
[],
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import CompoundExpression from "./compound_expression";
|
|
2
|
+
import Config from "./definitions/config";
|
|
3
|
+
|
|
4
|
+
import type {Expression} from "./expression";
|
|
5
|
+
|
|
6
|
+
function getConfigDependencies(e: Expression): Set<string> {
|
|
7
|
+
if (e instanceof Config) {
|
|
8
|
+
const singleConfig = new Set([e.key]);
|
|
9
|
+
return singleConfig;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let result = new Set<string>();
|
|
13
|
+
e.eachChild(arg => {
|
|
14
|
+
result = new Set([...result, ...getConfigDependencies(arg)]);
|
|
15
|
+
});
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isIndoorDependent(e: Expression): boolean {
|
|
20
|
+
if (e instanceof CompoundExpression && e.name === 'is-active-floor') {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let result = false;
|
|
25
|
+
e.eachChild(arg => {
|
|
26
|
+
if (!result && isIndoorDependent(arg)) {
|
|
27
|
+
result = true;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export {getConfigDependencies, isIndoorDependent};
|
package/expression/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import Coalesce from './definitions/coalesce';
|
|
|
9
9
|
import Let from './definitions/let';
|
|
10
10
|
import definitions from './definitions/index';
|
|
11
11
|
import * as isConstant from './is_constant';
|
|
12
|
+
import * as expressionDependencies from './expression_dependencies';
|
|
12
13
|
import RuntimeError from './runtime_error';
|
|
13
14
|
import {success, error} from '../util/result';
|
|
14
15
|
import {
|
|
@@ -60,16 +61,17 @@ export interface GlobalProperties {
|
|
|
60
61
|
accumulated?: Value;
|
|
61
62
|
brightness?: number;
|
|
62
63
|
worldview?: string;
|
|
64
|
+
activeFloors?: Set<string>;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
export class StyleExpression {
|
|
66
68
|
expression: Expression;
|
|
67
|
-
|
|
68
69
|
_evaluator: EvaluationContext;
|
|
69
70
|
_defaultValue: Value;
|
|
70
71
|
_warningHistory: {[key: string]: boolean};
|
|
71
72
|
_enumValues?: {[_: string]: unknown};
|
|
72
73
|
configDependencies: Set<string>;
|
|
74
|
+
isIndoorDependent: boolean;
|
|
73
75
|
|
|
74
76
|
constructor(expression: Expression, propertySpec?: StylePropertySpecification, scope?: string, options?: ConfigOptions, iconImageUseTheme?: string) {
|
|
75
77
|
this.expression = expression;
|
|
@@ -77,7 +79,8 @@ export class StyleExpression {
|
|
|
77
79
|
this._evaluator = new EvaluationContext(scope, options, iconImageUseTheme);
|
|
78
80
|
this._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null;
|
|
79
81
|
this._enumValues = propertySpec && propertySpec.type === 'enum' ? propertySpec.values : null;
|
|
80
|
-
this.configDependencies =
|
|
82
|
+
this.configDependencies = expressionDependencies.getConfigDependencies(expression);
|
|
83
|
+
this.isIndoorDependent = expressionDependencies.isIndoorDependent(expression);
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
evaluateWithoutErrorHandling(
|
|
@@ -124,7 +127,6 @@ export class StyleExpression {
|
|
|
124
127
|
this._evaluator.featureTileCoord = featureTileCoord || null;
|
|
125
128
|
this._evaluator.featureDistanceData = featureDistanceData || null;
|
|
126
129
|
this._evaluator.iconImageUseTheme = iconImageUseTheme || null;
|
|
127
|
-
|
|
128
130
|
try {
|
|
129
131
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
130
132
|
const val = this.expression.evaluate(this._evaluator);
|
|
@@ -190,6 +192,7 @@ export class ZoomConstantExpression<Kind extends EvaluationKind> {
|
|
|
190
192
|
kind: Kind;
|
|
191
193
|
isStateDependent: boolean;
|
|
192
194
|
configDependencies: Set<string>;
|
|
195
|
+
isIndoorDependent: boolean;
|
|
193
196
|
_styleExpression: StyleExpression;
|
|
194
197
|
isLightConstant: boolean | null | undefined;
|
|
195
198
|
isLineProgressConstant: boolean | null | undefined;
|
|
@@ -200,7 +203,8 @@ export class ZoomConstantExpression<Kind extends EvaluationKind> {
|
|
|
200
203
|
this.isLightConstant = isLightConstant;
|
|
201
204
|
this.isLineProgressConstant = isLineProgressConstant;
|
|
202
205
|
this.isStateDependent = kind !== ('constant' as EvaluationKind) && !isConstant.isStateConstant(expression.expression);
|
|
203
|
-
this.configDependencies =
|
|
206
|
+
this.configDependencies = expressionDependencies.getConfigDependencies(expression.expression);
|
|
207
|
+
this.isIndoorDependent = expressionDependencies.isIndoorDependent(expression.expression);
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
evaluateWithoutErrorHandling(
|
|
@@ -233,6 +237,7 @@ export class ZoomDependentExpression<Kind extends EvaluationKind> {
|
|
|
233
237
|
kind: Kind;
|
|
234
238
|
zoomStops: Array<number>;
|
|
235
239
|
isStateDependent: boolean;
|
|
240
|
+
isIndoorDependent: boolean;
|
|
236
241
|
isLightConstant: boolean | null | undefined;
|
|
237
242
|
isLineProgressConstant: boolean | null | undefined;
|
|
238
243
|
configDependencies: Set<string>;
|
|
@@ -245,9 +250,10 @@ export class ZoomDependentExpression<Kind extends EvaluationKind> {
|
|
|
245
250
|
this.zoomStops = zoomStops;
|
|
246
251
|
this._styleExpression = expression;
|
|
247
252
|
this.isStateDependent = kind !== ('camera' as EvaluationKind) && !isConstant.isStateConstant(expression.expression);
|
|
253
|
+
this.isIndoorDependent = expressionDependencies.isIndoorDependent(expression.expression);
|
|
248
254
|
this.isLightConstant = isLightConstant;
|
|
249
255
|
this.isLineProgressConstant = isLineProgressConstant;
|
|
250
|
-
this.configDependencies =
|
|
256
|
+
this.configDependencies = expressionDependencies.getConfigDependencies(expression.expression);
|
|
251
257
|
this.interpolationType = interpolationType;
|
|
252
258
|
}
|
|
253
259
|
|
|
@@ -287,6 +293,7 @@ export class ZoomDependentExpression<Kind extends EvaluationKind> {
|
|
|
287
293
|
export type ConstantExpression = {
|
|
288
294
|
kind: 'constant';
|
|
289
295
|
configDependencies: Set<string>;
|
|
296
|
+
isIndoorDependent: boolean;
|
|
290
297
|
readonly evaluate: <T = unknown>(
|
|
291
298
|
globals: GlobalProperties,
|
|
292
299
|
feature?: Feature,
|
|
@@ -301,6 +308,7 @@ export type ConstantExpression = {
|
|
|
301
308
|
export type SourceExpression = {
|
|
302
309
|
kind: 'source';
|
|
303
310
|
isStateDependent: boolean;
|
|
311
|
+
isIndoorDependent: boolean;
|
|
304
312
|
isLightConstant: boolean | null | undefined;
|
|
305
313
|
isLineProgressConstant: boolean | null | undefined;
|
|
306
314
|
configDependencies: Set<string>;
|
|
@@ -317,6 +325,7 @@ export type SourceExpression = {
|
|
|
317
325
|
export type CameraExpression = {
|
|
318
326
|
kind: 'camera';
|
|
319
327
|
isStateDependent: boolean;
|
|
328
|
+
isIndoorDependent: boolean;
|
|
320
329
|
configDependencies: Set<string>;
|
|
321
330
|
readonly evaluate: <T = unknown>(
|
|
322
331
|
globals: GlobalProperties,
|
|
@@ -333,6 +342,7 @@ export type CameraExpression = {
|
|
|
333
342
|
export interface CompositeExpression {
|
|
334
343
|
kind: 'composite';
|
|
335
344
|
isStateDependent: boolean;
|
|
345
|
+
isIndoorDependent: boolean;
|
|
336
346
|
isLightConstant: boolean | null | undefined;
|
|
337
347
|
isLineProgressConstant: boolean | null | undefined;
|
|
338
348
|
configDependencies: Set<string>;
|
|
@@ -484,6 +494,7 @@ export function normalizePropertyExpression<T>(
|
|
|
484
494
|
return {
|
|
485
495
|
kind: 'constant',
|
|
486
496
|
configDependencies: new Set(),
|
|
497
|
+
isIndoorDependent: false,
|
|
487
498
|
evaluate: () => constant
|
|
488
499
|
} as ConstantExpression;
|
|
489
500
|
}
|
|
@@ -56,19 +56,6 @@ function isStateConstant(e: Expression): boolean {
|
|
|
56
56
|
return result;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function getConfigDependencies(e: Expression): Set<string> {
|
|
60
|
-
if (e instanceof Config) {
|
|
61
|
-
const singleConfig = new Set([e.key]);
|
|
62
|
-
return singleConfig;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
let result = new Set<string>();
|
|
66
|
-
e.eachChild(arg => {
|
|
67
|
-
result = new Set([...result, ...getConfigDependencies(arg)]);
|
|
68
|
-
});
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
59
|
function isGlobalPropertyConstant(e: Expression, properties: Array<string>): boolean {
|
|
73
60
|
if (e instanceof CompoundExpression && properties.indexOf(e.name) >= 0) { return false; }
|
|
74
61
|
let result = true;
|
|
@@ -78,4 +65,4 @@ function isGlobalPropertyConstant(e: Expression, properties: Array<string>): boo
|
|
|
78
65
|
return result;
|
|
79
66
|
}
|
|
80
67
|
|
|
81
|
-
export {isFeatureConstant, isGlobalPropertyConstant, isStateConstant
|
|
68
|
+
export {isFeatureConstant, isGlobalPropertyConstant, isStateConstant};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapbox/mapbox-gl-style-spec",
|
|
3
|
-
"version": "14.16.0-beta.
|
|
3
|
+
"version": "14.16.0-beta.3",
|
|
4
4
|
"description": "a specification for mapbox gl styles",
|
|
5
5
|
"author": "Mapbox",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
23
|
"require": "./dist/index.cjs",
|
|
24
|
-
"import": "./dist/index.es.js"
|
|
24
|
+
"import": "./dist/index.es.js",
|
|
25
|
+
"types": "./dist/index.d.ts"
|
|
25
26
|
},
|
|
26
27
|
"./": {
|
|
27
28
|
"import": "./"
|
package/reference/v8.json
CHANGED
|
@@ -125,6 +125,7 @@
|
|
|
125
125
|
},
|
|
126
126
|
"indoor": {
|
|
127
127
|
"type": "indoor",
|
|
128
|
+
"private": true,
|
|
128
129
|
"experimental": true,
|
|
129
130
|
"doc": "Controls the behaviour of indoor features."
|
|
130
131
|
},
|
|
@@ -5746,6 +5747,19 @@
|
|
|
5746
5747
|
}
|
|
5747
5748
|
}
|
|
5748
5749
|
},
|
|
5750
|
+
"is-active-floor": {
|
|
5751
|
+
"doc": "Experimental. Returns `true` if the input floor id belongs to one of the active indoor floors, `false` otherwise. In case of array of strings, returns `true` if any of the input floor ids belongs to one of the active indoor floors, `false` otherwise. Only supported in filters.",
|
|
5752
|
+
"group": "Indoor",
|
|
5753
|
+
"experimental": true,
|
|
5754
|
+
"private": true,
|
|
5755
|
+
"sdk-support": {
|
|
5756
|
+
"basic functionality": {
|
|
5757
|
+
"js": "3.16.0",
|
|
5758
|
+
"android": "11.16.0",
|
|
5759
|
+
"ios": "11.16.0"
|
|
5760
|
+
}
|
|
5761
|
+
}
|
|
5762
|
+
},
|
|
5749
5763
|
"random": {
|
|
5750
5764
|
"doc": "Returns a random value in the specified range (first two input numbers) based on a supplied seed (third input). The seed can be an expression or a constant number or string value.",
|
|
5751
5765
|
"group": "Math",
|
|
@@ -6574,26 +6588,29 @@
|
|
|
6574
6588
|
}
|
|
6575
6589
|
}
|
|
6576
6590
|
},
|
|
6577
|
-
"
|
|
6578
|
-
"
|
|
6591
|
+
"indoor_source": {
|
|
6592
|
+
"sourceId": {
|
|
6579
6593
|
"type": "string",
|
|
6580
|
-
"doc": "
|
|
6594
|
+
"doc": "Source ID of a source to be used to retrieve indoor data.",
|
|
6581
6595
|
"experimental": true,
|
|
6596
|
+
"private": true,
|
|
6582
6597
|
"transition": false,
|
|
6583
|
-
"property-type": "data-constant"
|
|
6584
|
-
"expression": {
|
|
6585
|
-
"interpolated": false
|
|
6586
|
-
}
|
|
6598
|
+
"property-type": "data-constant"
|
|
6587
6599
|
},
|
|
6588
|
-
"
|
|
6589
|
-
"type": "
|
|
6590
|
-
"
|
|
6600
|
+
"sourceLayers": {
|
|
6601
|
+
"type": "array",
|
|
6602
|
+
"value": "string",
|
|
6603
|
+
"doc": "An array of source layers to be used to retrieve indoor data.",
|
|
6591
6604
|
"experimental": true,
|
|
6605
|
+
"private": true,
|
|
6592
6606
|
"transition": false,
|
|
6593
|
-
"property-type": "data-constant"
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6607
|
+
"property-type": "data-constant"
|
|
6608
|
+
}
|
|
6609
|
+
},
|
|
6610
|
+
"indoor": {
|
|
6611
|
+
"*": {
|
|
6612
|
+
"type": "indoor_source",
|
|
6613
|
+
"doc": "Specification of an indoor source - sourceId and sourceLayer required for vector source, for GeoJSON sourceLayers should be omitted."
|
|
6597
6614
|
}
|
|
6598
6615
|
},
|
|
6599
6616
|
"light": {
|
package/types.ts
CHANGED
|
@@ -329,14 +329,18 @@ export type ImportSpecification = {
|
|
|
329
329
|
};
|
|
330
330
|
|
|
331
331
|
export type IndoorSpecification = {
|
|
332
|
+
[_: string]: IndoorSourceSpecification
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
export type IndoorSourceSpecification = {
|
|
332
336
|
/**
|
|
333
337
|
* @experimental This property is experimental and subject to change in future versions.
|
|
334
338
|
*/
|
|
335
|
-
"
|
|
339
|
+
"sourceId"?: string,
|
|
336
340
|
/**
|
|
337
341
|
* @experimental This property is experimental and subject to change in future versions.
|
|
338
342
|
*/
|
|
339
|
-
"
|
|
343
|
+
"sourceLayers"?: Array<string>
|
|
340
344
|
};
|
|
341
345
|
|
|
342
346
|
export type ConfigSpecification = {
|
|
@@ -7,6 +7,7 @@ import latest from '../reference/latest';
|
|
|
7
7
|
|
|
8
8
|
import type {StyleSpecification, LayerSpecification, AppearanceSpecification} from '../types';
|
|
9
9
|
import type {StyleReference} from '../reference/latest';
|
|
10
|
+
import type {StylePropertySpecification} from '../style-spec';
|
|
10
11
|
|
|
11
12
|
export type AppearanceValidatorOptions = {
|
|
12
13
|
key: string;
|
|
@@ -37,7 +38,7 @@ export default function validateAppearance(options: AppearanceValidatorOptions):
|
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
|
|
40
|
-
if (name !== 'hidden' &&
|
|
41
|
+
if (name !== 'hidden' && condition === undefined) {
|
|
41
42
|
errors.push(new ValidationError(options.key, 'name', `Appearance with name different than "hidden" must have a condition`));
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -49,10 +50,8 @@ function validateProperties(options: AppearanceValidatorOptions): Array<Validati
|
|
|
49
50
|
|
|
50
51
|
const {styleSpec, layer, layerType} = options;
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
55
|
-
const layoutProperties = styleSpec[`layout_${layerType}`];
|
|
53
|
+
const paintProperties = styleSpec[`paint_${layerType}`] as Record<string, StylePropertySpecification> | undefined;
|
|
54
|
+
const layoutProperties = styleSpec[`layout_${layerType}`] as Record<string, StylePropertySpecification> | undefined;
|
|
56
55
|
const properties = options.object[options.objectKey] as object;
|
|
57
56
|
|
|
58
57
|
for (const propertyKey in properties) {
|
|
@@ -73,8 +72,7 @@ function validateProperties(options: AppearanceValidatorOptions): Array<Validati
|
|
|
73
72
|
layer,
|
|
74
73
|
layerType,
|
|
75
74
|
value: properties[propertyKey] as unknown,
|
|
76
|
-
|
|
77
|
-
valueSpec: (propertyType === 'paint' ? paintProperties[propertyKey] : layoutProperties[propertyKey]) as object,
|
|
75
|
+
valueSpec: (propertyType === 'paint' ? paintProperties[propertyKey] : layoutProperties[propertyKey]),
|
|
78
76
|
});
|
|
79
77
|
|
|
80
78
|
errors.push(...validateProperty(propertyValidationOptions, propertyType));
|
|
@@ -4,7 +4,7 @@ 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 '
|
|
7
|
+
import type {StylePropertySpecification} from '../style-spec';
|
|
8
8
|
import type {Expression} from '../expression/expression';
|
|
9
9
|
import type {StyleReference} from '../reference/latest';
|
|
10
10
|
import type {StyleSpecification} from '../types';
|
|
@@ -59,14 +59,12 @@ function validateNonExpressionFilter(options: FilterValidatorOptions): Validatio
|
|
|
59
59
|
case '<':
|
|
60
60
|
case '<=':
|
|
61
61
|
case '>':
|
|
62
|
-
// @ts-expect-error - falls through
|
|
63
62
|
case '>=':
|
|
64
63
|
if (value.length >= 2 && unbundle(value[1]) === '$type') {
|
|
65
64
|
errors.push(new ValidationError(key, value, `"$type" cannot be use with operator "${value[0]}"`));
|
|
66
65
|
}
|
|
67
66
|
/* falls through */
|
|
68
67
|
case '==':
|
|
69
|
-
// @ts-expect-error - falls through
|
|
70
68
|
case '!=':
|
|
71
69
|
if (value.length !== 3) {
|
|
72
70
|
errors.push(new ValidationError(key, value, `filter array for operator "${value[0]}" must have 3 elements`));
|
|
@@ -10,6 +10,7 @@ import validateSpec from './validate';
|
|
|
10
10
|
import {isObject, isString} from '../util/get_type';
|
|
11
11
|
|
|
12
12
|
import type {StyleReference} from '../reference/latest';
|
|
13
|
+
import type {PropertyValidatorOptions} from './validate_property';
|
|
13
14
|
import type {StyleSpecification, LayerSpecification, GeoJSONSourceSpecification} from '../types';
|
|
14
15
|
|
|
15
16
|
type LayerValidatorOptions = {
|
|
@@ -138,7 +139,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
|
|
|
138
139
|
style: options.style,
|
|
139
140
|
styleSpec: options.styleSpec,
|
|
140
141
|
objectElementValidators: {
|
|
141
|
-
'*'(options) {
|
|
142
|
+
'*'(options: PropertyValidatorOptions) {
|
|
142
143
|
return validateLayoutProperty(Object.assign({layerType: type}, options));
|
|
143
144
|
}
|
|
144
145
|
}
|
|
@@ -153,7 +154,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
|
|
|
153
154
|
style: options.style,
|
|
154
155
|
styleSpec: options.styleSpec,
|
|
155
156
|
objectElementValidators: {
|
|
156
|
-
'*'(options) {
|
|
157
|
+
'*'(options: PropertyValidatorOptions) {
|
|
157
158
|
return validatePaintProperty(Object.assign({layerType: type, layer}, options));
|
|
158
159
|
}
|
|
159
160
|
}
|
|
@@ -8,12 +8,13 @@ import {isGlobalPropertyConstant, isFeatureConstant, isStateConstant} from '../e
|
|
|
8
8
|
import {createPropertyExpression, isExpression} from '../expression/index';
|
|
9
9
|
|
|
10
10
|
import type {StyleReference} from '../reference/latest';
|
|
11
|
+
import type {StylePropertySpecification} from '../style-spec';
|
|
11
12
|
import type {StyleSpecification, LayerSpecification} from '../types';
|
|
12
13
|
|
|
13
14
|
export type PropertyValidatorOptions = {
|
|
14
15
|
key: string;
|
|
15
16
|
value: unknown;
|
|
16
|
-
valueSpec?:
|
|
17
|
+
valueSpec?: StylePropertySpecification;
|
|
17
18
|
style: Partial<StyleSpecification>;
|
|
18
19
|
styleSpec: StyleReference;
|
|
19
20
|
objectKey?: string;
|
|
@@ -28,29 +29,24 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
|
|
|
28
29
|
const styleSpec = options.styleSpec;
|
|
29
30
|
const value = options.value;
|
|
30
31
|
const propertyKey = options.objectKey;
|
|
31
|
-
|
|
32
|
-
const layerSpec = styleSpec[`${propertyType}_${options.layerType}`];
|
|
32
|
+
const layerSpec = styleSpec[`${propertyType}_${options.layerType}`] as Record<string, StylePropertySpecification> | undefined;
|
|
33
33
|
|
|
34
34
|
if (!layerSpec) return [];
|
|
35
35
|
|
|
36
36
|
const useThemeMatch = propertyKey.match(/^(.*)-use-theme$/);
|
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
38
37
|
if (useThemeMatch && layerSpec[useThemeMatch[1]]) {
|
|
39
|
-
if (isExpression(value)) {
|
|
38
|
+
if (isExpression(deepUnbundle(value))) {
|
|
40
39
|
const errors: ValidationError[] = [];
|
|
41
40
|
return errors.concat(validate({
|
|
42
|
-
key
|
|
41
|
+
key,
|
|
43
42
|
value,
|
|
44
43
|
valueSpec: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"zoom",
|
|
50
|
-
"feature"
|
|
51
|
-
]
|
|
44
|
+
type: 'string',
|
|
45
|
+
expression: {
|
|
46
|
+
interpolated: false,
|
|
47
|
+
parameters: ['zoom', 'feature']
|
|
52
48
|
},
|
|
53
|
-
|
|
49
|
+
'property-type': 'data-driven'
|
|
54
50
|
},
|
|
55
51
|
style,
|
|
56
52
|
styleSpec,
|
|
@@ -59,6 +55,7 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
|
|
|
59
55
|
propertyKey
|
|
60
56
|
}));
|
|
61
57
|
}
|
|
58
|
+
|
|
62
59
|
return validate({
|
|
63
60
|
key,
|
|
64
61
|
value,
|
|
@@ -69,7 +66,6 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
|
|
|
69
66
|
}
|
|
70
67
|
|
|
71
68
|
const transitionMatch = propertyKey.match(/^(.*)-transition$/);
|
|
72
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
73
69
|
if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) {
|
|
74
70
|
return validate({
|
|
75
71
|
key,
|
|
@@ -81,14 +77,12 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
|
|
|
81
77
|
});
|
|
82
78
|
}
|
|
83
79
|
|
|
84
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
85
80
|
const valueSpec = options.valueSpec || layerSpec[propertyKey];
|
|
86
81
|
if (!valueSpec) {
|
|
87
82
|
return [new ValidationWarning(key, value, `unknown property "${propertyKey}"`)];
|
|
88
83
|
}
|
|
89
84
|
|
|
90
85
|
let tokenMatch: RegExpExecArray | undefined;
|
|
91
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
|
92
86
|
if (isString(value) && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) {
|
|
93
87
|
const example = `\`{ "type": "identity", "property": ${tokenMatch ? JSON.stringify(tokenMatch[1]) : '"_"'} }\``;
|
|
94
88
|
return [new ValidationError(
|
|
@@ -107,10 +101,8 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
|
|
|
107
101
|
errors.push(new ValidationError(key, value, '"text-font" does not support identity functions'));
|
|
108
102
|
}
|
|
109
103
|
} 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
|
|
111
104
|
if (supportsPropertyExpression(valueSpec) && (supportsLightExpression(valueSpec) || supportsZoomExpression(valueSpec))) {
|
|
112
105
|
// 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
|
|
114
106
|
const expression = createPropertyExpression(deepUnbundle(value), valueSpec);
|
|
115
107
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
116
108
|
const expressionObj = (expression.value as any).expression || (expression.value as any)._styleExpression.expression;
|
|
@@ -128,7 +120,6 @@ export default function validateProperty(options: PropertyValidatorOptions, prop
|
|
|
128
120
|
return errors.concat(validate({
|
|
129
121
|
key: options.key,
|
|
130
122
|
value,
|
|
131
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
132
123
|
valueSpec,
|
|
133
124
|
style,
|
|
134
125
|
styleSpec,
|