resend-cli 1.2.1 → 1.3.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 (357) hide show
  1. package/README.md +25 -10
  2. package/dist/cli.cjs +539 -0
  3. package/package.json +31 -13
  4. package/.claude/settings.local.json +0 -5
  5. package/.claude/worktrees/emails-list/.claude/settings.local.json +0 -5
  6. package/.claude/worktrees/emails-list/.github/scripts/pr-title-check.js +0 -34
  7. package/.claude/worktrees/emails-list/.github/workflows/ci.yml +0 -32
  8. package/.claude/worktrees/emails-list/.github/workflows/pr-title-check.yml +0 -13
  9. package/.claude/worktrees/emails-list/.github/workflows/release.yml +0 -93
  10. package/.claude/worktrees/emails-list/CHANGELOG.md +0 -31
  11. package/.claude/worktrees/emails-list/LICENSE +0 -21
  12. package/.claude/worktrees/emails-list/README.md +0 -424
  13. package/.claude/worktrees/emails-list/biome.json +0 -36
  14. package/.claude/worktrees/emails-list/bun.lock +0 -76
  15. package/.claude/worktrees/emails-list/bunfig.toml +0 -2
  16. package/.claude/worktrees/emails-list/install.ps1 +0 -140
  17. package/.claude/worktrees/emails-list/install.sh +0 -301
  18. package/.claude/worktrees/emails-list/package.json +0 -43
  19. package/.claude/worktrees/emails-list/renovate.json +0 -6
  20. package/.claude/worktrees/emails-list/src/cli.ts +0 -74
  21. package/.claude/worktrees/emails-list/src/commands/api-keys/create.ts +0 -114
  22. package/.claude/worktrees/emails-list/src/commands/api-keys/delete.ts +0 -47
  23. package/.claude/worktrees/emails-list/src/commands/api-keys/index.ts +0 -26
  24. package/.claude/worktrees/emails-list/src/commands/api-keys/list.ts +0 -35
  25. package/.claude/worktrees/emails-list/src/commands/api-keys/utils.ts +0 -8
  26. package/.claude/worktrees/emails-list/src/commands/auth/index.ts +0 -20
  27. package/.claude/worktrees/emails-list/src/commands/auth/login.ts +0 -207
  28. package/.claude/worktrees/emails-list/src/commands/auth/logout.ts +0 -105
  29. package/.claude/worktrees/emails-list/src/commands/broadcasts/create.ts +0 -196
  30. package/.claude/worktrees/emails-list/src/commands/broadcasts/delete.ts +0 -46
  31. package/.claude/worktrees/emails-list/src/commands/broadcasts/get.ts +0 -59
  32. package/.claude/worktrees/emails-list/src/commands/broadcasts/index.ts +0 -43
  33. package/.claude/worktrees/emails-list/src/commands/broadcasts/list.ts +0 -60
  34. package/.claude/worktrees/emails-list/src/commands/broadcasts/send.ts +0 -56
  35. package/.claude/worktrees/emails-list/src/commands/broadcasts/update.ts +0 -95
  36. package/.claude/worktrees/emails-list/src/commands/broadcasts/utils.ts +0 -35
  37. package/.claude/worktrees/emails-list/src/commands/contact-properties/create.ts +0 -118
  38. package/.claude/worktrees/emails-list/src/commands/contact-properties/delete.ts +0 -48
  39. package/.claude/worktrees/emails-list/src/commands/contact-properties/get.ts +0 -46
  40. package/.claude/worktrees/emails-list/src/commands/contact-properties/index.ts +0 -48
  41. package/.claude/worktrees/emails-list/src/commands/contact-properties/list.ts +0 -68
  42. package/.claude/worktrees/emails-list/src/commands/contact-properties/update.ts +0 -88
  43. package/.claude/worktrees/emails-list/src/commands/contact-properties/utils.ts +0 -17
  44. package/.claude/worktrees/emails-list/src/commands/contacts/add-segment.ts +0 -78
  45. package/.claude/worktrees/emails-list/src/commands/contacts/create.ts +0 -122
  46. package/.claude/worktrees/emails-list/src/commands/contacts/delete.ts +0 -49
  47. package/.claude/worktrees/emails-list/src/commands/contacts/get.ts +0 -53
  48. package/.claude/worktrees/emails-list/src/commands/contacts/index.ts +0 -58
  49. package/.claude/worktrees/emails-list/src/commands/contacts/list.ts +0 -57
  50. package/.claude/worktrees/emails-list/src/commands/contacts/remove-segment.ts +0 -48
  51. package/.claude/worktrees/emails-list/src/commands/contacts/segments.ts +0 -39
  52. package/.claude/worktrees/emails-list/src/commands/contacts/topics.ts +0 -45
  53. package/.claude/worktrees/emails-list/src/commands/contacts/update-topics.ts +0 -90
  54. package/.claude/worktrees/emails-list/src/commands/contacts/update.ts +0 -77
  55. package/.claude/worktrees/emails-list/src/commands/contacts/utils.ts +0 -119
  56. package/.claude/worktrees/emails-list/src/commands/doctor.ts +0 -298
  57. package/.claude/worktrees/emails-list/src/commands/domains/create.ts +0 -83
  58. package/.claude/worktrees/emails-list/src/commands/domains/delete.ts +0 -42
  59. package/.claude/worktrees/emails-list/src/commands/domains/get.ts +0 -47
  60. package/.claude/worktrees/emails-list/src/commands/domains/index.ts +0 -35
  61. package/.claude/worktrees/emails-list/src/commands/domains/list.ts +0 -53
  62. package/.claude/worktrees/emails-list/src/commands/domains/update.ts +0 -75
  63. package/.claude/worktrees/emails-list/src/commands/domains/utils.ts +0 -44
  64. package/.claude/worktrees/emails-list/src/commands/domains/verify.ts +0 -38
  65. package/.claude/worktrees/emails-list/src/commands/emails/batch.ts +0 -140
  66. package/.claude/worktrees/emails-list/src/commands/emails/index.ts +0 -28
  67. package/.claude/worktrees/emails-list/src/commands/emails/list.ts +0 -73
  68. package/.claude/worktrees/emails-list/src/commands/emails/receiving/attachment.ts +0 -55
  69. package/.claude/worktrees/emails-list/src/commands/emails/receiving/attachments.ts +0 -68
  70. package/.claude/worktrees/emails-list/src/commands/emails/receiving/get.ts +0 -58
  71. package/.claude/worktrees/emails-list/src/commands/emails/receiving/index.ts +0 -28
  72. package/.claude/worktrees/emails-list/src/commands/emails/receiving/list.ts +0 -59
  73. package/.claude/worktrees/emails-list/src/commands/emails/receiving/utils.ts +0 -38
  74. package/.claude/worktrees/emails-list/src/commands/emails/send.ts +0 -189
  75. package/.claude/worktrees/emails-list/src/commands/open.ts +0 -24
  76. package/.claude/worktrees/emails-list/src/commands/segments/create.ts +0 -50
  77. package/.claude/worktrees/emails-list/src/commands/segments/delete.ts +0 -47
  78. package/.claude/worktrees/emails-list/src/commands/segments/get.ts +0 -38
  79. package/.claude/worktrees/emails-list/src/commands/segments/index.ts +0 -36
  80. package/.claude/worktrees/emails-list/src/commands/segments/list.ts +0 -58
  81. package/.claude/worktrees/emails-list/src/commands/segments/utils.ts +0 -7
  82. package/.claude/worktrees/emails-list/src/commands/teams/index.ts +0 -10
  83. package/.claude/worktrees/emails-list/src/commands/teams/list.ts +0 -35
  84. package/.claude/worktrees/emails-list/src/commands/teams/remove.ts +0 -83
  85. package/.claude/worktrees/emails-list/src/commands/teams/switch.ts +0 -73
  86. package/.claude/worktrees/emails-list/src/commands/topics/create.ts +0 -73
  87. package/.claude/worktrees/emails-list/src/commands/topics/delete.ts +0 -47
  88. package/.claude/worktrees/emails-list/src/commands/topics/get.ts +0 -42
  89. package/.claude/worktrees/emails-list/src/commands/topics/index.ts +0 -42
  90. package/.claude/worktrees/emails-list/src/commands/topics/list.ts +0 -34
  91. package/.claude/worktrees/emails-list/src/commands/topics/update.ts +0 -59
  92. package/.claude/worktrees/emails-list/src/commands/topics/utils.ts +0 -16
  93. package/.claude/worktrees/emails-list/src/commands/webhooks/create.ts +0 -128
  94. package/.claude/worktrees/emails-list/src/commands/webhooks/delete.ts +0 -49
  95. package/.claude/worktrees/emails-list/src/commands/webhooks/get.ts +0 -42
  96. package/.claude/worktrees/emails-list/src/commands/webhooks/index.ts +0 -44
  97. package/.claude/worktrees/emails-list/src/commands/webhooks/list.ts +0 -55
  98. package/.claude/worktrees/emails-list/src/commands/webhooks/update.ts +0 -83
  99. package/.claude/worktrees/emails-list/src/commands/webhooks/utils.ts +0 -36
  100. package/.claude/worktrees/emails-list/src/commands/whoami.ts +0 -71
  101. package/.claude/worktrees/emails-list/src/lib/actions.ts +0 -157
  102. package/.claude/worktrees/emails-list/src/lib/client.ts +0 -34
  103. package/.claude/worktrees/emails-list/src/lib/config.ts +0 -211
  104. package/.claude/worktrees/emails-list/src/lib/files.ts +0 -15
  105. package/.claude/worktrees/emails-list/src/lib/help-text.ts +0 -38
  106. package/.claude/worktrees/emails-list/src/lib/output.ts +0 -54
  107. package/.claude/worktrees/emails-list/src/lib/pagination.ts +0 -36
  108. package/.claude/worktrees/emails-list/src/lib/prompts.ts +0 -149
  109. package/.claude/worktrees/emails-list/src/lib/spinner.ts +0 -93
  110. package/.claude/worktrees/emails-list/src/lib/table.ts +0 -57
  111. package/.claude/worktrees/emails-list/src/lib/tty.ts +0 -28
  112. package/.claude/worktrees/emails-list/src/lib/version.ts +0 -4
  113. package/.claude/worktrees/emails-list/tests/commands/api-keys/create.test.ts +0 -195
  114. package/.claude/worktrees/emails-list/tests/commands/api-keys/delete.test.ts +0 -156
  115. package/.claude/worktrees/emails-list/tests/commands/api-keys/list.test.ts +0 -133
  116. package/.claude/worktrees/emails-list/tests/commands/auth/login.test.ts +0 -119
  117. package/.claude/worktrees/emails-list/tests/commands/auth/logout.test.ts +0 -146
  118. package/.claude/worktrees/emails-list/tests/commands/broadcasts/create.test.ts +0 -447
  119. package/.claude/worktrees/emails-list/tests/commands/broadcasts/delete.test.ts +0 -182
  120. package/.claude/worktrees/emails-list/tests/commands/broadcasts/get.test.ts +0 -146
  121. package/.claude/worktrees/emails-list/tests/commands/broadcasts/list.test.ts +0 -196
  122. package/.claude/worktrees/emails-list/tests/commands/broadcasts/send.test.ts +0 -161
  123. package/.claude/worktrees/emails-list/tests/commands/broadcasts/update.test.ts +0 -283
  124. package/.claude/worktrees/emails-list/tests/commands/contact-properties/create.test.ts +0 -250
  125. package/.claude/worktrees/emails-list/tests/commands/contact-properties/delete.test.ts +0 -183
  126. package/.claude/worktrees/emails-list/tests/commands/contact-properties/get.test.ts +0 -144
  127. package/.claude/worktrees/emails-list/tests/commands/contact-properties/list.test.ts +0 -180
  128. package/.claude/worktrees/emails-list/tests/commands/contact-properties/update.test.ts +0 -216
  129. package/.claude/worktrees/emails-list/tests/commands/contacts/add-segment.test.ts +0 -188
  130. package/.claude/worktrees/emails-list/tests/commands/contacts/create.test.ts +0 -270
  131. package/.claude/worktrees/emails-list/tests/commands/contacts/delete.test.ts +0 -192
  132. package/.claude/worktrees/emails-list/tests/commands/contacts/get.test.ts +0 -148
  133. package/.claude/worktrees/emails-list/tests/commands/contacts/list.test.ts +0 -175
  134. package/.claude/worktrees/emails-list/tests/commands/contacts/remove-segment.test.ts +0 -166
  135. package/.claude/worktrees/emails-list/tests/commands/contacts/segments.test.ts +0 -167
  136. package/.claude/worktrees/emails-list/tests/commands/contacts/topics.test.ts +0 -163
  137. package/.claude/worktrees/emails-list/tests/commands/contacts/update-topics.test.ts +0 -247
  138. package/.claude/worktrees/emails-list/tests/commands/contacts/update.test.ts +0 -205
  139. package/.claude/worktrees/emails-list/tests/commands/doctor.test.ts +0 -165
  140. package/.claude/worktrees/emails-list/tests/commands/domains/create.test.ts +0 -192
  141. package/.claude/worktrees/emails-list/tests/commands/domains/delete.test.ts +0 -156
  142. package/.claude/worktrees/emails-list/tests/commands/domains/get.test.ts +0 -137
  143. package/.claude/worktrees/emails-list/tests/commands/domains/list.test.ts +0 -164
  144. package/.claude/worktrees/emails-list/tests/commands/domains/update.test.ts +0 -223
  145. package/.claude/worktrees/emails-list/tests/commands/domains/verify.test.ts +0 -117
  146. package/.claude/worktrees/emails-list/tests/commands/emails/batch.test.ts +0 -313
  147. package/.claude/worktrees/emails-list/tests/commands/emails/list.test.ts +0 -196
  148. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/attachment.test.ts +0 -140
  149. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/attachments.test.ts +0 -168
  150. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/get.test.ts +0 -140
  151. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/list.test.ts +0 -181
  152. package/.claude/worktrees/emails-list/tests/commands/emails/send.test.ts +0 -309
  153. package/.claude/worktrees/emails-list/tests/commands/segments/create.test.ts +0 -163
  154. package/.claude/worktrees/emails-list/tests/commands/segments/delete.test.ts +0 -182
  155. package/.claude/worktrees/emails-list/tests/commands/segments/get.test.ts +0 -137
  156. package/.claude/worktrees/emails-list/tests/commands/segments/list.test.ts +0 -173
  157. package/.claude/worktrees/emails-list/tests/commands/teams/list.test.ts +0 -63
  158. package/.claude/worktrees/emails-list/tests/commands/teams/remove.test.ts +0 -103
  159. package/.claude/worktrees/emails-list/tests/commands/teams/switch.test.ts +0 -96
  160. package/.claude/worktrees/emails-list/tests/commands/topics/create.test.ts +0 -191
  161. package/.claude/worktrees/emails-list/tests/commands/topics/delete.test.ts +0 -156
  162. package/.claude/worktrees/emails-list/tests/commands/topics/get.test.ts +0 -125
  163. package/.claude/worktrees/emails-list/tests/commands/topics/list.test.ts +0 -124
  164. package/.claude/worktrees/emails-list/tests/commands/topics/update.test.ts +0 -177
  165. package/.claude/worktrees/emails-list/tests/commands/webhooks/create.test.ts +0 -224
  166. package/.claude/worktrees/emails-list/tests/commands/webhooks/delete.test.ts +0 -156
  167. package/.claude/worktrees/emails-list/tests/commands/webhooks/get.test.ts +0 -125
  168. package/.claude/worktrees/emails-list/tests/commands/webhooks/list.test.ts +0 -177
  169. package/.claude/worktrees/emails-list/tests/commands/webhooks/update.test.ts +0 -206
  170. package/.claude/worktrees/emails-list/tests/commands/whoami.test.ts +0 -99
  171. package/.claude/worktrees/emails-list/tests/helpers.ts +0 -93
  172. package/.claude/worktrees/emails-list/tests/lib/client.test.ts +0 -71
  173. package/.claude/worktrees/emails-list/tests/lib/config.test.ts +0 -414
  174. package/.claude/worktrees/emails-list/tests/lib/files.test.ts +0 -65
  175. package/.claude/worktrees/emails-list/tests/lib/help-text.test.ts +0 -97
  176. package/.claude/worktrees/emails-list/tests/lib/output.test.ts +0 -127
  177. package/.claude/worktrees/emails-list/tests/lib/prompts.test.ts +0 -178
  178. package/.claude/worktrees/emails-list/tests/lib/spinner.test.ts +0 -146
  179. package/.claude/worktrees/emails-list/tests/lib/table.test.ts +0 -63
  180. package/.claude/worktrees/emails-list/tests/lib/tty.test.ts +0 -85
  181. package/.claude/worktrees/emails-list/tsconfig.json +0 -14
  182. package/.github/scripts/pr-title-check.js +0 -34
  183. package/.github/workflows/ci.yml +0 -32
  184. package/.github/workflows/pr-title-check.yml +0 -13
  185. package/.github/workflows/release.yml +0 -120
  186. package/.github/workflows/test-install-windows.yml +0 -48
  187. package/CHANGELOG.md +0 -31
  188. package/biome.json +0 -36
  189. package/bun.lock +0 -76
  190. package/bunfig.toml +0 -2
  191. package/docs/agent-dx-gaps.md +0 -167
  192. package/docs/missing-commands.md +0 -58
  193. package/docs/production-readiness.md +0 -99
  194. package/docs/secure-key-storage.md +0 -174
  195. package/install.ps1 +0 -141
  196. package/install.sh +0 -301
  197. package/renovate.json +0 -4
  198. package/src/cli.ts +0 -82
  199. package/src/commands/api-keys/create.ts +0 -114
  200. package/src/commands/api-keys/delete.ts +0 -47
  201. package/src/commands/api-keys/index.ts +0 -26
  202. package/src/commands/api-keys/list.ts +0 -35
  203. package/src/commands/api-keys/utils.ts +0 -8
  204. package/src/commands/auth/index.ts +0 -20
  205. package/src/commands/auth/login.ts +0 -207
  206. package/src/commands/auth/logout.ts +0 -105
  207. package/src/commands/broadcasts/create.ts +0 -196
  208. package/src/commands/broadcasts/delete.ts +0 -46
  209. package/src/commands/broadcasts/get.ts +0 -59
  210. package/src/commands/broadcasts/index.ts +0 -43
  211. package/src/commands/broadcasts/list.ts +0 -60
  212. package/src/commands/broadcasts/send.ts +0 -56
  213. package/src/commands/broadcasts/update.ts +0 -95
  214. package/src/commands/broadcasts/utils.ts +0 -35
  215. package/src/commands/contact-properties/create.ts +0 -118
  216. package/src/commands/contact-properties/delete.ts +0 -48
  217. package/src/commands/contact-properties/get.ts +0 -46
  218. package/src/commands/contact-properties/index.ts +0 -48
  219. package/src/commands/contact-properties/list.ts +0 -68
  220. package/src/commands/contact-properties/update.ts +0 -88
  221. package/src/commands/contact-properties/utils.ts +0 -17
  222. package/src/commands/contacts/add-segment.ts +0 -78
  223. package/src/commands/contacts/create.ts +0 -122
  224. package/src/commands/contacts/delete.ts +0 -49
  225. package/src/commands/contacts/get.ts +0 -53
  226. package/src/commands/contacts/index.ts +0 -58
  227. package/src/commands/contacts/list.ts +0 -57
  228. package/src/commands/contacts/remove-segment.ts +0 -48
  229. package/src/commands/contacts/segments.ts +0 -39
  230. package/src/commands/contacts/topics.ts +0 -45
  231. package/src/commands/contacts/update-topics.ts +0 -90
  232. package/src/commands/contacts/update.ts +0 -77
  233. package/src/commands/contacts/utils.ts +0 -119
  234. package/src/commands/doctor.ts +0 -298
  235. package/src/commands/domains/create.ts +0 -83
  236. package/src/commands/domains/delete.ts +0 -42
  237. package/src/commands/domains/get.ts +0 -47
  238. package/src/commands/domains/index.ts +0 -35
  239. package/src/commands/domains/list.ts +0 -53
  240. package/src/commands/domains/update.ts +0 -75
  241. package/src/commands/domains/utils.ts +0 -44
  242. package/src/commands/domains/verify.ts +0 -38
  243. package/src/commands/emails/batch.ts +0 -140
  244. package/src/commands/emails/index.ts +0 -24
  245. package/src/commands/emails/receiving/attachment.ts +0 -55
  246. package/src/commands/emails/receiving/attachments.ts +0 -68
  247. package/src/commands/emails/receiving/get.ts +0 -58
  248. package/src/commands/emails/receiving/index.ts +0 -28
  249. package/src/commands/emails/receiving/list.ts +0 -59
  250. package/src/commands/emails/receiving/utils.ts +0 -38
  251. package/src/commands/emails/send.ts +0 -189
  252. package/src/commands/open.ts +0 -24
  253. package/src/commands/segments/create.ts +0 -50
  254. package/src/commands/segments/delete.ts +0 -47
  255. package/src/commands/segments/get.ts +0 -38
  256. package/src/commands/segments/index.ts +0 -36
  257. package/src/commands/segments/list.ts +0 -58
  258. package/src/commands/segments/utils.ts +0 -7
  259. package/src/commands/teams/index.ts +0 -10
  260. package/src/commands/teams/list.ts +0 -35
  261. package/src/commands/teams/remove.ts +0 -83
  262. package/src/commands/teams/switch.ts +0 -73
  263. package/src/commands/topics/create.ts +0 -73
  264. package/src/commands/topics/delete.ts +0 -47
  265. package/src/commands/topics/get.ts +0 -42
  266. package/src/commands/topics/index.ts +0 -42
  267. package/src/commands/topics/list.ts +0 -34
  268. package/src/commands/topics/update.ts +0 -59
  269. package/src/commands/topics/utils.ts +0 -16
  270. package/src/commands/webhooks/create.ts +0 -128
  271. package/src/commands/webhooks/delete.ts +0 -49
  272. package/src/commands/webhooks/get.ts +0 -42
  273. package/src/commands/webhooks/index.ts +0 -44
  274. package/src/commands/webhooks/list.ts +0 -55
  275. package/src/commands/webhooks/update.ts +0 -83
  276. package/src/commands/webhooks/utils.ts +0 -36
  277. package/src/commands/whoami.ts +0 -71
  278. package/src/lib/actions.ts +0 -157
  279. package/src/lib/client.ts +0 -37
  280. package/src/lib/config.ts +0 -211
  281. package/src/lib/files.ts +0 -15
  282. package/src/lib/help-text.ts +0 -38
  283. package/src/lib/output.ts +0 -54
  284. package/src/lib/pagination.ts +0 -36
  285. package/src/lib/prompts.ts +0 -149
  286. package/src/lib/spinner.ts +0 -93
  287. package/src/lib/table.ts +0 -57
  288. package/src/lib/tty.ts +0 -28
  289. package/src/lib/version.ts +0 -4
  290. package/tests/commands/api-keys/create.test.ts +0 -195
  291. package/tests/commands/api-keys/delete.test.ts +0 -156
  292. package/tests/commands/api-keys/list.test.ts +0 -133
  293. package/tests/commands/auth/login.test.ts +0 -119
  294. package/tests/commands/auth/logout.test.ts +0 -146
  295. package/tests/commands/broadcasts/create.test.ts +0 -447
  296. package/tests/commands/broadcasts/delete.test.ts +0 -182
  297. package/tests/commands/broadcasts/get.test.ts +0 -146
  298. package/tests/commands/broadcasts/list.test.ts +0 -196
  299. package/tests/commands/broadcasts/send.test.ts +0 -161
  300. package/tests/commands/broadcasts/update.test.ts +0 -283
  301. package/tests/commands/contact-properties/create.test.ts +0 -250
  302. package/tests/commands/contact-properties/delete.test.ts +0 -183
  303. package/tests/commands/contact-properties/get.test.ts +0 -144
  304. package/tests/commands/contact-properties/list.test.ts +0 -180
  305. package/tests/commands/contact-properties/update.test.ts +0 -216
  306. package/tests/commands/contacts/add-segment.test.ts +0 -188
  307. package/tests/commands/contacts/create.test.ts +0 -270
  308. package/tests/commands/contacts/delete.test.ts +0 -192
  309. package/tests/commands/contacts/get.test.ts +0 -148
  310. package/tests/commands/contacts/list.test.ts +0 -175
  311. package/tests/commands/contacts/remove-segment.test.ts +0 -166
  312. package/tests/commands/contacts/segments.test.ts +0 -167
  313. package/tests/commands/contacts/topics.test.ts +0 -163
  314. package/tests/commands/contacts/update-topics.test.ts +0 -247
  315. package/tests/commands/contacts/update.test.ts +0 -205
  316. package/tests/commands/doctor.test.ts +0 -165
  317. package/tests/commands/domains/create.test.ts +0 -192
  318. package/tests/commands/domains/delete.test.ts +0 -156
  319. package/tests/commands/domains/get.test.ts +0 -137
  320. package/tests/commands/domains/list.test.ts +0 -164
  321. package/tests/commands/domains/update.test.ts +0 -223
  322. package/tests/commands/domains/verify.test.ts +0 -117
  323. package/tests/commands/emails/batch.test.ts +0 -313
  324. package/tests/commands/emails/receiving/attachment.test.ts +0 -140
  325. package/tests/commands/emails/receiving/attachments.test.ts +0 -168
  326. package/tests/commands/emails/receiving/get.test.ts +0 -140
  327. package/tests/commands/emails/receiving/list.test.ts +0 -181
  328. package/tests/commands/emails/send.test.ts +0 -309
  329. package/tests/commands/segments/create.test.ts +0 -163
  330. package/tests/commands/segments/delete.test.ts +0 -182
  331. package/tests/commands/segments/get.test.ts +0 -137
  332. package/tests/commands/segments/list.test.ts +0 -173
  333. package/tests/commands/teams/list.test.ts +0 -63
  334. package/tests/commands/teams/remove.test.ts +0 -103
  335. package/tests/commands/teams/switch.test.ts +0 -96
  336. package/tests/commands/topics/create.test.ts +0 -191
  337. package/tests/commands/topics/delete.test.ts +0 -156
  338. package/tests/commands/topics/get.test.ts +0 -125
  339. package/tests/commands/topics/list.test.ts +0 -124
  340. package/tests/commands/topics/update.test.ts +0 -177
  341. package/tests/commands/webhooks/create.test.ts +0 -224
  342. package/tests/commands/webhooks/delete.test.ts +0 -156
  343. package/tests/commands/webhooks/get.test.ts +0 -125
  344. package/tests/commands/webhooks/list.test.ts +0 -177
  345. package/tests/commands/webhooks/update.test.ts +0 -206
  346. package/tests/commands/whoami.test.ts +0 -99
  347. package/tests/helpers.ts +0 -93
  348. package/tests/lib/client.test.ts +0 -71
  349. package/tests/lib/config.test.ts +0 -414
  350. package/tests/lib/files.test.ts +0 -65
  351. package/tests/lib/help-text.test.ts +0 -97
  352. package/tests/lib/output.test.ts +0 -127
  353. package/tests/lib/prompts.test.ts +0 -178
  354. package/tests/lib/spinner.test.ts +0 -146
  355. package/tests/lib/table.test.ts +0 -63
  356. package/tests/lib/tty.test.ts +0 -85
  357. package/tsconfig.json +0 -14
@@ -1,174 +0,0 @@
1
- # Secure API Key Storage via macOS Keychain
2
-
3
- ## Context
4
-
5
- API keys are currently stored as **plain text** in `~/.config/resend/credentials.json` (with `0o600` file permissions). The CLI already supports **multi-team profiles** — the credentials file has this structure:
6
-
7
- ```json
8
- { "active_team": "production", "teams": { "production": { "api_key": "re_..." }, "staging": { "api_key": "re_..." } } }
9
- ```
10
-
11
- The keychain integration must preserve this multi-team model: each team's API key gets its own keychain entry, and team metadata (active team, team list) stays in the config file.
12
-
13
- **Goal:** Move API key secrets into macOS Keychain while keeping team management metadata in the config file.
14
-
15
- ## Approach: Shell out to `/usr/bin/security`
16
-
17
- Use macOS's built-in `security` CLI to interact with Keychain. Zero dependencies, works with Bun compiled binaries.
18
-
19
- Each team gets its own keychain entry using the team name as the `account` field:
20
- - `security add-generic-password -s resend-cli -a <team> -w <key> -U` (store/update)
21
- - `security find-generic-password -s resend-cli -a <team> -w` (retrieve)
22
- - `security delete-generic-password -s resend-cli -a <team>` (delete)
23
-
24
- **Why not keytar (the prototype's approach):**
25
- `bun build --compile` produces a self-contained binary with embedded JS bytecode. Native N-API addons (`.node` files) cannot be embedded — they require OS-level dynamic library loading at runtime. The release workflow (`.github/workflows/release.yml`) cross-compiles to 5 platform targets from a single Ubuntu runner, which further rules out native modules needing per-platform node-gyp compilation. The prototype uses keytar because it's a standard Node.js/oclif package where native modules compile during `npm install`.
26
-
27
- **Why not other approaches:**
28
- - **Bun FFI**: Hundreds of lines of C-interop for CoreFoundation/Security.framework — not worth it
29
- - **Pure-JS wrappers**: Most just shell out to `security` internally anyway
30
-
31
- ## Key resolution priority (updated)
32
-
33
- 1. `--api-key` flag → source: `'flag'`
34
- 2. `RESEND_API_KEY` env var → source: `'env'`
35
- 3. **macOS Keychain** (for resolved team name) → source: `'keychain'` *(new)*
36
- 4. `credentials.json` teams → source: `'config'` *(kept as fallback)*
37
-
38
- Team resolution is unchanged: `--team` flag > `RESEND_TEAM` env > `active_team` in config > `"default"`
39
-
40
- ## Storage model
41
-
42
- **Keychain** stores secrets only:
43
- - Service: `resend-cli`, Account: `<team-name>`, Password: `<api-key>`
44
- - One entry per team
45
-
46
- **Config file** (`credentials.json`) stores non-secret metadata:
47
- - `active_team`: which team is currently active
48
- - `teams`: record of team names (but **no more `api_key` fields** when keychain is available)
49
-
50
- When keychain is available, the config file looks like:
51
- ```json
52
- { "active_team": "production", "teams": { "production": {}, "staging": {} } }
53
- ```
54
-
55
- When keychain is unavailable (fallback), `api_key` is stored in the teams record as before.
56
-
57
- ## Migration strategy
58
-
59
- No automatic migration. Both backends coexist:
60
- - New `resend login` writes key to keychain + team metadata to config (no `api_key` in config)
61
- - Old config files with `api_key` fields still work at lower priority
62
- - `resend logout` / `resend teams remove` clean up both keychain entry and config
63
- - Users naturally migrate when they next run `resend login`
64
-
65
- ## Files to change
66
-
67
- ### New: `src/lib/keychain.ts` (~60 lines)
68
-
69
- Keychain abstraction wrapping `/usr/bin/security` via `child_process.execFile` (arg array, no shell — safe from injection).
70
-
71
- ```
72
- keychainStore(team: string, apiKey: string): Promise<void>
73
- keychainGet(team: string): Promise<string | null> // null on not-found (exit code 44)
74
- keychainDelete(team: string): Promise<boolean>
75
- keychainAvailable(): boolean // process.platform === 'darwin' && existsSync('/usr/bin/security')
76
- ```
77
-
78
- Constants: `SERVICE = 'resend-cli'`
79
-
80
- ### Modify: `src/lib/config.ts`
81
-
82
- Current functions and how they change:
83
-
84
- - `ApiKeySource` type: add `'keychain'`
85
- - `TeamProfile` type: make `api_key` optional (`{ api_key?: string }`) — empty when key is in keychain
86
- - `resolveApiKey(flagValue?, teamName?)` → **async**: after env check, try `keychainGet(team)` before falling back to config file's `api_key`
87
- - `storeApiKey(apiKey, teamName?)` → **async**: if `keychainAvailable()`, store key in keychain and write team to config without `api_key`; otherwise write `api_key` to config as fallback
88
- - `removeApiKey(teamName?)` → **async**: delete from keychain + remove team from config
89
- - `removeTeam(teamName)` → **async**: delete from keychain + existing config cleanup
90
- - `resolveTeamName`, `readCredentials`, `writeCredentials`, `setActiveTeam`, `listTeams`: unchanged (they don't touch API keys directly)
91
-
92
- ### Modify: `src/lib/client.ts`
93
-
94
- - `createClient` and `requireClient` → **async** (add `await` to `resolveApiKey`)
95
-
96
- ### Modify: `src/commands/auth/login.ts`
97
-
98
- - `await storeApiKey(apiKey, teamName)` (line 151)
99
- - Update success message: "API key stored in macOS Keychain" vs "API key stored at {path}"
100
- - `await resolveApiKey()` (line 71)
101
-
102
- ### Modify: `src/commands/auth/logout.ts`
103
-
104
- - Check keychain + config to determine if logged in (not just file existence)
105
- - `await removeApiKey()`
106
- - Update confirmation message for keychain
107
-
108
- ### Modify: `src/commands/teams/remove.ts`
109
-
110
- - `await removeTeam(name)` — needs to delete keychain entry too
111
-
112
- ### Modify: `src/commands/doctor.ts`
113
-
114
- - `checkApiKeyPresence` → **async**: `await resolveApiKey()`
115
- - `checkApiValidationAndDomains` → `await resolveApiKey()`
116
- - Show `(source: keychain)` when applicable
117
- - When source is `'config'`, hint: "run `resend login` to migrate to Keychain"
118
-
119
- ### Modify: `src/commands/setup/utils.ts` and `src/commands/setup/claude-code.ts`
120
-
121
- - Add `await` to `resolveApiKey()` calls
122
-
123
- ### Update help text in: `src/cli.ts`, `login.ts`, `logout.ts`
124
-
125
- - Reflect new priority chain mentioning Keychain
126
-
127
- ### New: `tests/lib/keychain.test.ts`
128
-
129
- - Mock `execFile` to test store/get/delete without touching real keychain
130
- - Test per-team accounts work correctly
131
- - Test `keychainGet` returns `null` on exit code 44
132
- - Test `keychainAvailable` returns `false` on non-darwin
133
-
134
- ### Update: existing tests
135
-
136
- - Mock keychain module in config/auth tests
137
-
138
- ## File-based fallback hardening
139
-
140
- When keychain is unavailable (headless Linux, CI, containers), the file-based backend is used with hardening:
141
-
142
- 1. **Warn on fallback**: When `storeApiKey` writes to file instead of keychain, print:
143
- `"⚠ No system keychain available. API key stored in plain text at {path}. Consider using RESEND_API_KEY env var instead."`
144
-
145
- 2. **Permission check on read**: When `resolveApiKey` reads from the config file, verify permissions are still `0o600`. If loosened, warn:
146
- `"⚠ Credentials file {path} has loose permissions. Run: chmod 600 {path}"`
147
-
148
- 3. **Doctor check**: Show storage backend and warn if using file-based storage on a platform that supports keychain.
149
-
150
- **Industry context**: Plain text storage is common (AWS CLI, Stripe CLI, Heroku) but increasingly criticized. GitHub CLI now supports keychain (becoming default). Google Cloud uses encrypted SQLite. The trend is toward OS-level secure storage. The file fallback exists for environments where no keychain daemon is available.
151
-
152
- ## Future: Linux & Windows support
153
-
154
- The `keychain.ts` module abstracts the backend per platform:
155
-
156
- | Platform | System | CLI tool |
157
- |----------|--------|----------|
158
- | **macOS** | Keychain Access | `/usr/bin/security` |
159
- | **Linux** | libsecret / GNOME Keyring | `secret-tool` (`libsecret-tools`) |
160
- | **Windows** | Credential Manager | `cmdkey` or PowerShell |
161
-
162
- To add a platform: add platform-specific functions in `keychain.ts` and extend `keychainAvailable()`. The file-based fallback always remains for headless/CI environments.
163
-
164
- ## Verification
165
-
166
- 1. `bun run build` — ensure compiled binary works
167
- 2. `resend login --key re_test` — stores in keychain, verify in Keychain Access.app under service "resend-cli"
168
- 3. `resend login --key re_staging` with `--team staging` — second keychain entry
169
- 4. `resend teams list` — shows both teams
170
- 5. `resend teams switch staging` → `resend doctor` — shows staging key from keychain
171
- 6. `resend teams remove staging` — deletes keychain entry
172
- 7. `resend logout` — removes active team's keychain entry
173
- 8. `RESEND_API_KEY=re_env resend doctor` — env override still works
174
- 9. Test with old `credentials.json` containing `api_key` fields — falls back to file
package/install.ps1 DELETED
@@ -1,141 +0,0 @@
1
- #!/usr/bin/env pwsh
2
- # Resend CLI installer for Windows
3
- #
4
- # Usage (PowerShell):
5
- # irm https://resend.com/install.ps1 | iex
6
- #
7
- # Pin a version:
8
- # $env:RESEND_VERSION = 'v0.1.0'; irm https://resend.com/install.ps1 | iex
9
- #
10
- # Environment variables:
11
- # RESEND_INSTALL - Custom install directory (default: $HOME\.resend)
12
- # RESEND_VERSION - Version to install (default: latest)
13
-
14
- param(
15
- [string]$Version = $env:RESEND_VERSION
16
- )
17
-
18
- Set-StrictMode -Version Latest
19
- $ErrorActionPreference = 'Stop'
20
-
21
- # ─── Helpers ─────────────────────────────────────────────────────────────────
22
-
23
- function Write-Info { param($msg) Write-Host " $msg" -ForegroundColor DarkGray }
24
- function Write-Ok { param($msg) Write-Host " $msg" -ForegroundColor Green }
25
-
26
- function Write-Fail {
27
- param($msg)
28
- Write-Host " error: $msg" -ForegroundColor Red
29
- exit 1
30
- }
31
-
32
- # ─── Architecture detection ───────────────────────────────────────────────────
33
-
34
- if ($env:PROCESSOR_ARCHITECTURE -notin @('AMD64', 'EM64T')) {
35
- Write-Fail "Unsupported architecture: $env:PROCESSOR_ARCHITECTURE`n`n Resend CLI currently supports Windows x64 only."
36
- }
37
-
38
- # ─── Version + Download URL ───────────────────────────────────────────────────
39
-
40
- $repo = 'https://github.com/resend/resend-cli'
41
- $target = 'windows-x64'
42
-
43
- if ($Version) {
44
- $Version = $Version.TrimStart('v')
45
- if ($Version -notmatch '^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$') {
46
- Write-Fail "Invalid version format: $Version`n`n Expected: semantic version like 0.1.0 or 1.2.3-beta.1`n Usage: `$env:RESEND_VERSION = 'v0.1.0'; irm https://resend.com/install.ps1 | iex"
47
- }
48
- $url = "$repo/releases/download/v$Version/resend-$target.zip"
49
- } else {
50
- $url = "$repo/releases/latest/download/resend-$target.zip"
51
- }
52
-
53
- # ─── Install directory ────────────────────────────────────────────────────────
54
-
55
- $installDir = if ($env:RESEND_INSTALL) { $env:RESEND_INSTALL } else { Join-Path $HOME '.resend' }
56
- $binDir = Join-Path $installDir 'bin'
57
- $exe = Join-Path $binDir 'resend.exe'
58
-
59
- if (-not (Test-Path $binDir)) {
60
- New-Item -ItemType Directory -Path $binDir -Force | Out-Null
61
- }
62
-
63
- # ─── Download + Extract ───────────────────────────────────────────────────────
64
-
65
- Write-Host ""
66
- Write-Host " Installing Resend CLI..." -ForegroundColor White
67
- Write-Host ""
68
- Write-Info "Downloading from $url"
69
- Write-Host ""
70
-
71
- $tmpDir = Join-Path ([System.IO.Path]::GetTempPath()) "resend-$([System.Guid]::NewGuid())"
72
- New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
73
- $tmpZip = Join-Path $tmpDir 'resend.zip'
74
-
75
- try {
76
- try {
77
- # Force TLS 1.2 for Windows PowerShell 5.1 (no-op on PowerShell 7+ where it is the default)
78
- [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
79
- $ProgressPreference = 'SilentlyContinue' # Invoke-WebRequest is ~10x faster without progress bar
80
- Invoke-WebRequest -Uri $url -OutFile $tmpZip -UseBasicParsing
81
- } catch {
82
- Write-Fail "Download failed.`n`n Possible causes:`n - No internet connection`n - The version does not exist: $(if ($Version) { $Version } else { 'latest' })`n - GitHub is unreachable`n`n URL: $url"
83
- }
84
-
85
- try {
86
- Expand-Archive -Path $tmpZip -DestinationPath $binDir -Force
87
- } catch {
88
- Write-Fail "Failed to extract archive: $_"
89
- }
90
- }
91
- finally {
92
- Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
93
- }
94
-
95
- if (-not (Test-Path $exe)) {
96
- Write-Fail "Binary not found after extraction. The download may be corrupted — try again."
97
- }
98
-
99
- # ─── Verify installation ──────────────────────────────────────────────────────
100
-
101
- try {
102
- $installedVersion = (& $exe --version 2>$null).Trim()
103
- } catch {
104
- $installedVersion = 'unknown'
105
- }
106
-
107
- Write-Host ""
108
- Write-Ok "Resend CLI $installedVersion installed successfully!"
109
- Write-Host ""
110
- Write-Info "Binary: $exe"
111
-
112
- # ─── PATH setup ───────────────────────────────────────────────────────────────
113
-
114
- $userPath = [Environment]::GetEnvironmentVariable('PATH', 'User') ?? ''
115
- $pathEntries = $userPath -split ';' | Where-Object { $_ -ne '' }
116
-
117
- if ($pathEntries -contains $binDir) {
118
- # Already on PATH — just print the getting-started line
119
- Write-Host ""
120
- Write-Host " Run " -NoNewline
121
- Write-Host "resend --help" -ForegroundColor Cyan -NoNewline
122
- Write-Host " to get started"
123
- Write-Host ""
124
- exit 0
125
- }
126
-
127
- # Add to user PATH (persists across sessions — no admin rights needed)
128
- $newPath = ($pathEntries + $binDir) -join ';'
129
- [Environment]::SetEnvironmentVariable('PATH', $newPath, 'User')
130
- $env:PATH = "$env:PATH;$binDir" # Also update the current session
131
-
132
- Write-Info "Added $binDir to PATH (User scope)"
133
- Write-Host ""
134
- Write-Info "Restart your terminal, then:"
135
- Write-Host ""
136
- Write-Info "Next steps:"
137
- Write-Host ""
138
- Write-Host " `$env:RESEND_API_KEY = 're_...'" -ForegroundColor Cyan
139
- Write-Host " resend --help" -ForegroundColor Cyan
140
- Write-Host ""
141
- exit 0
package/install.sh DELETED
@@ -1,301 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Resend CLI installer
3
- #
4
- # Usage:
5
- # curl -fsSL https://resend.com/install.sh | bash
6
- # curl -fsSL https://resend.com/install.sh | bash -s v0.1.0
7
- #
8
- # Environment variables:
9
- # RESEND_INSTALL - Custom install directory (default: ~/.resend)
10
- # GITHUB_BASE - Custom GitHub base URL (default: https://github.com)
11
-
12
- # Wrap everything in a function to protect against partial download.
13
- # If the connection drops mid-transfer, bash won't execute a truncated script.
14
- main() {
15
-
16
- set -euo pipefail
17
-
18
- # ─── Colors (only when outputting to a terminal) ─────────────────────────────
19
-
20
- Color_Off='' Red='' Green='' Dim='' Bold='' Blue='' Yellow=''
21
-
22
- if [[ -t 1 ]]; then
23
- Color_Off='\033[0m'
24
- Red='\033[0;31m'
25
- Green='\033[0;32m'
26
- Yellow='\033[0;33m'
27
- Dim='\033[0;2m'
28
- Bold='\033[1m'
29
- Blue='\033[0;34m'
30
- fi
31
-
32
- # ─── Helpers ─────────────────────────────────────────────────────────────────
33
-
34
- error() {
35
- printf "%b\n" "${Red}error${Color_Off}: $*" >&2
36
- exit 1
37
- }
38
-
39
- warn() {
40
- printf "%b\n" "${Yellow}warn${Color_Off}: $*" >&2
41
- }
42
-
43
- info() {
44
- printf "%b\n" "${Dim}$*${Color_Off}"
45
- }
46
-
47
- success() {
48
- printf "%b\n" "${Green}$*${Color_Off}"
49
- }
50
-
51
- bold() {
52
- printf "%b\n" "${Bold}$*${Color_Off}"
53
- }
54
-
55
- tildify() {
56
- if [[ $1 == "$HOME"/* ]]; then
57
- echo "~${1#"$HOME"}"
58
- else
59
- echo "$1"
60
- fi
61
- }
62
-
63
- # ─── Dependency checks ──────────────────────────────────────────────────────
64
-
65
- command -v curl >/dev/null 2>&1 || error "curl is required but not found. Install it and try again."
66
- command -v tar >/dev/null 2>&1 || error "tar is required but not found. Install it and try again."
67
-
68
- # ─── OS / Architecture detection ────────────────────────────────────────────
69
-
70
- platform=$(uname -ms)
71
-
72
- case $platform in
73
- 'Darwin x86_64') target=darwin-x64 ;;
74
- 'Darwin arm64') target=darwin-arm64 ;;
75
- 'Linux aarch64') target=linux-arm64 ;;
76
- 'Linux arm64') target=linux-arm64 ;;
77
- 'Linux x86_64') target=linux-x64 ;;
78
- *)
79
- error "Unsupported platform: ${platform}.
80
-
81
- Resend CLI supports:
82
- - macOS (Apple Silicon / Intel)
83
- - Linux (x64 / arm64)
84
-
85
- For Windows, run this in PowerShell:
86
- irm https://resend.com/install.ps1 | iex"
87
- ;;
88
- esac
89
-
90
- # Detect Rosetta 2 on macOS — prefer native arm64 binary
91
- if [[ $target == "darwin-x64" ]]; then
92
- if [[ $(sysctl -n sysctl.proc_translated 2>/dev/null || echo 0) == "1" ]]; then
93
- target=darwin-arm64
94
- info " Rosetta 2 detected — installing native arm64 binary"
95
- fi
96
- fi
97
-
98
- # Detect musl (Alpine Linux) — glibc binaries won't work
99
- if [[ $target == linux-* ]]; then
100
- if ldd --version 2>&1 | grep -qi musl 2>/dev/null; then
101
- error "Alpine Linux (musl) is not currently supported.
102
-
103
- The compiled binary requires glibc. Use one of these alternatives:
104
- - npm install -g resend-cli
105
- - Run in a glibc-based container (e.g., ubuntu, debian)"
106
- fi
107
- fi
108
-
109
- # ─── Version + Download URL ─────────────────────────────────────────────────
110
-
111
- GITHUB_BASE=${GITHUB_BASE:-"https://github.com"}
112
-
113
- # Validate GITHUB_BASE is HTTPS to prevent download from arbitrary sources
114
- case "$GITHUB_BASE" in
115
- https://*) ;;
116
- *) error "GITHUB_BASE must start with https:// (got: ${GITHUB_BASE})" ;;
117
- esac
118
-
119
- REPO="${GITHUB_BASE}/resend/resend-cli"
120
-
121
- VERSION=${1:-}
122
-
123
- # Validate version format if provided
124
- if [[ -n $VERSION ]]; then
125
- # Strip leading 'v' if present, then re-add for the tag
126
- VERSION="${VERSION#v}"
127
- if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
128
- error "Invalid version format: ${VERSION}
129
-
130
- Expected: semantic version like 0.1.0 or 1.2.3-beta.1
131
- Usage: curl -fsSL https://resend.com/install.sh | bash -s v0.1.0"
132
- fi
133
- url="${REPO}/releases/download/v${VERSION}/resend-${target}.tar.gz"
134
- else
135
- url="${REPO}/releases/latest/download/resend-${target}.tar.gz"
136
- fi
137
-
138
- # ─── Install directory ──────────────────────────────────────────────────────
139
-
140
- install_dir="${RESEND_INSTALL:-$HOME/.resend}"
141
- bin_dir="${install_dir}/bin"
142
- exe="${bin_dir}/resend"
143
-
144
- mkdir -p "$bin_dir" || error "Failed to create install directory: ${bin_dir}"
145
-
146
- # ─── Download + Extract ─────────────────────────────────────────────────────
147
-
148
- echo ""
149
- bold " Installing Resend CLI..."
150
- echo ""
151
-
152
- tmpdir=$(mktemp -d) || error "Failed to create temporary directory"
153
- trap 'rm -rf "$tmpdir"' EXIT INT TERM
154
-
155
- tmpfile="${tmpdir}/resend.tar.gz"
156
-
157
- info " Downloading from ${url}"
158
- echo ""
159
-
160
- curl --fail --location --progress-bar --output "$tmpfile" "$url" ||
161
- error "Download failed.
162
-
163
- Possible causes:
164
- - No internet connection
165
- - The version does not exist: ${VERSION:-latest}
166
- - GitHub is unreachable
167
-
168
- URL: ${url}"
169
-
170
- tar -xzf "$tmpfile" -C "$bin_dir" ||
171
- error "Failed to extract archive. The download may be corrupted — try again."
172
-
173
- chmod +x "$exe" || error "Failed to make binary executable"
174
-
175
- # Strip macOS Gatekeeper quarantine flag (set automatically on curl downloads)
176
- # Without this, macOS will block the binary: "cannot be opened because Apple
177
- # cannot check it for malicious software"
178
- if [[ $(uname -s) == "Darwin" ]]; then
179
- xattr -d com.apple.quarantine "$exe" 2>/dev/null || true
180
- fi
181
-
182
- # ─── Verify installation ────────────────────────────────────────────────────
183
-
184
- installed_version=$("$exe" --version 2>/dev/null || echo "unknown")
185
-
186
- echo ""
187
- success " Resend CLI ${installed_version} installed successfully!"
188
- echo ""
189
- info " Binary: $(tildify "$exe")"
190
-
191
- # ─── PATH setup ─────────────────────────────────────────────────────────────
192
-
193
- # Check if already on PATH
194
- if command -v resend >/dev/null 2>&1; then
195
- existing=$(command -v resend)
196
- if [[ "$existing" == "$exe" ]]; then
197
- echo ""
198
- bold " Run ${Blue}resend --help${Color_Off}${Bold} to get started${Color_Off}"
199
- echo ""
200
- exit 0
201
- else
202
- warn "another 'resend' was found at ${existing}"
203
- info " The new installation at $(tildify "$exe") may be shadowed."
204
- fi
205
- fi
206
-
207
- # Check if bin_dir is already in PATH
208
- if echo "$PATH" | tr ':' '\n' | grep -qxF "${bin_dir}" 2>/dev/null; then
209
- echo ""
210
- bold " Run ${Blue}resend --help${Color_Off}${Bold} to get started${Color_Off}"
211
- echo ""
212
- exit 0
213
- fi
214
-
215
- # Determine shell config file
216
- shell_name=$(basename "${SHELL:-}")
217
- config=""
218
- shell_line=""
219
-
220
- # Build a $HOME-relative path for shell config (~ doesn't expand inside quotes)
221
- if [[ $bin_dir == "$HOME"/* ]]; then
222
- shell_bin_dir="\$HOME${bin_dir#"$HOME"}"
223
- else
224
- shell_bin_dir="$bin_dir"
225
- fi
226
-
227
- case $shell_name in
228
- zsh)
229
- config="${ZDOTDIR:-$HOME}/.zshrc"
230
- shell_line="export PATH=\"${shell_bin_dir}:\$PATH\""
231
- ;;
232
- bash)
233
- # macOS bash opens login shells — .bash_profile is loaded, not .bashrc.
234
- # Linux bash opens non-login interactive shells — .bashrc is preferred.
235
- if [[ $(uname -s) == "Darwin" ]]; then
236
- if [[ -f "$HOME/.bash_profile" ]]; then
237
- config="$HOME/.bash_profile"
238
- elif [[ -f "$HOME/.bashrc" ]]; then
239
- config="$HOME/.bashrc"
240
- else
241
- config="$HOME/.bash_profile"
242
- fi
243
- else
244
- if [[ -f "$HOME/.bashrc" ]]; then
245
- config="$HOME/.bashrc"
246
- elif [[ -f "$HOME/.bash_profile" ]]; then
247
- config="$HOME/.bash_profile"
248
- else
249
- config="$HOME/.bashrc"
250
- fi
251
- fi
252
- shell_line="export PATH=\"${shell_bin_dir}:\$PATH\""
253
- ;;
254
- fish)
255
- config="${XDG_CONFIG_HOME:-$HOME/.config}/fish/conf.d/resend.fish"
256
- mkdir -p "$(dirname "$config")"
257
- shell_line="fish_add_path ${shell_bin_dir}"
258
- ;;
259
- esac
260
-
261
- if [[ -n $config ]]; then
262
- # Check if PATH entry already exists (check both tildified and absolute)
263
- if [[ -f "$config" ]] && (grep -qF "$(tildify "$bin_dir")" "$config" 2>/dev/null || grep -qF "$bin_dir" "$config" 2>/dev/null); then
264
- info " PATH already configured in $(tildify "$config")"
265
- elif [[ -w "${config%/*}" ]] || [[ -w "$config" ]]; then
266
- {
267
- echo ""
268
- echo "# Resend CLI"
269
- echo "$shell_line"
270
- } >> "$config"
271
- info " Added $(tildify "$bin_dir") to \$PATH in $(tildify "$config")"
272
- echo ""
273
- info " To start using Resend CLI, run:"
274
- echo ""
275
- bold " source $(tildify "$config")"
276
- bold " resend --help"
277
- else
278
- echo ""
279
- info " Manually add to your shell config:"
280
- echo ""
281
- bold " ${shell_line}"
282
- fi
283
- else
284
- echo ""
285
- info " Add to your shell config:"
286
- echo ""
287
- bold " export PATH=\"${shell_bin_dir}:\$PATH\""
288
- fi
289
-
290
- echo ""
291
- info " Next steps:"
292
- echo ""
293
- bold " export RESEND_API_KEY=re_..."
294
- bold " resend --help"
295
- echo ""
296
-
297
- }
298
-
299
- # Run the installer — this line MUST be the last line in the file.
300
- # If the download is interrupted, bash will not execute an incomplete function.
301
- main "$@"
package/renovate.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
- "extends": ["config:recommended"]
4
- }