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
@@ -1,5 +1,12 @@
1
- import { AuthError, OAuthGrantSchema, } from "runline";
2
- import * as t from "typebox";
1
+ import { AuthError, } from "runline";
2
+ import { grantSchema } from "./credentials.js";
3
+ /** The grant every Google plugin's consent belongs to. */
4
+ export const GOOGLE_GRANT = "google";
5
+ /**
6
+ * Google's fixed token endpoint: a JSON credential's token_uri never
7
+ * selects egress.
8
+ */
9
+ export const GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
3
10
  /** Only legacy storage infers a method; host bindings always select it explicitly. */
4
11
  export function googleMethod(cfg) {
5
12
  if (cfg.authMethod !== undefined) {
@@ -51,6 +58,19 @@ const API_BASES = {
51
58
  calendar: "https://www.googleapis.com/calendar/v3/",
52
59
  gmail: "https://gmail.googleapis.com/gmail/v1/users/me/",
53
60
  };
61
+ /** The Cloud Console service each API base belongs to, to enable it by. */
62
+ const API_SERVICES = {
63
+ drive: "drive.googleapis.com",
64
+ upload: "drive.googleapis.com",
65
+ docs: "docs.googleapis.com",
66
+ sheets: "sheets.googleapis.com",
67
+ slides: "slides.googleapis.com",
68
+ script: "script.googleapis.com",
69
+ tasks: "tasks.googleapis.com",
70
+ people: "people.googleapis.com",
71
+ calendar: "calendar-json.googleapis.com",
72
+ gmail: "gmail.googleapis.com",
73
+ };
54
74
  const PLUGIN_TARGETS = {
55
75
  googleDrive: ["drive", "upload", "docs"],
56
76
  googleDocs: ["docs", "drive"],
@@ -62,11 +82,19 @@ const PLUGIN_TARGETS = {
62
82
  googleCalendar: ["calendar"],
63
83
  gmail: ["gmail"],
64
84
  };
65
- /** Builtin routing policy, never derived from action input or a returned URL. */
66
- export function googleResources(plugin) {
85
+ /** The API bases a builtin Google plugin calls; any other name is refused. */
86
+ function targetNames(plugin) {
67
87
  if (!Object.hasOwn(PLUGIN_TARGETS, plugin))
68
88
  throw new AuthError("request_not_allowed");
69
- const names = PLUGIN_TARGETS[plugin];
89
+ return PLUGIN_TARGETS[plugin];
90
+ }
91
+ /** The Cloud Console services a plugin calls, each to be enabled once. */
92
+ export function googleServices(plugin) {
93
+ return [...new Set(targetNames(plugin).map((name) => API_SERVICES[name]))];
94
+ }
95
+ /** Builtin routing policy, never derived from action input or a returned URL. */
96
+ export function googleResources(plugin) {
97
+ const names = targetNames(plugin);
70
98
  const targets = Object.fromEntries(names.map((name) => [
71
99
  name,
72
100
  {
@@ -112,24 +140,47 @@ export function googleResources(plugin) {
112
140
  : {}),
113
141
  };
114
142
  }
115
- /** Fixed vendor endpoints; a JSON credential's token_uri can never select egress. */
143
+ /**
144
+ * A Google plugin's credential declaration: its own targets and the scopes
145
+ * it signs service-account requests for, the method its config selects,
146
+ * and — for a service account — the JWT identity, subject included.
147
+ */
148
+ export function googleCredential(plugin, scopes) {
149
+ return (config) => {
150
+ const cfg = config;
151
+ const method = googleMethod(cfg);
152
+ return {
153
+ type: googleCredentialType(scopes, plugin),
154
+ method,
155
+ application: {
156
+ clientId: cfg.clientId,
157
+ clientSecret: cfg.clientSecret,
158
+ },
159
+ ...(method === "serviceAccount"
160
+ ? { jwtIdentity: googleIdentity(cfg) }
161
+ : {}),
162
+ };
163
+ };
164
+ }
116
165
  export function googleCredentialType(scopes, plugin) {
117
- const url = "https://oauth2.googleapis.com/token";
118
- const schema = t.Object({ grant: t.Optional(OAuthGrantSchema) }, { additionalProperties: false });
119
166
  const { targets, probe } = googleResources(plugin);
120
167
  return {
121
168
  id: "google.oauth",
122
169
  methods: {
123
170
  delegated: {
124
- schema,
171
+ schema: grantSchema,
125
172
  authentication: {
126
173
  kind: "oauth2",
127
- grantField: "grant",
174
+ field: "grant",
128
175
  renewal: "refresh",
176
+ grant: GOOGLE_GRANT,
129
177
  definition: {
130
178
  id: "google.oauth",
131
179
  provider: "google",
132
- refresh: { url, clientAuthentication: "client_secret_post" },
180
+ refresh: {
181
+ url: GOOGLE_TOKEN_URL,
182
+ clientAuthentication: "client_secret_post",
183
+ },
133
184
  },
134
185
  },
135
186
  targets,
@@ -138,16 +189,19 @@ export function googleCredentialType(scopes, plugin) {
138
189
  ...(scopes.length
139
190
  ? {
140
191
  serviceAccount: {
141
- schema,
192
+ schema: grantSchema,
142
193
  authentication: {
143
194
  kind: "oauth2",
144
- grantField: "grant",
195
+ field: "grant",
145
196
  renewal: "jwtBearer",
146
197
  scopes,
147
198
  definition: {
148
199
  id: "google.serviceAccount",
149
200
  provider: "google",
150
- jwtBearer: { url, clientAuthentication: "none" },
201
+ jwtBearer: {
202
+ url: GOOGLE_TOKEN_URL,
203
+ clientAuthentication: "none",
204
+ },
151
205
  },
152
206
  },
153
207
  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",
@@ -66,23 +67,22 @@ const EXT_MIME = {
66
67
  webp: "image/webp",
67
68
  gif: "image/gif",
68
69
  };
70
+ /** Larger than any provider accepts inline; a data URI past it only fails remotely. */
71
+ const MAX_IMAGE_BYTES = 50 * 1024 * 1024;
69
72
  /**
70
73
  * 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.
74
+ * (from the extension) + a `data:` URI for JSON APIs. Errors carry the
75
+ * plugin's name so they point at the right tool.
74
76
  */
75
- export function readImageInput(imagePath, pluginName) {
77
+ export async function readImageInput(imagePath, pluginName) {
76
78
  if (typeof imagePath !== "string" || imagePath.trim().length === 0) {
77
79
  throw new Error(`${pluginName}: imagePath is required`);
78
80
  }
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
- }
81
+ const bytes = await readLocalFile(imagePath, {
82
+ subject: `${pluginName}: imagePath`,
83
+ maxBytes: MAX_IMAGE_BYTES,
84
+ oversize: `${pluginName}: imagePath exceeds ${MAX_IMAGE_BYTES / (1024 * 1024)} MiB`,
85
+ });
86
86
  const ext = extname(imagePath).slice(1).toLowerCase();
87
87
  const mimeType = EXT_MIME[ext] ?? "image/png";
88
88
  const base64 = bytes.toString("base64");
@@ -1,45 +1,18 @@
1
1
  import { AuthError, downloadResource, } from "runline";
2
- import { credentialRuntime } from "./credentialAdapter.js";
3
- import { microsoftCredentialType, microsoftMethod, microsoftUserBase, } from "./microsoftCredentials.js";
4
- export { microsoftDriveBase } from "./microsoftCredentials.js";
5
- export function isAppOnly(cfg) {
6
- return microsoftMethod(cfg) === "appOnly";
7
- }
2
+ import { credentialBroker } from "./credentialAdapter.js";
3
+ import { jsonAnswer, requestFailed } from "./credentials.js";
4
+ import { MICROSOFT_GRANT, microsoftCredential, microsoftEndpoint, microsoftUserBase, } from "./microsoftCredentials.js";
5
+ export { microsoftCredential, microsoftDriveBase, } from "./microsoftCredentials.js";
8
6
  export function userBase(ctx) {
9
7
  return microsoftUserBase(ctx.connection.config);
10
8
  }
11
- function runtime(ctx, plugin, scopes) {
12
- const cfg = ctx.connection.config;
13
- const method = microsoftMethod(cfg);
14
- if (method === "appOnly" &&
15
- (!cfg.tenantId ||
16
- ["common", "organizations", "consumers"].includes(cfg.tenantId)))
17
- throw new AuthError("invalid_credentials");
18
- return credentialRuntime(ctx, microsoftCredentialType(cfg, plugin, scopes), method, (current) => {
19
- const c = current;
20
- return [
21
- microsoftMethod(c),
22
- c.tenantId,
23
- c.clientId,
24
- c.clientSecret,
25
- scopes,
26
- ];
27
- });
28
- }
29
- /** Compatibility token access uses the same grant runtime as resource requests. */
30
- export async function microsoftAccessToken(ctx, plugin, scopes) {
31
- const { binding, transport } = runtime(ctx, plugin, scopes);
32
- return transport.accessToken(binding);
33
- }
34
9
  export async function microsoftProbe(ctx, plugin, scopes) {
35
- const { binding, transport } = runtime(ctx, plugin, scopes);
36
- return transport.probe(binding);
10
+ return credentialBroker(ctx, microsoftCredential(plugin, scopes)).probe();
37
11
  }
38
12
  export async function graphResponse(ctx, plugin, scopes, method, path, body, contentType) {
39
13
  if (!path.startsWith("/") || path.startsWith("//"))
40
14
  throw new AuthError("request_not_allowed");
41
- const { binding, transport } = runtime(ctx, plugin, scopes);
42
- return transport.request(binding, {
15
+ return credentialBroker(ctx, microsoftCredential(plugin, scopes)).request({
43
16
  target: "graph",
44
17
  path: path.slice(1),
45
18
  method: method,
@@ -50,20 +23,16 @@ export async function graphResponse(ctx, plugin, scopes, method, path, body, con
50
23
  body,
51
24
  });
52
25
  }
53
- /** JSON and binary requests share the same destination, renewal and replay policy. */
26
+ /**
27
+ * A Graph JSON request that must succeed; its answer is read by
28
+ * `jsonAnswer`. JSON and binary requests share the same destination,
29
+ * renewal and replay policy through `graphResponse`.
30
+ */
54
31
  export async function graphRequest(ctx, plugin, scopes, method, path, body) {
55
32
  const res = await graphResponse(ctx, plugin, scopes, method, path, body === undefined ? undefined : JSON.stringify(body), body === undefined ? undefined : "application/json");
56
33
  if (!res.ok)
57
- throw new Error(`${plugin}: Graph request failed (HTTP ${res.status})`);
58
- if (res.status === 204)
59
- return { success: true };
60
- const text = await res.text();
61
- try {
62
- return text ? JSON.parse(text) : { success: true };
63
- }
64
- catch {
65
- throw new Error(`${plugin}: invalid Graph response`);
66
- }
34
+ throw requestFailed(plugin, res.status);
35
+ return jsonAnswer(res);
67
36
  }
68
37
  /** Graph-issued signed download URLs carry their own authority, never a bearer header. */
69
38
  export async function microsoftDownload(value) {
@@ -90,8 +59,23 @@ export async function microsoftDownload(value) {
90
59
  fetch: globalThis.fetch,
91
60
  });
92
61
  }
93
- /** Setup help shown by the OAuth wizard for all Microsoft plugins. */
94
- export function microsoftSetupHelp(apiName) {
62
+ /**
63
+ * A Microsoft Graph plugin's OAuth declaration: the multi-tenant endpoints,
64
+ * `offline_access` for a refresh token, the grant every Graph plugin
65
+ * shares, and setup steps naming the Graph permissions it needs
66
+ * (`permissions`, e.g. "Calendars.Read").
67
+ */
68
+ export function microsoftOAuth(scopes, permissions) {
69
+ return {
70
+ grant: MICROSOFT_GRANT,
71
+ authUrl: microsoftEndpoint("common", "authorize"),
72
+ tokenUrl: microsoftEndpoint("common", "token"),
73
+ scopes: [...scopes, "offline_access"],
74
+ setupHelp: setupHelp(permissions),
75
+ };
76
+ }
77
+ /** The OAuth wizard's steps for a Microsoft plugin. */
78
+ function setupHelp(permissions) {
95
79
  return [
96
80
  `You need a Microsoft Entra (Azure AD) app registration. One-time, ~5 minutes.`,
97
81
  "",
@@ -100,7 +84,7 @@ export function microsoftSetupHelp(apiName) {
100
84
  "2. Add a Web redirect URI (Authentication → Add platform → Web):",
101
85
  " {{redirectUri}}",
102
86
  "3. Certificates & secrets → New client secret → copy the VALUE (not the Secret ID).",
103
- `4. API permissions → Add → Microsoft Graph → Delegated → add the ${apiName} scopes,`,
87
+ `4. API permissions → Add → Microsoft Graph → Delegated → add the ${permissions} scopes,`,
104
88
  " then 'Grant admin consent'.",
105
89
  "5. Paste the Application (client) ID and the client secret VALUE below.",
106
90
  ];
@@ -1,5 +1,13 @@
1
- import { AuthError, OAuthGrantSchema, } from "runline";
2
- import * as t from "typebox";
1
+ import { AuthError, } from "runline";
2
+ import { grantSchema, pathSegment } from "./credentials.js";
3
+ /** The grant every Microsoft Graph plugin's delegated consent belongs to. */
4
+ export const MICROSOFT_GRANT = "microsoft";
5
+ /** A tenant's OAuth endpoint on the Microsoft identity platform. */
6
+ export function microsoftEndpoint(tenant, leg) {
7
+ if (!/^[a-zA-Z0-9.-]+$/.test(tenant))
8
+ throw new AuthError("invalid_credentials");
9
+ return `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/${leg}`;
10
+ }
3
11
  /** Compatibility inference is confined to legacy configs without an explicit method. */
4
12
  export function microsoftMethod(cfg) {
5
13
  if (cfg.authMethod !== undefined) {
@@ -16,25 +24,44 @@ export function microsoftUserBase(cfg) {
16
24
  return "/me";
17
25
  if (!cfg.userUpn)
18
26
  throw new AuthError("invalid_credentials");
19
- return `/users/${encodeURIComponent(cfg.userUpn)}`;
27
+ return `/users/${pathSegment(cfg.userUpn)}`;
20
28
  }
21
29
  export function microsoftDriveBase(cfg) {
22
30
  if (cfg.driveId)
23
- return `/drives/${encodeURIComponent(cfg.driveId)}`;
31
+ return `/drives/${pathSegment(cfg.driveId)}`;
24
32
  if (cfg.siteId)
25
- return `/sites/${encodeURIComponent(cfg.siteId)}/drive`;
33
+ return `/sites/${pathSegment(cfg.siteId)}/drive`;
26
34
  return `${microsoftUserBase(cfg)}/drive`;
27
35
  }
36
+ /**
37
+ * A Microsoft plugin's credential declaration. App-only signs for one
38
+ * tenant's directory, so a multi-tenant authority is refused here, where
39
+ * every signer reads it.
40
+ */
41
+ export function microsoftCredential(plugin, scopes) {
42
+ return (config) => {
43
+ const cfg = config;
44
+ const method = microsoftMethod(cfg);
45
+ if (method === "appOnly" &&
46
+ (!cfg.tenantId ||
47
+ ["common", "organizations", "consumers"].includes(cfg.tenantId)))
48
+ throw new AuthError("invalid_credentials");
49
+ return {
50
+ type: microsoftCredentialType(cfg, plugin, scopes),
51
+ method,
52
+ application: {
53
+ clientId: cfg.clientId,
54
+ clientSecret: cfg.clientSecret,
55
+ },
56
+ };
57
+ };
58
+ }
28
59
  /** Scope-appropriate probes never require User.Read merely to check mail/calendar/files. */
29
60
  export function microsoftCredentialType(cfg, plugin, scopes) {
30
- const tenant = cfg.tenantId || "common";
31
- if (!/^[a-zA-Z0-9.-]+$/.test(tenant))
32
- throw new AuthError("invalid_credentials");
33
61
  const endpoint = {
34
- url: `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token`,
62
+ url: microsoftEndpoint(cfg.tenantId || "common", "token"),
35
63
  clientAuthentication: "client_secret_post",
36
64
  };
37
- const schema = t.Object({ grant: t.Optional(OAuthGrantSchema) }, { additionalProperties: false });
38
65
  const methods = Object.fromEntries(["delegated", "appOnly"].map((method) => {
39
66
  let probe;
40
67
  const selected = { ...cfg, authMethod: method };
@@ -59,13 +86,13 @@ export function microsoftCredentialType(cfg, plugin, scopes) {
59
86
  return [
60
87
  method,
61
88
  {
62
- schema,
89
+ schema: grantSchema,
63
90
  authentication: {
64
91
  kind: "oauth2",
65
- grantField: "grant",
66
- renewal: method === "delegated"
67
- ? "refresh"
68
- : "clientCredentials",
92
+ field: "grant",
93
+ ...(method === "delegated"
94
+ ? { renewal: "refresh", grant: MICROSOFT_GRANT }
95
+ : { renewal: "clientCredentials" }),
69
96
  definition: {
70
97
  id: "microsoft.oauth",
71
98
  provider: "microsoft",
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Provider helpers: total readers for unshaped JSON, path-segment safety,
3
- * and bounded text or binary body reads.
2
+ * Provider helpers: total readers for unshaped JSON, and bounded text or
3
+ * binary body reads.
4
4
  *
5
5
  * The readers are total by design. These payloads are deep and change without
6
6
  * notice, so a missing or wrongly-typed field yields the empty value for its
@@ -34,18 +34,6 @@ export function numOrNull(value) {
34
34
  return null;
35
35
  }
36
36
  export const num = (value, fallback) => numOrNull(value) ?? fallback;
37
- /**
38
- * One path segment, escaped. Caller-supplied ids reach a URL carrying a bearer
39
- * token, so a segment that could climb out of its position is refused outright
40
- * rather than encoded and hoped about.
41
- */
42
- export function seg(value, what, plugin) {
43
- const raw = String(value ?? "").trim();
44
- if (!raw || raw === "." || raw === ".." || /[/\\?#]/.test(raw)) {
45
- throw new Error(`${plugin}: invalid ${what}`);
46
- }
47
- return encodeURIComponent(raw);
48
- }
49
37
  /**
50
38
  * Read a response body with a ceiling, so a hostile or broken endpoint cannot
51
39
  * make the process hold an unbounded string.
@@ -1,6 +1,6 @@
1
1
  import * as t from "typebox";
2
- import { authedFetch } from "./authedFetch.js";
3
- import { readBounded } from "./provider.js";
2
+ import { errorIdentifier, responseFailed } from "./credentials.js";
3
+ export { pathSegment } from "./credentials.js";
4
4
  export const STRICT_OBJECT = { additionalProperties: false };
5
5
  export const STRICT_UPDATE_OBJECT = {
6
6
  additionalProperties: false,
@@ -29,61 +29,21 @@ export const SHIFT_API_URL = "https://cloud.shift-labs.ai";
29
29
  export function baseUrl() {
30
30
  return `${SHIFT_API_URL}/`;
31
31
  }
32
- /** Default deadline; endpoints that hold the request open pass their own. */
33
- export const SHIFT_REQUEST_TIMEOUT_MS = 60_000;
34
- const MAX_RESPONSE_BYTES = 16 * 1024 * 1024;
35
32
  /**
36
- * The transport for every request carrying a Shift API key. Redirects are
37
- * refused so the key never reaches another host; one deadline covers the
38
- * whole exchange including the body, in place of any caller signal; the
39
- * text body is read with a ceiling and returned buffered, so JSON and text
40
- * callers consume it as usual.
33
+ * A failed response, read as a Shift error envelope when it is one: the
34
+ * service's `code` (else its `type`) and the offending `param`.
41
35
  */
42
- export async function shiftFetch(input, init = {}, timeoutMs = SHIFT_REQUEST_TIMEOUT_MS) {
43
- const response = await authedFetch(input, {
44
- ...init,
45
- signal: AbortSignal.timeout(timeoutMs),
36
+ export function shiftError(plugin, response) {
37
+ return responseFailed(plugin, response, (body) => {
38
+ const error = body && typeof body === "object"
39
+ ? body.error
40
+ : undefined;
41
+ if (!error || typeof error !== "object")
42
+ return { code: error };
43
+ const shaped = error;
44
+ return {
45
+ code: errorIdentifier(shaped.code) ?? shaped.type,
46
+ param: shaped.param,
47
+ };
46
48
  });
47
- const text = await readBounded(response, MAX_RESPONSE_BYTES, "Shift API response exceeds 16 MiB");
48
- return new Response(text || null, {
49
- status: response.status,
50
- statusText: response.statusText,
51
- headers: response.headers,
52
- });
53
- }
54
- export function apiKey(ctx) {
55
- const key = ctx.connection.config.apiKey;
56
- if (typeof key !== "string" || !key) {
57
- throw new Error("Shift Labs apiKey is required");
58
- }
59
- return key;
60
- }
61
- export async function request(ctx, path, init = {}, timeoutMs = SHIFT_REQUEST_TIMEOUT_MS) {
62
- const headers = new Headers(init.headers);
63
- headers.set("authorization", `Bearer ${apiKey(ctx)}`);
64
- if (init.body && !headers.has("content-type")) {
65
- headers.set("content-type", "application/json");
66
- }
67
- const response = await shiftFetch(new URL(path, baseUrl()), { ...init, headers }, timeoutMs);
68
- if (!response.ok) {
69
- throw new Error(`Shift Labs API error ${response.status}: ${await response.text()}`);
70
- }
71
- if (response.status === 204)
72
- return undefined;
73
- return (await response.json());
74
- }
75
- export function pathSegment(value) {
76
- return encodeURIComponent(value);
77
- }
78
- export function listParams(input) {
79
- const params = new URLSearchParams();
80
- for (const [key, value] of Object.entries((input ?? {}))) {
81
- if (value !== undefined)
82
- params.set(key, String(value));
83
- }
84
- return params;
85
- }
86
- export function withQuery(path, params) {
87
- const query = params.toString();
88
- return query ? `${path}?${query}` : path;
89
49
  }
@@ -0,0 +1,83 @@
1
+ import { AuthError, } from "runline";
2
+ import { credentialRequest, staticCredential } from "./credentials.js";
3
+ import { SHIFT_API_URL, shiftError } from "./shiftCloud.js";
4
+ /**
5
+ * The Shift family (shiftAtlas, shiftBwm, shiftCrm, shiftObjects,
6
+ * shiftPages, shiftWork) signs with one Shift API key, as a bearer, beneath
7
+ * the cloud API's /v1 surface. Each plugin may name its own probe: not every
8
+ * key reaches every service. Plugins whose service holds requests open
9
+ * (shiftOcr, shiftTranscription) declare the target's own deadline.
10
+ */
11
+ export function shiftCredential(options = {}) {
12
+ const { probe, timeoutMs, maxResponseBytes } = options;
13
+ return staticCredential({
14
+ id: "shift",
15
+ auth: { kind: "bearer" },
16
+ local: { secret: "apiKey" },
17
+ targets: {
18
+ api: {
19
+ baseUrl: `${SHIFT_API_URL}/v1/`,
20
+ methods: ["GET", "POST", "PATCH", "PUT", "DELETE"],
21
+ allowedHeaders: ["Idempotency-Key"],
22
+ ...(timeoutMs !== undefined ? { timeoutMs } : {}),
23
+ ...(maxResponseBytes !== undefined ? { maxResponseBytes } : {}),
24
+ },
25
+ },
26
+ ...(probe
27
+ ? {
28
+ probe: {
29
+ target: "api",
30
+ path: probe,
31
+ method: "GET",
32
+ acceptedStatuses: [200],
33
+ },
34
+ }
35
+ : {}),
36
+ });
37
+ }
38
+ /** An absolute /v1/... route as a path beneath the Shift target. */
39
+ export function shiftPath(route) {
40
+ if (!route.startsWith("/v1/"))
41
+ throw new AuthError("request_not_allowed");
42
+ return route.slice("/v1/".length);
43
+ }
44
+ /**
45
+ * A Shift plugin's credential and its request function, bound together so
46
+ * a plugin cannot sign with one declaration and declare another.
47
+ */
48
+ export function shiftClient(plugin, options) {
49
+ const credential = shiftCredential(options);
50
+ return {
51
+ credential,
52
+ request: (ctx, route, init) => shiftRequest(ctx, credential, plugin, route, init),
53
+ };
54
+ }
55
+ /**
56
+ * One Shift API call through the declared credential. A body is JSON text;
57
+ * an empty answer, as the Shift API contract has it, is no value. `T` is the
58
+ * caller's statement of the answer's shape, unchecked.
59
+ */
60
+ export async function shiftRequest(ctx, declaration, plugin, route, init = {}) {
61
+ const response = await credentialRequest(ctx, declaration, {
62
+ target: "api",
63
+ path: shiftPath(route),
64
+ method: (init.method ?? "GET"),
65
+ query: init.query,
66
+ ...(init.body !== undefined
67
+ ? { body: init.body, headers: { "Content-Type": "application/json" } }
68
+ : {}),
69
+ });
70
+ if (!response.ok)
71
+ throw await shiftError(plugin, response);
72
+ if (response.status === 204)
73
+ return undefined;
74
+ const text = await response.text();
75
+ if (!text)
76
+ return undefined;
77
+ try {
78
+ return JSON.parse(text);
79
+ }
80
+ catch {
81
+ throw new AuthError("invalid_response");
82
+ }
83
+ }