@jsreport/jsreport-core 3.1.2-test.2 → 3.4.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.
- package/LICENSE +166 -166
- package/README.md +310 -298
- package/index.js +29 -29
- package/lib/main/blobStorage/blobStorage.js +53 -52
- package/lib/main/blobStorage/inMemoryProvider.js +27 -27
- package/lib/main/blobStorage/mainActions.js +24 -24
- package/lib/main/createDefaultLoggerFormat.js +17 -17
- package/lib/main/defaults.js +14 -14
- package/lib/main/extensions/discover.js +20 -20
- package/lib/main/extensions/extensionsManager.js +264 -264
- package/lib/main/extensions/fileUtils.js +56 -56
- package/lib/main/extensions/findVersion.js +49 -49
- package/lib/main/extensions/locationCache.js +103 -103
- package/lib/main/extensions/sorter.js +10 -10
- package/lib/main/extensions/validateMinimalVersion.js +50 -50
- package/lib/main/folders/cascadeFolderRemove.js +25 -25
- package/lib/main/folders/getEntitiesInFolder.js +53 -53
- package/lib/main/folders/index.js +42 -42
- package/lib/main/folders/moveBetweenFolders.js +354 -354
- package/lib/main/folders/validateDuplicatedName.js +107 -107
- package/lib/main/folders/validateReservedName.js +53 -53
- package/lib/main/logger.js +254 -244
- package/lib/main/migration/resourcesToAssets.js +230 -230
- package/lib/main/migration/xlsxTemplatesToAssets.js +128 -128
- package/lib/main/monitoring.js +92 -91
- package/lib/main/optionsLoad.js +231 -237
- package/lib/main/optionsSchema.js +237 -237
- package/lib/main/profiler.js +13 -1
- package/lib/main/reporter.js +589 -579
- package/lib/main/request.js +21 -0
- package/lib/main/schemaValidator.js +252 -252
- package/lib/main/settings.js +154 -154
- package/lib/main/store/checkDuplicatedId.js +27 -27
- package/lib/main/store/collection.js +329 -329
- package/lib/main/store/documentStore.js +469 -469
- package/lib/main/store/mainActions.js +28 -28
- package/lib/main/store/memoryStoreProvider.js +99 -99
- package/lib/main/store/queue.js +48 -48
- package/lib/main/store/referenceUtils.js +251 -251
- package/lib/main/store/setupValidateId.js +43 -43
- package/lib/main/store/setupValidateShortid.js +71 -71
- package/lib/main/store/transaction.js +69 -69
- package/lib/main/store/typeUtils.js +180 -180
- package/lib/main/templates.js +34 -34
- package/lib/main/validateEntityName.js +62 -62
- package/lib/shared/createError.js +36 -36
- package/lib/shared/encryption.js +114 -114
- package/lib/shared/folders/index.js +11 -11
- package/lib/shared/folders/normalizeEntityPath.js +15 -15
- package/lib/shared/folders/resolveEntityFromPath.js +88 -88
- package/lib/shared/folders/resolveEntityPath.js +46 -46
- package/lib/shared/folders/resolveFolderFromPath.js +38 -38
- package/lib/shared/generateRequestId.js +4 -4
- package/lib/shared/listenerCollection.js +169 -169
- package/lib/shared/normalizeMetaFromLogs.js +30 -30
- package/lib/shared/reporter.js +128 -123
- package/lib/shared/request.js +64 -64
- package/lib/shared/tempFilesHandler.js +81 -81
- package/lib/shared/templates.js +82 -82
- package/lib/static/helpers.js +33 -33
- package/lib/worker/blobStorage.js +34 -34
- package/lib/worker/defaultProxyExtend.js +46 -46
- package/lib/worker/documentStore.js +49 -49
- package/lib/worker/extensionsManager.js +17 -17
- package/lib/worker/logger.js +48 -48
- package/lib/worker/render/diff.js +138 -138
- package/lib/worker/render/executeEngine.js +232 -207
- package/lib/worker/render/htmlRecipe.js +10 -10
- package/lib/worker/render/moduleHelper.js +45 -43
- package/lib/worker/render/noneEngine.js +12 -12
- package/lib/worker/render/profiler.js +162 -158
- package/lib/worker/render/render.js +202 -205
- package/lib/worker/render/resolveReferences.js +60 -60
- package/lib/worker/reporter.js +197 -191
- package/lib/worker/sandbox/runInSandbox.js +64 -12
- package/lib/worker/sandbox/safeSandbox.js +829 -828
- package/lib/worker/templates.js +80 -78
- package/lib/worker/workerHandler.js +55 -54
- package/package.json +91 -92
- package/test/blobStorage/common.js +25 -21
- 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
|
+
}
|