runline 0.33.0 → 0.35.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 (531) hide show
  1. package/dist/auth/oauth2.d.ts +7 -1
  2. package/dist/auth/oauth2.js +10 -0
  3. package/dist/auth/token.d.ts +1 -0
  4. package/dist/auth/token.js +19 -1
  5. package/dist/auth/types.d.ts +22 -1
  6. package/dist/core/engine.d.ts +7 -0
  7. package/dist/core/engine.js +21 -8
  8. package/dist/credentials/policy.d.ts +53 -1
  9. package/dist/credentials/policy.js +146 -6
  10. package/dist/credentials/registry.d.ts +9 -0
  11. package/dist/credentials/registry.js +184 -22
  12. package/dist/credentials/transport.d.ts +48 -2
  13. package/dist/credentials/transport.js +248 -70
  14. package/dist/credentials/types.d.ts +177 -10
  15. package/dist/index.d.ts +6 -5
  16. package/dist/index.js +3 -2
  17. package/dist/plugin/api.d.ts +7 -0
  18. package/dist/plugin/api.js +7 -0
  19. package/dist/plugin/schema.d.ts +16 -4
  20. package/dist/plugin/schema.js +28 -5
  21. package/dist/plugin/types.d.ts +20 -0
  22. package/dist/plugins/_shared/base64.js +30 -0
  23. package/dist/plugins/_shared/credentialAdapter.js +99 -15
  24. package/dist/plugins/_shared/credentials.js +416 -0
  25. package/dist/plugins/_shared/googleAuth.js +69 -39
  26. package/dist/plugins/_shared/googleCredentials.js +68 -14
  27. package/dist/plugins/_shared/localFile.js +40 -0
  28. package/dist/plugins/_shared/mediaFile.js +12 -12
  29. package/dist/plugins/_shared/microsoftAuth.js +31 -47
  30. package/dist/plugins/_shared/microsoftCredentials.js +42 -15
  31. package/dist/plugins/_shared/provider.js +2 -14
  32. package/dist/plugins/_shared/shiftCloud.js +16 -56
  33. package/dist/plugins/_shared/shiftCredentials.js +83 -0
  34. package/dist/plugins/_shared/shiftUpload.js +14 -10
  35. package/dist/plugins/actionNetwork/src/credentials.js +14 -0
  36. package/dist/plugins/actionNetwork/src/index.js +39 -50
  37. package/dist/plugins/activeCampaign/src/credentials.js +22 -0
  38. package/dist/plugins/activeCampaign/src/index.js +61 -132
  39. package/dist/plugins/adalo/src/credentials.js +16 -0
  40. package/dist/plugins/adalo/src/index.js +19 -43
  41. package/dist/plugins/affinity/src/credentials.js +19 -0
  42. package/dist/plugins/affinity/src/index.js +29 -54
  43. package/dist/plugins/agentMail/src/credentials.js +35 -0
  44. package/dist/plugins/agentMail/src/drafts.js +137 -0
  45. package/dist/plugins/agentMail/src/inboxes.js +95 -0
  46. package/dist/plugins/agentMail/src/index.js +35 -0
  47. package/dist/plugins/agentMail/src/messages.js +154 -0
  48. package/dist/plugins/agentMail/src/schemas.js +156 -0
  49. package/dist/plugins/agentMail/src/shared.js +203 -0
  50. package/dist/plugins/agentMail/src/threads.js +75 -0
  51. package/dist/plugins/agileCrm/src/credentials.js +16 -0
  52. package/dist/plugins/agileCrm/src/index.js +46 -112
  53. package/dist/plugins/airtable/src/credentials.js +19 -0
  54. package/dist/plugins/airtable/src/index.js +37 -50
  55. package/dist/plugins/airtop/src/credentials.js +20 -0
  56. package/dist/plugins/airtop/src/index.js +51 -75
  57. package/dist/plugins/apiTemplateIo/src/credentials.js +19 -0
  58. package/dist/plugins/apiTemplateIo/src/index.js +14 -31
  59. package/dist/plugins/asana/src/credentials.js +19 -0
  60. package/dist/plugins/asana/src/index.js +51 -72
  61. package/dist/plugins/autopilot/src/credentials.js +19 -0
  62. package/dist/plugins/autopilot/src/index.js +38 -45
  63. package/dist/plugins/bambooHr/src/credentials.js +16 -0
  64. package/dist/plugins/bambooHr/src/index.js +41 -67
  65. package/dist/plugins/bannerbear/src/credentials.js +19 -0
  66. package/dist/plugins/bannerbear/src/index.js +15 -27
  67. package/dist/plugins/baserow/src/credentials.js +17 -0
  68. package/dist/plugins/baserow/src/index.js +23 -49
  69. package/dist/plugins/beeminder/src/credentials.js +19 -0
  70. package/dist/plugins/beeminder/src/index.js +32 -54
  71. package/dist/plugins/bitly/src/credentials.js +19 -0
  72. package/dist/plugins/bitly/src/index.js +12 -26
  73. package/dist/plugins/bitwarden/src/credentials.js +62 -0
  74. package/dist/plugins/bitwarden/src/index.js +34 -80
  75. package/dist/plugins/box/src/credentials.js +19 -0
  76. package/dist/plugins/box/src/index.js +24 -49
  77. package/dist/plugins/brandfetch/src/credentials.js +13 -0
  78. package/dist/plugins/brandfetch/src/index.js +12 -17
  79. package/dist/plugins/brevo/src/credentials.js +19 -0
  80. package/dist/plugins/brevo/src/index.js +30 -51
  81. package/dist/plugins/bubble/src/credentials.js +28 -0
  82. package/dist/plugins/bubble/src/index.js +29 -65
  83. package/dist/plugins/chargebee/src/credentials.js +16 -0
  84. package/dist/plugins/chargebee/src/index.js +15 -45
  85. package/dist/plugins/circleci/src/credentials.js +19 -0
  86. package/dist/plugins/circleci/src/index.js +19 -39
  87. package/dist/plugins/ciscoWebex/src/credentials.js +19 -0
  88. package/dist/plugins/ciscoWebex/src/index.js +43 -61
  89. package/dist/plugins/clearbit/src/credentials.js +22 -0
  90. package/dist/plugins/clearbit/src/index.js +11 -21
  91. package/dist/plugins/clickup/src/credentials.js +19 -0
  92. package/dist/plugins/clickup/src/index.js +85 -117
  93. package/dist/plugins/clockify/src/credentials.js +19 -0
  94. package/dist/plugins/clockify/src/index.js +46 -61
  95. package/dist/plugins/cloudflare/src/credentials.js +19 -0
  96. package/dist/plugins/cloudflare/src/index.js +19 -34
  97. package/dist/plugins/cockpit/src/credentials.js +17 -0
  98. package/dist/plugins/cockpit/src/index.js +18 -31
  99. package/dist/plugins/coda/src/credentials.js +19 -0
  100. package/dist/plugins/coda/src/index.js +33 -50
  101. package/dist/plugins/coingecko/src/credentials.js +20 -0
  102. package/dist/plugins/coingecko/src/index.js +24 -34
  103. package/dist/plugins/contentful/src/credentials.js +26 -0
  104. package/dist/plugins/contentful/src/index.js +19 -40
  105. package/dist/plugins/convertkit/src/credentials.js +26 -0
  106. package/dist/plugins/convertkit/src/index.js +27 -45
  107. package/dist/plugins/copper/src/credentials.js +17 -0
  108. package/dist/plugins/copper/src/index.js +25 -47
  109. package/dist/plugins/cortex/src/credentials.js +28 -0
  110. package/dist/plugins/cortex/src/index.js +26 -49
  111. package/dist/plugins/currents/src/credentials.js +19 -0
  112. package/dist/plugins/currents/src/index.js +46 -59
  113. package/dist/plugins/customerIo/src/credentials.js +52 -0
  114. package/dist/plugins/customerIo/src/index.js +30 -58
  115. package/dist/plugins/databricks/src/credentials.js +13 -0
  116. package/dist/plugins/databricks/src/index.js +51 -103
  117. package/dist/plugins/deepl/src/credentials.js +19 -0
  118. package/dist/plugins/deepl/src/index.js +13 -39
  119. package/dist/plugins/demio/src/credentials.js +26 -0
  120. package/dist/plugins/demio/src/index.js +17 -41
  121. package/dist/plugins/dhl/src/credentials.js +13 -0
  122. package/dist/plugins/dhl/src/index.js +8 -19
  123. package/dist/plugins/discord/src/credentials.js +19 -0
  124. package/dist/plugins/discord/src/index.js +30 -58
  125. package/dist/plugins/discourse/src/credentials.js +18 -0
  126. package/dist/plugins/discourse/src/index.js +36 -53
  127. package/dist/plugins/disqus/src/credentials.js +13 -0
  128. package/dist/plugins/disqus/src/index.js +14 -32
  129. package/dist/plugins/drift/src/credentials.js +13 -0
  130. package/dist/plugins/drift/src/index.js +16 -26
  131. package/dist/plugins/dropbox/src/credentials.js +13 -0
  132. package/dist/plugins/dropbox/src/index.js +23 -30
  133. package/dist/plugins/dropcontact/src/credentials.js +13 -0
  134. package/dist/plugins/dropcontact/src/index.js +13 -18
  135. package/dist/plugins/egoi/src/credentials.js +19 -0
  136. package/dist/plugins/egoi/src/index.js +23 -38
  137. package/dist/plugins/elasticsearch/src/credentials.js +18 -0
  138. package/dist/plugins/elasticsearch/src/index.js +27 -48
  139. package/dist/plugins/elevenlabs/src/credentials.js +30 -0
  140. package/dist/plugins/elevenlabs/src/index.js +4 -1
  141. package/dist/plugins/elevenlabs/src/schemas.js +2 -1
  142. package/dist/plugins/elevenlabs/src/shared.js +87 -62
  143. package/dist/plugins/elevenlabs/src/workflows.js +2 -2
  144. package/dist/plugins/emelia/src/credentials.js +14 -0
  145. package/dist/plugins/emelia/src/index.js +19 -23
  146. package/dist/plugins/erpnext/src/credentials.js +27 -0
  147. package/dist/plugins/erpnext/src/index.js +21 -42
  148. package/dist/plugins/facebookGraph/src/credentials.js +20 -0
  149. package/dist/plugins/facebookGraph/src/index.js +39 -37
  150. package/dist/plugins/fal/src/credentials.js +14 -0
  151. package/dist/plugins/fal/src/index.js +5 -3
  152. package/dist/plugins/fal/src/shared.js +58 -63
  153. package/dist/plugins/freshdesk/src/credentials.js +20 -0
  154. package/dist/plugins/freshdesk/src/index.js +25 -46
  155. package/dist/plugins/freshservice/src/credentials.js +16 -0
  156. package/dist/plugins/freshservice/src/index.js +37 -58
  157. package/dist/plugins/freshworksCrm/src/credentials.js +16 -0
  158. package/dist/plugins/freshworksCrm/src/index.js +20 -39
  159. package/dist/plugins/getresponse/src/credentials.js +22 -0
  160. package/dist/plugins/getresponse/src/index.js +20 -32
  161. package/dist/plugins/gett/src/credentials.js +64 -0
  162. package/dist/plugins/gett/src/index.js +11 -6
  163. package/dist/plugins/gett/src/login.js +24 -0
  164. package/dist/plugins/gett/src/session.js +15 -38
  165. package/dist/plugins/gett/src/shared.js +41 -84
  166. package/dist/plugins/ghost/src/credentials.js +36 -0
  167. package/dist/plugins/ghost/src/index.js +18 -59
  168. package/dist/plugins/github/src/credentials.js +18 -0
  169. package/dist/plugins/github/src/index.js +55 -78
  170. package/dist/plugins/gitlab/src/credentials.js +24 -0
  171. package/dist/plugins/gitlab/src/index.js +29 -48
  172. package/dist/plugins/gmail/src/index.js +47 -108
  173. package/dist/plugins/gong/src/credentials.js +16 -0
  174. package/dist/plugins/gong/src/index.js +16 -32
  175. package/dist/plugins/googleAppsScript/src/index.js +109 -42
  176. package/dist/plugins/googleCalendar/src/index.js +20 -51
  177. package/dist/plugins/googleContacts/src/index.js +13 -40
  178. package/dist/plugins/googleDocs/src/index.js +3 -32
  179. package/dist/plugins/googleDocs/src/shared.js +2 -1
  180. package/dist/plugins/googleDrive/src/index.js +68 -97
  181. package/dist/plugins/googleImage/src/credentials.js +14 -0
  182. package/dist/plugins/googleImage/src/index.js +15 -26
  183. package/dist/plugins/googleSheets/src/index.js +27 -60
  184. package/dist/plugins/googleSlides/src/index.js +7 -35
  185. package/dist/plugins/googleTasks/src/index.js +14 -42
  186. package/dist/plugins/gotify/src/credentials.js +32 -0
  187. package/dist/plugins/gotify/src/index.js +14 -36
  188. package/dist/plugins/gotowebinar/src/credentials.js +13 -0
  189. package/dist/plugins/gotowebinar/src/index.js +52 -69
  190. package/dist/plugins/grafana/src/credentials.js +16 -0
  191. package/dist/plugins/grafana/src/index.js +34 -53
  192. package/dist/plugins/graphql/src/credentials.js +42 -0
  193. package/dist/plugins/graphql/src/index.js +21 -46
  194. package/dist/plugins/grist/src/credentials.js +30 -0
  195. package/dist/plugins/grist/src/index.js +14 -43
  196. package/dist/plugins/halopsa/src/credentials.js +56 -0
  197. package/dist/plugins/halopsa/src/index.js +20 -47
  198. package/dist/plugins/harvest/src/credentials.js +20 -0
  199. package/dist/plugins/harvest/src/index.js +24 -43
  200. package/dist/plugins/helpscout/src/credentials.js +13 -0
  201. package/dist/plugins/helpscout/src/index.js +26 -38
  202. package/dist/plugins/highlevel/src/credentials.js +19 -0
  203. package/dist/plugins/highlevel/src/index.js +42 -65
  204. package/dist/plugins/homeAssistant/src/credentials.js +27 -0
  205. package/dist/plugins/homeAssistant/src/index.js +34 -52
  206. package/dist/plugins/hubspot/src/credentials.js +16 -0
  207. package/dist/plugins/hubspot/src/index.js +29 -41
  208. package/dist/plugins/humanticAi/src/credentials.js +13 -0
  209. package/dist/plugins/humanticAi/src/index.js +15 -22
  210. package/dist/plugins/hunter/src/credentials.js +13 -0
  211. package/dist/plugins/hunter/src/index.js +18 -17
  212. package/dist/plugins/intercom/src/credentials.js +19 -0
  213. package/dist/plugins/intercom/src/index.js +25 -38
  214. package/dist/plugins/iterable/src/credentials.js +17 -0
  215. package/dist/plugins/iterable/src/index.js +26 -40
  216. package/dist/plugins/jenkins/src/credentials.js +16 -0
  217. package/dist/plugins/jenkins/src/index.js +22 -36
  218. package/dist/plugins/jira/src/credentials.js +16 -0
  219. package/dist/plugins/jira/src/index.js +35 -61
  220. package/dist/plugins/keap/src/credentials.js +19 -0
  221. package/dist/plugins/keap/src/index.js +43 -71
  222. package/dist/plugins/kobotoolbox/src/credentials.js +13 -0
  223. package/dist/plugins/kobotoolbox/src/index.js +46 -84
  224. package/dist/plugins/lemlist/src/credentials.js +19 -0
  225. package/dist/plugins/lemlist/src/index.js +35 -47
  226. package/dist/plugins/linear/src/attachments.js +7 -7
  227. package/dist/plugins/linear/src/comments.js +7 -7
  228. package/dist/plugins/linear/src/credentials.js +17 -0
  229. package/dist/plugins/linear/src/cycles.js +5 -5
  230. package/dist/plugins/linear/src/index.js +2 -0
  231. package/dist/plugins/linear/src/initiatives.js +6 -6
  232. package/dist/plugins/linear/src/issues.js +14 -14
  233. package/dist/plugins/linear/src/labels.js +6 -6
  234. package/dist/plugins/linear/src/organization.js +2 -2
  235. package/dist/plugins/linear/src/projects.js +12 -12
  236. package/dist/plugins/linear/src/shared.js +34 -32
  237. package/dist/plugins/linear/src/states.js +3 -3
  238. package/dist/plugins/linear/src/teams.js +4 -4
  239. package/dist/plugins/linear/src/users.js +3 -3
  240. package/dist/plugins/linear/src/views.js +5 -5
  241. package/dist/plugins/linear/src/webhooks.js +5 -5
  242. package/dist/plugins/lingvanex/src/credentials.js +13 -0
  243. package/dist/plugins/lingvanex/src/index.js +7 -9
  244. package/dist/plugins/linkedin/src/credentials.js +17 -0
  245. package/dist/plugins/linkedin/src/index.js +13 -17
  246. package/dist/plugins/lonescale/src/credentials.js +13 -0
  247. package/dist/plugins/lonescale/src/index.js +16 -26
  248. package/dist/plugins/magento/src/credentials.js +16 -0
  249. package/dist/plugins/magento/src/index.js +67 -84
  250. package/dist/plugins/mailcheck/src/credentials.js +17 -0
  251. package/dist/plugins/mailcheck/src/index.js +7 -9
  252. package/dist/plugins/mailchimp/src/credentials.js +32 -0
  253. package/dist/plugins/mailchimp/src/index.js +36 -44
  254. package/dist/plugins/mailerlite/src/credentials.js +13 -0
  255. package/dist/plugins/mailerlite/src/index.js +19 -32
  256. package/dist/plugins/mailgun/src/credentials.js +21 -0
  257. package/dist/plugins/mailgun/src/index.js +15 -21
  258. package/dist/plugins/mailjet/src/credentials.js +38 -0
  259. package/dist/plugins/mailjet/src/index.js +60 -115
  260. package/dist/plugins/mandrill/src/credentials.js +17 -0
  261. package/dist/plugins/mandrill/src/index.js +11 -12
  262. package/dist/plugins/marketstack/src/credentials.js +16 -0
  263. package/dist/plugins/marketstack/src/index.js +18 -28
  264. package/dist/plugins/matrix/src/credentials.js +19 -0
  265. package/dist/plugins/matrix/src/index.js +23 -52
  266. package/dist/plugins/mattermost/src/credentials.js +19 -0
  267. package/dist/plugins/mattermost/src/index.js +41 -73
  268. package/dist/plugins/mautic/src/credentials.js +16 -0
  269. package/dist/plugins/mautic/src/index.js +46 -62
  270. package/dist/plugins/medium/src/credentials.js +20 -0
  271. package/dist/plugins/medium/src/index.js +18 -23
  272. package/dist/plugins/messagebird/src/credentials.js +22 -0
  273. package/dist/plugins/messagebird/src/index.js +13 -18
  274. package/dist/plugins/metabase/src/credentials.js +19 -0
  275. package/dist/plugins/metabase/src/index.js +24 -40
  276. package/dist/plugins/microsoftCalendar/src/index.js +49 -18
  277. package/dist/plugins/microsoftFiles/src/index.js +95 -31
  278. package/dist/plugins/microsoftMail/src/index.js +63 -21
  279. package/dist/plugins/misp/src/credentials.js +16 -0
  280. package/dist/plugins/misp/src/index.js +60 -71
  281. package/dist/plugins/mocean/src/credentials.js +17 -0
  282. package/dist/plugins/mocean/src/index.js +11 -23
  283. package/dist/plugins/monday/src/credentials.js +14 -0
  284. package/dist/plugins/monday/src/index.js +31 -44
  285. package/dist/plugins/monicaCrm/src/credentials.js +19 -0
  286. package/dist/plugins/monicaCrm/src/index.js +25 -42
  287. package/dist/plugins/msg91/src/credentials.js +10 -0
  288. package/dist/plugins/msg91/src/index.js +15 -11
  289. package/dist/plugins/nasa/src/credentials.js +22 -0
  290. package/dist/plugins/nasa/src/index.js +24 -28
  291. package/dist/plugins/netlify/src/credentials.js +19 -0
  292. package/dist/plugins/netlify/src/index.js +27 -51
  293. package/dist/plugins/netscalerAdc/src/credentials.js +18 -0
  294. package/dist/plugins/netscalerAdc/src/index.js +16 -31
  295. package/dist/plugins/nextcloud/src/credentials.js +27 -0
  296. package/dist/plugins/nextcloud/src/index.js +55 -109
  297. package/dist/plugins/nocodb/src/credentials.js +16 -0
  298. package/dist/plugins/nocodb/src/index.js +19 -37
  299. package/dist/plugins/notion/src/credentials.js +21 -0
  300. package/dist/plugins/notion/src/index.js +25 -38
  301. package/dist/plugins/npm/src/credentials.js +19 -0
  302. package/dist/plugins/npm/src/index.js +22 -32
  303. package/dist/plugins/odoo/src/credentials.js +21 -0
  304. package/dist/plugins/odoo/src/index.js +53 -69
  305. package/dist/plugins/okta/src/credentials.js +23 -0
  306. package/dist/plugins/okta/src/index.js +30 -35
  307. package/dist/plugins/oneSimpleApi/src/credentials.js +16 -0
  308. package/dist/plugins/oneSimpleApi/src/index.js +19 -24
  309. package/dist/plugins/onfleet/src/credentials.js +23 -0
  310. package/dist/plugins/onfleet/src/index.js +42 -53
  311. package/dist/plugins/openai/src/credentials.js +13 -0
  312. package/dist/plugins/openai/src/index.js +16 -24
  313. package/dist/plugins/openweathermap/src/credentials.js +16 -0
  314. package/dist/plugins/openweathermap/src/index.js +22 -22
  315. package/dist/plugins/oura/src/credentials.js +19 -0
  316. package/dist/plugins/oura/src/index.js +13 -18
  317. package/dist/plugins/paddle/src/credentials.js +27 -0
  318. package/dist/plugins/paddle/src/index.js +20 -36
  319. package/dist/plugins/pagerduty/src/credentials.js +24 -0
  320. package/dist/plugins/pagerduty/src/index.js +30 -39
  321. package/dist/plugins/parallel/src/credentials.js +18 -0
  322. package/dist/plugins/parallel/src/index.js +16 -22
  323. package/dist/plugins/paypal/src/credentials.js +44 -0
  324. package/dist/plugins/paypal/src/index.js +14 -40
  325. package/dist/plugins/peekalink/src/credentials.js +16 -0
  326. package/dist/plugins/peekalink/src/index.js +10 -11
  327. package/dist/plugins/phantombuster/src/credentials.js +19 -0
  328. package/dist/plugins/phantombuster/src/index.js +19 -32
  329. package/dist/plugins/philipsHue/src/credentials.js +17 -0
  330. package/dist/plugins/philipsHue/src/index.js +15 -27
  331. package/dist/plugins/pipedrive/src/credentials.js +26 -0
  332. package/dist/plugins/pipedrive/src/index.js +43 -73
  333. package/dist/plugins/plaud/src/index.js +2 -1
  334. package/dist/plugins/plaud/src/shared.js +23 -19
  335. package/dist/plugins/plivo/src/credentials.js +20 -0
  336. package/dist/plugins/plivo/src/index.js +13 -19
  337. package/dist/plugins/posthog/src/credentials.js +18 -0
  338. package/dist/plugins/posthog/src/index.js +14 -20
  339. package/dist/plugins/profitwell/src/credentials.js +22 -0
  340. package/dist/plugins/profitwell/src/index.js +10 -17
  341. package/dist/plugins/pushbullet/src/credentials.js +19 -0
  342. package/dist/plugins/pushbullet/src/index.js +19 -27
  343. package/dist/plugins/pushcut/src/credentials.js +19 -0
  344. package/dist/plugins/pushcut/src/index.js +7 -8
  345. package/dist/plugins/pushover/src/credentials.js +14 -0
  346. package/dist/plugins/pushover/src/index.js +7 -12
  347. package/dist/plugins/quickbase/src/credentials.js +15 -0
  348. package/dist/plugins/quickbase/src/index.js +24 -34
  349. package/dist/plugins/quickbooks/src/credentials.js +22 -0
  350. package/dist/plugins/quickbooks/src/index.js +17 -46
  351. package/dist/plugins/raindrop/src/credentials.js +19 -0
  352. package/dist/plugins/raindrop/src/index.js +30 -32
  353. package/dist/plugins/recraft/src/credentials.js +13 -0
  354. package/dist/plugins/recraft/src/index.js +39 -28
  355. package/dist/plugins/reddit/src/credentials.js +26 -0
  356. package/dist/plugins/reddit/src/index.js +30 -34
  357. package/dist/plugins/replicate/src/credentials.js +23 -0
  358. package/dist/plugins/replicate/src/index.js +18 -28
  359. package/dist/plugins/rocketchat/src/credentials.js +17 -0
  360. package/dist/plugins/rocketchat/src/index.js +8 -19
  361. package/dist/plugins/rundeck/src/credentials.js +16 -0
  362. package/dist/plugins/rundeck/src/index.js +12 -28
  363. package/dist/plugins/salesforce/src/credentials.js +73 -0
  364. package/dist/plugins/salesforce/src/index.js +6 -0
  365. package/dist/plugins/salesforce/src/metadata.js +3 -16
  366. package/dist/plugins/salesforce/src/shared.js +25 -100
  367. package/dist/plugins/salesforce/src/sobjects.js +10 -9
  368. package/dist/plugins/salesmate/src/credentials.js +17 -0
  369. package/dist/plugins/salesmate/src/index.js +20 -37
  370. package/dist/plugins/securityScorecard/src/credentials.js +22 -0
  371. package/dist/plugins/securityScorecard/src/index.js +24 -37
  372. package/dist/plugins/segment/src/credentials.js +16 -0
  373. package/dist/plugins/segment/src/index.js +12 -16
  374. package/dist/plugins/sendgrid/src/credentials.js +13 -0
  375. package/dist/plugins/sendgrid/src/index.js +31 -35
  376. package/dist/plugins/sendy/src/credentials.js +18 -0
  377. package/dist/plugins/sendy/src/index.js +18 -24
  378. package/dist/plugins/sentry/src/credentials.js +16 -0
  379. package/dist/plugins/sentry/src/index.js +30 -98
  380. package/dist/plugins/servicenow/src/credentials.js +13 -0
  381. package/dist/plugins/servicenow/src/index.js +22 -41
  382. package/dist/plugins/shiftAtlas/src/graph.js +2 -2
  383. package/dist/plugins/shiftAtlas/src/index.js +2 -0
  384. package/dist/plugins/shiftAtlas/src/shared.js +3 -1
  385. package/dist/plugins/shiftBwm/src/index.js +4 -2
  386. package/dist/plugins/shiftBwm/src/shared.js +41 -16
  387. package/dist/plugins/shiftCrm/src/access.js +2 -2
  388. package/dist/plugins/shiftCrm/src/accounts.js +3 -3
  389. package/dist/plugins/shiftCrm/src/activities.js +3 -3
  390. package/dist/plugins/shiftCrm/src/credentials.js +6 -0
  391. package/dist/plugins/shiftCrm/src/index.js +2 -0
  392. package/dist/plugins/shiftCrm/src/opportunities.js +3 -3
  393. package/dist/plugins/shiftCrm/src/people.js +3 -3
  394. package/dist/plugins/shiftCrm/src/records.js +2 -2
  395. package/dist/plugins/shiftCrm/src/shared.js +2 -1
  396. package/dist/plugins/shiftCrm/src/tasks.js +3 -3
  397. package/dist/plugins/shiftObjects/src/credentials.js +2 -0
  398. package/dist/plugins/shiftObjects/src/index.js +2 -0
  399. package/dist/plugins/shiftObjects/src/objects.js +4 -3
  400. package/dist/plugins/shiftOcr/src/credentials.js +8 -0
  401. package/dist/plugins/shiftOcr/src/index.js +14 -8
  402. package/dist/plugins/shiftPages/src/index.js +2 -0
  403. package/dist/plugins/shiftPages/src/pages.js +5 -3
  404. package/dist/plugins/shiftPages/src/shared.js +3 -1
  405. package/dist/plugins/shiftTranscription/src/index.js +2 -0
  406. package/dist/plugins/shiftTranscription/src/shared.js +11 -1
  407. package/dist/plugins/shiftTranscription/src/transcription.js +5 -5
  408. package/dist/plugins/shiftWork/src/index.js +2 -0
  409. package/dist/plugins/shiftWork/src/issue-views.js +5 -5
  410. package/dist/plugins/shiftWork/src/issues.js +11 -7
  411. package/dist/plugins/shiftWork/src/projects.js +3 -3
  412. package/dist/plugins/shiftWork/src/shared.js +3 -1
  413. package/dist/plugins/shopify/src/credentials.js +16 -0
  414. package/dist/plugins/shopify/src/index.js +32 -59
  415. package/dist/plugins/signl4/src/credentials.js +17 -0
  416. package/dist/plugins/signl4/src/index.js +28 -29
  417. package/dist/plugins/slack/src/credentials.js +19 -0
  418. package/dist/plugins/slack/src/index.js +51 -60
  419. package/dist/plugins/sms77/src/credentials.js +17 -0
  420. package/dist/plugins/sms77/src/index.js +11 -16
  421. package/dist/plugins/splunk/src/credentials.js +19 -0
  422. package/dist/plugins/splunk/src/index.js +32 -74
  423. package/dist/plugins/spotify/src/credentials.js +19 -0
  424. package/dist/plugins/spotify/src/index.js +40 -55
  425. package/dist/plugins/stackby/src/credentials.js +13 -0
  426. package/dist/plugins/stackby/src/index.js +14 -23
  427. package/dist/plugins/steel/src/auth.js +27 -0
  428. package/dist/plugins/steel/src/browser.js +4 -3
  429. package/dist/plugins/steel/src/captchas.js +4 -3
  430. package/dist/plugins/steel/src/extensions.js +3 -2
  431. package/dist/plugins/steel/src/files.js +9 -10
  432. package/dist/plugins/steel/src/index.js +2 -0
  433. package/dist/plugins/steel/src/page/tools.js +3 -3
  434. package/dist/plugins/steel/src/profiles.js +4 -3
  435. package/dist/plugins/steel/src/sessions.js +13 -13
  436. package/dist/plugins/steel/src/shared.js +21 -51
  437. package/dist/plugins/storyblok/src/credentials.js +37 -0
  438. package/dist/plugins/storyblok/src/index.js +22 -66
  439. package/dist/plugins/strapi/src/credentials.js +71 -0
  440. package/dist/plugins/strapi/src/index.js +36 -70
  441. package/dist/plugins/strava/src/credentials.js +19 -0
  442. package/dist/plugins/strava/src/index.js +16 -33
  443. package/dist/plugins/stripe/src/credentials.js +19 -0
  444. package/dist/plugins/stripe/src/index.js +44 -58
  445. package/dist/plugins/supabase/src/credentials.js +30 -0
  446. package/dist/plugins/supabase/src/index.js +18 -40
  447. package/dist/plugins/syncromsp/src/credentials.js +16 -0
  448. package/dist/plugins/syncromsp/src/index.js +37 -70
  449. package/dist/plugins/tapfiliate/src/credentials.js +13 -0
  450. package/dist/plugins/tapfiliate/src/index.js +21 -31
  451. package/dist/plugins/telegram/src/credentials.js +20 -0
  452. package/dist/plugins/telegram/src/index.js +31 -39
  453. package/dist/plugins/thehive/src/credentials.js +14 -0
  454. package/dist/plugins/thehive/src/index.js +33 -50
  455. package/dist/plugins/thehiveProject/src/credentials.js +16 -0
  456. package/dist/plugins/thehiveProject/src/index.js +53 -122
  457. package/dist/plugins/todoist/src/credentials.js +26 -0
  458. package/dist/plugins/todoist/src/index.js +49 -79
  459. package/dist/plugins/together/src/credentials.js +16 -0
  460. package/dist/plugins/together/src/index.js +31 -33
  461. package/dist/plugins/travisci/src/credentials.js +24 -0
  462. package/dist/plugins/travisci/src/index.js +16 -30
  463. package/dist/plugins/trello/src/credentials.js +29 -0
  464. package/dist/plugins/trello/src/index.js +49 -64
  465. package/dist/plugins/twake/src/credentials.js +16 -0
  466. package/dist/plugins/twake/src/index.js +8 -10
  467. package/dist/plugins/twilio/src/credentials.js +23 -0
  468. package/dist/plugins/twilio/src/index.js +12 -26
  469. package/dist/plugins/twist/src/credentials.js +13 -0
  470. package/dist/plugins/twist/src/index.js +32 -44
  471. package/dist/plugins/twitter/src/credentials.js +16 -0
  472. package/dist/plugins/twitter/src/index.js +25 -37
  473. package/dist/plugins/typesafe/src/credentials.js +28 -0
  474. package/dist/plugins/typesafe/src/index.js +3 -1
  475. package/dist/plugins/typesafe/src/shared.js +23 -35
  476. package/dist/plugins/unleashedSoftware/src/credentials.js +21 -0
  477. package/dist/plugins/unleashedSoftware/src/index.js +13 -37
  478. package/dist/plugins/uplead/src/credentials.js +16 -0
  479. package/dist/plugins/uplead/src/index.js +11 -16
  480. package/dist/plugins/uproc/src/credentials.js +14 -0
  481. package/dist/plugins/uproc/src/index.js +7 -10
  482. package/dist/plugins/uptimerobot/src/credentials.js +14 -0
  483. package/dist/plugins/uptimerobot/src/index.js +28 -39
  484. package/dist/plugins/urlscanio/src/credentials.js +13 -0
  485. package/dist/plugins/urlscanio/src/index.js +13 -22
  486. package/dist/plugins/vercel/src/credentials.js +19 -0
  487. package/dist/plugins/vercel/src/deployments.js +27 -11
  488. package/dist/plugins/vercel/src/env.js +31 -12
  489. package/dist/plugins/vercel/src/index.js +2 -0
  490. package/dist/plugins/vercel/src/projects.js +6 -3
  491. package/dist/plugins/vercel/src/shared.js +32 -37
  492. package/dist/plugins/vero/src/credentials.js +17 -0
  493. package/dist/plugins/vero/src/index.js +18 -21
  494. package/dist/plugins/vonage/src/credentials.js +17 -0
  495. package/dist/plugins/vonage/src/index.js +14 -18
  496. package/dist/plugins/wekan/src/credentials.js +16 -0
  497. package/dist/plugins/wekan/src/index.js +33 -46
  498. package/dist/plugins/wolt/src/account.js +6 -0
  499. package/dist/plugins/wolt/src/catalog.js +2 -2
  500. package/dist/plugins/wolt/src/credentials.js +64 -0
  501. package/dist/plugins/wolt/src/index.js +8 -3
  502. package/dist/plugins/wolt/src/orders.js +2 -2
  503. package/dist/plugins/wolt/src/public.js +91 -0
  504. package/dist/plugins/wolt/src/shared.js +49 -158
  505. package/dist/plugins/woocommerce/src/credentials.js +16 -0
  506. package/dist/plugins/woocommerce/src/index.js +19 -37
  507. package/dist/plugins/wordpress/src/credentials.js +16 -0
  508. package/dist/plugins/wordpress/src/index.js +23 -42
  509. package/dist/plugins/xai/src/credentials.js +13 -0
  510. package/dist/plugins/xai/src/index.js +32 -31
  511. package/dist/plugins/xero/src/credentials.js +17 -0
  512. package/dist/plugins/xero/src/index.js +19 -36
  513. package/dist/plugins/yourls/src/credentials.js +17 -0
  514. package/dist/plugins/yourls/src/index.js +13 -23
  515. package/dist/plugins/zammad/src/credentials.js +15 -0
  516. package/dist/plugins/zammad/src/index.js +27 -47
  517. package/dist/plugins/zendesk/src/credentials.js +26 -0
  518. package/dist/plugins/zendesk/src/index.js +29 -48
  519. package/dist/plugins/zoho/src/credentials.js +17 -0
  520. package/dist/plugins/zoho/src/index.js +18 -38
  521. package/dist/plugins/zoom/src/credentials.js +19 -0
  522. package/dist/plugins/zoom/src/index.js +15 -30
  523. package/dist/plugins/zulip/src/credentials.js +16 -0
  524. package/dist/plugins/zulip/src/index.js +36 -42
  525. package/dist/sdk.d.ts +8 -0
  526. package/dist/sdk.js +3 -0
  527. package/package.json +2 -1
  528. package/dist/plugins/_shared/authedFetch.js +0 -33
  529. package/dist/plugins/_shared/tokenRefresh.js +0 -41
  530. package/dist/tests/helpers/engine-harness.d.ts +0 -1
  531. package/dist/tests/helpers/engine-harness.js +0 -236
@@ -53,10 +53,13 @@
53
53
  * for larger files, driven off whether the caller supplies bytes
54
54
  * (Buffer) vs a path (streamed).
55
55
  */
56
- import { createReadStream, readFileSync, statSync, writeFileSync } from "node:fs";
56
+ import { createReadStream, statSync, writeFileSync } from "node:fs";
57
57
  import * as t from "typebox";
58
- import { googleJsonRequest, googleResponse } from "../../_shared/googleAuth.js";
58
+ import { standardBase64 } from "../../_shared/base64.js";
59
+ import { jsonAnswer, pathSegment } from "../../_shared/credentials.js";
60
+ import { googleCredential, googleJsonRequest, googleOAuth, googleResponse, } from "../../_shared/googleAuth.js";
59
61
  import { Id, NonEmptyString, RawGoogleObject, StringMap, StringOrStringArray, stringEnum, } from "../../_shared/googleSchemas.js";
62
+ import { readLocalFile } from "../../_shared/localFile.js";
60
63
  const PermissionRole = stringEnum([
61
64
  "owner",
62
65
  "organizer",
@@ -110,11 +113,6 @@ function driveResponse(ctx, url, init = {}) {
110
113
  }
111
114
  // ─── Request ─────────────────────────────────────────────────────
112
115
  const API_BASE = "https://www.googleapis.com";
113
- function filePathId(id) {
114
- if (!/^[a-zA-Z0-9_-]+$/.test(id))
115
- throw new Error("googleDrive: invalid file ID");
116
- return id;
117
- }
118
116
  function uploadSession(value) {
119
117
  if (!value || !/^https:\/\/www\.googleapis\.com\/upload\/drive\/v3\/files(?:\/[a-zA-Z0-9_-]+)?\?/.test(value))
120
118
  throw new Error("googleDrive: invalid resumable session Location");
@@ -146,9 +144,12 @@ async function paginateAll(ctx, path, key, qs) {
146
144
  * mimeType. For resumable uploads we keep paths as paths so we can
147
145
  * stream instead of buffering 500 MB in memory.
148
146
  */
149
- function resolveContent(p) {
147
+ async function resolveContent(p) {
150
148
  if (typeof p.contentBase64 === "string") {
151
- const buf = Buffer.from(p.contentBase64, "base64");
149
+ const base64 = standardBase64(p.contentBase64);
150
+ if (base64 === undefined)
151
+ throw new Error("googleDrive: contentBase64 is not valid base64");
152
+ const buf = Buffer.from(base64, "base64");
152
153
  return {
153
154
  buffer: buf,
154
155
  size: buf.byteLength,
@@ -172,9 +173,14 @@ function resolveContent(p) {
172
173
  const BUFFER_THRESHOLD = 5 * 1024 * 1024;
173
174
  const fileName = p.name ?? p.contentPath.split("/").pop();
174
175
  if (stat.size <= BUFFER_THRESHOLD) {
176
+ const buffer = await readLocalFile(p.contentPath, {
177
+ subject: "googleDrive: contentPath",
178
+ maxBytes: BUFFER_THRESHOLD,
179
+ oversize: "googleDrive: contentPath grew while reading; retry the upload",
180
+ });
175
181
  return {
176
- buffer: readFileSync(p.contentPath),
177
- size: stat.size,
182
+ buffer,
183
+ size: buffer.byteLength,
178
184
  mimeType: p.mimeType,
179
185
  fileName,
180
186
  };
@@ -354,37 +360,8 @@ const SCOPES = ["https://www.googleapis.com/auth/drive"];
354
360
  export default function googleDrive(rl) {
355
361
  rl.setName("googleDrive");
356
362
  rl.setVersion("0.1.0");
357
- rl.setOAuth({
358
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
359
- tokenUrl: "https://oauth2.googleapis.com/token",
360
- scopes: SCOPES,
361
- authParams: { access_type: "offline", prompt: "consent" },
362
- setupHelp: [
363
- "You need a Google Cloud OAuth client. Takes ~5 minutes, one time.",
364
- "",
365
- "1. Create or pick a Google Cloud project:",
366
- " https://console.cloud.google.com/projectcreate",
367
- "",
368
- "2. Enable the Google Drive API:",
369
- " https://console.cloud.google.com/apis/library/drive.googleapis.com",
370
- "",
371
- "3. Configure the OAuth consent screen:",
372
- " https://console.cloud.google.com/apis/credentials/consent",
373
- " • Audience: External",
374
- "",
375
- "4. Add yourself as a test user:",
376
- " https://console.cloud.google.com/auth/audience",
377
- "",
378
- "5. Create the OAuth client:",
379
- " https://console.cloud.google.com/apis/credentials",
380
- " • + Create credentials → OAuth client ID",
381
- " • Application type: Web application",
382
- " • Authorized redirect URIs → + Add URI: {{redirectUri}}",
383
- "",
384
- "6. Paste the Client ID and Client Secret below, or export",
385
- " GOOGLE_DRIVE_CLIENT_ID and GOOGLE_DRIVE_CLIENT_SECRET.",
386
- ],
387
- });
363
+ rl.setCredential(googleCredential("googleDrive", SCOPES));
364
+ rl.setOAuth(googleOAuth("googleDrive", SCOPES, "GOOGLE_DRIVE"));
388
365
  rl.setConnectionSchema({
389
366
  authMethod: { type: "string", required: false, description: "delegated or serviceAccount (legacy configs infer the method)" },
390
367
  clientId: {
@@ -460,7 +437,7 @@ export default function googleDrive(rl) {
460
437
  }),
461
438
  async execute(input, ctx) {
462
439
  const p = (input ?? {});
463
- const content = resolveContent(p);
440
+ const content = await resolveContent(p);
464
441
  const metadata = {
465
442
  name: content.fileName ?? "Untitled",
466
443
  parents: [resolveParent(p.folderId, p.driveId)],
@@ -487,7 +464,7 @@ export default function googleDrive(rl) {
487
464
  qs.ocrLanguage = p.ocrLanguage;
488
465
  if (p.useContentAsIndexableText)
489
466
  qs.useContentAsIndexableText = p.useContentAsIndexableText;
490
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${uploaded.id}`, {}, qs);
467
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(uploaded.id)}`, {}, qs);
491
468
  },
492
469
  });
493
470
  rl.registerAction("file.createFromText", {
@@ -523,7 +500,7 @@ export default function googleDrive(rl) {
523
500
  const doc = (await driveRequest(ctx, "POST", "/drive/v3/files", metadata, {
524
501
  supportsAllDrives: true,
525
502
  }));
526
- const res = await driveResponse(ctx, `https://docs.googleapis.com/v1/documents/${encodeURIComponent(doc.id)}:batchUpdate`, {
503
+ const res = await driveResponse(ctx, `https://docs.googleapis.com/v1/documents/${pathSegment(doc.id)}:batchUpdate`, {
527
504
  method: "POST",
528
505
  headers: {
529
506
  "Content-Type": "application/json",
@@ -573,7 +550,7 @@ export default function googleDrive(rl) {
573
550
  async execute(input, ctx) {
574
551
  const p = (input ?? {});
575
552
  const fileId = p.fileId;
576
- const meta = (await driveRequest(ctx, "GET", `/drive/v3/files/${fileId}`, undefined, { fields: "mimeType,name", supportsAllDrives: true }));
553
+ const meta = (await driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(fileId)}`, undefined, { fields: "mimeType,name", supportsAllDrives: true }));
577
554
  const isGoogleNative = meta.mimeType?.includes("vnd.google-apps");
578
555
  let url;
579
556
  let contentType = meta.mimeType;
@@ -587,13 +564,13 @@ export default function googleDrive(rl) {
587
564
  };
588
565
  const mime = p.googleDocFormat ?? defaults[type] ?? "application/pdf";
589
566
  contentType = mime;
590
- const u = new URL(`${API_BASE}/drive/v3/files/${filePathId(fileId)}/export`);
567
+ const u = new URL(`${API_BASE}/drive/v3/files/${pathSegment(fileId)}/export`);
591
568
  u.searchParams.set("mimeType", mime);
592
569
  u.searchParams.set("supportsAllDrives", "true");
593
570
  url = u.toString();
594
571
  }
595
572
  else {
596
- const u = new URL(`${API_BASE}/drive/v3/files/${filePathId(fileId)}`);
573
+ const u = new URL(`${API_BASE}/drive/v3/files/${pathSegment(fileId)}`);
597
574
  u.searchParams.set("alt", "media");
598
575
  u.searchParams.set("supportsAllDrives", "true");
599
576
  url = u.toString();
@@ -640,7 +617,7 @@ export default function googleDrive(rl) {
640
617
  if (p.folderId || p.driveId) {
641
618
  body.parents = [resolveParent(p.folderId, p.driveId)];
642
619
  }
643
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/copy`, body, { supportsAllDrives: true });
620
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/copy`, body, { supportsAllDrives: true });
644
621
  },
645
622
  });
646
623
  rl.registerAction("file.move", {
@@ -653,10 +630,10 @@ export default function googleDrive(rl) {
653
630
  }, { additionalProperties: false }),
654
631
  async execute(input, ctx) {
655
632
  const p = (input ?? {});
656
- const current = (await driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}`, undefined, { fields: "parents", supportsAllDrives: true }));
633
+ const current = (await driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}`, undefined, { fields: "parents", supportsAllDrives: true }));
657
634
  const removeParents = (current.parents ?? []).join(",");
658
635
  const addParents = resolveParent(p.folderId, p.driveId);
659
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}`, undefined, {
636
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.fileId)}`, undefined, {
660
637
  supportsAllDrives: true,
661
638
  addParents,
662
639
  removeParents,
@@ -716,10 +693,10 @@ export default function googleDrive(rl) {
716
693
  // Step 1: upload new bytes if provided. Drive requires PATCH on
717
694
  // the upload endpoint for content replacement.
718
695
  if (hasBytes) {
719
- const c = resolveContent(p);
696
+ const c = await resolveContent(p);
720
697
  const mimeType = c.mimeType ?? p.mimeType ?? "application/octet-stream";
721
698
  if (c.buffer) {
722
- const url = new URL(`${API_BASE}/upload/drive/v3/files/${filePathId(fileId)}`);
699
+ const url = new URL(`${API_BASE}/upload/drive/v3/files/${pathSegment(fileId)}`);
723
700
  url.searchParams.set("uploadType", "media");
724
701
  url.searchParams.set("supportsAllDrives", "true");
725
702
  for (const key of [
@@ -744,7 +721,7 @@ export default function googleDrive(rl) {
744
721
  }
745
722
  else if (c.path) {
746
723
  // Resumable PATCH
747
- const initUrl = new URL(`${API_BASE}/upload/drive/v3/files/${filePathId(fileId)}`);
724
+ const initUrl = new URL(`${API_BASE}/upload/drive/v3/files/${pathSegment(fileId)}`);
748
725
  initUrl.searchParams.set("uploadType", "resumable");
749
726
  initUrl.searchParams.set("supportsAllDrives", "true");
750
727
  for (const key of [
@@ -814,11 +791,11 @@ export default function googleDrive(rl) {
814
791
  body.appProperties = p.appProperties;
815
792
  if (Object.keys(body).length === 0) {
816
793
  if (hasBytes && p.fields) {
817
- return driveRequest(ctx, "GET", `/drive/v3/files/${fileId}`, undefined, { supportsAllDrives: true, fields: p.fields });
794
+ return driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(fileId)}`, undefined, { supportsAllDrives: true, fields: p.fields });
818
795
  }
819
796
  return { id: fileId, success: true };
820
797
  }
821
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${fileId}`, body, {
798
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(fileId)}`, body, {
822
799
  supportsAllDrives: true,
823
800
  fields: p.fields,
824
801
  });
@@ -831,12 +808,12 @@ export default function googleDrive(rl) {
831
808
  async execute(input, ctx) {
832
809
  const p = (input ?? {});
833
810
  if (p.deletePermanently) {
834
- await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}`, undefined, {
811
+ await driveRequest(ctx, "DELETE", `/drive/v3/files/${pathSegment(p.fileId)}`, undefined, {
835
812
  supportsAllDrives: true,
836
813
  });
837
814
  }
838
815
  else {
839
- await driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}`, { trashed: true }, { supportsAllDrives: true });
816
+ await driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.fileId)}`, { trashed: true }, { supportsAllDrives: true });
840
817
  }
841
818
  return { id: p.fileId, success: true };
842
819
  },
@@ -847,7 +824,7 @@ export default function googleDrive(rl) {
847
824
  inputSchema: t.Object({ fileId: Id, fields: t.Optional(NonEmptyString) }, { additionalProperties: false }),
848
825
  async execute(input, ctx) {
849
826
  const p = (input ?? {});
850
- return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}`, undefined, { supportsAllDrives: true, fields: p.fields ?? "*" });
827
+ return driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}`, undefined, { supportsAllDrives: true, fields: p.fields ?? "*" });
851
828
  },
852
829
  });
853
830
  rl.registerAction("file.share", {
@@ -914,7 +891,7 @@ export default function googleDrive(rl) {
914
891
  qs.moveToNewOwnersRoot = p.moveToNewOwnersRoot;
915
892
  if (p.useDomainAdminAccess !== undefined)
916
893
  qs.useDomainAdminAccess = p.useDomainAdminAccess;
917
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/permissions`, body, qs);
894
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/permissions`, body, qs);
918
895
  },
919
896
  });
920
897
  rl.registerAction("file.listPermissions", {
@@ -923,7 +900,7 @@ export default function googleDrive(rl) {
923
900
  inputSchema: t.Object({ fileId: Id, useDomainAdminAccess: t.Optional(t.Boolean()) }, { additionalProperties: false }),
924
901
  async execute(input, ctx) {
925
902
  const p = (input ?? {});
926
- return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/permissions`, undefined, {
903
+ return driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}/permissions`, undefined, {
927
904
  supportsAllDrives: true,
928
905
  useDomainAdminAccess: p.useDomainAdminAccess,
929
906
  fields: "*",
@@ -936,7 +913,7 @@ export default function googleDrive(rl) {
936
913
  inputSchema: t.Object({ fileId: Id, permissionId: Id }, { additionalProperties: false }),
937
914
  async execute(input, ctx) {
938
915
  const p = (input ?? {});
939
- await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/permissions/${p.permissionId}`, undefined, { supportsAllDrives: true });
916
+ await driveRequest(ctx, "DELETE", `/drive/v3/files/${pathSegment(p.fileId)}/permissions/${pathSegment(p.permissionId)}`, undefined, { supportsAllDrives: true });
940
917
  return { success: true };
941
918
  },
942
919
  });
@@ -974,12 +951,12 @@ export default function googleDrive(rl) {
974
951
  async execute(input, ctx) {
975
952
  const p = (input ?? {});
976
953
  if (p.deletePermanently) {
977
- await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.folderId}`, undefined, {
954
+ await driveRequest(ctx, "DELETE", `/drive/v3/files/${pathSegment(p.folderId)}`, undefined, {
978
955
  supportsAllDrives: true,
979
956
  });
980
957
  }
981
958
  else {
982
- await driveRequest(ctx, "PATCH", `/drive/v3/files/${p.folderId}`, { trashed: true }, { supportsAllDrives: true });
959
+ await driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.folderId)}`, { trashed: true }, { supportsAllDrives: true });
983
960
  }
984
961
  return { id: p.folderId, success: true };
985
962
  },
@@ -1045,7 +1022,7 @@ export default function googleDrive(rl) {
1045
1022
  if (p[k] !== undefined)
1046
1023
  qs[k] = p[k];
1047
1024
  }
1048
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.folderId}/permissions`, body, qs);
1025
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.folderId)}/permissions`, body, qs);
1049
1026
  },
1050
1027
  });
1051
1028
  // ── File / folder search ──────────────────────────────
@@ -1147,7 +1124,7 @@ export default function googleDrive(rl) {
1147
1124
  const qs = {};
1148
1125
  if (p.useDomainAdminAccess !== undefined)
1149
1126
  qs.useDomainAdminAccess = p.useDomainAdminAccess;
1150
- return driveRequest(ctx, "GET", `/drive/v3/drives/${p.driveId}`, undefined, qs);
1127
+ return driveRequest(ctx, "GET", `/drive/v3/drives/${pathSegment(p.driveId)}`, undefined, qs);
1151
1128
  },
1152
1129
  });
1153
1130
  rl.registerAction("drive.list", {
@@ -1200,7 +1177,7 @@ export default function googleDrive(rl) {
1200
1177
  if (p[k] !== undefined)
1201
1178
  body[k] = p[k];
1202
1179
  }
1203
- return driveRequest(ctx, "PATCH", `/drive/v3/drives/${p.driveId}`, body);
1180
+ return driveRequest(ctx, "PATCH", `/drive/v3/drives/${pathSegment(p.driveId)}`, body);
1204
1181
  },
1205
1182
  });
1206
1183
  rl.registerAction("drive.delete", {
@@ -1209,7 +1186,7 @@ export default function googleDrive(rl) {
1209
1186
  inputSchema: t.Object({ driveId: Id }, { additionalProperties: false }),
1210
1187
  async execute(input, ctx) {
1211
1188
  const p = (input ?? {});
1212
- await driveRequest(ctx, "DELETE", `/drive/v3/drives/${p.driveId}`);
1189
+ await driveRequest(ctx, "DELETE", `/drive/v3/drives/${pathSegment(p.driveId)}`);
1213
1190
  return { success: true };
1214
1191
  },
1215
1192
  });
@@ -1251,7 +1228,7 @@ export default function googleDrive(rl) {
1251
1228
  do {
1252
1229
  if (pageToken)
1253
1230
  query.pageToken = pageToken;
1254
- const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${fileId}/comments`, undefined, query));
1231
+ const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(fileId)}/comments`, undefined, query));
1255
1232
  if (Array.isArray(page.comments))
1256
1233
  out.push(...page.comments);
1257
1234
  pageToken = page.nextPageToken;
@@ -1265,7 +1242,7 @@ export default function googleDrive(rl) {
1265
1242
  inputSchema: t.Object({ fileId: Id, commentId: Id, includeDeleted: t.Optional(t.Boolean()) }, { additionalProperties: false }),
1266
1243
  async execute(input, ctx) {
1267
1244
  const p = (input ?? {});
1268
- return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/comments/${p.commentId}`, undefined, { fields: COMMENT_FIELDS, includeDeleted: p.includeDeleted ?? false });
1245
+ return driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}`, undefined, { fields: COMMENT_FIELDS, includeDeleted: p.includeDeleted ?? false });
1269
1246
  },
1270
1247
  });
1271
1248
  rl.registerAction("comment.create", {
@@ -1281,7 +1258,7 @@ export default function googleDrive(rl) {
1281
1258
  const body = { content: p.content };
1282
1259
  if (p.quotedFileContent)
1283
1260
  body.quotedFileContent = p.quotedFileContent;
1284
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/comments`, body, { fields: COMMENT_FIELDS });
1261
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/comments`, body, { fields: COMMENT_FIELDS });
1285
1262
  },
1286
1263
  });
1287
1264
  rl.registerAction("comment.update", {
@@ -1290,7 +1267,7 @@ export default function googleDrive(rl) {
1290
1267
  inputSchema: t.Object({ fileId: Id, commentId: Id, content: NonEmptyString }, { additionalProperties: false }),
1291
1268
  async execute(input, ctx) {
1292
1269
  const p = (input ?? {});
1293
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}/comments/${p.commentId}`, { content: p.content }, { fields: COMMENT_FIELDS });
1270
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}`, { content: p.content }, { fields: COMMENT_FIELDS });
1294
1271
  },
1295
1272
  });
1296
1273
  rl.registerAction("comment.delete", {
@@ -1299,7 +1276,7 @@ export default function googleDrive(rl) {
1299
1276
  inputSchema: t.Object({ fileId: Id, commentId: Id }, { additionalProperties: false }),
1300
1277
  async execute(input, ctx) {
1301
1278
  const p = (input ?? {});
1302
- await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/comments/${p.commentId}`);
1279
+ await driveRequest(ctx, "DELETE", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}`);
1303
1280
  return { success: true };
1304
1281
  },
1305
1282
  });
@@ -1309,7 +1286,7 @@ export default function googleDrive(rl) {
1309
1286
  inputSchema: t.Object({ fileId: Id, commentId: Id, content: t.Optional(NonEmptyString) }, { additionalProperties: false }),
1310
1287
  async execute(input, ctx) {
1311
1288
  const p = (input ?? {});
1312
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies`, { action: "resolve", content: p.content ?? "Resolved." }, { fields: REPLY_FIELDS });
1289
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}/replies`, { action: "resolve", content: p.content ?? "Resolved." }, { fields: REPLY_FIELDS });
1313
1290
  },
1314
1291
  });
1315
1292
  rl.registerAction("comment.reopen", {
@@ -1318,7 +1295,7 @@ export default function googleDrive(rl) {
1318
1295
  inputSchema: t.Object({ fileId: Id, commentId: Id, content: t.Optional(NonEmptyString) }, { additionalProperties: false }),
1319
1296
  async execute(input, ctx) {
1320
1297
  const p = (input ?? {});
1321
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies`, { action: "reopen", content: p.content ?? "Reopened." }, { fields: REPLY_FIELDS });
1298
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}/replies`, { action: "reopen", content: p.content ?? "Reopened." }, { fields: REPLY_FIELDS });
1322
1299
  },
1323
1300
  });
1324
1301
  rl.registerAction("reply.list", {
@@ -1342,7 +1319,7 @@ export default function googleDrive(rl) {
1342
1319
  do {
1343
1320
  if (pageToken)
1344
1321
  query.pageToken = pageToken;
1345
- const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies`, undefined, query));
1322
+ const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}/replies`, undefined, query));
1346
1323
  if (Array.isArray(page.replies))
1347
1324
  out.push(...page.replies);
1348
1325
  pageToken = page.nextPageToken;
@@ -1364,7 +1341,7 @@ export default function googleDrive(rl) {
1364
1341
  const body = { content: p.content };
1365
1342
  if (p.action === "resolve" || p.action === "reopen")
1366
1343
  body.action = p.action;
1367
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies`, body, { fields: REPLY_FIELDS });
1344
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}/replies`, body, { fields: REPLY_FIELDS });
1368
1345
  },
1369
1346
  });
1370
1347
  rl.registerAction("reply.update", {
@@ -1373,7 +1350,7 @@ export default function googleDrive(rl) {
1373
1350
  inputSchema: t.Object({ fileId: Id, commentId: Id, replyId: Id, content: NonEmptyString }, { additionalProperties: false }),
1374
1351
  async execute(input, ctx) {
1375
1352
  const p = (input ?? {});
1376
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies/${p.replyId}`, { content: p.content }, { fields: REPLY_FIELDS });
1353
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}/replies/${pathSegment(p.replyId)}`, { content: p.content }, { fields: REPLY_FIELDS });
1377
1354
  },
1378
1355
  });
1379
1356
  rl.registerAction("reply.delete", {
@@ -1382,7 +1359,7 @@ export default function googleDrive(rl) {
1382
1359
  inputSchema: t.Object({ fileId: Id, commentId: Id, replyId: Id }, { additionalProperties: false }),
1383
1360
  async execute(input, ctx) {
1384
1361
  const p = (input ?? {});
1385
- await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies/${p.replyId}`);
1362
+ await driveRequest(ctx, "DELETE", `/drive/v3/files/${pathSegment(p.fileId)}/comments/${pathSegment(p.commentId)}/replies/${pathSegment(p.replyId)}`);
1386
1363
  return { success: true };
1387
1364
  },
1388
1365
  });
@@ -1420,7 +1397,7 @@ export default function googleDrive(rl) {
1420
1397
  do {
1421
1398
  if (pageToken)
1422
1399
  query.pageToken = pageToken;
1423
- const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${fileId}/revisions`, undefined, query));
1400
+ const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(fileId)}/revisions`, undefined, query));
1424
1401
  if (Array.isArray(page.revisions))
1425
1402
  out.push(...page.revisions);
1426
1403
  pageToken = page.nextPageToken;
@@ -1434,7 +1411,7 @@ export default function googleDrive(rl) {
1434
1411
  inputSchema: t.Object({ fileId: Id, revisionId: Id }, { additionalProperties: false }),
1435
1412
  async execute(input, ctx) {
1436
1413
  const p = (input ?? {});
1437
- return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/revisions/${p.revisionId}`, undefined, { fields: REVISION_FIELDS });
1414
+ return driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}/revisions/${pathSegment(p.revisionId)}`, undefined, { fields: REVISION_FIELDS });
1438
1415
  },
1439
1416
  });
1440
1417
  rl.registerAction("revision.download", {
@@ -1445,7 +1422,7 @@ export default function googleDrive(rl) {
1445
1422
  const p = (input ?? {});
1446
1423
  const fileId = p.fileId;
1447
1424
  const revisionId = p.revisionId;
1448
- const url = new URL(`${API_BASE}/drive/v3/files/${filePathId(fileId)}/revisions/${filePathId(revisionId)}`);
1425
+ const url = new URL(`${API_BASE}/drive/v3/files/${pathSegment(fileId)}/revisions/${pathSegment(revisionId)}`);
1449
1426
  url.searchParams.set("alt", "media");
1450
1427
  const res = await driveResponse(ctx, url.toString());
1451
1428
  if (!res.ok) {
@@ -1497,10 +1474,7 @@ export default function googleDrive(rl) {
1497
1474
  if (p[k] !== undefined)
1498
1475
  body[k] = p[k];
1499
1476
  }
1500
- if (Object.keys(body).length === 0) {
1501
- throw new Error("googleDrive.revision.update: pass at least one of keepForever / published / publishAuto / publishedOutsideDomain.");
1502
- }
1503
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}/revisions/${p.revisionId}`, body, { fields: REVISION_FIELDS });
1477
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.fileId)}/revisions/${pathSegment(p.revisionId)}`, body, { fields: REVISION_FIELDS });
1504
1478
  },
1505
1479
  });
1506
1480
  rl.registerAction("revision.delete", {
@@ -1509,7 +1483,7 @@ export default function googleDrive(rl) {
1509
1483
  inputSchema: t.Object({ fileId: Id, revisionId: Id }, { additionalProperties: false }),
1510
1484
  async execute(input, ctx) {
1511
1485
  const p = (input ?? {});
1512
- await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/revisions/${p.revisionId}`);
1486
+ await driveRequest(ctx, "DELETE", `/drive/v3/files/${pathSegment(p.fileId)}/revisions/${pathSegment(p.revisionId)}`);
1513
1487
  return { success: true };
1514
1488
  },
1515
1489
  });
@@ -1522,7 +1496,7 @@ export default function googleDrive(rl) {
1522
1496
  const fileId = p.fileId;
1523
1497
  const revisionId = p.revisionId;
1524
1498
  // 1. Pull the chosen revision's bytes.
1525
- const dl = await driveResponse(ctx, `${API_BASE}/drive/v3/files/${encodeURIComponent(fileId)}/revisions/${encodeURIComponent(revisionId)}?alt=media`);
1499
+ const dl = await driveResponse(ctx, `${API_BASE}/drive/v3/files/${pathSegment(fileId)}/revisions/${pathSegment(revisionId)}?alt=media`);
1526
1500
  if (!dl.ok) {
1527
1501
  throw new Error(`googleDrive: revision restore download failed (HTTP ${dl.status})`);
1528
1502
  }
@@ -1531,7 +1505,7 @@ export default function googleDrive(rl) {
1531
1505
  dl.headers.get("content-type") ??
1532
1506
  "application/octet-stream";
1533
1507
  // 2. Multipart-PATCH them as the new head of the same file.
1534
- const url = new URL(`${API_BASE}/upload/drive/v3/files/${filePathId(fileId)}`);
1508
+ const url = new URL(`${API_BASE}/upload/drive/v3/files/${pathSegment(fileId)}`);
1535
1509
  url.searchParams.set("uploadType", "multipart");
1536
1510
  url.searchParams.set("supportsAllDrives", "true");
1537
1511
  url.searchParams.set("fields", "id,name,mimeType,modifiedTime,size,headRevisionId,webViewLink");
@@ -1546,7 +1520,7 @@ export default function googleDrive(rl) {
1546
1520
  if (!res.ok) {
1547
1521
  throw new Error(`googleDrive: revision restore upload failed (HTTP ${res.status})`);
1548
1522
  }
1549
- const head = (await res.json());
1523
+ const head = (await jsonAnswer(res));
1550
1524
  return { fileId, restoredFromRevisionId: revisionId, head };
1551
1525
  },
1552
1526
  });
@@ -1685,10 +1659,7 @@ export default function googleDrive(rl) {
1685
1659
  qs.removeExpiration = true;
1686
1660
  if (p.useDomainAdminAccess)
1687
1661
  qs.useDomainAdminAccess = true;
1688
- if (Object.keys(body).length === 0 && !qs.removeExpiration) {
1689
- throw new Error("googleDrive.permission.update: pass at least one of role / expirationTime / removeExpiration.");
1690
- }
1691
- return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}/permissions/${p.permissionId}`, body, qs);
1662
+ return driveRequest(ctx, "PATCH", `/drive/v3/files/${pathSegment(p.fileId)}/permissions/${pathSegment(p.permissionId)}`, body, qs);
1692
1663
  },
1693
1664
  });
1694
1665
  // ─── Access proposals ───────────────────────────────────────────
@@ -1706,7 +1677,7 @@ export default function googleDrive(rl) {
1706
1677
  const out = [];
1707
1678
  let pageToken;
1708
1679
  do {
1709
- const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/accessproposals`, undefined, { pageSize: p.pageSize ?? 100, pageToken }));
1680
+ const page = (await driveRequest(ctx, "GET", `/drive/v3/files/${pathSegment(p.fileId)}/accessproposals`, undefined, { pageSize: p.pageSize ?? 100, pageToken }));
1710
1681
  if (Array.isArray(page.accessProposals))
1711
1682
  out.push(...page.accessProposals);
1712
1683
  pageToken = page.nextPageToken;
@@ -1744,7 +1715,7 @@ export default function googleDrive(rl) {
1744
1715
  }
1745
1716
  if (p.sendNotification !== undefined)
1746
1717
  body.sendNotification = p.sendNotification;
1747
- return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/accessproposals/${p.proposalId}:resolve`, body);
1718
+ return driveRequest(ctx, "POST", `/drive/v3/files/${pathSegment(p.fileId)}/accessproposals/${pathSegment(p.proposalId)}:resolve`, body);
1748
1719
  },
1749
1720
  });
1750
1721
  // ─── About ───────────────────────────────────────────────────────
@@ -1771,7 +1742,7 @@ export default function googleDrive(rl) {
1771
1742
  }, { additionalProperties: false }),
1772
1743
  async execute(input, ctx) {
1773
1744
  const p = (input ?? {});
1774
- const u = new URL(`${API_BASE}/drive/v3/files/${filePathId(String(p.fileId))}/export`);
1745
+ const u = new URL(`${API_BASE}/drive/v3/files/${pathSegment(p.fileId)}/export`);
1775
1746
  u.searchParams.set("mimeType", p.mimeType);
1776
1747
  const res = await driveResponse(ctx, u.toString());
1777
1748
  if (!res.ok) {
@@ -0,0 +1,14 @@
1
+ import { staticCredential } from "../../_shared/credentials.js";
2
+ /** A Google AI API key, appended by the transport as the `key` query
3
+ * parameter on the Generative Language API. */
4
+ export const googleImageCredential = staticCredential({
5
+ id: "googleImage",
6
+ auth: { kind: "queryKey", param: "key" },
7
+ local: { secret: "apiKey" },
8
+ targets: {
9
+ api: {
10
+ baseUrl: "https://generativelanguage.googleapis.com/v1beta/",
11
+ methods: ["POST"],
12
+ },
13
+ },
14
+ });
@@ -18,8 +18,18 @@
18
18
  * inline next to the instruction and writes the edited result to disk.
19
19
  */
20
20
  import * as t from "typebox";
21
+ import { credentialJson, pathSegment } from "../../_shared/credentials.js";
21
22
  import { readImageInput, SEND_FILE_NOTE, writeImageFile, } from "../../_shared/mediaFile.js";
22
- const BASE = "https://generativelanguage.googleapis.com/v1beta/models";
23
+ import { googleImageCredential } from "./credentials.js";
24
+ /** The model as one path segment before the fixed :generateContent verb. */
25
+ function generateContent(ctx, model, body) {
26
+ return credentialJson(ctx, googleImageCredential, "googleImage", {
27
+ target: "api",
28
+ path: `models/${pathSegment(model)}:generateContent`,
29
+ method: "POST",
30
+ json: body,
31
+ });
32
+ }
23
33
  /** Write every inline image part of a Gemini response to disk. */
24
34
  function saveInlineImages(data, saveDir) {
25
35
  const stamp = Date.now();
@@ -43,6 +53,7 @@ function saveInlineImages(data, saveDir) {
43
53
  export default function googleImage(rl) {
44
54
  rl.setName("googleImage");
45
55
  rl.setVersion("0.1.0");
56
+ rl.setCredential(googleImageCredential);
46
57
  rl.setConnectionSchema({
47
58
  apiKey: {
48
59
  type: "string",
@@ -72,22 +83,11 @@ export default function googleImage(rl) {
72
83
  if (typeof p.prompt !== "string" || p.prompt.length === 0) {
73
84
  throw new Error("googleImage: prompt is required");
74
85
  }
75
- const apiKey = ctx.connection.config.apiKey;
76
86
  const model = p.model ?? "gemini-2.5-flash-image";
77
- const url = `${BASE}/${model}:generateContent?key=${encodeURIComponent(apiKey)}`;
78
- const body = {
87
+ const data = await generateContent(ctx, model, {
79
88
  contents: [{ parts: [{ text: p.prompt }] }],
80
89
  generationConfig: { responseModalities: ["IMAGE", "TEXT"] },
81
- };
82
- const res = await fetch(url, {
83
- method: "POST",
84
- headers: { "Content-Type": "application/json" },
85
- body: JSON.stringify(body),
86
90
  });
87
- if (!res.ok) {
88
- throw new Error(`Google API error ${res.status}: ${await res.text()}`);
89
- }
90
- const data = (await res.json());
91
91
  const images = saveInlineImages(data, p.saveDir);
92
92
  return { provider: "googleImage", model, images, note: SEND_FILE_NOTE };
93
93
  },
@@ -117,11 +117,9 @@ export default function googleImage(rl) {
117
117
  if (typeof p.prompt !== "string" || p.prompt.length === 0) {
118
118
  throw new Error("googleImage: prompt is required");
119
119
  }
120
- const img = readImageInput(p.imagePath, "googleImage");
121
- const apiKey = ctx.connection.config.apiKey;
120
+ const img = await readImageInput(p.imagePath, "googleImage");
122
121
  const model = p.model ?? "gemini-2.5-flash-image";
123
- const url = `${BASE}/${model}:generateContent?key=${encodeURIComponent(apiKey)}`;
124
- const body = {
122
+ const data = await generateContent(ctx, model, {
125
123
  contents: [
126
124
  {
127
125
  parts: [
@@ -131,16 +129,7 @@ export default function googleImage(rl) {
131
129
  },
132
130
  ],
133
131
  generationConfig: { responseModalities: ["IMAGE", "TEXT"] },
134
- };
135
- const res = await fetch(url, {
136
- method: "POST",
137
- headers: { "Content-Type": "application/json" },
138
- body: JSON.stringify(body),
139
132
  });
140
- if (!res.ok) {
141
- throw new Error(`Google API error ${res.status}: ${await res.text()}`);
142
- }
143
- const data = (await res.json());
144
133
  const images = saveInlineImages(data, p.saveDir);
145
134
  if (images.length === 0) {
146
135
  throw new Error("googleImage: the model returned no edited image — it may have refused; try a more specific instruction");