@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,71 +1,71 @@
1
- const omit = require('lodash.omit')
2
-
3
- module.exports = (reporter) => {
4
- reporter.initializeListeners.add('core-validate-shortid', () => {
5
- for (const c of Object.keys(reporter.documentStore.collections)) {
6
- const es = reporter.documentStore.model.entitySets[c]
7
- const et = reporter.documentStore.model.entityTypes[es.entityType.substring('jsreport.'.length)]
8
-
9
- if (!et.shortid) {
10
- return
11
- }
12
-
13
- reporter.documentStore.collection(c).beforeInsertListeners.add('validate-shortid', (doc, req) => {
14
- return validateShortid(reporter, c, doc, undefined, req)
15
- })
16
-
17
- reporter.documentStore.collection(c).beforeUpdateListeners.add('validate-shortid', async (q, update, opts, req) => {
18
- if (update.$set && opts && opts.upsert === true) {
19
- await validateShortid(reporter, c, update.$set, undefined, req)
20
- }
21
-
22
- if (typeof update.$set.shortid === 'undefined') {
23
- return
24
- }
25
-
26
- const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
27
- return Promise.all(entitiesToUpdate.map(e => validateShortid(reporter, c, Object.assign({}, e, update.$set), e._id, req)))
28
- })
29
- }
30
- })
31
- }
32
-
33
- async function validateShortid (reporter, collectionName, doc, originalIdValue, req) {
34
- const shortid = doc.shortid
35
-
36
- if (!shortid) {
37
- throw reporter.createError('Entity shortid property can not be empty', {
38
- statusCode: 400
39
- })
40
- }
41
-
42
- const existingEntity = await findEntity(reporter, collectionName, shortid, req)
43
-
44
- if (existingEntity) {
45
- if (originalIdValue != null && existingEntity._id === originalIdValue) {
46
- return
47
- }
48
-
49
- throw reporter.createError(`Entity with shortid "${shortid}" already exists.`, {
50
- statusCode: 400,
51
- code: 'DUPLICATED_ENTITY',
52
- existingEntity,
53
- existingEntityEntitySet: collectionName
54
- })
55
- }
56
- }
57
-
58
- async function findEntity (reporter, collectionName, shortid, req) {
59
- const localReq = req ? reporter.Request(req) : req
60
-
61
- // we should validate without caring about permissions
62
- if (localReq) {
63
- localReq.context = localReq.context ? omit(localReq.context, 'user') : localReq.context
64
- }
65
-
66
- const existingEntity = await reporter.documentStore.collection(collectionName).findOne({
67
- shortid
68
- }, localReq)
69
-
70
- return existingEntity
71
- }
1
+ const omit = require('lodash.omit')
2
+
3
+ module.exports = (reporter) => {
4
+ reporter.initializeListeners.add('core-validate-shortid', () => {
5
+ for (const c of Object.keys(reporter.documentStore.collections)) {
6
+ const es = reporter.documentStore.model.entitySets[c]
7
+ const et = reporter.documentStore.model.entityTypes[es.entityType.substring('jsreport.'.length)]
8
+
9
+ if (!et.shortid) {
10
+ return
11
+ }
12
+
13
+ reporter.documentStore.collection(c).beforeInsertListeners.add('validate-shortid', (doc, req) => {
14
+ return validateShortid(reporter, c, doc, undefined, req)
15
+ })
16
+
17
+ reporter.documentStore.collection(c).beforeUpdateListeners.add('validate-shortid', async (q, update, opts, req) => {
18
+ if (update.$set && opts && opts.upsert === true) {
19
+ await validateShortid(reporter, c, update.$set, undefined, req)
20
+ }
21
+
22
+ if (typeof update.$set.shortid === 'undefined') {
23
+ return
24
+ }
25
+
26
+ const entitiesToUpdate = await reporter.documentStore.collection(c).find(q, req)
27
+ return Promise.all(entitiesToUpdate.map(e => validateShortid(reporter, c, Object.assign({}, e, update.$set), e._id, req)))
28
+ })
29
+ }
30
+ })
31
+ }
32
+
33
+ async function validateShortid (reporter, collectionName, doc, originalIdValue, req) {
34
+ const shortid = doc.shortid
35
+
36
+ if (!shortid) {
37
+ throw reporter.createError('Entity shortid property can not be empty', {
38
+ statusCode: 400
39
+ })
40
+ }
41
+
42
+ const existingEntity = await findEntity(reporter, collectionName, shortid, req)
43
+
44
+ if (existingEntity) {
45
+ if (originalIdValue != null && existingEntity._id === originalIdValue) {
46
+ return
47
+ }
48
+
49
+ throw reporter.createError(`Entity with shortid "${shortid}" already exists.`, {
50
+ statusCode: 400,
51
+ code: 'DUPLICATED_ENTITY',
52
+ existingEntity,
53
+ existingEntityEntitySet: collectionName
54
+ })
55
+ }
56
+ }
57
+
58
+ async function findEntity (reporter, collectionName, shortid, req) {
59
+ const localReq = req ? reporter.Request(req) : req
60
+
61
+ // we should validate without caring about permissions
62
+ if (localReq) {
63
+ localReq.context = localReq.context ? omit(localReq.context, 'user') : localReq.context
64
+ }
65
+
66
+ const existingEntity = await reporter.documentStore.collection(collectionName).findOne({
67
+ shortid
68
+ }, localReq)
69
+
70
+ return existingEntity
71
+ }
@@ -1,69 +1,69 @@
1
- const extend = require('node.extend.without.arrays')
2
-
3
- module.exports = ({ queue }) => {
4
- let commitedDocuments = {}
5
-
6
- return {
7
- getCurrentDocuments (opts = {}) {
8
- return opts.transaction == null ? commitedDocuments : opts.transaction.documents
9
- },
10
-
11
- begin () {
12
- return queue.push(async () => {
13
- return {
14
- documents: cloneDocuments(commitedDocuments),
15
- operations: [],
16
- beginTime: Date.now()
17
- }
18
- })
19
- },
20
-
21
- async operation (opts, fn) {
22
- if (fn == null) {
23
- fn = opts
24
- }
25
-
26
- if (opts.transaction) {
27
- return queue.push(() => {
28
- opts.transaction.operations.push(fn)
29
- return fn(opts.transaction.documents)
30
- })
31
- }
32
-
33
- return queue.push(() => fn(commitedDocuments))
34
- },
35
-
36
- async commit (transaction) {
37
- return queue.push(async () => {
38
- const documentsClone = cloneDocuments(commitedDocuments)
39
-
40
- for (const op of transaction.operations) {
41
- await op(documentsClone)
42
- }
43
-
44
- for (const entitySet in documentsClone) {
45
- for (const transactionEntity of documentsClone[entitySet]) {
46
- const commitedEntity = commitedDocuments[entitySet].find(e => e._id)
47
- if (commitedEntity &&
48
- transactionEntity.$$etag !== commitedEntity.$$etag &&
49
- commitedEntity.$$etag > transaction.beginTime
50
- ) {
51
- throw new Error(`Entity ${transactionEntity.name} was modified by another transaction`)
52
- }
53
- }
54
- }
55
-
56
- commitedDocuments = documentsClone
57
- })
58
- },
59
-
60
- async rollback (transaction) {}
61
- }
62
- }
63
-
64
- function cloneDocuments (obj) {
65
- return Object.keys(obj).reduce((acu, setName) => {
66
- acu[setName] = obj[setName].map((doc) => extend(true, {}, doc))
67
- return acu
68
- }, {})
69
- }
1
+ const extend = require('node.extend.without.arrays')
2
+
3
+ module.exports = ({ queue }) => {
4
+ let commitedDocuments = {}
5
+
6
+ return {
7
+ getCurrentDocuments (opts = {}) {
8
+ return opts.transaction == null ? commitedDocuments : opts.transaction.documents
9
+ },
10
+
11
+ begin () {
12
+ return queue.push(async () => {
13
+ return {
14
+ documents: cloneDocuments(commitedDocuments),
15
+ operations: [],
16
+ beginTime: Date.now()
17
+ }
18
+ })
19
+ },
20
+
21
+ async operation (opts, fn) {
22
+ if (fn == null) {
23
+ fn = opts
24
+ }
25
+
26
+ if (opts.transaction) {
27
+ return queue.push(() => {
28
+ opts.transaction.operations.push(fn)
29
+ return fn(opts.transaction.documents)
30
+ })
31
+ }
32
+
33
+ return queue.push(() => fn(commitedDocuments))
34
+ },
35
+
36
+ async commit (transaction) {
37
+ return queue.push(async () => {
38
+ const documentsClone = cloneDocuments(commitedDocuments)
39
+
40
+ for (const op of transaction.operations) {
41
+ await op(documentsClone)
42
+ }
43
+
44
+ for (const entitySet in documentsClone) {
45
+ for (const transactionEntity of documentsClone[entitySet]) {
46
+ const commitedEntity = commitedDocuments[entitySet].find(e => e._id)
47
+ if (commitedEntity &&
48
+ transactionEntity.$$etag !== commitedEntity.$$etag &&
49
+ commitedEntity.$$etag > transaction.beginTime
50
+ ) {
51
+ throw new Error(`Entity ${transactionEntity.name} was modified by another transaction`)
52
+ }
53
+ }
54
+ }
55
+
56
+ commitedDocuments = documentsClone
57
+ })
58
+ },
59
+
60
+ async rollback (transaction) {}
61
+ }
62
+ }
63
+
64
+ function cloneDocuments (obj) {
65
+ return Object.keys(obj).reduce((acu, setName) => {
66
+ acu[setName] = obj[setName].map((doc) => extend(true, {}, doc))
67
+ return acu
68
+ }, {})
69
+ }
@@ -1,180 +1,180 @@
1
-
2
- function getType (model, container, typeName, returnNormalizedTypeName) {
3
- const normalizedTypeName = typeName.replace(model.namespace + '.', '')
4
- const typeInfo = container[normalizedTypeName]
5
-
6
- if (!typeInfo) {
7
- return
8
- }
9
-
10
- if (returnNormalizedTypeName === true) {
11
- return normalizedTypeName
12
- }
13
-
14
- return typeInfo
15
- }
16
-
17
- function resolvePropDefinition (model, def) {
18
- const result = {}
19
- const collectionTypeRegExp = /^Collection\((\S+)\)$/
20
- const collectionMatchResult = collectionTypeRegExp.exec(def.type)
21
-
22
- if (def.type.startsWith('Edm')) {
23
- result.def = def
24
- } else if (collectionMatchResult != null && collectionMatchResult[1] != null) {
25
- const childType = collectionMatchResult[1]
26
-
27
- if (childType.startsWith('Edm')) {
28
- result.def = def
29
- result.subDef = { type: childType }
30
- } else {
31
- const subType = getType(model, model.complexTypes, childType)
32
-
33
- if (subType != null) {
34
- result.def = def
35
- result.subType = subType
36
- }
37
- }
38
- } else {
39
- const subType = getType(model, model.complexTypes, def.type)
40
-
41
- if (subType) {
42
- result.def = def
43
- result.subType = subType
44
- }
45
- }
46
-
47
- if (Object.keys(result).length === 0) {
48
- return
49
- }
50
-
51
- return result
52
- }
53
-
54
- const edmTypeToJSONSchema = {
55
- 'Edm.String': 'string',
56
- 'Edm.DateTimeOffset': { anyOf: [{ '$jsreport-stringToDate': true }, { '$jsreport-acceptsDate': true }] },
57
- 'Edm.Boolean': 'boolean',
58
- 'Edm.Int16': { type: 'integer', minimum: -32768, maximum: 32767 },
59
- 'Edm.Int32': { type: 'integer', minimum: -2147483648, maximum: 2147483647 },
60
- 'Edm.Double': 'number',
61
- 'Edm.Decimal': 'number',
62
- 'Edm.Binary': { anyOf: [{ type: 'null' }, { type: 'string' }, { '$jsreport-acceptsBuffer': true }] }
63
- }
64
-
65
- function typeDefToJSONSchema (model, def) {
66
- const jsonSchema = { type: 'object', properties: {} }
67
-
68
- if (def == null) {
69
- return
70
- }
71
-
72
- if (typeof def !== 'object' || Array.isArray(def)) {
73
- return
74
- }
75
-
76
- Object.keys(def).forEach((key) => {
77
- const propDef = def[key]
78
-
79
- if (propDef == null || propDef.type == null) {
80
- return
81
- }
82
-
83
- const extraSchema = propDef.schema
84
-
85
- const resolveResult = resolvePropDefinition(model, propDef)
86
-
87
- if (!resolveResult) {
88
- return
89
- }
90
-
91
- const isCollection = resolveResult.def.type.startsWith('Collection(')
92
-
93
- if (resolveResult.subType) {
94
- jsonSchema.properties[key] = typeDefToJSONSchema(model, resolveResult.subType)
95
- } else if (
96
- (isCollection && resolveResult.subType == null) ||
97
- (resolveResult.def.type.startsWith('Edm') && edmTypeToJSONSchema[resolveResult.def.type] != null)
98
- ) {
99
- let targetType = resolveResult.def.type
100
-
101
- if (isCollection && resolveResult.subType == null) {
102
- targetType = resolveResult.subDef.type
103
- }
104
-
105
- const value = edmTypeToJSONSchema[targetType]
106
-
107
- if (typeof value === 'string') {
108
- jsonSchema.properties[key] = { type: value }
109
- } else {
110
- jsonSchema.properties[key] = value
111
- }
112
- }
113
-
114
- if (isCollection) {
115
- jsonSchema.properties[key] = {
116
- type: 'array',
117
- items: jsonSchema.properties[key]
118
- }
119
- }
120
-
121
- if (extraSchema) {
122
- let originalType = jsonSchema.properties[key].type
123
- let newType = extraSchema.type
124
-
125
- if (originalType != null && newType != null) {
126
- if (!Array.isArray(originalType)) {
127
- originalType = [jsonSchema.properties[key].type]
128
- }
129
-
130
- if (!Array.isArray(newType)) {
131
- newType = [newType]
132
- }
133
-
134
- jsonSchema.properties[key] = {
135
- ...jsonSchema.properties[key],
136
- ...extraSchema,
137
- type: [...originalType, ...newType]
138
- }
139
- } else if (newType != null && originalType == null) {
140
- let newProperties = {}
141
-
142
- if (Array.isArray(jsonSchema.properties[key].anyOf)) {
143
- newProperties = {
144
- anyOf: [...jsonSchema.properties[key].anyOf, { type: newType }]
145
- }
146
- } else if (Array.isArray(jsonSchema.properties[key].allOf)) {
147
- newProperties = {
148
- allOf: [...jsonSchema.properties[key].allOf, { type: newType }]
149
- }
150
- } else if (Array.isArray(jsonSchema.properties[key].oneOf)) {
151
- newProperties = {
152
- oneOf: [...jsonSchema.properties[key].oneOf, { type: newType }]
153
- }
154
- }
155
-
156
- const copyExtraSchema = { ...extraSchema }
157
-
158
- delete copyExtraSchema.type
159
-
160
- jsonSchema.properties[key] = {
161
- ...jsonSchema.properties[key],
162
- ...copyExtraSchema,
163
- ...newProperties
164
- }
165
- } else {
166
- jsonSchema.properties[key] = Object.assign({}, jsonSchema.properties[key], extraSchema)
167
- }
168
- }
169
- })
170
-
171
- if (Object.keys(jsonSchema.properties).length === 0) {
172
- return
173
- }
174
-
175
- return jsonSchema
176
- }
177
-
178
- module.exports.getType = getType
179
- module.exports.resolvePropDefinition = resolvePropDefinition
180
- module.exports.typeDefToJSONSchema = typeDefToJSONSchema
1
+
2
+ function getType (model, container, typeName, returnNormalizedTypeName) {
3
+ const normalizedTypeName = typeName.replace(model.namespace + '.', '')
4
+ const typeInfo = container[normalizedTypeName]
5
+
6
+ if (!typeInfo) {
7
+ return
8
+ }
9
+
10
+ if (returnNormalizedTypeName === true) {
11
+ return normalizedTypeName
12
+ }
13
+
14
+ return typeInfo
15
+ }
16
+
17
+ function resolvePropDefinition (model, def) {
18
+ const result = {}
19
+ const collectionTypeRegExp = /^Collection\((\S+)\)$/
20
+ const collectionMatchResult = collectionTypeRegExp.exec(def.type)
21
+
22
+ if (def.type.startsWith('Edm')) {
23
+ result.def = def
24
+ } else if (collectionMatchResult != null && collectionMatchResult[1] != null) {
25
+ const childType = collectionMatchResult[1]
26
+
27
+ if (childType.startsWith('Edm')) {
28
+ result.def = def
29
+ result.subDef = { type: childType }
30
+ } else {
31
+ const subType = getType(model, model.complexTypes, childType)
32
+
33
+ if (subType != null) {
34
+ result.def = def
35
+ result.subType = subType
36
+ }
37
+ }
38
+ } else {
39
+ const subType = getType(model, model.complexTypes, def.type)
40
+
41
+ if (subType) {
42
+ result.def = def
43
+ result.subType = subType
44
+ }
45
+ }
46
+
47
+ if (Object.keys(result).length === 0) {
48
+ return
49
+ }
50
+
51
+ return result
52
+ }
53
+
54
+ const edmTypeToJSONSchema = {
55
+ 'Edm.String': 'string',
56
+ 'Edm.DateTimeOffset': { anyOf: [{ '$jsreport-stringToDate': true }, { '$jsreport-acceptsDate': true }] },
57
+ 'Edm.Boolean': 'boolean',
58
+ 'Edm.Int16': { type: 'integer', minimum: -32768, maximum: 32767 },
59
+ 'Edm.Int32': { type: 'integer', minimum: -2147483648, maximum: 2147483647 },
60
+ 'Edm.Double': 'number',
61
+ 'Edm.Decimal': 'number',
62
+ 'Edm.Binary': { anyOf: [{ type: 'null' }, { type: 'string' }, { '$jsreport-acceptsBuffer': true }] }
63
+ }
64
+
65
+ function typeDefToJSONSchema (model, def) {
66
+ const jsonSchema = { type: 'object', properties: {} }
67
+
68
+ if (def == null) {
69
+ return
70
+ }
71
+
72
+ if (typeof def !== 'object' || Array.isArray(def)) {
73
+ return
74
+ }
75
+
76
+ Object.keys(def).forEach((key) => {
77
+ const propDef = def[key]
78
+
79
+ if (propDef == null || propDef.type == null) {
80
+ return
81
+ }
82
+
83
+ const extraSchema = propDef.schema
84
+
85
+ const resolveResult = resolvePropDefinition(model, propDef)
86
+
87
+ if (!resolveResult) {
88
+ return
89
+ }
90
+
91
+ const isCollection = resolveResult.def.type.startsWith('Collection(')
92
+
93
+ if (resolveResult.subType) {
94
+ jsonSchema.properties[key] = typeDefToJSONSchema(model, resolveResult.subType)
95
+ } else if (
96
+ (isCollection && resolveResult.subType == null) ||
97
+ (resolveResult.def.type.startsWith('Edm') && edmTypeToJSONSchema[resolveResult.def.type] != null)
98
+ ) {
99
+ let targetType = resolveResult.def.type
100
+
101
+ if (isCollection && resolveResult.subType == null) {
102
+ targetType = resolveResult.subDef.type
103
+ }
104
+
105
+ const value = edmTypeToJSONSchema[targetType]
106
+
107
+ if (typeof value === 'string') {
108
+ jsonSchema.properties[key] = { type: value }
109
+ } else {
110
+ jsonSchema.properties[key] = value
111
+ }
112
+ }
113
+
114
+ if (isCollection) {
115
+ jsonSchema.properties[key] = {
116
+ type: 'array',
117
+ items: jsonSchema.properties[key]
118
+ }
119
+ }
120
+
121
+ if (extraSchema) {
122
+ let originalType = jsonSchema.properties[key].type
123
+ let newType = extraSchema.type
124
+
125
+ if (originalType != null && newType != null) {
126
+ if (!Array.isArray(originalType)) {
127
+ originalType = [jsonSchema.properties[key].type]
128
+ }
129
+
130
+ if (!Array.isArray(newType)) {
131
+ newType = [newType]
132
+ }
133
+
134
+ jsonSchema.properties[key] = {
135
+ ...jsonSchema.properties[key],
136
+ ...extraSchema,
137
+ type: [...originalType, ...newType]
138
+ }
139
+ } else if (newType != null && originalType == null) {
140
+ let newProperties = {}
141
+
142
+ if (Array.isArray(jsonSchema.properties[key].anyOf)) {
143
+ newProperties = {
144
+ anyOf: [...jsonSchema.properties[key].anyOf, { type: newType }]
145
+ }
146
+ } else if (Array.isArray(jsonSchema.properties[key].allOf)) {
147
+ newProperties = {
148
+ allOf: [...jsonSchema.properties[key].allOf, { type: newType }]
149
+ }
150
+ } else if (Array.isArray(jsonSchema.properties[key].oneOf)) {
151
+ newProperties = {
152
+ oneOf: [...jsonSchema.properties[key].oneOf, { type: newType }]
153
+ }
154
+ }
155
+
156
+ const copyExtraSchema = { ...extraSchema }
157
+
158
+ delete copyExtraSchema.type
159
+
160
+ jsonSchema.properties[key] = {
161
+ ...jsonSchema.properties[key],
162
+ ...copyExtraSchema,
163
+ ...newProperties
164
+ }
165
+ } else {
166
+ jsonSchema.properties[key] = Object.assign({}, jsonSchema.properties[key], extraSchema)
167
+ }
168
+ }
169
+ })
170
+
171
+ if (Object.keys(jsonSchema.properties).length === 0) {
172
+ return
173
+ }
174
+
175
+ return jsonSchema
176
+ }
177
+
178
+ module.exports.getType = getType
179
+ module.exports.resolvePropDefinition = resolvePropDefinition
180
+ module.exports.typeDefToJSONSchema = typeDefToJSONSchema