@jsreport/jsreport-core 4.6.1 → 4.7.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.
@@ -25,15 +25,37 @@ module.exports = function (message, options = {}) {
25
25
  error.weak = originalNormalized.weak
26
26
  }
27
27
 
28
- if (error.message == null || error.message === '') {
29
- error.message = `${originalNormalized.message}`
30
- } else {
31
- error.message += `\n(because) ${lowerCaseFirstLetter(originalNormalized.message)}`
28
+ const initialMsg = error.message == null || error.message === '' ? '' : error.message
29
+ const [messages, stacks] = getErrorMessagesAndStacks(originalNormalized)
30
+
31
+ if (initialMsg !== '') {
32
+ messages.unshift(initialMsg)
32
33
  }
33
34
 
35
+ error.message = messages.reduce((acu, msg) => {
36
+ if (acu === '') {
37
+ acu += msg
38
+ } else {
39
+ acu += `\n(because) ${lowerCaseFirstLetter(msg)}`
40
+ }
41
+
42
+ return acu
43
+ }, '')
44
+
34
45
  // stack is printed in reverse order (from cause to more high level error)
35
- if (error.stack != null && originalNormalized.stack != null) {
36
- error.stack = `${originalNormalized.stack}\nwrapped by:\n${error.stack}`
46
+ if (error.stack != null && originalNormalized.stack != null && stacks.length > 0) {
47
+ stacks.unshift(error.stack)
48
+ stacks.reverse()
49
+
50
+ error.stack = stacks.reduce((acu, stack) => {
51
+ if (acu === '') {
52
+ acu += stack
53
+ } else {
54
+ acu += `\nwrapped by:\n${stack}`
55
+ }
56
+
57
+ return acu
58
+ }, '')
37
59
  }
38
60
  }
39
61
  }
@@ -49,6 +71,23 @@ module.exports = function (message, options = {}) {
49
71
  return error
50
72
  }
51
73
 
74
+ function getErrorMessagesAndStacks (err) {
75
+ let currentErr = err
76
+ const messages = []
77
+ const stacks = []
78
+
79
+ while (currentErr != null) {
80
+ if (currentErr.message) {
81
+ messages.push(currentErr.message)
82
+ stacks.push(currentErr.stack ?? '(no stack available)')
83
+ }
84
+
85
+ currentErr = currentErr.cause
86
+ }
87
+
88
+ return [messages, stacks]
89
+ }
90
+
52
91
  function lowerCaseFirstLetter (str) {
53
92
  if (str === '' || typeof str !== 'string') {
54
93
  return str
@@ -41,4 +41,42 @@ module.exports = (reporter) => (proxy, req) => {
41
41
  return reporter.folders.resolveEntityPath(entity, es, req)
42
42
  }
43
43
  }
44
+
45
+ // expose tempfile functions
46
+ const createTempFileFns = [
47
+ 'getTempFilePath', 'openTempFile', 'writeTempFileSync', 'writeTempFile',
48
+ 'writeTempFileStream', 'copyFileToTempFile'
49
+ ]
50
+
51
+ const restOfTempFileFns = [
52
+ 'readTempFileSync', 'readTempFile', 'readTempFileStream'
53
+ ]
54
+
55
+ const allFns = [
56
+ ...createTempFileFns,
57
+ ...restOfTempFileFns
58
+ ]
59
+
60
+ for (const fnName of allFns) {
61
+ const shouldLimitCreation = createTempFileFns.includes(fnName)
62
+
63
+ proxy[fnName] = (...args) => {
64
+ if (shouldLimitCreation) {
65
+ // limiting the number of temp files to avoid breaking server, otherwise I see no
66
+ // reason why having more than 1000 calls per req should be valid usecase
67
+ const counter = reporter.runningRequests.keyValueStore.get('tmp-file-counter', req) || 0
68
+
69
+ if (counter > 1000) {
70
+ throw reporter.createError('Reached maximum limit of tmp file calls in sandbox', {
71
+ weak: true,
72
+ statusCode: 400
73
+ })
74
+ }
75
+
76
+ reporter.runningRequests.keyValueStore.set('tmp-file-counter', counter + 1, req)
77
+ }
78
+
79
+ return reporter[fnName](...args)
80
+ }
81
+ }
44
82
  }
@@ -57,22 +57,13 @@ module.exports = (reporter) => {
57
57
  }) => {
58
58
  if (proxy.templatingEngines) {
59
59
  proxy.templatingEngines.createStream = async (opts = {}) => {
60
- // limiting the number of temp files to avoid breaking server, otherwise I see no reason why having more than 1000 calls per req should be valid usecase
61
- const counter = reporter.runningRequests.keyValueStore.get('engine-stream-counter', req) || 0
62
- if (counter > 1000) {
63
- throw reporter.createError('Reached maximum limit of templatingEngine.createStream calls', {
64
- weak: true,
65
- statusCode: 400
66
- })
67
- }
68
- reporter.runningRequests.keyValueStore.set('engine-stream-counter', counter + 1, req)
69
-
70
60
  req.context.engineStreamEnabled = true
71
61
 
72
62
  const bufferSize = bytes(opts.bufferSize || '10mb')
73
63
  let buf = ''
74
64
 
75
- const { fileHandle, filename } = await reporter.openTempFile((uuid) => `${uuid}.stream`, 'a')
65
+ // using proxy.openTempFile to respect limits of temp files in sandbox
66
+ const { fileHandle, filename } = await proxy.openTempFile((uuid) => `${uuid}.stream`, 'a')
76
67
  proxy.templatingEngines.addFinishListener(() => fileHandle.close().catch((e) => reporter.logger.error('Failed to close temp file handle', e, req)))
77
68
 
78
69
  return {
@@ -14,10 +14,11 @@ const engineStream = require('./render/engineStream.js')
14
14
 
15
15
  class WorkerReporter extends Reporter {
16
16
  constructor (workerData, executeMain) {
17
- const { options, documentStore, extensionsDefs } = workerData
17
+ const { options, documentStore, extensionsDefs, workerId } = workerData
18
18
 
19
19
  super(options)
20
20
 
21
+ this.workerId = workerId
21
22
  this._executeMain = executeMain
22
23
  this._initialized = false
23
24
  this._lockedDown = false
@@ -1,8 +1,8 @@
1
1
  const WorkerReporter = require('./reporter')
2
2
  const omit = require('lodash.omit')
3
3
 
4
- module.exports = (userInitData, { executeMain, convertUint8ArrayToBuffer }) => {
5
- const reporter = new WorkerReporter(userInitData, async (actionName, data, req) => {
4
+ module.exports = (userInitData, { executeMain, convertUint8ArrayToBuffer, workerId }) => {
5
+ const reporter = new WorkerReporter({ ...userInitData, workerId }, async (actionName, data, req) => {
6
6
  const actionRes = await executeMain({
7
7
  actionName,
8
8
  data
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsreport/jsreport-core",
3
- "version": "4.6.1",
3
+ "version": "4.7.0",
4
4
  "description": "javascript based business reporting",
5
5
  "keywords": [
6
6
  "report",
@@ -40,11 +40,11 @@
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.2",
43
+ "@jsreport/advanced-workers": "2.1.0",
44
44
  "@jsreport/mingo": "2.4.1",
45
45
  "@jsreport/reap": "0.1.0",
46
- "@jsreport/serializator": "1.0.0",
47
- "@jsreport/ses": "1.1.0",
46
+ "@jsreport/serializator": "1.0.1",
47
+ "@jsreport/ses": "1.2.0",
48
48
  "ajv": "6.12.6",
49
49
  "app-root-path": "3.0.0",
50
50
  "bytes": "3.1.2",