@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.
Files changed (81) hide show
  1. package/LICENSE +166 -166
  2. package/README.md +310 -298
  3. package/index.js +29 -29
  4. package/lib/main/blobStorage/blobStorage.js +53 -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 +254 -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 +92 -91
  26. package/lib/main/optionsLoad.js +231 -237
  27. package/lib/main/optionsSchema.js +237 -237
  28. package/lib/main/profiler.js +13 -1
  29. package/lib/main/reporter.js +589 -579
  30. package/lib/main/request.js +21 -0
  31. package/lib/main/schemaValidator.js +252 -252
  32. package/lib/main/settings.js +154 -154
  33. package/lib/main/store/checkDuplicatedId.js +27 -27
  34. package/lib/main/store/collection.js +329 -329
  35. package/lib/main/store/documentStore.js +469 -469
  36. package/lib/main/store/mainActions.js +28 -28
  37. package/lib/main/store/memoryStoreProvider.js +99 -99
  38. package/lib/main/store/queue.js +48 -48
  39. package/lib/main/store/referenceUtils.js +251 -251
  40. package/lib/main/store/setupValidateId.js +43 -43
  41. package/lib/main/store/setupValidateShortid.js +71 -71
  42. package/lib/main/store/transaction.js +69 -69
  43. package/lib/main/store/typeUtils.js +180 -180
  44. package/lib/main/templates.js +34 -34
  45. package/lib/main/validateEntityName.js +62 -62
  46. package/lib/shared/createError.js +36 -36
  47. package/lib/shared/encryption.js +114 -114
  48. package/lib/shared/folders/index.js +11 -11
  49. package/lib/shared/folders/normalizeEntityPath.js +15 -15
  50. package/lib/shared/folders/resolveEntityFromPath.js +88 -88
  51. package/lib/shared/folders/resolveEntityPath.js +46 -46
  52. package/lib/shared/folders/resolveFolderFromPath.js +38 -38
  53. package/lib/shared/generateRequestId.js +4 -4
  54. package/lib/shared/listenerCollection.js +169 -169
  55. package/lib/shared/normalizeMetaFromLogs.js +30 -30
  56. package/lib/shared/reporter.js +128 -123
  57. package/lib/shared/request.js +64 -64
  58. package/lib/shared/tempFilesHandler.js +81 -81
  59. package/lib/shared/templates.js +82 -82
  60. package/lib/static/helpers.js +33 -33
  61. package/lib/worker/blobStorage.js +34 -34
  62. package/lib/worker/defaultProxyExtend.js +46 -46
  63. package/lib/worker/documentStore.js +49 -49
  64. package/lib/worker/extensionsManager.js +17 -17
  65. package/lib/worker/logger.js +48 -48
  66. package/lib/worker/render/diff.js +138 -138
  67. package/lib/worker/render/executeEngine.js +232 -207
  68. package/lib/worker/render/htmlRecipe.js +10 -10
  69. package/lib/worker/render/moduleHelper.js +45 -43
  70. package/lib/worker/render/noneEngine.js +12 -12
  71. package/lib/worker/render/profiler.js +162 -158
  72. package/lib/worker/render/render.js +202 -205
  73. package/lib/worker/render/resolveReferences.js +60 -60
  74. package/lib/worker/reporter.js +197 -191
  75. package/lib/worker/sandbox/runInSandbox.js +64 -12
  76. package/lib/worker/sandbox/safeSandbox.js +829 -828
  77. package/lib/worker/templates.js +80 -78
  78. package/lib/worker/workerHandler.js +55 -54
  79. package/package.json +91 -92
  80. package/test/blobStorage/common.js +25 -21
  81. package/test/store/common.js +1449 -1449
@@ -1,158 +1,162 @@
1
- const extend = require('node.extend.without.arrays')
2
- const isbinaryfile = require('isbinaryfile').isBinaryFileSync
3
- const omit = require('lodash.omit')
4
- const { createPatch } = require('./diff')
5
- const generateRequestId = require('../../shared/generateRequestId')
6
-
7
- class Profiler {
8
- constructor (reporter) {
9
- this.reporter = reporter
10
-
11
- this.reporter.addRequestContextMetaConfig('profiling', { sandboxReadOnly: true })
12
- this.reporter.addRequestContextMetaConfig('resolvedTemplate', { sandboxHidden: true })
13
-
14
- this.reporter.beforeMainActionListeners.add('profiler', (actionName, data, req) => {
15
- if (actionName === 'log' && req.context.profiling) {
16
- data.previousOperationId = req.context.profiling.lastOperationId
17
- }
18
- })
19
-
20
- this.profiledRequestsMap = new Map()
21
- const profileEventsFlushInterval = setInterval(async () => {
22
- for (const id of [...this.profiledRequestsMap.keys()]) {
23
- const profilingInfo = this.profiledRequestsMap.get(id)
24
- if (profilingInfo) {
25
- const batch = profilingInfo.batch
26
- profilingInfo.batch = []
27
- await this.reporter.executeMainAction('profile', batch, profilingInfo.req).catch((e) => this.reporter.logger.error(e, profilingInfo.req))
28
- }
29
- }
30
- }, 100)
31
- profileEventsFlushInterval.unref()
32
-
33
- this.reporter.closeListeners.add('profiler', this, () => {
34
- if (profileEventsFlushInterval) {
35
- clearInterval(profileEventsFlushInterval)
36
- }
37
- })
38
- }
39
-
40
- emit (m, req, res) {
41
- m.timestamp = m.timestamp || new Date().getTime()
42
-
43
- if (m.type === 'log' && !req.context.profiling) {
44
- // this means there is an action running, but not the render, and it is logging...
45
- return this.reporter.executeMainAction('log', m, req)
46
- }
47
-
48
- m.id = generateRequestId()
49
-
50
- if (m.previousEventId == null && req.context.profiling.lastEventId && m.type !== 'log') {
51
- m.previousEventId = req.context.profiling.lastEventId
52
- }
53
-
54
- if (m.type !== 'log') {
55
- req.context.profiling.lastEventId = m.id
56
- }
57
-
58
- m.operationId = m.operationId || generateRequestId()
59
- if (m.previousOperationId == null && req.context.profiling.lastOperationId) {
60
- m.previousOperationId = req.context.profiling.lastOperationId
61
- }
62
-
63
- if (m.type === 'operationStart') {
64
- req.context.profiling.lastOperationId = m.operationId
65
- }
66
-
67
- if (m.doDiffs !== false && req.context.profiling.mode === 'full' && (m.type === 'operationStart' || m.type === 'operationEnd')) {
68
- let content = res.content
69
-
70
- if (content != null) {
71
- if (isbinaryfile(content)) {
72
- content = {
73
- content: res.content.toString('base64'),
74
- encoding: 'base64'
75
- }
76
- } else {
77
- content = {
78
- content: createPatch('res', req.context.profiling.resLastVal ? req.context.profiling.resLastVal.toString() : '', res.content.toString(), 0),
79
- encoding: 'diff'
80
- }
81
- }
82
- }
83
-
84
- const stringifiedResMeta = JSON.stringify(omit(res.meta, ['logs']))
85
-
86
- m.res = { content, meta: { diff: createPatch('resMeta', req.context.profiling.resMetaLastVal || '', stringifiedResMeta, 0) } }
87
-
88
- const stringifiedReq = JSON.stringify({ template: req.template, data: req.data }, null, 2)
89
-
90
- m.req = { diff: createPatch('req', req.context.profiling.reqLastVal || '', stringifiedReq, 0) }
91
-
92
- req.context.profiling.resLastVal = res.content
93
- req.context.profiling.resMetaLastVal = stringifiedResMeta
94
- req.context.profiling.reqLastVal = stringifiedReq
95
- }
96
-
97
- if (!this.profiledRequestsMap.has(req.context.rootId)) {
98
- this.profiledRequestsMap.set(req.context.rootId, { req, batch: [] })
99
- }
100
-
101
- this.profiledRequestsMap.get(req.context.rootId).batch.push(m)
102
- return m
103
- }
104
-
105
- async renderStart (req, parentReq, res) {
106
- let templateName = 'anonymous'
107
- let template = req.context.resolvedTemplate
108
-
109
- if (parentReq) {
110
- template = await this.reporter.templates.resolveTemplate(req)
111
- // store a copy to prevent side-effects
112
- req.context.resolvedTemplate = extend(true, {}, template)
113
- } else {
114
- template = req.context.resolvedTemplate
115
- }
116
-
117
- if (template != null && template.name != null) {
118
- templateName = template.name
119
- }
120
-
121
- const profilerEvent = {
122
- type: 'operationStart',
123
- subtype: 'render',
124
- name: templateName,
125
- previousOperationId: parentReq ? parentReq.context.profiling.lastOperationId : null
126
- }
127
-
128
- if (!req.context.isChildRequest) {
129
- profilerEvent.profileId = req.context.profiling.entity._id
130
- }
131
-
132
- return this.emit(profilerEvent, req, res)
133
- }
134
-
135
- async renderEnd (operationId, req, res, err) {
136
- if (err) {
137
- err.previousOperationId = err.previousOperationId || req.context.profiling.lastOperationId
138
- } else {
139
- await this.emit({
140
- type: 'operationEnd',
141
- subtype: 'render',
142
- operationId
143
- }, req, res)
144
- }
145
-
146
- if (!req.context.isChildRequest) {
147
- const profilingInfo = this.profiledRequestsMap.get(req.context.rootId)
148
- if (profilingInfo) {
149
- this.profiledRequestsMap.delete(req.context.rootId)
150
- await this.reporter.executeMainAction('profile', profilingInfo.batch, req)
151
- }
152
- }
153
- }
154
- }
155
-
156
- module.exports = (reporter) => {
157
- return new Profiler(reporter)
158
- }
1
+ const extend = require('node.extend.without.arrays')
2
+ const isbinaryfile = require('isbinaryfile').isBinaryFileSync
3
+ const omit = require('lodash.omit')
4
+ const { createPatch } = require('./diff')
5
+ const generateRequestId = require('../../shared/generateRequestId')
6
+
7
+ class Profiler {
8
+ constructor (reporter) {
9
+ this.reporter = reporter
10
+
11
+ this.reporter.addRequestContextMetaConfig('profiling', { sandboxHidden: true })
12
+ this.reporter.addRequestContextMetaConfig('resolvedTemplate', { sandboxHidden: true })
13
+
14
+ this.reporter.beforeMainActionListeners.add('profiler', (actionName, data, req) => {
15
+ if (actionName === 'log' && req.context.profiling) {
16
+ data.previousOperationId = req.context.profiling.lastOperationId
17
+ }
18
+ })
19
+
20
+ this.profiledRequestsMap = new Map()
21
+ const profileEventsFlushInterval = setInterval(() => this.flush(), 100)
22
+ profileEventsFlushInterval.unref()
23
+
24
+ this.reporter.closeListeners.add('profiler', this, () => {
25
+ if (profileEventsFlushInterval) {
26
+ clearInterval(profileEventsFlushInterval)
27
+ }
28
+ })
29
+ }
30
+
31
+ async flush (id) {
32
+ const toProcess = id == null ? [...this.profiledRequestsMap.keys()] : [id]
33
+
34
+ for (const id of toProcess) {
35
+ const profilingInfo = this.profiledRequestsMap.get(id)
36
+ if (profilingInfo) {
37
+ const batch = profilingInfo.batch
38
+ profilingInfo.batch = []
39
+ await this.reporter.executeMainAction('profile', batch, profilingInfo.req).catch((e) => this.reporter.logger.error(e, profilingInfo.req))
40
+ }
41
+ }
42
+ }
43
+
44
+ emit (m, req, res) {
45
+ m.timestamp = m.timestamp || new Date().getTime()
46
+
47
+ if (m.type === 'log' && !req.context.profiling) {
48
+ // this means there is an action running, but not the render, and it is logging...
49
+ return this.reporter.executeMainAction('log', m, req)
50
+ }
51
+
52
+ m.id = generateRequestId()
53
+
54
+ if (m.previousEventId == null && req.context.profiling.lastEventId && m.type !== 'log') {
55
+ m.previousEventId = req.context.profiling.lastEventId
56
+ }
57
+
58
+ if (m.type !== 'log') {
59
+ req.context.profiling.lastEventId = m.id
60
+ }
61
+
62
+ m.operationId = m.operationId || generateRequestId()
63
+ if (m.previousOperationId == null && req.context.profiling.lastOperationId) {
64
+ m.previousOperationId = req.context.profiling.lastOperationId
65
+ }
66
+
67
+ if (m.type === 'operationStart') {
68
+ req.context.profiling.lastOperationId = m.operationId
69
+ }
70
+
71
+ if (m.doDiffs !== false && req.context.profiling.mode === 'full' && (m.type === 'operationStart' || m.type === 'operationEnd')) {
72
+ let content = res.content
73
+
74
+ if (content != null) {
75
+ if (isbinaryfile(content)) {
76
+ content = {
77
+ content: res.content.toString('base64'),
78
+ encoding: 'base64'
79
+ }
80
+ } else {
81
+ content = {
82
+ content: createPatch('res', req.context.profiling.resLastVal ? req.context.profiling.resLastVal.toString() : '', res.content.toString(), 0),
83
+ encoding: 'diff'
84
+ }
85
+ }
86
+ }
87
+
88
+ const stringifiedResMeta = JSON.stringify(omit(res.meta, ['logs']))
89
+
90
+ m.res = { content, meta: { diff: createPatch('resMeta', req.context.profiling.resMetaLastVal || '', stringifiedResMeta, 0) } }
91
+
92
+ const stringifiedReq = JSON.stringify({ template: req.template, data: req.data }, null, 2)
93
+
94
+ m.req = { diff: createPatch('req', req.context.profiling.reqLastVal || '', stringifiedReq, 0) }
95
+
96
+ req.context.profiling.resLastVal = (res.content == null || isbinaryfile(res.content)) ? null : res.content.toString()
97
+ req.context.profiling.resMetaLastVal = stringifiedResMeta
98
+ req.context.profiling.reqLastVal = stringifiedReq
99
+ }
100
+
101
+ if (!this.profiledRequestsMap.has(req.context.rootId)) {
102
+ this.profiledRequestsMap.set(req.context.rootId, { req, batch: [] })
103
+ }
104
+
105
+ this.profiledRequestsMap.get(req.context.rootId).batch.push(m)
106
+ return m
107
+ }
108
+
109
+ async renderStart (req, parentReq, res) {
110
+ let templateName = 'anonymous'
111
+ let template = req.context.resolvedTemplate
112
+
113
+ if (parentReq) {
114
+ template = await this.reporter.templates.resolveTemplate(req)
115
+ // store a copy to prevent side-effects
116
+ req.context.resolvedTemplate = extend(true, {}, template)
117
+ } else {
118
+ template = req.context.resolvedTemplate
119
+ }
120
+
121
+ if (template != null && template.name != null) {
122
+ templateName = template.name
123
+ }
124
+
125
+ const profilerEvent = {
126
+ type: 'operationStart',
127
+ subtype: 'render',
128
+ name: templateName,
129
+ previousOperationId: parentReq ? parentReq.context.profiling.lastOperationId : null
130
+ }
131
+
132
+ if (!req.context.isChildRequest) {
133
+ profilerEvent.profileId = req.context.profiling.entity._id
134
+ }
135
+
136
+ return this.emit(profilerEvent, req, res)
137
+ }
138
+
139
+ async renderEnd (operationId, req, res, err) {
140
+ if (err) {
141
+ err.previousOperationId = err.previousOperationId || req.context.profiling.lastOperationId
142
+ } else {
143
+ await this.emit({
144
+ type: 'operationEnd',
145
+ subtype: 'render',
146
+ operationId
147
+ }, req, res)
148
+ }
149
+
150
+ if (!req.context.isChildRequest) {
151
+ const profilingInfo = this.profiledRequestsMap.get(req.context.rootId)
152
+ if (profilingInfo) {
153
+ this.profiledRequestsMap.delete(req.context.rootId)
154
+ await this.reporter.executeMainAction('profile', profilingInfo.batch, req)
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ module.exports = (reporter) => {
161
+ return new Profiler(reporter)
162
+ }