@zapier/zapier-sdk 0.4.1 → 0.5.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 (374) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/api/auth.d.ts +9 -0
  3. package/dist/api/auth.d.ts.map +1 -0
  4. package/dist/api/auth.js +25 -0
  5. package/dist/api/client.d.ts +9 -0
  6. package/dist/api/client.d.ts.map +1 -0
  7. package/dist/api/client.js +322 -0
  8. package/dist/api/debug.d.ts +13 -0
  9. package/dist/api/debug.d.ts.map +1 -0
  10. package/dist/api/debug.js +55 -0
  11. package/dist/api/index.d.ts +29 -0
  12. package/dist/api/index.d.ts.map +1 -0
  13. package/dist/api/index.js +41 -0
  14. package/dist/api/polling.d.ts +16 -0
  15. package/dist/api/polling.d.ts.map +1 -0
  16. package/dist/api/polling.js +45 -0
  17. package/dist/api/schemas.d.ts +2473 -0
  18. package/dist/api/schemas.d.ts.map +1 -0
  19. package/dist/api/schemas.js +355 -0
  20. package/dist/api/types.d.ts +75 -0
  21. package/dist/api/types.d.ts.map +1 -0
  22. package/dist/api/types.js +11 -0
  23. package/dist/auth.d.ts +34 -0
  24. package/dist/auth.d.ts.map +1 -0
  25. package/dist/auth.js +47 -0
  26. package/dist/constants.d.ts +10 -0
  27. package/dist/constants.d.ts.map +1 -0
  28. package/dist/constants.js +9 -0
  29. package/dist/index.cjs +2108 -1379
  30. package/dist/index.d.mts +2440 -620
  31. package/dist/index.d.ts +17 -892
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +20 -0
  34. package/dist/index.mjs +2093 -1362
  35. package/dist/plugins/api/index.d.ts +14 -0
  36. package/dist/plugins/api/index.d.ts.map +1 -0
  37. package/dist/plugins/api/index.js +21 -0
  38. package/dist/plugins/apps/index.d.ts +11 -0
  39. package/dist/plugins/apps/index.d.ts.map +1 -0
  40. package/dist/plugins/apps/index.js +91 -0
  41. package/dist/plugins/apps/types.d.ts +30 -0
  42. package/dist/plugins/apps/types.d.ts.map +1 -0
  43. package/dist/plugins/apps/types.js +2 -0
  44. package/dist/plugins/fetch/index.d.ts +21 -0
  45. package/dist/plugins/fetch/index.d.ts.map +1 -0
  46. package/dist/plugins/fetch/index.js +20 -0
  47. package/dist/plugins/findFirstAuthentication/index.d.ts +20 -0
  48. package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -0
  49. package/dist/plugins/findFirstAuthentication/index.js +24 -0
  50. package/dist/plugins/findFirstAuthentication/index.test.d.ts +2 -0
  51. package/dist/plugins/findFirstAuthentication/index.test.d.ts.map +1 -0
  52. package/dist/plugins/findFirstAuthentication/index.test.js +171 -0
  53. package/dist/plugins/findFirstAuthentication/schemas.d.ts +29 -0
  54. package/dist/plugins/findFirstAuthentication/schemas.d.ts.map +1 -0
  55. package/dist/plugins/findFirstAuthentication/schemas.js +18 -0
  56. package/dist/plugins/findUniqueAuthentication/index.d.ts +20 -0
  57. package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -0
  58. package/dist/plugins/findUniqueAuthentication/index.js +31 -0
  59. package/dist/plugins/findUniqueAuthentication/index.test.d.ts +2 -0
  60. package/dist/plugins/findUniqueAuthentication/index.test.d.ts.map +1 -0
  61. package/dist/plugins/findUniqueAuthentication/index.test.js +152 -0
  62. package/dist/plugins/findUniqueAuthentication/schemas.d.ts +29 -0
  63. package/dist/plugins/findUniqueAuthentication/schemas.d.ts.map +1 -0
  64. package/dist/plugins/findUniqueAuthentication/schemas.js +18 -0
  65. package/dist/plugins/getAction/index.d.ts +23 -0
  66. package/dist/plugins/getAction/index.d.ts.map +1 -0
  67. package/dist/plugins/getAction/index.js +28 -0
  68. package/dist/plugins/getAction/index.test.d.ts +2 -0
  69. package/dist/plugins/getAction/index.test.d.ts.map +1 -0
  70. package/dist/plugins/getAction/index.test.js +186 -0
  71. package/dist/plugins/getAction/schemas.d.ts +23 -0
  72. package/dist/plugins/getAction/schemas.d.ts.map +1 -0
  73. package/dist/plugins/getAction/schemas.js +10 -0
  74. package/dist/plugins/getApp/index.d.ts +22 -0
  75. package/dist/plugins/getApp/index.d.ts.map +1 -0
  76. package/dist/plugins/getApp/index.js +39 -0
  77. package/dist/plugins/getApp/index.test.d.ts +2 -0
  78. package/dist/plugins/getApp/index.test.d.ts.map +1 -0
  79. package/dist/plugins/getApp/index.test.js +100 -0
  80. package/dist/plugins/getApp/schemas.d.ts +18 -0
  81. package/dist/plugins/getApp/schemas.d.ts.map +1 -0
  82. package/dist/plugins/getApp/schemas.js +10 -0
  83. package/dist/plugins/getAuthentication/index.d.ts +22 -0
  84. package/dist/plugins/getAuthentication/index.d.ts.map +1 -0
  85. package/dist/plugins/getAuthentication/index.js +41 -0
  86. package/dist/plugins/getAuthentication/index.test.d.ts +2 -0
  87. package/dist/plugins/getAuthentication/index.test.d.ts.map +1 -0
  88. package/dist/plugins/getAuthentication/index.test.js +205 -0
  89. package/dist/plugins/getAuthentication/schemas.d.ts +17 -0
  90. package/dist/plugins/getAuthentication/schemas.d.ts.map +1 -0
  91. package/dist/plugins/getAuthentication/schemas.js +11 -0
  92. package/dist/plugins/getProfile/index.d.ts +23 -0
  93. package/dist/plugins/getProfile/index.d.ts.map +1 -0
  94. package/dist/plugins/getProfile/index.js +29 -0
  95. package/dist/plugins/getProfile/schemas.d.ts +13 -0
  96. package/dist/plugins/getProfile/schemas.d.ts.map +1 -0
  97. package/dist/plugins/getProfile/schemas.js +5 -0
  98. package/dist/plugins/listActions/index.d.ts +28 -0
  99. package/dist/plugins/listActions/index.d.ts.map +1 -0
  100. package/dist/plugins/listActions/index.js +61 -0
  101. package/dist/plugins/listActions/index.test.d.ts +2 -0
  102. package/dist/plugins/listActions/index.test.d.ts.map +1 -0
  103. package/dist/plugins/listActions/index.test.js +467 -0
  104. package/dist/plugins/listActions/schemas.d.ts +29 -0
  105. package/dist/plugins/listActions/schemas.d.ts.map +1 -0
  106. package/dist/plugins/listActions/schemas.js +21 -0
  107. package/dist/plugins/listApps/index.d.ts +28 -0
  108. package/dist/plugins/listApps/index.d.ts.map +1 -0
  109. package/dist/plugins/listApps/index.js +62 -0
  110. package/dist/plugins/listApps/index.test.d.ts +2 -0
  111. package/dist/plugins/listApps/index.test.d.ts.map +1 -0
  112. package/dist/plugins/listApps/index.test.js +313 -0
  113. package/dist/plugins/listApps/schemas.d.ts +30 -0
  114. package/dist/plugins/listApps/schemas.d.ts.map +1 -0
  115. package/dist/plugins/listApps/schemas.js +23 -0
  116. package/dist/plugins/listAuthentications/index.d.ts +28 -0
  117. package/dist/plugins/listAuthentications/index.d.ts.map +1 -0
  118. package/dist/plugins/listAuthentications/index.js +77 -0
  119. package/dist/plugins/listAuthentications/index.test.d.ts +2 -0
  120. package/dist/plugins/listAuthentications/index.test.d.ts.map +1 -0
  121. package/dist/plugins/listAuthentications/index.test.js +564 -0
  122. package/dist/plugins/listAuthentications/schemas.d.ts +38 -0
  123. package/dist/plugins/listAuthentications/schemas.d.ts.map +1 -0
  124. package/dist/plugins/listAuthentications/schemas.js +28 -0
  125. package/dist/plugins/listInputFields/index.d.ts +28 -0
  126. package/dist/plugins/listInputFields/index.d.ts.map +1 -0
  127. package/dist/plugins/listInputFields/index.js +133 -0
  128. package/dist/plugins/listInputFields/index.test.d.ts +2 -0
  129. package/dist/plugins/listInputFields/index.test.d.ts.map +1 -0
  130. package/dist/plugins/listInputFields/index.test.js +325 -0
  131. package/dist/plugins/listInputFields/schemas.d.ts +38 -0
  132. package/dist/plugins/listInputFields/schemas.d.ts.map +1 -0
  133. package/dist/plugins/listInputFields/schemas.js +22 -0
  134. package/dist/plugins/registry/index.d.ts +11 -0
  135. package/dist/plugins/registry/index.d.ts.map +1 -0
  136. package/dist/plugins/registry/index.js +14 -0
  137. package/dist/plugins/request/index.d.ts +19 -0
  138. package/dist/plugins/request/index.d.ts.map +1 -0
  139. package/dist/plugins/request/index.js +62 -0
  140. package/dist/plugins/request/index.test.d.ts +2 -0
  141. package/dist/plugins/request/index.test.d.ts.map +1 -0
  142. package/dist/plugins/request/index.test.js +256 -0
  143. package/dist/plugins/request/schemas.d.ts +69 -0
  144. package/dist/plugins/request/schemas.d.ts.map +1 -0
  145. package/dist/plugins/request/schemas.js +42 -0
  146. package/dist/plugins/runAction/index.d.ts +28 -0
  147. package/dist/plugins/runAction/index.d.ts.map +1 -0
  148. package/dist/plugins/runAction/index.js +86 -0
  149. package/dist/plugins/runAction/index.test.d.ts +2 -0
  150. package/dist/plugins/runAction/index.test.d.ts.map +1 -0
  151. package/dist/plugins/runAction/index.test.js +320 -0
  152. package/dist/plugins/runAction/schemas.d.ts +37 -0
  153. package/dist/plugins/runAction/schemas.d.ts.map +1 -0
  154. package/dist/plugins/runAction/schemas.js +22 -0
  155. package/dist/resolvers/actionKey.d.ts +9 -0
  156. package/dist/resolvers/actionKey.d.ts.map +1 -0
  157. package/dist/resolvers/actionKey.js +19 -0
  158. package/dist/resolvers/actionType.d.ts +9 -0
  159. package/dist/resolvers/actionType.d.ts.map +1 -0
  160. package/dist/resolvers/actionType.js +22 -0
  161. package/dist/resolvers/appKey.d.ts +7 -0
  162. package/dist/resolvers/appKey.d.ts.map +1 -0
  163. package/dist/resolvers/appKey.js +5 -0
  164. package/dist/resolvers/authenticationId.d.ts +9 -0
  165. package/dist/resolvers/authenticationId.d.ts.map +1 -0
  166. package/dist/resolvers/authenticationId.js +33 -0
  167. package/dist/resolvers/index.d.ts +40 -0
  168. package/dist/resolvers/index.d.ts.map +1 -0
  169. package/dist/resolvers/index.js +91 -0
  170. package/dist/resolvers/inputs.d.ts +8 -0
  171. package/dist/resolvers/inputs.d.ts.map +1 -0
  172. package/dist/resolvers/inputs.js +14 -0
  173. package/dist/schemas/Action.d.ts +243 -0
  174. package/dist/schemas/Action.d.ts.map +1 -0
  175. package/dist/schemas/Action.js +34 -0
  176. package/dist/schemas/App.d.ts +26 -0
  177. package/dist/schemas/App.d.ts.map +1 -0
  178. package/dist/schemas/App.js +22 -0
  179. package/dist/schemas/Auth.d.ts +161 -0
  180. package/dist/schemas/Auth.d.ts.map +1 -0
  181. package/dist/schemas/Auth.js +41 -0
  182. package/dist/schemas/Field.d.ts +144 -0
  183. package/dist/schemas/Field.d.ts.map +1 -0
  184. package/dist/schemas/Field.js +105 -0
  185. package/dist/schemas/UserProfile.d.ts +163 -0
  186. package/dist/schemas/UserProfile.d.ts.map +1 -0
  187. package/dist/schemas/UserProfile.js +29 -0
  188. package/dist/sdk.d.ts +10 -0
  189. package/dist/sdk.d.ts.map +1 -0
  190. package/dist/sdk.js +94 -0
  191. package/dist/sdk.test.d.ts +2 -0
  192. package/dist/sdk.test.d.ts.map +1 -0
  193. package/dist/sdk.test.js +135 -0
  194. package/dist/types/domain.d.ts +36 -0
  195. package/dist/types/domain.d.ts.map +1 -0
  196. package/dist/types/domain.js +1 -0
  197. package/dist/types/domain.test.d.ts +2 -0
  198. package/dist/types/domain.test.d.ts.map +1 -0
  199. package/dist/types/domain.test.js +39 -0
  200. package/dist/types/errors.d.ts +143 -0
  201. package/dist/types/errors.d.ts.map +1 -0
  202. package/dist/types/errors.js +187 -0
  203. package/dist/types/events.d.ts +38 -0
  204. package/dist/types/events.d.ts.map +1 -0
  205. package/dist/types/events.js +7 -0
  206. package/dist/types/functions.d.ts +26 -0
  207. package/dist/types/functions.d.ts.map +1 -0
  208. package/dist/types/functions.js +4 -0
  209. package/dist/types/plugin.d.ts +61 -0
  210. package/dist/types/plugin.d.ts.map +1 -0
  211. package/dist/types/plugin.js +9 -0
  212. package/dist/types/properties.d.ts +22 -0
  213. package/dist/types/properties.d.ts.map +1 -0
  214. package/dist/types/properties.js +50 -0
  215. package/dist/types/sdk.d.ts +43 -0
  216. package/dist/types/sdk.d.ts.map +1 -0
  217. package/dist/types/sdk.js +4 -0
  218. package/dist/utils/array-utils.d.ts +31 -0
  219. package/dist/utils/array-utils.d.ts.map +1 -0
  220. package/dist/utils/array-utils.js +36 -0
  221. package/dist/utils/array-utils.test.d.ts +2 -0
  222. package/dist/utils/array-utils.test.d.ts.map +1 -0
  223. package/dist/utils/array-utils.test.js +107 -0
  224. package/dist/utils/domain-utils.d.ts +78 -0
  225. package/dist/utils/domain-utils.d.ts.map +1 -0
  226. package/dist/utils/domain-utils.js +218 -0
  227. package/dist/utils/domain-utils.test.d.ts +2 -0
  228. package/dist/utils/domain-utils.test.d.ts.map +1 -0
  229. package/dist/utils/domain-utils.test.js +192 -0
  230. package/dist/utils/function-utils.d.ts +45 -0
  231. package/dist/utils/function-utils.d.ts.map +1 -0
  232. package/dist/utils/function-utils.js +158 -0
  233. package/dist/utils/function-utils.test.d.ts +2 -0
  234. package/dist/utils/function-utils.test.d.ts.map +1 -0
  235. package/dist/utils/function-utils.test.js +110 -0
  236. package/dist/utils/pagination-utils.d.ts +37 -0
  237. package/dist/utils/pagination-utils.d.ts.map +1 -0
  238. package/dist/utils/pagination-utils.js +165 -0
  239. package/dist/utils/pagination-utils.test.d.ts +17 -0
  240. package/dist/utils/pagination-utils.test.d.ts.map +1 -0
  241. package/dist/utils/pagination-utils.test.js +461 -0
  242. package/dist/utils/schema-utils.d.ts +45 -0
  243. package/dist/utils/schema-utils.d.ts.map +1 -0
  244. package/dist/utils/schema-utils.js +65 -0
  245. package/dist/utils/validation.d.ts +4 -0
  246. package/dist/utils/validation.d.ts.map +1 -0
  247. package/dist/utils/validation.js +30 -0
  248. package/dist/utils/validation.test.d.ts +2 -0
  249. package/dist/utils/validation.test.d.ts.map +1 -0
  250. package/dist/utils/validation.test.js +43 -0
  251. package/package.json +12 -3
  252. package/src/api/client.ts +394 -171
  253. package/src/api/debug.ts +10 -1
  254. package/src/api/index.ts +0 -2
  255. package/src/api/polling.ts +28 -7
  256. package/src/api/schemas.ts +387 -0
  257. package/src/api/types.ts +72 -136
  258. package/src/constants.ts +10 -0
  259. package/src/index.ts +40 -19
  260. package/src/plugins/api/index.ts +47 -0
  261. package/src/plugins/apps/index.ts +25 -19
  262. package/src/plugins/apps/types.ts +7 -11
  263. package/src/plugins/fetch/index.ts +48 -40
  264. package/src/plugins/findFirstAuthentication/index.test.ts +206 -0
  265. package/src/plugins/findFirstAuthentication/index.ts +55 -0
  266. package/src/plugins/findFirstAuthentication/schemas.ts +41 -0
  267. package/src/plugins/findUniqueAuthentication/index.test.ts +197 -0
  268. package/src/plugins/findUniqueAuthentication/index.ts +72 -0
  269. package/src/plugins/findUniqueAuthentication/schemas.ts +42 -0
  270. package/src/plugins/getAction/index.test.ts +239 -0
  271. package/src/plugins/getAction/index.ts +57 -0
  272. package/src/plugins/getAction/schemas.ts +33 -0
  273. package/src/plugins/getApp/index.test.ts +127 -0
  274. package/src/plugins/getApp/index.ts +66 -0
  275. package/src/plugins/getApp/schemas.ts +38 -0
  276. package/src/plugins/getAuthentication/index.test.ts +284 -0
  277. package/src/plugins/getAuthentication/index.ts +86 -0
  278. package/src/plugins/getAuthentication/schemas.ts +31 -0
  279. package/src/plugins/getProfile/index.ts +55 -0
  280. package/src/plugins/getProfile/schemas.ts +26 -0
  281. package/src/plugins/listActions/index.test.ts +582 -0
  282. package/src/plugins/listActions/index.ts +115 -0
  283. package/src/plugins/listActions/schemas.ts +54 -0
  284. package/src/plugins/listApps/index.test.ts +357 -0
  285. package/src/plugins/listApps/index.ts +121 -0
  286. package/src/plugins/listApps/schemas.ts +49 -0
  287. package/src/plugins/listAuthentications/index.test.ts +709 -0
  288. package/src/plugins/listAuthentications/index.ts +136 -0
  289. package/src/plugins/listAuthentications/schemas.ts +60 -0
  290. package/src/plugins/listInputFields/index.test.ts +408 -0
  291. package/src/plugins/listInputFields/index.ts +204 -0
  292. package/src/plugins/listInputFields/schemas.ts +56 -0
  293. package/src/plugins/registry/index.ts +30 -0
  294. package/src/plugins/request/index.test.ts +329 -0
  295. package/src/plugins/request/index.ts +103 -0
  296. package/src/{functions → plugins}/request/schemas.ts +20 -9
  297. package/src/plugins/runAction/index.test.ts +387 -0
  298. package/src/plugins/runAction/index.ts +176 -0
  299. package/src/plugins/runAction/schemas.ts +53 -0
  300. package/src/resolvers/actionKey.ts +6 -4
  301. package/src/resolvers/actionType.ts +7 -2
  302. package/src/resolvers/appKey.ts +1 -1
  303. package/src/resolvers/authenticationId.ts +12 -3
  304. package/src/resolvers/inputs.ts +3 -1
  305. package/src/schemas/Action.ts +18 -12
  306. package/src/schemas/App.ts +11 -19
  307. package/src/schemas/Auth.ts +18 -13
  308. package/src/schemas/Field.ts +106 -11
  309. package/src/schemas/UserProfile.ts +43 -0
  310. package/src/sdk.test.ts +212 -0
  311. package/src/sdk.ts +132 -102
  312. package/src/types/domain.test.ts +50 -0
  313. package/src/types/domain.ts +43 -75
  314. package/src/types/errors.ts +275 -0
  315. package/src/types/functions.ts +27 -0
  316. package/src/types/optional-zapier-sdk-cli-login.d.ts +37 -0
  317. package/src/types/plugin.ts +105 -0
  318. package/src/types/properties.ts +4 -3
  319. package/src/types/sdk.ts +70 -48
  320. package/src/utils/array-utils.test.ts +131 -0
  321. package/src/utils/array-utils.ts +41 -0
  322. package/src/utils/domain-utils.test.ts +239 -0
  323. package/src/utils/domain-utils.ts +283 -0
  324. package/src/utils/function-utils.test.ts +141 -0
  325. package/src/utils/function-utils.ts +245 -0
  326. package/src/utils/pagination-utils.test.ts +620 -0
  327. package/src/utils/pagination-utils.ts +242 -0
  328. package/src/utils/validation.test.ts +50 -0
  329. package/src/utils/validation.ts +44 -0
  330. package/tsconfig.build.json +16 -2
  331. package/tsconfig.json +3 -1
  332. package/tsconfig.tsbuildinfo +1 -0
  333. package/tsup.config.ts +2 -0
  334. package/src/functions/bundleCode/index.ts +0 -78
  335. package/src/functions/bundleCode/info.ts +0 -9
  336. package/src/functions/bundleCode/schemas.ts +0 -30
  337. package/src/functions/findFirstAuthentication/index.ts +0 -24
  338. package/src/functions/findFirstAuthentication/info.ts +0 -9
  339. package/src/functions/findFirstAuthentication/schemas.ts +0 -50
  340. package/src/functions/findUniqueAuthentication/index.ts +0 -35
  341. package/src/functions/findUniqueAuthentication/info.ts +0 -9
  342. package/src/functions/findUniqueAuthentication/schemas.ts +0 -50
  343. package/src/functions/generateTypes/index.ts +0 -363
  344. package/src/functions/generateTypes/info.ts +0 -9
  345. package/src/functions/generateTypes/schemas.ts +0 -31
  346. package/src/functions/getAction/index.ts +0 -33
  347. package/src/functions/getAction/info.ts +0 -9
  348. package/src/functions/getAction/schemas.ts +0 -25
  349. package/src/functions/getApp/index.ts +0 -41
  350. package/src/functions/getApp/info.ts +0 -9
  351. package/src/functions/getApp/schemas.ts +0 -20
  352. package/src/functions/getAuthentication/index.ts +0 -50
  353. package/src/functions/getAuthentication/info.ts +0 -9
  354. package/src/functions/getAuthentication/schemas.ts +0 -29
  355. package/src/functions/listActions/index.ts +0 -149
  356. package/src/functions/listActions/info.ts +0 -9
  357. package/src/functions/listActions/schemas.ts +0 -30
  358. package/src/functions/listApps/index.ts +0 -60
  359. package/src/functions/listApps/info.ts +0 -9
  360. package/src/functions/listApps/schemas.ts +0 -32
  361. package/src/functions/listAuthentications/index.ts +0 -162
  362. package/src/functions/listAuthentications/info.ts +0 -9
  363. package/src/functions/listAuthentications/schemas.ts +0 -50
  364. package/src/functions/listFields/index.ts +0 -86
  365. package/src/functions/listFields/info.ts +0 -9
  366. package/src/functions/listFields/schemas.ts +0 -36
  367. package/src/functions/request/index.ts +0 -150
  368. package/src/functions/request/info.ts +0 -11
  369. package/src/functions/runAction/index.ts +0 -127
  370. package/src/functions/runAction/info.ts +0 -9
  371. package/src/functions/runAction/schemas.ts +0 -34
  372. package/src/plugins/apps/info.ts +0 -12
  373. package/src/plugins/fetch/types.ts +0 -2
  374. /package/src/{schema-utils.ts → utils/schema-utils.ts} +0 -0
package/dist/index.mjs CHANGED
@@ -1,21 +1,6 @@
1
1
  import { z } from 'zod';
2
2
 
3
- // src/types/domain.ts
4
- var ZapierSdkError = class extends Error {
5
- constructor(message, code) {
6
- super(message);
7
- this.code = code;
8
- this.name = "ZapierSdkError";
9
- }
10
- };
11
- var AppNotFoundError = class extends ZapierSdkError {
12
- constructor(appKey) {
13
- super(`App "${appKey}" not found`);
14
- this.name = "AppNotFoundError";
15
- this.code = "APP_NOT_FOUND";
16
- this.appKey = appKey;
17
- }
18
- };
3
+ // src/types/properties.ts
19
4
  function withFormatter(schema, formatMeta) {
20
5
  schema._def.formatMeta = formatMeta;
21
6
  return schema;
@@ -41,9 +26,12 @@ function isPositional(schema) {
41
26
  return false;
42
27
  }
43
28
 
29
+ // src/constants.ts
30
+ var MAX_PAGE_LIMIT = 1e4;
31
+
44
32
  // src/types/properties.ts
45
33
  var AppKeyPropertySchema = withPositional(
46
- z.string().min(1).describe("App slug (e.g., 'slack', 'github')")
34
+ z.string().min(1).describe("App key (e.g., 'SlackCLIAPI')")
47
35
  );
48
36
  var ActionTypePropertySchema = z.enum([
49
37
  "read",
@@ -58,20 +46,155 @@ var ActionTypePropertySchema = z.enum([
58
46
  var ActionKeyPropertySchema = z.string().min(1).describe("Action key to execute");
59
47
  var AuthenticationIdPropertySchema = z.number().int().describe("Authentication ID to use for this action");
60
48
  var InputsPropertySchema = z.record(z.any()).describe("Input parameters for the action");
61
- var LimitPropertySchema = z.number().int().min(1).max(1e3).default(50).describe("Maximum number of items to return");
49
+ var LimitPropertySchema = z.number().int().min(1).max(MAX_PAGE_LIMIT).default(50).describe("Maximum number of items to return");
62
50
  var OffsetPropertySchema = z.number().int().min(0).default(0).describe("Number of items to skip for pagination");
63
51
  var OutputPropertySchema = z.string().describe("Output file path");
64
52
  var DebugPropertySchema = z.boolean().default(false).describe("Enable debug logging");
65
53
  var ParamsPropertySchema = z.record(z.any()).describe("Additional parameters");
66
54
 
55
+ // src/types/errors.ts
56
+ var ZapierError = class extends Error {
57
+ constructor(message, options = {}) {
58
+ super(message);
59
+ this.statusCode = options.statusCode;
60
+ this.errors = options.errors;
61
+ this.cause = options.cause;
62
+ this.response = options.response;
63
+ Object.setPrototypeOf(this, new.target.prototype);
64
+ }
65
+ };
66
+ var ZapierApiError = class extends ZapierError {
67
+ constructor(message, options = {}) {
68
+ super(message, options);
69
+ this.name = "ZapierApiError";
70
+ }
71
+ };
72
+ var ZapierAppNotFoundError = class extends ZapierError {
73
+ constructor(message, options = {}) {
74
+ super(message, options);
75
+ this.name = "ZapierAppNotFoundError";
76
+ this.appKey = options.appKey;
77
+ }
78
+ };
79
+ var ZapierValidationError = class extends ZapierError {
80
+ constructor(message, options = {}) {
81
+ super(message, options);
82
+ this.name = "ZapierValidationError";
83
+ this.details = options.details;
84
+ }
85
+ };
86
+ var ZapierUnknownError = class extends ZapierError {
87
+ constructor(message, options = {}) {
88
+ super(message, options);
89
+ this.name = "ZapierUnknownError";
90
+ }
91
+ };
92
+ var ZapierAuthenticationError = class extends ZapierError {
93
+ constructor(message, options = {}) {
94
+ super(message, options);
95
+ this.name = "ZapierAuthenticationError";
96
+ }
97
+ };
98
+ var ZapierResourceNotFoundError = class extends ZapierError {
99
+ constructor(message, options = {}) {
100
+ super(message, options);
101
+ this.name = "ZapierResourceNotFoundError";
102
+ this.resourceType = options.resourceType;
103
+ this.resourceId = options.resourceId;
104
+ }
105
+ };
106
+ var ZapierConfigurationError = class extends ZapierError {
107
+ constructor(message, options = {}) {
108
+ super(message, options);
109
+ this.name = "ZapierConfigurationError";
110
+ this.configType = options.configType;
111
+ }
112
+ };
113
+ var ZapierBundleError = class extends ZapierError {
114
+ constructor(message, options = {}) {
115
+ super(message, options);
116
+ this.name = "ZapierBundleError";
117
+ this.buildErrors = options.buildErrors;
118
+ }
119
+ };
120
+ var ZapierTimeoutError = class extends ZapierError {
121
+ constructor(message, options = {}) {
122
+ super(message, options);
123
+ this.name = "ZapierTimeoutError";
124
+ this.attempts = options.attempts;
125
+ this.maxAttempts = options.maxAttempts;
126
+ }
127
+ };
128
+ var ZapierActionError = class extends ZapierError {
129
+ constructor(message, options = {}) {
130
+ super(message, options);
131
+ this.name = "ZapierActionError";
132
+ this.appKey = options.appKey;
133
+ this.actionKey = options.actionKey;
134
+ }
135
+ // Legacy accessor for backward compatibility
136
+ get actionErrors() {
137
+ return this.errors;
138
+ }
139
+ };
140
+ var ZapierNotFoundError = class extends ZapierError {
141
+ constructor(message, options = {}) {
142
+ super(message, options);
143
+ this.name = "ZapierNotFoundError";
144
+ }
145
+ };
146
+ function formatErrorMessage(error) {
147
+ let message = error.message;
148
+ if (error.errors && error.errors.length > 0) {
149
+ const additionalErrors = error.errors.slice(1);
150
+ if (additionalErrors.length > 0) {
151
+ const errorDetails = additionalErrors.map((err) => ` \u2022 ${err.detail || err.title || err.code}`).join("\n");
152
+ message += "\n\nAdditional errors:\n" + errorDetails;
153
+ }
154
+ }
155
+ if (error instanceof ZapierAppNotFoundError && error.appKey) {
156
+ message += `
157
+ App key: ${error.appKey}`;
158
+ }
159
+ if (error instanceof ZapierActionError && (error.appKey || error.actionKey)) {
160
+ const context = [];
161
+ if (error.appKey) context.push(`App: ${error.appKey}`);
162
+ if (error.actionKey) context.push(`Action: ${error.actionKey}`);
163
+ message += `
164
+ ${context.join(", ")}`;
165
+ }
166
+ if (error instanceof ZapierResourceNotFoundError && (error.resourceType || error.resourceId)) {
167
+ const context = [];
168
+ if (error.resourceType) context.push(`Type: ${error.resourceType}`);
169
+ if (error.resourceId) context.push(`ID: ${error.resourceId}`);
170
+ message += `
171
+ ${context.join(", ")}`;
172
+ }
173
+ if (error instanceof ZapierTimeoutError && (error.attempts || error.maxAttempts)) {
174
+ const context = [];
175
+ if (error.attempts) context.push(`Attempts: ${error.attempts}`);
176
+ if (error.maxAttempts) context.push(`Max attempts: ${error.maxAttempts}`);
177
+ message += `
178
+ ${context.join(", ")}`;
179
+ }
180
+ if (error instanceof ZapierBundleError && error.buildErrors && error.buildErrors.length > 0) {
181
+ message += "\n\nBuild errors:\n" + error.buildErrors.map((err) => ` \u2022 ${err}`).join("\n");
182
+ }
183
+ if (error.statusCode && !message.includes(`${error.statusCode}`)) {
184
+ message += `
185
+ HTTP Status: ${error.statusCode}`;
186
+ }
187
+ return message;
188
+ }
189
+
67
190
  // src/plugins/apps/index.ts
68
191
  function createActionFunction(appKey, actionType, actionKey, options, pinnedAuthId) {
69
- return async (actionOptions = {}) => {
192
+ return (actionOptions = {}) => {
70
193
  const { sdk } = options;
71
194
  const { inputs, authenticationId: providedAuthenticationId } = actionOptions;
72
195
  const authenticationId = pinnedAuthId || providedAuthenticationId;
73
196
  if (!authenticationId) {
74
- throw new Error(
197
+ throw new ZapierValidationError(
75
198
  `Authentication ID is required. Either use the factory pattern: sdk.apps.${appKey}({ authenticationId }) or provide authenticationId in the action call.`
76
199
  );
77
200
  }
@@ -90,7 +213,7 @@ function createActionTypeProxy(appKey, actionType, options, pinnedAuthId) {
90
213
  const { sdk } = options;
91
214
  const authenticationId = pinnedAuthId || init?.authenticationId;
92
215
  if (!authenticationId) {
93
- throw new Error(
216
+ throw new ZapierValidationError(
94
217
  `Authentication ID is required for fetch. Either use the factory pattern: sdk.apps.${appKey}({ authenticationId }).fetch(...) or provide authenticationId in the fetch call.`
95
218
  );
96
219
  }
@@ -164,57 +287,40 @@ function createAppsProxy(options) {
164
287
  });
165
288
  return appsProxy;
166
289
  }
167
- function createAppsPlugin(options) {
168
- return createAppsProxy(options);
169
- }
290
+ var appsPlugin = ({ sdk }) => {
291
+ return {
292
+ apps: createAppsProxy({ sdk })
293
+ };
294
+ };
170
295
 
171
296
  // src/plugins/fetch/index.ts
172
- function createFetchPlugin(options) {
173
- const { sdk } = options;
174
- return async function fetch(url, init) {
175
- const {
176
- authenticationId,
177
- callbackUrl,
178
- authenticationTemplate,
179
- ...fetchInit
180
- } = init || {};
181
- return sdk.request({
182
- url: url.toString(),
183
- method: fetchInit.method,
184
- body: fetchInit.body,
185
- headers: fetchInit.headers,
186
- authenticationId,
187
- callbackUrl,
188
- authenticationTemplate
189
- });
297
+ var fetchPlugin = ({ sdk }) => {
298
+ return {
299
+ fetch: async function fetch(url, init) {
300
+ const {
301
+ authenticationId,
302
+ callbackUrl,
303
+ authenticationTemplate,
304
+ ...fetchInit
305
+ } = init || {};
306
+ return sdk.request({
307
+ url: url.toString(),
308
+ method: fetchInit.method,
309
+ body: fetchInit.body,
310
+ headers: fetchInit.headers,
311
+ authenticationId,
312
+ callbackUrl,
313
+ authenticationTemplate
314
+ });
315
+ }
190
316
  };
191
- }
192
-
193
- // src/auth.ts
194
- function getTokenFromEnv() {
195
- return process.env.ZAPIER_TOKEN;
196
- }
197
- async function getTokenFromCliLogin(options = {}) {
198
- try {
199
- const { getToken } = await import('@zapier/zapier-sdk-cli-login');
200
- return await getToken(options);
201
- } catch {
202
- return void 0;
203
- }
204
- }
205
- async function getTokenFromEnvOrConfig(options = {}) {
206
- const envToken = getTokenFromEnv();
207
- if (envToken) {
208
- return envToken;
209
- }
210
- return getTokenFromCliLogin(options);
211
- }
317
+ };
212
318
 
213
319
  // src/resolvers/appKey.ts
214
320
  var appKeyResolver = {
215
321
  type: "static",
216
322
  inputType: "text",
217
- placeholder: "Enter app slug (e.g., 'slack', 'github')"
323
+ placeholder: "Enter app key (e.g., 'SlackCLIAPI' or slug like 'github')"
218
324
  };
219
325
 
220
326
  // src/resolvers/actionType.ts
@@ -222,8 +328,12 @@ var actionTypeResolver = {
222
328
  type: "dynamic",
223
329
  depends: ["appKey"],
224
330
  fetch: async (sdk, resolvedParams) => {
225
- const actions = await sdk.listActions({ appKey: resolvedParams.appKey });
226
- const types = [...new Set(actions.map((action) => action.type))];
331
+ const actionsResponse = await sdk.listActions({
332
+ appKey: resolvedParams.appKey
333
+ });
334
+ const types = [
335
+ ...new Set(actionsResponse.data.map((action) => action.action_type))
336
+ ];
227
337
  return types.map((type) => ({ key: type, name: type }));
228
338
  },
229
339
  prompt: (types) => ({
@@ -242,9 +352,11 @@ var actionKeyResolver = {
242
352
  type: "dynamic",
243
353
  depends: ["appKey", "actionType"],
244
354
  fetch: async (sdk, resolvedParams) => {
245
- const actions = await sdk.listActions({ appKey: resolvedParams.appKey });
246
- return actions.filter(
247
- (action) => action.type === resolvedParams.actionType
355
+ const actionsResponse = await sdk.listActions({
356
+ appKey: resolvedParams.appKey
357
+ });
358
+ return actionsResponse.data.filter(
359
+ (action) => action.action_type === resolvedParams.actionType
248
360
  );
249
361
  },
250
362
  prompt: (actions) => ({
@@ -252,7 +364,7 @@ var actionKeyResolver = {
252
364
  name: "actionKey",
253
365
  message: "Select action:",
254
366
  choices: actions.map((action) => ({
255
- name: `${action.name || action.key} - ${action.description || "No description"}`,
367
+ name: `${action.title || action.name || action.key} - ${action.description || "No description"}`,
256
368
  value: action.key
257
369
  }))
258
370
  })
@@ -263,10 +375,19 @@ var authenticationIdResolver = {
263
375
  type: "dynamic",
264
376
  depends: ["appKey"],
265
377
  fetch: async (sdk, resolvedParams) => {
266
- return await sdk.listAuthentications({
378
+ const myAuths = await sdk.listAuthentications({
379
+ appKey: resolvedParams.appKey,
380
+ maxItems: 1e3,
381
+ owner: "me"
382
+ });
383
+ const allAuths = await sdk.listAuthentications({
267
384
  appKey: resolvedParams.appKey,
268
- limit: 1e3
385
+ maxItems: 1e3
269
386
  });
387
+ const otherAuths = allAuths.data.filter(
388
+ (auth) => !myAuths.data.some((myAuth) => myAuth.id === auth.id)
389
+ );
390
+ return [...myAuths.data, ...otherAuths];
270
391
  },
271
392
  prompt: (auths, params) => ({
272
393
  type: "list",
@@ -290,12 +411,15 @@ var inputsResolver = {
290
411
  type: "fields",
291
412
  depends: ["appKey", "actionKey", "actionType", "authenticationId"],
292
413
  fetch: async (sdk, resolvedParams) => {
293
- return await sdk.listFields({
414
+ const fieldsResponse = await sdk.listInputFields({
294
415
  appKey: resolvedParams.appKey,
295
416
  actionKey: resolvedParams.actionKey,
296
417
  actionType: resolvedParams.actionType,
297
- authenticationId: resolvedParams.authenticationId
418
+ authenticationId: resolvedParams.authenticationId,
419
+ inputs: resolvedParams.inputs
420
+ // Pass along currently resolved inputs
298
421
  });
422
+ return fieldsResponse.data;
299
423
  }
300
424
  };
301
425
 
@@ -360,6 +484,59 @@ function getResolutionOrderForParams(paramNames) {
360
484
  return order;
361
485
  }
362
486
 
487
+ // src/auth.ts
488
+ function getTokenFromEnv() {
489
+ return process.env.ZAPIER_TOKEN;
490
+ }
491
+ async function getTokenFromCliLogin(options = {}) {
492
+ try {
493
+ const { getToken } = await import('@zapier/zapier-sdk-cli-login');
494
+ return await getToken(options);
495
+ } catch {
496
+ return void 0;
497
+ }
498
+ }
499
+ async function getTokenFromEnvOrConfig(options = {}) {
500
+ const envToken = getTokenFromEnv();
501
+ if (envToken) {
502
+ return envToken;
503
+ }
504
+ return getTokenFromCliLogin(options);
505
+ }
506
+ var RelayRequestSchema = z.object({
507
+ url: z.string().url().describe("The URL to request (will be proxied through Relay)"),
508
+ method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method"),
509
+ body: z.any().optional().describe("Request body as a string"),
510
+ authenticationId: z.number().int().optional().describe("Zapier authentication ID to use for the request"),
511
+ callbackUrl: z.string().url().optional().describe("URL to send async response to (makes request async)"),
512
+ authenticationTemplate: z.string().optional().describe(
513
+ "Optional JSON string authentication template to bypass Notary lookup"
514
+ ),
515
+ headers: z.union([
516
+ z.record(z.string()),
517
+ z.instanceof(Headers),
518
+ z.array(z.tuple([z.string(), z.string()]))
519
+ ]).optional().describe("Request headers")
520
+ }).extend({
521
+ relayBaseUrl: z.string().optional().describe("Base URL for Relay service")
522
+ }).describe("Make authenticated HTTP requests through Zapier's Relay service");
523
+ var RelayFetchSchema = RelayRequestSchema;
524
+
525
+ // src/plugins/registry/index.ts
526
+ var registryPlugin = ({ sdk, context }) => {
527
+ const metaKeys = Object.keys(context.meta || {});
528
+ const registryEntries = metaKeys.map((key) => {
529
+ return {
530
+ ...context.meta[key],
531
+ name: key,
532
+ implementation: sdk[key]
533
+ };
534
+ });
535
+ return {
536
+ __registry: registryEntries
537
+ };
538
+ };
539
+
363
540
  // src/api/auth.ts
364
541
  function isJwt(token) {
365
542
  const parts = token.split(".");
@@ -394,7 +571,13 @@ function createDebugFetch(options) {
394
571
  const method = options2?.method || "GET";
395
572
  debugLog(`\u2192 ${method} ${url}`, {
396
573
  headers: options2?.headers,
397
- body: options2?.body ? JSON.parse(options2.body) : void 0
574
+ body: options2?.body && typeof options2.body === "string" ? (() => {
575
+ try {
576
+ return JSON.parse(options2.body);
577
+ } catch {
578
+ return options2.body;
579
+ }
580
+ })() : options2?.body
398
581
  });
399
582
  try {
400
583
  const response = await originalFetch(input, options2);
@@ -429,1168 +612,1360 @@ async function pollUntilComplete(options) {
429
612
  resultExtractor = (response) => response
430
613
  } = options;
431
614
  let delay = initialDelay;
615
+ let errorCount = 0;
432
616
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
433
617
  const response = await fetchPoll();
434
618
  if (response.status === successStatus) {
619
+ errorCount = 0;
435
620
  const result = await response.json();
436
621
  return resultExtractor(result);
437
622
  } else if (response.status === pendingStatus) {
623
+ errorCount = 0;
438
624
  if (attempt < maxAttempts - 1) {
439
625
  await new Promise((resolve) => setTimeout(resolve, delay));
440
626
  delay = Math.min(delay * 2, maxDelay);
441
627
  continue;
442
628
  }
443
629
  } else {
444
- throw new Error(
445
- `Poll request failed: ${response.status} ${response.statusText}`
446
- );
630
+ errorCount++;
631
+ if (errorCount >= 3) {
632
+ throw new ZapierApiError(
633
+ `Poll request failed: ${response.status} ${response.statusText}`,
634
+ { statusCode: response.status }
635
+ );
636
+ }
637
+ if (attempt < maxAttempts - 1) {
638
+ await new Promise((resolve) => setTimeout(resolve, delay));
639
+ delay = Math.min(delay * 2, maxDelay);
640
+ continue;
641
+ }
447
642
  }
448
643
  }
449
- throw new Error(`Operation timed out after ${maxAttempts} attempts`);
644
+ throw new ZapierTimeoutError(
645
+ `Operation timed out after ${maxAttempts} attempts`,
646
+ { attempts: maxAttempts, maxAttempts }
647
+ );
450
648
  }
451
649
 
452
650
  // src/api/client.ts
453
- var SUBDOMAIN_PREFIXES = {
651
+ var SubdomainConfigMap = {
652
+ // e.g. https://relay.zapier.com
454
653
  relay: {
455
654
  authHeader: "X-Relay-Authorization"
456
655
  }
457
656
  };
458
- function createZapierApi(options) {
459
- const {
460
- baseUrl,
461
- token,
462
- getToken,
463
- debug = false,
464
- fetch: originalFetch = globalThis.fetch,
465
- onEvent
466
- } = options;
467
- const debugLog = createDebugLogger(debug);
468
- const fetch = createDebugFetch({ originalFetch, debugLog });
469
- function buildUrl(path, searchParams) {
470
- const pathSegments = path.split("/").filter(Boolean);
471
- let finalBaseUrl = baseUrl;
472
- let subdomainConfig;
473
- if (pathSegments.length > 0 && pathSegments[0] in SUBDOMAIN_PREFIXES) {
474
- const subdomain = pathSegments[0];
475
- subdomainConfig = SUBDOMAIN_PREFIXES[subdomain];
476
- const baseUrlObj = new URL(baseUrl);
477
- baseUrlObj.hostname = `${subdomain}.${baseUrlObj.hostname}`;
478
- finalBaseUrl = baseUrlObj.toString();
479
- path = "/" + pathSegments.slice(1).join("/");
480
- }
481
- const url = new URL(path, finalBaseUrl);
482
- if (searchParams) {
483
- Object.entries(searchParams).forEach(([key, value]) => {
484
- url.searchParams.set(key, value);
657
+ var ZapierApiClient = class {
658
+ constructor(options) {
659
+ this.options = options;
660
+ this.fetch = async (path, init) => {
661
+ return this.plainFetch(path, init);
662
+ };
663
+ this.get = async (path, options = {}) => {
664
+ return this.fetchJson("GET", path, void 0, options);
665
+ };
666
+ this.post = async (path, data, options = {}) => {
667
+ return this.fetchJson("POST", path, data, options);
668
+ };
669
+ this.put = async (path, data, options = {}) => {
670
+ return this.fetchJson("PUT", path, data, options);
671
+ };
672
+ this.delete = async (path, options = {}) => {
673
+ return this.fetchJson("DELETE", path, void 0, options);
674
+ };
675
+ this.poll = async (path, options = {}) => {
676
+ return pollUntilComplete({
677
+ fetchPoll: () => this.plainFetch(path, {
678
+ method: "GET",
679
+ searchParams: options.searchParams,
680
+ authRequired: options.authRequired
681
+ }),
682
+ maxAttempts: options.maxAttempts,
683
+ initialDelay: options.initialDelay,
684
+ maxDelay: options.maxDelay,
685
+ successStatus: options.successStatus,
686
+ pendingStatus: options.pendingStatus,
687
+ resultExtractor: options.resultExtractor
485
688
  });
689
+ };
690
+ }
691
+ // Helper to parse response data
692
+ async parseResult(response) {
693
+ try {
694
+ return { type: "json", data: await response.json() };
695
+ } catch {
696
+ return { type: "text", data: await response.text() };
486
697
  }
487
- return { url: url.toString(), subdomainConfig };
488
698
  }
489
- async function buildHeaders(options2 = {}, subdomainConfig) {
490
- const headers = {
491
- ...options2.headers
492
- };
493
- if (options2.authRequired !== false) {
494
- let resolvedToken = token;
495
- if (!resolvedToken && getToken) {
496
- resolvedToken = await getToken();
497
- }
498
- if (!resolvedToken) {
499
- resolvedToken = await getTokenFromEnvOrConfig({
500
- onEvent,
501
- fetch: originalFetch
502
- });
503
- }
504
- if (resolvedToken) {
505
- const authHeaderName = subdomainConfig?.authHeader || "Authorization";
506
- headers[authHeaderName] = getAuthorizationHeader(resolvedToken);
699
+ // Helper to get a token from the different places it could be gotten
700
+ async getAuthToken() {
701
+ if (this.options.token) {
702
+ return this.options.token;
703
+ }
704
+ if (this.options.getToken) {
705
+ const token = await this.options.getToken();
706
+ if (token) {
707
+ return token;
507
708
  }
508
709
  }
509
- return headers;
710
+ return getTokenFromEnvOrConfig({
711
+ onEvent: this.options.onEvent,
712
+ fetch: this.options.fetch
713
+ });
510
714
  }
511
- async function handleResponse(response, customErrorHandler, hadAuthToken) {
512
- if (!response.ok) {
513
- if (customErrorHandler) {
514
- const customError = customErrorHandler(response);
515
- if (customError) {
715
+ // Helper to handle responses
716
+ async handleResponse(params) {
717
+ const { response, customErrorHandler, wasMissingAuthToken } = params;
718
+ const { data: responseData } = await this.parseResult(response);
719
+ if (response.ok) {
720
+ return responseData;
721
+ }
722
+ const errorInfo = {
723
+ status: response.status,
724
+ statusText: response.statusText,
725
+ data: responseData
726
+ };
727
+ if (customErrorHandler) {
728
+ const customError = customErrorHandler(errorInfo);
729
+ if (customError) {
730
+ if (customError instanceof Error) {
516
731
  throw customError;
732
+ } else {
733
+ throw new Error(
734
+ `customErrorHandler returned a non-Error: ${JSON.stringify(customError)}`
735
+ );
517
736
  }
518
737
  }
519
- if (response.status >= 400 && response.status < 500 && true) {
520
- throw new Error(
521
- `Authentication required (HTTP ${response.status}). Please provide a token in options or set ZAPIER_TOKEN environment variable.`
738
+ }
739
+ const { message, errors } = this.parseErrorResponse(errorInfo);
740
+ const errorOptions = {
741
+ statusCode: response.status,
742
+ errors
743
+ };
744
+ if (response.status === 404) {
745
+ throw new ZapierNotFoundError(message, errorOptions);
746
+ }
747
+ if (response.status === 401 || response.status === 403) {
748
+ if (wasMissingAuthToken) {
749
+ throw new ZapierAuthenticationError(
750
+ `Authentication required (HTTP ${response.status}). Please provide a token in options or set ZAPIER_TOKEN environment variable.`,
751
+ errorOptions
522
752
  );
523
753
  }
524
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
754
+ throw new ZapierAuthenticationError(message, errorOptions);
755
+ }
756
+ if (response.status === 400) {
757
+ throw new ZapierValidationError(message, errorOptions);
758
+ }
759
+ throw new ZapierApiError(message, errorOptions);
760
+ }
761
+ hasErrorArray(data) {
762
+ return typeof data === "object" && data !== null && "errors" in data && Array.isArray(data.errors);
763
+ }
764
+ // Helper to check if data has API errors
765
+ isApiErrorArray(dataArray) {
766
+ const data = dataArray[0];
767
+ return typeof data === "object" && data !== null && "message" in data && "code" in data && "title" in data && "detail" in data;
768
+ }
769
+ // Do our best to extract an error message from the response data
770
+ extractErrorMessage(data) {
771
+ if (typeof data === "string") {
772
+ return data;
773
+ }
774
+ if (typeof data === "object" && data !== null) {
775
+ if ("message" in data && typeof data.message === "string") {
776
+ return data.message;
777
+ }
778
+ if ("error" in data) {
779
+ if (typeof data.error === "string") {
780
+ return data.error;
781
+ }
782
+ if (typeof data.error === "object" && data.error !== null) {
783
+ if ("message" in data.error && typeof data.error.message === "string") {
784
+ return data.error.message;
785
+ }
786
+ }
787
+ try {
788
+ return JSON.stringify(data.error);
789
+ } catch {
790
+ }
791
+ }
792
+ if ("errors" in data && Array.isArray(data.errors)) {
793
+ if (this.isApiErrorArray(data.errors)) {
794
+ return data.errors[0].detail || data.errors[0].title;
795
+ }
796
+ }
525
797
  }
798
+ return void 0;
799
+ }
800
+ // Helper to parse API error response
801
+ parseErrorResponse(errorInfo) {
802
+ const fallbackMessage = `HTTP ${errorInfo.status}: ${errorInfo.statusText}`;
526
803
  try {
527
- return await response.json();
804
+ if (typeof errorInfo.data === "string") {
805
+ return { message: `${fallbackMessage}: ${errorInfo.data}` };
806
+ }
807
+ const errorMessage = this.extractErrorMessage(errorInfo.data) || fallbackMessage;
808
+ if (this.hasErrorArray(errorInfo.data)) {
809
+ if (this.isApiErrorArray(errorInfo.data.errors)) {
810
+ return {
811
+ message: errorMessage,
812
+ errors: errorInfo.data.errors
813
+ };
814
+ } else {
815
+ return {
816
+ message: errorMessage,
817
+ errors: errorInfo.data.errors.map((e) => ({
818
+ status: errorInfo.status,
819
+ code: String(errorInfo.status),
820
+ title: errorInfo.statusText,
821
+ detail: JSON.stringify(e)
822
+ }))
823
+ };
824
+ }
825
+ }
826
+ return { message: errorMessage };
528
827
  } catch {
529
- return await response.text();
828
+ return { message: fallbackMessage };
530
829
  }
531
830
  }
532
- async function plainFetch(path, init) {
533
- if (!path.startsWith("/")) {
534
- throw new Error(
535
- `plainFetch expects a path starting with '/', got: ${path}`
536
- );
831
+ // Check if this is a path that needs subdomain routing
832
+ // e.g. /relay/workflows -> relay.zapier.com/workflows
833
+ applySubdomainBehavior(path) {
834
+ const pathSegments = path.split("/").filter(Boolean);
835
+ if (pathSegments.length > 0 && pathSegments[0] in SubdomainConfigMap) {
836
+ const domainPrefix = pathSegments[0];
837
+ const subdomainConfig = SubdomainConfigMap[domainPrefix];
838
+ const originalBaseUrl = new URL(this.options.baseUrl);
839
+ const finalBaseUrl = `https://${domainPrefix}.${originalBaseUrl.hostname}`;
840
+ const pathWithoutPrefix = "/" + pathSegments.slice(1).join("/");
841
+ return { url: new URL(pathWithoutPrefix, finalBaseUrl), subdomainConfig };
537
842
  }
538
- const { url, subdomainConfig } = buildUrl(path, init?.searchParams);
539
- const headers = await buildHeaders(init, subdomainConfig);
540
- const finalHeaders = {
541
- ...headers,
542
- ...init?.headers ? init.headers instanceof Headers ? Object.fromEntries(init.headers.entries()) : init.headers : {}
843
+ return {
844
+ url: new URL(path, this.options.baseUrl),
845
+ subdomainConfig: void 0
543
846
  };
544
- return await fetch(url, {
545
- ...init,
546
- headers: finalHeaders
547
- });
548
847
  }
549
- async function fetchJson(method, path, data, options2 = {}) {
550
- const headers = { ...options2.headers };
848
+ // Helper to build full URLs and return routing info
849
+ buildUrl(path, searchParams) {
850
+ const { url, subdomainConfig } = this.applySubdomainBehavior(path);
851
+ if (searchParams) {
852
+ Object.entries(searchParams).forEach(([key, value]) => {
853
+ url.searchParams.set(key, value);
854
+ });
855
+ }
856
+ return { url: url.toString(), subdomainConfig };
857
+ }
858
+ // Helper to build headers
859
+ async buildHeaders(options = {}, subdomainConfig) {
860
+ const headers = new Headers(options.headers ?? {});
861
+ const authToken = await this.getAuthToken();
862
+ if (authToken) {
863
+ const authHeaderName = subdomainConfig?.authHeader || "Authorization";
864
+ headers.set(authHeaderName, getAuthorizationHeader(authToken));
865
+ }
866
+ if (options.authRequired) {
867
+ if (headers.get("Authorization") == null && authToken == null) {
868
+ throw new ZapierAuthenticationError(
869
+ `Authentication required but no token available. Please set ZAPIER_TOKEN, or run the 'login' command with the CLI.`
870
+ );
871
+ }
872
+ }
873
+ return headers;
874
+ }
875
+ // Helper to perform HTTP requests with JSON handling
876
+ async fetchJson(method, path, data, options = {}) {
877
+ const headers = { ...options.headers };
551
878
  if (data && typeof data === "object") {
552
879
  headers["Content-Type"] = "application/json";
553
880
  }
554
- const response = await plainFetch(path, {
881
+ const wasMissingAuthToken = options.authRequired && await this.getAuthToken() == null;
882
+ const response = await this.plainFetch(path, {
883
+ ...options,
555
884
  method,
556
- body: data ? JSON.stringify(data) : void 0,
557
- headers,
558
- searchParams: options2.searchParams,
559
- authRequired: options2.authRequired
885
+ body: data != null ? JSON.stringify(data) : void 0,
886
+ headers
560
887
  });
561
- return handleResponse(response, options2.customErrorHandler);
888
+ const result = await this.handleResponse({
889
+ response,
890
+ customErrorHandler: options.customErrorHandler,
891
+ wasMissingAuthToken
892
+ });
893
+ if (typeof result === "string") {
894
+ throw new ZapierValidationError(
895
+ `Response could not be parsed as JSON: ${result}`
896
+ );
897
+ }
898
+ return result;
562
899
  }
563
- return {
564
- async get(path, options2 = {}) {
565
- return fetchJson("GET", path, void 0, options2);
566
- },
567
- async post(path, data, options2 = {}) {
568
- return fetchJson("POST", path, data, options2);
569
- },
570
- async put(path, data, options2 = {}) {
571
- return fetchJson("PUT", path, data, options2);
572
- },
573
- async delete(path, options2 = {}) {
574
- return fetchJson("DELETE", path, void 0, options2);
575
- },
576
- async poll(path, options2 = {}) {
577
- return pollUntilComplete({
578
- fetchPoll: () => plainFetch(path, {
579
- method: "GET",
580
- searchParams: options2.searchParams,
581
- authRequired: options2.authRequired
582
- }),
583
- maxAttempts: options2.maxAttempts,
584
- initialDelay: options2.initialDelay,
585
- maxDelay: options2.maxDelay,
586
- successStatus: options2.successStatus,
587
- pendingStatus: options2.pendingStatus,
588
- resultExtractor: options2.resultExtractor
589
- });
590
- },
591
- async fetch(path, init) {
592
- return plainFetch(path, init);
900
+ // Plain fetch method for API paths (must start with /)
901
+ async plainFetch(path, fetchOptions) {
902
+ if (!path.startsWith("/")) {
903
+ throw new ZapierValidationError(
904
+ `plainFetch expects a path starting with '/', got: ${path}`
905
+ );
593
906
  }
594
- };
595
- }
596
-
597
- // src/api/index.ts
598
- function generateRequestId() {
599
- return Math.random().toString(36).substring(2) + Date.now().toString(36);
600
- }
601
- function getOrCreateApiClient(config) {
907
+ if (fetchOptions?.body && typeof fetchOptions.body === "object") {
908
+ fetchOptions.body = JSON.stringify(fetchOptions.body);
909
+ }
910
+ const { url, subdomainConfig } = this.buildUrl(
911
+ path,
912
+ fetchOptions?.searchParams
913
+ );
914
+ const builtHeaders = await this.buildHeaders(
915
+ fetchOptions,
916
+ subdomainConfig
917
+ );
918
+ const inputHeaders = new Headers(fetchOptions?.headers ?? {});
919
+ const mergedHeaders = new Headers();
920
+ builtHeaders.forEach((value, key) => {
921
+ mergedHeaders.set(key, value);
922
+ });
923
+ inputHeaders.forEach((value, key) => {
924
+ mergedHeaders.set(key, value);
925
+ });
926
+ return await this.options.fetch(url, {
927
+ ...fetchOptions,
928
+ headers: mergedHeaders
929
+ });
930
+ }
931
+ };
932
+ var createZapierApi = (options) => {
602
933
  const {
603
- baseUrl = "https://zapier.com",
934
+ baseUrl,
604
935
  token,
605
936
  getToken,
606
- api: providedApi,
607
937
  debug = false,
608
- fetch: customFetch
609
- } = config;
610
- if (providedApi) {
611
- return providedApi;
612
- }
613
- return createZapierApi({
938
+ fetch: originalFetch = globalThis.fetch,
939
+ onEvent
940
+ } = options;
941
+ const debugLog = createDebugLogger(debug);
942
+ const debugFetch = createDebugFetch({ originalFetch, debugLog });
943
+ return new ZapierApiClient({
614
944
  baseUrl,
615
945
  token,
616
946
  getToken,
617
947
  debug,
618
- fetch: customFetch
619
- });
620
- }
621
-
622
- // src/functions/getApp/index.ts
623
- async function getApp(options) {
624
- const api = getOrCreateApiClient(options);
625
- const { appKey } = options;
626
- const app = await api.get(`/api/v4/apps/${appKey}/`, {
627
- customErrorHandler: (response) => {
628
- if (response.status === 404) {
629
- return new AppNotFoundError(appKey);
630
- }
631
- return void 0;
632
- }
948
+ fetch: debugFetch,
949
+ onEvent
633
950
  });
634
- return {
635
- key: app.slug,
636
- name: app.name,
637
- description: app.description,
638
- version: "1.0.0",
639
- category: app.category?.name,
640
- actions: [],
641
- triggers: [],
642
- current_implementation_id: app.current_implementation_id
643
- };
644
- }
951
+ };
645
952
 
646
- // src/functions/listAuthentications/index.ts
647
- async function listAuthentications(options = {}) {
648
- const api = getOrCreateApiClient(options);
649
- const listAuthenticationsInternal = async (options2 = {}) => {
650
- const searchParams = {};
651
- if (options2.appKey) {
652
- try {
653
- const app = await getApp({
654
- appKey: options2.appKey,
655
- api,
656
- token: options2.token,
657
- baseUrl: options2.baseUrl,
658
- debug: options2.debug,
659
- fetch: options2.fetch
660
- });
661
- const selectedApi = app.current_implementation_id;
662
- if (selectedApi) {
663
- const versionlessApi = selectedApi.split("@")[0];
664
- searchParams.versionless_selected_api = versionlessApi;
665
- }
666
- } catch (error) {
667
- if (error instanceof Error && error.name === "AppNotFoundError") {
668
- throw error;
669
- }
670
- console.warn(
671
- `Warning: Could not filter by app ${options2.appKey}:`,
672
- error instanceof Error ? error.message : "Unknown error"
673
- );
674
- }
675
- }
676
- if (options2.search) {
677
- searchParams.search = options2.search;
678
- } else if (options2.title) {
679
- searchParams.search = options2.title;
953
+ // src/plugins/api/index.ts
954
+ var apiPlugin = (params) => {
955
+ const {
956
+ fetch: customFetch = globalThis.fetch,
957
+ baseUrl = "https://zapier.com",
958
+ token,
959
+ getToken,
960
+ onEvent,
961
+ debug = false
962
+ } = params;
963
+ const api = createZapierApi({
964
+ baseUrl,
965
+ token,
966
+ getToken,
967
+ debug,
968
+ fetch: customFetch,
969
+ onEvent
970
+ });
971
+ return {
972
+ context: {
973
+ api
974
+ // Provide API client in context for other plugins to use
680
975
  }
681
- if (options2.account_id) {
682
- searchParams.account_id = options2.account_id;
976
+ };
977
+ };
978
+
979
+ // src/utils/pagination-utils.ts
980
+ var offsetCursorMarker = "$$offset$$";
981
+ function splitOffsetCursor(cursor) {
982
+ if (!cursor) {
983
+ return [0, cursor];
984
+ }
985
+ try {
986
+ const parsedCursor = JSON.parse(cursor);
987
+ if (!Array.isArray(parsedCursor)) {
988
+ return [0, cursor];
683
989
  }
684
- if (options2.owner) {
685
- searchParams.owner = options2.owner;
990
+ const [marker, offset, currentCursor] = parsedCursor;
991
+ if (marker !== offsetCursorMarker) {
992
+ return [0, cursor];
686
993
  }
687
- if (options2.limit) {
688
- searchParams.limit = options2.limit.toString();
994
+ if (typeof offset !== "number") {
995
+ return [0, cursor];
689
996
  }
690
- if (options2.offset) {
691
- searchParams.offset = options2.offset.toString();
997
+ return [offset, currentCursor];
998
+ } catch {
999
+ return [0, cursor];
1000
+ }
1001
+ }
1002
+ function createOffsetCursor(offset, currentCursor) {
1003
+ return JSON.stringify([offsetCursorMarker, offset, currentCursor]);
1004
+ }
1005
+ async function* paginateMaxItems(pageFunction, pageOptions) {
1006
+ let cursor = pageOptions?.cursor;
1007
+ let totalItemsYielded = 0;
1008
+ const maxItems = pageOptions?.maxItems;
1009
+ const pageSize = pageOptions?.pageSize;
1010
+ do {
1011
+ const options = {
1012
+ ...pageOptions || {},
1013
+ cursor,
1014
+ pageSize: maxItems !== void 0 && pageSize !== void 0 ? Math.min(pageSize, maxItems) : pageSize
1015
+ };
1016
+ const page = await pageFunction(options);
1017
+ if (maxItems !== void 0) {
1018
+ const remainingItems = maxItems - totalItemsYielded;
1019
+ if (page.data.length >= remainingItems) {
1020
+ const yieldedPage = {
1021
+ ...page,
1022
+ data: page.data.slice(0, remainingItems),
1023
+ nextCursor: void 0
1024
+ };
1025
+ yield yieldedPage;
1026
+ break;
1027
+ }
692
1028
  }
693
- const data = await api.get(
694
- "/api/v4/authentications/",
695
- {
696
- searchParams,
697
- customErrorHandler: (response) => {
698
- if (response.status === 401) {
699
- return new Error(
700
- `Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${response.status})`
701
- );
702
- }
703
- if (response.status === 403) {
704
- return new Error(
705
- `Access forbidden. Your token may not have the required scopes to list authentications. (HTTP ${response.status})`
706
- );
707
- }
708
- return void 0;
709
- }
1029
+ yield page;
1030
+ totalItemsYielded += page.data.length;
1031
+ cursor = page.nextCursor;
1032
+ } while (cursor);
1033
+ }
1034
+ async function* paginateBuffered(pageFunction, pageOptions) {
1035
+ const pageSize = pageOptions?.pageSize;
1036
+ const [cursorOffset, currentCursor] = splitOffsetCursor(pageOptions?.cursor);
1037
+ const options = {
1038
+ ...pageOptions || {},
1039
+ cursor: currentCursor
1040
+ };
1041
+ const iterator = paginateMaxItems(pageFunction, options);
1042
+ let bufferedPages = [];
1043
+ let isFirstPage = true;
1044
+ let cursor;
1045
+ for await (let page of iterator) {
1046
+ if (isFirstPage) {
1047
+ isFirstPage = false;
1048
+ if (cursorOffset) {
1049
+ page = {
1050
+ ...page,
1051
+ data: page.data.slice(cursorOffset)
1052
+ };
710
1053
  }
1054
+ }
1055
+ if (!pageSize) {
1056
+ yield page;
1057
+ cursor = page.nextCursor;
1058
+ continue;
1059
+ }
1060
+ const bufferedLength = bufferedPages.reduce(
1061
+ (acc, page2) => acc + page2.data.length,
1062
+ 0
711
1063
  );
712
- let auths = data.results || [];
713
- auths = auths.map((auth) => ({
714
- ...auth,
715
- title: auth.title || auth.label || void 0
716
- }));
717
- if (options2.title) {
718
- auths = auths.filter((auth) => auth.title === options2.title);
719
- }
720
- if (auths.length > 0) {
721
- auths.__pagination = {
722
- count: data.count,
723
- hasNext: !!data.next,
724
- hasPrevious: !!data.previous,
725
- nextUrl: data.next,
726
- previousUrl: data.previous
1064
+ if (bufferedLength + page.data.length < pageSize) {
1065
+ bufferedPages.push(page);
1066
+ cursor = page.nextCursor;
1067
+ continue;
1068
+ }
1069
+ const bufferedItems = bufferedPages.map((p) => p.data).flat();
1070
+ const allItems = [...bufferedItems, ...page.data];
1071
+ const pageItems = allItems.slice(0, pageSize);
1072
+ const remainingItems = allItems.slice(pageItems.length);
1073
+ if (remainingItems.length === 0) {
1074
+ yield {
1075
+ ...page,
1076
+ data: pageItems,
1077
+ nextCursor: page.nextCursor
727
1078
  };
1079
+ bufferedPages = [];
1080
+ cursor = page.nextCursor;
1081
+ continue;
728
1082
  }
729
- return auths;
730
- };
731
- if (options.limit && options.owner === void 0) {
732
- const ownedAuths = await listAuthenticationsInternal({
733
- ...options,
734
- owner: "me"
735
- });
736
- if (ownedAuths.length >= options.limit) {
737
- return ownedAuths.slice(0, options.limit);
1083
+ yield {
1084
+ ...page,
1085
+ data: pageItems,
1086
+ nextCursor: createOffsetCursor(
1087
+ page.data.length - remainingItems.length,
1088
+ cursor
1089
+ )
1090
+ };
1091
+ while (remainingItems.length > pageSize) {
1092
+ const pageItems2 = remainingItems.splice(0, pageSize);
1093
+ yield {
1094
+ ...page,
1095
+ data: pageItems2,
1096
+ nextCursor: createOffsetCursor(
1097
+ page.data.length - remainingItems.length,
1098
+ cursor
1099
+ )
1100
+ };
738
1101
  }
739
- const allAuths = await listAuthenticationsInternal({
740
- ...options,
741
- owner: void 0
742
- });
743
- const ownedAuthenticationIds = new Set(ownedAuths.map((auth) => auth.id));
744
- const additionalAuths = allAuths.filter(
745
- (auth) => !ownedAuthenticationIds.has(auth.id)
746
- );
747
- const combined = [...ownedAuths, ...additionalAuths];
748
- return combined.slice(0, options.limit);
1102
+ bufferedPages = [
1103
+ {
1104
+ ...page,
1105
+ data: remainingItems
1106
+ }
1107
+ ];
1108
+ cursor = page.nextCursor;
1109
+ }
1110
+ if (bufferedPages.length > 0) {
1111
+ const lastBufferedPage = bufferedPages.slice(-1)[0];
1112
+ const bufferedItems = bufferedPages.map((p) => p.data).flat();
1113
+ yield {
1114
+ ...lastBufferedPage,
1115
+ data: bufferedItems
1116
+ };
749
1117
  }
750
- return listAuthenticationsInternal(options);
751
1118
  }
1119
+ var paginate = paginateBuffered;
752
1120
 
753
- // src/functions/getAuthentication/index.ts
754
- async function getAuthentication(options) {
755
- const { authenticationId } = options;
756
- const api = getOrCreateApiClient(options);
757
- const data = await api.get(
758
- `/api/v4/authentications/${authenticationId}/`,
759
- {
760
- customErrorHandler: (response) => {
761
- if (response.status === 401) {
762
- return new Error(
763
- `Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${response.status})`
764
- );
765
- }
766
- if (response.status === 403) {
767
- return new Error(
768
- `Access forbidden. Your token may not have the required scopes to get authentication ${authenticationId}. (HTTP ${response.status})`
769
- );
770
- }
771
- if (response.status === 404) {
772
- return new Error(
773
- `Authentication ${authenticationId} not found. It may not exist or you may not have access to it. (HTTP ${response.status})`
774
- );
775
- }
776
- return void 0;
1121
+ // src/utils/validation.ts
1122
+ var validate = (schema, input) => {
1123
+ const result = schema.safeParse(input);
1124
+ if (!result.success) {
1125
+ const errorMessages = result.error.errors.map((error) => {
1126
+ const path = error.path.length > 0 ? error.path.join(".") : "input";
1127
+ return `${path}: ${error.message}`;
1128
+ });
1129
+ const message = `Validation failed:
1130
+ ${errorMessages.join("\n ")}`;
1131
+ throw new ZapierValidationError(message, {
1132
+ details: {
1133
+ zodErrors: result.error.errors,
1134
+ input
777
1135
  }
778
- }
779
- );
780
- return {
781
- ...data,
782
- title: data.title || data.label || void 0
1136
+ });
1137
+ }
1138
+ return result.data;
1139
+ };
1140
+ function createValidator(schema) {
1141
+ return function validateFn(input) {
1142
+ return validate(schema, input);
783
1143
  };
784
1144
  }
1145
+ var validateOptions = (schema, options) => {
1146
+ return validate(schema, options);
1147
+ };
785
1148
 
786
- // src/functions/findFirstAuthentication/index.ts
787
- async function findFirstAuthentication(options = {}) {
788
- const auths = await listAuthentications({
789
- ...options,
790
- limit: 1
791
- });
792
- return auths.length > 0 ? auths[0] : null;
793
- }
794
-
795
- // src/functions/findUniqueAuthentication/index.ts
796
- async function findUniqueAuthentication(options = {}) {
797
- const auths = await listAuthentications({
798
- ...options,
799
- limit: 2
800
- // Get up to 2 to check for uniqueness
801
- });
802
- if (auths.length === 0) {
803
- throw new Error("No authentication found matching the specified criteria");
1149
+ // src/utils/function-utils.ts
1150
+ function extractCursor(data) {
1151
+ if (!data?.next) {
1152
+ return void 0;
804
1153
  }
805
- if (auths.length > 1) {
806
- throw new Error(
807
- "Multiple authentications found matching the specified criteria. Expected exactly one."
808
- );
1154
+ try {
1155
+ const urlObj = new URL(data.next);
1156
+ const offset = urlObj.searchParams.get("offset");
1157
+ return offset || void 0;
1158
+ } catch {
1159
+ return void 0;
809
1160
  }
810
- return auths[0];
811
1161
  }
812
-
813
- // src/functions/listApps/index.ts
814
- async function listApps(options = {}) {
815
- const api = getOrCreateApiClient(options);
816
- const searchParams = {};
817
- if (options.category) {
818
- searchParams.category = options.category;
819
- }
820
- if (options.limit) {
821
- searchParams.limit = options.limit.toString();
822
- }
823
- if (options.offset) {
824
- searchParams.offset = options.offset.toString();
825
- }
826
- const data = await api.get("/api/v4/apps/", { searchParams });
827
- const apps = data.results?.map(
828
- (app) => ({
829
- key: app.slug,
830
- name: app.name,
831
- description: app.description,
832
- version: "1.0.0",
833
- // API doesn't provide version
834
- category: app.category?.name,
835
- actions: [],
836
- // Will be populated separately
837
- triggers: [],
838
- current_implementation_id: app.current_implementation_id
839
- })
840
- ) || [];
841
- if (apps.length > 0) {
842
- apps.__pagination = {
843
- count: data.count,
844
- hasNext: !!data.next,
845
- hasPrevious: !!data.previous,
846
- nextUrl: data.next,
847
- previousUrl: data.previous
848
- };
1162
+ function normalizeError(error) {
1163
+ if (error instanceof ZapierError) {
1164
+ return error;
849
1165
  }
850
- return apps;
1166
+ const message = error instanceof Error ? error.message : String(error);
1167
+ return new ZapierUnknownError(`Unknown error: ${message}`, { cause: error });
851
1168
  }
852
-
853
- // src/functions/listActions/index.ts
854
- async function listActions(options = {}) {
855
- const api = getOrCreateApiClient(options);
856
- if (options.appKey) {
857
- try {
858
- const appData = await getApp({
859
- appKey: options.appKey,
860
- api,
861
- token: options.token,
862
- baseUrl: options.baseUrl,
863
- debug: options.debug,
864
- fetch: options.fetch
865
- });
866
- const implementationId = appData.current_implementation_id?.split("@")[0];
867
- if (!implementationId) {
868
- throw new Error("No current_implementation_id found for app");
869
- }
870
- const searchParams2 = {
871
- global: "true",
872
- public_only: "true",
873
- selected_apis: implementationId
874
- };
875
- const data2 = await api.get("/api/v4/implementations/", {
876
- searchParams: searchParams2
877
- });
878
- const actions2 = [];
879
- for (const implementation of data2.results || []) {
880
- if (implementation.actions) {
881
- for (const action of implementation.actions) {
882
- const transformedAction = {
883
- key: action.key,
884
- name: action.name || action.label,
885
- description: action.description || "",
886
- appKey: implementation.slug || "",
887
- type: action.type || action.type_of || "read",
888
- inputFields: [],
889
- // Would need additional API call for detailed fields
890
- outputFields: []
891
- };
892
- if (options?.type && transformedAction.type !== options.type) {
893
- continue;
894
- }
895
- actions2.push(transformedAction);
896
- }
1169
+ function createFunction(coreFn, schema) {
1170
+ const functionName = coreFn.name;
1171
+ const namedFunctions = {
1172
+ [functionName]: async function(options) {
1173
+ try {
1174
+ const normalizedOptions = options ?? {};
1175
+ if (schema) {
1176
+ const validatedOptions = validateOptions(schema, normalizedOptions);
1177
+ return await coreFn({
1178
+ ...normalizedOptions,
1179
+ ...validatedOptions
1180
+ });
897
1181
  }
1182
+ return await coreFn(normalizedOptions);
1183
+ } catch (error) {
1184
+ throw normalizeError(error);
898
1185
  }
899
- if (actions2.length > 0) {
900
- actions2.__pagination = {
901
- count: data2.count,
902
- hasNext: !!data2.next,
903
- hasPrevious: !!data2.previous,
904
- nextUrl: data2.next,
905
- previousUrl: data2.previous
906
- };
907
- }
908
- return actions2;
909
- } catch (error) {
910
- if (error instanceof Error && error.name === "AppNotFoundError") {
911
- throw error;
1186
+ }
1187
+ };
1188
+ return namedFunctions[functionName];
1189
+ }
1190
+ function createPageFunction(coreFn) {
1191
+ const functionName = coreFn.name + "Page";
1192
+ const namedFunctions = {
1193
+ [functionName]: async function(options) {
1194
+ try {
1195
+ const result = await coreFn(options);
1196
+ if (result && typeof result === "object" && "data" in result) {
1197
+ const data = result.data;
1198
+ return {
1199
+ data: Array.isArray(data) ? data : [data],
1200
+ nextCursor: result.nextCursor
1201
+ };
1202
+ }
1203
+ if (Array.isArray(result)) {
1204
+ return { data: result };
1205
+ }
1206
+ return { data: [result] };
1207
+ } catch (error) {
1208
+ throw normalizeError(error);
912
1209
  }
913
- console.warn(
914
- "Optimized app lookup failed, falling back to full scan:",
915
- error
916
- );
917
1210
  }
918
- }
919
- const searchParams = {
920
- global: "true",
921
- public_only: "true"
922
1211
  };
923
- const data = await api.get("/api/v4/implementations/", { searchParams });
924
- const actions = [];
925
- for (const implementation of data.results || []) {
926
- if (implementation.actions) {
927
- for (const action of implementation.actions) {
928
- const transformedAction = {
929
- key: action.key,
930
- name: action.name || action.label,
931
- description: action.description || "",
932
- appKey: implementation.slug || "",
933
- type: action.type || action.type_of || "read",
934
- inputFields: [],
935
- // Would need additional API call for detailed fields
936
- outputFields: []
937
- };
938
- if (options?.appKey && transformedAction.appKey !== options.appKey) {
939
- continue;
1212
+ return namedFunctions[functionName];
1213
+ }
1214
+ function createPaginatedFunction(coreFn, schema) {
1215
+ const pageFunction = createPageFunction(coreFn);
1216
+ const functionName = coreFn.name;
1217
+ const validator = schema ? createValidator(schema) : null;
1218
+ const namedFunctions = {
1219
+ [functionName]: function(options) {
1220
+ const normalizedOptions = options ?? {};
1221
+ const validatedOptions = {
1222
+ ...normalizedOptions,
1223
+ ...validator ? validator(normalizedOptions) : normalizedOptions
1224
+ };
1225
+ const pageSize = validatedOptions.pageSize || 100;
1226
+ const optimizedOptions = {
1227
+ ...validatedOptions,
1228
+ pageSize
1229
+ };
1230
+ const iterator = paginate(pageFunction, optimizedOptions);
1231
+ const firstPagePromise = iterator.next().then((result) => {
1232
+ if (result.done) {
1233
+ throw new Error("Paginate should always iterate at least once");
940
1234
  }
941
- if (options?.type && transformedAction.type !== options.type) {
942
- continue;
1235
+ return result.value;
1236
+ });
1237
+ return Object.assign(firstPagePromise, {
1238
+ [Symbol.asyncIterator]: async function* () {
1239
+ yield await firstPagePromise;
1240
+ for await (const page of iterator) {
1241
+ yield page;
1242
+ }
1243
+ },
1244
+ items: function() {
1245
+ return {
1246
+ [Symbol.asyncIterator]: async function* () {
1247
+ const firstPage = await firstPagePromise;
1248
+ for (const item of firstPage.data) {
1249
+ yield item;
1250
+ }
1251
+ for await (const page of iterator) {
1252
+ for (const item of page.data) {
1253
+ yield item;
1254
+ }
1255
+ }
1256
+ }
1257
+ };
943
1258
  }
944
- actions.push(transformedAction);
1259
+ });
1260
+ }
1261
+ };
1262
+ return namedFunctions[functionName];
1263
+ }
1264
+ var NeedChoicesSchema = z.object({
1265
+ key: z.string().optional(),
1266
+ label: z.string().optional(),
1267
+ sample: z.string().optional(),
1268
+ value: z.string().optional()
1269
+ });
1270
+ var NeedSchema = z.object({
1271
+ key: z.string(),
1272
+ alters_custom_fields: z.boolean().nullable().optional(),
1273
+ capabilities: z.array(z.string()).optional(),
1274
+ choices: z.array(NeedChoicesSchema).optional(),
1275
+ computed: z.boolean().nullable().optional(),
1276
+ custom_field: z.boolean().optional(),
1277
+ default: z.string().optional(),
1278
+ depends_on: z.array(z.string()).optional(),
1279
+ format: z.literal("SELECT").optional(),
1280
+ from_search: z.boolean().optional(),
1281
+ from_write: z.boolean().optional(),
1282
+ help_text: z.string().optional(),
1283
+ help_text_html: z.string().optional(),
1284
+ input_format: z.array(z.string()).optional(),
1285
+ label: z.string().optional(),
1286
+ language: z.string().optional(),
1287
+ parent_key: z.string().optional(),
1288
+ placeholder: z.string().optional(),
1289
+ prefill: z.string().optional(),
1290
+ required: z.boolean().optional(),
1291
+ searchfill: z.string().optional(),
1292
+ send_in_json: z.boolean().optional(),
1293
+ regex: z.string().optional(),
1294
+ type: z.enum([
1295
+ "integer",
1296
+ "string",
1297
+ "text",
1298
+ "datetime",
1299
+ "boolean",
1300
+ "file",
1301
+ "decimal",
1302
+ "copy",
1303
+ "password",
1304
+ "dict",
1305
+ "code",
1306
+ "filter",
1307
+ "json"
1308
+ ]).optional(),
1309
+ list: z.boolean().optional()
1310
+ });
1311
+ var ActionLinksSchema = z.object({
1312
+ action_url: z.string().optional()
1313
+ });
1314
+ var ActionPermissionsSchema = z.object({
1315
+ can_use: z.boolean().optional()
1316
+ });
1317
+ var ActionSchema = z.object({
1318
+ id: z.string().optional(),
1319
+ type: z.enum([
1320
+ "filter",
1321
+ "read",
1322
+ "read_bulk",
1323
+ "run",
1324
+ "search",
1325
+ "search_and_write",
1326
+ "search_or_write",
1327
+ "write"
1328
+ ]),
1329
+ key: z.string(),
1330
+ name: z.string(),
1331
+ noun: z.string().optional(),
1332
+ description: z.string(),
1333
+ description_html: z.string().optional(),
1334
+ is_important: z.boolean().optional(),
1335
+ is_hidden: z.boolean().optional(),
1336
+ needs: z.array(NeedSchema).optional(),
1337
+ meta: z.string().optional(),
1338
+ selected_api: z.string().optional(),
1339
+ links: ActionLinksSchema.optional(),
1340
+ permissions: ActionPermissionsSchema.optional()
1341
+ });
1342
+ var ChoiceSchema = z.object({
1343
+ value: z.union([z.string(), z.number()]),
1344
+ label: z.string()
1345
+ });
1346
+ z.object({
1347
+ key: z.string(),
1348
+ label: z.string(),
1349
+ type: z.enum([
1350
+ "string",
1351
+ "number",
1352
+ "boolean",
1353
+ "datetime",
1354
+ "file",
1355
+ "object",
1356
+ "array"
1357
+ ]),
1358
+ required: z.boolean(),
1359
+ description: z.string().optional(),
1360
+ choices: z.array(ChoiceSchema).optional()
1361
+ });
1362
+ z.object({
1363
+ data: z.array(z.any())
1364
+ });
1365
+ var ActionFieldChoiceSchema = z.object({
1366
+ value: z.union([z.string(), z.number()]),
1367
+ label: z.string()
1368
+ });
1369
+ z.object({
1370
+ key: z.string(),
1371
+ label: z.string().optional(),
1372
+ required: z.boolean(),
1373
+ type: z.string().optional(),
1374
+ helpText: z.string().optional(),
1375
+ helpTextHtml: z.string().optional(),
1376
+ choices: z.array(ActionFieldChoiceSchema).optional(),
1377
+ default: z.string().optional(),
1378
+ placeholder: z.string().optional(),
1379
+ computed: z.boolean().optional(),
1380
+ customField: z.boolean().optional(),
1381
+ dependsOn: z.array(z.string()).optional(),
1382
+ format: z.string().optional(),
1383
+ inputFormat: z.array(z.string()).optional()
1384
+ });
1385
+ var AuthenticationSchema = z.object({
1386
+ id: z.number(),
1387
+ date: z.string(),
1388
+ lastchanged: z.string().optional(),
1389
+ account_id: z.number(),
1390
+ customuser_id: z.number().optional(),
1391
+ selected_api: z.string(),
1392
+ destination_selected_api: z.string().nullable().optional(),
1393
+ is_invite_only: z.boolean(),
1394
+ is_private: z.boolean(),
1395
+ shared_with_all: z.boolean(),
1396
+ is_stale: z.string().optional(),
1397
+ is_shared: z.string().optional(),
1398
+ marked_stale_at: z.string().nullable().optional(),
1399
+ label: z.string().nullable().optional(),
1400
+ identifier: z.string().nullable().optional(),
1401
+ title: z.string().nullable().optional(),
1402
+ url: z.string().optional(),
1403
+ groups: z.string().optional(),
1404
+ members: z.string().optional(),
1405
+ permissions: z.record(z.boolean()).optional()
1406
+ });
1407
+ z.object({
1408
+ count: z.number(),
1409
+ next: z.string().nullable().optional(),
1410
+ previous: z.string().nullable().optional(),
1411
+ results: z.array(AuthenticationSchema)
1412
+ });
1413
+ var UserProfileSchema = z.object({
1414
+ id: z.number(),
1415
+ code: z.string(),
1416
+ user_id: z.number(),
1417
+ auto_provisioned: z.boolean(),
1418
+ first_name: z.string(),
1419
+ last_name: z.string(),
1420
+ username: z.string(),
1421
+ personas: z.string(),
1422
+ user_generated_personas: z.string(),
1423
+ last_login: z.string(),
1424
+ email: z.string(),
1425
+ email_hash: z.string(),
1426
+ email_confirmed: z.boolean(),
1427
+ timezone: z.string(),
1428
+ photo_url: z.string(),
1429
+ has_seen_notifications: z.record(z.boolean().nullable()),
1430
+ signup: z.string(),
1431
+ since_signup: z.string(),
1432
+ has_activated: z.boolean(),
1433
+ enable_gz_creator: z.boolean(),
1434
+ should_see_nps_survey: z.boolean(),
1435
+ is_developer: z.boolean(),
1436
+ is_expert: z.boolean(),
1437
+ tos_agreement: z.boolean(),
1438
+ should_renew_tos: z.boolean(),
1439
+ is_gdpr_consented: z.boolean(),
1440
+ disable_ssl_check: z.boolean(),
1441
+ identity: z.number(),
1442
+ summary_schedule: z.string(),
1443
+ alert_triggers: z.string(),
1444
+ alert_actions: z.string(),
1445
+ is_staff: z.boolean(),
1446
+ is_zt_reviewer: z.boolean(),
1447
+ is_high_value: z.boolean(),
1448
+ is_temporary: z.boolean(),
1449
+ banner_message: z.string(),
1450
+ enable_totp_2fa: z.boolean(),
1451
+ viewed_help: z.record(z.boolean()),
1452
+ show_editor_migration_mesaging: z.boolean(),
1453
+ switches: z.record(z.any()),
1454
+ organizations: z.array(z.any().nullable()),
1455
+ primary_organization: z.any().nullable(),
1456
+ has_active_zaps: z.boolean(),
1457
+ has_google_sso: z.boolean(),
1458
+ auth_realm: z.string(),
1459
+ roles: z.array(
1460
+ z.object({
1461
+ account_id: z.number(),
1462
+ role: z.string()
1463
+ })
1464
+ )
1465
+ });
1466
+ z.object({
1467
+ age_in_days: z.string().optional(),
1468
+ api_docs_url: z.string().nullable().optional(),
1469
+ app_profile_url: z.string(),
1470
+ banner: z.string().optional(),
1471
+ categories: z.array(z.any()).optional(),
1472
+ // TODO: Define proper service_category type
1473
+ canonical_id: z.string().optional(),
1474
+ current_implementation_id: z.string(),
1475
+ days_since_last_update: z.string().optional(),
1476
+ description: z.string(),
1477
+ external_url: z.string(),
1478
+ hashtag: z.string().optional(),
1479
+ id: z.number().optional(),
1480
+ image: z.string().optional(),
1481
+ images: z.string().optional(),
1482
+ integration_overview_html: z.string().nullable().optional(),
1483
+ internal_id: z.string(),
1484
+ invite_url: z.string().nullable().optional(),
1485
+ is_beta: z.string().optional(),
1486
+ is_built_in: z.string().optional(),
1487
+ is_featured: z.string().optional(),
1488
+ is_premium: z.boolean().optional(),
1489
+ is_public: z.string().optional(),
1490
+ is_upcoming: z.string().optional(),
1491
+ learn_more_url: z.string(),
1492
+ name: z.string(),
1493
+ popularity: z.number(),
1494
+ primary_color: z.string(),
1495
+ request_count: z.string().optional(),
1496
+ slug: z.string(),
1497
+ zap_usage_count: z.number().nullable().optional()
1498
+ });
1499
+ var ServiceSchema = z.object({
1500
+ id: z.number().optional(),
1501
+ canonical_id: z.string().optional(),
1502
+ current_implementation_id: z.string(),
1503
+ name: z.string(),
1504
+ slug: z.string(),
1505
+ app_url: z.string().optional(),
1506
+ learn_more_url: z.string().optional(),
1507
+ description: z.string(),
1508
+ primary_color: z.string(),
1509
+ popularity: z.number(),
1510
+ image: z.string().optional(),
1511
+ images: z.string().optional()
1512
+ });
1513
+ z.object({
1514
+ results: z.array(ServiceSchema),
1515
+ next: z.string().nullable().optional(),
1516
+ previous: z.string().nullable().optional()
1517
+ });
1518
+ z.object({
1519
+ selected_api: z.string(),
1520
+ action: z.string(),
1521
+ type_of: z.string(),
1522
+ authentication_id: z.number().optional(),
1523
+ params: z.record(z.any()).optional()
1524
+ });
1525
+ z.object({
1526
+ success: z.boolean(),
1527
+ needs: z.array(NeedSchema).optional(),
1528
+ errors: z.array(z.string()).optional(),
1529
+ last_fetched_at: z.string().optional()
1530
+ });
1531
+ var ImplementationSchema = z.object({
1532
+ selected_api: z.string(),
1533
+ app_id: z.number().optional(),
1534
+ auth_type: z.string().optional(),
1535
+ auth_fields: z.string().optional(),
1536
+ actions: z.array(ActionSchema).optional(),
1537
+ is_deprecated: z.boolean().optional(),
1538
+ is_private_only: z.boolean().optional(),
1539
+ is_invite_only: z.boolean().optional(),
1540
+ is_beta: z.boolean().optional().default(false),
1541
+ is_premium: z.boolean().optional().default(false),
1542
+ is_hidden: z.string().optional(),
1543
+ name: z.string().optional(),
1544
+ slug: z.string().optional(),
1545
+ images: z.record(z.string().nullable()).optional(),
1546
+ primary_color: z.string().optional(),
1547
+ secondary_color: z.string().optional(),
1548
+ current_implementation: z.string().optional(),
1549
+ other_implementations: z.string().optional()
1550
+ });
1551
+ z.object({
1552
+ count: z.number(),
1553
+ next: z.string().nullable().optional(),
1554
+ previous: z.string().nullable().optional(),
1555
+ results: z.array(ImplementationSchema)
1556
+ });
1557
+ var ImplementationMetaSchema = z.object({
1558
+ id: z.string(),
1559
+ // e.g. "ZapierFormatterCLIAPI@1.0.7"
1560
+ name: z.string(),
1561
+ slug: z.string(),
1562
+ images: z.object({
1563
+ url_16x16: z.string().optional(),
1564
+ url_32x32: z.string().optional(),
1565
+ url_64x64: z.string().optional(),
1566
+ url_128x128: z.string().optional()
1567
+ }).optional(),
1568
+ // Include other fields for completeness but we'll only use what we need
1569
+ ageInDays: z.union([z.string(), z.number()]).optional(),
1570
+ authType: z.string().nullable().optional(),
1571
+ banner: z.string().optional(),
1572
+ categories: z.array(
1573
+ z.object({
1574
+ id: z.number(),
1575
+ name: z.string(),
1576
+ slug: z.string()
1577
+ })
1578
+ ).optional(),
1579
+ isBeta: z.boolean().optional(),
1580
+ isBuiltIn: z.boolean().optional(),
1581
+ isDeprecated: z.boolean().optional(),
1582
+ isFeatured: z.boolean().optional(),
1583
+ isHidden: z.boolean().optional(),
1584
+ isInvite: z.boolean().optional(),
1585
+ isPremium: z.boolean().optional(),
1586
+ isPublic: z.boolean().optional(),
1587
+ isUpcoming: z.boolean().optional(),
1588
+ popularity: z.number().optional(),
1589
+ apiDocsUrl: z.string().optional(),
1590
+ classification: z.string().optional()
1591
+ });
1592
+ z.object({
1593
+ count: z.number(),
1594
+ next: z.string().nullable().optional(),
1595
+ previous: z.string().nullable().optional(),
1596
+ results: z.array(ImplementationMetaSchema)
1597
+ });
1598
+
1599
+ // src/schemas/UserProfile.ts
1600
+ var UserProfileItemSchema = withFormatter(
1601
+ UserProfileSchema.omit({ user_id: true }).extend({
1602
+ full_name: z.string()
1603
+ // Computed field: first_name + " " + last_name
1604
+ }),
1605
+ {
1606
+ format: (item) => {
1607
+ const details = [];
1608
+ details.push({ text: item.email, style: "dim" });
1609
+ if (item.timezone) {
1610
+ details.push({
1611
+ text: `Timezone: ${item.timezone}`,
1612
+ style: "accent"
1613
+ });
945
1614
  }
1615
+ details.push({
1616
+ text: `Member since: ${item.since_signup}`,
1617
+ style: "dim"
1618
+ });
1619
+ return {
1620
+ title: item.full_name,
1621
+ subtitle: `@${item.username}`,
1622
+ details
1623
+ };
946
1624
  }
947
1625
  }
948
- if (actions.length > 0) {
949
- actions.__pagination = {
950
- count: data.count,
951
- hasNext: !!data.next,
952
- hasPrevious: !!data.previous,
953
- nextUrl: data.next,
954
- previousUrl: data.previous
1626
+ );
1627
+
1628
+ // src/plugins/getProfile/schemas.ts
1629
+ var GetProfileSchema = withOutputSchema(
1630
+ z.object({}).optional().describe("Get current user's profile information"),
1631
+ UserProfileItemSchema
1632
+ );
1633
+
1634
+ // src/plugins/getProfile/index.ts
1635
+ var getProfilePlugin = ({ context }) => {
1636
+ const getProfile = createFunction(async function getProfile2() {
1637
+ const profile = await context.api.get("/api/v4/profile/", {
1638
+ authRequired: true
1639
+ });
1640
+ const { user_id: _unusedUserId, ...data } = profile;
1641
+ return {
1642
+ data: {
1643
+ ...data,
1644
+ // Pass through all API response fields
1645
+ full_name: `${profile.first_name} ${profile.last_name}`
1646
+ // Computed field
1647
+ }
955
1648
  };
1649
+ }, GetProfileSchema);
1650
+ return {
1651
+ getProfile,
1652
+ context: {
1653
+ meta: {
1654
+ getProfile: {
1655
+ inputSchema: GetProfileSchema
1656
+ }
1657
+ }
1658
+ }
1659
+ };
1660
+ };
1661
+ var AppItemSchema = withFormatter(
1662
+ z.object({
1663
+ // Essential properties only
1664
+ title: z.string(),
1665
+ // Mapped from name
1666
+ key: z.string(),
1667
+ // Mapped from selected_api
1668
+ current_implementation_id: z.string(),
1669
+ // From id, keeps the full version
1670
+ version: z.string().optional(),
1671
+ // Extracted from implementation ID
1672
+ description: z.string().optional(),
1673
+ slug: z.string().optional()
1674
+ }),
1675
+ {
1676
+ format: (item) => {
1677
+ return {
1678
+ title: item.title,
1679
+ subtitle: `(${item.key})`,
1680
+ details: []
1681
+ };
1682
+ }
956
1683
  }
957
- return actions;
958
- }
1684
+ );
959
1685
 
960
- // src/functions/getAction/index.ts
961
- async function getAction(options) {
962
- const { appKey, actionKey, actionType } = options;
963
- const actions = await listActions({
964
- ...options,
965
- appKey
966
- });
967
- const action = actions.find(
968
- (a) => a.key === actionKey && a.type === actionType
969
- );
970
- if (!action) {
971
- throw new Error(`Action not found: ${actionKey} with type ${actionType}`);
972
- }
973
- return action;
974
- }
1686
+ // src/plugins/listApps/schemas.ts
1687
+ var ListAppsSchema = withOutputSchema(
1688
+ z.object({
1689
+ appKeys: z.array(z.string()).optional().describe(
1690
+ "Filter apps by app keys (e.g., 'SlackCLIAPI' or slug like 'github')"
1691
+ ),
1692
+ search: z.string().optional().describe("Search for apps by name"),
1693
+ pageSize: z.number().min(1).optional().describe("Number of apps per page"),
1694
+ maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
1695
+ }).describe("List all available apps with optional filtering"),
1696
+ AppItemSchema
1697
+ );
975
1698
 
976
- // src/functions/runAction/index.ts
977
- async function runAction(options) {
978
- const {
979
- appKey,
980
- actionType,
981
- actionKey,
982
- inputs,
983
- authenticationId: providedAuthenticationId
984
- } = options;
985
- const api = getOrCreateApiClient(options);
986
- const actionData = await getAction({
987
- ...options,
988
- appKey,
989
- actionKey,
990
- actionType
991
- });
992
- if (actionData.type !== actionType) {
993
- throw new Error(
994
- `Action type mismatch: expected ${actionType}, got ${actionData.type}`
995
- );
1699
+ // src/utils/domain-utils.ts
1700
+ function splitVersionedKey(versionedKey) {
1701
+ const parts = versionedKey.split("@");
1702
+ if (parts.length >= 2) {
1703
+ const baseKey = parts[0];
1704
+ const version = parts.slice(1).join("@");
1705
+ return [baseKey, version];
996
1706
  }
997
- const startTime = Date.now();
998
- const result = await executeAction({
999
- api,
1000
- appSlug: appKey,
1001
- actionKey,
1002
- actionType: actionData.type,
1003
- executionOptions: { inputs: inputs || {} },
1004
- authenticationId: providedAuthenticationId,
1005
- options
1006
- });
1007
- const executionTime = Date.now() - startTime;
1707
+ return [versionedKey, void 0];
1708
+ }
1709
+ function normalizeImplementationMetaToAppItem(implementationMeta) {
1710
+ const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
1008
1711
  return {
1009
- success: true,
1010
- data: result,
1011
- metadata: {
1012
- executionTime,
1013
- requestId: generateRequestId()
1014
- }
1712
+ title: implementationMeta.name,
1713
+ key: selectedApi,
1714
+ current_implementation_id: implementationMeta.id,
1715
+ // Keep the full versioned ID
1716
+ version: appVersion,
1717
+ // Extract version separately
1718
+ slug: implementationMeta.slug
1015
1719
  };
1016
1720
  }
1017
- async function executeAction(actionOptions) {
1018
- const {
1019
- api,
1020
- appSlug,
1021
- actionKey,
1022
- actionType,
1023
- executionOptions,
1024
- authenticationId,
1025
- options
1026
- } = actionOptions;
1027
- const appData = await getApp({
1028
- appKey: appSlug,
1029
- api,
1030
- token: options.token,
1031
- baseUrl: options.baseUrl,
1032
- debug: options.debug,
1033
- fetch: options.fetch
1034
- });
1035
- const selectedApi = appData.current_implementation_id;
1036
- if (!selectedApi) {
1037
- throw new Error("No current_implementation_id found for app");
1038
- }
1039
- const runRequest = {
1040
- data: {
1041
- authentication_id: authenticationId || 1,
1042
- selected_api: selectedApi,
1043
- action_key: actionKey,
1044
- action_type: actionType,
1045
- inputs: executionOptions.inputs || {}
1721
+ function normalizeAuthenticationItem(auth, options = {}) {
1722
+ let appKey = options.app_key;
1723
+ let version = options.version;
1724
+ if (auth.selected_api) {
1725
+ const [extractedAppKey, extractedVersion] = splitVersionedKey(
1726
+ auth.selected_api
1727
+ );
1728
+ if (!appKey) {
1729
+ appKey = extractedAppKey;
1730
+ }
1731
+ if (!version) {
1732
+ version = extractedVersion;
1046
1733
  }
1047
- };
1048
- const runData = await api.post("/api/actions/v1/runs", runRequest);
1049
- const runId = runData.data.id;
1050
- return await api.poll(`/api/actions/v1/runs/${runId}`, {
1051
- successStatus: 200,
1052
- pendingStatus: 202,
1053
- resultExtractor: (result) => result.data
1054
- });
1055
- }
1056
-
1057
- // src/functions/listFields/index.ts
1058
- async function listFields(options) {
1059
- const api = getOrCreateApiClient(options);
1060
- const { appKey, actionKey, actionType, authenticationId, params } = options;
1061
- const appData = await getApp({
1062
- appKey,
1063
- api,
1064
- token: options.token,
1065
- baseUrl: options.baseUrl,
1066
- debug: options.debug,
1067
- fetch: options.fetch
1068
- });
1069
- const selectedApi = appData.current_implementation_id;
1070
- if (!selectedApi) {
1071
- throw new Error("No current_implementation_id found for app");
1072
1734
  }
1073
- const needsRequest = {
1735
+ const {
1074
1736
  selected_api: selectedApi,
1075
- action: actionKey,
1076
- type_of: actionType,
1077
- authentication_id: authenticationId,
1078
- params: params || {}
1737
+ customuser_id: userId,
1738
+ ...restOfAuth
1739
+ } = auth;
1740
+ return {
1741
+ ...restOfAuth,
1742
+ // Pass through all other API response fields except selected_api
1743
+ implementation_id: selectedApi,
1744
+ // Rename selected_api to implementation_id
1745
+ title: auth.title || auth.label || void 0,
1746
+ // Coerce title from label if missing
1747
+ is_expired: auth.is_stale,
1748
+ // Map is_stale to is_expired
1749
+ expired_at: auth.marked_stale_at,
1750
+ // Map marked_stale_at to expired_at
1751
+ app_key: appKey,
1752
+ // App key from implementations endpoint or parsed from selected_api
1753
+ version,
1754
+ // Version from selected_api or provided
1755
+ user_id: userId
1756
+ // Map customuser_id to user_id
1079
1757
  };
1080
- const needsData = await api.post(
1081
- "/api/v4/implementations/needs/",
1082
- needsRequest
1083
- );
1084
- if (!needsData.success) {
1085
- throw new Error(
1086
- `Failed to get action fields: ${needsData.errors?.join(", ") || "Unknown error"}`
1087
- );
1088
- }
1089
- return (needsData.needs || []).map((need) => ({
1090
- key: need.key,
1091
- label: need.label,
1092
- required: need.required || false,
1093
- type: need.type,
1094
- helpText: need.help_text,
1095
- helpTextHtml: need.help_text_html,
1096
- choices: need.choices?.map((choice) => ({
1097
- value: choice.value,
1098
- label: choice.label
1099
- })),
1100
- default: need.default,
1101
- placeholder: need.placeholder,
1102
- computed: need.computed,
1103
- customField: need.custom_field,
1104
- dependsOn: need.depends_on,
1105
- format: need.format,
1106
- inputFormat: need.input_format
1107
- }));
1108
1758
  }
1109
-
1110
- // src/functions/generateTypes/index.ts
1111
- function generateFetchMethodSignature() {
1112
- return ` /** Make authenticated HTTP requests through Zapier's Relay service */
1113
- fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
1759
+ function normalizeActionItem(action) {
1760
+ const { name, type, selected_api: appKey, ...restOfAction } = action;
1761
+ return {
1762
+ ...restOfAction,
1763
+ app_key: appKey || "",
1764
+ action_type: type,
1765
+ title: name,
1766
+ // Map name to title
1767
+ type: "action"
1768
+ };
1114
1769
  }
1115
- async function generateTypes(options) {
1116
- const {
1117
- appKey,
1118
- authenticationId,
1119
- output = `./types/${appKey}.d.ts`
1120
- } = options;
1121
- const { app, version } = parseAppIdentifier(appKey);
1122
- const actions = await listActions({
1123
- ...options,
1124
- appKey: app
1125
- });
1126
- if (actions.length === 0) {
1127
- const typeDefinitions2 = generateEmptyTypesFile(app, version);
1128
- if (output) {
1129
- const fs = await import('fs');
1130
- const path = await import('path');
1131
- fs.mkdirSync(path.dirname(output), { recursive: true });
1132
- fs.writeFileSync(output, typeDefinitions2, "utf8");
1133
- }
1134
- return typeDefinitions2;
1135
- }
1136
- const actionsWithFields = [];
1137
- if (authenticationId) {
1138
- for (const action of actions) {
1139
- try {
1140
- const fields = await listFields({
1141
- ...options,
1142
- appKey: action.appKey,
1143
- actionKey: action.key,
1144
- actionType: action.type,
1145
- authenticationId
1146
- });
1147
- actionsWithFields.push({ ...action, inputFields: fields });
1148
- } catch {
1149
- actionsWithFields.push({ ...action, inputFields: [] });
1770
+ function groupVersionedAppKeysByType(appKeys) {
1771
+ const result = {
1772
+ selectedApi: [],
1773
+ slug: []
1774
+ };
1775
+ const seenSelectedApi = /* @__PURE__ */ new Set();
1776
+ const seenSlugs = /* @__PURE__ */ new Set();
1777
+ for (const key of appKeys) {
1778
+ const [keyWithoutVersion, version] = splitVersionedKey(key);
1779
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1780
+ if (uuidRegex.test(keyWithoutVersion)) {
1781
+ throw new Error(
1782
+ `UUID app keys are not supported. Use app slug or implementation ID instead of: ${key}`
1783
+ );
1784
+ }
1785
+ if (isSnakeCasedSlug(keyWithoutVersion)) {
1786
+ const dashified = dashifySnakeCasedSlug(keyWithoutVersion);
1787
+ const slugWithVersion = version ? `${dashified}@${version}` : dashified;
1788
+ if (!seenSlugs.has(slugWithVersion)) {
1789
+ seenSlugs.add(slugWithVersion);
1790
+ result.slug.push(slugWithVersion);
1150
1791
  }
1792
+ continue;
1793
+ }
1794
+ if (keyWithoutVersion.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/)) {
1795
+ seenSlugs.add(key);
1796
+ result.slug.push(key);
1797
+ continue;
1798
+ }
1799
+ if (!seenSelectedApi.has(key)) {
1800
+ seenSelectedApi.add(key);
1801
+ result.selectedApi.push(key);
1151
1802
  }
1152
- } else {
1153
- actions.forEach((action) => {
1154
- actionsWithFields.push({ ...action, inputFields: [] });
1155
- });
1156
- }
1157
- const typeDefinitions = generateTypeDefinitions(
1158
- app,
1159
- actionsWithFields,
1160
- version
1161
- );
1162
- if (output) {
1163
- const fs = await import('fs');
1164
- const path = await import('path');
1165
- fs.mkdirSync(path.dirname(output), { recursive: true });
1166
- fs.writeFileSync(output, typeDefinitions, "utf8");
1167
1803
  }
1168
- return typeDefinitions;
1804
+ return result;
1169
1805
  }
1170
- function parseAppIdentifier(identifier) {
1171
- const parts = identifier.split("@");
1806
+ function groupAppKeysByType(appKeys) {
1807
+ const grouped = groupVersionedAppKeysByType(appKeys);
1172
1808
  return {
1173
- app: parts[0],
1174
- version: parts[1]
1809
+ selectedApi: [
1810
+ ...new Set(grouped.selectedApi.map((key) => key.split("@")[0]))
1811
+ ],
1812
+ slug: [...new Set(grouped.slug.map((key) => key.split("@")[0]))]
1175
1813
  };
1176
1814
  }
1177
- function generateTypeDefinitions(appKey, actions, version) {
1178
- if (actions.length === 0) {
1179
- return generateEmptyTypesFile(appKey, version);
1815
+ function isSnakeCasedSlug(slug) {
1816
+ if (slug.match(/^_[0-9]/)) {
1817
+ slug = slug.slice(1);
1180
1818
  }
1181
- const actionsByType = actions.reduce(
1182
- (acc, action) => {
1183
- if (!acc[action.type]) {
1184
- acc[action.type] = [];
1185
- }
1186
- acc[action.type].push(action);
1187
- return acc;
1188
- },
1189
- {}
1190
- );
1191
- const appName = capitalize(appKey);
1192
- const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1193
- let output = `/* eslint-disable @typescript-eslint/naming-convention */
1194
- /**
1195
- * Auto-generated TypeScript types for Zapier ${appKey} actions
1196
- ${versionComment}
1197
- * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1198
- *
1199
- * Usage:
1200
- * import type { ${appName}Sdk } from './path/to/this/file'
1201
- * const sdk = createZapierSdk() as unknown as ${appName}Sdk
1202
- *
1203
- * // Direct usage (per-call auth):
1204
- * await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
1205
- *
1206
- * // Factory usage (pinned auth):
1207
- * const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
1208
- * await my${appName}.search.user_by_email({ inputs: { email } })
1209
- */
1210
-
1211
- import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
1212
- import { z } from 'zod'
1213
- import { RelayFetchSchema } from '@zapier/zapier-sdk'
1214
-
1215
- `;
1216
- actions.forEach((action) => {
1217
- if (action.inputFields.length > 0) {
1218
- const inputTypeName = `${appName}${capitalize(action.type)}${capitalize(
1219
- sanitizeActionName(action.key)
1220
- )}Inputs`;
1221
- output += `interface ${inputTypeName} {
1222
- `;
1223
- action.inputFields.forEach((field) => {
1224
- const isOptional = !field.required;
1225
- const fieldType = mapFieldTypeToTypeScript(field);
1226
- const description = field.helpText ? ` /** ${escapeComment(field.helpText)} */
1227
- ` : "";
1228
- output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}
1229
- `;
1230
- });
1231
- output += `}
1819
+ return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
1820
+ }
1821
+ function dashifySnakeCasedSlug(slug) {
1822
+ if (!isSnakeCasedSlug(slug)) {
1823
+ return slug;
1824
+ }
1825
+ if (slug.startsWith("_")) {
1826
+ slug = slug.slice(1);
1827
+ }
1828
+ return slug.replace(/_/g, "-");
1829
+ }
1232
1830
 
1233
- `;
1234
- }
1235
- });
1236
- Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
1237
- const typeName = `${appName}${capitalize(actionType)}Actions`;
1238
- output += `interface ${typeName} {
1239
- `;
1240
- typeActions.forEach((action) => {
1241
- const actionName = sanitizeActionName(action.key);
1242
- const description = action.description ? ` /** ${escapeComment(action.description)} */
1243
- ` : "";
1244
- if (action.inputFields.length > 0) {
1245
- const inputTypeName = `${appName}${capitalize(action.type)}${capitalize(
1246
- sanitizeActionName(action.key)
1247
- )}Inputs`;
1248
- output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>
1249
- `;
1250
- } else {
1251
- output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>
1252
- `;
1253
- }
1254
- });
1255
- output += `}
1256
-
1257
- `;
1258
- });
1259
- output += `interface ${appName}AppProxy {
1260
- `;
1261
- Object.keys(actionsByType).forEach((actionType) => {
1262
- const typeName = `${appName}${capitalize(actionType)}Actions`;
1263
- output += ` ${actionType}: ${typeName}
1264
- `;
1265
- });
1266
- output += generateFetchMethodSignature() + "\n";
1267
- output += `}
1268
-
1269
- `;
1270
- output += `interface ${appName}AppFactory {
1271
- `;
1272
- output += ` (options: { authenticationId: number }): ${appName}AppProxy
1273
- `;
1274
- output += `}
1275
-
1276
- `;
1277
- output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1278
-
1279
- `;
1280
- output += `export interface ${appName}Sdk {
1281
- `;
1282
- output += ` apps: {
1283
- `;
1284
- output += ` ${appKey}: ${appName}AppWithFactory
1285
- `;
1286
- output += ` }
1287
- `;
1288
- output += `}
1289
- `;
1290
- return output;
1291
- }
1292
- function generateEmptyTypesFile(appKey, version) {
1293
- const appName = capitalize(appKey);
1294
- const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1295
- return `/* eslint-disable @typescript-eslint/naming-convention */
1296
- /**
1297
- * Auto-generated TypeScript types for Zapier ${appKey} actions
1298
- ${versionComment}
1299
- * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1300
- *
1301
- * No actions found for this app.
1302
- */
1303
-
1304
- import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
1305
- import { z } from 'zod'
1306
- import { RelayFetchSchema } from '@zapier/zapier-sdk'
1307
-
1308
- interface ${appName}AppProxy {
1309
- // No actions available
1310
- ${generateFetchMethodSignature()}
1311
- }
1312
-
1313
- interface ${appName}AppFactory {
1314
- (options: { authenticationId: number }): ${appName}AppProxy
1315
- }
1316
-
1317
- type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1318
-
1319
- export interface ${appName}Sdk {
1320
- apps: {
1321
- ${appKey}: ${appName}AppWithFactory
1322
- }
1323
- }
1324
- `;
1325
- }
1326
- function capitalize(str) {
1327
- return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
1328
- }
1329
- function sanitizeActionName(actionKey) {
1330
- let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1331
- if (/^[0-9]/.test(sanitized)) {
1332
- sanitized = "_" + sanitized;
1333
- }
1334
- return sanitized;
1335
- }
1336
- function sanitizeFieldName(fieldKey) {
1337
- let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1338
- if (/^[0-9]/.test(sanitized)) {
1339
- sanitized = "_" + sanitized;
1340
- }
1341
- return sanitized;
1342
- }
1343
- function escapeComment(comment) {
1344
- return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
1345
- }
1346
- function mapFieldTypeToTypeScript(field) {
1347
- if (field.choices && field.choices.length > 0) {
1348
- const choiceValues = field.choices.filter(
1349
- (choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
1350
- ).map(
1351
- (choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value
1831
+ // src/plugins/listApps/index.ts
1832
+ var listAppsPlugin = ({ context }) => {
1833
+ const listApps = createPaginatedFunction(async function listAppsPage(options) {
1834
+ const api = context.api;
1835
+ const opts = options;
1836
+ const appKeys = [...opts.appKeys ?? []].map(
1837
+ (key) => splitVersionedKey(key)[0]
1352
1838
  );
1353
- if (choiceValues.length > 0) {
1354
- return choiceValues.join(" | ");
1355
- }
1356
- }
1357
- switch (field.type?.toLowerCase()) {
1358
- case "string":
1359
- case "text":
1360
- case "email":
1361
- case "url":
1362
- case "password":
1363
- return "string";
1364
- case "integer":
1365
- case "number":
1366
- return "number";
1367
- case "boolean":
1368
- return "boolean";
1369
- case "datetime":
1370
- case "date":
1371
- return "string";
1372
- // ISO date strings
1373
- case "file":
1374
- return "string";
1375
- // File URL or content
1376
- case "array":
1377
- return "any[]";
1378
- case "object":
1379
- return "Record<string, any>";
1380
- default:
1381
- return "string | number | boolean";
1382
- }
1383
- }
1384
-
1385
- // src/functions/bundleCode/index.ts
1386
- async function bundleCode(options) {
1387
- const {
1388
- input,
1389
- output,
1390
- target = "es2020",
1391
- cjs = false,
1392
- minify = false,
1393
- string: returnString = false
1394
- } = options;
1395
- const { buildSync } = await import('esbuild');
1396
- const fs = await import('fs');
1397
- const path = await import('path');
1398
- const resolvedInput = path.resolve(process.cwd(), input);
1399
- try {
1400
- const result = buildSync({
1401
- entryPoints: [resolvedInput],
1402
- bundle: true,
1403
- platform: "node",
1404
- target,
1405
- format: cjs ? "cjs" : "esm",
1406
- minify,
1407
- write: false,
1408
- external: [],
1409
- // Bundle everything
1410
- banner: {
1411
- js: "#!/usr/bin/env node"
1412
- }
1413
- });
1414
- if (result.errors.length > 0) {
1415
- throw new Error(
1416
- `Bundle failed: ${result.errors.map((e) => e.text).join(", ")}`
1839
+ if (opts.search) {
1840
+ const searchParams2 = {};
1841
+ searchParams2.term = opts.search;
1842
+ const searchEnvelope = await api.get(
1843
+ "/api/v4/implementations-meta/search/",
1844
+ {
1845
+ searchParams: searchParams2
1846
+ }
1417
1847
  );
1848
+ const implementations = searchEnvelope.results.map(
1849
+ normalizeImplementationMetaToAppItem
1850
+ );
1851
+ const appKeysSet = new Set(appKeys);
1852
+ for (const implementation of implementations) {
1853
+ if (!appKeysSet.has(implementation.key)) {
1854
+ appKeysSet.add(implementation.key);
1855
+ appKeys.push(implementation.key);
1856
+ }
1857
+ }
1418
1858
  }
1419
- const bundledCode = result.outputFiles?.[0]?.text;
1420
- if (!bundledCode) {
1421
- throw new Error("No output generated");
1422
- }
1423
- let finalOutput = bundledCode;
1424
- if (returnString) {
1425
- finalOutput = JSON.stringify(bundledCode);
1859
+ const searchParams = {};
1860
+ if (opts.pageSize) {
1861
+ searchParams.limit = opts.pageSize.toString();
1426
1862
  }
1427
- if (output) {
1428
- fs.mkdirSync(path.dirname(output), { recursive: true });
1429
- fs.writeFileSync(output, finalOutput, "utf8");
1863
+ searchParams.latest_only = "true";
1864
+ if (opts.cursor) {
1865
+ searchParams.offset = opts.cursor;
1430
1866
  }
1431
- return finalOutput;
1432
- } catch (error) {
1433
- throw new Error(
1434
- `Bundle failed: ${error instanceof Error ? error.message : "Unknown error"}`
1435
- );
1436
- }
1437
- }
1438
-
1439
- // src/functions/request/index.ts
1440
- function transformUrlToRelayPath(url) {
1441
- const targetUrl = new URL(url);
1442
- const relayPath = `/relay/${targetUrl.hostname}${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
1443
- return relayPath;
1444
- }
1445
- async function request(options) {
1446
- const {
1447
- url,
1448
- method = "GET",
1449
- body,
1450
- headers,
1451
- authenticationId,
1452
- callbackUrl,
1453
- authenticationTemplate,
1454
- ...config
1455
- } = options;
1456
- return relayFetch(
1457
- url,
1458
- {
1459
- method,
1460
- body,
1461
- headers,
1462
- authenticationId,
1463
- callbackUrl,
1464
- authenticationTemplate
1465
- },
1466
- config
1467
- );
1468
- }
1469
- async function relayFetch(url, options = {}, config = {}) {
1470
- const api = getOrCreateApiClient(config);
1471
- const {
1472
- authenticationId,
1473
- callbackUrl,
1474
- authenticationTemplate,
1475
- method = "GET",
1476
- body,
1477
- ...fetchOptions
1478
- } = options;
1479
- const relayPath = transformUrlToRelayPath(url);
1480
- const headers = {};
1481
- if (fetchOptions.headers) {
1482
- const headerEntries = fetchOptions.headers instanceof Headers ? Array.from(fetchOptions.headers.entries()) : Object.entries(fetchOptions.headers);
1483
- for (const [key, value] of headerEntries) {
1484
- headers[key] = value;
1867
+ if (appKeys.length > 0) {
1868
+ const groupedAppKeys = groupAppKeysByType(appKeys);
1869
+ if (groupedAppKeys.selectedApi.length > 0) {
1870
+ searchParams.selected_apis = groupedAppKeys.selectedApi.join(",");
1871
+ }
1872
+ if (groupedAppKeys.slug.length > 0) {
1873
+ searchParams.slugs = groupedAppKeys.slug.join(",");
1874
+ }
1485
1875
  }
1486
- }
1487
- if (authenticationId) {
1488
- headers["X-Relay-Authentication-Id"] = authenticationId.toString();
1489
- }
1490
- if (callbackUrl) {
1491
- headers["X-Relay-Callback-Url"] = callbackUrl;
1492
- }
1493
- if (authenticationTemplate) {
1494
- headers["X-Authentication-Template"] = authenticationTemplate;
1495
- }
1496
- return await api.fetch(relayPath, {
1497
- method,
1498
- body,
1499
- headers
1500
- });
1501
- }
1502
- var RelayRequestSchema = z.object({
1503
- url: z.string().url().describe("The URL to request (will be proxied through Relay)"),
1504
- method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method"),
1505
- body: z.string().optional().describe("Request body as a string"),
1506
- authenticationId: z.number().int().optional().describe("Zapier authentication ID to use for the request"),
1507
- callbackUrl: z.string().url().optional().describe("URL to send async response to (makes request async)"),
1508
- authenticationTemplate: z.string().optional().describe(
1509
- "Optional JSON string authentication template to bypass Notary lookup"
1510
- ),
1511
- headers: z.record(z.string()).optional().describe("Request headers")
1512
- }).describe("Make authenticated HTTP requests through Zapier's Relay service");
1513
- var RelayFetchSchema = RelayRequestSchema;
1514
- var AppItemSchema = withFormatter(
1515
- z.object({
1516
- key: z.string(),
1517
- name: z.string().optional(),
1518
- description: z.string().optional(),
1519
- category: z.string().optional()
1520
- }),
1521
- {
1522
- format: (item) => {
1523
- const details = [];
1524
- if (item.description) {
1525
- details.push({ text: item.description, style: "dim" });
1876
+ const implementationsEnvelope = await api.get(
1877
+ "/api/v4/implementations-meta/lookup/",
1878
+ {
1879
+ searchParams
1526
1880
  }
1527
- if (item.category) {
1528
- details.push({
1529
- text: `Category: ${item.category}`,
1530
- style: "accent"
1531
- });
1881
+ );
1882
+ return {
1883
+ data: implementationsEnvelope.results.map(
1884
+ normalizeImplementationMetaToAppItem
1885
+ ),
1886
+ nextCursor: extractCursor(implementationsEnvelope)
1887
+ };
1888
+ }, ListAppsSchema);
1889
+ return {
1890
+ listApps,
1891
+ context: {
1892
+ meta: {
1893
+ listApps: {
1894
+ inputSchema: ListAppsSchema
1895
+ }
1532
1896
  }
1533
- return {
1534
- title: item.name || item.key,
1535
- subtitle: `(${item.key})`,
1536
- details
1537
- };
1538
1897
  }
1539
- }
1540
- );
1541
-
1542
- // src/functions/listApps/schemas.ts
1543
- var ListAppsSchema = withOutputSchema(
1898
+ };
1899
+ };
1900
+ var GetAppSchema = withOutputSchema(
1544
1901
  z.object({
1545
- category: z.string().optional().describe("Filter apps by category"),
1546
- limit: LimitPropertySchema.optional().describe(
1547
- "Maximum number of items to return (1-200)"
1548
- ),
1549
- offset: OffsetPropertySchema.optional().describe(
1550
- "Number of items to skip for pagination"
1902
+ appKey: AppKeyPropertySchema.describe(
1903
+ "App key of app to fetch (e.g., 'SlackCLIAPI')"
1551
1904
  )
1552
- }).describe("List all available apps with optional filtering"),
1905
+ }).describe("Get detailed information about a specific app"),
1553
1906
  AppItemSchema
1554
1907
  );
1555
1908
 
1556
- // src/functions/listApps/info.ts
1557
- var listAppsInfo = {
1558
- name: listApps.name,
1559
- inputSchema: ListAppsSchema,
1560
- implementation: listApps
1561
- };
1562
- var GetAppSchema = z.object({
1563
- appKey: AppKeyPropertySchema.describe(
1564
- "App key or slug to fetch (e.g., google-sheets, slack, github)"
1565
- )
1566
- }).describe("Get detailed information about a specific app");
1567
-
1568
- // src/functions/getApp/info.ts
1569
- var getAppInfo = {
1570
- name: getApp.name,
1571
- inputSchema: GetAppSchema,
1572
- implementation: getApp
1909
+ // src/plugins/getApp/index.ts
1910
+ var getAppPlugin = ({ sdk }) => {
1911
+ const getApp = createFunction(async function getApp2(options) {
1912
+ const { appKey } = options;
1913
+ const appsIterator = sdk.listApps({
1914
+ ...options,
1915
+ appKeys: [appKey]
1916
+ }).items();
1917
+ const apps = [];
1918
+ for await (const app of appsIterator) {
1919
+ apps.push(app);
1920
+ break;
1921
+ }
1922
+ if (apps.length === 0) {
1923
+ throw new ZapierAppNotFoundError(appKey);
1924
+ }
1925
+ return {
1926
+ data: apps[0]
1927
+ };
1928
+ }, GetAppSchema);
1929
+ return {
1930
+ getApp,
1931
+ context: {
1932
+ meta: {
1933
+ getApp: {
1934
+ inputSchema: GetAppSchema
1935
+ }
1936
+ }
1937
+ }
1938
+ };
1573
1939
  };
1574
1940
  var ActionItemSchema = withFormatter(
1575
- z.object({
1576
- key: z.string(),
1577
- name: z.string().optional(),
1578
- type: z.string(),
1579
- appKey: z.string().optional(),
1580
- description: z.string().optional()
1941
+ ActionSchema.omit({ type: true, name: true }).extend({
1942
+ app_key: z.string(),
1943
+ // Mapped from selected_api
1944
+ action_type: ActionSchema.shape.type,
1945
+ // Mapped from original 'type' field
1946
+ title: z.string(),
1947
+ // Mapped from original 'name' field
1948
+ type: z.literal("action")
1949
+ // Fixed type identifier
1581
1950
  }),
1582
1951
  {
1583
1952
  format: (item) => {
1584
1953
  const details = [];
1585
- details.push({ text: `Type: ${item.type}`, style: "accent" });
1586
- if (item.appKey) {
1587
- details.push({ text: `App: ${item.appKey}`, style: "normal" });
1954
+ details.push({
1955
+ text: `Type: ${item.action_type}`,
1956
+ style: "accent"
1957
+ });
1958
+ if (item.app_key) {
1959
+ details.push({
1960
+ text: `App: ${item.app_key}`,
1961
+ style: "normal"
1962
+ });
1588
1963
  }
1589
1964
  if (item.description) {
1590
1965
  details.push({ text: item.description, style: "dim" });
1591
1966
  }
1592
1967
  return {
1593
- title: item.name || item.key,
1968
+ title: item.title || item.name || item.key,
1594
1969
  subtitle: `(${item.key})`,
1595
1970
  details
1596
1971
  };
@@ -1598,22 +1973,88 @@ var ActionItemSchema = withFormatter(
1598
1973
  }
1599
1974
  );
1600
1975
 
1601
- // src/functions/listActions/schemas.ts
1976
+ // src/plugins/listActions/schemas.ts
1602
1977
  var ListActionsSchema = withOutputSchema(
1603
1978
  z.object({
1604
- appKey: AppKeyPropertySchema.optional(),
1605
- type: ActionTypePropertySchema.optional().describe(
1979
+ appKey: AppKeyPropertySchema.describe(
1980
+ "App key of actions to list (e.g., 'SlackCLIAPI')"
1981
+ ),
1982
+ actionType: ActionTypePropertySchema.optional().describe(
1606
1983
  "Filter actions by type"
1607
- )
1984
+ ),
1985
+ pageSize: z.number().min(1).optional().describe("Number of actions per page"),
1986
+ maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
1608
1987
  }).describe("List all actions for a specific app"),
1609
1988
  ActionItemSchema
1610
1989
  );
1611
1990
 
1612
- // src/functions/listActions/info.ts
1613
- var listActionsInfo = {
1614
- name: listActions.name,
1615
- inputSchema: ListActionsSchema,
1616
- implementation: listActions
1991
+ // src/plugins/listActions/index.ts
1992
+ var listActionsPlugin = ({ sdk, context }) => {
1993
+ const listActions = createPaginatedFunction(async function listActionsPage(options) {
1994
+ const { api } = context;
1995
+ const app = await sdk.getApp({ appKey: options.appKey });
1996
+ const implementationId = app.data.current_implementation_id?.split("@")[0];
1997
+ if (!implementationId) {
1998
+ throw new ZapierConfigurationError(
1999
+ "No current_implementation_id found for app",
2000
+ { configType: "current_implementation_id" }
2001
+ );
2002
+ }
2003
+ const searchParams = {
2004
+ global: "true",
2005
+ public_only: "true",
2006
+ selected_apis: implementationId
2007
+ };
2008
+ const data = await api.get("/api/v4/implementations/", {
2009
+ searchParams,
2010
+ customErrorHandler: ({ status }) => {
2011
+ if (status === 401) {
2012
+ return new ZapierAuthenticationError(
2013
+ `Authentication failed. Your token may not have permission to access implementations or may be expired. (HTTP ${status})`,
2014
+ { statusCode: status }
2015
+ );
2016
+ }
2017
+ if (status === 403) {
2018
+ return new ZapierAuthenticationError(
2019
+ `Access forbidden. Your token may not have the required scopes to list implementations. (HTTP ${status})`,
2020
+ { statusCode: status }
2021
+ );
2022
+ }
2023
+ return void 0;
2024
+ }
2025
+ });
2026
+ let allActions = [];
2027
+ for (const implementation of data.results || []) {
2028
+ if (implementation.actions) {
2029
+ for (const action of implementation.actions) {
2030
+ const actionWithContext = {
2031
+ ...action,
2032
+ selected_api: action.selected_api || implementation.selected_api
2033
+ };
2034
+ allActions.push(normalizeActionItem(actionWithContext));
2035
+ }
2036
+ }
2037
+ }
2038
+ if (options.actionType) {
2039
+ allActions = allActions.filter(
2040
+ (action) => action.action_type === options.actionType
2041
+ );
2042
+ }
2043
+ return {
2044
+ data: allActions,
2045
+ nextCursor: void 0
2046
+ };
2047
+ }, ListActionsSchema);
2048
+ return {
2049
+ listActions,
2050
+ context: {
2051
+ meta: {
2052
+ listActions: {
2053
+ inputSchema: ListActionsSchema
2054
+ }
2055
+ }
2056
+ }
2057
+ };
1617
2058
  };
1618
2059
  var GetActionSchema = z.object({
1619
2060
  appKey: AppKeyPropertySchema,
@@ -1621,294 +2062,584 @@ var GetActionSchema = z.object({
1621
2062
  actionKey: ActionKeyPropertySchema
1622
2063
  }).describe("Get detailed information about a specific action");
1623
2064
 
1624
- // src/functions/getAction/info.ts
1625
- var getActionInfo = {
1626
- name: getAction.name,
1627
- inputSchema: GetActionSchema,
1628
- implementation: getAction
2065
+ // src/plugins/getAction/index.ts
2066
+ var getActionPlugin = ({ sdk }) => {
2067
+ const getAction = createFunction(async function getAction2(options) {
2068
+ const { actionKey, actionType, appKey } = options;
2069
+ const actionsResult = await sdk.listActions({ appKey });
2070
+ for (const action of actionsResult.data) {
2071
+ if (action.key === actionKey && action.action_type === actionType) {
2072
+ return { data: action };
2073
+ }
2074
+ }
2075
+ throw new ZapierResourceNotFoundError(
2076
+ `Action not found: ${actionKey} with type ${actionType}`,
2077
+ { resourceType: "Action", resourceId: `${actionKey} (${actionType})` }
2078
+ );
2079
+ }, GetActionSchema);
2080
+ return {
2081
+ getAction,
2082
+ context: {
2083
+ meta: {
2084
+ getAction: {
2085
+ inputSchema: GetActionSchema
2086
+ }
2087
+ }
2088
+ }
2089
+ };
1629
2090
  };
1630
2091
  var RunActionSchema = z.object({
1631
2092
  appKey: AppKeyPropertySchema,
1632
2093
  actionType: ActionTypePropertySchema,
1633
2094
  actionKey: ActionKeyPropertySchema,
2095
+ authenticationId: AuthenticationIdPropertySchema.nullable().optional(),
1634
2096
  inputs: InputsPropertySchema.optional().describe(
1635
2097
  "Input parameters for the action"
1636
2098
  ),
1637
- authenticationId: AuthenticationIdPropertySchema.optional()
2099
+ pageSize: z.number().min(1).optional().describe("Number of results per page"),
2100
+ maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
1638
2101
  }).describe("Execute an action with the given inputs");
1639
2102
 
1640
- // src/functions/runAction/info.ts
1641
- var runActionInfo = {
1642
- name: runAction.name,
1643
- inputSchema: RunActionSchema,
1644
- implementation: runAction
2103
+ // src/plugins/runAction/index.ts
2104
+ async function executeAction(actionOptions) {
2105
+ const {
2106
+ api,
2107
+ sdk,
2108
+ appKey,
2109
+ actionKey,
2110
+ actionType,
2111
+ executionOptions,
2112
+ authenticationId
2113
+ } = actionOptions;
2114
+ const appData = await sdk.getApp({ appKey });
2115
+ const selectedApi = appData.data.current_implementation_id;
2116
+ if (!selectedApi) {
2117
+ throw new ZapierConfigurationError(
2118
+ "No current_implementation_id found for app",
2119
+ { configType: "current_implementation_id" }
2120
+ );
2121
+ }
2122
+ const runRequestData = {
2123
+ selected_api: selectedApi,
2124
+ action_key: actionKey,
2125
+ action_type: actionType,
2126
+ inputs: executionOptions.inputs || {}
2127
+ };
2128
+ if (authenticationId !== null && authenticationId !== void 0) {
2129
+ runRequestData.authentication_id = authenticationId;
2130
+ }
2131
+ const runRequest = {
2132
+ data: runRequestData
2133
+ };
2134
+ const runData = await api.post("/api/actions/v1/runs", runRequest);
2135
+ const runId = runData.data.id;
2136
+ return await api.poll(`/api/actions/v1/runs/${runId}`, {
2137
+ successStatus: 200,
2138
+ pendingStatus: 202,
2139
+ resultExtractor: (result) => result.data
2140
+ });
2141
+ }
2142
+ var runActionPlugin = ({ sdk, context }) => {
2143
+ const runAction = createPaginatedFunction(async function runActionPage(options) {
2144
+ const { api } = context;
2145
+ const {
2146
+ appKey,
2147
+ actionKey,
2148
+ actionType,
2149
+ authenticationId,
2150
+ inputs = {}
2151
+ } = options;
2152
+ const actionData = await sdk.getAction({
2153
+ appKey,
2154
+ actionKey,
2155
+ actionType
2156
+ });
2157
+ if (actionData.data.action_type !== actionType) {
2158
+ throw new ZapierValidationError(
2159
+ `Action type mismatch: expected ${actionType}, got ${actionData.data.action_type}`
2160
+ );
2161
+ }
2162
+ const result = await executeAction({
2163
+ api,
2164
+ sdk,
2165
+ appKey,
2166
+ actionKey,
2167
+ actionType,
2168
+ executionOptions: { inputs },
2169
+ authenticationId});
2170
+ if (result.errors && result.errors.length > 0) {
2171
+ const errorMessage = result.errors.map(
2172
+ (error) => error.detail || error.title || "Unknown error"
2173
+ ).join("; ");
2174
+ throw new ZapierActionError(`Action execution failed: ${errorMessage}`, {
2175
+ appKey,
2176
+ actionKey
2177
+ });
2178
+ }
2179
+ return {
2180
+ data: result.results || [],
2181
+ nextCursor: void 0
2182
+ // No pagination implemented yet
2183
+ };
2184
+ }, RunActionSchema);
2185
+ return {
2186
+ runAction,
2187
+ context: {
2188
+ meta: {
2189
+ runAction: {
2190
+ inputSchema: RunActionSchema
2191
+ }
2192
+ }
2193
+ }
2194
+ };
1645
2195
  };
1646
- var AuthItemSchema = withFormatter(
1647
- z.object({
1648
- id: z.number(),
1649
- title: z.string().optional(),
1650
- identifier: z.string().optional(),
1651
- account_id: z.string().optional(),
1652
- is_private: z.boolean().optional(),
1653
- shared_with_all: z.boolean().optional(),
1654
- marked_stale_at: z.string().optional()
1655
- }),
1656
- {
1657
- format: (item) => {
1658
- const details = [];
1659
- if (item.identifier) {
1660
- details.push({
1661
- text: `Identifier: ${item.identifier}`,
1662
- style: "accent"
2196
+ var ListAuthenticationsSchema = z.object({
2197
+ appKey: AppKeyPropertySchema.optional().describe(
2198
+ "App key of authentications to list (e.g., 'SlackCLIAPI')"
2199
+ ),
2200
+ search: z.string().optional().describe("Search term to filter authentications by title"),
2201
+ title: z.string().optional().describe("Filter authentications by exact title match"),
2202
+ account_id: z.string().optional().describe("Filter by account ID"),
2203
+ owner: z.string().optional().describe("Filter by owner"),
2204
+ pageSize: z.number().min(1).optional().describe("Number of authentications per page"),
2205
+ maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
2206
+ }).describe("List available authentications with optional filtering");
2207
+
2208
+ // src/plugins/listAuthentications/index.ts
2209
+ var listAuthenticationsPlugin = ({ sdk, context }) => {
2210
+ const listAuthentications = createPaginatedFunction(
2211
+ async function listAuthenticationsPage(options) {
2212
+ const { api } = context;
2213
+ const searchParams = {};
2214
+ if (options.appKey) {
2215
+ const app = await sdk.getApp({
2216
+ appKey: options.appKey
1663
2217
  });
2218
+ const selectedApi = app.data.current_implementation_id;
2219
+ if (selectedApi) {
2220
+ const versionlessApi = selectedApi.split("@")[0];
2221
+ searchParams.versionless_selected_api = versionlessApi;
2222
+ }
1664
2223
  }
1665
- details.push({
1666
- text: `Account: ${item.account_id || "unknown"} | Private: ${item.is_private || false} | Shared: ${item.shared_with_all || false}`,
1667
- style: "dim"
1668
- });
1669
- if (item.marked_stale_at) {
1670
- details.push({
1671
- text: `\u26A0\uFE0F Marked stale: ${new Date(item.marked_stale_at).toLocaleDateString()}`,
1672
- style: "warning"
1673
- });
2224
+ if (options.search) {
2225
+ searchParams.search = options.search;
2226
+ } else if (options.title) {
2227
+ searchParams.search = options.title;
2228
+ }
2229
+ if (options.account_id) {
2230
+ searchParams.account_id = options.account_id;
2231
+ }
2232
+ if (options.owner) {
2233
+ searchParams.owner = options.owner;
2234
+ }
2235
+ searchParams.limit = options.pageSize.toString();
2236
+ if (options.cursor) {
2237
+ searchParams.offset = options.cursor;
2238
+ }
2239
+ const data = await api.get(
2240
+ "/api/v4/authentications/",
2241
+ {
2242
+ searchParams,
2243
+ customErrorHandler: ({ status }) => {
2244
+ if (status === 401) {
2245
+ return new ZapierAuthenticationError(
2246
+ `Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${status})`,
2247
+ { statusCode: status }
2248
+ );
2249
+ }
2250
+ if (status === 403) {
2251
+ return new ZapierAuthenticationError(
2252
+ `Access forbidden. Your token may not have the required scopes to list authentications. (HTTP ${status})`,
2253
+ { statusCode: status }
2254
+ );
2255
+ }
2256
+ return void 0;
2257
+ },
2258
+ authRequired: true
2259
+ }
2260
+ );
2261
+ let auths = (data.results || []).map(
2262
+ (auth) => normalizeAuthenticationItem(auth)
2263
+ );
2264
+ if (options.title) {
2265
+ auths = auths.filter((auth) => auth.title === options.title);
1674
2266
  }
1675
2267
  return {
1676
- title: item.title || `Authentication ${item.id}`,
1677
- subtitle: `(ID: ${item.id})`,
1678
- details
2268
+ data: auths,
2269
+ nextCursor: extractCursor(data)
1679
2270
  };
2271
+ },
2272
+ ListAuthenticationsSchema
2273
+ );
2274
+ return {
2275
+ listAuthentications,
2276
+ context: {
2277
+ meta: {
2278
+ listAuthentications: {
2279
+ inputSchema: ListAuthenticationsSchema
2280
+ }
2281
+ }
1680
2282
  }
1681
- }
1682
- );
1683
-
1684
- // src/functions/listAuthentications/schemas.ts
1685
- var ListAuthenticationsSchema = withOutputSchema(
1686
- z.object({
1687
- appKey: AppKeyPropertySchema.optional().describe(
1688
- "App slug to get authentications for (e.g., 'slack', 'github')"
1689
- ),
1690
- search: z.string().optional().describe("Search term to filter authentications by title"),
1691
- title: z.string().optional().describe("Filter authentications by exact title match"),
1692
- account_id: z.string().optional().describe("Filter by account ID"),
1693
- owner: z.string().optional().describe("Filter by owner"),
1694
- limit: LimitPropertySchema.optional().describe(
1695
- "Maximum number of items to return (1-200)"
1696
- ),
1697
- offset: OffsetPropertySchema.optional().describe(
1698
- "Number of items to skip for pagination"
1699
- )
1700
- }).describe("List available authentications with optional filtering"),
1701
- AuthItemSchema
1702
- );
1703
-
1704
- // src/functions/listAuthentications/info.ts
1705
- var listAuthenticationsInfo = {
1706
- name: listAuthentications.name,
1707
- inputSchema: ListAuthenticationsSchema,
1708
- implementation: listAuthentications
2283
+ };
1709
2284
  };
1710
- var GetAuthenticationSchema = withOutputSchema(
1711
- z.object({
1712
- authenticationId: z.number().int().positive().describe("Authentication ID to retrieve")
1713
- }).describe("Get a specific authentication by ID"),
1714
- AuthItemSchema
1715
- );
2285
+ var GetAuthenticationSchema = z.object({
2286
+ authenticationId: z.number().int().positive().describe("Authentication ID to retrieve")
2287
+ }).describe("Get a specific authentication by ID");
1716
2288
 
1717
- // src/functions/getAuthentication/info.ts
1718
- var getAuthenticationInfo = {
1719
- name: getAuthentication.name,
1720
- inputSchema: GetAuthenticationSchema,
1721
- implementation: getAuthentication
1722
- };
1723
- var FindFirstAuthenticationSchema = withOutputSchema(
1724
- z.object({
1725
- appKey: AppKeyPropertySchema.optional().describe(
1726
- "App slug to get authentications for (e.g., 'slack', 'github')"
1727
- ),
1728
- search: z.string().optional().describe("Search term to filter authentications by title"),
1729
- title: z.string().optional().describe("Filter authentications by exact title match"),
1730
- account_id: z.string().optional().describe("Filter by account ID"),
1731
- owner: z.string().optional().describe("Filter by owner"),
1732
- limit: LimitPropertySchema.optional().describe(
1733
- "Maximum number of items to return (1-200)"
1734
- ),
1735
- offset: OffsetPropertySchema.optional().describe(
1736
- "Number of items to skip for pagination"
1737
- )
1738
- }).describe("Find the first authentication matching the criteria"),
1739
- AuthItemSchema
1740
- );
1741
-
1742
- // src/functions/findFirstAuthentication/info.ts
1743
- var findFirstAuthenticationInfo = {
1744
- name: findFirstAuthentication.name,
1745
- inputSchema: FindFirstAuthenticationSchema,
1746
- implementation: findFirstAuthentication
2289
+ // src/plugins/getAuthentication/index.ts
2290
+ var getAuthenticationPlugin = ({ context }) => {
2291
+ const getAuthentication = createFunction(async function getAuthentication2(options) {
2292
+ const { api } = context;
2293
+ const { authenticationId } = options;
2294
+ const data = await api.get(
2295
+ `/api/v4/authentications/${authenticationId}/`,
2296
+ {
2297
+ customErrorHandler: ({ status }) => {
2298
+ if (status === 401) {
2299
+ return new ZapierAuthenticationError(
2300
+ `Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${status})`,
2301
+ { statusCode: status }
2302
+ );
2303
+ }
2304
+ if (status === 403) {
2305
+ return new ZapierAuthenticationError(
2306
+ `Access forbidden. Your token may not have the required scopes to get authentication ${authenticationId}. (HTTP ${status})`,
2307
+ { statusCode: status }
2308
+ );
2309
+ }
2310
+ if (status === 404) {
2311
+ return new ZapierResourceNotFoundError(
2312
+ `Authentication ${authenticationId} not found. It may not exist or you may not have access to it. (HTTP ${status})`,
2313
+ {
2314
+ resourceType: "Authentication",
2315
+ resourceId: String(authenticationId)
2316
+ }
2317
+ );
2318
+ }
2319
+ return void 0;
2320
+ },
2321
+ authRequired: true
2322
+ }
2323
+ );
2324
+ return {
2325
+ data: normalizeAuthenticationItem(data)
2326
+ };
2327
+ }, GetAuthenticationSchema);
2328
+ return {
2329
+ getAuthentication,
2330
+ context: {
2331
+ meta: {
2332
+ getAuthentication: {
2333
+ inputSchema: GetAuthenticationSchema
2334
+ }
2335
+ }
2336
+ }
2337
+ };
1747
2338
  };
1748
- var FindUniqueAuthenticationSchema = withOutputSchema(
1749
- z.object({
1750
- appKey: AppKeyPropertySchema.optional().describe(
1751
- "App slug to get authentications for (e.g., 'slack', 'github')"
1752
- ),
1753
- search: z.string().optional().describe("Search term to filter authentications by title"),
1754
- title: z.string().optional().describe("Filter authentications by exact title match"),
1755
- account_id: z.string().optional().describe("Filter by account ID"),
1756
- owner: z.string().optional().describe("Filter by owner"),
1757
- limit: LimitPropertySchema.optional().describe(
1758
- "Maximum number of items to return (1-200)"
1759
- ),
1760
- offset: OffsetPropertySchema.optional().describe(
1761
- "Number of items to skip for pagination"
1762
- )
1763
- }).describe("Find a unique authentication matching the criteria"),
1764
- AuthItemSchema
1765
- );
2339
+ var FindFirstAuthenticationSchema = z.object({
2340
+ appKey: AppKeyPropertySchema.optional().describe(
2341
+ "App key of authentication to find (e.g., 'SlackCLIAPI')"
2342
+ ),
2343
+ search: z.string().optional().describe("Search term to filter authentications by title"),
2344
+ title: z.string().optional().describe("Filter authentications by exact title match"),
2345
+ account_id: z.string().optional().describe("Filter by account ID"),
2346
+ owner: z.string().optional().describe("Filter by owner")
2347
+ }).describe("Find the first authentication matching the criteria");
1766
2348
 
1767
- // src/functions/findUniqueAuthentication/info.ts
1768
- var findUniqueAuthenticationInfo = {
1769
- name: findUniqueAuthentication.name,
1770
- inputSchema: FindUniqueAuthenticationSchema,
1771
- implementation: findUniqueAuthentication
1772
- };
1773
- var FieldItemSchema = withFormatter(
1774
- z.object({
1775
- key: z.string(),
1776
- name: z.string().optional(),
1777
- description: z.string().optional()
1778
- }),
1779
- {
1780
- format: (item) => {
1781
- const details = [];
1782
- if (item.description) {
1783
- details.push({ text: item.description, style: "dim" });
1784
- }
2349
+ // src/plugins/findFirstAuthentication/index.ts
2350
+ var findFirstAuthenticationPlugin = ({ sdk }) => {
2351
+ const findFirstAuthentication = createFunction(
2352
+ async function findFirstAuthentication2(options = {}) {
2353
+ const authsResponse = await sdk.listAuthentications({
2354
+ ...options,
2355
+ maxItems: 1
2356
+ });
1785
2357
  return {
1786
- title: item.name || item.key,
1787
- subtitle: `(${item.key})`,
1788
- details
2358
+ data: authsResponse.data.length > 0 ? authsResponse.data[0] : null
1789
2359
  };
2360
+ },
2361
+ FindFirstAuthenticationSchema
2362
+ );
2363
+ return {
2364
+ findFirstAuthentication,
2365
+ context: {
2366
+ meta: {
2367
+ findFirstAuthentication: {
2368
+ inputSchema: FindFirstAuthenticationSchema
2369
+ }
2370
+ }
1790
2371
  }
1791
- }
1792
- );
1793
-
1794
- // src/functions/listFields/schemas.ts
1795
- var ListFieldsSchema = withOutputSchema(
1796
- z.object({
1797
- appKey: AppKeyPropertySchema,
1798
- actionType: ActionTypePropertySchema,
1799
- actionKey: ActionKeyPropertySchema,
1800
- authenticationId: AuthenticationIdPropertySchema.optional(),
1801
- params: ParamsPropertySchema.optional().describe(
1802
- "Additional parameters that may affect available fields"
1803
- )
1804
- }).describe("Get the input fields required for a specific action"),
1805
- FieldItemSchema
1806
- );
1807
-
1808
- // src/functions/listFields/info.ts
1809
- var listFieldsInfo = {
1810
- name: listFields.name,
1811
- inputSchema: ListFieldsSchema,
1812
- implementation: listFields
2372
+ };
1813
2373
  };
1814
- var GenerateTypesSchema = z.object({
1815
- appKey: AppKeyPropertySchema.describe("App key to generate SDK code for"),
1816
- authenticationId: AuthenticationIdPropertySchema.optional(),
1817
- output: OutputPropertySchema.optional().describe(
1818
- "Output file path (defaults to generated/<appKey>.ts)"
2374
+ var FindUniqueAuthenticationSchema = z.object({
2375
+ appKey: AppKeyPropertySchema.optional().describe(
2376
+ "App key of authentication to find (e.g., 'SlackCLIAPI')"
1819
2377
  ),
1820
- debug: DebugPropertySchema.describe(
1821
- "Enable debug logging during generation"
1822
- )
1823
- }).describe("Generate TypeScript SDK code for a specific app");
2378
+ search: z.string().optional().describe("Search term to filter authentications by title"),
2379
+ title: z.string().optional().describe("Filter authentications by exact title match"),
2380
+ account_id: z.string().optional().describe("Filter by account ID"),
2381
+ owner: z.string().optional().describe("Filter by owner")
2382
+ }).describe("Find a unique authentication matching the criteria");
1824
2383
 
1825
- // src/functions/generateTypes/info.ts
1826
- var generateTypesInfo = {
1827
- name: generateTypes.name,
1828
- inputSchema: GenerateTypesSchema,
1829
- implementation: generateTypes
2384
+ // src/plugins/findUniqueAuthentication/index.ts
2385
+ var findUniqueAuthenticationPlugin = ({ sdk }) => {
2386
+ const findUniqueAuthentication = createFunction(
2387
+ async function findUniqueAuthentication2(options = {}) {
2388
+ const authsResponse = await sdk.listAuthentications({
2389
+ ...options,
2390
+ maxItems: 2
2391
+ // Get up to 2 to check for uniqueness
2392
+ });
2393
+ if (authsResponse.data.length === 0) {
2394
+ throw new ZapierResourceNotFoundError(
2395
+ "No authentication found matching the specified criteria",
2396
+ { resourceType: "Authentication" }
2397
+ );
2398
+ }
2399
+ if (authsResponse.data.length > 1) {
2400
+ throw new ZapierValidationError(
2401
+ "Multiple authentications found matching the specified criteria. Expected exactly one."
2402
+ );
2403
+ }
2404
+ return {
2405
+ data: authsResponse.data[0]
2406
+ };
2407
+ },
2408
+ FindUniqueAuthenticationSchema
2409
+ );
2410
+ return {
2411
+ findUniqueAuthentication,
2412
+ context: {
2413
+ meta: {
2414
+ findUniqueAuthentication: {
2415
+ inputSchema: FindUniqueAuthenticationSchema
2416
+ }
2417
+ }
2418
+ }
2419
+ };
1830
2420
  };
1831
- var BundleCodeSchema = z.object({
1832
- input: z.string().min(1).describe("Input TypeScript file path to bundle"),
1833
- output: OutputPropertySchema.optional().describe(
1834
- "Output file path (defaults to input with .js extension)"
2421
+ var ListInputFieldsSchema = z.object({
2422
+ appKey: AppKeyPropertySchema,
2423
+ actionType: ActionTypePropertySchema,
2424
+ actionKey: ActionKeyPropertySchema,
2425
+ authenticationId: AuthenticationIdPropertySchema.nullable().optional(),
2426
+ inputs: InputsPropertySchema.optional().describe(
2427
+ "Current input values that may affect available fields"
1835
2428
  ),
1836
- string: z.boolean().default(false).describe("Return bundled code as string instead of writing to file"),
1837
- minify: z.boolean().default(false).describe("Minify the bundled output"),
1838
- target: z.string().default("es2017").describe("ECMAScript target version"),
1839
- cjs: z.boolean().default(false).describe("Output CommonJS format instead of ESM")
1840
- }).describe("Bundle TypeScript code into executable JavaScript");
2429
+ pageSize: z.number().min(1).optional().describe("Number of input fields per page"),
2430
+ maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
2431
+ }).describe("Get the input fields required for a specific action");
1841
2432
 
1842
- // src/functions/bundleCode/info.ts
1843
- var bundleCodeInfo = {
1844
- name: bundleCode.name,
1845
- inputSchema: BundleCodeSchema,
1846
- implementation: bundleCode
2433
+ // src/plugins/listInputFields/index.ts
2434
+ function getInputFieldTypeFromNeed(need) {
2435
+ if (need.list) {
2436
+ return "ARRAY" /* ARRAY */;
2437
+ }
2438
+ const typeMap = {
2439
+ string: "STRING" /* STRING */,
2440
+ decimal: "NUMBER" /* NUMBER */,
2441
+ integer: "INTEGER" /* INTEGER */,
2442
+ boolean: "BOOLEAN" /* BOOLEAN */,
2443
+ dict: "OBJECT" /* OBJECT */
2444
+ };
2445
+ return typeMap[need.type || ""] || "STRING" /* STRING */;
2446
+ }
2447
+ function getInputFieldFormatFromNeed(need) {
2448
+ if (need.prefill || need.choices) {
2449
+ return "SELECT" /* SELECT */;
2450
+ }
2451
+ const formatMap = {
2452
+ text: "MULTILINE" /* MULTILINE */,
2453
+ datetime: "DATETIME" /* DATETIME */,
2454
+ file: "FILE" /* FILE */,
2455
+ password: "PASSWORD" /* PASSWORD */,
2456
+ code: "CODE" /* CODE */
2457
+ };
2458
+ return formatMap[need.type || ""];
2459
+ }
2460
+ function getItemsTypeFromNeed(need) {
2461
+ if (!need.list) {
2462
+ return void 0;
2463
+ }
2464
+ const typeMap = {
2465
+ string: "STRING" /* STRING */,
2466
+ decimal: "NUMBER" /* NUMBER */,
2467
+ integer: "INTEGER" /* INTEGER */,
2468
+ boolean: "BOOLEAN" /* BOOLEAN */,
2469
+ dict: "OBJECT" /* OBJECT */
2470
+ };
2471
+ return typeMap[need.type || ""] || "STRING" /* STRING */;
2472
+ }
2473
+ function transformNeedToInputFieldItem(need) {
2474
+ const itemsType = getItemsTypeFromNeed(need);
2475
+ return {
2476
+ ...need,
2477
+ // Pass through all original Need fields
2478
+ id: need.key,
2479
+ default_value: need.default || "",
2480
+ depends_on: need.depends_on || [],
2481
+ description: need.help_text || "",
2482
+ invalidates_input_fields: need.alters_custom_fields || false,
2483
+ is_required: need.required || false,
2484
+ placeholder: need.placeholder || "",
2485
+ title: need.label || "",
2486
+ value_type: getInputFieldTypeFromNeed(need),
2487
+ format: getInputFieldFormatFromNeed(need),
2488
+ items: itemsType ? { type: itemsType } : void 0
2489
+ };
2490
+ }
2491
+ var listInputFieldsPlugin = ({ sdk, context }) => {
2492
+ const listInputFields = createPaginatedFunction(
2493
+ async function listInputFieldsPage(options) {
2494
+ const { api } = context;
2495
+ const { appKey, actionKey, actionType, authenticationId, inputs } = options;
2496
+ const appData = await sdk.getApp({ appKey });
2497
+ const selectedApi = appData.data.current_implementation_id;
2498
+ if (!selectedApi) {
2499
+ throw new ZapierConfigurationError(
2500
+ "No current_implementation_id found for app",
2501
+ { configType: "current_implementation_id" }
2502
+ );
2503
+ }
2504
+ const needsRequest = {
2505
+ selected_api: selectedApi,
2506
+ action: actionKey,
2507
+ type_of: actionType,
2508
+ params: inputs || {}
2509
+ };
2510
+ if (authenticationId !== null) {
2511
+ needsRequest.authentication_id = authenticationId;
2512
+ }
2513
+ const needsData = await api.post(
2514
+ "/api/v4/implementations/needs/",
2515
+ needsRequest
2516
+ );
2517
+ if (!needsData.success) {
2518
+ throw new ZapierApiError(
2519
+ `Failed to get action fields: ${needsData.errors?.join(", ") || "Unknown error"}`
2520
+ );
2521
+ }
2522
+ const inputFields = (needsData.needs || []).map(
2523
+ transformNeedToInputFieldItem
2524
+ );
2525
+ return {
2526
+ data: inputFields,
2527
+ nextCursor: void 0
2528
+ // No pagination needed since we return all input fields
2529
+ };
2530
+ },
2531
+ ListInputFieldsSchema
2532
+ );
2533
+ return {
2534
+ listInputFields,
2535
+ context: {
2536
+ meta: {
2537
+ listInputFields: {
2538
+ inputSchema: ListInputFieldsSchema
2539
+ }
2540
+ }
2541
+ }
2542
+ };
1847
2543
  };
1848
2544
 
1849
- // src/functions/request/info.ts
1850
- var requestInfo = {
1851
- name: "request",
1852
- inputSchema: RelayRequestSchema,
1853
- implementation: request
2545
+ // src/plugins/request/index.ts
2546
+ function transformUrlToRelayPath(url) {
2547
+ const targetUrl = new URL(url);
2548
+ const relayPath = `/relay/${targetUrl.host}${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
2549
+ return relayPath;
2550
+ }
2551
+ var requestPlugin = ({ context }) => {
2552
+ const request = createFunction(async function request2(options) {
2553
+ const { api } = context;
2554
+ const {
2555
+ url,
2556
+ method = "GET",
2557
+ body,
2558
+ headers: optionsHeaders,
2559
+ authenticationId,
2560
+ callbackUrl,
2561
+ authenticationTemplate
2562
+ } = options;
2563
+ const relayPath = transformUrlToRelayPath(url);
2564
+ const headers = {};
2565
+ if (optionsHeaders) {
2566
+ const headerEntries = optionsHeaders instanceof Headers ? Array.from(optionsHeaders.entries()) : Array.isArray(optionsHeaders) ? optionsHeaders : Object.entries(optionsHeaders);
2567
+ for (const [key, value] of headerEntries) {
2568
+ headers[key] = value;
2569
+ }
2570
+ }
2571
+ if (authenticationId) {
2572
+ headers["X-Relay-Authentication-Id"] = authenticationId.toString();
2573
+ }
2574
+ if (callbackUrl) {
2575
+ headers["X-Relay-Callback-Url"] = callbackUrl;
2576
+ }
2577
+ if (authenticationTemplate) {
2578
+ headers["X-Authentication-Template"] = authenticationTemplate;
2579
+ }
2580
+ return await api.fetch(relayPath, {
2581
+ method,
2582
+ body,
2583
+ headers
2584
+ });
2585
+ }, RelayRequestSchema);
2586
+ return {
2587
+ request,
2588
+ context: {
2589
+ meta: {
2590
+ request: {
2591
+ inputSchema: RelayRequestSchema
2592
+ }
2593
+ }
2594
+ }
2595
+ };
1854
2596
  };
1855
2597
 
1856
2598
  // src/sdk.ts
1857
- var functionRegistry = [
1858
- listAppsInfo,
1859
- getAppInfo,
1860
- listActionsInfo,
1861
- getActionInfo,
1862
- runActionInfo,
1863
- listAuthenticationsInfo,
1864
- getAuthenticationInfo,
1865
- findFirstAuthenticationInfo,
1866
- findUniqueAuthenticationInfo,
1867
- listFieldsInfo,
1868
- generateTypesInfo,
1869
- bundleCodeInfo,
1870
- requestInfo
1871
- ];
1872
- function createZapierSdk(options = {}) {
1873
- const {
1874
- fetch: customFetch = globalThis.fetch,
1875
- baseUrl = "https://zapier.com",
1876
- token,
1877
- getToken,
1878
- onEvent,
1879
- debug = false
1880
- } = options;
1881
- const api = createZapierApi({
1882
- baseUrl,
1883
- token,
1884
- getToken,
1885
- debug,
1886
- fetch: customFetch,
1887
- onEvent
1888
- });
1889
- const baseSdk = {
1890
- // Registry for CLI
1891
- __registry: functionRegistry,
1892
- // Function implementations with API config injection
1893
- listApps: (options2 = {}) => listApps({ ...options2, api }),
1894
- getApp: (options2) => getApp({ ...options2, api }),
1895
- listActions: (options2 = {}) => listActions({ ...options2, api }),
1896
- getAction: (options2) => getAction({ ...options2, api }),
1897
- runAction: (options2) => runAction({ ...options2, api }),
1898
- listAuthentications: (options2 = {}) => listAuthentications({ ...options2, api }),
1899
- getAuthentication: (options2) => getAuthentication({ ...options2, api }),
1900
- findFirstAuthentication: (options2 = {}) => findFirstAuthentication({ ...options2, api }),
1901
- findUniqueAuthentication: (options2 = {}) => findUniqueAuthentication({ ...options2, api }),
1902
- listFields: (options2) => listFields({ ...options2, api }),
1903
- generateTypes: (options2) => generateTypes({ ...options2, api }),
1904
- bundleCode: (options2) => bundleCode(options2),
1905
- // No API config needed
1906
- request: (options2) => request({ ...options2, api })
2599
+ function createSdk(initialSdk = {}, initialContext = { meta: {} }) {
2600
+ return {
2601
+ ...initialSdk,
2602
+ getContext: () => initialContext,
2603
+ addPlugin(plugin, options = {}) {
2604
+ const currentSdkWithContext = {
2605
+ ...initialSdk,
2606
+ getContext: () => initialContext
2607
+ };
2608
+ const pluginResult = plugin({
2609
+ sdk: currentSdkWithContext,
2610
+ context: initialContext,
2611
+ ...options
2612
+ });
2613
+ const { context: pluginContext, ...sdkProperties } = pluginResult;
2614
+ const newSdk = { ...initialSdk, ...sdkProperties };
2615
+ let newContext = {
2616
+ ...initialContext,
2617
+ meta: initialContext.meta || {}
2618
+ };
2619
+ if (pluginContext) {
2620
+ const { meta: pluginMeta, ...otherPluginContext } = pluginContext;
2621
+ newContext = {
2622
+ ...newContext,
2623
+ ...otherPluginContext
2624
+ };
2625
+ if (pluginMeta) {
2626
+ newContext = {
2627
+ ...newContext,
2628
+ meta: {
2629
+ ...newContext.meta,
2630
+ // Existing meta (now guaranteed to exist)
2631
+ ...pluginMeta
2632
+ // New meta from plugin
2633
+ }
2634
+ };
2635
+ }
2636
+ }
2637
+ return createSdk(newSdk, newContext);
2638
+ }
1907
2639
  };
1908
- const fullSdk = baseSdk;
1909
- fullSdk.apps = createAppsPlugin({ sdk: fullSdk });
1910
- fullSdk.fetch = createFetchPlugin({ sdk: fullSdk });
1911
- return fullSdk;
2640
+ }
2641
+ function createZapierSdk(options = {}) {
2642
+ return createSdk().addPlugin(apiPlugin, options).addPlugin(listAppsPlugin).addPlugin(getAppPlugin).addPlugin(listActionsPlugin).addPlugin(getActionPlugin).addPlugin(listInputFieldsPlugin).addPlugin(runActionPlugin).addPlugin(listAuthenticationsPlugin).addPlugin(getAuthenticationPlugin).addPlugin(findFirstAuthenticationPlugin).addPlugin(findUniqueAuthenticationPlugin).addPlugin(requestPlugin).addPlugin(fetchPlugin).addPlugin(appsPlugin).addPlugin(getProfilePlugin).addPlugin(registryPlugin);
1912
2643
  }
1913
2644
 
1914
- export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppNotFoundError, AuthenticationIdPropertySchema, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZapierSdkError, actionKeyResolver, actionTypeResolver, appKeyResolver, authenticationIdResolver, bundleCode, createAppsPlugin, createFetchPlugin, createZapierSdk, findFirstAuthentication, findUniqueAuthentication, generateTypes, getAction, getApp, getAuthentication, getResolutionOrder, getResolutionOrderForParams, getResolvableParams, getResolver, getResolversForMissingParams, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, hasResolver, inputsResolver, isPositional, listActions, listApps, listAuthentications, listFields, relayFetch, request, resolverRegistry, runAction };
2645
+ export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, appKeyResolver, appsPlugin, authenticationIdResolver, createSdk, createZapierSdk, fetchPlugin, formatErrorMessage, getResolutionOrder, getResolutionOrderForParams, getResolvableParams, getResolver, getResolversForMissingParams, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, hasResolver, inputsResolver, isPositional, resolverRegistry };