@@ -327,7 +327,7 @@ function transformQueryKeyValue(className, key, value, schema, count = false) {
327
327
}
328
328
329
329
// Handle query constraints
330
- const transformedConstraint = transformConstraint ( value , field , count ) ;
330
+ const transformedConstraint = transformConstraint ( value , field , key , count ) ;
331
331
if ( transformedConstraint !== CannotTransform ) {
332
332
if ( transformedConstraint . $text ) {
333
333
return { key : '$text' , value : transformedConstraint . $text } ;
@@ -651,12 +651,15 @@ function transformTopLevelAtom(atom, field) {
651
651
// If it is not a valid constraint but it could be a valid something
652
652
// else, return CannotTransform.
653
653
// inArray is whether this is an array field.
654
- function transformConstraint ( constraint , field , count = false ) {
654
+ function transformConstraint ( constraint , field , key , count = false ) {
655
655
const inArray = field && field . type && field . type === 'Array' ;
656
+ // Check wether the given key has `.`
657
+ const isNestedKey = key . indexOf ( '.' ) > - 1 ;
656
658
if ( typeof constraint !== 'object' || ! constraint ) {
657
659
return CannotTransform ;
658
660
}
659
- const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom ;
661
+ // For inArray or nested key, we need to transform the interior atom
662
+ const transformFunction = ( inArray || isNestedKey ) ? transformInteriorAtom : transformTopLevelAtom ;
660
663
const transformer = atom => {
661
664
const result = transformFunction ( atom , field ) ;
662
665
if ( result === CannotTransform ) {
@@ -668,18 +671,18 @@ function transformConstraint(constraint, field, count = false) {
668
671
// This is a hack so that:
669
672
// $regex is handled before $options
670
673
// $nearSphere is handled before $maxDistance
671
- var keys = Object . keys ( constraint ) . sort ( ) . reverse ( ) ;
674
+ var constraintKeys = Object . keys ( constraint ) . sort ( ) . reverse ( ) ;
672
675
var answer = { } ;
673
- for ( var key of keys ) {
674
- switch ( key ) {
676
+ for ( var constraintKey of constraintKeys ) {
677
+ switch ( constraintKey ) {
675
678
case '$lt' :
676
679
case '$lte' :
677
680
case '$gt' :
678
681
case '$gte' :
679
682
case '$exists' :
680
683
case '$ne' :
681
684
case '$eq' : {
682
- const val = constraint [ key ] ;
685
+ const val = constraint [ constraintKey ] ;
683
686
if ( val && typeof val === 'object' && val . $relativeTime ) {
684
687
if ( field && field . type !== 'Date' ) {
685
688
throw new Parse . Error (
@@ -688,7 +691,7 @@ function transformConstraint(constraint, field, count = false) {
688
691
) ;
689
692
}
690
693
691
- switch ( key ) {
694
+ switch ( constraintKey ) {
692
695
case '$exists' :
693
696
case '$ne' :
694
697
case '$eq' :
@@ -700,28 +703,28 @@ function transformConstraint(constraint, field, count = false) {
700
703
701
704
const parserResult = Utils . relativeTimeToDate ( val . $relativeTime ) ;
702
705
if ( parserResult . status === 'success' ) {
703
- answer [ key ] = parserResult . result ;
706
+ answer [ constraintKey ] = parserResult . result ;
704
707
break ;
705
708
}
706
709
707
710
log . info ( 'Error while parsing relative date' , parserResult ) ;
708
711
throw new Parse . Error (
709
712
Parse . Error . INVALID_JSON ,
710
- `bad $relativeTime (${ key } ) value. ${ parserResult . info } `
713
+ `bad $relativeTime (${ constraintKey } ) value. ${ parserResult . info } `
711
714
) ;
712
715
}
713
716
714
- answer [ key ] = transformer ( val ) ;
717
+ answer [ constraintKey ] = transformer ( val ) ;
715
718
break ;
716
719
}
717
720
718
721
case '$in' :
719
722
case '$nin' : {
720
- const arr = constraint [ key ] ;
723
+ const arr = constraint [ constraintKey ] ;
721
724
if ( ! ( arr instanceof Array ) ) {
722
- throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad ' + key + ' value' ) ;
725
+ throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad ' + constraintKey + ' value' ) ;
723
726
}
724
- answer [ key ] = _ . flatMap ( arr , value => {
727
+ answer [ constraintKey ] = _ . flatMap ( arr , value => {
725
728
return ( atom => {
726
729
if ( Array . isArray ( atom ) ) {
727
730
return value . map ( transformer ) ;
@@ -733,13 +736,13 @@ function transformConstraint(constraint, field, count = false) {
733
736
break ;
734
737
}
735
738
case '$all' : {
736
- const arr = constraint [ key ] ;
739
+ const arr = constraint [ constraintKey ] ;
737
740
if ( ! ( arr instanceof Array ) ) {
738
- throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad ' + key + ' value' ) ;
741
+ throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad ' + constraintKey + ' value' ) ;
739
742
}
740
- answer [ key ] = arr . map ( transformInteriorAtom ) ;
743
+ answer [ constraintKey ] = arr . map ( transformInteriorAtom ) ;
741
744
742
- const values = answer [ key ] ;
745
+ const values = answer [ constraintKey ] ;
743
746
if ( isAnyValueRegex ( values ) && ! isAllValuesRegexOrNone ( values ) ) {
744
747
throw new Parse . Error (
745
748
Parse . Error . INVALID_JSON ,
@@ -750,15 +753,15 @@ function transformConstraint(constraint, field, count = false) {
750
753
break ;
751
754
}
752
755
case '$regex' :
753
- var s = constraint [ key ] ;
756
+ var s = constraint [ constraintKey ] ;
754
757
if ( typeof s !== 'string' ) {
755
758
throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad regex: ' + s ) ;
756
759
}
757
- answer [ key ] = s ;
760
+ answer [ constraintKey ] = s ;
758
761
break ;
759
762
760
763
case '$containedBy' : {
761
- const arr = constraint [ key ] ;
764
+ const arr = constraint [ constraintKey ] ;
762
765
if ( ! ( arr instanceof Array ) ) {
763
766
throw new Parse . Error ( Parse . Error . INVALID_JSON , `bad $containedBy: should be an array` ) ;
764
767
}
@@ -768,87 +771,87 @@ function transformConstraint(constraint, field, count = false) {
768
771
break ;
769
772
}
770
773
case '$options' :
771
- answer [ key ] = constraint [ key ] ;
774
+ answer [ constraintKey ] = constraint [ constraintKey ] ;
772
775
break ;
773
776
774
777
case '$text' : {
775
- const search = constraint [ key ] . $search ;
778
+ const search = constraint [ constraintKey ] . $search ;
776
779
if ( typeof search !== 'object' ) {
777
780
throw new Parse . Error ( Parse . Error . INVALID_JSON , `bad $text: $search, should be object` ) ;
778
781
}
779
782
if ( ! search . $term || typeof search . $term !== 'string' ) {
780
783
throw new Parse . Error ( Parse . Error . INVALID_JSON , `bad $text: $term, should be string` ) ;
781
784
} else {
782
- answer [ key ] = {
785
+ answer [ constraintKey ] = {
783
786
$search : search . $term ,
784
787
} ;
785
788
}
786
789
if ( search . $language && typeof search . $language !== 'string' ) {
787
790
throw new Parse . Error ( Parse . Error . INVALID_JSON , `bad $text: $language, should be string` ) ;
788
791
} else if ( search . $language ) {
789
- answer [ key ] . $language = search . $language ;
792
+ answer [ constraintKey ] . $language = search . $language ;
790
793
}
791
794
if ( search . $caseSensitive && typeof search . $caseSensitive !== 'boolean' ) {
792
795
throw new Parse . Error (
793
796
Parse . Error . INVALID_JSON ,
794
797
`bad $text: $caseSensitive, should be boolean`
795
798
) ;
796
799
} else if ( search . $caseSensitive ) {
797
- answer [ key ] . $caseSensitive = search . $caseSensitive ;
800
+ answer [ constraintKey ] . $caseSensitive = search . $caseSensitive ;
798
801
}
799
802
if ( search . $diacriticSensitive && typeof search . $diacriticSensitive !== 'boolean' ) {
800
803
throw new Parse . Error (
801
804
Parse . Error . INVALID_JSON ,
802
805
`bad $text: $diacriticSensitive, should be boolean`
803
806
) ;
804
807
} else if ( search . $diacriticSensitive ) {
805
- answer [ key ] . $diacriticSensitive = search . $diacriticSensitive ;
808
+ answer [ constraintKey ] . $diacriticSensitive = search . $diacriticSensitive ;
806
809
}
807
810
break ;
808
811
}
809
812
case '$nearSphere' : {
810
- const point = constraint [ key ] ;
813
+ const point = constraint [ constraintKey ] ;
811
814
if ( count ) {
812
815
answer . $geoWithin = {
813
816
$centerSphere : [ [ point . longitude , point . latitude ] , constraint . $maxDistance ] ,
814
817
} ;
815
818
} else {
816
- answer [ key ] = [ point . longitude , point . latitude ] ;
819
+ answer [ constraintKey ] = [ point . longitude , point . latitude ] ;
817
820
}
818
821
break ;
819
822
}
820
823
case '$maxDistance' : {
821
824
if ( count ) {
822
825
break ;
823
826
}
824
- answer [ key ] = constraint [ key ] ;
827
+ answer [ constraintKey ] = constraint [ constraintKey ] ;
825
828
break ;
826
829
}
827
830
// The SDKs don't seem to use these but they are documented in the
828
831
// REST API docs.
829
832
case '$maxDistanceInRadians' :
830
- answer [ '$maxDistance' ] = constraint [ key ] ;
833
+ answer [ '$maxDistance' ] = constraint [ constraintKey ] ;
831
834
break ;
832
835
case '$maxDistanceInMiles' :
833
- answer [ '$maxDistance' ] = constraint [ key ] / 3959 ;
836
+ answer [ '$maxDistance' ] = constraint [ constraintKey ] / 3959 ;
834
837
break ;
835
838
case '$maxDistanceInKilometers' :
836
- answer [ '$maxDistance' ] = constraint [ key ] / 6371 ;
839
+ answer [ '$maxDistance' ] = constraint [ constraintKey ] / 6371 ;
837
840
break ;
838
841
839
842
case '$select' :
840
843
case '$dontSelect' :
841
844
throw new Parse . Error (
842
845
Parse . Error . COMMAND_UNAVAILABLE ,
843
- 'the ' + key + ' constraint is not supported yet'
846
+ 'the ' + constraintKey + ' constraint is not supported yet'
844
847
) ;
845
848
846
849
case '$within' :
847
- var box = constraint [ key ] [ '$box' ] ;
850
+ var box = constraint [ constraintKey ] [ '$box' ] ;
848
851
if ( ! box || box . length != 2 ) {
849
852
throw new Parse . Error ( Parse . Error . INVALID_JSON , 'malformatted $within arg' ) ;
850
853
}
851
- answer [ key ] = {
854
+ answer [ constraintKey ] = {
852
855
$box : [
853
856
[ box [ 0 ] . longitude , box [ 0 ] . latitude ] ,
854
857
[ box [ 1 ] . longitude , box [ 1 ] . latitude ] ,
@@ -857,8 +860,8 @@ function transformConstraint(constraint, field, count = false) {
857
860
break ;
858
861
859
862
case '$geoWithin' : {
860
- const polygon = constraint [ key ] [ '$polygon' ] ;
861
- const centerSphere = constraint [ key ] [ '$centerSphere' ] ;
863
+ const polygon = constraint [ constraintKey ] [ '$polygon' ] ;
864
+ const centerSphere = constraint [ constraintKey ] [ '$centerSphere' ] ;
862
865
if ( polygon !== undefined ) {
863
866
let points ;
864
867
if ( typeof polygon === 'object' && polygon . __type === 'Polygon' ) {
@@ -895,7 +898,7 @@ function transformConstraint(constraint, field, count = false) {
895
898
}
896
899
return [ point . longitude , point . latitude ] ;
897
900
} ) ;
898
- answer [ key ] = {
901
+ answer [ constraintKey ] = {
899
902
$polygon : points ,
900
903
} ;
901
904
} else if ( centerSphere !== undefined ) {
@@ -924,14 +927,14 @@ function transformConstraint(constraint, field, count = false) {
924
927
'bad $geoWithin value; $centerSphere distance invalid'
925
928
) ;
926
929
}
927
- answer [ key ] = {
930
+ answer [ constraintKey ] = {
928
931
$centerSphere : [ [ point . longitude , point . latitude ] , distance ] ,
929
932
} ;
930
933
}
931
934
break ;
932
935
}
933
936
case '$geoIntersects' : {
934
- const point = constraint [ key ] [ '$point' ] ;
937
+ const point = constraint [ constraintKey ] [ '$point' ] ;
935
938
if ( ! GeoPointCoder . isValidJSON ( point ) ) {
936
939
throw new Parse . Error (
937
940
Parse . Error . INVALID_JSON ,
@@ -940,7 +943,7 @@ function transformConstraint(constraint, field, count = false) {
940
943
} else {
941
944
Parse . GeoPoint . _validate ( point . latitude , point . longitude ) ;
942
945
}
943
- answer [ key ] = {
946
+ answer [ constraintKey ] = {
944
947
$geometry : {
945
948
type : 'Point' ,
946
949
coordinates : [ point . longitude , point . latitude ] ,
@@ -949,8 +952,8 @@ function transformConstraint(constraint, field, count = false) {
949
952
break ;
950
953
}
951
954
default :
952
- if ( key . match ( / ^ \$ + / ) ) {
953
- throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad constraint: ' + key ) ;
955
+ if ( constraintKey . match ( / ^ \$ + / ) ) {
956
+ throw new Parse . Error ( Parse . Error . INVALID_JSON , 'bad constraint: ' + constraintKey ) ;
954
957
}
955
958
return CannotTransform ;
956
959
}
0 commit comments