monastery 3.0.22 → 3.1.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.
package/test/model.js CHANGED
@@ -21,102 +21,116 @@ test('model > model on manager', async () => {
21
21
  db2.close()
22
22
  })
23
23
 
24
- test('model setup', async () => {
25
- // Setup
26
- let user = db.model('user', { fields: {
27
- name: { type: 'string' },
28
- pets: [{ type: 'string' }],
29
- colors: { red: { type: 'string' } },
30
- points: [[{ type: 'number' }]],
31
- points2: [[{ x: { type: 'number' } }]],
32
- logo: { type: 'image' },
33
- }})
34
-
35
- // no fields defined
24
+ test('model setup with default fields', async () => {
25
+ // Default fields
36
26
  expect(db.model('user2', { fields: {} }).fields).toEqual({
37
27
  _id: {
28
+ schema: {
38
29
  insertOnly: true,
39
30
  isId: true,
31
+ isSchema: true,
32
+ isType: 'isId',
40
33
  type: 'id',
41
34
  },
35
+ },
42
36
  createdAt: {
37
+ schema: {
43
38
  default: expect.any(Function),
44
39
  insertOnly: true,
45
40
  isInteger: true,
41
+ isSchema: true,
42
+ isType: 'isInteger',
46
43
  timestampField: true,
47
44
  type: 'integer',
48
45
  },
49
- updatedAt: {
46
+ },
47
+ updatedAt: {
48
+ schema: {
50
49
  default: expect.any(Function),
51
50
  isInteger: true,
51
+ isSchema: true,
52
+ isType: 'isInteger',
52
53
  timestampField: true,
53
54
  type: 'integer',
54
55
  },
56
+ },
57
+ schema: {
58
+ isObject: true,
59
+ isSchema: true,
60
+ isType: 'isObject',
61
+ type: 'object',
62
+ },
63
+ })
64
+ })
65
+
66
+ test('model setup basics', async () => {
67
+ // Setup
68
+ let user = db.model('user', {
69
+ fields: {
70
+ name: { type: 'string' },
71
+ pets: [{ type: 'string' }],
72
+ colors: { red: { type: 'string' } },
73
+ points: [[{ type: 'number' }]],
74
+ points2: [[{ x: { type: 'number' } }]],
75
+ logo: { type: 'image' },
76
+ },
55
77
  })
56
78
 
57
79
  // Has model name
58
- expect(user.name).toEqual('user')
80
+ expect(user.name)
81
+ .toEqual('user')
82
+
83
+ // Expect to throw an error
84
+ expect(() => db.model('user', { fields: { type: 'any' } }))
85
+ .toThrow(
86
+ 'Instead of using { type: \'any\' } for user.fields, please use the new \'strict\' definition rule, '
87
+ + 'e.g. { schema: { strict: false }}'
88
+ )
59
89
 
60
90
  // Basic field
61
- expect(user.fields.name).toEqual({ type: 'string', isString: true })
91
+ expect(user.fields.name.schema)
92
+ .toEqual({ type: 'string', isString: true, isSchema: true, isType: 'isString' })
62
93
 
63
- // Image field
64
- expect(user.fields.logo).toEqual({ type: 'any', isAny: true, image: true })
94
+ // Image field (not processed by plugin)
95
+ expect(user.fields.logo.schema)
96
+ .toEqual({ type: 'any', isAny: true, image: true, isSchema: true, isType: 'isAny' })
65
97
 
66
98
  // Array field
67
- expect(user.fields.pets).toContainEqual({ type: 'string', isString: true })
99
+ expect(user.fields.pets)
100
+ .toContainEqual({ schema: { type: 'string', isString: true, isType: 'isString', isSchema: true } })
68
101
 
69
102
  // Array schema
70
- expect(user.fields.pets.schema).toEqual({ type: 'array', isArray: true })
103
+ expect(user.fields.pets.schema)
104
+ .toEqual({ type: 'array', isArray: true, isSchema: true, isType: 'isArray' })
71
105
 
72
106
  // Subdocument field and schema
73
107
  expect(user.fields.colors).toEqual({
74
- red: { isString: true, type: 'string' },
75
- schema: { isObject: true, type: 'object' },
108
+ red: { schema: { isString: true, type: 'string', isSchema: true, isType: 'isString' }},
109
+ schema: { isObject: true, type: 'object', isSchema: true, isType: 'isObject' },
76
110
  })
77
111
 
78
112
  // Array array field (no array properties)
79
113
  expect(JSON.stringify(user.fields.points)).toEqual(JSON.stringify(
80
- [[{ type: 'number', isNumber: true }]]
114
+ [[{
115
+ schema: { type: 'number', isType: 'isNumber', isNumber: true, isSchema: true },
116
+ }]]
81
117
  ))
82
118
 
83
119
  // Array array schema
84
- expect(user.fields.points.schema).toEqual({ type: 'array', isArray: true })
85
- expect(user.fields.points[0].schema).toEqual({ type: 'array', isArray: true })
120
+ expect(user.fields.points.schema).toEqual({ type: 'array', isArray: true, isSchema: true, isType: 'isArray' })
121
+ expect(user.fields.points[0].schema).toEqual({ type: 'array', isArray: true, isSchema: true, isType: 'isArray' })
86
122
 
87
123
  // Array array subdocument field (no array properties)
88
124
  expect(JSON.stringify(user.fields.points2)).toEqual(JSON.stringify(
89
125
  [[{
90
- x: { type: 'number', isNumber: true },
91
- schema: { type: 'object', isObject: true },
126
+ x: {
127
+ schema: { type: 'number', isType: 'isNumber', isNumber: true, isSchema: true },
128
+ },
129
+ schema: { type: 'object', isObject: true, isSchema: true, isType: 'isObject' },
92
130
  }]]
93
131
  ))
94
132
  })
95
133
 
96
- test('model setup with default fields', async () => {
97
- // Default fields
98
- expect(db.model('user2', { fields: {} }).fields).toEqual({
99
- _id: {
100
- insertOnly: true,
101
- isId: true,
102
- type: 'id',
103
- },
104
- createdAt: {
105
- default: expect.any(Function),
106
- insertOnly: true,
107
- isInteger: true,
108
- timestampField: true,
109
- type: 'integer',
110
- },
111
- updatedAt: {
112
- default: expect.any(Function),
113
- isInteger: true,
114
- timestampField: true,
115
- type: 'integer',
116
- },
117
- })
118
- })
119
-
120
134
  test('model setup with default objects', async () => {
121
135
  const db2 = monastery('127.0.0.1/monastery', { defaultObjects: true })
122
136
  let user = db2.model('user', { fields: {
@@ -131,13 +145,28 @@ test('model setup with default objects', async () => {
131
145
  expect(user.fields.pets.schema).toEqual({
132
146
  type: 'array',
133
147
  isArray: true,
148
+ isSchema: true,
149
+ isType: 'isArray',
134
150
  default: expect.any(Function),
135
151
  })
136
152
 
137
153
  // Subdocument field and schema
138
154
  expect(user.fields.colors).toEqual({
139
- red: { isString: true, type: 'string' },
140
- schema: { isObject: true, type: 'object', default: expect.any(Function) },
155
+ red: {
156
+ schema: {
157
+ isString: true,
158
+ type: 'string',
159
+ isSchema: true,
160
+ isType: 'isString',
161
+ },
162
+ },
163
+ schema: {
164
+ isObject: true,
165
+ type: 'object',
166
+ isSchema: true,
167
+ isType: 'isObject',
168
+ default: expect.any(Function),
169
+ },
141
170
  })
142
171
  db2.close()
143
172
  })
@@ -157,35 +186,67 @@ test('model setup with schema', async () => {
157
186
  // Object with schema
158
187
  expect(user.fields.pet).toEqual({
159
188
  name: {
160
- type: 'string',
161
- isString: true,
162
- minLength: 5,
189
+ schema: {
190
+ type: 'string',
191
+ isString: true,
192
+ isSchema: true,
193
+ isType: 'isString',
194
+ minLength: 5,
195
+ },
163
196
  },
164
197
  schema: {
165
198
  type: 'object',
166
199
  isObject: true,
200
+ isSchema: true,
201
+ isType: 'isObject',
167
202
  virtual: true,
168
203
  },
169
204
  })
170
205
  // Array with schema
171
206
  expect(user.fields.pets[0]).toEqual({
172
207
  name: {
173
- type: 'string',
174
- isString: true,
175
- minLength: 5,
208
+ schema: {
209
+ type: 'string',
210
+ isString: true,
211
+ isSchema: true,
212
+ isType: 'isString',
213
+ minLength: 5,
214
+ },
176
215
  },
177
216
  schema: {
178
217
  type: 'object',
179
218
  isObject: true,
219
+ isSchema: true,
220
+ isType: 'isObject',
180
221
  },
181
222
  })
182
223
  expect(user.fields.pets.schema).toEqual({
183
224
  type: 'array',
184
225
  isArray: true,
226
+ isSchema: true,
227
+ isType: 'isArray',
185
228
  virtual: true,
186
229
  })
187
230
  })
188
231
 
232
+ test('model setup with schema on root', async () => {
233
+ // Expect to throw an error
234
+ expect(() => db.model('user', { fields: { name: 'string' } }))
235
+ .toThrow('The user.fields object should be a valid document, e.g. { name: { type: \'string\' }}')
236
+
237
+ // root has schema
238
+ expect(db.model('user', { fields: { name: { type: 'string' } } }).fields.schema)
239
+ .toEqual({ type: 'object', isObject: true, isSchema: true, isType: 'isObject' })
240
+
241
+ // root has custom schema
242
+ expect(db.model('user', { fields: { schema: { nullObject: true } } }).fields.schema)
243
+ .toEqual({ type: 'object', isObject: true, isSchema: true, isType: 'isObject', nullObject: true })
244
+
245
+ // strict mode off
246
+ expect(db.model('user', { fields: { schema: { strict: false } } }).fields.schema)
247
+ .toEqual({ type: 'object', isObject: true, isSchema: true, isType: 'isObject', strict: false })
248
+ })
249
+
189
250
  test('model setup with messages', async () => {
190
251
  let user = db.model('user', {
191
252
  fields: {
@@ -313,15 +374,15 @@ test('model setup with messages', async () => {
313
374
  })
314
375
  })
315
376
 
316
- test('model reserved rules', async () => {
377
+ test('model setup with reserved and invalid rules', async () => {
317
378
  // Setup
318
379
  const db2 = monastery('127.0.0.1/monastery', { logLevel: 0 })
319
380
  let user = db2.model('user-model', {
320
381
  fields: {
321
382
  name: {
322
383
  type: 'string',
323
- params: {}, // reserved keyword (image plugin)
324
- paramsUnreserved: {},
384
+ params: {}, // reserved keyword (image plugin)
385
+ invalidRule: {}, // no rule function found
325
386
  },
326
387
  },
327
388
  rules: {
@@ -330,15 +391,20 @@ test('model reserved rules', async () => {
330
391
  },
331
392
  },
332
393
  })
333
- await expect(user.validate({ name: 'Martin' })).resolves.toEqual({
334
- name: 'Martin',
335
- createdAt: expect.any(Number),
336
- updatedAt: expect.any(Number),
394
+ expect(user.fields.name).toEqual({
395
+ schema: {
396
+ type: 'string',
397
+ isString: true,
398
+ isSchema: true,
399
+ isType: 'isString',
400
+ params: {}, // still included
401
+ // invalidRule: {}, should be removed
402
+ },
337
403
  })
338
404
  db2.close()
339
405
  })
340
406
 
341
- test('model indexes', async () => {
407
+ test('model indexes basic', async () => {
342
408
  // Setup: Need to test different types of indexes
343
409
  // Setup: Drop previously tested collections
344
410
  const allCollections = await db.db.listCollections().toArray()
@@ -430,7 +496,7 @@ test('model indexes', async () => {
430
496
  }])
431
497
  })
432
498
 
433
- test('model unique indexes', async () => {
499
+ test('model indexes unique', async () => {
434
500
  // Setup: Drop previously tested collections
435
501
  if ((await db.db.listCollections().toArray()).find(o => o.name == 'userUniqueIndex')) {
436
502
  await db.db.collection('userUniqueIndex').drop()
@@ -494,7 +560,7 @@ test('model unique indexes', async () => {
494
560
  })
495
561
  })
496
562
 
497
- test('model subdocument indexes', async () => {
563
+ test('model indexes subdocument', async () => {
498
564
  // Setup: Need to test different types of indexes
499
565
  // Setup: Drop previously tested collections
500
566
  if ((await db.db.listCollections().toArray()).find(o => o.name == 'userIndexSubdoc')) {
@@ -536,7 +602,7 @@ test('model subdocument indexes', async () => {
536
602
  }])
537
603
  })
538
604
 
539
- test('model array indexes', async () => {
605
+ test('model indexes array', async () => {
540
606
  // Setup: Need to test different types of indexes
541
607
  // Setup: Drop previously tested collections
542
608
  if ((await db.db.listCollections().toArray()).find(o => o.name == 'userIndexArray')) {
@@ -578,7 +644,7 @@ test('model array indexes', async () => {
578
644
  }])
579
645
  })
580
646
 
581
- test('model 2dsphere indexes', async () => {
647
+ test('model indexes 2dsphere', async () => {
582
648
  // Setup. The tested model needs to be unique as race condition issue arises when the same model
583
649
  // with text indexes are setup at the same time
584
650
  await db.model('user99', {
@@ -599,24 +665,40 @@ test('model 2dsphere indexes', async () => {
599
665
 
600
666
  // Schema check
601
667
  expect(db.user99.fields.location).toEqual({
602
- type: { type: 'string', default: 'Point', isString: true },
603
668
  coordinates: expect.any(Array),
669
+ type: {
670
+ schema: {
671
+ default: 'Point',
672
+ isSchema: true,
673
+ isString: true,
674
+ isType: 'isString',
675
+ type: 'string',
676
+ },
677
+ },
604
678
  schema: {
605
- default: undefined,
606
679
  index: '2dsphere',
607
680
  isObject: true,
608
- nullObject: undefined,
681
+ isSchema: true,
682
+ isType: 'isObject',
609
683
  type: 'object',
610
684
  },
611
685
  })
612
686
  expect(db.user99.fields.location2).toEqual({
613
- type: { type: 'string', default: 'Point', isString: true },
614
687
  coordinates: expect.any(Array),
688
+ type: {
689
+ schema: {
690
+ type: 'string',
691
+ default: 'Point',
692
+ isSchema: true,
693
+ isString: true,
694
+ isType: 'isString',
695
+ },
696
+ },
615
697
  schema: {
616
- default: undefined,
617
698
  index: { type: '2dsphere' },
618
699
  isObject: true,
619
- nullObject: undefined,
700
+ isSchema: true,
701
+ isType: 'isObject',
620
702
  type: 'object',
621
703
  },
622
704
  })
@@ -40,9 +40,13 @@ test('images no initialisation', async () => {
40
40
 
41
41
  // schema
42
42
  expect(db2.company.fields.logo).toEqual({
43
- image: true,
44
- isAny: true,
45
- type: 'any',
43
+ schema: {
44
+ image: true,
45
+ isAny: true,
46
+ isSchema: true,
47
+ isType: 'isAny',
48
+ type: 'any',
49
+ },
46
50
  })
47
51
 
48
52
  // found company
@@ -63,27 +67,45 @@ test('images no initialisation', async () => {
63
67
  })
64
68
 
65
69
  test('images initialisation', async () => {
66
- let user = db.model('user', { fields: {
67
- logo: { type: 'image' },
68
- logos: [{ type: 'image' }],
69
- users: [{ logo: { type: 'image' } }],
70
- }})
70
+ let user = db.model('user', {
71
+ fields: {
72
+ logo: { type: 'image' },
73
+ logos: [{ type: 'image' }],
74
+ users: [{ logo: { type: 'image' } }],
75
+ },
76
+ })
71
77
 
72
78
  // Initialisation success
73
79
  expect(db.opts.imagePlugin).toEqual(imagePluginFakeOpts)
74
80
 
81
+ function schemaForType(type) {
82
+ return {
83
+ schema: {
84
+ type: type,
85
+ isType: `is${util.ucFirst(type)}`,
86
+ [`is${util.ucFirst(type)}`]: true,
87
+ isSchema: true,
88
+ },
89
+ }
90
+ }
75
91
  let expected = {
76
- bucket: { type: 'string', isString: true },
77
- date: { type: 'number', isNumber: true },
78
- filename: { type: 'string', isString: true },
79
- filesize: { type: 'number', isNumber: true },
80
- metadata: { type: 'any', isAny: true },
81
- path: { type: 'string', isString: true },
92
+ bucket: schemaForType('string'),
93
+ date: schemaForType('number'),
94
+ filename: schemaForType('string'),
95
+ filesize: schemaForType('number'),
96
+ metadata: schemaForType('any'),
97
+ path: schemaForType('string'),
98
+ uid: schemaForType('string'),
82
99
  schema: {
83
- type: 'object', isObject: true, image: true, nullObject: true, default: undefined,
100
+ type: 'object',
101
+ isObject: true,
102
+ isSchema: true,
103
+ isType: 'isObject',
104
+ nullObject: true,
105
+ // Image rules
106
+ image: true,
84
107
  isImageObject: true,
85
108
  },
86
- uid: { type: 'string', isString: true },
87
109
  }
88
110
 
89
111
  // Logo schema
package/test/validate.js CHANGED
@@ -154,6 +154,87 @@ test('validation basic errors', async () => {
154
154
  })
155
155
  })
156
156
 
157
+ test('validation type any', async () => {
158
+ let user1 = db.model('user', {
159
+ fields: {
160
+ name: { type: 'any' },
161
+ },
162
+ })
163
+ // Any type on field
164
+ await expect(user1.validate({ name: 'benjamin' })).resolves.toEqual({ name: 'benjamin' })
165
+ await expect(user1.validate({ name: 1 })).resolves.toEqual({ name: 1 })
166
+ await expect(user1.validate({ name: null })).resolves.toEqual({ name: null })
167
+ await expect(user1.validate({ name: true })).resolves.toEqual({ name: true })
168
+ await expect(user1.validate({ name: false })).resolves.toEqual({ name: false })
169
+ await expect(user1.validate({ name: [1, 2] })).resolves.toEqual({ name: [1, 2] })
170
+ await expect(user1.validate({ name: { first: 1 } })).resolves.toEqual({ name: { first: 1 } })
171
+ })
172
+
173
+ test('validation schema with reserved and invalid rules', async () => {
174
+ const db2 = monastery('127.0.0.1/monastery', { logLevel: 0 })
175
+ let user = db2.model('user-model', {
176
+ fields: {
177
+ sub: {
178
+ name: {
179
+ type: 'string',
180
+ default: true, // reserved keyword
181
+ invalidRule: {}, // no rule function found
182
+ validRule: true,
183
+ },
184
+ },
185
+ },
186
+ rules: {
187
+ default: (value) => { // function shouldn't run (i.e. value still is 'Martin')
188
+ return false
189
+ },
190
+ validRule: (value) => {
191
+ if (value === 'Martin') return true
192
+ },
193
+ },
194
+ })
195
+ await expect(user.validate({ sub: { name: 'Martin' } })).resolves.toEqual({
196
+ createdAt: expect.any(Number),
197
+ updatedAt: expect.any(Number),
198
+ sub: {
199
+ name: 'Martin',
200
+ },
201
+ })
202
+ db2.close()
203
+ })
204
+
205
+ test('validation strict false', async () => {
206
+ let user1 = db.model('user', {
207
+ fields: {
208
+ name: { type: 'string' },
209
+ },
210
+ })
211
+ // strict on (default)
212
+ let inserted1 = await user1.insert({ data: { nonDefinedField: 1 } })
213
+ expect(inserted1).toEqual({
214
+ _id: inserted1._id,
215
+ })
216
+ let user2 = db.model('user', {
217
+ fields: {
218
+ name: { type: 'string' },
219
+ sub: {
220
+ name: { type: 'string' },
221
+ schema: { strict: false },
222
+ },
223
+ subArray: [{
224
+ name: { type: 'string' },
225
+ schema: { strict: false },
226
+ }],
227
+ schema: { strict: false },
228
+ },
229
+ })
230
+ // strict off
231
+ let inserted2 = await user2.insert({ data: { nonDefinedField: 1 } })
232
+ expect(inserted2).toEqual({
233
+ _id: inserted2._id,
234
+ nonDefinedField: 1,
235
+ })
236
+ })
237
+
157
238
  test('validation subdocument errors', async () => {
158
239
  let user = db.model('user', { fields: {
159
240
  animals: {
package/test/virtuals.js CHANGED
@@ -20,8 +20,8 @@ test('virtuals', async () => {
20
20
  name: { type: 'string' },
21
21
  },
22
22
  })
23
- expect(user.fields.name.virtual).toEqual(undefined)
24
- expect(user.fields.myBirds[0].virtual).toEqual(true)
23
+ expect(user.fields.name.schema.virtual).toEqual(undefined)
24
+ expect(user.fields.myBirds[0].schema.virtual).toEqual(true)
25
25
  expect(user.fields.myBirds.schema.virtual).toEqual(true)
26
26
 
27
27
  // Test insert/update/validate