@microsoft/m365-spec-parser 0.2.3 → 0.2.4-alpha.24cc1dfce.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 +344 -253
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +481 -332
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +344 -253
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +484 -333
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardGenerator.d.ts +5 -3
- package/dist/src/constants.d.ts +5 -4
- package/dist/src/interfaces.d.ts +12 -3
- package/dist/src/jsonDataGenerator.d.ts +6 -0
- package/dist/src/manifestUpdater.d.ts +3 -3
- package/dist/src/specParser.d.ts +2 -0
- package/dist/src/utils.d.ts +7 -4
- package/package.json +4 -4
package/dist/index.node.cjs.js
CHANGED
|
@@ -9,6 +9,7 @@ var fs = require('fs-extra');
|
|
|
9
9
|
var path = require('path');
|
|
10
10
|
var teamsManifest = require('@microsoft/teams-manifest');
|
|
11
11
|
var crypto = require('crypto');
|
|
12
|
+
var jsonSchemaRefParser = require('@apidevtools/json-schema-ref-parser');
|
|
12
13
|
|
|
13
14
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
15
|
|
|
@@ -80,11 +81,8 @@ exports.ErrorType = void 0;
|
|
|
80
81
|
ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
|
|
81
82
|
ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
|
|
82
83
|
ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
|
|
83
|
-
ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
|
|
84
84
|
ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
|
|
85
85
|
ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
|
|
86
|
-
ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
|
|
87
|
-
ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
|
|
88
86
|
ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
|
|
89
87
|
ErrorType["NoParameter"] = "no-parameter";
|
|
90
88
|
ErrorType["NoAPIInfo"] = "no-api-info";
|
|
@@ -103,6 +101,9 @@ exports.WarningType = void 0;
|
|
|
103
101
|
WarningType["OperationOnlyContainsOptionalParam"] = "operation-only-contains-optional-param";
|
|
104
102
|
WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
|
|
105
103
|
WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
|
|
104
|
+
WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
|
|
105
|
+
WarningType["UnsupportedAuthType"] = "unsupported-auth-type";
|
|
106
|
+
WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
|
|
106
107
|
WarningType["Unknown"] = "unknown";
|
|
107
108
|
})(exports.WarningType || (exports.WarningType = {}));
|
|
108
109
|
/**
|
|
@@ -140,25 +141,23 @@ ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converte
|
|
|
140
141
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
141
142
|
ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
|
|
142
143
|
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
144
|
+
ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
|
|
145
|
+
ConstantString.AuthTypeIsNotSupported = "Unsupported authorization type in API '%s'. No authorization will be used.";
|
|
143
146
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
144
147
|
ConstantString.FuncDescriptionTooLong = "The description of the function '%s' is too long. The current length is %s characters, while the maximum allowed length is %s characters.";
|
|
148
|
+
ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
|
|
145
149
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
146
150
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
147
151
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
148
152
|
ConstantString.GetMethod = "get";
|
|
149
153
|
ConstantString.PostMethod = "post";
|
|
150
154
|
ConstantString.AdaptiveCardVersion = "1.5";
|
|
151
|
-
ConstantString.AdaptiveCardSchema = "
|
|
155
|
+
ConstantString.AdaptiveCardSchema = "https://adaptivecards.io/schemas/adaptive-card.json";
|
|
152
156
|
ConstantString.AdaptiveCardType = "AdaptiveCard";
|
|
153
157
|
ConstantString.TextBlockType = "TextBlock";
|
|
154
158
|
ConstantString.ImageType = "Image";
|
|
155
159
|
ConstantString.ContainerType = "Container";
|
|
156
|
-
ConstantString.RegistrationIdPostfix =
|
|
157
|
-
apiKey: "REGISTRATION_ID",
|
|
158
|
-
oauth2: "CONFIGURATION_ID",
|
|
159
|
-
http: "REGISTRATION_ID",
|
|
160
|
-
openIdConnect: "REGISTRATION_ID",
|
|
161
|
-
};
|
|
160
|
+
ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
|
|
162
161
|
ConstantString.ResponseCodeFor20X = [
|
|
163
162
|
"200",
|
|
164
163
|
"201",
|
|
@@ -170,6 +169,7 @@ ConstantString.ResponseCodeFor20X = [
|
|
|
170
169
|
"207",
|
|
171
170
|
"208",
|
|
172
171
|
"226",
|
|
172
|
+
"2XX",
|
|
173
173
|
"default",
|
|
174
174
|
];
|
|
175
175
|
ConstantString.AllOperationMethods = [
|
|
@@ -235,16 +235,8 @@ class SpecParserError extends Error {
|
|
|
235
235
|
|
|
236
236
|
// Copyright (c) Microsoft Corporation.
|
|
237
237
|
class Utils {
|
|
238
|
-
static
|
|
239
|
-
|
|
240
|
-
for (const property in schema.properties) {
|
|
241
|
-
const nestedSchema = schema.properties[property];
|
|
242
|
-
if (nestedSchema.type === "object") {
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return false;
|
|
238
|
+
static isObjectSchema(schema) {
|
|
239
|
+
return schema.type === "object" || (!schema.type && !!schema.properties);
|
|
248
240
|
}
|
|
249
241
|
static containMultipleMediaTypes(bodyObject) {
|
|
250
242
|
return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
|
|
@@ -255,11 +247,32 @@ class Utils {
|
|
|
255
247
|
static isAPIKeyAuth(authScheme) {
|
|
256
248
|
return authScheme.type === "apiKey";
|
|
257
249
|
}
|
|
250
|
+
static isAPIKeyAuthButNotInCookie(authScheme) {
|
|
251
|
+
return authScheme.type === "apiKey" && authScheme.in !== "cookie";
|
|
252
|
+
}
|
|
258
253
|
static isOAuthWithAuthCodeFlow(authScheme) {
|
|
259
254
|
return !!(authScheme.type === "oauth2" &&
|
|
260
255
|
authScheme.flows &&
|
|
261
256
|
authScheme.flows.authorizationCode);
|
|
262
257
|
}
|
|
258
|
+
static isNotSupportedAuth(authSchemeArray) {
|
|
259
|
+
if (authSchemeArray.length === 0) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
for (const auths of authSchemeArray) {
|
|
266
|
+
if (auths.length === 1) {
|
|
267
|
+
if (Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme) ||
|
|
268
|
+
Utils.isBearerTokenAuth(auths[0].authScheme) ||
|
|
269
|
+
Utils.isAPIKeyAuthButNotInCookie(auths[0].authScheme)) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
263
276
|
static getAuthArray(securities, spec) {
|
|
264
277
|
var _a;
|
|
265
278
|
const result = [];
|
|
@@ -284,6 +297,20 @@ class Utils {
|
|
|
284
297
|
result.sort((a, b) => a[0].name.localeCompare(b[0].name));
|
|
285
298
|
return result;
|
|
286
299
|
}
|
|
300
|
+
static getAuthMap(spec) {
|
|
301
|
+
const authMap = {};
|
|
302
|
+
for (const url in spec.paths) {
|
|
303
|
+
for (const method in spec.paths[url]) {
|
|
304
|
+
const operation = spec.paths[url][method];
|
|
305
|
+
const authArray = Utils.getAuthArray(operation.security, spec);
|
|
306
|
+
if (authArray && authArray.length > 0) {
|
|
307
|
+
const currentAuth = authArray[0][0];
|
|
308
|
+
authMap[operation.operationId] = currentAuth;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return authMap;
|
|
313
|
+
}
|
|
287
314
|
static getAuthInfo(spec) {
|
|
288
315
|
let authInfo = undefined;
|
|
289
316
|
for (const url in spec.paths) {
|
|
@@ -312,27 +339,33 @@ class Utils {
|
|
|
312
339
|
let multipleMediaType = false;
|
|
313
340
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
314
341
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
315
|
-
if (responseObject
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
else {
|
|
328
|
-
return { json, multipleMediaType };
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
342
|
+
if (!responseObject) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
multipleMediaType = Utils.containMultipleMediaTypes(responseObject);
|
|
346
|
+
if (!allowMultipleMediaType && multipleMediaType) {
|
|
347
|
+
json = {};
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
const mediaObj = Utils.getJsonContentType(responseObject);
|
|
351
|
+
if (Object.keys(mediaObj).length > 0) {
|
|
352
|
+
json = mediaObj;
|
|
353
|
+
return { json, multipleMediaType };
|
|
332
354
|
}
|
|
333
355
|
}
|
|
334
356
|
return { json, multipleMediaType };
|
|
335
357
|
}
|
|
358
|
+
static getJsonContentType(responseObject) {
|
|
359
|
+
if (responseObject.content) {
|
|
360
|
+
for (const contentType of Object.keys(responseObject.content)) {
|
|
361
|
+
// json media type can also be "application/json; charset=utf-8"
|
|
362
|
+
if (contentType.indexOf("application/json") >= 0) {
|
|
363
|
+
return responseObject.content[contentType];
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return {};
|
|
368
|
+
}
|
|
336
369
|
static convertPathToCamelCase(path) {
|
|
337
370
|
const pathSegments = path.split(/[./{]/);
|
|
338
371
|
const camelCaseSegments = pathSegments.map((segment) => {
|
|
@@ -368,7 +401,7 @@ class Utils {
|
|
|
368
401
|
}
|
|
369
402
|
return newStr;
|
|
370
403
|
}
|
|
371
|
-
static checkServerUrl(servers) {
|
|
404
|
+
static checkServerUrl(servers, allowHttp = false) {
|
|
372
405
|
const errors = [];
|
|
373
406
|
let serverUrl;
|
|
374
407
|
try {
|
|
@@ -391,8 +424,7 @@ class Utils {
|
|
|
391
424
|
data: servers,
|
|
392
425
|
});
|
|
393
426
|
}
|
|
394
|
-
else if (protocol !== "https:") {
|
|
395
|
-
// Http server url is not supported
|
|
427
|
+
else if (protocol !== "https:" && !(protocol === "http:" && allowHttp)) {
|
|
396
428
|
const protocolString = protocol.slice(0, -1);
|
|
397
429
|
errors.push({
|
|
398
430
|
type: exports.ErrorType.UrlProtocolNotSupported,
|
|
@@ -408,10 +440,11 @@ class Utils {
|
|
|
408
440
|
let hasTopLevelServers = false;
|
|
409
441
|
let hasPathLevelServers = false;
|
|
410
442
|
let hasOperationLevelServers = false;
|
|
443
|
+
const allowHttp = options.projectType === exports.ProjectType.Copilot;
|
|
411
444
|
if (spec.servers && spec.servers.length >= 1) {
|
|
412
445
|
hasTopLevelServers = true;
|
|
413
446
|
// for multiple server, we only use the first url
|
|
414
|
-
const serverErrors = Utils.checkServerUrl(spec.servers);
|
|
447
|
+
const serverErrors = Utils.checkServerUrl(spec.servers, allowHttp);
|
|
415
448
|
errors.push(...serverErrors);
|
|
416
449
|
}
|
|
417
450
|
const paths = spec.paths;
|
|
@@ -419,7 +452,7 @@ class Utils {
|
|
|
419
452
|
const methods = paths[path];
|
|
420
453
|
if ((methods === null || methods === void 0 ? void 0 : methods.servers) && methods.servers.length >= 1) {
|
|
421
454
|
hasPathLevelServers = true;
|
|
422
|
-
const serverErrors = Utils.checkServerUrl(methods.servers);
|
|
455
|
+
const serverErrors = Utils.checkServerUrl(methods.servers, allowHttp);
|
|
423
456
|
errors.push(...serverErrors);
|
|
424
457
|
}
|
|
425
458
|
for (const method in methods) {
|
|
@@ -427,7 +460,7 @@ class Utils {
|
|
|
427
460
|
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
428
461
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
429
462
|
hasOperationLevelServers = true;
|
|
430
|
-
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
463
|
+
const serverErrors = Utils.checkServerUrl(operationObject.servers, allowHttp);
|
|
431
464
|
errors.push(...serverErrors);
|
|
432
465
|
}
|
|
433
466
|
}
|
|
@@ -474,7 +507,7 @@ class Utils {
|
|
|
474
507
|
optionalParams.push(parameter);
|
|
475
508
|
}
|
|
476
509
|
}
|
|
477
|
-
else if (schema
|
|
510
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
478
511
|
const { properties } = schema;
|
|
479
512
|
for (const property in properties) {
|
|
480
513
|
let isRequired = false;
|
|
@@ -588,29 +621,6 @@ class Utils {
|
|
|
588
621
|
const serverUrl = operationServer || methodServer || rootServer;
|
|
589
622
|
return serverUrl;
|
|
590
623
|
}
|
|
591
|
-
static limitACBodyProperties(body, maxCount) {
|
|
592
|
-
const result = [];
|
|
593
|
-
let currentCount = 0;
|
|
594
|
-
for (const element of body) {
|
|
595
|
-
if (element.type === ConstantString.ContainerType) {
|
|
596
|
-
const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
|
|
597
|
-
result.push({
|
|
598
|
-
type: ConstantString.ContainerType,
|
|
599
|
-
$data: element.$data,
|
|
600
|
-
items: items,
|
|
601
|
-
});
|
|
602
|
-
currentCount += items.length;
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
result.push(element);
|
|
606
|
-
currentCount++;
|
|
607
|
-
}
|
|
608
|
-
if (currentCount >= maxCount) {
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return result;
|
|
613
|
-
}
|
|
614
624
|
}
|
|
615
625
|
|
|
616
626
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -739,22 +749,6 @@ class Validator {
|
|
|
739
749
|
}
|
|
740
750
|
return result;
|
|
741
751
|
}
|
|
742
|
-
validateResponse(method, path) {
|
|
743
|
-
const result = { isValid: true, reason: [] };
|
|
744
|
-
const operationObject = this.spec.paths[path][method];
|
|
745
|
-
const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
|
|
746
|
-
if (this.options.projectType === exports.ProjectType.SME) {
|
|
747
|
-
// only support response body only contains “application/json” content type
|
|
748
|
-
if (multipleMediaType) {
|
|
749
|
-
result.reason.push(exports.ErrorType.ResponseContainMultipleMediaTypes);
|
|
750
|
-
}
|
|
751
|
-
else if (Object.keys(json).length === 0) {
|
|
752
|
-
// response body should not be empty
|
|
753
|
-
result.reason.push(exports.ErrorType.ResponseJsonIsEmpty);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return result;
|
|
757
|
-
}
|
|
758
752
|
validateServer(method, path) {
|
|
759
753
|
const result = { isValid: true, reason: [] };
|
|
760
754
|
const serverObj = Utils.getServerObject(this.spec, method, path);
|
|
@@ -763,8 +757,8 @@ class Validator {
|
|
|
763
757
|
result.reason.push(exports.ErrorType.NoServerInformation);
|
|
764
758
|
}
|
|
765
759
|
else {
|
|
766
|
-
|
|
767
|
-
const serverValidateResult = Utils.checkServerUrl([serverObj]);
|
|
760
|
+
const allowHttp = this.projectType === exports.ProjectType.Copilot;
|
|
761
|
+
const serverValidateResult = Utils.checkServerUrl([serverObj], allowHttp);
|
|
768
762
|
result.reason.push(...serverValidateResult.map((item) => item.type));
|
|
769
763
|
}
|
|
770
764
|
return result;
|
|
@@ -787,6 +781,9 @@ class Validator {
|
|
|
787
781
|
reason: [exports.ErrorType.MultipleAuthNotSupported],
|
|
788
782
|
};
|
|
789
783
|
}
|
|
784
|
+
if (this.projectType === exports.ProjectType.Copilot) {
|
|
785
|
+
return { isValid: true, reason: [] };
|
|
786
|
+
}
|
|
790
787
|
for (const auths of authSchemeArray) {
|
|
791
788
|
if (auths.length === 1) {
|
|
792
789
|
if ((this.options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
|
|
@@ -799,125 +796,6 @@ class Validator {
|
|
|
799
796
|
}
|
|
800
797
|
return { isValid: false, reason: [exports.ErrorType.AuthTypeIsNotSupported] };
|
|
801
798
|
}
|
|
802
|
-
checkPostBodySchema(schema, isRequired = false) {
|
|
803
|
-
var _a;
|
|
804
|
-
const paramResult = {
|
|
805
|
-
requiredNum: 0,
|
|
806
|
-
optionalNum: 0,
|
|
807
|
-
isValid: true,
|
|
808
|
-
reason: [],
|
|
809
|
-
};
|
|
810
|
-
if (Object.keys(schema).length === 0) {
|
|
811
|
-
return paramResult;
|
|
812
|
-
}
|
|
813
|
-
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
814
|
-
const isCopilot = this.projectType === exports.ProjectType.Copilot;
|
|
815
|
-
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
816
|
-
paramResult.isValid = false;
|
|
817
|
-
paramResult.reason = [exports.ErrorType.RequestBodyContainsNestedObject];
|
|
818
|
-
return paramResult;
|
|
819
|
-
}
|
|
820
|
-
if (schema.type === "string" ||
|
|
821
|
-
schema.type === "integer" ||
|
|
822
|
-
schema.type === "boolean" ||
|
|
823
|
-
schema.type === "number") {
|
|
824
|
-
if (isRequiredWithoutDefault) {
|
|
825
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
else if (schema.type === "object") {
|
|
832
|
-
const { properties } = schema;
|
|
833
|
-
for (const property in properties) {
|
|
834
|
-
let isRequired = false;
|
|
835
|
-
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
836
|
-
isRequired = true;
|
|
837
|
-
}
|
|
838
|
-
const result = this.checkPostBodySchema(properties[property], isRequired);
|
|
839
|
-
paramResult.requiredNum += result.requiredNum;
|
|
840
|
-
paramResult.optionalNum += result.optionalNum;
|
|
841
|
-
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
842
|
-
paramResult.reason.push(...result.reason);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
else {
|
|
846
|
-
if (isRequiredWithoutDefault && !isCopilot) {
|
|
847
|
-
paramResult.isValid = false;
|
|
848
|
-
paramResult.reason.push(exports.ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
return paramResult;
|
|
852
|
-
}
|
|
853
|
-
checkParamSchema(paramObject) {
|
|
854
|
-
const paramResult = {
|
|
855
|
-
requiredNum: 0,
|
|
856
|
-
optionalNum: 0,
|
|
857
|
-
isValid: true,
|
|
858
|
-
reason: [],
|
|
859
|
-
};
|
|
860
|
-
if (!paramObject) {
|
|
861
|
-
return paramResult;
|
|
862
|
-
}
|
|
863
|
-
const isCopilot = this.projectType === exports.ProjectType.Copilot;
|
|
864
|
-
for (let i = 0; i < paramObject.length; i++) {
|
|
865
|
-
const param = paramObject[i];
|
|
866
|
-
const schema = param.schema;
|
|
867
|
-
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
868
|
-
paramResult.isValid = false;
|
|
869
|
-
paramResult.reason.push(exports.ErrorType.ParamsContainsNestedObject);
|
|
870
|
-
continue;
|
|
871
|
-
}
|
|
872
|
-
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
873
|
-
if (isCopilot) {
|
|
874
|
-
if (isRequiredWithoutDefault) {
|
|
875
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
876
|
-
}
|
|
877
|
-
else {
|
|
878
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
879
|
-
}
|
|
880
|
-
continue;
|
|
881
|
-
}
|
|
882
|
-
if (param.in === "header" || param.in === "cookie") {
|
|
883
|
-
if (isRequiredWithoutDefault) {
|
|
884
|
-
paramResult.isValid = false;
|
|
885
|
-
paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
886
|
-
}
|
|
887
|
-
continue;
|
|
888
|
-
}
|
|
889
|
-
if (schema.type !== "boolean" &&
|
|
890
|
-
schema.type !== "string" &&
|
|
891
|
-
schema.type !== "number" &&
|
|
892
|
-
schema.type !== "integer") {
|
|
893
|
-
if (isRequiredWithoutDefault) {
|
|
894
|
-
paramResult.isValid = false;
|
|
895
|
-
paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
896
|
-
}
|
|
897
|
-
continue;
|
|
898
|
-
}
|
|
899
|
-
if (param.in === "query" || param.in === "path") {
|
|
900
|
-
if (isRequiredWithoutDefault) {
|
|
901
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
902
|
-
}
|
|
903
|
-
else {
|
|
904
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
return paramResult;
|
|
909
|
-
}
|
|
910
|
-
hasNestedObjectInSchema(schema) {
|
|
911
|
-
if (schema.type === "object") {
|
|
912
|
-
for (const property in schema.properties) {
|
|
913
|
-
const nestedSchema = schema.properties[property];
|
|
914
|
-
if (nestedSchema.type === "object") {
|
|
915
|
-
return true;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
return false;
|
|
920
|
-
}
|
|
921
799
|
}
|
|
922
800
|
|
|
923
801
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -927,7 +805,6 @@ class CopilotValidator extends Validator {
|
|
|
927
805
|
this.projectType = exports.ProjectType.Copilot;
|
|
928
806
|
this.options = options;
|
|
929
807
|
this.spec = spec;
|
|
930
|
-
this.checkCircularReference();
|
|
931
808
|
}
|
|
932
809
|
validateSpec() {
|
|
933
810
|
const result = { errors: [], warnings: [] };
|
|
@@ -953,10 +830,6 @@ class CopilotValidator extends Validator {
|
|
|
953
830
|
if (!methodAndPathResult.isValid) {
|
|
954
831
|
return methodAndPathResult;
|
|
955
832
|
}
|
|
956
|
-
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
957
|
-
if (!circularReferenceResult.isValid) {
|
|
958
|
-
return circularReferenceResult;
|
|
959
|
-
}
|
|
960
833
|
const operationObject = this.spec.paths[path][method];
|
|
961
834
|
// validate auth
|
|
962
835
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -968,24 +841,6 @@ class CopilotValidator extends Validator {
|
|
|
968
841
|
// validate server
|
|
969
842
|
const validateServerResult = this.validateServer(method, path);
|
|
970
843
|
result.reason.push(...validateServerResult.reason);
|
|
971
|
-
// validate response
|
|
972
|
-
const validateResponseResult = this.validateResponse(method, path);
|
|
973
|
-
result.reason.push(...validateResponseResult.reason);
|
|
974
|
-
// validate requestBody
|
|
975
|
-
const requestBody = operationObject.requestBody;
|
|
976
|
-
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
977
|
-
if (requestJsonBody) {
|
|
978
|
-
const requestBodySchema = requestJsonBody.schema;
|
|
979
|
-
if (requestBodySchema.type !== "object") {
|
|
980
|
-
result.reason.push(exports.ErrorType.PostBodySchemaIsNotJson);
|
|
981
|
-
}
|
|
982
|
-
const requestBodyParamResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
|
|
983
|
-
result.reason.push(...requestBodyParamResult.reason);
|
|
984
|
-
}
|
|
985
|
-
// validate parameters
|
|
986
|
-
const paramObject = operationObject.parameters;
|
|
987
|
-
const paramResult = this.checkParamSchema(paramObject);
|
|
988
|
-
result.reason.push(...paramResult.reason);
|
|
989
844
|
if (result.reason.length > 0) {
|
|
990
845
|
result.isValid = false;
|
|
991
846
|
}
|
|
@@ -1077,6 +932,108 @@ class SMEValidator extends Validator {
|
|
|
1077
932
|
}
|
|
1078
933
|
return result;
|
|
1079
934
|
}
|
|
935
|
+
validateResponse(method, path) {
|
|
936
|
+
const result = { isValid: true, reason: [] };
|
|
937
|
+
const operationObject = this.spec.paths[path][method];
|
|
938
|
+
const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
|
|
939
|
+
// only support response body only contains “application/json” content type
|
|
940
|
+
if (multipleMediaType) {
|
|
941
|
+
result.reason.push(exports.ErrorType.ResponseContainMultipleMediaTypes);
|
|
942
|
+
}
|
|
943
|
+
else if (Object.keys(json).length === 0) {
|
|
944
|
+
// response body should not be empty
|
|
945
|
+
result.reason.push(exports.ErrorType.ResponseJsonIsEmpty);
|
|
946
|
+
}
|
|
947
|
+
return result;
|
|
948
|
+
}
|
|
949
|
+
checkPostBodySchema(schema, isRequired = false) {
|
|
950
|
+
var _a;
|
|
951
|
+
const paramResult = {
|
|
952
|
+
requiredNum: 0,
|
|
953
|
+
optionalNum: 0,
|
|
954
|
+
isValid: true,
|
|
955
|
+
reason: [],
|
|
956
|
+
};
|
|
957
|
+
if (Object.keys(schema).length === 0) {
|
|
958
|
+
return paramResult;
|
|
959
|
+
}
|
|
960
|
+
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
961
|
+
const isCopilot = this.projectType === exports.ProjectType.Copilot;
|
|
962
|
+
if (schema.type === "string" ||
|
|
963
|
+
schema.type === "integer" ||
|
|
964
|
+
schema.type === "boolean" ||
|
|
965
|
+
schema.type === "number") {
|
|
966
|
+
if (isRequiredWithoutDefault) {
|
|
967
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
968
|
+
}
|
|
969
|
+
else {
|
|
970
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
974
|
+
const { properties } = schema;
|
|
975
|
+
for (const property in properties) {
|
|
976
|
+
let isRequired = false;
|
|
977
|
+
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
978
|
+
isRequired = true;
|
|
979
|
+
}
|
|
980
|
+
const result = this.checkPostBodySchema(properties[property], isRequired);
|
|
981
|
+
paramResult.requiredNum += result.requiredNum;
|
|
982
|
+
paramResult.optionalNum += result.optionalNum;
|
|
983
|
+
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
984
|
+
paramResult.reason.push(...result.reason);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
if (isRequiredWithoutDefault && !isCopilot) {
|
|
989
|
+
paramResult.isValid = false;
|
|
990
|
+
paramResult.reason.push(exports.ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
return paramResult;
|
|
994
|
+
}
|
|
995
|
+
checkParamSchema(paramObject) {
|
|
996
|
+
const paramResult = {
|
|
997
|
+
requiredNum: 0,
|
|
998
|
+
optionalNum: 0,
|
|
999
|
+
isValid: true,
|
|
1000
|
+
reason: [],
|
|
1001
|
+
};
|
|
1002
|
+
if (!paramObject) {
|
|
1003
|
+
return paramResult;
|
|
1004
|
+
}
|
|
1005
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
1006
|
+
const param = paramObject[i];
|
|
1007
|
+
const schema = param.schema;
|
|
1008
|
+
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
1009
|
+
if (param.in === "header" || param.in === "cookie") {
|
|
1010
|
+
if (isRequiredWithoutDefault) {
|
|
1011
|
+
paramResult.isValid = false;
|
|
1012
|
+
paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
1013
|
+
}
|
|
1014
|
+
continue;
|
|
1015
|
+
}
|
|
1016
|
+
if (schema.type !== "boolean" &&
|
|
1017
|
+
schema.type !== "string" &&
|
|
1018
|
+
schema.type !== "number" &&
|
|
1019
|
+
schema.type !== "integer") {
|
|
1020
|
+
if (isRequiredWithoutDefault) {
|
|
1021
|
+
paramResult.isValid = false;
|
|
1022
|
+
paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
1023
|
+
}
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
1026
|
+
if (param.in === "query" || param.in === "path") {
|
|
1027
|
+
if (isRequiredWithoutDefault) {
|
|
1028
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
1029
|
+
}
|
|
1030
|
+
else {
|
|
1031
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return paramResult;
|
|
1036
|
+
}
|
|
1080
1037
|
validateParamCount(postBodyResult, paramResult) {
|
|
1081
1038
|
const result = { isValid: true, reason: [] };
|
|
1082
1039
|
const totalRequiredParams = postBodyResult.requiredNum + paramResult.requiredNum;
|
|
@@ -1354,20 +1311,157 @@ class SpecFilter {
|
|
|
1354
1311
|
}
|
|
1355
1312
|
}
|
|
1356
1313
|
|
|
1314
|
+
// Copyright (c) Microsoft Corporation.
|
|
1315
|
+
class JsonDataGenerator {
|
|
1316
|
+
static generate(schema) {
|
|
1317
|
+
return this.generateMockData(schema);
|
|
1318
|
+
}
|
|
1319
|
+
static generateMockData(schema) {
|
|
1320
|
+
if (this.visitedSchemas.has(schema)) {
|
|
1321
|
+
return null; // Prevent circular reference
|
|
1322
|
+
}
|
|
1323
|
+
this.visitedSchemas.add(schema);
|
|
1324
|
+
let result;
|
|
1325
|
+
if (schema.anyOf) {
|
|
1326
|
+
// Select the first schema in anyOf
|
|
1327
|
+
const selectedSchema = schema.anyOf[0];
|
|
1328
|
+
result = this.generateMockData(selectedSchema);
|
|
1329
|
+
}
|
|
1330
|
+
else if (schema.oneOf) {
|
|
1331
|
+
// Select the first schema in oneOf
|
|
1332
|
+
const selectedSchema = schema.oneOf[0];
|
|
1333
|
+
result = this.generateMockData(selectedSchema);
|
|
1334
|
+
}
|
|
1335
|
+
else if (schema.allOf) {
|
|
1336
|
+
// merge all schemas in allOf
|
|
1337
|
+
result = {};
|
|
1338
|
+
for (const subschema of schema.allOf) {
|
|
1339
|
+
const data = this.generateMockData(subschema);
|
|
1340
|
+
result = Object.assign(Object.assign({}, result), data);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
else {
|
|
1344
|
+
switch (schema.type) {
|
|
1345
|
+
case "string":
|
|
1346
|
+
if (schema.example !== undefined) {
|
|
1347
|
+
result = schema.example;
|
|
1348
|
+
}
|
|
1349
|
+
else if (schema.format) {
|
|
1350
|
+
switch (schema.format) {
|
|
1351
|
+
case "date-time":
|
|
1352
|
+
result = "2024-11-01T05:25:43.593Z";
|
|
1353
|
+
break;
|
|
1354
|
+
case "email":
|
|
1355
|
+
result = "example@example.com";
|
|
1356
|
+
break;
|
|
1357
|
+
case "uuid":
|
|
1358
|
+
result = "123e4567-e89b-12d3-a456-426614174000";
|
|
1359
|
+
break;
|
|
1360
|
+
case "ipv4":
|
|
1361
|
+
result = "192.168.0.1";
|
|
1362
|
+
break;
|
|
1363
|
+
case "ipv6":
|
|
1364
|
+
result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
|
|
1365
|
+
break;
|
|
1366
|
+
default:
|
|
1367
|
+
result = "example string";
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
else {
|
|
1371
|
+
result = "example string";
|
|
1372
|
+
}
|
|
1373
|
+
break;
|
|
1374
|
+
case "number":
|
|
1375
|
+
if (schema.example !== undefined) {
|
|
1376
|
+
result = schema.example;
|
|
1377
|
+
}
|
|
1378
|
+
else if (schema.format) {
|
|
1379
|
+
switch (schema.format) {
|
|
1380
|
+
case "float":
|
|
1381
|
+
result = 3.14;
|
|
1382
|
+
break;
|
|
1383
|
+
case "double":
|
|
1384
|
+
result = 3.14159;
|
|
1385
|
+
break;
|
|
1386
|
+
default:
|
|
1387
|
+
result = 123;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
else {
|
|
1391
|
+
result = 123;
|
|
1392
|
+
}
|
|
1393
|
+
break;
|
|
1394
|
+
case "integer":
|
|
1395
|
+
if (schema.example !== undefined) {
|
|
1396
|
+
result = schema.example;
|
|
1397
|
+
}
|
|
1398
|
+
else if (schema.format) {
|
|
1399
|
+
switch (schema.format) {
|
|
1400
|
+
case "int32":
|
|
1401
|
+
result = 123456;
|
|
1402
|
+
break;
|
|
1403
|
+
case "int64":
|
|
1404
|
+
result = 123456789;
|
|
1405
|
+
break;
|
|
1406
|
+
default:
|
|
1407
|
+
result = 123;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
else {
|
|
1411
|
+
result = 123;
|
|
1412
|
+
}
|
|
1413
|
+
break;
|
|
1414
|
+
case "boolean":
|
|
1415
|
+
result = schema.example !== undefined ? schema.example : true;
|
|
1416
|
+
break;
|
|
1417
|
+
case "array":
|
|
1418
|
+
result = [this.generateMockData(schema.items)];
|
|
1419
|
+
break;
|
|
1420
|
+
case "object":
|
|
1421
|
+
result = {};
|
|
1422
|
+
if (schema.properties) {
|
|
1423
|
+
for (const key in schema.properties) {
|
|
1424
|
+
result[key] = this.generateMockData(schema.properties[key]);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
break;
|
|
1428
|
+
default:
|
|
1429
|
+
result = schema.example || null;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
this.visitedSchemas.delete(schema);
|
|
1433
|
+
return result;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
JsonDataGenerator.visitedSchemas = new Set();
|
|
1437
|
+
|
|
1357
1438
|
// Copyright (c) Microsoft Corporation.
|
|
1358
1439
|
class AdaptiveCardGenerator {
|
|
1359
|
-
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1440
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
|
|
1360
1441
|
try {
|
|
1361
1442
|
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1362
1443
|
let cardBody = [];
|
|
1444
|
+
let jsonData = {};
|
|
1445
|
+
const warnings = [];
|
|
1446
|
+
const operationId = operationItem.operationId;
|
|
1363
1447
|
let schema = json.schema;
|
|
1364
1448
|
let jsonPath = "$";
|
|
1365
1449
|
if (schema && Object.keys(schema).length > 0) {
|
|
1450
|
+
try {
|
|
1451
|
+
jsonData = JsonDataGenerator.generate(schema);
|
|
1452
|
+
}
|
|
1453
|
+
catch (err) {
|
|
1454
|
+
warnings.push({
|
|
1455
|
+
type: exports.WarningType.GenerateJsonDataFailed,
|
|
1456
|
+
content: Utils.format(ConstantString.GenerateJsonDataFailed, operationId, err.toString()),
|
|
1457
|
+
data: operationId,
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1366
1460
|
jsonPath = AdaptiveCardGenerator.getResponseJsonPathFromSchema(schema);
|
|
1367
1461
|
if (jsonPath !== "$") {
|
|
1368
1462
|
schema = schema.properties[jsonPath];
|
|
1369
1463
|
}
|
|
1370
|
-
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
|
|
1464
|
+
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount);
|
|
1371
1465
|
}
|
|
1372
1466
|
// if no schema, try to use example value
|
|
1373
1467
|
if (cardBody.length === 0 && (json.examples || json.example)) {
|
|
@@ -1395,16 +1489,20 @@ class AdaptiveCardGenerator {
|
|
|
1395
1489
|
version: ConstantString.AdaptiveCardVersion,
|
|
1396
1490
|
body: cardBody,
|
|
1397
1491
|
};
|
|
1398
|
-
return [fullCard, jsonPath];
|
|
1492
|
+
return [fullCard, jsonPath, jsonData, warnings];
|
|
1399
1493
|
}
|
|
1400
1494
|
catch (err) {
|
|
1401
1495
|
throw new SpecParserError(err.toString(), exports.ErrorType.GenerateAdaptiveCardFailed);
|
|
1402
1496
|
}
|
|
1403
1497
|
}
|
|
1404
|
-
static generateCardFromResponse(schema, name, parentArrayName = "") {
|
|
1498
|
+
static generateCardFromResponse(schema, name, parentArrayName = "", maxElementCount = Number.MAX_SAFE_INTEGER, counter = { count: 0 }) {
|
|
1499
|
+
if (counter.count >= maxElementCount) {
|
|
1500
|
+
return [];
|
|
1501
|
+
}
|
|
1405
1502
|
if (schema.type === "array") {
|
|
1406
1503
|
// schema.items can be arbitrary object: schema { type: array, items: {} }
|
|
1407
1504
|
if (Object.keys(schema.items).length === 0) {
|
|
1505
|
+
counter.count++;
|
|
1408
1506
|
return [
|
|
1409
1507
|
{
|
|
1410
1508
|
type: ConstantString.TextBlockType,
|
|
@@ -1413,7 +1511,7 @@ class AdaptiveCardGenerator {
|
|
|
1413
1511
|
},
|
|
1414
1512
|
];
|
|
1415
1513
|
}
|
|
1416
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
|
|
1514
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name, maxElementCount, counter);
|
|
1417
1515
|
const template = {
|
|
1418
1516
|
type: ConstantString.ContainerType,
|
|
1419
1517
|
$data: name ? `\${${name}}` : "${$root}",
|
|
@@ -1423,11 +1521,11 @@ class AdaptiveCardGenerator {
|
|
|
1423
1521
|
return [template];
|
|
1424
1522
|
}
|
|
1425
1523
|
// some schema may not contain type but contain properties
|
|
1426
|
-
if (
|
|
1524
|
+
if (Utils.isObjectSchema(schema)) {
|
|
1427
1525
|
const { properties } = schema;
|
|
1428
1526
|
const result = [];
|
|
1429
1527
|
for (const property in properties) {
|
|
1430
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
|
|
1528
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName, maxElementCount, counter);
|
|
1431
1529
|
result.push(...obj);
|
|
1432
1530
|
}
|
|
1433
1531
|
if (schema.additionalProperties) {
|
|
@@ -1440,6 +1538,7 @@ class AdaptiveCardGenerator {
|
|
|
1440
1538
|
schema.type === "integer" ||
|
|
1441
1539
|
schema.type === "boolean" ||
|
|
1442
1540
|
schema.type === "number") {
|
|
1541
|
+
counter.count++;
|
|
1443
1542
|
if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
|
|
1444
1543
|
// string in root: "ddd"
|
|
1445
1544
|
let text = "result: ${$root}";
|
|
@@ -1464,24 +1563,17 @@ class AdaptiveCardGenerator {
|
|
|
1464
1563
|
];
|
|
1465
1564
|
}
|
|
1466
1565
|
else {
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
{
|
|
1479
|
-
type: "Image",
|
|
1480
|
-
url: "${$data}",
|
|
1481
|
-
$when: "${$data != null && $data != ''}",
|
|
1482
|
-
},
|
|
1483
|
-
];
|
|
1484
|
-
}
|
|
1566
|
+
const url = name ? `\${${name}}` : "${$data}";
|
|
1567
|
+
const condition = name
|
|
1568
|
+
? `\${${name} != null && ${name} != ''}`
|
|
1569
|
+
: "${$data != null && $data != ''}";
|
|
1570
|
+
return [
|
|
1571
|
+
{
|
|
1572
|
+
type: "Image",
|
|
1573
|
+
url,
|
|
1574
|
+
$when: condition,
|
|
1575
|
+
},
|
|
1576
|
+
];
|
|
1485
1577
|
}
|
|
1486
1578
|
}
|
|
1487
1579
|
if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
|
|
@@ -1491,7 +1583,7 @@ class AdaptiveCardGenerator {
|
|
|
1491
1583
|
}
|
|
1492
1584
|
// Find the first array property in the response schema object with the well-known name
|
|
1493
1585
|
static getResponseJsonPathFromSchema(schema) {
|
|
1494
|
-
if (
|
|
1586
|
+
if (Utils.isObjectSchema(schema)) {
|
|
1495
1587
|
const { properties } = schema;
|
|
1496
1588
|
for (const property in properties) {
|
|
1497
1589
|
const schema = properties[property];
|
|
@@ -1643,7 +1735,7 @@ function inferProperties(card) {
|
|
|
1643
1735
|
|
|
1644
1736
|
// Copyright (c) Microsoft Corporation.
|
|
1645
1737
|
class ManifestUpdater {
|
|
1646
|
-
static updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options,
|
|
1738
|
+
static updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options, authMap, existingPluginManifestInfo) {
|
|
1647
1739
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1648
1740
|
const manifest = yield fs__default['default'].readJSON(manifestPath);
|
|
1649
1741
|
const apiPluginRelativePath = ManifestUpdater.getRelativePath(manifestPath, apiPluginFilePath);
|
|
@@ -1674,7 +1766,7 @@ class ManifestUpdater {
|
|
|
1674
1766
|
}
|
|
1675
1767
|
const appName = this.removeEnvs(manifest.name.short);
|
|
1676
1768
|
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
1677
|
-
const [apiPlugin, warnings] = yield ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName,
|
|
1769
|
+
const [apiPlugin, warnings] = yield ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authMap, options, existingPluginManifestInfo);
|
|
1678
1770
|
return [manifest, apiPlugin, warnings];
|
|
1679
1771
|
});
|
|
1680
1772
|
}
|
|
@@ -1697,29 +1789,14 @@ class ManifestUpdater {
|
|
|
1697
1789
|
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(schema)), exports.ErrorType.UpdateManifestFailed);
|
|
1698
1790
|
}
|
|
1699
1791
|
}
|
|
1700
|
-
static generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName,
|
|
1792
|
+
static generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authMap, options, existingPluginManifestInfo) {
|
|
1701
1793
|
var _a, _b, _c, _d;
|
|
1702
1794
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1703
1795
|
const warnings = [];
|
|
1704
1796
|
const functions = [];
|
|
1705
|
-
const
|
|
1797
|
+
const functionNamesMap = {};
|
|
1706
1798
|
const conversationStarters = [];
|
|
1707
1799
|
const paths = spec.paths;
|
|
1708
|
-
const pluginAuthObj = {
|
|
1709
|
-
type: "None",
|
|
1710
|
-
};
|
|
1711
|
-
if (authInfo) {
|
|
1712
|
-
if (Utils.isOAuthWithAuthCodeFlow(authInfo.authScheme)) {
|
|
1713
|
-
pluginAuthObj.type = "OAuthPluginVault";
|
|
1714
|
-
}
|
|
1715
|
-
else if (Utils.isBearerTokenAuth(authInfo.authScheme)) {
|
|
1716
|
-
pluginAuthObj.type = "ApiKeyPluginVault";
|
|
1717
|
-
}
|
|
1718
|
-
if (pluginAuthObj.type !== "None") {
|
|
1719
|
-
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1720
|
-
pluginAuthObj.reference_id = `\${{${safeRegistrationIdName}}}`;
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
1800
|
for (const pathUrl in paths) {
|
|
1724
1801
|
const pathItem = paths[pathUrl];
|
|
1725
1802
|
if (pathItem) {
|
|
@@ -1727,36 +1804,11 @@ class ManifestUpdater {
|
|
|
1727
1804
|
for (const method in operations) {
|
|
1728
1805
|
if (options.allowMethods.includes(method)) {
|
|
1729
1806
|
const operationItem = operations[method];
|
|
1730
|
-
const confirmationBodies = [];
|
|
1731
1807
|
if (operationItem) {
|
|
1732
1808
|
const operationId = operationItem.operationId;
|
|
1733
1809
|
const safeFunctionName = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
1734
1810
|
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
1735
1811
|
const summary = operationItem.summary;
|
|
1736
|
-
const paramObject = operationItem.parameters;
|
|
1737
|
-
const requestBody = operationItem.requestBody;
|
|
1738
|
-
if (paramObject) {
|
|
1739
|
-
for (let i = 0; i < paramObject.length; i++) {
|
|
1740
|
-
const param = paramObject[i];
|
|
1741
|
-
const schema = param.schema;
|
|
1742
|
-
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1743
|
-
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
if (requestBody) {
|
|
1747
|
-
const requestJsonBody = requestBody.content["application/json"];
|
|
1748
|
-
const requestBodySchema = requestJsonBody.schema;
|
|
1749
|
-
if (requestBodySchema.type === "object") {
|
|
1750
|
-
for (const property in requestBodySchema.properties) {
|
|
1751
|
-
const schema = requestBodySchema.properties[property];
|
|
1752
|
-
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1753
|
-
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
else {
|
|
1757
|
-
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), exports.ErrorType.UpdateManifestFailed);
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
1812
|
let funcDescription = operationItem.description || operationItem.summary || "";
|
|
1761
1813
|
if (funcDescription.length > ConstantString.FunctionDescriptionMaxLens) {
|
|
1762
1814
|
warnings.push({
|
|
@@ -1774,8 +1826,7 @@ class ManifestUpdater {
|
|
|
1774
1826
|
try {
|
|
1775
1827
|
const { json } = Utils.getResponseJson(operationItem);
|
|
1776
1828
|
if (json.schema) {
|
|
1777
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
|
|
1778
|
-
card.body = Utils.limitACBodyProperties(card.body, 5);
|
|
1829
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
|
|
1779
1830
|
const responseSemantic = wrapResponseSemantics(card, jsonPath);
|
|
1780
1831
|
funcObj.capabilities = {
|
|
1781
1832
|
response_semantics: responseSemantic,
|
|
@@ -1791,19 +1842,66 @@ class ManifestUpdater {
|
|
|
1791
1842
|
}
|
|
1792
1843
|
}
|
|
1793
1844
|
if (options.allowConfirmation && method !== ConstantString.GetMethod) {
|
|
1794
|
-
|
|
1795
|
-
|
|
1845
|
+
const paramObject = operationItem.parameters;
|
|
1846
|
+
const requestBody = operationItem.requestBody;
|
|
1847
|
+
const confirmationBodies = [];
|
|
1848
|
+
if (paramObject) {
|
|
1849
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
1850
|
+
const param = paramObject[i];
|
|
1851
|
+
const schema = param.schema;
|
|
1852
|
+
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1853
|
+
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
if (requestBody) {
|
|
1857
|
+
const requestJsonBody = Utils.getJsonContentType(requestBody);
|
|
1858
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
1859
|
+
if (Utils.isObjectSchema(requestBodySchema)) {
|
|
1860
|
+
for (const property in requestBodySchema.properties) {
|
|
1861
|
+
const schema = requestBodySchema.properties[property];
|
|
1862
|
+
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1863
|
+
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
else {
|
|
1867
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), exports.ErrorType.UpdateManifestFailed);
|
|
1868
|
+
}
|
|
1796
1869
|
}
|
|
1797
|
-
funcObj.capabilities.confirmation = {
|
|
1798
|
-
type: "AdaptiveCard",
|
|
1799
|
-
title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
|
|
1800
|
-
};
|
|
1801
1870
|
if (confirmationBodies.length > 0) {
|
|
1871
|
+
if (!funcObj.capabilities) {
|
|
1872
|
+
funcObj.capabilities = {};
|
|
1873
|
+
}
|
|
1874
|
+
funcObj.capabilities.confirmation = {
|
|
1875
|
+
type: "AdaptiveCard",
|
|
1876
|
+
title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
|
|
1877
|
+
};
|
|
1802
1878
|
funcObj.capabilities.confirmation.body = confirmationBodies.join("\n");
|
|
1803
1879
|
}
|
|
1804
1880
|
}
|
|
1805
1881
|
functions.push(funcObj);
|
|
1806
|
-
|
|
1882
|
+
const authInfo = authMap[operationId];
|
|
1883
|
+
let key = "None";
|
|
1884
|
+
let authName = "None";
|
|
1885
|
+
if (authInfo) {
|
|
1886
|
+
if (Utils.isOAuthWithAuthCodeFlow(authInfo.authScheme)) {
|
|
1887
|
+
key = "OAuthPluginVault";
|
|
1888
|
+
authName = authInfo.name;
|
|
1889
|
+
}
|
|
1890
|
+
else if (Utils.isBearerTokenAuth(authInfo.authScheme) ||
|
|
1891
|
+
Utils.isAPIKeyAuthButNotInCookie(authInfo.authScheme)) {
|
|
1892
|
+
key = "ApiKeyPluginVault";
|
|
1893
|
+
authName = authInfo.name;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
if (functionNamesMap[key]) {
|
|
1897
|
+
functionNamesMap[key].functionNames.push(safeFunctionName);
|
|
1898
|
+
}
|
|
1899
|
+
else {
|
|
1900
|
+
functionNamesMap[key] = {
|
|
1901
|
+
functionNames: [safeFunctionName],
|
|
1902
|
+
authName: authName,
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1807
1905
|
const conversationStarterStr = (summary !== null && summary !== void 0 ? summary : description).slice(0, ConstantString.ConversationStarterMaxLens);
|
|
1808
1906
|
if (conversationStarterStr) {
|
|
1809
1907
|
conversationStarters.push(conversationStarterStr);
|
|
@@ -1813,6 +1911,12 @@ class ManifestUpdater {
|
|
|
1813
1911
|
}
|
|
1814
1912
|
}
|
|
1815
1913
|
}
|
|
1914
|
+
if (Object.keys(functionNamesMap).length === 0) {
|
|
1915
|
+
functionNamesMap["None"] = {
|
|
1916
|
+
functionNames: [],
|
|
1917
|
+
authName: "None",
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1816
1920
|
let apiPlugin;
|
|
1817
1921
|
if (yield fs__default['default'].pathExists(apiPluginFilePath)) {
|
|
1818
1922
|
apiPlugin = yield fs__default['default'].readJSON(apiPluginFilePath);
|
|
@@ -1848,24 +1952,35 @@ class ManifestUpdater {
|
|
|
1848
1952
|
const relativePath = ManifestUpdater.getRelativePath(existingPluginManifestInfo.manifestPath, existingPluginManifestInfo.specPath);
|
|
1849
1953
|
apiPlugin.runtimes = apiPlugin.runtimes.filter((runtime) => runtime.spec.url !== relativePath);
|
|
1850
1954
|
}
|
|
1851
|
-
const
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1955
|
+
for (const authType in functionNamesMap) {
|
|
1956
|
+
const pluginAuthObj = {
|
|
1957
|
+
type: authType,
|
|
1958
|
+
};
|
|
1959
|
+
const authName = functionNamesMap[authType].authName;
|
|
1960
|
+
if (pluginAuthObj.type !== "None") {
|
|
1961
|
+
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authName}_${ConstantString.RegistrationIdPostfix}`);
|
|
1962
|
+
pluginAuthObj.reference_id = `\${{${safeRegistrationIdName}}}`;
|
|
1963
|
+
}
|
|
1964
|
+
const functionNamesInfo = functionNamesMap[authType];
|
|
1965
|
+
const index = apiPlugin.runtimes.findIndex((runtime) => {
|
|
1966
|
+
var _a, _b;
|
|
1967
|
+
return runtime.spec.url === specRelativePath &&
|
|
1968
|
+
runtime.type === "OpenApi" &&
|
|
1969
|
+
((_b = (_a = runtime.auth) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : "None") === authType;
|
|
1865
1970
|
});
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1971
|
+
if (index === -1) {
|
|
1972
|
+
apiPlugin.runtimes.push({
|
|
1973
|
+
type: "OpenApi",
|
|
1974
|
+
auth: pluginAuthObj,
|
|
1975
|
+
spec: {
|
|
1976
|
+
url: specRelativePath,
|
|
1977
|
+
},
|
|
1978
|
+
run_for_functions: functionNamesInfo.functionNames,
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
else {
|
|
1982
|
+
apiPlugin.runtimes[index].run_for_functions = functionNamesInfo.functionNames;
|
|
1983
|
+
}
|
|
1869
1984
|
}
|
|
1870
1985
|
if (!apiPlugin.name_for_human) {
|
|
1871
1986
|
apiPlugin.name_for_human = appName;
|
|
@@ -1908,7 +2023,7 @@ class ManifestUpdater {
|
|
|
1908
2023
|
};
|
|
1909
2024
|
if (authInfo) {
|
|
1910
2025
|
const auth = authInfo.authScheme;
|
|
1911
|
-
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix
|
|
2026
|
+
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix}`);
|
|
1912
2027
|
if (Utils.isAPIKeyAuth(auth) || Utils.isBearerTokenAuth(auth)) {
|
|
1913
2028
|
composeExtension.authorization = {
|
|
1914
2029
|
authType: "apiSecretServiceAuth",
|
|
@@ -2038,6 +2153,7 @@ class SpecParser {
|
|
|
2038
2153
|
};
|
|
2039
2154
|
this.pathOrSpec = pathOrDoc;
|
|
2040
2155
|
this.parser = new SwaggerParser__default['default']();
|
|
2156
|
+
this.refParser = new jsonSchemaRefParser.$RefParser();
|
|
2041
2157
|
this.options = Object.assign(Object.assign({}, this.defaultOptions), (options !== null && options !== void 0 ? options : {}));
|
|
2042
2158
|
}
|
|
2043
2159
|
/**
|
|
@@ -2051,12 +2167,15 @@ class SpecParser {
|
|
|
2051
2167
|
let hash = "";
|
|
2052
2168
|
try {
|
|
2053
2169
|
yield this.loadSpec();
|
|
2054
|
-
if (!this.
|
|
2170
|
+
if (!this.refParser.$refs.circular) {
|
|
2055
2171
|
yield this.parser.validate(this.spec);
|
|
2056
2172
|
}
|
|
2057
2173
|
else {
|
|
2174
|
+
// The following code hangs for Graph API, support will be added when SwaggerParser is updated.
|
|
2175
|
+
/*
|
|
2058
2176
|
const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec));
|
|
2059
|
-
|
|
2177
|
+
await this.parser.validate(clonedUnResolveSpec);
|
|
2178
|
+
*/
|
|
2060
2179
|
}
|
|
2061
2180
|
}
|
|
2062
2181
|
catch (e) {
|
|
@@ -2084,7 +2203,7 @@ class SpecParser {
|
|
|
2084
2203
|
};
|
|
2085
2204
|
}
|
|
2086
2205
|
// Remote reference not supported
|
|
2087
|
-
const refPaths = this.
|
|
2206
|
+
const refPaths = this.refParser.$refs.paths();
|
|
2088
2207
|
// refPaths [0] is the current spec file path
|
|
2089
2208
|
if (refPaths.length > 1) {
|
|
2090
2209
|
errors.push({
|
|
@@ -2219,7 +2338,7 @@ class SpecParser {
|
|
|
2219
2338
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
2220
2339
|
}
|
|
2221
2340
|
const clonedUnResolveSpec = JSON.parse(JSON.stringify(newUnResolvedSpec));
|
|
2222
|
-
const newSpec =
|
|
2341
|
+
const newSpec = yield this.deReferenceSpec(clonedUnResolveSpec);
|
|
2223
2342
|
return [newUnResolvedSpec, newSpec];
|
|
2224
2343
|
}
|
|
2225
2344
|
catch (err) {
|
|
@@ -2230,6 +2349,12 @@ class SpecParser {
|
|
|
2230
2349
|
}
|
|
2231
2350
|
});
|
|
2232
2351
|
}
|
|
2352
|
+
deReferenceSpec(spec) {
|
|
2353
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2354
|
+
const result = yield this.refParser.dereference(spec);
|
|
2355
|
+
return result;
|
|
2356
|
+
});
|
|
2357
|
+
}
|
|
2233
2358
|
/**
|
|
2234
2359
|
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
2235
2360
|
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
@@ -2247,7 +2372,31 @@ class SpecParser {
|
|
|
2247
2372
|
const newSpecs = yield this.getFilteredSpecs(filter, signal);
|
|
2248
2373
|
const newUnResolvedSpec = newSpecs[0];
|
|
2249
2374
|
const newSpec = newSpecs[1];
|
|
2250
|
-
const
|
|
2375
|
+
const paths = newUnResolvedSpec.paths;
|
|
2376
|
+
for (const pathUrl in paths) {
|
|
2377
|
+
const operations = paths[pathUrl];
|
|
2378
|
+
for (const method in operations) {
|
|
2379
|
+
const operationItem = operations[method];
|
|
2380
|
+
const operationId = operationItem.operationId;
|
|
2381
|
+
const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
|
|
2382
|
+
if (containsSpecialCharacters) {
|
|
2383
|
+
operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2384
|
+
result.warnings.push({
|
|
2385
|
+
type: exports.WarningType.OperationIdContainsSpecialCharacters,
|
|
2386
|
+
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2387
|
+
data: operationId,
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
const authArray = Utils.getAuthArray(operationItem.security, newSpec);
|
|
2391
|
+
if (Utils.isNotSupportedAuth(authArray)) {
|
|
2392
|
+
result.warnings.push({
|
|
2393
|
+
type: exports.WarningType.UnsupportedAuthType,
|
|
2394
|
+
content: Utils.format(ConstantString.AuthTypeIsNotSupported, operationId),
|
|
2395
|
+
data: operationId,
|
|
2396
|
+
});
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2251
2400
|
yield this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
|
|
2252
2401
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
2253
2402
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
@@ -2258,7 +2407,8 @@ class SpecParser {
|
|
|
2258
2407
|
specPath: this.pathOrSpec,
|
|
2259
2408
|
}
|
|
2260
2409
|
: undefined;
|
|
2261
|
-
const
|
|
2410
|
+
const authMap = Utils.getAuthMap(newSpec);
|
|
2411
|
+
const [updatedManifest, apiPlugin, warnings] = yield ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authMap, existingPluginManifestInfo);
|
|
2262
2412
|
result.warnings.push(...warnings);
|
|
2263
2413
|
yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 4 });
|
|
2264
2414
|
yield fs__default['default'].outputJSON(pluginFilePath, apiPlugin, { spaces: 4 });
|
|
@@ -2301,13 +2451,14 @@ class SpecParser {
|
|
|
2301
2451
|
if (this.options.allowMethods.includes(method)) {
|
|
2302
2452
|
const operation = newSpec.paths[url][method];
|
|
2303
2453
|
try {
|
|
2304
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
2454
|
+
const [card, jsonPath, jsonData, warnings] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
2455
|
+
result.warnings.push(...warnings);
|
|
2305
2456
|
const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2306
2457
|
const fileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
|
|
2307
2458
|
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
2308
2459
|
yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
2309
2460
|
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
|
|
2310
|
-
yield fs__default['default'].outputJSON(dataFileName,
|
|
2461
|
+
yield fs__default['default'].outputJSON(dataFileName, jsonData, { spaces: 2 });
|
|
2311
2462
|
}
|
|
2312
2463
|
catch (err) {
|
|
2313
2464
|
result.allSuccess = false;
|
|
@@ -2349,7 +2500,7 @@ class SpecParser {
|
|
|
2349
2500
|
this.isSwaggerFile = true;
|
|
2350
2501
|
}
|
|
2351
2502
|
const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec));
|
|
2352
|
-
this.spec =
|
|
2503
|
+
this.spec = yield this.deReferenceSpec(clonedUnResolveSpec);
|
|
2353
2504
|
}
|
|
2354
2505
|
});
|
|
2355
2506
|
}
|