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.
- package/README.md +25 -10
- package/dist/cli.cjs +539 -0
- package/package.json +31 -13
- package/.claude/settings.local.json +0 -5
- package/.claude/worktrees/emails-list/.claude/settings.local.json +0 -5
- package/.claude/worktrees/emails-list/.github/scripts/pr-title-check.js +0 -34
- package/.claude/worktrees/emails-list/.github/workflows/ci.yml +0 -32
- package/.claude/worktrees/emails-list/.github/workflows/pr-title-check.yml +0 -13
- package/.claude/worktrees/emails-list/.github/workflows/release.yml +0 -93
- package/.claude/worktrees/emails-list/CHANGELOG.md +0 -31
- package/.claude/worktrees/emails-list/LICENSE +0 -21
- package/.claude/worktrees/emails-list/README.md +0 -424
- package/.claude/worktrees/emails-list/biome.json +0 -36
- package/.claude/worktrees/emails-list/bun.lock +0 -76
- package/.claude/worktrees/emails-list/bunfig.toml +0 -2
- package/.claude/worktrees/emails-list/install.ps1 +0 -140
- package/.claude/worktrees/emails-list/install.sh +0 -301
- package/.claude/worktrees/emails-list/package.json +0 -43
- package/.claude/worktrees/emails-list/renovate.json +0 -6
- package/.claude/worktrees/emails-list/src/cli.ts +0 -74
- package/.claude/worktrees/emails-list/src/commands/api-keys/create.ts +0 -114
- package/.claude/worktrees/emails-list/src/commands/api-keys/delete.ts +0 -47
- package/.claude/worktrees/emails-list/src/commands/api-keys/index.ts +0 -26
- package/.claude/worktrees/emails-list/src/commands/api-keys/list.ts +0 -35
- package/.claude/worktrees/emails-list/src/commands/api-keys/utils.ts +0 -8
- package/.claude/worktrees/emails-list/src/commands/auth/index.ts +0 -20
- package/.claude/worktrees/emails-list/src/commands/auth/login.ts +0 -207
- package/.claude/worktrees/emails-list/src/commands/auth/logout.ts +0 -105
- package/.claude/worktrees/emails-list/src/commands/broadcasts/create.ts +0 -196
- package/.claude/worktrees/emails-list/src/commands/broadcasts/delete.ts +0 -46
- package/.claude/worktrees/emails-list/src/commands/broadcasts/get.ts +0 -59
- package/.claude/worktrees/emails-list/src/commands/broadcasts/index.ts +0 -43
- package/.claude/worktrees/emails-list/src/commands/broadcasts/list.ts +0 -60
- package/.claude/worktrees/emails-list/src/commands/broadcasts/send.ts +0 -56
- package/.claude/worktrees/emails-list/src/commands/broadcasts/update.ts +0 -95
- package/.claude/worktrees/emails-list/src/commands/broadcasts/utils.ts +0 -35
- package/.claude/worktrees/emails-list/src/commands/contact-properties/create.ts +0 -118
- package/.claude/worktrees/emails-list/src/commands/contact-properties/delete.ts +0 -48
- package/.claude/worktrees/emails-list/src/commands/contact-properties/get.ts +0 -46
- package/.claude/worktrees/emails-list/src/commands/contact-properties/index.ts +0 -48
- package/.claude/worktrees/emails-list/src/commands/contact-properties/list.ts +0 -68
- package/.claude/worktrees/emails-list/src/commands/contact-properties/update.ts +0 -88
- package/.claude/worktrees/emails-list/src/commands/contact-properties/utils.ts +0 -17
- package/.claude/worktrees/emails-list/src/commands/contacts/add-segment.ts +0 -78
- package/.claude/worktrees/emails-list/src/commands/contacts/create.ts +0 -122
- package/.claude/worktrees/emails-list/src/commands/contacts/delete.ts +0 -49
- package/.claude/worktrees/emails-list/src/commands/contacts/get.ts +0 -53
- package/.claude/worktrees/emails-list/src/commands/contacts/index.ts +0 -58
- package/.claude/worktrees/emails-list/src/commands/contacts/list.ts +0 -57
- package/.claude/worktrees/emails-list/src/commands/contacts/remove-segment.ts +0 -48
- package/.claude/worktrees/emails-list/src/commands/contacts/segments.ts +0 -39
- package/.claude/worktrees/emails-list/src/commands/contacts/topics.ts +0 -45
- package/.claude/worktrees/emails-list/src/commands/contacts/update-topics.ts +0 -90
- package/.claude/worktrees/emails-list/src/commands/contacts/update.ts +0 -77
- package/.claude/worktrees/emails-list/src/commands/contacts/utils.ts +0 -119
- package/.claude/worktrees/emails-list/src/commands/doctor.ts +0 -298
- package/.claude/worktrees/emails-list/src/commands/domains/create.ts +0 -83
- package/.claude/worktrees/emails-list/src/commands/domains/delete.ts +0 -42
- package/.claude/worktrees/emails-list/src/commands/domains/get.ts +0 -47
- package/.claude/worktrees/emails-list/src/commands/domains/index.ts +0 -35
- package/.claude/worktrees/emails-list/src/commands/domains/list.ts +0 -53
- package/.claude/worktrees/emails-list/src/commands/domains/update.ts +0 -75
- package/.claude/worktrees/emails-list/src/commands/domains/utils.ts +0 -44
- package/.claude/worktrees/emails-list/src/commands/domains/verify.ts +0 -38
- package/.claude/worktrees/emails-list/src/commands/emails/batch.ts +0 -140
- package/.claude/worktrees/emails-list/src/commands/emails/index.ts +0 -28
- package/.claude/worktrees/emails-list/src/commands/emails/list.ts +0 -73
- package/.claude/worktrees/emails-list/src/commands/emails/receiving/attachment.ts +0 -55
- package/.claude/worktrees/emails-list/src/commands/emails/receiving/attachments.ts +0 -68
- package/.claude/worktrees/emails-list/src/commands/emails/receiving/get.ts +0 -58
- package/.claude/worktrees/emails-list/src/commands/emails/receiving/index.ts +0 -28
- package/.claude/worktrees/emails-list/src/commands/emails/receiving/list.ts +0 -59
- package/.claude/worktrees/emails-list/src/commands/emails/receiving/utils.ts +0 -38
- package/.claude/worktrees/emails-list/src/commands/emails/send.ts +0 -189
- package/.claude/worktrees/emails-list/src/commands/open.ts +0 -24
- package/.claude/worktrees/emails-list/src/commands/segments/create.ts +0 -50
- package/.claude/worktrees/emails-list/src/commands/segments/delete.ts +0 -47
- package/.claude/worktrees/emails-list/src/commands/segments/get.ts +0 -38
- package/.claude/worktrees/emails-list/src/commands/segments/index.ts +0 -36
- package/.claude/worktrees/emails-list/src/commands/segments/list.ts +0 -58
- package/.claude/worktrees/emails-list/src/commands/segments/utils.ts +0 -7
- package/.claude/worktrees/emails-list/src/commands/teams/index.ts +0 -10
- package/.claude/worktrees/emails-list/src/commands/teams/list.ts +0 -35
- package/.claude/worktrees/emails-list/src/commands/teams/remove.ts +0 -83
- package/.claude/worktrees/emails-list/src/commands/teams/switch.ts +0 -73
- package/.claude/worktrees/emails-list/src/commands/topics/create.ts +0 -73
- package/.claude/worktrees/emails-list/src/commands/topics/delete.ts +0 -47
- package/.claude/worktrees/emails-list/src/commands/topics/get.ts +0 -42
- package/.claude/worktrees/emails-list/src/commands/topics/index.ts +0 -42
- package/.claude/worktrees/emails-list/src/commands/topics/list.ts +0 -34
- package/.claude/worktrees/emails-list/src/commands/topics/update.ts +0 -59
- package/.claude/worktrees/emails-list/src/commands/topics/utils.ts +0 -16
- package/.claude/worktrees/emails-list/src/commands/webhooks/create.ts +0 -128
- package/.claude/worktrees/emails-list/src/commands/webhooks/delete.ts +0 -49
- package/.claude/worktrees/emails-list/src/commands/webhooks/get.ts +0 -42
- package/.claude/worktrees/emails-list/src/commands/webhooks/index.ts +0 -44
- package/.claude/worktrees/emails-list/src/commands/webhooks/list.ts +0 -55
- package/.claude/worktrees/emails-list/src/commands/webhooks/update.ts +0 -83
- package/.claude/worktrees/emails-list/src/commands/webhooks/utils.ts +0 -36
- package/.claude/worktrees/emails-list/src/commands/whoami.ts +0 -71
- package/.claude/worktrees/emails-list/src/lib/actions.ts +0 -157
- package/.claude/worktrees/emails-list/src/lib/client.ts +0 -34
- package/.claude/worktrees/emails-list/src/lib/config.ts +0 -211
- package/.claude/worktrees/emails-list/src/lib/files.ts +0 -15
- package/.claude/worktrees/emails-list/src/lib/help-text.ts +0 -38
- package/.claude/worktrees/emails-list/src/lib/output.ts +0 -54
- package/.claude/worktrees/emails-list/src/lib/pagination.ts +0 -36
- package/.claude/worktrees/emails-list/src/lib/prompts.ts +0 -149
- package/.claude/worktrees/emails-list/src/lib/spinner.ts +0 -93
- package/.claude/worktrees/emails-list/src/lib/table.ts +0 -57
- package/.claude/worktrees/emails-list/src/lib/tty.ts +0 -28
- package/.claude/worktrees/emails-list/src/lib/version.ts +0 -4
- package/.claude/worktrees/emails-list/tests/commands/api-keys/create.test.ts +0 -195
- package/.claude/worktrees/emails-list/tests/commands/api-keys/delete.test.ts +0 -156
- package/.claude/worktrees/emails-list/tests/commands/api-keys/list.test.ts +0 -133
- package/.claude/worktrees/emails-list/tests/commands/auth/login.test.ts +0 -119
- package/.claude/worktrees/emails-list/tests/commands/auth/logout.test.ts +0 -146
- package/.claude/worktrees/emails-list/tests/commands/broadcasts/create.test.ts +0 -447
- package/.claude/worktrees/emails-list/tests/commands/broadcasts/delete.test.ts +0 -182
- package/.claude/worktrees/emails-list/tests/commands/broadcasts/get.test.ts +0 -146
- package/.claude/worktrees/emails-list/tests/commands/broadcasts/list.test.ts +0 -196
- package/.claude/worktrees/emails-list/tests/commands/broadcasts/send.test.ts +0 -161
- package/.claude/worktrees/emails-list/tests/commands/broadcasts/update.test.ts +0 -283
- package/.claude/worktrees/emails-list/tests/commands/contact-properties/create.test.ts +0 -250
- package/.claude/worktrees/emails-list/tests/commands/contact-properties/delete.test.ts +0 -183
- package/.claude/worktrees/emails-list/tests/commands/contact-properties/get.test.ts +0 -144
- package/.claude/worktrees/emails-list/tests/commands/contact-properties/list.test.ts +0 -180
- package/.claude/worktrees/emails-list/tests/commands/contact-properties/update.test.ts +0 -216
- package/.claude/worktrees/emails-list/tests/commands/contacts/add-segment.test.ts +0 -188
- package/.claude/worktrees/emails-list/tests/commands/contacts/create.test.ts +0 -270
- package/.claude/worktrees/emails-list/tests/commands/contacts/delete.test.ts +0 -192
- package/.claude/worktrees/emails-list/tests/commands/contacts/get.test.ts +0 -148
- package/.claude/worktrees/emails-list/tests/commands/contacts/list.test.ts +0 -175
- package/.claude/worktrees/emails-list/tests/commands/contacts/remove-segment.test.ts +0 -166
- package/.claude/worktrees/emails-list/tests/commands/contacts/segments.test.ts +0 -167
- package/.claude/worktrees/emails-list/tests/commands/contacts/topics.test.ts +0 -163
- package/.claude/worktrees/emails-list/tests/commands/contacts/update-topics.test.ts +0 -247
- package/.claude/worktrees/emails-list/tests/commands/contacts/update.test.ts +0 -205
- package/.claude/worktrees/emails-list/tests/commands/doctor.test.ts +0 -165
- package/.claude/worktrees/emails-list/tests/commands/domains/create.test.ts +0 -192
- package/.claude/worktrees/emails-list/tests/commands/domains/delete.test.ts +0 -156
- package/.claude/worktrees/emails-list/tests/commands/domains/get.test.ts +0 -137
- package/.claude/worktrees/emails-list/tests/commands/domains/list.test.ts +0 -164
- package/.claude/worktrees/emails-list/tests/commands/domains/update.test.ts +0 -223
- package/.claude/worktrees/emails-list/tests/commands/domains/verify.test.ts +0 -117
- package/.claude/worktrees/emails-list/tests/commands/emails/batch.test.ts +0 -313
- package/.claude/worktrees/emails-list/tests/commands/emails/list.test.ts +0 -196
- package/.claude/worktrees/emails-list/tests/commands/emails/receiving/attachment.test.ts +0 -140
- package/.claude/worktrees/emails-list/tests/commands/emails/receiving/attachments.test.ts +0 -168
- package/.claude/worktrees/emails-list/tests/commands/emails/receiving/get.test.ts +0 -140
- package/.claude/worktrees/emails-list/tests/commands/emails/receiving/list.test.ts +0 -181
- package/.claude/worktrees/emails-list/tests/commands/emails/send.test.ts +0 -309
- package/.claude/worktrees/emails-list/tests/commands/segments/create.test.ts +0 -163
- package/.claude/worktrees/emails-list/tests/commands/segments/delete.test.ts +0 -182
- package/.claude/worktrees/emails-list/tests/commands/segments/get.test.ts +0 -137
- package/.claude/worktrees/emails-list/tests/commands/segments/list.test.ts +0 -173
- package/.claude/worktrees/emails-list/tests/commands/teams/list.test.ts +0 -63
- package/.claude/worktrees/emails-list/tests/commands/teams/remove.test.ts +0 -103
- package/.claude/worktrees/emails-list/tests/commands/teams/switch.test.ts +0 -96
- package/.claude/worktrees/emails-list/tests/commands/topics/create.test.ts +0 -191
- package/.claude/worktrees/emails-list/tests/commands/topics/delete.test.ts +0 -156
- package/.claude/worktrees/emails-list/tests/commands/topics/get.test.ts +0 -125
- package/.claude/worktrees/emails-list/tests/commands/topics/list.test.ts +0 -124
- package/.claude/worktrees/emails-list/tests/commands/topics/update.test.ts +0 -177
- package/.claude/worktrees/emails-list/tests/commands/webhooks/create.test.ts +0 -224
- package/.claude/worktrees/emails-list/tests/commands/webhooks/delete.test.ts +0 -156
- package/.claude/worktrees/emails-list/tests/commands/webhooks/get.test.ts +0 -125
- package/.claude/worktrees/emails-list/tests/commands/webhooks/list.test.ts +0 -177
- package/.claude/worktrees/emails-list/tests/commands/webhooks/update.test.ts +0 -206
- package/.claude/worktrees/emails-list/tests/commands/whoami.test.ts +0 -99
- package/.claude/worktrees/emails-list/tests/helpers.ts +0 -93
- package/.claude/worktrees/emails-list/tests/lib/client.test.ts +0 -71
- package/.claude/worktrees/emails-list/tests/lib/config.test.ts +0 -414
- package/.claude/worktrees/emails-list/tests/lib/files.test.ts +0 -65
- package/.claude/worktrees/emails-list/tests/lib/help-text.test.ts +0 -97
- package/.claude/worktrees/emails-list/tests/lib/output.test.ts +0 -127
- package/.claude/worktrees/emails-list/tests/lib/prompts.test.ts +0 -178
- package/.claude/worktrees/emails-list/tests/lib/spinner.test.ts +0 -146
- package/.claude/worktrees/emails-list/tests/lib/table.test.ts +0 -63
- package/.claude/worktrees/emails-list/tests/lib/tty.test.ts +0 -85
- package/.claude/worktrees/emails-list/tsconfig.json +0 -14
- package/.github/scripts/pr-title-check.js +0 -34
- package/.github/workflows/ci.yml +0 -32
- package/.github/workflows/pr-title-check.yml +0 -13
- package/.github/workflows/release.yml +0 -120
- package/.github/workflows/test-install-windows.yml +0 -48
- package/CHANGELOG.md +0 -31
- package/biome.json +0 -36
- package/bun.lock +0 -76
- package/bunfig.toml +0 -2
- package/docs/agent-dx-gaps.md +0 -167
- package/docs/missing-commands.md +0 -58
- package/docs/production-readiness.md +0 -99
- package/docs/secure-key-storage.md +0 -174
- package/install.ps1 +0 -141
- package/install.sh +0 -301
- package/renovate.json +0 -4
- package/src/cli.ts +0 -82
- package/src/commands/api-keys/create.ts +0 -114
- package/src/commands/api-keys/delete.ts +0 -47
- package/src/commands/api-keys/index.ts +0 -26
- package/src/commands/api-keys/list.ts +0 -35
- package/src/commands/api-keys/utils.ts +0 -8
- package/src/commands/auth/index.ts +0 -20
- package/src/commands/auth/login.ts +0 -207
- package/src/commands/auth/logout.ts +0 -105
- package/src/commands/broadcasts/create.ts +0 -196
- package/src/commands/broadcasts/delete.ts +0 -46
- package/src/commands/broadcasts/get.ts +0 -59
- package/src/commands/broadcasts/index.ts +0 -43
- package/src/commands/broadcasts/list.ts +0 -60
- package/src/commands/broadcasts/send.ts +0 -56
- package/src/commands/broadcasts/update.ts +0 -95
- package/src/commands/broadcasts/utils.ts +0 -35
- package/src/commands/contact-properties/create.ts +0 -118
- package/src/commands/contact-properties/delete.ts +0 -48
- package/src/commands/contact-properties/get.ts +0 -46
- package/src/commands/contact-properties/index.ts +0 -48
- package/src/commands/contact-properties/list.ts +0 -68
- package/src/commands/contact-properties/update.ts +0 -88
- package/src/commands/contact-properties/utils.ts +0 -17
- package/src/commands/contacts/add-segment.ts +0 -78
- package/src/commands/contacts/create.ts +0 -122
- package/src/commands/contacts/delete.ts +0 -49
- package/src/commands/contacts/get.ts +0 -53
- package/src/commands/contacts/index.ts +0 -58
- package/src/commands/contacts/list.ts +0 -57
- package/src/commands/contacts/remove-segment.ts +0 -48
- package/src/commands/contacts/segments.ts +0 -39
- package/src/commands/contacts/topics.ts +0 -45
- package/src/commands/contacts/update-topics.ts +0 -90
- package/src/commands/contacts/update.ts +0 -77
- package/src/commands/contacts/utils.ts +0 -119
- package/src/commands/doctor.ts +0 -298
- package/src/commands/domains/create.ts +0 -83
- package/src/commands/domains/delete.ts +0 -42
- package/src/commands/domains/get.ts +0 -47
- package/src/commands/domains/index.ts +0 -35
- package/src/commands/domains/list.ts +0 -53
- package/src/commands/domains/update.ts +0 -75
- package/src/commands/domains/utils.ts +0 -44
- package/src/commands/domains/verify.ts +0 -38
- package/src/commands/emails/batch.ts +0 -140
- package/src/commands/emails/index.ts +0 -24
- package/src/commands/emails/receiving/attachment.ts +0 -55
- package/src/commands/emails/receiving/attachments.ts +0 -68
- package/src/commands/emails/receiving/get.ts +0 -58
- package/src/commands/emails/receiving/index.ts +0 -28
- package/src/commands/emails/receiving/list.ts +0 -59
- package/src/commands/emails/receiving/utils.ts +0 -38
- package/src/commands/emails/send.ts +0 -189
- package/src/commands/open.ts +0 -24
- package/src/commands/segments/create.ts +0 -50
- package/src/commands/segments/delete.ts +0 -47
- package/src/commands/segments/get.ts +0 -38
- package/src/commands/segments/index.ts +0 -36
- package/src/commands/segments/list.ts +0 -58
- package/src/commands/segments/utils.ts +0 -7
- package/src/commands/teams/index.ts +0 -10
- package/src/commands/teams/list.ts +0 -35
- package/src/commands/teams/remove.ts +0 -83
- package/src/commands/teams/switch.ts +0 -73
- package/src/commands/topics/create.ts +0 -73
- package/src/commands/topics/delete.ts +0 -47
- package/src/commands/topics/get.ts +0 -42
- package/src/commands/topics/index.ts +0 -42
- package/src/commands/topics/list.ts +0 -34
- package/src/commands/topics/update.ts +0 -59
- package/src/commands/topics/utils.ts +0 -16
- package/src/commands/webhooks/create.ts +0 -128
- package/src/commands/webhooks/delete.ts +0 -49
- package/src/commands/webhooks/get.ts +0 -42
- package/src/commands/webhooks/index.ts +0 -44
- package/src/commands/webhooks/list.ts +0 -55
- package/src/commands/webhooks/update.ts +0 -83
- package/src/commands/webhooks/utils.ts +0 -36
- package/src/commands/whoami.ts +0 -71
- package/src/lib/actions.ts +0 -157
- package/src/lib/client.ts +0 -37
- package/src/lib/config.ts +0 -211
- package/src/lib/files.ts +0 -15
- package/src/lib/help-text.ts +0 -38
- package/src/lib/output.ts +0 -54
- package/src/lib/pagination.ts +0 -36
- package/src/lib/prompts.ts +0 -149
- package/src/lib/spinner.ts +0 -93
- package/src/lib/table.ts +0 -57
- package/src/lib/tty.ts +0 -28
- package/src/lib/version.ts +0 -4
- package/tests/commands/api-keys/create.test.ts +0 -195
- package/tests/commands/api-keys/delete.test.ts +0 -156
- package/tests/commands/api-keys/list.test.ts +0 -133
- package/tests/commands/auth/login.test.ts +0 -119
- package/tests/commands/auth/logout.test.ts +0 -146
- package/tests/commands/broadcasts/create.test.ts +0 -447
- package/tests/commands/broadcasts/delete.test.ts +0 -182
- package/tests/commands/broadcasts/get.test.ts +0 -146
- package/tests/commands/broadcasts/list.test.ts +0 -196
- package/tests/commands/broadcasts/send.test.ts +0 -161
- package/tests/commands/broadcasts/update.test.ts +0 -283
- package/tests/commands/contact-properties/create.test.ts +0 -250
- package/tests/commands/contact-properties/delete.test.ts +0 -183
- package/tests/commands/contact-properties/get.test.ts +0 -144
- package/tests/commands/contact-properties/list.test.ts +0 -180
- package/tests/commands/contact-properties/update.test.ts +0 -216
- package/tests/commands/contacts/add-segment.test.ts +0 -188
- package/tests/commands/contacts/create.test.ts +0 -270
- package/tests/commands/contacts/delete.test.ts +0 -192
- package/tests/commands/contacts/get.test.ts +0 -148
- package/tests/commands/contacts/list.test.ts +0 -175
- package/tests/commands/contacts/remove-segment.test.ts +0 -166
- package/tests/commands/contacts/segments.test.ts +0 -167
- package/tests/commands/contacts/topics.test.ts +0 -163
- package/tests/commands/contacts/update-topics.test.ts +0 -247
- package/tests/commands/contacts/update.test.ts +0 -205
- package/tests/commands/doctor.test.ts +0 -165
- package/tests/commands/domains/create.test.ts +0 -192
- package/tests/commands/domains/delete.test.ts +0 -156
- package/tests/commands/domains/get.test.ts +0 -137
- package/tests/commands/domains/list.test.ts +0 -164
- package/tests/commands/domains/update.test.ts +0 -223
- package/tests/commands/domains/verify.test.ts +0 -117
- package/tests/commands/emails/batch.test.ts +0 -313
- package/tests/commands/emails/receiving/attachment.test.ts +0 -140
- package/tests/commands/emails/receiving/attachments.test.ts +0 -168
- package/tests/commands/emails/receiving/get.test.ts +0 -140
- package/tests/commands/emails/receiving/list.test.ts +0 -181
- package/tests/commands/emails/send.test.ts +0 -309
- package/tests/commands/segments/create.test.ts +0 -163
- package/tests/commands/segments/delete.test.ts +0 -182
- package/tests/commands/segments/get.test.ts +0 -137
- package/tests/commands/segments/list.test.ts +0 -173
- package/tests/commands/teams/list.test.ts +0 -63
- package/tests/commands/teams/remove.test.ts +0 -103
- package/tests/commands/teams/switch.test.ts +0 -96
- package/tests/commands/topics/create.test.ts +0 -191
- package/tests/commands/topics/delete.test.ts +0 -156
- package/tests/commands/topics/get.test.ts +0 -125
- package/tests/commands/topics/list.test.ts +0 -124
- package/tests/commands/topics/update.test.ts +0 -177
- package/tests/commands/webhooks/create.test.ts +0 -224
- package/tests/commands/webhooks/delete.test.ts +0 -156
- package/tests/commands/webhooks/get.test.ts +0 -125
- package/tests/commands/webhooks/list.test.ts +0 -177
- package/tests/commands/webhooks/update.test.ts +0 -206
- package/tests/commands/whoami.test.ts +0 -99
- package/tests/helpers.ts +0 -93
- package/tests/lib/client.test.ts +0 -71
- package/tests/lib/config.test.ts +0 -414
- package/tests/lib/files.test.ts +0 -65
- package/tests/lib/help-text.test.ts +0 -97
- package/tests/lib/output.test.ts +0 -127
- package/tests/lib/prompts.test.ts +0 -178
- package/tests/lib/spinner.test.ts +0 -146
- package/tests/lib/table.test.ts +0 -63
- package/tests/lib/tty.test.ts +0 -85
- package/tsconfig.json +0 -14
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { buildHelpText } from '../../../lib/help-text';
|
|
3
|
-
import { getAttachmentCommand } from './attachment';
|
|
4
|
-
import { listAttachmentsCommand } from './attachments';
|
|
5
|
-
import { getReceivingCommand } from './get';
|
|
6
|
-
import { listReceivingCommand } from './list';
|
|
7
|
-
|
|
8
|
-
export const receivingCommand = new Command('receiving')
|
|
9
|
-
.description(
|
|
10
|
-
'Manage received (inbound) emails — requires domain receiving to be enabled',
|
|
11
|
-
)
|
|
12
|
-
.addHelpText(
|
|
13
|
-
'after',
|
|
14
|
-
buildHelpText({
|
|
15
|
-
context:
|
|
16
|
-
'Receiving must be enabled on the domain first:\n resend domains update <id> --receiving enabled',
|
|
17
|
-
examples: [
|
|
18
|
-
'resend emails receiving list',
|
|
19
|
-
'resend emails receiving get <email-id>',
|
|
20
|
-
'resend emails receiving attachments <email-id>',
|
|
21
|
-
'resend emails receiving attachment <email-id> <attachment-id>',
|
|
22
|
-
],
|
|
23
|
-
}),
|
|
24
|
-
)
|
|
25
|
-
.addCommand(listReceivingCommand, { isDefault: true })
|
|
26
|
-
.addCommand(getReceivingCommand)
|
|
27
|
-
.addCommand(listAttachmentsCommand)
|
|
28
|
-
.addCommand(getAttachmentCommand);
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { runList } from '../../../lib/actions';
|
|
3
|
-
import type { GlobalOpts } from '../../../lib/client';
|
|
4
|
-
import { buildHelpText } from '../../../lib/help-text';
|
|
5
|
-
import {
|
|
6
|
-
buildPaginationOpts,
|
|
7
|
-
parseLimitOpt,
|
|
8
|
-
printPaginationHint,
|
|
9
|
-
} from '../../../lib/pagination';
|
|
10
|
-
import { renderReceivingEmailsTable } from './utils';
|
|
11
|
-
|
|
12
|
-
export const listReceivingCommand = new Command('list')
|
|
13
|
-
.alias('ls')
|
|
14
|
-
.description(
|
|
15
|
-
'List received (inbound) emails for domains with receiving enabled',
|
|
16
|
-
)
|
|
17
|
-
.option('--limit <n>', 'Maximum number of emails to return (1-100)', '10')
|
|
18
|
-
.option('--after <cursor>', 'Return emails after this cursor (next page)')
|
|
19
|
-
.option(
|
|
20
|
-
'--before <cursor>',
|
|
21
|
-
'Return emails before this cursor (previous page)',
|
|
22
|
-
)
|
|
23
|
-
.addHelpText(
|
|
24
|
-
'after',
|
|
25
|
-
buildHelpText({
|
|
26
|
-
context:
|
|
27
|
-
'Receiving must be enabled on the domain first:\n resend domains update <id> --receiving enabled\n\nPagination: use --after or --before with a received email ID as the cursor.\nOnly one of --after or --before may be used at a time.\nThe response includes has_more: true when additional pages exist.',
|
|
28
|
-
output:
|
|
29
|
-
' {"object":"list","has_more":false,"data":[{"id":"<uuid>","to":["inbox@yourdomain.com"],"from":"sender@external.com","subject":"Hello","created_at":"<iso-date>","message_id":"<str>","bcc":null,"cc":null,"reply_to":null,"attachments":[]}]}',
|
|
30
|
-
errorCodes: ['auth_error', 'invalid_limit', 'list_error'],
|
|
31
|
-
examples: [
|
|
32
|
-
'resend emails receiving list',
|
|
33
|
-
'resend emails receiving list --limit 25 --json',
|
|
34
|
-
'resend emails receiving list --after <email-id> --json',
|
|
35
|
-
],
|
|
36
|
-
}),
|
|
37
|
-
)
|
|
38
|
-
.action(async (opts, cmd) => {
|
|
39
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
40
|
-
|
|
41
|
-
const limit = parseLimitOpt(opts.limit, globalOpts);
|
|
42
|
-
const paginationOpts = buildPaginationOpts(limit, opts.after, opts.before);
|
|
43
|
-
|
|
44
|
-
await runList(
|
|
45
|
-
{
|
|
46
|
-
spinner: {
|
|
47
|
-
loading: 'Fetching received emails...',
|
|
48
|
-
success: 'Received emails fetched',
|
|
49
|
-
fail: 'Failed to list received emails',
|
|
50
|
-
},
|
|
51
|
-
sdkCall: (resend) => resend.emails.receiving.list(paginationOpts),
|
|
52
|
-
onInteractive: (list) => {
|
|
53
|
-
console.log(renderReceivingEmailsTable(list.data));
|
|
54
|
-
printPaginationHint(list);
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
globalOpts,
|
|
58
|
-
);
|
|
59
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ListAttachmentsResponseSuccess,
|
|
3
|
-
ListReceivingEmail,
|
|
4
|
-
} from 'resend';
|
|
5
|
-
import { renderTable } from '../../../lib/table';
|
|
6
|
-
|
|
7
|
-
export function renderReceivingEmailsTable(
|
|
8
|
-
emails: ListReceivingEmail[],
|
|
9
|
-
): string {
|
|
10
|
-
const rows = emails.map((e) => {
|
|
11
|
-
const to = e.to.join(', ');
|
|
12
|
-
const toStr = to.length > 40 ? `${to.slice(0, 37)}...` : to;
|
|
13
|
-
const subject =
|
|
14
|
-
e.subject.length > 50 ? `${e.subject.slice(0, 47)}...` : e.subject;
|
|
15
|
-
return [e.from, toStr, subject, e.created_at, e.id];
|
|
16
|
-
});
|
|
17
|
-
return renderTable(
|
|
18
|
-
['From', 'To', 'Subject', 'Created At', 'ID'],
|
|
19
|
-
rows,
|
|
20
|
-
'(no received emails)',
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function renderAttachmentsTable(
|
|
25
|
-
attachments: ListAttachmentsResponseSuccess['data'],
|
|
26
|
-
): string {
|
|
27
|
-
const rows = attachments.map((a) => [
|
|
28
|
-
a.filename ?? '(unnamed)',
|
|
29
|
-
a.content_type,
|
|
30
|
-
String(a.size),
|
|
31
|
-
a.id,
|
|
32
|
-
]);
|
|
33
|
-
return renderTable(
|
|
34
|
-
['Filename', 'Content-Type', 'Size (bytes)', 'ID'],
|
|
35
|
-
rows,
|
|
36
|
-
'(no attachments)',
|
|
37
|
-
);
|
|
38
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import * as p from '@clack/prompts';
|
|
2
|
-
import { Command } from '@commander-js/extra-typings';
|
|
3
|
-
import type { Resend } from 'resend';
|
|
4
|
-
import type { GlobalOpts } from '../../lib/client';
|
|
5
|
-
import { requireClient } from '../../lib/client';
|
|
6
|
-
import { readFile } from '../../lib/files';
|
|
7
|
-
import { buildHelpText } from '../../lib/help-text';
|
|
8
|
-
import { outputResult } from '../../lib/output';
|
|
9
|
-
import {
|
|
10
|
-
cancelAndExit,
|
|
11
|
-
promptForMissing,
|
|
12
|
-
requireText,
|
|
13
|
-
} from '../../lib/prompts';
|
|
14
|
-
import { withSpinner } from '../../lib/spinner';
|
|
15
|
-
import { isInteractive } from '../../lib/tty';
|
|
16
|
-
|
|
17
|
-
export async function fetchVerifiedDomains(resend: Resend): Promise<string[]> {
|
|
18
|
-
try {
|
|
19
|
-
const { data, error } = await resend.domains.list();
|
|
20
|
-
if (error || !data) {
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
return data.data
|
|
24
|
-
.filter(
|
|
25
|
-
(d) => d.status === 'verified' && d.capabilities.sending === 'enabled',
|
|
26
|
-
)
|
|
27
|
-
.map((d) => d.name);
|
|
28
|
-
} catch {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const FROM_PREFIXES = ['noreply', 'hello', 'hi', 'info', 'support', 'team'];
|
|
34
|
-
|
|
35
|
-
async function promptForFromAddress(domains: string[]): Promise<string> {
|
|
36
|
-
let domain: string;
|
|
37
|
-
if (domains.length === 1) {
|
|
38
|
-
domain = domains[0];
|
|
39
|
-
} else {
|
|
40
|
-
const result = await p.select({
|
|
41
|
-
message: 'Select a verified domain',
|
|
42
|
-
options: domains.map((d) => ({ value: d, label: d })),
|
|
43
|
-
});
|
|
44
|
-
if (p.isCancel(result)) {
|
|
45
|
-
cancelAndExit('Send cancelled.');
|
|
46
|
-
}
|
|
47
|
-
domain = result;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const options: Array<{ value: string | null; label: string }> =
|
|
51
|
-
FROM_PREFIXES.map((prefix) => ({
|
|
52
|
-
value: `${prefix}@${domain}`,
|
|
53
|
-
label: `${prefix}@${domain}`,
|
|
54
|
-
}));
|
|
55
|
-
options.push({ value: null, label: 'Custom address...' });
|
|
56
|
-
|
|
57
|
-
const result = await p.select({
|
|
58
|
-
message: `From address (@${domain})`,
|
|
59
|
-
options,
|
|
60
|
-
});
|
|
61
|
-
if (p.isCancel(result)) {
|
|
62
|
-
cancelAndExit('Send cancelled.');
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (result === null) {
|
|
66
|
-
const custom = await p.text({
|
|
67
|
-
message: 'From address',
|
|
68
|
-
placeholder: `you@${domain}`,
|
|
69
|
-
validate: (v) =>
|
|
70
|
-
!v || !v.includes('@') ? 'Enter a valid email address' : undefined,
|
|
71
|
-
});
|
|
72
|
-
if (p.isCancel(custom)) {
|
|
73
|
-
cancelAndExit('Send cancelled.');
|
|
74
|
-
}
|
|
75
|
-
return custom;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export const sendCommand = new Command('send')
|
|
82
|
-
.description('Send an email')
|
|
83
|
-
.option('--from <address>', 'Sender address (required)')
|
|
84
|
-
.option('--to <addresses...>', 'Recipient address(es) (required)')
|
|
85
|
-
.option('--subject <subject>', 'Email subject (required)')
|
|
86
|
-
.option('--html <html>', 'HTML body')
|
|
87
|
-
.option('--html-file <path>', 'Path to an HTML file for the body')
|
|
88
|
-
.option('--text <text>', 'Plain-text body')
|
|
89
|
-
.option('--cc <addresses...>', 'CC recipients')
|
|
90
|
-
.option('--bcc <addresses...>', 'BCC recipients')
|
|
91
|
-
.option('--reply-to <address>', 'Reply-to address')
|
|
92
|
-
.addHelpText(
|
|
93
|
-
'after',
|
|
94
|
-
buildHelpText({
|
|
95
|
-
context:
|
|
96
|
-
'Required: --from, --to, --subject, and one of --text | --html | --html-file',
|
|
97
|
-
output: ' {"id":"<email-id>"}',
|
|
98
|
-
errorCodes: ['auth_error', 'missing_body', 'send_error'],
|
|
99
|
-
examples: [
|
|
100
|
-
'resend emails send --from you@domain.com --to user@example.com --subject "Hello" --text "Hi"',
|
|
101
|
-
'resend emails send --from you@domain.com --to a@example.com --to b@example.com --subject "Hi" --html "<b>Hi</b>" --json',
|
|
102
|
-
'resend emails send --from you@domain.com --to user@example.com --subject "Hi" --html-file ./email.html --json',
|
|
103
|
-
'RESEND_API_KEY=re_123 resend emails send --from you@domain.com --to user@example.com --subject "Hi" --text "Hi"',
|
|
104
|
-
],
|
|
105
|
-
}),
|
|
106
|
-
)
|
|
107
|
-
.action(async (opts, cmd) => {
|
|
108
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
109
|
-
|
|
110
|
-
const resend = requireClient(globalOpts);
|
|
111
|
-
|
|
112
|
-
// Only fetch verified domains in interactive mode — non-interactive
|
|
113
|
-
// callers (CI, agents, scripts) must pass --from explicitly.
|
|
114
|
-
let fromAddress = opts.from;
|
|
115
|
-
if (!fromAddress && isInteractive()) {
|
|
116
|
-
const domains = await fetchVerifiedDomains(resend);
|
|
117
|
-
if (domains.length > 0) {
|
|
118
|
-
fromAddress = await promptForFromAddress(domains);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const filled = await promptForMissing(
|
|
123
|
-
{ from: fromAddress, to: opts.to?.[0], subject: opts.subject },
|
|
124
|
-
[
|
|
125
|
-
{
|
|
126
|
-
flag: 'from',
|
|
127
|
-
message: 'From address',
|
|
128
|
-
placeholder: 'you@example.com',
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
flag: 'to',
|
|
132
|
-
message: 'To address',
|
|
133
|
-
placeholder: 'recipient@example.com',
|
|
134
|
-
},
|
|
135
|
-
{ flag: 'subject', message: 'Subject', placeholder: 'Hello!' },
|
|
136
|
-
],
|
|
137
|
-
globalOpts,
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
let html = opts.html;
|
|
141
|
-
const text = opts.text;
|
|
142
|
-
|
|
143
|
-
if (opts.htmlFile) {
|
|
144
|
-
html = readFile(opts.htmlFile, globalOpts);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
let body: string | undefined = text;
|
|
148
|
-
if (!html && !text) {
|
|
149
|
-
body = await requireText(
|
|
150
|
-
undefined,
|
|
151
|
-
{
|
|
152
|
-
message: 'Email body (plain text)',
|
|
153
|
-
placeholder: 'Type your message...',
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
message: 'Missing email body. Provide --html, --html-file, or --text',
|
|
157
|
-
code: 'missing_body',
|
|
158
|
-
},
|
|
159
|
-
globalOpts,
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const toAddresses = opts.to ?? [filled.to];
|
|
164
|
-
|
|
165
|
-
const data = await withSpinner(
|
|
166
|
-
{
|
|
167
|
-
loading: 'Sending email...',
|
|
168
|
-
success: 'Email sent',
|
|
169
|
-
fail: 'Failed to send email',
|
|
170
|
-
},
|
|
171
|
-
() =>
|
|
172
|
-
resend.emails.send({
|
|
173
|
-
from: filled.from,
|
|
174
|
-
to: toAddresses,
|
|
175
|
-
subject: filled.subject,
|
|
176
|
-
...(html ? { html } : { text: body as string }),
|
|
177
|
-
...(opts.cc && { cc: opts.cc }),
|
|
178
|
-
...(opts.bcc && { bcc: opts.bcc }),
|
|
179
|
-
...(opts.replyTo && { replyTo: opts.replyTo }),
|
|
180
|
-
}),
|
|
181
|
-
'send_error',
|
|
182
|
-
globalOpts,
|
|
183
|
-
);
|
|
184
|
-
if (!globalOpts.json && isInteractive()) {
|
|
185
|
-
console.log(`\nEmail sent: ${data.id}`);
|
|
186
|
-
} else {
|
|
187
|
-
outputResult(data, { json: globalOpts.json });
|
|
188
|
-
}
|
|
189
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { buildHelpText } from '../lib/help-text';
|
|
3
|
-
|
|
4
|
-
export const openCommand = new Command('open')
|
|
5
|
-
.description('Open the Resend dashboard in your browser')
|
|
6
|
-
.addHelpText(
|
|
7
|
-
'after',
|
|
8
|
-
buildHelpText({
|
|
9
|
-
context: 'Opens https://resend.com/emails in your default browser.',
|
|
10
|
-
examples: ['resend open'],
|
|
11
|
-
}),
|
|
12
|
-
)
|
|
13
|
-
.action(async () => {
|
|
14
|
-
const url = 'https://resend.com/emails';
|
|
15
|
-
const { platform } = process;
|
|
16
|
-
const args =
|
|
17
|
-
platform === 'darwin'
|
|
18
|
-
? ['open', url]
|
|
19
|
-
: platform === 'win32'
|
|
20
|
-
? ['cmd', '/c', 'start', url]
|
|
21
|
-
: ['xdg-open', url];
|
|
22
|
-
|
|
23
|
-
Bun.spawn(args, { stdio: ['ignore', 'ignore', 'ignore'] });
|
|
24
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { runCreate } from '../../lib/actions';
|
|
3
|
-
import type { GlobalOpts } from '../../lib/client';
|
|
4
|
-
import { buildHelpText } from '../../lib/help-text';
|
|
5
|
-
import { requireText } from '../../lib/prompts';
|
|
6
|
-
|
|
7
|
-
export const createSegmentCommand = new Command('create')
|
|
8
|
-
.description('Create a new segment')
|
|
9
|
-
.option('--name <name>', 'Segment name (required)')
|
|
10
|
-
.addHelpText(
|
|
11
|
-
'after',
|
|
12
|
-
buildHelpText({
|
|
13
|
-
context: `Segments are named groups of contacts. Broadcasts target segments via segment_id.
|
|
14
|
-
Contacts can belong to multiple segments. Audiences are deprecated — use segments instead.
|
|
15
|
-
|
|
16
|
-
Non-interactive: --name is required.`,
|
|
17
|
-
output: ` {"object":"segment","id":"<uuid>","name":"<name>"}`,
|
|
18
|
-
errorCodes: ['auth_error', 'missing_name', 'create_error'],
|
|
19
|
-
examples: [
|
|
20
|
-
'resend segments create --name "Newsletter Subscribers"',
|
|
21
|
-
'resend segments create --name "Beta Users" --json',
|
|
22
|
-
],
|
|
23
|
-
}),
|
|
24
|
-
)
|
|
25
|
-
.action(async (opts, cmd) => {
|
|
26
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
27
|
-
|
|
28
|
-
const name = await requireText(
|
|
29
|
-
opts.name,
|
|
30
|
-
{ message: 'Segment name', placeholder: 'Newsletter Subscribers' },
|
|
31
|
-
{ message: 'Missing --name flag.', code: 'missing_name' },
|
|
32
|
-
globalOpts,
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
await runCreate(
|
|
36
|
-
{
|
|
37
|
-
spinner: {
|
|
38
|
-
loading: 'Creating segment...',
|
|
39
|
-
success: 'Segment created',
|
|
40
|
-
fail: 'Failed to create segment',
|
|
41
|
-
},
|
|
42
|
-
sdkCall: (resend) => resend.segments.create({ name }),
|
|
43
|
-
onInteractive: (data) => {
|
|
44
|
-
console.log(`\nSegment created: ${data.id}`);
|
|
45
|
-
console.log(`Name: ${data.name}`);
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
globalOpts,
|
|
49
|
-
);
|
|
50
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { runDelete } from '../../lib/actions';
|
|
3
|
-
import type { GlobalOpts } from '../../lib/client';
|
|
4
|
-
import { buildHelpText } from '../../lib/help-text';
|
|
5
|
-
|
|
6
|
-
export const deleteSegmentCommand = new Command('delete')
|
|
7
|
-
.alias('rm')
|
|
8
|
-
.description('Delete a segment')
|
|
9
|
-
.argument('<id>', 'Segment UUID')
|
|
10
|
-
.option(
|
|
11
|
-
'--yes',
|
|
12
|
-
'Skip the confirmation prompt (required in non-interactive mode)',
|
|
13
|
-
)
|
|
14
|
-
.addHelpText(
|
|
15
|
-
'after',
|
|
16
|
-
buildHelpText({
|
|
17
|
-
context: `Warning: Deleting a segment removes it as a target for future broadcasts,
|
|
18
|
-
but does NOT delete the contacts within it.
|
|
19
|
-
|
|
20
|
-
Non-interactive: --yes is required to confirm deletion when stdin/stdout is not a TTY.`,
|
|
21
|
-
output: ` {"object":"segment","id":"<uuid>","deleted":true}`,
|
|
22
|
-
errorCodes: ['auth_error', 'confirmation_required', 'delete_error'],
|
|
23
|
-
examples: [
|
|
24
|
-
'resend segments delete 78261eea-8f8b-4381-83c6-79fa7120f1cf --yes',
|
|
25
|
-
'resend segments delete 78261eea-8f8b-4381-83c6-79fa7120f1cf --yes --json',
|
|
26
|
-
],
|
|
27
|
-
}),
|
|
28
|
-
)
|
|
29
|
-
.action(async (id, opts, cmd) => {
|
|
30
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
31
|
-
await runDelete(
|
|
32
|
-
id,
|
|
33
|
-
!!opts.yes,
|
|
34
|
-
{
|
|
35
|
-
confirmMessage: `Delete segment ${id}?\nContacts will not be deleted, but broadcasts targeting this segment will no longer work.`,
|
|
36
|
-
spinner: {
|
|
37
|
-
loading: 'Deleting segment...',
|
|
38
|
-
success: 'Segment deleted',
|
|
39
|
-
fail: 'Failed to delete segment',
|
|
40
|
-
},
|
|
41
|
-
object: 'segment',
|
|
42
|
-
successMsg: 'Segment deleted.',
|
|
43
|
-
sdkCall: (resend) => resend.segments.remove(id),
|
|
44
|
-
},
|
|
45
|
-
globalOpts,
|
|
46
|
-
);
|
|
47
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { runGet } from '../../lib/actions';
|
|
3
|
-
import type { GlobalOpts } from '../../lib/client';
|
|
4
|
-
import { buildHelpText } from '../../lib/help-text';
|
|
5
|
-
|
|
6
|
-
export const getSegmentCommand = new Command('get')
|
|
7
|
-
.description('Retrieve a segment by ID')
|
|
8
|
-
.argument('<id>', 'Segment UUID')
|
|
9
|
-
.addHelpText(
|
|
10
|
-
'after',
|
|
11
|
-
buildHelpText({
|
|
12
|
-
output: ` {"object":"segment","id":"<uuid>","name":"<name>","created_at":"<iso-date>"}`,
|
|
13
|
-
errorCodes: ['auth_error', 'fetch_error'],
|
|
14
|
-
examples: [
|
|
15
|
-
'resend segments get 78261eea-8f8b-4381-83c6-79fa7120f1cf',
|
|
16
|
-
'resend segments get 78261eea-8f8b-4381-83c6-79fa7120f1cf --json',
|
|
17
|
-
],
|
|
18
|
-
}),
|
|
19
|
-
)
|
|
20
|
-
.action(async (id, _opts, cmd) => {
|
|
21
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
22
|
-
await runGet(
|
|
23
|
-
{
|
|
24
|
-
spinner: {
|
|
25
|
-
loading: 'Fetching segment...',
|
|
26
|
-
success: 'Segment fetched',
|
|
27
|
-
fail: 'Failed to fetch segment',
|
|
28
|
-
},
|
|
29
|
-
sdkCall: (resend) => resend.segments.get(id),
|
|
30
|
-
onInteractive: (data) => {
|
|
31
|
-
console.log(`\n${data.name}`);
|
|
32
|
-
console.log(`ID: ${data.id}`);
|
|
33
|
-
console.log(`Created: ${data.created_at}`);
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
globalOpts,
|
|
37
|
-
);
|
|
38
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { buildHelpText } from '../../lib/help-text';
|
|
3
|
-
import { createSegmentCommand } from './create';
|
|
4
|
-
import { deleteSegmentCommand } from './delete';
|
|
5
|
-
import { getSegmentCommand } from './get';
|
|
6
|
-
import { listSegmentsCommand } from './list';
|
|
7
|
-
|
|
8
|
-
export const segmentsCommand = new Command('segments')
|
|
9
|
-
.description(
|
|
10
|
-
'Manage segments — named groups of contacts used to target broadcasts',
|
|
11
|
-
)
|
|
12
|
-
.addHelpText(
|
|
13
|
-
'after',
|
|
14
|
-
buildHelpText({
|
|
15
|
-
context: `Segments are the modern replacement for Audiences (deprecated).
|
|
16
|
-
A segment is a named group of contacts. Broadcasts target segments via segment_id.
|
|
17
|
-
Contacts can belong to multiple segments.
|
|
18
|
-
|
|
19
|
-
Segment membership is managed through the contacts namespace:
|
|
20
|
-
resend contacts add-segment <contactId> --segment-id <segmentId>
|
|
21
|
-
resend contacts remove-segment <contactId> <segmentId>
|
|
22
|
-
resend contacts segments <contactId>
|
|
23
|
-
|
|
24
|
-
There is no "update" endpoint — to rename a segment, delete it and recreate.`,
|
|
25
|
-
examples: [
|
|
26
|
-
'resend segments list',
|
|
27
|
-
'resend segments create --name "Newsletter Subscribers"',
|
|
28
|
-
'resend segments get 78261eea-8f8b-4381-83c6-79fa7120f1cf',
|
|
29
|
-
'resend segments delete 78261eea-8f8b-4381-83c6-79fa7120f1cf --yes',
|
|
30
|
-
],
|
|
31
|
-
}),
|
|
32
|
-
)
|
|
33
|
-
.addCommand(createSegmentCommand)
|
|
34
|
-
.addCommand(getSegmentCommand)
|
|
35
|
-
.addCommand(listSegmentsCommand, { isDefault: true })
|
|
36
|
-
.addCommand(deleteSegmentCommand);
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { runList } from '../../lib/actions';
|
|
3
|
-
import type { GlobalOpts } from '../../lib/client';
|
|
4
|
-
import { buildHelpText } from '../../lib/help-text';
|
|
5
|
-
import {
|
|
6
|
-
buildPaginationOpts,
|
|
7
|
-
parseLimitOpt,
|
|
8
|
-
printPaginationHint,
|
|
9
|
-
} from '../../lib/pagination';
|
|
10
|
-
import { renderSegmentsTable } from './utils';
|
|
11
|
-
|
|
12
|
-
export const listSegmentsCommand = new Command('list')
|
|
13
|
-
.alias('ls')
|
|
14
|
-
.description('List all segments')
|
|
15
|
-
.option('--limit <n>', 'Maximum number of segments to return (1-100)', '10')
|
|
16
|
-
.option('--after <cursor>', 'Return segments after this cursor (next page)')
|
|
17
|
-
.option(
|
|
18
|
-
'--before <cursor>',
|
|
19
|
-
'Return segments before this cursor (previous page)',
|
|
20
|
-
)
|
|
21
|
-
.addHelpText(
|
|
22
|
-
'after',
|
|
23
|
-
buildHelpText({
|
|
24
|
-
context: `Pagination: use --after or --before with a segment ID as the cursor.
|
|
25
|
-
Only one of --after or --before may be used at a time.
|
|
26
|
-
The response includes has_more: true when additional pages exist.
|
|
27
|
-
|
|
28
|
-
Use "resend segments list" to discover segment IDs for use with broadcasts
|
|
29
|
-
or "resend contacts add-segment".`,
|
|
30
|
-
output: ` {"object":"list","data":[{"id":"<uuid>","name":"<name>","created_at":"<iso-date>"}],"has_more":false}`,
|
|
31
|
-
errorCodes: ['auth_error', 'invalid_limit', 'list_error'],
|
|
32
|
-
examples: [
|
|
33
|
-
'resend segments list',
|
|
34
|
-
'resend segments list --limit 25 --json',
|
|
35
|
-
'resend segments list --after 78261eea-8f8b-4381-83c6-79fa7120f1cf --json',
|
|
36
|
-
],
|
|
37
|
-
}),
|
|
38
|
-
)
|
|
39
|
-
.action(async (opts, cmd) => {
|
|
40
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
41
|
-
const limit = parseLimitOpt(opts.limit, globalOpts);
|
|
42
|
-
const paginationOpts = buildPaginationOpts(limit, opts.after, opts.before);
|
|
43
|
-
await runList(
|
|
44
|
-
{
|
|
45
|
-
spinner: {
|
|
46
|
-
loading: 'Fetching segments...',
|
|
47
|
-
success: 'Segments fetched',
|
|
48
|
-
fail: 'Failed to list segments',
|
|
49
|
-
},
|
|
50
|
-
sdkCall: (resend) => resend.segments.list(paginationOpts),
|
|
51
|
-
onInteractive: (list) => {
|
|
52
|
-
console.log(renderSegmentsTable(list.data));
|
|
53
|
-
printPaginationHint(list);
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
globalOpts,
|
|
57
|
-
);
|
|
58
|
-
});
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Segment } from 'resend';
|
|
2
|
-
import { renderTable } from '../../lib/table';
|
|
3
|
-
|
|
4
|
-
export function renderSegmentsTable(segments: Segment[]): string {
|
|
5
|
-
const rows = segments.map((s) => [s.name, s.id, s.created_at]);
|
|
6
|
-
return renderTable(['Name', 'ID', 'Created'], rows, '(no segments)');
|
|
7
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import { listCommand } from './list';
|
|
3
|
-
import { removeCommand } from './remove';
|
|
4
|
-
import { switchCommand } from './switch';
|
|
5
|
-
|
|
6
|
-
export const teamsCommand = new Command('teams')
|
|
7
|
-
.description('Manage team profiles for multiple API keys')
|
|
8
|
-
.addCommand(listCommand)
|
|
9
|
-
.addCommand(switchCommand)
|
|
10
|
-
.addCommand(removeCommand);
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings';
|
|
2
|
-
import type { GlobalOpts } from '../../lib/client';
|
|
3
|
-
import { listTeams } from '../../lib/config';
|
|
4
|
-
import { outputResult } from '../../lib/output';
|
|
5
|
-
import { isInteractive } from '../../lib/tty';
|
|
6
|
-
|
|
7
|
-
export const listCommand = new Command('list')
|
|
8
|
-
.description('List all team profiles')
|
|
9
|
-
.action((_opts, cmd) => {
|
|
10
|
-
const globalOpts = cmd.optsWithGlobals() as GlobalOpts;
|
|
11
|
-
const teams = listTeams();
|
|
12
|
-
|
|
13
|
-
if (globalOpts.json) {
|
|
14
|
-
outputResult({ teams }, { json: true });
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (teams.length === 0) {
|
|
19
|
-
console.log('No teams configured. Run: resend login');
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (isInteractive()) {
|
|
24
|
-
console.log('\n Teams\n');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
for (const team of teams) {
|
|
28
|
-
const marker = team.active ? ' (active)' : '';
|
|
29
|
-
console.log(` ${team.active ? '▸' : ' '} ${team.name}${marker}`);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (isInteractive()) {
|
|
33
|
-
console.log('');
|
|
34
|
-
}
|
|
35
|
-
});
|