@jsreport/jsreport-core 3.0.1 → 3.1.2-test.2

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 -284
  3. package/index.js +29 -27
  4. package/lib/main/blobStorage/blobStorage.js +52 -47
  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 -265
  11. package/lib/main/extensions/fileUtils.js +56 -55
  12. package/lib/main/extensions/findVersion.js +49 -53
  13. package/lib/main/extensions/locationCache.js +103 -97
  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 -210
  24. package/lib/main/migration/xlsxTemplatesToAssets.js +128 -118
  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 +579 -578
  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 -0
  53. package/lib/shared/normalizeMetaFromLogs.js +30 -30
  54. package/lib/shared/reporter.js +123 -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 +207 -200
  66. package/lib/worker/render/htmlRecipe.js +10 -10
  67. package/lib/worker/render/moduleHelper.js +43 -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 +205 -209
  71. package/lib/worker/render/resolveReferences.js +60 -60
  72. package/lib/worker/reporter.js +191 -187
  73. package/lib/worker/sandbox/runInSandbox.js +13 -4
  74. package/lib/worker/sandbox/safeSandbox.js +828 -822
  75. package/lib/worker/templates.js +78 -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
@@ -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