import { Env } from "../Env" ; import { CallExpr , Expr , ExprScope } from "../Expr" ; import { ExprEvaluatorContext , OperatorDescriptorMap } from "../ExprEvaluator" ; const hasOwnProperty = Object . prototype . hasOwnProperty ; enum LookupMode { get , has } function lookupMember ( context , args , lookupMode ) { const memberName = context . evaluate ( args [ 0 ] ) ; if ( typeof memberName !== "string" ) { throw new Error ( `expected the name of an attribute` ) ; } const object = context . evaluate ( args [ 1 ] ) as any ; if ( object && typeof object === "object" ) { if ( Env . isEnv ( object ) ) { const value = object . lookup ( memberName ) ?? null ; return lookupMode === LookupMode . get ? value : value !== null ; } if ( hasOwnProperty . call ( object , memberName ) ) { return lookupMode === LookupMode . get ? object [ memberName ] : true ; } } return lookupMode === LookupMode . get ? null : false ; } const operators = { in : { call : ( context , call ) => { const value = context . evaluate ( call . args [ 0 ] ) ; const object = context . evaluate ( call . args [ 1 ] ) ; if ( typeof value === "string" && typeof object === "string" ) { return object . includes ( value ) ; } else if ( Array . isArray ( object ) ) { return object . includes ( value ) ; } return false ; } } , get : { call : ( context , call ) => lookupMember ( context , call . args , LookupMode . get ) } , has : { call : ( context , call ) => lookupMember ( context , call . args , LookupMode . has ) } , "dynamic-properties" : { isDynamicOperator : ( ) => true , call : ( context , call ) => { if ( context . scope === ExprScope . Dynamic ) { return context . env ; } return call ; } } } ; export const ObjectOperators = operators ; export type ObjectOperatorNames = keyof typeof operators ;