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
@@ -0,0 +1,416 @@
1
+ import { AuthError, OAuthGrantSchema, staticSecretSchema, } from "runline";
2
+ import * as t from "typebox";
3
+ import { credentialBroker } from "./credentialAdapter.js";
4
+ /**
5
+ * The plugin side of the credential broker, shared by every plugin: one
6
+ * declaration factory for static keys, one stored grant shape for OAuth
7
+ * methods, one way to turn public config into an HTTPS target, one
8
+ * request path.
9
+ */
10
+ /**
11
+ * The stored shape of an OAuth method: one optional revisioned grant in the
12
+ * `grant` field, absent until the first issuance.
13
+ */
14
+ export const grantSchema = t.Object({ grant: t.Optional(OAuthGrantSchema) }, { additionalProperties: false });
15
+ /** The parts and placements a shorthand, or the general form, declares. */
16
+ function placementsOf(auth) {
17
+ if (auth.kind === "static") {
18
+ const { kind: _, ...declared } = auth;
19
+ return declared;
20
+ }
21
+ if (auth.kind === "basic")
22
+ return {
23
+ parts: ["username", "password"],
24
+ placements: [{ in: "basic", username: "username", password: "password" }],
25
+ };
26
+ const placement = auth.kind === "bearer"
27
+ ? {
28
+ in: "header",
29
+ part: "secret",
30
+ name: "Authorization",
31
+ prefix: "Bearer ",
32
+ }
33
+ : auth.kind === "queryKey"
34
+ ? { in: "query", part: "secret", name: auth.param }
35
+ : {
36
+ in: "header",
37
+ part: "secret",
38
+ name: auth.header,
39
+ ...(auth.prefix === undefined ? {} : { prefix: auth.prefix }),
40
+ };
41
+ return { parts: ["secret"], placements: [placement] };
42
+ }
43
+ /**
44
+ * A static-key plugin's declaration. The secret lives in one structured
45
+ * `credential` field — `{ secret }`, `{ username, password }` for basic, or
46
+ * the general form's named parts — and the method is named for the auth
47
+ * kind, so every static declaration has the same shape. A host stores the
48
+ * structured field; the CLI's flat fields are named by `local`.
49
+ */
50
+ export function staticCredential(spec) {
51
+ const field = "credential";
52
+ const { parts, optionalParts, placements } = placementsOf(spec.auth);
53
+ if (Object.keys(spec.local).sort().join() !== [...parts].sort().join())
54
+ throw new AuthError("invalid_definition");
55
+ const localSecret = Object.fromEntries(Object.entries(spec.local).map(([key, source]) => [
56
+ key,
57
+ typeof source === "string" ? { field: source } : source,
58
+ ]));
59
+ const fields = Object.values(localSecret).flatMap((source) => ("concat" in source ? source.concat : [source]).flatMap((part) => "field" in part ? [part.field] : []));
60
+ return (config) => {
61
+ const targets = typeof spec.targets === "function" ? spec.targets(config) : spec.targets;
62
+ const signed = !spec.optional ||
63
+ config.authenticated === true ||
64
+ fields.every((name) => typeof config[name] === "string" && config[name]);
65
+ return {
66
+ type: {
67
+ id: spec.id,
68
+ methods: {
69
+ [spec.auth.kind]: {
70
+ schema: t.Object({ [field]: staticSecretSchema(parts, optionalParts) }, { additionalProperties: false }),
71
+ authentication: {
72
+ kind: "static",
73
+ field,
74
+ parts,
75
+ ...(optionalParts ? { optionalParts } : {}),
76
+ placements,
77
+ },
78
+ targets,
79
+ ...(spec.probe ? { probe: spec.probe } : {}),
80
+ },
81
+ ...(spec.optional
82
+ ? {
83
+ none: {
84
+ schema: t.Object({}, { additionalProperties: false }),
85
+ authentication: { kind: "none" },
86
+ targets: spec.optional === true ? targets : spec.optional.targets,
87
+ },
88
+ }
89
+ : {}),
90
+ },
91
+ },
92
+ ...(signed
93
+ ? { method: spec.auth.kind, localSecret }
94
+ : { method: "none" }),
95
+ };
96
+ };
97
+ }
98
+ /**
99
+ * An HTTPS base URL from public config, with `path` appended beneath it.
100
+ * Anything else — plain HTTP, embedded credentials, a query or fragment —
101
+ * is invalid_credentials: the connection cannot be signed as configured.
102
+ */
103
+ export function httpsBase(value, path) {
104
+ try {
105
+ if (typeof value !== "string")
106
+ throw new Error();
107
+ const url = new URL(value);
108
+ if (url.protocol !== "https:" ||
109
+ url.username ||
110
+ url.password ||
111
+ url.search ||
112
+ url.hash ||
113
+ value.includes("?") ||
114
+ value.includes("#"))
115
+ throw new Error();
116
+ const base = url.pathname.endsWith("/") ? url.pathname : `${url.pathname}/`;
117
+ return `${url.origin}${base}${path}`;
118
+ }
119
+ catch {
120
+ throw new AuthError("invalid_credentials");
121
+ }
122
+ }
123
+ /** One DNS label from public config, for `https://{label}.provider.com/` hosts. */
124
+ export function hostLabel(value) {
125
+ if (typeof value !== "string" ||
126
+ !/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(value))
127
+ throw new AuthError("invalid_credentials");
128
+ return value;
129
+ }
130
+ /**
131
+ * One of a config field's documented values — a region, an environment,
132
+ * a hosting mode — or `fallback` when the field is absent. Anything else
133
+ * is invalid_credentials, never mapped to a default: a mistyped value
134
+ * would otherwise send the credential to another host.
135
+ */
136
+ export function configChoice(value, choices, fallback) {
137
+ if (value === undefined || value === null)
138
+ return fallback;
139
+ if (typeof value !== "string" ||
140
+ !choices.includes(value))
141
+ throw new AuthError("invalid_credentials");
142
+ return value;
143
+ }
144
+ /**
145
+ * A boolean config field, as a boolean or the string a CLI or environment
146
+ * variable gives (`"true"`, `"false"`); false when absent. Anything else
147
+ * is invalid_credentials, as for `configChoice`: a mistyped sandbox or
148
+ * SSL flag must not read as false and reach the live host.
149
+ */
150
+ export function configFlag(value) {
151
+ if (typeof value === "boolean")
152
+ return value;
153
+ return configChoice(value, ["true", "false"], "false") === "true";
154
+ }
155
+ /**
156
+ * An ID or name as exactly one path segment, the one encoder every plugin
157
+ * uses. A value that is not one segment is refused rather than encoded: an
158
+ * empty value would address the parent collection (`items/`), a dot segment
159
+ * a sibling, and a separator more than one segment.
160
+ */
161
+ export function pathSegment(value) {
162
+ const raw = value === undefined || value === null ? "" : String(value);
163
+ if (!raw || raw === "." || raw === ".." || /[/\\]/.test(raw))
164
+ throw new AuthError("request_not_allowed");
165
+ return encodeURIComponent(raw);
166
+ }
167
+ /**
168
+ * A slash-separated name the API addresses as a sub-path — a model's
169
+ * `owner/name`, a file path, a nested job — each segment by `pathSegment`,
170
+ * its slashes kept.
171
+ */
172
+ export function pathSegments(value) {
173
+ return String(value ?? "")
174
+ .split("/")
175
+ .map(pathSegment)
176
+ .join("/");
177
+ }
178
+ /**
179
+ * A slashed name as exactly one segment, its slashes encoded
180
+ * (`@scope/pkg` → `%40scope%2Fpkg`), for a target that declares
181
+ * `encodedSlashes`. An empty or dot piece, or a backslash, is refused.
182
+ */
183
+ export function slashEncodedSegment(value) {
184
+ return pathSegments(value).replaceAll("/", "%2F");
185
+ }
186
+ /** Parameters as `a=1&b=2`: arrays repeat the key; null and undefined are skipped. */
187
+ function encodeParams(params) {
188
+ const encoded = new URLSearchParams();
189
+ for (const [key, value] of Object.entries(params)) {
190
+ if (value === undefined || value === null)
191
+ continue;
192
+ for (const entry of Array.isArray(value) ? value : [value])
193
+ encoded.append(key, String(entry));
194
+ }
195
+ return encoded.toString();
196
+ }
197
+ function withQuery(path, query) {
198
+ if (!query)
199
+ return path;
200
+ const encoded = encodeParams(query);
201
+ if (!encoded)
202
+ return path;
203
+ return `${path}${path.includes("?") ? "&" : "?"}${encoded}`;
204
+ }
205
+ /** The one authenticated request path: the host's broker, else the local signer. */
206
+ export function credentialRequest(ctx, declaration, call) {
207
+ const body = call.json !== undefined
208
+ ? { type: "application/json", body: JSON.stringify(call.json) }
209
+ : call.form !== undefined
210
+ ? {
211
+ type: "application/x-www-form-urlencoded",
212
+ body: encodeParams(call.form),
213
+ }
214
+ : undefined;
215
+ const payload = body?.body ?? call.body;
216
+ return credentialBroker(ctx, declaration).request({
217
+ target: call.target,
218
+ path: withQuery(call.path, call.query),
219
+ method: call.method ?? "GET",
220
+ headers: {
221
+ Accept: "application/json",
222
+ ...(body ? { "Content-Type": body.type } : {}),
223
+ ...call.headers,
224
+ },
225
+ ...(payload !== undefined ? { body: payload } : {}),
226
+ ...(call.destination !== undefined
227
+ ? { destination: call.destination }
228
+ : {}),
229
+ ...(call.idempotencyKey !== undefined
230
+ ? { idempotencyKey: call.idempotencyKey }
231
+ : {}),
232
+ });
233
+ }
234
+ /**
235
+ * A step that writes a grant into the connection — an owner login run
236
+ * against the provider — happens only where the grant lives: this process,
237
+ * signing with its own connection. Under a host that keeps the grant, setup
238
+ * is the host's, and the step refuses before any request.
239
+ */
240
+ export function refuseUnderHost(ctx) {
241
+ if (ctx.credentials)
242
+ throw new AuthError("unsupported_operation");
243
+ }
244
+ /**
245
+ * A socket target's URL for this connection, from the broker: signed by
246
+ * the local signer, or a relay the host controls. A broker that serves no
247
+ * sockets refuses as unsupported_operation.
248
+ */
249
+ export async function credentialSocketUrl(ctx, declaration, call) {
250
+ const broker = credentialBroker(ctx, declaration);
251
+ if (!broker.socketUrl)
252
+ throw new AuthError("unsupported_operation");
253
+ return broker.socketUrl({
254
+ target: call.target,
255
+ path: withQuery(call.path, call.query),
256
+ });
257
+ }
258
+ /**
259
+ * A provider error identifier worth handing back — an error code, a field
260
+ * path — as a plain name. Anything else is not a name and is dropped, so
261
+ * the code and field slots of a failure never carry free text.
262
+ */
263
+ export function errorIdentifier(value) {
264
+ return typeof value === "string" && /^[\w.$:-]{1,100}$/.test(value)
265
+ ? value
266
+ : undefined;
267
+ }
268
+ /**
269
+ * How a failed request reads: its HTTP status when the status is the
270
+ * failure, and the identifiers a provider returns for correcting the call
271
+ * — its error `code` and the offending `param`. No free text from a failed
272
+ * response reaches it: that is where a provider may echo the credential.
273
+ */
274
+ export function failureMessage(plugin, status, detail = {}) {
275
+ const identifiers = [detail.code, detail.param && `param: ${detail.param}`]
276
+ .filter(Boolean)
277
+ .join(", ");
278
+ const inner = [status === undefined ? "" : `HTTP ${status}`, identifiers]
279
+ .filter(Boolean)
280
+ .join(" ");
281
+ return `${plugin}: request failed${inner ? ` (${inner})` : ""}`;
282
+ }
283
+ /** A code or field path as a plain identifier, numbers included. */
284
+ function identifierOf(value) {
285
+ return errorIdentifier(typeof value === "number" ? String(value) : value);
286
+ }
287
+ /**
288
+ * A successful response whose answer reports failure — Slack's `ok: false`,
289
+ * an OCS status, a GraphQL `errors` entry — by the provider's code, the
290
+ * field at fault and its message. The answer is 2xx data the plugin
291
+ * already holds, so the message stays for the caller to act on, reduced
292
+ * to one line of at most 300 characters.
293
+ */
294
+ export function answerFailed(plugin, detail) {
295
+ const head = failureMessage(plugin, undefined, {
296
+ code: identifierOf(detail.code),
297
+ param: identifierOf(detail.param),
298
+ });
299
+ const text = typeof detail.message === "string"
300
+ ? detail.message.replace(/[\u0000-\u001f\u007f\s]+/g, " ").trim()
301
+ : "";
302
+ const line = text.length > 300 ? `${text.slice(0, 300)}…` : text;
303
+ return new Error(line ? `${head}: ${line}` : head);
304
+ }
305
+ /** A GraphQL answer's `errors`, read by `answerFailed` from the first entry. */
306
+ export function graphqlFailed(plugin, errors) {
307
+ const first = (Array.isArray(errors) ? errors[0] : undefined);
308
+ return answerFailed(plugin, {
309
+ code: first?.extensions?.code,
310
+ param: Array.isArray(first?.path) ? first.path.join(".") : undefined,
311
+ message: first?.message,
312
+ });
313
+ }
314
+ /** A failed request, reported by status alone. */
315
+ export function requestFailed(plugin, status) {
316
+ return new Error(failureMessage(plugin, status));
317
+ }
318
+ /**
319
+ * A failed response by its status and the identifiers its error envelope
320
+ * names. `read` picks the code and param out of the parsed JSON body, in
321
+ * the provider's own shape; only what `errorIdentifier` accepts is kept,
322
+ * so a provider's messages never reach the error. A body that is not JSON
323
+ * reports the status alone. The status rides on the error for callers
324
+ * that branch on it.
325
+ */
326
+ export async function responseFailed(plugin, response, read) {
327
+ let envelope = {};
328
+ try {
329
+ envelope = read(JSON.parse(await response.text()));
330
+ }
331
+ catch {
332
+ envelope = {};
333
+ }
334
+ const params = (Array.isArray(envelope.param) ? envelope.param : [envelope.param])
335
+ .map(identifierOf)
336
+ .filter((param) => param !== undefined);
337
+ return Object.assign(new Error(failureMessage(plugin, response.status, {
338
+ code: identifierOf(envelope.code),
339
+ param: params.length ? params.join(", ") : undefined,
340
+ })), { status: response.status });
341
+ }
342
+ /** A request that must succeed, for callers that read the Response itself (headers, text, bytes). */
343
+ export async function credentialOk(ctx, declaration, plugin, call) {
344
+ const response = await credentialRequest(ctx, declaration, call);
345
+ if (!response.ok)
346
+ throw requestFailed(plugin, response.status);
347
+ return response;
348
+ }
349
+ /**
350
+ * A successful response's JSON. `T` is the caller's statement of the
351
+ * answer's shape, unchecked, as for any parsed JSON; without one it is
352
+ * `unknown`. An empty answer is `EmptyAnswer`, so a caller whose endpoint
353
+ * can answer empty includes it in `T`. Every JSON request path reads its
354
+ * answer here, so they cannot disagree about empty or malformed bodies.
355
+ */
356
+ export async function jsonAnswer(response) {
357
+ const empty = { success: true };
358
+ if (response.status === 204)
359
+ return empty;
360
+ const text = await response.text();
361
+ if (!text)
362
+ return empty;
363
+ try {
364
+ return JSON.parse(text);
365
+ }
366
+ catch {
367
+ throw new AuthError("invalid_response");
368
+ }
369
+ }
370
+ /**
371
+ * A successful response's JSON when its Content-Type says JSON; any other
372
+ * body — a text "OK", nothing at all — is an acknowledgement,
373
+ * `EmptyAnswer`. For APIs whose writes answer without JSON.
374
+ */
375
+ export async function jsonOrAcknowledged(response) {
376
+ return (response.headers.get("content-type") ?? "").includes("application/json")
377
+ ? jsonAnswer(response)
378
+ : { success: true };
379
+ }
380
+ /** A JSON request that must succeed; its answer is read by `jsonAnswer`. */
381
+ export async function credentialJson(ctx, declaration, plugin, call) {
382
+ return jsonAnswer(await credentialOk(ctx, declaration, plugin, call));
383
+ }
384
+ /**
385
+ * A next-page URL the API returned, as a path beneath the declared target
386
+ * it will be signed for. Anything outside that target's exact origin and
387
+ * path prefix is refused rather than followed with the credential attached.
388
+ */
389
+ export function pathWithin(ctx, declaration, target, value) {
390
+ const { type, method } = declaration(ctx.connection.config);
391
+ const targets = type.methods[method]?.targets ?? {};
392
+ if (!Object.hasOwn(targets, target))
393
+ throw new AuthError("request_not_allowed");
394
+ try {
395
+ const base = new URL(targets[target].baseUrl);
396
+ const url = new URL(value);
397
+ if (url.origin !== base.origin ||
398
+ url.username ||
399
+ url.password ||
400
+ url.hash ||
401
+ !url.pathname.startsWith(base.pathname))
402
+ throw new Error();
403
+ return `${url.pathname.slice(base.pathname.length)}${url.search}`;
404
+ }
405
+ catch {
406
+ throw new AuthError("request_not_allowed");
407
+ }
408
+ }
409
+ /** FormData as the buffered bytes the transport accepts, with its boundary. */
410
+ export async function multipartBody(form) {
411
+ const response = new Response(form);
412
+ const contentType = response.headers.get("content-type");
413
+ if (!contentType)
414
+ throw new AuthError("request_not_allowed");
415
+ return { body: new Uint8Array(await response.arrayBuffer()), contentType };
416
+ }
@@ -1,29 +1,68 @@
1
1
  import { AuthError, downloadResource, } from "runline";
2
- import { credentialRuntime } from "./credentialAdapter.js";
3
- import { googleCredentialType, googleIdentity, googleMethod, googleResources, } from "./googleCredentials.js";
4
- /** Explicit storage adapter: the registry owns token protocols and renewal. */
5
- export function googleRuntime(ctx, pluginName, scopes) {
6
- const config = ctx.connection.config;
7
- const method = googleMethod(config);
8
- const runtime = credentialRuntime(ctx, googleCredentialType(scopes, pluginName), method, (current) => {
9
- const cfg = current;
10
- return [
11
- pluginName,
12
- scopes,
13
- googleMethod(cfg),
14
- ...(method === "serviceAccount"
15
- ? [googleIdentity(cfg)]
16
- : [cfg.clientId, cfg.clientSecret]),
17
- ];
18
- });
19
- if (method === "serviceAccount")
20
- runtime.binding.jwtIdentity = googleIdentity(config);
21
- return runtime;
22
- }
23
- /** Trusted-runtime token compatibility only; resource consumers use googleResponse. */
24
- export async function googleAccessToken(ctx, pluginName, scopes) {
25
- const { binding, transport } = googleRuntime(ctx, pluginName, scopes);
26
- return transport.accessToken(binding);
2
+ import { credentialBroker } from "./credentialAdapter.js";
3
+ import { jsonAnswer, requestFailed } from "./credentials.js";
4
+ import { GOOGLE_GRANT, GOOGLE_TOKEN_URL, googleCredential, googleResources, googleServices, } from "./googleCredentials.js";
5
+ export { googleCredential } from "./googleCredentials.js";
6
+ /**
7
+ * A Google plugin's OAuth declaration: Google's endpoints, the offline
8
+ * consent that returns a refresh token (without `access_type=offline` and
9
+ * `prompt=consent` a repeat login omits it), the grant every Google plugin
10
+ * shares, and setup steps that enable the APIs its targets call and name
11
+ * its client variables (`env`: `GMAIL` → `GMAIL_CLIENT_ID`).
12
+ */
13
+ export function googleOAuth(plugin, scopes, env) {
14
+ return {
15
+ grant: GOOGLE_GRANT,
16
+ authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
17
+ tokenUrl: GOOGLE_TOKEN_URL,
18
+ scopes,
19
+ authParams: { access_type: "offline", prompt: "consent" },
20
+ setupHelp: [
21
+ "You need a Google Cloud OAuth client. Takes ~5 minutes, one time;",
22
+ "the same client serves every Google plugin.",
23
+ "Do the steps in order — skipping step 4 causes a 403 when you log in.",
24
+ "",
25
+ "1. Create a Google Cloud project (or pick an existing one):",
26
+ " https://console.cloud.google.com/projectcreate",
27
+ " Make sure the project is selected in the top navigation dropdown.",
28
+ "",
29
+ "2. Enable the APIs this plugin calls (click 'Enable' on each):",
30
+ ...googleServices(plugin).map((service) => ` https://console.cloud.google.com/apis/library/${service}`),
31
+ "",
32
+ "3. Configure the OAuth consent screen (first time only):",
33
+ " https://console.cloud.google.com/apis/credentials/consent",
34
+ " Click 'Get started' and fill in:",
35
+ " • App name: runline (or whatever)",
36
+ " • User support email: your email",
37
+ " • Audience: External",
38
+ " • Developer contact: your email",
39
+ " You can skip the Scopes screen — runline declares scopes at auth time.",
40
+ "",
41
+ "4. Add yourself as a test user (required — External apps in Testing mode",
42
+ " only allow authentication from addresses on this list):",
43
+ " https://console.cloud.google.com/auth/audience",
44
+ " Under 'Test users', click '+ Add users' and enter the Google address",
45
+ " you'll use to log in. Consent and refresh tokens expire every 7 days",
46
+ " while the app is in Testing mode.",
47
+ "",
48
+ "5. Create the OAuth client:",
49
+ " https://console.cloud.google.com/apis/credentials",
50
+ " • + Create credentials → OAuth client ID",
51
+ " • Application type: Web application",
52
+ " • Name: runline (or whatever)",
53
+ " • Authorized redirect URIs → + Add URI:",
54
+ " {{redirectUri}}",
55
+ " • Click Create, then copy the Client ID and Client Secret from the",
56
+ " dialog — the secret is only shown once.",
57
+ "",
58
+ "6. Paste them below (or re-run with --client-id / --client-secret,",
59
+ ` or export ${env}_CLIENT_ID and ${env}_CLIENT_SECRET).`,
60
+ "",
61
+ "During login you'll see a 'Google hasn't verified this app' warning.",
62
+ "Click 'Advanced → Go to runline (unsafe)' to continue — this is",
63
+ "expected for apps in Testing mode.",
64
+ ],
65
+ };
27
66
  }
28
67
  /** Translate builtin absolute URLs at one boundary; validate the raw path before URL normalization. */
29
68
  export async function googleResponse(ctx, plugin, scopes, url, init = {}, query) {
@@ -45,8 +84,7 @@ export async function googleResponse(ctx, plugin, scopes, url, init = {}, query)
45
84
  }
46
85
  path = `${separator < 0 ? path : path.slice(0, separator)}?${params}`;
47
86
  }
48
- const { binding, transport } = googleRuntime(ctx, plugin, scopes);
49
- return transport.request(binding, {
87
+ return credentialBroker(ctx, googleCredential(plugin, scopes)).request({
50
88
  target,
51
89
  path,
52
90
  method: (init.method ?? "GET"),
@@ -54,6 +92,7 @@ export async function googleResponse(ctx, plugin, scopes, url, init = {}, query)
54
92
  body: init.body,
55
93
  });
56
94
  }
95
+ /** A Google JSON request that must succeed; its answer is read by `jsonAnswer`. */
57
96
  export async function googleJsonRequest(ctx, plugin, scopes, method, url, body, query) {
58
97
  const response = await googleResponse(ctx, plugin, scopes, url, {
59
98
  method,
@@ -64,20 +103,11 @@ export async function googleJsonRequest(ctx, plugin, scopes, method, url, body,
64
103
  body: body === undefined ? undefined : JSON.stringify(body),
65
104
  }, query);
66
105
  if (!response.ok)
67
- throw new Error(`${plugin}: request failed (HTTP ${response.status})`);
68
- if (response.status === 204)
69
- return { success: true };
70
- const text = await response.text();
71
- try {
72
- return text ? JSON.parse(text) : { success: true };
73
- }
74
- catch {
75
- throw new AuthError("invalid_response");
76
- }
106
+ throw requestFailed(plugin, response.status);
107
+ return jsonAnswer(response);
77
108
  }
78
109
  export async function googleProbe(ctx, plugin, scopes) {
79
- const { binding, transport } = googleRuntime(ctx, plugin, scopes);
80
- return transport.probe(binding);
110
+ return credentialBroker(ctx, googleCredential(plugin, scopes)).probe();
81
111
  }
82
112
  /** Only Google-issued thumbnail hosts; never attach credentials to signed URLs. */
83
113
  export async function googleDownload(value) {