@microsoft/m365-spec-parser 0.2.4-alpha.ad0d7aa1a.0 → 0.2.4-alpha.db2563b3b.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.
@@ -114,12 +114,7 @@ ConstantString.AdaptiveCardType = "AdaptiveCard";
114
114
  ConstantString.TextBlockType = "TextBlock";
115
115
  ConstantString.ImageType = "Image";
116
116
  ConstantString.ContainerType = "Container";
117
- ConstantString.RegistrationIdPostfix = {
118
- apiKey: "REGISTRATION_ID",
119
- oauth2: "CONFIGURATION_ID",
120
- http: "REGISTRATION_ID",
121
- openIdConnect: "REGISTRATION_ID",
122
- };
117
+ ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
123
118
  ConstantString.ResponseCodeFor20X = [
124
119
  "200",
125
120
  "201",
@@ -254,6 +249,20 @@ class Utils {
254
249
  result.sort((a, b) => a[0].name.localeCompare(b[0].name));
255
250
  return result;
256
251
  }
252
+ static getAuthMap(spec) {
253
+ const authMap = {};
254
+ for (const url in spec.paths) {
255
+ for (const method in spec.paths[url]) {
256
+ const operation = spec.paths[url][method];
257
+ const authArray = Utils.getAuthArray(operation.security, spec);
258
+ if (authArray && authArray.length > 0) {
259
+ const currentAuth = authArray[0][0];
260
+ authMap[operation.operationId] = currentAuth;
261
+ }
262
+ }
263
+ }
264
+ return authMap;
265
+ }
257
266
  static getAuthInfo(spec) {
258
267
  let authInfo = undefined;
259
268
  for (const url in spec.paths) {
@@ -1678,7 +1687,7 @@ function inferProperties(card) {
1678
1687
 
1679
1688
  // Copyright (c) Microsoft Corporation.
1680
1689
  class ManifestUpdater {
1681
- static async updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options, authInfo, existingPluginManifestInfo) {
1690
+ static async updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec, options, authMap, existingPluginManifestInfo) {
1682
1691
  const manifest = await fs.readJSON(manifestPath);
1683
1692
  const apiPluginRelativePath = ManifestUpdater.getRelativePath(manifestPath, apiPluginFilePath);
1684
1693
  const useCopilotExtensionsInSchema = await ManifestUtil.useCopilotExtensionsInSchema(manifest);
@@ -1708,7 +1717,7 @@ class ManifestUpdater {
1708
1717
  }
1709
1718
  const appName = this.removeEnvs(manifest.name.short);
1710
1719
  const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
1711
- const [apiPlugin, warnings] = await ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authInfo, options, existingPluginManifestInfo);
1720
+ const [apiPlugin, warnings] = await ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authMap, options, existingPluginManifestInfo);
1712
1721
  return [manifest, apiPlugin, warnings];
1713
1722
  }
1714
1723
  static updateManifestDescription(manifest, spec) {
@@ -1730,28 +1739,13 @@ class ManifestUpdater {
1730
1739
  throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(schema)), ErrorType.UpdateManifestFailed);
1731
1740
  }
1732
1741
  }
1733
- static async generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authInfo, options, existingPluginManifestInfo) {
1742
+ static async generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authMap, options, existingPluginManifestInfo) {
1734
1743
  var _a, _b, _c, _d;
1735
1744
  const warnings = [];
1736
1745
  const functions = [];
1737
- const functionNames = [];
1746
+ const functionNamesMap = {};
1738
1747
  const conversationStarters = [];
1739
1748
  const paths = spec.paths;
1740
- const pluginAuthObj = {
1741
- type: "None",
1742
- };
1743
- if (authInfo) {
1744
- if (Utils.isOAuthWithAuthCodeFlow(authInfo.authScheme)) {
1745
- pluginAuthObj.type = "OAuthPluginVault";
1746
- }
1747
- else if (Utils.isBearerTokenAuth(authInfo.authScheme)) {
1748
- pluginAuthObj.type = "ApiKeyPluginVault";
1749
- }
1750
- if (pluginAuthObj.type !== "None") {
1751
- const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
1752
- pluginAuthObj.reference_id = `\${{${safeRegistrationIdName}}}`;
1753
- }
1754
- }
1755
1749
  for (const pathUrl in paths) {
1756
1750
  const pathItem = paths[pathUrl];
1757
1751
  if (pathItem) {
@@ -1834,7 +1828,28 @@ class ManifestUpdater {
1834
1828
  }
1835
1829
  }
1836
1830
  functions.push(funcObj);
1837
- functionNames.push(safeFunctionName);
1831
+ const authInfo = authMap[operationId];
1832
+ let key = "None";
1833
+ let authName = "None";
1834
+ if (authInfo) {
1835
+ if (Utils.isOAuthWithAuthCodeFlow(authInfo.authScheme)) {
1836
+ key = "OAuthPluginVault";
1837
+ authName = authInfo.name;
1838
+ }
1839
+ else if (Utils.isBearerTokenAuth(authInfo.authScheme)) {
1840
+ key = "ApiKeyPluginVault";
1841
+ authName = authInfo.name;
1842
+ }
1843
+ }
1844
+ if (functionNamesMap[key]) {
1845
+ functionNamesMap[key].functionNames.push(safeFunctionName);
1846
+ }
1847
+ else {
1848
+ functionNamesMap[key] = {
1849
+ functionNames: [safeFunctionName],
1850
+ authName: authName,
1851
+ };
1852
+ }
1838
1853
  const conversationStarterStr = (summary !== null && summary !== void 0 ? summary : description).slice(0, ConstantString.ConversationStarterMaxLens);
1839
1854
  if (conversationStarterStr) {
1840
1855
  conversationStarters.push(conversationStarterStr);
@@ -1844,6 +1859,12 @@ class ManifestUpdater {
1844
1859
  }
1845
1860
  }
1846
1861
  }
1862
+ if (Object.keys(functionNamesMap).length === 0) {
1863
+ functionNamesMap["None"] = {
1864
+ functionNames: [],
1865
+ authName: "None",
1866
+ };
1867
+ }
1847
1868
  let apiPlugin;
1848
1869
  if (await fs.pathExists(apiPluginFilePath)) {
1849
1870
  apiPlugin = await fs.readJSON(apiPluginFilePath);
@@ -1879,24 +1900,35 @@ class ManifestUpdater {
1879
1900
  const relativePath = ManifestUpdater.getRelativePath(existingPluginManifestInfo.manifestPath, existingPluginManifestInfo.specPath);
1880
1901
  apiPlugin.runtimes = apiPlugin.runtimes.filter((runtime) => runtime.spec.url !== relativePath);
1881
1902
  }
1882
- const index = apiPlugin.runtimes.findIndex((runtime) => {
1883
- var _a, _b;
1884
- return runtime.spec.url === specRelativePath &&
1885
- runtime.type === "OpenApi" &&
1886
- ((_b = (_a = runtime.auth) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : "None") === pluginAuthObj.type;
1887
- });
1888
- if (index === -1) {
1889
- apiPlugin.runtimes.push({
1890
- type: "OpenApi",
1891
- auth: pluginAuthObj,
1892
- spec: {
1893
- url: specRelativePath,
1894
- },
1895
- run_for_functions: functionNames,
1903
+ for (const authType in functionNamesMap) {
1904
+ const pluginAuthObj = {
1905
+ type: authType,
1906
+ };
1907
+ const authName = functionNamesMap[authType].authName;
1908
+ if (pluginAuthObj.type !== "None") {
1909
+ const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authName}_${ConstantString.RegistrationIdPostfix}`);
1910
+ pluginAuthObj.reference_id = `\${{${safeRegistrationIdName}}}`;
1911
+ }
1912
+ const functionNamesInfo = functionNamesMap[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") === authType;
1896
1918
  });
1897
- }
1898
- else {
1899
- apiPlugin.runtimes[index].run_for_functions = functionNames;
1919
+ if (index === -1) {
1920
+ apiPlugin.runtimes.push({
1921
+ type: "OpenApi",
1922
+ auth: pluginAuthObj,
1923
+ spec: {
1924
+ url: specRelativePath,
1925
+ },
1926
+ run_for_functions: functionNamesInfo.functionNames,
1927
+ });
1928
+ }
1929
+ else {
1930
+ apiPlugin.runtimes[index].run_for_functions = functionNamesInfo.functionNames;
1931
+ }
1900
1932
  }
1901
1933
  if (!apiPlugin.name_for_human) {
1902
1934
  apiPlugin.name_for_human = appName;
@@ -1937,7 +1969,7 @@ class ManifestUpdater {
1937
1969
  };
1938
1970
  if (authInfo) {
1939
1971
  const auth = authInfo.authScheme;
1940
- const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
1972
+ const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix}`);
1941
1973
  if (Utils.isAPIKeyAuth(auth) || Utils.isBearerTokenAuth(auth)) {
1942
1974
  composeExtension.authorization = {
1943
1975
  authType: "apiSecretServiceAuth",
@@ -2264,13 +2296,21 @@ class SpecParser {
2264
2296
  const newSpecs = await this.getFilteredSpecs(filter, signal);
2265
2297
  const newUnResolvedSpec = newSpecs[0];
2266
2298
  const newSpec = newSpecs[1];
2267
- const authInfo = Utils.getAuthInfo(newSpec);
2268
2299
  const paths = newUnResolvedSpec.paths;
2269
2300
  for (const pathUrl in paths) {
2270
2301
  const operations = paths[pathUrl];
2271
2302
  for (const method in operations) {
2272
2303
  const operationItem = operations[method];
2273
2304
  const operationId = operationItem.operationId;
2305
+ const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
2306
+ if (containsSpecialCharacters) {
2307
+ operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
2308
+ result.warnings.push({
2309
+ type: WarningType.OperationIdContainsSpecialCharacters,
2310
+ content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
2311
+ data: operationId,
2312
+ });
2313
+ }
2274
2314
  const authArray = Utils.getAuthArray(operationItem.security, newSpec);
2275
2315
  if (Utils.isNotSupportedAuth(authArray)) {
2276
2316
  result.warnings.push({
@@ -2279,16 +2319,6 @@ class SpecParser {
2279
2319
  data: operationId,
2280
2320
  });
2281
2321
  }
2282
- const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
2283
- if (!containsSpecialCharacters) {
2284
- continue;
2285
- }
2286
- operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
2287
- result.warnings.push({
2288
- type: WarningType.OperationIdContainsSpecialCharacters,
2289
- content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
2290
- data: operationId,
2291
- });
2292
2322
  }
2293
2323
  }
2294
2324
  await this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
@@ -2301,7 +2331,8 @@ class SpecParser {
2301
2331
  specPath: this.pathOrSpec,
2302
2332
  }
2303
2333
  : undefined;
2304
- const [updatedManifest, apiPlugin, warnings] = await ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authInfo, existingPluginManifestInfo);
2334
+ const authMap = Utils.getAuthMap(newSpec);
2335
+ const [updatedManifest, apiPlugin, warnings] = await ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authMap, existingPluginManifestInfo);
2305
2336
  result.warnings.push(...warnings);
2306
2337
  await fs.outputJSON(manifestPath, updatedManifest, { spaces: 4 });
2307
2338
  await fs.outputJSON(pluginFilePath, apiPlugin, { spaces: 4 });