@manyos/smileconnect-api 1.52.4 → 1.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  ### STAGE 1: Build ###
2
2
 
3
3
  # We label our stage as 'builder'
4
- FROM node:12.14 as builder
4
+ FROM node:16 as builder
5
5
  ARG NPM_TOKEN
6
6
  COPY package.json package-lock.json ./
7
7
 
package/app.js CHANGED
@@ -184,8 +184,12 @@ app.use('/v1/health', function (req, res, next) {
184
184
  //health check
185
185
  app.use('/v1/openapi/:clientId', async function (req, res, next) {
186
186
  const clientId = req.params.clientId;
187
- const spec = await config.getDesignPackage(clientId)
188
- res.json(spec)
187
+ try {
188
+ const spec = await config.getDesignPackage(clientId)
189
+ res.json(spec)
190
+ } catch (error) {
191
+ next(error)
192
+ }
189
193
  })
190
194
 
191
195
  const maxFilesize = process.env.MAX_FILESIZE || 5;
package/docs/releases.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  ## API
4
4
 
5
+ ### 1.53.0 - 17.11.11
6
+ Update NodeJs to v16
7
+
5
8
  ### 1.52.4 - 17.11.11
6
9
  Fix issue: Keep invisible ServiceCi Relation in Tickets during CI Relation Update
7
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manyos/smileconnect-api",
3
- "version": "1.52.4",
3
+ "version": "1.53.0",
4
4
  "description": "A proxy and abstraction layer for BMCs IT Service Management Suite",
5
5
  "main": "app.js",
6
6
  "scripts": {
package/util/config.js CHANGED
@@ -330,28 +330,34 @@ async function getDesignPackage(clientId) {
330
330
  const clientConfig = await getClientConfig(clientId)
331
331
  const schemas = {}
332
332
  let paths = {}
333
+
334
+ //generate docs for normal tickets
333
335
  const keys = Object.keys(ticketConfig)
336
+
334
337
  for (let x=0; x<keys.length; x++) {
335
338
  const key = keys[x]
336
339
  const config = ticketConfig[key]
337
340
  const clientObjectConfig = clientConfig[config.requestType]
338
341
  if (clientObjectConfig) {
339
- {
342
+ if (clientObjectConfig.fields && clientObjectConfig.fields.length > 0){
340
343
  const mapping = getDeprecatedMappingAsCustom(config.requestType)
341
- schemas[config.requestType] = await getObjectSchema(clientObjectConfig, mapping, config.forms.regular)
344
+ schemas[config.requestType] = await getObjectSchema(clientObjectConfig.fields, mapping, config.forms.regular)
342
345
  paths = {...paths, ... await getPathDef(config.assocTicketType, config.baseURI, config.requestType)}
343
346
  }
344
- if (config.requestTypeWorkLog) {
347
+ if (config.requestTypeWorkLog && clientConfig[config.requestTypeWorkLog].fields && clientConfig[config.requestTypeWorkLog].fields.length > 0) {
345
348
  const mapping = getDeprecatedMappingAsCustom(config.requestTypeWorkLog)
346
- schemas[config.requestTypeWorkLog] = await getObjectSchema(clientConfig[config.requestTypeWorkLog], mapping, config.forms.workLog)
349
+ schemas[config.requestTypeWorkLog] = await getObjectSchema(clientConfig[config.requestTypeWorkLog].fields, mapping, config.forms.workLog)
347
350
  paths = {...paths, ... await getPathDef(config.assocTicketType, config.baseURI + '/{ticketId}/worklogs', config.requestTypeWorkLog, true, true)}
348
351
  }
349
- if (config.requestTemplate) {
352
+ if (config.requestTemplate && clientConfig[config.requestTemplate].fields && clientConfig[config.requestTemplate].fields.length > 0) {
350
353
  const mapping = getDeprecatedMappingAsCustom(config.requestTemplate)
351
- schemas[config.requestTemplate] = await getObjectSchema(clientConfig[config.requestTemplate], mapping, config.forms.template)
354
+ schemas[config.requestTemplate] = await getObjectSchema(clientConfig[config.requestTemplate].fields, mapping, config.forms.template)
352
355
  }
353
356
  }
354
357
  }
358
+
359
+
360
+ //generate docs for custom Forms
355
361
  const customFormMappings = await getCustomFormMapping()
356
362
  const customKeys = Object.keys(customFormMappings)
357
363
  for (let x=0; x<customKeys.length; x++) {
@@ -360,14 +366,51 @@ async function getDesignPackage(clientId) {
360
366
  const clientObjectConfig = clientConfig[`custom_${formName}`]
361
367
  log.debug('key', key, clientObjectConfig)
362
368
  if (clientObjectConfig) {
363
- schemas[key] = await getObjectSchema(clientObjectConfig, customFormMappings[key].mapping, formName)
369
+ schemas[key] = await getObjectSchema(clientObjectConfig.fields, customFormMappings[key].mapping, formName)
364
370
  paths = {...paths, ... await getPathDef(key, '/v1/customForms/' + key, key)}
365
371
  }
366
372
  }
373
+
374
+
375
+ //generate docs for cmdb
376
+ const cmdbMapping = getDeprecatedMappingAsCustom('cmdbobject')
377
+
378
+ if (clientConfig.cmdbobject && clientConfig.cmdbobject.fields) {
379
+ schemas['cmdbobject'] = await getObjectSchema(clientConfig.cmdbobject.fields, cmdbMapping, 'AST:BaseElement')
380
+
381
+
382
+ const cmdbdef = Object.keys(clientConfig.cmdbobject)
383
+ const classConfigs = cmdbdef.filter(item => item.startsWith('fields_'))
384
+ const cmdbSchemaList = ['cmdbobject']
385
+ for (let x=0; x<classConfigs.length; x++) {
386
+ const classConfig = classConfigs[x]
387
+ const formName = classConfig.replace('fields_', '')
388
+ const fields = clientConfig.cmdbobject[classConfig]
389
+ const classMapping = getDeprecatedMappingAsCustom(`cmdbobject_${formName}`)
390
+ const classSchema = await getObjectSchema(fields, classMapping, formName)
391
+ let schemaName = `cmdbobject_${formName}`
392
+ schemaName = schemaName.replaceAll(':','_')
393
+ schemaName = schemaName.replaceAll(' ','_')
394
+ cmdbSchemaList.push(schemaName)
395
+ schemas[schemaName] = {
396
+ required: schemas['cmdbobject'].required.concat(classSchema.required),
397
+ properties: {...schemas['cmdbobject'].properties, ...classSchema.properties}
398
+ }
399
+ log.debug('customForm', formName, fields, classMapping, classSchema)
400
+ }
401
+
402
+ paths = {...paths, ... await getPathDef('cmdbobject', '/v1/cmdbobjects', cmdbSchemaList)}
403
+ }
404
+
367
405
  return {openapi: "3.0.1", info, servers, paths, components: {schemas}}
368
406
  }
369
407
 
370
- async function getPathDef(objectName, baseUri, tag, isSubTicket, suppressUpdate, suppressCreate) {
408
+ async function getPathDef(objectName, baseUri, schema, isSubTicket, suppressUpdate, suppressCreate) {
409
+ let tag = [schema]
410
+ if (Array.isArray(schema)) {
411
+ tag = schema
412
+ }
413
+
371
414
  const ticketIdParam = {
372
415
  name: "ticketId",
373
416
  description: "id of the parent object to retrieve",
@@ -396,39 +439,39 @@ async function getPathDef(objectName, baseUri, tag, isSubTicket, suppressUpdate,
396
439
  pathDef[`${baseUri}/{id}`] = {
397
440
  parameters,
398
441
  get: {
399
- tags: [tag],
442
+ tags: tag,
400
443
  summary: `Get a single ${objectName} object by id`,
401
444
  description: "A single object is returned in the data attribute",
402
445
  parameters: [],
403
- responses: await getApiResponse(tag, true)
446
+ responses: await getApiResponse(schema, true)
404
447
  }
405
448
  }
406
449
  if (!suppressUpdate) {
407
450
  pathDef[`${baseUri}/{id}`].put = {
408
- tags: [tag],
451
+ tags: tag,
409
452
  summary: `Update an object of type ${objectName}`,
410
453
  description: "A single object is returned in the data attribute",
411
454
  parameters: [],
412
- responses: await getApiResponse(tag, false)
455
+ responses: await getApiResponse(schema, false)
413
456
  }
414
457
  }
415
458
 
416
459
  pathDef[`${baseUri}`] = {
417
460
  get: {
418
- tags: [tag],
461
+ tags: tag,
419
462
  summary: `Get a list of object of type ${objectName}`,
420
463
  description: "An array ob objects is returned in the data attribute",
421
464
  parameters: [],
422
- responses: await getApiResponse(tag, false)
465
+ responses: await getApiResponse(schema, false)
423
466
  }
424
467
  }
425
468
  if (!suppressCreate) {
426
469
  pathDef[`${baseUri}`].post = {
427
- tags: [tag],
470
+ tags: tag,
428
471
  summary: `Create a new object of type ${objectName}`,
429
472
  description: "A single object is returned in the data attribute",
430
473
  parameters: [],
431
- responses: await getApiResponse(tag, false)
474
+ responses: await getApiResponse(schema, false)
432
475
  }
433
476
  }
434
477
  if (isSubTicket) {
@@ -438,6 +481,18 @@ async function getPathDef(objectName, baseUri, tag, isSubTicket, suppressUpdate,
438
481
  }
439
482
 
440
483
  async function getApiResponse(schema, single) {
484
+ let dataValue = {
485
+ "$ref": `#/components/schemas/${schema}`
486
+ }
487
+ if (Array.isArray(schema)) {
488
+ dataValue = {
489
+ oneOf: schema.map(item => {
490
+ return {
491
+ "$ref": `#/components/schemas/${item}`
492
+ }
493
+ })
494
+ }
495
+ }
441
496
  responses = {
442
497
  "200": {
443
498
  description: "successful operation",
@@ -456,24 +511,20 @@ async function getApiResponse(schema, single) {
456
511
  if (!single) {
457
512
  responses["200"].content["application/json"].schema.properties.data = {
458
513
  type: "array",
459
- items: {
460
- "$ref": `#/components/schemas/${schema}`
461
- }
514
+ items: dataValue
462
515
  }
463
516
  } else {
464
- responses["200"].content["application/json"].schema.properties.data = {
465
- "$ref": `#/components/schemas/${schema}`
466
- }
517
+ responses["200"].content["application/json"].schema.properties.data = dataValue
467
518
  }
468
519
  return responses
469
520
  }
470
521
 
471
- async function getObjectSchema(clientObjectConfig, mapping, formName) {
522
+ async function getObjectSchema(clientFields, mapping, formName) {
472
523
  const fields = await getFields(formName)
473
524
  const required = []
474
525
  const properties = {}
475
- log.debug('clientObjConf', clientObjectConfig)
476
- clientObjectConfig.fields.forEach(field => {
526
+ log.debug('clientFields', clientFields, mapping, formName)
527
+ clientFields.forEach(field => {
477
528
  const mappedName = mapping[field]
478
529
  const fieldDef = {}
479
530
  const fieldDetails = fields.find(item => item.name === field)