@jsreport/jsreport-core 3.1.1 → 3.3.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.
- package/LICENSE +166 -166
- package/README.md +298 -298
- package/index.js +29 -29
- package/lib/main/blobStorage/blobStorage.js +52 -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 +237 -237
- package/lib/main/optionsSchema.js +237 -237
- package/lib/main/profiler.js +13 -1
- package/lib/main/reporter.js +593 -579
- 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 -201
- package/lib/worker/render/resolveReferences.js +60 -60
- package/lib/worker/reporter.js +197 -191
- package/lib/worker/sandbox/runInSandbox.js +65 -13
- package/lib/worker/sandbox/safeSandbox.js +829 -828
- package/lib/worker/templates.js +80 -78
- package/lib/worker/workerHandler.js +54 -54
- package/package.json +91 -92
- package/test/blobStorage/common.js +21 -21
- package/test/store/common.js +1449 -1449
|
@@ -1,169 +1,169 @@
|
|
|
1
|
-
|
|
2
|
-
module.exports = function createListenerCollection (_name) {
|
|
3
|
-
const name = _name != null ? `${_name}` : 'Anonymous'
|
|
4
|
-
return new ListenerCollection(name)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
class ListenerCollection {
|
|
8
|
-
constructor (name) {
|
|
9
|
-
this._name = name
|
|
10
|
-
this._listeners = []
|
|
11
|
-
this._pre = []
|
|
12
|
-
this._post = []
|
|
13
|
-
this._postFail = []
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Add listener cb at the end of the current chain.
|
|
18
|
-
* @param {String} key
|
|
19
|
-
* @param {Object|Function} context
|
|
20
|
-
* @param {Function} listener
|
|
21
|
-
*/
|
|
22
|
-
add (key, context, listener) {
|
|
23
|
-
const fn = listener || context
|
|
24
|
-
const _context = listener === null ? this : context
|
|
25
|
-
|
|
26
|
-
this._listeners.push({
|
|
27
|
-
key: key,
|
|
28
|
-
fn,
|
|
29
|
-
context: _context
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Add the listener callback to the particular position in the chain.
|
|
35
|
-
* The position is specified by the index in the array or a condition
|
|
36
|
-
* Example
|
|
37
|
-
* listeners.insert({ pre: "another", post: "another2" }, "foo", this, function() {... });
|
|
38
|
-
*
|
|
39
|
-
* @param {Number|Object} indexOrCondition
|
|
40
|
-
* @param {String} key
|
|
41
|
-
* @param {Object} context
|
|
42
|
-
* @param {Function} listener
|
|
43
|
-
*/
|
|
44
|
-
insert (indexOrCondition, key, context, listener) {
|
|
45
|
-
const listenerOpts = {
|
|
46
|
-
key: key,
|
|
47
|
-
fn: listener || context,
|
|
48
|
-
context: listener === null ? this : context
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!isNaN(indexOrCondition)) {
|
|
52
|
-
return this._listeners.splice(indexOrCondition, 0, listenerOpts)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
let afterInsertIndex = null
|
|
56
|
-
let beforeInsertIndex = null
|
|
57
|
-
|
|
58
|
-
for (let i = 0; i < this._listeners.length; i++) {
|
|
59
|
-
if (this._listeners[i].key === indexOrCondition.after) {
|
|
60
|
-
afterInsertIndex = i + 1
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (this._listeners[i].key === indexOrCondition.before) {
|
|
64
|
-
beforeInsertIndex = i
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const index = afterInsertIndex !== null
|
|
69
|
-
? afterInsertIndex
|
|
70
|
-
: (beforeInsertIndex !== null ? beforeInsertIndex : this._listeners.length)
|
|
71
|
-
|
|
72
|
-
this._listeners.splice(index, 0, listenerOpts)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Remove the listener specified by its key from the collection
|
|
77
|
-
* @param {String} key
|
|
78
|
-
*/
|
|
79
|
-
remove (key) {
|
|
80
|
-
this._listeners = this._listeners.filter((l) => {
|
|
81
|
-
return l.key !== key
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/* Add hook that will be executed before actual listener */
|
|
86
|
-
pre (fn) {
|
|
87
|
-
this._pre.push(fn)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/* Add hook that will be executed after actual listener */
|
|
91
|
-
post (fn) {
|
|
92
|
-
this._post.push(fn)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/* Add hook that will be executed after actual listener when execution will fail */
|
|
96
|
-
postFail (fn) {
|
|
97
|
-
this._postFail.push(fn)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Fires listeners and returns value composed from all boolean results into the single bool
|
|
102
|
-
* @returns {Promise<Boolean>}
|
|
103
|
-
*/
|
|
104
|
-
async fireAndJoinResults (...args) {
|
|
105
|
-
const results = await this.fire(...args)
|
|
106
|
-
|
|
107
|
-
const successes = results.filter((r) => {
|
|
108
|
-
return r === true
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
const failures = results.filter((r) => {
|
|
112
|
-
return r === false
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
const dontCares = results.filter((r) => {
|
|
116
|
-
return r === null || r === undefined
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
if (successes.length && (successes.length + dontCares.length === results.length)) {
|
|
120
|
-
// override pass
|
|
121
|
-
return true
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (failures.length && (failures.length + dontCares.length === results.length)) {
|
|
125
|
-
return false
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (dontCares.length === results.length) {
|
|
129
|
-
return null
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return true
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Fire registered listeners in sequence and returns a promise containing wrapping an array of all
|
|
137
|
-
* individual results.
|
|
138
|
-
* The parameters passed to the fire are forwarded in the same order to the listeners.
|
|
139
|
-
* @returns {Promise<U>}
|
|
140
|
-
*/
|
|
141
|
-
async fire (...args) {
|
|
142
|
-
const self = this
|
|
143
|
-
|
|
144
|
-
const applyHook = function applyHook (l, hookArrayName, outerArgs) {
|
|
145
|
-
self[hookArrayName].forEach((p) => {
|
|
146
|
-
p.apply(l, outerArgs)
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const results = []
|
|
151
|
-
|
|
152
|
-
for (const l of this._listeners) {
|
|
153
|
-
const currentArgs = [...args]
|
|
154
|
-
applyHook(l, '_pre', currentArgs)
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
const val = await l.fn.apply(l.context, currentArgs)
|
|
158
|
-
applyHook(l, '_post', currentArgs)
|
|
159
|
-
results.push(val)
|
|
160
|
-
} catch (e) {
|
|
161
|
-
currentArgs.unshift(e)
|
|
162
|
-
applyHook(l, '_postFail', currentArgs)
|
|
163
|
-
throw e
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return results
|
|
168
|
-
}
|
|
169
|
-
}
|
|
1
|
+
|
|
2
|
+
module.exports = function createListenerCollection (_name) {
|
|
3
|
+
const name = _name != null ? `${_name}` : 'Anonymous'
|
|
4
|
+
return new ListenerCollection(name)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class ListenerCollection {
|
|
8
|
+
constructor (name) {
|
|
9
|
+
this._name = name
|
|
10
|
+
this._listeners = []
|
|
11
|
+
this._pre = []
|
|
12
|
+
this._post = []
|
|
13
|
+
this._postFail = []
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Add listener cb at the end of the current chain.
|
|
18
|
+
* @param {String} key
|
|
19
|
+
* @param {Object|Function} context
|
|
20
|
+
* @param {Function} listener
|
|
21
|
+
*/
|
|
22
|
+
add (key, context, listener) {
|
|
23
|
+
const fn = listener || context
|
|
24
|
+
const _context = listener === null ? this : context
|
|
25
|
+
|
|
26
|
+
this._listeners.push({
|
|
27
|
+
key: key,
|
|
28
|
+
fn,
|
|
29
|
+
context: _context
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Add the listener callback to the particular position in the chain.
|
|
35
|
+
* The position is specified by the index in the array or a condition
|
|
36
|
+
* Example
|
|
37
|
+
* listeners.insert({ pre: "another", post: "another2" }, "foo", this, function() {... });
|
|
38
|
+
*
|
|
39
|
+
* @param {Number|Object} indexOrCondition
|
|
40
|
+
* @param {String} key
|
|
41
|
+
* @param {Object} context
|
|
42
|
+
* @param {Function} listener
|
|
43
|
+
*/
|
|
44
|
+
insert (indexOrCondition, key, context, listener) {
|
|
45
|
+
const listenerOpts = {
|
|
46
|
+
key: key,
|
|
47
|
+
fn: listener || context,
|
|
48
|
+
context: listener === null ? this : context
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!isNaN(indexOrCondition)) {
|
|
52
|
+
return this._listeners.splice(indexOrCondition, 0, listenerOpts)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let afterInsertIndex = null
|
|
56
|
+
let beforeInsertIndex = null
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < this._listeners.length; i++) {
|
|
59
|
+
if (this._listeners[i].key === indexOrCondition.after) {
|
|
60
|
+
afterInsertIndex = i + 1
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (this._listeners[i].key === indexOrCondition.before) {
|
|
64
|
+
beforeInsertIndex = i
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const index = afterInsertIndex !== null
|
|
69
|
+
? afterInsertIndex
|
|
70
|
+
: (beforeInsertIndex !== null ? beforeInsertIndex : this._listeners.length)
|
|
71
|
+
|
|
72
|
+
this._listeners.splice(index, 0, listenerOpts)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Remove the listener specified by its key from the collection
|
|
77
|
+
* @param {String} key
|
|
78
|
+
*/
|
|
79
|
+
remove (key) {
|
|
80
|
+
this._listeners = this._listeners.filter((l) => {
|
|
81
|
+
return l.key !== key
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Add hook that will be executed before actual listener */
|
|
86
|
+
pre (fn) {
|
|
87
|
+
this._pre.push(fn)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Add hook that will be executed after actual listener */
|
|
91
|
+
post (fn) {
|
|
92
|
+
this._post.push(fn)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Add hook that will be executed after actual listener when execution will fail */
|
|
96
|
+
postFail (fn) {
|
|
97
|
+
this._postFail.push(fn)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Fires listeners and returns value composed from all boolean results into the single bool
|
|
102
|
+
* @returns {Promise<Boolean>}
|
|
103
|
+
*/
|
|
104
|
+
async fireAndJoinResults (...args) {
|
|
105
|
+
const results = await this.fire(...args)
|
|
106
|
+
|
|
107
|
+
const successes = results.filter((r) => {
|
|
108
|
+
return r === true
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
const failures = results.filter((r) => {
|
|
112
|
+
return r === false
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const dontCares = results.filter((r) => {
|
|
116
|
+
return r === null || r === undefined
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
if (successes.length && (successes.length + dontCares.length === results.length)) {
|
|
120
|
+
// override pass
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (failures.length && (failures.length + dontCares.length === results.length)) {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (dontCares.length === results.length) {
|
|
129
|
+
return null
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return true
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Fire registered listeners in sequence and returns a promise containing wrapping an array of all
|
|
137
|
+
* individual results.
|
|
138
|
+
* The parameters passed to the fire are forwarded in the same order to the listeners.
|
|
139
|
+
* @returns {Promise<U>}
|
|
140
|
+
*/
|
|
141
|
+
async fire (...args) {
|
|
142
|
+
const self = this
|
|
143
|
+
|
|
144
|
+
const applyHook = function applyHook (l, hookArrayName, outerArgs) {
|
|
145
|
+
self[hookArrayName].forEach((p) => {
|
|
146
|
+
p.apply(l, outerArgs)
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const results = []
|
|
151
|
+
|
|
152
|
+
for (const l of this._listeners) {
|
|
153
|
+
const currentArgs = [...args]
|
|
154
|
+
applyHook(l, '_pre', currentArgs)
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const val = await l.fn.apply(l.context, currentArgs)
|
|
158
|
+
applyHook(l, '_post', currentArgs)
|
|
159
|
+
results.push(val)
|
|
160
|
+
} catch (e) {
|
|
161
|
+
currentArgs.unshift(e)
|
|
162
|
+
applyHook(l, '_postFail', currentArgs)
|
|
163
|
+
throw e
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return results
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
const omit = require('lodash.omit')
|
|
2
|
-
|
|
3
|
-
module.exports = (level, msg, meta) => {
|
|
4
|
-
// detecting if meta is jsreport request object
|
|
5
|
-
if (meta != null && meta.context) {
|
|
6
|
-
meta.context.logs = meta.context.logs || []
|
|
7
|
-
|
|
8
|
-
meta.context.logs.push({
|
|
9
|
-
level: level,
|
|
10
|
-
message: msg,
|
|
11
|
-
timestamp: meta.timestamp || new Date().getTime()
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
// TODO adding cancel looks bad, its before script is adding req.cancel()
|
|
15
|
-
// excluding non relevant properties for the log
|
|
16
|
-
const newMeta = Object.assign({}, omit(meta, ['template', 'options', 'data', 'context', 'timestamp', 'cancel']))
|
|
17
|
-
|
|
18
|
-
if (newMeta.rootId == null && meta.context.rootId != null) {
|
|
19
|
-
newMeta.rootId = meta.context.rootId
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (newMeta.id == null && meta.context.id != null) {
|
|
23
|
-
newMeta.id = meta.context.id
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return newMeta
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return meta
|
|
30
|
-
}
|
|
1
|
+
const omit = require('lodash.omit')
|
|
2
|
+
|
|
3
|
+
module.exports = (level, msg, meta) => {
|
|
4
|
+
// detecting if meta is jsreport request object
|
|
5
|
+
if (meta != null && meta.context) {
|
|
6
|
+
meta.context.logs = meta.context.logs || []
|
|
7
|
+
|
|
8
|
+
meta.context.logs.push({
|
|
9
|
+
level: level,
|
|
10
|
+
message: msg,
|
|
11
|
+
timestamp: meta.timestamp || new Date().getTime()
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// TODO adding cancel looks bad, its before script is adding req.cancel()
|
|
15
|
+
// excluding non relevant properties for the log
|
|
16
|
+
const newMeta = Object.assign({}, omit(meta, ['template', 'options', 'data', 'context', 'timestamp', 'cancel']))
|
|
17
|
+
|
|
18
|
+
if (newMeta.rootId == null && meta.context.rootId != null) {
|
|
19
|
+
newMeta.rootId = meta.context.rootId
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (newMeta.id == null && meta.context.id != null) {
|
|
23
|
+
newMeta.id = meta.context.id
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return newMeta
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return meta
|
|
30
|
+
}
|
package/lib/shared/reporter.js
CHANGED
|
@@ -1,123 +1,128 @@
|
|
|
1
|
-
const EventEmitter = require('events')
|
|
2
|
-
const createListenerCollection = require('./listenerCollection')
|
|
3
|
-
const Request = require('./request')
|
|
4
|
-
const Templates = require('./templates')
|
|
5
|
-
const Folders = require('./folders')
|
|
6
|
-
const createOrExtendError = require('./createError')
|
|
7
|
-
const tempFilesHandler = require('./tempFilesHandler')
|
|
8
|
-
const encryption = require('./encryption')
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
1
|
+
const EventEmitter = require('events')
|
|
2
|
+
const createListenerCollection = require('./listenerCollection')
|
|
3
|
+
const Request = require('./request')
|
|
4
|
+
const Templates = require('./templates')
|
|
5
|
+
const Folders = require('./folders')
|
|
6
|
+
const createOrExtendError = require('./createError')
|
|
7
|
+
const tempFilesHandler = require('./tempFilesHandler')
|
|
8
|
+
const encryption = require('./encryption')
|
|
9
|
+
const generateRequestId = require('../shared/generateRequestId')
|
|
10
|
+
|
|
11
|
+
class Reporter extends EventEmitter {
|
|
12
|
+
constructor (options) {
|
|
13
|
+
super()
|
|
14
|
+
|
|
15
|
+
this.options = options || {}
|
|
16
|
+
this.Request = Request
|
|
17
|
+
|
|
18
|
+
// since `reporter` instance will be used for other extensions,
|
|
19
|
+
// it will quickly reach the limit of `10` listeners,
|
|
20
|
+
// we increase the limit to Infinity for now,
|
|
21
|
+
// later we should probably design
|
|
22
|
+
// a way to detect possible memory leaks from extensions
|
|
23
|
+
this.setMaxListeners(Infinity)
|
|
24
|
+
|
|
25
|
+
const coreVersion = require('../../package.json').version
|
|
26
|
+
|
|
27
|
+
this.version = coreVersion
|
|
28
|
+
this.coreVersion = coreVersion
|
|
29
|
+
|
|
30
|
+
this.initializeListeners = this.createListenerCollection('initialize')
|
|
31
|
+
this.afterRenderListeners = this.createListenerCollection('afterRender')
|
|
32
|
+
this.renderErrorListeners = this.createListenerCollection('renderError')
|
|
33
|
+
this.beforeRenderListeners = this.createListenerCollection('beforeRender')
|
|
34
|
+
this.closeListeners = this.createListenerCollection('close')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
createListenerCollection (name) {
|
|
38
|
+
return createListenerCollection(name)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a custom error or extends an existing one
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
createError (message, options = {}) {
|
|
47
|
+
return createOrExtendError(message, options)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
generateRequestId () {
|
|
51
|
+
return generateRequestId()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Ensures that the jsreport auto-cleanup temp directory (options.tempAutoCleanupDirectory) exists by doing a mkdir call
|
|
56
|
+
*
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
async ensureTempDirectoryExists () {
|
|
60
|
+
if (this.options.tempAutoCleanupDirectory == null) {
|
|
61
|
+
throw new Error('Can not use ensureTempDirectoryExists when tempAutoCleanupDirectory option is not initialized, make sure to initialize jsreport first using jsreport.init()')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return tempFilesHandler.ensureTempDirectoryExists(this.options.tempAutoCleanupDirectory)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reads a file from the jsreport auto-cleanup temp directory (options.tempAutoCleanupDirectory)
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
async readTempFile (filename, opts) {
|
|
73
|
+
if (this.options.tempAutoCleanupDirectory == null) {
|
|
74
|
+
throw new Error('Can not use readTempFile when tempAutoCleanupDirectory option is not initialized, make sure to initialize jsreport first using jsreport.init()')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return tempFilesHandler.readTempFile(this.options.tempAutoCleanupDirectory, filename, opts)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Creates a file into the jsreport auto-cleanup temp directory (options.tempAutoCleanupDirectory)
|
|
82
|
+
* ensuring that the directory always exists
|
|
83
|
+
*
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
async writeTempFile (filenameFn, content, opts) {
|
|
87
|
+
if (this.options.tempAutoCleanupDirectory == null) {
|
|
88
|
+
throw new Error('Can not use writeTempFile when tempAutoCleanupDirectory option is not initialized, make sure to initialize jsreport first using jsreport.init()')
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return tempFilesHandler.writeTempFile(this.options.tempAutoCleanupDirectory, filenameFn, content, opts)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Reads a file as stream from the jsreport auto-cleanup temp directory (options.tempAutoCleanupDirectory)
|
|
96
|
+
*
|
|
97
|
+
* @public
|
|
98
|
+
*/
|
|
99
|
+
async readTempFileStream (filename, opts) {
|
|
100
|
+
if (this.options.tempAutoCleanupDirectory == null) {
|
|
101
|
+
throw new Error('Can not use readTempFileStream when tempAutoCleanupDirectory option is not initialized, make sure to initialize jsreport first using jsreport.init()')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return tempFilesHandler.readTempFileStream(this.options.tempAutoCleanupDirectory, filename, opts)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Creates a file as stream into the jsreport auto-cleanup temp directory (options.tempAutoCleanupDirectory)
|
|
109
|
+
* ensuring that the directory always exists
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
async writeTempFileStream (filenameFn, opts) {
|
|
114
|
+
if (this.options.tempAutoCleanupDirectory == null) {
|
|
115
|
+
throw new Error('Can not use writeTempFileStream when tempAutoCleanupDirectory option is not initialized, make sure to initialize jsreport first using jsreport.init()')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return tempFilesHandler.writeTempFileStream(this.options.tempAutoCleanupDirectory, filenameFn, opts)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async init () {
|
|
122
|
+
this.templates = Templates(this)
|
|
123
|
+
this.folders = Folders(this)
|
|
124
|
+
this.encryption = encryption(this)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
module.exports = Reporter
|