@@ -269,16 +269,17 @@ const defaultMethods = {
269
269
} ,
270
270
// Adding this to spec something out, not to merge it quite yet
271
271
val : {
272
- method : ( args , context , above ) => {
272
+ method : ( args , context , above , engine ) => {
273
273
if ( Array . isArray ( args ) && args . length === 1 ) args = args [ 0 ]
274
+ // A unary optimization
274
275
if ( ! Array . isArray ( args ) ) {
275
- if ( args === null || args === undefined ) return context
276
276
const result = context [ args ]
277
277
if ( typeof result === 'undefined' ) return null
278
278
return result
279
279
}
280
280
let result = context
281
281
let start = 0
282
+ // This block handles scope traversal
282
283
if ( Array . isArray ( args [ 0 ] ) && args [ 0 ] . length === 1 ) {
283
284
start ++
284
285
const climb = + Math . abs ( args [ 0 ] [ 0 ] )
@@ -292,12 +293,13 @@ const defaultMethods = {
292
293
}
293
294
}
294
295
}
296
+ // This block handles traversing the path
295
297
for ( let i = start ; i < args . length ; i ++ ) {
296
- if ( args [ i ] === null ) continue
297
298
if ( result === null || result === undefined ) return null
298
299
result = result [ args [ i ] ]
299
300
}
300
301
if ( typeof result === 'undefined' ) return null
302
+ if ( typeof result === 'function' && ! engine . allowFunctions ) return null
301
303
return result
302
304
} ,
303
305
optimizeUnary : true ,
@@ -310,9 +312,14 @@ const defaultMethods = {
310
312
} ,
311
313
compile : ( data , buildState ) => {
312
314
function wrapNull ( data ) {
313
- if ( ! chainingSupported ) return buildState . compile `((( a) => a === null || a === undefined ? null : a)(${ data } ))`
314
- return buildState . compile `(${ data } ?? null)`
315
+ if ( ! chainingSupported ) return buildState . compile `(methods.preventFunctions((( a) => a === null || a === undefined ? null : a)(${ data } ) ))`
316
+ return buildState . compile `(methods.preventFunctions( ${ data } ?? null) )`
315
317
}
318
+
319
+ if ( ! buildState . engine . allowFunctions ) buildState . methods . preventFunctions = a => typeof a === 'function' ? null : a
320
+ else buildState . methods . preventFunctions = a => a
321
+
322
+ if ( typeof data === 'object' && ! Array . isArray ( data ) ) return false
316
323
if ( Array . isArray ( data ) && Array . isArray ( data [ 0 ] ) ) {
317
324
// A very, very specific optimization.
318
325
if ( buildState . iteratorCompile && Math . abs ( data [ 0 ] [ 0 ] || 0 ) === 1 && data [ 1 ] === 'index' ) return buildState . compile `index`
@@ -445,7 +452,7 @@ const defaultMethods = {
445
452
buildState . methods . push ( mapper )
446
453
if ( async ) {
447
454
if ( ! isSync ( mapper ) || selector . includes ( 'await' ) ) {
448
- buildState . detectAsync = true
455
+ buildState . asyncDetected = true
449
456
if ( typeof defaultValue !== 'undefined' ) {
450
457
return `await asyncIterators.reduce(${ selector } || [], (a,b) => methods[${
451
458
buildState . methods . length - 1
@@ -672,8 +679,8 @@ function createArrayIterativeMethod (name, useTruthy = false) {
672
679
const aboveArray = method . aboveDetected ? buildState . compile `[{ iterator: z, index: x }, context, above]` : buildState . compile `null`
673
680
674
681
if ( async ) {
675
- if ( ! isSyncDeep ( mapper , buildState . engine , buildState ) ) {
676
- buildState . detectAsync = true
682
+ if ( ! isSync ( method ) ) {
683
+ buildState . asyncDetected = true
677
684
return buildState . compile `await asyncIterators[${ name } ](${ selector } || [], async (i, x, z) => ${ method } (i, x, ${ aboveArray } ))`
678
685
}
679
686
}
0 commit comments