@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,230 +1,230 @@
1
- const Request = require('../../shared/request')
2
-
3
- module.exports = async (reporter) => {
4
- if (
5
- reporter.options.migrateResourcesToAssets === false ||
6
- reporter.documentStore.collection('scripts') == null ||
7
- reporter.documentStore.collection('data') == null
8
- ) {
9
- return
10
- }
11
-
12
- const migrated = await reporter.settings.findValue('core-migrated-resources')
13
-
14
- if (migrated) {
15
- return
16
- }
17
-
18
- const req = Request({})
19
- await reporter.documentStore.beginTransaction(req)
20
-
21
- try {
22
- const templateIds = await reporter.documentStore.collection('templates').find({}, { _id: 1 }, req)
23
-
24
- if (templateIds.length !== 0) {
25
- reporter.logger.debug('Running migration "resourcesToAssets"')
26
- }
27
-
28
- const templateToAssetResourcesMap = new Map()
29
- const dataToAssetMap = new Map()
30
- const dataEntitiesToRemove = []
31
-
32
- for (const templateId of templateIds) {
33
- const template = await reporter.documentStore.collection('templates').findOne({ _id: templateId._id }, req)
34
-
35
- if (template.resources == null) {
36
- continue
37
- }
38
-
39
- if (Array.isArray(template.resources.items)) {
40
- for (const dataItem of template.resources.items) {
41
- const dataEntity = await reporter.documentStore.collection('data').findOne({ shortid: dataItem.shortid }, req)
42
-
43
- if (dataEntity) {
44
- let newAsset
45
-
46
- if (dataToAssetMap.has(dataEntity._id)) {
47
- newAsset = dataToAssetMap.get(dataEntity._id)
48
- } else {
49
- const assetProps = {
50
- content: Buffer.from(dataEntity.dataJson || ''),
51
- folder: dataEntity.folder || null
52
- }
53
-
54
- if (dataEntity.readPermissions != null) {
55
- assetProps.readPermissions = dataEntity.readPermissions
56
- }
57
-
58
- if (dataEntity.editPermissions != null) {
59
- assetProps.editPermissions = dataEntity.editPermissions
60
- }
61
-
62
- newAsset = await insertUnique(reporter, 'assets', `${dataEntity.name}.json`, assetProps, req)
63
-
64
- dataToAssetMap.set(dataEntity._id, newAsset)
65
- }
66
-
67
- const assetResources = templateToAssetResourcesMap.get(template._id) || []
68
-
69
- assetResources.push({
70
- ...newAsset,
71
- originalName: dataEntity.name
72
- })
73
-
74
- templateToAssetResourcesMap.set(template._id, assetResources)
75
- dataEntitiesToRemove.push(dataEntity._id)
76
- }
77
- }
78
- }
79
-
80
- const templateAssetResources = templateToAssetResourcesMap.get(template._id) || []
81
-
82
- if (templateAssetResources.length > 0) {
83
- const scriptProps = {
84
- content: (
85
- `
86
- // THIS SCRIPT WAS GENERATED BY MIGRATION IN V3, IT PROVIDES BACKWARD COMPATIBILITY
87
- // WITH THE DEPRECATED jsreport-resources https://jsreport.net/learn/resources
88
- // THE RECOMMENDATION NOW IS TO USE jsreport-localization https://jsreport.net/learn/localization
89
- // SO WHEN YOU DECIDE TO USE jsreport-localization TO FULLY REPLACE THE jsreport-resources
90
- // JUST REMOVE THIS SCRIPT FROM YOUR TEMPLATE AND DELETE IT
91
- const jsreport = require('jsreport-proxy')
92
-
93
- async function beforeRender (req, res) {
94
- req.options.language = req.options.language || req.template.localization?.language
95
- const defaultLanguage = ${template.resources.defaultLanguage != null ? '\'' + template.resources.defaultLanguage + '\'' : 'undefined'}
96
- const assetsResources = [${templateAssetResources.map(a => `{ name: '${a.originalName}', shortid: '${a.shortid}' }`).join(', ')}]
97
-
98
- const resources = await Promise.all(assetsResources.map(async (r) => {
99
- const asset = await jsreport.documentStore.collection('assets').findOne({ shortid: r.shortid })
100
-
101
- if (asset == null) {
102
- throw new Error(\`Asset resources with shortid \${r.shortid} was not found (resource lookup)\`)
103
- }
104
-
105
- asset.resourceName = r.name
106
- asset.content = asset.content.toString()
107
-
108
- return asset
109
- }))
110
-
111
- resources.forEach((r) => {
112
- r.dataJson = r.content
113
- r.data = JSON.parse(r.content)
114
- })
115
-
116
- req.options.resources = resources
117
- req.data.$resources = resources
118
-
119
- const resourcesByName = {}
120
-
121
- resources.forEach((r) => {
122
- resourcesByName[r.resourceName] = r.data
123
- })
124
-
125
- req.options.resource = resourcesByName
126
- req.data.$resource = resourcesByName
127
-
128
- const isLocalizedRequest = req.options.language != null || defaultLanguage != null
129
-
130
- if (isLocalizedRequest) {
131
- let languageUsed
132
- let applicableResources = []
133
-
134
- if (req.options.language) {
135
- languageUsed = req.options.language
136
- applicableResources = resources.filter((r) => r.resourceName.startsWith(\`\${languageUsed}-\`))
137
- }
138
-
139
- if (!applicableResources.length && defaultLanguage) {
140
- languageUsed = defaultLanguage
141
- applicableResources = resources.filter((r) => r.resourceName.startsWith(\`\${languageUsed}-\`))
142
- }
143
-
144
- console.log(\`Found \${applicableResources.length} resources for language "\${languageUsed}"\`)
145
-
146
- req.options.localizedResources = applicableResources
147
- req.data.$localizedResources = applicableResources
148
-
149
- const localizedResourceByName = {}
150
-
151
- applicableResources.forEach((r) => {
152
- localizedResourceByName[r.resourceName.substring(\`\${languageUsed}-\`.length)] = r.data
153
- })
154
-
155
- req.options.localizedResource = applicableResources.length === 1 ? applicableResources[0].data : localizedResourceByName
156
- req.data.$localizedResource = req.options.localizedResource
157
- }
158
- }
159
- `
160
- ),
161
- folder: template.folder || null
162
- }
163
-
164
- if (template.readPermissions != null) {
165
- scriptProps.readPermissions = template.readPermissions
166
- }
167
-
168
- if (template.editPermissions != null) {
169
- scriptProps.editPermissions = template.editPermissions
170
- }
171
-
172
- const newScript = await insertUnique(reporter, 'scripts', `${template.name}_resources`, scriptProps, req)
173
-
174
- template.scripts = template.scripts || []
175
-
176
- template.scripts.unshift({
177
- shortid: newScript.shortid
178
- })
179
- }
180
-
181
- template.resources = null
182
-
183
- await reporter.documentStore.collection('templates').update({ _id: template._id }, { $set: template }, req)
184
- }
185
-
186
- for (const dataEntityId of dataEntitiesToRemove) {
187
- await reporter.documentStore.collection('data').remove({ _id: dataEntityId }, req)
188
- }
189
-
190
- if (templateIds.length !== 0) {
191
- reporter.logger.debug('Migration "resourcesToAssets" finished')
192
- }
193
-
194
- await reporter.documentStore.commitTransaction(req)
195
-
196
- await reporter.settings.addOrSet('core-migrated-resources', true)
197
- } catch (migrationErr) {
198
- await reporter.documentStore.rollbackTransaction(req)
199
-
200
- migrationErr.message = `Migration "resourcesToAssets" failed: ${migrationErr.message}`
201
-
202
- throw migrationErr
203
- }
204
- }
205
-
206
- async function insertUnique (reporter, collectionName, baseName, entity, req) {
207
- let newEntity
208
- let tryCount = 0
209
-
210
- while (newEntity == null) {
211
- try {
212
- const entityName = '_'.repeat(tryCount) + baseName
213
-
214
- newEntity = await reporter.documentStore.collection(collectionName).insert({
215
- ...entity,
216
- name: entityName
217
- }, req)
218
-
219
- return newEntity
220
- } catch (insertError) {
221
- tryCount++
222
-
223
- if (insertError.code === 'DUPLICATED_ENTITY') {
224
- continue
225
- } else {
226
- throw insertError
227
- }
228
- }
229
- }
230
- }
1
+ const Request = require('../../shared/request')
2
+
3
+ module.exports = async (reporter) => {
4
+ if (
5
+ reporter.options.migrateResourcesToAssets === false ||
6
+ reporter.documentStore.collection('scripts') == null ||
7
+ reporter.documentStore.collection('data') == null
8
+ ) {
9
+ return
10
+ }
11
+
12
+ const migrated = await reporter.settings.findValue('core-migrated-resources')
13
+
14
+ if (migrated) {
15
+ return
16
+ }
17
+
18
+ const req = Request({})
19
+ await reporter.documentStore.beginTransaction(req)
20
+
21
+ try {
22
+ const templateIds = await reporter.documentStore.collection('templates').find({}, { _id: 1 }, req)
23
+
24
+ if (templateIds.length !== 0) {
25
+ reporter.logger.debug('Running migration "resourcesToAssets"')
26
+ }
27
+
28
+ const templateToAssetResourcesMap = new Map()
29
+ const dataToAssetMap = new Map()
30
+ const dataEntitiesToRemove = []
31
+
32
+ for (const templateId of templateIds) {
33
+ const template = await reporter.documentStore.collection('templates').findOne({ _id: templateId._id }, req)
34
+
35
+ if (template.resources == null) {
36
+ continue
37
+ }
38
+
39
+ if (Array.isArray(template.resources.items)) {
40
+ for (const dataItem of template.resources.items) {
41
+ const dataEntity = await reporter.documentStore.collection('data').findOne({ shortid: dataItem.shortid }, req)
42
+
43
+ if (dataEntity) {
44
+ let newAsset
45
+
46
+ if (dataToAssetMap.has(dataEntity._id)) {
47
+ newAsset = dataToAssetMap.get(dataEntity._id)
48
+ } else {
49
+ const assetProps = {
50
+ content: Buffer.from(dataEntity.dataJson || ''),
51
+ folder: dataEntity.folder || null
52
+ }
53
+
54
+ if (dataEntity.readPermissions != null) {
55
+ assetProps.readPermissions = dataEntity.readPermissions
56
+ }
57
+
58
+ if (dataEntity.editPermissions != null) {
59
+ assetProps.editPermissions = dataEntity.editPermissions
60
+ }
61
+
62
+ newAsset = await insertUnique(reporter, 'assets', `${dataEntity.name}.json`, assetProps, req)
63
+
64
+ dataToAssetMap.set(dataEntity._id, newAsset)
65
+ }
66
+
67
+ const assetResources = templateToAssetResourcesMap.get(template._id) || []
68
+
69
+ assetResources.push({
70
+ ...newAsset,
71
+ originalName: dataEntity.name
72
+ })
73
+
74
+ templateToAssetResourcesMap.set(template._id, assetResources)
75
+ dataEntitiesToRemove.push(dataEntity._id)
76
+ }
77
+ }
78
+ }
79
+
80
+ const templateAssetResources = templateToAssetResourcesMap.get(template._id) || []
81
+
82
+ if (templateAssetResources.length > 0) {
83
+ const scriptProps = {
84
+ content: (
85
+ `
86
+ // THIS SCRIPT WAS GENERATED BY MIGRATION IN V3, IT PROVIDES BACKWARD COMPATIBILITY
87
+ // WITH THE DEPRECATED jsreport-resources https://jsreport.net/learn/resources
88
+ // THE RECOMMENDATION NOW IS TO USE jsreport-localization https://jsreport.net/learn/localization
89
+ // SO WHEN YOU DECIDE TO USE jsreport-localization TO FULLY REPLACE THE jsreport-resources
90
+ // JUST REMOVE THIS SCRIPT FROM YOUR TEMPLATE AND DELETE IT
91
+ const jsreport = require('jsreport-proxy')
92
+
93
+ async function beforeRender (req, res) {
94
+ req.options.language = req.options.language || req.template.localization?.language
95
+ const defaultLanguage = ${template.resources.defaultLanguage != null ? '\'' + template.resources.defaultLanguage + '\'' : 'undefined'}
96
+ const assetsResources = [${templateAssetResources.map(a => `{ name: '${a.originalName}', shortid: '${a.shortid}' }`).join(', ')}]
97
+
98
+ const resources = await Promise.all(assetsResources.map(async (r) => {
99
+ const asset = await jsreport.documentStore.collection('assets').findOne({ shortid: r.shortid })
100
+
101
+ if (asset == null) {
102
+ throw new Error(\`Asset resources with shortid \${r.shortid} was not found (resource lookup)\`)
103
+ }
104
+
105
+ asset.resourceName = r.name
106
+ asset.content = asset.content.toString()
107
+
108
+ return asset
109
+ }))
110
+
111
+ resources.forEach((r) => {
112
+ r.dataJson = r.content
113
+ r.data = JSON.parse(r.content)
114
+ })
115
+
116
+ req.options.resources = resources
117
+ req.data.$resources = resources
118
+
119
+ const resourcesByName = {}
120
+
121
+ resources.forEach((r) => {
122
+ resourcesByName[r.resourceName] = r.data
123
+ })
124
+
125
+ req.options.resource = resourcesByName
126
+ req.data.$resource = resourcesByName
127
+
128
+ const isLocalizedRequest = req.options.language != null || defaultLanguage != null
129
+
130
+ if (isLocalizedRequest) {
131
+ let languageUsed
132
+ let applicableResources = []
133
+
134
+ if (req.options.language) {
135
+ languageUsed = req.options.language
136
+ applicableResources = resources.filter((r) => r.resourceName.startsWith(\`\${languageUsed}-\`))
137
+ }
138
+
139
+ if (!applicableResources.length && defaultLanguage) {
140
+ languageUsed = defaultLanguage
141
+ applicableResources = resources.filter((r) => r.resourceName.startsWith(\`\${languageUsed}-\`))
142
+ }
143
+
144
+ console.log(\`Found \${applicableResources.length} resources for language "\${languageUsed}"\`)
145
+
146
+ req.options.localizedResources = applicableResources
147
+ req.data.$localizedResources = applicableResources
148
+
149
+ const localizedResourceByName = {}
150
+
151
+ applicableResources.forEach((r) => {
152
+ localizedResourceByName[r.resourceName.substring(\`\${languageUsed}-\`.length)] = r.data
153
+ })
154
+
155
+ req.options.localizedResource = applicableResources.length === 1 ? applicableResources[0].data : localizedResourceByName
156
+ req.data.$localizedResource = req.options.localizedResource
157
+ }
158
+ }
159
+ `
160
+ ),
161
+ folder: template.folder || null
162
+ }
163
+
164
+ if (template.readPermissions != null) {
165
+ scriptProps.readPermissions = template.readPermissions
166
+ }
167
+
168
+ if (template.editPermissions != null) {
169
+ scriptProps.editPermissions = template.editPermissions
170
+ }
171
+
172
+ const newScript = await insertUnique(reporter, 'scripts', `${template.name}_resources`, scriptProps, req)
173
+
174
+ template.scripts = template.scripts || []
175
+
176
+ template.scripts.unshift({
177
+ shortid: newScript.shortid
178
+ })
179
+ }
180
+
181
+ template.resources = null
182
+
183
+ await reporter.documentStore.collection('templates').update({ _id: template._id }, { $set: template }, req)
184
+ }
185
+
186
+ for (const dataEntityId of dataEntitiesToRemove) {
187
+ await reporter.documentStore.collection('data').remove({ _id: dataEntityId }, req)
188
+ }
189
+
190
+ if (templateIds.length !== 0) {
191
+ reporter.logger.debug('Migration "resourcesToAssets" finished')
192
+ }
193
+
194
+ await reporter.documentStore.commitTransaction(req)
195
+
196
+ await reporter.settings.addOrSet('core-migrated-resources', true)
197
+ } catch (migrationErr) {
198
+ await reporter.documentStore.rollbackTransaction(req)
199
+
200
+ migrationErr.message = `Migration "resourcesToAssets" failed: ${migrationErr.message}`
201
+
202
+ throw migrationErr
203
+ }
204
+ }
205
+
206
+ async function insertUnique (reporter, collectionName, baseName, entity, req) {
207
+ let newEntity
208
+ let tryCount = 0
209
+
210
+ while (newEntity == null) {
211
+ try {
212
+ const entityName = '_'.repeat(tryCount) + baseName
213
+
214
+ newEntity = await reporter.documentStore.collection(collectionName).insert({
215
+ ...entity,
216
+ name: entityName
217
+ }, req)
218
+
219
+ return newEntity
220
+ } catch (insertError) {
221
+ tryCount++
222
+
223
+ if (insertError.code === 'DUPLICATED_ENTITY') {
224
+ continue
225
+ } else {
226
+ throw insertError
227
+ }
228
+ }
229
+ }
230
+ }