@jsreport/jsreport-core 3.0.0 → 3.1.2-test.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 +298 -284
- package/index.js +29 -27
- package/lib/main/blobStorage/blobStorage.js +52 -47
- 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 -265
- package/lib/main/extensions/fileUtils.js +56 -55
- package/lib/main/extensions/findVersion.js +49 -53
- package/lib/main/extensions/locationCache.js +103 -97
- 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 +244 -244
- package/lib/main/migration/resourcesToAssets.js +230 -210
- package/lib/main/migration/xlsxTemplatesToAssets.js +128 -118
- package/lib/main/monitoring.js +91 -91
- package/lib/main/optionsLoad.js +237 -237
- package/lib/main/optionsSchema.js +237 -237
- package/lib/main/profiler.js +2 -1
- package/lib/main/reporter.js +575 -578
- 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 -0
- 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 +227 -190
- 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 +158 -158
- package/lib/worker/render/render.js +213 -209
- package/lib/worker/render/resolveReferences.js +60 -60
- package/lib/worker/reporter.js +192 -187
- package/lib/worker/sandbox/runInSandbox.js +13 -4
- package/lib/worker/sandbox/safeSandbox.js +828 -822
- package/lib/worker/templates.js +78 -78
- package/lib/worker/workerHandler.js +54 -54
- package/package.json +92 -92
- package/test/blobStorage/common.js +21 -21
- package/test/store/common.js +1449 -1449
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
const omit = require('lodash.omit')
|
|
2
|
-
const resolveEntityPath = require('../../shared/folders/resolveEntityPath')
|
|
3
|
-
|
|
4
|
-
async function findEntity (reporter, name, folder, req) {
|
|
5
|
-
for (const c of Object.keys(reporter.documentStore.collections)) {
|
|
6
|
-
if (!reporter.documentStore.model.entitySets[c].entityTypeDef.name) {
|
|
7
|
-
continue
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const localReq = req ? reporter.Request(req) : req
|
|
11
|
-
|
|
12
|
-
// we should validate against all entities without caring about permissions
|
|
13
|
-
if (localReq) {
|
|
14
|
-
localReq.context = localReq.context ? omit(localReq.context, 'user') : localReq.context
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const allEntities = await reporter.documentStore.collection(c).find({
|
|
18
|
-
folder
|
|
19
|
-
}, {
|
|
20
|
-
name: 1
|
|
21
|
-
}, localReq)
|
|
22
|
-
|
|
23
|
-
const existingEntity = allEntities.find((entity) => {
|
|
24
|
-
if (entity.name) {
|
|
25
|
-
// doing the check for case insensitive string (foo === FOO)
|
|
26
|
-
return entity.name.toLowerCase() === name.toLowerCase()
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return false
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
if (existingEntity) {
|
|
33
|
-
return { entity: existingEntity, entitySet: c }
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function validateDuplicatedName (reporter, c, doc, originalIdValue, req) {
|
|
39
|
-
const resolveEntityPathFn = resolveEntityPath(reporter)
|
|
40
|
-
|
|
41
|
-
if (!reporter.documentStore.model.entitySets[c].entityTypeDef.name) {
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const name = doc.name
|
|
46
|
-
|
|
47
|
-
if (!name) {
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const existingEntity = await findEntity(reporter, name, doc.folder, req)
|
|
52
|
-
|
|
53
|
-
if (existingEntity) {
|
|
54
|
-
if (originalIdValue != null && existingEntity.entity._id === originalIdValue) {
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let msg = `Entity with name "${name}" already exists`
|
|
59
|
-
let folder
|
|
60
|
-
|
|
61
|
-
if (doc.folder != null) {
|
|
62
|
-
folder = await reporter.documentStore.collection('folders').findOne({
|
|
63
|
-
shortid: doc.folder.shortid
|
|
64
|
-
}, req)
|
|
65
|
-
|
|
66
|
-
if (folder) {
|
|
67
|
-
const folderFullPath = await resolveEntityPathFn(folder, 'folders', req)
|
|
68
|
-
|
|
69
|
-
msg = `${msg} in the ${folderFullPath} folder.`
|
|
70
|
-
} else {
|
|
71
|
-
msg = `${msg} in the same folder.`
|
|
72
|
-
}
|
|
73
|
-
} else {
|
|
74
|
-
msg = `${msg} at the root level.`
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// prints existing name in message when name are different, this can happen because the name validation
|
|
78
|
-
// is case insensitivity (uppercase and lowercase form are equivalent)
|
|
79
|
-
if (reporter.documentStore.model.entitySets[existingEntity.entitySet].entityTypeDef.name && existingEntity.entity.name !== name) {
|
|
80
|
-
msg = `${msg} existing: "${existingEntity.entity.name}".`
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
throw reporter.createError(msg, {
|
|
84
|
-
statusCode: 400,
|
|
85
|
-
code: 'DUPLICATED_ENTITY',
|
|
86
|
-
existingEntity: existingEntity.entity,
|
|
87
|
-
existingEntityEntitySet: existingEntity.entitySet
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
module.exports = function (reporter) {
|
|
93
|
-
for (const c of Object.keys(reporter.documentStore.collections)) {
|
|
94
|
-
reporter.documentStore.collection(c).beforeInsertListeners.add('unique-name-folders', (doc, req) => validateDuplicatedName(reporter, c, doc, undefined, req))
|
|
95
|
-
reporter.documentStore.collection(c).beforeUpdateListeners.add('unique-name-folders', async (q, update, opts, req) => {
|
|
96
|
-
if (update.$set && opts && opts.upsert === true) {
|
|
97
|
-
await validateDuplicatedName(reporter, c, update.$set, undefined, req)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// we need to get folder spec so we need to load them anyway
|
|
101
|
-
const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
|
|
102
|
-
return Promise.all(entitiesToUpdate.map(e => validateDuplicatedName(reporter, c, Object.assign({}, e, update.$set), e._id, req)))
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
module.exports.validateDuplicatedName = validateDuplicatedName
|
|
1
|
+
const omit = require('lodash.omit')
|
|
2
|
+
const resolveEntityPath = require('../../shared/folders/resolveEntityPath')
|
|
3
|
+
|
|
4
|
+
async function findEntity (reporter, name, folder, req) {
|
|
5
|
+
for (const c of Object.keys(reporter.documentStore.collections)) {
|
|
6
|
+
if (!reporter.documentStore.model.entitySets[c].entityTypeDef.name) {
|
|
7
|
+
continue
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const localReq = req ? reporter.Request(req) : req
|
|
11
|
+
|
|
12
|
+
// we should validate against all entities without caring about permissions
|
|
13
|
+
if (localReq) {
|
|
14
|
+
localReq.context = localReq.context ? omit(localReq.context, 'user') : localReq.context
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const allEntities = await reporter.documentStore.collection(c).find({
|
|
18
|
+
folder
|
|
19
|
+
}, {
|
|
20
|
+
name: 1
|
|
21
|
+
}, localReq)
|
|
22
|
+
|
|
23
|
+
const existingEntity = allEntities.find((entity) => {
|
|
24
|
+
if (entity.name) {
|
|
25
|
+
// doing the check for case insensitive string (foo === FOO)
|
|
26
|
+
return entity.name.toLowerCase() === name.toLowerCase()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return false
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
if (existingEntity) {
|
|
33
|
+
return { entity: existingEntity, entitySet: c }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function validateDuplicatedName (reporter, c, doc, originalIdValue, req) {
|
|
39
|
+
const resolveEntityPathFn = resolveEntityPath(reporter)
|
|
40
|
+
|
|
41
|
+
if (!reporter.documentStore.model.entitySets[c].entityTypeDef.name) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const name = doc.name
|
|
46
|
+
|
|
47
|
+
if (!name) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const existingEntity = await findEntity(reporter, name, doc.folder, req)
|
|
52
|
+
|
|
53
|
+
if (existingEntity) {
|
|
54
|
+
if (originalIdValue != null && existingEntity.entity._id === originalIdValue) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let msg = `Entity with name "${name}" already exists`
|
|
59
|
+
let folder
|
|
60
|
+
|
|
61
|
+
if (doc.folder != null) {
|
|
62
|
+
folder = await reporter.documentStore.collection('folders').findOne({
|
|
63
|
+
shortid: doc.folder.shortid
|
|
64
|
+
}, req)
|
|
65
|
+
|
|
66
|
+
if (folder) {
|
|
67
|
+
const folderFullPath = await resolveEntityPathFn(folder, 'folders', req)
|
|
68
|
+
|
|
69
|
+
msg = `${msg} in the ${folderFullPath} folder.`
|
|
70
|
+
} else {
|
|
71
|
+
msg = `${msg} in the same folder.`
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
msg = `${msg} at the root level.`
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// prints existing name in message when name are different, this can happen because the name validation
|
|
78
|
+
// is case insensitivity (uppercase and lowercase form are equivalent)
|
|
79
|
+
if (reporter.documentStore.model.entitySets[existingEntity.entitySet].entityTypeDef.name && existingEntity.entity.name !== name) {
|
|
80
|
+
msg = `${msg} existing: "${existingEntity.entity.name}".`
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
throw reporter.createError(msg, {
|
|
84
|
+
statusCode: 400,
|
|
85
|
+
code: 'DUPLICATED_ENTITY',
|
|
86
|
+
existingEntity: existingEntity.entity,
|
|
87
|
+
existingEntityEntitySet: existingEntity.entitySet
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = function (reporter) {
|
|
93
|
+
for (const c of Object.keys(reporter.documentStore.collections)) {
|
|
94
|
+
reporter.documentStore.collection(c).beforeInsertListeners.add('unique-name-folders', (doc, req) => validateDuplicatedName(reporter, c, doc, undefined, req))
|
|
95
|
+
reporter.documentStore.collection(c).beforeUpdateListeners.add('unique-name-folders', async (q, update, opts, req) => {
|
|
96
|
+
if (update.$set && opts && opts.upsert === true) {
|
|
97
|
+
await validateDuplicatedName(reporter, c, update.$set, undefined, req)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// we need to get folder spec so we need to load them anyway
|
|
101
|
+
const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
|
|
102
|
+
return Promise.all(entitiesToUpdate.map(e => validateDuplicatedName(reporter, c, Object.assign({}, e, update.$set), e._id, req)))
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports.validateDuplicatedName = validateDuplicatedName
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
function validateReservedName (reporter, c, doc) {
|
|
2
|
-
if (doc.folder) {
|
|
3
|
-
return
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
if (!reporter.documentStore.model.entitySets[c].entityTypeDef.name) {
|
|
7
|
-
return
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const name = doc.name
|
|
11
|
-
|
|
12
|
-
if (!name) {
|
|
13
|
-
return
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const reservedNames = [
|
|
17
|
-
'storage',
|
|
18
|
-
...Object.keys(
|
|
19
|
-
reporter.documentStore.model.entitySets
|
|
20
|
-
).filter((name) => !reporter.documentStore.model.entitySets[name].splitIntoDirectories).map((name) => name.toLowerCase())
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
if (reservedNames.includes(name.toLowerCase())) {
|
|
24
|
-
throw reporter.createError(`The name "${name}" is reserved in the root folder.`, {
|
|
25
|
-
statusCode: 400
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
module.exports = function (reporter) {
|
|
31
|
-
for (const c of Object.keys(reporter.documentStore.collections)) {
|
|
32
|
-
if (!reporter.documentStore.model.entitySets[c].splitIntoDirectories) {
|
|
33
|
-
continue
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
reporter.documentStore.collection(c).beforeInsertListeners.add('folders', (doc, req) => validateReservedName(reporter, c, doc))
|
|
37
|
-
reporter.documentStore.collection(c).beforeUpdateListeners.add('folders', async (q, update, opts, req) => {
|
|
38
|
-
if (update.$set && opts && opts.upsert === true) {
|
|
39
|
-
await validateReservedName(reporter, c, update.$set)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (!update.$set.name || update.$set.folder) {
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// we need to get folder spec so we need to load them anyway
|
|
47
|
-
const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
|
|
48
|
-
entitiesToUpdate.forEach(e => validateReservedName(reporter, c, Object.assign({}, e, update.$set)))
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
module.exports.validateReservedName = validateReservedName
|
|
1
|
+
function validateReservedName (reporter, c, doc) {
|
|
2
|
+
if (doc.folder) {
|
|
3
|
+
return
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (!reporter.documentStore.model.entitySets[c].entityTypeDef.name) {
|
|
7
|
+
return
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const name = doc.name
|
|
11
|
+
|
|
12
|
+
if (!name) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const reservedNames = [
|
|
17
|
+
'storage',
|
|
18
|
+
...Object.keys(
|
|
19
|
+
reporter.documentStore.model.entitySets
|
|
20
|
+
).filter((name) => !reporter.documentStore.model.entitySets[name].splitIntoDirectories).map((name) => name.toLowerCase())
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
if (reservedNames.includes(name.toLowerCase())) {
|
|
24
|
+
throw reporter.createError(`The name "${name}" is reserved in the root folder.`, {
|
|
25
|
+
statusCode: 400
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = function (reporter) {
|
|
31
|
+
for (const c of Object.keys(reporter.documentStore.collections)) {
|
|
32
|
+
if (!reporter.documentStore.model.entitySets[c].splitIntoDirectories) {
|
|
33
|
+
continue
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
reporter.documentStore.collection(c).beforeInsertListeners.add('folders', (doc, req) => validateReservedName(reporter, c, doc))
|
|
37
|
+
reporter.documentStore.collection(c).beforeUpdateListeners.add('folders', async (q, update, opts, req) => {
|
|
38
|
+
if (update.$set && opts && opts.upsert === true) {
|
|
39
|
+
await validateReservedName(reporter, c, update.$set)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!update.$set.name || update.$set.folder) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// we need to get folder spec so we need to load them anyway
|
|
47
|
+
const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
|
|
48
|
+
entitiesToUpdate.forEach(e => validateReservedName(reporter, c, Object.assign({}, e, update.$set)))
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports.validateReservedName = validateReservedName
|