@oomol-lab/open-connector 1.6.4 → 1.7.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 (320) hide show
  1. package/assets/open-connector/catalog/apps/aisa.json +6394 -0
  2. package/assets/open-connector/catalog/apps/baizhi_mcp.json +135 -0
  3. package/assets/open-connector/catalog/apps/bilibili.json +2586 -0
  4. package/assets/open-connector/catalog/apps/bitwarden.json +1423 -0
  5. package/assets/open-connector/catalog/apps/cronfree.json +303 -0
  6. package/assets/open-connector/catalog/apps/cufinder.json +368 -0
  7. package/assets/open-connector/catalog/apps/discordbot.json +2888 -248
  8. package/assets/open-connector/catalog/apps/drawio_mcp.json +192 -0
  9. package/assets/open-connector/catalog/apps/firecrawl.json +176 -32
  10. package/assets/open-connector/catalog/apps/framejet.json +273 -0
  11. package/assets/open-connector/catalog/apps/futunn.json +2967 -0
  12. package/assets/open-connector/catalog/apps/gmail.json +298 -0
  13. package/assets/open-connector/catalog/apps/google_analytics.json +4 -1
  14. package/assets/open-connector/catalog/apps/google_bigquery.json +4 -1
  15. package/assets/open-connector/catalog/apps/google_search_console.json +4 -1
  16. package/assets/open-connector/catalog/apps/googlecalendar.json +4 -1
  17. package/assets/open-connector/catalog/apps/googlechat.json +694 -7
  18. package/assets/open-connector/catalog/apps/googledocs.json +4 -1
  19. package/assets/open-connector/catalog/apps/googlesheets.json +4 -1
  20. package/assets/open-connector/catalog/apps/granola.json +23 -0
  21. package/assets/open-connector/catalog/apps/investoday_mcp.json +22228 -197
  22. package/assets/open-connector/catalog/apps/ixspy.json +2274 -0
  23. package/assets/open-connector/catalog/apps/keepa.json +3534 -987
  24. package/assets/open-connector/catalog/apps/linear.json +17 -0
  25. package/assets/open-connector/catalog/apps/linear_mcp.json +510 -0
  26. package/assets/open-connector/catalog/apps/moneyforward_mcp.json +1432 -0
  27. package/assets/open-connector/catalog/apps/notion.json +446 -1
  28. package/assets/open-connector/catalog/apps/notion_mcp.json +490 -0
  29. package/assets/open-connector/catalog/apps/odoo.json +619 -0
  30. package/assets/open-connector/catalog/apps/osv.json +663 -0
  31. package/assets/open-connector/catalog/apps/outlook.json +30 -8
  32. package/assets/open-connector/catalog/apps/outlook_calendar.json +23 -2
  33. package/assets/open-connector/catalog/apps/pdf_vector.json +329 -0
  34. package/assets/open-connector/catalog/apps/postiz.json +334 -0
  35. package/assets/open-connector/catalog/apps/proworkflow.json +529 -0
  36. package/assets/open-connector/catalog/apps/pulsetic.json +406 -0
  37. package/assets/open-connector/catalog/apps/sellersprite_mcp.json +2 -1
  38. package/assets/open-connector/catalog/apps/shopee.json +1785 -0
  39. package/assets/open-connector/catalog/apps/slack.json +304 -0
  40. package/assets/open-connector/catalog/apps/slackbot.json +295 -0
  41. package/assets/open-connector/catalog/apps/speak_ai.json +360 -0
  42. package/assets/open-connector/catalog/apps/tencent_docs.json +3 -0
  43. package/assets/open-connector/catalog/apps/wisburg.json +1528 -0
  44. package/assets/open-connector/catalog/apps/youtube.json +4 -1
  45. package/assets/open-connector/catalog/apps/zerotier.json +3319 -0
  46. package/assets/open-connector/catalog/apps/zyhub.json +1585 -0
  47. package/assets/open-connector/catalog/apps-index.json +1 -1
  48. package/package.json +1 -1
  49. package/src/core/cast.d.ts +10 -0
  50. package/src/core/cast.js +14 -0
  51. package/src/core/guarded-fetch.d.ts +6 -3
  52. package/src/core/guarded-fetch.js +6 -3
  53. package/src/core/json-schema.d.ts +5 -1
  54. package/src/core/json-schema.js +14 -2
  55. package/src/core/provider-scenarios.js +67 -13
  56. package/src/core/request.js +4 -1
  57. package/src/core/types.d.ts +10 -1
  58. package/src/mcp.js +10 -7
  59. package/src/oauth/oauth-client-config-service.d.ts +16 -1
  60. package/src/oauth/oauth-client-config-service.js +59 -3
  61. package/src/oauth/oauth-credential-refresh-service.js +3 -1
  62. package/src/oauth/oauth-flow-service.d.ts +6 -0
  63. package/src/oauth/oauth-flow-service.js +21 -4
  64. package/src/oauth/oauth-token.d.ts +13 -0
  65. package/src/providers/17track/runtime.js +1 -1
  66. package/src/providers/action-contracts.generated.d.ts +32 -8
  67. package/src/providers/aifinmarket/runtime.js +1 -1
  68. package/src/providers/aisa/executors.d.ts +4 -0
  69. package/src/providers/aisa/executors.js +864 -0
  70. package/src/providers/aliyun_ack/runtime.js +1 -1
  71. package/src/providers/aliyun_sls/runtime.js +1 -1
  72. package/src/providers/app_store_server/runtime-helpers.js +1 -1
  73. package/src/providers/baizhi_mcp/actions.d.ts +2 -0
  74. package/src/providers/baizhi_mcp/actions.js +40 -0
  75. package/src/providers/baizhi_mcp/executors.d.ts +3 -0
  76. package/src/providers/baizhi_mcp/executors.js +102 -0
  77. package/src/providers/bazhuayu/runtime.js +2 -2
  78. package/src/providers/bilibili/articles.d.ts +3 -0
  79. package/src/providers/bilibili/articles.js +369 -0
  80. package/src/providers/bilibili/executors.d.ts +8 -0
  81. package/src/providers/bilibili/executors.js +262 -0
  82. package/src/providers/bilibili/runtime.d.ts +95 -0
  83. package/src/providers/bilibili/runtime.js +236 -0
  84. package/src/providers/bilibili/upload.d.ts +14 -0
  85. package/src/providers/bilibili/upload.js +107 -0
  86. package/src/providers/bitwarden/executors.d.ts +3 -0
  87. package/src/providers/bitwarden/executors.js +146 -0
  88. package/src/providers/cloudflare_browser_rendering/executors.js +1 -1
  89. package/src/providers/cloudflare_dns/executors.js +1 -1
  90. package/src/providers/{cloudflare-current-user.js → cloudflare_dns/runtime-user.js} +2 -2
  91. package/src/providers/cloudflare_dns/runtime.d.ts +1 -1
  92. package/src/providers/cloudflare_dns/runtime.js +1 -1
  93. package/src/providers/cloudflare_r2/executors.js +1 -1
  94. package/src/providers/cloudflare_r2/runtime.d.ts +1 -1
  95. package/src/providers/cloudflare_r2/runtime.js +1 -1
  96. package/src/providers/cloudflare_worker/executors.js +1 -1
  97. package/src/providers/cloudflare_worker/runtime.d.ts +1 -1
  98. package/src/providers/cloudflare_worker/runtime.js +1 -1
  99. package/src/providers/cronfree/executors.d.ts +4 -0
  100. package/src/providers/cronfree/executors.js +89 -0
  101. package/src/providers/cufinder/executors.d.ts +4 -0
  102. package/src/providers/cufinder/executors.js +105 -0
  103. package/src/providers/dingtalk_mcp/runtime.js +1 -1
  104. package/src/providers/discordbot/executors.d.ts +0 -9
  105. package/src/providers/discordbot/executors.js +9 -101
  106. package/src/providers/discordbot/runtime-guilds.d.ts +3 -0
  107. package/src/providers/discordbot/runtime-guilds.js +464 -0
  108. package/src/providers/discordbot/runtime.d.ts +42 -0
  109. package/src/providers/discordbot/runtime.js +124 -0
  110. package/src/providers/drawio_mcp/executors.d.ts +3 -0
  111. package/src/providers/drawio_mcp/executors.js +19 -0
  112. package/src/providers/drawio_mcp/runtime.d.ts +8 -0
  113. package/src/providers/drawio_mcp/runtime.js +175 -0
  114. package/src/providers/elevenreader/runtime.js +6 -5
  115. package/src/providers/fastmoss_mcp/executors.js +2 -2
  116. package/src/providers/finchina/executors.js +1 -1
  117. package/src/providers/framejet/executors.d.ts +4 -0
  118. package/src/providers/framejet/executors.js +19 -0
  119. package/src/providers/framejet/runtime.d.ts +16 -0
  120. package/src/providers/framejet/runtime.js +148 -0
  121. package/src/providers/futunn/actions.d.ts +2 -0
  122. package/src/providers/futunn/actions.js +152 -0
  123. package/src/providers/futunn/actions.research.d.ts +2 -0
  124. package/src/providers/futunn/actions.research.js +423 -0
  125. package/src/providers/futunn/actions.trading.d.ts +2 -0
  126. package/src/providers/futunn/actions.trading.js +204 -0
  127. package/src/providers/futunn/executors.d.ts +3 -0
  128. package/src/providers/futunn/executors.js +24 -0
  129. package/src/providers/futunn/runtime-research.d.ts +3 -0
  130. package/src/providers/futunn/runtime-research.js +133 -0
  131. package/src/providers/futunn/runtime-trading.d.ts +3 -0
  132. package/src/providers/futunn/runtime-trading.js +39 -0
  133. package/src/providers/futunn/runtime.d.ts +2 -0
  134. package/src/providers/futunn/runtime.js +50 -0
  135. package/src/providers/futunn/transport.d.ts +11 -0
  136. package/src/providers/futunn/transport.js +76 -0
  137. package/src/providers/gildata/executors.js +1 -1
  138. package/src/providers/gmail/attachment-stream.d.ts +2 -0
  139. package/src/providers/gmail/attachment-stream.js +162 -0
  140. package/src/providers/gmail/executors.d.ts +3 -1
  141. package/src/providers/gmail/executors.js +54 -26
  142. package/src/providers/gmail/message.d.ts +6 -8
  143. package/src/providers/gmail/message.js +4 -0
  144. package/src/providers/gmail/scopes.d.ts +32 -0
  145. package/src/providers/gmail/scopes.js +37 -0
  146. package/src/providers/google_analytics/executors.js +2 -2
  147. package/src/providers/google_analytics/scopes.js +6 -1
  148. package/src/providers/google_bigquery/executors.js +2 -2
  149. package/src/providers/google_bigquery/scopes.js +2 -0
  150. package/src/providers/google_search_console/executors.js +2 -2
  151. package/src/providers/google_search_console/scopes.js +2 -0
  152. package/src/providers/googleads/executors.js +1 -1
  153. package/src/providers/googleads/scopes.d.ts +1 -3
  154. package/src/providers/googleads/scopes.js +2 -4
  155. package/src/providers/googlecalendar/executors.js +1 -1
  156. package/src/providers/googlecalendar/runtime-shared.js +2 -2
  157. package/src/providers/googlecalendar/scopes.js +2 -0
  158. package/src/providers/googlechat/executors.d.ts +1 -3
  159. package/src/providers/googlechat/executors.js +219 -28
  160. package/src/providers/googlechat/members.d.ts +55 -0
  161. package/src/providers/googlechat/members.js +293 -0
  162. package/src/providers/googlechat/runtime.d.ts +16 -0
  163. package/src/providers/googlechat/runtime.js +25 -0
  164. package/src/providers/googlechat/scopes.d.ts +22 -3
  165. package/src/providers/googlechat/scopes.js +30 -7
  166. package/src/providers/googledocs/executors.js +1 -1
  167. package/src/providers/googledrive/executors.js +2 -2
  168. package/src/providers/{google-auth.d.ts → googledrive/runtime-auth.d.ts} +2 -2
  169. package/src/providers/{google-auth.js → googledrive/runtime-auth.js} +3 -3
  170. package/src/providers/googledrive/runtime-collaboration.js +1 -1
  171. package/src/providers/{google-runtime.d.ts → googledrive/runtime-request.d.ts} +1 -1
  172. package/src/providers/{google-runtime.js → googledrive/runtime-request.js} +2 -2
  173. package/src/providers/googleforms/executors.js +2 -2
  174. package/src/providers/googleforms/scopes.d.ts +0 -3
  175. package/src/providers/googleforms/scopes.js +2 -6
  176. package/src/providers/googlemeet/executors.js +2 -2
  177. package/src/providers/googlemeet/scopes.d.ts +0 -3
  178. package/src/providers/googlemeet/scopes.js +2 -6
  179. package/src/providers/googlesheets/executors.js +1 -1
  180. package/src/providers/googlesheets/scopes.js +2 -0
  181. package/src/providers/googleslides/executors.js +2 -2
  182. package/src/providers/googleslides/scopes.d.ts +0 -3
  183. package/src/providers/googleslides/scopes.js +2 -6
  184. package/src/providers/googletasks/executors.js +2 -2
  185. package/src/providers/googletasks/scopes.d.ts +0 -3
  186. package/src/providers/googletasks/scopes.js +2 -6
  187. package/src/providers/granola/actions.js +2 -0
  188. package/src/providers/granola/runtime-mcp.js +2 -0
  189. package/src/providers/granola/runtime.js +2 -2
  190. package/src/providers/indiegogo/executors.js +1 -1
  191. package/src/providers/investoday_mcp/executors.js +2 -2
  192. package/src/providers/investoday_mcp/official-actions.js +19 -372
  193. package/src/providers/investoday_mcp/official-tool-types.d.ts +10 -0
  194. package/src/providers/investoday_mcp/official-tool-types.js +4 -0
  195. package/src/providers/investoday_mcp/official-tools/charts.d.ts +2 -0
  196. package/src/providers/investoday_mcp/official-tools/charts.js +32 -0
  197. package/src/providers/investoday_mcp/official-tools/fixed-income.d.ts +2 -0
  198. package/src/providers/investoday_mcp/official-tools/fixed-income.js +326 -0
  199. package/src/providers/investoday_mcp/official-tools/funds.d.ts +2 -0
  200. package/src/providers/investoday_mcp/official-tools/funds.js +1085 -0
  201. package/src/providers/investoday_mcp/official-tools/hong-kong.d.ts +2 -0
  202. package/src/providers/investoday_mcp/official-tools/hong-kong.js +275 -0
  203. package/src/providers/investoday_mcp/official-tools/indices-industries.d.ts +2 -0
  204. package/src/providers/investoday_mcp/official-tools/indices-industries.js +642 -0
  205. package/src/providers/investoday_mcp/official-tools/macro-calendar.d.ts +2 -0
  206. package/src/providers/investoday_mcp/official-tools/macro-calendar.js +398 -0
  207. package/src/providers/investoday_mcp/official-tools/other.d.ts +2 -0
  208. package/src/providers/investoday_mcp/official-tools/other.js +131 -0
  209. package/src/providers/investoday_mcp/official-tools/research-news.d.ts +2 -0
  210. package/src/providers/investoday_mcp/official-tools/research-news.js +302 -0
  211. package/src/providers/investoday_mcp/official-tools/stocks.d.ts +2 -0
  212. package/src/providers/investoday_mcp/official-tools/stocks.js +2829 -0
  213. package/src/providers/ixspy/executors.d.ts +3 -0
  214. package/src/providers/ixspy/executors.js +220 -0
  215. package/src/providers/iyunbiao/runtime.js +2 -2
  216. package/src/providers/keepa/actions.d.ts +1 -1
  217. package/src/providers/keepa/actions.js +371 -149
  218. package/src/providers/keepa/deal-attributes.d.ts +1 -0
  219. package/src/providers/keepa/deal-attributes.js +26 -0
  220. package/src/providers/keepa/runtime.js +212 -18
  221. package/src/providers/kingdee/executors.js +1 -1
  222. package/src/providers/kingdee/runtime.js +2 -2
  223. package/src/providers/kuaidi100/runtime.js +1 -1
  224. package/src/providers/linear/executors.js +12 -9
  225. package/src/providers/linear_mcp/actions.d.ts +47 -0
  226. package/src/providers/linear_mcp/actions.js +102 -0
  227. package/src/providers/linear_mcp/endpoints.d.ts +3 -0
  228. package/src/providers/linear_mcp/endpoints.js +3 -0
  229. package/src/providers/linear_mcp/executors.d.ts +3 -0
  230. package/src/providers/linear_mcp/executors.js +9 -0
  231. package/src/providers/linear_mcp/runtime-mcp.d.ts +15 -0
  232. package/src/providers/linear_mcp/runtime-mcp.js +238 -0
  233. package/src/providers/lingxing_mcp/runtime.js +1 -1
  234. package/src/providers/mcdonalds_cn_mcp/runtime.js +1 -1
  235. package/src/providers/metabase/mcp-runtime.js +1 -1
  236. package/src/providers/moneyforward_mcp/executors.d.ts +3 -0
  237. package/src/providers/moneyforward_mcp/executors.js +11 -0
  238. package/src/providers/moneyforward_mcp/manifest.d.ts +31 -0
  239. package/src/providers/moneyforward_mcp/manifest.js +204 -0
  240. package/src/providers/moneyforward_mcp/runtime.d.ts +18 -0
  241. package/src/providers/moneyforward_mcp/runtime.js +296 -0
  242. package/src/providers/notion/executors.js +39 -3
  243. package/src/providers/notion_mcp/endpoints.d.ts +3 -0
  244. package/src/providers/notion_mcp/endpoints.js +3 -0
  245. package/src/providers/notion_mcp/executors.d.ts +3 -0
  246. package/src/providers/notion_mcp/executors.js +176 -0
  247. package/src/providers/notion_mcp/mcp-response.d.ts +86 -0
  248. package/src/providers/notion_mcp/mcp-response.js +314 -0
  249. package/src/providers/odoo/executors.d.ts +3 -0
  250. package/src/providers/odoo/executors.js +32 -0
  251. package/src/providers/odoo/runtime.d.ts +16 -0
  252. package/src/providers/odoo/runtime.js +140 -0
  253. package/src/providers/osv/executors.d.ts +2 -0
  254. package/src/providers/osv/executors.js +11 -0
  255. package/src/providers/osv/runtime.d.ts +9 -0
  256. package/src/providers/osv/runtime.js +66 -0
  257. package/src/providers/outlook/executors.js +27 -6
  258. package/src/providers/outlook/microsoft-graph.js +17 -6
  259. package/src/providers/outlook_calendar/executors.js +24 -7
  260. package/src/providers/patsnap_mcp/executors.js +2 -2
  261. package/src/providers/pdf_vector/executors.d.ts +4 -0
  262. package/src/providers/pdf_vector/executors.js +108 -0
  263. package/src/providers/postiz/executors.d.ts +4 -0
  264. package/src/providers/postiz/executors.js +83 -0
  265. package/src/providers/provider-runtime.d.ts +18 -0
  266. package/src/providers/provider-runtime.js +60 -4
  267. package/src/providers/proworkflow/executors.d.ts +4 -0
  268. package/src/providers/proworkflow/executors.js +135 -0
  269. package/src/providers/pulsetic/executors.d.ts +4 -0
  270. package/src/providers/pulsetic/executors.js +126 -0
  271. package/src/providers/registry.generated.js +24 -0
  272. package/src/providers/scrape_creators/catalog.js +1 -1
  273. package/src/providers/scrape_creators/runtime.js +1 -1
  274. package/src/providers/sellersprite_mcp/executors.js +2 -2
  275. package/src/providers/sellersprite_mcp/official-actions.js +3 -2
  276. package/src/providers/sentry/runtime.js +6 -7
  277. package/src/providers/shopee/actions.d.ts +2 -0
  278. package/src/providers/shopee/actions.js +474 -0
  279. package/src/providers/shopee/executors.d.ts +3 -0
  280. package/src/providers/shopee/executors.js +85 -0
  281. package/src/providers/shopee/runtime.d.ts +79 -0
  282. package/src/providers/shopee/runtime.js +693 -0
  283. package/src/providers/slack/actions.js +69 -3
  284. package/src/providers/slack/runtime.js +116 -21
  285. package/src/providers/slickdeals/runtime.js +1 -1
  286. package/src/providers/sorftime_mcp/executors.js +2 -2
  287. package/src/providers/speak_ai/executors.d.ts +3 -0
  288. package/src/providers/speak_ai/executors.js +187 -0
  289. package/src/providers/tikhub/bounded-response.d.ts +1 -1
  290. package/src/providers/tikhub/bounded-response.js +8 -34
  291. package/src/providers/tikhub/endpoint-catalog.js +1 -1
  292. package/src/providers/tikhub/runtime.js +2 -2
  293. package/src/providers/tongdaxin/executors.js +79 -15
  294. package/src/providers/tushare/runtime.js +22 -9
  295. package/src/providers/uspto/executors.js +1 -1
  296. package/src/providers/waffo/executors.js +1 -1
  297. package/src/providers/waffo/runtime.js +1 -1
  298. package/src/providers/wecom_mcp/runtime.js +1 -1
  299. package/src/providers/wisburg/executors.d.ts +4 -0
  300. package/src/providers/wisburg/executors.js +13 -0
  301. package/src/providers/wisburg/runtime.d.ts +12 -0
  302. package/src/providers/wisburg/runtime.js +133 -0
  303. package/src/providers/xydc_mcp/executors.js +2 -2
  304. package/src/providers/youtube/executors.js +1 -1
  305. package/src/providers/youtube/runtime.js +1 -1
  306. package/src/providers/zerotier/executors.d.ts +9 -0
  307. package/src/providers/zerotier/executors.js +629 -0
  308. package/src/providers/zerotier/runtime.d.ts +54 -0
  309. package/src/providers/zerotier/runtime.js +207 -0
  310. package/src/providers/zyhub/executors.d.ts +3 -0
  311. package/src/providers/zyhub/executors.js +240 -0
  312. package/src/server/api/openapi.js +12 -2
  313. package/src/server/api/runtime-api.d.ts +8 -1
  314. package/src/server/api/runtime-api.js +19 -1
  315. package/src/server/connect-server.js +10 -2
  316. package/src/server/files/transit-files.d.ts +3 -2
  317. package/src/server/files/transit-files.js +31 -35
  318. package/src/providers/sentry/scopes.d.ts +0 -1
  319. package/src/providers/sentry/scopes.js +0 -7
  320. /package/src/providers/{cloudflare-current-user.d.ts → cloudflare_dns/runtime-user.d.ts} +0 -0
@@ -1,10 +1,10 @@
1
- import { Buffer } from "node:buffer";
2
1
  import { optionalBoolean, optionalInteger, optionalRecord, optionalString, requiredString } from "../../core/cast.js";
3
- import { encodePathSegment, jsonObject } from "../../core/request.js";
4
- import { defineApiKeyProviderExecutors, defineProviderProxy, providerInputError, ProviderRequestError, providerResponseError, } from "../provider-runtime.js";
2
+ import { jsonObject } from "../../core/request.js";
3
+ import { combineProviderActionHandlers, defineApiKeyProviderExecutors, defineProviderProxy, ProviderRequestError, providerResponseError, } from "../provider-runtime.js";
4
+ import { guildActionHandlers } from "./runtime-guilds.js";
5
+ import { discordProxyBaseUrl, discordbotRequest, discordbotRequestJson, discordbotRequestNoContent, requiredPath, } from "./runtime.js";
5
6
  const service = "discordbot";
6
- const discordApiBaseUrl = "https://discord.com/api";
7
- export const discordbotActionHandlers = {
7
+ const coreActionHandlers = {
8
8
  test_auth(_input, context) {
9
9
  return testAuth(context);
10
10
  },
@@ -29,18 +29,6 @@ export const discordbotActionHandlers = {
29
29
  get_user(input, context) {
30
30
  return discordbotRequestJson({ path: `/users/${requiredPath(input.user_id, "user_id")}`, context });
31
31
  },
32
- get_guild(input, context) {
33
- return discordbotRequestJson({ path: `/guilds/${requiredPath(input.guild_id, "guild_id")}`, context });
34
- },
35
- list_guild_channels(input, context) {
36
- return discordbotRequestJson({
37
- path: `/guilds/${requiredPath(input.guild_id, "guild_id")}/channels`,
38
- context,
39
- }).then((channels) => ({ channels }));
40
- },
41
- list_guild_roles(input, context) {
42
- return discordbotRequestJson({ path: `/guilds/${requiredPath(input.guild_id, "guild_id")}/roles`, context }).then((roles) => ({ roles }));
43
- },
44
32
  get_channel(input, context) {
45
33
  return discordbotRequestJson({ path: `/channels/${requiredPath(input.channel_id, "channel_id")}`, context });
46
34
  },
@@ -77,22 +65,18 @@ export const discordbotActionHandlers = {
77
65
  context,
78
66
  }).then((message) => ({ message }));
79
67
  },
80
- async delete_message(input, context) {
81
- await discordbotRequest({
68
+ delete_message(input, context) {
69
+ return discordbotRequestNoContent({
82
70
  method: "DELETE",
83
71
  path: `/channels/${requiredPath(input.channel_id, "channel_id")}/messages/${requiredPath(input.message_id, "message_id")}`,
84
72
  context,
85
73
  });
86
- return { success: true };
87
- },
88
- get_guild_widget_png(input, context) {
89
- return getGuildWidgetPng(input, context);
90
74
  },
91
75
  };
92
- export const executors = defineApiKeyProviderExecutors(service, discordbotActionHandlers);
76
+ export const executors = defineApiKeyProviderExecutors(service, combineProviderActionHandlers(service, coreActionHandlers, guildActionHandlers));
93
77
  export const proxy = defineProviderProxy({
94
78
  service,
95
- baseUrl: discordApiBaseUrl,
79
+ baseUrl: discordProxyBaseUrl,
96
80
  auth: { type: "api_key_authorization", prefix: "Bot " },
97
81
  });
98
82
  export const credentialValidators = {
@@ -125,85 +109,9 @@ async function testAuth(context) {
125
109
  error_body: await response.text().catch(() => ""),
126
110
  };
127
111
  }
128
- async function getGuildWidgetPng(input, context) {
129
- const guildId = requiredString(input.guild_id, "guild_id", providerInputError);
130
- const response = await discordbotRequest({
131
- path: `/guilds/${encodePathSegment(guildId)}/widget.png`,
132
- query: jsonObject({ style: optionalString(input.style) }),
133
- context,
134
- authenticated: false,
135
- });
136
- const buffer = Buffer.from(await response.arrayBuffer());
137
- return {
138
- filename: `discord-guild-${guildId}-widget-${optionalString(input.style) ?? "shield"}.png`,
139
- mimeType: response.headers.get("content-type") ?? "image/png",
140
- sizeBytes: buffer.byteLength,
141
- dataBase64: buffer.toString("base64"),
142
- };
143
- }
144
- async function discordbotRequestJson(input) {
145
- const response = await discordbotRequest(input);
146
- try {
147
- return (await response.json());
148
- }
149
- catch {
150
- throw new ProviderRequestError(502, "Discord returned invalid JSON");
151
- }
152
- }
153
- async function discordbotRequest(input) {
154
- const url = new URL(`${discordApiBaseUrl}${input.path}`);
155
- for (const [key, value] of Object.entries(input.query ?? {})) {
156
- if (value !== undefined) {
157
- url.searchParams.set(key, String(value));
158
- }
159
- }
160
- const headers = new Headers();
161
- if (input.authenticated !== false) {
162
- headers.set("authorization", `Bot ${input.context.apiKey}`);
163
- }
164
- if (input.body !== undefined) {
165
- headers.set("content-type", "application/json");
166
- }
167
- const response = await input.context.fetcher(url, {
168
- method: input.method,
169
- headers,
170
- body: input.body === undefined ? undefined : JSON.stringify(input.body),
171
- signal: input.context.signal,
172
- });
173
- if (!input.skipError && !response.ok) {
174
- throw await toDiscordbotError(response, input.authenticated !== false);
175
- }
176
- return response;
177
- }
178
- async function toDiscordbotError(response, authenticated) {
179
- const text = await response.text().catch(() => "");
180
- let message = text;
181
- if (text) {
182
- try {
183
- const parsed = JSON.parse(text);
184
- message =
185
- optionalString(parsed.message) ??
186
- optionalString(parsed.error_description) ??
187
- optionalString(parsed.error) ??
188
- text;
189
- }
190
- catch { }
191
- }
192
- const resolvedMessage = message || `Discord request failed with ${response.status}`;
193
- if (authenticated && (response.status === 401 || response.status === 403)) {
194
- return new ProviderRequestError(401, resolvedMessage);
195
- }
196
- if (response.status === 429) {
197
- return new ProviderRequestError(429, resolvedMessage);
198
- }
199
- return new ProviderRequestError(response.status, resolvedMessage);
200
- }
201
112
  function assertSingleCursor(input) {
202
113
  const count = [input.around, input.before, input.after].filter((value) => optionalString(value)).length;
203
114
  if (count > 1) {
204
115
  throw new ProviderRequestError(400, "list_messages accepts only one of around, before, or after");
205
116
  }
206
117
  }
207
- function requiredPath(value, field) {
208
- return encodePathSegment(requiredString(value, field, providerInputError));
209
- }
@@ -0,0 +1,3 @@
1
+ import type { ProviderActionHandlerSubset } from "../provider-runtime.ts";
2
+ import type { DiscordbotActionHandler } from "./runtime.ts";
3
+ export declare const guildActionHandlers: ProviderActionHandlerSubset<"discordbot", DiscordbotActionHandler>;
@@ -0,0 +1,464 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { booleanString, looseArray, nullableBoolean, nullableInteger, nullableRawString, nullableString, objectArray, optionalBoolean, optionalInteger, optionalRawString, optionalRecord, optionalString, optionalStringArray, recordOrEmpty, } from "../../core/cast.js";
3
+ import { jsonObject } from "../../core/request.js";
4
+ import { providerInputError, requiredInputString } from "../provider-runtime.js";
5
+ import { discordbotRequest, discordbotRequestJson, discordbotRequestJsonOrNull, discordbotRequestNoContent, requiredPath, } from "./runtime.js";
6
+ export const guildActionHandlers = {
7
+ get_guild(input, context) {
8
+ return discordbotRequestJson({
9
+ path: guildPath(input),
10
+ query: { with_counts: booleanString(input.with_counts) },
11
+ context,
12
+ });
13
+ },
14
+ get_guild_preview(input, context) {
15
+ return discordbotRequestJson({ path: `${guildPath(input)}/preview`, context });
16
+ },
17
+ modify_guild(input, context) {
18
+ return discordbotRequestJson({
19
+ method: "PATCH",
20
+ path: guildPath(input),
21
+ body: jsonObject({
22
+ name: optionalString(input.name),
23
+ verification_level: nullableInteger(input.verification_level),
24
+ default_message_notifications: nullableInteger(input.default_message_notifications),
25
+ explicit_content_filter: nullableInteger(input.explicit_content_filter),
26
+ afk_channel_id: nullableString(input.afk_channel_id),
27
+ afk_timeout: optionalInteger(input.afk_timeout),
28
+ icon: nullableString(input.icon),
29
+ splash: nullableString(input.splash),
30
+ discovery_splash: nullableString(input.discovery_splash),
31
+ banner: nullableString(input.banner),
32
+ system_channel_id: nullableString(input.system_channel_id),
33
+ system_channel_flags: optionalInteger(input.system_channel_flags),
34
+ rules_channel_id: nullableString(input.rules_channel_id),
35
+ public_updates_channel_id: nullableString(input.public_updates_channel_id),
36
+ safety_alerts_channel_id: nullableString(input.safety_alerts_channel_id),
37
+ preferred_locale: nullableString(input.preferred_locale),
38
+ features: optionalStringArray(input.features),
39
+ description: nullableRawString(input.description),
40
+ premium_progress_bar_enabled: optionalBoolean(input.premium_progress_bar_enabled),
41
+ }),
42
+ auditLogReason: input.audit_log_reason,
43
+ context,
44
+ });
45
+ },
46
+ list_guild_channels(input, context) {
47
+ return discordbotRequestJson({ path: `${guildPath(input)}/channels`, context }).then((channels) => ({ channels }));
48
+ },
49
+ create_guild_channel(input, context) {
50
+ return discordbotRequestJson({
51
+ method: "POST",
52
+ path: `${guildPath(input)}/channels`,
53
+ body: jsonObject({
54
+ name: requiredInputString(input.name, "name"),
55
+ type: optionalInteger(input.type),
56
+ topic: channelTopic(input),
57
+ bitrate: optionalInteger(input.bitrate),
58
+ user_limit: optionalInteger(input.user_limit),
59
+ rate_limit_per_user: optionalInteger(input.rate_limit_per_user),
60
+ position: optionalInteger(input.position),
61
+ permission_overwrites: Array.isArray(input.permission_overwrites) ? input.permission_overwrites : undefined,
62
+ parent_id: optionalString(input.parent_id),
63
+ nsfw: optionalBoolean(input.nsfw),
64
+ rtc_region: nullableString(input.rtc_region),
65
+ video_quality_mode: optionalInteger(input.video_quality_mode),
66
+ default_auto_archive_duration: optionalInteger(input.default_auto_archive_duration),
67
+ default_reaction_emoji: optionalRecord(input.default_reaction_emoji),
68
+ available_tags: Array.isArray(input.available_tags) ? input.available_tags : undefined,
69
+ default_sort_order: optionalInteger(input.default_sort_order),
70
+ default_forum_layout: optionalInteger(input.default_forum_layout),
71
+ default_thread_rate_limit_per_user: optionalInteger(input.default_thread_rate_limit_per_user),
72
+ flags: optionalInteger(input.flags),
73
+ }),
74
+ auditLogReason: input.audit_log_reason,
75
+ context,
76
+ }).then((channel) => ({ channel }));
77
+ },
78
+ modify_guild_channel_positions(input, context) {
79
+ return discordbotRequestNoContent({
80
+ method: "PATCH",
81
+ path: `${guildPath(input)}/channels`,
82
+ body: requiredPositions(input.positions).map((position) => jsonObject({
83
+ id: requiredInputString(position.id, "positions[].id"),
84
+ position: nullableInteger(position.position),
85
+ lock_permissions: nullableBoolean(position.lock_permissions),
86
+ parent_id: nullableString(position.parent_id),
87
+ flags: nullableInteger(position.flags),
88
+ })),
89
+ context,
90
+ });
91
+ },
92
+ list_active_guild_threads(input, context) {
93
+ return discordbotRequestJson({ path: `${guildPath(input)}/threads/active`, context }).then((value) => {
94
+ const response = recordOrEmpty(value);
95
+ return { threads: looseArray(response.threads), members: looseArray(response.members) };
96
+ });
97
+ },
98
+ get_guild_member(input, context) {
99
+ return discordbotRequestJson({ path: memberPath(input), context });
100
+ },
101
+ list_guild_members(input, context) {
102
+ return discordbotRequestJson({
103
+ path: `${guildPath(input)}/members`,
104
+ query: { limit: optionalInteger(input.limit), after: optionalString(input.after) },
105
+ context,
106
+ }).then((members) => ({ members }));
107
+ },
108
+ search_guild_members(input, context) {
109
+ return discordbotRequestJson({
110
+ path: `${guildPath(input)}/members/search`,
111
+ query: {
112
+ query: requiredInputString(input.query, "query"),
113
+ limit: optionalInteger(input.limit),
114
+ },
115
+ context,
116
+ }).then((members) => ({ members }));
117
+ },
118
+ add_guild_member(input, context) {
119
+ return addGuildMember(input, context);
120
+ },
121
+ modify_guild_member(input, context) {
122
+ return discordbotRequestJsonOrNull({
123
+ method: "PATCH",
124
+ path: memberPath(input),
125
+ body: jsonObject({
126
+ nick: nullableRawString(input.nick),
127
+ roles: input.roles === null ? null : optionalStringArray(input.roles),
128
+ mute: nullableBoolean(input.mute),
129
+ deaf: nullableBoolean(input.deaf),
130
+ channel_id: nullableString(input.channel_id),
131
+ communication_disabled_until: nullableString(input.communication_disabled_until),
132
+ flags: nullableInteger(input.flags),
133
+ }),
134
+ auditLogReason: input.audit_log_reason,
135
+ context,
136
+ }).then((member) => ({ member }));
137
+ },
138
+ modify_current_member(input, context) {
139
+ return discordbotRequestJson({
140
+ method: "PATCH",
141
+ path: `${guildPath(input)}/members/@me`,
142
+ body: jsonObject({
143
+ nick: nullableRawString(input.nick),
144
+ avatar: nullableString(input.avatar),
145
+ banner: nullableString(input.banner),
146
+ bio: nullableRawString(input.bio),
147
+ }),
148
+ auditLogReason: input.audit_log_reason,
149
+ context,
150
+ });
151
+ },
152
+ add_guild_member_role(input, context) {
153
+ return discordbotRequestNoContent({
154
+ method: "PUT",
155
+ path: `${memberPath(input)}/roles/${requiredPath(input.role_id, "role_id")}`,
156
+ auditLogReason: input.audit_log_reason,
157
+ context,
158
+ });
159
+ },
160
+ remove_guild_member_role(input, context) {
161
+ return discordbotRequestNoContent({
162
+ method: "DELETE",
163
+ path: `${memberPath(input)}/roles/${requiredPath(input.role_id, "role_id")}`,
164
+ auditLogReason: input.audit_log_reason,
165
+ context,
166
+ });
167
+ },
168
+ remove_guild_member(input, context) {
169
+ return discordbotRequestNoContent({
170
+ method: "DELETE",
171
+ path: memberPath(input),
172
+ auditLogReason: input.audit_log_reason,
173
+ context,
174
+ });
175
+ },
176
+ list_guild_bans(input, context) {
177
+ return discordbotRequestJson({
178
+ path: `${guildPath(input)}/bans`,
179
+ query: {
180
+ limit: optionalInteger(input.limit),
181
+ before: optionalString(input.before),
182
+ after: optionalString(input.after),
183
+ },
184
+ context,
185
+ }).then((bans) => ({ bans }));
186
+ },
187
+ get_guild_ban(input, context) {
188
+ return discordbotRequestJson({ path: banPath(input), context });
189
+ },
190
+ create_guild_ban(input, context) {
191
+ return discordbotRequestNoContent({
192
+ method: "PUT",
193
+ path: banPath(input),
194
+ body: jsonObject({ delete_message_seconds: optionalInteger(input.delete_message_seconds) }),
195
+ auditLogReason: input.audit_log_reason,
196
+ context,
197
+ });
198
+ },
199
+ remove_guild_ban(input, context) {
200
+ return discordbotRequestNoContent({
201
+ method: "DELETE",
202
+ path: banPath(input),
203
+ auditLogReason: input.audit_log_reason,
204
+ context,
205
+ });
206
+ },
207
+ bulk_guild_ban(input, context) {
208
+ const userIds = optionalStringArray(input.user_ids);
209
+ if (!userIds || userIds.length === 0) {
210
+ throw providerInputError("user_ids must be a non-empty array of user ids");
211
+ }
212
+ return discordbotRequestJson({
213
+ method: "POST",
214
+ path: `${guildPath(input)}/bulk-ban`,
215
+ body: jsonObject({
216
+ user_ids: userIds,
217
+ delete_message_seconds: optionalInteger(input.delete_message_seconds),
218
+ }),
219
+ auditLogReason: input.audit_log_reason,
220
+ context,
221
+ }).then((value) => {
222
+ const response = recordOrEmpty(value);
223
+ return { banned_users: looseArray(response.banned_users), failed_users: looseArray(response.failed_users) };
224
+ });
225
+ },
226
+ list_guild_roles(input, context) {
227
+ return discordbotRequestJson({ path: `${guildPath(input)}/roles`, context }).then((roles) => ({ roles }));
228
+ },
229
+ get_guild_role(input, context) {
230
+ return discordbotRequestJson({ path: rolePath(input), context });
231
+ },
232
+ get_guild_role_member_counts(input, context) {
233
+ return discordbotRequestJson({ path: `${guildPath(input)}/roles/member-counts`, context }).then((counts) => ({
234
+ member_counts: recordOrEmpty(counts),
235
+ }));
236
+ },
237
+ create_guild_role(input, context) {
238
+ return discordbotRequestJson({
239
+ method: "POST",
240
+ path: `${guildPath(input)}/roles`,
241
+ body: roleBody(input),
242
+ auditLogReason: input.audit_log_reason,
243
+ context,
244
+ });
245
+ },
246
+ modify_guild_role_positions(input, context) {
247
+ return discordbotRequestJson({
248
+ method: "PATCH",
249
+ path: `${guildPath(input)}/roles`,
250
+ body: requiredPositions(input.positions).map((position) => jsonObject({
251
+ id: requiredInputString(position.id, "positions[].id"),
252
+ position: nullableInteger(position.position),
253
+ })),
254
+ auditLogReason: input.audit_log_reason,
255
+ context,
256
+ }).then((roles) => ({ roles }));
257
+ },
258
+ modify_guild_role(input, context) {
259
+ return discordbotRequestJson({
260
+ method: "PATCH",
261
+ path: rolePath(input),
262
+ body: roleBody(input),
263
+ auditLogReason: input.audit_log_reason,
264
+ context,
265
+ });
266
+ },
267
+ delete_guild_role(input, context) {
268
+ return discordbotRequestNoContent({
269
+ method: "DELETE",
270
+ path: rolePath(input),
271
+ auditLogReason: input.audit_log_reason,
272
+ context,
273
+ });
274
+ },
275
+ get_guild_prune_count(input, context) {
276
+ return discordbotRequestJson({
277
+ path: `${guildPath(input)}/prune`,
278
+ query: {
279
+ days: optionalInteger(input.days),
280
+ include_roles: optionalStringArray(input.include_roles)?.join(","),
281
+ },
282
+ context,
283
+ });
284
+ },
285
+ begin_guild_prune(input, context) {
286
+ return discordbotRequestJson({
287
+ method: "POST",
288
+ path: `${guildPath(input)}/prune`,
289
+ body: jsonObject({
290
+ days: optionalInteger(input.days),
291
+ compute_prune_count: optionalBoolean(input.compute_prune_count),
292
+ include_roles: optionalStringArray(input.include_roles),
293
+ }),
294
+ auditLogReason: input.audit_log_reason,
295
+ context,
296
+ });
297
+ },
298
+ list_guild_voice_regions(input, context) {
299
+ return discordbotRequestJson({ path: `${guildPath(input)}/regions`, context }).then((regions) => ({ regions }));
300
+ },
301
+ list_guild_invites(input, context) {
302
+ return discordbotRequestJson({ path: `${guildPath(input)}/invites`, context }).then((invites) => ({ invites }));
303
+ },
304
+ list_guild_integrations(input, context) {
305
+ return discordbotRequestJson({ path: `${guildPath(input)}/integrations`, context }).then((integrations) => ({
306
+ integrations,
307
+ }));
308
+ },
309
+ delete_guild_integration(input, context) {
310
+ return discordbotRequestNoContent({
311
+ method: "DELETE",
312
+ path: `${guildPath(input)}/integrations/${requiredPath(input.integration_id, "integration_id")}`,
313
+ auditLogReason: input.audit_log_reason,
314
+ context,
315
+ });
316
+ },
317
+ get_guild_widget_settings(input, context) {
318
+ return discordbotRequestJson({ path: `${guildPath(input)}/widget`, context });
319
+ },
320
+ modify_guild_widget(input, context) {
321
+ return discordbotRequestJson({
322
+ method: "PATCH",
323
+ path: `${guildPath(input)}/widget`,
324
+ body: jsonObject({
325
+ enabled: optionalBoolean(input.enabled),
326
+ channel_id: nullableString(input.channel_id),
327
+ }),
328
+ auditLogReason: input.audit_log_reason,
329
+ context,
330
+ });
331
+ },
332
+ get_guild_widget(input, context) {
333
+ return discordbotRequestJson({ path: `${guildPath(input)}/widget.json`, context });
334
+ },
335
+ get_guild_vanity_url(input, context) {
336
+ return discordbotRequestJson({ path: `${guildPath(input)}/vanity-url`, context });
337
+ },
338
+ get_guild_widget_png(input, context) {
339
+ return getGuildWidgetPng(input, context);
340
+ },
341
+ get_guild_welcome_screen(input, context) {
342
+ return discordbotRequestJson({ path: `${guildPath(input)}/welcome-screen`, context });
343
+ },
344
+ modify_guild_welcome_screen(input, context) {
345
+ return discordbotRequestJson({
346
+ method: "PATCH",
347
+ path: `${guildPath(input)}/welcome-screen`,
348
+ body: jsonObject({
349
+ enabled: nullableBoolean(input.enabled),
350
+ welcome_channels: input.welcome_channels === null
351
+ ? null
352
+ : Array.isArray(input.welcome_channels)
353
+ ? input.welcome_channels
354
+ : undefined,
355
+ description: nullableRawString(input.description),
356
+ }),
357
+ auditLogReason: input.audit_log_reason,
358
+ context,
359
+ });
360
+ },
361
+ get_guild_onboarding(input, context) {
362
+ return discordbotRequestJson({ path: `${guildPath(input)}/onboarding`, context });
363
+ },
364
+ modify_guild_onboarding(input, context) {
365
+ return discordbotRequestJson({
366
+ method: "PUT",
367
+ path: `${guildPath(input)}/onboarding`,
368
+ body: jsonObject({
369
+ prompts: Array.isArray(input.prompts) ? input.prompts : undefined,
370
+ default_channel_ids: optionalStringArray(input.default_channel_ids),
371
+ enabled: optionalBoolean(input.enabled),
372
+ mode: optionalInteger(input.mode),
373
+ }),
374
+ auditLogReason: input.audit_log_reason,
375
+ context,
376
+ });
377
+ },
378
+ modify_guild_incident_actions(input, context) {
379
+ return discordbotRequestJson({
380
+ method: "PUT",
381
+ path: `${guildPath(input)}/incident-actions`,
382
+ body: jsonObject({
383
+ invites_disabled_until: nullableString(input.invites_disabled_until),
384
+ dms_disabled_until: nullableString(input.dms_disabled_until),
385
+ }),
386
+ context,
387
+ });
388
+ },
389
+ };
390
+ async function addGuildMember(input, context) {
391
+ // Discord answers 204 with no body when the user is already in the guild.
392
+ const member = await discordbotRequestJsonOrNull({
393
+ method: "PUT",
394
+ path: memberPath(input),
395
+ body: jsonObject({
396
+ access_token: requiredInputString(input.access_token, "access_token"),
397
+ nick: optionalRawString(input.nick),
398
+ roles: optionalStringArray(input.roles),
399
+ mute: optionalBoolean(input.mute),
400
+ deaf: optionalBoolean(input.deaf),
401
+ }),
402
+ context,
403
+ });
404
+ return { already_member: member === null, member };
405
+ }
406
+ async function getGuildWidgetPng(input, context) {
407
+ const guildId = requiredInputString(input.guild_id, "guild_id");
408
+ const response = await discordbotRequest({
409
+ path: `${guildPath(input)}/widget.png`,
410
+ query: { style: optionalString(input.style) },
411
+ context,
412
+ authenticated: false,
413
+ });
414
+ const buffer = Buffer.from(await response.arrayBuffer());
415
+ return {
416
+ filename: `discord-guild-${guildId}-widget-${optionalString(input.style) ?? "shield"}.png`,
417
+ mimeType: response.headers.get("content-type") ?? "image/png",
418
+ sizeBytes: buffer.byteLength,
419
+ dataBase64: buffer.toString("base64"),
420
+ };
421
+ }
422
+ /**
423
+ * Discord allows 4096 characters in the topic of a forum (15) or media (16) channel
424
+ * and 1024 in every other channel type, including the default text channel.
425
+ */
426
+ function channelTopic(input) {
427
+ const topic = optionalRawString(input.topic);
428
+ const type = optionalInteger(input.type);
429
+ if (topic !== undefined && type !== 15 && type !== 16 && [...topic].length > 1024) {
430
+ throw providerInputError("topic must be at most 1024 characters unless type is 15 (forum) or 16 (media)");
431
+ }
432
+ return topic;
433
+ }
434
+ function roleBody(input) {
435
+ return jsonObject({
436
+ name: optionalRawString(input.name),
437
+ permissions: optionalString(input.permissions),
438
+ color: optionalInteger(input.color),
439
+ colors: optionalRecord(input.colors),
440
+ hoist: optionalBoolean(input.hoist),
441
+ icon: nullableString(input.icon),
442
+ unicode_emoji: nullableString(input.unicode_emoji),
443
+ mentionable: optionalBoolean(input.mentionable),
444
+ });
445
+ }
446
+ function requiredPositions(value) {
447
+ const positions = objectArray(value, "positions", providerInputError);
448
+ if (positions.length === 0) {
449
+ throw providerInputError("positions must not be empty");
450
+ }
451
+ return positions;
452
+ }
453
+ function guildPath(input) {
454
+ return `/guilds/${requiredPath(input.guild_id, "guild_id")}`;
455
+ }
456
+ function memberPath(input) {
457
+ return `${guildPath(input)}/members/${requiredPath(input.user_id, "user_id")}`;
458
+ }
459
+ function banPath(input) {
460
+ return `${guildPath(input)}/bans/${requiredPath(input.user_id, "user_id")}`;
461
+ }
462
+ function rolePath(input) {
463
+ return `${guildPath(input)}/roles/${requiredPath(input.role_id, "role_id")}`;
464
+ }
@@ -0,0 +1,42 @@
1
+ export declare const discordProxyBaseUrl = "https://discord.com/api";
2
+ export interface DiscordbotContext {
3
+ apiKey: string;
4
+ fetcher: typeof fetch;
5
+ signal?: AbortSignal;
6
+ }
7
+ export type DiscordbotActionHandler = (input: Record<string, unknown>, context: DiscordbotContext) => Promise<unknown>;
8
+ interface DiscordbotRequestOptions {
9
+ method?: string;
10
+ path: string;
11
+ query?: Record<string, unknown>;
12
+ /** JSON body. Discord's position endpoints take a top-level array. */
13
+ body?: Record<string, unknown> | unknown[];
14
+ context: DiscordbotContext;
15
+ authenticated?: boolean;
16
+ skipError?: boolean;
17
+ /** Sent as `X-Audit-Log-Reason` on endpoints that record one. */
18
+ auditLogReason?: unknown;
19
+ }
20
+ /** Send a Discord request and parse the JSON response body. */
21
+ export declare function discordbotRequestJson(input: DiscordbotRequestOptions): Promise<unknown>;
22
+ /**
23
+ * Send a Discord request whose success may be 200 with a JSON body or 204 with none,
24
+ * returning null for the 204.
25
+ */
26
+ export declare function discordbotRequestJsonOrNull(input: DiscordbotRequestOptions): Promise<unknown>;
27
+ /** Send a Discord request that answers with 204 No Content. */
28
+ export declare function discordbotRequestNoContent(input: DiscordbotRequestOptions): Promise<{
29
+ success: true;
30
+ }>;
31
+ /** Send a Discord request, mapping non-2xx responses to provider errors unless `skipError` is set. */
32
+ export declare function discordbotRequest(input: DiscordbotRequestOptions): Promise<Response>;
33
+ /**
34
+ * Read a required snowflake input for use as one URL path segment. Only digits are
35
+ * accepted, because percent-encoding cannot keep an arbitrary id inside one segment:
36
+ * URL parsing resolves `.` and `..` as dot segments, and Discord decodes `%2F` into a
37
+ * path separator before routing. Either would send the request, with the same method
38
+ * and bot token, to another endpoint: `role_id: ".."` turns a role DELETE into one on
39
+ * the guild itself, and `user_id: "U/roles/R"` on Add Guild Member grants role R.
40
+ */
41
+ export declare function requiredPath(value: unknown, field: string): string;
42
+ export {};