@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,207 +1,232 @@
1
- /*!
2
- * Copyright(c) 2018 Jan Blaha
3
- *
4
- * Child process script rendering html from template content, helpers and input data.
5
- * This script runs in the extra process because of multitenancy and security requirements, errors like infinite loop
6
- * should not affect other reports being rendered at the same time
7
- */
8
- const LRU = require('lru-cache')
9
- const { nanoid } = require('nanoid')
10
-
11
- module.exports = (reporter) => {
12
- const cache = LRU(reporter.options.sandbox.cache || { max: 100 })
13
- reporter.templatingEngines = { cache }
14
- const executionFnParsedParamsMap = new Map()
15
-
16
- reporter.extendProxy((proxy, req, {
17
- runInSandbox,
18
- context,
19
- getTopLevelFunctions
20
- }) => {
21
- proxy.templatingEngines = {
22
- evaluate: async ({ engine, content, helpers, data }, { entity, entitySet }) => {
23
- const engineImpl = reporter.extensionsManager.engines.find((e) => e.name === engine)
24
-
25
- if (!engine) {
26
- throw reporter.createError(`Engine '${engine}' not found. If this is a custom engine make sure it's properly installed from npm`, {
27
- statusCode: 400
28
- })
29
- }
30
-
31
- const res = await executeEngine({
32
- engine: engineImpl,
33
- content,
34
- helpers,
35
- systemHelpers: req.context.systemHelpers,
36
- data
37
- }, { handleErrors: false, entity, entitySet }, req)
38
- return res.content
39
- }
40
- }
41
- })
42
-
43
- return async (engine, req) => {
44
- executionFnParsedParamsMap.set(req.context.id, new Map())
45
- req.data.__appDirectory = reporter.options.appDirectory
46
- req.data.__rootDirectory = reporter.options.rootDirectory
47
- req.data.__parentModuleDirectory = reporter.options.parentModuleDirectory
48
-
49
- try {
50
- return await executeEngine({
51
- engine,
52
- content: req.template.content,
53
- helpers: req.template.helpers,
54
- systemHelpers: req.context.systemHelpers,
55
- data: req.data
56
- }, {
57
- handleErrors: true,
58
- entity: req.template,
59
- entitySet: 'templates'
60
- }, req)
61
- } finally {
62
- executionFnParsedParamsMap.delete(req.context.id)
63
- }
64
- }
65
-
66
- async function executeEngine ({ engine, content, helpers, systemHelpers, data }, { handleErrors, entity, entitySet }, req) {
67
- let entityPath
68
- if (entity._id) {
69
- entityPath = await reporter.folders.resolveEntityPath(entity, entitySet, req)
70
- entityPath = entityPath.substring(0, entityPath.lastIndexOf('/'))
71
- }
72
-
73
- const joinedHelpers = systemHelpers + '\n' + helpers
74
- const executionFnParsedParamsKey = `entity:${entity.shortid || 'anonymous'}:helpers:${joinedHelpers}`
75
-
76
- const executionFn = async ({ require, console, topLevelFunctions }) => {
77
- // cached components dont call runInSandbox but share the proxy, we get to it here
78
- if (entitySet !== 'templates') {
79
- const jsreport = require('jsreport-proxy')
80
- jsreport.currentPath = entityPath
81
- }
82
-
83
- const asyncResultMap = new Map()
84
- executionFnParsedParamsMap.get(req.context.id).get(executionFnParsedParamsKey).resolve({ require, console, topLevelFunctions })
85
- const key = `template:${content}:${engine.name}`
86
-
87
- if (!cache.has(key)) {
88
- try {
89
- cache.set(key, engine.compile(content, { require }))
90
- } catch (e) {
91
- e.property = 'content'
92
- throw e
93
- }
94
- }
95
-
96
- const compiledTemplate = cache.get(key)
97
-
98
- const wrappedTopLevelFunctions = {}
99
-
100
- for (const h of Object.keys(topLevelFunctions)) {
101
- wrappedTopLevelFunctions[h] = wrapHelperForAsyncSupport(topLevelFunctions[h], asyncResultMap)
102
- }
103
-
104
- let contentResult = await engine.execute(compiledTemplate, wrappedTopLevelFunctions, data, { require })
105
- const resolvedResultsMap = new Map()
106
- while (asyncResultMap.size > 0) {
107
- await Promise.all([...asyncResultMap.keys()].map(async (k) => {
108
- resolvedResultsMap.set(k, `${await asyncResultMap.get(k)}`)
109
- asyncResultMap.delete(k)
110
- }))
111
- }
112
-
113
- while (contentResult.includes('{#asyncHelperResult')) {
114
- contentResult = contentResult.replace(/{#asyncHelperResult ([^{}]+)}/g, (str, p1) => {
115
- const asyncResultId = p1
116
- return `${resolvedResultsMap.get(asyncResultId)}`
117
- })
118
- }
119
-
120
- return {
121
- content: contentResult
122
- }
123
- }
124
-
125
- // executionFnParsedParamsMap is there to cache parsed components helpers to speed up longer loops
126
- // we store there for the particular request and component a promise and only the first component gets compiled
127
- if (executionFnParsedParamsMap.get(req.context.id).has(executionFnParsedParamsKey)) {
128
- const { require, console, topLevelFunctions } = await (executionFnParsedParamsMap.get(req.context.id).get(executionFnParsedParamsKey).promise)
129
-
130
- return executionFn({ require, console, topLevelFunctions })
131
- } else {
132
- const awaiter = {}
133
- awaiter.promise = new Promise((resolve) => {
134
- awaiter.resolve = resolve
135
- })
136
- executionFnParsedParamsMap.get(req.context.id).set(executionFnParsedParamsKey, awaiter)
137
- }
138
-
139
- if (reporter.options.sandbox.cache && reporter.options.sandbox.cache.enabled === false) {
140
- cache.reset()
141
- }
142
-
143
- try {
144
- return await reporter.runInSandbox({
145
- context: {
146
- ...(engine.createContext ? engine.createContext() : {})
147
- },
148
- userCode: joinedHelpers,
149
- executionFn,
150
- currentPath: entityPath,
151
- errorLineNumberOffset: systemHelpers.split('\n').length,
152
- onRequire: (moduleName, { context }) => {
153
- if (engine.onRequire) {
154
- return engine.onRequire(moduleName, { context })
155
- }
156
- }
157
- }, req)
158
- } catch (e) {
159
- if (!handleErrors) {
160
- throw e
161
- }
162
-
163
- const nestedErrorWithEntity = e.entity != null
164
-
165
- const templatePath = req.template._id ? await reporter.folders.resolveEntityPath(req.template, 'templates', req) : 'anonymous'
166
- if (templatePath !== 'anonymous' && !nestedErrorWithEntity) {
167
- const templateFound = await reporter.folders.resolveEntityFromPath(templatePath, 'templates', req)
168
- if (templateFound != null) {
169
- e.entity = {
170
- shortid: templateFound.entity.shortid,
171
- name: templateFound.entity.name,
172
- content
173
- }
174
- }
175
- }
176
-
177
- e.message = `Error when evaluating engine ${engine.name} for template ${templatePath}\n` + e.message
178
-
179
- if (!nestedErrorWithEntity && e.property !== 'content') {
180
- e.property = 'helpers'
181
- }
182
-
183
- if (nestedErrorWithEntity) {
184
- // errors from nested assets evals needs an unwrap for some reason
185
- e.entity = { ...e.entity }
186
- }
187
-
188
- throw e
189
- }
190
- }
191
-
192
- function wrapHelperForAsyncSupport (fn, asyncResultMap) {
193
- return function (...args) {
194
- // important to call the helper with the current this to preserve the same behaviour
195
- const fnResult = fn.call(this, ...args)
196
-
197
- if (fnResult == null || typeof fnResult.then !== 'function') {
198
- return fnResult
199
- }
200
-
201
- const asyncResultId = nanoid(7)
202
- asyncResultMap.set(asyncResultId, fnResult)
203
-
204
- return `{#asyncHelperResult ${asyncResultId}}`
205
- }
206
- }
207
- }
1
+ /*!
2
+ * Copyright(c) 2018 Jan Blaha
3
+ *
4
+ * Child process script rendering html from template content, helpers and input data.
5
+ * This script runs in the extra process because of multitenancy and security requirements, errors like infinite loop
6
+ * should not affect other reports being rendered at the same time
7
+ */
8
+ const LRU = require('lru-cache')
9
+ const { nanoid } = require('nanoid')
10
+
11
+ module.exports = (reporter) => {
12
+ const cache = LRU(reporter.options.sandbox.cache || { max: 100 })
13
+
14
+ reporter.templatingEngines = { cache }
15
+
16
+ const executionFnParsedParamsMap = new Map()
17
+
18
+ const templatingEnginesEvaluate = async (mainCall, { engine, content, helpers, data }, { entity, entitySet }, req) => {
19
+ const engineImpl = reporter.extensionsManager.engines.find((e) => e.name === engine)
20
+
21
+ if (!engine) {
22
+ throw reporter.createError(`Engine '${engine}' not found. If this is a custom engine make sure it's properly installed from npm`, {
23
+ statusCode: 400
24
+ })
25
+ }
26
+
27
+ if (mainCall) {
28
+ executionFnParsedParamsMap.set(req.context.id, new Map())
29
+ }
30
+
31
+ try {
32
+ const res = await executeEngine({
33
+ engine: engineImpl,
34
+ content,
35
+ helpers,
36
+ data
37
+ }, { handleErrors: false, entity, entitySet }, req)
38
+
39
+ return res.content
40
+ } finally {
41
+ if (mainCall) {
42
+ executionFnParsedParamsMap.delete(req.context.id)
43
+ }
44
+ }
45
+ }
46
+
47
+ reporter.templatingEngines.evaluate = (executionInfo, entityInfo, req) => templatingEnginesEvaluate(true, executionInfo, entityInfo, req)
48
+
49
+ reporter.extendProxy((proxy, req, {
50
+ runInSandbox,
51
+ context,
52
+ getTopLevelFunctions
53
+ }) => {
54
+ proxy.templatingEngines = {
55
+ evaluate: async (executionInfo, entityInfo) => {
56
+ return templatingEnginesEvaluate(false, executionInfo, entityInfo, req)
57
+ }
58
+ }
59
+ })
60
+
61
+ return async (engine, req) => {
62
+ executionFnParsedParamsMap.set(req.context.id, new Map())
63
+ req.data.__appDirectory = reporter.options.appDirectory
64
+ req.data.__rootDirectory = reporter.options.rootDirectory
65
+ req.data.__parentModuleDirectory = reporter.options.parentModuleDirectory
66
+
67
+ try {
68
+ return await executeEngine({
69
+ engine,
70
+ content: req.template.content,
71
+ helpers: req.template.helpers,
72
+ data: req.data
73
+ }, {
74
+ handleErrors: true,
75
+ entity: req.template,
76
+ entitySet: 'templates'
77
+ }, req)
78
+ } finally {
79
+ executionFnParsedParamsMap.delete(req.context.id)
80
+ }
81
+ }
82
+
83
+ async function executeEngine ({ engine, content, helpers, data }, { handleErrors, entity, entitySet }, req) {
84
+ let entityPath
85
+
86
+ if (entity._id) {
87
+ entityPath = await reporter.folders.resolveEntityPath(entity, entitySet, req)
88
+ }
89
+
90
+ const registerResults = await reporter.registerHelpersListeners.fire(req)
91
+ const systemHelpers = []
92
+
93
+ for (const result of registerResults) {
94
+ if (result == null) {
95
+ continue
96
+ }
97
+
98
+ if (typeof result === 'string') {
99
+ systemHelpers.push(result)
100
+ }
101
+ }
102
+
103
+ const systemHelpersStr = systemHelpers.join('\n')
104
+ const joinedHelpers = systemHelpersStr + '\n' + (helpers || '')
105
+ const executionFnParsedParamsKey = `entity:${entity.shortid || 'anonymous'}:helpers:${joinedHelpers}`
106
+
107
+ const executionFn = async ({ require, console, topLevelFunctions }) => {
108
+ const asyncResultMap = new Map()
109
+ executionFnParsedParamsMap.get(req.context.id).get(executionFnParsedParamsKey).resolve({ require, console, topLevelFunctions })
110
+ const key = `template:${content}:${engine.name}`
111
+
112
+ if (!cache.has(key)) {
113
+ try {
114
+ cache.set(key, engine.compile(content, { require }))
115
+ } catch (e) {
116
+ e.property = 'content'
117
+ throw e
118
+ }
119
+ }
120
+
121
+ const compiledTemplate = cache.get(key)
122
+
123
+ const wrappedTopLevelFunctions = {}
124
+
125
+ for (const h of Object.keys(topLevelFunctions)) {
126
+ wrappedTopLevelFunctions[h] = wrapHelperForAsyncSupport(topLevelFunctions[h], asyncResultMap)
127
+ }
128
+
129
+ let contentResult = await engine.execute(compiledTemplate, wrappedTopLevelFunctions, data, { require })
130
+ const resolvedResultsMap = new Map()
131
+ while (asyncResultMap.size > 0) {
132
+ await Promise.all([...asyncResultMap.keys()].map(async (k) => {
133
+ resolvedResultsMap.set(k, `${await asyncResultMap.get(k)}`)
134
+ asyncResultMap.delete(k)
135
+ }))
136
+ }
137
+
138
+ while (contentResult.includes('{#asyncHelperResult')) {
139
+ contentResult = contentResult.replace(/{#asyncHelperResult ([^{}]+)}/g, (str, p1) => {
140
+ const asyncResultId = p1
141
+ return `${resolvedResultsMap.get(asyncResultId)}`
142
+ })
143
+ }
144
+
145
+ return {
146
+ content: contentResult
147
+ }
148
+ }
149
+
150
+ // executionFnParsedParamsMap is there to cache parsed components helpers to speed up longer loops
151
+ // we store there for the particular request and component a promise and only the first component gets compiled
152
+ if (executionFnParsedParamsMap.get(req.context.id).has(executionFnParsedParamsKey)) {
153
+ const { require, console, topLevelFunctions } = await (executionFnParsedParamsMap.get(req.context.id).get(executionFnParsedParamsKey).promise)
154
+
155
+ return executionFn({ require, console, topLevelFunctions })
156
+ } else {
157
+ const awaiter = {}
158
+ awaiter.promise = new Promise((resolve) => {
159
+ awaiter.resolve = resolve
160
+ })
161
+ executionFnParsedParamsMap.get(req.context.id).set(executionFnParsedParamsKey, awaiter)
162
+ }
163
+
164
+ if (reporter.options.sandbox.cache && reporter.options.sandbox.cache.enabled === false) {
165
+ cache.reset()
166
+ }
167
+
168
+ try {
169
+ return await reporter.runInSandbox({
170
+ context: {
171
+ ...(engine.createContext ? engine.createContext() : {})
172
+ },
173
+ userCode: joinedHelpers,
174
+ executionFn,
175
+ currentPath: entityPath,
176
+ errorLineNumberOffset: systemHelpersStr.split('\n').length,
177
+ onRequire: (moduleName, { context }) => {
178
+ if (engine.onRequire) {
179
+ return engine.onRequire(moduleName, { context })
180
+ }
181
+ }
182
+ }, req)
183
+ } catch (e) {
184
+ if (!handleErrors) {
185
+ throw e
186
+ }
187
+
188
+ const nestedErrorWithEntity = e.entity != null
189
+
190
+ const templatePath = req.template._id ? await reporter.folders.resolveEntityPath(req.template, 'templates', req) : 'anonymous'
191
+ if (templatePath !== 'anonymous' && !nestedErrorWithEntity) {
192
+ const templateFound = await reporter.folders.resolveEntityFromPath(templatePath, 'templates', req)
193
+ if (templateFound != null) {
194
+ e.entity = {
195
+ shortid: templateFound.entity.shortid,
196
+ name: templateFound.entity.name,
197
+ content
198
+ }
199
+ }
200
+ }
201
+
202
+ e.message = `Error when evaluating engine ${engine.name} for template ${templatePath}\n` + e.message
203
+
204
+ if (!nestedErrorWithEntity && e.property !== 'content') {
205
+ e.property = 'helpers'
206
+ }
207
+
208
+ if (nestedErrorWithEntity) {
209
+ // errors from nested assets evals needs an unwrap for some reason
210
+ e.entity = { ...e.entity }
211
+ }
212
+
213
+ throw e
214
+ }
215
+ }
216
+
217
+ function wrapHelperForAsyncSupport (fn, asyncResultMap) {
218
+ return function (...args) {
219
+ // important to call the helper with the current this to preserve the same behavior
220
+ const fnResult = fn.call(this, ...args)
221
+
222
+ if (fnResult == null || typeof fnResult.then !== 'function') {
223
+ return fnResult
224
+ }
225
+
226
+ const asyncResultId = nanoid(7)
227
+ asyncResultMap.set(asyncResultId, fnResult)
228
+
229
+ return `{#asyncHelperResult ${asyncResultId}}`
230
+ }
231
+ }
232
+ }
@@ -1,10 +1,10 @@
1
- /*!
2
- * Copyright(c) 2016 Jan Blaha
3
- *
4
- * Recipe running no document transformations. Just adds html response headers
5
- */
6
-
7
- module.exports = function (req, res) {
8
- res.meta.contentType = 'text/html'
9
- res.meta.fileExtension = 'html'
10
- }
1
+ /*!
2
+ * Copyright(c) 2016 Jan Blaha
3
+ *
4
+ * Recipe running no document transformations. Just adds html response headers
5
+ */
6
+
7
+ module.exports = function (req, res) {
8
+ res.meta.contentType = 'text/html'
9
+ res.meta.fileExtension = 'html'
10
+ }
@@ -1,43 +1,45 @@
1
- const fs = require('fs').promises
2
- const path = require('path')
3
-
4
- module.exports = (reporter) => {
5
- let helpersScript
6
- reporter.beforeRenderListeners.add('core-helpers', async (req) => {
7
- if (!helpersScript) {
8
- helpersScript = await fs.readFile(path.join(__dirname, '../../static/helpers.js'), 'utf8')
9
- }
10
- req.context.systemHelpers += helpersScript + '\n'
11
- })
12
-
13
- reporter.extendProxy((proxy, req, { safeRequire }) => {
14
- proxy.module = async (module) => {
15
- if (!reporter.options.allowLocalFilesAccess && reporter.options.sandbox.allowedModules !== '*') {
16
- if (reporter.options.sandbox.allowedModules.indexOf(module) === -1) {
17
- throw reporter.createError(`require of module ${module} was rejected. Either set allowLocalFilesAccess=true or sandbox.allowLocalModules='*' or sandbox.allowLocalModules=['${module}'] `, { status: 400 })
18
- }
19
- }
20
-
21
- const resolve = require('enhanced-resolve')
22
-
23
- const moduleResolve = resolve.create({
24
- extensions: ['.js', '.json']
25
- })
26
-
27
- const modulePath = await new Promise((resolve, reject) => {
28
- moduleResolve(reporter.options.rootDirectory, module, (err, result) => {
29
- if (err) {
30
- err.message = `module read error. ${err.message}`
31
- return reject(err)
32
- }
33
-
34
- resolve(result)
35
- })
36
- })
37
-
38
- const buf = await fs.readFile(modulePath)
39
-
40
- return buf.toString()
41
- }
42
- })
43
- }
1
+ const fs = require('fs').promises
2
+ const path = require('path')
3
+
4
+ module.exports = (reporter) => {
5
+ let helpersScript
6
+
7
+ reporter.registerHelpersListeners.add('core-helpers', (req) => {
8
+ return helpersScript
9
+ })
10
+
11
+ reporter.initializeListeners.add('core-helpers', async () => {
12
+ helpersScript = await fs.readFile(path.join(__dirname, '../../static/helpers.js'), 'utf8')
13
+ })
14
+
15
+ reporter.extendProxy((proxy, req, { safeRequire }) => {
16
+ proxy.module = async (module) => {
17
+ if (!reporter.options.allowLocalFilesAccess && reporter.options.sandbox.allowedModules !== '*') {
18
+ if (reporter.options.sandbox.allowedModules.indexOf(module) === -1) {
19
+ throw reporter.createError(`require of module ${module} was rejected. Either set allowLocalFilesAccess=true or sandbox.allowLocalModules='*' or sandbox.allowLocalModules=['${module}'] `, { status: 400 })
20
+ }
21
+ }
22
+
23
+ const resolve = require('enhanced-resolve')
24
+
25
+ const moduleResolve = resolve.create({
26
+ extensions: ['.js', '.json']
27
+ })
28
+
29
+ const modulePath = await new Promise((resolve, reject) => {
30
+ moduleResolve(reporter.options.rootDirectory, module, (err, result) => {
31
+ if (err) {
32
+ err.message = `module read error. ${err.message}`
33
+ return reject(err)
34
+ }
35
+
36
+ resolve(result)
37
+ })
38
+ })
39
+
40
+ const buf = await fs.readFile(modulePath)
41
+
42
+ return buf.toString()
43
+ }
44
+ })
45
+ }
@@ -1,12 +1,12 @@
1
- /*!
2
- * Copyright(c) 2018 Jan Blaha
3
- *
4
- * Engine running not templating engine compilation or rendering. Just return input html
5
- */
6
-
7
- module.exports = () => {
8
- return {
9
- compile: (html) => html,
10
- execute: (html) => html
11
- }
12
- }
1
+ /*!
2
+ * Copyright(c) 2018 Jan Blaha
3
+ *
4
+ * Engine running not templating engine compilation or rendering. Just return input html
5
+ */
6
+
7
+ module.exports = () => {
8
+ return {
9
+ compile: (html) => html,
10
+ execute: (html) => html
11
+ }
12
+ }