@jsreport/jsreport-core 3.1.2-test.2 → 3.2.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 (79) hide show
  1. package/LICENSE +166 -166
  2. package/README.md +298 -298
  3. package/index.js +29 -29
  4. package/lib/main/blobStorage/blobStorage.js +52 -52
  5. package/lib/main/blobStorage/inMemoryProvider.js +27 -27
  6. package/lib/main/blobStorage/mainActions.js +24 -24
  7. package/lib/main/createDefaultLoggerFormat.js +17 -17
  8. package/lib/main/defaults.js +14 -14
  9. package/lib/main/extensions/discover.js +20 -20
  10. package/lib/main/extensions/extensionsManager.js +264 -264
  11. package/lib/main/extensions/fileUtils.js +56 -56
  12. package/lib/main/extensions/findVersion.js +49 -49
  13. package/lib/main/extensions/locationCache.js +103 -103
  14. package/lib/main/extensions/sorter.js +10 -10
  15. package/lib/main/extensions/validateMinimalVersion.js +50 -50
  16. package/lib/main/folders/cascadeFolderRemove.js +25 -25
  17. package/lib/main/folders/getEntitiesInFolder.js +53 -53
  18. package/lib/main/folders/index.js +42 -42
  19. package/lib/main/folders/moveBetweenFolders.js +354 -354
  20. package/lib/main/folders/validateDuplicatedName.js +107 -107
  21. package/lib/main/folders/validateReservedName.js +53 -53
  22. package/lib/main/logger.js +244 -244
  23. package/lib/main/migration/resourcesToAssets.js +230 -230
  24. package/lib/main/migration/xlsxTemplatesToAssets.js +128 -128
  25. package/lib/main/monitoring.js +91 -91
  26. package/lib/main/optionsLoad.js +237 -237
  27. package/lib/main/optionsSchema.js +237 -237
  28. package/lib/main/reporter.js +574 -579
  29. package/lib/main/schemaValidator.js +252 -252
  30. package/lib/main/settings.js +154 -154
  31. package/lib/main/store/checkDuplicatedId.js +27 -27
  32. package/lib/main/store/collection.js +329 -329
  33. package/lib/main/store/documentStore.js +469 -469
  34. package/lib/main/store/mainActions.js +28 -28
  35. package/lib/main/store/memoryStoreProvider.js +99 -99
  36. package/lib/main/store/queue.js +48 -48
  37. package/lib/main/store/referenceUtils.js +251 -251
  38. package/lib/main/store/setupValidateId.js +43 -43
  39. package/lib/main/store/setupValidateShortid.js +71 -71
  40. package/lib/main/store/transaction.js +69 -69
  41. package/lib/main/store/typeUtils.js +180 -180
  42. package/lib/main/templates.js +34 -34
  43. package/lib/main/validateEntityName.js +62 -62
  44. package/lib/shared/createError.js +36 -36
  45. package/lib/shared/encryption.js +114 -114
  46. package/lib/shared/folders/index.js +11 -11
  47. package/lib/shared/folders/normalizeEntityPath.js +15 -15
  48. package/lib/shared/folders/resolveEntityFromPath.js +88 -88
  49. package/lib/shared/folders/resolveEntityPath.js +46 -46
  50. package/lib/shared/folders/resolveFolderFromPath.js +38 -38
  51. package/lib/shared/generateRequestId.js +4 -4
  52. package/lib/shared/listenerCollection.js +169 -169
  53. package/lib/shared/normalizeMetaFromLogs.js +30 -30
  54. package/lib/shared/reporter.js +128 -123
  55. package/lib/shared/request.js +64 -64
  56. package/lib/shared/tempFilesHandler.js +81 -81
  57. package/lib/shared/templates.js +82 -82
  58. package/lib/static/helpers.js +33 -33
  59. package/lib/worker/blobStorage.js +34 -34
  60. package/lib/worker/defaultProxyExtend.js +46 -46
  61. package/lib/worker/documentStore.js +49 -49
  62. package/lib/worker/extensionsManager.js +17 -17
  63. package/lib/worker/logger.js +48 -48
  64. package/lib/worker/render/diff.js +138 -138
  65. package/lib/worker/render/executeEngine.js +239 -207
  66. package/lib/worker/render/htmlRecipe.js +10 -10
  67. package/lib/worker/render/moduleHelper.js +45 -43
  68. package/lib/worker/render/noneEngine.js +12 -12
  69. package/lib/worker/render/profiler.js +158 -158
  70. package/lib/worker/render/render.js +202 -205
  71. package/lib/worker/render/resolveReferences.js +60 -60
  72. package/lib/worker/reporter.js +192 -191
  73. package/lib/worker/sandbox/runInSandbox.js +16 -9
  74. package/lib/worker/sandbox/safeSandbox.js +828 -828
  75. package/lib/worker/templates.js +80 -78
  76. package/lib/worker/workerHandler.js +54 -54
  77. package/package.json +92 -92
  78. package/test/blobStorage/common.js +21 -21
  79. package/test/store/common.js +1449 -1449
@@ -1,251 +1,251 @@
1
- const { resolvePropDefinition } = require('./typeUtils')
2
-
3
- function findReferencePropertiesInType (model, type, parentProps = []) {
4
- const properties = []
5
-
6
- for (const [propName, propDef] of Object.entries(type)) {
7
- const currentFullProps = [...parentProps, propName]
8
- const result = resolvePropDefinition(model, propDef)
9
-
10
- if (!result) {
11
- continue
12
- }
13
-
14
- if (result.subType) {
15
- const subProperties = findReferencePropertiesInType(model, result.subType, currentFullProps)
16
- properties.push(...subProperties)
17
- continue
18
- }
19
-
20
- if (result.def.referenceTo != null) {
21
- properties.push({
22
- name: currentFullProps.join('.'),
23
- referenceTo: result.def.referenceTo
24
- })
25
- }
26
- }
27
-
28
- return properties
29
- }
30
-
31
- function findPropertiesForCollectionReference (store, collectionReferenceOriginName, collectionReferenceTargetName) {
32
- const properties = []
33
-
34
- for (const prop of store.model.entitySets[collectionReferenceOriginName].referenceProperties) {
35
- if (prop.referenceTo === collectionReferenceTargetName) {
36
- properties.push(prop.name)
37
- }
38
- }
39
-
40
- return properties
41
- }
42
-
43
- function findLinkedEntitiesForReferenceValue (store, entitiesByCollection, collectionReferenceTargetName, referenceValue) {
44
- const linkedEntities = []
45
- const targetCollections = []
46
-
47
- for (const property of store.model.entitySets[collectionReferenceTargetName].linkedReferenceProperties) {
48
- if (!targetCollections.includes(property.entitySet)) {
49
- targetCollections.push(property.entitySet)
50
- }
51
- }
52
-
53
- for (const colName of targetCollections) {
54
- const entitiesInCollection = entitiesByCollection[colName] || []
55
-
56
- for (const entity of entitiesInCollection) {
57
- const properties = existsReferenceValue(store, colName, entity, collectionReferenceTargetName, referenceValue)
58
-
59
- if (properties) {
60
- linkedEntities.push({
61
- properties,
62
- entity
63
- })
64
- }
65
- }
66
- }
67
-
68
- return linkedEntities
69
- }
70
-
71
- function existsReferenceValue (store, collectionReferenceOriginName, entity, collectionReferenceTargetName, referenceValue) {
72
- let exists = false
73
- const propertiesToCheck = findPropertiesForCollectionReference(store, collectionReferenceOriginName, collectionReferenceTargetName)
74
-
75
- const properties = []
76
-
77
- for (const propName of propertiesToCheck) {
78
- const entityType = store.model.entitySets[collectionReferenceOriginName].entityTypeDef
79
-
80
- const propParts = propName.split('.')
81
-
82
- exists = existsReferenceInProperty(store, entityType, entity, referenceValue, propParts)
83
-
84
- if (exists) {
85
- properties.push(propName)
86
- }
87
- }
88
-
89
- if (properties.length === 0) {
90
- return
91
- }
92
-
93
- return properties
94
- }
95
-
96
- function existsReferenceInProperty (store, type, obj, referenceValue, propsToEvaluate) {
97
- if (obj == null || propsToEvaluate.length === 0) {
98
- return false
99
- }
100
-
101
- const currentPropName = propsToEvaluate[0]
102
- const restProps = propsToEvaluate.slice(1)
103
- const currentPropDef = type[currentPropName]
104
- const currentPropValue = obj[currentPropName]
105
-
106
- if (currentPropValue == null || currentPropDef == null) {
107
- return false
108
- }
109
-
110
- const resolveResult = store.resolvePropertyDefinition(currentPropDef)
111
-
112
- if (resolveResult.subType && resolveResult.def.type.startsWith('Collection(')) {
113
- if (!Array.isArray(currentPropValue)) {
114
- return false
115
- }
116
-
117
- return currentPropValue.some((val) => {
118
- return existsReferenceInProperty(store, resolveResult.subType, val, referenceValue, restProps)
119
- })
120
- } else if (resolveResult.def.type.startsWith('Collection(') && resolveResult.subType == null) {
121
- if (restProps.length > 0) {
122
- return false
123
- }
124
-
125
- if (!Array.isArray(currentPropValue)) {
126
- return false
127
- }
128
-
129
- return currentPropValue.some((val) => val === referenceValue)
130
- } else if (resolveResult.subType) {
131
- return existsReferenceInProperty(store, resolveResult.subType, currentPropValue, referenceValue, restProps)
132
- }
133
-
134
- if (restProps.length > 0) {
135
- return false
136
- }
137
-
138
- return currentPropValue === referenceValue
139
- }
140
-
141
- function updateReferenceValue (store, collectionReferenceOriginName, entity, collectionReferenceTargetName, referenceOpts, newReferenceValue) {
142
- if (!referenceOpts) {
143
- throw new Error('reference options is required')
144
- }
145
-
146
- // the update has some cases that depends on the presence of the options:
147
- // - when you pass referenceValue but no referenceProp, the newReferenceValye will ONLY be updated if the detected linked properties contain value equal to referenceValue
148
- // - when you pass referenceProp but no referenceValue, the newReferenceValue will be set in referenceProp of entity
149
- // - when you pass both referenceProp and referenceValue, the newReferenceValye will ONLY be updated if the referenceProp contain value equal to referenceValue
150
- const { referenceProp, referenceValue } = referenceOpts
151
-
152
- if (!referenceProp && !referenceValue) {
153
- throw new Error('reference options needs either .referenceProp or .referenceValue value to be present')
154
- }
155
-
156
- const propertiesToCheck = findPropertiesForCollectionReference(store, collectionReferenceOriginName, collectionReferenceTargetName)
157
-
158
- for (const propName of propertiesToCheck) {
159
- if (referenceProp != null && referenceProp !== propName) {
160
- continue
161
- }
162
-
163
- const entityType = store.model.entitySets[collectionReferenceOriginName].entityTypeDef
164
-
165
- const propParts = propName.split('.')
166
-
167
- updateReferenceInProperty(store, entityType, entity, referenceValue, newReferenceValue, propParts)
168
- }
169
- }
170
-
171
- function updateReferenceInProperty (store, type, obj, referenceValue, newReferenceValue, propsToEvaluate) {
172
- const currentPropName = propsToEvaluate[0]
173
- const restProps = propsToEvaluate.slice(1)
174
- const currentPropDef = type[currentPropName]
175
- const currentPropValue = obj[currentPropName]
176
-
177
- if (currentPropDef == null) {
178
- return
179
- }
180
-
181
- const resolveResult = store.resolvePropertyDefinition(currentPropDef)
182
-
183
- if (resolveResult.subType && resolveResult.def.type.startsWith('Collection(')) {
184
- if (restProps.length === 0) {
185
- return
186
- }
187
-
188
- if (!Array.isArray(currentPropValue)) {
189
- obj[currentPropName] = []
190
- }
191
-
192
- if (obj[currentPropName].length === 0) {
193
- const newItem = {}
194
- obj[currentPropName].push(newItem)
195
- updateReferenceInProperty(store, resolveResult.subType, newItem, undefined, newReferenceValue, restProps)
196
- } else {
197
- const exists = obj[currentPropName].some((val) => {
198
- return existsReferenceInProperty(store, resolveResult.subType, val, referenceValue, restProps)
199
- })
200
-
201
- if (exists) {
202
- obj[currentPropName].forEach((val, idx) => {
203
- obj[currentPropName][idx] = val || {}
204
- return updateReferenceInProperty(store, resolveResult.subType, obj[currentPropName][idx], referenceValue, newReferenceValue, restProps)
205
- })
206
- } else {
207
- const newItem = {}
208
- obj[currentPropName].push(newItem)
209
- updateReferenceInProperty(store, resolveResult.subType, newItem, undefined, newReferenceValue, restProps)
210
- }
211
- }
212
- } else if (resolveResult.def.type.startsWith('Collection(') && resolveResult.subType == null) {
213
- if (restProps.length > 0) {
214
- return
215
- }
216
-
217
- if (!Array.isArray(currentPropValue)) {
218
- obj[currentPropName] = []
219
- }
220
-
221
- if (referenceValue != null && obj[currentPropName].includes(referenceValue)) {
222
- obj[currentPropName].forEach((val, idx) => {
223
- if (val === referenceValue) {
224
- obj[currentPropName][idx] = newReferenceValue
225
- }
226
- })
227
- } else {
228
- obj[currentPropName].push(newReferenceValue)
229
- }
230
- } else if (resolveResult.subType) {
231
- obj[currentPropName] = obj[currentPropName] || {}
232
- return updateReferenceInProperty(store, resolveResult.subType, obj[currentPropName], referenceValue, newReferenceValue, restProps)
233
- }
234
-
235
- if (restProps.length > 0) {
236
- return
237
- }
238
-
239
- if (referenceValue != null) {
240
- if (obj[currentPropName] === referenceValue) {
241
- obj[currentPropName] = newReferenceValue
242
- }
243
- } else {
244
- obj[currentPropName] = newReferenceValue
245
- }
246
- }
247
-
248
- module.exports.findReferencePropertiesInType = findReferencePropertiesInType
249
- module.exports.findLinkedEntitiesForReferenceValue = findLinkedEntitiesForReferenceValue
250
- module.exports.existsReferenceValue = existsReferenceValue
251
- module.exports.updateReferenceValue = updateReferenceValue
1
+ const { resolvePropDefinition } = require('./typeUtils')
2
+
3
+ function findReferencePropertiesInType (model, type, parentProps = []) {
4
+ const properties = []
5
+
6
+ for (const [propName, propDef] of Object.entries(type)) {
7
+ const currentFullProps = [...parentProps, propName]
8
+ const result = resolvePropDefinition(model, propDef)
9
+
10
+ if (!result) {
11
+ continue
12
+ }
13
+
14
+ if (result.subType) {
15
+ const subProperties = findReferencePropertiesInType(model, result.subType, currentFullProps)
16
+ properties.push(...subProperties)
17
+ continue
18
+ }
19
+
20
+ if (result.def.referenceTo != null) {
21
+ properties.push({
22
+ name: currentFullProps.join('.'),
23
+ referenceTo: result.def.referenceTo
24
+ })
25
+ }
26
+ }
27
+
28
+ return properties
29
+ }
30
+
31
+ function findPropertiesForCollectionReference (store, collectionReferenceOriginName, collectionReferenceTargetName) {
32
+ const properties = []
33
+
34
+ for (const prop of store.model.entitySets[collectionReferenceOriginName].referenceProperties) {
35
+ if (prop.referenceTo === collectionReferenceTargetName) {
36
+ properties.push(prop.name)
37
+ }
38
+ }
39
+
40
+ return properties
41
+ }
42
+
43
+ function findLinkedEntitiesForReferenceValue (store, entitiesByCollection, collectionReferenceTargetName, referenceValue) {
44
+ const linkedEntities = []
45
+ const targetCollections = []
46
+
47
+ for (const property of store.model.entitySets[collectionReferenceTargetName].linkedReferenceProperties) {
48
+ if (!targetCollections.includes(property.entitySet)) {
49
+ targetCollections.push(property.entitySet)
50
+ }
51
+ }
52
+
53
+ for (const colName of targetCollections) {
54
+ const entitiesInCollection = entitiesByCollection[colName] || []
55
+
56
+ for (const entity of entitiesInCollection) {
57
+ const properties = existsReferenceValue(store, colName, entity, collectionReferenceTargetName, referenceValue)
58
+
59
+ if (properties) {
60
+ linkedEntities.push({
61
+ properties,
62
+ entity
63
+ })
64
+ }
65
+ }
66
+ }
67
+
68
+ return linkedEntities
69
+ }
70
+
71
+ function existsReferenceValue (store, collectionReferenceOriginName, entity, collectionReferenceTargetName, referenceValue) {
72
+ let exists = false
73
+ const propertiesToCheck = findPropertiesForCollectionReference(store, collectionReferenceOriginName, collectionReferenceTargetName)
74
+
75
+ const properties = []
76
+
77
+ for (const propName of propertiesToCheck) {
78
+ const entityType = store.model.entitySets[collectionReferenceOriginName].entityTypeDef
79
+
80
+ const propParts = propName.split('.')
81
+
82
+ exists = existsReferenceInProperty(store, entityType, entity, referenceValue, propParts)
83
+
84
+ if (exists) {
85
+ properties.push(propName)
86
+ }
87
+ }
88
+
89
+ if (properties.length === 0) {
90
+ return
91
+ }
92
+
93
+ return properties
94
+ }
95
+
96
+ function existsReferenceInProperty (store, type, obj, referenceValue, propsToEvaluate) {
97
+ if (obj == null || propsToEvaluate.length === 0) {
98
+ return false
99
+ }
100
+
101
+ const currentPropName = propsToEvaluate[0]
102
+ const restProps = propsToEvaluate.slice(1)
103
+ const currentPropDef = type[currentPropName]
104
+ const currentPropValue = obj[currentPropName]
105
+
106
+ if (currentPropValue == null || currentPropDef == null) {
107
+ return false
108
+ }
109
+
110
+ const resolveResult = store.resolvePropertyDefinition(currentPropDef)
111
+
112
+ if (resolveResult.subType && resolveResult.def.type.startsWith('Collection(')) {
113
+ if (!Array.isArray(currentPropValue)) {
114
+ return false
115
+ }
116
+
117
+ return currentPropValue.some((val) => {
118
+ return existsReferenceInProperty(store, resolveResult.subType, val, referenceValue, restProps)
119
+ })
120
+ } else if (resolveResult.def.type.startsWith('Collection(') && resolveResult.subType == null) {
121
+ if (restProps.length > 0) {
122
+ return false
123
+ }
124
+
125
+ if (!Array.isArray(currentPropValue)) {
126
+ return false
127
+ }
128
+
129
+ return currentPropValue.some((val) => val === referenceValue)
130
+ } else if (resolveResult.subType) {
131
+ return existsReferenceInProperty(store, resolveResult.subType, currentPropValue, referenceValue, restProps)
132
+ }
133
+
134
+ if (restProps.length > 0) {
135
+ return false
136
+ }
137
+
138
+ return currentPropValue === referenceValue
139
+ }
140
+
141
+ function updateReferenceValue (store, collectionReferenceOriginName, entity, collectionReferenceTargetName, referenceOpts, newReferenceValue) {
142
+ if (!referenceOpts) {
143
+ throw new Error('reference options is required')
144
+ }
145
+
146
+ // the update has some cases that depends on the presence of the options:
147
+ // - when you pass referenceValue but no referenceProp, the newReferenceValye will ONLY be updated if the detected linked properties contain value equal to referenceValue
148
+ // - when you pass referenceProp but no referenceValue, the newReferenceValue will be set in referenceProp of entity
149
+ // - when you pass both referenceProp and referenceValue, the newReferenceValye will ONLY be updated if the referenceProp contain value equal to referenceValue
150
+ const { referenceProp, referenceValue } = referenceOpts
151
+
152
+ if (!referenceProp && !referenceValue) {
153
+ throw new Error('reference options needs either .referenceProp or .referenceValue value to be present')
154
+ }
155
+
156
+ const propertiesToCheck = findPropertiesForCollectionReference(store, collectionReferenceOriginName, collectionReferenceTargetName)
157
+
158
+ for (const propName of propertiesToCheck) {
159
+ if (referenceProp != null && referenceProp !== propName) {
160
+ continue
161
+ }
162
+
163
+ const entityType = store.model.entitySets[collectionReferenceOriginName].entityTypeDef
164
+
165
+ const propParts = propName.split('.')
166
+
167
+ updateReferenceInProperty(store, entityType, entity, referenceValue, newReferenceValue, propParts)
168
+ }
169
+ }
170
+
171
+ function updateReferenceInProperty (store, type, obj, referenceValue, newReferenceValue, propsToEvaluate) {
172
+ const currentPropName = propsToEvaluate[0]
173
+ const restProps = propsToEvaluate.slice(1)
174
+ const currentPropDef = type[currentPropName]
175
+ const currentPropValue = obj[currentPropName]
176
+
177
+ if (currentPropDef == null) {
178
+ return
179
+ }
180
+
181
+ const resolveResult = store.resolvePropertyDefinition(currentPropDef)
182
+
183
+ if (resolveResult.subType && resolveResult.def.type.startsWith('Collection(')) {
184
+ if (restProps.length === 0) {
185
+ return
186
+ }
187
+
188
+ if (!Array.isArray(currentPropValue)) {
189
+ obj[currentPropName] = []
190
+ }
191
+
192
+ if (obj[currentPropName].length === 0) {
193
+ const newItem = {}
194
+ obj[currentPropName].push(newItem)
195
+ updateReferenceInProperty(store, resolveResult.subType, newItem, undefined, newReferenceValue, restProps)
196
+ } else {
197
+ const exists = obj[currentPropName].some((val) => {
198
+ return existsReferenceInProperty(store, resolveResult.subType, val, referenceValue, restProps)
199
+ })
200
+
201
+ if (exists) {
202
+ obj[currentPropName].forEach((val, idx) => {
203
+ obj[currentPropName][idx] = val || {}
204
+ return updateReferenceInProperty(store, resolveResult.subType, obj[currentPropName][idx], referenceValue, newReferenceValue, restProps)
205
+ })
206
+ } else {
207
+ const newItem = {}
208
+ obj[currentPropName].push(newItem)
209
+ updateReferenceInProperty(store, resolveResult.subType, newItem, undefined, newReferenceValue, restProps)
210
+ }
211
+ }
212
+ } else if (resolveResult.def.type.startsWith('Collection(') && resolveResult.subType == null) {
213
+ if (restProps.length > 0) {
214
+ return
215
+ }
216
+
217
+ if (!Array.isArray(currentPropValue)) {
218
+ obj[currentPropName] = []
219
+ }
220
+
221
+ if (referenceValue != null && obj[currentPropName].includes(referenceValue)) {
222
+ obj[currentPropName].forEach((val, idx) => {
223
+ if (val === referenceValue) {
224
+ obj[currentPropName][idx] = newReferenceValue
225
+ }
226
+ })
227
+ } else {
228
+ obj[currentPropName].push(newReferenceValue)
229
+ }
230
+ } else if (resolveResult.subType) {
231
+ obj[currentPropName] = obj[currentPropName] || {}
232
+ return updateReferenceInProperty(store, resolveResult.subType, obj[currentPropName], referenceValue, newReferenceValue, restProps)
233
+ }
234
+
235
+ if (restProps.length > 0) {
236
+ return
237
+ }
238
+
239
+ if (referenceValue != null) {
240
+ if (obj[currentPropName] === referenceValue) {
241
+ obj[currentPropName] = newReferenceValue
242
+ }
243
+ } else {
244
+ obj[currentPropName] = newReferenceValue
245
+ }
246
+ }
247
+
248
+ module.exports.findReferencePropertiesInType = findReferencePropertiesInType
249
+ module.exports.findLinkedEntitiesForReferenceValue = findLinkedEntitiesForReferenceValue
250
+ module.exports.existsReferenceValue = existsReferenceValue
251
+ module.exports.updateReferenceValue = updateReferenceValue
@@ -1,43 +1,43 @@
1
-
2
- module.exports = (reporter) => {
3
- reporter.initializeListeners.add('core-validate-id', () => {
4
- for (const c of Object.keys(reporter.documentStore.collections)) {
5
- reporter.documentStore.collection(c).beforeInsertListeners.add('validate-id', (doc, req) => {
6
- return validateIdForStoreChange(reporter, c, doc._id, undefined, req)
7
- })
8
-
9
- reporter.documentStore.collection(c).beforeUpdateListeners.add('validate-id', async (q, update, opts, req) => {
10
- if (update.$set && opts && opts.upsert === true) {
11
- await validateIdForStoreChange(reporter, c, update.$set._id, undefined, req)
12
- }
13
-
14
- if (!update.$set._id) {
15
- return
16
- }
17
-
18
- const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
19
-
20
- return Promise.all(entitiesToUpdate.map(e => validateIdForStoreChange(reporter, c, Object.assign({}, e, update.$set)._id, e._id, req)))
21
- })
22
- }
23
- })
24
- }
25
-
26
- async function validateIdForStoreChange (reporter, collectionName, idValue, originalIdValue, req) {
27
- const existingEntity = await reporter.documentStore.checkDuplicatedId(collectionName, idValue, req)
28
-
29
- if (!existingEntity) {
30
- return
31
- }
32
-
33
- if (originalIdValue != null && existingEntity._id === originalIdValue) {
34
- return
35
- }
36
-
37
- throw reporter.createError(`Entity with _id "${idValue}" already exists.`, {
38
- statusCode: 400,
39
- code: 'DUPLICATED_ENTITY',
40
- existingEntity,
41
- existingEntityEntitySet: collectionName
42
- })
43
- }
1
+
2
+ module.exports = (reporter) => {
3
+ reporter.initializeListeners.add('core-validate-id', () => {
4
+ for (const c of Object.keys(reporter.documentStore.collections)) {
5
+ reporter.documentStore.collection(c).beforeInsertListeners.add('validate-id', (doc, req) => {
6
+ return validateIdForStoreChange(reporter, c, doc._id, undefined, req)
7
+ })
8
+
9
+ reporter.documentStore.collection(c).beforeUpdateListeners.add('validate-id', async (q, update, opts, req) => {
10
+ if (update.$set && opts && opts.upsert === true) {
11
+ await validateIdForStoreChange(reporter, c, update.$set._id, undefined, req)
12
+ }
13
+
14
+ if (!update.$set._id) {
15
+ return
16
+ }
17
+
18
+ const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
19
+
20
+ return Promise.all(entitiesToUpdate.map(e => validateIdForStoreChange(reporter, c, Object.assign({}, e, update.$set)._id, e._id, req)))
21
+ })
22
+ }
23
+ })
24
+ }
25
+
26
+ async function validateIdForStoreChange (reporter, collectionName, idValue, originalIdValue, req) {
27
+ const existingEntity = await reporter.documentStore.checkDuplicatedId(collectionName, idValue, req)
28
+
29
+ if (!existingEntity) {
30
+ return
31
+ }
32
+
33
+ if (originalIdValue != null && existingEntity._id === originalIdValue) {
34
+ return
35
+ }
36
+
37
+ throw reporter.createError(`Entity with _id "${idValue}" already exists.`, {
38
+ statusCode: 400,
39
+ code: 'DUPLICATED_ENTITY',
40
+ existingEntity,
41
+ existingEntityEntitySet: collectionName
42
+ })
43
+ }