@joystick.js/db-canary 0.0.0-canary.2250 → 0.0.0-canary.2251

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 (69) hide show
  1. package/dist/server/lib/operations/find.js +1 -1
  2. package/dist/server/lib/operations/find_one.js +1 -1
  3. package/package.json +2 -2
  4. package/src/server/lib/operations/find.js +144 -15
  5. package/src/server/lib/operations/find_one.js +144 -14
  6. package/test_data_api_key_1758233848259_cglfjzhou/data.mdb +0 -0
  7. package/test_data_api_key_1758233848259_cglfjzhou/lock.mdb +0 -0
  8. package/test_data_api_key_1758233848502_urlje2utd/data.mdb +0 -0
  9. package/test_data_api_key_1758233848502_urlje2utd/lock.mdb +0 -0
  10. package/test_data_api_key_1758233848738_mtcpfe5ns/data.mdb +0 -0
  11. package/test_data_api_key_1758233848738_mtcpfe5ns/lock.mdb +0 -0
  12. package/test_data_api_key_1758233848856_9g97p6gag/data.mdb +0 -0
  13. package/test_data_api_key_1758233848856_9g97p6gag/lock.mdb +0 -0
  14. package/test_data_api_key_1758233857008_0tl9zzhj8/data.mdb +0 -0
  15. package/test_data_api_key_1758233857008_0tl9zzhj8/lock.mdb +0 -0
  16. package/test_data_api_key_1758233857120_60c2f2uhu/data.mdb +0 -0
  17. package/test_data_api_key_1758233857120_60c2f2uhu/lock.mdb +0 -0
  18. package/test_data_api_key_1758233857232_aw7fkqgd9/data.mdb +0 -0
  19. package/test_data_api_key_1758233857232_aw7fkqgd9/lock.mdb +0 -0
  20. package/test_data_api_key_1758234881285_4aeflubjb/data.mdb +0 -0
  21. package/test_data_api_key_1758234881285_4aeflubjb/lock.mdb +0 -0
  22. package/test_data_api_key_1758234881520_kb0amvtqb/data.mdb +0 -0
  23. package/test_data_api_key_1758234881520_kb0amvtqb/lock.mdb +0 -0
  24. package/test_data_api_key_1758234881756_k04gfv2va/data.mdb +0 -0
  25. package/test_data_api_key_1758234881756_k04gfv2va/lock.mdb +0 -0
  26. package/test_data_api_key_1758234881876_wn90dpo1z/data.mdb +0 -0
  27. package/test_data_api_key_1758234881876_wn90dpo1z/lock.mdb +0 -0
  28. package/test_data_api_key_1758234889461_26xz3dmbr/data.mdb +0 -0
  29. package/test_data_api_key_1758234889461_26xz3dmbr/lock.mdb +0 -0
  30. package/test_data_api_key_1758234889572_uziz7e0p5/data.mdb +0 -0
  31. package/test_data_api_key_1758234889572_uziz7e0p5/lock.mdb +0 -0
  32. package/test_data_api_key_1758234889684_5f9wmposh/data.mdb +0 -0
  33. package/test_data_api_key_1758234889684_5f9wmposh/lock.mdb +0 -0
  34. package/test_data_api_key_1758235657729_prwgm6mxr/data.mdb +0 -0
  35. package/test_data_api_key_1758235657729_prwgm6mxr/lock.mdb +0 -0
  36. package/test_data_api_key_1758235657961_rc2da0dc2/data.mdb +0 -0
  37. package/test_data_api_key_1758235657961_rc2da0dc2/lock.mdb +0 -0
  38. package/test_data_api_key_1758235658193_oqqxm0sny/data.mdb +0 -0
  39. package/test_data_api_key_1758235658193_oqqxm0sny/lock.mdb +0 -0
  40. package/test_data_api_key_1758235658309_vggac1pj6/data.mdb +0 -0
  41. package/test_data_api_key_1758235658309_vggac1pj6/lock.mdb +0 -0
  42. package/test_data_api_key_1758235665968_61ko07dd1/data.mdb +0 -0
  43. package/test_data_api_key_1758235665968_61ko07dd1/lock.mdb +0 -0
  44. package/test_data_api_key_1758235666082_50lrt6sq8/data.mdb +0 -0
  45. package/test_data_api_key_1758235666082_50lrt6sq8/lock.mdb +0 -0
  46. package/test_data_api_key_1758235666194_ykvauwlzh/data.mdb +0 -0
  47. package/test_data_api_key_1758235666194_ykvauwlzh/lock.mdb +0 -0
  48. package/test_data_api_key_1758236187207_9c4paeh09/data.mdb +0 -0
  49. package/test_data_api_key_1758236187207_9c4paeh09/lock.mdb +0 -0
  50. package/test_data_api_key_1758236187441_4n3o3gkkl/data.mdb +0 -0
  51. package/test_data_api_key_1758236187441_4n3o3gkkl/lock.mdb +0 -0
  52. package/test_data_api_key_1758236187672_jt6b21ye0/data.mdb +0 -0
  53. package/test_data_api_key_1758236187672_jt6b21ye0/lock.mdb +0 -0
  54. package/test_data_api_key_1758236187788_oo84fz9u6/data.mdb +0 -0
  55. package/test_data_api_key_1758236187788_oo84fz9u6/lock.mdb +0 -0
  56. package/test_data_api_key_1758236195507_o9zeznwlm/data.mdb +0 -0
  57. package/test_data_api_key_1758236195507_o9zeznwlm/lock.mdb +0 -0
  58. package/test_data_api_key_1758236195619_qsqd60y41/data.mdb +0 -0
  59. package/test_data_api_key_1758236195619_qsqd60y41/lock.mdb +0 -0
  60. package/test_data_api_key_1758236195731_im13iq284/data.mdb +0 -0
  61. package/test_data_api_key_1758236195731_im13iq284/lock.mdb +0 -0
  62. package/tests/server/cluster/master_read_write_operations.test.js +5 -14
  63. package/tests/server/integration/authentication_integration.test.js +18 -10
  64. package/tests/server/integration/backup_integration.test.js +35 -27
  65. package/tests/server/lib/api_key_manager.test.js +88 -32
  66. package/tests/server/lib/development_mode.test.js +2 -2
  67. package/tests/server/lib/operations/admin.test.js +20 -12
  68. package/tests/server/lib/operations/delete_one.test.js +10 -4
  69. package/tests/server/lib/operations/find_array_queries.test.js +261 -0
@@ -0,0 +1,261 @@
1
+ import test from 'ava';
2
+ import find from '../../../../src/server/lib/operations/find.js';
3
+ import find_one from '../../../../src/server/lib/operations/find_one.js';
4
+ import insert_one from '../../../../src/server/lib/operations/insert_one.js';
5
+ import { initialize_database, get_database, cleanup_database } from '../../../../src/server/lib/query_engine.js';
6
+
7
+ test.beforeEach(() => {
8
+ initialize_database('./test_data');
9
+ const db = get_database();
10
+ db.clearSync();
11
+ });
12
+
13
+ test.afterEach(async (t) => {
14
+ await cleanup_database();
15
+ });
16
+
17
+ test('find - should match array field with direct value', async (t) => {
18
+ await insert_one('default', 'products', {
19
+ name: 'MacBook Pro',
20
+ tags: ['laptop', 'apple', 'professional']
21
+ });
22
+ await insert_one('default', 'products', {
23
+ name: 'iPad Pro',
24
+ tags: ['tablet', 'apple', 'professional']
25
+ });
26
+ await insert_one('default', 'products', {
27
+ name: 'Dell XPS',
28
+ tags: ['laptop', 'dell', 'ultrabook']
29
+ });
30
+
31
+ // Test array field matching
32
+ const laptops = await find('default', 'products', { tags: 'laptop' });
33
+ t.is(laptops.length, 2);
34
+ t.true(laptops.some(doc => doc.name === 'MacBook Pro'));
35
+ t.true(laptops.some(doc => doc.name === 'Dell XPS'));
36
+
37
+ const apple_products = await find('default', 'products', { tags: 'apple' });
38
+ t.is(apple_products.length, 2);
39
+ t.true(apple_products.some(doc => doc.name === 'MacBook Pro'));
40
+ t.true(apple_products.some(doc => doc.name === 'iPad Pro'));
41
+ });
42
+
43
+ test('find - should match array field with $in operator', async (t) => {
44
+ await insert_one('default', 'products', {
45
+ name: 'MacBook Pro',
46
+ tags: ['laptop', 'apple', 'professional']
47
+ });
48
+ await insert_one('default', 'products', {
49
+ name: 'iPad Pro',
50
+ tags: ['tablet', 'apple', 'professional']
51
+ });
52
+ await insert_one('default', 'products', {
53
+ name: 'Dell XPS',
54
+ tags: ['laptop', 'dell', 'ultrabook']
55
+ });
56
+
57
+ // Test $in with array fields
58
+ const professional_products = await find('default', 'products', {
59
+ tags: { $in: ['professional'] }
60
+ });
61
+ t.is(professional_products.length, 2);
62
+ t.true(professional_products.some(doc => doc.name === 'MacBook Pro'));
63
+ t.true(professional_products.some(doc => doc.name === 'iPad Pro'));
64
+
65
+ const mobile_products = await find('default', 'products', {
66
+ tags: { $in: ['laptop', 'tablet'] }
67
+ });
68
+ t.is(mobile_products.length, 3);
69
+ });
70
+
71
+ test('find - should match nested array object queries', async (t) => {
72
+ await insert_one('default', 'products', {
73
+ name: 'MacBook Pro',
74
+ reviews: [
75
+ { rating: 5, comment: 'Great laptop!' },
76
+ { rating: 4, comment: 'Good value' }
77
+ ]
78
+ });
79
+ await insert_one('default', 'products', {
80
+ name: 'iPad Pro',
81
+ reviews: [
82
+ { rating: 5, comment: 'Perfect for drawing' },
83
+ { rating: 5, comment: 'Amazing display' }
84
+ ]
85
+ });
86
+ await insert_one('default', 'products', {
87
+ name: 'Dell XPS',
88
+ reviews: [
89
+ { rating: 4, comment: 'Compact and powerful' }
90
+ ]
91
+ });
92
+
93
+ // Test nested array object queries
94
+ const five_star_products = await find('default', 'products', { 'reviews.rating': 5 });
95
+ t.is(five_star_products.length, 2);
96
+ t.true(five_star_products.some(doc => doc.name === 'MacBook Pro'));
97
+ t.true(five_star_products.some(doc => doc.name === 'iPad Pro'));
98
+
99
+ const four_star_products = await find('default', 'products', { 'reviews.rating': 4 });
100
+ t.is(four_star_products.length, 2);
101
+ t.true(four_star_products.some(doc => doc.name === 'MacBook Pro'));
102
+ t.true(four_star_products.some(doc => doc.name === 'Dell XPS'));
103
+ });
104
+
105
+ test('find - should match nested object queries', async (t) => {
106
+ await insert_one('default', 'products', {
107
+ name: 'MacBook Pro',
108
+ specs: { ram: 16, storage: 512, processor: 'M2 Pro' }
109
+ });
110
+ await insert_one('default', 'products', {
111
+ name: 'iPad Pro',
112
+ specs: { ram: 8, storage: 128, processor: 'M2' }
113
+ });
114
+ await insert_one('default', 'products', {
115
+ name: 'Dell XPS',
116
+ specs: { ram: 16, storage: 256, processor: 'Intel i7' }
117
+ });
118
+
119
+ // Test nested object queries
120
+ const high_ram_products = await find('default', 'products', { 'specs.ram': { $gte: 16 } });
121
+ t.is(high_ram_products.length, 2);
122
+ t.true(high_ram_products.some(doc => doc.name === 'MacBook Pro'));
123
+ t.true(high_ram_products.some(doc => doc.name === 'Dell XPS'));
124
+
125
+ const m2_products = await find('default', 'products', { 'specs.processor': { $regex: 'M2' } });
126
+ t.is(m2_products.length, 2);
127
+ t.true(m2_products.some(doc => doc.name === 'MacBook Pro'));
128
+ t.true(m2_products.some(doc => doc.name === 'iPad Pro'));
129
+ });
130
+
131
+ test('find - should handle complex $or queries with arrays', async (t) => {
132
+ await insert_one('default', 'products', {
133
+ name: 'MacBook Pro',
134
+ brand: 'Apple',
135
+ tags: ['laptop', 'professional'],
136
+ specs: { ram: 16 }
137
+ });
138
+ await insert_one('default', 'products', {
139
+ name: 'iPad Pro',
140
+ brand: 'Apple',
141
+ tags: ['tablet', 'professional'],
142
+ specs: { ram: 8 }
143
+ });
144
+ await insert_one('default', 'products', {
145
+ name: 'Dell XPS',
146
+ brand: 'Dell',
147
+ tags: ['laptop', 'ultrabook'],
148
+ specs: { ram: 16 }
149
+ });
150
+
151
+ // Test complex $or with array and nested queries
152
+ const complex_query = await find('default', 'products', {
153
+ $or: [
154
+ { brand: 'Apple' },
155
+ { 'specs.ram': { $gte: 16 } }
156
+ ]
157
+ });
158
+ t.is(complex_query.length, 3); // All products match either condition
159
+
160
+ const array_or_query = await find('default', 'products', {
161
+ $or: [
162
+ { tags: 'professional' },
163
+ { tags: 'ultrabook' }
164
+ ]
165
+ });
166
+ t.is(array_or_query.length, 3); // All products have either tag
167
+ });
168
+
169
+ test('find_one - should work with array field matching', async (t) => {
170
+ await insert_one('default', 'products', {
171
+ name: 'MacBook Pro',
172
+ tags: ['laptop', 'apple', 'professional']
173
+ });
174
+ await insert_one('default', 'products', {
175
+ name: 'iPad Pro',
176
+ tags: ['tablet', 'apple', 'professional']
177
+ });
178
+
179
+ // Test find_one with array field
180
+ const apple_product = await find_one('default', 'products', { tags: 'apple' });
181
+ t.truthy(apple_product);
182
+ t.true(['MacBook Pro', 'iPad Pro'].includes(apple_product.name));
183
+
184
+ const laptop_product = await find_one('default', 'products', { tags: 'laptop' });
185
+ t.truthy(laptop_product);
186
+ t.is(laptop_product.name, 'MacBook Pro');
187
+ });
188
+
189
+ test('find_one - should work with nested array object queries', async (t) => {
190
+ await insert_one('default', 'products', {
191
+ name: 'MacBook Pro',
192
+ reviews: [
193
+ { rating: 5, comment: 'Great laptop!' },
194
+ { rating: 4, comment: 'Good value' }
195
+ ]
196
+ });
197
+ await insert_one('default', 'products', {
198
+ name: 'Dell XPS',
199
+ reviews: [
200
+ { rating: 4, comment: 'Compact and powerful' }
201
+ ]
202
+ });
203
+
204
+ // Test find_one with nested array object query
205
+ const five_star_product = await find_one('default', 'products', { 'reviews.rating': 5 });
206
+ t.truthy(five_star_product);
207
+ t.is(five_star_product.name, 'MacBook Pro');
208
+
209
+ const four_star_product = await find_one('default', 'products', { 'reviews.rating': 4 });
210
+ t.truthy(four_star_product);
211
+ t.true(['MacBook Pro', 'Dell XPS'].includes(four_star_product.name));
212
+ });
213
+
214
+ test('find - should handle array fields with comparison operators', async (t) => {
215
+ await insert_one('default', 'products', {
216
+ name: 'Product A',
217
+ ratings: [1, 2, 3, 4, 5]
218
+ });
219
+ await insert_one('default', 'products', {
220
+ name: 'Product B',
221
+ ratings: [3, 4, 5]
222
+ });
223
+ await insert_one('default', 'products', {
224
+ name: 'Product C',
225
+ ratings: [1, 2]
226
+ });
227
+
228
+ // Test array fields with comparison operators
229
+ const high_rated = await find('default', 'products', { ratings: { $gte: 4 } });
230
+ t.is(high_rated.length, 2);
231
+ t.true(high_rated.some(doc => doc.name === 'Product A'));
232
+ t.true(high_rated.some(doc => doc.name === 'Product B'));
233
+
234
+ const low_rated = await find('default', 'products', { ratings: { $lte: 2 } });
235
+ t.is(low_rated.length, 2);
236
+ t.true(low_rated.some(doc => doc.name === 'Product A'));
237
+ t.true(low_rated.some(doc => doc.name === 'Product C'));
238
+ });
239
+
240
+ test('find - should handle empty arrays correctly', async (t) => {
241
+ await insert_one('default', 'products', {
242
+ name: 'Product A',
243
+ tags: ['laptop', 'apple']
244
+ });
245
+ await insert_one('default', 'products', {
246
+ name: 'Product B',
247
+ tags: []
248
+ });
249
+ await insert_one('default', 'products', {
250
+ name: 'Product C'
251
+ // No tags field
252
+ });
253
+
254
+ // Test queries with empty arrays
255
+ const laptop_products = await find('default', 'products', { tags: 'laptop' });
256
+ t.is(laptop_products.length, 1);
257
+ t.is(laptop_products[0].name, 'Product A');
258
+
259
+ const no_match = await find('default', 'products', { tags: 'nonexistent' });
260
+ t.is(no_match.length, 0);
261
+ });