@onchaindb/sdk 0.4.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/.claude/settings.local.json +10 -2
  2. package/README.md +422 -355
  3. package/dist/batch.d.ts +1 -10
  4. package/dist/batch.d.ts.map +1 -1
  5. package/dist/batch.js +4 -26
  6. package/dist/batch.js.map +1 -1
  7. package/dist/client.d.ts +29 -43
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +199 -323
  10. package/dist/client.js.map +1 -1
  11. package/dist/database.d.ts +14 -131
  12. package/dist/database.d.ts.map +1 -1
  13. package/dist/database.js +35 -131
  14. package/dist/database.js.map +1 -1
  15. package/dist/index.d.ts +6 -9
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -15
  18. package/dist/index.js.map +1 -1
  19. package/dist/query-sdk/ConditionBuilder.d.ts +3 -11
  20. package/dist/query-sdk/ConditionBuilder.d.ts.map +1 -1
  21. package/dist/query-sdk/ConditionBuilder.js +10 -48
  22. package/dist/query-sdk/ConditionBuilder.js.map +1 -1
  23. package/dist/query-sdk/NestedBuilders.d.ts +33 -30
  24. package/dist/query-sdk/NestedBuilders.d.ts.map +1 -1
  25. package/dist/query-sdk/NestedBuilders.js +46 -43
  26. package/dist/query-sdk/NestedBuilders.js.map +1 -1
  27. package/dist/query-sdk/QueryBuilder.d.ts +4 -2
  28. package/dist/query-sdk/QueryBuilder.d.ts.map +1 -1
  29. package/dist/query-sdk/QueryBuilder.js +47 -169
  30. package/dist/query-sdk/QueryBuilder.js.map +1 -1
  31. package/dist/query-sdk/QueryResult.d.ts +0 -38
  32. package/dist/query-sdk/QueryResult.d.ts.map +1 -1
  33. package/dist/query-sdk/QueryResult.js +1 -227
  34. package/dist/query-sdk/QueryResult.js.map +1 -1
  35. package/dist/query-sdk/index.d.ts +1 -1
  36. package/dist/query-sdk/index.d.ts.map +1 -1
  37. package/dist/query-sdk/index.js.map +1 -1
  38. package/dist/query-sdk/operators.d.ts +32 -28
  39. package/dist/query-sdk/operators.d.ts.map +1 -1
  40. package/dist/query-sdk/operators.js +45 -155
  41. package/dist/query-sdk/operators.js.map +1 -1
  42. package/dist/types.d.ts +153 -1
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js.map +1 -1
  45. package/jest.config.js +4 -0
  46. package/package.json +1 -1
  47. package/skills.md +0 -1
  48. package/src/client.ts +243 -745
  49. package/src/database.ts +70 -493
  50. package/src/index.ts +40 -193
  51. package/src/query-sdk/ConditionBuilder.ts +37 -89
  52. package/src/query-sdk/NestedBuilders.ts +90 -92
  53. package/src/query-sdk/QueryBuilder.ts +59 -218
  54. package/src/query-sdk/QueryResult.ts +4 -330
  55. package/src/query-sdk/README.md +214 -583
  56. package/src/query-sdk/index.ts +1 -1
  57. package/src/query-sdk/operators.ts +91 -200
  58. package/src/query-sdk/tests/FieldConditionBuilder.test.ts +70 -71
  59. package/src/query-sdk/tests/LogicalOperator.test.ts +43 -82
  60. package/src/query-sdk/tests/NestedBuilders.test.ts +229 -309
  61. package/src/query-sdk/tests/QueryBuilder.test.ts +5 -5
  62. package/src/query-sdk/tests/QueryResult.test.ts +41 -435
  63. package/src/query-sdk/tests/comprehensive.test.ts +4 -185
  64. package/src/tests/client-requests.test.ts +280 -0
  65. package/src/tests/client-validation.test.ts +80 -0
  66. package/src/types.ts +229 -8
  67. package/src/batch.ts +0 -257
  68. package/src/query-sdk/dist/ConditionBuilder.d.ts +0 -22
  69. package/src/query-sdk/dist/ConditionBuilder.js +0 -90
  70. package/src/query-sdk/dist/FieldConditionBuilder.d.ts +0 -1
  71. package/src/query-sdk/dist/FieldConditionBuilder.js +0 -6
  72. package/src/query-sdk/dist/NestedBuilders.d.ts +0 -43
  73. package/src/query-sdk/dist/NestedBuilders.js +0 -144
  74. package/src/query-sdk/dist/OnChainDB.d.ts +0 -19
  75. package/src/query-sdk/dist/OnChainDB.js +0 -123
  76. package/src/query-sdk/dist/QueryBuilder.d.ts +0 -70
  77. package/src/query-sdk/dist/QueryBuilder.js +0 -295
  78. package/src/query-sdk/dist/QueryResult.d.ts +0 -52
  79. package/src/query-sdk/dist/QueryResult.js +0 -293
  80. package/src/query-sdk/dist/SelectionBuilder.d.ts +0 -20
  81. package/src/query-sdk/dist/SelectionBuilder.js +0 -80
  82. package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +0 -27
  83. package/src/query-sdk/dist/adapters/HttpClientAdapter.js +0 -170
  84. package/src/query-sdk/dist/index.d.ts +0 -36
  85. package/src/query-sdk/dist/index.js +0 -27
  86. package/src/query-sdk/dist/operators.d.ts +0 -56
  87. package/src/query-sdk/dist/operators.js +0 -289
  88. package/src/query-sdk/dist/tests/setup.d.ts +0 -15
  89. package/src/query-sdk/dist/tests/setup.js +0 -46
  90. package/src/query-sdk/jest.config.js +0 -25
  91. package/src/query-sdk/package.json +0 -46
  92. package/src/query-sdk/tests/aggregations.test.ts +0 -653
  93. package/src/query-sdk/tests/integration.test.ts +0 -608
  94. package/src/query-sdk/tests/operators.test.ts +0 -327
  95. package/src/query-sdk/tests/unit.test.ts +0 -794
  96. package/src/query-sdk/tsconfig.json +0 -26
  97. package/src/query-sdk/yarn.lock +0 -3092
@@ -1,653 +0,0 @@
1
- import { QueryBuilder, FieldConditionBuilder, LogicalOperator } from '../index';
2
-
3
- describe('QueryBuilder - Query Building Verification', () => {
4
- const serverUrl = 'http://localhost:3000';
5
- const app = 'testApp';
6
-
7
- describe('Basic query structure', () => {
8
- test('should build correct query request with collection', () => {
9
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
10
-
11
- const request = queryBuilder
12
- .collection('users')
13
- .whereField('email').equals('alice@example.com')
14
- .getQueryRequest();
15
-
16
- expect(request.root).toBe('testApp::users');
17
- expect(request.find).toEqual({
18
- email: { is: 'alice@example.com' }
19
- });
20
- });
21
-
22
- test('should build query with multiple whereField conditions', () => {
23
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
24
-
25
- // Note: chaining whereField overwrites previous condition in current implementation
26
- const request = queryBuilder
27
- .collection('users')
28
- .whereField('active').equals(true)
29
- .getQueryRequest();
30
-
31
- expect(request.find).toEqual({
32
- active: { is: true }
33
- });
34
- });
35
-
36
- test('should build query with limit and offset', () => {
37
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
38
-
39
- const request = queryBuilder
40
- .collection('orders')
41
- .whereField('status').equals('completed')
42
- .limit(50)
43
- .offset(100)
44
- .getQueryRequest();
45
-
46
- expect(request.limit).toBe(50);
47
- expect(request.offset).toBe(100);
48
- expect(request.root).toBe('testApp::orders');
49
- });
50
-
51
- test('should build query with orderBy', () => {
52
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
53
-
54
- const request = queryBuilder
55
- .collection('products')
56
- .whereField('category').equals('electronics')
57
- .orderBy('price')
58
- .getQueryRequest();
59
-
60
- expect(request.sortBy).toBe('price');
61
- });
62
-
63
- test('should build query with field selection', () => {
64
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
65
-
66
- const request = queryBuilder
67
- .collection('users')
68
- .whereField('active').equals(true)
69
- .selectFields(['id', 'name', 'email'])
70
- .getQueryRequest();
71
-
72
- expect(request.select).toEqual({
73
- id: true,
74
- name: true,
75
- email: true
76
- });
77
- });
78
-
79
- test('should build query with selectAll', () => {
80
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
81
-
82
- const request = queryBuilder
83
- .collection('users')
84
- .selectAll()
85
- .getQueryRequest();
86
-
87
- expect(request.select).toEqual({});
88
- });
89
- });
90
-
91
- describe('Complex find conditions', () => {
92
- test('should build AND conditions correctly', () => {
93
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
94
-
95
- const request = queryBuilder
96
- .collection('users')
97
- .find(builder =>
98
- LogicalOperator.And([
99
- LogicalOperator.Condition(new FieldConditionBuilder('status').equals('active')),
100
- LogicalOperator.Condition(new FieldConditionBuilder('age').greaterThan(18))
101
- ])
102
- )
103
- .getQueryRequest();
104
-
105
- expect(request.find).toEqual({
106
- and: [
107
- { status: { is: 'active' } },
108
- { age: { greaterThan: 18 } }
109
- ]
110
- });
111
- });
112
-
113
- test('should build OR conditions correctly', () => {
114
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
115
-
116
- const request = queryBuilder
117
- .collection('orders')
118
- .find(builder =>
119
- LogicalOperator.Or([
120
- LogicalOperator.Condition(new FieldConditionBuilder('status').equals('pending')),
121
- LogicalOperator.Condition(new FieldConditionBuilder('status').equals('processing'))
122
- ])
123
- )
124
- .getQueryRequest();
125
-
126
- expect(request.find).toEqual({
127
- or: [
128
- { status: { is: 'pending' } },
129
- { status: { is: 'processing' } }
130
- ]
131
- });
132
- });
133
-
134
- test('should build NOT conditions correctly', () => {
135
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
136
-
137
- const request = queryBuilder
138
- .collection('users')
139
- .find(builder =>
140
- LogicalOperator.Not([
141
- LogicalOperator.Condition(new FieldConditionBuilder('status').equals('banned'))
142
- ])
143
- )
144
- .getQueryRequest();
145
-
146
- expect(request.find).toEqual({
147
- not: [
148
- { status: { is: 'banned' } }
149
- ]
150
- });
151
- });
152
-
153
- test('should build nested AND/OR conditions', () => {
154
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
155
-
156
- const request = queryBuilder
157
- .collection('products')
158
- .find(builder =>
159
- LogicalOperator.And([
160
- LogicalOperator.Condition(new FieldConditionBuilder('active').equals(true)),
161
- LogicalOperator.Or([
162
- LogicalOperator.Condition(new FieldConditionBuilder('category').equals('electronics')),
163
- LogicalOperator.Condition(new FieldConditionBuilder('category').equals('computers'))
164
- ])
165
- ])
166
- )
167
- .getQueryRequest();
168
-
169
- expect(request.find).toEqual({
170
- and: [
171
- { active: { is: true } },
172
- {
173
- or: [
174
- { category: { is: 'electronics' } },
175
- { category: { is: 'computers' } }
176
- ]
177
- }
178
- ]
179
- });
180
- });
181
- });
182
-
183
- describe('WhereClause operators', () => {
184
- test('should build equals condition', () => {
185
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
186
-
187
- const request = queryBuilder
188
- .collection('users')
189
- .whereField('name').equals('John')
190
- .getQueryRequest();
191
-
192
- expect(request.find).toEqual({
193
- name: { is: 'John' }
194
- });
195
- });
196
-
197
- test('should build notEquals condition', () => {
198
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
199
-
200
- const request = queryBuilder
201
- .collection('users')
202
- .whereField('status').notEquals('deleted')
203
- .getQueryRequest();
204
-
205
- expect(request.find).toEqual({
206
- status: { isNot: 'deleted' }
207
- });
208
- });
209
-
210
- test('should build greaterThan condition', () => {
211
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
212
-
213
- const request = queryBuilder
214
- .collection('products')
215
- .whereField('price').greaterThan(100)
216
- .getQueryRequest();
217
-
218
- expect(request.find).toEqual({
219
- price: { greaterThan: 100 }
220
- });
221
- });
222
-
223
- test('should build greaterThanOrEqual condition', () => {
224
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
225
-
226
- const request = queryBuilder
227
- .collection('products')
228
- .whereField('stock').greaterThanOrEqual(10)
229
- .getQueryRequest();
230
-
231
- expect(request.find).toEqual({
232
- stock: { greaterThanOrEqual: 10 }
233
- });
234
- });
235
-
236
- test('should build lessThan condition', () => {
237
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
238
-
239
- const request = queryBuilder
240
- .collection('products')
241
- .whereField('price').lessThan(50)
242
- .getQueryRequest();
243
-
244
- expect(request.find).toEqual({
245
- price: { lessThan: 50 }
246
- });
247
- });
248
-
249
- test('should build lessThanOrEqual condition', () => {
250
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
251
-
252
- const request = queryBuilder
253
- .collection('orders')
254
- .whereField('quantity').lessThanOrEqual(100)
255
- .getQueryRequest();
256
-
257
- expect(request.find).toEqual({
258
- quantity: { lessThanOrEqual: 100 }
259
- });
260
- });
261
-
262
- test('should build contains condition', () => {
263
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
264
-
265
- const request = queryBuilder
266
- .collection('posts')
267
- .whereField('content').contains('blockchain')
268
- .getQueryRequest();
269
-
270
- expect(request.find).toEqual({
271
- content: { includes: 'blockchain' }
272
- });
273
- });
274
-
275
- test('should build startsWith condition', () => {
276
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
277
-
278
- const request = queryBuilder
279
- .collection('users')
280
- .whereField('email').startsWith('admin')
281
- .getQueryRequest();
282
-
283
- expect(request.find).toEqual({
284
- email: { startsWith: 'admin' }
285
- });
286
- });
287
-
288
- test('should build endsWith condition', () => {
289
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
290
-
291
- const request = queryBuilder
292
- .collection('users')
293
- .whereField('email').endsWith('@example.com')
294
- .getQueryRequest();
295
-
296
- expect(request.find).toEqual({
297
- email: { endsWith: '@example.com' }
298
- });
299
- });
300
-
301
- test('should build in condition', () => {
302
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
303
-
304
- const request = queryBuilder
305
- .collection('orders')
306
- .whereField('status').in(['pending', 'processing', 'shipped'])
307
- .getQueryRequest();
308
-
309
- expect(request.find).toEqual({
310
- status: { in: ['pending', 'processing', 'shipped'] }
311
- });
312
- });
313
-
314
- test('should build notIn condition', () => {
315
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
316
-
317
- const request = queryBuilder
318
- .collection('users')
319
- .whereField('role').notIn(['banned', 'suspended'])
320
- .getQueryRequest();
321
-
322
- expect(request.find).toEqual({
323
- role: { notIn: ['banned', 'suspended'] }
324
- });
325
- });
326
-
327
- test('should build exists condition', () => {
328
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
329
-
330
- const request = queryBuilder
331
- .collection('profiles')
332
- .whereField('avatar').exists()
333
- .getQueryRequest();
334
-
335
- expect(request.find).toEqual({
336
- avatar: { exists: true }
337
- });
338
- });
339
-
340
- test('should build notExists condition', () => {
341
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
342
-
343
- const request = queryBuilder
344
- .collection('profiles')
345
- .whereField('deletedAt').notExists()
346
- .getQueryRequest();
347
-
348
- expect(request.find).toEqual({
349
- deletedAt: { exists: false }
350
- });
351
- });
352
-
353
- test('should build isNull condition', () => {
354
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
355
-
356
- const request = queryBuilder
357
- .collection('orders')
358
- .whereField('cancelledAt').isNull()
359
- .getQueryRequest();
360
-
361
- expect(request.find).toEqual({
362
- cancelledAt: { isNull: true }
363
- });
364
- });
365
-
366
- test('should build isNotNull condition', () => {
367
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
368
-
369
- const request = queryBuilder
370
- .collection('orders')
371
- .whereField('completedAt').isNotNull()
372
- .getQueryRequest();
373
-
374
- expect(request.find).toEqual({
375
- completedAt: { isNull: false }
376
- });
377
- });
378
-
379
- test('should build between condition', () => {
380
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
381
-
382
- const request = queryBuilder
383
- .collection('products')
384
- .whereField('price').between(10, 100)
385
- .getQueryRequest();
386
-
387
- expect(request.find).toEqual({
388
- price: { betweenOp: { from: 10, to: 100 } }
389
- });
390
- });
391
-
392
- test('should build regExpMatches condition', () => {
393
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
394
-
395
- const request = queryBuilder
396
- .collection('logs')
397
- .whereField('message').regExpMatches('^ERROR:.*')
398
- .getQueryRequest();
399
-
400
- expect(request.find).toEqual({
401
- message: { regExpMatches: '^ERROR:.*' }
402
- });
403
- });
404
- });
405
-
406
- describe('Nested field queries', () => {
407
- test('should build nested field condition with dot notation', () => {
408
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
409
-
410
- const request = queryBuilder
411
- .collection('users')
412
- .whereField('profile.country').equals('USA')
413
- .getQueryRequest();
414
-
415
- expect(request.find).toEqual({
416
- profile: {
417
- country: {
418
- is: 'USA'
419
- }
420
- }
421
- });
422
- });
423
-
424
- test('should build deeply nested field condition', () => {
425
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
426
-
427
- const request = queryBuilder
428
- .collection('data')
429
- .whereField('a.b.c.d').greaterThan(100)
430
- .getQueryRequest();
431
-
432
- expect(request.find).toEqual({
433
- a: {
434
- b: {
435
- c: {
436
- d: {
437
- greaterThan: 100
438
- }
439
- }
440
- }
441
- }
442
- });
443
- });
444
- });
445
-
446
- describe('Server-side JOINs', () => {
447
- test('should build simple server join', () => {
448
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
449
-
450
- const request = queryBuilder
451
- .collection('posts')
452
- .whereField('published').equals(true)
453
- .joinOne('author', 'users')
454
- .onField('authorId').equals('userId')
455
- .selectFields(['name', 'email'])
456
- .build()
457
- .getQueryRequest();
458
-
459
- expect(request.root).toBe('testApp::posts');
460
- expect(request.find.author).toBeDefined();
461
- expect(request.find.author.model).toBe('users');
462
- expect(request.find.author.many).toBe(false);
463
- expect(request.find.author.resolve.select).toEqual({
464
- name: true,
465
- email: true
466
- });
467
- });
468
-
469
- test('should build one-to-many join', () => {
470
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
471
-
472
- const request = queryBuilder
473
- .collection('users')
474
- .joinMany('posts', 'posts')
475
- .onField('authorId').equals('userId')
476
- .selectAll()
477
- .build()
478
- .getQueryRequest();
479
-
480
- expect(request.find.posts).toBeDefined();
481
- expect(request.find.posts.model).toBe('posts');
482
- expect(request.find.posts.many).toBe(true);
483
- });
484
-
485
- test('should build multiple joins', () => {
486
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
487
-
488
- const request = queryBuilder
489
- .collection('posts')
490
- .joinOne('author', 'users')
491
- .selectFields(['name'])
492
- .build()
493
- .joinMany('comments', 'comments')
494
- .selectFields(['text', 'createdAt'])
495
- .build()
496
- .getQueryRequest();
497
-
498
- expect(request.find.author).toBeDefined();
499
- expect(request.find.author.many).toBe(false);
500
- expect(request.find.comments).toBeDefined();
501
- expect(request.find.comments.many).toBe(true);
502
- });
503
- });
504
-
505
- describe('includeHistory', () => {
506
- test('should include history flag when set to true', () => {
507
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
508
-
509
- const request = queryBuilder
510
- .collection('documents')
511
- .whereField('id').equals('doc123')
512
- .includeHistory(true)
513
- .getQueryRequest();
514
-
515
- expect((request as any).include_history).toBe(true);
516
- });
517
-
518
- test('should not include history flag when not set', () => {
519
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
520
-
521
- const request = queryBuilder
522
- .collection('documents')
523
- .whereField('id').equals('doc123')
524
- .getQueryRequest();
525
-
526
- expect((request as any).include_history).toBeUndefined();
527
- });
528
- });
529
-
530
- describe('Query validation', () => {
531
- test('should validate query with find conditions', () => {
532
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
533
-
534
- queryBuilder.whereField('name').equals('test');
535
- expect(queryBuilder.isValid()).toBe(true);
536
- });
537
-
538
- test('should validate query with selections only', () => {
539
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
540
-
541
- queryBuilder.selectFields(['id', 'name']);
542
- expect(queryBuilder.isValid()).toBe(true);
543
- });
544
-
545
- test('should invalidate empty query', () => {
546
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
547
-
548
- expect(queryBuilder.isValid()).toBe(false);
549
- });
550
- });
551
-
552
- describe('Query cloning', () => {
553
- test('should create independent clone', () => {
554
- const original = new QueryBuilder(undefined, serverUrl, app)
555
- .collection('users')
556
- .whereField('status').equals('active')
557
- .limit(10);
558
-
559
- const cloned = original.clone();
560
-
561
- // Modify clone
562
- cloned.limit(20);
563
- cloned.offset(50);
564
-
565
- const originalRequest = original.getQueryRequest();
566
- const clonedRequest = cloned.getQueryRequest();
567
-
568
- expect(originalRequest.limit).toBe(10);
569
- expect(originalRequest.offset).toBeUndefined();
570
- expect(clonedRequest.limit).toBe(20);
571
- expect(clonedRequest.offset).toBe(50);
572
- });
573
- });
574
-
575
- describe('Full query examples', () => {
576
- test('should build complete e-commerce query', () => {
577
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
578
-
579
- const request = queryBuilder
580
- .collection('orders')
581
- .find(builder =>
582
- LogicalOperator.And([
583
- LogicalOperator.Condition(new FieldConditionBuilder('status').equals('completed')),
584
- LogicalOperator.Condition(new FieldConditionBuilder('total').greaterThan(100)),
585
- LogicalOperator.Or([
586
- LogicalOperator.Condition(new FieldConditionBuilder('paymentMethod').equals('credit_card')),
587
- LogicalOperator.Condition(new FieldConditionBuilder('paymentMethod').equals('paypal'))
588
- ])
589
- ])
590
- )
591
- .selectFields(['id', 'customerId', 'total', 'createdAt'])
592
- .orderBy('createdAt')
593
- .limit(50)
594
- .offset(0)
595
- .getQueryRequest();
596
-
597
- expect(request).toEqual({
598
- find: {
599
- and: [
600
- { status: { is: 'completed' } },
601
- { total: { greaterThan: 100 } },
602
- {
603
- or: [
604
- { paymentMethod: { is: 'credit_card' } },
605
- { paymentMethod: { is: 'paypal' } }
606
- ]
607
- }
608
- ]
609
- },
610
- select: {
611
- id: true,
612
- customerId: true,
613
- total: true,
614
- createdAt: true
615
- },
616
- sortBy: 'createdAt',
617
- limit: 50,
618
- offset: 0,
619
- root: 'testApp::orders'
620
- });
621
- });
622
-
623
- test('should build user search query with joins', () => {
624
- const queryBuilder = new QueryBuilder(undefined, serverUrl, app);
625
-
626
- const request = queryBuilder
627
- .collection('users')
628
- .whereField('profile.verified').equals(true)
629
- .joinMany('posts', 'posts')
630
- .onField('authorId').equals('userId')
631
- .selectFields(['title', 'likes'])
632
- .build()
633
- .joinOne('subscription', 'subscriptions')
634
- .onField('userId').equals('id')
635
- .selectFields(['plan', 'expiresAt'])
636
- .build()
637
- .selectFields(['id', 'name', 'email'])
638
- .limit(20)
639
- .getQueryRequest();
640
-
641
- expect(request.root).toBe('testApp::users');
642
- expect(request.find.profile.verified.is).toBe(true);
643
- expect(request.find.posts.many).toBe(true);
644
- expect(request.find.subscription.many).toBe(false);
645
- expect(request.select).toEqual({
646
- id: true,
647
- name: true,
648
- email: true
649
- });
650
- expect(request.limit).toBe(20);
651
- });
652
- });
653
- });