@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.esm2017.mjs
CHANGED
|
@@ -19,7 +19,7 @@ var ErrorType;
|
|
|
19
19
|
ErrorType["NoExtraAPICanBeAdded"] = "no-extra-api-can-be-added";
|
|
20
20
|
ErrorType["ResolveServerUrlFailed"] = "resolve-server-url-failed";
|
|
21
21
|
ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
|
|
22
|
-
ErrorType["
|
|
22
|
+
ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
|
|
23
23
|
ErrorType["ListFailed"] = "list-failed";
|
|
24
24
|
ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
|
|
25
25
|
ErrorType["FilterSpecFailed"] = "filter-spec-failed";
|
|
@@ -27,6 +27,7 @@ var ErrorType;
|
|
|
27
27
|
ErrorType["GenerateAdaptiveCardFailed"] = "generate-adaptive-card-failed";
|
|
28
28
|
ErrorType["GenerateFailed"] = "generate-failed";
|
|
29
29
|
ErrorType["ValidateFailed"] = "validate-failed";
|
|
30
|
+
ErrorType["GetSpecFailed"] = "get-spec-failed";
|
|
30
31
|
ErrorType["Cancelled"] = "cancelled";
|
|
31
32
|
ErrorType["Unknown"] = "unknown";
|
|
32
33
|
})(ErrorType || (ErrorType = {}));
|
|
@@ -49,7 +50,13 @@ var ValidationStatus;
|
|
|
49
50
|
ValidationStatus[ValidationStatus["Valid"] = 0] = "Valid";
|
|
50
51
|
ValidationStatus[ValidationStatus["Warning"] = 1] = "Warning";
|
|
51
52
|
ValidationStatus[ValidationStatus["Error"] = 2] = "Error";
|
|
52
|
-
})(ValidationStatus || (ValidationStatus = {}));
|
|
53
|
+
})(ValidationStatus || (ValidationStatus = {}));
|
|
54
|
+
var ProjectType;
|
|
55
|
+
(function (ProjectType) {
|
|
56
|
+
ProjectType[ProjectType["Copilot"] = 0] = "Copilot";
|
|
57
|
+
ProjectType[ProjectType["SME"] = 1] = "SME";
|
|
58
|
+
ProjectType[ProjectType["TeamsAi"] = 2] = "TeamsAi";
|
|
59
|
+
})(ProjectType || (ProjectType = {}));
|
|
53
60
|
|
|
54
61
|
// Copyright (c) Microsoft Corporation.
|
|
55
62
|
class ConstantString {
|
|
@@ -68,7 +75,8 @@ ConstantString.ResolveServerUrlFailed = "Unable to resolve the server URL: pleas
|
|
|
68
75
|
ConstantString.OperationOnlyContainsOptionalParam = "Operation %s contains multiple optional parameters. The first optional parameter is used for this command.";
|
|
69
76
|
ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converted to OpenAPI 3.0.";
|
|
70
77
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
71
|
-
ConstantString.
|
|
78
|
+
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
79
|
+
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
72
80
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
73
81
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
74
82
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
@@ -80,6 +88,7 @@ ConstantString.AdaptiveCardType = "AdaptiveCard";
|
|
|
80
88
|
ConstantString.TextBlockType = "TextBlock";
|
|
81
89
|
ConstantString.ContainerType = "Container";
|
|
82
90
|
ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
|
|
91
|
+
ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
|
|
83
92
|
ConstantString.ResponseCodeFor20X = [
|
|
84
93
|
"200",
|
|
85
94
|
"201",
|
|
@@ -139,7 +148,8 @@ ConstantString.FullDescriptionMaxLens = 4000;
|
|
|
139
148
|
ConstantString.CommandDescriptionMaxLens = 128;
|
|
140
149
|
ConstantString.ParameterDescriptionMaxLens = 128;
|
|
141
150
|
ConstantString.CommandTitleMaxLens = 32;
|
|
142
|
-
ConstantString.ParameterTitleMaxLens = 32;
|
|
151
|
+
ConstantString.ParameterTitleMaxLens = 32;
|
|
152
|
+
ConstantString.SMERequiredParamsMaxNum = 5;
|
|
143
153
|
|
|
144
154
|
// Copyright (c) Microsoft Corporation.
|
|
145
155
|
class SpecParserError extends Error {
|
|
@@ -151,7 +161,18 @@ class SpecParserError extends Error {
|
|
|
151
161
|
|
|
152
162
|
// Copyright (c) Microsoft Corporation.
|
|
153
163
|
class Utils {
|
|
154
|
-
static
|
|
164
|
+
static hasNestedObjectInSchema(schema) {
|
|
165
|
+
if (schema.type === "object") {
|
|
166
|
+
for (const property in schema.properties) {
|
|
167
|
+
const nestedSchema = schema.properties[property];
|
|
168
|
+
if (nestedSchema.type === "object") {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
static checkParameters(paramObject, isCopilot) {
|
|
155
176
|
const paramResult = {
|
|
156
177
|
requiredNum: 0,
|
|
157
178
|
optionalNum: 0,
|
|
@@ -163,7 +184,20 @@ class Utils {
|
|
|
163
184
|
for (let i = 0; i < paramObject.length; i++) {
|
|
164
185
|
const param = paramObject[i];
|
|
165
186
|
const schema = param.schema;
|
|
187
|
+
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
188
|
+
paramResult.isValid = false;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
166
191
|
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
192
|
+
if (isCopilot) {
|
|
193
|
+
if (isRequiredWithoutDefault) {
|
|
194
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
198
|
+
}
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
167
201
|
if (param.in === "header" || param.in === "cookie") {
|
|
168
202
|
if (isRequiredWithoutDefault) {
|
|
169
203
|
paramResult.isValid = false;
|
|
@@ -190,7 +224,7 @@ class Utils {
|
|
|
190
224
|
}
|
|
191
225
|
return paramResult;
|
|
192
226
|
}
|
|
193
|
-
static checkPostBody(schema, isRequired = false) {
|
|
227
|
+
static checkPostBody(schema, isRequired = false, isCopilot = false) {
|
|
194
228
|
var _a;
|
|
195
229
|
const paramResult = {
|
|
196
230
|
requiredNum: 0,
|
|
@@ -201,6 +235,10 @@ class Utils {
|
|
|
201
235
|
return paramResult;
|
|
202
236
|
}
|
|
203
237
|
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
238
|
+
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
239
|
+
paramResult.isValid = false;
|
|
240
|
+
return paramResult;
|
|
241
|
+
}
|
|
204
242
|
if (schema.type === "string" ||
|
|
205
243
|
schema.type === "integer" ||
|
|
206
244
|
schema.type === "boolean" ||
|
|
@@ -219,19 +257,22 @@ class Utils {
|
|
|
219
257
|
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
220
258
|
isRequired = true;
|
|
221
259
|
}
|
|
222
|
-
const result = Utils.checkPostBody(properties[property], isRequired);
|
|
260
|
+
const result = Utils.checkPostBody(properties[property], isRequired, isCopilot);
|
|
223
261
|
paramResult.requiredNum += result.requiredNum;
|
|
224
262
|
paramResult.optionalNum += result.optionalNum;
|
|
225
263
|
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
226
264
|
}
|
|
227
265
|
}
|
|
228
266
|
else {
|
|
229
|
-
if (isRequiredWithoutDefault) {
|
|
267
|
+
if (isRequiredWithoutDefault && !isCopilot) {
|
|
230
268
|
paramResult.isValid = false;
|
|
231
269
|
}
|
|
232
270
|
}
|
|
233
271
|
return paramResult;
|
|
234
272
|
}
|
|
273
|
+
static containMultipleMediaTypes(bodyObject) {
|
|
274
|
+
return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
|
|
275
|
+
}
|
|
235
276
|
/**
|
|
236
277
|
* Checks if the given API is supported.
|
|
237
278
|
* @param {string} method - The HTTP method of the API.
|
|
@@ -246,32 +287,40 @@ class Utils {
|
|
|
246
287
|
* 5. response body should be “application/json” and not empty, and response code should be 20X
|
|
247
288
|
* 6. only support request body with “application/json” content type
|
|
248
289
|
*/
|
|
249
|
-
static isSupportedApi(method, path, spec,
|
|
290
|
+
static isSupportedApi(method, path, spec, options) {
|
|
291
|
+
var _a;
|
|
250
292
|
const pathObj = spec.paths[path];
|
|
251
293
|
method = method.toLocaleLowerCase();
|
|
252
294
|
if (pathObj) {
|
|
253
|
-
if ((
|
|
254
|
-
pathObj[method]) {
|
|
295
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && pathObj[method]) {
|
|
255
296
|
const securities = pathObj[method].security;
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
297
|
+
const isTeamsAi = options.projectType === ProjectType.TeamsAi;
|
|
298
|
+
const isCopilot = options.projectType === ProjectType.Copilot;
|
|
299
|
+
// Teams AI project doesn't care about auth, it will use authProvider for user to implement
|
|
300
|
+
if (!isTeamsAi) {
|
|
301
|
+
const authArray = Utils.getAuthArray(securities, spec);
|
|
302
|
+
if (!Utils.isSupportedAuth(authArray, options)) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
259
305
|
}
|
|
260
306
|
const operationObject = pathObj[method];
|
|
261
|
-
if (!allowMissingId && !operationObject.operationId) {
|
|
307
|
+
if (!options.allowMissingId && !operationObject.operationId) {
|
|
262
308
|
return false;
|
|
263
309
|
}
|
|
264
310
|
const paramObject = operationObject.parameters;
|
|
265
311
|
const requestBody = operationObject.requestBody;
|
|
266
312
|
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
267
|
-
|
|
268
|
-
if (mediaTypesCount > 1) {
|
|
313
|
+
if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
|
|
269
314
|
return false;
|
|
270
315
|
}
|
|
271
|
-
const responseJson = Utils.getResponseJson(operationObject);
|
|
316
|
+
const responseJson = Utils.getResponseJson(operationObject, isTeamsAi);
|
|
272
317
|
if (Object.keys(responseJson).length === 0) {
|
|
273
318
|
return false;
|
|
274
319
|
}
|
|
320
|
+
// Teams AI project doesn't care about request parameters/body
|
|
321
|
+
if (isTeamsAi) {
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
275
324
|
let requestBodyParamResult = {
|
|
276
325
|
requiredNum: 0,
|
|
277
326
|
optionalNum: 0,
|
|
@@ -279,18 +328,26 @@ class Utils {
|
|
|
279
328
|
};
|
|
280
329
|
if (requestJsonBody) {
|
|
281
330
|
const requestBodySchema = requestJsonBody.schema;
|
|
282
|
-
|
|
331
|
+
if (isCopilot && requestBodySchema.type !== "object") {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
|
|
283
335
|
}
|
|
284
336
|
if (!requestBodyParamResult.isValid) {
|
|
285
337
|
return false;
|
|
286
338
|
}
|
|
287
|
-
const paramResult = Utils.checkParameters(paramObject);
|
|
339
|
+
const paramResult = Utils.checkParameters(paramObject, isCopilot);
|
|
288
340
|
if (!paramResult.isValid) {
|
|
289
341
|
return false;
|
|
290
342
|
}
|
|
343
|
+
// Copilot support arbitrary parameters
|
|
344
|
+
if (isCopilot) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
291
347
|
if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
|
|
292
|
-
if (allowMultipleParameters &&
|
|
293
|
-
requestBodyParamResult.requiredNum + paramResult.requiredNum <=
|
|
348
|
+
if (options.allowMultipleParameters &&
|
|
349
|
+
requestBodyParamResult.requiredNum + paramResult.requiredNum <=
|
|
350
|
+
ConstantString.SMERequiredParamsMaxNum) {
|
|
294
351
|
return true;
|
|
295
352
|
}
|
|
296
353
|
return false;
|
|
@@ -309,29 +366,31 @@ class Utils {
|
|
|
309
366
|
}
|
|
310
367
|
return false;
|
|
311
368
|
}
|
|
312
|
-
static isSupportedAuth(authSchemaArray,
|
|
369
|
+
static isSupportedAuth(authSchemaArray, options) {
|
|
313
370
|
if (authSchemaArray.length === 0) {
|
|
314
371
|
return true;
|
|
315
372
|
}
|
|
316
|
-
if (allowAPIKeyAuth || allowOauth2) {
|
|
373
|
+
if (options.allowAPIKeyAuth || options.allowOauth2) {
|
|
317
374
|
// Currently we don't support multiple auth in one operation
|
|
318
375
|
if (authSchemaArray.length > 0 && authSchemaArray.every((auths) => auths.length > 1)) {
|
|
319
376
|
return false;
|
|
320
377
|
}
|
|
321
378
|
for (const auths of authSchemaArray) {
|
|
322
379
|
if (auths.length === 1) {
|
|
323
|
-
if (!allowOauth2 &&
|
|
380
|
+
if (!options.allowOauth2 &&
|
|
381
|
+
options.allowAPIKeyAuth &&
|
|
382
|
+
Utils.isAPIKeyAuth(auths[0].authSchema)) {
|
|
324
383
|
return true;
|
|
325
384
|
}
|
|
326
|
-
else if (!allowAPIKeyAuth &&
|
|
327
|
-
allowOauth2 &&
|
|
328
|
-
Utils.
|
|
385
|
+
else if (!options.allowAPIKeyAuth &&
|
|
386
|
+
options.allowOauth2 &&
|
|
387
|
+
Utils.isOAuthWithAuthCodeFlow(auths[0].authSchema)) {
|
|
329
388
|
return true;
|
|
330
389
|
}
|
|
331
|
-
else if (allowAPIKeyAuth &&
|
|
332
|
-
allowOauth2 &&
|
|
390
|
+
else if (options.allowAPIKeyAuth &&
|
|
391
|
+
options.allowOauth2 &&
|
|
333
392
|
(Utils.isAPIKeyAuth(auths[0].authSchema) ||
|
|
334
|
-
Utils.
|
|
393
|
+
Utils.isOAuthWithAuthCodeFlow(auths[0].authSchema))) {
|
|
335
394
|
return true;
|
|
336
395
|
}
|
|
337
396
|
}
|
|
@@ -342,10 +401,11 @@ class Utils {
|
|
|
342
401
|
static isAPIKeyAuth(authSchema) {
|
|
343
402
|
return authSchema.type === "apiKey";
|
|
344
403
|
}
|
|
345
|
-
static
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
404
|
+
static isOAuthWithAuthCodeFlow(authSchema) {
|
|
405
|
+
if (authSchema.type === "oauth2" && authSchema.flows && authSchema.flows.authorizationCode) {
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
return false;
|
|
349
409
|
}
|
|
350
410
|
static getAuthArray(securities, spec) {
|
|
351
411
|
var _a;
|
|
@@ -373,18 +433,19 @@ class Utils {
|
|
|
373
433
|
static updateFirstLetter(str) {
|
|
374
434
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
375
435
|
}
|
|
376
|
-
static getResponseJson(operationObject) {
|
|
436
|
+
static getResponseJson(operationObject, isTeamsAiProject = false) {
|
|
377
437
|
var _a, _b;
|
|
378
438
|
let json = {};
|
|
379
439
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
380
440
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
381
|
-
const mediaTypesCount = Object.keys((responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) || {}).length;
|
|
382
|
-
if (mediaTypesCount > 1) {
|
|
383
|
-
return {};
|
|
384
|
-
}
|
|
385
441
|
if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
|
|
386
442
|
json = responseObject.content["application/json"];
|
|
387
|
-
|
|
443
|
+
if (!isTeamsAiProject && Utils.containMultipleMediaTypes(responseObject)) {
|
|
444
|
+
json = {};
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
388
449
|
}
|
|
389
450
|
}
|
|
390
451
|
return json;
|
|
@@ -458,7 +519,7 @@ class Utils {
|
|
|
458
519
|
}
|
|
459
520
|
return errors;
|
|
460
521
|
}
|
|
461
|
-
static validateServer(spec,
|
|
522
|
+
static validateServer(spec, options) {
|
|
462
523
|
const errors = [];
|
|
463
524
|
let hasTopLevelServers = false;
|
|
464
525
|
let hasPathLevelServers = false;
|
|
@@ -479,7 +540,7 @@ class Utils {
|
|
|
479
540
|
}
|
|
480
541
|
for (const method in methods) {
|
|
481
542
|
const operationObject = methods[method];
|
|
482
|
-
if (Utils.isSupportedApi(method, path, spec,
|
|
543
|
+
if (Utils.isSupportedApi(method, path, spec, options)) {
|
|
483
544
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
484
545
|
hasOperationLevelServers = true;
|
|
485
546
|
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
@@ -566,7 +627,7 @@ class Utils {
|
|
|
566
627
|
param.value = schema.default;
|
|
567
628
|
}
|
|
568
629
|
}
|
|
569
|
-
static parseApiInfo(operationItem,
|
|
630
|
+
static parseApiInfo(operationItem, options) {
|
|
570
631
|
var _a, _b;
|
|
571
632
|
const requiredParams = [];
|
|
572
633
|
const optionalParams = [];
|
|
@@ -580,7 +641,7 @@ class Utils {
|
|
|
580
641
|
description: ((_a = param.description) !== null && _a !== void 0 ? _a : "").slice(0, ConstantString.ParameterDescriptionMaxLens),
|
|
581
642
|
};
|
|
582
643
|
const schema = param.schema;
|
|
583
|
-
if (allowMultipleParameters && schema) {
|
|
644
|
+
if (options.allowMultipleParameters && schema) {
|
|
584
645
|
Utils.updateParameterWithInputType(schema, parameter);
|
|
585
646
|
}
|
|
586
647
|
if (param.in !== "header" && param.in !== "cookie") {
|
|
@@ -598,7 +659,7 @@ class Utils {
|
|
|
598
659
|
const requestJson = requestBody.content["application/json"];
|
|
599
660
|
if (Object.keys(requestJson).length !== 0) {
|
|
600
661
|
const schema = requestJson.schema;
|
|
601
|
-
const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", allowMultipleParameters, requestBody.required);
|
|
662
|
+
const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", !!options.allowMultipleParameters, requestBody.required);
|
|
602
663
|
requiredParams.push(...requiredP);
|
|
603
664
|
optionalParams.push(...optionalP);
|
|
604
665
|
}
|
|
@@ -629,14 +690,13 @@ class Utils {
|
|
|
629
690
|
}
|
|
630
691
|
return [command, warning];
|
|
631
692
|
}
|
|
632
|
-
static listSupportedAPIs(spec,
|
|
693
|
+
static listSupportedAPIs(spec, options) {
|
|
633
694
|
const paths = spec.paths;
|
|
634
695
|
const result = {};
|
|
635
696
|
for (const path in paths) {
|
|
636
697
|
const methods = paths[path];
|
|
637
698
|
for (const method in methods) {
|
|
638
|
-
|
|
639
|
-
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
|
|
699
|
+
if (Utils.isSupportedApi(method, path, spec, options)) {
|
|
640
700
|
const operationObject = methods[method];
|
|
641
701
|
result[`${method.toUpperCase()} ${path}`] = operationObject;
|
|
642
702
|
}
|
|
@@ -644,7 +704,7 @@ class Utils {
|
|
|
644
704
|
}
|
|
645
705
|
return result;
|
|
646
706
|
}
|
|
647
|
-
static validateSpec(spec, parser, isSwaggerFile,
|
|
707
|
+
static validateSpec(spec, parser, isSwaggerFile, options) {
|
|
648
708
|
const errors = [];
|
|
649
709
|
const warnings = [];
|
|
650
710
|
if (isSwaggerFile) {
|
|
@@ -654,7 +714,7 @@ class Utils {
|
|
|
654
714
|
});
|
|
655
715
|
}
|
|
656
716
|
// Server validation
|
|
657
|
-
const serverErrors = Utils.validateServer(spec,
|
|
717
|
+
const serverErrors = Utils.validateServer(spec, options);
|
|
658
718
|
errors.push(...serverErrors);
|
|
659
719
|
// Remote reference not supported
|
|
660
720
|
const refPaths = parser.$refs.paths();
|
|
@@ -667,7 +727,7 @@ class Utils {
|
|
|
667
727
|
});
|
|
668
728
|
}
|
|
669
729
|
// No supported API
|
|
670
|
-
const apiMap = Utils.listSupportedAPIs(spec,
|
|
730
|
+
const apiMap = Utils.listSupportedAPIs(spec, options);
|
|
671
731
|
if (Object.keys(apiMap).length === 0) {
|
|
672
732
|
errors.push({
|
|
673
733
|
type: ErrorType.NoSupportedApi,
|
|
@@ -723,14 +783,14 @@ class Utils {
|
|
|
723
783
|
|
|
724
784
|
// Copyright (c) Microsoft Corporation.
|
|
725
785
|
class SpecFilter {
|
|
726
|
-
static specFilter(filter, unResolveSpec, resolvedSpec,
|
|
786
|
+
static specFilter(filter, unResolveSpec, resolvedSpec, options) {
|
|
727
787
|
try {
|
|
728
788
|
const newSpec = Object.assign({}, unResolveSpec);
|
|
729
789
|
const newPaths = {};
|
|
730
790
|
for (const filterItem of filter) {
|
|
731
791
|
const [method, path] = filterItem.split(" ");
|
|
732
792
|
const methodName = method.toLowerCase();
|
|
733
|
-
if (!Utils.isSupportedApi(methodName, path, resolvedSpec,
|
|
793
|
+
if (!Utils.isSupportedApi(methodName, path, resolvedSpec, options)) {
|
|
734
794
|
continue;
|
|
735
795
|
}
|
|
736
796
|
if (!newPaths[path]) {
|
|
@@ -756,46 +816,168 @@ class SpecFilter {
|
|
|
756
816
|
|
|
757
817
|
// Copyright (c) Microsoft Corporation.
|
|
758
818
|
class ManifestUpdater {
|
|
759
|
-
static async
|
|
819
|
+
static async updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options) {
|
|
820
|
+
const manifest = await fs.readJSON(manifestPath);
|
|
821
|
+
const apiPluginRelativePath = ManifestUpdater.getRelativePath(manifestPath, apiPluginFilePath);
|
|
822
|
+
manifest.plugins = [
|
|
823
|
+
{
|
|
824
|
+
pluginFile: apiPluginRelativePath,
|
|
825
|
+
},
|
|
826
|
+
];
|
|
827
|
+
ManifestUpdater.updateManifestDescription(manifest, spec);
|
|
828
|
+
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
829
|
+
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, options);
|
|
830
|
+
return [manifest, apiPlugin];
|
|
831
|
+
}
|
|
832
|
+
static updateManifestDescription(manifest, spec) {
|
|
760
833
|
var _a, _b;
|
|
834
|
+
manifest.description = {
|
|
835
|
+
short: spec.info.title.slice(0, ConstantString.ShortDescriptionMaxLens),
|
|
836
|
+
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),
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
static mapOpenAPISchemaToFuncParam(schema, method, pathUrl) {
|
|
840
|
+
let parameter;
|
|
841
|
+
if (schema.type === "string" ||
|
|
842
|
+
schema.type === "boolean" ||
|
|
843
|
+
schema.type === "integer" ||
|
|
844
|
+
schema.type === "number" ||
|
|
845
|
+
schema.type === "array") {
|
|
846
|
+
parameter = schema;
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(schema)), ErrorType.UpdateManifestFailed);
|
|
850
|
+
}
|
|
851
|
+
return parameter;
|
|
852
|
+
}
|
|
853
|
+
static generatePluginManifestSchema(spec, specRelativePath, options) {
|
|
854
|
+
var _a, _b, _c;
|
|
855
|
+
const functions = [];
|
|
856
|
+
const functionNames = [];
|
|
857
|
+
const paths = spec.paths;
|
|
858
|
+
for (const pathUrl in paths) {
|
|
859
|
+
const pathItem = paths[pathUrl];
|
|
860
|
+
if (pathItem) {
|
|
861
|
+
const operations = pathItem;
|
|
862
|
+
for (const method in operations) {
|
|
863
|
+
if (options.allowMethods.includes(method)) {
|
|
864
|
+
const operationItem = operations[method];
|
|
865
|
+
if (operationItem) {
|
|
866
|
+
const operationId = operationItem.operationId;
|
|
867
|
+
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
868
|
+
const paramObject = operationItem.parameters;
|
|
869
|
+
const requestBody = operationItem.requestBody;
|
|
870
|
+
const parameters = {
|
|
871
|
+
type: "object",
|
|
872
|
+
properties: {},
|
|
873
|
+
required: [],
|
|
874
|
+
};
|
|
875
|
+
if (paramObject) {
|
|
876
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
877
|
+
const param = paramObject[i];
|
|
878
|
+
const schema = param.schema;
|
|
879
|
+
parameters.properties[param.name] = ManifestUpdater.mapOpenAPISchemaToFuncParam(schema, method, pathUrl);
|
|
880
|
+
if (param.required) {
|
|
881
|
+
parameters.required.push(param.name);
|
|
882
|
+
}
|
|
883
|
+
if (!parameters.properties[param.name].description) {
|
|
884
|
+
parameters.properties[param.name].description = (_b = param.description) !== null && _b !== void 0 ? _b : "";
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (requestBody) {
|
|
889
|
+
const requestJsonBody = requestBody.content["application/json"];
|
|
890
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
891
|
+
if (requestBodySchema.type === "object") {
|
|
892
|
+
if (requestBodySchema.required) {
|
|
893
|
+
parameters.required.push(...requestBodySchema.required);
|
|
894
|
+
}
|
|
895
|
+
for (const property in requestBodySchema.properties) {
|
|
896
|
+
const schema = requestBodySchema.properties[property];
|
|
897
|
+
parameters.properties[property] = ManifestUpdater.mapOpenAPISchemaToFuncParam(schema, method, pathUrl);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
const funcObj = {
|
|
905
|
+
name: operationId,
|
|
906
|
+
description: description,
|
|
907
|
+
parameters: parameters,
|
|
908
|
+
};
|
|
909
|
+
functions.push(funcObj);
|
|
910
|
+
functionNames.push(operationId);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
const apiPlugin = {
|
|
917
|
+
schema_version: "v2",
|
|
918
|
+
name_for_human: spec.info.title,
|
|
919
|
+
description_for_human: (_c = spec.info.description) !== null && _c !== void 0 ? _c : "<Please add description of the plugin>",
|
|
920
|
+
functions: functions,
|
|
921
|
+
runtimes: [
|
|
922
|
+
{
|
|
923
|
+
type: "OpenApi",
|
|
924
|
+
auth: {
|
|
925
|
+
type: "none", // TODO, support auth in the future
|
|
926
|
+
},
|
|
927
|
+
spec: {
|
|
928
|
+
url: specRelativePath,
|
|
929
|
+
},
|
|
930
|
+
run_for_functions: functionNames,
|
|
931
|
+
},
|
|
932
|
+
],
|
|
933
|
+
};
|
|
934
|
+
return apiPlugin;
|
|
935
|
+
}
|
|
936
|
+
static async updateManifest(manifestPath, outputSpecPath, spec, options, adaptiveCardFolder, authInfo) {
|
|
761
937
|
try {
|
|
762
938
|
const originalManifest = await fs.readJSON(manifestPath);
|
|
763
939
|
const updatedPart = {};
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
commands
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
940
|
+
updatedPart.composeExtensions = [];
|
|
941
|
+
let warnings = [];
|
|
942
|
+
if (options.projectType === ProjectType.SME) {
|
|
943
|
+
const updateResult = await ManifestUpdater.generateCommands(spec, manifestPath, options, adaptiveCardFolder);
|
|
944
|
+
const commands = updateResult[0];
|
|
945
|
+
warnings = updateResult[1];
|
|
946
|
+
const composeExtension = {
|
|
947
|
+
composeExtensionType: "apiBased",
|
|
948
|
+
apiSpecificationFile: ManifestUpdater.getRelativePath(manifestPath, outputSpecPath),
|
|
949
|
+
commands: commands,
|
|
950
|
+
};
|
|
951
|
+
if (authInfo) {
|
|
952
|
+
let auth = authInfo.authSchema;
|
|
953
|
+
if (Utils.isAPIKeyAuth(auth)) {
|
|
954
|
+
auth = auth;
|
|
955
|
+
const safeApiSecretRegistrationId = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix}`);
|
|
956
|
+
composeExtension.authorization = {
|
|
957
|
+
authType: "apiSecretServiceAuth",
|
|
958
|
+
apiSecretServiceAuthConfiguration: {
|
|
959
|
+
apiSecretRegistrationId: `\${{${safeApiSecretRegistrationId}}}`,
|
|
960
|
+
},
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
else if (Utils.isOAuthWithAuthCodeFlow(auth)) {
|
|
964
|
+
const safeOAuth2RegistrationId = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.OAuthRegistrationIdPostFix}`);
|
|
965
|
+
composeExtension.authorization = {
|
|
966
|
+
authType: "oAuth2.0",
|
|
967
|
+
oAuthConfiguration: {
|
|
968
|
+
oauthConfigurationId: `\${{${safeOAuth2RegistrationId}}}`,
|
|
969
|
+
},
|
|
970
|
+
};
|
|
971
|
+
updatedPart.webApplicationInfo = {
|
|
972
|
+
id: "${{AAD_APP_CLIENT_ID}}",
|
|
973
|
+
resource: "api://${{DOMAIN}}/${{AAD_APP_CLIENT_ID}}",
|
|
974
|
+
};
|
|
975
|
+
}
|
|
792
976
|
}
|
|
977
|
+
updatedPart.composeExtensions = [composeExtension];
|
|
793
978
|
}
|
|
794
|
-
updatedPart.description =
|
|
795
|
-
|
|
796
|
-
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),
|
|
797
|
-
};
|
|
798
|
-
updatedPart.composeExtensions = [composeExtension];
|
|
979
|
+
updatedPart.description = originalManifest.description;
|
|
980
|
+
ManifestUpdater.updateManifestDescription(updatedPart, spec);
|
|
799
981
|
const updatedManifest = Object.assign(Object.assign({}, originalManifest), updatedPart);
|
|
800
982
|
return [updatedManifest, warnings];
|
|
801
983
|
}
|
|
@@ -803,7 +985,8 @@ class ManifestUpdater {
|
|
|
803
985
|
throw new SpecParserError(err.toString(), ErrorType.UpdateManifestFailed);
|
|
804
986
|
}
|
|
805
987
|
}
|
|
806
|
-
static async generateCommands(spec,
|
|
988
|
+
static async generateCommands(spec, manifestPath, options, adaptiveCardFolder) {
|
|
989
|
+
var _a;
|
|
807
990
|
const paths = spec.paths;
|
|
808
991
|
const commands = [];
|
|
809
992
|
const warnings = [];
|
|
@@ -814,14 +997,16 @@ class ManifestUpdater {
|
|
|
814
997
|
const operations = pathItem;
|
|
815
998
|
// Currently only support GET and POST method
|
|
816
999
|
for (const method in operations) {
|
|
817
|
-
if (
|
|
1000
|
+
if ((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) {
|
|
818
1001
|
const operationItem = operations[method];
|
|
819
1002
|
if (operationItem) {
|
|
820
|
-
const [command, warning] = Utils.parseApiInfo(operationItem,
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
1003
|
+
const [command, warning] = Utils.parseApiInfo(operationItem, options);
|
|
1004
|
+
if (adaptiveCardFolder) {
|
|
1005
|
+
const adaptiveCardPath = path.join(adaptiveCardFolder, command.id + ".json");
|
|
1006
|
+
command.apiResponseRenderingTemplateFile = (await fs.pathExists(adaptiveCardPath))
|
|
1007
|
+
? ManifestUpdater.getRelativePath(manifestPath, adaptiveCardPath)
|
|
1008
|
+
: "";
|
|
1009
|
+
}
|
|
825
1010
|
if (warning) {
|
|
826
1011
|
warnings.push(warning);
|
|
827
1012
|
}
|
|
@@ -1106,6 +1291,8 @@ class SpecParser {
|
|
|
1106
1291
|
allowAPIKeyAuth: false,
|
|
1107
1292
|
allowMultipleParameters: false,
|
|
1108
1293
|
allowOauth2: false,
|
|
1294
|
+
allowMethods: ["get", "post"],
|
|
1295
|
+
projectType: ProjectType.SME,
|
|
1109
1296
|
};
|
|
1110
1297
|
this.pathOrSpec = pathOrDoc;
|
|
1111
1298
|
this.parser = new SwaggerParser();
|
|
@@ -1138,7 +1325,7 @@ class SpecParser {
|
|
|
1138
1325
|
],
|
|
1139
1326
|
};
|
|
1140
1327
|
}
|
|
1141
|
-
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options
|
|
1328
|
+
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options);
|
|
1142
1329
|
}
|
|
1143
1330
|
catch (err) {
|
|
1144
1331
|
throw new SpecParserError(err.toString(), ErrorType.ValidateFailed);
|
|
@@ -1200,48 +1387,105 @@ class SpecParser {
|
|
|
1200
1387
|
throw new SpecParserError(err.toString(), ErrorType.ListFailed);
|
|
1201
1388
|
}
|
|
1202
1389
|
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Generate specs according to the filters.
|
|
1392
|
+
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1393
|
+
*/
|
|
1394
|
+
async getFilteredSpecs(filter, signal) {
|
|
1395
|
+
try {
|
|
1396
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1397
|
+
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1398
|
+
}
|
|
1399
|
+
await this.loadSpec();
|
|
1400
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1401
|
+
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1402
|
+
}
|
|
1403
|
+
const newUnResolvedSpec = SpecFilter.specFilter(filter, this.unResolveSpec, this.spec, this.options);
|
|
1404
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1405
|
+
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1406
|
+
}
|
|
1407
|
+
const newSpec = (await this.parser.dereference(newUnResolvedSpec));
|
|
1408
|
+
return [newUnResolvedSpec, newSpec];
|
|
1409
|
+
}
|
|
1410
|
+
catch (err) {
|
|
1411
|
+
if (err instanceof SpecParserError) {
|
|
1412
|
+
throw err;
|
|
1413
|
+
}
|
|
1414
|
+
throw new SpecParserError(err.toString(), ErrorType.GetSpecFailed);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1203
1417
|
/**
|
|
1204
1418
|
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
1205
1419
|
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
1206
1420
|
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1207
1421
|
* @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
|
|
1208
|
-
* @param
|
|
1422
|
+
* @param pluginFilePath File path of the api plugin file to generate.
|
|
1209
1423
|
*/
|
|
1210
|
-
async
|
|
1424
|
+
async generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, signal) {
|
|
1211
1425
|
const result = {
|
|
1212
1426
|
allSuccess: true,
|
|
1213
1427
|
warnings: [],
|
|
1214
1428
|
};
|
|
1215
1429
|
try {
|
|
1216
|
-
|
|
1217
|
-
|
|
1430
|
+
const newSpecs = await this.getFilteredSpecs(filter, signal);
|
|
1431
|
+
const newUnResolvedSpec = newSpecs[0];
|
|
1432
|
+
const newSpec = newSpecs[1];
|
|
1433
|
+
let resultStr;
|
|
1434
|
+
if (outputSpecPath.endsWith(".yaml") || outputSpecPath.endsWith(".yml")) {
|
|
1435
|
+
resultStr = jsyaml.dump(newUnResolvedSpec);
|
|
1218
1436
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1437
|
+
else {
|
|
1438
|
+
resultStr = JSON.stringify(newUnResolvedSpec, null, 2);
|
|
1222
1439
|
}
|
|
1223
|
-
|
|
1440
|
+
await fs.outputFile(outputSpecPath, resultStr);
|
|
1224
1441
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1225
1442
|
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1226
1443
|
}
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
|
|
1444
|
+
const [updatedManifest, apiPlugin] = await ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options);
|
|
1445
|
+
await fs.outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1446
|
+
await fs.outputJSON(pluginFilePath, apiPlugin, { spaces: 2 });
|
|
1447
|
+
}
|
|
1448
|
+
catch (err) {
|
|
1449
|
+
if (err instanceof SpecParserError) {
|
|
1450
|
+
throw err;
|
|
1451
|
+
}
|
|
1452
|
+
throw new SpecParserError(err.toString(), ErrorType.GenerateFailed);
|
|
1453
|
+
}
|
|
1454
|
+
return result;
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
1458
|
+
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
1459
|
+
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1460
|
+
* @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
|
|
1461
|
+
* @param adaptiveCardFolder Folder path where the Adaptive Card files will be generated. If not specified or empty, Adaptive Card files will not be generated.
|
|
1462
|
+
*/
|
|
1463
|
+
async generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal) {
|
|
1464
|
+
const result = {
|
|
1465
|
+
allSuccess: true,
|
|
1466
|
+
warnings: [],
|
|
1467
|
+
};
|
|
1468
|
+
try {
|
|
1469
|
+
const newSpecs = await this.getFilteredSpecs(filter, signal);
|
|
1470
|
+
const newUnResolvedSpec = newSpecs[0];
|
|
1471
|
+
const newSpec = newSpecs[1];
|
|
1472
|
+
const authSet = new Set();
|
|
1473
|
+
let hasMultipleAuth = false;
|
|
1230
1474
|
for (const url in newSpec.paths) {
|
|
1231
1475
|
for (const method in newSpec.paths[url]) {
|
|
1232
1476
|
const operation = newSpec.paths[url][method];
|
|
1233
1477
|
const authArray = Utils.getAuthArray(operation.security, newSpec);
|
|
1234
1478
|
if (authArray && authArray.length > 0) {
|
|
1235
|
-
|
|
1236
|
-
if (
|
|
1237
|
-
|
|
1479
|
+
authSet.add(authArray[0][0]);
|
|
1480
|
+
if (authSet.size > 1) {
|
|
1481
|
+
hasMultipleAuth = true;
|
|
1238
1482
|
break;
|
|
1239
1483
|
}
|
|
1240
1484
|
}
|
|
1241
1485
|
}
|
|
1242
1486
|
}
|
|
1243
|
-
if (
|
|
1244
|
-
throw new SpecParserError(ConstantString.
|
|
1487
|
+
if (hasMultipleAuth && this.options.projectType !== ProjectType.TeamsAi) {
|
|
1488
|
+
throw new SpecParserError(ConstantString.MultipleAuthNotSupported, ErrorType.MultipleAuthNotSupported);
|
|
1245
1489
|
}
|
|
1246
1490
|
let resultStr;
|
|
1247
1491
|
if (outputSpecPath.endsWith(".yaml") || outputSpecPath.endsWith(".yml")) {
|
|
@@ -1251,26 +1495,28 @@ class SpecParser {
|
|
|
1251
1495
|
resultStr = JSON.stringify(newUnResolvedSpec, null, 2);
|
|
1252
1496
|
}
|
|
1253
1497
|
await fs.outputFile(outputSpecPath, resultStr);
|
|
1254
|
-
|
|
1255
|
-
for (const
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1498
|
+
if (adaptiveCardFolder) {
|
|
1499
|
+
for (const url in newSpec.paths) {
|
|
1500
|
+
for (const method in newSpec.paths[url]) {
|
|
1501
|
+
// paths object may contain description/summary which is not a http method, so we need to check if it is a operation object
|
|
1502
|
+
if (this.options.allowMethods.includes(method)) {
|
|
1503
|
+
const operation = newSpec.paths[url][method];
|
|
1504
|
+
try {
|
|
1505
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
1506
|
+
const fileName = path.join(adaptiveCardFolder, `${operation.operationId}.json`);
|
|
1507
|
+
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
1508
|
+
await fs.outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
1509
|
+
const dataFileName = path.join(adaptiveCardFolder, `${operation.operationId}.data.json`);
|
|
1510
|
+
await fs.outputJSON(dataFileName, {}, { spaces: 2 });
|
|
1511
|
+
}
|
|
1512
|
+
catch (err) {
|
|
1513
|
+
result.allSuccess = false;
|
|
1514
|
+
result.warnings.push({
|
|
1515
|
+
type: WarningType.GenerateCardFailed,
|
|
1516
|
+
content: err.toString(),
|
|
1517
|
+
data: operation.operationId,
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1274
1520
|
}
|
|
1275
1521
|
}
|
|
1276
1522
|
}
|
|
@@ -1278,8 +1524,8 @@ class SpecParser {
|
|
|
1278
1524
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1279
1525
|
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1280
1526
|
}
|
|
1281
|
-
const
|
|
1282
|
-
const [updatedManifest, warnings] = await ManifestUpdater.updateManifest(manifestPath, outputSpecPath,
|
|
1527
|
+
const authInfo = Array.from(authSet)[0];
|
|
1528
|
+
const [updatedManifest, warnings] = await ManifestUpdater.updateManifest(manifestPath, outputSpecPath, newSpec, this.options, adaptiveCardFolder, authInfo);
|
|
1283
1529
|
await fs.outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1284
1530
|
result.warnings.push(...warnings);
|
|
1285
1531
|
}
|
|
@@ -1308,11 +1554,11 @@ class SpecParser {
|
|
|
1308
1554
|
if (this.apiMap !== undefined) {
|
|
1309
1555
|
return this.apiMap;
|
|
1310
1556
|
}
|
|
1311
|
-
const result = Utils.listSupportedAPIs(spec, this.options
|
|
1557
|
+
const result = Utils.listSupportedAPIs(spec, this.options);
|
|
1312
1558
|
this.apiMap = result;
|
|
1313
1559
|
return result;
|
|
1314
1560
|
}
|
|
1315
1561
|
}
|
|
1316
1562
|
|
|
1317
|
-
export { ConstantString, ErrorType, SpecParser, SpecParserError, Utils, ValidationStatus, WarningType };
|
|
1563
|
+
export { AdaptiveCardGenerator, ConstantString, ErrorType, ProjectType, SpecParser, SpecParserError, Utils, ValidationStatus, WarningType };
|
|
1318
1564
|
//# sourceMappingURL=index.esm2017.mjs.map
|