@microsoft/m365-spec-parser 0.1.1-alpha.a277dba4e.0 → 0.1.1-alpha.b54a7ba8f.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 +167 -93
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +198 -121
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +167 -93
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +198 -121
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/interfaces.d.ts +30 -1
- package/dist/src/manifestUpdater.d.ts +2 -1
- package/dist/src/specParser.browser.d.ts +1 -0
- package/dist/src/specParser.d.ts +1 -1
- package/dist/src/utils.d.ts +9 -8
- package/package.json +3 -3
package/dist/index.node.cjs.js
CHANGED
|
@@ -71,6 +71,21 @@ exports.ErrorType = void 0;
|
|
|
71
71
|
ErrorType["GenerateFailed"] = "generate-failed";
|
|
72
72
|
ErrorType["ValidateFailed"] = "validate-failed";
|
|
73
73
|
ErrorType["GetSpecFailed"] = "get-spec-failed";
|
|
74
|
+
ErrorType["AuthTypeIsNotSupported"] = "auth-type-is-not-supported";
|
|
75
|
+
ErrorType["MissingOperationId"] = "missing-operation-id";
|
|
76
|
+
ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
|
|
77
|
+
ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
|
|
78
|
+
ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
|
|
79
|
+
ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
|
|
80
|
+
ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
|
|
81
|
+
ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
|
|
82
|
+
ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
|
|
83
|
+
ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
|
|
84
|
+
ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
|
|
85
|
+
ErrorType["NoParameter"] = "no-parameter";
|
|
86
|
+
ErrorType["NoAPIInfo"] = "no-api-info";
|
|
87
|
+
ErrorType["MethodNotAllowed"] = "method-not-allowed";
|
|
88
|
+
ErrorType["UrlPathNotExist"] = "url-path-not-exist";
|
|
74
89
|
ErrorType["Cancelled"] = "cancelled";
|
|
75
90
|
ErrorType["Unknown"] = "unknown";
|
|
76
91
|
})(exports.ErrorType || (exports.ErrorType = {}));
|
|
@@ -221,6 +236,7 @@ class Utils {
|
|
|
221
236
|
requiredNum: 0,
|
|
222
237
|
optionalNum: 0,
|
|
223
238
|
isValid: true,
|
|
239
|
+
reason: [],
|
|
224
240
|
};
|
|
225
241
|
if (!paramObject) {
|
|
226
242
|
return paramResult;
|
|
@@ -230,6 +246,7 @@ class Utils {
|
|
|
230
246
|
const schema = param.schema;
|
|
231
247
|
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
232
248
|
paramResult.isValid = false;
|
|
249
|
+
paramResult.reason.push(exports.ErrorType.ParamsContainsNestedObject);
|
|
233
250
|
continue;
|
|
234
251
|
}
|
|
235
252
|
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
@@ -245,6 +262,7 @@ class Utils {
|
|
|
245
262
|
if (param.in === "header" || param.in === "cookie") {
|
|
246
263
|
if (isRequiredWithoutDefault) {
|
|
247
264
|
paramResult.isValid = false;
|
|
265
|
+
paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
248
266
|
}
|
|
249
267
|
continue;
|
|
250
268
|
}
|
|
@@ -254,6 +272,7 @@ class Utils {
|
|
|
254
272
|
schema.type !== "integer") {
|
|
255
273
|
if (isRequiredWithoutDefault) {
|
|
256
274
|
paramResult.isValid = false;
|
|
275
|
+
paramResult.reason.push(exports.ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
257
276
|
}
|
|
258
277
|
continue;
|
|
259
278
|
}
|
|
@@ -274,6 +293,7 @@ class Utils {
|
|
|
274
293
|
requiredNum: 0,
|
|
275
294
|
optionalNum: 0,
|
|
276
295
|
isValid: true,
|
|
296
|
+
reason: [],
|
|
277
297
|
};
|
|
278
298
|
if (Object.keys(schema).length === 0) {
|
|
279
299
|
return paramResult;
|
|
@@ -281,6 +301,7 @@ class Utils {
|
|
|
281
301
|
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
282
302
|
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
283
303
|
paramResult.isValid = false;
|
|
304
|
+
paramResult.reason = [exports.ErrorType.RequestBodyContainsNestedObject];
|
|
284
305
|
return paramResult;
|
|
285
306
|
}
|
|
286
307
|
if (schema.type === "string" ||
|
|
@@ -305,11 +326,13 @@ class Utils {
|
|
|
305
326
|
paramResult.requiredNum += result.requiredNum;
|
|
306
327
|
paramResult.optionalNum += result.optionalNum;
|
|
307
328
|
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
329
|
+
paramResult.reason.push(...result.reason);
|
|
308
330
|
}
|
|
309
331
|
}
|
|
310
332
|
else {
|
|
311
333
|
if (isRequiredWithoutDefault && !isCopilot) {
|
|
312
334
|
paramResult.isValid = false;
|
|
335
|
+
paramResult.reason.push(exports.ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
313
336
|
}
|
|
314
337
|
}
|
|
315
338
|
return paramResult;
|
|
@@ -333,103 +356,123 @@ class Utils {
|
|
|
333
356
|
*/
|
|
334
357
|
static isSupportedApi(method, path, spec, options) {
|
|
335
358
|
var _a;
|
|
336
|
-
const
|
|
359
|
+
const result = { isValid: true, reason: [] };
|
|
337
360
|
method = method.toLocaleLowerCase();
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
361
|
+
if (options.allowMethods && !options.allowMethods.includes(method)) {
|
|
362
|
+
result.isValid = false;
|
|
363
|
+
result.reason.push(exports.ErrorType.MethodNotAllowed);
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
const pathObj = spec.paths[path];
|
|
367
|
+
if (!pathObj || !pathObj[method]) {
|
|
368
|
+
result.isValid = false;
|
|
369
|
+
result.reason.push(exports.ErrorType.UrlPathNotExist);
|
|
370
|
+
return result;
|
|
371
|
+
}
|
|
372
|
+
const securities = pathObj[method].security;
|
|
373
|
+
const isTeamsAi = options.projectType === exports.ProjectType.TeamsAi;
|
|
374
|
+
const isCopilot = options.projectType === exports.ProjectType.Copilot;
|
|
375
|
+
// Teams AI project doesn't care about auth, it will use authProvider for user to implement
|
|
376
|
+
if (!isTeamsAi) {
|
|
377
|
+
const authArray = Utils.getAuthArray(securities, spec);
|
|
378
|
+
const authCheckResult = Utils.isSupportedAuth(authArray, options);
|
|
379
|
+
if (!authCheckResult.isValid) {
|
|
380
|
+
result.reason.push(...authCheckResult.reason);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
const operationObject = pathObj[method];
|
|
384
|
+
if (!options.allowMissingId && !operationObject.operationId) {
|
|
385
|
+
result.reason.push(exports.ErrorType.MissingOperationId);
|
|
386
|
+
}
|
|
387
|
+
const rootServer = spec.servers && spec.servers[0];
|
|
388
|
+
const methodServer = spec.paths[path].servers && ((_a = spec.paths[path]) === null || _a === void 0 ? void 0 : _a.servers[0]);
|
|
389
|
+
const operationServer = operationObject.servers && operationObject.servers[0];
|
|
390
|
+
const serverUrl = operationServer || methodServer || rootServer;
|
|
391
|
+
if (!serverUrl) {
|
|
392
|
+
result.reason.push(exports.ErrorType.NoServerInformation);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
const serverValidateResult = Utils.checkServerUrl([serverUrl]);
|
|
396
|
+
result.reason.push(...serverValidateResult.map((item) => item.type));
|
|
397
|
+
}
|
|
398
|
+
const paramObject = operationObject.parameters;
|
|
399
|
+
const requestBody = operationObject.requestBody;
|
|
400
|
+
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
401
|
+
if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
|
|
402
|
+
result.reason.push(exports.ErrorType.PostBodyContainMultipleMediaTypes);
|
|
403
|
+
}
|
|
404
|
+
const { json, multipleMediaType } = Utils.getResponseJson(operationObject, isTeamsAi);
|
|
405
|
+
if (multipleMediaType && !isTeamsAi) {
|
|
406
|
+
result.reason.push(exports.ErrorType.ResponseContainMultipleMediaTypes);
|
|
407
|
+
}
|
|
408
|
+
else if (Object.keys(json).length === 0) {
|
|
409
|
+
result.reason.push(exports.ErrorType.ResponseJsonIsEmpty);
|
|
410
|
+
}
|
|
411
|
+
// Teams AI project doesn't care about request parameters/body
|
|
412
|
+
if (!isTeamsAi) {
|
|
413
|
+
let requestBodyParamResult = {
|
|
414
|
+
requiredNum: 0,
|
|
415
|
+
optionalNum: 0,
|
|
416
|
+
isValid: true,
|
|
417
|
+
reason: [],
|
|
418
|
+
};
|
|
419
|
+
if (requestJsonBody) {
|
|
420
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
421
|
+
if (isCopilot && requestBodySchema.type !== "object") {
|
|
422
|
+
result.reason.push(exports.ErrorType.PostBodySchemaIsNotJson);
|
|
386
423
|
}
|
|
387
|
-
|
|
388
|
-
if (
|
|
389
|
-
|
|
424
|
+
requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
|
|
425
|
+
if (!requestBodyParamResult.isValid && requestBodyParamResult.reason) {
|
|
426
|
+
result.reason.push(...requestBodyParamResult.reason);
|
|
390
427
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
428
|
+
}
|
|
429
|
+
const paramResult = Utils.checkParameters(paramObject, isCopilot);
|
|
430
|
+
if (!paramResult.isValid && paramResult.reason) {
|
|
431
|
+
result.reason.push(...paramResult.reason);
|
|
432
|
+
}
|
|
433
|
+
// Copilot support arbitrary parameters
|
|
434
|
+
if (!isCopilot && paramResult.isValid && requestBodyParamResult.isValid) {
|
|
435
|
+
const totalRequiredParams = requestBodyParamResult.requiredNum + paramResult.requiredNum;
|
|
436
|
+
const totalParams = totalRequiredParams + requestBodyParamResult.optionalNum + paramResult.optionalNum;
|
|
437
|
+
if (totalRequiredParams > 1) {
|
|
438
|
+
if (!options.allowMultipleParameters ||
|
|
439
|
+
totalRequiredParams > ConstantString.SMERequiredParamsMaxNum) {
|
|
440
|
+
result.reason.push(exports.ErrorType.ExceededRequiredParamsLimit);
|
|
396
441
|
}
|
|
397
|
-
return false;
|
|
398
442
|
}
|
|
399
|
-
else if (
|
|
400
|
-
|
|
401
|
-
paramResult.requiredNum +
|
|
402
|
-
paramResult.optionalNum ===
|
|
403
|
-
0) {
|
|
404
|
-
return false;
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
return true;
|
|
443
|
+
else if (totalParams === 0) {
|
|
444
|
+
result.reason.push(exports.ErrorType.NoParameter);
|
|
408
445
|
}
|
|
409
446
|
}
|
|
410
447
|
}
|
|
411
|
-
|
|
448
|
+
if (result.reason.length > 0) {
|
|
449
|
+
result.isValid = false;
|
|
450
|
+
}
|
|
451
|
+
return result;
|
|
412
452
|
}
|
|
413
453
|
static isSupportedAuth(authSchemeArray, options) {
|
|
414
454
|
if (authSchemeArray.length === 0) {
|
|
415
|
-
return true;
|
|
455
|
+
return { isValid: true, reason: [] };
|
|
416
456
|
}
|
|
417
457
|
if (options.allowAPIKeyAuth || options.allowOauth2 || options.allowBearerTokenAuth) {
|
|
418
458
|
// Currently we don't support multiple auth in one operation
|
|
419
459
|
if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
|
|
420
|
-
return
|
|
460
|
+
return {
|
|
461
|
+
isValid: false,
|
|
462
|
+
reason: [exports.ErrorType.MultipleAuthNotSupported],
|
|
463
|
+
};
|
|
421
464
|
}
|
|
422
465
|
for (const auths of authSchemeArray) {
|
|
423
466
|
if (auths.length === 1) {
|
|
424
467
|
if ((options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
|
|
425
468
|
(options.allowOauth2 && Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme)) ||
|
|
426
469
|
(options.allowBearerTokenAuth && Utils.isBearerTokenAuth(auths[0].authScheme))) {
|
|
427
|
-
return true;
|
|
470
|
+
return { isValid: true, reason: [] };
|
|
428
471
|
}
|
|
429
472
|
}
|
|
430
473
|
}
|
|
431
474
|
}
|
|
432
|
-
return false;
|
|
475
|
+
return { isValid: false, reason: [exports.ErrorType.AuthTypeIsNotSupported] };
|
|
433
476
|
}
|
|
434
477
|
static isBearerTokenAuth(authScheme) {
|
|
435
478
|
return authScheme.type === "http" && authScheme.scheme === "bearer";
|
|
@@ -472,11 +515,17 @@ class Utils {
|
|
|
472
515
|
static getResponseJson(operationObject, isTeamsAiProject = false) {
|
|
473
516
|
var _a, _b;
|
|
474
517
|
let json = {};
|
|
518
|
+
let multipleMediaType = false;
|
|
475
519
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
476
520
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
477
521
|
if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
|
|
522
|
+
multipleMediaType = false;
|
|
478
523
|
json = responseObject.content["application/json"];
|
|
479
|
-
if (
|
|
524
|
+
if (Utils.containMultipleMediaTypes(responseObject)) {
|
|
525
|
+
multipleMediaType = true;
|
|
526
|
+
if (isTeamsAiProject) {
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
480
529
|
json = {};
|
|
481
530
|
}
|
|
482
531
|
else {
|
|
@@ -484,7 +533,7 @@ class Utils {
|
|
|
484
533
|
}
|
|
485
534
|
}
|
|
486
535
|
}
|
|
487
|
-
return json;
|
|
536
|
+
return { json, multipleMediaType };
|
|
488
537
|
}
|
|
489
538
|
static convertPathToCamelCase(path) {
|
|
490
539
|
const pathSegments = path.split(/[./{]/);
|
|
@@ -504,10 +553,10 @@ class Utils {
|
|
|
504
553
|
return undefined;
|
|
505
554
|
}
|
|
506
555
|
}
|
|
507
|
-
static
|
|
556
|
+
static resolveEnv(str) {
|
|
508
557
|
const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
|
|
509
|
-
let matches = placeHolderReg.exec(
|
|
510
|
-
let
|
|
558
|
+
let matches = placeHolderReg.exec(str);
|
|
559
|
+
let newStr = str;
|
|
511
560
|
while (matches != null) {
|
|
512
561
|
const envVar = matches[1];
|
|
513
562
|
const envVal = process.env[envVar];
|
|
@@ -515,17 +564,17 @@ class Utils {
|
|
|
515
564
|
throw new Error(Utils.format(ConstantString.ResolveServerUrlFailed, envVar));
|
|
516
565
|
}
|
|
517
566
|
else {
|
|
518
|
-
|
|
567
|
+
newStr = newStr.replace(matches[0], envVal);
|
|
519
568
|
}
|
|
520
|
-
matches = placeHolderReg.exec(
|
|
569
|
+
matches = placeHolderReg.exec(str);
|
|
521
570
|
}
|
|
522
|
-
return
|
|
571
|
+
return newStr;
|
|
523
572
|
}
|
|
524
573
|
static checkServerUrl(servers) {
|
|
525
574
|
const errors = [];
|
|
526
575
|
let serverUrl;
|
|
527
576
|
try {
|
|
528
|
-
serverUrl = Utils.
|
|
577
|
+
serverUrl = Utils.resolveEnv(servers[0].url);
|
|
529
578
|
}
|
|
530
579
|
catch (err) {
|
|
531
580
|
errors.push({
|
|
@@ -556,6 +605,7 @@ class Utils {
|
|
|
556
605
|
return errors;
|
|
557
606
|
}
|
|
558
607
|
static validateServer(spec, options) {
|
|
608
|
+
var _a;
|
|
559
609
|
const errors = [];
|
|
560
610
|
let hasTopLevelServers = false;
|
|
561
611
|
let hasPathLevelServers = false;
|
|
@@ -576,7 +626,7 @@ class Utils {
|
|
|
576
626
|
}
|
|
577
627
|
for (const method in methods) {
|
|
578
628
|
const operationObject = methods[method];
|
|
579
|
-
if (
|
|
629
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
580
630
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
581
631
|
hasOperationLevelServers = true;
|
|
582
632
|
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
@@ -728,15 +778,21 @@ class Utils {
|
|
|
728
778
|
}
|
|
729
779
|
return [command, warning];
|
|
730
780
|
}
|
|
731
|
-
static
|
|
781
|
+
static listAPIs(spec, options) {
|
|
782
|
+
var _a;
|
|
732
783
|
const paths = spec.paths;
|
|
733
784
|
const result = {};
|
|
734
785
|
for (const path in paths) {
|
|
735
786
|
const methods = paths[path];
|
|
736
787
|
for (const method in methods) {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
788
|
+
const operationObject = methods[method];
|
|
789
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
790
|
+
const validateResult = Utils.isSupportedApi(method, path, spec, options);
|
|
791
|
+
result[`${method.toUpperCase()} ${path}`] = {
|
|
792
|
+
operation: operationObject,
|
|
793
|
+
isValid: validateResult.isValid,
|
|
794
|
+
reason: validateResult.reason,
|
|
795
|
+
};
|
|
740
796
|
}
|
|
741
797
|
}
|
|
742
798
|
}
|
|
@@ -745,13 +801,13 @@ class Utils {
|
|
|
745
801
|
static validateSpec(spec, parser, isSwaggerFile, options) {
|
|
746
802
|
const errors = [];
|
|
747
803
|
const warnings = [];
|
|
804
|
+
const apiMap = Utils.listAPIs(spec, options);
|
|
748
805
|
if (isSwaggerFile) {
|
|
749
806
|
warnings.push({
|
|
750
807
|
type: exports.WarningType.ConvertSwaggerToOpenAPI,
|
|
751
808
|
content: ConstantString.ConvertSwaggerToOpenAPI,
|
|
752
809
|
});
|
|
753
810
|
}
|
|
754
|
-
// Server validation
|
|
755
811
|
const serverErrors = Utils.validateServer(spec, options);
|
|
756
812
|
errors.push(...serverErrors);
|
|
757
813
|
// Remote reference not supported
|
|
@@ -765,8 +821,8 @@ class Utils {
|
|
|
765
821
|
});
|
|
766
822
|
}
|
|
767
823
|
// No supported API
|
|
768
|
-
const
|
|
769
|
-
if (
|
|
824
|
+
const validAPIs = Object.entries(apiMap).filter(([, value]) => value.isValid);
|
|
825
|
+
if (validAPIs.length === 0) {
|
|
770
826
|
errors.push({
|
|
771
827
|
type: exports.ErrorType.NoSupportedApi,
|
|
772
828
|
content: ConstantString.NoSupportedApi,
|
|
@@ -775,8 +831,8 @@ class Utils {
|
|
|
775
831
|
// OperationId missing
|
|
776
832
|
const apisMissingOperationId = [];
|
|
777
833
|
for (const key in apiMap) {
|
|
778
|
-
const
|
|
779
|
-
if (!
|
|
834
|
+
const { operation } = apiMap[key];
|
|
835
|
+
if (!operation.operationId) {
|
|
780
836
|
apisMissingOperationId.push(key);
|
|
781
837
|
}
|
|
782
838
|
}
|
|
@@ -835,25 +891,32 @@ class Utils {
|
|
|
835
891
|
// Copyright (c) Microsoft Corporation.
|
|
836
892
|
class SpecFilter {
|
|
837
893
|
static specFilter(filter, unResolveSpec, resolvedSpec, options) {
|
|
894
|
+
var _a;
|
|
838
895
|
try {
|
|
839
896
|
const newSpec = Object.assign({}, unResolveSpec);
|
|
840
897
|
const newPaths = {};
|
|
841
898
|
for (const filterItem of filter) {
|
|
842
899
|
const [method, path] = filterItem.split(" ");
|
|
843
900
|
const methodName = method.toLowerCase();
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
901
|
+
const pathObj = (_a = resolvedSpec.paths) === null || _a === void 0 ? void 0 : _a[path];
|
|
902
|
+
if (ConstantString.AllOperationMethods.includes(methodName) &&
|
|
903
|
+
pathObj &&
|
|
904
|
+
pathObj[methodName]) {
|
|
905
|
+
const validateResult = Utils.isSupportedApi(methodName, path, resolvedSpec, options);
|
|
906
|
+
if (!validateResult.isValid) {
|
|
907
|
+
continue;
|
|
908
|
+
}
|
|
909
|
+
if (!newPaths[path]) {
|
|
910
|
+
newPaths[path] = Object.assign({}, unResolveSpec.paths[path]);
|
|
911
|
+
for (const m of ConstantString.AllOperationMethods) {
|
|
912
|
+
delete newPaths[path][m];
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
newPaths[path][methodName] = unResolveSpec.paths[path][methodName];
|
|
916
|
+
// Add the operationId if missing
|
|
917
|
+
if (!newPaths[path][methodName].operationId) {
|
|
918
|
+
newPaths[path][methodName].operationId = `${methodName}${Utils.convertPathToCamelCase(path)}`;
|
|
851
919
|
}
|
|
852
|
-
}
|
|
853
|
-
newPaths[path][methodName] = unResolveSpec.paths[path][methodName];
|
|
854
|
-
// Add the operationId if missing
|
|
855
|
-
if (!newPaths[path][methodName].operationId) {
|
|
856
|
-
newPaths[path][methodName].operationId = `${methodName}${Utils.convertPathToCamelCase(path)}`;
|
|
857
920
|
}
|
|
858
921
|
}
|
|
859
922
|
newSpec.paths = newPaths;
|
|
@@ -876,9 +939,10 @@ class ManifestUpdater {
|
|
|
876
939
|
pluginFile: apiPluginRelativePath,
|
|
877
940
|
},
|
|
878
941
|
];
|
|
942
|
+
const appName = this.removeEnvs(manifest.name.short);
|
|
879
943
|
ManifestUpdater.updateManifestDescription(manifest, spec);
|
|
880
944
|
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
881
|
-
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, options);
|
|
945
|
+
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, appName, options);
|
|
882
946
|
return [manifest, apiPlugin];
|
|
883
947
|
});
|
|
884
948
|
}
|
|
@@ -903,7 +967,7 @@ class ManifestUpdater {
|
|
|
903
967
|
}
|
|
904
968
|
return parameter;
|
|
905
969
|
}
|
|
906
|
-
static generatePluginManifestSchema(spec, specRelativePath, options) {
|
|
970
|
+
static generatePluginManifestSchema(spec, specRelativePath, appName, options) {
|
|
907
971
|
var _a, _b, _c;
|
|
908
972
|
const functions = [];
|
|
909
973
|
const functionNames = [];
|
|
@@ -968,7 +1032,7 @@ class ManifestUpdater {
|
|
|
968
1032
|
}
|
|
969
1033
|
const apiPlugin = {
|
|
970
1034
|
schema_version: "v2",
|
|
971
|
-
name_for_human:
|
|
1035
|
+
name_for_human: appName,
|
|
972
1036
|
description_for_human: (_c = spec.info.description) !== null && _c !== void 0 ? _c : "<Please add description of the plugin>",
|
|
973
1037
|
functions: functions,
|
|
974
1038
|
runtimes: [
|
|
@@ -1079,13 +1143,22 @@ class ManifestUpdater {
|
|
|
1079
1143
|
const relativePath = path__default['default'].relative(path__default['default'].dirname(from), to);
|
|
1080
1144
|
return path__default['default'].normalize(relativePath).replace(/\\/g, "/");
|
|
1081
1145
|
}
|
|
1146
|
+
static removeEnvs(str) {
|
|
1147
|
+
const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
|
|
1148
|
+
const matches = placeHolderReg.exec(str);
|
|
1149
|
+
let newStr = str;
|
|
1150
|
+
if (matches != null) {
|
|
1151
|
+
newStr = newStr.replace(matches[0], "");
|
|
1152
|
+
}
|
|
1153
|
+
return newStr;
|
|
1154
|
+
}
|
|
1082
1155
|
}
|
|
1083
1156
|
|
|
1084
1157
|
// Copyright (c) Microsoft Corporation.
|
|
1085
1158
|
class AdaptiveCardGenerator {
|
|
1086
1159
|
static generateAdaptiveCard(operationItem) {
|
|
1087
1160
|
try {
|
|
1088
|
-
const json = Utils.getResponseJson(operationItem);
|
|
1161
|
+
const { json } = Utils.getResponseJson(operationItem);
|
|
1089
1162
|
let cardBody = [];
|
|
1090
1163
|
let schema = json.schema;
|
|
1091
1164
|
let jsonPath = "$";
|
|
@@ -1423,20 +1496,22 @@ class SpecParser {
|
|
|
1423
1496
|
try {
|
|
1424
1497
|
yield this.loadSpec();
|
|
1425
1498
|
const spec = this.spec;
|
|
1426
|
-
const apiMap = this.
|
|
1499
|
+
const apiMap = this.getAPIs(spec);
|
|
1427
1500
|
const result = {
|
|
1428
|
-
|
|
1501
|
+
APIs: [],
|
|
1429
1502
|
allAPICount: 0,
|
|
1430
1503
|
validAPICount: 0,
|
|
1431
1504
|
};
|
|
1432
1505
|
for (const apiKey in apiMap) {
|
|
1506
|
+
const { operation, isValid, reason } = apiMap[apiKey];
|
|
1507
|
+
const [method, path] = apiKey.split(" ");
|
|
1433
1508
|
const apiResult = {
|
|
1434
1509
|
api: "",
|
|
1435
1510
|
server: "",
|
|
1436
1511
|
operationId: "",
|
|
1512
|
+
isValid: isValid,
|
|
1513
|
+
reason: reason,
|
|
1437
1514
|
};
|
|
1438
|
-
const [method, path] = apiKey.split(" ");
|
|
1439
|
-
const operation = apiMap[apiKey];
|
|
1440
1515
|
const rootServer = spec.servers && spec.servers[0];
|
|
1441
1516
|
const methodServer = spec.paths[path].servers && ((_a = spec.paths[path]) === null || _a === void 0 ? void 0 : _a.servers[0]);
|
|
1442
1517
|
const operationServer = operation.servers && operation.servers[0];
|
|
@@ -1444,7 +1519,7 @@ class SpecParser {
|
|
|
1444
1519
|
if (!serverUrl) {
|
|
1445
1520
|
throw new SpecParserError(ConstantString.NoServerInformation, exports.ErrorType.NoServerInformation);
|
|
1446
1521
|
}
|
|
1447
|
-
apiResult.server = Utils.
|
|
1522
|
+
apiResult.server = Utils.resolveEnv(serverUrl.url);
|
|
1448
1523
|
let operationId = operation.operationId;
|
|
1449
1524
|
if (!operationId) {
|
|
1450
1525
|
operationId = `${method.toLowerCase()}${Utils.convertPathToCamelCase(path)}`;
|
|
@@ -1458,10 +1533,10 @@ class SpecParser {
|
|
|
1458
1533
|
}
|
|
1459
1534
|
}
|
|
1460
1535
|
apiResult.api = apiKey;
|
|
1461
|
-
result.
|
|
1536
|
+
result.APIs.push(apiResult);
|
|
1462
1537
|
}
|
|
1463
|
-
result.allAPICount =
|
|
1464
|
-
result.validAPICount = result.
|
|
1538
|
+
result.allAPICount = result.APIs.length;
|
|
1539
|
+
result.validAPICount = result.APIs.filter((api) => api.isValid).length;
|
|
1465
1540
|
return result;
|
|
1466
1541
|
}
|
|
1467
1542
|
catch (err) {
|
|
@@ -1559,15 +1634,18 @@ class SpecParser {
|
|
|
1559
1634
|
const newSpecs = yield this.getFilteredSpecs(filter, signal);
|
|
1560
1635
|
const newUnResolvedSpec = newSpecs[0];
|
|
1561
1636
|
const newSpec = newSpecs[1];
|
|
1562
|
-
const authSet = new Set();
|
|
1563
1637
|
let hasMultipleAuth = false;
|
|
1638
|
+
let authInfo = undefined;
|
|
1564
1639
|
for (const url in newSpec.paths) {
|
|
1565
1640
|
for (const method in newSpec.paths[url]) {
|
|
1566
1641
|
const operation = newSpec.paths[url][method];
|
|
1567
1642
|
const authArray = Utils.getAuthArray(operation.security, newSpec);
|
|
1568
1643
|
if (authArray && authArray.length > 0) {
|
|
1569
|
-
|
|
1570
|
-
if (
|
|
1644
|
+
const currentAuth = authArray[0][0];
|
|
1645
|
+
if (!authInfo) {
|
|
1646
|
+
authInfo = authArray[0][0];
|
|
1647
|
+
}
|
|
1648
|
+
else if (authInfo.name !== currentAuth.name) {
|
|
1571
1649
|
hasMultipleAuth = true;
|
|
1572
1650
|
break;
|
|
1573
1651
|
}
|
|
@@ -1614,7 +1692,6 @@ class SpecParser {
|
|
|
1614
1692
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1615
1693
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1616
1694
|
}
|
|
1617
|
-
const authInfo = Array.from(authSet)[0];
|
|
1618
1695
|
const [updatedManifest, warnings] = yield ManifestUpdater.updateManifest(manifestPath, outputSpecPath, newSpec, this.options, adaptiveCardFolder, authInfo);
|
|
1619
1696
|
yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1620
1697
|
result.warnings.push(...warnings);
|
|
@@ -1643,11 +1720,11 @@ class SpecParser {
|
|
|
1643
1720
|
}
|
|
1644
1721
|
});
|
|
1645
1722
|
}
|
|
1646
|
-
|
|
1723
|
+
getAPIs(spec) {
|
|
1647
1724
|
if (this.apiMap !== undefined) {
|
|
1648
1725
|
return this.apiMap;
|
|
1649
1726
|
}
|
|
1650
|
-
const result = Utils.
|
|
1727
|
+
const result = Utils.listAPIs(spec, this.options);
|
|
1651
1728
|
this.apiMap = result;
|
|
1652
1729
|
return result;
|
|
1653
1730
|
}
|