🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@mastra/brightdata

Package Overview
Dependencies
Maintainers
6
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mastra/brightdata - npm Package Compare versions

Comparing version
0.2.1
to
0.2.3
+1
-1
dist/client.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,KAAK,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAC;AAErD,MAAM,WAAW,uBAAuB;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,aAAc,SAAQ,cAAc;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE;QACN,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KACtE,CAAC;IACF,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAyFD,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,gBAAgB,CA+CtF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzE"}
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,KAAK,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAC;AAErD,MAAM,WAAW,uBAAuB;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,aAAc,SAAQ,cAAc;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE;QACN,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KACtE,CAAC;IACF,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAyFD,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,gBAAgB,CA2CtF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzE"}

@@ -81,5 +81,3 @@ 'use strict';

if (!apiKey) {
throw new Error(
"Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var."
);
throw new Error("Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.");
}

@@ -86,0 +84,0 @@ const timeout = config?.timeout;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/client.ts","../src/search.ts","../src/fetch.ts","../src/tools.ts"],"names":["z","createTool","inputSchema","outputSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["const REQUEST_ENDPOINT = 'https://api.brightdata.com/request';\nconst DEFAULT_SERP_ZONE = 'sdk_serp';\nconst DEFAULT_WEB_UNLOCKER_ZONE = 'sdk_unlocker';\nconst DEFAULT_TIMEOUT = 120_000;\n\ntype RequestFormat = 'raw' | 'json';\ntype DataFormat = 'html' | 'markdown' | 'screenshot';\n\nexport interface BrightDataClientOptions {\n [key: string]: unknown;\n apiKey?: string;\n timeout?: number;\n webUnlockerZone?: string;\n serpZone?: string;\n}\n\ninterface RequestOptions {\n country?: string;\n dataFormat?: DataFormat;\n format?: RequestFormat;\n method?: string;\n timeout?: number;\n zone?: string;\n}\n\ninterface SearchOptions extends RequestOptions {\n language?: string;\n start?: number;\n}\n\ninterface BrightDataRequestBody {\n country?: string;\n data_format?: Exclude<DataFormat, 'html'>;\n format: RequestFormat;\n method: string;\n url: string;\n zone: string;\n}\n\nexport interface BrightDataClient {\n search: {\n google: (query: string, options?: SearchOptions) => Promise<unknown>;\n };\n scrapeUrl: (url: string, options?: RequestOptions) => Promise<string>;\n close: () => Promise<void>;\n}\n\nasync function requestBrightData(\n apiKey: string,\n body: BrightDataRequestBody,\n timeout = DEFAULT_TIMEOUT,\n): Promise<unknown> {\n const effectiveTimeout = Number.isFinite(timeout) && timeout > 0 ? timeout : DEFAULT_TIMEOUT;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);\n\n try {\n const response = await fetch(REQUEST_ENDPOINT, {\n body: JSON.stringify(body),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n signal: controller.signal,\n });\n\n const responseText = await response.text();\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n throw new Error('invalid API key or insufficient permissions');\n }\n\n if (response.status === 400) {\n throw new Error(`bad request: ${responseText}`);\n }\n\n throw new Error(`request failed with status ${response.status}: ${responseText}`);\n }\n\n if (body.format === 'json') {\n return responseText ? JSON.parse(responseText) : {};\n }\n\n return responseText;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timed out after ${effectiveTimeout}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\nfunction buildGoogleSearchUrl(query: string, options: SearchOptions = {}) {\n const url = new URL('https://www.google.com/search');\n url.searchParams.set('q', query.trim());\n if ((options.format ?? 'json') === 'json') {\n url.searchParams.set('brd_json', '1');\n }\n url.searchParams.set('hl', options.language ?? 'en');\n\n if (options.country) {\n url.searchParams.set('gl', options.country);\n }\n\n if (options.start !== undefined) {\n url.searchParams.set('start', String(options.start));\n }\n\n return url.toString();\n}\n\nfunction toRequestBody(url: string, zone: string, options: RequestOptions = {}): BrightDataRequestBody {\n const body: BrightDataRequestBody = {\n format: options.format ?? 'raw',\n method: options.method ?? 'GET',\n url,\n zone,\n };\n\n if (options.country) {\n body.country = options.country;\n }\n\n if (options.dataFormat && options.dataFormat !== 'html') {\n body.data_format = options.dataFormat;\n }\n\n return body;\n}\n\nexport function getBrightDataClient(config?: BrightDataClientOptions): BrightDataClient {\n const apiKey = config?.apiKey ?? process.env.BRIGHTDATA_API_TOKEN;\n if (!apiKey) {\n throw new Error(\n 'Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.',\n );\n }\n\n const timeout = config?.timeout;\n const serpZone = config?.serpZone ?? process.env.BRIGHTDATA_SERP_ZONE ?? DEFAULT_SERP_ZONE;\n const webUnlockerZone =\n config?.webUnlockerZone ?? process.env.BRIGHTDATA_WEB_UNLOCKER_ZONE ?? DEFAULT_WEB_UNLOCKER_ZONE;\n\n return {\n search: {\n google: async (query: string, options: SearchOptions = {}) => {\n if (options.language && !/^[a-z]{2}$/i.test(options.language)) {\n throw new Error('language must be a two-letter code (e.g. \"en\", \"es\")');\n }\n\n const normalizedOptions = options.language\n ? { ...options, language: options.language.toLowerCase() }\n : options;\n\n const url = buildGoogleSearchUrl(query, normalizedOptions);\n return requestBrightData(\n apiKey,\n toRequestBody(url, normalizedOptions.zone ?? serpZone, {\n ...normalizedOptions,\n format: normalizedOptions.format ?? 'json',\n method: 'GET',\n }),\n normalizedOptions.timeout ?? timeout,\n );\n },\n },\n scrapeUrl: async (url: string, options: RequestOptions = {}) => {\n const response = await requestBrightData(\n apiKey,\n toRequestBody(url, options.zone ?? webUnlockerZone, options),\n options.timeout ?? timeout,\n );\n\n return typeof response === 'string' ? response : JSON.stringify(response);\n },\n close: async () => {},\n };\n}\n\nexport async function closeClient(client: BrightDataClient): Promise<void> {\n const close = client.close;\n try {\n await close.call(client);\n } catch {\n // best-effort cleanup; never mask the primary tool error from the finally block\n }\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n query: z.string().describe('The search query'),\n country: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Country must be a 2-letter code')\n .optional()\n .describe('2-letter country code for geo-targeted results (e.g., \"us\", \"gb\")'),\n language: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Language must be a 2-letter code')\n .optional()\n .describe('Language code for localized Google results (e.g., \"en\", \"es\", \"fr\")'),\n start: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Result offset for pagination (e.g. 10 to get the second page of 10 results)'),\n});\n\nconst outputSchema = z.object({\n query: z.string(),\n results: z.array(\n z.object({\n link: z.string(),\n title: z.string(),\n description: z.string(),\n }),\n ),\n currentPage: z.number(),\n});\n\nexport function createBrightDataSearchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-search',\n description:\n \"Search Google and get back parsed organic results (link, title, description). Uses Bright Data's SERP API which bypasses bot detection. Supports country and language targeting, plus pagination via result offset.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const rawResponse = await client.search.google(input.query, {\n country: input.country,\n language: input.language,\n start: input.start,\n });\n\n const response: { organic?: unknown; current_page?: unknown } =\n typeof rawResponse === 'string' ? JSON.parse(rawResponse) : rawResponse;\n\n const organic = Array.isArray(response.organic) ? response.organic : [];\n const results = organic\n .map((entry: unknown) => {\n if (!entry || typeof entry !== 'object') return null;\n const e = entry as Record<string, unknown>;\n const link = typeof e.link === 'string' ? e.link.trim() : '';\n const title = typeof e.title === 'string' ? e.title.trim() : '';\n const description = typeof e.description === 'string' ? e.description.trim() : '';\n if (!link || !title) return null;\n return { link, title, description };\n })\n .filter((r): r is { link: string; title: string; description: string } => r !== null);\n\n const parsedPage = Number(response.current_page);\n const currentPage = Number.isFinite(parsedPage) && parsedPage > 0 ? parsedPage : 1;\n\n return {\n query: input.query,\n results,\n currentPage,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n url: z.string().url().describe('The URL to fetch'),\n});\n\nconst outputSchema = z.object({\n url: z.string(),\n content: z.string().describe('Page content as Markdown'),\n});\n\nexport function createBrightDataFetchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-fetch',\n description:\n \"Fetch a webpage and return its content as Markdown. Uses Bright Data's Web Unlocker which bypasses bot detection and CAPTCHAs. Pass any URL, including pages that block normal scrapers.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const content = await client.scrapeUrl(input.url, {\n dataFormat: 'markdown',\n });\n\n return {\n url: input.url,\n content,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import type { BrightDataClientOptions } from './client.js';\nimport { createBrightDataFetchTool } from './fetch.js';\nimport { createBrightDataSearchTool } from './search.js';\n\nexport function createBrightDataTools(config?: BrightDataClientOptions) {\n return {\n webSearch: createBrightDataSearchTool(config),\n webFetch: createBrightDataFetchTool(config),\n };\n}\n"]}
{"version":3,"sources":["../src/client.ts","../src/search.ts","../src/fetch.ts","../src/tools.ts"],"names":["z","createTool","inputSchema","outputSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["const REQUEST_ENDPOINT = 'https://api.brightdata.com/request';\nconst DEFAULT_SERP_ZONE = 'sdk_serp';\nconst DEFAULT_WEB_UNLOCKER_ZONE = 'sdk_unlocker';\nconst DEFAULT_TIMEOUT = 120_000;\n\ntype RequestFormat = 'raw' | 'json';\ntype DataFormat = 'html' | 'markdown' | 'screenshot';\n\nexport interface BrightDataClientOptions {\n [key: string]: unknown;\n apiKey?: string;\n timeout?: number;\n webUnlockerZone?: string;\n serpZone?: string;\n}\n\ninterface RequestOptions {\n country?: string;\n dataFormat?: DataFormat;\n format?: RequestFormat;\n method?: string;\n timeout?: number;\n zone?: string;\n}\n\ninterface SearchOptions extends RequestOptions {\n language?: string;\n start?: number;\n}\n\ninterface BrightDataRequestBody {\n country?: string;\n data_format?: Exclude<DataFormat, 'html'>;\n format: RequestFormat;\n method: string;\n url: string;\n zone: string;\n}\n\nexport interface BrightDataClient {\n search: {\n google: (query: string, options?: SearchOptions) => Promise<unknown>;\n };\n scrapeUrl: (url: string, options?: RequestOptions) => Promise<string>;\n close: () => Promise<void>;\n}\n\nasync function requestBrightData(\n apiKey: string,\n body: BrightDataRequestBody,\n timeout = DEFAULT_TIMEOUT,\n): Promise<unknown> {\n const effectiveTimeout = Number.isFinite(timeout) && timeout > 0 ? timeout : DEFAULT_TIMEOUT;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);\n\n try {\n const response = await fetch(REQUEST_ENDPOINT, {\n body: JSON.stringify(body),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n signal: controller.signal,\n });\n\n const responseText = await response.text();\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n throw new Error('invalid API key or insufficient permissions');\n }\n\n if (response.status === 400) {\n throw new Error(`bad request: ${responseText}`);\n }\n\n throw new Error(`request failed with status ${response.status}: ${responseText}`);\n }\n\n if (body.format === 'json') {\n return responseText ? JSON.parse(responseText) : {};\n }\n\n return responseText;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timed out after ${effectiveTimeout}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\nfunction buildGoogleSearchUrl(query: string, options: SearchOptions = {}) {\n const url = new URL('https://www.google.com/search');\n url.searchParams.set('q', query.trim());\n if ((options.format ?? 'json') === 'json') {\n url.searchParams.set('brd_json', '1');\n }\n url.searchParams.set('hl', options.language ?? 'en');\n\n if (options.country) {\n url.searchParams.set('gl', options.country);\n }\n\n if (options.start !== undefined) {\n url.searchParams.set('start', String(options.start));\n }\n\n return url.toString();\n}\n\nfunction toRequestBody(url: string, zone: string, options: RequestOptions = {}): BrightDataRequestBody {\n const body: BrightDataRequestBody = {\n format: options.format ?? 'raw',\n method: options.method ?? 'GET',\n url,\n zone,\n };\n\n if (options.country) {\n body.country = options.country;\n }\n\n if (options.dataFormat && options.dataFormat !== 'html') {\n body.data_format = options.dataFormat;\n }\n\n return body;\n}\n\nexport function getBrightDataClient(config?: BrightDataClientOptions): BrightDataClient {\n const apiKey = config?.apiKey ?? process.env.BRIGHTDATA_API_TOKEN;\n if (!apiKey) {\n throw new Error('Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.');\n }\n\n const timeout = config?.timeout;\n const serpZone = config?.serpZone ?? process.env.BRIGHTDATA_SERP_ZONE ?? DEFAULT_SERP_ZONE;\n const webUnlockerZone =\n config?.webUnlockerZone ?? process.env.BRIGHTDATA_WEB_UNLOCKER_ZONE ?? DEFAULT_WEB_UNLOCKER_ZONE;\n\n return {\n search: {\n google: async (query: string, options: SearchOptions = {}) => {\n if (options.language && !/^[a-z]{2}$/i.test(options.language)) {\n throw new Error('language must be a two-letter code (e.g. \"en\", \"es\")');\n }\n\n const normalizedOptions = options.language ? { ...options, language: options.language.toLowerCase() } : options;\n\n const url = buildGoogleSearchUrl(query, normalizedOptions);\n return requestBrightData(\n apiKey,\n toRequestBody(url, normalizedOptions.zone ?? serpZone, {\n ...normalizedOptions,\n format: normalizedOptions.format ?? 'json',\n method: 'GET',\n }),\n normalizedOptions.timeout ?? timeout,\n );\n },\n },\n scrapeUrl: async (url: string, options: RequestOptions = {}) => {\n const response = await requestBrightData(\n apiKey,\n toRequestBody(url, options.zone ?? webUnlockerZone, options),\n options.timeout ?? timeout,\n );\n\n return typeof response === 'string' ? response : JSON.stringify(response);\n },\n close: async () => {},\n };\n}\n\nexport async function closeClient(client: BrightDataClient): Promise<void> {\n const close = client.close;\n try {\n await close.call(client);\n } catch {\n // best-effort cleanup; never mask the primary tool error from the finally block\n }\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n query: z.string().describe('The search query'),\n country: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Country must be a 2-letter code')\n .optional()\n .describe('2-letter country code for geo-targeted results (e.g., \"us\", \"gb\")'),\n language: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Language must be a 2-letter code')\n .optional()\n .describe('Language code for localized Google results (e.g., \"en\", \"es\", \"fr\")'),\n start: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Result offset for pagination (e.g. 10 to get the second page of 10 results)'),\n});\n\nconst outputSchema = z.object({\n query: z.string(),\n results: z.array(\n z.object({\n link: z.string(),\n title: z.string(),\n description: z.string(),\n }),\n ),\n currentPage: z.number(),\n});\n\nexport function createBrightDataSearchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-search',\n description:\n \"Search Google and get back parsed organic results (link, title, description). Uses Bright Data's SERP API which bypasses bot detection. Supports country and language targeting, plus pagination via result offset.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const rawResponse = await client.search.google(input.query, {\n country: input.country,\n language: input.language,\n start: input.start,\n });\n\n const response: { organic?: unknown; current_page?: unknown } =\n typeof rawResponse === 'string' ? JSON.parse(rawResponse) : rawResponse;\n\n const organic = Array.isArray(response.organic) ? response.organic : [];\n const results = organic\n .map((entry: unknown) => {\n if (!entry || typeof entry !== 'object') return null;\n const e = entry as Record<string, unknown>;\n const link = typeof e.link === 'string' ? e.link.trim() : '';\n const title = typeof e.title === 'string' ? e.title.trim() : '';\n const description = typeof e.description === 'string' ? e.description.trim() : '';\n if (!link || !title) return null;\n return { link, title, description };\n })\n .filter((r): r is { link: string; title: string; description: string } => r !== null);\n\n const parsedPage = Number(response.current_page);\n const currentPage = Number.isFinite(parsedPage) && parsedPage > 0 ? parsedPage : 1;\n\n return {\n query: input.query,\n results,\n currentPage,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n url: z.string().url().describe('The URL to fetch'),\n});\n\nconst outputSchema = z.object({\n url: z.string(),\n content: z.string().describe('Page content as Markdown'),\n});\n\nexport function createBrightDataFetchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-fetch',\n description:\n \"Fetch a webpage and return its content as Markdown. Uses Bright Data's Web Unlocker which bypasses bot detection and CAPTCHAs. Pass any URL, including pages that block normal scrapers.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const content = await client.scrapeUrl(input.url, {\n dataFormat: 'markdown',\n });\n\n return {\n url: input.url,\n content,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import type { BrightDataClientOptions } from './client.js';\nimport { createBrightDataFetchTool } from './fetch.js';\nimport { createBrightDataSearchTool } from './search.js';\n\nexport function createBrightDataTools(config?: BrightDataClientOptions) {\n return {\n webSearch: createBrightDataSearchTool(config),\n webFetch: createBrightDataFetchTool(config),\n };\n}\n"]}

@@ -79,5 +79,3 @@ import { createTool } from '@mastra/core/tools';

if (!apiKey) {
throw new Error(
"Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var."
);
throw new Error("Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.");
}

@@ -84,0 +82,0 @@ const timeout = config?.timeout;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/client.ts","../src/search.ts","../src/fetch.ts","../src/tools.ts"],"names":["inputSchema","z","outputSchema","createTool"],"mappings":";;;;AAAA,IAAM,gBAAA,GAAmB,oCAAA;AACzB,IAAM,iBAAA,GAAoB,UAAA;AAC1B,IAAM,yBAAA,GAA4B,cAAA;AAClC,IAAM,eAAA,GAAkB,IAAA;AA4CxB,eAAe,iBAAA,CACb,MAAA,EACA,IAAA,EACA,OAAA,GAAU,eAAA,EACQ;AAClB,EAAA,MAAM,mBAAmB,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,IAAK,OAAA,GAAU,IAAI,OAAA,GAAU,eAAA;AAC7E,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,YAAY,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,gBAAgB,CAAA;AAEvE,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,gBAAA,EAAkB;AAAA,MAC7C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAAA,MACzB,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,MAAM,CAAA,CAAA;AAAA,QAC/B,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,MAAA,EAAQ,MAAA;AAAA,MACR,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AAED,IAAA,MAAM,YAAA,GAAe,MAAM,QAAA,CAAS,IAAA,EAAK;AAEzC,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,QAAA,CAAS,MAAA,KAAW,GAAA,IAAO,QAAA,CAAS,WAAW,GAAA,EAAK;AACtD,QAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,MAC/D;AAEA,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgB,YAAY,CAAA,CAAE,CAAA;AAAA,MAChD;AAEA,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,SAAS,MAAM,CAAA,EAAA,EAAK,YAAY,CAAA,CAAE,CAAA;AAAA,IAClF;AAEA,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC1B,MAAA,OAAO,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,YAAY,IAAI,EAAC;AAAA,IACpD;AAEA,IAAA,OAAO,YAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACzD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,gBAAgB,CAAA,EAAA,CAAI,CAAA;AAAA,IACjE;AACA,IAAA,MAAM,KAAA;AAAA,EACR,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,SAAS,CAAA;AAAA,EACxB;AACF;AAEA,SAAS,oBAAA,CAAqB,KAAA,EAAe,OAAA,GAAyB,EAAC,EAAG;AACxE,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,+BAA+B,CAAA;AACnD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,KAAA,CAAM,MAAM,CAAA;AACtC,EAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAU,MAAA,MAAY,MAAA,EAAQ;AACzC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,GAAG,CAAA;AAAA,EACtC;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,IAAA,EAAM,OAAA,CAAQ,YAAY,IAAI,CAAA;AAEnD,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,IAAA,EAAM,OAAA,CAAQ,OAAO,CAAA;AAAA,EAC5C;AAEA,EAAA,IAAI,OAAA,CAAQ,UAAU,MAAA,EAAW;AAC/B,IAAA,GAAA,CAAI,aAAa,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACrD;AAEA,EAAA,OAAO,IAAI,QAAA,EAAS;AACtB;AAEA,SAAS,aAAA,CAAc,GAAA,EAAa,IAAA,EAAc,OAAA,GAA0B,EAAC,EAA0B;AACrG,EAAA,MAAM,IAAA,GAA8B;AAAA,IAClC,MAAA,EAAQ,QAAQ,MAAA,IAAU,KAAA;AAAA,IAC1B,MAAA,EAAQ,QAAQ,MAAA,IAAU,KAAA;AAAA,IAC1B,GAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,OAAA;AAAA,EACzB;AAEA,EAAA,IAAI,OAAA,CAAQ,UAAA,IAAc,OAAA,CAAQ,UAAA,KAAe,MAAA,EAAQ;AACvD,IAAA,IAAA,CAAK,cAAc,OAAA,CAAQ,UAAA;AAAA,EAC7B;AAEA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,oBAAoB,MAAA,EAAoD;AACtF,EAAA,MAAM,MAAA,GAAS,MAAA,EAAQ,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,oBAAA;AAC7C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,UAAU,MAAA,EAAQ,OAAA;AACxB,EAAA,MAAM,QAAA,GAAW,MAAA,EAAQ,QAAA,IAAY,OAAA,CAAQ,IAAI,oBAAA,IAAwB,iBAAA;AACzE,EAAA,MAAM,eAAA,GACJ,MAAA,EAAQ,eAAA,IAAmB,OAAA,CAAQ,IAAI,4BAAA,IAAgC,yBAAA;AAEzE,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,MAAA,EAAQ,OAAO,KAAA,EAAe,OAAA,GAAyB,EAAC,KAAM;AAC5D,QAAA,IAAI,QAAQ,QAAA,IAAY,CAAC,cAAc,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC7D,UAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;AAAA,QACxE;AAEA,QAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,QAAA,GAC9B,EAAE,GAAG,OAAA,EAAS,QAAA,EAAU,OAAA,CAAQ,QAAA,CAAS,WAAA,EAAY,EAAE,GACvD,OAAA;AAEJ,QAAA,MAAM,GAAA,GAAM,oBAAA,CAAqB,KAAA,EAAO,iBAAiB,CAAA;AACzD,QAAA,OAAO,iBAAA;AAAA,UACL,MAAA;AAAA,UACA,aAAA,CAAc,GAAA,EAAK,iBAAA,CAAkB,IAAA,IAAQ,QAAA,EAAU;AAAA,YACrD,GAAG,iBAAA;AAAA,YACH,MAAA,EAAQ,kBAAkB,MAAA,IAAU,MAAA;AAAA,YACpC,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,UACD,kBAAkB,OAAA,IAAW;AAAA,SAC/B;AAAA,MACF;AAAA,KACF;AAAA,IACA,SAAA,EAAW,OAAO,GAAA,EAAa,OAAA,GAA0B,EAAC,KAAM;AAC9D,MAAA,MAAM,WAAW,MAAM,iBAAA;AAAA,QACrB,MAAA;AAAA,QACA,aAAA,CAAc,GAAA,EAAK,OAAA,CAAQ,IAAA,IAAQ,iBAAiB,OAAO,CAAA;AAAA,QAC3D,QAAQ,OAAA,IAAW;AAAA,OACrB;AAEA,MAAA,OAAO,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,IAAA,CAAK,UAAU,QAAQ,CAAA;AAAA,IAC1E,CAAA;AAAA,IACA,OAAO,YAAY;AAAA,IAAC;AAAA,GACtB;AACF;AAEA,eAAsB,YAAY,MAAA,EAAyC;AACzE,EAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;ACxLA,IAAM,WAAA,GAAc,EAAE,MAAA,CAAO;AAAA,EAC3B,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,kBAAkB,CAAA;AAAA,EAC7C,OAAA,EAAS,CAAA,CACN,MAAA,EAAO,CACP,KAAA,CAAM,aAAA,EAAe,iCAAiC,CAAA,CACtD,QAAA,EAAS,CACT,QAAA,CAAS,mEAAmE,CAAA;AAAA,EAC/E,QAAA,EAAU,CAAA,CACP,MAAA,EAAO,CACP,KAAA,CAAM,aAAA,EAAe,kCAAkC,CAAA,CACvD,QAAA,EAAS,CACT,QAAA,CAAS,qEAAqE,CAAA;AAAA,EACjF,KAAA,EAAO,CAAA,CACJ,MAAA,EAAO,CACP,GAAA,EAAI,CACJ,WAAA,EAAY,CACZ,QAAA,EAAS,CACT,QAAA,CAAS,6EAA6E;AAC3F,CAAC,CAAA;AAED,IAAM,YAAA,GAAe,EAAE,MAAA,CAAO;AAAA,EAC5B,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,EAChB,SAAS,CAAA,CAAE,KAAA;AAAA,IACT,EAAE,MAAA,CAAO;AAAA,MACP,IAAA,EAAM,EAAE,MAAA,EAAO;AAAA,MACf,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,MAChB,WAAA,EAAa,EAAE,MAAA;AAAO,KACvB;AAAA,GACH;AAAA,EACA,WAAA,EAAa,EAAE,MAAA;AACjB,CAAC,CAAA;AAEM,SAAS,2BAA2B,MAAA,EAAkC;AAC3E,EAAA,OAAO,UAAA,CAAW;AAAA,IAChB,EAAA,EAAI,mBAAA;AAAA,IACJ,WAAA,EACE,qNAAA;AAAA,IACF,WAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA,EAAS,OAAM,KAAA,KAAS;AACtB,MAAA,MAAM,MAAA,GAAS,oBAAoB,MAAM,CAAA;AACzC,MAAA,IAAI;AACF,QAAA,MAAM,cAAc,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAM,KAAA,EAAO;AAAA,UAC1D,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,OAAO,KAAA,CAAM;AAAA,SACd,CAAA;AAED,QAAA,MAAM,WACJ,OAAO,WAAA,KAAgB,WAAW,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,GAAI,WAAA;AAE9D,QAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAA,GAAI,QAAA,CAAS,UAAU,EAAC;AACtE,QAAA,MAAM,OAAA,GAAU,OAAA,CACb,GAAA,CAAI,CAAC,KAAA,KAAmB;AACvB,UAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,IAAA;AAChD,UAAA,MAAM,CAAA,GAAI,KAAA;AACV,UAAA,MAAM,IAAA,GAAO,OAAO,CAAA,CAAE,IAAA,KAAS,WAAW,CAAA,CAAE,IAAA,CAAK,MAAK,GAAI,EAAA;AAC1D,UAAA,MAAM,KAAA,GAAQ,OAAO,CAAA,CAAE,KAAA,KAAU,WAAW,CAAA,CAAE,KAAA,CAAM,MAAK,GAAI,EAAA;AAC7D,UAAA,MAAM,WAAA,GAAc,OAAO,CAAA,CAAE,WAAA,KAAgB,WAAW,CAAA,CAAE,WAAA,CAAY,MAAK,GAAI,EAAA;AAC/E,UAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,KAAA,EAAO,OAAO,IAAA;AAC5B,UAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,WAAA,EAAY;AAAA,QACpC,CAAC,CAAA,CACA,MAAA,CAAO,CAAC,CAAA,KAAiE,MAAM,IAAI,CAAA;AAEtF,QAAA,MAAM,UAAA,GAAa,MAAA,CAAO,QAAA,CAAS,YAAY,CAAA;AAC/C,QAAA,MAAM,cAAc,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,IAAK,UAAA,GAAa,IAAI,UAAA,GAAa,CAAA;AAEjF,QAAA,OAAO;AAAA,UACL,OAAO,KAAA,CAAM,KAAA;AAAA,UACb,OAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAA,SAAE;AACA,QAAA,MAAM,YAAY,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF;AAAA,GACD,CAAA;AACH;AC7EA,IAAMA,YAAAA,GAAcC,EAAE,MAAA,CAAO;AAAA,EAC3B,KAAKA,CAAAA,CAAE,MAAA,GAAS,GAAA,EAAI,CAAE,SAAS,kBAAkB;AACnD,CAAC,CAAA;AAED,IAAMC,aAAAA,GAAeD,EAAE,MAAA,CAAO;AAAA,EAC5B,GAAA,EAAKA,EAAE,MAAA,EAAO;AAAA,EACd,OAAA,EAASA,CAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,0BAA0B;AACzD,CAAC,CAAA;AAEM,SAAS,0BAA0B,MAAA,EAAkC;AAC1E,EAAA,OAAOE,UAAAA,CAAW;AAAA,IAChB,EAAA,EAAI,kBAAA;AAAA,IACJ,WAAA,EACE,0LAAA;AAAA,IACF,WAAA,EAAAH,YAAAA;AAAA,IACA,YAAA,EAAAE,aAAAA;AAAA,IACA,OAAA,EAAS,OAAM,KAAA,KAAS;AACtB,MAAA,MAAM,MAAA,GAAS,oBAAoB,MAAM,CAAA;AACzC,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,SAAA,CAAU,MAAM,GAAA,EAAK;AAAA,UAChD,UAAA,EAAY;AAAA,SACb,CAAA;AAED,QAAA,OAAO;AAAA,UACL,KAAK,KAAA,CAAM,GAAA;AAAA,UACX;AAAA,SACF;AAAA,MACF,CAAA,SAAE;AACA,QAAA,MAAM,YAAY,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF;AAAA,GACD,CAAA;AACH;;;AClCO,SAAS,sBAAsB,MAAA,EAAkC;AACtE,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,2BAA2B,MAAM,CAAA;AAAA,IAC5C,QAAA,EAAU,0BAA0B,MAAM;AAAA,GAC5C;AACF","file":"index.js","sourcesContent":["const REQUEST_ENDPOINT = 'https://api.brightdata.com/request';\nconst DEFAULT_SERP_ZONE = 'sdk_serp';\nconst DEFAULT_WEB_UNLOCKER_ZONE = 'sdk_unlocker';\nconst DEFAULT_TIMEOUT = 120_000;\n\ntype RequestFormat = 'raw' | 'json';\ntype DataFormat = 'html' | 'markdown' | 'screenshot';\n\nexport interface BrightDataClientOptions {\n [key: string]: unknown;\n apiKey?: string;\n timeout?: number;\n webUnlockerZone?: string;\n serpZone?: string;\n}\n\ninterface RequestOptions {\n country?: string;\n dataFormat?: DataFormat;\n format?: RequestFormat;\n method?: string;\n timeout?: number;\n zone?: string;\n}\n\ninterface SearchOptions extends RequestOptions {\n language?: string;\n start?: number;\n}\n\ninterface BrightDataRequestBody {\n country?: string;\n data_format?: Exclude<DataFormat, 'html'>;\n format: RequestFormat;\n method: string;\n url: string;\n zone: string;\n}\n\nexport interface BrightDataClient {\n search: {\n google: (query: string, options?: SearchOptions) => Promise<unknown>;\n };\n scrapeUrl: (url: string, options?: RequestOptions) => Promise<string>;\n close: () => Promise<void>;\n}\n\nasync function requestBrightData(\n apiKey: string,\n body: BrightDataRequestBody,\n timeout = DEFAULT_TIMEOUT,\n): Promise<unknown> {\n const effectiveTimeout = Number.isFinite(timeout) && timeout > 0 ? timeout : DEFAULT_TIMEOUT;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);\n\n try {\n const response = await fetch(REQUEST_ENDPOINT, {\n body: JSON.stringify(body),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n signal: controller.signal,\n });\n\n const responseText = await response.text();\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n throw new Error('invalid API key or insufficient permissions');\n }\n\n if (response.status === 400) {\n throw new Error(`bad request: ${responseText}`);\n }\n\n throw new Error(`request failed with status ${response.status}: ${responseText}`);\n }\n\n if (body.format === 'json') {\n return responseText ? JSON.parse(responseText) : {};\n }\n\n return responseText;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timed out after ${effectiveTimeout}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\nfunction buildGoogleSearchUrl(query: string, options: SearchOptions = {}) {\n const url = new URL('https://www.google.com/search');\n url.searchParams.set('q', query.trim());\n if ((options.format ?? 'json') === 'json') {\n url.searchParams.set('brd_json', '1');\n }\n url.searchParams.set('hl', options.language ?? 'en');\n\n if (options.country) {\n url.searchParams.set('gl', options.country);\n }\n\n if (options.start !== undefined) {\n url.searchParams.set('start', String(options.start));\n }\n\n return url.toString();\n}\n\nfunction toRequestBody(url: string, zone: string, options: RequestOptions = {}): BrightDataRequestBody {\n const body: BrightDataRequestBody = {\n format: options.format ?? 'raw',\n method: options.method ?? 'GET',\n url,\n zone,\n };\n\n if (options.country) {\n body.country = options.country;\n }\n\n if (options.dataFormat && options.dataFormat !== 'html') {\n body.data_format = options.dataFormat;\n }\n\n return body;\n}\n\nexport function getBrightDataClient(config?: BrightDataClientOptions): BrightDataClient {\n const apiKey = config?.apiKey ?? process.env.BRIGHTDATA_API_TOKEN;\n if (!apiKey) {\n throw new Error(\n 'Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.',\n );\n }\n\n const timeout = config?.timeout;\n const serpZone = config?.serpZone ?? process.env.BRIGHTDATA_SERP_ZONE ?? DEFAULT_SERP_ZONE;\n const webUnlockerZone =\n config?.webUnlockerZone ?? process.env.BRIGHTDATA_WEB_UNLOCKER_ZONE ?? DEFAULT_WEB_UNLOCKER_ZONE;\n\n return {\n search: {\n google: async (query: string, options: SearchOptions = {}) => {\n if (options.language && !/^[a-z]{2}$/i.test(options.language)) {\n throw new Error('language must be a two-letter code (e.g. \"en\", \"es\")');\n }\n\n const normalizedOptions = options.language\n ? { ...options, language: options.language.toLowerCase() }\n : options;\n\n const url = buildGoogleSearchUrl(query, normalizedOptions);\n return requestBrightData(\n apiKey,\n toRequestBody(url, normalizedOptions.zone ?? serpZone, {\n ...normalizedOptions,\n format: normalizedOptions.format ?? 'json',\n method: 'GET',\n }),\n normalizedOptions.timeout ?? timeout,\n );\n },\n },\n scrapeUrl: async (url: string, options: RequestOptions = {}) => {\n const response = await requestBrightData(\n apiKey,\n toRequestBody(url, options.zone ?? webUnlockerZone, options),\n options.timeout ?? timeout,\n );\n\n return typeof response === 'string' ? response : JSON.stringify(response);\n },\n close: async () => {},\n };\n}\n\nexport async function closeClient(client: BrightDataClient): Promise<void> {\n const close = client.close;\n try {\n await close.call(client);\n } catch {\n // best-effort cleanup; never mask the primary tool error from the finally block\n }\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n query: z.string().describe('The search query'),\n country: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Country must be a 2-letter code')\n .optional()\n .describe('2-letter country code for geo-targeted results (e.g., \"us\", \"gb\")'),\n language: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Language must be a 2-letter code')\n .optional()\n .describe('Language code for localized Google results (e.g., \"en\", \"es\", \"fr\")'),\n start: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Result offset for pagination (e.g. 10 to get the second page of 10 results)'),\n});\n\nconst outputSchema = z.object({\n query: z.string(),\n results: z.array(\n z.object({\n link: z.string(),\n title: z.string(),\n description: z.string(),\n }),\n ),\n currentPage: z.number(),\n});\n\nexport function createBrightDataSearchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-search',\n description:\n \"Search Google and get back parsed organic results (link, title, description). Uses Bright Data's SERP API which bypasses bot detection. Supports country and language targeting, plus pagination via result offset.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const rawResponse = await client.search.google(input.query, {\n country: input.country,\n language: input.language,\n start: input.start,\n });\n\n const response: { organic?: unknown; current_page?: unknown } =\n typeof rawResponse === 'string' ? JSON.parse(rawResponse) : rawResponse;\n\n const organic = Array.isArray(response.organic) ? response.organic : [];\n const results = organic\n .map((entry: unknown) => {\n if (!entry || typeof entry !== 'object') return null;\n const e = entry as Record<string, unknown>;\n const link = typeof e.link === 'string' ? e.link.trim() : '';\n const title = typeof e.title === 'string' ? e.title.trim() : '';\n const description = typeof e.description === 'string' ? e.description.trim() : '';\n if (!link || !title) return null;\n return { link, title, description };\n })\n .filter((r): r is { link: string; title: string; description: string } => r !== null);\n\n const parsedPage = Number(response.current_page);\n const currentPage = Number.isFinite(parsedPage) && parsedPage > 0 ? parsedPage : 1;\n\n return {\n query: input.query,\n results,\n currentPage,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n url: z.string().url().describe('The URL to fetch'),\n});\n\nconst outputSchema = z.object({\n url: z.string(),\n content: z.string().describe('Page content as Markdown'),\n});\n\nexport function createBrightDataFetchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-fetch',\n description:\n \"Fetch a webpage and return its content as Markdown. Uses Bright Data's Web Unlocker which bypasses bot detection and CAPTCHAs. Pass any URL, including pages that block normal scrapers.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const content = await client.scrapeUrl(input.url, {\n dataFormat: 'markdown',\n });\n\n return {\n url: input.url,\n content,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import type { BrightDataClientOptions } from './client.js';\nimport { createBrightDataFetchTool } from './fetch.js';\nimport { createBrightDataSearchTool } from './search.js';\n\nexport function createBrightDataTools(config?: BrightDataClientOptions) {\n return {\n webSearch: createBrightDataSearchTool(config),\n webFetch: createBrightDataFetchTool(config),\n };\n}\n"]}
{"version":3,"sources":["../src/client.ts","../src/search.ts","../src/fetch.ts","../src/tools.ts"],"names":["inputSchema","z","outputSchema","createTool"],"mappings":"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","file":"index.js","sourcesContent":["const REQUEST_ENDPOINT = 'https://api.brightdata.com/request';\nconst DEFAULT_SERP_ZONE = 'sdk_serp';\nconst DEFAULT_WEB_UNLOCKER_ZONE = 'sdk_unlocker';\nconst DEFAULT_TIMEOUT = 120_000;\n\ntype RequestFormat = 'raw' | 'json';\ntype DataFormat = 'html' | 'markdown' | 'screenshot';\n\nexport interface BrightDataClientOptions {\n [key: string]: unknown;\n apiKey?: string;\n timeout?: number;\n webUnlockerZone?: string;\n serpZone?: string;\n}\n\ninterface RequestOptions {\n country?: string;\n dataFormat?: DataFormat;\n format?: RequestFormat;\n method?: string;\n timeout?: number;\n zone?: string;\n}\n\ninterface SearchOptions extends RequestOptions {\n language?: string;\n start?: number;\n}\n\ninterface BrightDataRequestBody {\n country?: string;\n data_format?: Exclude<DataFormat, 'html'>;\n format: RequestFormat;\n method: string;\n url: string;\n zone: string;\n}\n\nexport interface BrightDataClient {\n search: {\n google: (query: string, options?: SearchOptions) => Promise<unknown>;\n };\n scrapeUrl: (url: string, options?: RequestOptions) => Promise<string>;\n close: () => Promise<void>;\n}\n\nasync function requestBrightData(\n apiKey: string,\n body: BrightDataRequestBody,\n timeout = DEFAULT_TIMEOUT,\n): Promise<unknown> {\n const effectiveTimeout = Number.isFinite(timeout) && timeout > 0 ? timeout : DEFAULT_TIMEOUT;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);\n\n try {\n const response = await fetch(REQUEST_ENDPOINT, {\n body: JSON.stringify(body),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n signal: controller.signal,\n });\n\n const responseText = await response.text();\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n throw new Error('invalid API key or insufficient permissions');\n }\n\n if (response.status === 400) {\n throw new Error(`bad request: ${responseText}`);\n }\n\n throw new Error(`request failed with status ${response.status}: ${responseText}`);\n }\n\n if (body.format === 'json') {\n return responseText ? JSON.parse(responseText) : {};\n }\n\n return responseText;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timed out after ${effectiveTimeout}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\nfunction buildGoogleSearchUrl(query: string, options: SearchOptions = {}) {\n const url = new URL('https://www.google.com/search');\n url.searchParams.set('q', query.trim());\n if ((options.format ?? 'json') === 'json') {\n url.searchParams.set('brd_json', '1');\n }\n url.searchParams.set('hl', options.language ?? 'en');\n\n if (options.country) {\n url.searchParams.set('gl', options.country);\n }\n\n if (options.start !== undefined) {\n url.searchParams.set('start', String(options.start));\n }\n\n return url.toString();\n}\n\nfunction toRequestBody(url: string, zone: string, options: RequestOptions = {}): BrightDataRequestBody {\n const body: BrightDataRequestBody = {\n format: options.format ?? 'raw',\n method: options.method ?? 'GET',\n url,\n zone,\n };\n\n if (options.country) {\n body.country = options.country;\n }\n\n if (options.dataFormat && options.dataFormat !== 'html') {\n body.data_format = options.dataFormat;\n }\n\n return body;\n}\n\nexport function getBrightDataClient(config?: BrightDataClientOptions): BrightDataClient {\n const apiKey = config?.apiKey ?? process.env.BRIGHTDATA_API_TOKEN;\n if (!apiKey) {\n throw new Error('Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.');\n }\n\n const timeout = config?.timeout;\n const serpZone = config?.serpZone ?? process.env.BRIGHTDATA_SERP_ZONE ?? DEFAULT_SERP_ZONE;\n const webUnlockerZone =\n config?.webUnlockerZone ?? process.env.BRIGHTDATA_WEB_UNLOCKER_ZONE ?? DEFAULT_WEB_UNLOCKER_ZONE;\n\n return {\n search: {\n google: async (query: string, options: SearchOptions = {}) => {\n if (options.language && !/^[a-z]{2}$/i.test(options.language)) {\n throw new Error('language must be a two-letter code (e.g. \"en\", \"es\")');\n }\n\n const normalizedOptions = options.language ? { ...options, language: options.language.toLowerCase() } : options;\n\n const url = buildGoogleSearchUrl(query, normalizedOptions);\n return requestBrightData(\n apiKey,\n toRequestBody(url, normalizedOptions.zone ?? serpZone, {\n ...normalizedOptions,\n format: normalizedOptions.format ?? 'json',\n method: 'GET',\n }),\n normalizedOptions.timeout ?? timeout,\n );\n },\n },\n scrapeUrl: async (url: string, options: RequestOptions = {}) => {\n const response = await requestBrightData(\n apiKey,\n toRequestBody(url, options.zone ?? webUnlockerZone, options),\n options.timeout ?? timeout,\n );\n\n return typeof response === 'string' ? response : JSON.stringify(response);\n },\n close: async () => {},\n };\n}\n\nexport async function closeClient(client: BrightDataClient): Promise<void> {\n const close = client.close;\n try {\n await close.call(client);\n } catch {\n // best-effort cleanup; never mask the primary tool error from the finally block\n }\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n query: z.string().describe('The search query'),\n country: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Country must be a 2-letter code')\n .optional()\n .describe('2-letter country code for geo-targeted results (e.g., \"us\", \"gb\")'),\n language: z\n .string()\n .regex(/^[a-z]{2}$/i, 'Language must be a 2-letter code')\n .optional()\n .describe('Language code for localized Google results (e.g., \"en\", \"es\", \"fr\")'),\n start: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Result offset for pagination (e.g. 10 to get the second page of 10 results)'),\n});\n\nconst outputSchema = z.object({\n query: z.string(),\n results: z.array(\n z.object({\n link: z.string(),\n title: z.string(),\n description: z.string(),\n }),\n ),\n currentPage: z.number(),\n});\n\nexport function createBrightDataSearchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-search',\n description:\n \"Search Google and get back parsed organic results (link, title, description). Uses Bright Data's SERP API which bypasses bot detection. Supports country and language targeting, plus pagination via result offset.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const rawResponse = await client.search.google(input.query, {\n country: input.country,\n language: input.language,\n start: input.start,\n });\n\n const response: { organic?: unknown; current_page?: unknown } =\n typeof rawResponse === 'string' ? JSON.parse(rawResponse) : rawResponse;\n\n const organic = Array.isArray(response.organic) ? response.organic : [];\n const results = organic\n .map((entry: unknown) => {\n if (!entry || typeof entry !== 'object') return null;\n const e = entry as Record<string, unknown>;\n const link = typeof e.link === 'string' ? e.link.trim() : '';\n const title = typeof e.title === 'string' ? e.title.trim() : '';\n const description = typeof e.description === 'string' ? e.description.trim() : '';\n if (!link || !title) return null;\n return { link, title, description };\n })\n .filter((r): r is { link: string; title: string; description: string } => r !== null);\n\n const parsedPage = Number(response.current_page);\n const currentPage = Number.isFinite(parsedPage) && parsedPage > 0 ? parsedPage : 1;\n\n return {\n query: input.query,\n results,\n currentPage,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { closeClient, getBrightDataClient } from './client.js';\nimport type { BrightDataClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n url: z.string().url().describe('The URL to fetch'),\n});\n\nconst outputSchema = z.object({\n url: z.string(),\n content: z.string().describe('Page content as Markdown'),\n});\n\nexport function createBrightDataFetchTool(config?: BrightDataClientOptions) {\n return createTool({\n id: 'brightdata-fetch',\n description:\n \"Fetch a webpage and return its content as Markdown. Uses Bright Data's Web Unlocker which bypasses bot detection and CAPTCHAs. Pass any URL, including pages that block normal scrapers.\",\n inputSchema,\n outputSchema,\n execute: async input => {\n const client = getBrightDataClient(config);\n try {\n const content = await client.scrapeUrl(input.url, {\n dataFormat: 'markdown',\n });\n\n return {\n url: input.url,\n content,\n };\n } finally {\n await closeClient(client);\n }\n },\n });\n}\n","import type { BrightDataClientOptions } from './client.js';\nimport { createBrightDataFetchTool } from './fetch.js';\nimport { createBrightDataSearchTool } from './search.js';\n\nexport function createBrightDataTools(config?: BrightDataClientOptions) {\n return {\n webSearch: createBrightDataSearchTool(config),\n webFetch: createBrightDataFetchTool(config),\n };\n}\n"]}
{
"name": "@mastra/brightdata",
"version": "0.2.1",
"version": "0.2.3",
"description": "Bright Data web search and web fetch tools for Mastra agents",

@@ -53,7 +53,7 @@ "type": "module",

"typescript": "^6.0.3",
"vitest": "4.1.5",
"vitest": "4.1.8",
"zod": "^4.4.3",
"@internal/lint": "0.0.100",
"@mastra/core": "1.38.0",
"@internal/types-builder": "0.0.75"
"@internal/lint": "0.0.105",
"@internal/types-builder": "0.0.80",
"@mastra/core": "1.43.0"
},

@@ -60,0 +60,0 @@ "scripts": {