@tool-bridge/server 0.1.1 → 0.3.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.
Files changed (107) hide show
  1. package/dist/airtable-V6446SVY.js +792 -0
  2. package/dist/alt_text_generator_ai-HV7JZPDT.js +72 -0
  3. package/dist/amap-TTTVB6WS.js +755 -0
  4. package/dist/anthropic-JH3RA363.js +224 -0
  5. package/dist/apify-ETNN7ITU.js +262 -0
  6. package/dist/brave_search-3DDR2MMB.js +322 -0
  7. package/dist/chunk-CSJEZHQO.js +252 -0
  8. package/dist/chunk-JLTYA2B3.js +20121 -0
  9. package/dist/chunk-K7FVSFUX.js +333 -0
  10. package/dist/{chunk-MQEYFCJB.js → chunk-KGYJEEBI.js} +2770 -21574
  11. package/dist/circleci-MX3TX3HC.js +409 -0
  12. package/dist/clerk-MRPORVF4.js +1036 -0
  13. package/dist/cloudflare_dns-OWP7DD7L.js +605 -0
  14. package/dist/cohere-GPECP66S.js +197 -0
  15. package/dist/confluence-BN7LZ6BC.js +436 -0
  16. package/dist/convertapi-SBEOFOFQ.js +161 -0
  17. package/dist/currencyapi-P2YY7Y7P.js +306 -0
  18. package/dist/deepseek-MWB3NYIN.js +205 -0
  19. package/dist/docker_hub-3JSCIGQ3.js +946 -0
  20. package/dist/dropbox-RFIBDAXO.js +1308 -0
  21. package/dist/dub-YVP57ELQ.js +706 -0
  22. package/dist/e2b-NFSUHTZR.js +305 -0
  23. package/dist/exa-KTDY6IV3.js +360 -0
  24. package/dist/fal_ai-OCUENLNQ.js +405 -0
  25. package/dist/feishu-5CWBQ7E5.js +225 -0
  26. package/dist/feishu_custom_bot-ZJR22OK6.js +240 -0
  27. package/dist/figma-YULGANSA.js +798 -0
  28. package/dist/firehydrant-2V6YSYAP.js +573 -0
  29. package/dist/fixer-LTCDB3CJ.js +171 -0
  30. package/dist/fly-IXPKMAML.js +478 -0
  31. package/dist/front-KRFB4M5X.js +379 -0
  32. package/dist/geocodio-VVURKYHQ.js +236 -0
  33. package/dist/ghost-6J2RIOUB.js +341 -0
  34. package/dist/github-5Z6KQRYH.js +5410 -0
  35. package/dist/gmail-KU4NZ7VA.js +1894 -0
  36. package/dist/googlecalendar-X44DFFXG.js +2539 -0
  37. package/dist/googledocs-WSGLPKSF.js +1322 -0
  38. package/dist/grafana-4PKSSDXY.js +817 -0
  39. package/dist/graphhopper-DF65ZNGK.js +336 -0
  40. package/dist/index.d.ts +181 -2
  41. package/dist/index.js +2 -1
  42. package/dist/ip2proxy-UCAQ5P2J.js +118 -0
  43. package/dist/ipgeolocation_io-UX6FCA2S.js +333 -0
  44. package/dist/ipqualityscore-MKTRXIZJ.js +287 -0
  45. package/dist/jina_ai-MRHPCSV5.js +119 -0
  46. package/dist/jira-EG7ZPOIW.js +627 -0
  47. package/dist/langsmith-FNO3RCOZ.js +597 -0
  48. package/dist/lemlist-SN6BJHSG.js +298 -0
  49. package/dist/linear-H3VU4PSD.js +2163 -0
  50. package/dist/logsnag-OY2JJT2H.js +167 -0
  51. package/dist/main.js +246 -2
  52. package/dist/mattermost-C5SQ7PGD.js +320 -0
  53. package/dist/mem0-LMLE5BFC.js +567 -0
  54. package/dist/memos-UWFAMBZC.js +781 -0
  55. package/dist/metabase-SRYDSDJ6.js +365 -0
  56. package/dist/mistral_ai-YNIJ7VDM.js +1195 -0
  57. package/dist/mother_duck-CPGOFEXE.js +322 -0
  58. package/dist/ngrok-CDJFBSOM.js +375 -0
  59. package/dist/notes-DIVFH3P3.js +109 -0
  60. package/dist/notion-HGDKS4HK.js +945 -0
  61. package/dist/open_exchange_rates-COHHYJDD.js +216 -0
  62. package/dist/openai-4TRT66GW.js +795 -0
  63. package/dist/opengraph_io-YKVW4PXI.js +377 -0
  64. package/dist/openrouter-6CV7B7V5.js +444 -0
  65. package/dist/outline-YWDUK5F7.js +604 -0
  66. package/dist/paddle-MEU7HWDZ.js +464 -0
  67. package/dist/perplexity-MRQUDBIC.js +238 -0
  68. package/dist/pinecone-JI7X2TAF.js +599 -0
  69. package/dist/pipedrive-6JQPAW23.js +453 -0
  70. package/dist/polar-7BF56CMC.js +400 -0
  71. package/dist/posthog-YPU5ADEN.js +3462 -0
  72. package/dist/postmark-BEU5OFKU.js +441 -0
  73. package/dist/prerender-UT5GOOZH.js +180 -0
  74. package/dist/pubmed-3SGOE24Q.js +1052 -0
  75. package/dist/railway-CEK4GLRQ.js +452 -0
  76. package/dist/readwise-DXQUQU67.js +482 -0
  77. package/dist/render-7TGAU5AW.js +473 -0
  78. package/dist/replicate-VICFSQ5A.js +347 -0
  79. package/dist/resend-3E76WK3O.js +100 -0
  80. package/dist/rootly-36GY46BY.js +345 -0
  81. package/dist/scrapfly-VDVUYAHX.js +289 -0
  82. package/dist/scrapingbee-3KTPMAVY.js +247 -0
  83. package/dist/screenshot_fyi-LKG62C3J.js +116 -0
  84. package/dist/semantic_scholar-4WREECYO.js +626 -0
  85. package/dist/sentry-HUQTGXOV.js +1139 -0
  86. package/dist/shodan-SGRKU4KS.js +303 -0
  87. package/dist/shopify-YCZ4L5HT.js +620 -0
  88. package/dist/stripe-OEBKMELB.js +583 -0
  89. package/dist/supabase-I3DBY7L4.js +937 -0
  90. package/dist/tavily-B2YHCNRD.js +349 -0
  91. package/dist/telegram-2VYJELZX.js +1773 -0
  92. package/dist/telnyx-HHXD3CXL.js +237 -0
  93. package/dist/todoist-PHFDEEIS.js +672 -0
  94. package/dist/trello-WUSAK6YN.js +1091 -0
  95. package/dist/turso-FW56U2B3.js +432 -0
  96. package/dist/twilio-M5JI7XHA.js +321 -0
  97. package/dist/umami-HAYODRC4.js +411 -0
  98. package/dist/unsplash-EDPTNEHJ.js +364 -0
  99. package/dist/upstash_redis-GC2CLIWD.js +299 -0
  100. package/dist/uptimerobot-XMSNYLIT.js +481 -0
  101. package/dist/v2ex-KU4ECD65.js +672 -0
  102. package/dist/vercel-THPCEFHW.js +1096 -0
  103. package/dist/wolfram_alpha_api-WHHTH4GU.js +212 -0
  104. package/dist/wordpress-O6TQEQNF.js +822 -0
  105. package/dist/workos-A3VHHWI3.js +681 -0
  106. package/dist/zhihu-BJAI64YJ.js +273 -0
  107. package/package.json +5 -4
@@ -0,0 +1,247 @@
1
+ import {
2
+ createProviderPlugin,
3
+ guardedFetch,
4
+ requireApiKey,
5
+ upstreamError
6
+ } from "./chunk-CSJEZHQO.js";
7
+ import "./chunk-K7FVSFUX.js";
8
+ import {
9
+ external_exports
10
+ } from "./chunk-JLTYA2B3.js";
11
+ import "./chunk-MLKGABMK.js";
12
+
13
+ // ../plugins/src/scrapingbee/api.ts
14
+ var SERVICE = "scrapingbee";
15
+ var API_BASE = "https://app.scrapingbee.com/api/v1/";
16
+ function record(value) {
17
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
18
+ }
19
+ function compact(input) {
20
+ return Object.fromEntries(
21
+ Object.entries(input).filter((entry) => entry[1] !== void 0)
22
+ );
23
+ }
24
+ function str(value) {
25
+ return value === void 0 || value === "" ? void 0 : value;
26
+ }
27
+ function bool(value) {
28
+ return value === void 0 ? void 0 : String(value);
29
+ }
30
+ function int(value) {
31
+ return value === void 0 ? void 0 : String(value);
32
+ }
33
+ function buildUrl(path, apiKey, params) {
34
+ const url = new URL(path, API_BASE);
35
+ url.searchParams.set("api_key", apiKey);
36
+ for (const [key, value] of Object.entries(params)) {
37
+ if (value !== void 0) url.searchParams.set(key, value);
38
+ }
39
+ return url.toString();
40
+ }
41
+ function errorMessage(body, status) {
42
+ const trimmed = body.trim();
43
+ if (trimmed === "") return `ScrapingBee request failed with status ${status}`;
44
+ try {
45
+ const payload = record(JSON.parse(trimmed));
46
+ const message = typeof payload?.message === "string" ? payload.message.trim() : "";
47
+ if (message !== "") return message;
48
+ const error = typeof payload?.error === "string" ? payload.error.trim() : "";
49
+ if (error !== "") return error;
50
+ } catch {
51
+ }
52
+ return trimmed;
53
+ }
54
+ function headerNumber(headers, name) {
55
+ const value = headers.get(name);
56
+ if (value === null || value === "") return void 0;
57
+ const parsed = Number(value);
58
+ return Number.isFinite(parsed) ? parsed : void 0;
59
+ }
60
+ function headerInteger(headers, name) {
61
+ const value = headers.get(name);
62
+ if (value === null || value === "") return void 0;
63
+ const trimmed = value.trim();
64
+ if (!/^-?\d+$/.test(trimmed)) return void 0;
65
+ const parsed = Number(trimmed);
66
+ return Number.isInteger(parsed) ? parsed : void 0;
67
+ }
68
+ function requireInt(value, field) {
69
+ if (typeof value !== "number" || !Number.isInteger(value)) {
70
+ throw upstreamError(502, `scrapingbee response missing ${field}`);
71
+ }
72
+ return value;
73
+ }
74
+ function requireStr(value, field) {
75
+ if (typeof value !== "string" || value === "") {
76
+ throw upstreamError(502, `scrapingbee response missing ${field}`);
77
+ }
78
+ return value;
79
+ }
80
+ function fetchParams(input) {
81
+ return compact({
82
+ url: input.url,
83
+ render_js: bool(input.renderJs),
84
+ wait: int(input.waitMs),
85
+ wait_for: str(input.waitFor),
86
+ device: str(input.device),
87
+ block_ads: bool(input.blockAds),
88
+ block_resources: bool(input.blockResources),
89
+ country_code: str(input.countryCode),
90
+ premium_proxy: bool(input.premiumProxy),
91
+ stealth_proxy: bool(input.stealthProxy),
92
+ transparent_status_code: bool(input.transparentStatusCode),
93
+ retry: int(input.retry)
94
+ });
95
+ }
96
+ async function requestText(ctx, path, params) {
97
+ const response = await guardedFetch(buildUrl(path, requireApiKey(ctx, SERVICE), params), { method: "GET" });
98
+ const body = await response.text();
99
+ if (!response.ok) throw upstreamError(response.status, errorMessage(body, response.status));
100
+ return { body, response };
101
+ }
102
+ async function fetchHtml(input, ctx) {
103
+ const { body, response } = await requestText(ctx, "", fetchParams(input));
104
+ return compact({
105
+ html: body,
106
+ statusCode: response.status,
107
+ contentType: response.headers.get("content-type") ?? void 0,
108
+ initialStatusCode: headerInteger(response.headers, "spb-initial-status-code"),
109
+ resolvedUrl: response.headers.get("spb-resolved-url") ?? void 0,
110
+ creditCost: headerNumber(response.headers, "spb-cost")
111
+ });
112
+ }
113
+ async function extractData(input, ctx) {
114
+ const { body, response } = await requestText(ctx, "", {
115
+ ...fetchParams(input),
116
+ extract_rules: JSON.stringify(input.extractRules)
117
+ });
118
+ let payload;
119
+ try {
120
+ payload = JSON.parse(body);
121
+ } catch {
122
+ throw upstreamError(502, "scrapingbee extract_data response is not valid JSON");
123
+ }
124
+ const data = record(payload);
125
+ if (data === void 0) throw upstreamError(502, "scrapingbee extract_data response must be a JSON object");
126
+ return compact({
127
+ data: { ...data },
128
+ statusCode: response.status,
129
+ resolvedUrl: response.headers.get("spb-resolved-url") ?? void 0,
130
+ creditCost: headerNumber(response.headers, "spb-cost")
131
+ });
132
+ }
133
+ async function getUsageStats(_input, ctx) {
134
+ const { body } = await requestText(ctx, "usage", {});
135
+ let payload;
136
+ try {
137
+ payload = JSON.parse(body);
138
+ } catch {
139
+ throw upstreamError(502, "scrapingbee usage response is not valid JSON");
140
+ }
141
+ const usage = record(payload);
142
+ if (usage === void 0) throw upstreamError(502, "scrapingbee usage response must be an object");
143
+ return {
144
+ usage: {
145
+ max_api_credit: requireInt(usage.max_api_credit, "max_api_credit"),
146
+ used_api_credit: requireInt(usage.used_api_credit, "used_api_credit"),
147
+ max_concurrency: requireInt(usage.max_concurrency, "max_concurrency"),
148
+ current_concurrency: requireInt(usage.current_concurrency, "current_concurrency"),
149
+ renewal_subscription_date: requireStr(usage.renewal_subscription_date, "renewal_subscription_date")
150
+ }
151
+ };
152
+ }
153
+
154
+ // ../plugins/src/scrapingbee/schema.ts
155
+ var fetchHtmlInput = external_exports.strictObject({
156
+ url: external_exports.url().describe("The public URL to fetch with ScrapingBee."),
157
+ renderJs: external_exports.boolean().describe("Whether ScrapingBee should render JavaScript before returning the page.").optional(),
158
+ waitMs: external_exports.int().min(0).describe("How many milliseconds ScrapingBee should wait before returning the page.").optional(),
159
+ waitFor: external_exports.string().min(1).describe("The CSS selector ScrapingBee should wait for before returning the page.").optional(),
160
+ device: external_exports.enum(["desktop", "mobile"]).describe("The device preset used for the request.").optional(),
161
+ blockAds: external_exports.boolean().describe("Whether ScrapingBee should block ads on the page.").optional(),
162
+ blockResources: external_exports.boolean().describe("Whether ScrapingBee should block images and CSS resources.").optional(),
163
+ countryCode: external_exports.string().min(2).max(2).describe("The two-letter country code used for request geolocation.").optional(),
164
+ premiumProxy: external_exports.boolean().describe("Whether ScrapingBee should use premium proxy routing.").optional(),
165
+ stealthProxy: external_exports.boolean().describe("Whether ScrapingBee should use stealth proxy routing.").optional(),
166
+ transparentStatusCode: external_exports.boolean().describe("Whether ScrapingBee should return the target page status code transparently.").optional(),
167
+ retry: external_exports.int().min(1).describe("How many times ScrapingBee should retry the request on failure.").optional()
168
+ }).describe("The input payload for fetching page HTML with ScrapingBee.");
169
+ var fetchHtmlOutput = external_exports.strictObject({
170
+ html: external_exports.string().describe("The HTML content returned by ScrapingBee."),
171
+ statusCode: external_exports.int().describe("The HTTP status code returned by ScrapingBee."),
172
+ contentType: external_exports.string().describe("The content type returned by ScrapingBee.").optional(),
173
+ initialStatusCode: external_exports.int().describe("The original target page status code reported by ScrapingBee.").optional(),
174
+ resolvedUrl: external_exports.string().describe("The final resolved URL reported by ScrapingBee.").optional(),
175
+ creditCost: external_exports.number().describe("The request credit cost reported by ScrapingBee.").optional()
176
+ }).describe("The output payload for fetching page HTML with ScrapingBee.");
177
+ var extractDataInput = external_exports.strictObject({
178
+ url: external_exports.url().describe("The public URL to extract data from with ScrapingBee."),
179
+ extractRules: external_exports.record(external_exports.string(), external_exports.unknown().describe("A JSON-compatible value used in ScrapingBee extraction rules or responses.")).describe("The extraction rules object serialized into the extract_rules query parameter."),
180
+ renderJs: external_exports.boolean().describe("Whether ScrapingBee should render JavaScript before returning the page.").optional(),
181
+ waitMs: external_exports.int().min(0).describe("How many milliseconds ScrapingBee should wait before returning the page.").optional(),
182
+ waitFor: external_exports.string().min(1).describe("The CSS selector ScrapingBee should wait for before returning the page.").optional(),
183
+ device: external_exports.enum(["desktop", "mobile"]).describe("The device preset used for the request.").optional(),
184
+ blockAds: external_exports.boolean().describe("Whether ScrapingBee should block ads on the page.").optional(),
185
+ blockResources: external_exports.boolean().describe("Whether ScrapingBee should block images and CSS resources.").optional(),
186
+ countryCode: external_exports.string().min(2).max(2).describe("The two-letter country code used for request geolocation.").optional(),
187
+ premiumProxy: external_exports.boolean().describe("Whether ScrapingBee should use premium proxy routing.").optional(),
188
+ stealthProxy: external_exports.boolean().describe("Whether ScrapingBee should use stealth proxy routing.").optional(),
189
+ transparentStatusCode: external_exports.boolean().describe("Whether ScrapingBee should return the target page status code transparently.").optional(),
190
+ retry: external_exports.int().min(1).describe("How many times ScrapingBee should retry the request on failure.").optional()
191
+ }).describe("The input payload for extracting structured data with ScrapingBee.");
192
+ var extractDataOutput = external_exports.strictObject({
193
+ data: external_exports.record(external_exports.string(), external_exports.unknown().describe("A JSON-compatible value used in ScrapingBee extraction rules or responses.")).describe("The structured data object returned by ScrapingBee extract_rules."),
194
+ statusCode: external_exports.int().describe("The HTTP status code returned by ScrapingBee."),
195
+ resolvedUrl: external_exports.string().describe("The final resolved URL reported by ScrapingBee.").optional(),
196
+ creditCost: external_exports.number().describe("The request credit cost reported by ScrapingBee.").optional()
197
+ }).describe("The output payload for extracting structured data with ScrapingBee.");
198
+ var getUsageStatsInput = external_exports.strictObject({}).describe("The input payload for retrieving ScrapingBee usage statistics.");
199
+ var getUsageStatsOutput = external_exports.strictObject({
200
+ usage: external_exports.strictObject({
201
+ max_api_credit: external_exports.int().describe("The maximum API credits available in the current billing period.").optional(),
202
+ used_api_credit: external_exports.int().describe("The API credits already consumed in the current billing period.").optional(),
203
+ max_concurrency: external_exports.int().describe("The maximum number of concurrent requests allowed.").optional(),
204
+ current_concurrency: external_exports.int().describe("The current number of concurrent requests in use.").optional(),
205
+ renewal_subscription_date: external_exports.string().describe("The renewal timestamp for the current subscription period.").optional()
206
+ }).describe("The current ScrapingBee usage snapshot.").optional()
207
+ }).describe("The output payload for retrieving ScrapingBee usage statistics.");
208
+ var scrapingbeeActions = {
209
+ fetch_html: {
210
+ description: "Fetch HTML content from one public URL with optional rendering and proxy controls.",
211
+ effect: "read",
212
+ inputSchema: fetchHtmlInput,
213
+ outputSchema: external_exports.toJSONSchema(fetchHtmlOutput, { io: "output", unrepresentable: "any" })
214
+ },
215
+ extract_data: {
216
+ description: "Extract structured JSON data from one public URL with ScrapingBee extract_rules.",
217
+ effect: "write",
218
+ inputSchema: extractDataInput,
219
+ outputSchema: external_exports.toJSONSchema(extractDataOutput, { io: "output", unrepresentable: "any" })
220
+ },
221
+ get_usage_stats: {
222
+ description: "Retrieve the current ScrapingBee API usage and concurrency statistics.",
223
+ effect: "read",
224
+ inputSchema: getUsageStatsInput,
225
+ outputSchema: external_exports.toJSONSchema(getUsageStatsOutput, { io: "output", unrepresentable: "any" })
226
+ }
227
+ };
228
+
229
+ // ../plugins/src/scrapingbee/index.ts
230
+ function createScrapingbeePlugin() {
231
+ return createProviderPlugin({
232
+ description: "ScrapingBee",
233
+ actions: scrapingbeeActions,
234
+ // 上游的 credentialValidators 打的就是 /usage,它只读、无必填入参且不消耗信用点。
235
+ credentialProbe: "get_usage_stats",
236
+ handlers: {
237
+ fetch_html: fetchHtml,
238
+ extract_data: extractData,
239
+ get_usage_stats: getUsageStats
240
+ }
241
+ });
242
+ }
243
+ var scrapingbee_default = createScrapingbeePlugin();
244
+ export {
245
+ createScrapingbeePlugin,
246
+ scrapingbee_default as default
247
+ };
@@ -0,0 +1,116 @@
1
+ import {
2
+ createProviderPlugin,
3
+ guardedFetch,
4
+ requireApiKey,
5
+ upstreamError
6
+ } from "./chunk-CSJEZHQO.js";
7
+ import "./chunk-K7FVSFUX.js";
8
+ import {
9
+ external_exports
10
+ } from "./chunk-JLTYA2B3.js";
11
+ import "./chunk-MLKGABMK.js";
12
+
13
+ // ../plugins/src/screenshot_fyi/schema.ts
14
+ var takeScreenshotInput = external_exports.strictObject({
15
+ url: external_exports.url().describe("The complete website URL to capture, including the protocol."),
16
+ width: external_exports.int().min(1).describe("The viewport width in pixels.").optional(),
17
+ height: external_exports.int().min(1).describe("The viewport height in pixels.").optional(),
18
+ fullPage: external_exports.boolean().describe("Whether to capture the full scrollable page instead of only the viewport.").optional(),
19
+ darkMode: external_exports.boolean().describe("Whether to render the target page with dark mode enabled.").optional(),
20
+ disableCookieBanners: external_exports.boolean().describe("Whether screenshot.fyi should hide cookie banners before capture.").optional()
21
+ }).describe("The input payload for capturing a website screenshot with screenshot.fyi.");
22
+ var takeScreenshotOutput = external_exports.strictObject({
23
+ url: external_exports.url().describe("The generated screenshot URL returned by screenshot.fyi.").optional()
24
+ }).describe("The output payload for a screenshot.fyi screenshot capture.");
25
+ var screenshotFyiActions = {
26
+ take_screenshot: {
27
+ description: "Capture a website screenshot with screenshot.fyi and return the generated URL.",
28
+ effect: "write",
29
+ inputSchema: takeScreenshotInput,
30
+ outputSchema: external_exports.toJSONSchema(takeScreenshotOutput, { io: "output", unrepresentable: "any" })
31
+ }
32
+ };
33
+
34
+ // ../plugins/src/screenshot_fyi/api.ts
35
+ var SERVICE = "screenshot_fyi";
36
+ var API_BASE = "https://www.screenshot.fyi";
37
+ var CAPTURE_PATH = "/api/take";
38
+ var REQUEST_TIMEOUT_MS = 3e4;
39
+ function toRecord(value) {
40
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
41
+ }
42
+ function text(value) {
43
+ if (typeof value !== "string") return void 0;
44
+ const trimmed = value.trim();
45
+ return trimmed === "" ? void 0 : trimmed;
46
+ }
47
+ function errorMessage(payload, status) {
48
+ const direct = text(payload);
49
+ if (direct !== void 0) return direct;
50
+ const record = toRecord(payload);
51
+ const top = text(record?.error);
52
+ const detail = Array.isArray(record?.details) ? text(toRecord(record.details[0])?.message) : void 0;
53
+ if (top !== void 0 && detail !== void 0) return `${top}: ${detail}`;
54
+ return top ?? detail ?? `screenshot.fyi \u8FD4\u56DE HTTP ${status}`;
55
+ }
56
+ async function readPayload(response) {
57
+ const body = await response.text();
58
+ if (body.trim() === "") return null;
59
+ try {
60
+ return JSON.parse(body);
61
+ } catch {
62
+ throw upstreamError(502, "screenshot.fyi \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94");
63
+ }
64
+ }
65
+ function buildQuery(input) {
66
+ const query = { url: input.url };
67
+ if (input.width !== void 0) query.width = String(input.width);
68
+ if (input.height !== void 0) query.height = String(input.height);
69
+ if (input.fullPage !== void 0) query.fullPage = String(input.fullPage);
70
+ if (input.darkMode !== void 0) query.darkMode = String(input.darkMode);
71
+ if (input.disableCookieBanners !== void 0) query.disableCookieBanners = String(input.disableCookieBanners);
72
+ return query;
73
+ }
74
+ async function capture(url) {
75
+ try {
76
+ return await guardedFetch(url.toString(), {
77
+ method: "GET",
78
+ headers: { accept: "application/json" },
79
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
80
+ });
81
+ } catch (error) {
82
+ if (error instanceof Error && error.name === "TimeoutError") {
83
+ throw upstreamError(504, `screenshot.fyi ${REQUEST_TIMEOUT_MS / 1e3}s \u5185\u6CA1\u6709\u8FD4\u56DE\u622A\u56FE`);
84
+ }
85
+ throw error;
86
+ }
87
+ }
88
+ async function takeScreenshot(input, ctx) {
89
+ const target = new URL(CAPTURE_PATH, API_BASE);
90
+ target.searchParams.set("accessKey", requireApiKey(ctx, SERVICE));
91
+ for (const [key, value] of Object.entries(buildQuery(input))) {
92
+ target.searchParams.set(key, value);
93
+ }
94
+ const response = await capture(target);
95
+ const payload = await readPayload(response);
96
+ if (!response.ok) throw upstreamError(response.status, errorMessage(payload, response.status));
97
+ const screenshotUrl = text(toRecord(payload)?.url);
98
+ if (screenshotUrl === void 0) {
99
+ throw upstreamError(502, "screenshot.fyi \u7684\u6210\u529F\u54CD\u5E94\u91CC\u6CA1\u6709\u622A\u56FE url");
100
+ }
101
+ return { url: screenshotUrl };
102
+ }
103
+
104
+ // ../plugins/src/screenshot_fyi/index.ts
105
+ function createScreenshotFyiPlugin() {
106
+ return createProviderPlugin({
107
+ description: "screenshot.fyi",
108
+ actions: screenshotFyiActions,
109
+ handlers: { take_screenshot: takeScreenshot }
110
+ });
111
+ }
112
+ var screenshot_fyi_default = createScreenshotFyiPlugin();
113
+ export {
114
+ createScreenshotFyiPlugin,
115
+ screenshot_fyi_default as default
116
+ };