@smartbear/mcp 0.26.0 → 0.27.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/README.md +10 -2
- package/dist/package.json.js +1 -1
- package/dist/qmetry/client/api/client-api.js +13 -1
- package/dist/qmetry/client/auto-resolve.js +23 -1
- package/dist/qmetry/client/handlers.js +10 -2
- package/dist/qmetry/client/issues.js +113 -1
- package/dist/qmetry/client/testcase.js +82 -1
- package/dist/qmetry/client/testsuite.js +20 -8
- package/dist/qmetry/client/tools/index.js +5 -2
- package/dist/qmetry/client/tools/issue-tools.js +163 -1
- package/dist/qmetry/client/tools/testcase-tools.js +81 -7
- package/dist/qmetry/client/tools/testsuite-tools.js +291 -26
- package/dist/qmetry/client/tools/udf-tools.js +294 -0
- package/dist/qmetry/client/udf.js +376 -0
- package/dist/qmetry/client.js +30 -3
- package/dist/qmetry/config/constants.js +63 -2
- package/dist/qmetry/config/rest-endpoints.js +7 -1
- package/dist/qmetry/types/common.js +85 -47
- package/dist/qmetry/types/issues.js +5 -0
- package/dist/qmetry/types/udf.js +77 -0
- package/dist/swagger/client/api.js +421 -8
- package/dist/swagger/client/configuration.js +9 -0
- package/dist/swagger/client/functional-testing-api.js +38 -2
- package/dist/swagger/client/functional-testing-tools.js +18 -0
- package/dist/swagger/client/functional-testing-types.js +11 -0
- package/dist/swagger/client/portal-types.js +35 -3
- package/dist/swagger/client/portal-utils.js +50 -0
- package/dist/swagger/client/registry-types.js +8 -0
- package/dist/swagger/client/tools.js +25 -4
- package/dist/swagger/client/utils.js +37 -0
- package/dist/swagger/client.js +37 -5
- package/package.json +1 -1
|
@@ -20,7 +20,7 @@ const GetProductSectionsArgsSchema = z.object({
|
|
|
20
20
|
"Page number for paginated results - specifies which page of results to retrieve (default is 1)"
|
|
21
21
|
),
|
|
22
22
|
size: z.number().optional().describe(
|
|
23
|
-
"Number of items per page for pagination - controls how many results are returned per page (default is
|
|
23
|
+
"Number of items per page for pagination - controls how many results are returned per page (default is 10)"
|
|
24
24
|
)
|
|
25
25
|
});
|
|
26
26
|
const GetTableOfContentsArgsSchema = z.object({
|
|
@@ -176,7 +176,15 @@ const UpdateProductArgsSchema = ProductArgsSchema.extend({
|
|
|
176
176
|
"Change navigation visibility - true hides from portal landing page menus while keeping the product accessible via direct links"
|
|
177
177
|
)
|
|
178
178
|
});
|
|
179
|
+
const ResolveOrganizationPortalArgsSchema = z.object({
|
|
180
|
+
organizationId: z.string().uuid().describe(
|
|
181
|
+
"Swagger organization UUID - the organization to resolve portal details for"
|
|
182
|
+
)
|
|
183
|
+
});
|
|
179
184
|
const PublishProductArgsSchema = ProductArgsSchema.extend({
|
|
185
|
+
tableOfContentsId: z.string().optional().describe(
|
|
186
|
+
"Optional table of contents UUID, or identifier in the format 'portal-subdomain:product-slug:section-slug:table-of-contents-slug'. When provided, publishPortalProduct uses it to resolve the published URL path for the returned preview/live link."
|
|
187
|
+
),
|
|
180
188
|
preview: z.boolean().optional().default(false).describe(
|
|
181
189
|
"Whether to publish as preview (true) or live (false). Preview allows testing before going live. Defaults to false (live publication)"
|
|
182
190
|
)
|
|
@@ -190,10 +198,10 @@ const UpdateDocumentArgsSchema = z.object({
|
|
|
190
198
|
"The document content to update (HTML or Markdown based on document type)"
|
|
191
199
|
),
|
|
192
200
|
type: z.enum(["html", "markdown"]).optional().describe(
|
|
193
|
-
"Content type
|
|
201
|
+
"Content type of the document. Note: documents with type 'html' and source 'internal' cannot be edited via API — only 'html' + 'external' and all 'markdown' combinations are supported."
|
|
194
202
|
),
|
|
195
203
|
source: z.enum(["internal", "external"]).optional().describe(
|
|
196
|
-
"
|
|
204
|
+
"Where the document content is managed. 'internal': editable in both portal UI and API. 'external': editable via API only. Note: 'html' + 'internal' documents cannot be updated via API."
|
|
197
205
|
)
|
|
198
206
|
});
|
|
199
207
|
const DeleteTableOfContentsArgsSchema = z.object({
|
|
@@ -204,7 +212,30 @@ const DeleteTableOfContentsArgsSchema = z.object({
|
|
|
204
212
|
"Flag to include all the nested tables of contents (default: false)"
|
|
205
213
|
)
|
|
206
214
|
});
|
|
215
|
+
const CreateDocumentationPageArgsSchema = z.object({
|
|
216
|
+
portalId: z.string().describe("Portal UUID or subdomain - unique identifier for the portal"),
|
|
217
|
+
productId: z.string().uuid().describe("Product UUID - unique identifier for the product"),
|
|
218
|
+
pageTitle: z.string().describe(
|
|
219
|
+
"Title of the documentation page - will be displayed in navigation (3-255 characters, used to generate the page slug)"
|
|
220
|
+
),
|
|
221
|
+
pageContent: z.string().optional().describe(
|
|
222
|
+
"Content of the documentation page. Provide HTML when contentType is 'html', Markdown when contentType is 'markdown'."
|
|
223
|
+
),
|
|
224
|
+
contentType: z.enum(["markdown", "html"]).default("markdown").optional().describe(
|
|
225
|
+
"Content type of the documentation page. 'markdown' works with both 'internal' and 'external' source. 'html' only works with 'external' source — html + internal is not supported by the API and will return an error."
|
|
226
|
+
),
|
|
227
|
+
source: z.enum(["internal", "external"]).default("internal").optional().describe(
|
|
228
|
+
"Where the document content is managed. 'internal': editable in both the portal UI and via API. 'external': editable via API only, not in the portal UI. Constraint: 'html' content type only supports 'external' source."
|
|
229
|
+
),
|
|
230
|
+
order: z.number().optional().default(0).describe(
|
|
231
|
+
"Order position of the documentation page within its parent section or item"
|
|
232
|
+
),
|
|
233
|
+
parentId: z.string().nullable().optional().default(null).describe(
|
|
234
|
+
"Parent table of contents item ID - null for top-level pages, or ID of parent item for nested structure"
|
|
235
|
+
)
|
|
236
|
+
});
|
|
207
237
|
export {
|
|
238
|
+
CreateDocumentationPageArgsSchema,
|
|
208
239
|
CreatePortalArgsSchema,
|
|
209
240
|
CreateProductArgsSchema,
|
|
210
241
|
CreateTableOfContentsArgsSchema,
|
|
@@ -215,6 +246,7 @@ export {
|
|
|
215
246
|
PortalArgsSchema,
|
|
216
247
|
ProductArgsSchema,
|
|
217
248
|
PublishProductArgsSchema,
|
|
249
|
+
ResolveOrganizationPortalArgsSchema,
|
|
218
250
|
UpdateDocumentArgsSchema,
|
|
219
251
|
UpdatePortalArgsSchema,
|
|
220
252
|
UpdateProductArgsSchema
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ToolError } from "../../common/tools.js";
|
|
2
|
+
const SUBDOMAIN_MIN_LENGTH = 3;
|
|
3
|
+
const SUBDOMAIN_MAX_LENGTH = 20;
|
|
4
|
+
const PORTAL_NAME_MIN_LENGTH = 3;
|
|
5
|
+
const PORTAL_NAME_MAX_LENGTH = 40;
|
|
6
|
+
function slugify(value, maxLength) {
|
|
7
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLength).replace(/-+$/, "");
|
|
8
|
+
}
|
|
9
|
+
function buildSubdomainCandidate(organizationId, organizationName) {
|
|
10
|
+
const fallback = `portal-${organizationId.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 8)}`;
|
|
11
|
+
if (!organizationName) {
|
|
12
|
+
return fallback;
|
|
13
|
+
}
|
|
14
|
+
const sanitized = slugify(organizationName, SUBDOMAIN_MAX_LENGTH);
|
|
15
|
+
return sanitized.length >= SUBDOMAIN_MIN_LENGTH ? sanitized : fallback;
|
|
16
|
+
}
|
|
17
|
+
function buildSuffixedSubdomain(baseSubdomain, organizationId) {
|
|
18
|
+
const idSuffix = organizationId.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 4);
|
|
19
|
+
const trimmedBase = baseSubdomain.slice(0, SUBDOMAIN_MAX_LENGTH - idSuffix.length - 1).replace(/-+$/, "");
|
|
20
|
+
return `${trimmedBase}-${idSuffix}`;
|
|
21
|
+
}
|
|
22
|
+
function buildPortalName(organizationName) {
|
|
23
|
+
const trimmed = organizationName?.trim();
|
|
24
|
+
if (!trimmed || trimmed.length < PORTAL_NAME_MIN_LENGTH) {
|
|
25
|
+
return void 0;
|
|
26
|
+
}
|
|
27
|
+
return trimmed.slice(0, PORTAL_NAME_MAX_LENGTH);
|
|
28
|
+
}
|
|
29
|
+
function isConflictError(error) {
|
|
30
|
+
return error instanceof ToolError && (error.metadata?.get("status") === 409 || error.message.startsWith("HTTP 409"));
|
|
31
|
+
}
|
|
32
|
+
function isOrganizationPortalConflict(error) {
|
|
33
|
+
if (!(error instanceof ToolError)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const message = error.message.toLowerCase();
|
|
37
|
+
return message.includes("already exists") && message.includes("organization");
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
PORTAL_NAME_MAX_LENGTH,
|
|
41
|
+
PORTAL_NAME_MIN_LENGTH,
|
|
42
|
+
SUBDOMAIN_MAX_LENGTH,
|
|
43
|
+
SUBDOMAIN_MIN_LENGTH,
|
|
44
|
+
buildPortalName,
|
|
45
|
+
buildSubdomainCandidate,
|
|
46
|
+
buildSuffixedSubdomain,
|
|
47
|
+
isConflictError,
|
|
48
|
+
isOrganizationPortalConflict,
|
|
49
|
+
slugify
|
|
50
|
+
};
|
|
@@ -38,6 +38,13 @@ const ScanStandardizationParamsSchema = z.object({
|
|
|
38
38
|
"API definition content (OpenAPI/AsyncAPI specification in JSON or YAML format) to scan for standardization errors"
|
|
39
39
|
)
|
|
40
40
|
});
|
|
41
|
+
const ScanApiStandardizationFromRegistryParamsSchema = z.object({
|
|
42
|
+
orgName: z.string().describe(
|
|
43
|
+
"The organization name that owns the API and provides the standardization rules (case-sensitive)"
|
|
44
|
+
),
|
|
45
|
+
apiName: z.string().describe("API name (case-sensitive)"),
|
|
46
|
+
version: z.string().describe("Version identifier")
|
|
47
|
+
});
|
|
41
48
|
const CreateApiFromPromptParamsSchema = z.object({
|
|
42
49
|
owner: z.string().describe("API owner (organization or user, case-sensitive)"),
|
|
43
50
|
apiName: z.string().describe("API name"),
|
|
@@ -67,6 +74,7 @@ export {
|
|
|
67
74
|
ApiSearchParamsSchema,
|
|
68
75
|
CreateApiFromPromptParamsSchema,
|
|
69
76
|
CreateApiParamsSchema,
|
|
77
|
+
ScanApiStandardizationFromRegistryParamsSchema,
|
|
70
78
|
ScanStandardizationParamsSchema,
|
|
71
79
|
StandardizeApiParamsSchema
|
|
72
80
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FUNCTIONAL_TESTING_TOOLS } from "./functional-testing-tools.js";
|
|
2
|
-
import { CreatePortalArgsSchema, PortalArgsSchema, UpdatePortalArgsSchema, CreateProductArgsSchema, ProductArgsSchema, UpdateProductArgsSchema, PublishProductArgsSchema, GetProductSectionsArgsSchema, CreateTableOfContentsArgsSchema, GetTableOfContentsArgsSchema, DeleteTableOfContentsArgsSchema, GetDocumentArgsSchema, UpdateDocumentArgsSchema } from "./portal-types.js";
|
|
3
|
-
import { ApiSearchParamsSchema, ApiDefinitionParamsSchema, CreateApiParamsSchema, ScanStandardizationParamsSchema, CreateApiFromPromptParamsSchema, StandardizeApiParamsSchema } from "./registry-types.js";
|
|
2
|
+
import { CreatePortalArgsSchema, PortalArgsSchema, UpdatePortalArgsSchema, ResolveOrganizationPortalArgsSchema, CreateProductArgsSchema, ProductArgsSchema, UpdateProductArgsSchema, PublishProductArgsSchema, GetProductSectionsArgsSchema, CreateTableOfContentsArgsSchema, GetTableOfContentsArgsSchema, DeleteTableOfContentsArgsSchema, CreateDocumentationPageArgsSchema, GetDocumentArgsSchema, UpdateDocumentArgsSchema } from "./portal-types.js";
|
|
3
|
+
import { ApiSearchParamsSchema, ApiDefinitionParamsSchema, CreateApiParamsSchema, ScanStandardizationParamsSchema, ScanApiStandardizationFromRegistryParamsSchema, CreateApiFromPromptParamsSchema, StandardizeApiParamsSchema } from "./registry-types.js";
|
|
4
4
|
import { OrganizationsQuerySchema } from "./user-management-types.js";
|
|
5
5
|
const TOOLS = [
|
|
6
6
|
{
|
|
@@ -30,6 +30,13 @@ const TOOLS = [
|
|
|
30
30
|
inputSchema: UpdatePortalArgsSchema,
|
|
31
31
|
handler: "updatePortal"
|
|
32
32
|
},
|
|
33
|
+
{
|
|
34
|
+
title: "Resolve Organization Portal",
|
|
35
|
+
toolset: "Portals",
|
|
36
|
+
summary: "Resolve portal details for a Swagger organization in a single step. Given an organization UUID, returns the portal ID, subdomain, customDomain (when configured), and the list of products (with productId, productSlug, and productName) for the organization's portal. If the organization has no portal yet, a new portal is created automatically. Use this tool to obtain all portal context needed for subsequent portal and product operations.",
|
|
37
|
+
inputSchema: ResolveOrganizationPortalArgsSchema,
|
|
38
|
+
handler: "resolveOrganizationPortal"
|
|
39
|
+
},
|
|
33
40
|
{
|
|
34
41
|
title: "List Portal Products",
|
|
35
42
|
toolset: "Products",
|
|
@@ -69,7 +76,7 @@ const TOOLS = [
|
|
|
69
76
|
{
|
|
70
77
|
title: "Publish Portal Product",
|
|
71
78
|
toolset: "Products",
|
|
72
|
-
summary: "Publish a product's content to make it live or as preview. This endpoint publishes the current content of a product, making it visible to portal visitors. Use preview mode to test before going live.",
|
|
79
|
+
summary: "Publish a product's content to make it live or as preview. This endpoint publishes the current content of a product, making it visible to portal visitors. Use preview mode to test before going live. Optionally provide `tableOfContentsId` to get a page-specific URL. Returns publication status, a live or preview URL (null if URL building fails), product and portal metadata, and an optional `warning` when metadata/URL building failed — a warning does NOT mean the publish failed.",
|
|
73
80
|
inputSchema: PublishProductArgsSchema,
|
|
74
81
|
handler: "publishPortalProduct"
|
|
75
82
|
},
|
|
@@ -102,6 +109,13 @@ const TOOLS = [
|
|
|
102
109
|
handler: "deleteTableOfContents"
|
|
103
110
|
},
|
|
104
111
|
// Document management tools
|
|
112
|
+
{
|
|
113
|
+
title: "Create Documentation Page",
|
|
114
|
+
toolset: "Documents",
|
|
115
|
+
summary: "Create a documentation page in a portal product in a single tool call. Supports markdown and html content types. Returns the page location details (productId, sectionId, slug) and a draftUrl to edit it in the portal.",
|
|
116
|
+
inputSchema: CreateDocumentationPageArgsSchema,
|
|
117
|
+
handler: "createDocumentationPage"
|
|
118
|
+
},
|
|
105
119
|
{
|
|
106
120
|
title: "Get Document",
|
|
107
121
|
toolset: "Documents",
|
|
@@ -149,10 +163,17 @@ const TOOLS = [
|
|
|
149
163
|
{
|
|
150
164
|
title: "Scan API Standardization",
|
|
151
165
|
toolset: "Registry API",
|
|
152
|
-
summary: "Run a standardization scan against an API definition using the organization's governance and standardization rules. Accepts a YAML or JSON OpenAPI/AsyncAPI definition and returns a list of
|
|
166
|
+
summary: "Run a standardization scan against an API definition using the organization's governance and standardization rules. Accepts a raw YAML or JSON OpenAPI/AsyncAPI definition and returns a list of validation errors, the total issue count, and counts grouped by severity. Use this tool when the user provides the API definition content directly (as raw YAML or JSON) and asks to validate, scan, or check the governance or standardization of the API.",
|
|
153
167
|
inputSchema: ScanStandardizationParamsSchema,
|
|
154
168
|
handler: "scanStandardization"
|
|
155
169
|
},
|
|
170
|
+
{
|
|
171
|
+
title: "Scan API Standardization from Registry",
|
|
172
|
+
toolset: "Registry API",
|
|
173
|
+
summary: "Run a standardization scan on an API that already exists in SwaggerHub Registry, identified by organization name, API name, and version. Fetches the API definition from the registry internally and scans it against the organization's governance and standardization rules. Returns a list of validation errors, total issue count, counts grouped by severity, and a SwaggerHub UI URL for the scanned API. Use this tool when the user identifies the API by org name, API name, and version and asks to validate, scan, or check the governance or standardization of an existing API.",
|
|
174
|
+
inputSchema: ScanApiStandardizationFromRegistryParamsSchema,
|
|
175
|
+
handler: "scanApiStandardizationFromRegistry"
|
|
176
|
+
},
|
|
156
177
|
{
|
|
157
178
|
title: "Create API from Prompt",
|
|
158
179
|
toolset: "Registry API",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
function normalizeSlug(value) {
|
|
2
|
+
const slug = value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
3
|
+
if (slug.length < 3) {
|
|
4
|
+
throw new Error(`Slug "${slug}" is too short (minimum 3 characters).`);
|
|
5
|
+
}
|
|
6
|
+
return slug;
|
|
7
|
+
}
|
|
8
|
+
function findTableOfContentsItem(items, targetId) {
|
|
9
|
+
for (const item of items) {
|
|
10
|
+
if (item.id === targetId) {
|
|
11
|
+
return item;
|
|
12
|
+
}
|
|
13
|
+
const nestedMatch = findTableOfContentsItem(item.children ?? [], targetId);
|
|
14
|
+
if (nestedMatch) {
|
|
15
|
+
return nestedMatch;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function buildPortalLiveUrl(config, portal, productSlug, section, tocItem, preview = false) {
|
|
21
|
+
const host = portal?.customDomain ?? portal?.subdomain;
|
|
22
|
+
const portalUiDomain = portal?.customDomain ? "" : config.getPortalUiDomainSuffix();
|
|
23
|
+
if (!host || !productSlug) {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
const baseUrl = `https://${host}${portalUiDomain}/${productSlug}`;
|
|
27
|
+
const previewSuffix = preview ? "?preview=product" : "";
|
|
28
|
+
if (section?.slug && tocItem?.slug) {
|
|
29
|
+
return `${baseUrl}/${section.slug}/${tocItem.slug}${previewSuffix}`;
|
|
30
|
+
}
|
|
31
|
+
return `${baseUrl}${previewSuffix}`;
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
buildPortalLiveUrl,
|
|
35
|
+
findTableOfContentsItem,
|
|
36
|
+
normalizeSlug
|
|
37
|
+
};
|
package/dist/swagger/client.js
CHANGED
|
@@ -17,6 +17,9 @@ const ConfigurationSchema = z.object({
|
|
|
17
17
|
ui_base_path: z.string().optional().describe("Base URL for the SwaggerHub UI (optional)"),
|
|
18
18
|
functional_testing_api_token: z.string().optional().describe(
|
|
19
19
|
"Swagger Functional Testing API token. Leave empty to disable Functional Testing tools."
|
|
20
|
+
),
|
|
21
|
+
functional_testing_base_path: z.string().optional().describe(
|
|
22
|
+
"Base URL for Swagger Functional Testing API requests (optional)"
|
|
20
23
|
)
|
|
21
24
|
});
|
|
22
25
|
class SwaggerClient {
|
|
@@ -29,7 +32,8 @@ class SwaggerClient {
|
|
|
29
32
|
configPrefix = "Swagger";
|
|
30
33
|
config = ConfigurationSchema;
|
|
31
34
|
async configure(_server, config, _cache) {
|
|
32
|
-
|
|
35
|
+
const hasSwaggerAuth = !!config.api_key || !!getRequestHeader("Swagger-Api-Key") || !!getRequestHeader("Authorization");
|
|
36
|
+
if (hasSwaggerAuth) {
|
|
33
37
|
this._apiKey = config.api_key;
|
|
34
38
|
this.api = new SwaggerAPI(
|
|
35
39
|
new SwaggerConfiguration({
|
|
@@ -45,7 +49,8 @@ class SwaggerClient {
|
|
|
45
49
|
this._ftApiToken = config.functional_testing_api_token;
|
|
46
50
|
this.ftApi = new FunctionalTestingAPI(
|
|
47
51
|
() => this.getFtAuthToken(),
|
|
48
|
-
USER_AGENT
|
|
52
|
+
USER_AGENT,
|
|
53
|
+
config.functional_testing_base_path
|
|
49
54
|
);
|
|
50
55
|
}
|
|
51
56
|
}
|
|
@@ -89,6 +94,9 @@ class SwaggerClient {
|
|
|
89
94
|
const { portalId, ...body } = args;
|
|
90
95
|
return this.getApi().updatePortal(portalId, body);
|
|
91
96
|
}
|
|
97
|
+
async resolveOrganizationPortal(args) {
|
|
98
|
+
return this.getApi().resolveOrganizationPortal(args);
|
|
99
|
+
}
|
|
92
100
|
async getPortalProducts(args) {
|
|
93
101
|
return this.getApi().getPortalProducts(args.portalId);
|
|
94
102
|
}
|
|
@@ -107,8 +115,12 @@ class SwaggerClient {
|
|
|
107
115
|
return this.getApi().updatePortalProduct(productId, body);
|
|
108
116
|
}
|
|
109
117
|
async publishPortalProduct(args) {
|
|
110
|
-
const { productId, preview } = args;
|
|
111
|
-
return this.getApi().publishPortalProduct(
|
|
118
|
+
const { productId, preview, tableOfContentsId } = args;
|
|
119
|
+
return this.getApi().publishPortalProduct(
|
|
120
|
+
productId,
|
|
121
|
+
preview,
|
|
122
|
+
tableOfContentsId ?? null
|
|
123
|
+
);
|
|
112
124
|
}
|
|
113
125
|
async getPortalProductSections(args) {
|
|
114
126
|
const { productId, ...params } = args;
|
|
@@ -130,6 +142,9 @@ class SwaggerClient {
|
|
|
130
142
|
async deleteTableOfContents(args) {
|
|
131
143
|
return this.getApi().deleteTableOfContents(args);
|
|
132
144
|
}
|
|
145
|
+
async createDocumentationPage(args) {
|
|
146
|
+
return this.getApi().createDocumentationPage(args);
|
|
147
|
+
}
|
|
133
148
|
// Registry API methods for SwaggerHub Design functionality
|
|
134
149
|
async searchApis(args = {}) {
|
|
135
150
|
return this.getApi().searchApis(args);
|
|
@@ -150,14 +165,31 @@ class SwaggerClient {
|
|
|
150
165
|
async scanStandardization(args) {
|
|
151
166
|
return this.getApi().scanStandardization(args);
|
|
152
167
|
}
|
|
168
|
+
async scanApiStandardizationFromRegistry(args) {
|
|
169
|
+
return this.getApi().scanApiStandardizationFromRegistry(args);
|
|
170
|
+
}
|
|
153
171
|
async standardizeApi(args) {
|
|
154
172
|
return this.getApi().standardizeApi(args);
|
|
155
173
|
}
|
|
174
|
+
// Functional Testing methods
|
|
156
175
|
async listFunctionalTestingTests() {
|
|
176
|
+
return this.withFunctionalTesting((ftApi) => ftApi.listTests());
|
|
177
|
+
}
|
|
178
|
+
async runFunctionalTestingTest(args) {
|
|
179
|
+
return this.withFunctionalTesting((ftApi) => ftApi.runTest(args));
|
|
180
|
+
}
|
|
181
|
+
async getFunctionalTestingExecution(args) {
|
|
182
|
+
return this.withFunctionalTesting((ftApi) => ftApi.getTestExecution(args));
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Perform an operation with the Functional Testing API.
|
|
186
|
+
* Throws a ToolError if Functional Testing is not configured
|
|
187
|
+
*/
|
|
188
|
+
async withFunctionalTesting(fn) {
|
|
157
189
|
if (!this.ftApi) {
|
|
158
190
|
throw new ToolError("Functional Testing API not configured");
|
|
159
191
|
}
|
|
160
|
-
return this.ftApi
|
|
192
|
+
return fn(this.ftApi);
|
|
161
193
|
}
|
|
162
194
|
async registerTools(register, _getInput) {
|
|
163
195
|
TOOLS.forEach((tool) => {
|