Skip to content

Commit 174c7d4

Browse files
committed
feat: refactor API endpoints to use centralized domain constants
1 parent eee8f17 commit 174c7d4

27 files changed

+107
-85
lines changed

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import addFailureLogsTools from "./tools/getFailureLogs.js";
1717
import addAutomateTools from "./tools/automate.js";
1818
import addSelfHealTools from "./tools/selfheal.js";
1919
import { setupOnInitialized } from "./oninitialized.js";
20+
import { DOMAINS } from "./lib/domains.js";
2021

2122
function registerTools(server: McpServer) {
2223
addSDKTools(server);
@@ -30,6 +31,8 @@ function registerTools(server: McpServer) {
3031
addSelfHealTools(server);
3132
}
3233

34+
console.log(DOMAINS.APP_LIVE);
35+
3336
// Create an MCP server
3437
const server: McpServer = new McpServer({
3538
name: "BrowserStack MCP Server",

src/lib/api.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import config from "../config.js";
2+
import { DOMAINS } from "./domains.js";
23

34
export async function getLatestO11YBuildInfo(
45
buildName: string,
56
projectName: string,
67
) {
7-
const buildsUrl = `https://api-observability.browserstack.com/ext/v1/builds/latest?build_name=${encodeURIComponent(
8+
const buildsUrl = `${DOMAINS.API_OBSERVABILITY}/ext/v1/builds/latest?build_name=${encodeURIComponent(
89
buildName,
910
)}&project_name=${encodeURIComponent(projectName)}`;
1011

src/lib/device-cache.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fs from "fs";
22
import os from "os";
33
import path from "path";
4+
import { DOMAINS } from "./domains.js";
45

56
const CACHE_DIR = path.join(os.homedir(), ".browserstack", "combined_cache");
67
const CACHE_FILE = path.join(CACHE_DIR, "data.json");
@@ -13,12 +14,9 @@ export enum BrowserStackProducts {
1314
}
1415

1516
const URLS: Record<BrowserStackProducts, string> = {
16-
[BrowserStackProducts.LIVE]:
17-
"https://www.browserstack.com/list-of-browsers-and-platforms/live.json",
18-
[BrowserStackProducts.APP_LIVE]:
19-
"https://www.browserstack.com/list-of-browsers-and-platforms/app_live.json",
20-
[BrowserStackProducts.APP_AUTOMATE]:
21-
"https://www.browserstack.com/list-of-browsers-and-platforms/app_automate.json",
17+
[BrowserStackProducts.LIVE]: `${DOMAINS.WWW}/list-of-browsers-and-platforms/live.json`,
18+
[BrowserStackProducts.APP_LIVE]: `${DOMAINS.WWW}/list-of-browsers-and-platforms/app_live.json`,
19+
[BrowserStackProducts.APP_AUTOMATE]: `${DOMAINS.WWW}/list-of-browsers-and-platforms/app_automate.json`,
2220
};
2321

2422
/**

src/lib/domains.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const DOMAINS = {
2+
API: process.env.API_DOMAIN || "https://api.browserstack.com",
3+
API_CLOUD:
4+
process.env.API_CLOUD_DOMAIN || "https://api-cloud.browserstack.com",
5+
TEST_MANAGEMENT:
6+
process.env.TEST_MGMT_DOMAIN || "https://test-management.browserstack.com",
7+
API_OBSERVABILITY:
8+
process.env.API_OBSERVABILITY_DOMAIN ||
9+
"https://api-observability.browserstack.com",
10+
LIVE: process.env.LIVE_DOMAIN || "https://live.browserstack.com",
11+
WWW: process.env.WWW_DOMAIN || "https://www.browserstack.com",
12+
APP_LIVE: process.env.APP_LIVE_DOMAIN || "https://app-live.browserstack.com",
13+
API_ACCESSIBILITY:
14+
process.env.API_ACCESSIBILITY_DOMAIN ||
15+
"https://api-accessibility.browserstack.com",
16+
SCANNER: process.env.SCANNER_DOMAIN || "https://scanner.browserstack.com",
17+
} as const;

src/lib/instrumentation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logger from "../logger.js";
22
import config from "../config.js";
33
import { createRequire } from "module";
4+
import { DOMAINS } from "./domains.js";
45
const require = createRequire(import.meta.url);
56
const packageJson = require("../../package.json");
67
import axios from "axios";
@@ -27,7 +28,7 @@ export function trackMCP(
2728
return;
2829
}
2930

30-
const instrumentationEndpoint = "https://api.browserstack.com/sdk/v1/event";
31+
const instrumentationEndpoint = `${DOMAINS.API}/sdk/v1/event`;
3132
const isSuccess = !error;
3233
const mcpClient = clientInfo?.name || "unknown";
3334

src/logger.ts

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,24 @@
11
import { pino } from "pino";
22

3-
let logger: pino.Logger;
4-
5-
if (process.env.NODE_ENV === "development") {
6-
logger = pino({
7-
level: "debug",
8-
transport: {
9-
targets: [
10-
{
11-
level: "debug",
12-
target: "pino-pretty",
13-
options: {
14-
colorize: true,
15-
levelFirst: true,
16-
destination:
17-
process.platform === "win32"
18-
? "C:\\Windows\\Temp\\browserstack-mcp-server.log"
19-
: "/tmp/browserstack-mcp-server.log",
20-
},
3+
// Always use the full logger configuration regardless of environment
4+
const logger: pino.Logger = pino({
5+
level: "trace",
6+
transport: {
7+
targets: [
8+
{
9+
level: "trace",
10+
target: "pino-pretty",
11+
options: {
12+
colorize: true,
13+
levelFirst: true,
14+
destination:
15+
process.platform === "win32"
16+
? "C:\\Windows\\Temp\\browserstack-mcp-server.log"
17+
: "/tmp/browserstack-mcp-server.log",
2118
},
22-
],
23-
},
24-
});
25-
} else {
26-
// NULL logger
27-
logger = pino({
28-
level: "info",
29-
transport: {
30-
target: "pino/file",
31-
options: {
32-
destination: process.platform === "win32" ? "NUL" : "/dev/null",
3319
},
34-
},
35-
});
36-
}
20+
],
21+
},
22+
});
3723

3824
export default logger;

src/tools/accessibility.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { AccessibilityScanner } from "./accessiblity-utils/scanner.js";
55
import { AccessibilityReportFetcher } from "./accessiblity-utils/report-fetcher.js";
66
import { trackMCP } from "../lib/instrumentation.js";
77
import { parseAccessibilityReportFromCSV } from "./accessiblity-utils/report-parser.js";
8+
import { DOMAINS } from "../lib/domains.js";
89

910
const scanner = new AccessibilityScanner();
1011
const reportFetcher = new AccessibilityReportFetcher();
@@ -37,7 +38,7 @@ async function runAccessibilityScan(
3738
content: [
3839
{
3940
type: "text",
40-
text: `❌ Accessibility scan "${name}" failed with status: ${status} , check the BrowserStack dashboard for more details [https://scanner.browserstack.com/site-scanner/scan-details/${name}].`,
41+
text: `❌ Accessibility scan "${name}" failed with status: ${status} , check the BrowserStack dashboard for more details [${DOMAINS.SCANNER}/site-scanner/scan-details/${name}].`,
4142
isError: true,
4243
},
4344
],
@@ -55,7 +56,7 @@ async function runAccessibilityScan(
5556
content: [
5657
{
5758
type: "text",
58-
text: `✅ Accessibility scan "${name}" completed. check the BrowserStack dashboard for more details [https://scanner.browserstack.com/site-scanner/scan-details/${name}].`,
59+
text: `✅ Accessibility scan "${name}" completed. check the BrowserStack dashboard for more details [${DOMAINS.SCANNER}/site-scanner/scan-details/${name}].`,
5960
},
6061
{
6162
type: "text",

src/tools/accessiblity-utils/report-fetcher.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import axios from "axios";
22
import config from "../../config.js";
3+
import { DOMAINS } from "../../lib/domains.js";
34

45
interface ReportInitResponse {
56
success: true;
@@ -21,7 +22,7 @@ export class AccessibilityReportFetcher {
2122

2223
async getReportLink(scanId: string, scanRunId: string): Promise<string> {
2324
// Initiate CSV link generation
24-
const initUrl = `https://api-accessibility.browserstack.com/api/website-scanner/v1/scans/${scanId}/scan_runs/issues?scan_run_id=${scanRunId}`;
25+
const initUrl = `${DOMAINS.API_ACCESSIBILITY}/api/website-scanner/v1/scans/${scanId}/scan_runs/issues?scan_run_id=${scanRunId}`;
2526
const initResp = await axios.get<ReportInitResponse>(initUrl, {
2627
auth: this.auth,
2728
});
@@ -33,7 +34,7 @@ export class AccessibilityReportFetcher {
3334
const taskId = initResp.data.data.task_id;
3435

3536
// Fetch the generated CSV link
36-
const reportUrl = `https://api-accessibility.browserstack.com/api/website-scanner/v1/scans/${scanId}/scan_runs/issues?task_id=${encodeURIComponent(
37+
const reportUrl = `${DOMAINS.API_ACCESSIBILITY}/api/website-scanner/v1/scans/${scanId}/scan_runs/issues?task_id=${encodeURIComponent(
3738
taskId,
3839
)}`;
3940
const reportResp = await axios.get<ReportResponse>(reportUrl, {

src/tools/accessiblity-utils/scanner.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
ensureLocalBinarySetup,
77
killExistingBrowserStackLocalProcesses,
88
} from "../../lib/local.js";
9+
import { DOMAINS } from "../../lib/domains.js";
910

1011
export interface AccessibilityScanResponse {
1112
success: boolean;
@@ -73,8 +74,8 @@ export class AccessibilityScanner {
7374
}
7475

7576
try {
76-
const { data } = await axios.post<AccessibilityScanResponse>(
77-
"https://api-accessibility.browserstack.com/api/website-scanner/v1/scans",
77+
const { data } = await axios.post(
78+
`${DOMAINS.API_ACCESSIBILITY}/api/website-scanner/v1/scans`,
7879
requestBody,
7980
{ auth: this.auth },
8081
);
@@ -99,7 +100,7 @@ export class AccessibilityScanner {
99100
): Promise<AccessibilityScanStatus> {
100101
try {
101102
const { data } = await axios.get<AccessibilityScanStatus>(
102-
`https://api-accessibility.browserstack.com/api/website-scanner/v1/scans/${scanId}/scan_runs/${scanRunId}/status`,
103+
`${DOMAINS.API_ACCESSIBILITY}/api/website-scanner/v1/scans/${scanId}/scan_runs/${scanRunId}/status`,
103104
{ auth: this.auth },
104105
);
105106
if (!data.success)

src/tools/appautomate-utils/appautomate.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import axios from "axios";
33
import config from "../../config.js";
44
import FormData from "form-data";
55
import { customFuzzySearch } from "../../lib/fuzzy.js";
6+
import { DOMAINS } from "../../lib/domains.js";
67

78
interface Device {
89
device: string;
@@ -135,7 +136,7 @@ export async function uploadApp(appPath: string): Promise<string> {
135136
formData.append("file", fs.createReadStream(filePath));
136137

137138
const response = await axios.post<UploadResponse>(
138-
"https://api-cloud.browserstack.com/app-automate/upload",
139+
`${DOMAINS.API_CLOUD}/app-automate/upload`,
139140
formData,
140141
{
141142
headers: {

0 commit comments

Comments
 (0)