@@ -11,20 +11,16 @@ var Parse = require('parse/node').Parse;
11
11
//
12
12
// There are several options that can help transform:
13
13
//
14
- // query: true indicates that query constraints like $lt are allowed in
15
- // the value.
16
- //
17
14
// update: true indicates that __op operators like Add and Delete
18
15
// in the value are converted to a mongo update form. Otherwise they are
19
16
// converted to static data.
20
17
//
21
18
// validate: true indicates that key names are to be validated.
22
19
//
23
20
// Returns an object with {key: key, value: value}.
24
- export function transformKeyValue ( schema , className , restKey , restValue , {
21
+ function transformKeyValue ( schema , className , restKey , restValue , {
25
22
inArray,
26
23
inObject,
27
- query,
28
24
update,
29
25
validate,
30
26
} = { } ) {
@@ -66,47 +62,17 @@ export function transformKeyValue(schema, className, restKey, restValue, {
66
62
return { key : key , value : restValue } ;
67
63
break ;
68
64
case '$or' :
69
- if ( ! query ) {
70
- throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME ,
71
- 'you can only use $or in queries' ) ;
72
- }
73
- if ( ! ( restValue instanceof Array ) ) {
74
- throw new Parse . Error ( Parse . Error . INVALID_QUERY ,
75
- 'bad $or format - use an array value' ) ;
76
- }
77
- var mongoSubqueries = restValue . map ( ( s ) => {
78
- return transformWhere ( schema , className , s ) ;
79
- } ) ;
80
- return { key : '$or' , value : mongoSubqueries } ;
65
+ throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME , 'you can only use $or in queries' ) ;
81
66
case '$and' :
82
- if ( ! query ) {
83
- throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME ,
84
- 'you can only use $and in queries' ) ;
85
- }
86
- if ( ! ( restValue instanceof Array ) ) {
87
- throw new Parse . Error ( Parse . Error . INVALID_QUERY ,
88
- 'bad $and format - use an array value' ) ;
89
- }
90
- var mongoSubqueries = restValue . map ( ( s ) => {
91
- return transformWhere ( schema , className , s ) ;
92
- } ) ;
93
- return { key : '$and' , value : mongoSubqueries } ;
67
+ throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME , 'you can only use $and in queries' ) ;
94
68
default :
95
69
// Other auth data
96
70
var authDataMatch = key . match ( / ^ a u t h D a t a \. ( [ a - z A - Z 0 - 9 _ ] + ) \. i d $ / ) ;
97
71
if ( authDataMatch ) {
98
- if ( query ) {
99
- var provider = authDataMatch [ 1 ] ;
100
- // Special-case auth data.
101
- return { key : '_auth_data_' + provider + '.id' , value : restValue } ;
102
- }
103
- throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME ,
104
- 'can only query on ' + key ) ;
105
- break ;
106
- } ;
72
+ throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME , 'can only query on ' + key ) ;
73
+ }
107
74
if ( validate && ! key . match ( / ^ [ a - z A - Z ] [ a - z A - Z 0 - 9 _ \. ] * $ / ) ) {
108
- throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME ,
109
- 'invalid key name: ' + key ) ;
75
+ throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME , 'invalid key name: ' + key ) ;
110
76
}
111
77
}
112
78
@@ -123,20 +89,6 @@ export function transformKeyValue(schema, className, restKey, restValue, {
123
89
}
124
90
var expectedTypeIsArray = ( expected && expected . type === 'Array' ) ;
125
91
126
- // Handle query constraints
127
- if ( query ) {
128
- value = transformConstraint ( restValue , expectedTypeIsArray ) ;
129
- if ( value !== CannotTransform ) {
130
- return { key : key , value : value } ;
131
- }
132
- }
133
-
134
- if ( expectedTypeIsArray && query && ! ( restValue instanceof Array ) ) {
135
- return {
136
- key : key , value : { '$all' : [ restValue ] }
137
- } ;
138
- }
139
-
140
92
// Handle atomic values
141
93
var value = transformAtom ( restValue , false , { inArray, inObject } ) ;
142
94
if ( value !== CannotTransform ) {
@@ -154,10 +106,6 @@ export function transformKeyValue(schema, className, restKey, restValue, {
154
106
155
107
// Handle arrays
156
108
if ( restValue instanceof Array ) {
157
- if ( query ) {
158
- throw new Parse . Error ( Parse . Error . INVALID_JSON ,
159
- 'cannot use array as query param' ) ;
160
- }
161
109
value = restValue . map ( ( restObj ) => {
162
110
var out = transformKeyValue ( schema , className , restKey , restObj , { inArray : true } ) ;
163
111
return out . value ;
@@ -182,20 +130,105 @@ export function transformKeyValue(schema, className, restKey, restValue, {
182
130
return { key : key , value : value } ;
183
131
}
184
132
133
+ const valueAsDate = value => {
134
+ if ( typeof value === 'string' ) {
135
+ return new Date ( value ) ;
136
+ } else if ( value instanceof Date ) {
137
+ return value ;
138
+ }
139
+ return false ;
140
+ }
141
+
142
+ function transformQueryKeyValue ( className , key , value , { validate } = { } , schema ) {
143
+ switch ( key ) {
144
+ case 'createdAt' :
145
+ if ( valueAsDate ( value ) ) {
146
+ return { key : '_created_at' , value : valueAsDate ( value ) }
147
+ }
148
+ key = '_created_at' ;
149
+ break ;
150
+ case 'updatedAt' :
151
+ if ( valueAsDate ( value ) ) {
152
+ return { key : '_updated_at' , value : valueAsDate ( value ) }
153
+ }
154
+ key = '_updated_at' ;
155
+ break ;
156
+ case 'expiresAt' :
157
+ if ( valueAsDate ( value ) ) {
158
+ return { key : 'expiresAt' , value : valueAsDate ( value ) }
159
+ }
160
+ break ;
161
+ case 'objectId' : return { key : '_id' , value}
162
+ case 'sessionToken' : return { key : '_session_token' , value}
163
+ case '_rperm' :
164
+ case '_wperm' :
165
+ case '_perishable_token' :
166
+ case '_email_verify_token' : return { key, value}
167
+ case '$or' :
168
+ if ( ! ( value instanceof Array ) ) {
169
+ throw new Parse . Error ( Parse . Error . INVALID_QUERY , 'bad $or format - use an array value' ) ;
170
+ }
171
+ return { key : '$or' , value : value . map ( subQuery => transformWhere ( className , subQuery , { } , schema ) ) } ;
172
+ case '$and' :
173
+ if ( ! ( value instanceof Array ) ) {
174
+ throw new Parse . Error ( Parse . Error . INVALID_QUERY , 'bad $and format - use an array value' ) ;
175
+ }
176
+ return { key : '$and' , value : value . map ( subQuery => transformWhere ( className , subQuery , { } , schema ) ) } ;
177
+ default :
178
+ // Other auth data
179
+ const authDataMatch = key . match ( / ^ a u t h D a t a \. ( [ a - z A - Z 0 - 9 _ ] + ) \. i d $ / ) ;
180
+ if ( authDataMatch ) {
181
+ const provider = authDataMatch [ 1 ] ;
182
+ // Special-case auth data.
183
+ return { key : `_auth_data_${ provider } .id` , value} ;
184
+ }
185
+ if ( validate && ! key . match ( / ^ [ a - z A - Z ] [ a - z A - Z 0 - 9 _ \. ] * $ / ) ) {
186
+ throw new Parse . Error ( Parse . Error . INVALID_KEY_NAME , 'invalid key name: ' + key ) ;
187
+ }
188
+ }
189
+
190
+ const expectedTypeIsArray =
191
+ schema &&
192
+ schema . fields [ key ] &&
193
+ schema . fields [ key ] . type === 'Array' ;
194
+
195
+ const expectedTypeIsPointer =
196
+ schema &&
197
+ schema . fields [ key ] &&
198
+ schema . fields [ key ] . type === 'Pointer' ;
199
+
200
+ if ( expectedTypeIsPointer || ! schema && value && value . __type === 'Pointer' ) {
201
+ key = '_p_' + key ;
202
+ }
203
+
204
+ // Handle query constraints
205
+ if ( transformConstraint ( value , expectedTypeIsArray ) !== CannotTransform ) {
206
+ return { key, value : transformConstraint ( value , expectedTypeIsArray ) } ;
207
+ }
208
+
209
+ if ( expectedTypeIsArray && ! ( value instanceof Array ) ) {
210
+ return { key, value : { '$all' : [ value ] } } ;
211
+ }
212
+
213
+ // Handle atomic values
214
+ if ( transformAtom ( value , false ) !== CannotTransform ) {
215
+ return { key, value : transformAtom ( value , false ) } ;
216
+ } else {
217
+ throw new Parse . Error ( Parse . Error . INVALID_JSON , `You cannot use ${ value } as a query parameter.` ) ;
218
+ }
219
+ }
185
220
186
221
// Main exposed method to help run queries.
187
222
// restWhere is the "where" clause in REST API form.
188
223
// Returns the mongo form of the query.
189
224
// Throws a Parse.Error if the input query is invalid.
190
- function transformWhere ( schema , className , restWhere , options = { validate : true } ) {
225
+ function transformWhere ( className , restWhere , { validate = true } = { } , schema ) {
191
226
let mongoWhere = { } ;
192
227
if ( restWhere [ 'ACL' ] ) {
193
228
throw new Parse . Error ( Parse . Error . INVALID_QUERY , 'Cannot query on ACL.' ) ;
194
229
}
195
- let transformKeyOptions = { query : true } ;
196
- transformKeyOptions . validate = options . validate ;
197
230
for ( let restKey in restWhere ) {
198
- let out = transformKeyValue ( schema , className , restKey , restWhere [ restKey ] , transformKeyOptions ) ;
231
+ let out = transformQueryKeyValue ( className , restKey , restWhere [ restKey ] , { validate } , schema ) ;
199
232
mongoWhere [ out . key ] = out . value ;
200
233
}
201
234
return mongoWhere ;
0 commit comments