@jsreport/jsreport-core 3.1.2-test.2 → 3.2.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.
Files changed (79) hide show
  1. package/LICENSE +166 -166
  2. package/README.md +298 -298
  3. package/index.js +29 -29
  4. package/lib/main/blobStorage/blobStorage.js +52 -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 +244 -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 +91 -91
  26. package/lib/main/optionsLoad.js +237 -237
  27. package/lib/main/optionsSchema.js +237 -237
  28. package/lib/main/reporter.js +574 -579
  29. package/lib/main/schemaValidator.js +252 -252
  30. package/lib/main/settings.js +154 -154
  31. package/lib/main/store/checkDuplicatedId.js +27 -27
  32. package/lib/main/store/collection.js +329 -329
  33. package/lib/main/store/documentStore.js +469 -469
  34. package/lib/main/store/mainActions.js +28 -28
  35. package/lib/main/store/memoryStoreProvider.js +99 -99
  36. package/lib/main/store/queue.js +48 -48
  37. package/lib/main/store/referenceUtils.js +251 -251
  38. package/lib/main/store/setupValidateId.js +43 -43
  39. package/lib/main/store/setupValidateShortid.js +71 -71
  40. package/lib/main/store/transaction.js +69 -69
  41. package/lib/main/store/typeUtils.js +180 -180
  42. package/lib/main/templates.js +34 -34
  43. package/lib/main/validateEntityName.js +62 -62
  44. package/lib/shared/createError.js +36 -36
  45. package/lib/shared/encryption.js +114 -114
  46. package/lib/shared/folders/index.js +11 -11
  47. package/lib/shared/folders/normalizeEntityPath.js +15 -15
  48. package/lib/shared/folders/resolveEntityFromPath.js +88 -88
  49. package/lib/shared/folders/resolveEntityPath.js +46 -46
  50. package/lib/shared/folders/resolveFolderFromPath.js +38 -38
  51. package/lib/shared/generateRequestId.js +4 -4
  52. package/lib/shared/listenerCollection.js +169 -169
  53. package/lib/shared/normalizeMetaFromLogs.js +30 -30
  54. package/lib/shared/reporter.js +128 -123
  55. package/lib/shared/request.js +64 -64
  56. package/lib/shared/tempFilesHandler.js +81 -81
  57. package/lib/shared/templates.js +82 -82
  58. package/lib/static/helpers.js +33 -33
  59. package/lib/worker/blobStorage.js +34 -34
  60. package/lib/worker/defaultProxyExtend.js +46 -46
  61. package/lib/worker/documentStore.js +49 -49
  62. package/lib/worker/extensionsManager.js +17 -17
  63. package/lib/worker/logger.js +48 -48
  64. package/lib/worker/render/diff.js +138 -138
  65. package/lib/worker/render/executeEngine.js +239 -207
  66. package/lib/worker/render/htmlRecipe.js +10 -10
  67. package/lib/worker/render/moduleHelper.js +45 -43
  68. package/lib/worker/render/noneEngine.js +12 -12
  69. package/lib/worker/render/profiler.js +158 -158
  70. package/lib/worker/render/render.js +202 -205
  71. package/lib/worker/render/resolveReferences.js +60 -60
  72. package/lib/worker/reporter.js +192 -191
  73. package/lib/worker/sandbox/runInSandbox.js +16 -9
  74. package/lib/worker/sandbox/safeSandbox.js +828 -828
  75. package/lib/worker/templates.js +80 -78
  76. package/lib/worker/workerHandler.js +54 -54
  77. package/package.json +92 -92
  78. package/test/blobStorage/common.js +21 -21
  79. package/test/store/common.js +1449 -1449
package/README.md CHANGED
@@ -1,298 +1,298 @@
1
- # @jsreport/jsreport-core
2
- [![NPM Version](http://img.shields.io/npm/v/@jsreport/jsreport-core.svg?style=flat-square)](https://npmjs.com/package/@jsreport/jsreport-core)
3
-
4
- **The minimalist [jsreport](http://jsreport.net) rendering core.**
5
- The full distribution can be found in the [jsreport](https://npmjs.com/package/jsreport) package.
6
-
7
- [jsreport](http://jsreport.net) is a platform providing dynamic documents assembling and printing. It supports various document types or printing techniques.
8
-
9
- `@jsreport/jsreport-core` contains the jsreport rendering core that is useless alone. It is up to you which jsreport extensions you combine
10
-
11
- ## Quick example
12
-
13
- To generate a document using jsreport, you always need a javascript templating engine. The **engine** is used to dynamically assemble the document based on the input values. For start lets pick [@jsreport/jsreport-handlebars](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-handlebars) engine and install it using npm.
14
-
15
- Next to the engine, you need something we call **recipe**. A recipe represents the technique used to print the document. It can be an HTML to pdf conversion, DOCX rendering, and others. In this example lets pick [@jsreport/jsreport-chrome-pdf](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-chrome-pdf). This recipe implements HTML to pdf conversion using [chrome](https://developers.google.com/web/updates/2017/04/headless-chrome). So in this example, we use handlebars to assemble HTML based on the input data and then print the output into the final pdf.
16
-
17
- > npm install @jsreport/jsreport-core<br/>
18
- > npm install @jsreport/jsreport-handlebars<br/>
19
- > npm install puppeteer @jsreport/jsreport-chrome-pdf
20
-
21
- ```js
22
- const fs = require('fs').promises
23
-
24
- const jsreport = require('@jsreport/jsreport-core')()
25
- jsreport.use(require('@jsreport/jsreport-chrome-pdf')())
26
- jsreport.use(require('@jsreport/jsreport-handlebars')())
27
-
28
- await jsreport.init()
29
- const result = await jsreport.render({
30
- template: {
31
- content: '<h1>Hello {{foo}}</h1>',
32
- engine: 'handlebars',
33
- recipe: 'chrome-pdf'
34
- },
35
- data: {
36
- foo: "world"
37
- }
38
- })
39
- await fs.writeFile('out.pdf', resp.content)
40
- ```
41
-
42
- ## Render
43
- `render` is the main method that invokes report generation. A single parameter is an object representing describing what to render. It has the following structure:
44
- ```js
45
- {
46
- //[required definition of the document]
47
- template: {
48
- //[required] templating engine used to assemble document
49
- engine: "handlebars",
50
- //[required] recipe used for printing previously assembled document
51
- recipe: "chrome-pdf",
52
- //[required] template for the engine
53
- content: "<h1>{{foo}}</h1>",
54
- //javascript helper functions used by templating engines
55
- helpers: "function foo() { ...} " +
56
- "function foo2() { ... }"
57
- //any other settings used by recipes
58
- ...
59
- },
60
- //dynamic data inputs used by templating engines
61
- data: { foo: "hello world"}
62
- ...
63
- }
64
- ```
65
-
66
- In case you have the template stored in the [jsreport templates store](https://github.com/jsreport/jsreport-core#template-store), you can reference the template using a name or path.
67
-
68
- ```js
69
- {
70
- template: {
71
- name: '/myfolder/mytemplate'
72
- },
73
- data: { foo: "hello world"}
74
- ...
75
- }
76
- ```
77
-
78
- The render returns a promise with the single response value
79
- ```js
80
- {
81
- //node.js buffer with the document
82
- content: ...
83
- //stream with the document
84
- stream: ...
85
- //object containing metadata about the report generation (reportName, logs, etc)..
86
- meta: { ... }
87
- }
88
- ```
89
-
90
- The convention is that jsreport repository extension starts with `jsreport-xxx`, but the extension real name and also the recipes or engines it registers excludes the `jsreport-` prefix. This means if you install extension `@jsreport/jsreport-handlebars` the engine's name you specify in the render should be `handlebars`.
91
-
92
-
93
- ### Require in the helpers
94
- jsreport by default runs helpers in the sandbox where is the `require` function blocked. To unblock particular modules or local scripts you need to configure `sandbox.allowedModules` option.
95
-
96
- ```js
97
- const jsreport = require('@jsreport/jsreport-core')({
98
- sandbox: { allowedModules: ['moment'] }
99
- })
100
-
101
- // or unblock everything
102
-
103
- const jsreport = require('@jsreport/jsreport-core')({
104
- sandbox: { allowedModules: '*' }
105
- })
106
- ```
107
-
108
- Additionally, jsreport provides global variables which can be used to build the local script path and read it.
109
-
110
- ```js
111
- const jsreport = require('@jsreport/jsreport-core')({
112
- sandbox: { allowedModules: '*' }
113
- })
114
-
115
- await jsreport.init()
116
- await jsreport.render({
117
- template: {
118
- content: '<script>{{jquery}}</script>',
119
- helpers: `
120
- function jquery() {
121
- const fs = require('fs')
122
- const path = require('path')
123
-
124
- return fs.readFileSync(path.join(__rootDirectory, 'jquery.js'))
125
- }
126
- `,
127
- engine: 'handlebars',
128
- recipe: 'chrome-pdf'
129
- }
130
- })
131
-
132
- ```
133
-
134
- The following variables are available in the global scope:
135
-
136
- - `__rootDirectory` - two directories up from jsreport-core
137
- - `__appDirectory` - directory of the script which is used when starting node
138
- - `__parentModuleDirectory` - directory of script which was initializing jsreport-core
139
-
140
- ## Extensions
141
- You need to install additional packages (extensions) even for the simplest pdf printing. This is the philosophy of jsreport, and you will need to install additional extensions very often. There are many extensions adding support for persisting templates, dynamic script evaluation, adding browser based reports studio or exposing API. To get the idea of the whole platform you can install the full [jsreport](http://jsreport.net/) distribution and pick what you like. Then you can go back to `jsreport-core` and install extensions you need.
142
-
143
- You are also welcome to write your own extension or even publish it to the community. See the following articles how to get started.
144
-
145
- - [Implementing custom jsreport extension](http://jsreport.net/learn/custom-extension)
146
- - [Implementing custom jsreport recipe](http://jsreport.net/learn/custom-recipe)
147
- - [Implementing custom jsreport engine](http://jsreport.net/learn/custom-engine)
148
-
149
- The best place to find availible extensions is in the [jsreport documentation](https://jsreport.net/learn) or you can search in this [monorepo's packages](https://github.com/jsreport/jsreport/tree/master/packages) - every package with `jsreport-` prefix is an extension.
150
-
151
- ## Extensions auto discovery
152
- jsreport by default auto-discovers extensions in the application's directory tree. This means, there is no need to explicitely `require` and call `jsreport.use` for all extensions you want to use. However it is prefered for the clarity.
153
-
154
- ## Configuration
155
- jsreport accepts options as the first parameter. The core options are the following:
156
-
157
- ```js
158
- require('@jsreport/jsreport-core')({
159
- // optionally specifies where's the application root and where jsreport searches for extensions
160
- rootDirectory: path.join(__dirname, '../../'),
161
- // optionally specifies where the application stores temporary files used by the conversion pipeline
162
- tempDirectory: path.join(dataDirectory, 'temp'),
163
- // options for logging
164
- logger: {
165
- silent: false // when true, it will silence all transports defined in logger
166
- },
167
- // options for templating engines and other scripts execution
168
- // see the https://github.com/pofider/node-script-manager for more information
169
- sandbox: {
170
- cache: {
171
- max: 100, //LRU cache with max 100 entries, see npm lru-cache for other options
172
- enabled: true //disable cache
173
- }
174
- },
175
- loadConfig: false,
176
- // the temporary files used to render reports are cleaned up by default
177
- autoTempCleanup: true,
178
- // set to false when you want to always force crawling node_modules when searching for extensions and starting jsreport
179
- useExtensionsLocationCache: true
180
- })
181
- ```
182
-
183
- `jsreport-core` is also able to load configuration from other sources including configuration file, environment variables and command line parameters. This can be opted in through option `loadConfig:true`. If this option is set to true the configuration is merged from the following sources in the particular order:
184
-
185
- 1. configuration file jsreport.config.json or the one specified in `configFile` environment variable
186
- 2. command-line arguments
187
- 3. process environment variables
188
- 4. options passed directly to `require('@jsreport/jsreport-core')({})`
189
-
190
- Each extension (recipe, store...) usually provides some options you can apply and adapt its behavior. These options can be typically set through standard configuration under the top-level `extensions` property, options in there with the name corresponding to the extension's name are forwarded to the particular extension. This is the common way how to globally configure all extensions at one place.
191
-
192
- ```js
193
- require('@jsreport/jsreport-core')({
194
- ...
195
- "extensions": {
196
- "scripts": {
197
- "allowedModules": ["url"]
198
- }
199
- }
200
- })
201
- ```
202
-
203
- You can find configuration notes for the full jsreport distribution [here](http://jsreport.net/learn/configuration).
204
-
205
- ## Logging
206
- jsreport leverages [winston](https://github.com/winstonjs/winston) logging abstraction together with [debug](https://github.com/visionmedia/debug) utility. To output logs in the console just simply set the `DEBUG` environment variable
207
-
208
- ```bash
209
- DEBUG=jsreport node app.js
210
- ```
211
-
212
- on windows do
213
-
214
- ```bash
215
- set DEBUG=jsreport & node app.js
216
- ```
217
-
218
- To declarative configure logging levels and outputs you can see [this page](https://jsreport.net/learn/configuration#logging-configuration) which contains all the details for that.
219
-
220
- jsreport also exposes `logger` property which can be used to adapt the logging as you like. You can for example just add [winston](https://github.com/winstonjs/winston) console transport and filter in only important log messages into console.
221
-
222
- ```js
223
- const winston = require('winston')
224
- const jsreport = require('@jsreport/jsreport-core')()
225
- jsreport.logger.add(winston.transports.Console, { level: 'info' })
226
- ```
227
-
228
- ## Typescript
229
- jsreport types are in the [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) repository.
230
- You can install [@types/jsreport-core](https://www.npmjs.com/package/@types/jsreport-core) and invidual types for extensions, or get all types at once from [@types/jsreport](https://www.npmjs.com/package/@types/jsreport).
231
-
232
- You can also find [jsreport typescript examples here](https://github.com/jsreport/jsreport-typescript-example).
233
-
234
- ## Listeners
235
- jsreport extensions are mainly using the system of event listeners to adapt the rendering process. Extensions, can for example listen to event, which is called before the rendering process starts and adapt the input values.
236
-
237
- ```js
238
- //jsreport must be initialized at this time
239
- jsreport.beforeRenderListeners.add('name-of-listener', (req, res) => {
240
- req.template.content = 'Changing the template in listener!'
241
- })
242
- ```
243
-
244
- To start the listening, you must first add the listener function to the right listener. In the example is used `beforeRenderListeners` which is called before the rendering starts. jsreport then in the right time sequentially fires all the listener functions and let them do the required work. If the function returns a promise, jsreport awaits until it is fulfilled.
245
-
246
- Note this technique can be used in extensions, but also outside in nodejs application using jsreport.
247
-
248
- jsreport currently support these main listeners
249
-
250
- - `initializeListeners()`- called when all extensions are initialized<br/>
251
- - `beforeRenderListeners(req, res)` - very first in the rendering pipeline, used to load templates and parse input data<br/>
252
- - `validateRenderListeners(req, res)` - possible to reject rendering before it starts, jsut return failed promise or exception<br/>
253
- - `afterTemplatingEnginesExecutedListeners(req, res)` - engine like handlebars or jsrender extracted the content, the `res.content` contains Buffer with extracted content<br/>
254
- - `afterRenderListeners(req, res)` - recipes are executed, `res.content` contains final buffer which will be returned as a stream back, the last change to modify the output or send it elsewhere<br/>
255
- - `renderErrorListeners(req, res, err)` - fired when there is error somewhere in the rendering pipeline
256
- - `closeListeners()` called when jsreport is about to be closed, you will usually put here some code that clean up some resource
257
-
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.
260
-
261
- ## Template store
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
263
-
264
- The persistence API is almost compatible to the mongodb API:
265
- ```js
266
- jsreport.documentStore.collection('templates')
267
- .find({name: 'test'})
268
- .then((res) => {})
269
-
270
- jsreport.documentStore.collection('templates')
271
- .update({name: 'test'}, { $set: { attr: 'value' })
272
- .then((res) => {})
273
-
274
- jsreport.documentStore.collection('templates')
275
- .insert({name: 'test'})
276
- .then((res) => {})
277
-
278
- jsreport.documentStore.collection('templates')
279
- .remove({name: 'test'})
280
- .then((res) => {})
281
- ```
282
-
283
- ## Changelog
284
-
285
- ### 3.1.0
286
-
287
- - fix blob storage append to not existing blob (mongo)
288
- - use relative path to the currently evaluated entity
289
- - fix performance issue in sandbox with long buffer (don't use restore() of sandbox through a method attached to the sandbox)
290
- - update migration `xlsxTemplatesToAssets`, `resourcesToAssets` to inherit permissions and change name for resource script to `${template.name}_resources`
291
- - refactor ListenerCollection for better stack traces
292
- - fix startup extensions logs not recognized as npm source
293
- - fix extensions cache entry root path
294
- - don't crash process when monitoring persist fails
295
- - fix compilation (updates to vm2)
296
-
297
- ## License
298
- LGPL
1
+ # @jsreport/jsreport-core
2
+ [![NPM Version](http://img.shields.io/npm/v/@jsreport/jsreport-core.svg?style=flat-square)](https://npmjs.com/package/@jsreport/jsreport-core)
3
+
4
+ **The minimalist [jsreport](http://jsreport.net) rendering core.**
5
+ The full distribution can be found in the [jsreport](https://npmjs.com/package/jsreport) package.
6
+
7
+ [jsreport](http://jsreport.net) is a platform providing dynamic documents assembling and printing. It supports various document types or printing techniques.
8
+
9
+ `@jsreport/jsreport-core` contains the jsreport rendering core that is useless alone. It is up to you which jsreport extensions you combine
10
+
11
+ ## Quick example
12
+
13
+ To generate a document using jsreport, you always need a javascript templating engine. The **engine** is used to dynamically assemble the document based on the input values. For start lets pick [@jsreport/jsreport-handlebars](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-handlebars) engine and install it using npm.
14
+
15
+ Next to the engine, you need something we call **recipe**. A recipe represents the technique used to print the document. It can be an HTML to pdf conversion, DOCX rendering, and others. In this example lets pick [@jsreport/jsreport-chrome-pdf](https://github.com/jsreport/jsreport/tree/master/packages/jsreport-chrome-pdf). This recipe implements HTML to pdf conversion using [chrome](https://developers.google.com/web/updates/2017/04/headless-chrome). So in this example, we use handlebars to assemble HTML based on the input data and then print the output into the final pdf.
16
+
17
+ > npm install @jsreport/jsreport-core<br/>
18
+ > npm install @jsreport/jsreport-handlebars<br/>
19
+ > npm install puppeteer @jsreport/jsreport-chrome-pdf
20
+
21
+ ```js
22
+ const fs = require('fs').promises
23
+
24
+ const jsreport = require('@jsreport/jsreport-core')()
25
+ jsreport.use(require('@jsreport/jsreport-chrome-pdf')())
26
+ jsreport.use(require('@jsreport/jsreport-handlebars')())
27
+
28
+ await jsreport.init()
29
+ const result = await jsreport.render({
30
+ template: {
31
+ content: '<h1>Hello {{foo}}</h1>',
32
+ engine: 'handlebars',
33
+ recipe: 'chrome-pdf'
34
+ },
35
+ data: {
36
+ foo: "world"
37
+ }
38
+ })
39
+ await fs.writeFile('out.pdf', resp.content)
40
+ ```
41
+
42
+ ## Render
43
+ `render` is the main method that invokes report generation. A single parameter is an object representing describing what to render. It has the following structure:
44
+ ```js
45
+ {
46
+ //[required definition of the document]
47
+ template: {
48
+ //[required] templating engine used to assemble document
49
+ engine: "handlebars",
50
+ //[required] recipe used for printing previously assembled document
51
+ recipe: "chrome-pdf",
52
+ //[required] template for the engine
53
+ content: "<h1>{{foo}}</h1>",
54
+ //javascript helper functions used by templating engines
55
+ helpers: "function foo() { ...} " +
56
+ "function foo2() { ... }"
57
+ //any other settings used by recipes
58
+ ...
59
+ },
60
+ //dynamic data inputs used by templating engines
61
+ data: { foo: "hello world"}
62
+ ...
63
+ }
64
+ ```
65
+
66
+ In case you have the template stored in the [jsreport templates store](https://github.com/jsreport/jsreport-core#template-store), you can reference the template using a name or path.
67
+
68
+ ```js
69
+ {
70
+ template: {
71
+ name: '/myfolder/mytemplate'
72
+ },
73
+ data: { foo: "hello world"}
74
+ ...
75
+ }
76
+ ```
77
+
78
+ The render returns a promise with the single response value
79
+ ```js
80
+ {
81
+ //node.js buffer with the document
82
+ content: ...
83
+ //stream with the document
84
+ stream: ...
85
+ //object containing metadata about the report generation (reportName, logs, etc)..
86
+ meta: { ... }
87
+ }
88
+ ```
89
+
90
+ The convention is that jsreport repository extension starts with `jsreport-xxx`, but the extension real name and also the recipes or engines it registers excludes the `jsreport-` prefix. This means if you install extension `@jsreport/jsreport-handlebars` the engine's name you specify in the render should be `handlebars`.
91
+
92
+
93
+ ### Require in the helpers
94
+ jsreport by default runs helpers in the sandbox where is the `require` function blocked. To unblock particular modules or local scripts you need to configure `sandbox.allowedModules` option.
95
+
96
+ ```js
97
+ const jsreport = require('@jsreport/jsreport-core')({
98
+ sandbox: { allowedModules: ['moment'] }
99
+ })
100
+
101
+ // or unblock everything
102
+
103
+ const jsreport = require('@jsreport/jsreport-core')({
104
+ sandbox: { allowedModules: '*' }
105
+ })
106
+ ```
107
+
108
+ Additionally, jsreport provides global variables which can be used to build the local script path and read it.
109
+
110
+ ```js
111
+ const jsreport = require('@jsreport/jsreport-core')({
112
+ sandbox: { allowedModules: '*' }
113
+ })
114
+
115
+ await jsreport.init()
116
+ await jsreport.render({
117
+ template: {
118
+ content: '<script>{{jquery}}</script>',
119
+ helpers: `
120
+ function jquery() {
121
+ const fs = require('fs')
122
+ const path = require('path')
123
+
124
+ return fs.readFileSync(path.join(__rootDirectory, 'jquery.js'))
125
+ }
126
+ `,
127
+ engine: 'handlebars',
128
+ recipe: 'chrome-pdf'
129
+ }
130
+ })
131
+
132
+ ```
133
+
134
+ The following variables are available in the global scope:
135
+
136
+ - `__rootDirectory` - two directories up from jsreport-core
137
+ - `__appDirectory` - directory of the script which is used when starting node
138
+ - `__parentModuleDirectory` - directory of script which was initializing jsreport-core
139
+
140
+ ## Extensions
141
+ You need to install additional packages (extensions) even for the simplest pdf printing. This is the philosophy of jsreport, and you will need to install additional extensions very often. There are many extensions adding support for persisting templates, dynamic script evaluation, adding browser based reports studio or exposing API. To get the idea of the whole platform you can install the full [jsreport](http://jsreport.net/) distribution and pick what you like. Then you can go back to `jsreport-core` and install extensions you need.
142
+
143
+ You are also welcome to write your own extension or even publish it to the community. See the following articles how to get started.
144
+
145
+ - [Implementing custom jsreport extension](http://jsreport.net/learn/custom-extension)
146
+ - [Implementing custom jsreport recipe](http://jsreport.net/learn/custom-recipe)
147
+ - [Implementing custom jsreport engine](http://jsreport.net/learn/custom-engine)
148
+
149
+ The best place to find availible extensions is in the [jsreport documentation](https://jsreport.net/learn) or you can search in this [monorepo's packages](https://github.com/jsreport/jsreport/tree/master/packages) - every package with `jsreport-` prefix is an extension.
150
+
151
+ ## Extensions auto discovery
152
+ jsreport by default auto-discovers extensions in the application's directory tree. This means, there is no need to explicitely `require` and call `jsreport.use` for all extensions you want to use. However it is prefered for the clarity.
153
+
154
+ ## Configuration
155
+ jsreport accepts options as the first parameter. The core options are the following:
156
+
157
+ ```js
158
+ require('@jsreport/jsreport-core')({
159
+ // optionally specifies where's the application root and where jsreport searches for extensions
160
+ rootDirectory: path.join(__dirname, '../../'),
161
+ // optionally specifies where the application stores temporary files used by the conversion pipeline
162
+ tempDirectory: path.join(dataDirectory, 'temp'),
163
+ // options for logging
164
+ logger: {
165
+ silent: false // when true, it will silence all transports defined in logger
166
+ },
167
+ // options for templating engines and other scripts execution
168
+ // see the https://github.com/pofider/node-script-manager for more information
169
+ sandbox: {
170
+ cache: {
171
+ max: 100, //LRU cache with max 100 entries, see npm lru-cache for other options
172
+ enabled: true //disable cache
173
+ }
174
+ },
175
+ loadConfig: false,
176
+ // the temporary files used to render reports are cleaned up by default
177
+ autoTempCleanup: true,
178
+ // set to false when you want to always force crawling node_modules when searching for extensions and starting jsreport
179
+ useExtensionsLocationCache: true
180
+ })
181
+ ```
182
+
183
+ `jsreport-core` is also able to load configuration from other sources including configuration file, environment variables and command line parameters. This can be opted in through option `loadConfig:true`. If this option is set to true the configuration is merged from the following sources in the particular order:
184
+
185
+ 1. configuration file jsreport.config.json or the one specified in `configFile` environment variable
186
+ 2. command-line arguments
187
+ 3. process environment variables
188
+ 4. options passed directly to `require('@jsreport/jsreport-core')({})`
189
+
190
+ Each extension (recipe, store...) usually provides some options you can apply and adapt its behavior. These options can be typically set through standard configuration under the top-level `extensions` property, options in there with the name corresponding to the extension's name are forwarded to the particular extension. This is the common way how to globally configure all extensions at one place.
191
+
192
+ ```js
193
+ require('@jsreport/jsreport-core')({
194
+ ...
195
+ "extensions": {
196
+ "scripts": {
197
+ "allowedModules": ["url"]
198
+ }
199
+ }
200
+ })
201
+ ```
202
+
203
+ You can find configuration notes for the full jsreport distribution [here](http://jsreport.net/learn/configuration).
204
+
205
+ ## Logging
206
+ jsreport leverages [winston](https://github.com/winstonjs/winston) logging abstraction together with [debug](https://github.com/visionmedia/debug) utility. To output logs in the console just simply set the `DEBUG` environment variable
207
+
208
+ ```bash
209
+ DEBUG=jsreport node app.js
210
+ ```
211
+
212
+ on windows do
213
+
214
+ ```bash
215
+ set DEBUG=jsreport & node app.js
216
+ ```
217
+
218
+ To declarative configure logging levels and outputs you can see [this page](https://jsreport.net/learn/configuration#logging-configuration) which contains all the details for that.
219
+
220
+ jsreport also exposes `logger` property which can be used to adapt the logging as you like. You can for example just add [winston](https://github.com/winstonjs/winston) console transport and filter in only important log messages into console.
221
+
222
+ ```js
223
+ const winston = require('winston')
224
+ const jsreport = require('@jsreport/jsreport-core')()
225
+ jsreport.logger.add(winston.transports.Console, { level: 'info' })
226
+ ```
227
+
228
+ ## Typescript
229
+ jsreport types are in the [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) repository.
230
+ You can install [@types/jsreport-core](https://www.npmjs.com/package/@types/jsreport-core) and invidual types for extensions, or get all types at once from [@types/jsreport](https://www.npmjs.com/package/@types/jsreport).
231
+
232
+ You can also find [jsreport typescript examples here](https://github.com/jsreport/jsreport-typescript-example).
233
+
234
+ ## Listeners
235
+ jsreport extensions are mainly using the system of event listeners to adapt the rendering process. Extensions, can for example listen to event, which is called before the rendering process starts and adapt the input values.
236
+
237
+ ```js
238
+ //jsreport must be initialized at this time
239
+ jsreport.beforeRenderListeners.add('name-of-listener', (req, res) => {
240
+ req.template.content = 'Changing the template in listener!'
241
+ })
242
+ ```
243
+
244
+ To start the listening, you must first add the listener function to the right listener. In the example is used `beforeRenderListeners` which is called before the rendering starts. jsreport then in the right time sequentially fires all the listener functions and let them do the required work. If the function returns a promise, jsreport awaits until it is fulfilled.
245
+
246
+ Note this technique can be used in extensions, but also outside in nodejs application using jsreport.
247
+
248
+ jsreport currently support these main listeners
249
+
250
+ - `initializeListeners()`- called when all extensions are initialized<br/>
251
+ - `beforeRenderListeners(req, res)` - very first in the rendering pipeline, used to load templates and parse input data<br/>
252
+ - `validateRenderListeners(req, res)` - possible to reject rendering before it starts, jsut return failed promise or exception<br/>
253
+ - `afterTemplatingEnginesExecutedListeners(req, res)` - engine like handlebars or jsrender extracted the content, the `res.content` contains Buffer with extracted content<br/>
254
+ - `afterRenderListeners(req, res)` - recipes are executed, `res.content` contains final buffer which will be returned as a stream back, the last change to modify the output or send it elsewhere<br/>
255
+ - `renderErrorListeners(req, res, err)` - fired when there is error somewhere in the rendering pipeline
256
+ - `closeListeners()` called when jsreport is about to be closed, you will usually put here some code that clean up some resource
257
+
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.
260
+
261
+ ## Template store
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
263
+
264
+ The persistence API is almost compatible to the mongodb API:
265
+ ```js
266
+ jsreport.documentStore.collection('templates')
267
+ .find({name: 'test'})
268
+ .then((res) => {})
269
+
270
+ jsreport.documentStore.collection('templates')
271
+ .update({name: 'test'}, { $set: { attr: 'value' })
272
+ .then((res) => {})
273
+
274
+ jsreport.documentStore.collection('templates')
275
+ .insert({name: 'test'})
276
+ .then((res) => {})
277
+
278
+ jsreport.documentStore.collection('templates')
279
+ .remove({name: 'test'})
280
+ .then((res) => {})
281
+ ```
282
+
283
+ ## Changelog
284
+
285
+ ### 3.1.0
286
+
287
+ - fix blob storage append to not existing blob (mongo)
288
+ - use relative path to the currently evaluated entity
289
+ - fix performance issue in sandbox with long buffer (don't use restore() of sandbox through a method attached to the sandbox)
290
+ - update migration `xlsxTemplatesToAssets`, `resourcesToAssets` to inherit permissions and change name for resource script to `${template.name}_resources`
291
+ - refactor ListenerCollection for better stack traces
292
+ - fix startup extensions logs not recognized as npm source
293
+ - fix extensions cache entry root path
294
+ - don't crash process when monitoring persist fails
295
+ - fix compilation (updates to vm2)
296
+
297
+ ## License
298
+ LGPL