@microsoft/m365-spec-parser 0.2.3-alpha.09af212fe.0 → 0.2.3-alpha.1e0763330.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.
@@ -41,8 +41,6 @@ var ErrorType;
41
41
  ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
42
42
  ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
43
43
  ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
44
- ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
45
- ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
46
44
  ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
47
45
  ErrorType["NoParameter"] = "no-parameter";
48
46
  ErrorType["NoAPIInfo"] = "no-api-info";
@@ -62,6 +60,7 @@ var WarningType;
62
60
  WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
63
61
  WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
64
62
  WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
63
+ WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
65
64
  WarningType["Unknown"] = "unknown";
66
65
  })(WarningType || (WarningType = {}));
67
66
  /**
@@ -102,6 +101,7 @@ ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are u
102
101
  ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
103
102
  ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
104
103
  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.";
104
+ ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
105
105
  ConstantString.WrappedCardVersion = "devPreview";
106
106
  ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
107
107
  ConstantString.WrappedCardResponseLayout = "list";
@@ -195,17 +195,6 @@ class SpecParserError extends Error {
195
195
 
196
196
  // Copyright (c) Microsoft Corporation.
197
197
  class Utils {
198
- static hasNestedObjectInSchema(schema) {
199
- if (this.isObjectSchema(schema)) {
200
- for (const property in schema.properties) {
201
- const nestedSchema = schema.properties[property];
202
- if (this.isObjectSchema(nestedSchema)) {
203
- return true;
204
- }
205
- }
206
- }
207
- return false;
208
- }
209
198
  static isObjectSchema(schema) {
210
199
  return schema.type === "object" || (!schema.type && !!schema.properties);
211
200
  }
@@ -275,27 +264,33 @@ class Utils {
275
264
  let multipleMediaType = false;
276
265
  for (const code of ConstantString.ResponseCodeFor20X) {
277
266
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
278
- if (responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) {
279
- for (const contentType of Object.keys(responseObject.content)) {
280
- // json media type can also be "application/json; charset=utf-8"
281
- if (contentType.indexOf("application/json") >= 0) {
282
- multipleMediaType = false;
283
- json = responseObject.content[contentType];
284
- if (Utils.containMultipleMediaTypes(responseObject)) {
285
- multipleMediaType = true;
286
- if (!allowMultipleMediaType) {
287
- json = {};
288
- }
289
- }
290
- else {
291
- return { json, multipleMediaType };
292
- }
293
- }
294
- }
267
+ if (!responseObject) {
268
+ continue;
269
+ }
270
+ multipleMediaType = Utils.containMultipleMediaTypes(responseObject);
271
+ if (!allowMultipleMediaType && multipleMediaType) {
272
+ json = {};
273
+ continue;
274
+ }
275
+ const mediaObj = Utils.getJsonContentType(responseObject);
276
+ if (Object.keys(mediaObj).length > 0) {
277
+ json = mediaObj;
278
+ return { json, multipleMediaType };
295
279
  }
296
280
  }
297
281
  return { json, multipleMediaType };
298
282
  }
283
+ static getJsonContentType(responseObject) {
284
+ if (responseObject.content) {
285
+ for (const contentType of Object.keys(responseObject.content)) {
286
+ // json media type can also be "application/json; charset=utf-8"
287
+ if (contentType.indexOf("application/json") >= 0) {
288
+ return responseObject.content[contentType];
289
+ }
290
+ }
291
+ }
292
+ return {};
293
+ }
299
294
  static convertPathToCamelCase(path) {
300
295
  const pathSegments = path.split(/[./{]/);
301
296
  const camelCaseSegments = pathSegments.map((segment) => {
@@ -752,11 +747,6 @@ class Validator {
752
747
  }
753
748
  const isRequiredWithoutDefault = isRequired && schema.default === undefined;
754
749
  const isCopilot = this.projectType === ProjectType.Copilot;
755
- if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
756
- paramResult.isValid = false;
757
- paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
758
- return paramResult;
759
- }
760
750
  if (schema.type === "string" ||
761
751
  schema.type === "integer" ||
762
752
  schema.type === "boolean" ||
@@ -804,11 +794,6 @@ class Validator {
804
794
  for (let i = 0; i < paramObject.length; i++) {
805
795
  const param = paramObject[i];
806
796
  const schema = param.schema;
807
- if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
808
- paramResult.isValid = false;
809
- paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
810
- continue;
811
- }
812
797
  const isRequiredWithoutDefault = param.required && schema.default === undefined;
813
798
  if (isCopilot) {
814
799
  if (isRequiredWithoutDefault) {
@@ -1283,15 +1268,152 @@ class SpecFilter {
1283
1268
  }
1284
1269
  }
1285
1270
 
1271
+ // Copyright (c) Microsoft Corporation.
1272
+ class JsonDataGenerator {
1273
+ static generate(schema) {
1274
+ return this.generateMockData(schema);
1275
+ }
1276
+ static generateMockData(schema) {
1277
+ if (this.visitedSchemas.has(schema)) {
1278
+ return null; // Prevent circular reference
1279
+ }
1280
+ this.visitedSchemas.add(schema);
1281
+ let result;
1282
+ if (schema.anyOf) {
1283
+ // Select the first schema in anyOf
1284
+ const selectedSchema = schema.anyOf[0];
1285
+ result = this.generateMockData(selectedSchema);
1286
+ }
1287
+ else if (schema.oneOf) {
1288
+ // Select the first schema in oneOf
1289
+ const selectedSchema = schema.oneOf[0];
1290
+ result = this.generateMockData(selectedSchema);
1291
+ }
1292
+ else if (schema.allOf) {
1293
+ // merge all schemas in allOf
1294
+ result = {};
1295
+ for (const subschema of schema.allOf) {
1296
+ const data = this.generateMockData(subschema);
1297
+ result = Object.assign(Object.assign({}, result), data);
1298
+ }
1299
+ }
1300
+ else {
1301
+ switch (schema.type) {
1302
+ case "string":
1303
+ if (schema.example !== undefined) {
1304
+ result = schema.example;
1305
+ }
1306
+ else if (schema.format) {
1307
+ switch (schema.format) {
1308
+ case "date-time":
1309
+ result = "2024-11-01T05:25:43.593Z";
1310
+ break;
1311
+ case "email":
1312
+ result = "example@example.com";
1313
+ break;
1314
+ case "uuid":
1315
+ result = "123e4567-e89b-12d3-a456-426614174000";
1316
+ break;
1317
+ case "ipv4":
1318
+ result = "192.168.0.1";
1319
+ break;
1320
+ case "ipv6":
1321
+ result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
1322
+ break;
1323
+ default:
1324
+ result = "example string";
1325
+ }
1326
+ }
1327
+ else {
1328
+ result = "example string";
1329
+ }
1330
+ break;
1331
+ case "number":
1332
+ if (schema.example !== undefined) {
1333
+ result = schema.example;
1334
+ }
1335
+ else if (schema.format) {
1336
+ switch (schema.format) {
1337
+ case "float":
1338
+ result = 3.14;
1339
+ break;
1340
+ case "double":
1341
+ result = 3.14159;
1342
+ break;
1343
+ default:
1344
+ result = 123;
1345
+ }
1346
+ }
1347
+ else {
1348
+ result = 123;
1349
+ }
1350
+ break;
1351
+ case "integer":
1352
+ if (schema.example !== undefined) {
1353
+ result = schema.example;
1354
+ }
1355
+ else if (schema.format) {
1356
+ switch (schema.format) {
1357
+ case "int32":
1358
+ result = 123456;
1359
+ break;
1360
+ case "int64":
1361
+ result = 123456789;
1362
+ break;
1363
+ default:
1364
+ result = 123;
1365
+ }
1366
+ }
1367
+ else {
1368
+ result = 123;
1369
+ }
1370
+ break;
1371
+ case "boolean":
1372
+ result = schema.example !== undefined ? schema.example : true;
1373
+ break;
1374
+ case "array":
1375
+ result = [this.generateMockData(schema.items)];
1376
+ break;
1377
+ case "object":
1378
+ result = {};
1379
+ if (schema.properties) {
1380
+ for (const key in schema.properties) {
1381
+ result[key] = this.generateMockData(schema.properties[key]);
1382
+ }
1383
+ }
1384
+ break;
1385
+ default:
1386
+ result = schema.example || null;
1387
+ }
1388
+ }
1389
+ this.visitedSchemas.delete(schema);
1390
+ return result;
1391
+ }
1392
+ }
1393
+ JsonDataGenerator.visitedSchemas = new Set();
1394
+
1286
1395
  // Copyright (c) Microsoft Corporation.
1287
1396
  class AdaptiveCardGenerator {
1288
1397
  static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
1289
1398
  try {
1290
1399
  const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
1291
1400
  let cardBody = [];
1401
+ let jsonData = {};
1402
+ const warnings = [];
1403
+ const operationId = operationItem.operationId;
1292
1404
  let schema = json.schema;
1293
1405
  let jsonPath = "$";
1294
1406
  if (schema && Object.keys(schema).length > 0) {
1407
+ try {
1408
+ jsonData = JsonDataGenerator.generate(schema);
1409
+ }
1410
+ catch (err) {
1411
+ warnings.push({
1412
+ type: WarningType.GenerateJsonDataFailed,
1413
+ content: Utils.format(ConstantString.GenerateJsonDataFailed, operationId, err.toString()),
1414
+ data: operationId,
1415
+ });
1416
+ }
1295
1417
  jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
1296
1418
  if (jsonPath !== "$") {
1297
1419
  schema = schema.properties[jsonPath];
@@ -1324,7 +1446,7 @@ class AdaptiveCardGenerator {
1324
1446
  version: ConstantString.AdaptiveCardVersion,
1325
1447
  body: cardBody,
1326
1448
  };
1327
- return [fullCard, jsonPath];
1449
+ return [fullCard, jsonPath, jsonData, warnings];
1328
1450
  }
1329
1451
  catch (err) {
1330
1452
  throw new SpecParserError(err.toString(), ErrorType.GenerateAdaptiveCardFailed);
@@ -1651,36 +1773,11 @@ class ManifestUpdater {
1651
1773
  for (const method in operations) {
1652
1774
  if (options.allowMethods.includes(method)) {
1653
1775
  const operationItem = operations[method];
1654
- const confirmationBodies = [];
1655
1776
  if (operationItem) {
1656
1777
  const operationId = operationItem.operationId;
1657
1778
  const safeFunctionName = operationId.replace(/[^a-zA-Z0-9]/g, "_");
1658
1779
  const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
1659
1780
  const summary = operationItem.summary;
1660
- const paramObject = operationItem.parameters;
1661
- const requestBody = operationItem.requestBody;
1662
- if (paramObject) {
1663
- for (let i = 0; i < paramObject.length; i++) {
1664
- const param = paramObject[i];
1665
- const schema = param.schema;
1666
- ManifestUpdater.checkSchema(schema, method, pathUrl);
1667
- confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
1668
- }
1669
- }
1670
- if (requestBody) {
1671
- const requestJsonBody = requestBody.content["application/json"];
1672
- const requestBodySchema = requestJsonBody.schema;
1673
- if (Utils.isObjectSchema(requestBodySchema)) {
1674
- for (const property in requestBodySchema.properties) {
1675
- const schema = requestBodySchema.properties[property];
1676
- ManifestUpdater.checkSchema(schema, method, pathUrl);
1677
- confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
1678
- }
1679
- }
1680
- else {
1681
- throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
1682
- }
1683
- }
1684
1781
  let funcDescription = operationItem.description || operationItem.summary || "";
1685
1782
  if (funcDescription.length > ConstantString.FunctionDescriptionMaxLens) {
1686
1783
  warnings.push({
@@ -1714,14 +1811,39 @@ class ManifestUpdater {
1714
1811
  }
1715
1812
  }
1716
1813
  if (options.allowConfirmation && method !== ConstantString.GetMethod) {
1717
- if (!funcObj.capabilities) {
1718
- funcObj.capabilities = {};
1814
+ const paramObject = operationItem.parameters;
1815
+ const requestBody = operationItem.requestBody;
1816
+ const confirmationBodies = [];
1817
+ if (paramObject) {
1818
+ for (let i = 0; i < paramObject.length; i++) {
1819
+ const param = paramObject[i];
1820
+ const schema = param.schema;
1821
+ ManifestUpdater.checkSchema(schema, method, pathUrl);
1822
+ confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
1823
+ }
1824
+ }
1825
+ if (requestBody) {
1826
+ const requestJsonBody = Utils.getJsonContentType(requestBody);
1827
+ const requestBodySchema = requestJsonBody.schema;
1828
+ if (Utils.isObjectSchema(requestBodySchema)) {
1829
+ for (const property in requestBodySchema.properties) {
1830
+ const schema = requestBodySchema.properties[property];
1831
+ ManifestUpdater.checkSchema(schema, method, pathUrl);
1832
+ confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
1833
+ }
1834
+ }
1835
+ else {
1836
+ throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
1837
+ }
1719
1838
  }
1720
- funcObj.capabilities.confirmation = {
1721
- type: "AdaptiveCard",
1722
- title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
1723
- };
1724
1839
  if (confirmationBodies.length > 0) {
1840
+ if (!funcObj.capabilities) {
1841
+ funcObj.capabilities = {};
1842
+ }
1843
+ funcObj.capabilities.confirmation = {
1844
+ type: "AdaptiveCard",
1845
+ title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
1846
+ };
1725
1847
  funcObj.capabilities.confirmation.body = confirmationBodies.join("\n");
1726
1848
  }
1727
1849
  }
@@ -2228,13 +2350,14 @@ class SpecParser {
2228
2350
  if (this.options.allowMethods.includes(method)) {
2229
2351
  const operation = newSpec.paths[url][method];
2230
2352
  try {
2231
- const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
2353
+ const [card, jsonPath, jsonData, warnings] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
2354
+ result.warnings.push(...warnings);
2232
2355
  const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
2233
2356
  const fileName = path.join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
2234
2357
  const wrappedCard = wrapAdaptiveCard(card, jsonPath);
2235
2358
  await fs.outputJSON(fileName, wrappedCard, { spaces: 2 });
2236
2359
  const dataFileName = path.join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
2237
- await fs.outputJSON(dataFileName, {}, { spaces: 2 });
2360
+ await fs.outputJSON(dataFileName, jsonData, { spaces: 2 });
2238
2361
  }
2239
2362
  catch (err) {
2240
2363
  result.allSuccess = false;