@microsoft/m365-spec-parser 0.2.3 → 0.2.4-alpha.e84e1682b.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/dist/index.esm2017.js +302 -247
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +355 -282
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +302 -247
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +355 -282
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardGenerator.d.ts +5 -3
- package/dist/src/constants.d.ts +3 -1
- package/dist/src/interfaces.d.ts +2 -3
- package/dist/src/jsonDataGenerator.d.ts +6 -0
- package/dist/src/utils.d.ts +4 -4
- package/package.json +3 -3
package/dist/index.esm2017.mjs
CHANGED
|
@@ -38,11 +38,8 @@ var ErrorType;
|
|
|
38
38
|
ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
|
|
39
39
|
ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
|
|
40
40
|
ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
|
|
41
|
-
ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
|
|
42
41
|
ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
|
|
43
42
|
ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
|
|
44
|
-
ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
|
|
45
|
-
ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
|
|
46
43
|
ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
|
|
47
44
|
ErrorType["NoParameter"] = "no-parameter";
|
|
48
45
|
ErrorType["NoAPIInfo"] = "no-api-info";
|
|
@@ -61,6 +58,8 @@ var WarningType;
|
|
|
61
58
|
WarningType["OperationOnlyContainsOptionalParam"] = "operation-only-contains-optional-param";
|
|
62
59
|
WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
|
|
63
60
|
WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
|
|
61
|
+
WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
|
|
62
|
+
WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
|
|
64
63
|
WarningType["Unknown"] = "unknown";
|
|
65
64
|
})(WarningType || (WarningType = {}));
|
|
66
65
|
/**
|
|
@@ -98,15 +97,17 @@ ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converte
|
|
|
98
97
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
99
98
|
ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
|
|
100
99
|
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
100
|
+
ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
|
|
101
101
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
102
102
|
ConstantString.FuncDescriptionTooLong = "The description of the function '%s' is too long. The current length is %s characters, while the maximum allowed length is %s characters.";
|
|
103
|
+
ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
|
|
103
104
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
104
105
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
105
106
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
106
107
|
ConstantString.GetMethod = "get";
|
|
107
108
|
ConstantString.PostMethod = "post";
|
|
108
109
|
ConstantString.AdaptiveCardVersion = "1.5";
|
|
109
|
-
ConstantString.AdaptiveCardSchema = "
|
|
110
|
+
ConstantString.AdaptiveCardSchema = "https://adaptivecards.io/schemas/adaptive-card.json";
|
|
110
111
|
ConstantString.AdaptiveCardType = "AdaptiveCard";
|
|
111
112
|
ConstantString.TextBlockType = "TextBlock";
|
|
112
113
|
ConstantString.ImageType = "Image";
|
|
@@ -193,16 +194,8 @@ class SpecParserError extends Error {
|
|
|
193
194
|
|
|
194
195
|
// Copyright (c) Microsoft Corporation.
|
|
195
196
|
class Utils {
|
|
196
|
-
static
|
|
197
|
-
|
|
198
|
-
for (const property in schema.properties) {
|
|
199
|
-
const nestedSchema = schema.properties[property];
|
|
200
|
-
if (nestedSchema.type === "object") {
|
|
201
|
-
return true;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return false;
|
|
197
|
+
static isObjectSchema(schema) {
|
|
198
|
+
return schema.type === "object" || (!schema.type && !!schema.properties);
|
|
206
199
|
}
|
|
207
200
|
static containMultipleMediaTypes(bodyObject) {
|
|
208
201
|
return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
|
|
@@ -270,27 +263,33 @@ class Utils {
|
|
|
270
263
|
let multipleMediaType = false;
|
|
271
264
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
272
265
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
273
|
-
if (responseObject
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
else {
|
|
286
|
-
return { json, multipleMediaType };
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
266
|
+
if (!responseObject) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
multipleMediaType = Utils.containMultipleMediaTypes(responseObject);
|
|
270
|
+
if (!allowMultipleMediaType && multipleMediaType) {
|
|
271
|
+
json = {};
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const mediaObj = Utils.getJsonContentType(responseObject);
|
|
275
|
+
if (Object.keys(mediaObj).length > 0) {
|
|
276
|
+
json = mediaObj;
|
|
277
|
+
return { json, multipleMediaType };
|
|
290
278
|
}
|
|
291
279
|
}
|
|
292
280
|
return { json, multipleMediaType };
|
|
293
281
|
}
|
|
282
|
+
static getJsonContentType(responseObject) {
|
|
283
|
+
if (responseObject.content) {
|
|
284
|
+
for (const contentType of Object.keys(responseObject.content)) {
|
|
285
|
+
// json media type can also be "application/json; charset=utf-8"
|
|
286
|
+
if (contentType.indexOf("application/json") >= 0) {
|
|
287
|
+
return responseObject.content[contentType];
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return {};
|
|
292
|
+
}
|
|
294
293
|
static convertPathToCamelCase(path) {
|
|
295
294
|
const pathSegments = path.split(/[./{]/);
|
|
296
295
|
const camelCaseSegments = pathSegments.map((segment) => {
|
|
@@ -326,7 +325,7 @@ class Utils {
|
|
|
326
325
|
}
|
|
327
326
|
return newStr;
|
|
328
327
|
}
|
|
329
|
-
static checkServerUrl(servers) {
|
|
328
|
+
static checkServerUrl(servers, allowHttp = false) {
|
|
330
329
|
const errors = [];
|
|
331
330
|
let serverUrl;
|
|
332
331
|
try {
|
|
@@ -349,8 +348,7 @@ class Utils {
|
|
|
349
348
|
data: servers,
|
|
350
349
|
});
|
|
351
350
|
}
|
|
352
|
-
else if (protocol !== "https:") {
|
|
353
|
-
// Http server url is not supported
|
|
351
|
+
else if (protocol !== "https:" && !(protocol === "http:" && allowHttp)) {
|
|
354
352
|
const protocolString = protocol.slice(0, -1);
|
|
355
353
|
errors.push({
|
|
356
354
|
type: ErrorType.UrlProtocolNotSupported,
|
|
@@ -366,10 +364,11 @@ class Utils {
|
|
|
366
364
|
let hasTopLevelServers = false;
|
|
367
365
|
let hasPathLevelServers = false;
|
|
368
366
|
let hasOperationLevelServers = false;
|
|
367
|
+
const allowHttp = options.projectType === ProjectType.Copilot;
|
|
369
368
|
if (spec.servers && spec.servers.length >= 1) {
|
|
370
369
|
hasTopLevelServers = true;
|
|
371
370
|
// for multiple server, we only use the first url
|
|
372
|
-
const serverErrors = Utils.checkServerUrl(spec.servers);
|
|
371
|
+
const serverErrors = Utils.checkServerUrl(spec.servers, allowHttp);
|
|
373
372
|
errors.push(...serverErrors);
|
|
374
373
|
}
|
|
375
374
|
const paths = spec.paths;
|
|
@@ -377,7 +376,7 @@ class Utils {
|
|
|
377
376
|
const methods = paths[path];
|
|
378
377
|
if ((methods === null || methods === void 0 ? void 0 : methods.servers) && methods.servers.length >= 1) {
|
|
379
378
|
hasPathLevelServers = true;
|
|
380
|
-
const serverErrors = Utils.checkServerUrl(methods.servers);
|
|
379
|
+
const serverErrors = Utils.checkServerUrl(methods.servers, allowHttp);
|
|
381
380
|
errors.push(...serverErrors);
|
|
382
381
|
}
|
|
383
382
|
for (const method in methods) {
|
|
@@ -385,7 +384,7 @@ class Utils {
|
|
|
385
384
|
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
386
385
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
387
386
|
hasOperationLevelServers = true;
|
|
388
|
-
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
387
|
+
const serverErrors = Utils.checkServerUrl(operationObject.servers, allowHttp);
|
|
389
388
|
errors.push(...serverErrors);
|
|
390
389
|
}
|
|
391
390
|
}
|
|
@@ -432,7 +431,7 @@ class Utils {
|
|
|
432
431
|
optionalParams.push(parameter);
|
|
433
432
|
}
|
|
434
433
|
}
|
|
435
|
-
else if (schema
|
|
434
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
436
435
|
const { properties } = schema;
|
|
437
436
|
for (const property in properties) {
|
|
438
437
|
let isRequired = false;
|
|
@@ -546,29 +545,6 @@ class Utils {
|
|
|
546
545
|
const serverUrl = operationServer || methodServer || rootServer;
|
|
547
546
|
return serverUrl;
|
|
548
547
|
}
|
|
549
|
-
static limitACBodyProperties(body, maxCount) {
|
|
550
|
-
const result = [];
|
|
551
|
-
let currentCount = 0;
|
|
552
|
-
for (const element of body) {
|
|
553
|
-
if (element.type === ConstantString.ContainerType) {
|
|
554
|
-
const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
|
|
555
|
-
result.push({
|
|
556
|
-
type: ConstantString.ContainerType,
|
|
557
|
-
$data: element.$data,
|
|
558
|
-
items: items,
|
|
559
|
-
});
|
|
560
|
-
currentCount += items.length;
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
result.push(element);
|
|
564
|
-
currentCount++;
|
|
565
|
-
}
|
|
566
|
-
if (currentCount >= maxCount) {
|
|
567
|
-
break;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return result;
|
|
571
|
-
}
|
|
572
548
|
}
|
|
573
549
|
|
|
574
550
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -697,22 +673,6 @@ class Validator {
|
|
|
697
673
|
}
|
|
698
674
|
return result;
|
|
699
675
|
}
|
|
700
|
-
validateResponse(method, path) {
|
|
701
|
-
const result = { isValid: true, reason: [] };
|
|
702
|
-
const operationObject = this.spec.paths[path][method];
|
|
703
|
-
const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
|
|
704
|
-
if (this.options.projectType === ProjectType.SME) {
|
|
705
|
-
// only support response body only contains “application/json” content type
|
|
706
|
-
if (multipleMediaType) {
|
|
707
|
-
result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
|
|
708
|
-
}
|
|
709
|
-
else if (Object.keys(json).length === 0) {
|
|
710
|
-
// response body should not be empty
|
|
711
|
-
result.reason.push(ErrorType.ResponseJsonIsEmpty);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
return result;
|
|
715
|
-
}
|
|
716
676
|
validateServer(method, path) {
|
|
717
677
|
const result = { isValid: true, reason: [] };
|
|
718
678
|
const serverObj = Utils.getServerObject(this.spec, method, path);
|
|
@@ -721,8 +681,8 @@ class Validator {
|
|
|
721
681
|
result.reason.push(ErrorType.NoServerInformation);
|
|
722
682
|
}
|
|
723
683
|
else {
|
|
724
|
-
|
|
725
|
-
const serverValidateResult = Utils.checkServerUrl([serverObj]);
|
|
684
|
+
const allowHttp = this.projectType === ProjectType.Copilot;
|
|
685
|
+
const serverValidateResult = Utils.checkServerUrl([serverObj], allowHttp);
|
|
726
686
|
result.reason.push(...serverValidateResult.map((item) => item.type));
|
|
727
687
|
}
|
|
728
688
|
return result;
|
|
@@ -757,125 +717,6 @@ class Validator {
|
|
|
757
717
|
}
|
|
758
718
|
return { isValid: false, reason: [ErrorType.AuthTypeIsNotSupported] };
|
|
759
719
|
}
|
|
760
|
-
checkPostBodySchema(schema, isRequired = false) {
|
|
761
|
-
var _a;
|
|
762
|
-
const paramResult = {
|
|
763
|
-
requiredNum: 0,
|
|
764
|
-
optionalNum: 0,
|
|
765
|
-
isValid: true,
|
|
766
|
-
reason: [],
|
|
767
|
-
};
|
|
768
|
-
if (Object.keys(schema).length === 0) {
|
|
769
|
-
return paramResult;
|
|
770
|
-
}
|
|
771
|
-
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
772
|
-
const isCopilot = this.projectType === ProjectType.Copilot;
|
|
773
|
-
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
774
|
-
paramResult.isValid = false;
|
|
775
|
-
paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
|
|
776
|
-
return paramResult;
|
|
777
|
-
}
|
|
778
|
-
if (schema.type === "string" ||
|
|
779
|
-
schema.type === "integer" ||
|
|
780
|
-
schema.type === "boolean" ||
|
|
781
|
-
schema.type === "number") {
|
|
782
|
-
if (isRequiredWithoutDefault) {
|
|
783
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
784
|
-
}
|
|
785
|
-
else {
|
|
786
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
else if (schema.type === "object") {
|
|
790
|
-
const { properties } = schema;
|
|
791
|
-
for (const property in properties) {
|
|
792
|
-
let isRequired = false;
|
|
793
|
-
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
794
|
-
isRequired = true;
|
|
795
|
-
}
|
|
796
|
-
const result = this.checkPostBodySchema(properties[property], isRequired);
|
|
797
|
-
paramResult.requiredNum += result.requiredNum;
|
|
798
|
-
paramResult.optionalNum += result.optionalNum;
|
|
799
|
-
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
800
|
-
paramResult.reason.push(...result.reason);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
if (isRequiredWithoutDefault && !isCopilot) {
|
|
805
|
-
paramResult.isValid = false;
|
|
806
|
-
paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
return paramResult;
|
|
810
|
-
}
|
|
811
|
-
checkParamSchema(paramObject) {
|
|
812
|
-
const paramResult = {
|
|
813
|
-
requiredNum: 0,
|
|
814
|
-
optionalNum: 0,
|
|
815
|
-
isValid: true,
|
|
816
|
-
reason: [],
|
|
817
|
-
};
|
|
818
|
-
if (!paramObject) {
|
|
819
|
-
return paramResult;
|
|
820
|
-
}
|
|
821
|
-
const isCopilot = this.projectType === ProjectType.Copilot;
|
|
822
|
-
for (let i = 0; i < paramObject.length; i++) {
|
|
823
|
-
const param = paramObject[i];
|
|
824
|
-
const schema = param.schema;
|
|
825
|
-
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
826
|
-
paramResult.isValid = false;
|
|
827
|
-
paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
|
|
828
|
-
continue;
|
|
829
|
-
}
|
|
830
|
-
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
831
|
-
if (isCopilot) {
|
|
832
|
-
if (isRequiredWithoutDefault) {
|
|
833
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
837
|
-
}
|
|
838
|
-
continue;
|
|
839
|
-
}
|
|
840
|
-
if (param.in === "header" || param.in === "cookie") {
|
|
841
|
-
if (isRequiredWithoutDefault) {
|
|
842
|
-
paramResult.isValid = false;
|
|
843
|
-
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
844
|
-
}
|
|
845
|
-
continue;
|
|
846
|
-
}
|
|
847
|
-
if (schema.type !== "boolean" &&
|
|
848
|
-
schema.type !== "string" &&
|
|
849
|
-
schema.type !== "number" &&
|
|
850
|
-
schema.type !== "integer") {
|
|
851
|
-
if (isRequiredWithoutDefault) {
|
|
852
|
-
paramResult.isValid = false;
|
|
853
|
-
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
854
|
-
}
|
|
855
|
-
continue;
|
|
856
|
-
}
|
|
857
|
-
if (param.in === "query" || param.in === "path") {
|
|
858
|
-
if (isRequiredWithoutDefault) {
|
|
859
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
860
|
-
}
|
|
861
|
-
else {
|
|
862
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
return paramResult;
|
|
867
|
-
}
|
|
868
|
-
hasNestedObjectInSchema(schema) {
|
|
869
|
-
if (schema.type === "object") {
|
|
870
|
-
for (const property in schema.properties) {
|
|
871
|
-
const nestedSchema = schema.properties[property];
|
|
872
|
-
if (nestedSchema.type === "object") {
|
|
873
|
-
return true;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
return false;
|
|
878
|
-
}
|
|
879
720
|
}
|
|
880
721
|
|
|
881
722
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -885,7 +726,6 @@ class CopilotValidator extends Validator {
|
|
|
885
726
|
this.projectType = ProjectType.Copilot;
|
|
886
727
|
this.options = options;
|
|
887
728
|
this.spec = spec;
|
|
888
|
-
this.checkCircularReference();
|
|
889
729
|
}
|
|
890
730
|
validateSpec() {
|
|
891
731
|
const result = { errors: [], warnings: [] };
|
|
@@ -911,10 +751,6 @@ class CopilotValidator extends Validator {
|
|
|
911
751
|
if (!methodAndPathResult.isValid) {
|
|
912
752
|
return methodAndPathResult;
|
|
913
753
|
}
|
|
914
|
-
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
915
|
-
if (!circularReferenceResult.isValid) {
|
|
916
|
-
return circularReferenceResult;
|
|
917
|
-
}
|
|
918
754
|
const operationObject = this.spec.paths[path][method];
|
|
919
755
|
// validate auth
|
|
920
756
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -926,24 +762,6 @@ class CopilotValidator extends Validator {
|
|
|
926
762
|
// validate server
|
|
927
763
|
const validateServerResult = this.validateServer(method, path);
|
|
928
764
|
result.reason.push(...validateServerResult.reason);
|
|
929
|
-
// validate response
|
|
930
|
-
const validateResponseResult = this.validateResponse(method, path);
|
|
931
|
-
result.reason.push(...validateResponseResult.reason);
|
|
932
|
-
// validate requestBody
|
|
933
|
-
const requestBody = operationObject.requestBody;
|
|
934
|
-
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
935
|
-
if (requestJsonBody) {
|
|
936
|
-
const requestBodySchema = requestJsonBody.schema;
|
|
937
|
-
if (requestBodySchema.type !== "object") {
|
|
938
|
-
result.reason.push(ErrorType.PostBodySchemaIsNotJson);
|
|
939
|
-
}
|
|
940
|
-
const requestBodyParamResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
|
|
941
|
-
result.reason.push(...requestBodyParamResult.reason);
|
|
942
|
-
}
|
|
943
|
-
// validate parameters
|
|
944
|
-
const paramObject = operationObject.parameters;
|
|
945
|
-
const paramResult = this.checkParamSchema(paramObject);
|
|
946
|
-
result.reason.push(...paramResult.reason);
|
|
947
765
|
if (result.reason.length > 0) {
|
|
948
766
|
result.isValid = false;
|
|
949
767
|
}
|
|
@@ -1035,6 +853,108 @@ class SMEValidator extends Validator {
|
|
|
1035
853
|
}
|
|
1036
854
|
return result;
|
|
1037
855
|
}
|
|
856
|
+
validateResponse(method, path) {
|
|
857
|
+
const result = { isValid: true, reason: [] };
|
|
858
|
+
const operationObject = this.spec.paths[path][method];
|
|
859
|
+
const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
|
|
860
|
+
// only support response body only contains “application/json” content type
|
|
861
|
+
if (multipleMediaType) {
|
|
862
|
+
result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
|
|
863
|
+
}
|
|
864
|
+
else if (Object.keys(json).length === 0) {
|
|
865
|
+
// response body should not be empty
|
|
866
|
+
result.reason.push(ErrorType.ResponseJsonIsEmpty);
|
|
867
|
+
}
|
|
868
|
+
return result;
|
|
869
|
+
}
|
|
870
|
+
checkPostBodySchema(schema, isRequired = false) {
|
|
871
|
+
var _a;
|
|
872
|
+
const paramResult = {
|
|
873
|
+
requiredNum: 0,
|
|
874
|
+
optionalNum: 0,
|
|
875
|
+
isValid: true,
|
|
876
|
+
reason: [],
|
|
877
|
+
};
|
|
878
|
+
if (Object.keys(schema).length === 0) {
|
|
879
|
+
return paramResult;
|
|
880
|
+
}
|
|
881
|
+
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
882
|
+
const isCopilot = this.projectType === ProjectType.Copilot;
|
|
883
|
+
if (schema.type === "string" ||
|
|
884
|
+
schema.type === "integer" ||
|
|
885
|
+
schema.type === "boolean" ||
|
|
886
|
+
schema.type === "number") {
|
|
887
|
+
if (isRequiredWithoutDefault) {
|
|
888
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
895
|
+
const { properties } = schema;
|
|
896
|
+
for (const property in properties) {
|
|
897
|
+
let isRequired = false;
|
|
898
|
+
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
899
|
+
isRequired = true;
|
|
900
|
+
}
|
|
901
|
+
const result = this.checkPostBodySchema(properties[property], isRequired);
|
|
902
|
+
paramResult.requiredNum += result.requiredNum;
|
|
903
|
+
paramResult.optionalNum += result.optionalNum;
|
|
904
|
+
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
905
|
+
paramResult.reason.push(...result.reason);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
else {
|
|
909
|
+
if (isRequiredWithoutDefault && !isCopilot) {
|
|
910
|
+
paramResult.isValid = false;
|
|
911
|
+
paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return paramResult;
|
|
915
|
+
}
|
|
916
|
+
checkParamSchema(paramObject) {
|
|
917
|
+
const paramResult = {
|
|
918
|
+
requiredNum: 0,
|
|
919
|
+
optionalNum: 0,
|
|
920
|
+
isValid: true,
|
|
921
|
+
reason: [],
|
|
922
|
+
};
|
|
923
|
+
if (!paramObject) {
|
|
924
|
+
return paramResult;
|
|
925
|
+
}
|
|
926
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
927
|
+
const param = paramObject[i];
|
|
928
|
+
const schema = param.schema;
|
|
929
|
+
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
930
|
+
if (param.in === "header" || param.in === "cookie") {
|
|
931
|
+
if (isRequiredWithoutDefault) {
|
|
932
|
+
paramResult.isValid = false;
|
|
933
|
+
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
934
|
+
}
|
|
935
|
+
continue;
|
|
936
|
+
}
|
|
937
|
+
if (schema.type !== "boolean" &&
|
|
938
|
+
schema.type !== "string" &&
|
|
939
|
+
schema.type !== "number" &&
|
|
940
|
+
schema.type !== "integer") {
|
|
941
|
+
if (isRequiredWithoutDefault) {
|
|
942
|
+
paramResult.isValid = false;
|
|
943
|
+
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
944
|
+
}
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
if (param.in === "query" || param.in === "path") {
|
|
948
|
+
if (isRequiredWithoutDefault) {
|
|
949
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
950
|
+
}
|
|
951
|
+
else {
|
|
952
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return paramResult;
|
|
957
|
+
}
|
|
1038
958
|
validateParamCount(postBodyResult, paramResult) {
|
|
1039
959
|
const result = { isValid: true, reason: [] };
|
|
1040
960
|
const totalRequiredParams = postBodyResult.requiredNum + paramResult.requiredNum;
|
|
@@ -1312,20 +1232,157 @@ class SpecFilter {
|
|
|
1312
1232
|
}
|
|
1313
1233
|
}
|
|
1314
1234
|
|
|
1235
|
+
// Copyright (c) Microsoft Corporation.
|
|
1236
|
+
class JsonDataGenerator {
|
|
1237
|
+
static generate(schema) {
|
|
1238
|
+
return this.generateMockData(schema);
|
|
1239
|
+
}
|
|
1240
|
+
static generateMockData(schema) {
|
|
1241
|
+
if (this.visitedSchemas.has(schema)) {
|
|
1242
|
+
return null; // Prevent circular reference
|
|
1243
|
+
}
|
|
1244
|
+
this.visitedSchemas.add(schema);
|
|
1245
|
+
let result;
|
|
1246
|
+
if (schema.anyOf) {
|
|
1247
|
+
// Select the first schema in anyOf
|
|
1248
|
+
const selectedSchema = schema.anyOf[0];
|
|
1249
|
+
result = this.generateMockData(selectedSchema);
|
|
1250
|
+
}
|
|
1251
|
+
else if (schema.oneOf) {
|
|
1252
|
+
// Select the first schema in oneOf
|
|
1253
|
+
const selectedSchema = schema.oneOf[0];
|
|
1254
|
+
result = this.generateMockData(selectedSchema);
|
|
1255
|
+
}
|
|
1256
|
+
else if (schema.allOf) {
|
|
1257
|
+
// merge all schemas in allOf
|
|
1258
|
+
result = {};
|
|
1259
|
+
for (const subschema of schema.allOf) {
|
|
1260
|
+
const data = this.generateMockData(subschema);
|
|
1261
|
+
result = Object.assign(Object.assign({}, result), data);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
else {
|
|
1265
|
+
switch (schema.type) {
|
|
1266
|
+
case "string":
|
|
1267
|
+
if (schema.example !== undefined) {
|
|
1268
|
+
result = schema.example;
|
|
1269
|
+
}
|
|
1270
|
+
else if (schema.format) {
|
|
1271
|
+
switch (schema.format) {
|
|
1272
|
+
case "date-time":
|
|
1273
|
+
result = "2024-11-01T05:25:43.593Z";
|
|
1274
|
+
break;
|
|
1275
|
+
case "email":
|
|
1276
|
+
result = "example@example.com";
|
|
1277
|
+
break;
|
|
1278
|
+
case "uuid":
|
|
1279
|
+
result = "123e4567-e89b-12d3-a456-426614174000";
|
|
1280
|
+
break;
|
|
1281
|
+
case "ipv4":
|
|
1282
|
+
result = "192.168.0.1";
|
|
1283
|
+
break;
|
|
1284
|
+
case "ipv6":
|
|
1285
|
+
result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
|
|
1286
|
+
break;
|
|
1287
|
+
default:
|
|
1288
|
+
result = "example string";
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
result = "example string";
|
|
1293
|
+
}
|
|
1294
|
+
break;
|
|
1295
|
+
case "number":
|
|
1296
|
+
if (schema.example !== undefined) {
|
|
1297
|
+
result = schema.example;
|
|
1298
|
+
}
|
|
1299
|
+
else if (schema.format) {
|
|
1300
|
+
switch (schema.format) {
|
|
1301
|
+
case "float":
|
|
1302
|
+
result = 3.14;
|
|
1303
|
+
break;
|
|
1304
|
+
case "double":
|
|
1305
|
+
result = 3.14159;
|
|
1306
|
+
break;
|
|
1307
|
+
default:
|
|
1308
|
+
result = 123;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
else {
|
|
1312
|
+
result = 123;
|
|
1313
|
+
}
|
|
1314
|
+
break;
|
|
1315
|
+
case "integer":
|
|
1316
|
+
if (schema.example !== undefined) {
|
|
1317
|
+
result = schema.example;
|
|
1318
|
+
}
|
|
1319
|
+
else if (schema.format) {
|
|
1320
|
+
switch (schema.format) {
|
|
1321
|
+
case "int32":
|
|
1322
|
+
result = 123456;
|
|
1323
|
+
break;
|
|
1324
|
+
case "int64":
|
|
1325
|
+
result = 123456789;
|
|
1326
|
+
break;
|
|
1327
|
+
default:
|
|
1328
|
+
result = 123;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
result = 123;
|
|
1333
|
+
}
|
|
1334
|
+
break;
|
|
1335
|
+
case "boolean":
|
|
1336
|
+
result = schema.example !== undefined ? schema.example : true;
|
|
1337
|
+
break;
|
|
1338
|
+
case "array":
|
|
1339
|
+
result = [this.generateMockData(schema.items)];
|
|
1340
|
+
break;
|
|
1341
|
+
case "object":
|
|
1342
|
+
result = {};
|
|
1343
|
+
if (schema.properties) {
|
|
1344
|
+
for (const key in schema.properties) {
|
|
1345
|
+
result[key] = this.generateMockData(schema.properties[key]);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
break;
|
|
1349
|
+
default:
|
|
1350
|
+
result = schema.example || null;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
this.visitedSchemas.delete(schema);
|
|
1354
|
+
return result;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
JsonDataGenerator.visitedSchemas = new Set();
|
|
1358
|
+
|
|
1315
1359
|
// Copyright (c) Microsoft Corporation.
|
|
1316
1360
|
class AdaptiveCardGenerator {
|
|
1317
|
-
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1361
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
|
|
1318
1362
|
try {
|
|
1319
1363
|
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1320
1364
|
let cardBody = [];
|
|
1365
|
+
let jsonData = {};
|
|
1366
|
+
const warnings = [];
|
|
1367
|
+
const operationId = operationItem.operationId;
|
|
1321
1368
|
let schema = json.schema;
|
|
1322
1369
|
let jsonPath = "$";
|
|
1323
1370
|
if (schema && Object.keys(schema).length > 0) {
|
|
1371
|
+
try {
|
|
1372
|
+
jsonData = JsonDataGenerator.generate(schema);
|
|
1373
|
+
}
|
|
1374
|
+
catch (err) {
|
|
1375
|
+
warnings.push({
|
|
1376
|
+
type: WarningType.GenerateJsonDataFailed,
|
|
1377
|
+
content: Utils.format(ConstantString.GenerateJsonDataFailed, operationId, err.toString()),
|
|
1378
|
+
data: operationId,
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1324
1381
|
jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
|
|
1325
1382
|
if (jsonPath !== "$") {
|
|
1326
1383
|
schema = schema.properties[jsonPath];
|
|
1327
1384
|
}
|
|
1328
|
-
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
|
|
1385
|
+
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount);
|
|
1329
1386
|
}
|
|
1330
1387
|
// if no schema, try to use example value
|
|
1331
1388
|
if (cardBody.length === 0 && (json.examples || json.example)) {
|
|
@@ -1353,16 +1410,20 @@ class AdaptiveCardGenerator {
|
|
|
1353
1410
|
version: ConstantString.AdaptiveCardVersion,
|
|
1354
1411
|
body: cardBody,
|
|
1355
1412
|
};
|
|
1356
|
-
return [fullCard, jsonPath];
|
|
1413
|
+
return [fullCard, jsonPath, jsonData, warnings];
|
|
1357
1414
|
}
|
|
1358
1415
|
catch (err) {
|
|
1359
1416
|
throw new SpecParserError(err.toString(), ErrorType.GenerateAdaptiveCardFailed);
|
|
1360
1417
|
}
|
|
1361
1418
|
}
|
|
1362
|
-
static generateCardFromResponse(schema, name, parentArrayName = "") {
|
|
1419
|
+
static generateCardFromResponse(schema, name, parentArrayName = "", maxElementCount = Number.MAX_SAFE_INTEGER, counter = { count: 0 }) {
|
|
1420
|
+
if (counter.count >= maxElementCount) {
|
|
1421
|
+
return [];
|
|
1422
|
+
}
|
|
1363
1423
|
if (schema.type === "array") {
|
|
1364
1424
|
// schema.items can be arbitrary object: schema { type: array, items: {} }
|
|
1365
1425
|
if (Object.keys(schema.items).length === 0) {
|
|
1426
|
+
counter.count++;
|
|
1366
1427
|
return [
|
|
1367
1428
|
{
|
|
1368
1429
|
type: ConstantString.TextBlockType,
|
|
@@ -1371,7 +1432,7 @@ class AdaptiveCardGenerator {
|
|
|
1371
1432
|
},
|
|
1372
1433
|
];
|
|
1373
1434
|
}
|
|
1374
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
|
|
1435
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name, maxElementCount, counter);
|
|
1375
1436
|
const template = {
|
|
1376
1437
|
type: ConstantString.ContainerType,
|
|
1377
1438
|
$data: name ? `\${${name}}` : "${$root}",
|
|
@@ -1381,11 +1442,11 @@ class AdaptiveCardGenerator {
|
|
|
1381
1442
|
return [template];
|
|
1382
1443
|
}
|
|
1383
1444
|
// some schema may not contain type but contain properties
|
|
1384
|
-
if (
|
|
1445
|
+
if (Utils.isObjectSchema(schema)) {
|
|
1385
1446
|
const { properties } = schema;
|
|
1386
1447
|
const result = [];
|
|
1387
1448
|
for (const property in properties) {
|
|
1388
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
|
|
1449
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName, maxElementCount, counter);
|
|
1389
1450
|
result.push(...obj);
|
|
1390
1451
|
}
|
|
1391
1452
|
if (schema.additionalProperties) {
|
|
@@ -1398,6 +1459,7 @@ class AdaptiveCardGenerator {
|
|
|
1398
1459
|
schema.type === "integer" ||
|
|
1399
1460
|
schema.type === "boolean" ||
|
|
1400
1461
|
schema.type === "number") {
|
|
1462
|
+
counter.count++;
|
|
1401
1463
|
if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
|
|
1402
1464
|
// string in root: "ddd"
|
|
1403
1465
|
let text = "result: ${$root}";
|
|
@@ -1422,24 +1484,17 @@ class AdaptiveCardGenerator {
|
|
|
1422
1484
|
];
|
|
1423
1485
|
}
|
|
1424
1486
|
else {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
{
|
|
1437
|
-
type: "Image",
|
|
1438
|
-
url: "${$data}",
|
|
1439
|
-
$when: "${$data != null && $data != ''}",
|
|
1440
|
-
},
|
|
1441
|
-
];
|
|
1442
|
-
}
|
|
1487
|
+
const url = name ? `\${${name}}` : "${$data}";
|
|
1488
|
+
const condition = name
|
|
1489
|
+
? `\${${name} != null && ${name} != ''}`
|
|
1490
|
+
: "${$data != null && $data != ''}";
|
|
1491
|
+
return [
|
|
1492
|
+
{
|
|
1493
|
+
type: "Image",
|
|
1494
|
+
url,
|
|
1495
|
+
$when: condition,
|
|
1496
|
+
},
|
|
1497
|
+
];
|
|
1443
1498
|
}
|
|
1444
1499
|
}
|
|
1445
1500
|
if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
|
|
@@ -1449,7 +1504,7 @@ class AdaptiveCardGenerator {
|
|
|
1449
1504
|
}
|
|
1450
1505
|
// Find the first array property in the response schema object with the well-known name
|
|
1451
1506
|
static getResponseJsonPathFromSchema(schema) {
|
|
1452
|
-
if (
|
|
1507
|
+
if (Utils.isObjectSchema(schema)) {
|
|
1453
1508
|
const { properties } = schema;
|
|
1454
1509
|
for (const property in properties) {
|
|
1455
1510
|
const schema = properties[property];
|
|
@@ -1682,36 +1737,11 @@ class ManifestUpdater {
|
|
|
1682
1737
|
for (const method in operations) {
|
|
1683
1738
|
if (options.allowMethods.includes(method)) {
|
|
1684
1739
|
const operationItem = operations[method];
|
|
1685
|
-
const confirmationBodies = [];
|
|
1686
1740
|
if (operationItem) {
|
|
1687
1741
|
const operationId = operationItem.operationId;
|
|
1688
1742
|
const safeFunctionName = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
1689
1743
|
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
1690
1744
|
const summary = operationItem.summary;
|
|
1691
|
-
const paramObject = operationItem.parameters;
|
|
1692
|
-
const requestBody = operationItem.requestBody;
|
|
1693
|
-
if (paramObject) {
|
|
1694
|
-
for (let i = 0; i < paramObject.length; i++) {
|
|
1695
|
-
const param = paramObject[i];
|
|
1696
|
-
const schema = param.schema;
|
|
1697
|
-
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1698
|
-
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
if (requestBody) {
|
|
1702
|
-
const requestJsonBody = requestBody.content["application/json"];
|
|
1703
|
-
const requestBodySchema = requestJsonBody.schema;
|
|
1704
|
-
if (requestBodySchema.type === "object") {
|
|
1705
|
-
for (const property in requestBodySchema.properties) {
|
|
1706
|
-
const schema = requestBodySchema.properties[property];
|
|
1707
|
-
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1708
|
-
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
else {
|
|
1712
|
-
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
1745
|
let funcDescription = operationItem.description || operationItem.summary || "";
|
|
1716
1746
|
if (funcDescription.length > ConstantString.FunctionDescriptionMaxLens) {
|
|
1717
1747
|
warnings.push({
|
|
@@ -1729,8 +1759,7 @@ class ManifestUpdater {
|
|
|
1729
1759
|
try {
|
|
1730
1760
|
const { json } = Utils.getResponseJson(operationItem);
|
|
1731
1761
|
if (json.schema) {
|
|
1732
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
|
|
1733
|
-
card.body = Utils.limitACBodyProperties(card.body, 5);
|
|
1762
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
|
|
1734
1763
|
const responseSemantic = wrapResponseSemantics(card, jsonPath);
|
|
1735
1764
|
funcObj.capabilities = {
|
|
1736
1765
|
response_semantics: responseSemantic,
|
|
@@ -1746,14 +1775,39 @@ class ManifestUpdater {
|
|
|
1746
1775
|
}
|
|
1747
1776
|
}
|
|
1748
1777
|
if (options.allowConfirmation && method !== ConstantString.GetMethod) {
|
|
1749
|
-
|
|
1750
|
-
|
|
1778
|
+
const paramObject = operationItem.parameters;
|
|
1779
|
+
const requestBody = operationItem.requestBody;
|
|
1780
|
+
const confirmationBodies = [];
|
|
1781
|
+
if (paramObject) {
|
|
1782
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
1783
|
+
const param = paramObject[i];
|
|
1784
|
+
const schema = param.schema;
|
|
1785
|
+
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1786
|
+
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
if (requestBody) {
|
|
1790
|
+
const requestJsonBody = Utils.getJsonContentType(requestBody);
|
|
1791
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
1792
|
+
if (Utils.isObjectSchema(requestBodySchema)) {
|
|
1793
|
+
for (const property in requestBodySchema.properties) {
|
|
1794
|
+
const schema = requestBodySchema.properties[property];
|
|
1795
|
+
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1796
|
+
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
else {
|
|
1800
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
|
|
1801
|
+
}
|
|
1751
1802
|
}
|
|
1752
|
-
funcObj.capabilities.confirmation = {
|
|
1753
|
-
type: "AdaptiveCard",
|
|
1754
|
-
title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
|
|
1755
|
-
};
|
|
1756
1803
|
if (confirmationBodies.length > 0) {
|
|
1804
|
+
if (!funcObj.capabilities) {
|
|
1805
|
+
funcObj.capabilities = {};
|
|
1806
|
+
}
|
|
1807
|
+
funcObj.capabilities.confirmation = {
|
|
1808
|
+
type: "AdaptiveCard",
|
|
1809
|
+
title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
|
|
1810
|
+
};
|
|
1757
1811
|
funcObj.capabilities.confirmation.body = confirmationBodies.join("\n");
|
|
1758
1812
|
}
|
|
1759
1813
|
}
|
|
@@ -2189,6 +2243,24 @@ class SpecParser {
|
|
|
2189
2243
|
const newUnResolvedSpec = newSpecs[0];
|
|
2190
2244
|
const newSpec = newSpecs[1];
|
|
2191
2245
|
const authInfo = Utils.getAuthInfo(newSpec);
|
|
2246
|
+
const paths = newUnResolvedSpec.paths;
|
|
2247
|
+
for (const pathUrl in paths) {
|
|
2248
|
+
const operations = paths[pathUrl];
|
|
2249
|
+
for (const method in operations) {
|
|
2250
|
+
const operationItem = operations[method];
|
|
2251
|
+
const operationId = operationItem.operationId;
|
|
2252
|
+
const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
|
|
2253
|
+
if (!containsSpecialCharacters) {
|
|
2254
|
+
continue;
|
|
2255
|
+
}
|
|
2256
|
+
operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2257
|
+
result.warnings.push({
|
|
2258
|
+
type: WarningType.OperationIdContainsSpecialCharacters,
|
|
2259
|
+
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2260
|
+
data: operationId,
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2192
2264
|
await this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
|
|
2193
2265
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
2194
2266
|
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
@@ -2240,13 +2312,14 @@ class SpecParser {
|
|
|
2240
2312
|
if (this.options.allowMethods.includes(method)) {
|
|
2241
2313
|
const operation = newSpec.paths[url][method];
|
|
2242
2314
|
try {
|
|
2243
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
2315
|
+
const [card, jsonPath, jsonData, warnings] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
2316
|
+
result.warnings.push(...warnings);
|
|
2244
2317
|
const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2245
2318
|
const fileName = path.join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
|
|
2246
2319
|
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
2247
2320
|
await fs.outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
2248
2321
|
const dataFileName = path.join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
|
|
2249
|
-
await fs.outputJSON(dataFileName,
|
|
2322
|
+
await fs.outputJSON(dataFileName, jsonData, { spaces: 2 });
|
|
2250
2323
|
}
|
|
2251
2324
|
catch (err) {
|
|
2252
2325
|
result.allSuccess = false;
|