@microsoft/m365-spec-parser 0.1.1-alpha.78701ec6a.0 → 0.1.1-alpha.8d8f5a0bb.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 +234 -18
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +268 -55
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +238 -18
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +274 -54
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/index.browser.d.ts +2 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/interfaces.d.ts +2 -0
- package/dist/src/manifestUpdater.d.ts +6 -2
- package/dist/src/specFilter.d.ts +1 -1
- package/dist/src/specParser.browser.d.ts +15 -1
- package/dist/src/specParser.d.ts +15 -1
- package/dist/src/utils.d.ts +7 -6
- package/package.json +4 -4
package/dist/index.node.cjs.js
CHANGED
|
@@ -69,6 +69,7 @@ exports.ErrorType = void 0;
|
|
|
69
69
|
ErrorType["GenerateAdaptiveCardFailed"] = "generate-adaptive-card-failed";
|
|
70
70
|
ErrorType["GenerateFailed"] = "generate-failed";
|
|
71
71
|
ErrorType["ValidateFailed"] = "validate-failed";
|
|
72
|
+
ErrorType["GetSpecFailed"] = "get-spec-failed";
|
|
72
73
|
ErrorType["Cancelled"] = "cancelled";
|
|
73
74
|
ErrorType["Unknown"] = "unknown";
|
|
74
75
|
})(exports.ErrorType || (exports.ErrorType = {}));
|
|
@@ -111,6 +112,7 @@ ConstantString.OperationOnlyContainsOptionalParam = "Operation %s contains multi
|
|
|
111
112
|
ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converted to OpenAPI 3.0.";
|
|
112
113
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
113
114
|
ConstantString.MultipleAPIKeyNotSupported = "Multiple API keys are not supported. Please make sure that all selected APIs use the same API key.";
|
|
115
|
+
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
114
116
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
115
117
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
116
118
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
@@ -193,7 +195,18 @@ class SpecParserError extends Error {
|
|
|
193
195
|
|
|
194
196
|
// Copyright (c) Microsoft Corporation.
|
|
195
197
|
class Utils {
|
|
196
|
-
static
|
|
198
|
+
static hasNestedObjectInSchema(schema) {
|
|
199
|
+
if (schema.type === "object") {
|
|
200
|
+
for (const property in schema.properties) {
|
|
201
|
+
const nestedSchema = schema.properties[property];
|
|
202
|
+
if (nestedSchema.type === "object") {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
static checkParameters(paramObject, isCopilot) {
|
|
197
210
|
const paramResult = {
|
|
198
211
|
requiredNum: 0,
|
|
199
212
|
optionalNum: 0,
|
|
@@ -205,7 +218,20 @@ class Utils {
|
|
|
205
218
|
for (let i = 0; i < paramObject.length; i++) {
|
|
206
219
|
const param = paramObject[i];
|
|
207
220
|
const schema = param.schema;
|
|
221
|
+
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
222
|
+
paramResult.isValid = false;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
208
225
|
const isRequiredWithoutDefault = param.required && schema.default === undefined;
|
|
226
|
+
if (isCopilot) {
|
|
227
|
+
if (isRequiredWithoutDefault) {
|
|
228
|
+
paramResult.requiredNum = paramResult.requiredNum + 1;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
232
|
+
}
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
209
235
|
if (param.in === "header" || param.in === "cookie") {
|
|
210
236
|
if (isRequiredWithoutDefault) {
|
|
211
237
|
paramResult.isValid = false;
|
|
@@ -232,7 +258,7 @@ class Utils {
|
|
|
232
258
|
}
|
|
233
259
|
return paramResult;
|
|
234
260
|
}
|
|
235
|
-
static checkPostBody(schema, isRequired = false) {
|
|
261
|
+
static checkPostBody(schema, isRequired = false, isCopilot = false) {
|
|
236
262
|
var _a;
|
|
237
263
|
const paramResult = {
|
|
238
264
|
requiredNum: 0,
|
|
@@ -243,6 +269,10 @@ class Utils {
|
|
|
243
269
|
return paramResult;
|
|
244
270
|
}
|
|
245
271
|
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
272
|
+
if (isCopilot && this.hasNestedObjectInSchema(schema)) {
|
|
273
|
+
paramResult.isValid = false;
|
|
274
|
+
return paramResult;
|
|
275
|
+
}
|
|
246
276
|
if (schema.type === "string" ||
|
|
247
277
|
schema.type === "integer" ||
|
|
248
278
|
schema.type === "boolean" ||
|
|
@@ -261,14 +291,14 @@ class Utils {
|
|
|
261
291
|
if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
|
|
262
292
|
isRequired = true;
|
|
263
293
|
}
|
|
264
|
-
const result = Utils.checkPostBody(properties[property], isRequired);
|
|
294
|
+
const result = Utils.checkPostBody(properties[property], isRequired, isCopilot);
|
|
265
295
|
paramResult.requiredNum += result.requiredNum;
|
|
266
296
|
paramResult.optionalNum += result.optionalNum;
|
|
267
297
|
paramResult.isValid = paramResult.isValid && result.isValid;
|
|
268
298
|
}
|
|
269
299
|
}
|
|
270
300
|
else {
|
|
271
|
-
if (isRequiredWithoutDefault) {
|
|
301
|
+
if (isRequiredWithoutDefault && !isCopilot) {
|
|
272
302
|
paramResult.isValid = false;
|
|
273
303
|
}
|
|
274
304
|
}
|
|
@@ -288,7 +318,7 @@ class Utils {
|
|
|
288
318
|
* 5. response body should be “application/json” and not empty, and response code should be 20X
|
|
289
319
|
* 6. only support request body with “application/json” content type
|
|
290
320
|
*/
|
|
291
|
-
static isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
|
|
321
|
+
static isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot) {
|
|
292
322
|
const pathObj = spec.paths[path];
|
|
293
323
|
method = method.toLocaleLowerCase();
|
|
294
324
|
if (pathObj) {
|
|
@@ -321,15 +351,22 @@ class Utils {
|
|
|
321
351
|
};
|
|
322
352
|
if (requestJsonBody) {
|
|
323
353
|
const requestBodySchema = requestJsonBody.schema;
|
|
324
|
-
|
|
354
|
+
if (isCopilot && requestBodySchema.type !== "object") {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
|
|
325
358
|
}
|
|
326
359
|
if (!requestBodyParamResult.isValid) {
|
|
327
360
|
return false;
|
|
328
361
|
}
|
|
329
|
-
const paramResult = Utils.checkParameters(paramObject);
|
|
362
|
+
const paramResult = Utils.checkParameters(paramObject, isCopilot);
|
|
330
363
|
if (!paramResult.isValid) {
|
|
331
364
|
return false;
|
|
332
365
|
}
|
|
366
|
+
// Copilot support arbitrary parameters
|
|
367
|
+
if (isCopilot) {
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
333
370
|
if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
|
|
334
371
|
if (allowMultipleParameters &&
|
|
335
372
|
requestBodyParamResult.requiredNum + paramResult.requiredNum <= 5) {
|
|
@@ -500,7 +537,7 @@ class Utils {
|
|
|
500
537
|
}
|
|
501
538
|
return errors;
|
|
502
539
|
}
|
|
503
|
-
static validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
|
|
540
|
+
static validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot) {
|
|
504
541
|
const errors = [];
|
|
505
542
|
let hasTopLevelServers = false;
|
|
506
543
|
let hasPathLevelServers = false;
|
|
@@ -521,7 +558,7 @@ class Utils {
|
|
|
521
558
|
}
|
|
522
559
|
for (const method in methods) {
|
|
523
560
|
const operationObject = methods[method];
|
|
524
|
-
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
|
|
561
|
+
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot)) {
|
|
525
562
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
526
563
|
hasOperationLevelServers = true;
|
|
527
564
|
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
@@ -671,14 +708,14 @@ class Utils {
|
|
|
671
708
|
}
|
|
672
709
|
return [command, warning];
|
|
673
710
|
}
|
|
674
|
-
static listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
|
|
711
|
+
static listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot) {
|
|
675
712
|
const paths = spec.paths;
|
|
676
713
|
const result = {};
|
|
677
714
|
for (const path in paths) {
|
|
678
715
|
const methods = paths[path];
|
|
679
716
|
for (const method in methods) {
|
|
680
717
|
// For developer preview, only support GET operation with only 1 parameter without auth
|
|
681
|
-
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
|
|
718
|
+
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot)) {
|
|
682
719
|
const operationObject = methods[method];
|
|
683
720
|
result[`${method.toUpperCase()} ${path}`] = operationObject;
|
|
684
721
|
}
|
|
@@ -686,7 +723,7 @@ class Utils {
|
|
|
686
723
|
}
|
|
687
724
|
return result;
|
|
688
725
|
}
|
|
689
|
-
static validateSpec(spec, parser, isSwaggerFile, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
|
|
726
|
+
static validateSpec(spec, parser, isSwaggerFile, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot) {
|
|
690
727
|
const errors = [];
|
|
691
728
|
const warnings = [];
|
|
692
729
|
if (isSwaggerFile) {
|
|
@@ -696,7 +733,7 @@ class Utils {
|
|
|
696
733
|
});
|
|
697
734
|
}
|
|
698
735
|
// Server validation
|
|
699
|
-
const serverErrors = Utils.validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2);
|
|
736
|
+
const serverErrors = Utils.validateServer(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot);
|
|
700
737
|
errors.push(...serverErrors);
|
|
701
738
|
// Remote reference not supported
|
|
702
739
|
const refPaths = parser.$refs.paths();
|
|
@@ -709,7 +746,7 @@ class Utils {
|
|
|
709
746
|
});
|
|
710
747
|
}
|
|
711
748
|
// No supported API
|
|
712
|
-
const apiMap = Utils.listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2);
|
|
749
|
+
const apiMap = Utils.listSupportedAPIs(spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot);
|
|
713
750
|
if (Object.keys(apiMap).length === 0) {
|
|
714
751
|
errors.push({
|
|
715
752
|
type: exports.ErrorType.NoSupportedApi,
|
|
@@ -765,14 +802,14 @@ class Utils {
|
|
|
765
802
|
|
|
766
803
|
// Copyright (c) Microsoft Corporation.
|
|
767
804
|
class SpecFilter {
|
|
768
|
-
static specFilter(filter, unResolveSpec, resolvedSpec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2) {
|
|
805
|
+
static specFilter(filter, unResolveSpec, resolvedSpec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot) {
|
|
769
806
|
try {
|
|
770
807
|
const newSpec = Object.assign({}, unResolveSpec);
|
|
771
808
|
const newPaths = {};
|
|
772
809
|
for (const filterItem of filter) {
|
|
773
810
|
const [method, path] = filterItem.split(" ");
|
|
774
811
|
const methodName = method.toLowerCase();
|
|
775
|
-
if (!Utils.isSupportedApi(methodName, path, resolvedSpec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2)) {
|
|
812
|
+
if (!Utils.isSupportedApi(methodName, path, resolvedSpec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot)) {
|
|
776
813
|
continue;
|
|
777
814
|
}
|
|
778
815
|
if (!newPaths[path]) {
|
|
@@ -798,8 +835,126 @@ class SpecFilter {
|
|
|
798
835
|
|
|
799
836
|
// Copyright (c) Microsoft Corporation.
|
|
800
837
|
class ManifestUpdater {
|
|
801
|
-
static
|
|
838
|
+
static updateManifestWithAiPlugin(manifestPath, outputSpecPath, apiPluginFilePath, spec) {
|
|
839
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
840
|
+
const manifest = yield fs__default['default'].readJSON(manifestPath);
|
|
841
|
+
const apiPluginRelativePath = ManifestUpdater.getRelativePath(manifestPath, apiPluginFilePath);
|
|
842
|
+
manifest.plugins = [
|
|
843
|
+
{
|
|
844
|
+
pluginFile: apiPluginRelativePath,
|
|
845
|
+
},
|
|
846
|
+
];
|
|
847
|
+
ManifestUpdater.updateManifestDescription(manifest, spec);
|
|
848
|
+
const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
|
|
849
|
+
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath);
|
|
850
|
+
return [manifest, apiPlugin];
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
static updateManifestDescription(manifest, spec) {
|
|
802
854
|
var _a, _b;
|
|
855
|
+
manifest.description = {
|
|
856
|
+
short: spec.info.title.slice(0, ConstantString.ShortDescriptionMaxLens),
|
|
857
|
+
full: (_b = ((_a = spec.info.description) !== null && _a !== void 0 ? _a : manifest.description.full)) === null || _b === void 0 ? void 0 : _b.slice(0, ConstantString.FullDescriptionMaxLens),
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
static mapOpenAPISchemaToFuncParam(schema, method, pathUrl) {
|
|
861
|
+
let parameter;
|
|
862
|
+
if (schema.type === "string" ||
|
|
863
|
+
schema.type === "boolean" ||
|
|
864
|
+
schema.type === "integer" ||
|
|
865
|
+
schema.type === "number" ||
|
|
866
|
+
schema.type === "array") {
|
|
867
|
+
parameter = schema;
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(schema)), exports.ErrorType.UpdateManifestFailed);
|
|
871
|
+
}
|
|
872
|
+
return parameter;
|
|
873
|
+
}
|
|
874
|
+
static generatePluginManifestSchema(spec, specRelativePath) {
|
|
875
|
+
var _a, _b, _c;
|
|
876
|
+
const functions = [];
|
|
877
|
+
const functionNames = [];
|
|
878
|
+
const paths = spec.paths;
|
|
879
|
+
for (const pathUrl in paths) {
|
|
880
|
+
const pathItem = paths[pathUrl];
|
|
881
|
+
if (pathItem) {
|
|
882
|
+
const operations = pathItem;
|
|
883
|
+
for (const method in operations) {
|
|
884
|
+
if (ConstantString.AllOperationMethods.includes(method)) {
|
|
885
|
+
const operationItem = operations[method];
|
|
886
|
+
if (operationItem) {
|
|
887
|
+
const operationId = operationItem.operationId;
|
|
888
|
+
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
889
|
+
const paramObject = operationItem.parameters;
|
|
890
|
+
const requestBody = operationItem.requestBody;
|
|
891
|
+
const parameters = {
|
|
892
|
+
type: "object",
|
|
893
|
+
properties: {},
|
|
894
|
+
required: [],
|
|
895
|
+
};
|
|
896
|
+
if (paramObject) {
|
|
897
|
+
for (let i = 0; i < paramObject.length; i++) {
|
|
898
|
+
const param = paramObject[i];
|
|
899
|
+
const schema = param.schema;
|
|
900
|
+
parameters.properties[param.name] = ManifestUpdater.mapOpenAPISchemaToFuncParam(schema, method, pathUrl);
|
|
901
|
+
if (param.required) {
|
|
902
|
+
parameters.required.push(param.name);
|
|
903
|
+
}
|
|
904
|
+
if (!parameters.properties[param.name].description) {
|
|
905
|
+
parameters.properties[param.name].description = (_b = param.description) !== null && _b !== void 0 ? _b : "";
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
if (requestBody) {
|
|
910
|
+
const requestJsonBody = requestBody.content["application/json"];
|
|
911
|
+
const requestBodySchema = requestJsonBody.schema;
|
|
912
|
+
if (requestBodySchema.type === "object") {
|
|
913
|
+
if (requestBodySchema.required) {
|
|
914
|
+
parameters.required.push(...requestBodySchema.required);
|
|
915
|
+
}
|
|
916
|
+
for (const property in requestBodySchema.properties) {
|
|
917
|
+
const schema = requestBodySchema.properties[property];
|
|
918
|
+
parameters.properties[property] = ManifestUpdater.mapOpenAPISchemaToFuncParam(schema, method, pathUrl);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
throw new SpecParserError(Utils.format(ConstantString.UnsupportedSchema, method, pathUrl, JSON.stringify(requestBodySchema)), exports.ErrorType.UpdateManifestFailed);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
const funcObj = {
|
|
926
|
+
name: operationId,
|
|
927
|
+
description: description,
|
|
928
|
+
parameters: parameters,
|
|
929
|
+
};
|
|
930
|
+
functions.push(funcObj);
|
|
931
|
+
functionNames.push(operationId);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
const apiPlugin = {
|
|
938
|
+
schema_version: "v2",
|
|
939
|
+
name_for_human: spec.info.title,
|
|
940
|
+
description_for_human: (_c = spec.info.description) !== null && _c !== void 0 ? _c : "<Please add description of the plugin>",
|
|
941
|
+
functions: functions,
|
|
942
|
+
runtimes: [
|
|
943
|
+
{
|
|
944
|
+
type: "OpenApi",
|
|
945
|
+
auth: {
|
|
946
|
+
type: "none", // TODO, support auth in the future
|
|
947
|
+
},
|
|
948
|
+
spec: {
|
|
949
|
+
url: specRelativePath,
|
|
950
|
+
},
|
|
951
|
+
run_for_functions: functionNames,
|
|
952
|
+
},
|
|
953
|
+
],
|
|
954
|
+
};
|
|
955
|
+
return apiPlugin;
|
|
956
|
+
}
|
|
957
|
+
static updateManifest(manifestPath, outputSpecPath, adaptiveCardFolder, spec, allowMultipleParameters, auth, isMe) {
|
|
803
958
|
return __awaiter(this, void 0, void 0, function* () {
|
|
804
959
|
try {
|
|
805
960
|
const originalManifest = yield fs__default['default'].readJSON(manifestPath);
|
|
@@ -834,11 +989,9 @@ class ManifestUpdater {
|
|
|
834
989
|
};
|
|
835
990
|
}
|
|
836
991
|
}
|
|
837
|
-
updatedPart.description =
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
};
|
|
841
|
-
updatedPart.composeExtensions = [composeExtension];
|
|
992
|
+
updatedPart.description = originalManifest.description;
|
|
993
|
+
ManifestUpdater.updateManifestDescription(updatedPart, spec);
|
|
994
|
+
updatedPart.composeExtensions = isMe === undefined || isMe === true ? [composeExtension] : [];
|
|
842
995
|
const updatedManifest = Object.assign(Object.assign({}, originalManifest), updatedPart);
|
|
843
996
|
return [updatedManifest, warnings];
|
|
844
997
|
}
|
|
@@ -1152,6 +1305,7 @@ class SpecParser {
|
|
|
1152
1305
|
allowAPIKeyAuth: false,
|
|
1153
1306
|
allowMultipleParameters: false,
|
|
1154
1307
|
allowOauth2: false,
|
|
1308
|
+
isCopilot: false,
|
|
1155
1309
|
};
|
|
1156
1310
|
this.pathOrSpec = pathOrDoc;
|
|
1157
1311
|
this.parser = new SwaggerParser__default['default']();
|
|
@@ -1185,7 +1339,7 @@ class SpecParser {
|
|
|
1185
1339
|
],
|
|
1186
1340
|
};
|
|
1187
1341
|
}
|
|
1188
|
-
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2);
|
|
1342
|
+
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2, this.options.isCopilot);
|
|
1189
1343
|
}
|
|
1190
1344
|
catch (err) {
|
|
1191
1345
|
throw new SpecParserError(err.toString(), exports.ErrorType.ValidateFailed);
|
|
@@ -1252,32 +1406,94 @@ class SpecParser {
|
|
|
1252
1406
|
}
|
|
1253
1407
|
});
|
|
1254
1408
|
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Generate specs according to the filters.
|
|
1411
|
+
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1412
|
+
*/
|
|
1413
|
+
getFilteredSpecs(filter, signal) {
|
|
1414
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1415
|
+
try {
|
|
1416
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1417
|
+
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1418
|
+
}
|
|
1419
|
+
yield this.loadSpec();
|
|
1420
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1421
|
+
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1422
|
+
}
|
|
1423
|
+
const newUnResolvedSpec = SpecFilter.specFilter(filter, this.unResolveSpec, this.spec, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2, this.options.isCopilot);
|
|
1424
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1425
|
+
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1426
|
+
}
|
|
1427
|
+
const newSpec = (yield this.parser.dereference(newUnResolvedSpec));
|
|
1428
|
+
return [newUnResolvedSpec, newSpec];
|
|
1429
|
+
}
|
|
1430
|
+
catch (err) {
|
|
1431
|
+
if (err instanceof SpecParserError) {
|
|
1432
|
+
throw err;
|
|
1433
|
+
}
|
|
1434
|
+
throw new SpecParserError(err.toString(), exports.ErrorType.GetSpecFailed);
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1255
1438
|
/**
|
|
1256
1439
|
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
1257
1440
|
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
1258
1441
|
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1259
1442
|
* @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
|
|
1260
|
-
* @param
|
|
1443
|
+
* @param pluginFilePath File path of the api plugin file to generate.
|
|
1261
1444
|
*/
|
|
1262
|
-
|
|
1445
|
+
generateForCopilot(manifestPath, filter, outputSpecPath, pluginFilePath, signal) {
|
|
1263
1446
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1264
1447
|
const result = {
|
|
1265
1448
|
allSuccess: true,
|
|
1266
1449
|
warnings: [],
|
|
1267
1450
|
};
|
|
1268
1451
|
try {
|
|
1269
|
-
|
|
1270
|
-
|
|
1452
|
+
const newSpecs = yield this.getFilteredSpecs(filter, signal);
|
|
1453
|
+
const newUnResolvedSpec = newSpecs[0];
|
|
1454
|
+
const newSpec = newSpecs[1];
|
|
1455
|
+
let resultStr;
|
|
1456
|
+
if (outputSpecPath.endsWith(".yaml") || outputSpecPath.endsWith(".yml")) {
|
|
1457
|
+
resultStr = jsyaml__default['default'].dump(newUnResolvedSpec);
|
|
1271
1458
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1459
|
+
else {
|
|
1460
|
+
resultStr = JSON.stringify(newUnResolvedSpec, null, 2);
|
|
1275
1461
|
}
|
|
1276
|
-
|
|
1462
|
+
yield fs__default['default'].outputFile(outputSpecPath, resultStr);
|
|
1277
1463
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1278
1464
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1279
1465
|
}
|
|
1280
|
-
const
|
|
1466
|
+
const [updatedManifest, apiPlugin] = yield ManifestUpdater.updateManifestWithAiPlugin(manifestPath, outputSpecPath, pluginFilePath, newSpec);
|
|
1467
|
+
yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1468
|
+
yield fs__default['default'].outputJSON(pluginFilePath, apiPlugin, { spaces: 2 });
|
|
1469
|
+
}
|
|
1470
|
+
catch (err) {
|
|
1471
|
+
if (err instanceof SpecParserError) {
|
|
1472
|
+
throw err;
|
|
1473
|
+
}
|
|
1474
|
+
throw new SpecParserError(err.toString(), exports.ErrorType.GenerateFailed);
|
|
1475
|
+
}
|
|
1476
|
+
return result;
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file.
|
|
1481
|
+
* @param manifestPath A file path of the Teams app manifest file to update.
|
|
1482
|
+
* @param filter An array of strings that represent the filters to apply when generating the artifacts. If filter is empty, it would process nothing.
|
|
1483
|
+
* @param outputSpecPath File path of the new OpenAPI specification file to generate. If not specified or empty, no spec file will be generated.
|
|
1484
|
+
* @param adaptiveCardFolder Folder path where the Adaptive Card files will be generated. If not specified or empty, Adaptive Card files will not be generated.
|
|
1485
|
+
* @param isMe Boolean that indicates whether the project is an Messaging Extension. For Messaging Extension, composeExtensions will be added in Teams app manifest.
|
|
1486
|
+
*/
|
|
1487
|
+
generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal, isMe) {
|
|
1488
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1489
|
+
const result = {
|
|
1490
|
+
allSuccess: true,
|
|
1491
|
+
warnings: [],
|
|
1492
|
+
};
|
|
1493
|
+
try {
|
|
1494
|
+
const newSpecs = yield this.getFilteredSpecs(filter, signal);
|
|
1495
|
+
const newUnResolvedSpec = newSpecs[0];
|
|
1496
|
+
const newSpec = newSpecs[1];
|
|
1281
1497
|
const AuthSet = new Set();
|
|
1282
1498
|
let hasMultipleAPIKeyAuth = false;
|
|
1283
1499
|
for (const url in newSpec.paths) {
|
|
@@ -1304,26 +1520,29 @@ class SpecParser {
|
|
|
1304
1520
|
resultStr = JSON.stringify(newUnResolvedSpec, null, 2);
|
|
1305
1521
|
}
|
|
1306
1522
|
yield fs__default['default'].outputFile(outputSpecPath, resultStr);
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
const
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1523
|
+
if (isMe === undefined || isMe === true) {
|
|
1524
|
+
// Only generate adaptive card for Messaging Extension
|
|
1525
|
+
for (const url in newSpec.paths) {
|
|
1526
|
+
for (const method in newSpec.paths[url]) {
|
|
1527
|
+
// paths object may contain description/summary, so we need to check if it is a operation object
|
|
1528
|
+
if (method === ConstantString.PostMethod || method === ConstantString.GetMethod) {
|
|
1529
|
+
const operation = newSpec.paths[url][method];
|
|
1530
|
+
try {
|
|
1531
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
1532
|
+
const fileName = path__default['default'].join(adaptiveCardFolder, `${operation.operationId}.json`);
|
|
1533
|
+
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
1534
|
+
yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
1535
|
+
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${operation.operationId}.data.json`);
|
|
1536
|
+
yield fs__default['default'].outputJSON(dataFileName, {}, { spaces: 2 });
|
|
1537
|
+
}
|
|
1538
|
+
catch (err) {
|
|
1539
|
+
result.allSuccess = false;
|
|
1540
|
+
result.warnings.push({
|
|
1541
|
+
type: exports.WarningType.GenerateCardFailed,
|
|
1542
|
+
content: err.toString(),
|
|
1543
|
+
data: operation.operationId,
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1327
1546
|
}
|
|
1328
1547
|
}
|
|
1329
1548
|
}
|
|
@@ -1332,7 +1551,7 @@ class SpecParser {
|
|
|
1332
1551
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1333
1552
|
}
|
|
1334
1553
|
const auth = Array.from(AuthSet)[0];
|
|
1335
|
-
const [updatedManifest, warnings] = yield ManifestUpdater.updateManifest(manifestPath, outputSpecPath, adaptiveCardFolder, newSpec, this.options.allowMultipleParameters, auth);
|
|
1554
|
+
const [updatedManifest, warnings] = yield ManifestUpdater.updateManifest(manifestPath, outputSpecPath, adaptiveCardFolder, newSpec, this.options.allowMultipleParameters, auth, isMe);
|
|
1336
1555
|
yield fs__default['default'].outputJSON(manifestPath, updatedManifest, { spaces: 2 });
|
|
1337
1556
|
result.warnings.push(...warnings);
|
|
1338
1557
|
}
|
|
@@ -1364,12 +1583,13 @@ class SpecParser {
|
|
|
1364
1583
|
if (this.apiMap !== undefined) {
|
|
1365
1584
|
return this.apiMap;
|
|
1366
1585
|
}
|
|
1367
|
-
const result = Utils.listSupportedAPIs(spec, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2);
|
|
1586
|
+
const result = Utils.listSupportedAPIs(spec, this.options.allowMissingId, this.options.allowAPIKeyAuth, this.options.allowMultipleParameters, this.options.allowOauth2, this.options.isCopilot);
|
|
1368
1587
|
this.apiMap = result;
|
|
1369
1588
|
return result;
|
|
1370
1589
|
}
|
|
1371
1590
|
}
|
|
1372
1591
|
|
|
1592
|
+
exports.AdaptiveCardGenerator = AdaptiveCardGenerator;
|
|
1373
1593
|
exports.ConstantString = ConstantString;
|
|
1374
1594
|
exports.SpecParser = SpecParser;
|
|
1375
1595
|
exports.SpecParserError = SpecParserError;
|