@microsoft/m365-spec-parser 0.2.3-alpha.86ff45725.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.
@@ -35,8 +35,6 @@ var ErrorType;
35
35
  ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
36
36
  ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
37
37
  ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
38
- ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
39
- ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
40
38
  ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
41
39
  ErrorType["NoParameter"] = "no-parameter";
42
40
  ErrorType["NoAPIInfo"] = "no-api-info";
@@ -112,7 +110,7 @@ ConstantString.WrappedCardResponseLayout = "list";
112
110
  ConstantString.GetMethod = "get";
113
111
  ConstantString.PostMethod = "post";
114
112
  ConstantString.AdaptiveCardVersion = "1.5";
115
- ConstantString.AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json";
113
+ ConstantString.AdaptiveCardSchema = "https://adaptivecards.io/schemas/adaptive-card.json";
116
114
  ConstantString.AdaptiveCardType = "AdaptiveCard";
117
115
  ConstantString.TextBlockType = "TextBlock";
118
116
  ConstantString.ImageType = "Image";
@@ -191,17 +189,6 @@ ConstantString.PluginManifestSchema = "https://developer.microsoft.com/json-sche
191
189
 
192
190
  // Copyright (c) Microsoft Corporation.
193
191
  class Utils {
194
- static hasNestedObjectInSchema(schema) {
195
- if (this.isObjectSchema(schema)) {
196
- for (const property in schema.properties) {
197
- const nestedSchema = schema.properties[property];
198
- if (this.isObjectSchema(nestedSchema)) {
199
- return true;
200
- }
201
- }
202
- }
203
- return false;
204
- }
205
192
  static isObjectSchema(schema) {
206
193
  return schema.type === "object" || (!schema.type && !!schema.properties);
207
194
  }
@@ -271,27 +258,33 @@ class Utils {
271
258
  let multipleMediaType = false;
272
259
  for (const code of ConstantString.ResponseCodeFor20X) {
273
260
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
274
- if (responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) {
275
- for (const contentType of Object.keys(responseObject.content)) {
276
- // json media type can also be "application/json; charset=utf-8"
277
- if (contentType.indexOf("application/json") >= 0) {
278
- multipleMediaType = false;
279
- json = responseObject.content[contentType];
280
- if (Utils.containMultipleMediaTypes(responseObject)) {
281
- multipleMediaType = true;
282
- if (!allowMultipleMediaType) {
283
- json = {};
284
- }
285
- }
286
- else {
287
- return { json, multipleMediaType };
288
- }
289
- }
290
- }
261
+ if (!responseObject) {
262
+ continue;
263
+ }
264
+ multipleMediaType = Utils.containMultipleMediaTypes(responseObject);
265
+ if (!allowMultipleMediaType && multipleMediaType) {
266
+ json = {};
267
+ continue;
268
+ }
269
+ const mediaObj = Utils.getJsonContentType(responseObject);
270
+ if (Object.keys(mediaObj).length > 0) {
271
+ json = mediaObj;
272
+ return { json, multipleMediaType };
291
273
  }
292
274
  }
293
275
  return { json, multipleMediaType };
294
276
  }
277
+ static getJsonContentType(responseObject) {
278
+ if (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
+ return responseObject.content[contentType];
283
+ }
284
+ }
285
+ }
286
+ return {};
287
+ }
295
288
  static convertPathToCamelCase(path) {
296
289
  const pathSegments = path.split(/[./{]/);
297
290
  const camelCaseSegments = pathSegments.map((segment) => {
@@ -327,7 +320,7 @@ class Utils {
327
320
  }
328
321
  return newStr;
329
322
  }
330
- static checkServerUrl(servers) {
323
+ static checkServerUrl(servers, allowHttp = false) {
331
324
  const errors = [];
332
325
  let serverUrl;
333
326
  try {
@@ -350,8 +343,7 @@ class Utils {
350
343
  data: servers,
351
344
  });
352
345
  }
353
- else if (protocol !== "https:") {
354
- // Http server url is not supported
346
+ else if (protocol !== "https:" && !(protocol === "http:" && allowHttp)) {
355
347
  const protocolString = protocol.slice(0, -1);
356
348
  errors.push({
357
349
  type: ErrorType.UrlProtocolNotSupported,
@@ -367,10 +359,11 @@ class Utils {
367
359
  let hasTopLevelServers = false;
368
360
  let hasPathLevelServers = false;
369
361
  let hasOperationLevelServers = false;
362
+ const allowHttp = options.projectType === ProjectType.Copilot;
370
363
  if (spec.servers && spec.servers.length >= 1) {
371
364
  hasTopLevelServers = true;
372
365
  // for multiple server, we only use the first url
373
- const serverErrors = Utils.checkServerUrl(spec.servers);
366
+ const serverErrors = Utils.checkServerUrl(spec.servers, allowHttp);
374
367
  errors.push(...serverErrors);
375
368
  }
376
369
  const paths = spec.paths;
@@ -378,7 +371,7 @@ class Utils {
378
371
  const methods = paths[path];
379
372
  if ((methods === null || methods === void 0 ? void 0 : methods.servers) && methods.servers.length >= 1) {
380
373
  hasPathLevelServers = true;
381
- const serverErrors = Utils.checkServerUrl(methods.servers);
374
+ const serverErrors = Utils.checkServerUrl(methods.servers, allowHttp);
382
375
  errors.push(...serverErrors);
383
376
  }
384
377
  for (const method in methods) {
@@ -386,7 +379,7 @@ class Utils {
386
379
  if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
387
380
  if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
388
381
  hasOperationLevelServers = true;
389
- const serverErrors = Utils.checkServerUrl(operationObject.servers);
382
+ const serverErrors = Utils.checkServerUrl(operationObject.servers, allowHttp);
390
383
  errors.push(...serverErrors);
391
384
  }
392
385
  }
@@ -699,8 +692,8 @@ class Validator {
699
692
  result.reason.push(ErrorType.NoServerInformation);
700
693
  }
701
694
  else {
702
- // server url should be absolute url with https protocol
703
- const serverValidateResult = Utils.checkServerUrl([serverObj]);
695
+ const allowHttp = this.projectType === ProjectType.Copilot;
696
+ const serverValidateResult = Utils.checkServerUrl([serverObj], allowHttp);
704
697
  result.reason.push(...serverValidateResult.map((item) => item.type));
705
698
  }
706
699
  return result;
@@ -748,11 +741,6 @@ class Validator {
748
741
  }
749
742
  const isRequiredWithoutDefault = isRequired && schema.default === undefined;
750
743
  const isCopilot = this.projectType === ProjectType.Copilot;
751
- if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
752
- paramResult.isValid = false;
753
- paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
754
- return paramResult;
755
- }
756
744
  if (schema.type === "string" ||
757
745
  schema.type === "integer" ||
758
746
  schema.type === "boolean" ||
@@ -800,11 +788,6 @@ class Validator {
800
788
  for (let i = 0; i < paramObject.length; i++) {
801
789
  const param = paramObject[i];
802
790
  const schema = param.schema;
803
- if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
804
- paramResult.isValid = false;
805
- paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
806
- continue;
807
- }
808
791
  const isRequiredWithoutDefault = param.required && schema.default === undefined;
809
792
  if (isCopilot) {
810
793
  if (isRequiredWithoutDefault) {
@@ -1277,15 +1260,152 @@ class SpecParser {
1277
1260
  }
1278
1261
  }
1279
1262
 
1263
+ // Copyright (c) Microsoft Corporation.
1264
+ class JsonDataGenerator {
1265
+ static generate(schema) {
1266
+ return this.generateMockData(schema);
1267
+ }
1268
+ static generateMockData(schema) {
1269
+ if (this.visitedSchemas.has(schema)) {
1270
+ return null; // Prevent circular reference
1271
+ }
1272
+ this.visitedSchemas.add(schema);
1273
+ let result;
1274
+ if (schema.anyOf) {
1275
+ // Select the first schema in anyOf
1276
+ const selectedSchema = schema.anyOf[0];
1277
+ result = this.generateMockData(selectedSchema);
1278
+ }
1279
+ else if (schema.oneOf) {
1280
+ // Select the first schema in oneOf
1281
+ const selectedSchema = schema.oneOf[0];
1282
+ result = this.generateMockData(selectedSchema);
1283
+ }
1284
+ else if (schema.allOf) {
1285
+ // merge all schemas in allOf
1286
+ result = {};
1287
+ for (const subschema of schema.allOf) {
1288
+ const data = this.generateMockData(subschema);
1289
+ result = Object.assign(Object.assign({}, result), data);
1290
+ }
1291
+ }
1292
+ else {
1293
+ switch (schema.type) {
1294
+ case "string":
1295
+ if (schema.example !== undefined) {
1296
+ result = schema.example;
1297
+ }
1298
+ else if (schema.format) {
1299
+ switch (schema.format) {
1300
+ case "date-time":
1301
+ result = "2024-11-01T05:25:43.593Z";
1302
+ break;
1303
+ case "email":
1304
+ result = "example@example.com";
1305
+ break;
1306
+ case "uuid":
1307
+ result = "123e4567-e89b-12d3-a456-426614174000";
1308
+ break;
1309
+ case "ipv4":
1310
+ result = "192.168.0.1";
1311
+ break;
1312
+ case "ipv6":
1313
+ result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
1314
+ break;
1315
+ default:
1316
+ result = "example string";
1317
+ }
1318
+ }
1319
+ else {
1320
+ result = "example string";
1321
+ }
1322
+ break;
1323
+ case "number":
1324
+ if (schema.example !== undefined) {
1325
+ result = schema.example;
1326
+ }
1327
+ else if (schema.format) {
1328
+ switch (schema.format) {
1329
+ case "float":
1330
+ result = 3.14;
1331
+ break;
1332
+ case "double":
1333
+ result = 3.14159;
1334
+ break;
1335
+ default:
1336
+ result = 123;
1337
+ }
1338
+ }
1339
+ else {
1340
+ result = 123;
1341
+ }
1342
+ break;
1343
+ case "integer":
1344
+ if (schema.example !== undefined) {
1345
+ result = schema.example;
1346
+ }
1347
+ else if (schema.format) {
1348
+ switch (schema.format) {
1349
+ case "int32":
1350
+ result = 123456;
1351
+ break;
1352
+ case "int64":
1353
+ result = 123456789;
1354
+ break;
1355
+ default:
1356
+ result = 123;
1357
+ }
1358
+ }
1359
+ else {
1360
+ result = 123;
1361
+ }
1362
+ break;
1363
+ case "boolean":
1364
+ result = schema.example !== undefined ? schema.example : true;
1365
+ break;
1366
+ case "array":
1367
+ result = [this.generateMockData(schema.items)];
1368
+ break;
1369
+ case "object":
1370
+ result = {};
1371
+ if (schema.properties) {
1372
+ for (const key in schema.properties) {
1373
+ result[key] = this.generateMockData(schema.properties[key]);
1374
+ }
1375
+ }
1376
+ break;
1377
+ default:
1378
+ result = schema.example || null;
1379
+ }
1380
+ }
1381
+ this.visitedSchemas.delete(schema);
1382
+ return result;
1383
+ }
1384
+ }
1385
+ JsonDataGenerator.visitedSchemas = new Set();
1386
+
1280
1387
  // Copyright (c) Microsoft Corporation.
1281
1388
  class AdaptiveCardGenerator {
1282
1389
  static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
1283
1390
  try {
1284
1391
  const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
1285
1392
  let cardBody = [];
1393
+ let jsonData = {};
1394
+ const warnings = [];
1395
+ const operationId = operationItem.operationId;
1286
1396
  let schema = json.schema;
1287
1397
  let jsonPath = "$";
1288
1398
  if (schema && Object.keys(schema).length > 0) {
1399
+ try {
1400
+ jsonData = JsonDataGenerator.generate(schema);
1401
+ }
1402
+ catch (err) {
1403
+ warnings.push({
1404
+ type: WarningType.GenerateJsonDataFailed,
1405
+ content: Utils.format(ConstantString.GenerateJsonDataFailed, operationId, err.toString()),
1406
+ data: operationId,
1407
+ });
1408
+ }
1289
1409
  jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
1290
1410
  if (jsonPath !== "$") {
1291
1411
  schema = schema.properties[jsonPath];
@@ -1318,7 +1438,7 @@ class AdaptiveCardGenerator {
1318
1438
  version: ConstantString.AdaptiveCardVersion,
1319
1439
  body: cardBody,
1320
1440
  };
1321
- return [fullCard, jsonPath];
1441
+ return [fullCard, jsonPath, jsonData, warnings];
1322
1442
  }
1323
1443
  catch (err) {
1324
1444
  throw new SpecParserError(err.toString(), ErrorType.GenerateAdaptiveCardFailed);