@jsreport/jsreport-core 4.2.2 → 4.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/README.md
CHANGED
|
@@ -256,7 +256,7 @@ jsreport currently support these main listeners
|
|
|
256
256
|
- `closeListeners()` called when jsreport is about to be closed, you will usually put here some code that clean up some resource
|
|
257
257
|
|
|
258
258
|
## Studio
|
|
259
|
-
jsreport includes also visual html studio and rest API. This is provided through two extensions, [@jsreport/jsreport-express](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-express) extension to have a web server available and [@jsreport/jsreport-studio](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-studio) for the web UI, both extensions should be installed in order to have the studio ready. See the documentation of each extension for the details
|
|
259
|
+
jsreport includes also visual html studio and rest API. This is provided through two extensions, [@jsreport/jsreport-express](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-express) extension to have a web server available and [@jsreport/jsreport-studio](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-studio) for the web UI, both extensions should be installed in order to have the studio ready. See the documentation of each extension for the details
|
|
260
260
|
|
|
261
261
|
## Template store
|
|
262
262
|
`jsreport-core` includes API for persisting and accessing report templates. This API is then used by extensions mainly in combination with jsreport [studio](#studio). `jsreport-core` implements just in-memory persistence, but you can add other persistence methods through extensions, see the [template stores](https://jsreport.net/learn/template-stores) docummentation
|
|
@@ -282,11 +282,17 @@ jsreport.documentStore.collection('templates')
|
|
|
282
282
|
|
|
283
283
|
## Changelog
|
|
284
284
|
|
|
285
|
+
### 4.3.0
|
|
286
|
+
|
|
287
|
+
- expose safe properties of `req.context.user` in sandbox
|
|
288
|
+
- fix component execution when wrapped with async helper
|
|
289
|
+
- fix jsdom require in sandbox
|
|
290
|
+
|
|
285
291
|
### 4.2.2
|
|
286
292
|
|
|
287
293
|
- fix recursive component rendering
|
|
288
294
|
|
|
289
|
-
###
|
|
295
|
+
### 4.2.1
|
|
290
296
|
|
|
291
297
|
- response.output.update now accepts Web ReadableStream (which is what new version of puppeteer returns)
|
|
292
298
|
|
|
@@ -259,16 +259,29 @@ module.exports = (reporter) => {
|
|
|
259
259
|
const resolvedResultsMap = new Map()
|
|
260
260
|
|
|
261
261
|
// we need to use the cloned map, because there can be a waitForAsyncHelper pending that needs the asyncResultMap values
|
|
262
|
-
|
|
262
|
+
let clonedMap = new Map(asyncResultMap)
|
|
263
|
+
|
|
263
264
|
while (clonedMap.size > 0) {
|
|
264
|
-
|
|
265
|
+
const keysEvaluated = [...clonedMap.keys()]
|
|
266
|
+
|
|
267
|
+
await Promise.all(keysEvaluated.map(async (k) => {
|
|
265
268
|
const result = await clonedMap.get(k)
|
|
266
269
|
asyncCallChainSet.delete(k)
|
|
267
270
|
resolvedResultsMap.set(k, `${result}`)
|
|
268
271
|
clonedMap.delete(k)
|
|
269
272
|
}))
|
|
273
|
+
|
|
274
|
+
// we need to remove the keys processed from the original map at this point
|
|
275
|
+
// (after the await) because during the async work the asyncResultMap will be read
|
|
276
|
+
for (const k of keysEvaluated) {
|
|
277
|
+
asyncResultMap.delete(k)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// we want to process the new generated pending async results
|
|
281
|
+
if (asyncResultMap.size > 0) {
|
|
282
|
+
clonedMap = new Map(asyncResultMap)
|
|
283
|
+
}
|
|
270
284
|
}
|
|
271
|
-
asyncResultMap.clear()
|
|
272
285
|
|
|
273
286
|
while (contentResult.includes('{#asyncHelperResult')) {
|
|
274
287
|
contentResult = contentResult.replace(/{#asyncHelperResult ([^{}]+)}/g, (str, p1) => {
|
|
@@ -284,6 +297,7 @@ module.exports = (reporter) => {
|
|
|
284
297
|
return `${resolvedResultsMap.get(asyncResultId)}`
|
|
285
298
|
})
|
|
286
299
|
}
|
|
300
|
+
|
|
287
301
|
contentResult = contentResult.replace(/asyncUnresolvedHelperResult/g, 'asyncHelperResult')
|
|
288
302
|
|
|
289
303
|
await executionFinishListenersMap.get(executionId).fire()
|
|
@@ -253,6 +253,23 @@ function applyPropertiesConfig (context, hierarchyPropertiesConfig, {
|
|
|
253
253
|
shouldStoreOriginal = false
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
// allow configuring parent as hidden, but child props as readonly so we expose
|
|
257
|
+
// just part of the parent
|
|
258
|
+
// const ignoreParentHidden = false
|
|
259
|
+
const ignoreParentHidden = (
|
|
260
|
+
isHidden &&
|
|
261
|
+
isGrouped &&
|
|
262
|
+
(hierarchyPropertiesConfig.inner != null || hierarchyPropertiesConfig.standalone != null)
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if (parentOpts?.originalSandboxHidden !== true && ignoreParentHidden) {
|
|
266
|
+
// we store the original value for the top parent with hidden value
|
|
267
|
+
shouldStoreOriginal = true
|
|
268
|
+
} else if (parentOpts && parentOpts.originalSandboxHidden === true) {
|
|
269
|
+
// we don't store original value when parent was configured as hidden
|
|
270
|
+
shouldStoreOriginal = false
|
|
271
|
+
}
|
|
272
|
+
|
|
256
273
|
// saving original value
|
|
257
274
|
if (shouldStoreOriginal) {
|
|
258
275
|
let exists = true
|
|
@@ -284,6 +301,19 @@ function applyPropertiesConfig (context, hierarchyPropertiesConfig, {
|
|
|
284
301
|
Object.keys(c.standalone).forEach((standaloneKey) => {
|
|
285
302
|
const standaloneConfig = c.standalone[standaloneKey]
|
|
286
303
|
|
|
304
|
+
const newParentOpts = {
|
|
305
|
+
sandboxHidden: ignoreParentHidden ? false : isHidden,
|
|
306
|
+
sandboxReadOnly: isReadOnly
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// set and inherit originalSandboxHidden if needed
|
|
310
|
+
if (
|
|
311
|
+
parentOpts?.originalSandboxHidden === true ||
|
|
312
|
+
(ignoreParentHidden && isHidden)
|
|
313
|
+
) {
|
|
314
|
+
newParentOpts.originalSandboxHidden = true
|
|
315
|
+
}
|
|
316
|
+
|
|
287
317
|
applyPropertiesConfig(context, standaloneConfig, {
|
|
288
318
|
original,
|
|
289
319
|
customProxies,
|
|
@@ -291,7 +321,7 @@ function applyPropertiesConfig (context, hierarchyPropertiesConfig, {
|
|
|
291
321
|
isRoot: false,
|
|
292
322
|
isGrouped: false,
|
|
293
323
|
onlyReadOnlyTopLevel,
|
|
294
|
-
parentOpts:
|
|
324
|
+
parentOpts: newParentOpts
|
|
295
325
|
}, readOnlyConfigured)
|
|
296
326
|
})
|
|
297
327
|
}
|
|
@@ -300,19 +330,65 @@ function applyPropertiesConfig (context, hierarchyPropertiesConfig, {
|
|
|
300
330
|
Object.keys(c.inner).forEach((innerKey) => {
|
|
301
331
|
const innerConfig = c.inner[innerKey]
|
|
302
332
|
|
|
333
|
+
const newParentOpts = {
|
|
334
|
+
sandboxHidden: ignoreParentHidden ? false : isHidden,
|
|
335
|
+
sandboxReadOnly: isReadOnly
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// set and inherit originalSandboxHidden if needed
|
|
339
|
+
if (
|
|
340
|
+
parentOpts?.originalSandboxHidden === true ||
|
|
341
|
+
(ignoreParentHidden && isHidden)
|
|
342
|
+
) {
|
|
343
|
+
newParentOpts.originalSandboxHidden = true
|
|
344
|
+
}
|
|
345
|
+
|
|
303
346
|
applyPropertiesConfig(context, innerConfig, {
|
|
304
347
|
original,
|
|
305
348
|
customProxies,
|
|
306
349
|
prop: innerKey,
|
|
307
350
|
isRoot: false,
|
|
308
351
|
isGrouped: true,
|
|
309
|
-
parentOpts:
|
|
352
|
+
parentOpts: newParentOpts
|
|
310
353
|
}, readOnlyConfigured)
|
|
311
354
|
})
|
|
312
355
|
}
|
|
313
356
|
|
|
314
357
|
if (isHidden) {
|
|
315
|
-
|
|
358
|
+
if (ignoreParentHidden) {
|
|
359
|
+
// when parent is hidden but there are configuration for child properties we just copy
|
|
360
|
+
// the properties listed there, we do this because we want to work with just the configured
|
|
361
|
+
// properties, the other properties should not be exposed
|
|
362
|
+
const currentValue = get(context, prop)
|
|
363
|
+
|
|
364
|
+
if (currentValue != null && typeof currentValue === 'object') {
|
|
365
|
+
let newValue
|
|
366
|
+
|
|
367
|
+
if (Array.isArray(currentValue)) {
|
|
368
|
+
newValue = []
|
|
369
|
+
} else {
|
|
370
|
+
newValue = {}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
for (const config of [hierarchyPropertiesConfig.standalone, hierarchyPropertiesConfig.inner]) {
|
|
374
|
+
if (config == null) {
|
|
375
|
+
continue
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
for (const childProp of Object.keys(config)) {
|
|
379
|
+
if (hasOwn(context, childProp)) {
|
|
380
|
+
const childValue = get(context, childProp)
|
|
381
|
+
const targetProp = childProp.replace(`${prop}.`, '')
|
|
382
|
+
set(newValue, targetProp, childValue)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
set(context, prop, newValue)
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
omitProp(context, prop)
|
|
391
|
+
}
|
|
316
392
|
} else if (isReadOnly) {
|
|
317
393
|
readOnlyProp(context, prop, readOnlyConfigured, customProxies, {
|
|
318
394
|
onlyTopLevel: false,
|
|
@@ -38,7 +38,7 @@ module.exports = function createSandboxRequire (safeExecution, isolateModules, m
|
|
|
38
38
|
|
|
39
39
|
if (isolateModules) {
|
|
40
40
|
const requireExtensions = Object.create(null)
|
|
41
|
-
isolatedRequire.setDefaultRequireExtensions(requireExtensions,
|
|
41
|
+
isolatedRequire.setDefaultRequireExtensions(requireExtensions, requireFromRootDirectory, compileScript)
|
|
42
42
|
modulesMeta.requireExtensions = requireExtensions
|
|
43
43
|
}
|
|
44
44
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsreport/jsreport-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "javascript based business reporting",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"report",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@node-rs/jsonwebtoken": "0.2.0",
|
|
81
|
+
"jsdom": "17.0.0",
|
|
81
82
|
"mocha": "10.1.0",
|
|
82
83
|
"should": "13.2.3",
|
|
83
84
|
"standard": "16.0.4",
|