assai 2.0.0 → 2.1.1

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 (60) hide show
  1. package/README.md +148 -148
  2. package/dist/src/__test/mock_get_collection.d.mts +2 -0
  3. package/dist/src/factories/create_mongo_collection.d.mts +55 -11
  4. package/dist/src/usecases/mongo/operation/aggregate.d.mts +16 -0
  5. package/dist/src/usecases/mongo/operation/bulk_write.d.mts +15 -0
  6. package/dist/src/usecases/mongo/operation/find_one_and_delete.d.mts +16 -0
  7. package/dist/src/usecases/mongo/operation/find_one_and_replace.d.mts +18 -0
  8. package/dist/src/usecases/mongo/operation/find_one_and_update.d.mts +18 -0
  9. package/dist/src/usecases/mongo/operation/index.d.mts +5 -0
  10. package/dist/src/usecases/mongo/transformers/id/rename_to_mongo_id.d.mts +3 -0
  11. package/dist/src/usecases/mongo/transformers/object_id/ids_into_strings.d.mts +5 -0
  12. package/dist/src/usecases/mongo/transformers/object_id/strings_into_id.d.mts +3 -0
  13. package/dist/src/usecases/mongo/transformers/timestamps.d.mts +5 -0
  14. package/index.mjs +2 -2
  15. package/jsconfig.json +17 -20
  16. package/jsconfig.prod.json +12 -12
  17. package/package.json +40 -39
  18. package/src/__test/manage_mock_database.mjs +24 -24
  19. package/src/__test/manage_mock_registry.mjs +54 -54
  20. package/src/__test/mock_get_collection.mjs +22 -20
  21. package/src/data/errors/operation_fail.mjs +9 -9
  22. package/src/data/errors/unsupported_error.mjs +9 -9
  23. package/src/data/interfaces/mongo_operator.mjs +2 -2
  24. package/src/data/interfaces/native_collection.mjs +27 -27
  25. package/src/factories/create_mock_collection.mjs +173 -173
  26. package/src/factories/create_mongo_collection.mjs +224 -181
  27. package/src/factories/index.mjs +1 -1
  28. package/src/types.ts +31 -31
  29. package/src/usecases/index.mjs +1 -1
  30. package/src/usecases/mongo/generate_new_id.mjs +4 -4
  31. package/src/usecases/mongo/index.mjs +3 -3
  32. package/src/usecases/mongo/mongo_client.mjs +36 -36
  33. package/src/usecases/mongo/operation/additional/delete_one_or_throw.mjs +17 -17
  34. package/src/usecases/mongo/operation/additional/index.mjs +1 -1
  35. package/src/usecases/mongo/operation/aggregate.mjs +21 -0
  36. package/src/usecases/mongo/operation/bulk_write.mjs +54 -0
  37. package/src/usecases/mongo/operation/count.mjs +16 -16
  38. package/src/usecases/mongo/operation/delete_many.mjs +15 -15
  39. package/src/usecases/mongo/operation/delete_one.mjs +16 -16
  40. package/src/usecases/mongo/operation/find.mjs +34 -34
  41. package/src/usecases/mongo/operation/find_one.mjs +32 -32
  42. package/src/usecases/mongo/operation/find_one_and_delete.mjs +23 -0
  43. package/src/usecases/mongo/operation/find_one_and_replace.mjs +24 -0
  44. package/src/usecases/mongo/operation/find_one_and_update.mjs +40 -0
  45. package/src/usecases/mongo/operation/index.mjs +15 -10
  46. package/src/usecases/mongo/operation/insert_many.mjs +39 -39
  47. package/src/usecases/mongo/operation/insert_one.mjs +32 -32
  48. package/src/usecases/mongo/operation/update_many.mjs +39 -39
  49. package/src/usecases/mongo/operation/update_one.mjs +40 -40
  50. package/src/usecases/mongo/transformers/id/index.mjs +4 -4
  51. package/src/usecases/mongo/transformers/id/rename_find_options.mjs +12 -12
  52. package/src/usecases/mongo/transformers/id/rename_to_dev_id.mjs +14 -13
  53. package/src/usecases/mongo/transformers/id/rename_to_mongo_id.mjs +34 -13
  54. package/src/usecases/mongo/transformers/index.mjs +2 -2
  55. package/src/usecases/mongo/transformers/input_transformer.mjs +32 -32
  56. package/src/usecases/mongo/transformers/object_id/ids_into_strings.mjs +47 -30
  57. package/src/usecases/mongo/transformers/object_id/index.mjs +3 -3
  58. package/src/usecases/mongo/transformers/object_id/strings_into_id.mjs +90 -44
  59. package/src/usecases/mongo/transformers/output_transformer.mjs +18 -18
  60. package/src/usecases/mongo/transformers/timestamps.mjs +32 -22
@@ -1,174 +1,174 @@
1
- import { ObjectId } from 'mongodb'
2
- import { NotImplemented } from '../data/errors/unsupported_error.mjs'
3
-
4
- /** @type {Record<string, any[]>} */
5
- const memory = {}
6
-
7
- /**
8
- * @template {import('mongodb').Document} T
9
- * @param {string} [name]
10
- * @returns {import('../data/interfaces/native_collection.mjs').InativeCollection<T>}
11
- */
12
- export function createMockCollection(name = 'mock') {
13
-
14
- function getItems() {
15
- let items = memory[name]
16
- if (items == null) {
17
- items = []
18
- memory[name] = items
19
- }
20
- return items
21
- }
22
-
23
- /**
24
- *
25
- * @param {import('mongodb').Filter<T>} filter
26
- */
27
- function getFilteredItems(filter) {
28
- const keys = Object.keys(filter)
29
- const dollarFilters = keys.filter(x => x.startsWith('$'))
30
- if (dollarFilters.length > 0) {
31
- throw new NotImplemented('root dollar sign filters not supported')
32
- }
33
-
34
- /** @type {((item: T) => boolean)[]} */
35
- const fieldFilter = []
36
- for (const field of keys) {
37
- const value = filter[field]
38
- /**
39
- * @returns {import('../data/interfaces/mongo_operator.mjs').ImongoOperator[]}
40
- */
41
- function getOperators() {
42
- if (value == null) return ['$eq']
43
- if (typeof value != 'object') return ['$eq']
44
- if (Array.isArray(value)) return ['$eq']
45
- if (value instanceof RegExp) {
46
- throw new NotImplemented('Search using a regular expression is not supported')
47
- }
48
-
49
- // Getting operators used in query
50
- const fieldInnerKeys = Object.keys(value)
51
- const operators = fieldInnerKeys.filter(x => x.startsWith('$'))
52
- const hasOperator = operators.length > 0
53
-
54
- // Lack of operator presumes equal operator
55
- if (!hasOperator) return ['$eq']
56
-
57
- const areAllKeysOperators = fieldInnerKeys.every(x => x.startsWith('$'))
58
- if (!areAllKeysOperators) {
59
- // Means the object contained operators (such as "$eq" or "$lt"),
60
- // But not all keys are operators, which is not valid.
61
- throw new Error(`The value on field ${field} does not look right...`)
62
- }
63
-
64
- // Reading operators from object
65
- /** @type {import('../data/interfaces/mongo_operator.mjs').ImongoOperator[]} */
66
- const usedOperators = []
67
- for (const operator of operators) {
68
- switch (operator) {
69
- case '$eq':
70
- usedOperators.push('$eq')
71
- default:
72
- throw new NotImplemented(`Operator ${operator} not implemented`)
73
- }
74
- }
75
- return usedOperators
76
- }
77
-
78
- const operators = getOperators()
79
- for (const operator of operators) {
80
- switch (operator) {
81
- case '$eq':
82
- fieldFilter.push((doc) => {
83
- const savedValue = doc[field]
84
- return savedValue == value
85
- })
86
- default:
87
- throw new NotImplemented(`Operator ${operator} is not supported`)
88
- }
89
- }
90
- }
91
-
92
- const allCollectionItems = getItems()
93
- return allCollectionItems.filter(savedDoc => {
94
- return fieldFilter.every(comparator => {
95
- return comparator(savedDoc)
96
- })
97
- })
98
- }
99
-
100
- /**
101
- * $set
102
- * @param {*} doc
103
- * @param {*} update The update object. Should not contain operator
104
- */
105
- function performSetUpdate(doc, update) {
106
- for (const [field, newValue] of Object.entries(update)) {
107
- doc[field] = newValue
108
- }
109
- }
110
-
111
- return {
112
- async insertOne(doc) {
113
- const items = getItems()
114
- if (doc._id == null) {
115
- // @ts-ignore
116
- doc._id = new ObjectId()
117
- }
118
- items.push(doc)
119
- },
120
- async deleteOne(filter) {
121
- const documentsToDelete = getFilteredItems(filter)
122
- const allCollectionItems = getItems()
123
-
124
- // Deleting the documents, one document at a time
125
- while (documentsToDelete.length > 0) {
126
- const docToDelete = documentsToDelete[0]
127
- const index = allCollectionItems.indexOf(docToDelete)
128
- if (index < 0) {
129
- throw new Error('Document extracted from memory was not found in memory')
130
- }
131
- allCollectionItems.splice(index, 1)
132
- }
133
- },
134
- async updateOne(filter, update) {
135
- // Getting document to update
136
- const documentsToUpdate = getFilteredItems(filter)
137
- if (documentsToUpdate.length == 0) {
138
- return
139
- }
140
- const docToUpdate = documentsToUpdate[0]
141
-
142
- const updateKeys = Object.keys(update)
143
- const operators = updateKeys.filter(x => x.startsWith('$'))
144
-
145
- // Checking for empty updates
146
- if (updateKeys.length == 0) {
147
- return
148
- }
149
-
150
- // Is a simple $set operation
151
- if (operators.length == 0) {
152
- performSetUpdate(docToUpdate, update)
153
- return
154
- }
155
-
156
- // Validating update object
157
- if (updateKeys.length != operators.length) {
158
- throw new Error('This update does not look right...')
159
- }
160
-
161
- // Processing complex update
162
- for (const operator of operators) {
163
- const value = update[operator]
164
- switch (operator) {
165
- case '$set':
166
- performSetUpdate(docToUpdate, value)
167
- break
168
- default:
169
- throw new Error(`Operator ${operator} not supported`)
170
- }
171
- }
172
- }
173
- }
1
+ import { ObjectId } from 'mongodb'
2
+ import { NotImplemented } from '../data/errors/unsupported_error.mjs'
3
+
4
+ /** @type {Record<string, any[]>} */
5
+ const memory = {}
6
+
7
+ /**
8
+ * @template {import('mongodb').Document} T
9
+ * @param {string} [name]
10
+ * @returns {import('../data/interfaces/native_collection.mjs').InativeCollection<T>}
11
+ */
12
+ export function createMockCollection(name = 'mock') {
13
+
14
+ function getItems() {
15
+ let items = memory[name]
16
+ if (items == null) {
17
+ items = []
18
+ memory[name] = items
19
+ }
20
+ return items
21
+ }
22
+
23
+ /**
24
+ *
25
+ * @param {import('mongodb').Filter<T>} filter
26
+ */
27
+ function getFilteredItems(filter) {
28
+ const keys = Object.keys(filter)
29
+ const dollarFilters = keys.filter(x => x.startsWith('$'))
30
+ if (dollarFilters.length > 0) {
31
+ throw new NotImplemented('root dollar sign filters not supported')
32
+ }
33
+
34
+ /** @type {((item: T) => boolean)[]} */
35
+ const fieldFilter = []
36
+ for (const field of keys) {
37
+ const value = filter[field]
38
+ /**
39
+ * @returns {import('../data/interfaces/mongo_operator.mjs').ImongoOperator[]}
40
+ */
41
+ function getOperators() {
42
+ if (value == null) return ['$eq']
43
+ if (typeof value != 'object') return ['$eq']
44
+ if (Array.isArray(value)) return ['$eq']
45
+ if (value instanceof RegExp) {
46
+ throw new NotImplemented('Search using a regular expression is not supported')
47
+ }
48
+
49
+ // Getting operators used in query
50
+ const fieldInnerKeys = Object.keys(value)
51
+ const operators = fieldInnerKeys.filter(x => x.startsWith('$'))
52
+ const hasOperator = operators.length > 0
53
+
54
+ // Lack of operator presumes equal operator
55
+ if (!hasOperator) return ['$eq']
56
+
57
+ const areAllKeysOperators = fieldInnerKeys.every(x => x.startsWith('$'))
58
+ if (!areAllKeysOperators) {
59
+ // Means the object contained operators (such as "$eq" or "$lt"),
60
+ // But not all keys are operators, which is not valid.
61
+ throw new Error(`The value on field ${field} does not look right...`)
62
+ }
63
+
64
+ // Reading operators from object
65
+ /** @type {import('../data/interfaces/mongo_operator.mjs').ImongoOperator[]} */
66
+ const usedOperators = []
67
+ for (const operator of operators) {
68
+ switch (operator) {
69
+ case '$eq':
70
+ usedOperators.push('$eq')
71
+ default:
72
+ throw new NotImplemented(`Operator ${operator} not implemented`)
73
+ }
74
+ }
75
+ return usedOperators
76
+ }
77
+
78
+ const operators = getOperators()
79
+ for (const operator of operators) {
80
+ switch (operator) {
81
+ case '$eq':
82
+ fieldFilter.push((doc) => {
83
+ const savedValue = doc[field]
84
+ return savedValue == value
85
+ })
86
+ default:
87
+ throw new NotImplemented(`Operator ${operator} is not supported`)
88
+ }
89
+ }
90
+ }
91
+
92
+ const allCollectionItems = getItems()
93
+ return allCollectionItems.filter(savedDoc => {
94
+ return fieldFilter.every(comparator => {
95
+ return comparator(savedDoc)
96
+ })
97
+ })
98
+ }
99
+
100
+ /**
101
+ * $set
102
+ * @param {*} doc
103
+ * @param {*} update The update object. Should not contain operator
104
+ */
105
+ function performSetUpdate(doc, update) {
106
+ for (const [field, newValue] of Object.entries(update)) {
107
+ doc[field] = newValue
108
+ }
109
+ }
110
+
111
+ return {
112
+ async insertOne(doc) {
113
+ const items = getItems()
114
+ if (doc._id == null) {
115
+ // @ts-ignore
116
+ doc._id = new ObjectId()
117
+ }
118
+ items.push(doc)
119
+ },
120
+ async deleteOne(filter) {
121
+ const documentsToDelete = getFilteredItems(filter)
122
+ const allCollectionItems = getItems()
123
+
124
+ // Deleting the documents, one document at a time
125
+ while (documentsToDelete.length > 0) {
126
+ const docToDelete = documentsToDelete[0]
127
+ const index = allCollectionItems.indexOf(docToDelete)
128
+ if (index < 0) {
129
+ throw new Error('Document extracted from memory was not found in memory')
130
+ }
131
+ allCollectionItems.splice(index, 1)
132
+ }
133
+ },
134
+ async updateOne(filter, update) {
135
+ // Getting document to update
136
+ const documentsToUpdate = getFilteredItems(filter)
137
+ if (documentsToUpdate.length == 0) {
138
+ return
139
+ }
140
+ const docToUpdate = documentsToUpdate[0]
141
+
142
+ const updateKeys = Object.keys(update)
143
+ const operators = updateKeys.filter(x => x.startsWith('$'))
144
+
145
+ // Checking for empty updates
146
+ if (updateKeys.length == 0) {
147
+ return
148
+ }
149
+
150
+ // Is a simple $set operation
151
+ if (operators.length == 0) {
152
+ performSetUpdate(docToUpdate, update)
153
+ return
154
+ }
155
+
156
+ // Validating update object
157
+ if (updateKeys.length != operators.length) {
158
+ throw new Error('This update does not look right...')
159
+ }
160
+
161
+ // Processing complex update
162
+ for (const operator of operators) {
163
+ const value = update[operator]
164
+ switch (operator) {
165
+ case '$set':
166
+ performSetUpdate(docToUpdate, value)
167
+ break
168
+ default:
169
+ throw new Error(`Operator ${operator} not supported`)
170
+ }
171
+ }
172
+ }
173
+ }
174
174
  }