@microsoft/m365-spec-parser 0.1.1-alpha.78701ec6a.0 → 0.1.1-alpha.a372ccf67.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.
- package/dist/index.esm2017.js +296 -56
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +382 -136
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +300 -56
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +388 -135
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/constants.d.ts +4 -1
- package/dist/src/index.browser.d.ts +2 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/interfaces.d.ts +32 -2
- package/dist/src/manifestUpdater.d.ts +8 -4
- package/dist/src/specFilter.d.ts +2 -1
- package/dist/src/specParser.browser.d.ts +15 -1
- package/dist/src/specParser.d.ts +14 -1
- package/dist/src/utils.d.ts +14 -12
- package/package.json +4 -4
package/dist/index.node.cjs.js
CHANGED
|
@@ -61,7 +61,7 @@ exports.ErrorType = void 0;
|
|
|
61
61
|
ErrorType["NoExtraAPICanBeAdded"] = "no-extra-api-can-be-added";
|
|
62
62
|
ErrorType["ResolveServerUrlFailed"] = "resolve-server-url-failed";
|
|
63
63
|
ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
|
|
64
|
-
ErrorType["
|
|
64
|
+
ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
|
|
65
65
|
ErrorType["ListFailed"] = "list-failed";
|
|
66
66
|
ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
|
|
67
67
|
ErrorType["FilterSpecFailed"] = "filter-spec-failed";
|
|
@@ -69,6 +69,7 @@ exports.ErrorType = void 0;
|
|
|
69
69
|
ErrorType["GenerateAdaptiveCardFailed"] = "generate-adaptive-card-failed";
|
|
70
70
|
ErrorType["GenerateFailed"] = "generate-failed";
|
|
71
71
|
ErrorType["ValidateFailed"] = "validate-failed";
|
|
72
|
+
ErrorType["GetSpecFailed"] = "get-spec-failed";
|
|
72
73
|
ErrorType["Cancelled"] = "cancelled";
|
|
73
74
|
ErrorType["Unknown"] = "unknown";
|
|
74
75
|
})(exports.ErrorType || (exports.ErrorType = {}));
|
|
@@ -91,7 +92,13 @@ exports.ValidationStatus = void 0;
|
|
|
91
92
|
ValidationStatus[ValidationStatus["Valid"] = 0] = "Valid";
|
|
92
93
|
ValidationStatus[ValidationStatus["Warning"] = 1] = "Warning";
|
|
93
94
|
ValidationStatus[ValidationStatus["Error"] = 2] = "Error";
|
|
94
|
-
})(exports.ValidationStatus || (exports.ValidationStatus = {}));
|
|
95
|
+
})(exports.ValidationStatus || (exports.ValidationStatus = {}));
|
|
96
|
+
exports.ProjectType = void 0;
|
|
97
|
+
(function (ProjectType) {
|
|
98
|
+
ProjectType[ProjectType["Copilot"] = 0] = "Copilot";
|
|
99
|
+
ProjectType[ProjectType["SME"] = 1] = "SME";
|
|
100
|
+
ProjectType[ProjectType["TeamsAi"] = 2] = "TeamsAi";
|
|
101
|
+
})(exports.ProjectType || (exports.ProjectType = {}));
|
|
95
102
|
|
|
96
103
|
// Copyright (c) Microsoft Corporation.
|
|
97
104
|
class ConstantString {
|
|
@@ -110,7 +117,8 @@ ConstantString.ResolveServerUrlFailed = "Unable to resolve the server URL: pleas
|
|
|
110
117
|
ConstantString.OperationOnlyContainsOptionalParam = "Operation %s contains multiple optional parameters. The first optional parameter is used for this command.";
|
|
111
118
|
ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converted to OpenAPI 3.0.";
|
|
112
119
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
113
|
-
ConstantString.
|
|
120
|
+
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
121
|
+
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
114
122
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
115
123
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
116
124
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
@@ -122,6 +130,7 @@ ConstantString.AdaptiveCardType = "AdaptiveCard";
|
|
|
122
130
|
ConstantString.TextBlockType = "TextBlock";
|
|
123
131
|
ConstantString.ContainerType = "Container";
|
|
124
132
|
ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
|
|
133
|
+
ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
|
|
125
134
|
ConstantString.ResponseCodeFor20X = [
|
|
126
135
|
"200",
|
|
127
136
|
"201",
|
|
@@ -181,7 +190,8 @@ ConstantString.FullDescriptionMaxLens = 4000;
|
|
|
181
190
|
ConstantString.CommandDescriptionMaxLens = 128;
|
|
182
191
|
ConstantString.ParameterDescriptionMaxLens = 128;
|
|
183
192
|
ConstantString.CommandTitleMaxLens = 32;
|
|
184
|
-
ConstantString.ParameterTitleMaxLens = 32;
|
|
193
|
+
ConstantString.ParameterTitleMaxLens = 32;
|
|
194
|
+
ConstantString.SMERequiredParamsMaxNum = 5;
|
|
185
195
|
|
|
186
196
|
// Copyright (c) Microsoft Corporation.
|
|
187
197
|
class SpecParserError extends Error {
|
|
@@ -193,7 +203,18 @@ class SpecParserError extends Error {
|
|
|
193
203
|
|
|
194
204
|
// Copyright (c) Microsoft Corporation.
|
|
195
205
|
class Utils {
|
|
196
|
-
static
|
|
206
|
+
static hasNestedObjectInSchema(schema) {
|
|
207
|
+
if (schema.type === "object") {
|
|
208
|
+
for (const property in schema.properties) {
|
|
209
|
+
const nestedSchema = schema.properties[property];
|
|
210
|
+
if (nestedSchema.type === "object") {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
static checkParameters(paramObject, isCopilot) {
|
|
197
218
|
const paramResult = {
|
|
198
219
|
requiredNum: 0,
|
|
199
220
|
optionalNum: 0,
|
|
@@ -205,7 +226,20 @@ class Utils {
|
|
|
205
226
|
for (let i = 0; i < paramObject.length; i++) {
|
|
206
227
|
const param = paramObject[i];
|
|
207
228
|
const schema = param.schema;
|
|
229
|
+
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
230
|
+
paramResult.isValid = false;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
208
233
|
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
234
|
+
if (isCopilot) {
|
|
235
|
+
if (isRequiredWithoutDefault) {
|
|
236
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
240
|
+
}
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
209
243
|
if (param.in === "header" || param.in === "cookie") {
|
|
210
244
|
if (isRequiredWithoutDefault) {
|
|
211
245
|
paramResult.isValid = false;
|
|
@@ -232,7 +266,7 @@ class Utils {
|
|
|
232
266
|
}
|
|
233
267
|
return paramResult;
|
|
234
268
|
}
|
|
235
|
-
static checkPostBody(schema, isRequired = false) {
|
|
269
|
+
static checkPostBody(schema, isRequired = false, isCopilot = false) {
|
|
236
270
|
var _a;
|
|
237
271
|
const paramResult = {
|
|
238
272
|
requiredNum: 0,
|
|
@@ -243,6 +277,10 @@ class Utils {
|
|
|
243
277
|
return paramResult;
|
|
244
278
|
}
|
|
245
279
|
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
280
|
+
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
281
|
+
paramResult.isValid = false;
|
|
282
|
+
return paramResult;
|
|
283
|
+
}
|
|
246
284
|
if (schema.type === "string" ||
|
|
247
285
|
schema.type === "integer" ||
|
|
248
286
|
schema.type === "boolean" ||
|
|
@@ -261,19 +299,22 @@ class Utils {
|
|
|
261
299
|
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
262
300
|
isRequired = true;
|
|
263
301
|
}
|
|
264
|
-
const result = Utils.checkPostBody(properties[property], isRequired);
|
|
302
|
+
const result = Utils.checkPostBody(properties[property], isRequired, isCopilot);
|
|
265
303
|
paramResult.requiredNum += result.requiredNum;
|
|
266
304
|
paramResult.optionalNum += result.optionalNum;
|
|
267
305
|
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
268
306
|
}
|
|
269
307
|
}
|
|
270
308
|
else {
|
|
271
|
-
if (isRequiredWithoutDefault) {
|
|
309
|
+
if (isRequiredWithoutDefault && !isCopilot) {
|
|
272
310
|
paramResult.isValid = false;
|
|
273
311
|
}
|
|
274
312
|
}
|
|
275
313
|
return paramResult;
|
|
276
314
|
}
|
|
315
|
+
static containMultipleMediaTypes(bodyObject) {
|
|
316
|
+
return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
|
|
317
|
+
}
|
|
277
318
|
/**
|
|
278
319
|
* Checks if the given API is supported.
|
|
279
320
|
* @param {string} method - The HTTP method of the API.
|
|
@@ -288,32 +329,40 @@ class Utils {
|
|
|
288
329
|
* 5. response body should be “application/json” and not empty, and response code should be 20X
|
|
289
330
|
* 6. only support request body with “application/json” content type
|
|
290
331
|
*/
|
|
291
|
-
static isSupportedApi(method, path, spec,
|
|
332
|
+
static isSupportedApi(method, path, spec, options) {
|
|
333
|
+
var _a;
|
|
292
334
|
const pathObj = spec.paths[path];
|
|
293
335
|
method = method.toLocaleLowerCase();
|
|
294
336
|
if (pathObj) {
|
|
295
|
-
if ((
|
|
296
|
-
pathObj[method]) {
|
|
337
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && pathObj[method]) {
|
|
297
338
|
const securities = pathObj[method].security;
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
339
|
+
const isTeamsAi = options.projectType === exports.ProjectType.TeamsAi;
|
|
340
|
+
const isCopilot = options.projectType === exports.ProjectType.Copilot;
|
|
341
|
+
// Teams AI project doesn't care about auth, it will use authProvider for user to implement
|
|
342
|
+
if (!isTeamsAi) {
|
|
343
|
+
const authArray = Utils.getAuthArray(securities, spec);
|
|
344
|
+
if (!Utils.isSupportedAuth(authArray, options)) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
301
347
|
}
|
|
302
348
|
const operationObject = pathObj[method];
|
|
303
|
-
if (!allowMissingId && !operationObject.operationId) {
|
|
349
|
+
if (!options.allowMissingId && !operationObject.operationId) {
|
|
304
350
|
return false;
|
|
305
351
|
}
|
|
306
352
|
const paramObject = operationObject.parameters;
|
|
307
353
|
const requestBody = operationObject.requestBody;
|
|
308
354
|
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
309
|
-
|
|
310
|
-
if (mediaTypesCount > 1) {
|
|
355
|
+
if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
|
|
311
356
|
return false;
|
|
312
357
|
}
|
|
313
|
-
const responseJson = Utils.getResponseJson(operationObject);
|
|
358
|
+
const responseJson = Utils.getResponseJson(operationObject, isTeamsAi);
|
|
314
359
|
if (Object.keys(responseJson).length === 0) {
|
|
315
360
|
return false;
|
|
316
361
|
}
|
|
362
|
+
// Teams AI project doesn't care about request parameters/body
|
|
363
|
+
if (isTeamsAi) {
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
317
366
|
let requestBodyParamResult = {
|
|
318
367
|
requiredNum: 0,
|
|
319
368
|
optionalNum: 0,
|
|
@@ -321,18 +370,26 @@ class Utils {
|
|
|
321
370
|
};
|
|
322
371
|
if (requestJsonBody) {
|
|
323
372
|
const requestBodySchema = requestJsonBody.schema;
|
|
324
|
-
|
|
373
|
+
if (isCopilot && requestBodySchema.type !== "object") {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
|
|
325
377
|
}
|
|
326
378
|
if (!requestBodyParamResult.isValid) {
|
|
327
379
|
return false;
|
|
328
380
|
}
|
|
329
|
-
const paramResult = Utils.checkParameters(paramObject);
|
|
381
|
+
const paramResult = Utils.checkParameters(paramObject, isCopilot);
|
|
330
382
|
if (!paramResult.isValid) {
|
|
331
383
|
return false;
|
|
332
384
|
}
|
|
385
|
+
// Copilot support arbitrary parameters
|
|
386
|
+
if (isCopilot) {
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
333
389
|
if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
|
|
334
|
-
if (allowMultipleParameters &&
|
|
335
|
-
requestBodyParamResult.requiredNum + paramResult.requiredNum <=
|
|
390
|
+
if (options.allowMultipleParameters &&
|
|
391
|
+
requestBodyParamResult.requiredNum + paramResult.requiredNum <=
|
|
392
|
+
ConstantString.SMERequiredParamsMaxNum) {
|
|
336
393
|
return true;
|
|
337
394
|
}
|
|
338
395
|
return false;
|
|
@@ -351,29 +408,31 @@ class Utils {
|
|
|
351
408
|
}
|
|
352
409
|
return false;
|
|
353
410
|
}
|
|
354
|
-
static isSupportedAuth(authSchemaArray,
|
|
411
|
+
static isSupportedAuth(authSchemaArray, options) {
|
|
355
412
|
if (authSchemaArray.length === 0) {
|
|
356
413
|
return true;
|
|
357
414
|
}
|
|
358
|
-
if (allowAPIKeyAuth || allowOauth2) {
|
|
415
|
+
if (options.allowAPIKeyAuth || options.allowOauth2) {
|
|
359
416
|
// Currently we don't support multiple auth in one operation
|
|
360
417
|
if (authSchemaArray.length > 0 && authSchemaArray.every((auths) => auths.length > 1)) {
|
|
361
418
|
return false;
|
|
362
419
|
}
|
|
363
420
|
for (const auths of authSchemaArray) {
|
|
364
421
|
if (auths.length === 1) {
|
|
365
|
-
if (!allowOauth2 &&
|
|
422
|
+
if (!options.allowOauth2 &&
|
|
423
|
+
options.allowAPIKeyAuth &&
|
|
424
|
+
Utils.isAPIKeyAuth(auths[0].authSchema)) {
|
|
366
425
|
return true;
|
|
367
426
|
}
|
|
368
|
-
else if (!allowAPIKeyAuth &&
|
|
369
|
-
allowOauth2 &&
|
|
370
|
-
Utils.
|
|
427
|
+
else if (!options.allowAPIKeyAuth &&
|
|
428
|
+
options.allowOauth2 &&
|
|
429
|
+
Utils.isOAuthWithAuthCodeFlow(auths[0].authSchema)) {
|
|
371
430
|
return true;
|
|
372
431
|
}
|
|
373
|
-
else if (allowAPIKeyAuth &&
|
|
374
|
-
allowOauth2 &&
|
|
432
|
+
else if (options.allowAPIKeyAuth &&
|
|
433
|
+
options.allowOauth2 &&
|
|
375
434
|
(Utils.isAPIKeyAuth(auths[0].authSchema) ||
|
|
376
|
-
Utils.
|
|
435
|
+
Utils.isOAuthWithAuthCodeFlow(auths[0].authSchema))) {
|
|
377
436
|
return true;
|
|
378
437
|
}
|
|
379
438
|
}
|
|
@@ -384,10 +443,11 @@ class Utils {
|
|
|
384
443
|
static isAPIKeyAuth(authSchema) {
|
|
385
444
|
return authSchema.type === "apiKey";
|
|
386
445
|
}
|
|
387
|
-
static
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
446
|
+
static isOAuthWithAuthCodeFlow(authSchema) {
|
|
447
|
+
if (authSchema.type === "oauth2" && authSchema.flows && authSchema.flows.authorizationCode) {
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
return false;
|
|
391
451
|
}
|
|
392
452
|
static getAuthArray(securities, spec) {
|
|
393
453
|
var _a;
|
|
@@ -415,18 +475,19 @@ class Utils {
|
|
|
415
475
|
static updateFirstLetter(str) {
|
|
416
476
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
417
477
|
}
|
|
418
|
-
static getResponseJson(operationObject) {
|
|
478
|
+
static getResponseJson(operationObject, isTeamsAiProject = false) {
|
|
419
479
|
var _a, _b;
|
|
420
480
|
let json = {};
|
|
421
481
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
422
482
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
423
|
-
const mediaTypesCount = Object.keys((responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) || {}).length;
|
|
424
|
-
if (mediaTypesCount > 1) {
|
|
425
|
-
return {};
|
|
426
|
-
}
|
|
427
483
|
if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
|
|
428
484
|
json = responseObject.content["application/json"];
|
|
429
|
-
|
|
485
|
+
if (!isTeamsAiProject && Utils.containMultipleMediaTypes(responseObject)) {
|
|
486
|
+
json = {};
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
430
491
|
}
|
|
431
492
|
}
|
|
432
493
|
return json;
|
|
@@ -500,7 +561,7 @@ class Utils {
|
|
|
500
561
|
}
|
|
501
562
|
return errors;
|
|
502
563
|
}
|
|
503
|
-
static validateServer(spec,
|
|
564
|
+
static validateServer(spec, options) {
|
|
504
565
|
const errors = [];
|
|
505
566
|
let hasTopLevelServers = false;
|
|
506
567
|
let hasPathLevelServers = false;
|
|
@@ -521,7 +582,7 @@ class Utils {
|
|
|
521
582
|
}
|
|
522
583
|
for (const method in methods) {
|
|
523
584
|
const operationObject = methods[method];
|
|
524
|
-
if (Utils.isSupportedApi(method, path, spec,
|
|
585
|
+
if (Utils.isSupportedApi(method, path, spec, options)) {
|
|
525
586
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
526
587
|
hasOperationLevelServers = true;
|
|
527
588
|
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
@@ -608,7 +669,7 @@ class Utils {
|
|
|
608
669
|
param.value = schema.default;
|
|
609
670
|
}
|
|
610
671
|
}
|
|
611
|
-
static parseApiInfo(operationItem,
|
|
672
|
+
static parseApiInfo(operationItem, options) {
|
|
612
673
|
var _a, _b;
|
|
613
674
|
const requiredParams = [];
|
|
614
675
|
const optionalParams = [];
|
|
@@ -622,7 +683,7 @@ class Utils {
|
|
|
622
683
|
description: ((_a = param.description) !== null && _a !== void 0 ? _a : "").slice(0, ConstantString.ParameterDescriptionMaxLens),
|
|
623
684
|
};
|
|
624
685
|
const schema = param.schema;
|
|
625
|
-
if (allowMultipleParameters && schema) {
|
|
686
|
+
if (options.allowMultipleParameters && schema) {
|
|
626
687
|
Utils.updateParameterWithInputType(schema, parameter);
|
|
627
688
|
}
|
|
628
689
|
if (param.in !== "header" && param.in !== "cookie") {
|
|
@@ -640,7 +701,7 @@ class Utils {
|
|
|
640
701
|
const requestJson = requestBody.content["application/json"];
|
|
641
702
|
if (Object.keys(requestJson).length !== 0) {
|
|
642
703
|
const schema = requestJson.schema;
|
|
643
|
-
const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", allowMultipleParameters, requestBody.required);
|
|
704
|
+
const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", !!options.allowMultipleParameters, requestBody.required);
|
|
644
705
|
requiredParams.push(...requiredP);
|
|
645
706
|
optionalParams.push(...optionalP);
|
|
646
707
|
}
|
|
@@ -671,14 +732,13 @@ class Utils {
|
|
|
671
732
|
}
|
|
672
733
|
return [command, warning];
|
|
673
734
|
}
|
|
674
|
-
static listSupportedAPIs(spec,
|
|
735
|
+
static listSupportedAPIs(spec, options) {
|
|
675
736
|
const paths = spec.paths;
|
|
676
737
|
const result = {};
|
|
677
738
|
for (const path in paths) {
|
|
678
739
|
const methods = paths[path];
|
|
679
740
|
for (const method in methods) {
|
|
680
|
-
|
|
681
|
-
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
|
|
741
|
+
if (Utils.isSupportedApi(method, path, spec, options)) {
|
|
682
742
|
const operationObject = methods[method];
|
|
683
743
|
result[`${method.toUpperCase()} ${path}`] = operationObject;
|
|
684
744
|
}
|
|
@@ -686,7 +746,7 @@ class Utils {
|
|
|
686
746
|
}
|
|
687
747
|
return result;
|
|
688
748
|
}
|
|
689
|
-
static validateSpec(spec, parser, isSwaggerFile,
|
|
749
|
+
static validateSpec(spec, parser, isSwaggerFile, options) {
|
|
690
750
|
const errors = [];
|
|
691
751
|
const warnings = [];
|
|
692
752
|
if (isSwaggerFile) {
|
|
@@ -696,7 +756,7 @@ class Utils {
|
|
|
696
756
|
});
|
|
697
757
|
}
|
|
698
758
|
// Server validation
|
|
699
|
-
const serverErrors = Utils.validateServer(spec,
|
|
759
|
+
const serverErrors = Utils.validateServer(spec, options);
|
|
700
760
|
errors.push(...serverErrors);
|
|
701
761
|
// Remote reference not supported
|
|
702
762
|
const refPaths = parser.$refs.paths();
|
|
@@ -709,7 +769,7 @@ class Utils {
|
|
|
709
769
|
});
|
|
710
770
|
}
|
|
711
771
|
// No supported API
|
|
712
|
-
const apiMap = Utils.listSupportedAPIs(spec,
|
|
772
|
+
const apiMap = Utils.listSupportedAPIs(spec, options);
|
|
713
773
|
if (Object.keys(apiMap).length === 0) {
|
|
714
774
|
errors.push({
|
|
715
775
|
type: exports.ErrorType.NoSupportedApi,
|
|
@@ -765,14 +825,14 @@ class Utils {
|
|
|
765
825
|
|
|
766
826
|
// Copyright (c) Microsoft Corporation.
|
|
767
827
|
class SpecFilter {
|
|
768
|
-
static specFilter(filter, unResolveSpec, resolvedSpec,
|
|
828
|
+
static specFilter(filter, unResolveSpec, resolvedSpec, options) {
|
|
769
829
|
try {
|
|
770
830
|
const newSpec = Object.assign({}, unResolveSpec);
|
|
771
831
|
const newPaths = {};
|
|
772
832
|
for (const filterItem of filter) {
|
|
773
833
|
const [method, path] = filterItem.split(" ");
|
|
774
834
|
const methodName = method.toLowerCase();
|
|
775
|
-
if (!Utils.isSupportedApi(methodName, path, resolvedSpec,
|
|
835
|
+
if (!Utils.isSupportedApi(methodName, path, resolvedSpec, options)) {
|
|
776
836
|
continue;
|
|
777
837
|
}
|
|
778
838
|
if (!newPaths[path]) {
|
|
@@ -798,47 +858,171 @@ class SpecFilter {
|
|
|
798
858
|
|
|
799
859
|
// Copyright (c) Microsoft Corporation.
|
|
800
860
|
class ManifestUpdater {
|
|
801
|
-
static
|
|
861
|
+
static updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options) {
|
|
862
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
863
|
+
const manifest = yield fs__default['default'].readJSON(manifestPath);
|
|
864
|
+
const apiPluginRelativePath = ManifestUpdater.getRelativePath(manifestPath, apiPluginFilePath);
|
|
865
|
+
manifest.plugins = [
|
|
866
|
+
{
|
|
867
|
+
pluginFile: apiPluginRelativePath,
|
|
868
|
+
},
|
|
869
|
+
];
|
|
870
|
+
ManifestUpdater.updateManifestDescription(manifest, spec);
|
|
871
|
+
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
872
|
+
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, options);
|
|
873
|
+
return [manifest, apiPlugin];
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
static updateManifestDescription(manifest, spec) {
|
|
802
877
|
var _a, _b;
|
|
878
|
+
manifest.description = {
|
|
879
|
+
short: spec.info.title.slice(0, ConstantString.ShortDescriptionMaxLens),
|
|
880
|
+
full: (_b = ((_a = spec.info.description) !== null && _a !== void 0 ? _a : manifest.description.full)) === null || _b === void 0 ? void 0 : _b.slice(0, ConstantString.FullDescriptionMaxLens),
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
static mapOpenAPISchemaToFuncParam(schema, method, pathUrl) {
|
|
884
|
+
let parameter;
|
|
885
|
+
if (schema.type === "string" ||
|
|
886
|
+
schema.type === "boolean" ||
|
|
887
|
+
schema.type === "integer" ||
|
|
888
|
+
schema.type === "number" ||
|
|
889
|
+
schema.type === "array") {
|
|
890
|
+
parameter = schema;
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(schema)), exports.ErrorType.UpdateManifestFailed);
|
|
894
|
+
}
|
|
895
|
+
return parameter;
|
|
896
|
+
}
|
|
897
|
+
static generatePluginManifestSchema(spec, specRelativePath, options) {
|
|
898
|
+
var _a, _b, _c;
|
|
899
|
+
const functions = [];
|
|
900
|
+
const functionNames = [];
|
|
901
|
+
const paths = spec.paths;
|
|
902
|
+
for (const pathUrl in paths) {
|
|
903
|
+
const pathItem = paths[pathUrl];
|
|
904
|
+
if (pathItem) {
|
|
905
|
+
const operations = pathItem;
|
|
906
|
+
for (const method in operations) {
|
|
907
|
+
if (options.allowMethods.includes(method)) {
|
|
908
|
+
const operationItem = operations[method];
|
|
909
|
+
if (operationItem) {
|
|
910
|
+
const operationId = operationItem.operationId;
|
|
911
|
+
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
912
|
+
const paramObject = operationItem.parameters;
|
|
913
|
+
const requestBody = operationItem.requestBody;
|
|
914
|
+
const parameters = {
|
|
915
|
+
type: "object",
|
|
916
|
+
properties: {},
|
|
917
|
+
required: [],
|
|
918
|
+
};
|
|
919
|
+
if (paramObject) {
|
|
920
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
921
|
+
const param = paramObject[i];
|
|
922
|
+
const schema = param.schema;
|
|
923
|
+
parameters.properties[param.name] = ManifestUpdater.mapOpenAPISchemaToFuncParam(schema, method, pathUrl);
|
|
924
|
+
if (param.required) {
|
|
925
|
+
parameters.required.push(param.name);
|
|
926
|
+
}
|
|
927
|
+
if (!parameters.properties[param.name].description) {
|
|
928
|
+
parameters.properties[param.name].description = (_b = param.description) !== null && _b !== void 0 ? _b : "";
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
if (requestBody) {
|
|
933
|
+
const requestJsonBody = requestBody.content["application/json"];
|
|
934
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
935
|
+
if (requestBodySchema.type === "object") {
|
|
936
|
+
if (requestBodySchema.required) {
|
|
937
|
+
parameters.required.push(...requestBodySchema.required);
|
|
938
|
+
}
|
|
939
|
+
for (const property in requestBodySchema.properties) {
|
|
940
|
+
const schema = requestBodySchema.properties[property];
|
|
941
|
+
parameters.properties[property] = ManifestUpdater.mapOpenAPISchemaToFuncParam(schema, method, pathUrl);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), exports.ErrorType.UpdateManifestFailed);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
const funcObj = {
|
|
949
|
+
name: operationId,
|
|
950
|
+
description: description,
|
|
951
|
+
parameters: parameters,
|
|
952
|
+
};
|
|
953
|
+
functions.push(funcObj);
|
|
954
|
+
functionNames.push(operationId);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
const apiPlugin = {
|
|
961
|
+
schema_version: "v2",
|
|
962
|
+
name_for_human: spec.info.title,
|
|
963
|
+
description_for_human: (_c = spec.info.description) !== null && _c !== void 0 ? _c : "<Please add description of the plugin>",
|
|
964
|
+
functions: functions,
|
|
965
|
+
runtimes: [
|
|
966
|
+
{
|
|
967
|
+
type: "OpenApi",
|
|
968
|
+
auth: {
|
|
969
|
+
type: "none", // TODO, support auth in the future
|
|
970
|
+
},
|
|
971
|
+
spec: {
|
|
972
|
+
url: specRelativePath,
|
|
973
|
+
},
|
|
974
|
+
run_for_functions: functionNames,
|
|
975
|
+
},
|
|
976
|
+
],
|
|
977
|
+
};
|
|
978
|
+
return apiPlugin;
|
|
979
|
+
}
|
|
980
|
+
static updateManifest(manifestPath, outputSpecPath, spec, options, adaptiveCardFolder, authInfo) {
|
|
803
981
|
return __awaiter(this, void 0, void 0, function* () {
|
|
804
982
|
try {
|
|
805
983
|
const originalManifest = yield fs__default['default'].readJSON(manifestPath);
|
|
806
984
|
const updatedPart = {};
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
commands
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
985
|
+
updatedPart.composeExtensions = [];
|
|
986
|
+
let warnings = [];
|
|
987
|
+
if (options.projectType === exports.ProjectType.SME) {
|
|
988
|
+
const updateResult = yield ManifestUpdater.generateCommands(spec, manifestPath, options, adaptiveCardFolder);
|
|
989
|
+
const commands = updateResult[0];
|
|
990
|
+
warnings = updateResult[1];
|
|
991
|
+
const composeExtension = {
|
|
992
|
+
composeExtensionType: "apiBased",
|
|
993
|
+
apiSpecificationFile: ManifestUpdater.getRelativePath(manifestPath, outputSpecPath),
|
|
994
|
+
commands: commands,
|
|
995
|
+
};
|
|
996
|
+
if (authInfo) {
|
|
997
|
+
let auth = authInfo.authSchema;
|
|
998
|
+
if (Utils.isAPIKeyAuth(auth)) {
|
|
999
|
+
auth = auth;
|
|
1000
|
+
const safeApiSecretRegistrationId = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix}`);
|
|
1001
|
+
composeExtension.authorization = {
|
|
1002
|
+
authType: "apiSecretServiceAuth",
|
|
1003
|
+
apiSecretServiceAuthConfiguration: {
|
|
1004
|
+
apiSecretRegistrationId: `\${{${safeApiSecretRegistrationId}}}`,
|
|
1005
|
+
},
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
else if (Utils.isOAuthWithAuthCodeFlow(auth)) {
|
|
1009
|
+
const safeOAuth2RegistrationId = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.OAuthRegistrationIdPostFix}`);
|
|
1010
|
+
composeExtension.authorization = {
|
|
1011
|
+
authType: "oAuth2.0",
|
|
1012
|
+
oAuthConfiguration: {
|
|
1013
|
+
oauthConfigurationId: `\${{${safeOAuth2RegistrationId}}}`,
|
|
1014
|
+
},
|
|
1015
|
+
};
|
|
1016
|
+
updatedPart.webApplicationInfo = {
|
|
1017
|
+
id: "${{AAD_APP_CLIENT_ID}}",
|
|
1018
|
+
resource: "api://${{DOMAIN}}/${{AAD_APP_CLIENT_ID}}",
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
835
1021
|
}
|
|
1022
|
+
updatedPart.composeExtensions = [composeExtension];
|
|
836
1023
|
}
|
|
837
|
-
updatedPart.description =
|
|
838
|
-
|
|
839
|
-
full: (_b = ((_a = spec.info.description) !== null && _a !== void 0 ? _a : originalManifest.description.full)) === null || _b === void 0 ? void 0 : _b.slice(0, ConstantString.FullDescriptionMaxLens),
|
|
840
|
-
};
|
|
841
|
-
updatedPart.composeExtensions = [composeExtension];
|
|
1024
|
+
updatedPart.description = originalManifest.description;
|
|
1025
|
+
ManifestUpdater.updateManifestDescription(updatedPart, spec);
|
|
842
1026
|
const updatedManifest = Object.assign(Object.assign({}, originalManifest), updatedPart);
|
|
843
1027
|
return [updatedManifest, warnings];
|
|
844
1028
|
}
|
|
@@ -847,7 +1031,8 @@ class ManifestUpdater {
|
|
|
847
1031
|
}
|
|
848
1032
|
});
|
|
849
1033
|
}
|
|
850
|
-
static generateCommands(spec,
|
|
1034
|
+
static generateCommands(spec, manifestPath, options, adaptiveCardFolder) {
|
|
1035
|
+
var _a;
|
|
851
1036
|
return __awaiter(this, void 0, void 0, function* () {
|
|
852
1037
|
const paths = spec.paths;
|
|
853
1038
|
const commands = [];
|
|
@@ -859,14 +1044,16 @@ class ManifestUpdater {
|
|
|
859
1044
|
const operations = pathItem;
|
|
860
1045
|
// Currently only support GET and POST method
|
|
861
1046
|
for (const method in operations) {
|
|
862
|
-
if (
|
|
1047
|
+
if ((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) {
|
|
863
1048
|
const operationItem = operations[method];
|
|
864
1049
|
if (operationItem) {
|
|
865
|
-
const [command, warning] = Utils.parseApiInfo(operationItem,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
1050
|
+
const [command, warning] = Utils.parseApiInfo(operationItem, options);
|
|
1051
|
+
if (adaptiveCardFolder) {
|
|
1052
|
+
const adaptiveCardPath = path__default['default'].join(adaptiveCardFolder, command.id + ".json");
|
|
1053
|
+
command.apiResponseRenderingTemplateFile = (yield fs__default['default'].pathExists(adaptiveCardPath))
|
|
1054
|
+
? ManifestUpdater.getRelativePath(manifestPath, adaptiveCardPath)
|
|
1055
|
+
: "";
|
|
1056
|
+
}
|
|
870
1057
|
if (warning) {
|
|
871
1058
|
warnings.push(warning);
|
|
872
1059
|
}
|
|
@@ -1152,6 +1339,8 @@ class SpecParser {
|
|
|
1152
1339
|
allowAPIKeyAuth: false,
|
|
1153
1340
|
allowMultipleParameters: false,
|
|
1154
1341
|
allowOauth2: false,
|
|
1342
|
+
allowMethods: ["get", "post"],
|
|
1343
|
+
projectType: exports.ProjectType.SME,
|
|
1155
1344
|
};
|
|
1156
1345
|
this.pathOrSpec = pathOrDoc;
|
|
1157
1346
|
this.parser = new SwaggerParser__default['default']();
|
|
@@ -1185,7 +1374,7 @@ class SpecParser {
|
|
|
1185
1374
|
],
|
|
1186
1375
|
};
|
|
1187
1376
|
}
|
|
1188
|
-
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options
|
|
1377
|
+
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options);
|
|
1189
1378
|
}
|
|
1190
1379
|
catch (err) {
|
|
1191
1380
|
throw new SpecParserError(err.toString(), exports.ErrorType.ValidateFailed);
|
|
@@ -1252,49 +1441,110 @@ class SpecParser {
|
|
|
1252
1441
|
}
|
|
1253
1442
|
});
|
|
1254
1443
|
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Generate specs according to the filters.
|
|
1446
|
+
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1447
|
+
*/
|
|
1448
|
+
getFilteredSpecs(filter, signal) {
|
|
1449
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1450
|
+
try {
|
|
1451
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1452
|
+
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1453
|
+
}
|
|
1454
|
+
yield this.loadSpec();
|
|
1455
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1456
|
+
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1457
|
+
}
|
|
1458
|
+
const newUnResolvedSpec = SpecFilter.specFilter(filter, this.unResolveSpec, this.spec, this.options);
|
|
1459
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1460
|
+
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1461
|
+
}
|
|
1462
|
+
const newSpec = (yield this.parser.dereference(newUnResolvedSpec));
|
|
1463
|
+
return [newUnResolvedSpec, newSpec];
|
|
1464
|
+
}
|
|
1465
|
+
catch (err) {
|
|
1466
|
+
if (err instanceof SpecParserError) {
|
|
1467
|
+
throw err;
|
|
1468
|
+
}
|
|
1469
|
+
throw new SpecParserError(err.toString(), exports.ErrorType.GetSpecFailed);
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1255
1473
|
/**
|
|
1256
1474
|
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
1257
1475
|
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
1258
1476
|
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1259
1477
|
* @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
|
|
1260
|
-
* @param
|
|
1478
|
+
* @param pluginFilePath File path of the api plugin file to generate.
|
|
1261
1479
|
*/
|
|
1262
|
-
|
|
1480
|
+
generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, signal) {
|
|
1263
1481
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1264
1482
|
const result = {
|
|
1265
1483
|
allSuccess: true,
|
|
1266
1484
|
warnings: [],
|
|
1267
1485
|
};
|
|
1268
1486
|
try {
|
|
1269
|
-
|
|
1270
|
-
|
|
1487
|
+
const newSpecs = yield this.getFilteredSpecs(filter, signal);
|
|
1488
|
+
const newUnResolvedSpec = newSpecs[0];
|
|
1489
|
+
const newSpec = newSpecs[1];
|
|
1490
|
+
let resultStr;
|
|
1491
|
+
if (outputSpecPath.endsWith(".yaml") || outputSpecPath.endsWith(".yml")) {
|
|
1492
|
+
resultStr = jsyaml__default['default'].dump(newUnResolvedSpec);
|
|
1271
1493
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1494
|
+
else {
|
|
1495
|
+
resultStr = JSON.stringify(newUnResolvedSpec, null, 2);
|
|
1275
1496
|
}
|
|
1276
|
-
|
|
1497
|
+
yield fs__default['default'].outputFile(outputSpecPath, resultStr);
|
|
1277
1498
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1278
1499
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1279
1500
|
}
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1501
|
+
const [updatedManifest, apiPlugin] = yield ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options);
|
|
1502
|
+
yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1503
|
+
yield fs__default['default'].outputJSON(pluginFilePath, apiPlugin, { spaces: 2 });
|
|
1504
|
+
}
|
|
1505
|
+
catch (err) {
|
|
1506
|
+
if (err instanceof SpecParserError) {
|
|
1507
|
+
throw err;
|
|
1508
|
+
}
|
|
1509
|
+
throw new SpecParserError(err.toString(), exports.ErrorType.GenerateFailed);
|
|
1510
|
+
}
|
|
1511
|
+
return result;
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
1516
|
+
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
1517
|
+
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1518
|
+
* @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
|
|
1519
|
+
* @param adaptiveCardFolder Folder path where the Adaptive Card files will be generated. If not specified or empty, Adaptive Card files will not be generated.
|
|
1520
|
+
*/
|
|
1521
|
+
generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal) {
|
|
1522
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1523
|
+
const result = {
|
|
1524
|
+
allSuccess: true,
|
|
1525
|
+
warnings: [],
|
|
1526
|
+
};
|
|
1527
|
+
try {
|
|
1528
|
+
const newSpecs = yield this.getFilteredSpecs(filter, signal);
|
|
1529
|
+
const newUnResolvedSpec = newSpecs[0];
|
|
1530
|
+
const newSpec = newSpecs[1];
|
|
1531
|
+
const authSet = new Set();
|
|
1532
|
+
let hasMultipleAuth = false;
|
|
1283
1533
|
for (const url in newSpec.paths) {
|
|
1284
1534
|
for (const method in newSpec.paths[url]) {
|
|
1285
1535
|
const operation = newSpec.paths[url][method];
|
|
1286
1536
|
const authArray = Utils.getAuthArray(operation.security, newSpec);
|
|
1287
1537
|
if (authArray && authArray.length > 0) {
|
|
1288
|
-
|
|
1289
|
-
if (
|
|
1290
|
-
|
|
1538
|
+
authSet.add(authArray[0][0]);
|
|
1539
|
+
if (authSet.size > 1) {
|
|
1540
|
+
hasMultipleAuth = true;
|
|
1291
1541
|
break;
|
|
1292
1542
|
}
|
|
1293
1543
|
}
|
|
1294
1544
|
}
|
|
1295
1545
|
}
|
|
1296
|
-
if (
|
|
1297
|
-
throw new SpecParserError(ConstantString.
|
|
1546
|
+
if (hasMultipleAuth && this.options.projectType !== exports.ProjectType.TeamsAi) {
|
|
1547
|
+
throw new SpecParserError(ConstantString.MultipleAuthNotSupported, exports.ErrorType.MultipleAuthNotSupported);
|
|
1298
1548
|
}
|
|
1299
1549
|
let resultStr;
|
|
1300
1550
|
if (outputSpecPath.endsWith(".yaml") || outputSpecPath.endsWith(".yml")) {
|
|
@@ -1304,26 +1554,28 @@ class SpecParser {
|
|
|
1304
1554
|
resultStr = JSON.stringify(newUnResolvedSpec, null, 2);
|
|
1305
1555
|
}
|
|
1306
1556
|
yield fs__default['default'].outputFile(outputSpecPath, resultStr);
|
|
1307
|
-
|
|
1308
|
-
for (const
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1557
|
+
if (adaptiveCardFolder) {
|
|
1558
|
+
for (const url in newSpec.paths) {
|
|
1559
|
+
for (const method in newSpec.paths[url]) {
|
|
1560
|
+
// paths object may contain description/summary which is not a http method, so we need to check if it is a operation object
|
|
1561
|
+
if (this.options.allowMethods.includes(method)) {
|
|
1562
|
+
const operation = newSpec.paths[url][method];
|
|
1563
|
+
try {
|
|
1564
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
1565
|
+
const fileName = path__default['default'].join(adaptiveCardFolder, `${operation.operationId}.json`);
|
|
1566
|
+
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
1567
|
+
yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
1568
|
+
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${operation.operationId}.data.json`);
|
|
1569
|
+
yield fs__default['default'].outputJSON(dataFileName, {}, { spaces: 2 });
|
|
1570
|
+
}
|
|
1571
|
+
catch (err) {
|
|
1572
|
+
result.allSuccess = false;
|
|
1573
|
+
result.warnings.push({
|
|
1574
|
+
type: exports.WarningType.GenerateCardFailed,
|
|
1575
|
+
content: err.toString(),
|
|
1576
|
+
data: operation.operationId,
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1327
1579
|
}
|
|
1328
1580
|
}
|
|
1329
1581
|
}
|
|
@@ -1331,8 +1583,8 @@ class SpecParser {
|
|
|
1331
1583
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1332
1584
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1333
1585
|
}
|
|
1334
|
-
const
|
|
1335
|
-
const [updatedManifest, warnings] = yield ManifestUpdater.updateManifest(manifestPath, outputSpecPath,
|
|
1586
|
+
const authInfo = Array.from(authSet)[0];
|
|
1587
|
+
const [updatedManifest, warnings] = yield ManifestUpdater.updateManifest(manifestPath, outputSpecPath, newSpec, this.options, adaptiveCardFolder, authInfo);
|
|
1336
1588
|
yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1337
1589
|
result.warnings.push(...warnings);
|
|
1338
1590
|
}
|
|
@@ -1364,12 +1616,13 @@ class SpecParser {
|
|
|
1364
1616
|
if (this.apiMap !== undefined) {
|
|
1365
1617
|
return this.apiMap;
|
|
1366
1618
|
}
|
|
1367
|
-
const result = Utils.listSupportedAPIs(spec, this.options
|
|
1619
|
+
const result = Utils.listSupportedAPIs(spec, this.options);
|
|
1368
1620
|
this.apiMap = result;
|
|
1369
1621
|
return result;
|
|
1370
1622
|
}
|
|
1371
1623
|
}
|
|
1372
1624
|
|
|
1625
|
+
exports.AdaptiveCardGenerator = AdaptiveCardGenerator;
|
|
1373
1626
|
exports.ConstantString = ConstantString;
|
|
1374
1627
|
exports.SpecParser = SpecParser;
|
|
1375
1628
|
exports.SpecParserError = SpecParserError;
|