runline 0.34.0 → 0.36.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 (493) hide show
  1. package/dist/auth/errors.d.ts +3 -3
  2. package/dist/auth/errors.js +3 -3
  3. package/dist/core/engine.js +12 -8
  4. package/dist/credentials/aws-plugin.d.ts +79 -0
  5. package/dist/credentials/aws-plugin.js +179 -0
  6. package/dist/credentials/aws.d.ts +41 -0
  7. package/dist/credentials/aws.js +213 -0
  8. package/dist/credentials/broker.d.ts +11 -0
  9. package/dist/credentials/broker.js +222 -0
  10. package/dist/credentials/plugin.d.ts +255 -0
  11. package/dist/{plugins/_shared/credentials.js → credentials/plugin.js} +40 -12
  12. package/dist/credentials/policy.d.ts +11 -3
  13. package/dist/credentials/policy.js +22 -3
  14. package/dist/credentials/registry.d.ts +14 -0
  15. package/dist/credentials/registry.js +60 -2
  16. package/dist/credentials/sigv4.d.ts +47 -0
  17. package/dist/credentials/sigv4.js +145 -0
  18. package/dist/credentials/transport.d.ts +9 -0
  19. package/dist/credentials/transport.js +106 -26
  20. package/dist/credentials/types.d.ts +73 -4
  21. package/dist/index.d.ts +9 -2
  22. package/dist/index.js +6 -1
  23. package/dist/plugin/schema.d.ts +16 -4
  24. package/dist/plugin/schema.js +28 -5
  25. package/dist/plugin/types.d.ts +8 -0
  26. package/dist/plugins/_shared/base64.js +30 -0
  27. package/dist/plugins/_shared/googleAuth.js +65 -6
  28. package/dist/plugins/_shared/googleCredentials.js +41 -9
  29. package/dist/plugins/_shared/localFile.js +40 -0
  30. package/dist/plugins/_shared/mediaFile.js +16 -13
  31. package/dist/plugins/_shared/microsoftAuth.js +22 -9
  32. package/dist/plugins/_shared/microsoftCredentials.js +13 -9
  33. package/dist/plugins/_shared/shiftCloud.js +14 -19
  34. package/dist/plugins/_shared/shiftCredentials.js +1 -2
  35. package/dist/plugins/_shared/shiftUpload.js +14 -10
  36. package/dist/plugins/actionNetwork/src/credentials.js +1 -1
  37. package/dist/plugins/actionNetwork/src/index.js +1 -1
  38. package/dist/plugins/activeCampaign/src/credentials.js +1 -1
  39. package/dist/plugins/activeCampaign/src/index.js +1 -1
  40. package/dist/plugins/adalo/src/credentials.js +1 -1
  41. package/dist/plugins/adalo/src/index.js +1 -1
  42. package/dist/plugins/affinity/src/credentials.js +1 -1
  43. package/dist/plugins/affinity/src/index.js +1 -1
  44. package/dist/plugins/agentMail/src/credentials.js +35 -0
  45. package/dist/plugins/agentMail/src/drafts.js +137 -0
  46. package/dist/plugins/agentMail/src/inboxes.js +95 -0
  47. package/dist/plugins/agentMail/src/index.js +35 -0
  48. package/dist/plugins/agentMail/src/messages.js +154 -0
  49. package/dist/plugins/agentMail/src/schemas.js +156 -0
  50. package/dist/plugins/agentMail/src/shared.js +202 -0
  51. package/dist/plugins/agentMail/src/threads.js +75 -0
  52. package/dist/plugins/agileCrm/src/credentials.js +1 -1
  53. package/dist/plugins/agileCrm/src/index.js +1 -1
  54. package/dist/plugins/airtable/src/credentials.js +1 -1
  55. package/dist/plugins/airtable/src/index.js +1 -1
  56. package/dist/plugins/airtop/src/credentials.js +1 -1
  57. package/dist/plugins/airtop/src/index.js +1 -1
  58. package/dist/plugins/apiTemplateIo/src/credentials.js +1 -1
  59. package/dist/plugins/apiTemplateIo/src/index.js +1 -1
  60. package/dist/plugins/asana/src/credentials.js +1 -1
  61. package/dist/plugins/asana/src/index.js +1 -1
  62. package/dist/plugins/autopilot/src/credentials.js +1 -1
  63. package/dist/plugins/autopilot/src/index.js +1 -1
  64. package/dist/plugins/bambooHr/src/credentials.js +1 -1
  65. package/dist/plugins/bambooHr/src/index.js +1 -1
  66. package/dist/plugins/bannerbear/src/credentials.js +1 -1
  67. package/dist/plugins/bannerbear/src/index.js +1 -1
  68. package/dist/plugins/baserow/src/credentials.js +1 -1
  69. package/dist/plugins/baserow/src/index.js +1 -1
  70. package/dist/plugins/beeminder/src/credentials.js +1 -1
  71. package/dist/plugins/beeminder/src/index.js +1 -1
  72. package/dist/plugins/bitly/src/credentials.js +1 -1
  73. package/dist/plugins/bitly/src/index.js +1 -1
  74. package/dist/plugins/bitwarden/src/credentials.js +1 -1
  75. package/dist/plugins/bitwarden/src/index.js +1 -1
  76. package/dist/plugins/box/src/credentials.js +1 -1
  77. package/dist/plugins/box/src/index.js +1 -1
  78. package/dist/plugins/brandfetch/src/credentials.js +1 -1
  79. package/dist/plugins/brandfetch/src/index.js +1 -1
  80. package/dist/plugins/brevo/src/credentials.js +1 -1
  81. package/dist/plugins/brevo/src/index.js +1 -1
  82. package/dist/plugins/bubble/src/credentials.js +1 -1
  83. package/dist/plugins/bubble/src/index.js +1 -1
  84. package/dist/plugins/chargebee/src/credentials.js +1 -1
  85. package/dist/plugins/chargebee/src/index.js +1 -1
  86. package/dist/plugins/circleci/src/credentials.js +1 -1
  87. package/dist/plugins/circleci/src/index.js +1 -1
  88. package/dist/plugins/ciscoWebex/src/credentials.js +1 -1
  89. package/dist/plugins/ciscoWebex/src/index.js +1 -1
  90. package/dist/plugins/clearbit/src/credentials.js +1 -1
  91. package/dist/plugins/clearbit/src/index.js +1 -1
  92. package/dist/plugins/clickup/src/credentials.js +1 -1
  93. package/dist/plugins/clickup/src/index.js +1 -1
  94. package/dist/plugins/clockify/src/credentials.js +1 -1
  95. package/dist/plugins/clockify/src/index.js +1 -1
  96. package/dist/plugins/cloudflare/src/credentials.js +1 -1
  97. package/dist/plugins/cloudflare/src/index.js +1 -1
  98. package/dist/plugins/cockpit/src/credentials.js +1 -1
  99. package/dist/plugins/cockpit/src/index.js +1 -1
  100. package/dist/plugins/coda/src/credentials.js +1 -1
  101. package/dist/plugins/coda/src/index.js +1 -1
  102. package/dist/plugins/coingecko/src/credentials.js +1 -1
  103. package/dist/plugins/coingecko/src/index.js +1 -1
  104. package/dist/plugins/contentful/src/credentials.js +1 -1
  105. package/dist/plugins/contentful/src/index.js +1 -1
  106. package/dist/plugins/convertkit/src/credentials.js +1 -1
  107. package/dist/plugins/convertkit/src/index.js +1 -1
  108. package/dist/plugins/copper/src/credentials.js +1 -1
  109. package/dist/plugins/copper/src/index.js +1 -1
  110. package/dist/plugins/cortex/src/credentials.js +1 -1
  111. package/dist/plugins/cortex/src/index.js +1 -1
  112. package/dist/plugins/currents/src/credentials.js +1 -1
  113. package/dist/plugins/currents/src/index.js +1 -1
  114. package/dist/plugins/customerIo/src/credentials.js +1 -1
  115. package/dist/plugins/customerIo/src/index.js +1 -1
  116. package/dist/plugins/databricks/src/credentials.js +1 -1
  117. package/dist/plugins/databricks/src/index.js +1 -1
  118. package/dist/plugins/deepl/src/credentials.js +1 -1
  119. package/dist/plugins/deepl/src/index.js +1 -1
  120. package/dist/plugins/demio/src/credentials.js +1 -1
  121. package/dist/plugins/demio/src/index.js +1 -1
  122. package/dist/plugins/dhl/src/credentials.js +1 -1
  123. package/dist/plugins/dhl/src/index.js +1 -1
  124. package/dist/plugins/discord/src/credentials.js +1 -1
  125. package/dist/plugins/discord/src/index.js +1 -1
  126. package/dist/plugins/discourse/src/credentials.js +1 -1
  127. package/dist/plugins/discourse/src/index.js +1 -1
  128. package/dist/plugins/disqus/src/credentials.js +1 -1
  129. package/dist/plugins/disqus/src/index.js +1 -1
  130. package/dist/plugins/drift/src/credentials.js +1 -1
  131. package/dist/plugins/drift/src/index.js +1 -1
  132. package/dist/plugins/dropbox/src/credentials.js +1 -1
  133. package/dist/plugins/dropbox/src/index.js +1 -1
  134. package/dist/plugins/dropcontact/src/credentials.js +1 -1
  135. package/dist/plugins/dropcontact/src/index.js +1 -1
  136. package/dist/plugins/egoi/src/credentials.js +1 -1
  137. package/dist/plugins/egoi/src/index.js +1 -1
  138. package/dist/plugins/elasticsearch/src/credentials.js +1 -1
  139. package/dist/plugins/elasticsearch/src/index.js +1 -1
  140. package/dist/plugins/elevenlabs/src/credentials.js +1 -1
  141. package/dist/plugins/elevenlabs/src/shared.js +30 -46
  142. package/dist/plugins/elevenlabs/src/workflows.js +1 -1
  143. package/dist/plugins/emelia/src/credentials.js +1 -1
  144. package/dist/plugins/emelia/src/index.js +1 -1
  145. package/dist/plugins/erpnext/src/credentials.js +1 -1
  146. package/dist/plugins/erpnext/src/index.js +1 -1
  147. package/dist/plugins/facebookGraph/src/credentials.js +1 -1
  148. package/dist/plugins/facebookGraph/src/index.js +1 -2
  149. package/dist/plugins/fal/src/credentials.js +1 -1
  150. package/dist/plugins/fal/src/index.js +1 -1
  151. package/dist/plugins/fal/src/shared.js +1 -1
  152. package/dist/plugins/freshdesk/src/credentials.js +1 -1
  153. package/dist/plugins/freshdesk/src/index.js +1 -1
  154. package/dist/plugins/freshservice/src/credentials.js +1 -1
  155. package/dist/plugins/freshservice/src/index.js +1 -1
  156. package/dist/plugins/freshworksCrm/src/credentials.js +1 -1
  157. package/dist/plugins/freshworksCrm/src/index.js +1 -1
  158. package/dist/plugins/getresponse/src/credentials.js +1 -1
  159. package/dist/plugins/getresponse/src/index.js +1 -1
  160. package/dist/plugins/gett/src/credentials.js +1 -2
  161. package/dist/plugins/gett/src/index.js +1 -1
  162. package/dist/plugins/gett/src/login.js +1 -1
  163. package/dist/plugins/gett/src/session.js +1 -1
  164. package/dist/plugins/gett/src/shared.js +1 -2
  165. package/dist/plugins/ghost/src/credentials.js +1 -1
  166. package/dist/plugins/ghost/src/index.js +1 -1
  167. package/dist/plugins/github/src/credentials.js +1 -1
  168. package/dist/plugins/github/src/index.js +1 -1
  169. package/dist/plugins/gitlab/src/credentials.js +1 -1
  170. package/dist/plugins/gitlab/src/index.js +1 -1
  171. package/dist/plugins/gmail/src/index.js +23 -86
  172. package/dist/plugins/gong/src/credentials.js +1 -1
  173. package/dist/plugins/gong/src/index.js +1 -1
  174. package/dist/plugins/googleAppsScript/src/index.js +14 -2
  175. package/dist/plugins/googleCalendar/src/index.js +7 -40
  176. package/dist/plugins/googleContacts/src/index.js +3 -33
  177. package/dist/plugins/googleDocs/src/index.js +2 -33
  178. package/dist/plugins/googleDocs/src/shared.js +1 -1
  179. package/dist/plugins/googleDrive/src/index.js +20 -46
  180. package/dist/plugins/googleImage/src/credentials.js +1 -1
  181. package/dist/plugins/googleImage/src/index.js +2 -2
  182. package/dist/plugins/googleSheets/src/index.js +3 -35
  183. package/dist/plugins/googleSlides/src/index.js +3 -33
  184. package/dist/plugins/googleTasks/src/index.js +3 -33
  185. package/dist/plugins/gotify/src/credentials.js +1 -1
  186. package/dist/plugins/gotify/src/index.js +1 -1
  187. package/dist/plugins/gotowebinar/src/credentials.js +1 -1
  188. package/dist/plugins/gotowebinar/src/index.js +1 -1
  189. package/dist/plugins/grafana/src/credentials.js +1 -1
  190. package/dist/plugins/grafana/src/index.js +1 -1
  191. package/dist/plugins/graphql/src/credentials.js +1 -1
  192. package/dist/plugins/graphql/src/index.js +1 -1
  193. package/dist/plugins/grist/src/credentials.js +1 -1
  194. package/dist/plugins/grist/src/index.js +1 -1
  195. package/dist/plugins/halopsa/src/credentials.js +1 -2
  196. package/dist/plugins/halopsa/src/index.js +1 -1
  197. package/dist/plugins/harvest/src/credentials.js +1 -1
  198. package/dist/plugins/harvest/src/index.js +1 -1
  199. package/dist/plugins/helpscout/src/credentials.js +1 -1
  200. package/dist/plugins/helpscout/src/index.js +1 -1
  201. package/dist/plugins/highlevel/src/credentials.js +1 -1
  202. package/dist/plugins/highlevel/src/index.js +9 -3
  203. package/dist/plugins/homeAssistant/src/credentials.js +1 -1
  204. package/dist/plugins/homeAssistant/src/index.js +1 -1
  205. package/dist/plugins/hubspot/src/credentials.js +1 -1
  206. package/dist/plugins/hubspot/src/index.js +1 -1
  207. package/dist/plugins/humanticAi/src/credentials.js +1 -1
  208. package/dist/plugins/humanticAi/src/index.js +1 -1
  209. package/dist/plugins/hunter/src/credentials.js +1 -1
  210. package/dist/plugins/hunter/src/index.js +1 -1
  211. package/dist/plugins/intercom/src/credentials.js +1 -1
  212. package/dist/plugins/intercom/src/index.js +1 -1
  213. package/dist/plugins/iterable/src/credentials.js +1 -1
  214. package/dist/plugins/iterable/src/index.js +1 -1
  215. package/dist/plugins/jenkins/src/credentials.js +1 -1
  216. package/dist/plugins/jenkins/src/index.js +1 -1
  217. package/dist/plugins/jira/src/credentials.js +1 -1
  218. package/dist/plugins/jira/src/index.js +1 -1
  219. package/dist/plugins/keap/src/credentials.js +1 -1
  220. package/dist/plugins/keap/src/index.js +1 -1
  221. package/dist/plugins/kobotoolbox/src/credentials.js +1 -1
  222. package/dist/plugins/kobotoolbox/src/index.js +1 -1
  223. package/dist/plugins/lemlist/src/credentials.js +1 -1
  224. package/dist/plugins/lemlist/src/index.js +1 -1
  225. package/dist/plugins/linear/src/credentials.js +1 -1
  226. package/dist/plugins/linear/src/shared.js +1 -1
  227. package/dist/plugins/lingvanex/src/credentials.js +1 -1
  228. package/dist/plugins/lingvanex/src/index.js +1 -1
  229. package/dist/plugins/linkedin/src/credentials.js +1 -1
  230. package/dist/plugins/linkedin/src/index.js +1 -1
  231. package/dist/plugins/lonescale/src/credentials.js +1 -1
  232. package/dist/plugins/lonescale/src/index.js +1 -1
  233. package/dist/plugins/magento/src/credentials.js +1 -1
  234. package/dist/plugins/magento/src/index.js +1 -1
  235. package/dist/plugins/mailcheck/src/credentials.js +1 -1
  236. package/dist/plugins/mailcheck/src/index.js +1 -1
  237. package/dist/plugins/mailchimp/src/credentials.js +1 -1
  238. package/dist/plugins/mailchimp/src/index.js +1 -1
  239. package/dist/plugins/mailerlite/src/credentials.js +1 -1
  240. package/dist/plugins/mailerlite/src/index.js +1 -1
  241. package/dist/plugins/mailgun/src/credentials.js +1 -1
  242. package/dist/plugins/mailgun/src/index.js +1 -1
  243. package/dist/plugins/mailjet/src/credentials.js +1 -1
  244. package/dist/plugins/mailjet/src/index.js +1 -1
  245. package/dist/plugins/mandrill/src/credentials.js +1 -1
  246. package/dist/plugins/mandrill/src/index.js +1 -1
  247. package/dist/plugins/marketstack/src/credentials.js +1 -1
  248. package/dist/plugins/marketstack/src/index.js +1 -1
  249. package/dist/plugins/matrix/src/credentials.js +1 -1
  250. package/dist/plugins/matrix/src/index.js +1 -1
  251. package/dist/plugins/mattermost/src/credentials.js +1 -1
  252. package/dist/plugins/mattermost/src/index.js +1 -1
  253. package/dist/plugins/mautic/src/credentials.js +1 -1
  254. package/dist/plugins/mautic/src/index.js +1 -1
  255. package/dist/plugins/medium/src/credentials.js +1 -1
  256. package/dist/plugins/medium/src/index.js +1 -1
  257. package/dist/plugins/messagebird/src/credentials.js +1 -1
  258. package/dist/plugins/messagebird/src/index.js +1 -1
  259. package/dist/plugins/metabase/src/credentials.js +1 -1
  260. package/dist/plugins/metabase/src/index.js +1 -1
  261. package/dist/plugins/microsoftCalendar/src/index.js +2 -7
  262. package/dist/plugins/microsoftFiles/src/index.js +17 -9
  263. package/dist/plugins/microsoftMail/src/index.js +2 -7
  264. package/dist/plugins/misp/src/credentials.js +1 -1
  265. package/dist/plugins/misp/src/index.js +1 -1
  266. package/dist/plugins/mocean/src/credentials.js +1 -1
  267. package/dist/plugins/mocean/src/index.js +1 -1
  268. package/dist/plugins/monday/src/credentials.js +1 -1
  269. package/dist/plugins/monday/src/index.js +1 -1
  270. package/dist/plugins/monicaCrm/src/credentials.js +1 -1
  271. package/dist/plugins/monicaCrm/src/index.js +1 -1
  272. package/dist/plugins/msg91/src/credentials.js +1 -1
  273. package/dist/plugins/msg91/src/index.js +1 -1
  274. package/dist/plugins/nasa/src/credentials.js +1 -1
  275. package/dist/plugins/nasa/src/index.js +1 -1
  276. package/dist/plugins/netlify/src/credentials.js +1 -1
  277. package/dist/plugins/netlify/src/index.js +1 -1
  278. package/dist/plugins/netscalerAdc/src/credentials.js +1 -1
  279. package/dist/plugins/netscalerAdc/src/index.js +1 -1
  280. package/dist/plugins/nextcloud/src/credentials.js +1 -2
  281. package/dist/plugins/nextcloud/src/index.js +1 -1
  282. package/dist/plugins/nocodb/src/credentials.js +1 -1
  283. package/dist/plugins/nocodb/src/index.js +1 -1
  284. package/dist/plugins/notion/src/credentials.js +1 -1
  285. package/dist/plugins/notion/src/index.js +1 -1
  286. package/dist/plugins/npm/src/credentials.js +1 -1
  287. package/dist/plugins/npm/src/index.js +1 -1
  288. package/dist/plugins/odoo/src/credentials.js +1 -1
  289. package/dist/plugins/odoo/src/index.js +1 -2
  290. package/dist/plugins/okta/src/credentials.js +1 -1
  291. package/dist/plugins/okta/src/index.js +1 -2
  292. package/dist/plugins/oneSimpleApi/src/credentials.js +1 -1
  293. package/dist/plugins/oneSimpleApi/src/index.js +1 -1
  294. package/dist/plugins/onfleet/src/credentials.js +1 -1
  295. package/dist/plugins/onfleet/src/index.js +1 -1
  296. package/dist/plugins/openai/src/credentials.js +1 -1
  297. package/dist/plugins/openai/src/index.js +2 -2
  298. package/dist/plugins/openweathermap/src/credentials.js +1 -1
  299. package/dist/plugins/openweathermap/src/index.js +1 -1
  300. package/dist/plugins/oura/src/credentials.js +1 -1
  301. package/dist/plugins/oura/src/index.js +1 -1
  302. package/dist/plugins/paddle/src/credentials.js +1 -1
  303. package/dist/plugins/paddle/src/index.js +1 -1
  304. package/dist/plugins/pagerduty/src/credentials.js +1 -1
  305. package/dist/plugins/pagerduty/src/index.js +1 -1
  306. package/dist/plugins/parallel/src/credentials.js +1 -1
  307. package/dist/plugins/parallel/src/index.js +15 -1
  308. package/dist/plugins/paypal/src/credentials.js +1 -1
  309. package/dist/plugins/paypal/src/index.js +1 -1
  310. package/dist/plugins/peekalink/src/credentials.js +1 -1
  311. package/dist/plugins/peekalink/src/index.js +1 -1
  312. package/dist/plugins/phantombuster/src/credentials.js +1 -1
  313. package/dist/plugins/phantombuster/src/index.js +1 -1
  314. package/dist/plugins/philipsHue/src/credentials.js +1 -1
  315. package/dist/plugins/philipsHue/src/index.js +1 -1
  316. package/dist/plugins/pipedrive/src/credentials.js +1 -1
  317. package/dist/plugins/pipedrive/src/index.js +1 -1
  318. package/dist/plugins/plaud/src/shared.js +1 -2
  319. package/dist/plugins/plivo/src/credentials.js +1 -1
  320. package/dist/plugins/plivo/src/index.js +1 -1
  321. package/dist/plugins/posthog/src/credentials.js +1 -1
  322. package/dist/plugins/posthog/src/index.js +1 -1
  323. package/dist/plugins/profitwell/src/credentials.js +1 -1
  324. package/dist/plugins/profitwell/src/index.js +1 -1
  325. package/dist/plugins/pushbullet/src/credentials.js +1 -1
  326. package/dist/plugins/pushbullet/src/index.js +1 -1
  327. package/dist/plugins/pushcut/src/credentials.js +1 -1
  328. package/dist/plugins/pushcut/src/index.js +1 -1
  329. package/dist/plugins/pushover/src/credentials.js +1 -1
  330. package/dist/plugins/pushover/src/index.js +1 -1
  331. package/dist/plugins/quickbase/src/credentials.js +1 -1
  332. package/dist/plugins/quickbase/src/index.js +1 -1
  333. package/dist/plugins/quickbooks/src/credentials.js +1 -1
  334. package/dist/plugins/quickbooks/src/index.js +1 -1
  335. package/dist/plugins/raindrop/src/credentials.js +1 -1
  336. package/dist/plugins/raindrop/src/index.js +1 -1
  337. package/dist/plugins/recraft/src/credentials.js +1 -1
  338. package/dist/plugins/recraft/src/index.js +2 -2
  339. package/dist/plugins/reddit/src/credentials.js +1 -1
  340. package/dist/plugins/reddit/src/index.js +1 -1
  341. package/dist/plugins/replicate/src/credentials.js +1 -1
  342. package/dist/plugins/replicate/src/index.js +2 -2
  343. package/dist/plugins/rocketchat/src/credentials.js +1 -1
  344. package/dist/plugins/rocketchat/src/index.js +1 -1
  345. package/dist/plugins/rundeck/src/credentials.js +1 -1
  346. package/dist/plugins/rundeck/src/index.js +1 -1
  347. package/dist/plugins/salesforce/src/credentials.js +1 -2
  348. package/dist/plugins/salesforce/src/shared.js +1 -2
  349. package/dist/plugins/salesforce/src/sobjects.js +1 -1
  350. package/dist/plugins/salesmate/src/credentials.js +1 -1
  351. package/dist/plugins/salesmate/src/index.js +1 -1
  352. package/dist/plugins/securityScorecard/src/credentials.js +1 -1
  353. package/dist/plugins/securityScorecard/src/index.js +1 -1
  354. package/dist/plugins/segment/src/credentials.js +1 -1
  355. package/dist/plugins/segment/src/index.js +1 -1
  356. package/dist/plugins/sendgrid/src/credentials.js +1 -1
  357. package/dist/plugins/sendgrid/src/index.js +1 -2
  358. package/dist/plugins/sendy/src/credentials.js +1 -1
  359. package/dist/plugins/sendy/src/index.js +1 -1
  360. package/dist/plugins/sentry/src/credentials.js +1 -1
  361. package/dist/plugins/sentry/src/index.js +1 -1
  362. package/dist/plugins/servicenow/src/credentials.js +1 -1
  363. package/dist/plugins/servicenow/src/index.js +1 -1
  364. package/dist/plugins/shiftAtlas/src/graph.js +2 -1
  365. package/dist/plugins/shiftAtlas/src/shared.js +1 -1
  366. package/dist/plugins/shiftBwm/src/shared.js +2 -4
  367. package/dist/plugins/shiftCrm/src/access.js +2 -1
  368. package/dist/plugins/shiftCrm/src/accounts.js +2 -1
  369. package/dist/plugins/shiftCrm/src/imports.js +2 -1
  370. package/dist/plugins/shiftCrm/src/opportunities.js +2 -1
  371. package/dist/plugins/shiftCrm/src/people.js +2 -1
  372. package/dist/plugins/shiftCrm/src/records.js +2 -1
  373. package/dist/plugins/shiftCrm/src/shared.js +1 -1
  374. package/dist/plugins/shiftCrm/src/tasks.js +2 -1
  375. package/dist/plugins/shiftObjects/src/objects.js +3 -2
  376. package/dist/plugins/shiftOcr/src/index.js +10 -4
  377. package/dist/plugins/shiftPages/src/pages.js +2 -1
  378. package/dist/plugins/shiftPages/src/shared.js +3 -2
  379. package/dist/plugins/shiftTranscription/src/shared.js +1 -1
  380. package/dist/plugins/shiftTranscription/src/transcription.js +3 -2
  381. package/dist/plugins/shiftWork/src/issue-views.js +2 -1
  382. package/dist/plugins/shiftWork/src/issues.js +2 -1
  383. package/dist/plugins/shiftWork/src/projects.js +2 -1
  384. package/dist/plugins/shiftWork/src/shared.js +1 -1
  385. package/dist/plugins/shopify/src/credentials.js +1 -1
  386. package/dist/plugins/shopify/src/index.js +1 -1
  387. package/dist/plugins/signl4/src/credentials.js +1 -1
  388. package/dist/plugins/signl4/src/index.js +1 -1
  389. package/dist/plugins/slack/src/credentials.js +1 -1
  390. package/dist/plugins/slack/src/index.js +1 -1
  391. package/dist/plugins/sms77/src/credentials.js +1 -1
  392. package/dist/plugins/sms77/src/index.js +1 -1
  393. package/dist/plugins/splunk/src/credentials.js +1 -1
  394. package/dist/plugins/splunk/src/index.js +1 -1
  395. package/dist/plugins/spotify/src/credentials.js +1 -1
  396. package/dist/plugins/spotify/src/index.js +1 -1
  397. package/dist/plugins/stackby/src/credentials.js +1 -1
  398. package/dist/plugins/stackby/src/index.js +1 -1
  399. package/dist/plugins/steel/src/auth.js +1 -1
  400. package/dist/plugins/steel/src/browser.js +1 -1
  401. package/dist/plugins/steel/src/captchas.js +1 -1
  402. package/dist/plugins/steel/src/extensions.js +1 -1
  403. package/dist/plugins/steel/src/files.js +1 -1
  404. package/dist/plugins/steel/src/profiles.js +1 -1
  405. package/dist/plugins/steel/src/sessions.js +1 -1
  406. package/dist/plugins/steel/src/shared.js +1 -1
  407. package/dist/plugins/storyblok/src/credentials.js +1 -1
  408. package/dist/plugins/storyblok/src/index.js +1 -1
  409. package/dist/plugins/strapi/src/credentials.js +1 -1
  410. package/dist/plugins/strapi/src/index.js +1 -1
  411. package/dist/plugins/strava/src/credentials.js +1 -1
  412. package/dist/plugins/strava/src/index.js +1 -1
  413. package/dist/plugins/stripe/src/credentials.js +1 -1
  414. package/dist/plugins/stripe/src/index.js +1 -1
  415. package/dist/plugins/supabase/src/credentials.js +1 -1
  416. package/dist/plugins/supabase/src/index.js +1 -1
  417. package/dist/plugins/syncromsp/src/credentials.js +1 -1
  418. package/dist/plugins/syncromsp/src/index.js +1 -1
  419. package/dist/plugins/tapfiliate/src/credentials.js +1 -1
  420. package/dist/plugins/tapfiliate/src/index.js +1 -1
  421. package/dist/plugins/telegram/src/credentials.js +1 -1
  422. package/dist/plugins/telegram/src/index.js +1 -1
  423. package/dist/plugins/thehive/src/credentials.js +1 -1
  424. package/dist/plugins/thehive/src/index.js +1 -1
  425. package/dist/plugins/thehiveProject/src/credentials.js +1 -1
  426. package/dist/plugins/thehiveProject/src/index.js +1 -1
  427. package/dist/plugins/todoist/src/credentials.js +1 -1
  428. package/dist/plugins/todoist/src/index.js +1 -1
  429. package/dist/plugins/together/src/credentials.js +1 -1
  430. package/dist/plugins/together/src/index.js +2 -2
  431. package/dist/plugins/travisci/src/credentials.js +1 -1
  432. package/dist/plugins/travisci/src/index.js +1 -1
  433. package/dist/plugins/trello/src/credentials.js +1 -1
  434. package/dist/plugins/trello/src/index.js +1 -1
  435. package/dist/plugins/twake/src/credentials.js +1 -1
  436. package/dist/plugins/twake/src/index.js +1 -1
  437. package/dist/plugins/twilio/src/credentials.js +1 -1
  438. package/dist/plugins/twilio/src/index.js +1 -1
  439. package/dist/plugins/twist/src/credentials.js +1 -1
  440. package/dist/plugins/twist/src/index.js +1 -1
  441. package/dist/plugins/twitter/src/credentials.js +1 -1
  442. package/dist/plugins/twitter/src/index.js +1 -1
  443. package/dist/plugins/typesafe/src/credentials.js +1 -1
  444. package/dist/plugins/typesafe/src/shared.js +1 -1
  445. package/dist/plugins/unleashedSoftware/src/credentials.js +1 -1
  446. package/dist/plugins/unleashedSoftware/src/index.js +1 -1
  447. package/dist/plugins/uplead/src/credentials.js +1 -1
  448. package/dist/plugins/uplead/src/index.js +1 -1
  449. package/dist/plugins/uproc/src/credentials.js +1 -1
  450. package/dist/plugins/uproc/src/index.js +1 -1
  451. package/dist/plugins/uptimerobot/src/credentials.js +1 -1
  452. package/dist/plugins/uptimerobot/src/index.js +1 -1
  453. package/dist/plugins/urlscanio/src/credentials.js +1 -1
  454. package/dist/plugins/urlscanio/src/index.js +1 -1
  455. package/dist/plugins/vercel/src/credentials.js +1 -1
  456. package/dist/plugins/vercel/src/deployments.js +1 -1
  457. package/dist/plugins/vercel/src/env.js +1 -1
  458. package/dist/plugins/vercel/src/projects.js +1 -1
  459. package/dist/plugins/vercel/src/shared.js +1 -2
  460. package/dist/plugins/vero/src/credentials.js +1 -1
  461. package/dist/plugins/vero/src/index.js +1 -1
  462. package/dist/plugins/vonage/src/credentials.js +1 -1
  463. package/dist/plugins/vonage/src/index.js +1 -1
  464. package/dist/plugins/wekan/src/credentials.js +1 -1
  465. package/dist/plugins/wekan/src/index.js +1 -1
  466. package/dist/plugins/wolt/src/account.js +1 -1
  467. package/dist/plugins/wolt/src/credentials.js +1 -1
  468. package/dist/plugins/wolt/src/index.js +1 -1
  469. package/dist/plugins/wolt/src/shared.js +1 -2
  470. package/dist/plugins/woocommerce/src/credentials.js +1 -1
  471. package/dist/plugins/woocommerce/src/index.js +1 -1
  472. package/dist/plugins/wordpress/src/credentials.js +1 -1
  473. package/dist/plugins/wordpress/src/index.js +1 -1
  474. package/dist/plugins/xai/src/credentials.js +1 -1
  475. package/dist/plugins/xai/src/index.js +2 -2
  476. package/dist/plugins/xero/src/credentials.js +1 -1
  477. package/dist/plugins/xero/src/index.js +1 -1
  478. package/dist/plugins/yourls/src/credentials.js +1 -1
  479. package/dist/plugins/yourls/src/index.js +1 -1
  480. package/dist/plugins/zammad/src/credentials.js +1 -1
  481. package/dist/plugins/zammad/src/index.js +1 -1
  482. package/dist/plugins/zendesk/src/credentials.js +1 -1
  483. package/dist/plugins/zendesk/src/index.js +1 -1
  484. package/dist/plugins/zoho/src/credentials.js +1 -1
  485. package/dist/plugins/zoho/src/index.js +1 -1
  486. package/dist/plugins/zoom/src/credentials.js +1 -1
  487. package/dist/plugins/zoom/src/index.js +1 -1
  488. package/dist/plugins/zulip/src/credentials.js +1 -1
  489. package/dist/plugins/zulip/src/index.js +1 -1
  490. package/package.json +4 -2
  491. package/dist/plugins/_shared/credentialAdapter.js +0 -152
  492. package/dist/tests/helpers/engine-harness.d.ts +0 -1
  493. package/dist/tests/helpers/engine-harness.js +0 -236
package/dist/index.js CHANGED
@@ -7,12 +7,17 @@ export { FileConnectionProvider } from "./connections/file.js";
7
7
  export { MemoryConnectionProvider } from "./connections/memory.js";
8
8
  export { ExecutionEngine } from "./core/engine.js";
9
9
  export { buildAuthUrl, exchangeAuthCode, generatePKCE, OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_URI, oauthCallback, runOAuth, } from "./core/oauth.js";
10
+ export { awsEndpoint, awsRegion, parseAwsXml } from "./credentials/aws.js";
11
+ export { awsCredential, awsFailed, awsJson, awsList, awsQuery, awsTarget, } from "./credentials/aws-plugin.js";
12
+ export { brokerFor } from "./credentials/broker.js";
10
13
  export { downloadResource } from "./credentials/http.js";
11
- export { CredentialRegistry, OAuthGrantSchema, OAuthTokensSchema, staticSecretSchema, validateCredential, } from "./credentials/registry.js";
14
+ export { answerFailed, configChoice, configFlag, credentialJson, credentialOk, credentialRequest, credentialSocketUrl, errorIdentifier, failureMessage, grantSchema, graphqlFailed, hostLabel, httpsBase, jsonAnswer, jsonOrAcknowledged, multipartBody, pathSegment, pathSegments, pathWithin, refuseUnderHost, requestFailed, responseFailed, slashEncodedSegment, staticCredential, } from "./credentials/plugin.js";
15
+ export { AwsAccessKeySchema, AwsSessionSchema, CredentialRegistry, OAuthGrantSchema, OAuthTokensSchema, staticSecretSchema, validateCredential, } from "./credentials/registry.js";
12
16
  export { CredentialTransport } from "./credentials/transport.js";
13
17
  export { createPluginAPI, isPluginFunction, resolvePluginExport, } from "./plugin/api.js";
14
18
  export { installPlugin, listInstalled, parsePluginSource, removePlugin, } from "./plugin/installer.js";
15
19
  export { discoverPlugins, loadAllPlugins, loadPluginFromPath, loadPluginsFromConfig, } from "./plugin/loader.js";
16
20
  export { PluginRegistry, registry } from "./plugin/registry.js";
21
+ export { connectionFields } from "./plugin/schema.js";
17
22
  export { Runline } from "./sdk.js";
18
23
  export { commandExists, syncExec } from "./utils/cli.js";
@@ -16,13 +16,25 @@ export declare function connectionFields(schema: ConnectionSchema | undefined):
16
16
  export declare function helpInputs(schema: InputSchema | undefined): Record<string, HelpInput>;
17
17
  export declare function validateLegacyInput(schema: LegacyInputSchema, input: unknown): ValidationResult;
18
18
  /**
19
- * A call written with no arguments is a call with an empty argument set.
19
+ * A value as JSON would carry it: plain-object keys whose value is
20
+ * `undefined` are dropped, at every depth. JSON has no `undefined`, and a
21
+ * schema's `required` counts a present key as given, so `{ name: undefined }`
22
+ * would otherwise satisfy a rule that needs a name. Arrays keep their
23
+ * length; other objects (a Buffer, a Date) pass through untouched.
20
24
  *
25
+ * Self-contained, because the worker's `actions.check` runs this same
26
+ * source: preflight and execution cannot disagree about what was passed.
27
+ */
28
+ export declare function dropUndefined(value: unknown): unknown;
29
+ /**
30
+ * An action's arguments as validation and `execute` see them.
31
+ *
32
+ * A call written with no arguments is a call with an empty argument set:
21
33
  * `linear.user.me()` supplies no argument, so object validation needs an
22
34
  * empty object to accept no-input actions and name missing required fields.
23
- *
24
- * Only `undefined` is normalized: an explicit `null` or `42` is an
25
- * argument, and a wrong one.
35
+ * An explicit `null` or `42` is an argument, and a wrong one. Keys holding
36
+ * `undefined` are absent, by `dropUndefined`. The worker's `actions.check`
37
+ * runs this source too, so it may call nothing but `dropUndefined`.
26
38
  */
27
39
  export declare function normalizeActionInput(input: unknown): unknown;
28
40
  export declare function validateTypedInput(schema: TypedInputSchema, rawInput: unknown): ValidationResult;
@@ -187,16 +187,39 @@ export function validateLegacyInput(schema, input) {
187
187
  return validationResult({ missing, unknown, typeErrors });
188
188
  }
189
189
  /**
190
- * A call written with no arguments is a call with an empty argument set.
190
+ * A value as JSON would carry it: plain-object keys whose value is
191
+ * `undefined` are dropped, at every depth. JSON has no `undefined`, and a
192
+ * schema's `required` counts a present key as given, so `{ name: undefined }`
193
+ * would otherwise satisfy a rule that needs a name. Arrays keep their
194
+ * length; other objects (a Buffer, a Date) pass through untouched.
191
195
  *
196
+ * Self-contained, because the worker's `actions.check` runs this same
197
+ * source: preflight and execution cannot disagree about what was passed.
198
+ */
199
+ export function dropUndefined(value) {
200
+ if (Array.isArray(value))
201
+ return value.map((entry) => dropUndefined(entry));
202
+ if (value === null || typeof value !== "object")
203
+ return value;
204
+ const prototype = Object.getPrototypeOf(value);
205
+ if (prototype !== Object.prototype && prototype !== null)
206
+ return value;
207
+ return Object.fromEntries(Object.entries(value)
208
+ .filter(([, entry]) => entry !== undefined)
209
+ .map(([key, entry]) => [key, dropUndefined(entry)]));
210
+ }
211
+ /**
212
+ * An action's arguments as validation and `execute` see them.
213
+ *
214
+ * A call written with no arguments is a call with an empty argument set:
192
215
  * `linear.user.me()` supplies no argument, so object validation needs an
193
216
  * empty object to accept no-input actions and name missing required fields.
194
- *
195
- * Only `undefined` is normalized: an explicit `null` or `42` is an
196
- * argument, and a wrong one.
217
+ * An explicit `null` or `42` is an argument, and a wrong one. Keys holding
218
+ * `undefined` are absent, by `dropUndefined`. The worker's `actions.check`
219
+ * runs this source too, so it may call nothing but `dropUndefined`.
197
220
  */
198
221
  export function normalizeActionInput(input) {
199
- return input === undefined ? {} : input;
222
+ return input === undefined ? {} : dropUndefined(input);
200
223
  }
201
224
  export function validateTypedInput(schema, rawInput) {
202
225
  const input = normalizeActionInput(rawInput);
@@ -108,6 +108,14 @@ export type OAuthConfig = OAuthSetupOptions & ({
108
108
  interface OAuthSetupOptions {
109
109
  /** Scopes to request on the consent screen. */
110
110
  scopes: string[];
111
+ /**
112
+ * The grant this plugin's consent belongs to, shared by every plugin
113
+ * declaring the same id (`google`, `microsoft`): one provider, one OAuth
114
+ * client, one person's consent. A host may hold one connection for the
115
+ * whole grant and ask for the union of its plugins' scopes. The plugin's
116
+ * credential declares the same id, so its tokens are the grant's.
117
+ */
118
+ grant?: string;
111
119
  /**
112
120
  * Provider-fixed loopback callback (`http://localhost:<port>/<path>`),
113
121
  * replacing Runline's default `http://127.0.0.1:47823/callback`. Use only
@@ -0,0 +1,30 @@
1
+ import * as t from "typebox";
2
+ /**
3
+ * Caller-supplied base64 in the standard padded alphabet: whitespace
4
+ * dropped, base64url's `-` and `_` mapped to `+` and `/`, padding
5
+ * restored. So a gmail.message.getAttachment result (base64url, unpadded)
6
+ * and a googleDrive download (standard) are equally accepted. Undefined
7
+ * when the value is not base64: a character outside both alphabets,
8
+ * padding anywhere but the end, or a length no encoding produces.
9
+ *
10
+ * Flat character-class patterns only: values run to many megabytes.
11
+ */
12
+ export function standardBase64(value) {
13
+ const compact = value.replace(/\s+/g, "").replace(/={1,2}$/, "");
14
+ if (!/^[A-Za-z0-9+/_-]*$/.test(compact) || compact.length % 4 === 1)
15
+ return undefined;
16
+ const standard = compact.replace(/-/g, "+").replace(/_/g, "/");
17
+ return standard.padEnd(Math.ceil(standard.length / 4) * 4, "=");
18
+ }
19
+ /**
20
+ * A googleDrive.file.download result, accepted wherever attachment bytes
21
+ * are: exactly its fields, so the result passes through unedited while
22
+ * anything else is still refused. Its `name` and `mimeType` stand in for
23
+ * an attachment's own when those are left out.
24
+ */
25
+ export const DownloadedFile = t.Object({
26
+ contentBase64: t.String(),
27
+ name: t.Optional(t.String()),
28
+ mimeType: t.Optional(t.String()),
29
+ size: t.Optional(t.Integer({ minimum: 0 })),
30
+ }, { additionalProperties: false });
@@ -1,8 +1,67 @@
1
- import { AuthError, downloadResource, } from "runline";
2
- import { credentialBroker } from "./credentialAdapter.js";
3
- import { jsonAnswer, requestFailed } from "./credentials.js";
4
- import { googleCredential, googleResources } from "./googleCredentials.js";
1
+ import { AuthError, brokerFor, downloadResource, jsonAnswer, requestFailed, } from "runline";
2
+ import { GOOGLE_GRANT, GOOGLE_TOKEN_URL, googleCredential, googleResources, googleServices, } from "./googleCredentials.js";
5
3
  export { googleCredential } from "./googleCredentials.js";
4
+ /**
5
+ * A Google plugin's OAuth declaration: Google's endpoints, the offline
6
+ * consent that returns a refresh token (without `access_type=offline` and
7
+ * `prompt=consent` a repeat login omits it), the grant every Google plugin
8
+ * shares, and setup steps that enable the APIs its targets call and name
9
+ * its client variables (`env`: `GMAIL` → `GMAIL_CLIENT_ID`).
10
+ */
11
+ export function googleOAuth(plugin, scopes, env) {
12
+ return {
13
+ grant: GOOGLE_GRANT,
14
+ authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
15
+ tokenUrl: GOOGLE_TOKEN_URL,
16
+ scopes,
17
+ authParams: { access_type: "offline", prompt: "consent" },
18
+ setupHelp: [
19
+ "You need a Google Cloud OAuth client. Takes ~5 minutes, one time;",
20
+ "the same client serves every Google plugin.",
21
+ "Do the steps in order — skipping step 4 causes a 403 when you log in.",
22
+ "",
23
+ "1. Create a Google Cloud project (or pick an existing one):",
24
+ " https://console.cloud.google.com/projectcreate",
25
+ " Make sure the project is selected in the top navigation dropdown.",
26
+ "",
27
+ "2. Enable the APIs this plugin calls (click 'Enable' on each):",
28
+ ...googleServices(plugin).map((service) => ` https://console.cloud.google.com/apis/library/${service}`),
29
+ "",
30
+ "3. Configure the OAuth consent screen (first time only):",
31
+ " https://console.cloud.google.com/apis/credentials/consent",
32
+ " Click 'Get started' and fill in:",
33
+ " • App name: runline (or whatever)",
34
+ " • User support email: your email",
35
+ " • Audience: External",
36
+ " • Developer contact: your email",
37
+ " You can skip the Scopes screen — runline declares scopes at auth time.",
38
+ "",
39
+ "4. Add yourself as a test user (required — External apps in Testing mode",
40
+ " only allow authentication from addresses on this list):",
41
+ " https://console.cloud.google.com/auth/audience",
42
+ " Under 'Test users', click '+ Add users' and enter the Google address",
43
+ " you'll use to log in. Consent and refresh tokens expire every 7 days",
44
+ " while the app is in Testing mode.",
45
+ "",
46
+ "5. Create the OAuth client:",
47
+ " https://console.cloud.google.com/apis/credentials",
48
+ " • + Create credentials → OAuth client ID",
49
+ " • Application type: Web application",
50
+ " • Name: runline (or whatever)",
51
+ " • Authorized redirect URIs → + Add URI:",
52
+ " {{redirectUri}}",
53
+ " • Click Create, then copy the Client ID and Client Secret from the",
54
+ " dialog — the secret is only shown once.",
55
+ "",
56
+ "6. Paste them below (or re-run with --client-id / --client-secret,",
57
+ ` or export ${env}_CLIENT_ID and ${env}_CLIENT_SECRET).`,
58
+ "",
59
+ "During login you'll see a 'Google hasn't verified this app' warning.",
60
+ "Click 'Advanced → Go to runline (unsafe)' to continue — this is",
61
+ "expected for apps in Testing mode.",
62
+ ],
63
+ };
64
+ }
6
65
  /** Translate builtin absolute URLs at one boundary; validate the raw path before URL normalization. */
7
66
  export async function googleResponse(ctx, plugin, scopes, url, init = {}, query) {
8
67
  const resources = googleResources(plugin);
@@ -23,7 +82,7 @@ export async function googleResponse(ctx, plugin, scopes, url, init = {}, query)
23
82
  }
24
83
  path = `${separator < 0 ? path : path.slice(0, separator)}?${params}`;
25
84
  }
26
- return credentialBroker(ctx, googleCredential(plugin, scopes)).request({
85
+ return brokerFor(ctx, googleCredential(plugin, scopes)).request({
27
86
  target,
28
87
  path,
29
88
  method: (init.method ?? "GET"),
@@ -46,7 +105,7 @@ export async function googleJsonRequest(ctx, plugin, scopes, method, url, body,
46
105
  return jsonAnswer(response);
47
106
  }
48
107
  export async function googleProbe(ctx, plugin, scopes) {
49
- return credentialBroker(ctx, googleCredential(plugin, scopes)).probe();
108
+ return brokerFor(ctx, googleCredential(plugin, scopes)).probe();
50
109
  }
51
110
  /** Only Google-issued thumbnail hosts; never attach credentials to signed URLs. */
52
111
  export async function googleDownload(value) {
@@ -1,5 +1,11 @@
1
- import { AuthError, } from "runline";
2
- import { grantSchema } from "./credentials.js";
1
+ import { AuthError, grantSchema, } from "runline";
2
+ /** The grant every Google plugin's consent belongs to. */
3
+ export const GOOGLE_GRANT = "google";
4
+ /**
5
+ * Google's fixed token endpoint: a JSON credential's token_uri never
6
+ * selects egress.
7
+ */
8
+ export const GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
3
9
  /** Only legacy storage infers a method; host bindings always select it explicitly. */
4
10
  export function googleMethod(cfg) {
5
11
  if (cfg.authMethod !== undefined) {
@@ -51,6 +57,19 @@ const API_BASES = {
51
57
  calendar: "https://www.googleapis.com/calendar/v3/",
52
58
  gmail: "https://gmail.googleapis.com/gmail/v1/users/me/",
53
59
  };
60
+ /** The Cloud Console service each API base belongs to, to enable it by. */
61
+ const API_SERVICES = {
62
+ drive: "drive.googleapis.com",
63
+ upload: "drive.googleapis.com",
64
+ docs: "docs.googleapis.com",
65
+ sheets: "sheets.googleapis.com",
66
+ slides: "slides.googleapis.com",
67
+ script: "script.googleapis.com",
68
+ tasks: "tasks.googleapis.com",
69
+ people: "people.googleapis.com",
70
+ calendar: "calendar-json.googleapis.com",
71
+ gmail: "gmail.googleapis.com",
72
+ };
54
73
  const PLUGIN_TARGETS = {
55
74
  googleDrive: ["drive", "upload", "docs"],
56
75
  googleDocs: ["docs", "drive"],
@@ -62,11 +81,19 @@ const PLUGIN_TARGETS = {
62
81
  googleCalendar: ["calendar"],
63
82
  gmail: ["gmail"],
64
83
  };
65
- /** Builtin routing policy, never derived from action input or a returned URL. */
66
- export function googleResources(plugin) {
84
+ /** The API bases a builtin Google plugin calls; any other name is refused. */
85
+ function targetNames(plugin) {
67
86
  if (!Object.hasOwn(PLUGIN_TARGETS, plugin))
68
87
  throw new AuthError("request_not_allowed");
69
- const names = PLUGIN_TARGETS[plugin];
88
+ return PLUGIN_TARGETS[plugin];
89
+ }
90
+ /** The Cloud Console services a plugin calls, each to be enabled once. */
91
+ export function googleServices(plugin) {
92
+ return [...new Set(targetNames(plugin).map((name) => API_SERVICES[name]))];
93
+ }
94
+ /** Builtin routing policy, never derived from action input or a returned URL. */
95
+ export function googleResources(plugin) {
96
+ const names = targetNames(plugin);
70
97
  const targets = Object.fromEntries(names.map((name) => [
71
98
  name,
72
99
  {
@@ -134,9 +161,7 @@ export function googleCredential(plugin, scopes) {
134
161
  };
135
162
  };
136
163
  }
137
- /** Fixed vendor endpoints; a JSON credential's token_uri can never select egress. */
138
164
  export function googleCredentialType(scopes, plugin) {
139
- const url = "https://oauth2.googleapis.com/token";
140
165
  const { targets, probe } = googleResources(plugin);
141
166
  return {
142
167
  id: "google.oauth",
@@ -147,10 +172,14 @@ export function googleCredentialType(scopes, plugin) {
147
172
  kind: "oauth2",
148
173
  field: "grant",
149
174
  renewal: "refresh",
175
+ grant: GOOGLE_GRANT,
150
176
  definition: {
151
177
  id: "google.oauth",
152
178
  provider: "google",
153
- refresh: { url, clientAuthentication: "client_secret_post" },
179
+ refresh: {
180
+ url: GOOGLE_TOKEN_URL,
181
+ clientAuthentication: "client_secret_post",
182
+ },
154
183
  },
155
184
  },
156
185
  targets,
@@ -168,7 +197,10 @@ export function googleCredentialType(scopes, plugin) {
168
197
  definition: {
169
198
  id: "google.serviceAccount",
170
199
  provider: "google",
171
- jwtBearer: { url, clientAuthentication: "none" },
200
+ jwtBearer: {
201
+ url: GOOGLE_TOKEN_URL,
202
+ clientAuthentication: "none",
203
+ },
172
204
  },
173
205
  },
174
206
  targets,
@@ -0,0 +1,40 @@
1
+ import { constants } from "node:fs";
2
+ import { open } from "node:fs/promises";
3
+ /**
4
+ * A file on the runline host that an action input names — an attachment,
5
+ * an upload, an image to edit — read as one bounded buffer. It must be a
6
+ * regular file: the nonblocking open lets fstat refuse a FIFO or device
7
+ * without waiting on a writer. The size is checked before allocation and
8
+ * the bytes are read through the same handle, so a file swapped or grown
9
+ * between the check and the read cannot slip past the bound.
10
+ */
11
+ export async function readLocalFile(path, options) {
12
+ const { subject } = options;
13
+ let file;
14
+ try {
15
+ file = await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
16
+ }
17
+ catch (error) {
18
+ const code = error.code;
19
+ throw new Error(`${subject} is unreadable${typeof code === "string" ? ` (${code})` : ""}`);
20
+ }
21
+ try {
22
+ const stat = await file.stat();
23
+ if (!stat.isFile())
24
+ throw new Error(`${subject} must be a regular file`);
25
+ if (stat.size > options.maxBytes)
26
+ throw new Error(options.oversize);
27
+ const bytes = Buffer.alloc(stat.size);
28
+ let offset = 0;
29
+ while (offset < bytes.length) {
30
+ const { bytesRead } = await file.read(bytes, offset, bytes.length - offset, offset);
31
+ if (!bytesRead)
32
+ throw new Error(`${subject} changed while reading`);
33
+ offset += bytesRead;
34
+ }
35
+ return bytes;
36
+ }
37
+ finally {
38
+ await file.close();
39
+ }
40
+ }
@@ -9,9 +9,10 @@
9
9
  * available (same pattern as googleDrive/googleSlides).
10
10
  */
11
11
  import { randomUUID } from "node:crypto";
12
- import { readFileSync, writeFileSync } from "node:fs";
12
+ import { writeFileSync } from "node:fs";
13
13
  import { tmpdir } from "node:os";
14
14
  import { basename, extname, join } from "node:path";
15
+ import { readLocalFile } from "./localFile.js";
15
16
  const MIME_EXT = {
16
17
  "image/png": "png",
17
18
  "image/jpeg": "jpg",
@@ -56,7 +57,10 @@ export function writeMediaFile(opts) {
56
57
  */
57
58
  export function writeImageFile(opts) {
58
59
  const { base64, ...rest } = opts;
59
- return writeMediaFile({ ...rest, bytes: Buffer.from(base64 ?? "", "base64") });
60
+ return writeMediaFile({
61
+ ...rest,
62
+ bytes: Buffer.from(base64 ?? "", "base64"),
63
+ });
60
64
  }
61
65
  export const SEND_FILE_NOTE = "File(s) written to disk. Deliver each to the user with send_file using its `path`.";
62
66
  const EXT_MIME = {
@@ -66,23 +70,22 @@ const EXT_MIME = {
66
70
  webp: "image/webp",
67
71
  gif: "image/gif",
68
72
  };
73
+ /** Larger than any provider accepts inline; a data URI past it only fails remotely. */
74
+ const MAX_IMAGE_BYTES = 50 * 1024 * 1024;
69
75
  /**
70
76
  * Read a local image for an `image.edit` call: bytes + base64 + mime
71
- * (from the extension) + a `data:` URI for JSON APIs. Throws with the
72
- * plugin's name when the file can't be read so errors point at the
73
- * right tool.
77
+ * (from the extension) + a `data:` URI for JSON APIs. Errors carry the
78
+ * plugin's name so they point at the right tool.
74
79
  */
75
- export function readImageInput(imagePath, pluginName) {
80
+ export async function readImageInput(imagePath, pluginName) {
76
81
  if (typeof imagePath !== "string" || imagePath.trim().length === 0) {
77
82
  throw new Error(`${pluginName}: imagePath is required`);
78
83
  }
79
- let bytes;
80
- try {
81
- bytes = readFileSync(imagePath);
82
- }
83
- catch (err) {
84
- throw new Error(`${pluginName}: cannot read image at ${imagePath} — ${err instanceof Error ? err.message : String(err)}`);
85
- }
84
+ const bytes = await readLocalFile(imagePath, {
85
+ subject: `${pluginName}: imagePath`,
86
+ maxBytes: MAX_IMAGE_BYTES,
87
+ oversize: `${pluginName}: imagePath exceeds ${MAX_IMAGE_BYTES / (1024 * 1024)} MiB`,
88
+ });
86
89
  const ext = extname(imagePath).slice(1).toLowerCase();
87
90
  const mimeType = EXT_MIME[ext] ?? "image/png";
88
91
  const base64 = bytes.toString("base64");
@@ -1,18 +1,16 @@
1
- import { AuthError, downloadResource, } from "runline";
2
- import { credentialBroker } from "./credentialAdapter.js";
3
- import { jsonAnswer, requestFailed } from "./credentials.js";
4
- import { microsoftCredential, microsoftUserBase, } from "./microsoftCredentials.js";
1
+ import { AuthError, brokerFor, downloadResource, jsonAnswer, requestFailed, } from "runline";
2
+ import { MICROSOFT_GRANT, microsoftCredential, microsoftEndpoint, microsoftUserBase, } from "./microsoftCredentials.js";
5
3
  export { microsoftCredential, microsoftDriveBase, } from "./microsoftCredentials.js";
6
4
  export function userBase(ctx) {
7
5
  return microsoftUserBase(ctx.connection.config);
8
6
  }
9
7
  export async function microsoftProbe(ctx, plugin, scopes) {
10
- return credentialBroker(ctx, microsoftCredential(plugin, scopes)).probe();
8
+ return brokerFor(ctx, microsoftCredential(plugin, scopes)).probe();
11
9
  }
12
10
  export async function graphResponse(ctx, plugin, scopes, method, path, body, contentType) {
13
11
  if (!path.startsWith("/") || path.startsWith("//"))
14
12
  throw new AuthError("request_not_allowed");
15
- return credentialBroker(ctx, microsoftCredential(plugin, scopes)).request({
13
+ return brokerFor(ctx, microsoftCredential(plugin, scopes)).request({
16
14
  target: "graph",
17
15
  path: path.slice(1),
18
16
  method: method,
@@ -59,8 +57,23 @@ export async function microsoftDownload(value) {
59
57
  fetch: globalThis.fetch,
60
58
  });
61
59
  }
62
- /** Setup help shown by the OAuth wizard for all Microsoft plugins. */
63
- export function microsoftSetupHelp(apiName) {
60
+ /**
61
+ * A Microsoft Graph plugin's OAuth declaration: the multi-tenant endpoints,
62
+ * `offline_access` for a refresh token, the grant every Graph plugin
63
+ * shares, and setup steps naming the Graph permissions it needs
64
+ * (`permissions`, e.g. "Calendars.Read").
65
+ */
66
+ export function microsoftOAuth(scopes, permissions) {
67
+ return {
68
+ grant: MICROSOFT_GRANT,
69
+ authUrl: microsoftEndpoint("common", "authorize"),
70
+ tokenUrl: microsoftEndpoint("common", "token"),
71
+ scopes: [...scopes, "offline_access"],
72
+ setupHelp: setupHelp(permissions),
73
+ };
74
+ }
75
+ /** The OAuth wizard's steps for a Microsoft plugin. */
76
+ function setupHelp(permissions) {
64
77
  return [
65
78
  `You need a Microsoft Entra (Azure AD) app registration. One-time, ~5 minutes.`,
66
79
  "",
@@ -69,7 +82,7 @@ export function microsoftSetupHelp(apiName) {
69
82
  "2. Add a Web redirect URI (Authentication → Add platform → Web):",
70
83
  " {{redirectUri}}",
71
84
  "3. Certificates & secrets → New client secret → copy the VALUE (not the Secret ID).",
72
- `4. API permissions → Add → Microsoft Graph → Delegated → add the ${apiName} scopes,`,
85
+ `4. API permissions → Add → Microsoft Graph → Delegated → add the ${permissions} scopes,`,
73
86
  " then 'Grant admin consent'.",
74
87
  "5. Paste the Application (client) ID and the client secret VALUE below.",
75
88
  ];
@@ -1,5 +1,12 @@
1
- import { AuthError, } from "runline";
2
- import { grantSchema, pathSegment } from "./credentials.js";
1
+ import { AuthError, grantSchema, pathSegment, } from "runline";
2
+ /** The grant every Microsoft Graph plugin's delegated consent belongs to. */
3
+ export const MICROSOFT_GRANT = "microsoft";
4
+ /** A tenant's OAuth endpoint on the Microsoft identity platform. */
5
+ export function microsoftEndpoint(tenant, leg) {
6
+ if (!/^[a-zA-Z0-9.-]+$/.test(tenant))
7
+ throw new AuthError("invalid_credentials");
8
+ return `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/${leg}`;
9
+ }
3
10
  /** Compatibility inference is confined to legacy configs without an explicit method. */
4
11
  export function microsoftMethod(cfg) {
5
12
  if (cfg.authMethod !== undefined) {
@@ -50,11 +57,8 @@ export function microsoftCredential(plugin, scopes) {
50
57
  }
51
58
  /** Scope-appropriate probes never require User.Read merely to check mail/calendar/files. */
52
59
  export function microsoftCredentialType(cfg, plugin, scopes) {
53
- const tenant = cfg.tenantId || "common";
54
- if (!/^[a-zA-Z0-9.-]+$/.test(tenant))
55
- throw new AuthError("invalid_credentials");
56
60
  const endpoint = {
57
- url: `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token`,
61
+ url: microsoftEndpoint(cfg.tenantId || "common", "token"),
58
62
  clientAuthentication: "client_secret_post",
59
63
  };
60
64
  const methods = Object.fromEntries(["delegated", "appOnly"].map((method) => {
@@ -85,9 +89,9 @@ export function microsoftCredentialType(cfg, plugin, scopes) {
85
89
  authentication: {
86
90
  kind: "oauth2",
87
91
  field: "grant",
88
- renewal: method === "delegated"
89
- ? "refresh"
90
- : "clientCredentials",
92
+ ...(method === "delegated"
93
+ ? { renewal: "refresh", grant: MICROSOFT_GRANT }
94
+ : { renewal: "clientCredentials" }),
91
95
  definition: {
92
96
  id: "microsoft.oauth",
93
97
  provider: "microsoft",
@@ -1,6 +1,5 @@
1
+ import { errorIdentifier, responseFailed } from "runline";
1
2
  import * as t from "typebox";
2
- import { errorIdentifier, failureMessage } from "./credentials.js";
3
- export { pathSegment } from "./credentials.js";
4
3
  export const STRICT_OBJECT = { additionalProperties: false };
5
4
  export const STRICT_UPDATE_OBJECT = {
6
5
  additionalProperties: false,
@@ -33,21 +32,17 @@ export function baseUrl() {
33
32
  * A failed response, read as a Shift error envelope when it is one: the
34
33
  * service's `code` (else its `type`) and the offending `param`.
35
34
  */
36
- export async function shiftError(plugin, response) {
37
- let code;
38
- let param;
39
- try {
40
- const error = (await response.json()).error;
41
- if (typeof error === "string")
42
- code = errorIdentifier(error);
43
- else if (error && typeof error === "object") {
44
- const shaped = error;
45
- code = errorIdentifier(shaped.code) ?? errorIdentifier(shaped.type);
46
- param = errorIdentifier(shaped.param);
47
- }
48
- }
49
- catch {
50
- // Not an error envelope: the status alone.
51
- }
52
- return new Error(failureMessage(plugin, response.status, { code, param }));
35
+ export function shiftError(plugin, response) {
36
+ return responseFailed(plugin, response, (body) => {
37
+ const error = body && typeof body === "object"
38
+ ? body.error
39
+ : undefined;
40
+ if (!error || typeof error !== "object")
41
+ return { code: error };
42
+ const shaped = error;
43
+ return {
44
+ code: errorIdentifier(shaped.code) ?? shaped.type,
45
+ param: shaped.param,
46
+ };
47
+ });
53
48
  }
@@ -1,5 +1,4 @@
1
- import { AuthError, } from "runline";
2
- import { credentialRequest, staticCredential } from "./credentials.js";
1
+ import { AuthError, credentialRequest, staticCredential, } from "runline";
3
2
  import { SHIFT_API_URL, shiftError } from "./shiftCloud.js";
4
3
  /**
5
4
  * The Shift family (shiftAtlas, shiftBwm, shiftCrm, shiftObjects,
@@ -1,6 +1,7 @@
1
1
  import { openAsBlob } from "node:fs";
2
- import { readFile, stat } from "node:fs/promises";
2
+ import { stat } from "node:fs/promises";
3
3
  import { extname } from "node:path";
4
+ import { readLocalFile } from "./localFile.js";
4
5
  /**
5
6
  * The Shift cloud signed-grant upload arc, shared by every plugin that
6
7
  * moves local file bytes into the cloud (shiftTranscription assets,
@@ -10,8 +11,8 @@ import { extname } from "node:path";
10
11
  * live here once: the openAsBlob streaming fallback, grant-header
11
12
  * merging, and the size ceilings.
12
13
  *
13
- * shiftOcr deliberately does not use this arc — it inlines small files
14
- * as base64 data URLs instead of uploading through a grant.
14
+ * shiftOcr inlines small files as base64 data URLs and takes this arc
15
+ * only for files too large to inline.
15
16
  */
16
17
  /** Mirrors the public service contracts' 5 GiB upload ceiling. */
17
18
  export const SIGNED_UPLOAD_MAX_BYTES = 5 * 1024 * 1024 * 1024;
@@ -87,22 +88,25 @@ export async function statUploadFile(path, maxBytes, label = "File") {
87
88
  }
88
89
  return file.size;
89
90
  }
90
- async function fileBody(path, sizeBytes) {
91
+ async function fileBody(path) {
91
92
  try {
92
93
  return await openAsBlob(path);
93
94
  }
94
95
  catch {
95
- if (sizeBytes > MAX_BUFFERED_BYTES) {
96
- throw new Error("This runtime cannot stream uploads and the file is too large to buffer.");
97
- }
98
- return new Blob([await readFile(path)]);
96
+ return new Blob([
97
+ await readLocalFile(path, {
98
+ subject: "File",
99
+ maxBytes: MAX_BUFFERED_BYTES,
100
+ oversize: "This runtime cannot stream uploads and the file is too large to buffer.",
101
+ }),
102
+ ]);
99
103
  }
100
104
  }
101
105
  /**
102
106
  * PUT a local file's bytes to a signed grant. Grant headers win;
103
107
  * content-type is filled in only when the grant leaves it unset.
104
108
  */
105
- export async function putThroughGrant(grant, path, contentType, sizeBytes, label = "Upload") {
109
+ export async function putThroughGrant(grant, path, contentType, label = "Upload") {
106
110
  const headers = new Headers(grant.headers);
107
111
  if (!headers.has("content-type")) {
108
112
  headers.set("content-type", contentType);
@@ -110,7 +114,7 @@ export async function putThroughGrant(grant, path, contentType, sizeBytes, label
110
114
  const response = await fetch(grant.url, {
111
115
  method: grant.method,
112
116
  headers,
113
- body: await fileBody(path, sizeBytes),
117
+ body: await fileBody(path),
114
118
  });
115
119
  if (!response.ok) {
116
120
  throw new Error(`${label} failed: HTTP ${response.status}`);
@@ -1,4 +1,4 @@
1
- import { staticCredential } from "../../_shared/credentials.js";
1
+ import { staticCredential } from "runline";
2
2
  /** An OSDI API token, sent as the OSDI-API-Token header to Action Network's
3
3
  * one API origin. */
4
4
  export const actionNetworkCredential = staticCredential({