@@ -4,10 +4,10 @@ import {deepUnbundle} from '../util/unbundle_jsonlint';
44import { isStateConstant , isGlobalPropertyConstant , isFeatureConstant } from '../expression/is_constant' ;
55import CompoundExpression from '../expression/compound_expression' ;
66
7+ import type { StylePropertySpecification } from '../../style-spec/style-spec' ;
78import type { Expression } from '../expression/expression' ;
89import type { StyleReference } from '../reference/latest' ;
910import type { StyleSpecification } from '../types' ;
10- import type { StylePropertySpecification } from '../style-spec' ;
1111
1212export type ExpressionValidatorOptions = {
1313 key : string ;
@@ -17,7 +17,7 @@ export type ExpressionValidatorOptions = {
1717 propertyType ?: 'layout' | 'paint' | 'filter' ;
1818 style ?: Partial < StyleSpecification > ;
1919 styleSpec ?: StyleReference ;
20- expressionContext ?: 'property' | 'filter' | 'cluster-initial' | 'cluster-reduce' | 'cluster-map' ;
20+ expressionContext ?: 'property' | 'filter' | 'cluster-initial' | 'cluster-reduce' | 'cluster-map' | 'appearance' ;
2121} ;
2222
2323export default function validateExpression ( options : ExpressionValidatorOptions ) : ValidationError [ ] {
@@ -48,6 +48,11 @@ export default function validateExpression(options: ExpressionValidatorOptions):
4848 return disallowedFilterParameters ( expressionObj , options ) ;
4949 }
5050
51+ if ( options . expressionContext === 'appearance' ) {
52+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
53+ return checkDisallowedParameters ( expressionObj , options ) ;
54+ }
55+
5156 if ( options . expressionContext && options . expressionContext . indexOf ( 'cluster' ) === 0 ) {
5257 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
5358 if ( ! isGlobalPropertyConstant ( expressionObj , [ 'zoom' , 'feature-state' ] ) ) {
@@ -97,3 +102,34 @@ export function disallowedFilterParameters(e: Expression, options: any): Validat
97102
98103 return errors ;
99104}
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+ }
0 commit comments