@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.esm2017.mjs
CHANGED
|
@@ -29,6 +29,21 @@ var ErrorType;
|
|
|
29
29
|
ErrorType["GenerateFailed"] = "generate-failed";
|
|
30
30
|
ErrorType["ValidateFailed"] = "validate-failed";
|
|
31
31
|
ErrorType["GetSpecFailed"] = "get-spec-failed";
|
|
32
|
+
ErrorType["AuthTypeIsNotSupported"] = "auth-type-is-not-supported";
|
|
33
|
+
ErrorType["MissingOperationId"] = "missing-operation-id";
|
|
34
|
+
ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
|
|
35
|
+
ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
|
|
36
|
+
ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
|
|
37
|
+
ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
|
|
38
|
+
ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
|
|
39
|
+
ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
|
|
40
|
+
ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
|
|
41
|
+
ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
|
|
42
|
+
ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
|
|
43
|
+
ErrorType["NoParameter"] = "no-parameter";
|
|
44
|
+
ErrorType["NoAPIInfo"] = "no-api-info";
|
|
45
|
+
ErrorType["MethodNotAllowed"] = "method-not-allowed";
|
|
46
|
+
ErrorType["UrlPathNotExist"] = "url-path-not-exist";
|
|
32
47
|
ErrorType["Cancelled"] = "cancelled";
|
|
33
48
|
ErrorType["Unknown"] = "unknown";
|
|
34
49
|
})(ErrorType || (ErrorType = {}));
|
|
@@ -179,6 +194,7 @@ class Utils {
|
|
|
179
194
|
requiredNum: 0,
|
|
180
195
|
optionalNum: 0,
|
|
181
196
|
isValid: true,
|
|
197
|
+
reason: [],
|
|
182
198
|
};
|
|
183
199
|
if (!paramObject) {
|
|
184
200
|
return paramResult;
|
|
@@ -188,6 +204,7 @@ class Utils {
|
|
|
188
204
|
const schema = param.schema;
|
|
189
205
|
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
190
206
|
paramResult.isValid = false;
|
|
207
|
+
paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
|
|
191
208
|
continue;
|
|
192
209
|
}
|
|
193
210
|
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
@@ -203,6 +220,7 @@ class Utils {
|
|
|
203
220
|
if (param.in === "header" || param.in === "cookie") {
|
|
204
221
|
if (isRequiredWithoutDefault) {
|
|
205
222
|
paramResult.isValid = false;
|
|
223
|
+
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
206
224
|
}
|
|
207
225
|
continue;
|
|
208
226
|
}
|
|
@@ -212,6 +230,7 @@ class Utils {
|
|
|
212
230
|
schema.type !== "integer") {
|
|
213
231
|
if (isRequiredWithoutDefault) {
|
|
214
232
|
paramResult.isValid = false;
|
|
233
|
+
paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
|
|
215
234
|
}
|
|
216
235
|
continue;
|
|
217
236
|
}
|
|
@@ -232,6 +251,7 @@ class Utils {
|
|
|
232
251
|
requiredNum: 0,
|
|
233
252
|
optionalNum: 0,
|
|
234
253
|
isValid: true,
|
|
254
|
+
reason: [],
|
|
235
255
|
};
|
|
236
256
|
if (Object.keys(schema).length === 0) {
|
|
237
257
|
return paramResult;
|
|
@@ -239,6 +259,7 @@ class Utils {
|
|
|
239
259
|
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
240
260
|
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
241
261
|
paramResult.isValid = false;
|
|
262
|
+
paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
|
|
242
263
|
return paramResult;
|
|
243
264
|
}
|
|
244
265
|
if (schema.type === "string" ||
|
|
@@ -263,11 +284,13 @@ class Utils {
|
|
|
263
284
|
paramResult.requiredNum += result.requiredNum;
|
|
264
285
|
paramResult.optionalNum += result.optionalNum;
|
|
265
286
|
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
287
|
+
paramResult.reason.push(...result.reason);
|
|
266
288
|
}
|
|
267
289
|
}
|
|
268
290
|
else {
|
|
269
291
|
if (isRequiredWithoutDefault && !isCopilot) {
|
|
270
292
|
paramResult.isValid = false;
|
|
293
|
+
paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
|
|
271
294
|
}
|
|
272
295
|
}
|
|
273
296
|
return paramResult;
|
|
@@ -291,103 +314,123 @@ class Utils {
|
|
|
291
314
|
*/
|
|
292
315
|
static isSupportedApi(method, path, spec, options) {
|
|
293
316
|
var _a;
|
|
294
|
-
const
|
|
317
|
+
const result = { isValid: true, reason: [] };
|
|
295
318
|
method = method.toLocaleLowerCase();
|
|
296
|
-
if (
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
319
|
+
if (options.allowMethods && !options.allowMethods.includes(method)) {
|
|
320
|
+
result.isValid = false;
|
|
321
|
+
result.reason.push(ErrorType.MethodNotAllowed);
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
const pathObj = spec.paths[path];
|
|
325
|
+
if (!pathObj || !pathObj[method]) {
|
|
326
|
+
result.isValid = false;
|
|
327
|
+
result.reason.push(ErrorType.UrlPathNotExist);
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
const securities = pathObj[method].security;
|
|
331
|
+
const isTeamsAi = options.projectType === ProjectType.TeamsAi;
|
|
332
|
+
const isCopilot = options.projectType === ProjectType.Copilot;
|
|
333
|
+
// Teams AI project doesn't care about auth, it will use authProvider for user to implement
|
|
334
|
+
if (!isTeamsAi) {
|
|
335
|
+
const authArray = Utils.getAuthArray(securities, spec);
|
|
336
|
+
const authCheckResult = Utils.isSupportedAuth(authArray, options);
|
|
337
|
+
if (!authCheckResult.isValid) {
|
|
338
|
+
result.reason.push(...authCheckResult.reason);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const operationObject = pathObj[method];
|
|
342
|
+
if (!options.allowMissingId && !operationObject.operationId) {
|
|
343
|
+
result.reason.push(ErrorType.MissingOperationId);
|
|
344
|
+
}
|
|
345
|
+
const rootServer = spec.servers && spec.servers[0];
|
|
346
|
+
const methodServer = spec.paths[path].servers && ((_a = spec.paths[path]) === null || _a === void 0 ? void 0 : _a.servers[0]);
|
|
347
|
+
const operationServer = operationObject.servers && operationObject.servers[0];
|
|
348
|
+
const serverUrl = operationServer || methodServer || rootServer;
|
|
349
|
+
if (!serverUrl) {
|
|
350
|
+
result.reason.push(ErrorType.NoServerInformation);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
const serverValidateResult = Utils.checkServerUrl([serverUrl]);
|
|
354
|
+
result.reason.push(...serverValidateResult.map((item) => item.type));
|
|
355
|
+
}
|
|
356
|
+
const paramObject = operationObject.parameters;
|
|
357
|
+
const requestBody = operationObject.requestBody;
|
|
358
|
+
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
359
|
+
if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
|
|
360
|
+
result.reason.push(ErrorType.PostBodyContainMultipleMediaTypes);
|
|
361
|
+
}
|
|
362
|
+
const { json, multipleMediaType } = Utils.getResponseJson(operationObject, isTeamsAi);
|
|
363
|
+
if (multipleMediaType && !isTeamsAi) {
|
|
364
|
+
result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
|
|
365
|
+
}
|
|
366
|
+
else if (Object.keys(json).length === 0) {
|
|
367
|
+
result.reason.push(ErrorType.ResponseJsonIsEmpty);
|
|
368
|
+
}
|
|
369
|
+
// Teams AI project doesn't care about request parameters/body
|
|
370
|
+
if (!isTeamsAi) {
|
|
371
|
+
let requestBodyParamResult = {
|
|
372
|
+
requiredNum: 0,
|
|
373
|
+
optionalNum: 0,
|
|
374
|
+
isValid: true,
|
|
375
|
+
reason: [],
|
|
376
|
+
};
|
|
377
|
+
if (requestJsonBody) {
|
|
378
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
379
|
+
if (isCopilot && requestBodySchema.type !== "object") {
|
|
380
|
+
result.reason.push(ErrorType.PostBodySchemaIsNotJson);
|
|
344
381
|
}
|
|
345
|
-
|
|
346
|
-
if (
|
|
347
|
-
|
|
382
|
+
requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
|
|
383
|
+
if (!requestBodyParamResult.isValid && requestBodyParamResult.reason) {
|
|
384
|
+
result.reason.push(...requestBodyParamResult.reason);
|
|
348
385
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
386
|
+
}
|
|
387
|
+
const paramResult = Utils.checkParameters(paramObject, isCopilot);
|
|
388
|
+
if (!paramResult.isValid && paramResult.reason) {
|
|
389
|
+
result.reason.push(...paramResult.reason);
|
|
390
|
+
}
|
|
391
|
+
// Copilot support arbitrary parameters
|
|
392
|
+
if (!isCopilot && paramResult.isValid && requestBodyParamResult.isValid) {
|
|
393
|
+
const totalRequiredParams = requestBodyParamResult.requiredNum + paramResult.requiredNum;
|
|
394
|
+
const totalParams = totalRequiredParams + requestBodyParamResult.optionalNum + paramResult.optionalNum;
|
|
395
|
+
if (totalRequiredParams > 1) {
|
|
396
|
+
if (!options.allowMultipleParameters ||
|
|
397
|
+
totalRequiredParams > ConstantString.SMERequiredParamsMaxNum) {
|
|
398
|
+
result.reason.push(ErrorType.ExceededRequiredParamsLimit);
|
|
354
399
|
}
|
|
355
|
-
return false;
|
|
356
400
|
}
|
|
357
|
-
else if (
|
|
358
|
-
|
|
359
|
-
paramResult.requiredNum +
|
|
360
|
-
paramResult.optionalNum ===
|
|
361
|
-
0) {
|
|
362
|
-
return false;
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
return true;
|
|
401
|
+
else if (totalParams === 0) {
|
|
402
|
+
result.reason.push(ErrorType.NoParameter);
|
|
366
403
|
}
|
|
367
404
|
}
|
|
368
405
|
}
|
|
369
|
-
|
|
406
|
+
if (result.reason.length > 0) {
|
|
407
|
+
result.isValid = false;
|
|
408
|
+
}
|
|
409
|
+
return result;
|
|
370
410
|
}
|
|
371
411
|
static isSupportedAuth(authSchemeArray, options) {
|
|
372
412
|
if (authSchemeArray.length === 0) {
|
|
373
|
-
return true;
|
|
413
|
+
return { isValid: true, reason: [] };
|
|
374
414
|
}
|
|
375
415
|
if (options.allowAPIKeyAuth || options.allowOauth2 || options.allowBearerTokenAuth) {
|
|
376
416
|
// Currently we don't support multiple auth in one operation
|
|
377
417
|
if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
|
|
378
|
-
return
|
|
418
|
+
return {
|
|
419
|
+
isValid: false,
|
|
420
|
+
reason: [ErrorType.MultipleAuthNotSupported],
|
|
421
|
+
};
|
|
379
422
|
}
|
|
380
423
|
for (const auths of authSchemeArray) {
|
|
381
424
|
if (auths.length === 1) {
|
|
382
425
|
if ((options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
|
|
383
426
|
(options.allowOauth2 && Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme)) ||
|
|
384
427
|
(options.allowBearerTokenAuth && Utils.isBearerTokenAuth(auths[0].authScheme))) {
|
|
385
|
-
return true;
|
|
428
|
+
return { isValid: true, reason: [] };
|
|
386
429
|
}
|
|
387
430
|
}
|
|
388
431
|
}
|
|
389
432
|
}
|
|
390
|
-
return false;
|
|
433
|
+
return { isValid: false, reason: [ErrorType.AuthTypeIsNotSupported] };
|
|
391
434
|
}
|
|
392
435
|
static isBearerTokenAuth(authScheme) {
|
|
393
436
|
return authScheme.type === "http" && authScheme.scheme === "bearer";
|
|
@@ -430,11 +473,17 @@ class Utils {
|
|
|
430
473
|
static getResponseJson(operationObject, isTeamsAiProject = false) {
|
|
431
474
|
var _a, _b;
|
|
432
475
|
let json = {};
|
|
476
|
+
let multipleMediaType = false;
|
|
433
477
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
434
478
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
435
479
|
if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
|
|
480
|
+
multipleMediaType = false;
|
|
436
481
|
json = responseObject.content["application/json"];
|
|
437
|
-
if (
|
|
482
|
+
if (Utils.containMultipleMediaTypes(responseObject)) {
|
|
483
|
+
multipleMediaType = true;
|
|
484
|
+
if (isTeamsAiProject) {
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
438
487
|
json = {};
|
|
439
488
|
}
|
|
440
489
|
else {
|
|
@@ -442,7 +491,7 @@ class Utils {
|
|
|
442
491
|
}
|
|
443
492
|
}
|
|
444
493
|
}
|
|
445
|
-
return json;
|
|
494
|
+
return { json, multipleMediaType };
|
|
446
495
|
}
|
|
447
496
|
static convertPathToCamelCase(path) {
|
|
448
497
|
const pathSegments = path.split(/[./{]/);
|
|
@@ -462,10 +511,10 @@ class Utils {
|
|
|
462
511
|
return undefined;
|
|
463
512
|
}
|
|
464
513
|
}
|
|
465
|
-
static
|
|
514
|
+
static resolveEnv(str) {
|
|
466
515
|
const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
|
|
467
|
-
let matches = placeHolderReg.exec(
|
|
468
|
-
let
|
|
516
|
+
let matches = placeHolderReg.exec(str);
|
|
517
|
+
let newStr = str;
|
|
469
518
|
while (matches != null) {
|
|
470
519
|
const envVar = matches[1];
|
|
471
520
|
const envVal = process.env[envVar];
|
|
@@ -473,17 +522,17 @@ class Utils {
|
|
|
473
522
|
throw new Error(Utils.format(ConstantString.ResolveServerUrlFailed, envVar));
|
|
474
523
|
}
|
|
475
524
|
else {
|
|
476
|
-
|
|
525
|
+
newStr = newStr.replace(matches[0], envVal);
|
|
477
526
|
}
|
|
478
|
-
matches = placeHolderReg.exec(
|
|
527
|
+
matches = placeHolderReg.exec(str);
|
|
479
528
|
}
|
|
480
|
-
return
|
|
529
|
+
return newStr;
|
|
481
530
|
}
|
|
482
531
|
static checkServerUrl(servers) {
|
|
483
532
|
const errors = [];
|
|
484
533
|
let serverUrl;
|
|
485
534
|
try {
|
|
486
|
-
serverUrl = Utils.
|
|
535
|
+
serverUrl = Utils.resolveEnv(servers[0].url);
|
|
487
536
|
}
|
|
488
537
|
catch (err) {
|
|
489
538
|
errors.push({
|
|
@@ -514,6 +563,7 @@ class Utils {
|
|
|
514
563
|
return errors;
|
|
515
564
|
}
|
|
516
565
|
static validateServer(spec, options) {
|
|
566
|
+
var _a;
|
|
517
567
|
const errors = [];
|
|
518
568
|
let hasTopLevelServers = false;
|
|
519
569
|
let hasPathLevelServers = false;
|
|
@@ -534,7 +584,7 @@ class Utils {
|
|
|
534
584
|
}
|
|
535
585
|
for (const method in methods) {
|
|
536
586
|
const operationObject = methods[method];
|
|
537
|
-
if (
|
|
587
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
538
588
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
539
589
|
hasOperationLevelServers = true;
|
|
540
590
|
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
@@ -686,15 +736,21 @@ class Utils {
|
|
|
686
736
|
}
|
|
687
737
|
return [command, warning];
|
|
688
738
|
}
|
|
689
|
-
static
|
|
739
|
+
static listAPIs(spec, options) {
|
|
740
|
+
var _a;
|
|
690
741
|
const paths = spec.paths;
|
|
691
742
|
const result = {};
|
|
692
743
|
for (const path in paths) {
|
|
693
744
|
const methods = paths[path];
|
|
694
745
|
for (const method in methods) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
746
|
+
const operationObject = methods[method];
|
|
747
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
|
|
748
|
+
const validateResult = Utils.isSupportedApi(method, path, spec, options);
|
|
749
|
+
result[`${method.toUpperCase()} ${path}`] = {
|
|
750
|
+
operation: operationObject,
|
|
751
|
+
isValid: validateResult.isValid,
|
|
752
|
+
reason: validateResult.reason,
|
|
753
|
+
};
|
|
698
754
|
}
|
|
699
755
|
}
|
|
700
756
|
}
|
|
@@ -703,13 +759,13 @@ class Utils {
|
|
|
703
759
|
static validateSpec(spec, parser, isSwaggerFile, options) {
|
|
704
760
|
const errors = [];
|
|
705
761
|
const warnings = [];
|
|
762
|
+
const apiMap = Utils.listAPIs(spec, options);
|
|
706
763
|
if (isSwaggerFile) {
|
|
707
764
|
warnings.push({
|
|
708
765
|
type: WarningType.ConvertSwaggerToOpenAPI,
|
|
709
766
|
content: ConstantString.ConvertSwaggerToOpenAPI,
|
|
710
767
|
});
|
|
711
768
|
}
|
|
712
|
-
// Server validation
|
|
713
769
|
const serverErrors = Utils.validateServer(spec, options);
|
|
714
770
|
errors.push(...serverErrors);
|
|
715
771
|
// Remote reference not supported
|
|
@@ -723,8 +779,8 @@ class Utils {
|
|
|
723
779
|
});
|
|
724
780
|
}
|
|
725
781
|
// No supported API
|
|
726
|
-
const
|
|
727
|
-
if (
|
|
782
|
+
const validAPIs = Object.entries(apiMap).filter(([, value]) => value.isValid);
|
|
783
|
+
if (validAPIs.length === 0) {
|
|
728
784
|
errors.push({
|
|
729
785
|
type: ErrorType.NoSupportedApi,
|
|
730
786
|
content: ConstantString.NoSupportedApi,
|
|
@@ -733,8 +789,8 @@ class Utils {
|
|
|
733
789
|
// OperationId missing
|
|
734
790
|
const apisMissingOperationId = [];
|
|
735
791
|
for (const key in apiMap) {
|
|
736
|
-
const
|
|
737
|
-
if (!
|
|
792
|
+
const { operation } = apiMap[key];
|
|
793
|
+
if (!operation.operationId) {
|
|
738
794
|
apisMissingOperationId.push(key);
|
|
739
795
|
}
|
|
740
796
|
}
|
|
@@ -793,25 +849,32 @@ class Utils {
|
|
|
793
849
|
// Copyright (c) Microsoft Corporation.
|
|
794
850
|
class SpecFilter {
|
|
795
851
|
static specFilter(filter, unResolveSpec, resolvedSpec, options) {
|
|
852
|
+
var _a;
|
|
796
853
|
try {
|
|
797
854
|
const newSpec = Object.assign({}, unResolveSpec);
|
|
798
855
|
const newPaths = {};
|
|
799
856
|
for (const filterItem of filter) {
|
|
800
857
|
const [method, path] = filterItem.split(" ");
|
|
801
858
|
const methodName = method.toLowerCase();
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
859
|
+
const pathObj = (_a = resolvedSpec.paths) === null || _a === void 0 ? void 0 : _a[path];
|
|
860
|
+
if (ConstantString.AllOperationMethods.includes(methodName) &&
|
|
861
|
+
pathObj &&
|
|
862
|
+
pathObj[methodName]) {
|
|
863
|
+
const validateResult = Utils.isSupportedApi(methodName, path, resolvedSpec, options);
|
|
864
|
+
if (!validateResult.isValid) {
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
if (!newPaths[path]) {
|
|
868
|
+
newPaths[path] = Object.assign({}, unResolveSpec.paths[path]);
|
|
869
|
+
for (const m of ConstantString.AllOperationMethods) {
|
|
870
|
+
delete newPaths[path][m];
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
newPaths[path][methodName] = unResolveSpec.paths[path][methodName];
|
|
874
|
+
// Add the operationId if missing
|
|
875
|
+
if (!newPaths[path][methodName].operationId) {
|
|
876
|
+
newPaths[path][methodName].operationId = `${methodName}${Utils.convertPathToCamelCase(path)}`;
|
|
809
877
|
}
|
|
810
|
-
}
|
|
811
|
-
newPaths[path][methodName] = unResolveSpec.paths[path][methodName];
|
|
812
|
-
// Add the operationId if missing
|
|
813
|
-
if (!newPaths[path][methodName].operationId) {
|
|
814
|
-
newPaths[path][methodName].operationId = `${methodName}${Utils.convertPathToCamelCase(path)}`;
|
|
815
878
|
}
|
|
816
879
|
}
|
|
817
880
|
newSpec.paths = newPaths;
|
|
@@ -833,9 +896,10 @@ class ManifestUpdater {
|
|
|
833
896
|
pluginFile: apiPluginRelativePath,
|
|
834
897
|
},
|
|
835
898
|
];
|
|
899
|
+
const appName = this.removeEnvs(manifest.name.short);
|
|
836
900
|
ManifestUpdater.updateManifestDescription(manifest, spec);
|
|
837
901
|
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
838
|
-
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, options);
|
|
902
|
+
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, appName, options);
|
|
839
903
|
return [manifest, apiPlugin];
|
|
840
904
|
}
|
|
841
905
|
static updateManifestDescription(manifest, spec) {
|
|
@@ -859,7 +923,7 @@ class ManifestUpdater {
|
|
|
859
923
|
}
|
|
860
924
|
return parameter;
|
|
861
925
|
}
|
|
862
|
-
static generatePluginManifestSchema(spec, specRelativePath, options) {
|
|
926
|
+
static generatePluginManifestSchema(spec, specRelativePath, appName, options) {
|
|
863
927
|
var _a, _b, _c;
|
|
864
928
|
const functions = [];
|
|
865
929
|
const functionNames = [];
|
|
@@ -924,7 +988,7 @@ class ManifestUpdater {
|
|
|
924
988
|
}
|
|
925
989
|
const apiPlugin = {
|
|
926
990
|
schema_version: "v2",
|
|
927
|
-
name_for_human:
|
|
991
|
+
name_for_human: appName,
|
|
928
992
|
description_for_human: (_c = spec.info.description) !== null && _c !== void 0 ? _c : "<Please add description of the plugin>",
|
|
929
993
|
functions: functions,
|
|
930
994
|
runtimes: [
|
|
@@ -1031,13 +1095,22 @@ class ManifestUpdater {
|
|
|
1031
1095
|
const relativePath = path.relative(path.dirname(from), to);
|
|
1032
1096
|
return path.normalize(relativePath).replace(/\\/g, "/");
|
|
1033
1097
|
}
|
|
1098
|
+
static removeEnvs(str) {
|
|
1099
|
+
const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
|
|
1100
|
+
const matches = placeHolderReg.exec(str);
|
|
1101
|
+
let newStr = str;
|
|
1102
|
+
if (matches != null) {
|
|
1103
|
+
newStr = newStr.replace(matches[0], "");
|
|
1104
|
+
}
|
|
1105
|
+
return newStr;
|
|
1106
|
+
}
|
|
1034
1107
|
}
|
|
1035
1108
|
|
|
1036
1109
|
// Copyright (c) Microsoft Corporation.
|
|
1037
1110
|
class AdaptiveCardGenerator {
|
|
1038
1111
|
static generateAdaptiveCard(operationItem) {
|
|
1039
1112
|
try {
|
|
1040
|
-
const json = Utils.getResponseJson(operationItem);
|
|
1113
|
+
const { json } = Utils.getResponseJson(operationItem);
|
|
1041
1114
|
let cardBody = [];
|
|
1042
1115
|
let schema = json.schema;
|
|
1043
1116
|
let jsonPath = "$";
|
|
@@ -1370,20 +1443,22 @@ class SpecParser {
|
|
|
1370
1443
|
try {
|
|
1371
1444
|
await this.loadSpec();
|
|
1372
1445
|
const spec = this.spec;
|
|
1373
|
-
const apiMap = this.
|
|
1446
|
+
const apiMap = this.getAPIs(spec);
|
|
1374
1447
|
const result = {
|
|
1375
|
-
|
|
1448
|
+
APIs: [],
|
|
1376
1449
|
allAPICount: 0,
|
|
1377
1450
|
validAPICount: 0,
|
|
1378
1451
|
};
|
|
1379
1452
|
for (const apiKey in apiMap) {
|
|
1453
|
+
const { operation, isValid, reason } = apiMap[apiKey];
|
|
1454
|
+
const [method, path] = apiKey.split(" ");
|
|
1380
1455
|
const apiResult = {
|
|
1381
1456
|
api: "",
|
|
1382
1457
|
server: "",
|
|
1383
1458
|
operationId: "",
|
|
1459
|
+
isValid: isValid,
|
|
1460
|
+
reason: reason,
|
|
1384
1461
|
};
|
|
1385
|
-
const [method, path] = apiKey.split(" ");
|
|
1386
|
-
const operation = apiMap[apiKey];
|
|
1387
1462
|
const rootServer = spec.servers && spec.servers[0];
|
|
1388
1463
|
const methodServer = spec.paths[path].servers && ((_a = spec.paths[path]) === null || _a === void 0 ? void 0 : _a.servers[0]);
|
|
1389
1464
|
const operationServer = operation.servers && operation.servers[0];
|
|
@@ -1391,7 +1466,7 @@ class SpecParser {
|
|
|
1391
1466
|
if (!serverUrl) {
|
|
1392
1467
|
throw new SpecParserError(ConstantString.NoServerInformation, ErrorType.NoServerInformation);
|
|
1393
1468
|
}
|
|
1394
|
-
apiResult.server = Utils.
|
|
1469
|
+
apiResult.server = Utils.resolveEnv(serverUrl.url);
|
|
1395
1470
|
let operationId = operation.operationId;
|
|
1396
1471
|
if (!operationId) {
|
|
1397
1472
|
operationId = `${method.toLowerCase()}${Utils.convertPathToCamelCase(path)}`;
|
|
@@ -1405,10 +1480,10 @@ class SpecParser {
|
|
|
1405
1480
|
}
|
|
1406
1481
|
}
|
|
1407
1482
|
apiResult.api = apiKey;
|
|
1408
|
-
result.
|
|
1483
|
+
result.APIs.push(apiResult);
|
|
1409
1484
|
}
|
|
1410
|
-
result.allAPICount =
|
|
1411
|
-
result.validAPICount = result.
|
|
1485
|
+
result.allAPICount = result.APIs.length;
|
|
1486
|
+
result.validAPICount = result.APIs.filter((api) => api.isValid).length;
|
|
1412
1487
|
return result;
|
|
1413
1488
|
}
|
|
1414
1489
|
catch (err) {
|
|
@@ -1500,15 +1575,18 @@ class SpecParser {
|
|
|
1500
1575
|
const newSpecs = await this.getFilteredSpecs(filter, signal);
|
|
1501
1576
|
const newUnResolvedSpec = newSpecs[0];
|
|
1502
1577
|
const newSpec = newSpecs[1];
|
|
1503
|
-
const authSet = new Set();
|
|
1504
1578
|
let hasMultipleAuth = false;
|
|
1579
|
+
let authInfo = undefined;
|
|
1505
1580
|
for (const url in newSpec.paths) {
|
|
1506
1581
|
for (const method in newSpec.paths[url]) {
|
|
1507
1582
|
const operation = newSpec.paths[url][method];
|
|
1508
1583
|
const authArray = Utils.getAuthArray(operation.security, newSpec);
|
|
1509
1584
|
if (authArray && authArray.length > 0) {
|
|
1510
|
-
|
|
1511
|
-
if (
|
|
1585
|
+
const currentAuth = authArray[0][0];
|
|
1586
|
+
if (!authInfo) {
|
|
1587
|
+
authInfo = authArray[0][0];
|
|
1588
|
+
}
|
|
1589
|
+
else if (authInfo.name !== currentAuth.name) {
|
|
1512
1590
|
hasMultipleAuth = true;
|
|
1513
1591
|
break;
|
|
1514
1592
|
}
|
|
@@ -1555,7 +1633,6 @@ class SpecParser {
|
|
|
1555
1633
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1556
1634
|
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
1557
1635
|
}
|
|
1558
|
-
const authInfo = Array.from(authSet)[0];
|
|
1559
1636
|
const [updatedManifest, warnings] = await ManifestUpdater.updateManifest(manifestPath, outputSpecPath, newSpec, this.options, adaptiveCardFolder, authInfo);
|
|
1560
1637
|
await fs.outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1561
1638
|
result.warnings.push(...warnings);
|
|
@@ -1581,11 +1658,11 @@ class SpecParser {
|
|
|
1581
1658
|
this.spec = (await this.parser.dereference(clonedUnResolveSpec));
|
|
1582
1659
|
}
|
|
1583
1660
|
}
|
|
1584
|
-
|
|
1661
|
+
getAPIs(spec) {
|
|
1585
1662
|
if (this.apiMap !== undefined) {
|
|
1586
1663
|
return this.apiMap;
|
|
1587
1664
|
}
|
|
1588
|
-
const result = Utils.
|
|
1665
|
+
const result = Utils.listAPIs(spec, this.options);
|
|
1589
1666
|
this.apiMap = result;
|
|
1590
1667
|
return result;
|
|
1591
1668
|
}
|