@microsoft/m365-spec-parser 0.1.1-alpha.ebe783822.0 → 0.1.1-alpha.fb5afedc0.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.
@@ -15,7 +15,7 @@ var ErrorType;
15
15
  ErrorType["NoExtraAPICanBeAdded"] = "no-extra-api-can-be-added";
16
16
  ErrorType["ResolveServerUrlFailed"] = "resolve-server-url-failed";
17
17
  ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
18
- ErrorType["MultipleAPIKeyNotSupported"] = "multiple-api-key-not-supported";
18
+ ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
19
19
  ErrorType["ListFailed"] = "list-failed";
20
20
  ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
21
21
  ErrorType["FilterSpecFailed"] = "filter-spec-failed";
@@ -23,6 +23,7 @@ var ErrorType;
23
23
  ErrorType["GenerateAdaptiveCardFailed"] = "generate-adaptive-card-failed";
24
24
  ErrorType["GenerateFailed"] = "generate-failed";
25
25
  ErrorType["ValidateFailed"] = "validate-failed";
26
+ ErrorType["GetSpecFailed"] = "get-spec-failed";
26
27
  ErrorType["Cancelled"] = "cancelled";
27
28
  ErrorType["Unknown"] = "unknown";
28
29
  })(ErrorType || (ErrorType = {}));
@@ -45,7 +46,13 @@ var ValidationStatus;
45
46
  ValidationStatus[ValidationStatus["Valid"] = 0] = "Valid";
46
47
  ValidationStatus[ValidationStatus["Warning"] = 1] = "Warning";
47
48
  ValidationStatus[ValidationStatus["Error"] = 2] = "Error";
48
- })(ValidationStatus || (ValidationStatus = {}));
49
+ })(ValidationStatus || (ValidationStatus = {}));
50
+ var ProjectType;
51
+ (function (ProjectType) {
52
+ ProjectType[ProjectType["Copilot"] = 0] = "Copilot";
53
+ ProjectType[ProjectType["SME"] = 1] = "SME";
54
+ ProjectType[ProjectType["TeamsAi"] = 2] = "TeamsAi";
55
+ })(ProjectType || (ProjectType = {}));
49
56
 
50
57
  // Copyright (c) Microsoft Corporation.
51
58
  class SpecParserError extends Error {
@@ -72,7 +79,8 @@ ConstantString.ResolveServerUrlFailed = "Unable to resolve the server URL: pleas
72
79
  ConstantString.OperationOnlyContainsOptionalParam = "Operation %s contains multiple optional parameters. The first optional parameter is used for this command.";
73
80
  ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converted to OpenAPI 3.0.";
74
81
  ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
75
- ConstantString.MultipleAPIKeyNotSupported = "Multiple API keys are not supported. Please make sure that all selected APIs use the same API key.";
82
+ ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
83
+ ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
76
84
  ConstantString.WrappedCardVersion = "devPreview";
77
85
  ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
78
86
  ConstantString.WrappedCardResponseLayout = "list";
@@ -84,6 +92,7 @@ ConstantString.AdaptiveCardType = "AdaptiveCard";
84
92
  ConstantString.TextBlockType = "TextBlock";
85
93
  ConstantString.ContainerType = "Container";
86
94
  ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
95
+ ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
87
96
  ConstantString.ResponseCodeFor20X = [
88
97
  "200",
89
98
  "201",
@@ -143,11 +152,23 @@ ConstantString.FullDescriptionMaxLens = 4000;
143
152
  ConstantString.CommandDescriptionMaxLens = 128;
144
153
  ConstantString.ParameterDescriptionMaxLens = 128;
145
154
  ConstantString.CommandTitleMaxLens = 32;
146
- ConstantString.ParameterTitleMaxLens = 32;
155
+ ConstantString.ParameterTitleMaxLens = 32;
156
+ ConstantString.SMERequiredParamsMaxNum = 5;
147
157
 
148
158
  // Copyright (c) Microsoft Corporation.
149
159
  class Utils {
150
- static checkParameters(paramObject) {
160
+ static hasNestedObjectInSchema(schema) {
161
+ if (schema.type === "object") {
162
+ for (const property in schema.properties) {
163
+ const nestedSchema = schema.properties[property];
164
+ if (nestedSchema.type === "object") {
165
+ return true;
166
+ }
167
+ }
168
+ }
169
+ return false;
170
+ }
171
+ static checkParameters(paramObject, isCopilot) {
151
172
  const paramResult = {
152
173
  requiredNum: 0,
153
174
  optionalNum: 0,
@@ -159,7 +180,20 @@ class Utils {
159
180
  for (let i = 0; i < paramObject.length; i++) {
160
181
  const param = paramObject[i];
161
182
  const schema = param.schema;
183
+ if (isCopilot && this.hasNestedObjectInSchema(schema)) {
184
+ paramResult.isValid = false;
185
+ continue;
186
+ }
162
187
  const isRequiredWithoutDefault = param.required && schema.default === undefined;
188
+ if (isCopilot) {
189
+ if (isRequiredWithoutDefault) {
190
+ paramResult.requiredNum = paramResult.requiredNum + 1;
191
+ }
192
+ else {
193
+ paramResult.optionalNum = paramResult.optionalNum + 1;
194
+ }
195
+ continue;
196
+ }
163
197
  if (param.in === "header" || param.in === "cookie") {
164
198
  if (isRequiredWithoutDefault) {
165
199
  paramResult.isValid = false;
@@ -186,7 +220,7 @@ class Utils {
186
220
  }
187
221
  return paramResult;
188
222
  }
189
- static checkPostBody(schema, isRequired = false) {
223
+ static checkPostBody(schema, isRequired = false, isCopilot = false) {
190
224
  var _a;
191
225
  const paramResult = {
192
226
  requiredNum: 0,
@@ -197,6 +231,10 @@ class Utils {
197
231
  return paramResult;
198
232
  }
199
233
  const isRequiredWithoutDefault = isRequired && schema.default === undefined;
234
+ if (isCopilot && this.hasNestedObjectInSchema(schema)) {
235
+ paramResult.isValid = false;
236
+ return paramResult;
237
+ }
200
238
  if (schema.type === "string" ||
201
239
  schema.type === "integer" ||
202
240
  schema.type === "boolean" ||
@@ -215,19 +253,22 @@ class Utils {
215
253
  if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
216
254
  isRequired = true;
217
255
  }
218
- const result = Utils.checkPostBody(properties[property], isRequired);
256
+ const result = Utils.checkPostBody(properties[property], isRequired, isCopilot);
219
257
  paramResult.requiredNum += result.requiredNum;
220
258
  paramResult.optionalNum += result.optionalNum;
221
259
  paramResult.isValid = paramResult.isValid && result.isValid;
222
260
  }
223
261
  }
224
262
  else {
225
- if (isRequiredWithoutDefault) {
263
+ if (isRequiredWithoutDefault && !isCopilot) {
226
264
  paramResult.isValid = false;
227
265
  }
228
266
  }
229
267
  return paramResult;
230
268
  }
269
+ static containMultipleMediaTypes(bodyObject) {
270
+ return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
271
+ }
231
272
  /**
232
273
  * Checks if the given API is supported.
233
274
  * @param {string} method - The HTTP method of the API.
@@ -242,32 +283,40 @@ class Utils {
242
283
  * 5. response body should be “application/json” and not empty, and response code should be 20X
243
284
  * 6. only support request body with “application/json” content type
244
285
  */
245
- static isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
286
+ static isSupportedApi(method, path, spec, options) {
287
+ var _a;
246
288
  const pathObj = spec.paths[path];
247
289
  method = method.toLocaleLowerCase();
248
290
  if (pathObj) {
249
- if ((method === ConstantString.PostMethod || method === ConstantString.GetMethod) &&
250
- pathObj[method]) {
291
+ if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && pathObj[method]) {
251
292
  const securities = pathObj[method].security;
252
- const authArray = Utils.getAuthArray(securities, spec);
253
- if (!Utils.isSupportedAuth(authArray, allowAPIKeyAuth, allowOauth2)) {
254
- return false;
293
+ const isTeamsAi = options.projectType === ProjectType.TeamsAi;
294
+ const isCopilot = options.projectType === ProjectType.Copilot;
295
+ // Teams AI project doesn't care about auth, it will use authProvider for user to implement
296
+ if (!isTeamsAi) {
297
+ const authArray = Utils.getAuthArray(securities, spec);
298
+ if (!Utils.isSupportedAuth(authArray, options)) {
299
+ return false;
300
+ }
255
301
  }
256
302
  const operationObject = pathObj[method];
257
- if (!allowMissingId && !operationObject.operationId) {
303
+ if (!options.allowMissingId && !operationObject.operationId) {
258
304
  return false;
259
305
  }
260
306
  const paramObject = operationObject.parameters;
261
307
  const requestBody = operationObject.requestBody;
262
308
  const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
263
- const mediaTypesCount = Object.keys((requestBody === null || requestBody === void 0 ? void 0 : requestBody.content) || {}).length;
264
- if (mediaTypesCount > 1) {
309
+ if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
265
310
  return false;
266
311
  }
267
- const responseJson = Utils.getResponseJson(operationObject);
312
+ const responseJson = Utils.getResponseJson(operationObject, isTeamsAi);
268
313
  if (Object.keys(responseJson).length === 0) {
269
314
  return false;
270
315
  }
316
+ // Teams AI project doesn't care about request parameters/body
317
+ if (isTeamsAi) {
318
+ return true;
319
+ }
271
320
  let requestBodyParamResult = {
272
321
  requiredNum: 0,
273
322
  optionalNum: 0,
@@ -275,18 +324,26 @@ class Utils {
275
324
  };
276
325
  if (requestJsonBody) {
277
326
  const requestBodySchema = requestJsonBody.schema;
278
- requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required);
327
+ if (isCopilot && requestBodySchema.type !== "object") {
328
+ return false;
329
+ }
330
+ requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
279
331
  }
280
332
  if (!requestBodyParamResult.isValid) {
281
333
  return false;
282
334
  }
283
- const paramResult = Utils.checkParameters(paramObject);
335
+ const paramResult = Utils.checkParameters(paramObject, isCopilot);
284
336
  if (!paramResult.isValid) {
285
337
  return false;
286
338
  }
339
+ // Copilot support arbitrary parameters
340
+ if (isCopilot) {
341
+ return true;
342
+ }
287
343
  if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
288
- if (allowMultipleParameters &&
289
- requestBodyParamResult.requiredNum + paramResult.requiredNum <= 5) {
344
+ if (options.allowMultipleParameters &&
345
+ requestBodyParamResult.requiredNum + paramResult.requiredNum <=
346
+ ConstantString.SMERequiredParamsMaxNum) {
290
347
  return true;
291
348
  }
292
349
  return false;
@@ -305,29 +362,20 @@ class Utils {
305
362
  }
306
363
  return false;
307
364
  }
308
- static isSupportedAuth(authSchemaArray, allowAPIKeyAuth, allowOauth2) {
309
- if (authSchemaArray.length === 0) {
365
+ static isSupportedAuth(authSchemeArray, options) {
366
+ if (authSchemeArray.length === 0) {
310
367
  return true;
311
368
  }
312
- if (allowAPIKeyAuth || allowOauth2) {
369
+ if (options.allowAPIKeyAuth || options.allowOauth2 || options.allowBearerTokenAuth) {
313
370
  // Currently we don't support multiple auth in one operation
314
- if (authSchemaArray.length > 0 && authSchemaArray.every((auths) => auths.length > 1)) {
371
+ if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
315
372
  return false;
316
373
  }
317
- for (const auths of authSchemaArray) {
374
+ for (const auths of authSchemeArray) {
318
375
  if (auths.length === 1) {
319
- if (!allowOauth2 && allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authSchema)) {
320
- return true;
321
- }
322
- else if (!allowAPIKeyAuth &&
323
- allowOauth2 &&
324
- Utils.isBearerTokenAuth(auths[0].authSchema)) {
325
- return true;
326
- }
327
- else if (allowAPIKeyAuth &&
328
- allowOauth2 &&
329
- (Utils.isAPIKeyAuth(auths[0].authSchema) ||
330
- Utils.isBearerTokenAuth(auths[0].authSchema))) {
376
+ if ((options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
377
+ (options.allowOauth2 && Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme)) ||
378
+ (options.allowBearerTokenAuth && Utils.isBearerTokenAuth(auths[0].authScheme))) {
331
379
  return true;
332
380
  }
333
381
  }
@@ -335,13 +383,17 @@ class Utils {
335
383
  }
336
384
  return false;
337
385
  }
338
- static isAPIKeyAuth(authSchema) {
339
- return authSchema.type === "apiKey";
386
+ static isBearerTokenAuth(authScheme) {
387
+ return authScheme.type === "http" && authScheme.scheme === "bearer";
340
388
  }
341
- static isBearerTokenAuth(authSchema) {
342
- return (authSchema.type === "oauth2" ||
343
- authSchema.type === "openIdConnect" ||
344
- (authSchema.type === "http" && authSchema.scheme === "bearer"));
389
+ static isAPIKeyAuth(authScheme) {
390
+ return authScheme.type === "apiKey";
391
+ }
392
+ static isOAuthWithAuthCodeFlow(authScheme) {
393
+ if (authScheme.type === "oauth2" && authScheme.flows && authScheme.flows.authorizationCode) {
394
+ return true;
395
+ }
396
+ return false;
345
397
  }
346
398
  static getAuthArray(securities, spec) {
347
399
  var _a;
@@ -354,7 +406,7 @@ class Utils {
354
406
  for (const name in security) {
355
407
  const auth = securitySchemas[name];
356
408
  authArray.push({
357
- authSchema: auth,
409
+ authScheme: auth,
358
410
  name: name,
359
411
  });
360
412
  }
@@ -369,18 +421,19 @@ class Utils {
369
421
  static updateFirstLetter(str) {
370
422
  return str.charAt(0).toUpperCase() + str.slice(1);
371
423
  }
372
- static getResponseJson(operationObject) {
424
+ static getResponseJson(operationObject, isTeamsAiProject = false) {
373
425
  var _a, _b;
374
426
  let json = {};
375
427
  for (const code of ConstantString.ResponseCodeFor20X) {
376
428
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
377
- const mediaTypesCount = Object.keys((responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) || {}).length;
378
- if (mediaTypesCount > 1) {
379
- return {};
380
- }
381
429
  if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
382
430
  json = responseObject.content["application/json"];
383
- break;
431
+ if (!isTeamsAiProject && Utils.containMultipleMediaTypes(responseObject)) {
432
+ json = {};
433
+ }
434
+ else {
435
+ break;
436
+ }
384
437
  }
385
438
  }
386
439
  return json;
@@ -454,7 +507,7 @@ class Utils {
454
507
  }
455
508
  return errors;
456
509
  }
457
- static validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
510
+ static validateServer(spec, options) {
458
511
  const errors = [];
459
512
  let hasTopLevelServers = false;
460
513
  let hasPathLevelServers = false;
@@ -475,7 +528,7 @@ class Utils {
475
528
  }
476
529
  for (const method in methods) {
477
530
  const operationObject = methods[method];
478
- if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
531
+ if (Utils.isSupportedApi(method, path, spec, options)) {
479
532
  if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
480
533
  hasOperationLevelServers = true;
481
534
  const serverErrors = Utils.checkServerUrl(operationObject.servers);
@@ -518,6 +571,7 @@ class Utils {
518
571
  Utils.updateParameterWithInputType(schema, parameter);
519
572
  }
520
573
  if (isRequired && schema.default === undefined) {
574
+ parameter.isRequired = true;
521
575
  requiredParams.push(parameter);
522
576
  }
523
577
  else {
@@ -562,7 +616,7 @@ class Utils {
562
616
  param.value = schema.default;
563
617
  }
564
618
  }
565
- static parseApiInfo(operationItem, allowMultipleParameters) {
619
+ static parseApiInfo(operationItem, options) {
566
620
  var _a, _b;
567
621
  const requiredParams = [];
568
622
  const optionalParams = [];
@@ -576,11 +630,12 @@ class Utils {
576
630
  description: ((_a = param.description) !== null && _a !== void 0 ? _a : "").slice(0, ConstantString.ParameterDescriptionMaxLens),
577
631
  };
578
632
  const schema = param.schema;
579
- if (allowMultipleParameters && schema) {
633
+ if (options.allowMultipleParameters && schema) {
580
634
  Utils.updateParameterWithInputType(schema, parameter);
581
635
  }
582
636
  if (param.in !== "header" && param.in !== "cookie") {
583
637
  if (param.required && (schema === null || schema === void 0 ? void 0 : schema.default) === undefined) {
638
+ parameter.isRequired = true;
584
639
  requiredParams.push(parameter);
585
640
  }
586
641
  else {
@@ -594,7 +649,7 @@ class Utils {
594
649
  const requestJson = requestBody.content["application/json"];
595
650
  if (Object.keys(requestJson).length !== 0) {
596
651
  const schema = requestJson.schema;
597
- const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", allowMultipleParameters, requestBody.required);
652
+ const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", !!options.allowMultipleParameters, requestBody.required);
598
653
  requiredParams.push(...requiredP);
599
654
  optionalParams.push(...optionalP);
600
655
  }
@@ -625,14 +680,13 @@ class Utils {
625
680
  }
626
681
  return [command, warning];
627
682
  }
628
- static listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
683
+ static listSupportedAPIs(spec, options) {
629
684
  const paths = spec.paths;
630
685
  const result = {};
631
686
  for (const path in paths) {
632
687
  const methods = paths[path];
633
688
  for (const method in methods) {
634
- // For developer preview, only support GET operation with only 1 parameter without auth
635
- if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
689
+ if (Utils.isSupportedApi(method, path, spec, options)) {
636
690
  const operationObject = methods[method];
637
691
  result[`${method.toUpperCase()} ${path}`] = operationObject;
638
692
  }
@@ -640,7 +694,7 @@ class Utils {
640
694
  }
641
695
  return result;
642
696
  }
643
- static validateSpec(spec, parser, isSwaggerFile, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
697
+ static validateSpec(spec, parser, isSwaggerFile, options) {
644
698
  const errors = [];
645
699
  const warnings = [];
646
700
  if (isSwaggerFile) {
@@ -650,7 +704,7 @@ class Utils {
650
704
  });
651
705
  }
652
706
  // Server validation
653
- const serverErrors = Utils.validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2);
707
+ const serverErrors = Utils.validateServer(spec, options);
654
708
  errors.push(...serverErrors);
655
709
  // Remote reference not supported
656
710
  const refPaths = parser.$refs.paths();
@@ -663,7 +717,7 @@ class Utils {
663
717
  });
664
718
  }
665
719
  // No supported API
666
- const apiMap = Utils.listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2);
720
+ const apiMap = Utils.listSupportedAPIs(spec, options);
667
721
  if (Object.keys(apiMap).length === 0) {
668
722
  errors.push({
669
723
  type: ErrorType.NoSupportedApi,
@@ -733,7 +787,10 @@ class SpecParser {
733
787
  allowSwagger: false,
734
788
  allowAPIKeyAuth: false,
735
789
  allowMultipleParameters: false,
790
+ allowBearerTokenAuth: false,
736
791
  allowOauth2: false,
792
+ allowMethods: ["get", "post"],
793
+ projectType: ProjectType.SME,
737
794
  };
738
795
  this.pathOrSpec = pathOrDoc;
739
796
  this.parser = new SwaggerParser();
@@ -770,7 +827,7 @@ class SpecParser {
770
827
  ],
771
828
  };
772
829
  }
773
- return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2);
830
+ return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options);
774
831
  }
775
832
  catch (err) {
776
833
  throw new SpecParserError(err.toString(), ErrorType.ValidateFailed);
@@ -789,7 +846,7 @@ class SpecParser {
789
846
  if (!operationId) {
790
847
  continue;
791
848
  }
792
- const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options.allowMultipleParameters);
849
+ const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options);
793
850
  const apiInfo = {
794
851
  method: method,
795
852
  path: path,
@@ -818,12 +875,32 @@ class SpecParser {
818
875
  async list() {
819
876
  throw new Error("Method not implemented.");
820
877
  }
878
+ /**
879
+ * Generate specs according to the filters.
880
+ * @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
881
+ */
882
+ // eslint-disable-next-line @typescript-eslint/require-await
883
+ async getFilteredSpecs(filter, signal) {
884
+ throw new Error("Method not implemented.");
885
+ }
886
+ /**
887
+ * Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
888
+ * @param manifestPath A file path of the Teams app manifest file to update.
889
+ * @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
890
+ * @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
891
+ * @param pluginFilePath File path of the api plugin file to generate.
892
+ */
893
+ // eslint-disable-next-line @typescript-eslint/require-await
894
+ async generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, signal) {
895
+ throw new Error("Method not implemented.");
896
+ }
821
897
  /**
822
898
  * Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
823
899
  * @param manifestPath A file path of the Teams app manifest file to update.
824
900
  * @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
825
901
  * @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
826
902
  * @param adaptiveCardFolder Folder path where the Adaptive Card files will be generated. If not specified or empty, Adaptive Card files will not be generated.
903
+ * @param isMe Boolean that indicates whether the project is an Messaging Extension. For Messaging Extension, composeExtensions will be added in Teams app manifest.
827
904
  */
828
905
  // eslint-disable-next-line @typescript-eslint/require-await
829
906
  async generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal) {
@@ -843,11 +920,169 @@ class SpecParser {
843
920
  if (this.apiMap !== undefined) {
844
921
  return this.apiMap;
845
922
  }
846
- const result = Utils.listSupportedAPIs(spec, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2);
923
+ const result = Utils.listSupportedAPIs(spec, this.options);
847
924
  this.apiMap = result;
848
925
  return result;
849
926
  }
850
927
  }
851
928
 
852
- export { ConstantString, ErrorType, SpecParser, SpecParserError, Utils, ValidationStatus, WarningType };
929
+ // Copyright (c) Microsoft Corporation.
930
+ class AdaptiveCardGenerator {
931
+ static generateAdaptiveCard(operationItem) {
932
+ try {
933
+ const json = Utils.getResponseJson(operationItem);
934
+ let cardBody = [];
935
+ let schema = json.schema;
936
+ let jsonPath = "$";
937
+ if (schema && Object.keys(schema).length > 0) {
938
+ jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
939
+ if (jsonPath !== "$") {
940
+ schema = schema.properties[jsonPath];
941
+ }
942
+ cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
943
+ }
944
+ // if no schema, try to use example value
945
+ if (cardBody.length === 0 && (json.examples || json.example)) {
946
+ cardBody = [
947
+ {
948
+ type: ConstantString.TextBlockType,
949
+ text: "${jsonStringify($root)}",
950
+ wrap: true,
951
+ },
952
+ ];
953
+ }
954
+ // if no example value, use default success response
955
+ if (cardBody.length === 0) {
956
+ cardBody = [
957
+ {
958
+ type: ConstantString.TextBlockType,
959
+ text: "success",
960
+ wrap: true,
961
+ },
962
+ ];
963
+ }
964
+ const fullCard = {
965
+ type: ConstantString.AdaptiveCardType,
966
+ $schema: ConstantString.AdaptiveCardSchema,
967
+ version: ConstantString.AdaptiveCardVersion,
968
+ body: cardBody,
969
+ };
970
+ return [fullCard, jsonPath];
971
+ }
972
+ catch (err) {
973
+ throw new SpecParserError(err.toString(), ErrorType.GenerateAdaptiveCardFailed);
974
+ }
975
+ }
976
+ static generateCardFromResponse(schema, name, parentArrayName = "") {
977
+ if (schema.type === "array") {
978
+ // schema.items can be arbitrary object: schema { type: array, items: {} }
979
+ if (Object.keys(schema.items).length === 0) {
980
+ return [
981
+ {
982
+ type: ConstantString.TextBlockType,
983
+ text: name ? `${name}: \${jsonStringify(${name})}` : "result: ${jsonStringify($root)}",
984
+ wrap: true,
985
+ },
986
+ ];
987
+ }
988
+ const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
989
+ const template = {
990
+ type: ConstantString.ContainerType,
991
+ $data: name ? `\${${name}}` : "${$root}",
992
+ items: Array(),
993
+ };
994
+ template.items.push(...obj);
995
+ return [template];
996
+ }
997
+ // some schema may not contain type but contain properties
998
+ if (schema.type === "object" || (!schema.type && schema.properties)) {
999
+ const { properties } = schema;
1000
+ const result = [];
1001
+ for (const property in properties) {
1002
+ const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
1003
+ result.push(...obj);
1004
+ }
1005
+ if (schema.additionalProperties) {
1006
+ // TODO: better ways to handler warnings.
1007
+ console.warn(ConstantString.AdditionalPropertiesNotSupported);
1008
+ }
1009
+ return result;
1010
+ }
1011
+ if (schema.type === "string" ||
1012
+ schema.type === "integer" ||
1013
+ schema.type === "boolean" ||
1014
+ schema.type === "number") {
1015
+ if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
1016
+ // string in root: "ddd"
1017
+ let text = "result: ${$root}";
1018
+ if (name) {
1019
+ // object { id: "1" }
1020
+ text = `${name}: \${if(${name}, ${name}, 'N/A')}`;
1021
+ if (parentArrayName) {
1022
+ // object types inside array: { tags: ["id": 1, "name": "name"] }
1023
+ text = `${parentArrayName}.${text}`;
1024
+ }
1025
+ }
1026
+ else if (parentArrayName) {
1027
+ // string array: photoUrls: ["1", "2"]
1028
+ text = `${parentArrayName}: ` + "${$data}";
1029
+ }
1030
+ return [
1031
+ {
1032
+ type: ConstantString.TextBlockType,
1033
+ text,
1034
+ wrap: true,
1035
+ },
1036
+ ];
1037
+ }
1038
+ else {
1039
+ if (name) {
1040
+ return [
1041
+ {
1042
+ type: "Image",
1043
+ url: `\${${name}}`,
1044
+ $when: `\${${name} != null}`,
1045
+ },
1046
+ ];
1047
+ }
1048
+ else {
1049
+ return [
1050
+ {
1051
+ type: "Image",
1052
+ url: "${$data}",
1053
+ $when: "${$data != null}",
1054
+ },
1055
+ ];
1056
+ }
1057
+ }
1058
+ }
1059
+ if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
1060
+ throw new Error(Utils.format(ConstantString.SchemaNotSupported, JSON.stringify(schema)));
1061
+ }
1062
+ throw new Error(Utils.format(ConstantString.UnknownSchema, JSON.stringify(schema)));
1063
+ }
1064
+ // Find the first array property in the response schema object with the well-known name
1065
+ static getResponseJsonPathFromSchema(schema) {
1066
+ if (schema.type === "object" || (!schema.type && schema.properties)) {
1067
+ const { properties } = schema;
1068
+ for (const property in properties) {
1069
+ const schema = properties[property];
1070
+ if (schema.type === "array" &&
1071
+ Utils.isWellKnownName(property, ConstantString.WellknownResultNames)) {
1072
+ return property;
1073
+ }
1074
+ }
1075
+ }
1076
+ return "$";
1077
+ }
1078
+ static isImageUrlProperty(schema, name, parentArrayName) {
1079
+ const propertyName = name ? name : parentArrayName;
1080
+ return (!!propertyName &&
1081
+ schema.type === "string" &&
1082
+ Utils.isWellKnownName(propertyName, ConstantString.WellknownImageName) &&
1083
+ (propertyName.toLocaleLowerCase().indexOf("url") >= 0 || schema.format === "uri"));
1084
+ }
1085
+ }
1086
+
1087
+ export { AdaptiveCardGenerator, ConstantString, ErrorType, SpecParser, SpecParserError, Utils, ValidationStatus, WarningType };
853
1088
  //# sourceMappingURL=index.esm2017.js.map