@oomol-lab/open-connector 1.6.5 → 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 (243) hide show
  1. package/assets/open-connector/catalog/apps/aisa.json +6138 -312
  2. package/assets/open-connector/catalog/apps/baizhi_mcp.json +135 -0
  3. package/assets/open-connector/catalog/apps/discordbot.json +2888 -248
  4. package/assets/open-connector/catalog/apps/drawio_mcp.json +192 -0
  5. package/assets/open-connector/catalog/apps/firecrawl.json +176 -32
  6. package/assets/open-connector/catalog/apps/framejet.json +273 -0
  7. package/assets/open-connector/catalog/apps/futunn.json +2967 -0
  8. package/assets/open-connector/catalog/apps/gmail.json +225 -0
  9. package/assets/open-connector/catalog/apps/google_analytics.json +4 -1
  10. package/assets/open-connector/catalog/apps/google_bigquery.json +4 -1
  11. package/assets/open-connector/catalog/apps/google_search_console.json +4 -1
  12. package/assets/open-connector/catalog/apps/googlecalendar.json +4 -1
  13. package/assets/open-connector/catalog/apps/googlechat.json +694 -7
  14. package/assets/open-connector/catalog/apps/googledocs.json +4 -1
  15. package/assets/open-connector/catalog/apps/googlesheets.json +4 -1
  16. package/assets/open-connector/catalog/apps/granola.json +23 -0
  17. package/assets/open-connector/catalog/apps/keepa.json +3534 -987
  18. package/assets/open-connector/catalog/apps/linear.json +17 -0
  19. package/assets/open-connector/catalog/apps/linear_mcp.json +510 -0
  20. package/assets/open-connector/catalog/apps/moneyforward_mcp.json +1432 -0
  21. package/assets/open-connector/catalog/apps/notion.json +446 -1
  22. package/assets/open-connector/catalog/apps/notion_mcp.json +490 -0
  23. package/assets/open-connector/catalog/apps/odoo.json +619 -0
  24. package/assets/open-connector/catalog/apps/outlook.json +30 -8
  25. package/assets/open-connector/catalog/apps/outlook_calendar.json +23 -2
  26. package/assets/open-connector/catalog/apps/postiz.json +334 -0
  27. package/assets/open-connector/catalog/apps/proworkflow.json +529 -0
  28. package/assets/open-connector/catalog/apps/sellersprite_mcp.json +2 -1
  29. package/assets/open-connector/catalog/apps/slack.json +223 -0
  30. package/assets/open-connector/catalog/apps/slackbot.json +214 -0
  31. package/assets/open-connector/catalog/apps/tencent_docs.json +3 -0
  32. package/assets/open-connector/catalog/apps/wisburg.json +1528 -0
  33. package/assets/open-connector/catalog/apps/youtube.json +4 -1
  34. package/assets/open-connector/catalog/apps/zerotier.json +3319 -0
  35. package/assets/open-connector/catalog/apps-index.json +1 -1
  36. package/package.json +1 -1
  37. package/src/core/cast.d.ts +10 -0
  38. package/src/core/cast.js +14 -0
  39. package/src/core/guarded-fetch.d.ts +6 -3
  40. package/src/core/guarded-fetch.js +6 -3
  41. package/src/core/provider-scenarios.js +67 -13
  42. package/src/core/request.js +4 -1
  43. package/src/core/types.d.ts +1 -1
  44. package/src/mcp.js +10 -7
  45. package/src/oauth/oauth-client-config-service.d.ts +16 -1
  46. package/src/oauth/oauth-client-config-service.js +59 -3
  47. package/src/oauth/oauth-flow-service.d.ts +6 -0
  48. package/src/oauth/oauth-flow-service.js +4 -2
  49. package/src/providers/17track/runtime.js +1 -1
  50. package/src/providers/action-contracts.generated.d.ts +17 -5
  51. package/src/providers/aifinmarket/runtime.js +1 -1
  52. package/src/providers/aisa/executors.js +734 -46
  53. package/src/providers/aliyun_ack/runtime.js +1 -1
  54. package/src/providers/aliyun_sls/runtime.js +1 -1
  55. package/src/providers/app_store_server/runtime-helpers.js +1 -1
  56. package/src/providers/baizhi_mcp/actions.d.ts +2 -0
  57. package/src/providers/baizhi_mcp/actions.js +40 -0
  58. package/src/providers/baizhi_mcp/executors.d.ts +3 -0
  59. package/src/providers/baizhi_mcp/executors.js +102 -0
  60. package/src/providers/bazhuayu/runtime.js +2 -2
  61. package/src/providers/bilibili/runtime.js +2 -4
  62. package/src/providers/bilibili/upload.js +9 -7
  63. package/src/providers/cloudflare_browser_rendering/executors.js +1 -1
  64. package/src/providers/cloudflare_dns/executors.js +1 -1
  65. package/src/providers/{cloudflare-current-user.js → cloudflare_dns/runtime-user.js} +2 -2
  66. package/src/providers/cloudflare_dns/runtime.d.ts +1 -1
  67. package/src/providers/cloudflare_dns/runtime.js +1 -1
  68. package/src/providers/cloudflare_r2/executors.js +1 -1
  69. package/src/providers/cloudflare_r2/runtime.d.ts +1 -1
  70. package/src/providers/cloudflare_r2/runtime.js +1 -1
  71. package/src/providers/cloudflare_worker/executors.js +1 -1
  72. package/src/providers/cloudflare_worker/runtime.d.ts +1 -1
  73. package/src/providers/cloudflare_worker/runtime.js +1 -1
  74. package/src/providers/dingtalk_mcp/runtime.js +1 -1
  75. package/src/providers/discordbot/executors.d.ts +0 -9
  76. package/src/providers/discordbot/executors.js +9 -101
  77. package/src/providers/discordbot/runtime-guilds.d.ts +3 -0
  78. package/src/providers/discordbot/runtime-guilds.js +464 -0
  79. package/src/providers/discordbot/runtime.d.ts +42 -0
  80. package/src/providers/discordbot/runtime.js +124 -0
  81. package/src/providers/drawio_mcp/executors.d.ts +3 -0
  82. package/src/providers/drawio_mcp/executors.js +19 -0
  83. package/src/providers/drawio_mcp/runtime.d.ts +8 -0
  84. package/src/providers/drawio_mcp/runtime.js +175 -0
  85. package/src/providers/fastmoss_mcp/executors.js +2 -2
  86. package/src/providers/finchina/executors.js +1 -1
  87. package/src/providers/framejet/executors.d.ts +4 -0
  88. package/src/providers/framejet/executors.js +19 -0
  89. package/src/providers/framejet/runtime.d.ts +16 -0
  90. package/src/providers/framejet/runtime.js +148 -0
  91. package/src/providers/futunn/actions.d.ts +2 -0
  92. package/src/providers/futunn/actions.js +152 -0
  93. package/src/providers/futunn/actions.research.d.ts +2 -0
  94. package/src/providers/futunn/actions.research.js +423 -0
  95. package/src/providers/futunn/actions.trading.d.ts +2 -0
  96. package/src/providers/futunn/actions.trading.js +204 -0
  97. package/src/providers/futunn/executors.d.ts +3 -0
  98. package/src/providers/futunn/executors.js +24 -0
  99. package/src/providers/futunn/runtime-research.d.ts +3 -0
  100. package/src/providers/futunn/runtime-research.js +133 -0
  101. package/src/providers/futunn/runtime-trading.d.ts +3 -0
  102. package/src/providers/futunn/runtime-trading.js +39 -0
  103. package/src/providers/futunn/runtime.d.ts +2 -0
  104. package/src/providers/futunn/runtime.js +50 -0
  105. package/src/providers/futunn/transport.d.ts +11 -0
  106. package/src/providers/futunn/transport.js +76 -0
  107. package/src/providers/gildata/executors.js +1 -1
  108. package/src/providers/gmail/executors.js +3 -3
  109. package/src/providers/gmail/message.d.ts +6 -8
  110. package/src/providers/gmail/message.js +4 -0
  111. package/src/providers/gmail/scopes.d.ts +32 -0
  112. package/src/providers/gmail/scopes.js +37 -0
  113. package/src/providers/google_analytics/executors.js +2 -2
  114. package/src/providers/google_analytics/scopes.js +6 -1
  115. package/src/providers/google_bigquery/executors.js +2 -2
  116. package/src/providers/google_bigquery/scopes.js +2 -0
  117. package/src/providers/google_search_console/executors.js +2 -2
  118. package/src/providers/google_search_console/scopes.js +2 -0
  119. package/src/providers/googleads/executors.js +1 -1
  120. package/src/providers/googleads/scopes.d.ts +1 -3
  121. package/src/providers/googleads/scopes.js +2 -4
  122. package/src/providers/googlecalendar/executors.js +1 -1
  123. package/src/providers/googlecalendar/runtime-shared.js +2 -2
  124. package/src/providers/googlecalendar/scopes.js +2 -0
  125. package/src/providers/googlechat/executors.d.ts +1 -3
  126. package/src/providers/googlechat/executors.js +219 -28
  127. package/src/providers/googlechat/members.d.ts +55 -0
  128. package/src/providers/googlechat/members.js +293 -0
  129. package/src/providers/googlechat/runtime.d.ts +16 -0
  130. package/src/providers/googlechat/runtime.js +25 -0
  131. package/src/providers/googlechat/scopes.d.ts +22 -3
  132. package/src/providers/googlechat/scopes.js +30 -7
  133. package/src/providers/googledocs/executors.js +1 -1
  134. package/src/providers/googledrive/executors.js +2 -2
  135. package/src/providers/{google-auth.d.ts → googledrive/runtime-auth.d.ts} +2 -2
  136. package/src/providers/{google-auth.js → googledrive/runtime-auth.js} +3 -3
  137. package/src/providers/googledrive/runtime-collaboration.js +1 -1
  138. package/src/providers/{google-runtime.d.ts → googledrive/runtime-request.d.ts} +1 -1
  139. package/src/providers/{google-runtime.js → googledrive/runtime-request.js} +2 -2
  140. package/src/providers/googleforms/executors.js +2 -2
  141. package/src/providers/googleforms/scopes.d.ts +0 -3
  142. package/src/providers/googleforms/scopes.js +2 -6
  143. package/src/providers/googlemeet/executors.js +2 -2
  144. package/src/providers/googlemeet/scopes.d.ts +0 -3
  145. package/src/providers/googlemeet/scopes.js +2 -6
  146. package/src/providers/googlesheets/executors.js +1 -1
  147. package/src/providers/googlesheets/scopes.js +2 -0
  148. package/src/providers/googleslides/executors.js +2 -2
  149. package/src/providers/googleslides/scopes.d.ts +0 -3
  150. package/src/providers/googleslides/scopes.js +2 -6
  151. package/src/providers/googletasks/executors.js +2 -2
  152. package/src/providers/googletasks/scopes.d.ts +0 -3
  153. package/src/providers/googletasks/scopes.js +2 -6
  154. package/src/providers/granola/actions.js +2 -0
  155. package/src/providers/granola/runtime-mcp.js +2 -0
  156. package/src/providers/granola/runtime.js +2 -2
  157. package/src/providers/indiegogo/executors.js +1 -1
  158. package/src/providers/investoday_mcp/executors.js +2 -2
  159. package/src/providers/iyunbiao/runtime.js +2 -2
  160. package/src/providers/keepa/actions.d.ts +1 -1
  161. package/src/providers/keepa/actions.js +371 -149
  162. package/src/providers/keepa/deal-attributes.d.ts +1 -0
  163. package/src/providers/keepa/deal-attributes.js +26 -0
  164. package/src/providers/keepa/runtime.js +212 -18
  165. package/src/providers/kingdee/executors.js +1 -1
  166. package/src/providers/kingdee/runtime.js +2 -2
  167. package/src/providers/kuaidi100/runtime.js +1 -1
  168. package/src/providers/linear/executors.js +12 -9
  169. package/src/providers/linear_mcp/actions.d.ts +47 -0
  170. package/src/providers/linear_mcp/actions.js +102 -0
  171. package/src/providers/linear_mcp/endpoints.d.ts +3 -0
  172. package/src/providers/linear_mcp/endpoints.js +3 -0
  173. package/src/providers/linear_mcp/executors.d.ts +3 -0
  174. package/src/providers/linear_mcp/executors.js +9 -0
  175. package/src/providers/linear_mcp/runtime-mcp.d.ts +15 -0
  176. package/src/providers/linear_mcp/runtime-mcp.js +238 -0
  177. package/src/providers/lingxing_mcp/runtime.js +1 -1
  178. package/src/providers/mcdonalds_cn_mcp/runtime.js +1 -1
  179. package/src/providers/metabase/mcp-runtime.js +1 -1
  180. package/src/providers/moneyforward_mcp/executors.d.ts +3 -0
  181. package/src/providers/moneyforward_mcp/executors.js +11 -0
  182. package/src/providers/moneyforward_mcp/manifest.d.ts +31 -0
  183. package/src/providers/moneyforward_mcp/manifest.js +204 -0
  184. package/src/providers/moneyforward_mcp/runtime.d.ts +18 -0
  185. package/src/providers/moneyforward_mcp/runtime.js +296 -0
  186. package/src/providers/notion/executors.js +39 -3
  187. package/src/providers/notion_mcp/endpoints.d.ts +3 -0
  188. package/src/providers/notion_mcp/endpoints.js +3 -0
  189. package/src/providers/notion_mcp/executors.d.ts +3 -0
  190. package/src/providers/notion_mcp/executors.js +176 -0
  191. package/src/providers/notion_mcp/mcp-response.d.ts +86 -0
  192. package/src/providers/notion_mcp/mcp-response.js +314 -0
  193. package/src/providers/odoo/executors.d.ts +3 -0
  194. package/src/providers/odoo/executors.js +32 -0
  195. package/src/providers/odoo/runtime.d.ts +16 -0
  196. package/src/providers/odoo/runtime.js +140 -0
  197. package/src/providers/outlook/executors.js +27 -6
  198. package/src/providers/outlook/microsoft-graph.js +17 -6
  199. package/src/providers/outlook_calendar/executors.js +24 -7
  200. package/src/providers/patsnap_mcp/executors.js +2 -2
  201. package/src/providers/postiz/executors.d.ts +4 -0
  202. package/src/providers/postiz/executors.js +83 -0
  203. package/src/providers/provider-runtime.d.ts +15 -0
  204. package/src/providers/provider-runtime.js +57 -4
  205. package/src/providers/proworkflow/executors.d.ts +4 -0
  206. package/src/providers/proworkflow/executors.js +135 -0
  207. package/src/providers/registry.generated.js +12 -0
  208. package/src/providers/scrape_creators/catalog.js +1 -1
  209. package/src/providers/scrape_creators/runtime.js +1 -1
  210. package/src/providers/sellersprite_mcp/executors.js +2 -2
  211. package/src/providers/sellersprite_mcp/official-actions.js +3 -2
  212. package/src/providers/sentry/runtime.js +6 -7
  213. package/src/providers/slack/actions.js +52 -3
  214. package/src/providers/slack/runtime.js +58 -21
  215. package/src/providers/slickdeals/runtime.js +1 -1
  216. package/src/providers/sorftime_mcp/executors.js +2 -2
  217. package/src/providers/tikhub/bounded-response.d.ts +1 -1
  218. package/src/providers/tikhub/bounded-response.js +8 -34
  219. package/src/providers/tikhub/endpoint-catalog.js +1 -1
  220. package/src/providers/tikhub/runtime.js +2 -2
  221. package/src/providers/tongdaxin/executors.js +79 -15
  222. package/src/providers/uspto/executors.js +1 -1
  223. package/src/providers/waffo/executors.js +1 -1
  224. package/src/providers/waffo/runtime.js +1 -1
  225. package/src/providers/wecom_mcp/runtime.js +1 -1
  226. package/src/providers/wisburg/executors.d.ts +4 -0
  227. package/src/providers/wisburg/executors.js +13 -0
  228. package/src/providers/wisburg/runtime.d.ts +12 -0
  229. package/src/providers/wisburg/runtime.js +133 -0
  230. package/src/providers/xydc_mcp/executors.js +2 -2
  231. package/src/providers/youtube/executors.js +1 -1
  232. package/src/providers/youtube/runtime.js +1 -1
  233. package/src/providers/zerotier/executors.d.ts +9 -0
  234. package/src/providers/zerotier/executors.js +629 -0
  235. package/src/providers/zerotier/runtime.d.ts +54 -0
  236. package/src/providers/zerotier/runtime.js +207 -0
  237. package/src/server/api/openapi.js +12 -2
  238. package/src/server/api/runtime-api.d.ts +8 -1
  239. package/src/server/api/runtime-api.js +19 -1
  240. package/src/server/connect-server.js +10 -2
  241. package/src/providers/sentry/scopes.d.ts +0 -1
  242. package/src/providers/sentry/scopes.js +0 -7
  243. /package/src/providers/{cloudflare-current-user.d.ts → cloudflare_dns/runtime-user.d.ts} +0 -0
@@ -0,0 +1,24 @@
1
+ import { defineOAuthProviderExecutors, defineProviderProxy } from "../provider-runtime.js";
2
+ import { futunnActions } from "./actions.js";
3
+ import { executeFutunnAction } from "./runtime.js";
4
+ import { futunnApiBaseUrl } from "./transport.js";
5
+ const service = "futunn";
6
+ function createHandler(actionName) {
7
+ return (input, context) => executeFutunnAction({
8
+ actionName,
9
+ input,
10
+ accessToken: context.accessToken,
11
+ signal: context.signal,
12
+ }, context.fetcher);
13
+ }
14
+ const handlers = Object.fromEntries(futunnActions.map((action) => [action.name, createHandler(action.name)]));
15
+ export const executors = defineOAuthProviderExecutors(service, handlers);
16
+ export const proxy = defineProviderProxy({
17
+ service,
18
+ baseUrl: futunnApiBaseUrl,
19
+ auth: { type: "oauth_bearer" },
20
+ skipDnsValidation: true,
21
+ customizeRequest({ headers }) {
22
+ headers.set("accept", "application/json");
23
+ },
24
+ });
@@ -0,0 +1,3 @@
1
+ import type { FutunnActionInput } from "./transport.ts";
2
+ export declare function isFutunnResearchAction(name: string): boolean;
3
+ export declare function executeFutunnResearchAction(input: FutunnActionInput, fetcher: typeof fetch): Promise<unknown>;
@@ -0,0 +1,133 @@
1
+ import { optionalNumber, optionalRecord } from "../../core/cast.js";
2
+ import { ProviderRequestError, requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { futunnResearchActions } from "./actions.research.js";
4
+ import { readFutunnData, readFutunnList, requestFutunn } from "./transport.js";
5
+ const researchNames = new Set(futunnResearchActions.map((action) => action.name));
6
+ export function isFutunnResearchAction(name) {
7
+ return researchNames.has(name);
8
+ }
9
+ export async function executeFutunnResearchAction(input, fetcher) {
10
+ const v = input.input;
11
+ const request = (path, query, body, allowNoData = false) => requestFutunn(input, fetcher, path, query, body, allowNoData);
12
+ const securityPath = (suffix) => `/api/v1.0/quote/${encodeURIComponent(requiredInputString(v.symbol, "symbol"))}/${suffix}`;
13
+ switch (input.actionName) {
14
+ case "search_news":
15
+ case "search_community": {
16
+ const news = input.actionName === "search_news";
17
+ const envelope = await request(`/api/v1.0/quote/${news ? "find-news" : "find-community"}`, {
18
+ symbol: v.keyword,
19
+ size: v.size,
20
+ [news ? "news_type" : "community_type"]: v.type,
21
+ sort_type: v.sortType,
22
+ lang: v.language,
23
+ });
24
+ return { items: readFutunnList(readFutunnData(envelope), "search results") };
25
+ }
26
+ case "get_security_info": {
27
+ const data = requiredResponseRecord(readFutunnData(await request("/api/v1.0/quote/stock-basicinfo", {}, { code_list: v.symbols })), "Futunn security info");
28
+ return { securities: readFutunnList(data.basic_list, "basic_list") };
29
+ }
30
+ case "get_market_state": {
31
+ const data = requiredResponseRecord(readFutunnData(await request("/api/v1.0/quote/market-state", {}, {
32
+ code_list: v.symbols,
33
+ is_contain_ba: v.includePreAfterMarket,
34
+ is_contain_overnight: v.includeOvernight,
35
+ is_need_crypto_multi_broker: v.includeCryptoBrokers,
36
+ })), "Futunn market state");
37
+ return { states: readFutunnList(data.market_state_list, "market_state_list") };
38
+ }
39
+ case "screen_stocks": {
40
+ const envelope = await request("/api/v1.0/quote/stock-screen", {}, {
41
+ screen_queries: v.screenQueries,
42
+ retrieve_queries: v.retrieveQueries,
43
+ sort: v.sort,
44
+ sorts: v.sorts,
45
+ next_key: v.nextKey,
46
+ limit: v.limit,
47
+ watchlist_stock_ids: v.watchlistStockIds,
48
+ holding_stock_ids: v.holdingStockIds,
49
+ user_stock_list_mode: v.userStockListMode,
50
+ });
51
+ const data = requiredResponseRecord(readFutunnData(envelope), "Futunn screening data");
52
+ return {
53
+ items: readFutunnList(data.items, "screening items"),
54
+ pagination: optionalRecord(envelope.pagination) ?? null,
55
+ };
56
+ }
57
+ case "get_financial_statements": {
58
+ const envelope = await request(securityPath("financials/statements"), {
59
+ statement_type: v.statementType,
60
+ financial_type: v.financialType,
61
+ currency_code: v.currencyCode,
62
+ next_key: v.nextKey,
63
+ limit: v.limit,
64
+ }, undefined, true);
65
+ const noData = envelope.ret_code === -10;
66
+ const data = noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn financial statements");
67
+ return {
68
+ reports: data === null ? [] : readFutunnList(data.report_list, "report_list"),
69
+ pagination: optionalRecord(envelope.pagination) ?? null,
70
+ noData,
71
+ };
72
+ }
73
+ case "get_revenue_breakdown": {
74
+ const envelope = await request(securityPath("financials/revenue-breakdown"), { date: v.date, financial_type: v.financialType, currency_code: v.currencyCode }, undefined, true);
75
+ const noData = envelope.ret_code === -10;
76
+ return {
77
+ revenue: noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn revenue breakdown"),
78
+ noData,
79
+ };
80
+ }
81
+ case "get_operational_efficiency": {
82
+ const envelope = await request(securityPath("company/operational-efficiency"), {
83
+ limit: v.limit,
84
+ financial_type: v.financialType,
85
+ currency_code: v.currencyCode,
86
+ next_key: v.nextKey,
87
+ }, undefined, true);
88
+ const noData = envelope.ret_code === -10;
89
+ return {
90
+ efficiency: noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn operational efficiency"),
91
+ pagination: optionalRecord(envelope.pagination) ?? null,
92
+ noData,
93
+ };
94
+ }
95
+ case "get_valuation":
96
+ return {
97
+ valuation: requiredResponseRecord(readFutunnData(await request(securityPath("valuation/detail"), {
98
+ valuation_type: v.valuationType,
99
+ interval_type: v.intervalType,
100
+ })), "Futunn valuation"),
101
+ };
102
+ case "get_capital_flow": {
103
+ const data = requiredResponseRecord(readFutunnData(await request(securityPath("capital-flow"), { section: v.section })), "Futunn capital flow");
104
+ return {
105
+ flows: readFutunnList(data.flow_list, "flow_list"),
106
+ lastValidTime: optionalNumber(data.last_valid_time) ?? null,
107
+ };
108
+ }
109
+ case "get_capital_flow_history": {
110
+ const envelope = await request(securityPath("capital-flow/history"), {
111
+ period_type: v.periodType,
112
+ start: v.start,
113
+ end: v.end,
114
+ count: v.count,
115
+ });
116
+ const data = requiredResponseRecord(readFutunnData(envelope), "Futunn capital flow history");
117
+ return {
118
+ flows: readFutunnList(data.flow_list, "flow_list"),
119
+ pagination: optionalRecord(envelope.pagination) ?? null,
120
+ };
121
+ }
122
+ case "get_capital_distribution": {
123
+ const envelope = await request(securityPath("capital-distribution"), {}, undefined, true);
124
+ const noData = envelope.ret_code === -10;
125
+ return {
126
+ distribution: noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn capital distribution"),
127
+ noData,
128
+ };
129
+ }
130
+ default:
131
+ throw new ProviderRequestError(400, `Unknown Futunn research action: ${input.actionName}`);
132
+ }
133
+ }
@@ -0,0 +1,3 @@
1
+ import type { FutunnActionInput } from "./transport.ts";
2
+ export declare function isFutunnTradingAction(name: string): boolean;
3
+ export declare function executeFutunnTradingAction(input: FutunnActionInput, fetcher: typeof fetch): Promise<unknown>;
@@ -0,0 +1,39 @@
1
+ import { optionalBoolean, optionalString } from "../../core/cast.js";
2
+ import { ProviderRequestError, requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { futunnTradingActions } from "./actions.trading.js";
4
+ import { readFutunnData, readFutunnList, requestFutunn } from "./transport.js";
5
+ const tradingNames = new Set(futunnTradingActions.map((action) => action.name));
6
+ export function isFutunnTradingAction(name) {
7
+ return tradingNames.has(name);
8
+ }
9
+ const listEndpoints = {
10
+ list_open_orders: { path: "orders", field: "orders", history: false },
11
+ list_history_orders: { path: "orders_history", field: "orders", history: true },
12
+ list_today_deals: { path: "order_fills", field: "order_fills", history: false },
13
+ list_history_deals: { path: "fills_history", field: "order_fills", history: true },
14
+ };
15
+ export async function executeFutunnTradingAction(input, fetcher) {
16
+ const v = input.input;
17
+ const path = `/api/v1.0/accounts/${encodeURIComponent(requiredInputString(v.accountId, "accountId"))}`;
18
+ if (input.actionName === "get_order_details") {
19
+ const envelope = await requestFutunn(input, fetcher, `${path}/orders/detail`, {}, { exchange: v.exchange, order_ids: v.orderIds });
20
+ return { orders: readFutunnList(readFutunnData(envelope), "order details") };
21
+ }
22
+ const endpoint = listEndpoints[input.actionName];
23
+ if (!endpoint)
24
+ throw new ProviderRequestError(400, `Unknown Futunn trading action: ${input.actionName}`);
25
+ const envelope = await requestFutunn(input, fetcher, `${path}/${endpoint.path}`, {
26
+ trd_market: v.market,
27
+ page_flag: v.pageFlag ?? "",
28
+ page_size: v.pageSize,
29
+ code: endpoint.history ? v.code : undefined,
30
+ start: endpoint.history ? v.start : undefined,
31
+ end: endpoint.history ? v.end : undefined,
32
+ });
33
+ const data = requiredResponseRecord(readFutunnData(envelope), "Futunn account records");
34
+ return {
35
+ [endpoint.field === "orders" ? "orders" : "deals"]: readFutunnList(data[endpoint.field], endpoint.field),
36
+ pageFlag: optionalString(data.page_flag) ?? null,
37
+ completed: optionalBoolean(data.completed) ?? null,
38
+ };
39
+ }
@@ -0,0 +1,2 @@
1
+ import type { FutunnActionInput } from "./transport.ts";
2
+ export declare function executeFutunnAction(input: FutunnActionInput, fetcher: typeof fetch): Promise<unknown>;
@@ -0,0 +1,50 @@
1
+ import { optionalNumber } from "../../core/cast.js";
2
+ import { requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { executeFutunnResearchAction, isFutunnResearchAction } from "./runtime-research.js";
4
+ import { executeFutunnTradingAction, isFutunnTradingAction } from "./runtime-trading.js";
5
+ import { readFutunnData, readFutunnList, requestFutunn } from "./transport.js";
6
+ export async function executeFutunnAction(input, fetcher) {
7
+ const values = input.input;
8
+ const request = (path, query, body) => requestFutunn(input, fetcher, path, query, body).then(readFutunnData);
9
+ if (isFutunnResearchAction(input.actionName))
10
+ return executeFutunnResearchAction(input, fetcher);
11
+ if (isFutunnTradingAction(input.actionName))
12
+ return executeFutunnTradingAction(input, fetcher);
13
+ switch (input.actionName) {
14
+ case "get_market_snapshot": {
15
+ const data = requiredResponseRecord(await request("/api/v1.0/quote/snapshot", {}, { code_list: values.symbols }), "Futunn snapshot data");
16
+ return { snapshots: readFutunnList(data.snapshot_list, "snapshot_list") };
17
+ }
18
+ case "get_history_kline": {
19
+ const data = requiredResponseRecord(await request(`/api/v1.0/quote/${encodeURIComponent(requiredInputString(values.symbol, "symbol"))}/history-kline`, {
20
+ start: values.start,
21
+ end: values.end,
22
+ ktype: values.ktype,
23
+ autype: values.autype,
24
+ num: values.num,
25
+ extended_time: values.extendedTime,
26
+ }), "Futunn history data");
27
+ return {
28
+ bars: readFutunnList(data.kline_list, "kline_list"),
29
+ nextTime: optionalNumber(data.next_time) ?? null,
30
+ volumePrecision: optionalNumber(data.volume_precision) ?? null,
31
+ };
32
+ }
33
+ case "list_trading_days": {
34
+ const data = requiredResponseRecord(await request("/api/v1.0/quote/trading-days", values), "Futunn calendar data");
35
+ return { tradingDays: readFutunnList(data.trading_days, "trading_days") };
36
+ }
37
+ case "list_accounts": {
38
+ const data = requiredResponseRecord(await request("/api/v1.0/accounts/authorized_trd_accs"), "Futunn account data");
39
+ return { accounts: readFutunnList(data.accounts, "accounts") };
40
+ }
41
+ case "get_account_funds":
42
+ return {
43
+ funds: requiredResponseRecord(await request(`/api/v1.0/accounts/${encodeURIComponent(requiredInputString(values.accountId, "accountId"))}/funds`, { currency: values.currency }), "Futunn funds"),
44
+ };
45
+ case "list_positions":
46
+ return {
47
+ positions: readFutunnList(await request(`/api/v1.0/accounts/${encodeURIComponent(requiredInputString(values.accountId, "accountId"))}/positions`, { code: values.code, pl_ratio_min: values.plRatioMin, pl_ratio_max: values.plRatioMax }), "positions"),
48
+ };
49
+ }
50
+ }
@@ -0,0 +1,11 @@
1
+ export interface FutunnActionInput {
2
+ actionName: string;
3
+ input: Record<string, unknown>;
4
+ accessToken: string;
5
+ signal?: AbortSignal;
6
+ }
7
+ export declare const futunnApiBaseUrl = "https://webapi.futunn.com";
8
+ export declare function readFutunnResponse(response: Response, allowNoData?: boolean): Promise<Record<string, unknown>>;
9
+ export declare function requestFutunn(input: FutunnActionInput, fetcher: typeof fetch, path: string, query?: Record<string, unknown>, body?: unknown, allowNoData?: boolean): Promise<Record<string, unknown>>;
10
+ export declare function readFutunnList(value: unknown, label: string): unknown[];
11
+ export declare function readFutunnData(envelope: Record<string, unknown>): unknown;
@@ -0,0 +1,76 @@
1
+ import { optionalRecord, optionalString } from "../../core/cast.js";
2
+ import { ProviderRequestError, providerUserAgent, requiredResponseRecord, runProviderRequest, } from "../provider-runtime.js";
3
+ export const futunnApiBaseUrl = "https://webapi.futunn.com";
4
+ export async function readFutunnResponse(response, allowNoData = false) {
5
+ let payload;
6
+ try {
7
+ payload = JSON.parse(await response.text(), (key, value, context) => {
8
+ // Preserve the source decimal text of uint64 trading account IDs during JSON parsing.
9
+ if (key !== "account_id" || typeof value !== "number")
10
+ return value;
11
+ if (!Number.isInteger(value))
12
+ throw new Error("Invalid Futunn account ID");
13
+ if (Number.isSafeInteger(value))
14
+ return String(value);
15
+ if (!context?.source)
16
+ throw new Error("Futunn account ID source is unavailable");
17
+ return BigInt(context.source).toString();
18
+ });
19
+ }
20
+ catch {
21
+ throw new ProviderRequestError(response.ok ? 502 : response.status, "Futunn returned invalid JSON");
22
+ }
23
+ const envelope = requiredResponseRecord(payload, "Futunn response");
24
+ if (response.ok && allowNoData && envelope.ret_code === -10)
25
+ return envelope;
26
+ const error = optionalRecord(envelope.error);
27
+ if (!response.ok ||
28
+ envelope.s === "error" ||
29
+ (envelope.ret_code !== undefined && envelope.ret_code !== 0) ||
30
+ envelope.error) {
31
+ const message = optionalString(envelope.errmsg) ??
32
+ optionalString(envelope.ret_msg) ??
33
+ optionalString(envelope.error_description) ??
34
+ optionalString(error?.message) ??
35
+ optionalString(envelope.error) ??
36
+ "request failed";
37
+ const code = envelope.errcode ?? envelope.ret_code ?? error?.code;
38
+ throw new ProviderRequestError(response.ok ? 502 : response.status, `Futunn${code === undefined ? "" : ` (${String(code)})`}: ${message}`);
39
+ }
40
+ return envelope;
41
+ }
42
+ export async function requestFutunn(input, fetcher, path, query = {}, body, allowNoData = false) {
43
+ const url = new URL(path, futunnApiBaseUrl);
44
+ for (const [key, value] of Object.entries(query)) {
45
+ if (value !== undefined)
46
+ url.searchParams.set(key, String(value));
47
+ }
48
+ return runProviderRequest({ label: "Futunn", signal: input.signal }, async (signal) => {
49
+ const response = await fetcher(url, {
50
+ method: body === undefined ? "GET" : "POST",
51
+ headers: {
52
+ authorization: `Bearer ${input.accessToken}`,
53
+ accept: "application/json",
54
+ "content-type": "application/json",
55
+ "user-agent": providerUserAgent,
56
+ },
57
+ body: body === undefined ? undefined : JSON.stringify(body),
58
+ signal,
59
+ redirect: "manual",
60
+ });
61
+ const envelope = await readFutunnResponse(response, allowNoData);
62
+ if (envelope.s === "ok" || envelope.ret_code === 0 || (allowNoData && envelope.ret_code === -10))
63
+ return envelope;
64
+ throw new ProviderRequestError(502, "Futunn response is missing its success envelope");
65
+ });
66
+ }
67
+ export function readFutunnList(value, label) {
68
+ if (!Array.isArray(value))
69
+ throw new ProviderRequestError(502, `Futunn ${label} must be an array`);
70
+ return value;
71
+ }
72
+ export function readFutunnData(envelope) {
73
+ if (envelope.ret_code === -10)
74
+ return null;
75
+ return envelope.s === "ok" ? envelope.d : envelope.data;
76
+ }
@@ -202,7 +202,7 @@ function buildGildataMcpInput(serverType, apiKey, fetcher, parentSignal, request
202
202
  }
203
203
  return response;
204
204
  },
205
- redirect: "error",
205
+ redirect: "manual",
206
206
  terminateSession: true,
207
207
  signal: parentSignal,
208
208
  requestTimeoutMs,
@@ -1,7 +1,7 @@
1
1
  import { looseArray, optionalRecord, optionalString } from "../../core/cast.js";
2
2
  import { encodePathSegment } from "../../core/request.js";
3
- import { googleBearerProxyAuth, googleServiceAccountValidator, resolveGoogleAccessToken } from "../google-auth.js";
4
- import { defineProviderExecutors, defineProviderProxy, ProviderRequestError, readProviderErrorTextBody, readProviderJsonBody, requiredInputString, runProviderRequest, } from "../provider-runtime.js";
3
+ import { googleBearerProxyAuth, googleServiceAccountValidator, resolveGoogleAccessToken, } from "../googledrive/runtime-auth.js";
4
+ import { defineProviderExecutors, defineProviderProxy, ProviderRequestError, readProviderErrorTextBody, readProviderJsonBody, requiredInputString, runProviderRequest, withRetryAfterSeconds, } from "../provider-runtime.js";
5
5
  import { decodeGmailAttachment } from "./attachment-stream.js";
6
6
  import { buildRecipients, encodeMimeMessage, extractBodyContent, firstAddress, normalizeGmailMessage, normalizeMessageId, normalizeThreadId, parseAddressList, readHeader, resolveReplyHeaders, summarizeGmailMessage, } from "./message.js";
7
7
  import { gmailOAuthScopes } from "./scopes.js";
@@ -787,5 +787,5 @@ async function readGmailError(response) {
787
787
  }
788
788
  const rateLimited = response.status === 403 &&
789
789
  looseArray(error?.errors).some((entry) => gmailQuotaReasons.has(optionalString(optionalRecord(entry)?.reason) ?? ""));
790
- return new ProviderRequestError(response.status, optionalString(error?.message) ?? `gmail request failed with ${response.status}`, undefined, rateLimited ? "rate_limited" : undefined);
790
+ return new ProviderRequestError(response.status, optionalString(error?.message) ?? `gmail request failed with ${response.status}`, withRetryAfterSeconds(response), rateLimited ? "rate_limited" : undefined);
791
791
  }
@@ -20,6 +20,7 @@ export interface GmailMessageResource {
20
20
  internalDate?: string;
21
21
  labelIds?: string[];
22
22
  snippet?: string;
23
+ sizeEstimate?: number;
23
24
  raw?: string;
24
25
  payload?: GmailMessagePart;
25
26
  }
@@ -39,13 +40,7 @@ export interface GmailAttachmentSummary {
39
40
  mimeType: string;
40
41
  size: number;
41
42
  }
42
- export interface NormalizedGmailMessage {
43
- messageId: string;
44
- threadId: string;
45
- labelIds: string[];
46
- subject: string;
47
- sender: string;
48
- to: string;
43
+ export interface NormalizedGmailMessage extends GmailMessageSummary {
49
44
  preview: {
50
45
  subject: string;
51
46
  body: string;
@@ -53,7 +48,6 @@ export interface NormalizedGmailMessage {
53
48
  payload: GmailMessagePart | null;
54
49
  messageText: string;
55
50
  attachmentList: GmailAttachmentSummary[];
56
- messageTimestamp: string;
57
51
  raw?: string;
58
52
  }
59
53
  export interface GmailMessageSummary {
@@ -64,6 +58,10 @@ export interface GmailMessageSummary {
64
58
  sender: string;
65
59
  to: string;
66
60
  messageTimestamp: string;
61
+ historyId?: string;
62
+ internalDate?: string;
63
+ sizeEstimate?: number;
64
+ snippet?: string;
67
65
  }
68
66
  export interface MimeMessageInput {
69
67
  to: string[];
@@ -8,6 +8,10 @@ export function summarizeGmailMessage(resource) {
8
8
  sender: readHeader(headers, "From"),
9
9
  to: readHeader(headers, "To"),
10
10
  messageTimestamp: toMessageTimestamp(resource.internalDate, readHeader(headers, "Date")),
11
+ historyId: resource.historyId,
12
+ internalDate: resource.internalDate,
13
+ sizeEstimate: resource.sizeEstimate,
14
+ snippet: resource.snippet,
11
15
  };
12
16
  }
13
17
  export function normalizeGmailMessage(resource) {
@@ -10,4 +10,36 @@ export declare const gmailComposeScopes: string[];
10
10
  export declare const gmailSendScopes: string[];
11
11
  export declare const gmailLabelScopes: string[];
12
12
  export declare const gmailSettingsBasicScopes: string[];
13
+ /**
14
+ * The scopes a SERVICE ACCOUNT token is minted for, and the ones the proxy
15
+ * resolves with. Unchanged: a domain-wide-delegation grant lists these exact
16
+ * scopes in the Workspace admin console, and a token request naming a scope the
17
+ * admin has not authorized fails outright — so this list cannot grow without
18
+ * breaking every existing service-account connection.
19
+ */
13
20
  export declare const gmailOAuthScopes: string[];
21
+ /**
22
+ * The scopes a user OAuth authorization may request — the menu, not a minimum.
23
+ *
24
+ * `gmail.readonly` is here and not in {@link gmailOAuthScopes} because the two
25
+ * lists answer different questions. That one asks "what does a service account
26
+ * token need to cover every action"; `modify` subsumes `readonly` there, so
27
+ * adding it would be redundant at best and, through domain-wide delegation,
28
+ * breaking at worst.
29
+ *
30
+ * This one is what `filterDeclaredScopes` intersects a caller's
31
+ * `requestedScopes` against, so a scope absent here cannot be requested AT ALL.
32
+ * Leaving `readonly` out therefore forced every read-only integration to
33
+ * authorize `gmail.modify` — write, label and trash on the user's mailbox — in
34
+ * order to call actions that declare `gmailReadScopes`. That is the opposite of
35
+ * least privilege, and it is invisible: consent succeeds, so nothing reports
36
+ * that more was granted than the integration can use.
37
+ *
38
+ * Note for anyone storing a client config WITHOUT `requestedScopes`:
39
+ * `getEffectiveScopes` falls back to this whole list, so such a config now asks
40
+ * for four scopes rather than three. `readonly` is subsumed by `modify`, so no
41
+ * new capability is granted — but the consent screen gains a line, and a
42
+ * deployment that wants the narrow set should say so explicitly with
43
+ * `requestedScopes`, which is the correct posture regardless.
44
+ */
45
+ export declare const gmailAuthorizableScopes: string[];
@@ -10,4 +10,41 @@ export const gmailComposeScopes = [gmailComposeScope];
10
10
  export const gmailSendScopes = [gmailSendScope];
11
11
  export const gmailLabelScopes = [gmailLabelsScope];
12
12
  export const gmailSettingsBasicScopes = [gmailSettingsBasicScope];
13
+ /**
14
+ * The scopes a SERVICE ACCOUNT token is minted for, and the ones the proxy
15
+ * resolves with. Unchanged: a domain-wide-delegation grant lists these exact
16
+ * scopes in the Workspace admin console, and a token request naming a scope the
17
+ * admin has not authorized fails outright — so this list cannot grow without
18
+ * breaking every existing service-account connection.
19
+ */
13
20
  export const gmailOAuthScopes = [gmailModifyScope, gmailLabelsScope, gmailSettingsBasicScope];
21
+ /**
22
+ * The scopes a user OAuth authorization may request — the menu, not a minimum.
23
+ *
24
+ * `gmail.readonly` is here and not in {@link gmailOAuthScopes} because the two
25
+ * lists answer different questions. That one asks "what does a service account
26
+ * token need to cover every action"; `modify` subsumes `readonly` there, so
27
+ * adding it would be redundant at best and, through domain-wide delegation,
28
+ * breaking at worst.
29
+ *
30
+ * This one is what `filterDeclaredScopes` intersects a caller's
31
+ * `requestedScopes` against, so a scope absent here cannot be requested AT ALL.
32
+ * Leaving `readonly` out therefore forced every read-only integration to
33
+ * authorize `gmail.modify` — write, label and trash on the user's mailbox — in
34
+ * order to call actions that declare `gmailReadScopes`. That is the opposite of
35
+ * least privilege, and it is invisible: consent succeeds, so nothing reports
36
+ * that more was granted than the integration can use.
37
+ *
38
+ * Note for anyone storing a client config WITHOUT `requestedScopes`:
39
+ * `getEffectiveScopes` falls back to this whole list, so such a config now asks
40
+ * for four scopes rather than three. `readonly` is subsumed by `modify`, so no
41
+ * new capability is granted — but the consent screen gains a line, and a
42
+ * deployment that wants the narrow set should say so explicitly with
43
+ * `requestedScopes`, which is the correct posture regardless.
44
+ */
45
+ export const gmailAuthorizableScopes = [
46
+ gmailReadonlyScope,
47
+ gmailModifyScope,
48
+ gmailLabelsScope,
49
+ gmailSettingsBasicScope,
50
+ ];
@@ -1,6 +1,6 @@
1
1
  import { compactObject, objectArray, optionalBooleanOrNull, optionalIntegerOrNull, optionalObjectArray, optionalRecord as asOptionalObject, optionalScalarString, optionalString as optionalNonEmptyString, optionalStringOrNull, requiredRecord, } from "../../core/cast.js";
2
- import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator } from "../google-auth.js";
3
- import { googleJsonRequest } from "../google-runtime.js";
2
+ import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator, } from "../googledrive/runtime-auth.js";
3
+ import { googleJsonRequest } from "../googledrive/runtime-request.js";
4
4
  import { defineProviderProxy, ProviderRequestError } from "../provider-runtime.js";
5
5
  import { googleAnalyticsOAuthScopes } from "./scopes.js";
6
6
  const service = "google_analytics";
@@ -1,5 +1,10 @@
1
+ import { googleIdentityScopes } from "../googleads/scopes.js";
1
2
  export const googleAnalyticsReadonlyScope = "https://www.googleapis.com/auth/analytics.readonly";
2
3
  export const googleAnalyticsEditScope = "https://www.googleapis.com/auth/analytics.edit";
3
4
  export const googleAnalyticsReadScopes = [googleAnalyticsReadonlyScope];
4
5
  export const googleAnalyticsWriteScopes = [googleAnalyticsEditScope];
5
- export const googleAnalyticsOAuthScopes = [googleAnalyticsReadonlyScope, googleAnalyticsEditScope];
6
+ export const googleAnalyticsOAuthScopes = [
7
+ googleAnalyticsReadonlyScope,
8
+ googleAnalyticsEditScope,
9
+ ...googleIdentityScopes,
10
+ ];
@@ -1,6 +1,6 @@
1
1
  import { booleanString, compactObject, optionalBoolean, optionalInteger as asOptionalInteger, requiredRecord, } from "../../core/cast.js";
2
- import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator } from "../google-auth.js";
3
- import { googleJsonRequest, googleRequest } from "../google-runtime.js";
2
+ import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator, } from "../googledrive/runtime-auth.js";
3
+ import { googleJsonRequest, googleRequest } from "../googledrive/runtime-request.js";
4
4
  import { defineProviderProxy, ProviderRequestError } from "../provider-runtime.js";
5
5
  import { googleBigQueryOAuthScopes } from "./scopes.js";
6
6
  const bigQueryApiBaseUrl = "https://bigquery.googleapis.com/bigquery/v2";
@@ -1,3 +1,4 @@
1
+ import { googleIdentityScopes } from "../googleads/scopes.js";
1
2
  export const bigQueryScope = "https://www.googleapis.com/auth/bigquery";
2
3
  export const bigQueryReadOnlyScope = "https://www.googleapis.com/auth/bigquery.readonly";
3
4
  export const bigQueryInsertDataScope = "https://www.googleapis.com/auth/bigquery.insertdata";
@@ -14,4 +15,5 @@ export const googleBigQueryOAuthScopes = [
14
15
  bigQueryInsertDataScope,
15
16
  devStorageReadOnlyScope,
16
17
  devStorageReadWriteScope,
18
+ ...googleIdentityScopes,
17
19
  ];
@@ -1,6 +1,6 @@
1
1
  import { compactObject, optionalNumber, optionalRecord as asOptionalObject, optionalString as asOptionalString, pickOptionalInteger, pickOptionalString as pickNonEmptyString, } from "../../core/cast.js";
2
- import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator } from "../google-auth.js";
3
- import { googleJsonRequest, googleRequest } from "../google-runtime.js";
2
+ import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator, } from "../googledrive/runtime-auth.js";
3
+ import { googleJsonRequest, googleRequest } from "../googledrive/runtime-request.js";
4
4
  import { defineProviderProxy, ProviderRequestError } from "../provider-runtime.js";
5
5
  import { googleSearchConsoleOAuthScopes } from "./scopes.js";
6
6
  const service = "google_search_console";
@@ -1,3 +1,4 @@
1
+ import { googleIdentityScopes } from "../googleads/scopes.js";
1
2
  export const googleSearchConsoleReadonlyScope = "https://www.googleapis.com/auth/webmasters.readonly";
2
3
  export const googleSearchConsoleFullScope = "https://www.googleapis.com/auth/webmasters";
3
4
  export const googleSearchConsoleReadScopes = [googleSearchConsoleReadonlyScope];
@@ -5,4 +6,5 @@ export const googleSearchConsoleWriteScopes = [googleSearchConsoleFullScope];
5
6
  export const googleSearchConsoleOAuthScopes = [
6
7
  googleSearchConsoleReadonlyScope,
7
8
  googleSearchConsoleFullScope,
9
+ ...googleIdentityScopes,
8
10
  ];
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { compactObject, objectArray, optionalBoolean, optionalRecord, optionalScalarString, optionalString, } from "../../core/cast.js";
3
- import { googleJsonRequest, googleRequest } from "../google-runtime.js";
3
+ import { googleJsonRequest, googleRequest } from "../googledrive/runtime-request.js";
4
4
  import { defineProviderExecutors, defineProviderProxy, ProviderRequestError, requireOAuthCredential, requiredInputString, } from "../provider-runtime.js";
5
5
  import { googleAdsScope } from "./scopes.js";
6
6
  export const googleAdsApiBaseUrl = "https://googleads.googleapis.com/v22";
@@ -1,5 +1,3 @@
1
1
  export declare const googleAdsScope = "https://www.googleapis.com/auth/adwords";
2
- export declare const googleOpenIdScope = "openid";
3
- export declare const googleEmailScope = "email";
4
- export declare const googleProfileScope = "profile";
2
+ export declare const googleIdentityScopes: string[];
5
3
  export declare const googleAdsOAuthScopes: string[];
@@ -1,5 +1,3 @@
1
1
  export const googleAdsScope = "https://www.googleapis.com/auth/adwords";
2
- export const googleOpenIdScope = "openid";
3
- export const googleEmailScope = "email";
4
- export const googleProfileScope = "profile";
5
- export const googleAdsOAuthScopes = [googleAdsScope, googleOpenIdScope, googleEmailScope, googleProfileScope];
2
+ export const googleIdentityScopes = ["openid", "email", "profile"];
3
+ export const googleAdsOAuthScopes = [googleAdsScope, ...googleIdentityScopes];
@@ -1,5 +1,5 @@
1
1
  import { compactObject, optionalString, pickOptionalBoolean, pickOptionalInteger, pickOptionalString, requiredRecord, } from "../../core/cast.js";
2
- import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator } from "../google-auth.js";
2
+ import { defineGoogleProviderExecutors, googleBearerProxyAuth, googleServiceAccountValidator, } from "../googledrive/runtime-auth.js";
3
3
  import { combineProviderActionHandlers, defineProviderProxy, ProviderRequestError } from "../provider-runtime.js";
4
4
  import { googlecalendarEventActionHandlers } from "./runtime-events.js";
5
5
  import { googlecalendarApiBaseUrl, googlecalendarJsonRequest, googlecalendarRequest, resolveCalendarId, resolveRuleId, resolveSettingId, } from "./runtime-shared.js";
@@ -1,5 +1,5 @@
1
1
  import { optionalRecord, optionalString as asOptionalString, pickOptionalString } from "../../core/cast.js";
2
- import { providerUserAgent, ProviderRequestError } from "../provider-runtime.js";
2
+ import { providerUserAgent, ProviderRequestError, withRetryAfterSeconds } from "../provider-runtime.js";
3
3
  export const googlecalendarApiBaseUrl = "https://www.googleapis.com/calendar/v3";
4
4
  const service = "googlecalendar";
5
5
  const googleDefaultRequestTimeoutMs = 30_000;
@@ -142,7 +142,7 @@ async function assertGoogleResponse(response) {
142
142
  return;
143
143
  }
144
144
  const { message, details } = await extractGoogleError(response);
145
- throw new ProviderRequestError(response.status, message, details);
145
+ throw new ProviderRequestError(response.status, message, withRetryAfterSeconds(response, details));
146
146
  }
147
147
  async function extractGoogleError(response) {
148
148
  const rawText = await response.text().catch(() => "");