expression-evaluation: Support key/value pair object arrays (like product meta data) (#41594)

* Test key/value pair arrays in expressions

* Support key/value pair arrays in expressions

* Changelog
This commit is contained in:
Matt Sherman 2023-11-21 15:39:57 -05:00 committed by GitHub
parent cb539c787f
commit 6944345371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 2 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Support arrays with key/value pair objects in expressions (like post meta data).

View File

@ -79,6 +79,23 @@ const grammar = `
}
}, head );
}
function getPropertyValue( obj, propertyName ) {
if ( Object.hasOwn( obj, propertyName ) ) {
return obj[ propertyName ];
} else if (
Array.isArray( obj ) &&
obj.length > 0 &&
Object.hasOwn( obj[ 0 ], 'key' ) &&
Object.hasOwn( obj[ 0 ], 'value' )
) {
// We likely dealing with an array of objects with key/value pairs (like post meta data)
const item = obj.find( ( item ) => item.key === propertyName );
return item?.value;
}
return undefined;
}
}}
Start
@ -116,10 +133,10 @@ __ "skipped"
IdentifierPath
= variable:Identifier accessor:(__ "." __ Identifier)* {
const path = variable.split( '.' );
let result = path.reduce( ( nextObject, propertyName ) => nextObject[ propertyName ], options.context );
let result = path.reduce( getPropertyValue, options.context );
for ( let i = 0; i < accessor.length; i++ ) {
result = result[ accessor[ i ][ 3 ] ];
result = getPropertyValue( result, accessor[ i ][ 3 ] );
}
return result;

View File

@ -172,6 +172,25 @@ describe( 'evaluate', () => {
expect( result ).toEqual( 'baz' );
} );
it( 'should evaluate a nested context property with a key/value pair array (like meta_data)', () => {
const result = evaluate( 'foo.bar.baz', {
foo: {
bar: [
{
key: 'bee',
value: 'boo',
},
{
key: 'baz',
value: 'qux',
},
],
},
} );
expect( result ).toEqual( 'qux' );
} );
it( 'should evaluate a NOT expression', () => {
const result = evaluate( '!foo', {
foo: true,