@microsoft/m365-spec-parser 0.2.6-alpha.d99d3c39d.0 → 0.2.6-alpha.dea29f186.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.
@@ -89,6 +89,7 @@ exports.ErrorType = void 0;
89
89
  ErrorType["UrlPathNotExist"] = "url-path-not-exist";
90
90
  ErrorType["Cancelled"] = "cancelled";
91
91
  ErrorType["Unknown"] = "unknown";
92
+ ErrorType["AddAuthFailed"] = "add-auth-failed";
92
93
  })(exports.ErrorType || (exports.ErrorType = {}));
93
94
  /**
94
95
  * An enum that represents the types of warnings that can occur during validation.
@@ -119,7 +120,12 @@ exports.ProjectType = void 0;
119
120
  ProjectType[ProjectType["Copilot"] = 0] = "Copilot";
120
121
  ProjectType[ProjectType["SME"] = 1] = "SME";
121
122
  ProjectType[ProjectType["TeamsAi"] = 2] = "TeamsAi";
122
- })(exports.ProjectType || (exports.ProjectType = {}));
123
+ })(exports.ProjectType || (exports.ProjectType = {}));
124
+ exports.AdaptiveCardUpdateStrategy = void 0;
125
+ (function (AdaptiveCardUpdateStrategy) {
126
+ AdaptiveCardUpdateStrategy[AdaptiveCardUpdateStrategy["CreateNew"] = 0] = "CreateNew";
127
+ AdaptiveCardUpdateStrategy[AdaptiveCardUpdateStrategy["KeepExisting"] = 1] = "KeepExisting";
128
+ })(exports.AdaptiveCardUpdateStrategy || (exports.AdaptiveCardUpdateStrategy = {}));
123
129
 
124
130
  // Copyright (c) Microsoft Corporation.
125
131
  class ConstantString {
@@ -145,8 +151,8 @@ ConstantString.AuthTypeIsNotSupported = "Unsupported authorization type in API '
145
151
  ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
146
152
  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.";
147
153
  ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
148
- ConstantString.WrappedCardVersion = "devPreview";
149
- ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
154
+ ConstantString.WrappedCardVersion = "1.0";
155
+ ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
150
156
  ConstantString.WrappedCardResponseLayout = "list";
151
157
  ConstantString.GetMethod = "get";
152
158
  ConstantString.PostMethod = "post";
@@ -620,6 +626,35 @@ class Utils {
620
626
  const serverUrl = operationServer || methodServer || rootServer;
621
627
  return serverUrl;
622
628
  }
629
+ static getAuthSchemaObject(authType, authParameters) {
630
+ switch (authType) {
631
+ case "oauth":
632
+ case "microsoft-entra":
633
+ return {
634
+ type: "oauth2",
635
+ flows: {
636
+ authorizationCode: {
637
+ authorizationUrl: authParameters.authorizationUrl,
638
+ tokenUrl: authParameters.tokenUrl,
639
+ refreshUrl: authParameters.refreshUrl,
640
+ scopes: authParameters.scopes,
641
+ },
642
+ },
643
+ };
644
+ case "api-key":
645
+ return {
646
+ type: "apiKey",
647
+ in: authParameters.in,
648
+ name: authParameters.name,
649
+ };
650
+ case "bearer-token":
651
+ default:
652
+ return {
653
+ type: "http",
654
+ scheme: "bearer",
655
+ };
656
+ }
657
+ }
623
658
  }
624
659
 
625
660
  // Copyright (c) Microsoft Corporation.
@@ -1765,8 +1800,8 @@ class ManifestUpdater {
1765
1800
  }
1766
1801
  const appName = this.removeEnvs(manifest.name.short);
1767
1802
  const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
1768
- const [apiPlugin, warnings] = yield ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authMap, options, existingPluginManifestInfo);
1769
- return [manifest, apiPlugin, warnings];
1803
+ const [apiPlugin, warnings, jsonDataSet] = yield ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, apiPluginFilePath, appName, authMap, options, existingPluginManifestInfo);
1804
+ return [manifest, apiPlugin, warnings, jsonDataSet];
1770
1805
  });
1771
1806
  }
1772
1807
  static updateManifestDescription(manifest, spec) {
@@ -1794,6 +1829,7 @@ class ManifestUpdater {
1794
1829
  const warnings = [];
1795
1830
  const functions = [];
1796
1831
  const functionNamesMap = {};
1832
+ const jsonDataSet = {};
1797
1833
  const conversationStarters = [];
1798
1834
  const paths = spec.paths;
1799
1835
  for (const pathUrl in paths) {
@@ -1825,11 +1861,17 @@ class ManifestUpdater {
1825
1861
  try {
1826
1862
  const { json } = Utils.getResponseJson(operationItem);
1827
1863
  if (json.schema) {
1828
- const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
1864
+ const [card, jsonPath, jsonData] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
1829
1865
  const responseSemantic = wrapResponseSemantics(card, jsonPath);
1830
1866
  funcObj.capabilities = {
1831
1867
  response_semantics: responseSemantic,
1832
1868
  };
1869
+ if (jsonPath === "$") {
1870
+ jsonDataSet[safeFunctionName] = jsonData;
1871
+ }
1872
+ else {
1873
+ jsonDataSet[safeFunctionName] = jsonData[jsonPath];
1874
+ }
1833
1875
  }
1834
1876
  }
1835
1877
  catch (err) {
@@ -2001,7 +2043,7 @@ class ManifestUpdater {
2001
2043
  .map((text) => ({ text }));
2002
2044
  }
2003
2045
  }
2004
- return [apiPlugin, warnings];
2046
+ return [apiPlugin, warnings, jsonDataSet];
2005
2047
  });
2006
2048
  }
2007
2049
  static updateManifest(manifestPath, outputSpecPath, spec, options, adaptiveCardFolder, authInfo) {
@@ -2245,6 +2287,41 @@ class SpecParser {
2245
2287
  throw new Error("Method not implemented.");
2246
2288
  });
2247
2289
  }
2290
+ addAuthScheme(authName, authType, authParameters, signal) {
2291
+ return __awaiter(this, void 0, void 0, function* () {
2292
+ try {
2293
+ yield this.loadSpec();
2294
+ const spec = this.spec;
2295
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
2296
+ throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
2297
+ }
2298
+ if (!spec.components) {
2299
+ spec.components = {};
2300
+ }
2301
+ if (!spec.components.securitySchemes) {
2302
+ spec.components.securitySchemes = {};
2303
+ }
2304
+ spec.components.securitySchemes[authName] = Utils.getAuthSchemaObject(authType, authParameters);
2305
+ const paths = spec.paths;
2306
+ for (const path in paths) {
2307
+ const methods = paths[path];
2308
+ for (const method in methods) {
2309
+ const operationId = methods[method].operationId;
2310
+ if (authParameters.apis.includes(operationId)) {
2311
+ methods[method].security = [{ [authName]: [] }];
2312
+ }
2313
+ }
2314
+ }
2315
+ yield this.saveFilterSpec(this.pathOrSpec, this.spec);
2316
+ }
2317
+ catch (err) {
2318
+ if (err instanceof SpecParserError) {
2319
+ throw err;
2320
+ }
2321
+ throw new SpecParserError(err.toString(), exports.ErrorType.AddAuthFailed);
2322
+ }
2323
+ });
2324
+ }
2248
2325
  /**
2249
2326
  * Lists all the OpenAPI operations in the specification file.
2250
2327
  * @returns A string array that represents the HTTP method and path of each operation, such as ['GET /pets/{petId}', 'GET /user/{userId}']
@@ -2272,6 +2349,8 @@ class SpecParser {
2272
2349
  operationId: operationId,
2273
2350
  isValid: isValid,
2274
2351
  reason: reason,
2352
+ description: operation.description,
2353
+ summary: operation.summary,
2275
2354
  };
2276
2355
  // Try best to parse server url and auth type
2277
2356
  try {
@@ -2360,7 +2439,7 @@ class SpecParser {
2360
2439
  * @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
2361
2440
  * @param pluginFilePath File path of the api plugin file to generate.
2362
2441
  */
2363
- generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, existingPluginFilePath, signal) {
2442
+ generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, existingPluginFilePath, signal, adaptiveCardUpdateStrategy) {
2364
2443
  return __awaiter(this, void 0, void 0, function* () {
2365
2444
  const result = {
2366
2445
  allSuccess: true,
@@ -2406,7 +2485,8 @@ class SpecParser {
2406
2485
  }
2407
2486
  : undefined;
2408
2487
  const authMap = Utils.getAuthMap(newSpec);
2409
- const [updatedManifest, apiPlugin, warnings] = yield ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authMap, existingPluginManifestInfo);
2488
+ const [updatedManifest, apiPlugin, warnings, jsonDataSet] = yield ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec, this.options, authMap, existingPluginManifestInfo);
2489
+ yield this.separateAdaptiveCards(apiPlugin, pluginFilePath, jsonDataSet, adaptiveCardUpdateStrategy);
2410
2490
  result.warnings.push(...warnings);
2411
2491
  yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 4 });
2412
2492
  yield fs__default['default'].outputJSON(pluginFilePath, apiPlugin, { spaces: 4 });
@@ -2499,6 +2579,7 @@ class SpecParser {
2499
2579
  const newSpecs = yield this.getFilteredSpecs(filter, signal);
2500
2580
  const newSpec = newSpecs[1];
2501
2581
  const apiPlugin = (yield fs__default['default'].readJSON(pluginFilePath));
2582
+ const jsonDataSet = {};
2502
2583
  const paths = newSpec.paths;
2503
2584
  for (const pathUrl in paths) {
2504
2585
  const pathItem = paths[pathUrl];
@@ -2516,7 +2597,13 @@ class SpecParser {
2516
2597
  }
2517
2598
  const { json } = Utils.getResponseJson(operationItem);
2518
2599
  if (json.schema) {
2519
- const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
2600
+ const [card, jsonPath, jsonData] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
2601
+ if (jsonPath === "$") {
2602
+ jsonDataSet[safeFunctionName] = jsonData;
2603
+ }
2604
+ else {
2605
+ jsonDataSet[safeFunctionName] = jsonData[jsonPath];
2606
+ }
2520
2607
  const responseSemantic = wrapResponseSemantics(card, jsonPath);
2521
2608
  apiPlugin.functions.find((func) => func.name === safeFunctionName).capabilities = {
2522
2609
  response_semantics: responseSemantic,
@@ -2531,9 +2618,47 @@ class SpecParser {
2531
2618
  }
2532
2619
  }
2533
2620
  }
2621
+ yield this.separateAdaptiveCards(apiPlugin, pluginFilePath, jsonDataSet);
2534
2622
  yield fs__default['default'].outputJSON(pluginFilePath, apiPlugin, { spaces: 4 });
2535
2623
  });
2536
2624
  }
2625
+ separateAdaptiveCards(apiPlugin, pluginFilePath, jsonDataSet = {}, adaptiveCardUpdateStrategy) {
2626
+ var _a, _b;
2627
+ return __awaiter(this, void 0, void 0, function* () {
2628
+ const functions = apiPlugin.functions;
2629
+ if (!adaptiveCardUpdateStrategy) {
2630
+ adaptiveCardUpdateStrategy = exports.AdaptiveCardUpdateStrategy.CreateNew;
2631
+ }
2632
+ if (functions) {
2633
+ const adaptiveCardFolder = path__default['default'].join(path__default['default'].dirname(pluginFilePath), "adaptiveCards");
2634
+ for (const func of functions) {
2635
+ if ((_a = func.capabilities) === null || _a === void 0 ? void 0 : _a.response_semantics) {
2636
+ const responseSemantic = func.capabilities.response_semantics;
2637
+ const card = responseSemantic.static_template;
2638
+ if (card && Object.keys(card).length !== 0) {
2639
+ let cardName = func.name;
2640
+ if (adaptiveCardUpdateStrategy === exports.AdaptiveCardUpdateStrategy.CreateNew) {
2641
+ cardName = this.findUniqueCardName(func.name, adaptiveCardFolder);
2642
+ }
2643
+ else {
2644
+ if (adaptiveCardUpdateStrategy === exports.AdaptiveCardUpdateStrategy.KeepExisting &&
2645
+ fs__default['default'].existsSync(path__default['default'].join(adaptiveCardFolder, `${cardName}.json`))) {
2646
+ responseSemantic.static_template = { file: `adaptiveCards/${cardName}.json` };
2647
+ continue;
2648
+ }
2649
+ }
2650
+ const cardPath = path__default['default'].join(adaptiveCardFolder, `${cardName}.json`);
2651
+ const dataPath = path__default['default'].join(adaptiveCardFolder, `${cardName}.data.json`);
2652
+ responseSemantic.static_template = { file: `adaptiveCards/${cardName}.json` };
2653
+ yield fs__default['default'].outputJSON(cardPath, card, { spaces: 4 });
2654
+ const data = (_b = jsonDataSet[cardName]) !== null && _b !== void 0 ? _b : {};
2655
+ yield fs__default['default'].outputJSON(dataPath, data, { spaces: 4 });
2656
+ }
2657
+ }
2658
+ }
2659
+ }
2660
+ });
2661
+ }
2537
2662
  loadSpec() {
2538
2663
  return __awaiter(this, void 0, void 0, function* () {
2539
2664
  if (!this.spec) {
@@ -2580,6 +2705,18 @@ class SpecParser {
2580
2705
  const specResolved = Utils.resolveEnv(specString);
2581
2706
  return JSON.parse(specResolved);
2582
2707
  }
2708
+ findUniqueCardName(defaultName, cardFolder) {
2709
+ let cardName = defaultName;
2710
+ let counter = 1;
2711
+ while (true) {
2712
+ if (!fs__default['default'].existsSync(path__default['default'].join(cardFolder, cardName + ".json"))) {
2713
+ break;
2714
+ }
2715
+ cardName = `${defaultName}${counter}`;
2716
+ counter++;
2717
+ }
2718
+ return cardName;
2719
+ }
2583
2720
  }
2584
2721
 
2585
2722
  exports.AdaptiveCardGenerator = AdaptiveCardGenerator;