@microsoft/m365-spec-parser 0.1.1-alpha.44548b1b3.0 → 0.1.1-alpha.4cb5c08a8.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";
@@ -24,6 +25,21 @@ var ErrorType;
24
25
  ErrorType["GenerateFailed"] = "generate-failed";
25
26
  ErrorType["ValidateFailed"] = "validate-failed";
26
27
  ErrorType["GetSpecFailed"] = "get-spec-failed";
28
+ ErrorType["AuthTypeIsNotSupported"] = "auth-type-is-not-supported";
29
+ ErrorType["MissingOperationId"] = "missing-operation-id";
30
+ ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
31
+ ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
32
+ ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
33
+ ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
34
+ ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
35
+ ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
36
+ ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
37
+ ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
38
+ ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
39
+ ErrorType["NoParameter"] = "no-parameter";
40
+ ErrorType["NoAPIInfo"] = "no-api-info";
41
+ ErrorType["MethodNotAllowed"] = "method-not-allowed";
42
+ ErrorType["UrlPathNotExist"] = "url-path-not-exist";
27
43
  ErrorType["Cancelled"] = "cancelled";
28
44
  ErrorType["Unknown"] = "unknown";
29
45
  })(ErrorType || (ErrorType = {}));
@@ -46,7 +62,13 @@ var ValidationStatus;
46
62
  ValidationStatus[ValidationStatus["Valid"] = 0] = "Valid";
47
63
  ValidationStatus[ValidationStatus["Warning"] = 1] = "Warning";
48
64
  ValidationStatus[ValidationStatus["Error"] = 2] = "Error";
49
- })(ValidationStatus || (ValidationStatus = {}));
65
+ })(ValidationStatus || (ValidationStatus = {}));
66
+ var ProjectType;
67
+ (function (ProjectType) {
68
+ ProjectType[ProjectType["Copilot"] = 0] = "Copilot";
69
+ ProjectType[ProjectType["SME"] = 1] = "SME";
70
+ ProjectType[ProjectType["TeamsAi"] = 2] = "TeamsAi";
71
+ })(ProjectType || (ProjectType = {}));
50
72
 
51
73
  // Copyright (c) Microsoft Corporation.
52
74
  class SpecParserError extends Error {
@@ -73,7 +95,9 @@ ConstantString.ResolveServerUrlFailed = "Unable to resolve the server URL: pleas
73
95
  ConstantString.OperationOnlyContainsOptionalParam = "Operation %s contains multiple optional parameters. The first optional parameter is used for this command.";
74
96
  ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converted to OpenAPI 3.0.";
75
97
  ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
76
- ConstantString.MultipleAPIKeyNotSupported = "Multiple API keys are not supported. Please make sure that all selected APIs use the same API key.";
98
+ ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
99
+ ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
100
+ ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
77
101
  ConstantString.WrappedCardVersion = "devPreview";
78
102
  ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
79
103
  ConstantString.WrappedCardResponseLayout = "list";
@@ -85,6 +109,7 @@ ConstantString.AdaptiveCardType = "AdaptiveCard";
85
109
  ConstantString.TextBlockType = "TextBlock";
86
110
  ConstantString.ContainerType = "Container";
87
111
  ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
112
+ ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
88
113
  ConstantString.ResponseCodeFor20X = [
89
114
  "200",
90
115
  "201",
@@ -144,15 +169,28 @@ ConstantString.FullDescriptionMaxLens = 4000;
144
169
  ConstantString.CommandDescriptionMaxLens = 128;
145
170
  ConstantString.ParameterDescriptionMaxLens = 128;
146
171
  ConstantString.CommandTitleMaxLens = 32;
147
- ConstantString.ParameterTitleMaxLens = 32;
172
+ ConstantString.ParameterTitleMaxLens = 32;
173
+ ConstantString.SMERequiredParamsMaxNum = 5;
148
174
 
149
175
  // Copyright (c) Microsoft Corporation.
150
176
  class Utils {
151
- static checkParameters(paramObject) {
177
+ static hasNestedObjectInSchema(schema) {
178
+ if (schema.type === "object") {
179
+ for (const property in schema.properties) {
180
+ const nestedSchema = schema.properties[property];
181
+ if (nestedSchema.type === "object") {
182
+ return true;
183
+ }
184
+ }
185
+ }
186
+ return false;
187
+ }
188
+ static checkParameters(paramObject, isCopilot) {
152
189
  const paramResult = {
153
190
  requiredNum: 0,
154
191
  optionalNum: 0,
155
192
  isValid: true,
193
+ reason: [],
156
194
  };
157
195
  if (!paramObject) {
158
196
  return paramResult;
@@ -160,10 +198,25 @@ class Utils {
160
198
  for (let i = 0; i < paramObject.length; i++) {
161
199
  const param = paramObject[i];
162
200
  const schema = param.schema;
201
+ if (isCopilot && this.hasNestedObjectInSchema(schema)) {
202
+ paramResult.isValid = false;
203
+ paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
204
+ continue;
205
+ }
163
206
  const isRequiredWithoutDefault = param.required && schema.default === undefined;
207
+ if (isCopilot) {
208
+ if (isRequiredWithoutDefault) {
209
+ paramResult.requiredNum = paramResult.requiredNum + 1;
210
+ }
211
+ else {
212
+ paramResult.optionalNum = paramResult.optionalNum + 1;
213
+ }
214
+ continue;
215
+ }
164
216
  if (param.in === "header" || param.in === "cookie") {
165
217
  if (isRequiredWithoutDefault) {
166
218
  paramResult.isValid = false;
219
+ paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
167
220
  }
168
221
  continue;
169
222
  }
@@ -173,6 +226,7 @@ class Utils {
173
226
  schema.type !== "integer") {
174
227
  if (isRequiredWithoutDefault) {
175
228
  paramResult.isValid = false;
229
+ paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
176
230
  }
177
231
  continue;
178
232
  }
@@ -187,17 +241,23 @@ class Utils {
187
241
  }
188
242
  return paramResult;
189
243
  }
190
- static checkPostBody(schema, isRequired = false) {
244
+ static checkPostBody(schema, isRequired = false, isCopilot = false) {
191
245
  var _a;
192
246
  const paramResult = {
193
247
  requiredNum: 0,
194
248
  optionalNum: 0,
195
249
  isValid: true,
250
+ reason: [],
196
251
  };
197
252
  if (Object.keys(schema).length === 0) {
198
253
  return paramResult;
199
254
  }
200
255
  const isRequiredWithoutDefault = isRequired && schema.default === undefined;
256
+ if (isCopilot && this.hasNestedObjectInSchema(schema)) {
257
+ paramResult.isValid = false;
258
+ paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
259
+ return paramResult;
260
+ }
201
261
  if (schema.type === "string" ||
202
262
  schema.type === "integer" ||
203
263
  schema.type === "boolean" ||
@@ -216,19 +276,24 @@ class Utils {
216
276
  if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
217
277
  isRequired = true;
218
278
  }
219
- const result = Utils.checkPostBody(properties[property], isRequired);
279
+ const result = Utils.checkPostBody(properties[property], isRequired, isCopilot);
220
280
  paramResult.requiredNum += result.requiredNum;
221
281
  paramResult.optionalNum += result.optionalNum;
222
282
  paramResult.isValid = paramResult.isValid && result.isValid;
283
+ paramResult.reason.push(...result.reason);
223
284
  }
224
285
  }
225
286
  else {
226
- if (isRequiredWithoutDefault) {
287
+ if (isRequiredWithoutDefault && !isCopilot) {
227
288
  paramResult.isValid = false;
289
+ paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
228
290
  }
229
291
  }
230
292
  return paramResult;
231
293
  }
294
+ static containMultipleMediaTypes(bodyObject) {
295
+ return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
296
+ }
232
297
  /**
233
298
  * Checks if the given API is supported.
234
299
  * @param {string} method - The HTTP method of the API.
@@ -243,106 +308,137 @@ class Utils {
243
308
  * 5. response body should be “application/json” and not empty, and response code should be 20X
244
309
  * 6. only support request body with “application/json” content type
245
310
  */
246
- static isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
247
- const pathObj = spec.paths[path];
311
+ static isSupportedApi(method, path, spec, options) {
312
+ var _a;
313
+ const result = { isValid: true, reason: [] };
248
314
  method = method.toLocaleLowerCase();
249
- if (pathObj) {
250
- if ((method === ConstantString.PostMethod || method === ConstantString.GetMethod) &&
251
- pathObj[method]) {
252
- const securities = pathObj[method].security;
253
- const authArray = Utils.getAuthArray(securities, spec);
254
- if (!Utils.isSupportedAuth(authArray, allowAPIKeyAuth, allowOauth2)) {
255
- return false;
256
- }
257
- const operationObject = pathObj[method];
258
- if (!allowMissingId && !operationObject.operationId) {
259
- return false;
260
- }
261
- const paramObject = operationObject.parameters;
262
- const requestBody = operationObject.requestBody;
263
- const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
264
- const mediaTypesCount = Object.keys((requestBody === null || requestBody === void 0 ? void 0 : requestBody.content) || {}).length;
265
- if (mediaTypesCount > 1) {
266
- return false;
267
- }
268
- const responseJson = Utils.getResponseJson(operationObject);
269
- if (Object.keys(responseJson).length === 0) {
270
- return false;
271
- }
272
- let requestBodyParamResult = {
273
- requiredNum: 0,
274
- optionalNum: 0,
275
- isValid: true,
276
- };
277
- if (requestJsonBody) {
278
- const requestBodySchema = requestJsonBody.schema;
279
- requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required);
280
- }
281
- if (!requestBodyParamResult.isValid) {
282
- return false;
315
+ if (options.allowMethods && !options.allowMethods.includes(method)) {
316
+ result.isValid = false;
317
+ result.reason.push(ErrorType.MethodNotAllowed);
318
+ return result;
319
+ }
320
+ const pathObj = spec.paths[path];
321
+ if (!pathObj || !pathObj[method]) {
322
+ result.isValid = false;
323
+ result.reason.push(ErrorType.UrlPathNotExist);
324
+ return result;
325
+ }
326
+ const securities = pathObj[method].security;
327
+ const isTeamsAi = options.projectType === ProjectType.TeamsAi;
328
+ const isCopilot = options.projectType === ProjectType.Copilot;
329
+ // Teams AI project doesn't care about auth, it will use authProvider for user to implement
330
+ if (!isTeamsAi) {
331
+ const authArray = Utils.getAuthArray(securities, spec);
332
+ const authCheckResult = Utils.isSupportedAuth(authArray, options);
333
+ if (!authCheckResult.isValid) {
334
+ result.reason.push(...authCheckResult.reason);
335
+ }
336
+ }
337
+ const operationObject = pathObj[method];
338
+ if (!options.allowMissingId && !operationObject.operationId) {
339
+ result.reason.push(ErrorType.MissingOperationId);
340
+ }
341
+ const rootServer = spec.servers && spec.servers[0];
342
+ const methodServer = spec.paths[path].servers && ((_a = spec.paths[path]) === null || _a === void 0 ? void 0 : _a.servers[0]);
343
+ const operationServer = operationObject.servers && operationObject.servers[0];
344
+ const serverUrl = operationServer || methodServer || rootServer;
345
+ if (!serverUrl) {
346
+ result.reason.push(ErrorType.NoServerInformation);
347
+ }
348
+ else {
349
+ const serverValidateResult = Utils.checkServerUrl([serverUrl]);
350
+ result.reason.push(...serverValidateResult.map((item) => item.type));
351
+ }
352
+ const paramObject = operationObject.parameters;
353
+ const requestBody = operationObject.requestBody;
354
+ const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
355
+ if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
356
+ result.reason.push(ErrorType.PostBodyContainMultipleMediaTypes);
357
+ }
358
+ const { json, multipleMediaType } = Utils.getResponseJson(operationObject, isTeamsAi);
359
+ if (multipleMediaType && !isTeamsAi) {
360
+ result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
361
+ }
362
+ else if (Object.keys(json).length === 0) {
363
+ result.reason.push(ErrorType.ResponseJsonIsEmpty);
364
+ }
365
+ // Teams AI project doesn't care about request parameters/body
366
+ if (!isTeamsAi) {
367
+ let requestBodyParamResult = {
368
+ requiredNum: 0,
369
+ optionalNum: 0,
370
+ isValid: true,
371
+ reason: [],
372
+ };
373
+ if (requestJsonBody) {
374
+ const requestBodySchema = requestJsonBody.schema;
375
+ if (isCopilot && requestBodySchema.type !== "object") {
376
+ result.reason.push(ErrorType.PostBodySchemaIsNotJson);
283
377
  }
284
- const paramResult = Utils.checkParameters(paramObject);
285
- if (!paramResult.isValid) {
286
- return false;
378
+ requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
379
+ if (!requestBodyParamResult.isValid && requestBodyParamResult.reason) {
380
+ result.reason.push(...requestBodyParamResult.reason);
287
381
  }
288
- if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
289
- if (allowMultipleParameters &&
290
- requestBodyParamResult.requiredNum + paramResult.requiredNum <= 5) {
291
- return true;
382
+ }
383
+ const paramResult = Utils.checkParameters(paramObject, isCopilot);
384
+ if (!paramResult.isValid && paramResult.reason) {
385
+ result.reason.push(...paramResult.reason);
386
+ }
387
+ // Copilot support arbitrary parameters
388
+ if (!isCopilot && paramResult.isValid && requestBodyParamResult.isValid) {
389
+ const totalRequiredParams = requestBodyParamResult.requiredNum + paramResult.requiredNum;
390
+ const totalParams = totalRequiredParams + requestBodyParamResult.optionalNum + paramResult.optionalNum;
391
+ if (totalRequiredParams > 1) {
392
+ if (!options.allowMultipleParameters ||
393
+ totalRequiredParams > ConstantString.SMERequiredParamsMaxNum) {
394
+ result.reason.push(ErrorType.ExceededRequiredParamsLimit);
292
395
  }
293
- return false;
294
396
  }
295
- else if (requestBodyParamResult.requiredNum +
296
- requestBodyParamResult.optionalNum +
297
- paramResult.requiredNum +
298
- paramResult.optionalNum ===
299
- 0) {
300
- return false;
301
- }
302
- else {
303
- return true;
397
+ else if (totalParams === 0) {
398
+ result.reason.push(ErrorType.NoParameter);
304
399
  }
305
400
  }
306
401
  }
307
- return false;
402
+ if (result.reason.length > 0) {
403
+ result.isValid = false;
404
+ }
405
+ return result;
308
406
  }
309
- static isSupportedAuth(authSchemaArray, allowAPIKeyAuth, allowOauth2) {
310
- if (authSchemaArray.length === 0) {
311
- return true;
407
+ static isSupportedAuth(authSchemeArray, options) {
408
+ if (authSchemeArray.length === 0) {
409
+ return { isValid: true, reason: [] };
312
410
  }
313
- if (allowAPIKeyAuth || allowOauth2) {
411
+ if (options.allowAPIKeyAuth || options.allowOauth2 || options.allowBearerTokenAuth) {
314
412
  // Currently we don't support multiple auth in one operation
315
- if (authSchemaArray.length > 0 && authSchemaArray.every((auths) => auths.length > 1)) {
316
- return false;
413
+ if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
414
+ return {
415
+ isValid: false,
416
+ reason: [ErrorType.MultipleAuthNotSupported],
417
+ };
317
418
  }
318
- for (const auths of authSchemaArray) {
419
+ for (const auths of authSchemeArray) {
319
420
  if (auths.length === 1) {
320
- if (!allowOauth2 && allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authSchema)) {
321
- return true;
322
- }
323
- else if (!allowAPIKeyAuth &&
324
- allowOauth2 &&
325
- Utils.isBearerTokenAuth(auths[0].authSchema)) {
326
- return true;
327
- }
328
- else if (allowAPIKeyAuth &&
329
- allowOauth2 &&
330
- (Utils.isAPIKeyAuth(auths[0].authSchema) ||
331
- Utils.isBearerTokenAuth(auths[0].authSchema))) {
332
- return true;
421
+ if ((options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
422
+ (options.allowOauth2 && Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme)) ||
423
+ (options.allowBearerTokenAuth && Utils.isBearerTokenAuth(auths[0].authScheme))) {
424
+ return { isValid: true, reason: [] };
333
425
  }
334
426
  }
335
427
  }
336
428
  }
337
- return false;
429
+ return { isValid: false, reason: [ErrorType.AuthTypeIsNotSupported] };
338
430
  }
339
- static isAPIKeyAuth(authSchema) {
340
- return authSchema.type === "apiKey";
431
+ static isBearerTokenAuth(authScheme) {
432
+ return authScheme.type === "http" && authScheme.scheme === "bearer";
341
433
  }
342
- static isBearerTokenAuth(authSchema) {
343
- return (authSchema.type === "oauth2" ||
344
- authSchema.type === "openIdConnect" ||
345
- (authSchema.type === "http" && authSchema.scheme === "bearer"));
434
+ static isAPIKeyAuth(authScheme) {
435
+ return authScheme.type === "apiKey";
436
+ }
437
+ static isOAuthWithAuthCodeFlow(authScheme) {
438
+ if (authScheme.type === "oauth2" && authScheme.flows && authScheme.flows.authorizationCode) {
439
+ return true;
440
+ }
441
+ return false;
346
442
  }
347
443
  static getAuthArray(securities, spec) {
348
444
  var _a;
@@ -355,7 +451,7 @@ class Utils {
355
451
  for (const name in security) {
356
452
  const auth = securitySchemas[name];
357
453
  authArray.push({
358
- authSchema: auth,
454
+ authScheme: auth,
359
455
  name: name,
360
456
  });
361
457
  }
@@ -370,21 +466,28 @@ class Utils {
370
466
  static updateFirstLetter(str) {
371
467
  return str.charAt(0).toUpperCase() + str.slice(1);
372
468
  }
373
- static getResponseJson(operationObject) {
469
+ static getResponseJson(operationObject, isTeamsAiProject = false) {
374
470
  var _a, _b;
375
471
  let json = {};
472
+ let multipleMediaType = false;
376
473
  for (const code of ConstantString.ResponseCodeFor20X) {
377
474
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
378
- const mediaTypesCount = Object.keys((responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) || {}).length;
379
- if (mediaTypesCount > 1) {
380
- return {};
381
- }
382
475
  if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
476
+ multipleMediaType = false;
383
477
  json = responseObject.content["application/json"];
384
- break;
478
+ if (Utils.containMultipleMediaTypes(responseObject)) {
479
+ multipleMediaType = true;
480
+ if (isTeamsAiProject) {
481
+ break;
482
+ }
483
+ json = {};
484
+ }
485
+ else {
486
+ break;
487
+ }
385
488
  }
386
489
  }
387
- return json;
490
+ return { json, multipleMediaType };
388
491
  }
389
492
  static convertPathToCamelCase(path) {
390
493
  const pathSegments = path.split(/[./{]/);
@@ -404,10 +507,10 @@ class Utils {
404
507
  return undefined;
405
508
  }
406
509
  }
407
- static resolveServerUrl(url) {
510
+ static resolveEnv(str) {
408
511
  const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
409
- let matches = placeHolderReg.exec(url);
410
- let newUrl = url;
512
+ let matches = placeHolderReg.exec(str);
513
+ let newStr = str;
411
514
  while (matches != null) {
412
515
  const envVar = matches[1];
413
516
  const envVal = process.env[envVar];
@@ -415,17 +518,17 @@ class Utils {
415
518
  throw new Error(Utils.format(ConstantString.ResolveServerUrlFailed, envVar));
416
519
  }
417
520
  else {
418
- newUrl = newUrl.replace(matches[0], envVal);
521
+ newStr = newStr.replace(matches[0], envVal);
419
522
  }
420
- matches = placeHolderReg.exec(url);
523
+ matches = placeHolderReg.exec(str);
421
524
  }
422
- return newUrl;
525
+ return newStr;
423
526
  }
424
527
  static checkServerUrl(servers) {
425
528
  const errors = [];
426
529
  let serverUrl;
427
530
  try {
428
- serverUrl = Utils.resolveServerUrl(servers[0].url);
531
+ serverUrl = Utils.resolveEnv(servers[0].url);
429
532
  }
430
533
  catch (err) {
431
534
  errors.push({
@@ -455,7 +558,8 @@ class Utils {
455
558
  }
456
559
  return errors;
457
560
  }
458
- static validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
561
+ static validateServer(spec, options) {
562
+ var _a;
459
563
  const errors = [];
460
564
  let hasTopLevelServers = false;
461
565
  let hasPathLevelServers = false;
@@ -476,7 +580,7 @@ class Utils {
476
580
  }
477
581
  for (const method in methods) {
478
582
  const operationObject = methods[method];
479
- if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
583
+ if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
480
584
  if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
481
585
  hasOperationLevelServers = true;
482
586
  const serverErrors = Utils.checkServerUrl(operationObject.servers);
@@ -519,6 +623,7 @@ class Utils {
519
623
  Utils.updateParameterWithInputType(schema, parameter);
520
624
  }
521
625
  if (isRequired && schema.default === undefined) {
626
+ parameter.isRequired = true;
522
627
  requiredParams.push(parameter);
523
628
  }
524
629
  else {
@@ -563,7 +668,7 @@ class Utils {
563
668
  param.value = schema.default;
564
669
  }
565
670
  }
566
- static parseApiInfo(operationItem, allowMultipleParameters) {
671
+ static parseApiInfo(operationItem, options) {
567
672
  var _a, _b;
568
673
  const requiredParams = [];
569
674
  const optionalParams = [];
@@ -577,11 +682,12 @@ class Utils {
577
682
  description: ((_a = param.description) !== null && _a !== void 0 ? _a : "").slice(0, ConstantString.ParameterDescriptionMaxLens),
578
683
  };
579
684
  const schema = param.schema;
580
- if (allowMultipleParameters && schema) {
685
+ if (options.allowMultipleParameters && schema) {
581
686
  Utils.updateParameterWithInputType(schema, parameter);
582
687
  }
583
688
  if (param.in !== "header" && param.in !== "cookie") {
584
689
  if (param.required && (schema === null || schema === void 0 ? void 0 : schema.default) === undefined) {
690
+ parameter.isRequired = true;
585
691
  requiredParams.push(parameter);
586
692
  }
587
693
  else {
@@ -595,7 +701,7 @@ class Utils {
595
701
  const requestJson = requestBody.content["application/json"];
596
702
  if (Object.keys(requestJson).length !== 0) {
597
703
  const schema = requestJson.schema;
598
- const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", allowMultipleParameters, requestBody.required);
704
+ const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", !!options.allowMultipleParameters, requestBody.required);
599
705
  requiredParams.push(...requiredP);
600
706
  optionalParams.push(...optionalP);
601
707
  }
@@ -626,32 +732,37 @@ class Utils {
626
732
  }
627
733
  return [command, warning];
628
734
  }
629
- static listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
735
+ static listAPIs(spec, options) {
736
+ var _a;
630
737
  const paths = spec.paths;
631
738
  const result = {};
632
739
  for (const path in paths) {
633
740
  const methods = paths[path];
634
741
  for (const method in methods) {
635
- // For developer preview, only support GET operation with only 1 parameter without auth
636
- if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
637
- const operationObject = methods[method];
638
- result[`${method.toUpperCase()} ${path}`] = operationObject;
742
+ const operationObject = methods[method];
743
+ if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
744
+ const validateResult = Utils.isSupportedApi(method, path, spec, options);
745
+ result[`${method.toUpperCase()} ${path}`] = {
746
+ operation: operationObject,
747
+ isValid: validateResult.isValid,
748
+ reason: validateResult.reason,
749
+ };
639
750
  }
640
751
  }
641
752
  }
642
753
  return result;
643
754
  }
644
- static validateSpec(spec, parser, isSwaggerFile, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
755
+ static validateSpec(spec, parser, isSwaggerFile, options) {
645
756
  const errors = [];
646
757
  const warnings = [];
758
+ const apiMap = Utils.listAPIs(spec, options);
647
759
  if (isSwaggerFile) {
648
760
  warnings.push({
649
761
  type: WarningType.ConvertSwaggerToOpenAPI,
650
762
  content: ConstantString.ConvertSwaggerToOpenAPI,
651
763
  });
652
764
  }
653
- // Server validation
654
- const serverErrors = Utils.validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2);
765
+ const serverErrors = Utils.validateServer(spec, options);
655
766
  errors.push(...serverErrors);
656
767
  // Remote reference not supported
657
768
  const refPaths = parser.$refs.paths();
@@ -664,8 +775,8 @@ class Utils {
664
775
  });
665
776
  }
666
777
  // No supported API
667
- const apiMap = Utils.listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2);
668
- if (Object.keys(apiMap).length === 0) {
778
+ const validAPIs = Object.entries(apiMap).filter(([, value]) => value.isValid);
779
+ if (validAPIs.length === 0) {
669
780
  errors.push({
670
781
  type: ErrorType.NoSupportedApi,
671
782
  content: ConstantString.NoSupportedApi,
@@ -674,8 +785,8 @@ class Utils {
674
785
  // OperationId missing
675
786
  const apisMissingOperationId = [];
676
787
  for (const key in apiMap) {
677
- const pathObjectItem = apiMap[key];
678
- if (!pathObjectItem.operationId) {
788
+ const { operation } = apiMap[key];
789
+ if (!operation.operationId) {
679
790
  apisMissingOperationId.push(key);
680
791
  }
681
792
  }
@@ -716,6 +827,19 @@ class Utils {
716
827
  }
717
828
  return safeRegistrationIdEnvName;
718
829
  }
830
+ static getAllAPICount(spec) {
831
+ let count = 0;
832
+ const paths = spec.paths;
833
+ for (const path in paths) {
834
+ const methods = paths[path];
835
+ for (const method in methods) {
836
+ if (ConstantString.AllOperationMethods.includes(method)) {
837
+ count++;
838
+ }
839
+ }
840
+ }
841
+ return count;
842
+ }
719
843
  }
720
844
 
721
845
  // Copyright (c) Microsoft Corporation.
@@ -734,7 +858,10 @@ class SpecParser {
734
858
  allowSwagger: false,
735
859
  allowAPIKeyAuth: false,
736
860
  allowMultipleParameters: false,
861
+ allowBearerTokenAuth: false,
737
862
  allowOauth2: false,
863
+ allowMethods: ["get", "post"],
864
+ projectType: ProjectType.SME,
738
865
  };
739
866
  this.pathOrSpec = pathOrDoc;
740
867
  this.parser = new SwaggerParser();
@@ -771,7 +898,7 @@ class SpecParser {
771
898
  ],
772
899
  };
773
900
  }
774
- return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2);
901
+ return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options);
775
902
  }
776
903
  catch (err) {
777
904
  throw new SpecParserError(err.toString(), ErrorType.ValidateFailed);
@@ -790,7 +917,7 @@ class SpecParser {
790
917
  if (!operationId) {
791
918
  continue;
792
919
  }
793
- const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options.allowMultipleParameters);
920
+ const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options);
794
921
  const apiInfo = {
795
922
  method: method,
796
923
  path: path,
@@ -827,6 +954,17 @@ class SpecParser {
827
954
  async getFilteredSpecs(filter, signal) {
828
955
  throw new Error("Method not implemented.");
829
956
  }
957
+ /**
958
+ * Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
959
+ * @param manifestPath A file path of the Teams app manifest file to update.
960
+ * @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
961
+ * @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
962
+ * @param pluginFilePath File path of the api plugin file to generate.
963
+ */
964
+ // eslint-disable-next-line @typescript-eslint/require-await
965
+ async generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, signal) {
966
+ throw new Error("Method not implemented.");
967
+ }
830
968
  /**
831
969
  * Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
832
970
  * @param manifestPath A file path of the Teams app manifest file to update.
@@ -836,7 +974,7 @@ class SpecParser {
836
974
  * @param isMe Boolean that indicates whether the project is an Messaging Extension. For Messaging Extension, composeExtensions will be added in Teams app manifest.
837
975
  */
838
976
  // eslint-disable-next-line @typescript-eslint/require-await
839
- async generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal, isMe) {
977
+ async generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal) {
840
978
  throw new Error("Method not implemented.");
841
979
  }
842
980
  async loadSpec() {
@@ -853,17 +991,35 @@ class SpecParser {
853
991
  if (this.apiMap !== undefined) {
854
992
  return this.apiMap;
855
993
  }
856
- const result = Utils.listSupportedAPIs(spec, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2);
994
+ const result = this.listSupportedAPIs(spec, this.options);
857
995
  this.apiMap = result;
858
996
  return result;
859
997
  }
998
+ listSupportedAPIs(spec, options) {
999
+ var _a;
1000
+ const paths = spec.paths;
1001
+ const result = {};
1002
+ for (const path in paths) {
1003
+ const methods = paths[path];
1004
+ for (const method in methods) {
1005
+ const operationObject = methods[method];
1006
+ if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
1007
+ const validateResult = Utils.isSupportedApi(method, path, spec, options);
1008
+ if (validateResult.isValid) {
1009
+ result[`${method.toUpperCase()} ${path}`] = operationObject;
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+ return result;
1015
+ }
860
1016
  }
861
1017
 
862
1018
  // Copyright (c) Microsoft Corporation.
863
1019
  class AdaptiveCardGenerator {
864
1020
  static generateAdaptiveCard(operationItem) {
865
1021
  try {
866
- const json = Utils.getResponseJson(operationItem);
1022
+ const { json } = Utils.getResponseJson(operationItem);
867
1023
  let cardBody = [];
868
1024
  let schema = json.schema;
869
1025
  let jsonPath = "$";