@tool-bridge/server 0.16.0 → 0.19.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 (115) hide show
  1. package/dist/{airtable-S3T4TAN7.js → airtable-23JBIM6X.js} +106 -114
  2. package/dist/{alt_text_generator_ai-4DIRIDKL.js → alt_text_generator_ai-ADWBTCIH.js} +25 -16
  3. package/dist/{amap-LGVGNPML.js → amap-CYQCYW2Z.js} +114 -123
  4. package/dist/{anthropic-27RFZO35.js → anthropic-5P62HDNR.js} +34 -56
  5. package/dist/{apify-6WLYAIAS.js → apify-54RZUAGW.js} +31 -49
  6. package/dist/{brave_search-K2SVJ66F.js → brave_search-AHJ6FTD5.js} +52 -77
  7. package/dist/{chunk-VK3V2WTY.js → chunk-B4P6YZFS.js} +4 -6
  8. package/dist/{chunk-BB6ZLMTU.js → chunk-CLEZ6YQ6.js} +2600 -481
  9. package/dist/chunk-JXHMDBAY.js +45 -0
  10. package/dist/chunk-LMLX3DJF.js +50 -0
  11. package/dist/{chunk-YB2FLNWI.js → chunk-OKRZPQ3R.js} +2558 -1926
  12. package/dist/chunk-SWBNHIO4.js +977 -0
  13. package/dist/chunk-U67V476Y.js +35 -0
  14. package/dist/chunk-VLOIDU5U.js +283 -0
  15. package/dist/{circleci-WV3ITU7Q.js → circleci-UM3NSQJ3.js} +36 -55
  16. package/dist/{clerk-NFQEFKS4.js → clerk-FE5LQ2CZ.js} +60 -80
  17. package/dist/{cloudflare_dns-2RK5ASBJ.js → cloudflare_dns-KEZABKUT.js} +90 -113
  18. package/dist/{cohere-5KEW7LWT.js → cohere-4IPJADXP.js} +33 -49
  19. package/dist/{confluence-SZE63S46.js → confluence-56QEKNQI.js} +79 -115
  20. package/dist/{convertapi-QPG2JC5K.js → convertapi-3QRM5K5T.js} +13 -16
  21. package/dist/{currencyapi-UO2APQRY.js → currencyapi-L6G4OND5.js} +30 -53
  22. package/dist/{deepseek-LJELIMM3.js → deepseek-LGC6HBFG.js} +30 -38
  23. package/dist/{docker_hub-2MFXSBOF.js → docker_hub-XDMK3BIU.js} +141 -157
  24. package/dist/{dropbox-GQYNTTVA.js → dropbox-4QARMFZU.js} +134 -141
  25. package/dist/{dub-KI2LHXST.js → dub-C6JSJKOT.js} +61 -93
  26. package/dist/{e2b-WO6ISY3C.js → e2b-6A6TVACJ.js} +39 -69
  27. package/dist/{exa-IZ7B3BPT.js → exa-SIWWW6AA.js} +49 -77
  28. package/dist/{fal_ai-LTMF36GJ.js → fal_ai-3IJXOKSP.js} +37 -44
  29. package/dist/{feishu-WM7SLSFD.js → feishu-L4KDA4DC.js} +4 -6
  30. package/dist/{feishu_custom_bot-66W3MXH2.js → feishu_custom_bot-SDM75H4P.js} +4 -5
  31. package/dist/{figma-2Z274VQZ.js → figma-6DD436DN.js} +56 -81
  32. package/dist/{firehydrant-IFI4R65V.js → firehydrant-SYSGYB3R.js} +40 -53
  33. package/dist/{fixer-BCCZEB3D.js → fixer-FZG7ASTF.js} +31 -43
  34. package/dist/{fly-755FXYB5.js → fly-HMRCZBUC.js} +50 -66
  35. package/dist/{front-4FZKKXXK.js → front-FAFSD7I3.js} +43 -66
  36. package/dist/{geocodio-WYKDJ3DP.js → geocodio-4D3TWENM.js} +37 -63
  37. package/dist/{ghost-5BNQTCOH.js → ghost-OSO2FOZS.js} +51 -57
  38. package/dist/{github-ULELF5VX.js → github-OR4I4RHE.js} +48 -41
  39. package/dist/{gmail-G34WT64J.js → gmail-5AOPJ63E.js} +26 -36
  40. package/dist/{googlecalendar-BQU255SC.js → googlecalendar-SOJIJUWH.js} +57 -78
  41. package/dist/{googledocs-HPCNQXYJ.js → googledocs-QSKN5TLN.js} +14 -22
  42. package/dist/{grafana-VOV24FIC.js → grafana-R3AIZM7M.js} +95 -122
  43. package/dist/{graphhopper-D5RXW6AP.js → graphhopper-4CR3QOAX.js} +32 -46
  44. package/dist/index.d.ts +108 -56
  45. package/dist/index.js +4 -3
  46. package/dist/{ip2proxy-DAYO7EKZ.js → ip2proxy-OBCG6X6J.js} +35 -42
  47. package/dist/{ipgeolocation_io-XD4PSLII.js → ipgeolocation_io-NHH3DTQW.js} +40 -60
  48. package/dist/{ipqualityscore-K27QEAWK.js → ipqualityscore-7POMCBEC.js} +30 -42
  49. package/dist/{jina_ai-E6UXFV2P.js → jina_ai-YXVKROV4.js} +32 -58
  50. package/dist/{jira-ZDSXGQ6W.js → jira-LADO3VJU.js} +116 -126
  51. package/dist/{langsmith-TIFJRREW.js → langsmith-XZ6UAQFU.js} +101 -121
  52. package/dist/{lemlist-DASEMJMA.js → lemlist-P74GLNE7.js} +57 -68
  53. package/dist/{linear-KE6UP4SP.js → linear-CXJ7D37A.js} +109 -118
  54. package/dist/{logsnag-IMNDN4R5.js → logsnag-EVVHWFLK.js} +31 -48
  55. package/dist/main.js +103 -102
  56. package/dist/{mattermost-HHHMUXQA.js → mattermost-WG2MRGBD.js} +45 -62
  57. package/dist/{mem0-D2FGGOIY.js → mem0-HQWUKG6U.js} +72 -98
  58. package/dist/{memos-4OVIGFPH.js → memos-SQMJIFOE.js} +68 -122
  59. package/dist/{metabase-33WCX5YD.js → metabase-E27G2DZI.js} +47 -60
  60. package/dist/{mistral_ai-QIMZ2JYL.js → mistral_ai-MIL63NIT.js} +35 -40
  61. package/dist/{mother_duck-M6VWS2VH.js → mother_duck-AIZVCBNR.js} +42 -62
  62. package/dist/{ngrok-Z2PKQBHH.js → ngrok-XS4DVIQS.js} +42 -58
  63. package/dist/{notes-SS4RPC4K.js → notes-JEOUSL2Y.js} +3 -5
  64. package/dist/{notion-FJCNQ6I7.js → notion-U4EZVDW2.js} +83 -97
  65. package/dist/{open_exchange_rates-WU57WTT5.js → open_exchange_rates-AZSQEYEJ.js} +35 -39
  66. package/dist/{openai-JODZ4GKT.js → openai-HW3SYMTQ.js} +51 -55
  67. package/dist/{opengraph_io-SQRAUSV5.js → opengraph_io-QX74MAEL.js} +61 -79
  68. package/dist/{openrouter-Q5XXEJZ7.js → openrouter-OXSKYL6N.js} +41 -55
  69. package/dist/{outline-RT2EHJ2X.js → outline-CCQAPDSW.js} +89 -104
  70. package/dist/{paddle-OF2V7GAC.js → paddle-6KQPSSCK.js} +34 -49
  71. package/dist/{perplexity-LNZEWLHG.js → perplexity-2TXO7IQE.js} +33 -50
  72. package/dist/{pinecone-JSJIXZYN.js → pinecone-YOO7NULI.js} +65 -91
  73. package/dist/{pipedrive-D4CKVUXR.js → pipedrive-Q6RIFIFP.js} +37 -59
  74. package/dist/{polar-M7ZYP6UR.js → polar-KUMGCES3.js} +43 -53
  75. package/dist/{posthog-YV7CZOH4.js → posthog-VXQHBSMB.js} +58 -77
  76. package/dist/{postmark-KYHLECRG.js → postmark-YLIPF52S.js} +52 -71
  77. package/dist/{prerender-HCMHBKV2.js → prerender-CRY7UJN5.js} +32 -50
  78. package/dist/{pubmed-WYVLCCN3.js → pubmed-3Z4T5AM7.js} +28 -60
  79. package/dist/{railway-TWIRD5KR.js → railway-BP37IGFL.js} +32 -39
  80. package/dist/{readwise-UZ467IQ7.js → readwise-HTKICF4K.js} +62 -78
  81. package/dist/{render-MECUC5CC.js → render-WIVTUXJH.js} +48 -64
  82. package/dist/{replicate-A5MEK3SW.js → replicate-JJYPA43D.js} +41 -58
  83. package/dist/{resend-BC6EAWJQ.js → resend-TKHZVG7A.js} +27 -37
  84. package/dist/{rootly-ZM3QDUIS.js → rootly-FRSZLG5U.js} +64 -76
  85. package/dist/{scrapfly-WAML42QJ.js → scrapfly-M5WXGQWE.js} +45 -51
  86. package/dist/{scrapingbee-DG7PET3V.js → scrapingbee-PMXNLLBK.js} +25 -33
  87. package/dist/{screenshot_fyi-HY6WTHIO.js → screenshot_fyi-HFW4TAOH.js} +29 -47
  88. package/dist/{semantic_scholar-C5IZA7IP.js → semantic_scholar-KXVH2VZQ.js} +37 -56
  89. package/dist/{sentry-OKBPSTDM.js → sentry-WWOT2LRX.js} +66 -85
  90. package/dist/{shodan-PPC6DYU4.js → shodan-FY635H35.js} +42 -53
  91. package/dist/{shopify-EWGUHBXO.js → shopify-HQLBVSA5.js} +32 -49
  92. package/dist/{stripe-6RPDPC5W.js → stripe-GJN2GOHB.js} +4 -5
  93. package/dist/{supabase-SK7DQ42N.js → supabase-BBNZGQU6.js} +69 -88
  94. package/dist/{tavily-YCG5VQMH.js → tavily-DPENIBOG.js} +37 -62
  95. package/dist/{telegram-2OES5FYB.js → telegram-L4NONG6H.js} +168 -177
  96. package/dist/{telnyx-POOSBBR4.js → telnyx-H67MAEZS.js} +30 -50
  97. package/dist/{todoist-M7YD6YSS.js → todoist-G2BSP4DX.js} +77 -89
  98. package/dist/{trello-IS6V5W3E.js → trello-7WMVFDG2.js} +108 -122
  99. package/dist/{turso-RCFHUFVH.js → turso-ZUAESFC2.js} +52 -64
  100. package/dist/{twilio-OS2RXFGO.js → twilio-EYFYIX3B.js} +48 -55
  101. package/dist/{umami-PQ2SJ2LN.js → umami-AXAUDUVF.js} +49 -69
  102. package/dist/{unsplash-C6BPZO4E.js → unsplash-UCQAWPLR.js} +35 -52
  103. package/dist/{upstash_redis-WH6UER7H.js → upstash_redis-ZPZ4ASU6.js} +28 -40
  104. package/dist/{uptimerobot-M3YZGS6Z.js → uptimerobot-4QVKKUD5.js} +11 -12
  105. package/dist/{v2ex-R4JWTEHN.js → v2ex-VGEFJTYC.js} +36 -61
  106. package/dist/{vercel-FZVYUOQD.js → vercel-JME4TSCN.js} +124 -150
  107. package/dist/{webapi-VLM4IKVB.js → webapi-GW5QXWXE.js} +1 -1
  108. package/dist/{wolfram_alpha_api-2KOLO5DC.js → wolfram_alpha_api-TRGU2MDG.js} +26 -34
  109. package/dist/{wordpress-XRWGO6LG.js → wordpress-WRUKLCZR.js} +87 -104
  110. package/dist/{workos-WR4NKOYL.js → workos-ZDW4EHS4.js} +37 -56
  111. package/dist/{zhihu-BKZIB3WA.js → zhihu-4VI67CWU.js} +35 -57
  112. package/package.json +3 -3
  113. package/dist/chunk-2O27H4Y2.js +0 -183
  114. package/dist/chunk-GKX72JMJ.js +0 -378
  115. package/dist/chunk-MLKGABMK.js +0 -9
@@ -1,31 +1,29 @@
1
+ import {
2
+ createProviderHttpClient
3
+ } from "./chunk-VLOIDU5U.js";
4
+ import {
5
+ asJsonObject,
6
+ trimmedText
7
+ } from "./chunk-JXHMDBAY.js";
1
8
  import {
2
9
  createProviderPlugin,
3
10
  requireCredential,
4
11
  upstreamError
5
- } from "./chunk-VK3V2WTY.js";
12
+ } from "./chunk-B4P6YZFS.js";
6
13
  import {
7
- assertPublicHttpUrl,
8
- guardedFetch
9
- } from "./chunk-2O27H4Y2.js";
10
- import "./chunk-GKX72JMJ.js";
14
+ assertPublicHttpUrl
15
+ } from "./chunk-SWBNHIO4.js";
11
16
  import {
12
17
  TBError,
13
18
  external_exports
14
- } from "./chunk-YB2FLNWI.js";
15
- import "./chunk-MLKGABMK.js";
19
+ } from "./chunk-OKRZPQ3R.js";
20
+ import "./chunk-U67V476Y.js";
16
21
 
17
22
  // ../plugins/src/ghost/api.ts
18
23
  var SERVICE = "ghost";
19
24
  var CONTENT_PATH_PREFIX = "/ghost/api/content";
20
25
  var CONTENT_API_VERSION = "v5.0";
21
- function text(value) {
22
- if (typeof value !== "string") return void 0;
23
- const trimmed = value.trim();
24
- return trimmed === "" ? void 0 : trimmed;
25
- }
26
- function record(value) {
27
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
28
- }
26
+ var http = createProviderHttpClient({ service: SERVICE });
29
27
  function contentBaseUrl(ctx) {
30
28
  const raw = requireCredential(ctx, SERVICE, "siteUrl");
31
29
  let url;
@@ -47,75 +45,71 @@ function contentBaseUrl(ctx) {
47
45
  return `${site}${CONTENT_PATH_PREFIX}/${CONTENT_API_VERSION}`;
48
46
  }
49
47
  function errorMessage(status, payload) {
50
- const body = record(payload);
48
+ const body = asJsonObject(payload);
51
49
  const errors = body?.errors;
52
50
  if (Array.isArray(errors)) {
53
- const message = text(record(errors[0])?.message);
51
+ const message = trimmedText(asJsonObject(errors[0])?.message);
54
52
  if (message !== void 0) return message;
55
53
  }
56
- return text(body?.message) ?? `Ghost \u8FD4\u56DE HTTP ${status}`;
54
+ return trimmedText(body?.message) ?? `Ghost \u8FD4\u56DE HTTP ${status}`;
55
+ }
56
+ function errorPayload(data, bodyKind) {
57
+ return bodyKind === "invalid-json" ? { message: data } : data;
57
58
  }
58
59
  async function request(ctx, path, query = {}) {
59
- const url = new URL(path.replace(/^\/+/, ""), `${contentBaseUrl(ctx)}/`);
60
- url.searchParams.set("key", requireCredential(ctx, SERVICE, "apiKey"));
61
- for (const [key, value] of Object.entries(query)) {
62
- if (value !== void 0) url.searchParams.set(key, String(value));
63
- }
64
- const response = await guardedFetch(url.toString(), {
65
- method: "GET",
66
- headers: { accept: "application/json" }
60
+ const result = await http.request({
61
+ // base 里已经带 /ghost/api/content/v5.0;薄层会保住这段部署路径。
62
+ baseUrl: `${contentBaseUrl(ctx)}/`,
63
+ path,
64
+ query: [
65
+ ["key", requireCredential(ctx, SERVICE, "apiKey")],
66
+ ...Object.entries(query)
67
+ ],
68
+ headers: { accept: "application/json" },
69
+ invalidJsonMessage: "Ghost \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94",
70
+ mapError: ({ bodyKind, data, status }) => upstreamError(
71
+ status,
72
+ errorMessage(status, errorPayload(data, bodyKind))
73
+ )
67
74
  });
68
- const body = await response.text();
69
- let payload = {};
70
- if (body !== "") {
71
- try {
72
- payload = JSON.parse(body);
73
- } catch {
74
- if (response.ok) {
75
- throw new TBError("unavailable", "Ghost \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94", { retryable: true });
76
- }
77
- payload = { message: body };
78
- }
79
- }
80
- if (!response.ok) throw upstreamError(response.status, errorMessage(response.status, payload));
81
- return payload;
75
+ return result.data === void 0 ? {} : result.data;
82
76
  }
83
77
  function browseQuery(input) {
84
78
  return {
85
79
  limit: input.limit,
86
80
  page: input.page,
87
- include: text(input.include),
88
- fields: text(input.fields),
89
- formats: text(input.formats),
90
- filter: text(input.filter),
91
- order: text(input.order)
81
+ include: trimmedText(input.include),
82
+ fields: trimmedText(input.fields),
83
+ formats: trimmedText(input.formats),
84
+ filter: trimmedText(input.filter),
85
+ order: trimmedText(input.order)
92
86
  };
93
87
  }
94
88
  function readQuery(input) {
95
89
  return {
96
- include: text(input.include),
97
- fields: text(input.fields),
98
- formats: text(input.formats)
90
+ include: trimmedText(input.include),
91
+ fields: trimmedText(input.fields),
92
+ formats: trimmedText(input.formats)
99
93
  };
100
94
  }
101
95
  async function browse(input, ctx, collection) {
102
- const payload = record(await request(ctx, `/${collection}/`, browseQuery(input))) ?? {};
96
+ const payload = asJsonObject(await request(ctx, `/${collection}/`, browseQuery(input))) ?? {};
103
97
  const items = payload[collection];
104
98
  return {
105
- [collection]: Array.isArray(items) ? items.map((item) => record(item) ?? {}) : [],
106
- meta: record(payload.meta) ?? null
99
+ [collection]: Array.isArray(items) ? items.map((item) => asJsonObject(item) ?? {}) : [],
100
+ meta: asJsonObject(payload.meta) ?? null
107
101
  };
108
102
  }
109
103
  async function read(input, ctx, collection) {
110
- const id = text(input.id);
111
- const slug = text(input.slug);
104
+ const id = trimmedText(input.id);
105
+ const slug = trimmedText(input.slug);
112
106
  if (id === void 0 && slug === void 0) {
113
107
  throw new TBError("invalid_argument", "id or slug is required");
114
108
  }
115
109
  const path = id === void 0 ? `/${collection}/slug/${encodeURIComponent(slug)}/` : `/${collection}/${encodeURIComponent(id)}/`;
116
- const payload = record(await request(ctx, path, readQuery(input))) ?? {};
110
+ const payload = asJsonObject(await request(ctx, path, readQuery(input))) ?? {};
117
111
  const items = payload[collection];
118
- const resource = Array.isArray(items) ? record(items[0]) : void 0;
112
+ const resource = Array.isArray(items) ? asJsonObject(items[0]) : void 0;
119
113
  return { [collection.slice(0, -1)]: resource ?? null };
120
114
  }
121
115
  function listPosts(input, ctx) {
@@ -143,8 +137,8 @@ function getAuthor(input, ctx) {
143
137
  return read(input, ctx, "authors");
144
138
  }
145
139
  async function readSettings(_input, ctx) {
146
- const payload = record(await request(ctx, "/settings/"));
147
- return { settings: record(payload?.settings) ?? null };
140
+ const payload = asJsonObject(await request(ctx, "/settings/"));
141
+ return { settings: asJsonObject(payload?.settings) ?? null };
148
142
  }
149
143
 
150
144
  // ../plugins/src/ghost/schema.ts
@@ -1,31 +1,31 @@
1
+ import {
2
+ createProviderHttpClient
3
+ } from "./chunk-VLOIDU5U.js";
4
+ import {
5
+ asJsonObject,
6
+ compactDefined,
7
+ trimmedText
8
+ } from "./chunk-JXHMDBAY.js";
1
9
  import {
2
10
  createProviderPlugin,
3
11
  requireApiKey,
4
12
  upstreamError
5
- } from "./chunk-VK3V2WTY.js";
6
- import {
7
- guardedFetch
8
- } from "./chunk-2O27H4Y2.js";
9
- import "./chunk-GKX72JMJ.js";
13
+ } from "./chunk-B4P6YZFS.js";
14
+ import "./chunk-SWBNHIO4.js";
10
15
  import {
11
16
  TBError,
12
17
  external_exports
13
- } from "./chunk-YB2FLNWI.js";
14
- import "./chunk-MLKGABMK.js";
18
+ } from "./chunk-OKRZPQ3R.js";
19
+ import "./chunk-U67V476Y.js";
15
20
 
16
21
  // ../plugins/src/github/api/shared.ts
17
22
  var SERVICE = "github";
18
23
  var API_BASE = "https://api.github.com";
19
24
  var API_VERSION = "2022-11-28";
20
25
  var USER_AGENT = "tool-bridge";
21
- function text(value) {
22
- if (typeof value !== "string") return void 0;
23
- const trimmed = value.trim();
24
- return trimmed === "" ? void 0 : trimmed;
25
- }
26
- function record(value) {
27
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
28
- }
26
+ var http = createProviderHttpClient({ baseUrl: `${API_BASE}/`, service: SERVICE });
27
+ var text = trimmedText;
28
+ var record = asJsonObject;
29
29
  function objectArray(value) {
30
30
  return Array.isArray(value) ? value : [];
31
31
  }
@@ -68,31 +68,18 @@ function requireBranchOrTagRef(ref) {
68
68
  }
69
69
  return ref;
70
70
  }
71
- function buildUrl(path, query) {
72
- const url = new URL(`${API_BASE}${path}`);
73
- for (const [key, value] of Object.entries(query ?? {})) {
74
- if (value !== void 0) url.searchParams.set(key, String(value));
75
- }
76
- return url.toString();
77
- }
78
- function headers(ctx, hasJsonBody) {
79
- const result = {
71
+ function headers(ctx) {
72
+ return {
80
73
  "accept": "application/vnd.github+json",
81
74
  "authorization": `Bearer ${requireApiKey(ctx, SERVICE)}`,
82
75
  "x-github-api-version": API_VERSION,
83
76
  "user-agent": USER_AGENT
84
77
  };
85
- if (hasJsonBody) result["content-type"] = "application/json";
86
- return result;
87
78
  }
88
- async function readJson(response) {
89
- const body = await response.text();
90
- if (body === "") return null;
91
- try {
92
- return JSON.parse(body);
93
- } catch {
94
- return { message: body };
95
- }
79
+ function payloadOf(result) {
80
+ if (result.bodyKind === "empty") return null;
81
+ if (result.bodyKind === "json") return result.data;
82
+ return { message: String(result.data) };
96
83
  }
97
84
  function isRateLimited(response, message) {
98
85
  if (response.headers.get("x-ratelimit-remaining") === "0") return true;
@@ -122,12 +109,34 @@ function githubError(response, payload) {
122
109
  return upstreamError(response.status, message);
123
110
  }
124
111
  async function requestRaw(ctx, input) {
125
- const response = await guardedFetch(buildUrl(input.path, input.query), {
112
+ const result = await http.request({
126
113
  method: input.method ?? "GET",
127
- headers: headers(ctx, input.body !== void 0),
128
- body: input.body === void 0 ? void 0 : JSON.stringify(input.body)
114
+ path: input.path,
115
+ query: Object.entries(input.query ?? {}),
116
+ headers: headers(ctx),
117
+ ...input.body === void 0 ? {} : { json: input.body },
118
+ invalidJson: "text",
119
+ // GitHub 有三个 action 用 404 表达 false;其他调用方仍在下面将它映射为错误。
120
+ acceptStatuses: [404],
121
+ mapError: (context) => githubError(
122
+ {
123
+ headers: context.headers,
124
+ ok: false,
125
+ status: context.status,
126
+ statusText: context.statusText
127
+ },
128
+ payloadOf(context)
129
+ )
129
130
  });
130
- return { payload: await readJson(response), response };
131
+ return {
132
+ payload: payloadOf(result),
133
+ response: {
134
+ headers: result.headers,
135
+ ok: result.status >= 200 && result.status <= 299,
136
+ status: result.status,
137
+ statusText: result.statusText
138
+ }
139
+ };
131
140
  }
132
141
  async function requestJson(ctx, input) {
133
142
  const { payload, response } = await requestRaw(ctx, input);
@@ -144,9 +153,7 @@ async function requestNoContent(ctx, input) {
144
153
  const { payload, response } = await requestRaw(ctx, input);
145
154
  if (!response.ok) throw githubError(response, payload);
146
155
  }
147
- function compact(input) {
148
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
149
- }
156
+ var compact = compactDefined;
150
157
  function decodeContent(contentBase64, encoding) {
151
158
  if (contentBase64 === "") return "";
152
159
  if (encoding !== void 0 && encoding !== "base64") return void 0;
@@ -1,21 +1,25 @@
1
+ import {
2
+ createProviderHttpClient
3
+ } from "./chunk-VLOIDU5U.js";
4
+ import {
5
+ asJsonObject
6
+ } from "./chunk-JXHMDBAY.js";
1
7
  import {
2
8
  createProviderPlugin,
3
9
  requireApiKey,
4
10
  upstreamError
5
- } from "./chunk-VK3V2WTY.js";
6
- import {
7
- guardedFetch
8
- } from "./chunk-2O27H4Y2.js";
9
- import "./chunk-GKX72JMJ.js";
11
+ } from "./chunk-B4P6YZFS.js";
12
+ import "./chunk-SWBNHIO4.js";
10
13
  import {
11
14
  TBError,
12
15
  external_exports
13
- } from "./chunk-YB2FLNWI.js";
14
- import "./chunk-MLKGABMK.js";
16
+ } from "./chunk-OKRZPQ3R.js";
17
+ import "./chunk-U67V476Y.js";
15
18
 
16
19
  // ../plugins/src/gmail/api/shared.ts
17
20
  var SERVICE = "gmail";
18
21
  var API_BASE = "https://gmail.googleapis.com/gmail/v1";
22
+ var http = createProviderHttpClient({ baseUrl: `${API_BASE}/`, service: SERVICE });
19
23
  var USER_ID = "me";
20
24
  var RATE_LIMIT_REASONS = /* @__PURE__ */ new Set([
21
25
  "dailyLimitExceeded",
@@ -33,9 +37,7 @@ function toStringArray(value) {
33
37
  function normalizeFormat(value, fallback) {
34
38
  return trimmedString(value) || fallback;
35
39
  }
36
- function record(value) {
37
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
38
- }
40
+ var record = asJsonObject;
39
41
  function requireRecord(value, label) {
40
42
  const result = record(value);
41
43
  if (result === void 0) throw new TBError("unavailable", `Gmail \u7684 ${label} \u4E0D\u662F\u5BF9\u8C61`, { retryable: true });
@@ -77,18 +79,9 @@ async function hydrateInBatches(items, hydrate, batchSize = 10) {
77
79
  }
78
80
  return hydrated;
79
81
  }
80
- function buildUrl(path, query) {
82
+ function buildPath(path) {
81
83
  const segments = path.map((segment) => encodeURIComponent(segment)).join("/");
82
- const url = new URL(`${API_BASE}/users/${encodeURIComponent(USER_ID)}${segments === "" ? "" : `/${segments}`}`);
83
- for (const [key, value] of Object.entries(query)) {
84
- if (value === void 0) continue;
85
- if (Array.isArray(value)) {
86
- for (const item of value) url.searchParams.append(key, item);
87
- continue;
88
- }
89
- url.searchParams.set(key, String(value));
90
- }
91
- return url.toString();
84
+ return `users/${encodeURIComponent(USER_ID)}${segments === "" ? "" : `/${segments}`}`;
92
85
  }
93
86
  function errorMessage(payload) {
94
87
  const error = record(payload)?.error;
@@ -112,25 +105,22 @@ async function send(ctx, input) {
112
105
  const headers = {
113
106
  authorization: `Bearer ${requireApiKey(ctx, SERVICE)}`
114
107
  };
115
- if (hasBody) headers["content-type"] = "application/json";
116
- const response = await guardedFetch(buildUrl(input.path, input.query ?? {}), {
108
+ const response = await http.request({
117
109
  method: input.method ?? "GET",
110
+ path: buildPath(input.path),
111
+ query: Object.entries(input.query ?? {}),
118
112
  headers,
119
- ...hasBody ? { body: JSON.stringify(input.body) } : {}
113
+ ...hasBody ? { json: input.body } : {},
114
+ invalidJson: "text",
115
+ mapError: ({ bodyKind, data, status }) => gmailError(
116
+ status,
117
+ bodyKind === "json" ? data : null
118
+ )
120
119
  });
121
- const body = await response.text();
122
- let payload = null;
123
- if (body !== "") {
124
- try {
125
- payload = JSON.parse(body);
126
- } catch {
127
- if (response.ok) {
128
- throw new TBError("unavailable", "Gmail \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94", { retryable: true });
129
- }
130
- }
120
+ if (response.bodyKind === "invalid-json") {
121
+ throw new TBError("unavailable", "Gmail \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94", { retryable: true });
131
122
  }
132
- if (!response.ok) throw gmailError(response.status, payload);
133
- return { payload };
123
+ return { payload: response.bodyKind === "empty" ? null : response.data };
134
124
  }
135
125
  async function requestJson(ctx, input) {
136
126
  return (await send(ctx, input)).payload;
@@ -1,22 +1,29 @@
1
+ import {
2
+ createProviderHttpClient
3
+ } from "./chunk-VLOIDU5U.js";
4
+ import {
5
+ asJsonObject,
6
+ compactDefined,
7
+ trimmedText
8
+ } from "./chunk-JXHMDBAY.js";
1
9
  import {
2
10
  createProviderPlugin,
3
11
  requireApiKey,
4
12
  upstreamError
5
- } from "./chunk-VK3V2WTY.js";
6
- import {
7
- guardedFetch
8
- } from "./chunk-2O27H4Y2.js";
9
- import "./chunk-GKX72JMJ.js";
13
+ } from "./chunk-B4P6YZFS.js";
14
+ import "./chunk-SWBNHIO4.js";
10
15
  import {
11
16
  TBError,
12
17
  external_exports
13
- } from "./chunk-YB2FLNWI.js";
14
- import "./chunk-MLKGABMK.js";
18
+ } from "./chunk-OKRZPQ3R.js";
19
+ import "./chunk-U67V476Y.js";
15
20
 
16
21
  // ../plugins/src/googlecalendar/api/shared.ts
17
22
  var SERVICE = "googlecalendar";
18
23
  var API_BASE = "https://www.googleapis.com/calendar/v3";
19
24
  var REQUEST_TIMEOUT_MS = 3e4;
25
+ var GOOGLE_API_ORIGIN = new URL(API_BASE).origin;
26
+ var http = createProviderHttpClient({ baseUrl: `${GOOGLE_API_ORIGIN}/`, service: SERVICE });
20
27
  var MAX_ERROR_MESSAGE_LENGTH = 500;
21
28
  var RATE_LIMIT_REASONS = /* @__PURE__ */ new Set([
22
29
  "rateLimitExceeded",
@@ -24,14 +31,8 @@ var RATE_LIMIT_REASONS = /* @__PURE__ */ new Set([
24
31
  "quotaExceeded",
25
32
  "dailyLimitExceeded"
26
33
  ]);
27
- function text(value) {
28
- if (typeof value !== "string") return void 0;
29
- const trimmed = value.trim();
30
- return trimmed === "" ? void 0 : trimmed;
31
- }
32
- function record(value) {
33
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
34
- }
34
+ var text = trimmedText;
35
+ var record = asJsonObject;
35
36
  function requireRecord(value, label) {
36
37
  const result = record(value);
37
38
  if (result === void 0) {
@@ -39,11 +40,7 @@ function requireRecord(value, label) {
39
40
  }
40
41
  return result;
41
42
  }
42
- function compact(input) {
43
- return Object.fromEntries(
44
- Object.entries(input).filter((entry) => entry[1] !== void 0)
45
- );
46
- }
43
+ var compact = compactDefined;
47
44
  function bool(value) {
48
45
  return value === void 0 ? void 0 : String(value);
49
46
  }
@@ -64,98 +61,80 @@ function repeated(value) {
64
61
  const items = value.filter((item) => item !== "");
65
62
  return items.length > 0 ? items : void 0;
66
63
  }
67
- function buildUrl(url, query) {
64
+ function requestTarget(url, query) {
68
65
  const target = new URL(url);
69
- for (const [key, value] of Object.entries(query ?? {})) {
70
- if (value === void 0) continue;
71
- if (Array.isArray(value)) {
72
- for (const item of value) target.searchParams.append(key, item);
73
- continue;
74
- }
75
- target.searchParams.set(key, value);
66
+ if (target.origin !== GOOGLE_API_ORIGIN) {
67
+ throw new TBError("invalid_argument", "Google Calendar \u8BF7\u6C42\u5FC5\u987B\u4FDD\u6301\u5728 Google API origin");
76
68
  }
77
- return target.toString();
78
- }
79
- function headers(ctx, hasJsonBody) {
80
- const result = {
81
- accept: "application/json",
82
- authorization: `Bearer ${requireApiKey(ctx, SERVICE)}`
69
+ return {
70
+ path: target.pathname.replace(/^\/+/, ""),
71
+ query: [
72
+ ...target.searchParams.entries(),
73
+ ...Object.entries(query ?? {})
74
+ ]
83
75
  };
84
- if (hasJsonBody) result["content-type"] = "application/json";
85
- return result;
86
76
  }
87
77
  function truncate(value) {
88
78
  return value.length <= MAX_ERROR_MESSAGE_LENGTH ? value : `${value.slice(0, MAX_ERROR_MESSAGE_LENGTH)}\u2026`;
89
79
  }
90
- async function readError(response) {
91
- const raw = await response.text().catch(() => "");
92
- const fallback = `Google Calendar \u8FD4\u56DE HTTP ${response.status}`;
93
- if (raw === "") return { message: fallback, reasons: [] };
94
- let payload;
95
- try {
96
- payload = JSON.parse(raw);
97
- } catch {
98
- return { message: truncate(raw), reasons: [] };
99
- }
80
+ function readError(context) {
81
+ const fallback = `Google Calendar \u8FD4\u56DE HTTP ${context.status}`;
82
+ if (context.bodyKind === "empty") return { message: fallback, reasons: [] };
83
+ if (context.bodyKind !== "json") return { message: truncate(String(context.data)), reasons: [] };
84
+ const payload = context.data;
100
85
  const body = record(payload);
101
86
  const error = record(body?.error);
102
87
  const reasons = Array.isArray(error?.errors) ? error.errors.map((item) => text(record(item)?.reason)).filter((item) => item !== void 0) : [];
103
- const message = text(error?.message) ?? text(body?.error_description) ?? truncate(raw);
88
+ const serialized = JSON.stringify(payload);
89
+ const message = text(error?.message) ?? text(body?.error_description) ?? (serialized === void 0 ? fallback : truncate(serialized));
104
90
  return { message, reasons };
105
91
  }
106
- async function calendarError(response, syncTokenAware) {
107
- const { message, reasons } = await readError(response);
108
- if (syncTokenAware && response.status === 410) {
92
+ function calendarError(context, syncTokenAware) {
93
+ const { message, reasons } = readError(context);
94
+ if (syncTokenAware && context.status === 410) {
109
95
  return new TBError(
110
96
  "invalid_argument",
111
97
  `syncToken \u5DF2\u8FC7\u671F,\u53BB\u6389 syncToken \u91CD\u65B0\u505A\u4E00\u6B21\u5168\u91CF\u540C\u6B65(\u4E0A\u6E38:${message})`
112
98
  );
113
99
  }
114
- if (response.status === 403 && reasons.some((reason) => RATE_LIMIT_REASONS.has(reason))) {
100
+ if (context.status === 403 && reasons.some((reason) => RATE_LIMIT_REASONS.has(reason))) {
115
101
  return upstreamError(429, message);
116
102
  }
117
- return upstreamError(response.status, message);
103
+ return upstreamError(context.status, message);
118
104
  }
119
105
  async function send(ctx, input) {
120
106
  const hasBody = input.body !== void 0;
121
- let response;
122
- try {
123
- response = await guardedFetch(buildUrl(input.url, input.query), {
124
- method: input.method ?? (hasBody ? "POST" : "GET"),
125
- headers: headers(ctx, hasBody),
126
- body: hasBody ? JSON.stringify(input.body) : void 0,
127
- // 不设超时会让一个挂死的端点拖住整个调用;上游同样给了 30s 的独立预算。
128
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
129
- });
130
- } catch (error) {
131
- if (error instanceof TBError) throw error;
132
- if (error instanceof Error && error.name === "TimeoutError") {
133
- throw upstreamError(504, `Google Calendar \u8BF7\u6C42\u8D85\u65F6(${REQUEST_TIMEOUT_MS / 1e3} \u79D2)`);
134
- }
135
- const message = error instanceof Error ? error.message : "unknown network error";
136
- throw upstreamError(502, `Google Calendar \u8BF7\u6C42\u5931\u8D25:${message}`);
137
- }
138
- if (!response.ok) throw await calendarError(response, input.syncTokenAware ?? false);
139
- return response;
107
+ const target = requestTarget(input.url, input.query);
108
+ return await http.request({
109
+ method: input.method ?? (hasBody ? "POST" : "GET"),
110
+ path: target.path,
111
+ query: target.query,
112
+ headers: {
113
+ accept: "application/json",
114
+ authorization: `Bearer ${requireApiKey(ctx, SERVICE)}`
115
+ },
116
+ ...hasBody ? { json: input.body } : {},
117
+ invalidJson: "text",
118
+ timeoutMs: REQUEST_TIMEOUT_MS,
119
+ mapError: (context) => calendarError(context, input.syncTokenAware ?? false),
120
+ mapTransportError: ({ kind, message }) => kind === "timeout" ? upstreamError(504, `Google Calendar \u8BF7\u6C42\u8D85\u65F6(${REQUEST_TIMEOUT_MS / 1e3} \u79D2)`) : upstreamError(502, `Google Calendar \u8BF7\u6C42\u5931\u8D25:${message ?? "unknown network error"}`)
121
+ });
140
122
  }
141
123
  async function requestJson(ctx, input) {
142
124
  const response = await send(ctx, input);
143
- const body = await response.text();
144
- if (body === "") {
125
+ if (response.bodyKind === "empty") {
145
126
  throw new TBError("unavailable", "Google Calendar \u5728\u5E94\u56DE JSON \u7684\u5730\u65B9\u56DE\u4E86\u7A7A\u54CD\u5E94\u4F53", { retryable: true });
146
127
  }
147
- try {
148
- return JSON.parse(body);
149
- } catch {
128
+ if (response.bodyKind !== "json") {
150
129
  throw new TBError("unavailable", "Google Calendar \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94", { retryable: true });
151
130
  }
131
+ return response.data;
152
132
  }
153
133
  async function requestRecord(ctx, input) {
154
134
  return requireRecord(await requestJson(ctx, input), "Google Calendar \u54CD\u5E94");
155
135
  }
156
136
  async function requestNoContent(ctx, input) {
157
- const response = await send(ctx, input);
158
- await response.text().catch(() => "");
137
+ await send(ctx, input);
159
138
  }
160
139
  async function deleteWithSuccess(ctx, url) {
161
140
  await requestNoContent(ctx, { url, method: "DELETE" });