@microsoft/m365-spec-parser 0.2.3-alpha.786f6c493.0 → 0.2.3-alpha.8abc127ff.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.
@@ -65,8 +65,6 @@ var ErrorType;
65
65
  ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
66
66
  ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
67
67
  ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
68
- ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
69
- ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
70
68
  ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
71
69
  ErrorType["NoParameter"] = "no-parameter";
72
70
  ErrorType["NoAPIInfo"] = "no-api-info";
@@ -142,7 +140,7 @@ ConstantString.WrappedCardResponseLayout = "list";
142
140
  ConstantString.GetMethod = "get";
143
141
  ConstantString.PostMethod = "post";
144
142
  ConstantString.AdaptiveCardVersion = "1.5";
145
- ConstantString.AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json";
143
+ ConstantString.AdaptiveCardSchema = "https://adaptivecards.io/schemas/adaptive-card.json";
146
144
  ConstantString.AdaptiveCardType = "AdaptiveCard";
147
145
  ConstantString.TextBlockType = "TextBlock";
148
146
  ConstantString.ImageType = "Image";
@@ -221,17 +219,6 @@ ConstantString.PluginManifestSchema = "https://developer.microsoft.com/json-sche
221
219
 
222
220
  // Copyright (c) Microsoft Corporation.
223
221
  class Utils {
224
- static hasNestedObjectInSchema(schema) {
225
- if (this.isObjectSchema(schema)) {
226
- for (const property in schema.properties) {
227
- const nestedSchema = schema.properties[property];
228
- if (this.isObjectSchema(nestedSchema)) {
229
- return true;
230
- }
231
- }
232
- }
233
- return false;
234
- }
235
222
  static isObjectSchema(schema) {
236
223
  return schema.type === "object" || (!schema.type && !!schema.properties);
237
224
  }
@@ -301,27 +288,33 @@ class Utils {
301
288
  let multipleMediaType = false;
302
289
  for (const code of ConstantString.ResponseCodeFor20X) {
303
290
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
304
- if (responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) {
305
- for (const contentType of Object.keys(responseObject.content)) {
306
- // json media type can also be "application/json; charset=utf-8"
307
- if (contentType.indexOf("application/json") >= 0) {
308
- multipleMediaType = false;
309
- json = responseObject.content[contentType];
310
- if (Utils.containMultipleMediaTypes(responseObject)) {
311
- multipleMediaType = true;
312
- if (!allowMultipleMediaType) {
313
- json = {};
314
- }
315
- }
316
- else {
317
- return { json, multipleMediaType };
318
- }
319
- }
320
- }
291
+ if (!responseObject) {
292
+ continue;
293
+ }
294
+ multipleMediaType = Utils.containMultipleMediaTypes(responseObject);
295
+ if (!allowMultipleMediaType && multipleMediaType) {
296
+ json = {};
297
+ continue;
298
+ }
299
+ const mediaObj = Utils.getJsonContentType(responseObject);
300
+ if (Object.keys(mediaObj).length > 0) {
301
+ json = mediaObj;
302
+ return { json, multipleMediaType };
321
303
  }
322
304
  }
323
305
  return { json, multipleMediaType };
324
306
  }
307
+ static getJsonContentType(responseObject) {
308
+ if (responseObject.content) {
309
+ for (const contentType of Object.keys(responseObject.content)) {
310
+ // json media type can also be "application/json; charset=utf-8"
311
+ if (contentType.indexOf("application/json") >= 0) {
312
+ return responseObject.content[contentType];
313
+ }
314
+ }
315
+ }
316
+ return {};
317
+ }
325
318
  static convertPathToCamelCase(path) {
326
319
  const pathSegments = path.split(/[./{]/);
327
320
  const camelCaseSegments = pathSegments.map((segment) => {
@@ -357,7 +350,7 @@ class Utils {
357
350
  }
358
351
  return newStr;
359
352
  }
360
- static checkServerUrl(servers) {
353
+ static checkServerUrl(servers, allowHttp = false) {
361
354
  const errors = [];
362
355
  let serverUrl;
363
356
  try {
@@ -380,8 +373,7 @@ class Utils {
380
373
  data: servers,
381
374
  });
382
375
  }
383
- else if (protocol !== "https:") {
384
- // Http server url is not supported
376
+ else if (protocol !== "https:" && !(protocol === "http:" && allowHttp)) {
385
377
  const protocolString = protocol.slice(0, -1);
386
378
  errors.push({
387
379
  type: ErrorType.UrlProtocolNotSupported,
@@ -397,10 +389,11 @@ class Utils {
397
389
  let hasTopLevelServers = false;
398
390
  let hasPathLevelServers = false;
399
391
  let hasOperationLevelServers = false;
392
+ const allowHttp = options.projectType === ProjectType.Copilot;
400
393
  if (spec.servers && spec.servers.length >= 1) {
401
394
  hasTopLevelServers = true;
402
395
  // for multiple server, we only use the first url
403
- const serverErrors = Utils.checkServerUrl(spec.servers);
396
+ const serverErrors = Utils.checkServerUrl(spec.servers, allowHttp);
404
397
  errors.push(...serverErrors);
405
398
  }
406
399
  const paths = spec.paths;
@@ -408,7 +401,7 @@ class Utils {
408
401
  const methods = paths[path];
409
402
  if ((methods === null || methods === void 0 ? void 0 : methods.servers) && methods.servers.length >= 1) {
410
403
  hasPathLevelServers = true;
411
- const serverErrors = Utils.checkServerUrl(methods.servers);
404
+ const serverErrors = Utils.checkServerUrl(methods.servers, allowHttp);
412
405
  errors.push(...serverErrors);
413
406
  }
414
407
  for (const method in methods) {
@@ -416,7 +409,7 @@ class Utils {
416
409
  if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
417
410
  if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
418
411
  hasOperationLevelServers = true;
419
- const serverErrors = Utils.checkServerUrl(operationObject.servers);
412
+ const serverErrors = Utils.checkServerUrl(operationObject.servers, allowHttp);
420
413
  errors.push(...serverErrors);
421
414
  }
422
415
  }
@@ -729,8 +722,8 @@ class Validator {
729
722
  result.reason.push(ErrorType.NoServerInformation);
730
723
  }
731
724
  else {
732
- // server url should be absolute url with https protocol
733
- const serverValidateResult = Utils.checkServerUrl([serverObj]);
725
+ const allowHttp = this.projectType === ProjectType.Copilot;
726
+ const serverValidateResult = Utils.checkServerUrl([serverObj], allowHttp);
734
727
  result.reason.push(...serverValidateResult.map((item) => item.type));
735
728
  }
736
729
  return result;
@@ -778,11 +771,6 @@ class Validator {
778
771
  }
779
772
  const isRequiredWithoutDefault = isRequired && schema.default === undefined;
780
773
  const isCopilot = this.projectType === ProjectType.Copilot;
781
- if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
782
- paramResult.isValid = false;
783
- paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
784
- return paramResult;
785
- }
786
774
  if (schema.type === "string" ||
787
775
  schema.type === "integer" ||
788
776
  schema.type === "boolean" ||
@@ -830,11 +818,6 @@ class Validator {
830
818
  for (let i = 0; i < paramObject.length; i++) {
831
819
  const param = paramObject[i];
832
820
  const schema = param.schema;
833
- if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
834
- paramResult.isValid = false;
835
- paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
836
- continue;
837
- }
838
821
  const isRequiredWithoutDefault = param.required && schema.default === undefined;
839
822
  if (isCopilot) {
840
823
  if (isRequiredWithoutDefault) {
@@ -1321,15 +1304,152 @@ class SpecParser {
1321
1304
  }
1322
1305
  }
1323
1306
 
1307
+ // Copyright (c) Microsoft Corporation.
1308
+ class JsonDataGenerator {
1309
+ static generate(schema) {
1310
+ return this.generateMockData(schema);
1311
+ }
1312
+ static generateMockData(schema) {
1313
+ if (this.visitedSchemas.has(schema)) {
1314
+ return null; // Prevent circular reference
1315
+ }
1316
+ this.visitedSchemas.add(schema);
1317
+ let result;
1318
+ if (schema.anyOf) {
1319
+ // Select the first schema in anyOf
1320
+ const selectedSchema = schema.anyOf[0];
1321
+ result = this.generateMockData(selectedSchema);
1322
+ }
1323
+ else if (schema.oneOf) {
1324
+ // Select the first schema in oneOf
1325
+ const selectedSchema = schema.oneOf[0];
1326
+ result = this.generateMockData(selectedSchema);
1327
+ }
1328
+ else if (schema.allOf) {
1329
+ // merge all schemas in allOf
1330
+ result = {};
1331
+ for (const subschema of schema.allOf) {
1332
+ const data = this.generateMockData(subschema);
1333
+ result = Object.assign(Object.assign({}, result), data);
1334
+ }
1335
+ }
1336
+ else {
1337
+ switch (schema.type) {
1338
+ case "string":
1339
+ if (schema.example !== undefined) {
1340
+ result = schema.example;
1341
+ }
1342
+ else if (schema.format) {
1343
+ switch (schema.format) {
1344
+ case "date-time":
1345
+ result = "2024-11-01T05:25:43.593Z";
1346
+ break;
1347
+ case "email":
1348
+ result = "example@example.com";
1349
+ break;
1350
+ case "uuid":
1351
+ result = "123e4567-e89b-12d3-a456-426614174000";
1352
+ break;
1353
+ case "ipv4":
1354
+ result = "192.168.0.1";
1355
+ break;
1356
+ case "ipv6":
1357
+ result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
1358
+ break;
1359
+ default:
1360
+ result = "example string";
1361
+ }
1362
+ }
1363
+ else {
1364
+ result = "example string";
1365
+ }
1366
+ break;
1367
+ case "number":
1368
+ if (schema.example !== undefined) {
1369
+ result = schema.example;
1370
+ }
1371
+ else if (schema.format) {
1372
+ switch (schema.format) {
1373
+ case "float":
1374
+ result = 3.14;
1375
+ break;
1376
+ case "double":
1377
+ result = 3.14159;
1378
+ break;
1379
+ default:
1380
+ result = 123;
1381
+ }
1382
+ }
1383
+ else {
1384
+ result = 123;
1385
+ }
1386
+ break;
1387
+ case "integer":
1388
+ if (schema.example !== undefined) {
1389
+ result = schema.example;
1390
+ }
1391
+ else if (schema.format) {
1392
+ switch (schema.format) {
1393
+ case "int32":
1394
+ result = 123456;
1395
+ break;
1396
+ case "int64":
1397
+ result = 123456789;
1398
+ break;
1399
+ default:
1400
+ result = 123;
1401
+ }
1402
+ }
1403
+ else {
1404
+ result = 123;
1405
+ }
1406
+ break;
1407
+ case "boolean":
1408
+ result = schema.example !== undefined ? schema.example : true;
1409
+ break;
1410
+ case "array":
1411
+ result = [this.generateMockData(schema.items)];
1412
+ break;
1413
+ case "object":
1414
+ result = {};
1415
+ if (schema.properties) {
1416
+ for (const key in schema.properties) {
1417
+ result[key] = this.generateMockData(schema.properties[key]);
1418
+ }
1419
+ }
1420
+ break;
1421
+ default:
1422
+ result = schema.example || null;
1423
+ }
1424
+ }
1425
+ this.visitedSchemas.delete(schema);
1426
+ return result;
1427
+ }
1428
+ }
1429
+ JsonDataGenerator.visitedSchemas = new Set();
1430
+
1324
1431
  // Copyright (c) Microsoft Corporation.
1325
1432
  class AdaptiveCardGenerator {
1326
1433
  static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
1327
1434
  try {
1328
1435
  const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
1329
1436
  let cardBody = [];
1437
+ let jsonData = {};
1438
+ const warnings = [];
1439
+ const operationId = operationItem.operationId;
1330
1440
  let schema = json.schema;
1331
1441
  let jsonPath = "$";
1332
1442
  if (schema && Object.keys(schema).length > 0) {
1443
+ try {
1444
+ jsonData = JsonDataGenerator.generate(schema);
1445
+ }
1446
+ catch (err) {
1447
+ warnings.push({
1448
+ type: WarningType.GenerateJsonDataFailed,
1449
+ content: Utils.format(ConstantString.GenerateJsonDataFailed, operationId, err.toString()),
1450
+ data: operationId,
1451
+ });
1452
+ }
1333
1453
  jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
1334
1454
  if (jsonPath !== "$") {
1335
1455
  schema = schema.properties[jsonPath];
@@ -1362,7 +1482,7 @@ class AdaptiveCardGenerator {
1362
1482
  version: ConstantString.AdaptiveCardVersion,
1363
1483
  body: cardBody,
1364
1484
  };
1365
- return [fullCard, jsonPath];
1485
+ return [fullCard, jsonPath, jsonData, warnings];
1366
1486
  }
1367
1487
  catch (err) {
1368
1488
  throw new SpecParserError(err.toString(), ErrorType.GenerateAdaptiveCardFailed);