@manyos/smileconnect-api 1.71.8 → 1.72.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/conf/clients.json +27 -1
- package/docs/releases.md +3 -0
- package/package.json +1 -1
- package/util/config.js +123 -40
package/conf/clients.json
CHANGED
|
@@ -2693,7 +2693,33 @@
|
|
|
2693
2693
|
},
|
|
2694
2694
|
"scriptEndpoints": {
|
|
2695
2695
|
"personData": {
|
|
2696
|
-
"options": {
|
|
2696
|
+
"options": {
|
|
2697
|
+
"openAPISpec": {
|
|
2698
|
+
"summary": "Bla bla",
|
|
2699
|
+
"decription": "Bla bla bla bla bla",
|
|
2700
|
+
"requestSchema": {
|
|
2701
|
+
"type": "object",
|
|
2702
|
+
"properties": {
|
|
2703
|
+
"loginid": {
|
|
2704
|
+
"type": "string",
|
|
2705
|
+
"maxLength": 15,
|
|
2706
|
+
"description": "Login ID"
|
|
2707
|
+
}
|
|
2708
|
+
},
|
|
2709
|
+
"required": ["loginid"]
|
|
2710
|
+
},
|
|
2711
|
+
"responseSchema": {
|
|
2712
|
+
"type": "object",
|
|
2713
|
+
"properties": {
|
|
2714
|
+
"approver": {
|
|
2715
|
+
"type": "string",
|
|
2716
|
+
"description": "Approver username"
|
|
2717
|
+
}
|
|
2718
|
+
},
|
|
2719
|
+
"required": ["approver"]
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
},
|
|
2697
2723
|
"scripts": [
|
|
2698
2724
|
"script1_env",
|
|
2699
2725
|
"script1"
|
package/docs/releases.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
3
|
## API
|
|
4
|
+
### 1.72.0 - 13.11.25
|
|
5
|
+
Improve OpenAPI Documentation generation. Add requestBody for POST and put requests. Allow custom definition for scriptendpoints.
|
|
6
|
+
|
|
4
7
|
### 1.71.8 - 22.10.25
|
|
5
8
|
Fix error when include classAttributes was used in CI Search
|
|
6
9
|
|
package/package.json
CHANGED
package/util/config.js
CHANGED
|
@@ -11,6 +11,8 @@ const mappingUtil = require('../util/mappingUtil');
|
|
|
11
11
|
const CacheService = require ('../util/cache.service');
|
|
12
12
|
|
|
13
13
|
const CONSTANTS = require('./constants');
|
|
14
|
+
const {response} = require("express");
|
|
15
|
+
const {get} = require("mongoose");
|
|
14
16
|
|
|
15
17
|
const configFileCustomFormMapping = 'conf/customFormMapping.json';
|
|
16
18
|
|
|
@@ -396,11 +398,13 @@ async function getDesignPackage(clientId) {
|
|
|
396
398
|
if (clientObjectConfig.fields && clientObjectConfig.fields.length > 0){
|
|
397
399
|
const mapping = getDeprecatedMappingAsCustom(config.requestType)
|
|
398
400
|
schemas[config.requestType] = await getObjectSchema(clientObjectConfig.fields, mapping, config.forms.regular)
|
|
401
|
+
schemas[config.requestType+'_create_update'] = await getObjectSchema(clientObjectConfig.fields, mapping, config.forms.regular, true)
|
|
399
402
|
paths = {...paths, ... await getPathDef(config.assocTicketType, config.baseURI, config.requestType)}
|
|
400
403
|
}
|
|
401
404
|
if (config.requestTypeWorkLog && clientConfig[config.requestTypeWorkLog].fields && clientConfig[config.requestTypeWorkLog].fields.length > 0) {
|
|
402
405
|
const mapping = getDeprecatedMappingAsCustom(config.requestTypeWorkLog)
|
|
403
406
|
schemas[config.requestTypeWorkLog] = await getObjectSchema(clientConfig[config.requestTypeWorkLog].fields, mapping, config.forms.workLog)
|
|
407
|
+
schemas[config.requestTypeWorkLog + '_create_update'] = await getObjectSchema(clientConfig[config.requestTypeWorkLog].fields, mapping, config.forms.workLog, true)
|
|
404
408
|
paths = {...paths, ... await getPathDef(config.assocTicketType, config.baseURI + '/{ticketId}/worklogs', config.requestTypeWorkLog, true, true)}
|
|
405
409
|
}
|
|
406
410
|
if (config.requestTemplate && clientConfig[config.requestTemplate].fields && clientConfig[config.requestTemplate].fields.length > 0) {
|
|
@@ -454,7 +458,8 @@ async function getDesignPackage(clientId) {
|
|
|
454
458
|
const clientObjectConfig = clientConfig[`custom_${formName}`]
|
|
455
459
|
log.debug('key', key, clientObjectConfig)
|
|
456
460
|
if (clientObjectConfig) {
|
|
457
|
-
schemas[key] = await getObjectSchema(clientObjectConfig.fields, customFormMappings[key].mapping, formName)
|
|
461
|
+
schemas[key] = await getObjectSchema(clientObjectConfig.fields, customFormMappings[key].mapping, formName);
|
|
462
|
+
schemas[key+'_create_update'] = await getObjectSchema(clientObjectConfig.fields, customFormMappings[key].mapping, formName, true);
|
|
458
463
|
paths = {...paths, ... await getPathDef(key, '/v1/customForms/' + key, key)}
|
|
459
464
|
}
|
|
460
465
|
}
|
|
@@ -465,18 +470,21 @@ async function getDesignPackage(clientId) {
|
|
|
465
470
|
const scriptKeys = Object.keys(clientConfig.scriptEndpoints)
|
|
466
471
|
for (let x=0; x < scriptKeys.length; x++) {
|
|
467
472
|
const key = scriptKeys[x]
|
|
473
|
+
const endpointConfig = clientConfig.scriptEndpoints[key];
|
|
474
|
+
const openAPISpec = endpointConfig.options.openAPISpec;
|
|
468
475
|
log.debug('key', key)
|
|
469
|
-
//schemas[key] = await getObjectSchema(clientObjectConfig.fields, customFormMappings[key].mapping, formName)
|
|
470
476
|
const pathDef = {}
|
|
471
477
|
pathDef[`/v1/scriptEndpoints/${key}`] = {};
|
|
472
478
|
pathDef[`/v1/scriptEndpoints/${key}`].post = {
|
|
473
479
|
tags: [key],
|
|
474
|
-
summary: `Run scripts associated with this endpoint`,
|
|
475
|
-
description: "Run scripts associated that are associated with this endpoint. The return Schema is defined in the scripts.",
|
|
480
|
+
summary: openAPISpec.summary || `Run scripts associated with this endpoint`,
|
|
481
|
+
description: openAPISpec.decription || "Run scripts associated that are associated with this endpoint. The return Schema is defined in the scripts.",
|
|
476
482
|
parameters: [],
|
|
477
|
-
responses: await getApiResponse("scriptEndpoint_" + key, true)
|
|
483
|
+
responses: await getApiResponse("scriptEndpoint_" + key, true),
|
|
484
|
+
requestBody: await getApiRequestBody("scriptEndpoint_" + key)
|
|
478
485
|
}
|
|
479
|
-
schemas["scriptEndpoint_" + key] = {};
|
|
486
|
+
schemas["scriptEndpoint_" + key] = openAPISpec.responseSchema || {};
|
|
487
|
+
schemas["scriptEndpoint_" + key + '_create_update'] = openAPISpec.requestSchema || {};
|
|
480
488
|
paths = {...paths, ... pathDef}
|
|
481
489
|
}
|
|
482
490
|
}
|
|
@@ -486,6 +494,7 @@ async function getDesignPackage(clientId) {
|
|
|
486
494
|
|
|
487
495
|
if (clientConfig.cmdbobject && clientConfig.cmdbobject.fields) {
|
|
488
496
|
schemas['cmdbobject'] = await getObjectSchema(clientConfig.cmdbobject.fields, cmdbMapping, 'AST:BaseElement')
|
|
497
|
+
schemas['cmdbobject_create_update'] = await getObjectSchema(clientConfig.cmdbobject.fields, cmdbMapping, 'AST:BaseElement', true)
|
|
489
498
|
|
|
490
499
|
|
|
491
500
|
const cmdbdef = Object.keys(clientConfig.cmdbobject)
|
|
@@ -505,6 +514,10 @@ async function getDesignPackage(clientId) {
|
|
|
505
514
|
required: schemas['cmdbobject'].required.concat(classSchema.required),
|
|
506
515
|
properties: {...schemas['cmdbobject'].properties, ...classSchema.properties}
|
|
507
516
|
}
|
|
517
|
+
schemas[`${schemaName}_create_update`] = {
|
|
518
|
+
required: schemas['cmdbobject'].required.concat(classSchema.required),
|
|
519
|
+
properties: {...schemas['cmdbobject'].properties, ...classSchema.properties}
|
|
520
|
+
}
|
|
508
521
|
log.debug('customForm', formName, fields, classMapping, classSchema)
|
|
509
522
|
}
|
|
510
523
|
|
|
@@ -551,7 +564,7 @@ async function getPathDef(objectName, baseUri, schema, isSubTicket, suppressUpda
|
|
|
551
564
|
tags: tag,
|
|
552
565
|
summary: `Get a single ${objectName} object by id`,
|
|
553
566
|
description: "A single object is returned in the data attribute",
|
|
554
|
-
parameters:
|
|
567
|
+
parameters: getOpenApiParameters('get'),
|
|
555
568
|
responses: await getApiResponse(schema, true)
|
|
556
569
|
}
|
|
557
570
|
}
|
|
@@ -560,8 +573,9 @@ async function getPathDef(objectName, baseUri, schema, isSubTicket, suppressUpda
|
|
|
560
573
|
tags: tag,
|
|
561
574
|
summary: `Update an object of type ${objectName}`,
|
|
562
575
|
description: "A single object is returned in the data attribute",
|
|
563
|
-
parameters:
|
|
564
|
-
responses: await getApiResponse(schema, true)
|
|
576
|
+
parameters: getOpenApiParameters('put'),
|
|
577
|
+
responses: await getApiResponse(schema, true),
|
|
578
|
+
requestBody: await getApiRequestBody(schema)
|
|
565
579
|
}
|
|
566
580
|
}
|
|
567
581
|
|
|
@@ -570,7 +584,7 @@ async function getPathDef(objectName, baseUri, schema, isSubTicket, suppressUpda
|
|
|
570
584
|
tags: tag,
|
|
571
585
|
summary: `Get a list of object of type ${objectName}`,
|
|
572
586
|
description: "An array ob objects is returned in the data attribute",
|
|
573
|
-
parameters:
|
|
587
|
+
parameters: getOpenApiParameters('getAll'),
|
|
574
588
|
responses: await getApiResponse(schema, false)
|
|
575
589
|
}
|
|
576
590
|
}
|
|
@@ -579,8 +593,9 @@ async function getPathDef(objectName, baseUri, schema, isSubTicket, suppressUpda
|
|
|
579
593
|
tags: tag,
|
|
580
594
|
summary: `Create a new object of type ${objectName}`,
|
|
581
595
|
description: "A single object is returned in the data attribute",
|
|
582
|
-
parameters:
|
|
583
|
-
responses: await getApiResponse(schema, false)
|
|
596
|
+
parameters: getOpenApiParameters('post'),
|
|
597
|
+
responses: await getApiResponse(schema, false),
|
|
598
|
+
requestBody: await getApiRequestBody(schema)
|
|
584
599
|
}
|
|
585
600
|
}
|
|
586
601
|
if (isSubTicket) {
|
|
@@ -589,6 +604,43 @@ async function getPathDef(objectName, baseUri, schema, isSubTicket, suppressUpda
|
|
|
589
604
|
return pathDef
|
|
590
605
|
}
|
|
591
606
|
|
|
607
|
+
function getOpenApiParameters(operation) {
|
|
608
|
+
const parameters = [
|
|
609
|
+
{
|
|
610
|
+
"examples": {
|
|
611
|
+
"sample": {
|
|
612
|
+
"value": "user123"
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
"name": "impersonateUser",
|
|
616
|
+
"description": "If the clientConfig has the option allowDynamicImpersonate set to *true* then the URL Parameter *impersonateUser* can be used to determine the used Remedy User.",
|
|
617
|
+
"schema": {
|
|
618
|
+
"type": "string"
|
|
619
|
+
},
|
|
620
|
+
"in": "query",
|
|
621
|
+
"required": false
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
"examples": {
|
|
625
|
+
"include": {
|
|
626
|
+
"value": "ciRelations,ticketRelations"
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
"name": "include",
|
|
630
|
+
"description": "Defines if and which related objects shoudl be included.\nPossible values:\nciRelations,ticketRelations,personRelations,organisationRelations,supportGroupRelations,persons,supportGroups,organisations,cmdbObjects,incidents,workOrders,changes, problems",
|
|
631
|
+
"schema": {
|
|
632
|
+
"type": "array",
|
|
633
|
+
"items": {
|
|
634
|
+
"type": "string"
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
"in": "query",
|
|
638
|
+
"required": false
|
|
639
|
+
}
|
|
640
|
+
]
|
|
641
|
+
return parameters;
|
|
642
|
+
}
|
|
643
|
+
|
|
592
644
|
async function getApiResponse(schema, single) {
|
|
593
645
|
let dataValue = {
|
|
594
646
|
"$ref": `#/components/schemas/${schema}`
|
|
@@ -628,7 +680,35 @@ async function getApiResponse(schema, single) {
|
|
|
628
680
|
return responses
|
|
629
681
|
}
|
|
630
682
|
|
|
631
|
-
async function
|
|
683
|
+
async function getApiRequestBody(schema) {
|
|
684
|
+
let dataValue = {
|
|
685
|
+
"$ref": `#/components/schemas/${schema}_create_update`
|
|
686
|
+
}
|
|
687
|
+
if (Array.isArray(schema)) {
|
|
688
|
+
dataValue = {
|
|
689
|
+
oneOf: schema.map(item => {
|
|
690
|
+
return {
|
|
691
|
+
"$ref": `#/components/schemas/${item}_create_update`
|
|
692
|
+
}
|
|
693
|
+
})
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return requestBody = {
|
|
697
|
+
content: {
|
|
698
|
+
"application/json": {
|
|
699
|
+
schema: {
|
|
700
|
+
type: "object",
|
|
701
|
+
properties: {
|
|
702
|
+
data: dataValue
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
required: true
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
async function getObjectSchema(clientFields, mapping, formName, isCreateUpdate = false) {
|
|
632
712
|
const fields = await getFields(formName)
|
|
633
713
|
const required = []
|
|
634
714
|
const properties = {}
|
|
@@ -638,37 +718,40 @@ async function getObjectSchema(clientFields, mapping, formName) {
|
|
|
638
718
|
const fieldDef = {}
|
|
639
719
|
const fieldDetails = fields.find(item => item.name === field)
|
|
640
720
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
if (fieldDetails
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
fieldDef.maxLength = fieldDetails.fieldLimit.maxLength
|
|
648
|
-
}
|
|
649
|
-
if (fieldDetails.type === 'SelectionField') {
|
|
650
|
-
fieldDef.type = 'string'
|
|
651
|
-
if (fieldDetails.fieldLimit && fieldDetails.fieldLimit.values) {
|
|
652
|
-
const enumVals = fieldDetails.fieldLimit.values.map(item => item.enumItemName)
|
|
653
|
-
fieldDef.enum = enumVals
|
|
654
|
-
} else if (fieldDetails.fieldLimit && fieldDetails.fieldLimit.valueMapping) {
|
|
655
|
-
const enumVals = Object.values(fieldDetails.fieldLimit.valueMapping)
|
|
656
|
-
fieldDef.enum = enumVals
|
|
721
|
+
// remove id field from create/update schema
|
|
722
|
+
if (!isCreateUpdate || mappedName !== 'id') {
|
|
723
|
+
if (fieldDetails) {
|
|
724
|
+
fieldDef.type = fieldDetails.type
|
|
725
|
+
if (fieldDetails.entryMode === 'Required') {
|
|
726
|
+
required.push(mappedName)
|
|
657
727
|
}
|
|
728
|
+
if(fieldDetails.fieldLimit) {
|
|
729
|
+
fieldDef.maxLength = fieldDetails.fieldLimit.maxLength
|
|
730
|
+
}
|
|
731
|
+
if (fieldDetails.type === 'SelectionField') {
|
|
732
|
+
fieldDef.type = 'string'
|
|
733
|
+
if (fieldDetails.fieldLimit && fieldDetails.fieldLimit.values) {
|
|
734
|
+
const enumVals = fieldDetails.fieldLimit.values.map(item => item.enumItemName)
|
|
735
|
+
fieldDef.enum = enumVals
|
|
736
|
+
} else if (fieldDetails.fieldLimit && fieldDetails.fieldLimit.valueMapping) {
|
|
737
|
+
const enumVals = Object.values(fieldDetails.fieldLimit.valueMapping)
|
|
738
|
+
fieldDef.enum = enumVals
|
|
739
|
+
}
|
|
658
740
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
741
|
+
} else if (fieldDetails.type === 'CharacterField') {
|
|
742
|
+
fieldDef.type = 'string'
|
|
743
|
+
} else if (fieldDetails.type === 'DateTimeField') {
|
|
744
|
+
fieldDef.type = 'string'
|
|
745
|
+
fieldDef.format = 'date-time'
|
|
746
|
+
} else if (fieldDetails.type === 'DateField') {
|
|
747
|
+
fieldDef.format = 'date'
|
|
748
|
+
} else if (fieldDetails.type === 'DecimalField') {
|
|
749
|
+
fieldDef.type = 'number'
|
|
750
|
+
}
|
|
751
|
+
//fieldDef.details = fieldDetails
|
|
668
752
|
}
|
|
669
|
-
|
|
753
|
+
properties[mappedName] = fieldDef
|
|
670
754
|
}
|
|
671
|
-
properties[mappedName] = fieldDef
|
|
672
755
|
})
|
|
673
756
|
//mappedFields.push(fields)
|
|
674
757
|
return {required, properties}
|