@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.
@@ -80,11 +80,8 @@ exports.ErrorType = void 0;
80
80
  ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
81
81
  ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
82
82
  ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
83
- ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
84
83
  ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
85
84
  ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
86
- ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
87
- ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
88
85
  ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
89
86
  ErrorType["NoParameter"] = "no-parameter";
90
87
  ErrorType["NoAPIInfo"] = "no-api-info";
@@ -103,6 +100,8 @@ exports.WarningType = void 0;
103
100
  WarningType["OperationOnlyContainsOptionalParam"] = "operation-only-contains-optional-param";
104
101
  WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
105
102
  WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
103
+ WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
104
+ WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
106
105
  WarningType["Unknown"] = "unknown";
107
106
  })(exports.WarningType || (exports.WarningType = {}));
108
107
  /**
@@ -140,15 +139,17 @@ ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converte
140
139
  ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
141
140
  ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
142
141
  ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
142
+ ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
143
143
  ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
144
144
  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.";
145
+ ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
145
146
  ConstantString.WrappedCardVersion = "devPreview";
146
147
  ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
147
148
  ConstantString.WrappedCardResponseLayout = "list";
148
149
  ConstantString.GetMethod = "get";
149
150
  ConstantString.PostMethod = "post";
150
151
  ConstantString.AdaptiveCardVersion = "1.5";
151
- ConstantString.AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json";
152
+ ConstantString.AdaptiveCardSchema = "https://adaptivecards.io/schemas/adaptive-card.json";
152
153
  ConstantString.AdaptiveCardType = "AdaptiveCard";
153
154
  ConstantString.TextBlockType = "TextBlock";
154
155
  ConstantString.ImageType = "Image";
@@ -235,16 +236,8 @@ class SpecParserError extends Error {
235
236
 
236
237
  // Copyright (c) Microsoft Corporation.
237
238
  class Utils {
238
- static hasNestedObjectInSchema(schema) {
239
- if (schema.type === "object") {
240
- for (const property in schema.properties) {
241
- const nestedSchema = schema.properties[property];
242
- if (nestedSchema.type === "object") {
243
- return true;
244
- }
245
- }
246
- }
247
- return false;
239
+ static isObjectSchema(schema) {
240
+ return schema.type === "object" || (!schema.type && !!schema.properties);
248
241
  }
249
242
  static containMultipleMediaTypes(bodyObject) {
250
243
  return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
@@ -312,27 +305,33 @@ class Utils {
312
305
  let multipleMediaType = false;
313
306
  for (const code of ConstantString.ResponseCodeFor20X) {
314
307
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
315
- if (responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) {
316
- for (const contentType of Object.keys(responseObject.content)) {
317
- // json media type can also be "application/json; charset=utf-8"
318
- if (contentType.indexOf("application/json") >= 0) {
319
- multipleMediaType = false;
320
- json = responseObject.content[contentType];
321
- if (Utils.containMultipleMediaTypes(responseObject)) {
322
- multipleMediaType = true;
323
- if (!allowMultipleMediaType) {
324
- json = {};
325
- }
326
- }
327
- else {
328
- return { json, multipleMediaType };
329
- }
330
- }
331
- }
308
+ if (!responseObject) {
309
+ continue;
310
+ }
311
+ multipleMediaType = Utils.containMultipleMediaTypes(responseObject);
312
+ if (!allowMultipleMediaType && multipleMediaType) {
313
+ json = {};
314
+ continue;
315
+ }
316
+ const mediaObj = Utils.getJsonContentType(responseObject);
317
+ if (Object.keys(mediaObj).length > 0) {
318
+ json = mediaObj;
319
+ return { json, multipleMediaType };
332
320
  }
333
321
  }
334
322
  return { json, multipleMediaType };
335
323
  }
324
+ static getJsonContentType(responseObject) {
325
+ if (responseObject.content) {
326
+ for (const contentType of Object.keys(responseObject.content)) {
327
+ // json media type can also be "application/json; charset=utf-8"
328
+ if (contentType.indexOf("application/json") >= 0) {
329
+ return responseObject.content[contentType];
330
+ }
331
+ }
332
+ }
333
+ return {};
334
+ }
336
335
  static convertPathToCamelCase(path) {
337
336
  const pathSegments = path.split(/[./{]/);
338
337
  const camelCaseSegments = pathSegments.map((segment) => {
@@ -368,7 +367,7 @@ class Utils {
368
367
  }
369
368
  return newStr;
370
369
  }
371
- static checkServerUrl(servers) {
370
+ static checkServerUrl(servers, allowHttp = false) {
372
371
  const errors = [];
373
372
  let serverUrl;
374
373
  try {
@@ -391,8 +390,7 @@ class Utils {
391
390
  data: servers,
392
391
  });
393
392
  }
394
- else if (protocol !== "https:") {
395
- // Http server url is not supported
393
+ else if (protocol !== "https:" && !(protocol === "http:" && allowHttp)) {
396
394
  const protocolString = protocol.slice(0, -1);
397
395
  errors.push({
398
396
  type: exports.ErrorType.UrlProtocolNotSupported,
@@ -408,10 +406,11 @@ class Utils {
408
406
  let hasTopLevelServers = false;
409
407
  let hasPathLevelServers = false;
410
408
  let hasOperationLevelServers = false;
409
+ const allowHttp = options.projectType === exports.ProjectType.Copilot;
411
410
  if (spec.servers && spec.servers.length >= 1) {
412
411
  hasTopLevelServers = true;
413
412
  // for multiple server, we only use the first url
414
- const serverErrors = Utils.checkServerUrl(spec.servers);
413
+ const serverErrors = Utils.checkServerUrl(spec.servers, allowHttp);
415
414
  errors.push(...serverErrors);
416
415
  }
417
416
  const paths = spec.paths;
@@ -419,7 +418,7 @@ class Utils {
419
418
  const methods = paths[path];
420
419
  if ((methods === null || methods === void 0 ? void 0 : methods.servers) && methods.servers.length >= 1) {
421
420
  hasPathLevelServers = true;
422
- const serverErrors = Utils.checkServerUrl(methods.servers);
421
+ const serverErrors = Utils.checkServerUrl(methods.servers, allowHttp);
423
422
  errors.push(...serverErrors);
424
423
  }
425
424
  for (const method in methods) {
@@ -427,7 +426,7 @@ class Utils {
427
426
  if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
428
427
  if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
429
428
  hasOperationLevelServers = true;
430
- const serverErrors = Utils.checkServerUrl(operationObject.servers);
429
+ const serverErrors = Utils.checkServerUrl(operationObject.servers, allowHttp);
431
430
  errors.push(...serverErrors);
432
431
  }
433
432
  }
@@ -474,7 +473,7 @@ class Utils {
474
473
  optionalParams.push(parameter);
475
474
  }
476
475
  }
477
- else if (schema.type === "object") {
476
+ else if (Utils.isObjectSchema(schema)) {
478
477
  const { properties } = schema;
479
478
  for (const property in properties) {
480
479
  let isRequired = false;
@@ -588,29 +587,6 @@ class Utils {
588
587
  const serverUrl = operationServer || methodServer || rootServer;
589
588
  return serverUrl;
590
589
  }
591
- static limitACBodyProperties(body, maxCount) {
592
- const result = [];
593
- let currentCount = 0;
594
- for (const element of body) {
595
- if (element.type === ConstantString.ContainerType) {
596
- const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
597
- result.push({
598
- type: ConstantString.ContainerType,
599
- $data: element.$data,
600
- items: items,
601
- });
602
- currentCount += items.length;
603
- }
604
- else {
605
- result.push(element);
606
- currentCount++;
607
- }
608
- if (currentCount >= maxCount) {
609
- break;
610
- }
611
- }
612
- return result;
613
- }
614
590
  }
615
591
 
616
592
  // Copyright (c) Microsoft Corporation.
@@ -739,22 +715,6 @@ class Validator {
739
715
  }
740
716
  return result;
741
717
  }
742
- validateResponse(method, path) {
743
- const result = { isValid: true, reason: [] };
744
- const operationObject = this.spec.paths[path][method];
745
- const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
746
- if (this.options.projectType === exports.ProjectType.SME) {
747
- // only support response body only contains “application/json” content type
748
- if (multipleMediaType) {
749
- result.reason.push(exports.ErrorType.ResponseContainMultipleMediaTypes);
750
- }
751
- else if (Object.keys(json).length === 0) {
752
- // response body should not be empty
753
- result.reason.push(exports.ErrorType.ResponseJsonIsEmpty);
754
- }
755
- }
756
- return result;
757
- }
758
718
  validateServer(method, path) {
759
719
  const result = { isValid: true, reason: [] };
760
720
  const serverObj = Utils.getServerObject(this.spec, method, path);
@@ -763,8 +723,8 @@ class Validator {
763
723
  result.reason.push(exports.ErrorType.NoServerInformation);
764
724
  }
765
725
  else {
766
- // server url should be absolute url with https protocol
767
- const serverValidateResult = Utils.checkServerUrl([serverObj]);
726
+ const allowHttp = this.projectType === exports.ProjectType.Copilot;
727
+ const serverValidateResult = Utils.checkServerUrl([serverObj], allowHttp);
768
728
  result.reason.push(...serverValidateResult.map((item) => item.type));
769
729
  }
770
730
  return result;
@@ -799,125 +759,6 @@ class Validator {
799
759
  }
800
760
  return { isValid: false, reason: [exports.ErrorType.AuthTypeIsNotSupported] };
801
761
  }
802
- checkPostBodySchema(schema, isRequired = false) {
803
- var _a;
804
- const paramResult = {
805
- requiredNum: 0,
806
- optionalNum: 0,
807
- isValid: true,
808
- reason: [],
809
- };
810
- if (Object.keys(schema).length === 0) {
811
- return paramResult;
812
- }
813
- const isRequiredWithoutDefault = isRequired && schema.default === undefined;
814
- const isCopilot = this.projectType === exports.ProjectType.Copilot;
815
- if (isCopilot && this.hasNestedObjectInSchema(schema)) {
816
- paramResult.isValid = false;
817
- paramResult.reason = [exports.ErrorType.RequestBodyContainsNestedObject];
818
- return paramResult;
819
- }
820
- if (schema.type === "string" ||
821
- schema.type === "integer" ||
822
- schema.type === "boolean" ||
823
- schema.type === "number") {
824
- if (isRequiredWithoutDefault) {
825
- paramResult.requiredNum = paramResult.requiredNum + 1;
826
- }
827
- else {
828
- paramResult.optionalNum = paramResult.optionalNum + 1;
829
- }
830
- }
831
- else if (schema.type === "object") {
832
- const { properties } = schema;
833
- for (const property in properties) {
834
- let isRequired = false;
835
- if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
836
- isRequired = true;
837
- }
838
- const result = this.checkPostBodySchema(properties[property], isRequired);
839
- paramResult.requiredNum += result.requiredNum;
840
- paramResult.optionalNum += result.optionalNum;
841
- paramResult.isValid = paramResult.isValid && result.isValid;
842
- paramResult.reason.push(...result.reason);
843
- }
844
- }
845
- else {
846
- if (isRequiredWithoutDefault && !isCopilot) {
847
- paramResult.isValid = false;
848
- paramResult.reason.push(exports.ErrorType.PostBodyContainsRequiredUnsupportedSchema);
849
- }
850
- }
851
- return paramResult;
852
- }
853
- checkParamSchema(paramObject) {
854
- const paramResult = {
855
- requiredNum: 0,
856
- optionalNum: 0,
857
- isValid: true,
858
- reason: [],
859
- };
860
- if (!paramObject) {
861
- return paramResult;
862
- }
863
- const isCopilot = this.projectType === exports.ProjectType.Copilot;
864
- for (let i = 0; i < paramObject.length; i++) {
865
- const param = paramObject[i];
866
- const schema = param.schema;
867
- if (isCopilot && this.hasNestedObjectInSchema(schema)) {
868
- paramResult.isValid = false;
869
- paramResult.reason.push(exports.ErrorType.ParamsContainsNestedObject);
870
- continue;
871
- }
872
- const isRequiredWithoutDefault = param.required && schema.default === undefined;
873
- if (isCopilot) {
874
- if (isRequiredWithoutDefault) {
875
- paramResult.requiredNum = paramResult.requiredNum + 1;
876
- }
877
- else {
878
- paramResult.optionalNum = paramResult.optionalNum + 1;
879
- }
880
- continue;
881
- }
882
- if (param.in === "header" || param.in === "cookie") {
883
- if (isRequiredWithoutDefault) {
884
- paramResult.isValid = false;
885
- paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
886
- }
887
- continue;
888
- }
889
- if (schema.type !== "boolean" &&
890
- schema.type !== "string" &&
891
- schema.type !== "number" &&
892
- schema.type !== "integer") {
893
- if (isRequiredWithoutDefault) {
894
- paramResult.isValid = false;
895
- paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
896
- }
897
- continue;
898
- }
899
- if (param.in === "query" || param.in === "path") {
900
- if (isRequiredWithoutDefault) {
901
- paramResult.requiredNum = paramResult.requiredNum + 1;
902
- }
903
- else {
904
- paramResult.optionalNum = paramResult.optionalNum + 1;
905
- }
906
- }
907
- }
908
- return paramResult;
909
- }
910
- hasNestedObjectInSchema(schema) {
911
- if (schema.type === "object") {
912
- for (const property in schema.properties) {
913
- const nestedSchema = schema.properties[property];
914
- if (nestedSchema.type === "object") {
915
- return true;
916
- }
917
- }
918
- }
919
- return false;
920
- }
921
762
  }
922
763
 
923
764
  // Copyright (c) Microsoft Corporation.
@@ -927,7 +768,6 @@ class CopilotValidator extends Validator {
927
768
  this.projectType = exports.ProjectType.Copilot;
928
769
  this.options = options;
929
770
  this.spec = spec;
930
- this.checkCircularReference();
931
771
  }
932
772
  validateSpec() {
933
773
  const result = { errors: [], warnings: [] };
@@ -953,10 +793,6 @@ class CopilotValidator extends Validator {
953
793
  if (!methodAndPathResult.isValid) {
954
794
  return methodAndPathResult;
955
795
  }
956
- const circularReferenceResult = this.validateCircularReference(method, path);
957
- if (!circularReferenceResult.isValid) {
958
- return circularReferenceResult;
959
- }
960
796
  const operationObject = this.spec.paths[path][method];
961
797
  // validate auth
962
798
  const authCheckResult = this.validateAuth(method, path);
@@ -968,24 +804,6 @@ class CopilotValidator extends Validator {
968
804
  // validate server
969
805
  const validateServerResult = this.validateServer(method, path);
970
806
  result.reason.push(...validateServerResult.reason);
971
- // validate response
972
- const validateResponseResult = this.validateResponse(method, path);
973
- result.reason.push(...validateResponseResult.reason);
974
- // validate requestBody
975
- const requestBody = operationObject.requestBody;
976
- const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
977
- if (requestJsonBody) {
978
- const requestBodySchema = requestJsonBody.schema;
979
- if (requestBodySchema.type !== "object") {
980
- result.reason.push(exports.ErrorType.PostBodySchemaIsNotJson);
981
- }
982
- const requestBodyParamResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
983
- result.reason.push(...requestBodyParamResult.reason);
984
- }
985
- // validate parameters
986
- const paramObject = operationObject.parameters;
987
- const paramResult = this.checkParamSchema(paramObject);
988
- result.reason.push(...paramResult.reason);
989
807
  if (result.reason.length > 0) {
990
808
  result.isValid = false;
991
809
  }
@@ -1077,6 +895,108 @@ class SMEValidator extends Validator {
1077
895
  }
1078
896
  return result;
1079
897
  }
898
+ validateResponse(method, path) {
899
+ const result = { isValid: true, reason: [] };
900
+ const operationObject = this.spec.paths[path][method];
901
+ const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
902
+ // only support response body only contains “application/json” content type
903
+ if (multipleMediaType) {
904
+ result.reason.push(exports.ErrorType.ResponseContainMultipleMediaTypes);
905
+ }
906
+ else if (Object.keys(json).length === 0) {
907
+ // response body should not be empty
908
+ result.reason.push(exports.ErrorType.ResponseJsonIsEmpty);
909
+ }
910
+ return result;
911
+ }
912
+ checkPostBodySchema(schema, isRequired = false) {
913
+ var _a;
914
+ const paramResult = {
915
+ requiredNum: 0,
916
+ optionalNum: 0,
917
+ isValid: true,
918
+ reason: [],
919
+ };
920
+ if (Object.keys(schema).length === 0) {
921
+ return paramResult;
922
+ }
923
+ const isRequiredWithoutDefault = isRequired && schema.default === undefined;
924
+ const isCopilot = this.projectType === exports.ProjectType.Copilot;
925
+ if (schema.type === "string" ||
926
+ schema.type === "integer" ||
927
+ schema.type === "boolean" ||
928
+ schema.type === "number") {
929
+ if (isRequiredWithoutDefault) {
930
+ paramResult.requiredNum = paramResult.requiredNum + 1;
931
+ }
932
+ else {
933
+ paramResult.optionalNum = paramResult.optionalNum + 1;
934
+ }
935
+ }
936
+ else if (Utils.isObjectSchema(schema)) {
937
+ const { properties } = schema;
938
+ for (const property in properties) {
939
+ let isRequired = false;
940
+ if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
941
+ isRequired = true;
942
+ }
943
+ const result = this.checkPostBodySchema(properties[property], isRequired);
944
+ paramResult.requiredNum += result.requiredNum;
945
+ paramResult.optionalNum += result.optionalNum;
946
+ paramResult.isValid = paramResult.isValid && result.isValid;
947
+ paramResult.reason.push(...result.reason);
948
+ }
949
+ }
950
+ else {
951
+ if (isRequiredWithoutDefault && !isCopilot) {
952
+ paramResult.isValid = false;
953
+ paramResult.reason.push(exports.ErrorType.PostBodyContainsRequiredUnsupportedSchema);
954
+ }
955
+ }
956
+ return paramResult;
957
+ }
958
+ checkParamSchema(paramObject) {
959
+ const paramResult = {
960
+ requiredNum: 0,
961
+ optionalNum: 0,
962
+ isValid: true,
963
+ reason: [],
964
+ };
965
+ if (!paramObject) {
966
+ return paramResult;
967
+ }
968
+ for (let i = 0; i < paramObject.length; i++) {
969
+ const param = paramObject[i];
970
+ const schema = param.schema;
971
+ const isRequiredWithoutDefault = param.required && schema.default === undefined;
972
+ if (param.in === "header" || param.in === "cookie") {
973
+ if (isRequiredWithoutDefault) {
974
+ paramResult.isValid = false;
975
+ paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
976
+ }
977
+ continue;
978
+ }
979
+ if (schema.type !== "boolean" &&
980
+ schema.type !== "string" &&
981
+ schema.type !== "number" &&
982
+ schema.type !== "integer") {
983
+ if (isRequiredWithoutDefault) {
984
+ paramResult.isValid = false;
985
+ paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
986
+ }
987
+ continue;
988
+ }
989
+ if (param.in === "query" || param.in === "path") {
990
+ if (isRequiredWithoutDefault) {
991
+ paramResult.requiredNum = paramResult.requiredNum + 1;
992
+ }
993
+ else {
994
+ paramResult.optionalNum = paramResult.optionalNum + 1;
995
+ }
996
+ }
997
+ }
998
+ return paramResult;
999
+ }
1080
1000
  validateParamCount(postBodyResult, paramResult) {
1081
1001
  const result = { isValid: true, reason: [] };
1082
1002
  const totalRequiredParams = postBodyResult.requiredNum + paramResult.requiredNum;
@@ -1354,20 +1274,157 @@ class SpecFilter {
1354
1274
  }
1355
1275
  }
1356
1276
 
1277
+ // Copyright (c) Microsoft Corporation.
1278
+ class JsonDataGenerator {
1279
+ static generate(schema) {
1280
+ return this.generateMockData(schema);
1281
+ }
1282
+ static generateMockData(schema) {
1283
+ if (this.visitedSchemas.has(schema)) {
1284
+ return null; // Prevent circular reference
1285
+ }
1286
+ this.visitedSchemas.add(schema);
1287
+ let result;
1288
+ if (schema.anyOf) {
1289
+ // Select the first schema in anyOf
1290
+ const selectedSchema = schema.anyOf[0];
1291
+ result = this.generateMockData(selectedSchema);
1292
+ }
1293
+ else if (schema.oneOf) {
1294
+ // Select the first schema in oneOf
1295
+ const selectedSchema = schema.oneOf[0];
1296
+ result = this.generateMockData(selectedSchema);
1297
+ }
1298
+ else if (schema.allOf) {
1299
+ // merge all schemas in allOf
1300
+ result = {};
1301
+ for (const subschema of schema.allOf) {
1302
+ const data = this.generateMockData(subschema);
1303
+ result = Object.assign(Object.assign({}, result), data);
1304
+ }
1305
+ }
1306
+ else {
1307
+ switch (schema.type) {
1308
+ case "string":
1309
+ if (schema.example !== undefined) {
1310
+ result = schema.example;
1311
+ }
1312
+ else if (schema.format) {
1313
+ switch (schema.format) {
1314
+ case "date-time":
1315
+ result = "2024-11-01T05:25:43.593Z";
1316
+ break;
1317
+ case "email":
1318
+ result = "example@example.com";
1319
+ break;
1320
+ case "uuid":
1321
+ result = "123e4567-e89b-12d3-a456-426614174000";
1322
+ break;
1323
+ case "ipv4":
1324
+ result = "192.168.0.1";
1325
+ break;
1326
+ case "ipv6":
1327
+ result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
1328
+ break;
1329
+ default:
1330
+ result = "example string";
1331
+ }
1332
+ }
1333
+ else {
1334
+ result = "example string";
1335
+ }
1336
+ break;
1337
+ case "number":
1338
+ if (schema.example !== undefined) {
1339
+ result = schema.example;
1340
+ }
1341
+ else if (schema.format) {
1342
+ switch (schema.format) {
1343
+ case "float":
1344
+ result = 3.14;
1345
+ break;
1346
+ case "double":
1347
+ result = 3.14159;
1348
+ break;
1349
+ default:
1350
+ result = 123;
1351
+ }
1352
+ }
1353
+ else {
1354
+ result = 123;
1355
+ }
1356
+ break;
1357
+ case "integer":
1358
+ if (schema.example !== undefined) {
1359
+ result = schema.example;
1360
+ }
1361
+ else if (schema.format) {
1362
+ switch (schema.format) {
1363
+ case "int32":
1364
+ result = 123456;
1365
+ break;
1366
+ case "int64":
1367
+ result = 123456789;
1368
+ break;
1369
+ default:
1370
+ result = 123;
1371
+ }
1372
+ }
1373
+ else {
1374
+ result = 123;
1375
+ }
1376
+ break;
1377
+ case "boolean":
1378
+ result = schema.example !== undefined ? schema.example : true;
1379
+ break;
1380
+ case "array":
1381
+ result = [this.generateMockData(schema.items)];
1382
+ break;
1383
+ case "object":
1384
+ result = {};
1385
+ if (schema.properties) {
1386
+ for (const key in schema.properties) {
1387
+ result[key] = this.generateMockData(schema.properties[key]);
1388
+ }
1389
+ }
1390
+ break;
1391
+ default:
1392
+ result = schema.example || null;
1393
+ }
1394
+ }
1395
+ this.visitedSchemas.delete(schema);
1396
+ return result;
1397
+ }
1398
+ }
1399
+ JsonDataGenerator.visitedSchemas = new Set();
1400
+
1357
1401
  // Copyright (c) Microsoft Corporation.
1358
1402
  class AdaptiveCardGenerator {
1359
- static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
1403
+ static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
1360
1404
  try {
1361
1405
  const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
1362
1406
  let cardBody = [];
1407
+ let jsonData = {};
1408
+ const warnings = [];
1409
+ const operationId = operationItem.operationId;
1363
1410
  let schema = json.schema;
1364
1411
  let jsonPath = "$";
1365
1412
  if (schema && Object.keys(schema).length > 0) {
1413
+ try {
1414
+ jsonData = JsonDataGenerator.generate(schema);
1415
+ }
1416
+ catch (err) {
1417
+ warnings.push({
1418
+ type: exports.WarningType.GenerateJsonDataFailed,
1419
+ content: Utils.format(ConstantString.GenerateJsonDataFailed, operationId, err.toString()),
1420
+ data: operationId,
1421
+ });
1422
+ }
1366
1423
  jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
1367
1424
  if (jsonPath !== "$") {
1368
1425
  schema = schema.properties[jsonPath];
1369
1426
  }
1370
- cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
1427
+ cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount);
1371
1428
  }
1372
1429
  // if no schema, try to use example value
1373
1430
  if (cardBody.length === 0 && (json.examples || json.example)) {
@@ -1395,16 +1452,20 @@ class AdaptiveCardGenerator {
1395
1452
  version: ConstantString.AdaptiveCardVersion,
1396
1453
  body: cardBody,
1397
1454
  };
1398
- return [fullCard, jsonPath];
1455
+ return [fullCard, jsonPath, jsonData, warnings];
1399
1456
  }
1400
1457
  catch (err) {
1401
1458
  throw new SpecParserError(err.toString(), exports.ErrorType.GenerateAdaptiveCardFailed);
1402
1459
  }
1403
1460
  }
1404
- static generateCardFromResponse(schema, name, parentArrayName = "") {
1461
+ static generateCardFromResponse(schema, name, parentArrayName = "", maxElementCount = Number.MAX_SAFE_INTEGER, counter = { count: 0 }) {
1462
+ if (counter.count >= maxElementCount) {
1463
+ return [];
1464
+ }
1405
1465
  if (schema.type === "array") {
1406
1466
  // schema.items can be arbitrary object: schema { type: array, items: {} }
1407
1467
  if (Object.keys(schema.items).length === 0) {
1468
+ counter.count++;
1408
1469
  return [
1409
1470
  {
1410
1471
  type: ConstantString.TextBlockType,
@@ -1413,7 +1474,7 @@ class AdaptiveCardGenerator {
1413
1474
  },
1414
1475
  ];
1415
1476
  }
1416
- const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
1477
+ const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name, maxElementCount, counter);
1417
1478
  const template = {
1418
1479
  type: ConstantString.ContainerType,
1419
1480
  $data: name ? `\${${name}}` : "${$root}",
@@ -1423,11 +1484,11 @@ class AdaptiveCardGenerator {
1423
1484
  return [template];
1424
1485
  }
1425
1486
  // some schema may not contain type but contain properties
1426
- if (schema.type === "object" || (!schema.type && schema.properties)) {
1487
+ if (Utils.isObjectSchema(schema)) {
1427
1488
  const { properties } = schema;
1428
1489
  const result = [];
1429
1490
  for (const property in properties) {
1430
- const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
1491
+ const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName, maxElementCount, counter);
1431
1492
  result.push(...obj);
1432
1493
  }
1433
1494
  if (schema.additionalProperties) {
@@ -1440,6 +1501,7 @@ class AdaptiveCardGenerator {
1440
1501
  schema.type === "integer" ||
1441
1502
  schema.type === "boolean" ||
1442
1503
  schema.type === "number") {
1504
+ counter.count++;
1443
1505
  if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
1444
1506
  // string in root: "ddd"
1445
1507
  let text = "result: ${$root}";
@@ -1464,24 +1526,17 @@ class AdaptiveCardGenerator {
1464
1526
  ];
1465
1527
  }
1466
1528
  else {
1467
- if (name) {
1468
- return [
1469
- {
1470
- type: "Image",
1471
- url: `\${${name}}`,
1472
- $when: `\${${name} != null && ${name} != ''}`,
1473
- },
1474
- ];
1475
- }
1476
- else {
1477
- return [
1478
- {
1479
- type: "Image",
1480
- url: "${$data}",
1481
- $when: "${$data != null && $data != ''}",
1482
- },
1483
- ];
1484
- }
1529
+ const url = name ? `\${${name}}` : "${$data}";
1530
+ const condition = name
1531
+ ? `\${${name} != null && ${name} != ''}`
1532
+ : "${$data != null && $data != ''}";
1533
+ return [
1534
+ {
1535
+ type: "Image",
1536
+ url,
1537
+ $when: condition,
1538
+ },
1539
+ ];
1485
1540
  }
1486
1541
  }
1487
1542
  if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
@@ -1491,7 +1546,7 @@ class AdaptiveCardGenerator {
1491
1546
  }
1492
1547
  // Find the first array property in the response schema object with the well-known name
1493
1548
  static getResponseJsonPathFromSchema(schema) {
1494
- if (schema.type === "object" || (!schema.type && schema.properties)) {
1549
+ if (Utils.isObjectSchema(schema)) {
1495
1550
  const { properties } = schema;
1496
1551
  for (const property in properties) {
1497
1552
  const schema = properties[property];
@@ -1727,36 +1782,11 @@ class ManifestUpdater {
1727
1782
  for (const method in operations) {
1728
1783
  if (options.allowMethods.includes(method)) {
1729
1784
  const operationItem = operations[method];
1730
- const confirmationBodies = [];
1731
1785
  if (operationItem) {
1732
1786
  const operationId = operationItem.operationId;
1733
1787
  const safeFunctionName = operationId.replace(/[^a-zA-Z0-9]/g, "_");
1734
1788
  const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
1735
1789
  const summary = operationItem.summary;
1736
- const paramObject = operationItem.parameters;
1737
- const requestBody = operationItem.requestBody;
1738
- if (paramObject) {
1739
- for (let i = 0; i < paramObject.length; i++) {
1740
- const param = paramObject[i];
1741
- const schema = param.schema;
1742
- ManifestUpdater.checkSchema(schema, method, pathUrl);
1743
- confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
1744
- }
1745
- }
1746
- if (requestBody) {
1747
- const requestJsonBody = requestBody.content["application/json"];
1748
- const requestBodySchema = requestJsonBody.schema;
1749
- if (requestBodySchema.type === "object") {
1750
- for (const property in requestBodySchema.properties) {
1751
- const schema = requestBodySchema.properties[property];
1752
- ManifestUpdater.checkSchema(schema, method, pathUrl);
1753
- confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
1754
- }
1755
- }
1756
- else {
1757
- throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), exports.ErrorType.UpdateManifestFailed);
1758
- }
1759
- }
1760
1790
  let funcDescription = operationItem.description || operationItem.summary || "";
1761
1791
  if (funcDescription.length > ConstantString.FunctionDescriptionMaxLens) {
1762
1792
  warnings.push({
@@ -1774,8 +1804,7 @@ class ManifestUpdater {
1774
1804
  try {
1775
1805
  const { json } = Utils.getResponseJson(operationItem);
1776
1806
  if (json.schema) {
1777
- const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
1778
- card.body = Utils.limitACBodyProperties(card.body, 5);
1807
+ const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
1779
1808
  const responseSemantic = wrapResponseSemantics(card, jsonPath);
1780
1809
  funcObj.capabilities = {
1781
1810
  response_semantics: responseSemantic,
@@ -1791,14 +1820,39 @@ class ManifestUpdater {
1791
1820
  }
1792
1821
  }
1793
1822
  if (options.allowConfirmation && method !== ConstantString.GetMethod) {
1794
- if (!funcObj.capabilities) {
1795
- funcObj.capabilities = {};
1823
+ const paramObject = operationItem.parameters;
1824
+ const requestBody = operationItem.requestBody;
1825
+ const confirmationBodies = [];
1826
+ if (paramObject) {
1827
+ for (let i = 0; i < paramObject.length; i++) {
1828
+ const param = paramObject[i];
1829
+ const schema = param.schema;
1830
+ ManifestUpdater.checkSchema(schema, method, pathUrl);
1831
+ confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
1832
+ }
1833
+ }
1834
+ if (requestBody) {
1835
+ const requestJsonBody = Utils.getJsonContentType(requestBody);
1836
+ const requestBodySchema = requestJsonBody.schema;
1837
+ if (Utils.isObjectSchema(requestBodySchema)) {
1838
+ for (const property in requestBodySchema.properties) {
1839
+ const schema = requestBodySchema.properties[property];
1840
+ ManifestUpdater.checkSchema(schema, method, pathUrl);
1841
+ confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
1842
+ }
1843
+ }
1844
+ else {
1845
+ throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), exports.ErrorType.UpdateManifestFailed);
1846
+ }
1796
1847
  }
1797
- funcObj.capabilities.confirmation = {
1798
- type: "AdaptiveCard",
1799
- title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
1800
- };
1801
1848
  if (confirmationBodies.length > 0) {
1849
+ if (!funcObj.capabilities) {
1850
+ funcObj.capabilities = {};
1851
+ }
1852
+ funcObj.capabilities.confirmation = {
1853
+ type: "AdaptiveCard",
1854
+ title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
1855
+ };
1802
1856
  funcObj.capabilities.confirmation.body = confirmationBodies.join("\n");
1803
1857
  }
1804
1858
  }
@@ -2248,6 +2302,24 @@ class SpecParser {
2248
2302
  const newUnResolvedSpec = newSpecs[0];
2249
2303
  const newSpec = newSpecs[1];
2250
2304
  const authInfo = Utils.getAuthInfo(newSpec);
2305
+ const paths = newUnResolvedSpec.paths;
2306
+ for (const pathUrl in paths) {
2307
+ const operations = paths[pathUrl];
2308
+ for (const method in operations) {
2309
+ const operationItem = operations[method];
2310
+ const operationId = operationItem.operationId;
2311
+ const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
2312
+ if (!containsSpecialCharacters) {
2313
+ continue;
2314
+ }
2315
+ operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
2316
+ result.warnings.push({
2317
+ type: exports.WarningType.OperationIdContainsSpecialCharacters,
2318
+ content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
2319
+ data: operationId,
2320
+ });
2321
+ }
2322
+ }
2251
2323
  yield this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
2252
2324
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
2253
2325
  throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
@@ -2301,13 +2373,14 @@ class SpecParser {
2301
2373
  if (this.options.allowMethods.includes(method)) {
2302
2374
  const operation = newSpec.paths[url][method];
2303
2375
  try {
2304
- const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
2376
+ const [card, jsonPath, jsonData, warnings] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
2377
+ result.warnings.push(...warnings);
2305
2378
  const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
2306
2379
  const fileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
2307
2380
  const wrappedCard = wrapAdaptiveCard(card, jsonPath);
2308
2381
  yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
2309
2382
  const dataFileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
2310
- yield fs__default['default'].outputJSON(dataFileName, {}, { spaces: 2 });
2383
+ yield fs__default['default'].outputJSON(dataFileName, jsonData, { spaces: 2 });
2311
2384
  }
2312
2385
  catch (err) {
2313
2386
  result.allSuccess = false;