@jsreport/jsreport-core 4.1.0 → 4.2.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/README.md +5 -0
- package/lib/main/reporter.js +13 -17
- package/lib/main/request.js +25 -16
- package/lib/shared/reporter.js +67 -1
- package/lib/shared/reqStorage.js +20 -0
- package/lib/shared/response.js +249 -0
- package/lib/shared/tempFilesHandler.js +95 -29
- package/lib/worker/defaultProxyExtend.js +2 -4
- package/lib/worker/render/engineStream.js +97 -0
- package/lib/worker/render/executeEngine.js +32 -6
- package/lib/worker/render/profiler.js +12 -4
- package/lib/worker/render/render.js +15 -8
- package/lib/worker/reporter.js +7 -13
- package/lib/worker/sandbox/isolatedRequire.js +25 -46
- package/lib/worker/sandbox/requireSandbox.js +69 -24
- package/lib/worker/sandbox/resolveFilename.js +30 -0
- package/lib/worker/sandbox/runInSandbox.js +16 -0
- package/package.json +3 -3
- package/test/extensions/validExtensions/listeners/main.js +16 -8
- package/test/extensions/validExtensions/listeners/worker.js +81 -81
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = function resolveFilename (cache, resolveModulePath, moduleId, extra) {
|
|
3
|
+
const { parentModulePath, options } = extra
|
|
4
|
+
const useCache = options == null
|
|
5
|
+
const resolveCacheKey = parentModulePath ? `${parentModulePath}::${moduleId}` : moduleId
|
|
6
|
+
let fullModulePath
|
|
7
|
+
|
|
8
|
+
if (useCache && cache.has(resolveCacheKey)) {
|
|
9
|
+
fullModulePath = cache.get(resolveCacheKey)
|
|
10
|
+
} else {
|
|
11
|
+
if (parentModulePath) {
|
|
12
|
+
const optionsToUse = { ...options }
|
|
13
|
+
|
|
14
|
+
// search from the parent module path by default if not explicit .paths has been passed
|
|
15
|
+
if (optionsToUse.paths == null) {
|
|
16
|
+
optionsToUse.paths = [parentModulePath]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fullModulePath = resolveModulePath(moduleId, optionsToUse)
|
|
20
|
+
} else {
|
|
21
|
+
fullModulePath = resolveModulePath(moduleId)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (useCache) {
|
|
25
|
+
cache.set(resolveCacheKey, fullModulePath)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return fullModulePath
|
|
30
|
+
}
|
|
@@ -66,6 +66,22 @@ module.exports = function createRunInSandbox (reporter) {
|
|
|
66
66
|
const m = reporter.options.sandbox.modules.find((m) => m.alias === moduleName || m.path === moduleName)
|
|
67
67
|
|
|
68
68
|
if (m) {
|
|
69
|
+
const cachedModuleFromOutside = require.cache[m.path]
|
|
70
|
+
|
|
71
|
+
// this is an optimization, the requireMap always go the built-in node require,
|
|
72
|
+
// which has an overhead, even if the module you are trying to resolve is already cached
|
|
73
|
+
// node will try to resolve filename when the require happens from different module than
|
|
74
|
+
// it was requested first time.
|
|
75
|
+
// this becomes an issue when you do a lazy require inside helper execution, if this helper
|
|
76
|
+
// is a hot path (executed multiple times during rendering)
|
|
77
|
+
// then you are adding extra time per the amount of times you call the helper
|
|
78
|
+
// (which is big if you call this in a loop for 15K items),
|
|
79
|
+
// the solution is to try first from the require cache directly, and fallback to built-in require
|
|
80
|
+
// when not found, we can do this because we are sure the m.path is the path to the resolved filename of module
|
|
81
|
+
if (cachedModuleFromOutside != null) {
|
|
82
|
+
return cachedModuleFromOutside.exports
|
|
83
|
+
}
|
|
84
|
+
|
|
69
85
|
return require(m.path)
|
|
70
86
|
}
|
|
71
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsreport/jsreport-core",
|
|
3
|
-
"version": "4.1
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"description": "javascript based business reporting",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"report",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@babel/parser": "7.23.5",
|
|
41
41
|
"@babel/traverse": "7.23.5",
|
|
42
42
|
"@colors/colors": "1.5.0",
|
|
43
|
-
"@jsreport/advanced-workers": "2.0.
|
|
43
|
+
"@jsreport/advanced-workers": "2.0.2",
|
|
44
44
|
"@jsreport/mingo": "2.4.1",
|
|
45
45
|
"@jsreport/reap": "0.1.0",
|
|
46
46
|
"@jsreport/serializator": "1.0.0",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@node-rs/jsonwebtoken": "0.2.0",
|
|
81
|
-
"mocha": "
|
|
81
|
+
"mocha": "10.1.0",
|
|
82
82
|
"should": "13.2.3",
|
|
83
83
|
"standard": "16.0.4",
|
|
84
84
|
"std-mocks": "1.0.1",
|
|
@@ -8,23 +8,31 @@ module.exports = (reporter, definition) => {
|
|
|
8
8
|
|
|
9
9
|
reporter.registerMainAction('test-beforeRender-listeners', async (data, req) => {
|
|
10
10
|
data.req = reporter.Request(data.req)
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const localRes = reporter.Response(data.req.context.id)
|
|
12
|
+
await localRes.parse(data.res)
|
|
13
|
+
await reporter.tests.beforeRenderListeners.fire(data.req, localRes)
|
|
14
|
+
return { req: data.req, res: localRes.serialize() }
|
|
13
15
|
})
|
|
14
16
|
reporter.registerMainAction('test-afterRender-listeners', async (data, req) => {
|
|
15
17
|
data.req = reporter.Request(data.req)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
const localRes = reporter.Response(data.req.context.id)
|
|
19
|
+
await localRes.parse(data.res)
|
|
20
|
+
await reporter.tests.afterRenderListeners.fire(data.req, localRes)
|
|
21
|
+
return { req: data.req, res: localRes.serialize() }
|
|
18
22
|
})
|
|
19
23
|
reporter.registerMainAction('test-validateRender-listeners', async (data, req) => {
|
|
20
24
|
data.req = reporter.Request(data.req)
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
const localRes = reporter.Response(data.req.context.id)
|
|
26
|
+
await localRes.parse(data.res)
|
|
27
|
+
await reporter.tests.validateRenderListeners.fire(data.req, localRes)
|
|
28
|
+
return { req: data.req, res: localRes.serialize() }
|
|
23
29
|
})
|
|
24
30
|
reporter.registerMainAction('test-afterTemplatingEnginesExecuted-listeners', async (data, req) => {
|
|
25
31
|
data.req = reporter.Request(data.req)
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
const localRes = reporter.Response(data.req.context.id)
|
|
33
|
+
await localRes.parse(data.res)
|
|
34
|
+
await reporter.tests.afterTemplatingEnginesExecutedListeners.fire(data.req, localRes)
|
|
35
|
+
return { req: data.req, res: localRes.serialize() }
|
|
28
36
|
})
|
|
29
37
|
|
|
30
38
|
let beforeRenderEval
|
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
const extend = require('node.extend.without.arrays')
|
|
2
|
-
const vm = require('vm')
|
|
3
|
-
const Module = require('module')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const process = require('process')
|
|
6
|
-
|
|
7
|
-
module.exports = (reporter, definition) => {
|
|
8
|
-
reporter.initializeListeners.add('test-listeners', () => {
|
|
9
|
-
reporter.beforeRenderListeners.add('listeners', async (req, res) => {
|
|
10
|
-
const result = await reporter.executeMainAction('test-beforeRender-listeners', { req, res }, req)
|
|
11
|
-
extend(true, req, result.req)
|
|
12
|
-
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
reporter.afterRenderListeners.add('listeners', async (req, res) => {
|
|
16
|
-
const result = await reporter.executeMainAction('test-afterRender-listeners', { req, res }, req)
|
|
17
|
-
extend(true, req, result.req)
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
reporter.validateRenderListeners.add('listeners', async (req, res) => {
|
|
22
|
-
const result = await reporter.executeMainAction('test-validateRender-listeners', { req, res }, req)
|
|
23
|
-
extend(true, req, result.req)
|
|
24
|
-
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
reporter.afterTemplatingEnginesExecutedListeners.add('listeners', async (req, res) => {
|
|
28
|
-
const result = await reporter.executeMainAction('test-afterTemplatingEnginesExecuted-listeners', { req, res }, req)
|
|
29
|
-
extend(true, req, result.req)
|
|
30
|
-
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const evalInWorker = (code, req, res) => {
|
|
34
|
-
const script = new vm.Script(`
|
|
35
|
-
;(function () {
|
|
36
|
-
return ${code}
|
|
37
|
-
})()
|
|
38
|
-
`)
|
|
39
|
-
|
|
40
|
-
return script.runInThisContext({
|
|
41
|
-
displayErrors: true
|
|
42
|
-
})(req, res, {
|
|
43
|
-
mainModuleFilename: require.main.filename,
|
|
44
|
-
require: (m) => {
|
|
45
|
-
if (Module.builtinModules.includes(m)) {
|
|
46
|
-
return require(m)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
return require(path.join(process.cwd(), 'node_modules', m))
|
|
51
|
-
} catch (e) {
|
|
52
|
-
// hack, make it working in monorepo as well as normal extension
|
|
53
|
-
return require(path.join(process.cwd(), '../../node_modules', m))
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
reporter
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
reporter.afterRenderListeners.add('eval-listeners', async (req, res) => {
|
|
61
|
-
const code = await reporter.executeMainAction('test-afterRenderEval', {}, req)
|
|
62
|
-
if (code) {
|
|
63
|
-
return evalInWorker(code, req, res)
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
reporter.beforeRenderListeners.insert(0, 'eval-listeners', async (req, res) => {
|
|
68
|
-
const code = await reporter.executeMainAction('test-beforeRenderEval', {}, req)
|
|
69
|
-
if (code) {
|
|
70
|
-
return evalInWorker(code, req, res)
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
reporter.afterTemplatingEnginesExecutedListeners.add('eval-listeners', async (req, res) => {
|
|
75
|
-
const code = await reporter.executeMainAction('test-afterTemplatingEnginesExecutedEval', {}, req)
|
|
76
|
-
if (code) {
|
|
77
|
-
return evalInWorker(code, req, res)
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
}
|
|
1
|
+
const extend = require('node.extend.without.arrays')
|
|
2
|
+
const vm = require('vm')
|
|
3
|
+
const Module = require('module')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const process = require('process')
|
|
6
|
+
|
|
7
|
+
module.exports = (reporter, definition) => {
|
|
8
|
+
reporter.initializeListeners.add('test-listeners', () => {
|
|
9
|
+
reporter.beforeRenderListeners.add('listeners', async (req, res) => {
|
|
10
|
+
const result = await reporter.executeMainAction('test-beforeRender-listeners', { req, res: await res.serialize() }, req)
|
|
11
|
+
extend(true, req, result.req)
|
|
12
|
+
await res.parse(result.res)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
reporter.afterRenderListeners.add('listeners', async (req, res) => {
|
|
16
|
+
const result = await reporter.executeMainAction('test-afterRender-listeners', { req, res: await res.serialize() }, req)
|
|
17
|
+
extend(true, req, result.req)
|
|
18
|
+
await res.parse(result.res)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
reporter.validateRenderListeners.add('listeners', async (req, res) => {
|
|
22
|
+
const result = await reporter.executeMainAction('test-validateRender-listeners', { req, res: await res.serialize() }, req)
|
|
23
|
+
extend(true, req, result.req)
|
|
24
|
+
await res.parse(result.res)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
reporter.afterTemplatingEnginesExecutedListeners.add('listeners', async (req, res) => {
|
|
28
|
+
const result = await reporter.executeMainAction('test-afterTemplatingEnginesExecuted-listeners', { req, res: await res.serialize() }, req)
|
|
29
|
+
extend(true, req, result.req)
|
|
30
|
+
await res.parse(result.res)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const evalInWorker = (code, req, res) => {
|
|
34
|
+
const script = new vm.Script(`
|
|
35
|
+
;(function () {
|
|
36
|
+
return ${code}
|
|
37
|
+
})()
|
|
38
|
+
`)
|
|
39
|
+
|
|
40
|
+
return script.runInThisContext({
|
|
41
|
+
displayErrors: true
|
|
42
|
+
})(req, res, {
|
|
43
|
+
mainModuleFilename: require.main.filename,
|
|
44
|
+
require: (m) => {
|
|
45
|
+
if (Module.builtinModules.includes(m)) {
|
|
46
|
+
return require(m)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
return require(path.join(process.cwd(), 'node_modules', m))
|
|
51
|
+
} catch (e) {
|
|
52
|
+
// hack, make it working in monorepo as well as normal extension
|
|
53
|
+
return require(path.join(process.cwd(), '../../node_modules', m))
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
reporter
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
reporter.afterRenderListeners.add('eval-listeners', async (req, res) => {
|
|
61
|
+
const code = await reporter.executeMainAction('test-afterRenderEval', {}, req)
|
|
62
|
+
if (code) {
|
|
63
|
+
return evalInWorker(code, req, res)
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
reporter.beforeRenderListeners.insert(0, 'eval-listeners', async (req, res) => {
|
|
68
|
+
const code = await reporter.executeMainAction('test-beforeRenderEval', {}, req)
|
|
69
|
+
if (code) {
|
|
70
|
+
return evalInWorker(code, req, res)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
reporter.afterTemplatingEnginesExecutedListeners.add('eval-listeners', async (req, res) => {
|
|
75
|
+
const code = await reporter.executeMainAction('test-afterTemplatingEnginesExecutedEval', {}, req)
|
|
76
|
+
if (code) {
|
|
77
|
+
return evalInWorker(code, req, res)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
}
|