@microsoft/m365-spec-parser 0.2.5-beta.2025012205.0 → 0.2.5-rc.1
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 +193 -176
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +274 -295
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +193 -176
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +275 -298
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/constants.d.ts +4 -3
- package/dist/src/interfaces.d.ts +3 -10
- package/dist/src/manifestUpdater.d.ts +3 -3
- package/dist/src/specParser.d.ts +0 -1
- package/dist/src/utils.d.ts +3 -6
- package/package.json +4 -3
package/dist/index.esm2017.mjs
CHANGED
|
@@ -38,8 +38,11 @@ var ErrorType;
|
|
|
38
38
|
ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
|
|
39
39
|
ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
|
|
40
40
|
ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
|
|
41
|
+
ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
|
|
41
42
|
ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
|
|
42
43
|
ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
|
|
44
|
+
ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
|
|
45
|
+
ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
|
|
43
46
|
ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
|
|
44
47
|
ErrorType["NoParameter"] = "no-parameter";
|
|
45
48
|
ErrorType["NoAPIInfo"] = "no-api-info";
|
|
@@ -59,7 +62,6 @@ var WarningType;
|
|
|
59
62
|
WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
|
|
60
63
|
WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
|
|
61
64
|
WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
|
|
62
|
-
WarningType["UnsupportedAuthType"] = "unsupported-auth-type";
|
|
63
65
|
WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
|
|
64
66
|
WarningType["Unknown"] = "unknown";
|
|
65
67
|
})(WarningType || (WarningType = {}));
|
|
@@ -99,7 +101,6 @@ ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please conve
|
|
|
99
101
|
ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
|
|
100
102
|
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
101
103
|
ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
|
|
102
|
-
ConstantString.AuthTypeIsNotSupported = "Unsupported authorization type in API '%s'. No authorization will be used.";
|
|
103
104
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
104
105
|
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.";
|
|
105
106
|
ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
|
|
@@ -109,12 +110,17 @@ ConstantString.WrappedCardResponseLayout = "list";
|
|
|
109
110
|
ConstantString.GetMethod = "get";
|
|
110
111
|
ConstantString.PostMethod = "post";
|
|
111
112
|
ConstantString.AdaptiveCardVersion = "1.5";
|
|
112
|
-
ConstantString.AdaptiveCardSchema = "
|
|
113
|
+
ConstantString.AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json";
|
|
113
114
|
ConstantString.AdaptiveCardType = "AdaptiveCard";
|
|
114
115
|
ConstantString.TextBlockType = "TextBlock";
|
|
115
116
|
ConstantString.ImageType = "Image";
|
|
116
117
|
ConstantString.ContainerType = "Container";
|
|
117
|
-
ConstantString.RegistrationIdPostfix =
|
|
118
|
+
ConstantString.RegistrationIdPostfix = {
|
|
119
|
+
apiKey: "REGISTRATION_ID",
|
|
120
|
+
oauth2: "CONFIGURATION_ID",
|
|
121
|
+
http: "REGISTRATION_ID",
|
|
122
|
+
openIdConnect: "REGISTRATION_ID",
|
|
123
|
+
};
|
|
118
124
|
ConstantString.ResponseCodeFor20X = [
|
|
119
125
|
"200",
|
|
120
126
|
"201",
|
|
@@ -126,7 +132,6 @@ ConstantString.ResponseCodeFor20X = [
|
|
|
126
132
|
"207",
|
|
127
133
|
"208",
|
|
128
134
|
"226",
|
|
129
|
-
"2XX",
|
|
130
135
|
"default",
|
|
131
136
|
];
|
|
132
137
|
ConstantString.AllOperationMethods = [
|
|
@@ -192,6 +197,17 @@ class SpecParserError extends Error {
|
|
|
192
197
|
|
|
193
198
|
// Copyright (c) Microsoft Corporation.
|
|
194
199
|
class Utils {
|
|
200
|
+
static hasNestedObjectInSchema(schema) {
|
|
201
|
+
if (this.isObjectSchema(schema)) {
|
|
202
|
+
for (const property in schema.properties) {
|
|
203
|
+
const nestedSchema = schema.properties[property];
|
|
204
|
+
if (this.isObjectSchema(nestedSchema)) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
195
211
|
static isObjectSchema(schema) {
|
|
196
212
|
return schema.type === "object" || (!schema.type && !!schema.properties);
|
|
197
213
|
}
|
|
@@ -204,32 +220,11 @@ class Utils {
|
|
|
204
220
|
static isAPIKeyAuth(authScheme) {
|
|
205
221
|
return authScheme.type === "apiKey";
|
|
206
222
|
}
|
|
207
|
-
static isAPIKeyAuthButNotInCookie(authScheme) {
|
|
208
|
-
return authScheme.type === "apiKey" && authScheme.in !== "cookie";
|
|
209
|
-
}
|
|
210
223
|
static isOAuthWithAuthCodeFlow(authScheme) {
|
|
211
224
|
return !!(authScheme.type === "oauth2" &&
|
|
212
225
|
authScheme.flows &&
|
|
213
226
|
authScheme.flows.authorizationCode);
|
|
214
227
|
}
|
|
215
|
-
static isNotSupportedAuth(authSchemeArray) {
|
|
216
|
-
if (authSchemeArray.length === 0) {
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
for (const auths of authSchemeArray) {
|
|
223
|
-
if (auths.length === 1) {
|
|
224
|
-
if (Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme) ||
|
|
225
|
-
Utils.isBearerTokenAuth(auths[0].authScheme) ||
|
|
226
|
-
Utils.isAPIKeyAuthButNotInCookie(auths[0].authScheme)) {
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
228
|
static getAuthArray(securities, spec) {
|
|
234
229
|
var _a;
|
|
235
230
|
const result = [];
|
|
@@ -254,20 +249,6 @@ class Utils {
|
|
|
254
249
|
result.sort((a, b) => a[0].name.localeCompare(b[0].name));
|
|
255
250
|
return result;
|
|
256
251
|
}
|
|
257
|
-
static getAuthMap(spec) {
|
|
258
|
-
const authMap = {};
|
|
259
|
-
for (const url in spec.paths) {
|
|
260
|
-
for (const method in spec.paths[url]) {
|
|
261
|
-
const operation = spec.paths[url][method];
|
|
262
|
-
const authArray = Utils.getAuthArray(operation.security, spec);
|
|
263
|
-
if (authArray && authArray.length > 0) {
|
|
264
|
-
const currentAuth = authArray[0][0];
|
|
265
|
-
authMap[operation.operationId] = currentAuth;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
return authMap;
|
|
270
|
-
}
|
|
271
252
|
static getAuthInfo(spec) {
|
|
272
253
|
let authInfo = undefined;
|
|
273
254
|
for (const url in spec.paths) {
|
|
@@ -296,32 +277,26 @@ class Utils {
|
|
|
296
277
|
let multipleMediaType = false;
|
|
297
278
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
298
279
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
static getJsonContentType(responseObject) {
|
|
316
|
-
if (responseObject.content) {
|
|
317
|
-
for (const contentType of Object.keys(responseObject.content)) {
|
|
318
|
-
// json media type can also be "application/json; charset=utf-8"
|
|
319
|
-
if (contentType.indexOf("application/json") >= 0) {
|
|
320
|
-
return responseObject.content[contentType];
|
|
280
|
+
if (responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) {
|
|
281
|
+
for (const contentType of Object.keys(responseObject.content)) {
|
|
282
|
+
// json media type can also be "application/json; charset=utf-8"
|
|
283
|
+
if (contentType.indexOf("application/json") >= 0) {
|
|
284
|
+
multipleMediaType = false;
|
|
285
|
+
json = responseObject.content[contentType];
|
|
286
|
+
if (Utils.containMultipleMediaTypes(responseObject)) {
|
|
287
|
+
multipleMediaType = true;
|
|
288
|
+
if (!allowMultipleMediaType) {
|
|
289
|
+
json = {};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
return { json, multipleMediaType };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
321
296
|
}
|
|
322
297
|
}
|
|
323
298
|
}
|
|
324
|
-
return {};
|
|
299
|
+
return { json, multipleMediaType };
|
|
325
300
|
}
|
|
326
301
|
static convertPathToCamelCase(path) {
|
|
327
302
|
const pathSegments = path.split(/[./{]/);
|
|
@@ -358,7 +333,7 @@ class Utils {
|
|
|
358
333
|
}
|
|
359
334
|
return newStr;
|
|
360
335
|
}
|
|
361
|
-
static checkServerUrl(servers
|
|
336
|
+
static checkServerUrl(servers) {
|
|
362
337
|
const errors = [];
|
|
363
338
|
let serverUrl;
|
|
364
339
|
try {
|
|
@@ -381,7 +356,8 @@ class Utils {
|
|
|
381
356
|
data: servers,
|
|
382
357
|
});
|
|
383
358
|
}
|
|
384
|
-
else if (protocol !== "https:"
|
|
359
|
+
else if (protocol !== "https:") {
|
|
360
|
+
// Http server url is not supported
|
|
385
361
|
const protocolString = protocol.slice(0, -1);
|
|
386
362
|
errors.push({
|
|
387
363
|
type: ErrorType.UrlProtocolNotSupported,
|
|
@@ -397,11 +373,10 @@ class Utils {
|
|
|
397
373
|
let hasTopLevelServers = false;
|
|
398
374
|
let hasPathLevelServers = false;
|
|
399
375
|
let hasOperationLevelServers = false;
|
|
400
|
-
const allowHttp = options.projectType === ProjectType.Copilot;
|
|
401
376
|
if (spec.servers && spec.servers.length >= 1) {
|
|
402
377
|
hasTopLevelServers = true;
|
|
403
378
|
// for multiple server, we only use the first url
|
|
404
|
-
const serverErrors = Utils.checkServerUrl(spec.servers
|
|
379
|
+
const serverErrors = Utils.checkServerUrl(spec.servers);
|
|
405
380
|
errors.push(...serverErrors);
|
|
406
381
|
}
|
|
407
382
|
const paths = spec.paths;
|
|
@@ -409,7 +384,7 @@ class Utils {
|
|
|
409
384
|
const methods = paths[path];
|
|
410
385
|
if ((methods === null || methods === void 0 ? void 0 : methods.servers) && methods.servers.length >= 1) {
|
|
411
386
|
hasPathLevelServers = true;
|
|
412
|
-
const serverErrors = Utils.checkServerUrl(methods.servers
|
|
387
|
+
const serverErrors = Utils.checkServerUrl(methods.servers);
|
|
413
388
|
errors.push(...serverErrors);
|
|
414
389
|
}
|
|
415
390
|
for (const method in methods) {
|
|
@@ -417,7 +392,7 @@ class Utils {
|
|
|
417
392
|
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
418
393
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
419
394
|
hasOperationLevelServers = true;
|
|
420
|
-
const serverErrors = Utils.checkServerUrl(operationObject.servers
|
|
395
|
+
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
421
396
|
errors.push(...serverErrors);
|
|
422
397
|
}
|
|
423
398
|
}
|
|
@@ -706,6 +681,22 @@ class Validator {
|
|
|
706
681
|
}
|
|
707
682
|
return result;
|
|
708
683
|
}
|
|
684
|
+
validateResponse(method, path) {
|
|
685
|
+
const result = { isValid: true, reason: [] };
|
|
686
|
+
const operationObject = this.spec.paths[path][method];
|
|
687
|
+
const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
|
|
688
|
+
if (this.options.projectType === ProjectType.SME) {
|
|
689
|
+
// only support response body only contains “application/json” content type
|
|
690
|
+
if (multipleMediaType) {
|
|
691
|
+
result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
|
|
692
|
+
}
|
|
693
|
+
else if (Object.keys(json).length === 0) {
|
|
694
|
+
// response body should not be empty
|
|
695
|
+
result.reason.push(ErrorType.ResponseJsonIsEmpty);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return result;
|
|
699
|
+
}
|
|
709
700
|
validateServer(method, path) {
|
|
710
701
|
const result = { isValid: true, reason: [] };
|
|
711
702
|
const serverObj = Utils.getServerObject(this.spec, method, path);
|
|
@@ -714,8 +705,8 @@ class Validator {
|
|
|
714
705
|
result.reason.push(ErrorType.NoServerInformation);
|
|
715
706
|
}
|
|
716
707
|
else {
|
|
717
|
-
|
|
718
|
-
const serverValidateResult = Utils.checkServerUrl([serverObj]
|
|
708
|
+
// server url should be absolute url with https protocol
|
|
709
|
+
const serverValidateResult = Utils.checkServerUrl([serverObj]);
|
|
719
710
|
result.reason.push(...serverValidateResult.map((item) => item.type));
|
|
720
711
|
}
|
|
721
712
|
return result;
|
|
@@ -738,9 +729,6 @@ class Validator {
|
|
|
738
729
|
reason: [ErrorType.MultipleAuthNotSupported],
|
|
739
730
|
};
|
|
740
731
|
}
|
|
741
|
-
if (this.projectType === ProjectType.Copilot) {
|
|
742
|
-
return { isValid: true, reason: [] };
|
|
743
|
-
}
|
|
744
732
|
for (const auths of authSchemeArray) {
|
|
745
733
|
if (auths.length === 1) {
|
|
746
734
|
if ((this.options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
|
|
@@ -753,6 +741,114 @@ class Validator {
|
|
|
753
741
|
}
|
|
754
742
|
return { isValid: false, reason: [ErrorType.AuthTypeIsNotSupported] };
|
|
755
743
|
}
|
|
744
|
+
checkPostBodySchema(schema, isRequired = false) {
|
|
745
|
+
var _a;
|
|
746
|
+
const paramResult = {
|
|
747
|
+
requiredNum: 0,
|
|
748
|
+
optionalNum: 0,
|
|
749
|
+
isValid: true,
|
|
750
|
+
reason: [],
|
|
751
|
+
};
|
|
752
|
+
if (Object.keys(schema).length === 0) {
|
|
753
|
+
return paramResult;
|
|
754
|
+
}
|
|
755
|
+
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
756
|
+
const isCopilot = this.projectType === ProjectType.Copilot;
|
|
757
|
+
if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
|
|
758
|
+
paramResult.isValid = false;
|
|
759
|
+
paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
|
|
760
|
+
return paramResult;
|
|
761
|
+
}
|
|
762
|
+
if (schema.type === "string" ||
|
|
763
|
+
schema.type === "integer" ||
|
|
764
|
+
schema.type === "boolean" ||
|
|
765
|
+
schema.type === "number") {
|
|
766
|
+
if (isRequiredWithoutDefault) {
|
|
767
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
774
|
+
const { properties } = schema;
|
|
775
|
+
for (const property in properties) {
|
|
776
|
+
let isRequired = false;
|
|
777
|
+
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
778
|
+
isRequired = true;
|
|
779
|
+
}
|
|
780
|
+
const result = this.checkPostBodySchema(properties[property], isRequired);
|
|
781
|
+
paramResult.requiredNum += result.requiredNum;
|
|
782
|
+
paramResult.optionalNum += result.optionalNum;
|
|
783
|
+
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
784
|
+
paramResult.reason.push(...result.reason);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
if (isRequiredWithoutDefault && !isCopilot) {
|
|
789
|
+
paramResult.isValid = false;
|
|
790
|
+
paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return paramResult;
|
|
794
|
+
}
|
|
795
|
+
checkParamSchema(paramObject) {
|
|
796
|
+
const paramResult = {
|
|
797
|
+
requiredNum: 0,
|
|
798
|
+
optionalNum: 0,
|
|
799
|
+
isValid: true,
|
|
800
|
+
reason: [],
|
|
801
|
+
};
|
|
802
|
+
if (!paramObject) {
|
|
803
|
+
return paramResult;
|
|
804
|
+
}
|
|
805
|
+
const isCopilot = this.projectType === ProjectType.Copilot;
|
|
806
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
807
|
+
const param = paramObject[i];
|
|
808
|
+
const schema = param.schema;
|
|
809
|
+
if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
|
|
810
|
+
paramResult.isValid = false;
|
|
811
|
+
paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
815
|
+
if (isCopilot) {
|
|
816
|
+
if (isRequiredWithoutDefault) {
|
|
817
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
821
|
+
}
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
if (param.in === "header" || param.in === "cookie") {
|
|
825
|
+
if (isRequiredWithoutDefault) {
|
|
826
|
+
paramResult.isValid = false;
|
|
827
|
+
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
828
|
+
}
|
|
829
|
+
continue;
|
|
830
|
+
}
|
|
831
|
+
if (schema.type !== "boolean" &&
|
|
832
|
+
schema.type !== "string" &&
|
|
833
|
+
schema.type !== "number" &&
|
|
834
|
+
schema.type !== "integer") {
|
|
835
|
+
if (isRequiredWithoutDefault) {
|
|
836
|
+
paramResult.isValid = false;
|
|
837
|
+
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
838
|
+
}
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
if (param.in === "query" || param.in === "path") {
|
|
842
|
+
if (isRequiredWithoutDefault) {
|
|
843
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return paramResult;
|
|
851
|
+
}
|
|
756
852
|
}
|
|
757
853
|
|
|
758
854
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -762,6 +858,7 @@ class CopilotValidator extends Validator {
|
|
|
762
858
|
this.projectType = ProjectType.Copilot;
|
|
763
859
|
this.options = options;
|
|
764
860
|
this.spec = spec;
|
|
861
|
+
this.checkCircularReference();
|
|
765
862
|
}
|
|
766
863
|
validateSpec() {
|
|
767
864
|
const result = { errors: [], warnings: [] };
|
|
@@ -787,6 +884,10 @@ class CopilotValidator extends Validator {
|
|
|
787
884
|
if (!methodAndPathResult.isValid) {
|
|
788
885
|
return methodAndPathResult;
|
|
789
886
|
}
|
|
887
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
888
|
+
if (!circularReferenceResult.isValid) {
|
|
889
|
+
return circularReferenceResult;
|
|
890
|
+
}
|
|
790
891
|
const operationObject = this.spec.paths[path][method];
|
|
791
892
|
// validate auth
|
|
792
893
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -798,6 +899,24 @@ class CopilotValidator extends Validator {
|
|
|
798
899
|
// validate server
|
|
799
900
|
const validateServerResult = this.validateServer(method, path);
|
|
800
901
|
result.reason.push(...validateServerResult.reason);
|
|
902
|
+
// validate response
|
|
903
|
+
const validateResponseResult = this.validateResponse(method, path);
|
|
904
|
+
result.reason.push(...validateResponseResult.reason);
|
|
905
|
+
// validate requestBody
|
|
906
|
+
const requestBody = operationObject.requestBody;
|
|
907
|
+
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
908
|
+
if (requestJsonBody) {
|
|
909
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
910
|
+
if (!Utils.isObjectSchema(requestBodySchema)) {
|
|
911
|
+
result.reason.push(ErrorType.PostBodySchemaIsNotJson);
|
|
912
|
+
}
|
|
913
|
+
const requestBodyParamResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
|
|
914
|
+
result.reason.push(...requestBodyParamResult.reason);
|
|
915
|
+
}
|
|
916
|
+
// validate parameters
|
|
917
|
+
const paramObject = operationObject.parameters;
|
|
918
|
+
const paramResult = this.checkParamSchema(paramObject);
|
|
919
|
+
result.reason.push(...paramResult.reason);
|
|
801
920
|
if (result.reason.length > 0) {
|
|
802
921
|
result.isValid = false;
|
|
803
922
|
}
|
|
@@ -889,108 +1008,6 @@ class SMEValidator extends Validator {
|
|
|
889
1008
|
}
|
|
890
1009
|
return result;
|
|
891
1010
|
}
|
|
892
|
-
validateResponse(method, path) {
|
|
893
|
-
const result = { isValid: true, reason: [] };
|
|
894
|
-
const operationObject = this.spec.paths[path][method];
|
|
895
|
-
const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
|
|
896
|
-
// only support response body only contains “application/json” content type
|
|
897
|
-
if (multipleMediaType) {
|
|
898
|
-
result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
|
|
899
|
-
}
|
|
900
|
-
else if (Object.keys(json).length === 0) {
|
|
901
|
-
// response body should not be empty
|
|
902
|
-
result.reason.push(ErrorType.ResponseJsonIsEmpty);
|
|
903
|
-
}
|
|
904
|
-
return result;
|
|
905
|
-
}
|
|
906
|
-
checkPostBodySchema(schema, isRequired = false) {
|
|
907
|
-
var _a;
|
|
908
|
-
const paramResult = {
|
|
909
|
-
requiredNum: 0,
|
|
910
|
-
optionalNum: 0,
|
|
911
|
-
isValid: true,
|
|
912
|
-
reason: [],
|
|
913
|
-
};
|
|
914
|
-
if (Object.keys(schema).length === 0) {
|
|
915
|
-
return paramResult;
|
|
916
|
-
}
|
|
917
|
-
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
918
|
-
const isCopilot = this.projectType === ProjectType.Copilot;
|
|
919
|
-
if (schema.type === "string" ||
|
|
920
|
-
schema.type === "integer" ||
|
|
921
|
-
schema.type === "boolean" ||
|
|
922
|
-
schema.type === "number") {
|
|
923
|
-
if (isRequiredWithoutDefault) {
|
|
924
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
925
|
-
}
|
|
926
|
-
else {
|
|
927
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
else if (Utils.isObjectSchema(schema)) {
|
|
931
|
-
const { properties } = schema;
|
|
932
|
-
for (const property in properties) {
|
|
933
|
-
let isRequired = false;
|
|
934
|
-
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
935
|
-
isRequired = true;
|
|
936
|
-
}
|
|
937
|
-
const result = this.checkPostBodySchema(properties[property], isRequired);
|
|
938
|
-
paramResult.requiredNum += result.requiredNum;
|
|
939
|
-
paramResult.optionalNum += result.optionalNum;
|
|
940
|
-
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
941
|
-
paramResult.reason.push(...result.reason);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
else {
|
|
945
|
-
if (isRequiredWithoutDefault && !isCopilot) {
|
|
946
|
-
paramResult.isValid = false;
|
|
947
|
-
paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
return paramResult;
|
|
951
|
-
}
|
|
952
|
-
checkParamSchema(paramObject) {
|
|
953
|
-
const paramResult = {
|
|
954
|
-
requiredNum: 0,
|
|
955
|
-
optionalNum: 0,
|
|
956
|
-
isValid: true,
|
|
957
|
-
reason: [],
|
|
958
|
-
};
|
|
959
|
-
if (!paramObject) {
|
|
960
|
-
return paramResult;
|
|
961
|
-
}
|
|
962
|
-
for (let i = 0; i < paramObject.length; i++) {
|
|
963
|
-
const param = paramObject[i];
|
|
964
|
-
const schema = param.schema;
|
|
965
|
-
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
966
|
-
if (param.in === "header" || param.in === "cookie") {
|
|
967
|
-
if (isRequiredWithoutDefault) {
|
|
968
|
-
paramResult.isValid = false;
|
|
969
|
-
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
970
|
-
}
|
|
971
|
-
continue;
|
|
972
|
-
}
|
|
973
|
-
if (schema.type !== "boolean" &&
|
|
974
|
-
schema.type !== "string" &&
|
|
975
|
-
schema.type !== "number" &&
|
|
976
|
-
schema.type !== "integer") {
|
|
977
|
-
if (isRequiredWithoutDefault) {
|
|
978
|
-
paramResult.isValid = false;
|
|
979
|
-
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
980
|
-
}
|
|
981
|
-
continue;
|
|
982
|
-
}
|
|
983
|
-
if (param.in === "query" || param.in === "path") {
|
|
984
|
-
if (isRequiredWithoutDefault) {
|
|
985
|
-
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
return paramResult;
|
|
993
|
-
}
|
|
994
1011
|
validateParamCount(postBodyResult, paramResult) {
|
|
995
1012
|
const result = { isValid: true, reason: [] };
|
|
996
1013
|
const totalRequiredParams = postBodyResult.requiredNum + paramResult.requiredNum;
|
|
@@ -1692,7 +1709,7 @@ function inferProperties(card) {
|
|
|
1692
1709
|
|
|
1693
1710
|
// Copyright (c) Microsoft Corporation.
|
|
1694
1711
|
class ManifestUpdater {
|
|
1695
|
-
static async updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options,
|
|
1712
|
+
static async updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options, authInfo, existingPluginManifestInfo) {
|
|
1696
1713
|
const manifest = await fs.readJSON(manifestPath);
|
|
1697
1714
|
const apiPluginRelativePath = ManifestUpdater.getRelativePath(manifestPath, apiPluginFilePath);
|
|
1698
1715
|
const useCopilotExtensionsInSchema = await ManifestUtil.useCopilotExtensionsInSchema(manifest);
|
|
@@ -1722,7 +1739,7 @@ class ManifestUpdater {
|
|
|
1722
1739
|
}
|
|
1723
1740
|
const appName = this.removeEnvs(manifest.name.short);
|
|
1724
1741
|
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
1725
|
-
const [apiPlugin, warnings] = await ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName,
|
|
1742
|
+
const [apiPlugin, warnings] = await ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authInfo, options, existingPluginManifestInfo);
|
|
1726
1743
|
return [manifest, apiPlugin, warnings];
|
|
1727
1744
|
}
|
|
1728
1745
|
static updateManifestDescription(manifest, spec) {
|
|
@@ -1744,13 +1761,28 @@ class ManifestUpdater {
|
|
|
1744
1761
|
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(schema)), ErrorType.UpdateManifestFailed);
|
|
1745
1762
|
}
|
|
1746
1763
|
}
|
|
1747
|
-
static async generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName,
|
|
1764
|
+
static async generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authInfo, options, existingPluginManifestInfo) {
|
|
1748
1765
|
var _a, _b, _c, _d;
|
|
1749
1766
|
const warnings = [];
|
|
1750
1767
|
const functions = [];
|
|
1751
|
-
const
|
|
1768
|
+
const functionNames = [];
|
|
1752
1769
|
const conversationStarters = [];
|
|
1753
1770
|
const paths = spec.paths;
|
|
1771
|
+
const pluginAuthObj = {
|
|
1772
|
+
type: "None",
|
|
1773
|
+
};
|
|
1774
|
+
if (authInfo) {
|
|
1775
|
+
if (Utils.isOAuthWithAuthCodeFlow(authInfo.authScheme)) {
|
|
1776
|
+
pluginAuthObj.type = "OAuthPluginVault";
|
|
1777
|
+
}
|
|
1778
|
+
else if (Utils.isBearerTokenAuth(authInfo.authScheme)) {
|
|
1779
|
+
pluginAuthObj.type = "ApiKeyPluginVault";
|
|
1780
|
+
}
|
|
1781
|
+
if (pluginAuthObj.type !== "None") {
|
|
1782
|
+
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1783
|
+
pluginAuthObj.reference_id = `\${{${safeRegistrationIdName}}}`;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1754
1786
|
for (const pathUrl in paths) {
|
|
1755
1787
|
const pathItem = paths[pathUrl];
|
|
1756
1788
|
if (pathItem) {
|
|
@@ -1758,11 +1790,36 @@ class ManifestUpdater {
|
|
|
1758
1790
|
for (const method in operations) {
|
|
1759
1791
|
if (options.allowMethods.includes(method)) {
|
|
1760
1792
|
const operationItem = operations[method];
|
|
1793
|
+
const confirmationBodies = [];
|
|
1761
1794
|
if (operationItem) {
|
|
1762
1795
|
const operationId = operationItem.operationId;
|
|
1763
1796
|
const safeFunctionName = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
1764
1797
|
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
1765
1798
|
const summary = operationItem.summary;
|
|
1799
|
+
const paramObject = operationItem.parameters;
|
|
1800
|
+
const requestBody = operationItem.requestBody;
|
|
1801
|
+
if (paramObject) {
|
|
1802
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
1803
|
+
const param = paramObject[i];
|
|
1804
|
+
const schema = param.schema;
|
|
1805
|
+
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1806
|
+
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
if (requestBody) {
|
|
1810
|
+
const requestJsonBody = requestBody.content["application/json"];
|
|
1811
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
1812
|
+
if (Utils.isObjectSchema(requestBodySchema)) {
|
|
1813
|
+
for (const property in requestBodySchema.properties) {
|
|
1814
|
+
const schema = requestBodySchema.properties[property];
|
|
1815
|
+
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1816
|
+
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
else {
|
|
1820
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1766
1823
|
let funcDescription = operationItem.description || operationItem.summary || "";
|
|
1767
1824
|
if (funcDescription.length > ConstantString.FunctionDescriptionMaxLens) {
|
|
1768
1825
|
warnings.push({
|
|
@@ -1796,66 +1853,19 @@ class ManifestUpdater {
|
|
|
1796
1853
|
}
|
|
1797
1854
|
}
|
|
1798
1855
|
if (options.allowConfirmation && method !== ConstantString.GetMethod) {
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
const confirmationBodies = [];
|
|
1802
|
-
if (paramObject) {
|
|
1803
|
-
for (let i = 0; i < paramObject.length; i++) {
|
|
1804
|
-
const param = paramObject[i];
|
|
1805
|
-
const schema = param.schema;
|
|
1806
|
-
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1807
|
-
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(param.name));
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
if (requestBody) {
|
|
1811
|
-
const requestJsonBody = Utils.getJsonContentType(requestBody);
|
|
1812
|
-
const requestBodySchema = requestJsonBody.schema;
|
|
1813
|
-
if (Utils.isObjectSchema(requestBodySchema)) {
|
|
1814
|
-
for (const property in requestBodySchema.properties) {
|
|
1815
|
-
const schema = requestBodySchema.properties[property];
|
|
1816
|
-
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
1817
|
-
confirmationBodies.push(ManifestUpdater.getConfirmationBodyItem(property));
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
else {
|
|
1821
|
-
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), ErrorType.UpdateManifestFailed);
|
|
1822
|
-
}
|
|
1856
|
+
if (!funcObj.capabilities) {
|
|
1857
|
+
funcObj.capabilities = {};
|
|
1823
1858
|
}
|
|
1859
|
+
funcObj.capabilities.confirmation = {
|
|
1860
|
+
type: "AdaptiveCard",
|
|
1861
|
+
title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
|
|
1862
|
+
};
|
|
1824
1863
|
if (confirmationBodies.length > 0) {
|
|
1825
|
-
if (!funcObj.capabilities) {
|
|
1826
|
-
funcObj.capabilities = {};
|
|
1827
|
-
}
|
|
1828
|
-
funcObj.capabilities.confirmation = {
|
|
1829
|
-
type: "AdaptiveCard",
|
|
1830
|
-
title: (_b = operationItem.summary) !== null && _b !== void 0 ? _b : description,
|
|
1831
|
-
};
|
|
1832
1864
|
funcObj.capabilities.confirmation.body = confirmationBodies.join("\n");
|
|
1833
1865
|
}
|
|
1834
1866
|
}
|
|
1835
1867
|
functions.push(funcObj);
|
|
1836
|
-
|
|
1837
|
-
let key = "None";
|
|
1838
|
-
let authName = "None";
|
|
1839
|
-
if (authInfo) {
|
|
1840
|
-
if (Utils.isOAuthWithAuthCodeFlow(authInfo.authScheme)) {
|
|
1841
|
-
key = "OAuthPluginVault";
|
|
1842
|
-
authName = authInfo.name;
|
|
1843
|
-
}
|
|
1844
|
-
else if (Utils.isBearerTokenAuth(authInfo.authScheme) ||
|
|
1845
|
-
Utils.isAPIKeyAuthButNotInCookie(authInfo.authScheme)) {
|
|
1846
|
-
key = "ApiKeyPluginVault";
|
|
1847
|
-
authName = authInfo.name;
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
if (functionNamesMap[key]) {
|
|
1851
|
-
functionNamesMap[key].functionNames.push(safeFunctionName);
|
|
1852
|
-
}
|
|
1853
|
-
else {
|
|
1854
|
-
functionNamesMap[key] = {
|
|
1855
|
-
functionNames: [safeFunctionName],
|
|
1856
|
-
authName: authName,
|
|
1857
|
-
};
|
|
1858
|
-
}
|
|
1868
|
+
functionNames.push(safeFunctionName);
|
|
1859
1869
|
const conversationStarterStr = (summary !== null && summary !== void 0 ? summary : description).slice(0, ConstantString.ConversationStarterMaxLens);
|
|
1860
1870
|
if (conversationStarterStr) {
|
|
1861
1871
|
conversationStarters.push(conversationStarterStr);
|
|
@@ -1865,12 +1875,6 @@ class ManifestUpdater {
|
|
|
1865
1875
|
}
|
|
1866
1876
|
}
|
|
1867
1877
|
}
|
|
1868
|
-
if (Object.keys(functionNamesMap).length === 0) {
|
|
1869
|
-
functionNamesMap["None"] = {
|
|
1870
|
-
functionNames: [],
|
|
1871
|
-
authName: "None",
|
|
1872
|
-
};
|
|
1873
|
-
}
|
|
1874
1878
|
let apiPlugin;
|
|
1875
1879
|
if (await fs.pathExists(apiPluginFilePath)) {
|
|
1876
1880
|
apiPlugin = await fs.readJSON(apiPluginFilePath);
|
|
@@ -1906,35 +1910,24 @@ class ManifestUpdater {
|
|
|
1906
1910
|
const relativePath = ManifestUpdater.getRelativePath(existingPluginManifestInfo.manifestPath, existingPluginManifestInfo.specPath);
|
|
1907
1911
|
apiPlugin.runtimes = apiPlugin.runtimes.filter((runtime) => runtime.spec.url !== relativePath);
|
|
1908
1912
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
((_b = (_a = runtime.auth) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : "None") === authType;
|
|
1913
|
+
const index = apiPlugin.runtimes.findIndex((runtime) => {
|
|
1914
|
+
var _a, _b;
|
|
1915
|
+
return runtime.spec.url === specRelativePath &&
|
|
1916
|
+
runtime.type === "OpenApi" &&
|
|
1917
|
+
((_b = (_a = runtime.auth) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : "None") === pluginAuthObj.type;
|
|
1918
|
+
});
|
|
1919
|
+
if (index === -1) {
|
|
1920
|
+
apiPlugin.runtimes.push({
|
|
1921
|
+
type: "OpenApi",
|
|
1922
|
+
auth: pluginAuthObj,
|
|
1923
|
+
spec: {
|
|
1924
|
+
url: specRelativePath,
|
|
1925
|
+
},
|
|
1926
|
+
run_for_functions: functionNames,
|
|
1924
1927
|
});
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
auth: pluginAuthObj,
|
|
1929
|
-
spec: {
|
|
1930
|
-
url: specRelativePath,
|
|
1931
|
-
},
|
|
1932
|
-
run_for_functions: functionNamesInfo.functionNames,
|
|
1933
|
-
});
|
|
1934
|
-
}
|
|
1935
|
-
else {
|
|
1936
|
-
apiPlugin.runtimes[index].run_for_functions = functionNamesInfo.functionNames;
|
|
1937
|
-
}
|
|
1928
|
+
}
|
|
1929
|
+
else {
|
|
1930
|
+
apiPlugin.runtimes[index].run_for_functions = functionNames;
|
|
1938
1931
|
}
|
|
1939
1932
|
if (!apiPlugin.name_for_human) {
|
|
1940
1933
|
apiPlugin.name_for_human = appName;
|
|
@@ -1975,7 +1968,7 @@ class ManifestUpdater {
|
|
|
1975
1968
|
};
|
|
1976
1969
|
if (authInfo) {
|
|
1977
1970
|
const auth = authInfo.authScheme;
|
|
1978
|
-
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix}`);
|
|
1971
|
+
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1979
1972
|
if (Utils.isAPIKeyAuth(auth) || Utils.isBearerTokenAuth(auth)) {
|
|
1980
1973
|
composeExtension.authorization = {
|
|
1981
1974
|
authType: "apiSecretServiceAuth",
|
|
@@ -2118,11 +2111,8 @@ class SpecParser {
|
|
|
2118
2111
|
await this.parser.validate(this.spec);
|
|
2119
2112
|
}
|
|
2120
2113
|
else {
|
|
2121
|
-
// The following code still hangs for Graph API, support will be added when SwaggerParser is updated.
|
|
2122
|
-
/*
|
|
2123
2114
|
const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec));
|
|
2124
2115
|
await this.parser.validate(clonedUnResolveSpec);
|
|
2125
|
-
*/
|
|
2126
2116
|
}
|
|
2127
2117
|
}
|
|
2128
2118
|
catch (e) {
|
|
@@ -2279,7 +2269,7 @@ class SpecParser {
|
|
|
2279
2269
|
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
2280
2270
|
}
|
|
2281
2271
|
const clonedUnResolveSpec = JSON.parse(JSON.stringify(newUnResolvedSpec));
|
|
2282
|
-
const newSpec = await this.
|
|
2272
|
+
const newSpec = (await this.parser.dereference(clonedUnResolveSpec));
|
|
2283
2273
|
return [newUnResolvedSpec, newSpec];
|
|
2284
2274
|
}
|
|
2285
2275
|
catch (err) {
|
|
@@ -2289,10 +2279,6 @@ class SpecParser {
|
|
|
2289
2279
|
throw new SpecParserError(err.toString(), ErrorType.GetSpecFailed);
|
|
2290
2280
|
}
|
|
2291
2281
|
}
|
|
2292
|
-
async deReferenceSpec(spec) {
|
|
2293
|
-
const result = await this.parser.dereference(spec);
|
|
2294
|
-
return result;
|
|
2295
|
-
}
|
|
2296
2282
|
/**
|
|
2297
2283
|
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
2298
2284
|
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
@@ -2309,6 +2295,7 @@ class SpecParser {
|
|
|
2309
2295
|
const newSpecs = await this.getFilteredSpecs(filter, signal);
|
|
2310
2296
|
const newUnResolvedSpec = newSpecs[0];
|
|
2311
2297
|
const newSpec = newSpecs[1];
|
|
2298
|
+
const authInfo = Utils.getAuthInfo(newSpec);
|
|
2312
2299
|
const paths = newUnResolvedSpec.paths;
|
|
2313
2300
|
for (const pathUrl in paths) {
|
|
2314
2301
|
const operations = paths[pathUrl];
|
|
@@ -2316,22 +2303,15 @@ class SpecParser {
|
|
|
2316
2303
|
const operationItem = operations[method];
|
|
2317
2304
|
const operationId = operationItem.operationId;
|
|
2318
2305
|
const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
|
|
2319
|
-
if (containsSpecialCharacters) {
|
|
2320
|
-
|
|
2321
|
-
result.warnings.push({
|
|
2322
|
-
type: WarningType.OperationIdContainsSpecialCharacters,
|
|
2323
|
-
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2324
|
-
data: operationId,
|
|
2325
|
-
});
|
|
2326
|
-
}
|
|
2327
|
-
const authArray = Utils.getAuthArray(operationItem.security, newSpec);
|
|
2328
|
-
if (Utils.isNotSupportedAuth(authArray)) {
|
|
2329
|
-
result.warnings.push({
|
|
2330
|
-
type: WarningType.UnsupportedAuthType,
|
|
2331
|
-
content: Utils.format(ConstantString.AuthTypeIsNotSupported, operationId),
|
|
2332
|
-
data: operationId,
|
|
2333
|
-
});
|
|
2306
|
+
if (!containsSpecialCharacters) {
|
|
2307
|
+
continue;
|
|
2334
2308
|
}
|
|
2309
|
+
operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2310
|
+
result.warnings.push({
|
|
2311
|
+
type: WarningType.OperationIdContainsSpecialCharacters,
|
|
2312
|
+
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2313
|
+
data: operationId,
|
|
2314
|
+
});
|
|
2335
2315
|
}
|
|
2336
2316
|
}
|
|
2337
2317
|
await this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
|
|
@@ -2344,8 +2324,7 @@ class SpecParser {
|
|
|
2344
2324
|
specPath: this.pathOrSpec,
|
|
2345
2325
|
}
|
|
2346
2326
|
: undefined;
|
|
2347
|
-
const
|
|
2348
|
-
const [updatedManifest, apiPlugin, warnings] = await ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authMap, existingPluginManifestInfo);
|
|
2327
|
+
const [updatedManifest, apiPlugin, warnings] = await ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authInfo, existingPluginManifestInfo);
|
|
2349
2328
|
result.warnings.push(...warnings);
|
|
2350
2329
|
await fs.outputJSON(manifestPath, updatedManifest, { spaces: 4 });
|
|
2351
2330
|
await fs.outputJSON(pluginFilePath, apiPlugin, { spaces: 4 });
|
|
@@ -2433,7 +2412,7 @@ class SpecParser {
|
|
|
2433
2412
|
this.isSwaggerFile = true;
|
|
2434
2413
|
}
|
|
2435
2414
|
const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec));
|
|
2436
|
-
this.spec = await this.
|
|
2415
|
+
this.spec = (await this.parser.dereference(clonedUnResolveSpec));
|
|
2437
2416
|
}
|
|
2438
2417
|
}
|
|
2439
2418
|
getAPIs(spec) {
|