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