@microsoft/m365-spec-parser 0.2.1 → 0.2.2-alpha.3031916b6.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 +52 -4
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +106 -26
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +52 -4
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +106 -26
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardGenerator.d.ts +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/interfaces.d.ts +6 -1
- package/dist/src/specParser.d.ts +1 -0
- package/dist/src/utils.d.ts +5 -5
- package/package.json +3 -3
package/dist/index.node.cjs.js
CHANGED
|
@@ -59,10 +59,12 @@ exports.ErrorType = void 0;
|
|
|
59
59
|
ErrorType["RelativeServerUrlNotSupported"] = "relative-server-url-not-supported";
|
|
60
60
|
ErrorType["NoSupportedApi"] = "no-supported-api";
|
|
61
61
|
ErrorType["NoExtraAPICanBeAdded"] = "no-extra-api-can-be-added";
|
|
62
|
+
ErrorType["AddedAPINotInOriginalSpec"] = "added-api-not-in-original-spec";
|
|
62
63
|
ErrorType["ResolveServerUrlFailed"] = "resolve-server-url-failed";
|
|
63
64
|
ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
|
|
64
65
|
ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
|
|
65
66
|
ErrorType["SpecVersionNotSupported"] = "spec-version-not-supported";
|
|
67
|
+
ErrorType["CircularReferenceNotSupported"] = "circular-reference-not-supported";
|
|
66
68
|
ErrorType["ListFailed"] = "list-failed";
|
|
67
69
|
ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
|
|
68
70
|
ErrorType["FilterSpecFailed"] = "filter-spec-failed";
|
|
@@ -299,7 +301,7 @@ class Utils {
|
|
|
299
301
|
static updateFirstLetter(str) {
|
|
300
302
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
301
303
|
}
|
|
302
|
-
static getResponseJson(operationObject) {
|
|
304
|
+
static getResponseJson(operationObject, allowMultipleMediaType = false) {
|
|
303
305
|
var _a, _b;
|
|
304
306
|
let json = {};
|
|
305
307
|
let multipleMediaType = false;
|
|
@@ -310,7 +312,9 @@ class Utils {
|
|
|
310
312
|
json = responseObject.content["application/json"];
|
|
311
313
|
if (Utils.containMultipleMediaTypes(responseObject)) {
|
|
312
314
|
multipleMediaType = true;
|
|
313
|
-
|
|
315
|
+
if (!allowMultipleMediaType) {
|
|
316
|
+
json = {};
|
|
317
|
+
}
|
|
314
318
|
}
|
|
315
319
|
else {
|
|
316
320
|
break;
|
|
@@ -578,6 +582,19 @@ class Utils {
|
|
|
578
582
|
|
|
579
583
|
// Copyright (c) Microsoft Corporation.
|
|
580
584
|
class Validator {
|
|
585
|
+
constructor() {
|
|
586
|
+
this.hasCircularReference = false;
|
|
587
|
+
}
|
|
588
|
+
checkCircularReference() {
|
|
589
|
+
try {
|
|
590
|
+
JSON.stringify(this.spec);
|
|
591
|
+
}
|
|
592
|
+
catch (e) {
|
|
593
|
+
if (e.message.includes("Converting circular structure to JSON")) {
|
|
594
|
+
this.hasCircularReference = true;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
581
598
|
listAPIs() {
|
|
582
599
|
var _a;
|
|
583
600
|
if (this.apiMap) {
|
|
@@ -673,6 +690,22 @@ class Validator {
|
|
|
673
690
|
}
|
|
674
691
|
return result;
|
|
675
692
|
}
|
|
693
|
+
validateCircularReference(method, path) {
|
|
694
|
+
const result = { isValid: true, reason: [] };
|
|
695
|
+
if (this.hasCircularReference) {
|
|
696
|
+
const operationObject = this.spec.paths[path][method];
|
|
697
|
+
try {
|
|
698
|
+
JSON.stringify(operationObject);
|
|
699
|
+
}
|
|
700
|
+
catch (e) {
|
|
701
|
+
if (e.message.includes("Converting circular structure to JSON")) {
|
|
702
|
+
result.isValid = false;
|
|
703
|
+
result.reason.push(exports.ErrorType.CircularReferenceNotSupported);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return result;
|
|
708
|
+
}
|
|
676
709
|
validateResponse(method, path) {
|
|
677
710
|
const result = { isValid: true, reason: [] };
|
|
678
711
|
const operationObject = this.spec.paths[path][method];
|
|
@@ -861,6 +894,7 @@ class CopilotValidator extends Validator {
|
|
|
861
894
|
this.projectType = exports.ProjectType.Copilot;
|
|
862
895
|
this.options = options;
|
|
863
896
|
this.spec = spec;
|
|
897
|
+
this.checkCircularReference();
|
|
864
898
|
}
|
|
865
899
|
validateSpec() {
|
|
866
900
|
const result = { errors: [], warnings: [] };
|
|
@@ -886,6 +920,10 @@ class CopilotValidator extends Validator {
|
|
|
886
920
|
if (!methodAndPathResult.isValid) {
|
|
887
921
|
return methodAndPathResult;
|
|
888
922
|
}
|
|
923
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
924
|
+
if (!circularReferenceResult.isValid) {
|
|
925
|
+
return circularReferenceResult;
|
|
926
|
+
}
|
|
889
927
|
const operationObject = this.spec.paths[path][method];
|
|
890
928
|
// validate auth
|
|
891
929
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -929,6 +967,7 @@ class SMEValidator extends Validator {
|
|
|
929
967
|
this.projectType = exports.ProjectType.SME;
|
|
930
968
|
this.options = options;
|
|
931
969
|
this.spec = spec;
|
|
970
|
+
this.checkCircularReference();
|
|
932
971
|
}
|
|
933
972
|
validateSpec() {
|
|
934
973
|
const result = { errors: [], warnings: [] };
|
|
@@ -956,6 +995,10 @@ class SMEValidator extends Validator {
|
|
|
956
995
|
if (!methodAndPathResult.isValid) {
|
|
957
996
|
return methodAndPathResult;
|
|
958
997
|
}
|
|
998
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
999
|
+
if (!circularReferenceResult.isValid) {
|
|
1000
|
+
return circularReferenceResult;
|
|
1001
|
+
}
|
|
959
1002
|
const operationObject = this.spec.paths[path][method];
|
|
960
1003
|
// validate auth
|
|
961
1004
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -1026,6 +1069,7 @@ class TeamsAIValidator extends Validator {
|
|
|
1026
1069
|
this.projectType = exports.ProjectType.TeamsAi;
|
|
1027
1070
|
this.options = options;
|
|
1028
1071
|
this.spec = spec;
|
|
1072
|
+
this.checkCircularReference();
|
|
1029
1073
|
}
|
|
1030
1074
|
validateSpec() {
|
|
1031
1075
|
const result = { errors: [], warnings: [] };
|
|
@@ -1045,6 +1089,10 @@ class TeamsAIValidator extends Validator {
|
|
|
1045
1089
|
if (!methodAndPathResult.isValid) {
|
|
1046
1090
|
return methodAndPathResult;
|
|
1047
1091
|
}
|
|
1092
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
1093
|
+
if (!circularReferenceResult.isValid) {
|
|
1094
|
+
return circularReferenceResult;
|
|
1095
|
+
}
|
|
1048
1096
|
const operationObject = this.spec.paths[path][method];
|
|
1049
1097
|
// validate operationId
|
|
1050
1098
|
if (!this.options.allowMissingId && !operationObject.operationId) {
|
|
@@ -1120,9 +1168,9 @@ class SpecFilter {
|
|
|
1120
1168
|
|
|
1121
1169
|
// Copyright (c) Microsoft Corporation.
|
|
1122
1170
|
class AdaptiveCardGenerator {
|
|
1123
|
-
static generateAdaptiveCard(operationItem) {
|
|
1171
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1124
1172
|
try {
|
|
1125
|
-
const { json } = Utils.getResponseJson(operationItem);
|
|
1173
|
+
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1126
1174
|
let cardBody = [];
|
|
1127
1175
|
let schema = json.schema;
|
|
1128
1176
|
let jsonPath = "$";
|
|
@@ -1643,7 +1691,6 @@ class ManifestUpdater {
|
|
|
1643
1691
|
const auth = authInfo.authScheme;
|
|
1644
1692
|
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1645
1693
|
if (Utils.isAPIKeyAuth(auth) || Utils.isBearerTokenAuth(auth)) {
|
|
1646
|
-
const safeApiSecretRegistrationId = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1647
1694
|
composeExtension.authorization = {
|
|
1648
1695
|
authType: "apiSecretServiceAuth",
|
|
1649
1696
|
apiSecretServiceAuthConfiguration: {
|
|
@@ -1652,16 +1699,13 @@ class ManifestUpdater {
|
|
|
1652
1699
|
};
|
|
1653
1700
|
}
|
|
1654
1701
|
else if (Utils.isOAuthWithAuthCodeFlow(auth)) {
|
|
1702
|
+
// TODO: below schema is coming from design doc, may need to update when shcema is finalized
|
|
1655
1703
|
composeExtension.authorization = {
|
|
1656
1704
|
authType: "oAuth2.0",
|
|
1657
1705
|
oAuthConfiguration: {
|
|
1658
1706
|
oauthConfigurationId: `\${{${safeRegistrationIdName}}}`,
|
|
1659
1707
|
},
|
|
1660
1708
|
};
|
|
1661
|
-
updatedPart.webApplicationInfo = {
|
|
1662
|
-
id: "${{AAD_APP_CLIENT_ID}}",
|
|
1663
|
-
resource: "api://${{DOMAIN}}/${{AAD_APP_CLIENT_ID}}",
|
|
1664
|
-
};
|
|
1665
1709
|
}
|
|
1666
1710
|
}
|
|
1667
1711
|
updatedPart.composeExtensions = [composeExtension];
|
|
@@ -1699,12 +1743,17 @@ class ManifestUpdater {
|
|
|
1699
1743
|
command.parameters = command.parameters.filter((param) => param.isRequired);
|
|
1700
1744
|
}
|
|
1701
1745
|
else if (command.parameters && command.parameters.length > 0) {
|
|
1702
|
-
command.parameters
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1746
|
+
if (command.parameters.length > 1) {
|
|
1747
|
+
command.parameters = [command.parameters[0]];
|
|
1748
|
+
warnings.push({
|
|
1749
|
+
type: exports.WarningType.OperationOnlyContainsOptionalParam,
|
|
1750
|
+
content: Utils.format(ConstantString.OperationOnlyContainsOptionalParam, command.id),
|
|
1751
|
+
data: {
|
|
1752
|
+
commandId: command.id,
|
|
1753
|
+
parameterName: command.parameters[0].name,
|
|
1754
|
+
},
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1708
1757
|
}
|
|
1709
1758
|
if (adaptiveCardFolder) {
|
|
1710
1759
|
const adaptiveCardPath = path__default['default'].join(adaptiveCardFolder, command.id + ".json");
|
|
@@ -1782,7 +1831,13 @@ class SpecParser {
|
|
|
1782
1831
|
try {
|
|
1783
1832
|
try {
|
|
1784
1833
|
yield this.loadSpec();
|
|
1785
|
-
|
|
1834
|
+
if (!this.parser.$refs.circular) {
|
|
1835
|
+
yield this.parser.validate(this.spec);
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec));
|
|
1839
|
+
yield this.parser.validate(clonedUnResolveSpec);
|
|
1840
|
+
}
|
|
1786
1841
|
}
|
|
1787
1842
|
catch (e) {
|
|
1788
1843
|
return {
|
|
@@ -1874,19 +1929,36 @@ class SpecParser {
|
|
|
1874
1929
|
isValid: isValid,
|
|
1875
1930
|
reason: reason,
|
|
1876
1931
|
};
|
|
1877
|
-
|
|
1932
|
+
// Try best to parse server url and auth type
|
|
1933
|
+
try {
|
|
1878
1934
|
const serverObj = Utils.getServerObject(spec, method.toLocaleLowerCase(), path);
|
|
1879
1935
|
if (serverObj) {
|
|
1880
|
-
apiResult.server =
|
|
1936
|
+
apiResult.server = serverObj.url;
|
|
1881
1937
|
}
|
|
1938
|
+
}
|
|
1939
|
+
catch (err) {
|
|
1940
|
+
// ignore
|
|
1941
|
+
}
|
|
1942
|
+
try {
|
|
1882
1943
|
const authArray = Utils.getAuthArray(operation.security, spec);
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1944
|
+
if (authArray.length !== 0) {
|
|
1945
|
+
for (const auths of authArray) {
|
|
1946
|
+
if (auths.length === 1) {
|
|
1947
|
+
apiResult.auth = auths[0];
|
|
1948
|
+
break;
|
|
1949
|
+
}
|
|
1950
|
+
else {
|
|
1951
|
+
apiResult.auth = {
|
|
1952
|
+
authScheme: { type: "multipleAuth" },
|
|
1953
|
+
name: auths.map((auth) => auth.name).join(", "),
|
|
1954
|
+
};
|
|
1955
|
+
}
|
|
1887
1956
|
}
|
|
1888
1957
|
}
|
|
1889
1958
|
}
|
|
1959
|
+
catch (err) {
|
|
1960
|
+
// ignore
|
|
1961
|
+
}
|
|
1890
1962
|
result.APIs.push(apiResult);
|
|
1891
1963
|
}
|
|
1892
1964
|
result.allAPICount = result.APIs.length;
|
|
@@ -1919,7 +1991,8 @@ class SpecParser {
|
|
|
1919
1991
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1920
1992
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1921
1993
|
}
|
|
1922
|
-
const
|
|
1994
|
+
const clonedUnResolveSpec = JSON.parse(JSON.stringify(newUnResolvedSpec));
|
|
1995
|
+
const newSpec = (yield this.parser.dereference(clonedUnResolveSpec));
|
|
1923
1996
|
return [newUnResolvedSpec, newSpec];
|
|
1924
1997
|
}
|
|
1925
1998
|
catch (err) {
|
|
@@ -1996,10 +2069,11 @@ class SpecParser {
|
|
|
1996
2069
|
const operation = newSpec.paths[url][method];
|
|
1997
2070
|
try {
|
|
1998
2071
|
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
1999
|
-
const
|
|
2072
|
+
const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2073
|
+
const fileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
|
|
2000
2074
|
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
2001
2075
|
yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
2002
|
-
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${
|
|
2076
|
+
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
|
|
2003
2077
|
yield fs__default['default'].outputJSON(dataFileName, {}, { spaces: 2 });
|
|
2004
2078
|
}
|
|
2005
2079
|
catch (err) {
|
|
@@ -2033,7 +2107,8 @@ class SpecParser {
|
|
|
2033
2107
|
loadSpec() {
|
|
2034
2108
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2035
2109
|
if (!this.spec) {
|
|
2036
|
-
|
|
2110
|
+
const spec = (yield this.parser.parse(this.pathOrSpec));
|
|
2111
|
+
this.unResolveSpec = this.resolveEnvForSpec(spec);
|
|
2037
2112
|
// Convert swagger 2.0 to openapi 3.0
|
|
2038
2113
|
if (!this.unResolveSpec.openapi && this.unResolveSpec.swagger === "2.0") {
|
|
2039
2114
|
const specObj = yield converter__default['default'].convert(this.unResolveSpec, {});
|
|
@@ -2070,6 +2145,11 @@ class SpecParser {
|
|
|
2070
2145
|
yield fs__default['default'].outputFile(outputSpecPath, resultStr);
|
|
2071
2146
|
});
|
|
2072
2147
|
}
|
|
2148
|
+
resolveEnvForSpec(spec) {
|
|
2149
|
+
const specString = JSON.stringify(spec);
|
|
2150
|
+
const specResolved = Utils.resolveEnv(specString);
|
|
2151
|
+
return JSON.parse(specResolved);
|
|
2152
|
+
}
|
|
2073
2153
|
}
|
|
2074
2154
|
|
|
2075
2155
|
exports.AdaptiveCardGenerator = AdaptiveCardGenerator;
|