@tool-bridge/server 0.1.0 → 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-6SMIQ6QU.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,345 @@
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/rootly/api.ts
14
+ var SERVICE = "rootly";
15
+ var API_BASE = "https://api.rootly.com/v1";
16
+ var JSON_API_CONTENT_TYPE = "application/vnd.api+json";
17
+ function toRecord(value) {
18
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
19
+ }
20
+ function text(value) {
21
+ if (typeof value !== "string") return void 0;
22
+ const trimmed = value.trim();
23
+ return trimmed === "" ? void 0 : trimmed;
24
+ }
25
+ function requireRecord(value, label) {
26
+ const record = toRecord(value);
27
+ if (record === void 0) throw upstreamError(502, `${label} was not an object`);
28
+ return record;
29
+ }
30
+ async function readPayload(response) {
31
+ const body = await response.text();
32
+ if (body.trim() === "") return {};
33
+ try {
34
+ return JSON.parse(body);
35
+ } catch {
36
+ if (!response.ok) return { errors: [{ detail: body }] };
37
+ throw upstreamError(502, "Rootly returned invalid JSON");
38
+ }
39
+ }
40
+ function errorMessage(payload, status) {
41
+ const object = toRecord(payload);
42
+ const errors = Array.isArray(object?.errors) ? object.errors : [];
43
+ const first = toRecord(errors[0]);
44
+ return text(first?.detail) ?? text(first?.title) ?? `Rootly request failed with ${status}`;
45
+ }
46
+ async function requestJson(ctx, path, query) {
47
+ const url = new URL(`${API_BASE}${path}`);
48
+ for (const [name, value] of Object.entries(query)) url.searchParams.set(name, value);
49
+ const response = await guardedFetch(url.toString(), {
50
+ headers: {
51
+ "accept": JSON_API_CONTENT_TYPE,
52
+ "authorization": `Bearer ${requireApiKey(ctx, SERVICE)}`,
53
+ "content-type": JSON_API_CONTENT_TYPE
54
+ }
55
+ });
56
+ const payload = await readPayload(response);
57
+ if (!response.ok) throw upstreamError(response.status, errorMessage(payload, response.status));
58
+ return payload;
59
+ }
60
+ function readResource(value, label) {
61
+ const object = requireRecord(value, label);
62
+ const data = object.data === void 0 ? object : requireRecord(object.data, `${label} data`);
63
+ const id = text(data.id);
64
+ const type = text(data.type);
65
+ if (id === void 0 || type === void 0) {
66
+ throw upstreamError(502, `${label} did not include JSON:API id and type`);
67
+ }
68
+ return {
69
+ ...data,
70
+ id,
71
+ type,
72
+ attributes: toRecord(data.attributes) ?? {},
73
+ relationships: toRecord(data.relationships) ?? {}
74
+ };
75
+ }
76
+ function readSidecars(payload) {
77
+ const object = requireRecord(payload, "Rootly response");
78
+ const included = Array.isArray(object.included) ? object.included : void 0;
79
+ const links = toRecord(object.links);
80
+ const meta = toRecord(object.meta);
81
+ return {
82
+ ...included === void 0 ? {} : { included },
83
+ ...links === void 0 ? {} : { links },
84
+ ...meta === void 0 ? {} : { meta }
85
+ };
86
+ }
87
+ async function getSingleResource(ctx, path, query) {
88
+ const payload = await requestJson(ctx, path, query);
89
+ return { resource: readResource(payload, "Rootly resource"), ...readSidecars(payload), raw: payload };
90
+ }
91
+ async function getList(ctx, path, query) {
92
+ const payload = await requestJson(ctx, path, query);
93
+ const object = requireRecord(payload, "Rootly list response");
94
+ if (!Array.isArray(object.data)) {
95
+ throw upstreamError(502, "Rootly list response did not include data array");
96
+ }
97
+ return {
98
+ resources: object.data.map((item) => readResource(item, "Rootly list resource")),
99
+ ...readSidecars(payload),
100
+ raw: payload
101
+ };
102
+ }
103
+ function compact(input) {
104
+ return Object.fromEntries(
105
+ Object.entries(input).filter((entry) => entry[1] !== void 0)
106
+ );
107
+ }
108
+ function includeQuery(include) {
109
+ return { include: include === void 0 || include.length === 0 ? void 0 : include.join(",") };
110
+ }
111
+ function pageQuery(input, options = {}) {
112
+ return {
113
+ ...options.cursor === true ? { "page[after]": text(input.pageAfter) } : {},
114
+ "page[number]": input.pageNumber === void 0 ? void 0 : String(input.pageNumber),
115
+ "page[size]": input.pageSize === void 0 ? void 0 : String(input.pageSize)
116
+ };
117
+ }
118
+ function configurationQuery(input, options = {}) {
119
+ return compact({
120
+ ...includeQuery(input.include),
121
+ ...pageQuery(input),
122
+ "filter[search]": text(input.search),
123
+ "filter[name]": text(input.name),
124
+ "filter[slug]": text(input.slug),
125
+ "filter[external_id]": text(input.externalId),
126
+ ...options.includeColor === true ? { "filter[color]": text(input.color) } : {},
127
+ "filter[alert_broadcast_enabled]": input.alertBroadcastEnabled === void 0 ? void 0 : String(input.alertBroadcastEnabled),
128
+ "filter[incident_broadcast_enabled]": input.incidentBroadcastEnabled === void 0 ? void 0 : String(input.incidentBroadcastEnabled),
129
+ "filter[created_at][gt]": text(input.createdAtGt),
130
+ "filter[created_at][gte]": text(input.createdAtGte),
131
+ "filter[created_at][lt]": text(input.createdAtLt),
132
+ "filter[created_at][lte]": text(input.createdAtLte),
133
+ "sort": text(input.sort)
134
+ });
135
+ }
136
+ function getCurrentUser(_input, ctx) {
137
+ return getSingleResource(ctx, "/users/me", {});
138
+ }
139
+ function listIncidents(input, ctx) {
140
+ return getList(ctx, "/incidents", compact({
141
+ ...pageQuery(input, { cursor: true }),
142
+ "filter[search]": text(input.search),
143
+ "filter[kind]": text(input.kind),
144
+ "filter[status]": text(input.status),
145
+ "filter[private]": input.private === void 0 ? void 0 : String(input.private),
146
+ "filter[user_id]": input.userId === void 0 ? void 0 : String(input.userId),
147
+ "filter[severity]": text(input.severity),
148
+ "filter[severity_id]": text(input.severityId),
149
+ "filter[labels]": text(input.labels),
150
+ "filter[service_ids]": text(input.serviceIds),
151
+ "filter[service_names]": text(input.serviceNames),
152
+ "filter[team_ids]": text(input.teamIds),
153
+ "filter[team_names]": text(input.teamNames),
154
+ "filter[created_at][gt]": text(input.createdAtGt),
155
+ "filter[created_at][gte]": text(input.createdAtGte),
156
+ "filter[created_at][lt]": text(input.createdAtLt),
157
+ "filter[created_at][lte]": text(input.createdAtLte),
158
+ "sort": text(input.sort)
159
+ }));
160
+ }
161
+ function getIncident(input, ctx) {
162
+ return getSingleResource(
163
+ ctx,
164
+ `/incidents/${encodeURIComponent(input.id)}`,
165
+ compact(includeQuery(input.include))
166
+ );
167
+ }
168
+ function listServices(input, ctx) {
169
+ return getList(ctx, "/services", configurationQuery(input));
170
+ }
171
+ function listTeams(input, ctx) {
172
+ return getList(ctx, "/teams", configurationQuery(input, { includeColor: true }));
173
+ }
174
+
175
+ // ../plugins/src/rootly/schema.ts
176
+ var getCurrentUserInput = external_exports.strictObject({}).describe("This action does not require input.");
177
+ var getCurrentUserOutput = external_exports.strictObject({
178
+ resource: external_exports.looseObject({
179
+ id: external_exports.string().min(1).describe("The Rootly resource ID.").optional(),
180
+ type: external_exports.string().min(1).describe("The Rootly resource type.").optional(),
181
+ attributes: external_exports.looseObject({}).describe("The Rootly resource attributes.").optional(),
182
+ relationships: external_exports.looseObject({}).describe("The Rootly resource relationships.").optional()
183
+ }).describe("A Rootly JSON:API resource."),
184
+ included: external_exports.array(external_exports.looseObject({}).describe("One included Rootly JSON:API resource.")).describe("Included Rootly JSON:API resources.").optional(),
185
+ raw: external_exports.looseObject({}).describe("The raw Rootly JSON:API response.")
186
+ }).describe("A Rootly single-resource response.");
187
+ var listIncidentsInput = external_exports.strictObject({
188
+ pageAfter: external_exports.string().min(1).describe("The Rootly cursor from meta.next_cursor.").optional(),
189
+ pageNumber: external_exports.int().min(1).describe("The page number to request.").optional(),
190
+ pageSize: external_exports.int().min(1).describe("The number of records to request per page.").optional(),
191
+ search: external_exports.string().min(1).describe("Search text for Rootly incident filtering.").optional(),
192
+ kind: external_exports.string().min(1).describe("Rootly incident kind filter.").optional(),
193
+ status: external_exports.string().min(1).describe("Rootly incident status filter.").optional(),
194
+ private: external_exports.boolean().describe("Whether to filter private incidents.").optional(),
195
+ userId: external_exports.int().min(1).describe("Rootly user ID filter.").optional(),
196
+ severity: external_exports.string().min(1).describe("Rootly severity name filter.").optional(),
197
+ severityId: external_exports.string().min(1).describe("Rootly severity ID filter.").optional(),
198
+ labels: external_exports.string().min(1).describe("Comma-separated Rootly label filter.").optional(),
199
+ serviceIds: external_exports.string().min(1).describe("Comma-separated Rootly service ID filter.").optional(),
200
+ serviceNames: external_exports.string().min(1).describe("Comma-separated Rootly service name filter.").optional(),
201
+ teamIds: external_exports.string().min(1).describe("Comma-separated Rootly team ID filter.").optional(),
202
+ teamNames: external_exports.string().min(1).describe("Comma-separated Rootly team name filter.").optional(),
203
+ createdAtGt: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
204
+ createdAtGte: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
205
+ createdAtLt: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
206
+ createdAtLte: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
207
+ sort: external_exports.string().min(1).describe("The Rootly sort expression, such as name or -created_at.").optional()
208
+ }).describe("Input for listing Rootly incidents.");
209
+ var listIncidentsOutput = external_exports.strictObject({
210
+ resources: external_exports.array(external_exports.looseObject({
211
+ id: external_exports.string().min(1).describe("The Rootly resource ID.").optional(),
212
+ type: external_exports.string().min(1).describe("The Rootly resource type.").optional(),
213
+ attributes: external_exports.looseObject({}).describe("The Rootly resource attributes.").optional(),
214
+ relationships: external_exports.looseObject({}).describe("The Rootly resource relationships.").optional()
215
+ }).describe("A Rootly JSON:API resource.")).describe("Rootly JSON:API resources."),
216
+ included: external_exports.array(external_exports.looseObject({}).describe("One included Rootly JSON:API resource.")).describe("Included Rootly JSON:API resources.").optional(),
217
+ links: external_exports.looseObject({}).describe("Rootly pagination or resource links.").optional(),
218
+ meta: external_exports.looseObject({}).describe("Rootly response metadata.").optional(),
219
+ raw: external_exports.looseObject({}).describe("The raw Rootly JSON:API response.")
220
+ }).describe("A Rootly list response.");
221
+ var getIncidentInput = external_exports.strictObject({
222
+ id: external_exports.string().min(1).describe("The Rootly resource UUID or slug."),
223
+ include: external_exports.array(external_exports.string().min(1).describe("One Rootly include value.")).min(1).describe("Related Rootly resources to include in the JSON:API response.").optional()
224
+ }).describe("Input for retrieving one Rootly resource.");
225
+ var getIncidentOutput = external_exports.strictObject({
226
+ resource: external_exports.looseObject({
227
+ id: external_exports.string().min(1).describe("The Rootly resource ID.").optional(),
228
+ type: external_exports.string().min(1).describe("The Rootly resource type.").optional(),
229
+ attributes: external_exports.looseObject({}).describe("The Rootly resource attributes.").optional(),
230
+ relationships: external_exports.looseObject({}).describe("The Rootly resource relationships.").optional()
231
+ }).describe("A Rootly JSON:API resource."),
232
+ included: external_exports.array(external_exports.looseObject({}).describe("One included Rootly JSON:API resource.")).describe("Included Rootly JSON:API resources.").optional(),
233
+ raw: external_exports.looseObject({}).describe("The raw Rootly JSON:API response.")
234
+ }).describe("A Rootly single-resource response.");
235
+ var listServicesInput = external_exports.strictObject({
236
+ include: external_exports.array(external_exports.string().min(1).describe("One Rootly include value.")).min(1).describe("Related Rootly resources to include in the JSON:API response.").optional(),
237
+ pageNumber: external_exports.int().min(1).describe("The page number to request.").optional(),
238
+ pageSize: external_exports.int().min(1).describe("The number of records to request per page.").optional(),
239
+ search: external_exports.string().min(1).describe("Search text for Rootly filtering.").optional(),
240
+ name: external_exports.string().min(1).describe("Rootly name filter.").optional(),
241
+ slug: external_exports.string().min(1).describe("Rootly slug filter.").optional(),
242
+ externalId: external_exports.string().min(1).describe("Rootly external ID filter.").optional(),
243
+ alertBroadcastEnabled: external_exports.boolean().describe("Whether alert broadcast is enabled.").optional(),
244
+ incidentBroadcastEnabled: external_exports.boolean().describe("Whether incident broadcast is enabled.").optional(),
245
+ createdAtGt: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
246
+ createdAtGte: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
247
+ createdAtLt: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
248
+ createdAtLte: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
249
+ sort: external_exports.string().min(1).describe("The Rootly sort expression, such as name or -created_at.").optional()
250
+ }).describe("Input for listing Rootly services.");
251
+ var listServicesOutput = external_exports.strictObject({
252
+ resources: external_exports.array(external_exports.looseObject({
253
+ id: external_exports.string().min(1).describe("The Rootly resource ID.").optional(),
254
+ type: external_exports.string().min(1).describe("The Rootly resource type.").optional(),
255
+ attributes: external_exports.looseObject({}).describe("The Rootly resource attributes.").optional(),
256
+ relationships: external_exports.looseObject({}).describe("The Rootly resource relationships.").optional()
257
+ }).describe("A Rootly JSON:API resource.")).describe("Rootly JSON:API resources."),
258
+ included: external_exports.array(external_exports.looseObject({}).describe("One included Rootly JSON:API resource.")).describe("Included Rootly JSON:API resources.").optional(),
259
+ links: external_exports.looseObject({}).describe("Rootly pagination or resource links.").optional(),
260
+ meta: external_exports.looseObject({}).describe("Rootly response metadata.").optional(),
261
+ raw: external_exports.looseObject({}).describe("The raw Rootly JSON:API response.")
262
+ }).describe("A Rootly list response.");
263
+ var listTeamsInput = external_exports.strictObject({
264
+ include: external_exports.array(external_exports.string().min(1).describe("One Rootly include value.")).min(1).describe("Related Rootly resources to include in the JSON:API response.").optional(),
265
+ pageNumber: external_exports.int().min(1).describe("The page number to request.").optional(),
266
+ pageSize: external_exports.int().min(1).describe("The number of records to request per page.").optional(),
267
+ search: external_exports.string().min(1).describe("Search text for Rootly filtering.").optional(),
268
+ name: external_exports.string().min(1).describe("Rootly name filter.").optional(),
269
+ slug: external_exports.string().min(1).describe("Rootly slug filter.").optional(),
270
+ externalId: external_exports.string().min(1).describe("Rootly external ID filter.").optional(),
271
+ alertBroadcastEnabled: external_exports.boolean().describe("Whether alert broadcast is enabled.").optional(),
272
+ incidentBroadcastEnabled: external_exports.boolean().describe("Whether incident broadcast is enabled.").optional(),
273
+ createdAtGt: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
274
+ createdAtGte: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
275
+ createdAtLt: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
276
+ createdAtLte: external_exports.iso.datetime({ offset: true }).describe("The ISO 8601 timestamp for this filter.").optional(),
277
+ sort: external_exports.string().min(1).describe("The Rootly sort expression, such as name or -created_at.").optional(),
278
+ color: external_exports.string().min(1).describe("Rootly team color filter.").optional()
279
+ }).describe("Input for listing Rootly teams.");
280
+ var listTeamsOutput = external_exports.strictObject({
281
+ resources: external_exports.array(external_exports.looseObject({
282
+ id: external_exports.string().min(1).describe("The Rootly resource ID.").optional(),
283
+ type: external_exports.string().min(1).describe("The Rootly resource type.").optional(),
284
+ attributes: external_exports.looseObject({}).describe("The Rootly resource attributes.").optional(),
285
+ relationships: external_exports.looseObject({}).describe("The Rootly resource relationships.").optional()
286
+ }).describe("A Rootly JSON:API resource.")).describe("Rootly JSON:API resources."),
287
+ included: external_exports.array(external_exports.looseObject({}).describe("One included Rootly JSON:API resource.")).describe("Included Rootly JSON:API resources.").optional(),
288
+ links: external_exports.looseObject({}).describe("Rootly pagination or resource links.").optional(),
289
+ meta: external_exports.looseObject({}).describe("Rootly response metadata.").optional(),
290
+ raw: external_exports.looseObject({}).describe("The raw Rootly JSON:API response.")
291
+ }).describe("A Rootly list response.");
292
+ var rootlyActions = {
293
+ get_current_user: {
294
+ description: "Get the Rootly user associated with the API key.",
295
+ effect: "read",
296
+ inputSchema: getCurrentUserInput,
297
+ outputSchema: external_exports.toJSONSchema(getCurrentUserOutput, { io: "output", unrepresentable: "any" })
298
+ },
299
+ list_incidents: {
300
+ description: "List Rootly incidents with common filters and pagination.",
301
+ effect: "read",
302
+ inputSchema: listIncidentsInput,
303
+ outputSchema: external_exports.toJSONSchema(listIncidentsOutput, { io: "output", unrepresentable: "any" })
304
+ },
305
+ get_incident: {
306
+ description: "Retrieve one Rootly incident by UUID or slug.",
307
+ effect: "read",
308
+ inputSchema: getIncidentInput,
309
+ outputSchema: external_exports.toJSONSchema(getIncidentOutput, { io: "output", unrepresentable: "any" })
310
+ },
311
+ list_services: {
312
+ description: "List Rootly services with common filters and pagination.",
313
+ effect: "read",
314
+ inputSchema: listServicesInput,
315
+ outputSchema: external_exports.toJSONSchema(listServicesOutput, { io: "output", unrepresentable: "any" })
316
+ },
317
+ list_teams: {
318
+ description: "List Rootly teams with common filters and pagination.",
319
+ effect: "read",
320
+ inputSchema: listTeamsInput,
321
+ outputSchema: external_exports.toJSONSchema(listTeamsOutput, { io: "output", unrepresentable: "any" })
322
+ }
323
+ };
324
+
325
+ // ../plugins/src/rootly/index.ts
326
+ function createRootlyPlugin() {
327
+ return createProviderPlugin({
328
+ description: "Rootly",
329
+ actions: rootlyActions,
330
+ // 上游 credentialValidators 打的就是 /users/me,与 get_current_user 同一个接口。
331
+ credentialProbe: "get_current_user",
332
+ handlers: {
333
+ get_current_user: getCurrentUser,
334
+ list_incidents: listIncidents,
335
+ get_incident: getIncident,
336
+ list_services: listServices,
337
+ list_teams: listTeams
338
+ }
339
+ });
340
+ }
341
+ var rootly_default = createRootlyPlugin();
342
+ export {
343
+ createRootlyPlugin,
344
+ rootly_default as default
345
+ };
@@ -0,0 +1,289 @@
1
+ import {
2
+ createProviderPlugin,
3
+ guardedFetch,
4
+ requireApiKey,
5
+ upstreamError
6
+ } from "./chunk-CSJEZHQO.js";
7
+ import "./chunk-K7FVSFUX.js";
8
+ import {
9
+ TBError,
10
+ external_exports
11
+ } from "./chunk-JLTYA2B3.js";
12
+ import "./chunk-MLKGABMK.js";
13
+
14
+ // ../plugins/src/scrapfly/api.ts
15
+ var SERVICE = "scrapfly";
16
+ var API_BASE = "https://api.scrapfly.io";
17
+ var SCRAPE_URL = `${API_BASE}/scrape`;
18
+ var METRICS_URL = `${API_BASE}/scrape/monitoring/metrics`;
19
+ var REQUEST_TIMEOUT_MS = 16e4;
20
+ var MAX_ERROR_MESSAGE_LENGTH = 300;
21
+ function looksLikeHtml(value) {
22
+ return /^<!doctype html/i.test(value) || /^<html[\s>]/i.test(value);
23
+ }
24
+ function errorMessage(body, headers, status) {
25
+ const trimmed = body.trim();
26
+ if (trimmed !== "") {
27
+ try {
28
+ const parsed = JSON.parse(trimmed);
29
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
30
+ const record = parsed;
31
+ for (const key of ["message", "error", "detail"]) {
32
+ const value = record[key];
33
+ if (typeof value === "string" && value.trim() !== "") return value.trim();
34
+ }
35
+ }
36
+ } catch {
37
+ }
38
+ if (looksLikeHtml(trimmed)) return "Scrapfly \u8FD4\u56DE\u4E86\u975E JSON \u7684\u9519\u8BEF\u54CD\u5E94";
39
+ return trimmed.length <= MAX_ERROR_MESSAGE_LENGTH ? trimmed : `${trimmed.slice(0, MAX_ERROR_MESSAGE_LENGTH)}...`;
40
+ }
41
+ return headers.get("x-scrapfly-reject-code") ?? `Scrapfly \u8FD4\u56DE HTTP ${status}`;
42
+ }
43
+ function buildUrl(base, apiKey, query) {
44
+ const url = new URL(base);
45
+ url.searchParams.set("key", apiKey);
46
+ for (const [key, value] of Object.entries(query)) {
47
+ if (value === void 0) continue;
48
+ if (Array.isArray(value)) {
49
+ for (const item of value) url.searchParams.append(`${key}[]`, item);
50
+ continue;
51
+ }
52
+ url.searchParams.set(key, String(value));
53
+ }
54
+ return url;
55
+ }
56
+ async function request(ctx, base, query, init) {
57
+ const url = buildUrl(base, requireApiKey(ctx, SERVICE), query);
58
+ let response;
59
+ try {
60
+ response = await guardedFetch(url.toString(), {
61
+ ...init,
62
+ headers: { accept: "application/json", ...init.headers },
63
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
64
+ });
65
+ } catch (error) {
66
+ if (error instanceof TBError) throw error;
67
+ if (error instanceof Error && error.name === "TimeoutError") {
68
+ throw upstreamError(504, `Scrapfly ${REQUEST_TIMEOUT_MS / 1e3}s \u5185\u6CA1\u6709\u8FD4\u56DE`);
69
+ }
70
+ throw new TBError(
71
+ "unavailable",
72
+ error instanceof Error ? `Scrapfly \u8BF7\u6C42\u5931\u8D25: ${error.message}` : "Scrapfly \u8BF7\u6C42\u5931\u8D25",
73
+ { retryable: true }
74
+ );
75
+ }
76
+ if (!response.ok) {
77
+ throw upstreamError(
78
+ response.status,
79
+ errorMessage(await response.text().catch(() => ""), response.headers, response.status)
80
+ );
81
+ }
82
+ return response;
83
+ }
84
+ async function readJson(response, label) {
85
+ const body = await response.text();
86
+ if (body.trim() === "") {
87
+ throw new TBError("unavailable", `${label}\u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94\u4F53`, { retryable: true });
88
+ }
89
+ try {
90
+ return JSON.parse(body);
91
+ } catch {
92
+ throw new TBError("unavailable", `${label}\u8FD4\u56DE\u4E86\u975E\u6CD5 JSON`, { retryable: true });
93
+ }
94
+ }
95
+ function requireRecord(payload, label) {
96
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
97
+ throw new TBError("unavailable", `${label}\u4E0D\u662F JSON \u5BF9\u8C61`, { retryable: true });
98
+ }
99
+ return payload;
100
+ }
101
+ function toRecord(value) {
102
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
103
+ return value;
104
+ }
105
+ function headerInt(headers, name) {
106
+ const value = headers.get(name);
107
+ if (value === null || value === "") return null;
108
+ const parsed = Number(value);
109
+ return Number.isInteger(parsed) ? parsed : null;
110
+ }
111
+ function responseMetadata(response) {
112
+ return {
113
+ status_code: response.status,
114
+ api_cost: headerInt(response.headers, "x-scrapfly-api-cost"),
115
+ remaining_api_credit: headerInt(response.headers, "x-scrapfly-remaining-api-credit"),
116
+ reject_code: response.headers.get("x-scrapfly-reject-code"),
117
+ reject_description: response.headers.get("x-scrapfly-reject-description"),
118
+ reject_retryable: response.headers.get("x-scrapfly-reject-retryable")
119
+ };
120
+ }
121
+ async function scrape(input, ctx) {
122
+ const method = input.method ?? "GET";
123
+ if ((method === "GET" || method === "HEAD") && input.body !== void 0 && input.body !== "") {
124
+ throw new TBError("invalid_argument", `${method} \u6293\u53D6\u8BF7\u6C42\u4E0D\u80FD\u5E26 body`);
125
+ }
126
+ if (input.body !== void 0 && input.body !== "" && input.content_type === void 0) {
127
+ throw new TBError("invalid_argument", "\u7ED9\u4E86 body \u5C31\u5FC5\u987B\u7ED9 content_type");
128
+ }
129
+ const targetHeaders = {};
130
+ for (const [key, value] of Object.entries(input.headers ?? {})) {
131
+ if (value.trim() !== "") targetHeaders[`headers[${key}]`] = value.trim();
132
+ }
133
+ const tags = input.tags?.map((tag) => tag.trim()).filter((tag) => tag !== "");
134
+ const response = await request(
135
+ ctx,
136
+ SCRAPE_URL,
137
+ {
138
+ url: input.url,
139
+ country: input.country,
140
+ proxy_pool: input.proxy_pool,
141
+ render_js: input.render_js,
142
+ asp: input.asp,
143
+ retry: input.retry,
144
+ timeout: input.timeout,
145
+ wait_for_selector: input.wait_for_selector,
146
+ cache: input.cache,
147
+ cache_ttl: input.cache_ttl,
148
+ cache_clear: input.cache_clear,
149
+ session: input.session,
150
+ session_sticky_proxy: input.session_sticky_proxy,
151
+ format: input.format,
152
+ correlation_id: input.correlation_id,
153
+ debug: input.debug,
154
+ ...targetHeaders,
155
+ tags: tags !== void 0 && tags.length > 0 ? tags : void 0
156
+ },
157
+ {
158
+ method,
159
+ body: input.body === void 0 || input.body === "" ? void 0 : input.body,
160
+ headers: input.content_type === void 0 ? void 0 : { "content-type": input.content_type }
161
+ }
162
+ );
163
+ const payload = requireRecord(await readJson(response, "Scrapfly \u6293\u53D6\u54CD\u5E94"), "Scrapfly \u6293\u53D6\u54CD\u5E94");
164
+ return {
165
+ result: requireRecord(payload.result, "Scrapfly \u6293\u53D6\u7ED3\u679C"),
166
+ config: toRecord(payload.config),
167
+ context: toRecord(payload.context),
168
+ metadata: responseMetadata(response),
169
+ headers: Object.fromEntries(response.headers.entries())
170
+ };
171
+ }
172
+ async function getMonitoringMetrics(input, ctx) {
173
+ const response = await request(
174
+ ctx,
175
+ METRICS_URL,
176
+ {
177
+ aggregation: input.aggregation,
178
+ period: input.period,
179
+ start: input.start,
180
+ end: input.end,
181
+ group_subdomain: input.group_subdomain
182
+ },
183
+ { method: "GET" }
184
+ );
185
+ return {
186
+ metrics: requireRecord(
187
+ await readJson(response, "Scrapfly \u76D1\u63A7\u6307\u6807\u54CD\u5E94"),
188
+ "Scrapfly \u76D1\u63A7\u6307\u6807\u54CD\u5E94"
189
+ ),
190
+ metadata: responseMetadata(response),
191
+ headers: Object.fromEntries(response.headers.entries())
192
+ };
193
+ }
194
+
195
+ // ../plugins/src/scrapfly/schema.ts
196
+ var scrapeInput = external_exports.strictObject({
197
+ url: external_exports.url().describe("The public URL Scrapfly should scrape."),
198
+ method: external_exports.enum(["GET", "POST", "PUT", "PATCH", "HEAD", "OPTIONS"]).describe("The HTTP method Scrapfly should use against the target URL.").optional(),
199
+ body: external_exports.string().describe("The raw request body Scrapfly should send to the target URL.").optional(),
200
+ content_type: external_exports.string().min(1).describe("The Content-Type header for the target request body.").optional(),
201
+ format: external_exports.string().min(1).describe("The content format Scrapfly should return.").optional(),
202
+ country: external_exports.string().min(2).describe("The proxy country selection accepted by Scrapfly, such as us, us,ca,mx, or -gb.").optional(),
203
+ proxy_pool: external_exports.enum(["public_datacenter_pool", "public_residential_pool"]).describe("The Scrapfly proxy pool to use for the scrape.").optional(),
204
+ render_js: external_exports.boolean().describe("Whether Scrapfly should render JavaScript before returning.").optional(),
205
+ asp: external_exports.boolean().describe("Whether Scrapfly should enable Anti Scraping Protection.").optional(),
206
+ retry: external_exports.boolean().describe("Whether Scrapfly should retry the scrape request.").optional(),
207
+ timeout: external_exports.int().min(1e3).max(15e4).describe("The scrape timeout in milliseconds.").optional(),
208
+ wait_for_selector: external_exports.string().min(1).describe("The CSS selector Scrapfly should wait for before returning content.").optional(),
209
+ cache: external_exports.boolean().describe("Whether Scrapfly should use cached scrape results when available.").optional(),
210
+ cache_ttl: external_exports.int().min(1).describe("The cache time-to-live in seconds.").optional(),
211
+ cache_clear: external_exports.boolean().describe("Whether Scrapfly should clear any matching cached result.").optional(),
212
+ session: external_exports.string().min(1).max(255).describe("The Scrapfly session name used to keep browsing state.").optional(),
213
+ session_sticky_proxy: external_exports.boolean().describe("Whether Scrapfly should keep the session proxy sticky.").optional(),
214
+ headers: external_exports.record(external_exports.string(), external_exports.string().describe("A target request header value.")).describe("Target request headers Scrapfly should send to the scraped website.").optional(),
215
+ tags: external_exports.array(external_exports.string().min(1).describe("One Scrapfly monitoring tag.")).describe("Tags for grouping the scrape in Scrapfly monitoring.").optional(),
216
+ correlation_id: external_exports.string().min(1).describe("A caller-provided correlation identifier for monitoring.").optional(),
217
+ debug: external_exports.boolean().describe("Whether Scrapfly should expose debug data for the scrape.").optional()
218
+ }).describe("The input payload for scraping a URL with Scrapfly.");
219
+ var scrapeOutput = external_exports.strictObject({
220
+ result: external_exports.looseObject({
221
+ content: external_exports.unknown().describe("The scraped content, a large object URL, or encoded binary content."),
222
+ status_code: external_exports.int().describe("The HTTP status code returned by the target website."),
223
+ format: external_exports.string().describe("The Scrapfly result content format.")
224
+ }).describe("The result object returned by Scrapfly.").optional(),
225
+ config: external_exports.looseObject({}).describe("The scrape configuration returned by Scrapfly.").optional(),
226
+ context: external_exports.looseObject({}).describe("Additional context returned by Scrapfly.").optional(),
227
+ metadata: external_exports.strictObject({
228
+ status_code: external_exports.int().describe("The HTTP status code returned by Scrapfly.").optional(),
229
+ api_cost: external_exports.int().describe("The API credit cost reported by Scrapfly.").nullable().optional(),
230
+ remaining_api_credit: external_exports.int().describe("Remaining API credit reported by Scrapfly.").nullable().optional(),
231
+ reject_code: external_exports.string().describe("The Scrapfly reject code when a scrape is rejected.").nullable().optional(),
232
+ reject_description: external_exports.string().describe("The Scrapfly reject documentation URL when a scrape is rejected.").nullable().optional(),
233
+ reject_retryable: external_exports.string().describe("Whether Scrapfly reported the rejection as retryable.").nullable().optional()
234
+ }).describe("Metadata collected from Scrapfly response headers.").optional(),
235
+ headers: external_exports.record(external_exports.string(), external_exports.string().describe("One response header value.")).describe("Response headers returned by Scrapfly.").optional()
236
+ }).describe("The response returned when scraping with Scrapfly.");
237
+ var getMonitoringMetricsInput = external_exports.strictObject({
238
+ aggregation: external_exports.string().min(1).describe("The metrics aggregation list accepted by Scrapfly, such as account, project, or account,project,target.").optional(),
239
+ period: external_exports.enum(["last5m", "last1h", "last7d", "last24h", "subscription"]).describe("The monitoring period to retrieve.").optional(),
240
+ start: external_exports.string().min(1).describe("The UTC start date accepted by Scrapfly when period is omitted.").optional(),
241
+ end: external_exports.string().min(1).describe("The UTC end date accepted by Scrapfly when period is omitted.").optional(),
242
+ group_subdomain: external_exports.boolean().describe("Whether target aggregation should group subdomains.").optional()
243
+ }).describe("The input payload for retrieving Scrapfly monitoring metrics.");
244
+ var getMonitoringMetricsOutput = external_exports.strictObject({
245
+ metrics: external_exports.looseObject({}).describe("Monitoring metrics returned by Scrapfly.").optional(),
246
+ metadata: external_exports.strictObject({
247
+ status_code: external_exports.int().describe("The HTTP status code returned by Scrapfly.").optional(),
248
+ api_cost: external_exports.int().describe("The API credit cost reported by Scrapfly.").nullable().optional(),
249
+ remaining_api_credit: external_exports.int().describe("Remaining API credit reported by Scrapfly.").nullable().optional(),
250
+ reject_code: external_exports.string().describe("The Scrapfly reject code when a scrape is rejected.").nullable().optional(),
251
+ reject_description: external_exports.string().describe("The Scrapfly reject documentation URL when a scrape is rejected.").nullable().optional(),
252
+ reject_retryable: external_exports.string().describe("Whether Scrapfly reported the rejection as retryable.").nullable().optional()
253
+ }).describe("Metadata collected from Scrapfly response headers.").optional(),
254
+ headers: external_exports.record(external_exports.string(), external_exports.string().describe("One response header value.")).describe("Response headers returned by Scrapfly.").optional()
255
+ }).describe("The response returned when retrieving Scrapfly monitoring metrics.");
256
+ var scrapflyActions = {
257
+ scrape: {
258
+ description: "Scrape one public URL through Scrapfly and return the documented JSON response envelope.",
259
+ effect: "write",
260
+ inputSchema: scrapeInput,
261
+ outputSchema: external_exports.toJSONSchema(scrapeOutput, { io: "output", unrepresentable: "any" })
262
+ },
263
+ get_monitoring_metrics: {
264
+ description: "Retrieve Scrapfly monitoring metrics for the connected API key.",
265
+ effect: "read",
266
+ inputSchema: getMonitoringMetricsInput,
267
+ outputSchema: external_exports.toJSONSchema(getMonitoringMetricsOutput, { io: "output", unrepresentable: "any" })
268
+ }
269
+ };
270
+
271
+ // ../plugins/src/scrapfly/index.ts
272
+ function createScrapflyPlugin() {
273
+ return createProviderPlugin({
274
+ description: "Scrapfly",
275
+ actions: scrapflyActions,
276
+ // 不设 credentialProbe:唯一的 read action(get_monitoring_metrics)对**非企业版**
277
+ // 账号返回 402,而上游的 credentialValidators 明确把 402 视作"凭证有效、只是没这个
278
+ // 套餐"。挂载期探针拿不到这个区分,会把合法的非企业版 key 当场拒掉。
279
+ handlers: {
280
+ scrape,
281
+ get_monitoring_metrics: getMonitoringMetrics
282
+ }
283
+ });
284
+ }
285
+ var scrapfly_default = createScrapflyPlugin();
286
+ export {
287
+ createScrapflyPlugin,
288
+ scrapfly_default as default
289
+ };